blob: 9c45a32f8d5ca141a272f3138126e339fbcec0c3 [file] [log] [blame]
Harald Welte0db44132019-10-17 11:09:05 +02001module STP_Tests_M3UA {
2
3/* Osmocom STP test suite in in TTCN-3
4 * (C) 2019 Harald Welte <laforge@gnumonks.org>
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +07005 * (C) 2024 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
Harald Welte0db44132019-10-17 11:09:05 +02006 * All rights reserved.
7 *
8 * Released under the terms of GNU General Public License, Version 2 or
9 * (at your option) any later version.
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 */
13
14friend module STP_Tests;
15
16import from General_Types all;
17import from Osmocom_Types all;
18import from IPL4asp_Types all;
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +070019import from Misc_Helpers all;
Harald Welte0db44132019-10-17 11:09:05 +020020
21import from Osmocom_VTY_Functions all;
22
23import from M3UA_Types all;
24import from M3UA_Templates all;
25import from M3UA_CodecPort all;
26import from M3UA_CodecPort_CtrlFunct all;
27
28import from M3UA_Emulation all;
29import from MTP3asp_Types all;
30import from MTP3asp_PortType all;
31
32import from SCCP_Types all;
33import from SCCP_Templates all;
34import from SCCPasp_Types all;
35import from SCCP_Emulation all;
Vadim Yanitskiy741aa572024-06-12 06:16:43 +070036import from SCTP_Templates all;
Harald Welte0db44132019-10-17 11:09:05 +020037
38import from STP_Tests_Common all;
39
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +070040private const integer NR_M3UA := 4; /* number of M3UA clients in ATS */
41private const integer NR_M3UA_SRV := 4; /* number of M3UA servres in ATS */
Harald Welte829dac42019-11-05 16:55:30 +010042
Harald Welte1c4e9842021-02-07 23:03:28 +010043modulepar {
44 /* STP-side IP addresses */
45 HostList mp_stp_m3ua_ip := { "127.0.0.1", "::1" };
46 /* local IP addresses */
47 HostList mp_local_m3ua_ip := { "127.0.0.1", "::1" };
48 M3uaConfigs mp_m3ua_configs := {
49 /* as-sender: One ASP within AS */
50 {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +070051 use_tcp := false,
52 remote_port := 2905,
53 local_port := 9999,
Harald Welte1c4e9842021-02-07 23:03:28 +010054 point_code := 23,
55 routing_ctx := 1023
56 },
57 /* as-receiver: Two ASP within AS */
58 {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +070059 use_tcp := false,
60 remote_port := 2905,
61 local_port := 10000,
Harald Welte1c4e9842021-02-07 23:03:28 +010062 point_code := 42,
63 routing_ctx := 1042
64 }, {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +070065 use_tcp := false,
66 remote_port := 2905,
67 local_port := 10001,
Harald Welte1c4e9842021-02-07 23:03:28 +010068 point_code := 42,
69 routing_ctx := 1042
70 },
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +070071 /* as-sender-tcp: One ASP within AS */
72 {
73 use_tcp := true,
74 remote_port := 2905,
75 local_port := 9999,
76 point_code := 123,
77 routing_ctx := 1123
78 },
Harald Welte1c4e9842021-02-07 23:03:28 +010079 /* as-client: One ASP within AS */
80 {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +070081 use_tcp := false,
82 remote_port := 2906,
83 local_port := 10002,
Harald Welte1c4e9842021-02-07 23:03:28 +010084 point_code := 55,
85 routing_ctx := 1055
Harald Welte6baf5e72023-04-15 20:30:52 +080086 },
87 /* as-client60-norctx */
88 {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +070089 use_tcp := false,
90 remote_port := 2907,
91 local_port := 11060,
Harald Welte6baf5e72023-04-15 20:30:52 +080092 point_code := 60,
93 routing_ctx := -
94 },
95 /* as-client61-norctx */
96 {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +070097 use_tcp := false,
98 remote_port := 2907,
99 local_port := 11061,
Harald Welte6baf5e72023-04-15 20:30:52 +0800100 point_code := 61,
101 routing_ctx := -
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700102 },
103 /* as-client-tcp: One ASP within AS */
104 {
105 use_tcp := true,
106 remote_port := 2906,
107 local_port := 10002,
108 point_code := 155,
109 routing_ctx := 1155
Harald Welte1c4e9842021-02-07 23:03:28 +0100110 }
111 };
112 integer mp_recovery_timeout_msec := 2000;
113 charstring mp_sccp_service_type := "mtp3_itu";
114}
115
116type record M3uaConfig {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700117 /* use TCP (true) or SCTP (false) */
118 boolean use_tcp,
119 /* STP-side SCTP (or TCP) port for M3UA */
120 integer remote_port,
Harald Welte1c4e9842021-02-07 23:03:28 +0100121 /* local M3UA base port on TTCN3 side */
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700122 integer local_port,
Harald Welte1c4e9842021-02-07 23:03:28 +0100123 /* point code routed via this M3U */
124 integer point_code,
125 /* associated routing context */
126 integer routing_ctx
127};
128type record length (NR_M3UA+NR_M3UA_SRV) of M3uaConfig M3uaConfigs;
129
Harald Welte829dac42019-11-05 16:55:30 +0100130private function M3UA_SRV(integer idx) return integer {
131 return NR_M3UA+idx;
132}
Harald Welte0db44132019-10-17 11:09:05 +0200133
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700134private function f_m3ua_cli_config(integer idx) return M3uaConfig {
135 if (idx < 0 or idx >= NR_M3UA) {
136 setverdict(fail, "f_m3ua_cli_config(): unexpected idx");
137 Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
138 }
139 return mp_m3ua_configs[idx];
140}
141
142private function f_m3ua_srv_config(integer idx) return M3uaConfig {
143 if (idx < 0 or idx >= NR_M3UA_SRV) {
144 setverdict(fail, "f_m3ua_srv_config(): unexpected idx");
145 Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
146 }
147 return mp_m3ua_configs[M3UA_SRV(idx)];
148}
149
Harald Welte0db44132019-10-17 11:09:05 +0200150type component RAW_M3UA_CT extends Test_CT {
Harald Welte829dac42019-11-05 16:55:30 +0100151 port M3UA_CODEC_PT M3UA[NR_M3UA+NR_M3UA_SRV];
152 var integer g_m3ua_conn_id[NR_M3UA+NR_M3UA_SRV];
Harald Welte0db44132019-10-17 11:09:05 +0200153}
154
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700155private template PortEvent tr_ConnOpened := {
Harald Welte829dac42019-11-05 16:55:30 +0100156 connOpened := ?
157}
158
Harald Welte0db44132019-10-17 11:09:05 +0200159
160private altstep as_m3ua_sctp() runs on RAW_M3UA_CT {
161 [] any from M3UA.receive(tr_SctpAssocChange) { repeat; }
162 [] any from M3UA.receive(tr_SctpPeerAddrChange) { repeat; }
163}
164
Harald Welte42bcc442021-02-07 21:26:30 +0100165private altstep as_m3ua_ssnm_ignore() runs on RAW_M3UA_CT {
166 var M3UA_RecvFrom rx;
167 [] any from M3UA.receive(t_M3UA_RecvFrom(tr_M3UA_SSNM)) -> value rx {
168 log("Ignoring M3UA SSNM", rx);
169 repeat;
170 }
171}
172
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700173friend function f_M3UA_send(integer idx, template (present) PDU_M3UA msg, integer stream := 0)
Harald Welte0db44132019-10-17 11:09:05 +0200174runs on RAW_M3UA_CT {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700175 if (mp_m3ua_configs[idx].use_tcp) {
176 M3UA[idx].send(t_M3UA_Send(g_m3ua_conn_id[idx], msg, omit));
177 } else {
178 M3UA[idx].send(t_M3UA_Send(g_m3ua_conn_id[idx], msg, stream));
179 }
Harald Welte0db44132019-10-17 11:09:05 +0200180}
181
182friend function f_M3UA_exp(integer idx, template (present) PDU_M3UA msg) runs on RAW_M3UA_CT {
183 var M3UA_RecvFrom rx;
Harald Welte30812592021-02-08 09:50:46 +0100184 timer T := 5.0;
185 T.start;
Harald Welte0db44132019-10-17 11:09:05 +0200186 alt {
187 [] M3UA[idx].receive(t_M3UA_RecvFrom(msg)) {
188 setverdict(pass);
189 }
190 [] M3UA[idx].receive(t_M3UA_RecvFrom(?)) -> value rx {
191 setverdict(fail, "Received unexpected M3UA[", idx, "] ", rx,
192 "while waiting for ", msg);
193 mtc.stop;
194 }
Harald Welte30812592021-02-08 09:50:46 +0100195 [] T.timeout {
196 setverdict(fail, "Timeout waiting for M3UA[", idx, "] ", msg);
197 mtc.stop;
198 }
Harald Welte0db44132019-10-17 11:09:05 +0200199 }
200}
201
Harald Welte3e5f05e2023-04-15 20:02:52 +0800202/* flush any number of queued messages matching 'msg' */
203friend function f_M3UA_flush(integer idx, template (present) PDU_M3UA msg) runs on RAW_M3UA_CT {
204 var M3UA_RecvFrom rx;
205 timer T := 0.01;
206 T.start;
207 alt {
208 /* this should normally be possible with something like M3UA[idx].check(receive(...)) but somehow
209 * TITAN complains about the 'check' token, so it looks that feature of TTCN3 is not supported? */
210 [] M3UA[idx].receive(t_M3UA_RecvFrom(msg)) {
211 repeat;
212 }
213 [] T.timeout {
214 }
215 }
216}
217
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200218private template (value) Socket ts_Socket(HostName hostName, PortNumber portNumber) := {
219 hostName := hostName,
220 portNumber := portNumber
221};
222
223private template (value) SctpTuple ts_SCTP(template (omit) integer ppid := 3,
224 template (omit) integer stream := 0,
225 template (omit) SocketList remSocks := omit) := {
226 sinfo_stream := stream,
227 sinfo_ppid := ppid,
228 remSocks := remSocks,
229 assocId := omit
230};
231
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700232friend function f_M3UA_connect_sctp(integer i) runs on RAW_M3UA_CT {
Harald Welte0db44132019-10-17 11:09:05 +0200233 var Result res;
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200234 var Option opt_add_local_addrs;
235 var OptionList opt_list := {};
236 var template SocketList opt_add_remote_addrs;
Harald Welte1c4e9842021-02-07 23:03:28 +0100237 var M3uaConfig m3cfg := mp_m3ua_configs[i];
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200238
239 if (lengthof(mp_local_m3ua_ip) == 0 or lengthof(mp_stp_m3ua_ip) == 0) {
240 setverdict(fail, "Empty local or remote address trying to connect SCTP socket: ",
241 mp_local_m3ua_ip, " / ", mp_stp_m3ua_ip);
242 mtc.stop;
243 }
244
245 if (lengthof(mp_local_m3ua_ip) > 1) {
246 opt_add_local_addrs.sctpAdditionalLocalAddresses := substr(mp_local_m3ua_ip, 1,
247 lengthof(mp_local_m3ua_ip) - 1); //{mp_local_m3ua_ip};
248 opt_list := {opt_add_local_addrs};
249 }
250
251 if (lengthof(mp_stp_m3ua_ip) > 1) {
252 for (var integer j := 1; j < lengthof(mp_stp_m3ua_ip); j := j + 1) {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700253 var Socket sk := valueof(ts_Socket(mp_stp_m3ua_ip[j], m3cfg.remote_port));
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200254 opt_add_remote_addrs[j - 1] := sk;
255 }
256 } else {
257 opt_add_remote_addrs := omit;
258 }
259
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700260 res := M3UA_CodecPort_CtrlFunct.f_IPL4_connect(M3UA[i], mp_stp_m3ua_ip[0], m3cfg.remote_port,
261 mp_local_m3ua_ip[0], m3cfg.local_port, 0,
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200262 {sctp:=valueof(ts_SCTP(3, 0, opt_add_remote_addrs))},
263 opt_list);
Harald Welte0db44132019-10-17 11:09:05 +0200264 if (not ispresent(res.connId)) {
265 setverdict(fail, "Could not connect M3UA socket, check your configuration");
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200266 mtc.stop;
Harald Welte0db44132019-10-17 11:09:05 +0200267 }
268 g_m3ua_conn_id[i] := res.connId;
269}
270
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700271friend function f_M3UA_connect_tcp(integer i) runs on RAW_M3UA_CT {
272 var M3uaConfig m3cfg := mp_m3ua_configs[i];
273 var Result res;
274
275 /* XXX: M3UA-over-TCP is not supported by osmo-stp <= 1.8.1 */
276 if (not Misc_Helpers.f_osmo_repo_is("nightly")) {
277 log("Not connect()ing m3cfg := ", m3cfg, " (not supported by IUT)");
278 g_m3ua_conn_id[i] := -1;
279 return;
280 }
281
282 if (lengthof(mp_local_m3ua_ip) == 0 or lengthof(mp_stp_m3ua_ip) == 0) {
283 setverdict(fail, "Empty local or remote address trying to connect TCP socket: ",
284 mp_local_m3ua_ip, " / ", mp_stp_m3ua_ip);
285 mtc.stop;
286 }
287
288 res := M3UA_CodecPort_CtrlFunct.f_IPL4_connect(M3UA[i], mp_stp_m3ua_ip[0], m3cfg.remote_port,
289 mp_local_m3ua_ip[0], m3cfg.local_port, 0,
290 {tcp:={}});
291 if (not ispresent(res.connId)) {
292 setverdict(fail, "Could not connect M3UA socket, check your configuration");
293 mtc.stop;
294 }
295 g_m3ua_conn_id[i] := res.connId;
296 M3UA_CodecPort.f_set_tcp_segmentation(M3UA[i], res.connId);
297}
298
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100299friend function f_M3UA_close(integer i) runs on RAW_M3UA_CT {
300 var Result res;
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700301 if (g_m3ua_conn_id[i] < 0) {
302 log("Not close()ing m3cfg := ", mp_m3ua_configs[i], " (not connected)");
303 /* not connected */
304 return;
305 }
306 if (mp_m3ua_configs[i].use_tcp) {
307 res := M3UA_CodecPort_CtrlFunct.f_IPL4_close(M3UA[i], g_m3ua_conn_id[i], {tcp:={}});
308 } else {
309 res := M3UA_CodecPort_CtrlFunct.f_IPL4_close(M3UA[i], g_m3ua_conn_id[i], {sctp:=valueof(ts_SCTP)});
310 }
311 g_m3ua_conn_id[i] := -1;
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100312}
313
Harald Welte829dac42019-11-05 16:55:30 +0100314friend function f_M3UA_listen(integer i) runs on RAW_M3UA_CT {
315 var Result res;
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200316 var Option opt_add_local_addrs;
317 var OptionList opt_list := {};
Harald Welte1c4e9842021-02-07 23:03:28 +0100318 var M3uaConfig m3cfg := mp_m3ua_configs[i];
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200319
Vadim Yanitskiy7b541af2024-03-07 18:21:17 +0700320 /* XXX: M3UA-over-TCP is not supported by osmo-stp <= 1.8.1 */
321 if (not Misc_Helpers.f_osmo_repo_is("nightly") and m3cfg.use_tcp) {
322 log("Not listen()ing m3cfg := ", m3cfg, " (not supported by IUT)");
323 return;
324 }
325
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200326 if (lengthof(mp_local_m3ua_ip) == 0 ) {
327 setverdict(fail, "Empty local address trying to bind SCTP socket: ",
328 mp_local_m3ua_ip);
329 mtc.stop;
330 }
331
332 if (lengthof(mp_local_m3ua_ip) > 1) {
333 opt_add_local_addrs.sctpAdditionalLocalAddresses := substr(mp_local_m3ua_ip, 1,
334 lengthof(mp_local_m3ua_ip) - 1); //{mp_local_m3ua_ip};
335 opt_list := {opt_add_local_addrs};
336 }
337
Vadim Yanitskiyf5878122024-03-07 18:19:00 +0700338 if (m3cfg.use_tcp) {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700339 res := M3UA_CodecPort_CtrlFunct.f_IPL4_listen(M3UA[i], mp_local_m3ua_ip[0], m3cfg.local_port,
340 {tcp:={}});
341 } else {
342 res := M3UA_CodecPort_CtrlFunct.f_IPL4_listen(M3UA[i], mp_local_m3ua_ip[0], m3cfg.local_port,
343 {sctp:=valueof(ts_SCTP)}, opt_list);
344 }
Harald Welte829dac42019-11-05 16:55:30 +0100345 if (not ispresent(res.connId)) {
346 setverdict(fail, "Could not bind M3UA socket, check your configuration");
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200347 mtc.stop;
Harald Welte829dac42019-11-05 16:55:30 +0100348 }
Vadim Yanitskiyf5878122024-03-07 18:19:00 +0700349 if (m3cfg.use_tcp) {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700350 M3UA_CodecPort.f_set_tcp_segmentation(M3UA[i], res.connId);
351 }
Harald Welte829dac42019-11-05 16:55:30 +0100352}
353
Harald Welte27cfb7a2021-02-08 09:58:28 +0100354friend function f_init_m3ua(boolean ignore_ssnm := true) runs on RAW_M3UA_CT {
Harald Welte0db44132019-10-17 11:09:05 +0200355 var integer i;
356
357 f_init_common();
358
359 activate(as_m3ua_sctp());
Harald Welte27cfb7a2021-02-08 09:58:28 +0100360 if (ignore_ssnm) {
361 activate(as_m3ua_ssnm_ignore());
362 }
Harald Welte0db44132019-10-17 11:09:05 +0200363
364 for (i := 0; i < NR_M3UA; i:=i+1) {
Vadim Yanitskiy7b541af2024-03-07 18:21:17 +0700365 /* XXX: M3UA-over-TCP is not supported by osmo-stp <= 1.8.1 */
366 if (not Misc_Helpers.f_osmo_repo_is("nightly") and mp_m3ua_configs[i].use_tcp) {
367 log("Not connect()ing m3cfg := ", mp_m3ua_configs[i], " (not supported by IUT)");
368 g_m3ua_conn_id[i] := -1;
369 continue;
370 }
Harald Welte0db44132019-10-17 11:09:05 +0200371 map(self:M3UA[i], system:M3UA_CODEC_PT);
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700372 if (mp_m3ua_configs[i].use_tcp) {
373 f_M3UA_connect_tcp(i);
374 } else {
375 f_M3UA_connect_sctp(i);
376 }
Harald Welte0db44132019-10-17 11:09:05 +0200377 }
378}
379
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100380friend function f_clear_m3ua() runs on RAW_M3UA_CT {
381 var integer i;
382
383 log("Clearing M3UA...");
384
385 for (i := 0; i < NR_M3UA; i:=i+1) {
386 f_M3UA_close(i);
387 }
388 /* Wait for recovery timer to trigger and shutdown all AS: */
389 f_sleep(int2float(mp_recovery_timeout_msec)/1000.0 + 0.5);
390 setverdict(pass, "M3UA cleared");
391}
392
Harald Welte829dac42019-11-05 16:55:30 +0100393friend function f_init_m3ua_srv() runs on RAW_M3UA_CT {
394 var integer i;
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700395 var PortEvent port_evt;
Harald Welte829dac42019-11-05 16:55:30 +0100396
397 for (i := NR_M3UA; i < NR_M3UA+NR_M3UA_SRV; i:=i+1) {
Vadim Yanitskiy7b541af2024-03-07 18:21:17 +0700398 /* XXX: M3UA-over-TCP is not supported by osmo-stp <= 1.8.1 */
399 if (not Misc_Helpers.f_osmo_repo_is("nightly") and mp_m3ua_configs[i].use_tcp) {
400 log("Not listen()ing m3cfg := ", mp_m3ua_configs[i], " (not supported by IUT)");
401 g_m3ua_conn_id[i] := -1;
402 continue;
403 }
Harald Welte829dac42019-11-05 16:55:30 +0100404 map(self:M3UA[i], system:M3UA_CODEC_PT);
405 /* bind+ listen */
406 f_M3UA_listen(i);
407 /* wait for accept() */
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700408 M3UA[i].receive(tr_ConnOpened) -> value port_evt {
409 g_m3ua_conn_id[i] := port_evt.connOpened.connId;
Harald Welte829dac42019-11-05 16:55:30 +0100410 }
411 }
412}
413
414
415/***********************************************************************
416 * Test the STP in M3UA SG role (we are ASP)
417 ***********************************************************************/
418
Harald Welte0db44132019-10-17 11:09:05 +0200419/* perform an outbound ASP-UP procedure */
420friend function f_M3UA_asp_up(integer idx, template (omit) OCT4 aspid := omit) runs on RAW_M3UA_CT {
421 f_M3UA_send(idx, ts_M3UA_ASPUP(aspid));
422 f_M3UA_exp(idx, tr_M3UA_ASPUP_ACK);
423}
424
425/* perform an outbound BEAT procedure */
426friend function f_M3UA_beat(integer idx, template (omit) octetstring hbd) runs on RAW_M3UA_CT {
427 if (istemplatekind(hbd, "omit")) {
428 f_M3UA_send(idx, ts_M3UA_BEAT(omit));
429 f_M3UA_exp(idx, tr_M3UA_BEAT_ACK(omit));
430 } else {
431 f_M3UA_send(idx, ts_M3UA_BEAT(ts_M3UA_hb_data(hbd)));
432 f_M3UA_exp(idx, tr_M3UA_BEAT_ACK(tr_M3UA_hb_data(hbd)));
433 }
434}
435
436/* perform an outbound ASP-ACTIVATE procedure */
437friend function f_M3UA_asp_act(integer idx, template (omit) M3UA_Traffic_Mode_Type tmt := omit,
438 template (omit) OCT4 rctx := omit) runs on RAW_M3UA_CT {
439 f_M3UA_send(idx, ts_M3UA_ASPAC(tmt, rctx));
440 f_M3UA_exp(idx, tr_M3UA_ASPAC_ACK(tmt, rctx));
441}
442
Harald Welte27cfb7a2021-02-08 09:58:28 +0100443/* perform an outbound ASP-INACTIVATE procedure */
444friend function f_M3UA_asp_inact(integer idx, template (omit) OCT4 rctx := omit) runs on RAW_M3UA_CT {
445 f_M3UA_send(idx, ts_M3UA_ASPIA(rctx));
446 f_M3UA_exp(idx, tr_M3UA_ASPIA_ACK(rctx));
447}
448
Harald Welte0db44132019-10-17 11:09:05 +0200449/* perform outbound ASP-UP and ASP-ACT, optionally expect interemittent NOTIFY */
450friend function f_M3UA_asp_up_act(integer idx, template (omit) M3UA_Traffic_Mode_Type tmt := omit,
451 template (omit) OCT4 rctx := omit,
452 template (omit) OCT2 ntfy_after_up := c_M3UA_ST_I_AS_INACTIVE,
453 template (omit) OCT2 ntfy_after_act := c_M3UA_ST_I_AS_ACTIVE)
454runs on RAW_M3UA_CT {
455 f_M3UA_asp_up(idx, omit);
456 if (not istemplatekind(ntfy_after_up, "omit")) {
457 f_M3UA_exp(idx, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, ntfy_after_up, *));
458 }
459 f_M3UA_asp_act(idx, tmt, rctx);
460 if (not istemplatekind(ntfy_after_act, "omit")) {
461 f_M3UA_exp(idx, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, ntfy_after_act, *));
462 }
463}
464
465
466/* Test the ASP-UP procedure */
467testcase TC_connect_asp_up() runs on RAW_M3UA_CT {
468 f_init_m3ua();
469 f_M3UA_asp_up(0);
470 f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_INACTIVE, *));
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100471 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200472}
473
474/* Test the heartbeat procedure without optional heartbeat data payload */
475testcase TC_beat() runs on RAW_M3UA_CT {
476 f_init_m3ua();
477 f_M3UA_asp_up(0);
478 f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_INACTIVE, *));
479 f_M3UA_beat(0, omit);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100480 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200481}
482
483/* Test the heartbeat procedure with optional heartbeat data payload */
484testcase TC_beat_payload() runs on RAW_M3UA_CT {
485 f_init_m3ua();
486 f_M3UA_asp_up(0);
487 f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_INACTIVE, *));
488 f_M3UA_beat(0, 'a1a2a3a4a5'O);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100489 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200490}
491
492/* Test the ASP-ACTIVATE procedure (without traffic-mode or routing ctx) */
493testcase TC_asp_act() runs on RAW_M3UA_CT {
494 f_init_m3ua();
495 f_M3UA_asp_up_act(0);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100496 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200497}
498
499/* Test the ASP-ACTIVATE procedure with traffic-mode override */
500testcase TC_asp_act_override() runs on RAW_M3UA_CT {
501 f_init_m3ua();
502 f_M3UA_asp_up_act(0, c_M3UA_TMT_override, omit);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100503 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200504}
505
506/* Test the ASP-ACTIVATE procedure with traffic-mode override */
507testcase TC_asp_act_loadshare() runs on RAW_M3UA_CT {
508 f_init_m3ua();
509 f_M3UA_asp_up_act(0, c_M3UA_TMT_loadshare, omit);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100510 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200511}
512
513/* Test the ASP-ACTIVATE procedure with traffic-mode broadcast */
514testcase TC_asp_act_broadcast() runs on RAW_M3UA_CT {
515 f_init_m3ua();
516 f_M3UA_asp_up_act(0, c_M3UA_TMT_broadcast, omit);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100517 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200518}
519
Harald Welte15a85012020-06-13 16:35:45 +0200520/* test whether the STP accepts M3UA DATA without Routing Context IE */
521testcase TC_act_rctx_data_no_rctx() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700522 var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
523 var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
524 var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(1).routing_ctx, 4);
525 var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(1).point_code, 4);
Harald Welte15a85012020-06-13 16:35:45 +0200526
527 f_init_m3ua();
528 /* bring up the sender specifying a routing context */
529
530 f_M3UA_asp_up_act(0, rctx := rctx_sender);
531 f_M3UA_asp_up_act(1);
532
533 /* check if DATA is accepted without Routing Context IE */
534 f_test_traffic(0, omit, pc_sender, 1, rctx_receiver, pc_receiver);
535
536 f_clear_m3ua();
537}
538
Harald Welte0db44132019-10-17 11:09:05 +0200539/* Test if traffic is routed from idx_tx/pc_tx to idx_rx/pc_rx */
540private function f_test_traffic(integer idx_tx, template (omit) OCT4 rctx_sender, OCT4 pc_tx,
541 integer idx_rx, template (omit) OCT4 rctx_receiver, OCT4 pc_rx,
542 OCT1 si := '23'O, OCT1 ni := '00'O, OCT1 mp := '00'O, OCT1 sls := '00'O)
543runs on RAW_M3UA_CT {
Harald Welte67881ae2022-04-12 22:52:47 +0200544 var octetstring data := f_rnd_octstring_rnd_len(100);
Harald Welte0db44132019-10-17 11:09:05 +0200545 f_M3UA_send(idx_tx, ts_M3UA_DATA(rctx_sender,
546 ts_M3UA_protocol_data(pc_tx, pc_rx, si, ni, mp, sls, data)), 1);
547 f_M3UA_exp(idx_rx, tr_M3UA_DATA(rctx_receiver,
548 tr_M3UA_protocol_data(pc_tx, pc_rx, si, ni, mp, sls, data)));
549}
550
551
552/* test "traffic-mode override" behavior */
553testcase TC_tmt_override() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700554 var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
555 var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
556 var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(1).routing_ctx, 4);
557 var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(1).point_code, 4);
Harald Welte0db44132019-10-17 11:09:05 +0200558
559 f_init_m3ua();
560
561 /* bring up the 'sender' side (single ASP in AS) */
562 f_M3UA_asp_up_act(0, omit, omit);
563
564 /* activate the first 'receiver' side ASP */
565 f_M3UA_asp_up_act(1, c_M3UA_TMT_override, rctx_receiver);
566
567 /* verify traffic is routed from sender to [sole] receiver */
568 f_test_traffic(0, rctx_sender, pc_sender, 1, rctx_receiver, pc_receiver);
569
570 /* activate the second 'receiver' side ASP (no NOTIFY as AS state doesn't change) */
571 f_M3UA_asp_up_act(2, c_M3UA_TMT_override, rctx_receiver, omit, omit);
572
573 /* we expect a NOTIFY to the *other* ASP Other/Alternat-ASP-Active */
574 f_M3UA_exp(1, tr_M3UA_NOTIFY(c_M3UA_ST_T_OTHER, c_M3UA_ST_I_ALTERNATE_ASP, *));
575
576 /* verify traffic is routed from sender to new receiver */
577 f_test_traffic(0, rctx_sender, pc_sender, 2, rctx_receiver, pc_receiver);
578
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100579 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200580}
581
582private altstep as_count_rx(integer idx, template (present) PDU_M3UA exp, inout integer counter)
583runs on RAW_M3UA_CT {
584 [] M3UA[idx].receive(t_M3UA_RecvFrom(exp)) {
585 counter := counter + 1;
586 }
587}
588
589/* test "traffic-mode load-share" behavior */
590testcase TC_tmt_loadshare() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700591 var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
592 var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
593 var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(1).routing_ctx, 4);
594 var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(1).point_code, 4);
Harald Welte0db44132019-10-17 11:09:05 +0200595 var integer i;
596
597 f_init_m3ua();
598
599 /* FIXME: configure the STP via VTY to set traffic-mode */
600
601 /* bring up the 'sender' side (single ASP in AS) */
602 f_M3UA_asp_up_act(0, omit, rctx_sender);
603
604 /* activate the first 'receiver' side ASP */
Harald Welte0db44132019-10-17 11:09:05 +0200605 f_M3UA_asp_up_act(1, c_M3UA_TMT_loadshare, omit); // TODO: rctx
606
607 /* verify traffic is routed from sender to [sole] receiver */
608 for (i := 0; i < 10; i := i+1) {
609 f_test_traffic(0, rctx_sender, pc_sender, 1, rctx_receiver, pc_receiver);
610 }
611
612 /* activate the second 'receiver' side ASP (no NOTIFY) */
613 f_M3UA_asp_up_act(2, c_M3UA_TMT_loadshare, omit, omit, omit); // TODO: rctx
614
615 /* verify traffic is routed from sender to new receiver */
616 const integer iter_per_asp := 5;
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700617 var integer num_rx[NR_M3UA] := { 0, 0, 0, 0 };
Harald Welte0db44132019-10-17 11:09:05 +0200618 for (i := 0; i < 2*iter_per_asp; i := i+1) {
Harald Welte67881ae2022-04-12 22:52:47 +0200619 var octetstring data := f_rnd_octstring_rnd_len(100);
Harald Welte0db44132019-10-17 11:09:05 +0200620 var template (value) M3UA_Protocol_Data tx_pd;
621 var template (present) M3UA_Protocol_Data rx_pd;
622 tx_pd := ts_M3UA_protocol_data(pc_sender, pc_receiver, '23'O, '00'O, '00'O, '00'O, data);
623 rx_pd := tr_M3UA_protocol_data(pc_sender, pc_receiver, '23'O, '00'O, '00'O, '00'O, data);
624 f_M3UA_send(0, ts_M3UA_DATA(rctx_sender, tx_pd), 1);
625 alt {
Pau Espin Pedrol4d915782020-08-21 12:24:35 +0200626 [] as_count_rx(1, tr_M3UA_DATA(rctx_receiver, rx_pd), num_rx[1]);
627 [] as_count_rx(2, tr_M3UA_DATA(rctx_receiver, rx_pd), num_rx[2]);
Harald Welte0db44132019-10-17 11:09:05 +0200628 }
629 }
630 /* FIXME: check for extraneous messages? */
631 for (i := 1; i <= 2; i := i+1) {
632 if (num_rx[i] != iter_per_asp) {
Harald Welteb9f7bbb2019-10-29 09:07:11 +0100633 setverdict(fail, "Received ", num_rx[i], " out of expected ", iter_per_asp,
634 "M3UA DATA messages at M3UA port ", i);
Harald Welte0db44132019-10-17 11:09:05 +0200635 }
636 }
637 setverdict(pass);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100638
639 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200640}
641
642/* test "traffic-mode broadcast" behavior */
643testcase TC_tmt_broadcast() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700644 var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
645 var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
646 var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(1).routing_ctx, 4);
647 var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(1).point_code, 4);
Harald Welte0db44132019-10-17 11:09:05 +0200648 var integer i;
649
650 f_init_m3ua();
651
652 /* FIXME: configure the STP via VTY to set traffic-mode */
653
654 /* bring up the 'sender' side (single ASP in AS) */
655 f_M3UA_asp_up_act(0, omit, omit); // TODO: rctx
656
657 /* activate the first 'receiver' side ASP */
Harald Welte0db44132019-10-17 11:09:05 +0200658 f_M3UA_asp_up_act(1, c_M3UA_TMT_broadcast, omit); // TODO: rctx
659
660 /* verify traffic is routed from sender to [sole] receiver */
661 for (i := 0; i < 10; i := i+1) {
662 f_test_traffic(0, rctx_sender, pc_sender, 1, rctx_receiver, pc_receiver);
663 }
664
665 /* activate the second 'receiver' side ASP */
666 f_M3UA_asp_up_act(2, c_M3UA_TMT_broadcast, omit, omit, omit); // TODO: rctx
667
668 /* verify traffic is routed from sender to new receiver */
669 for (i := 0; i < 10; i := i+1) {
Harald Welte67881ae2022-04-12 22:52:47 +0200670 var octetstring data := f_rnd_octstring_rnd_len(100);
Harald Welte0db44132019-10-17 11:09:05 +0200671 var template (value) M3UA_Protocol_Data tx_pd;
672 var template (present) M3UA_Protocol_Data rx_pd;
673 tx_pd := ts_M3UA_protocol_data(pc_sender, pc_receiver, '23'O, '00'O, '00'O, '00'O, data);
674 rx_pd := tr_M3UA_protocol_data(pc_sender, pc_receiver, '23'O, '00'O, '00'O, '00'O, data);
675 f_M3UA_send(0, ts_M3UA_DATA(rctx_sender, tx_pd), 1);
676 /* each message must be received both on 1 and 2 */
677 f_M3UA_exp(1, tr_M3UA_DATA(rctx_receiver, rx_pd));
678 f_M3UA_exp(2, tr_M3UA_DATA(rctx_receiver, rx_pd));
679 }
680 setverdict(pass);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100681
682 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200683}
684
685private function f_M3UA_rkm_register(OCT4 id, OCT3 dpc, OCT4 rctx,
686 template (present) OCT4 exp_status := c_M3UA_REGSTS_SUCCESS)
687runs on RAW_M3UA_CT
688{
689 f_M3UA_send(0, ts_M3UA_REG_REQ({ts_M3UA_rkey(id:=id, dpc:=dpc, rctx:=rctx)}));
690 f_M3UA_exp(0, tr_M3UA_REG_RSP({tr_M3UA_reg_res(id:=id, status:=exp_status, rctx:=rctx)}));
691}
692
693/* Send RKM registration; expect -EPERM as RCTX doesn't match config and dynamic not permitted */
694testcase TC_rkm_reg_static_notpermitted() runs on RAW_M3UA_CT {
695 f_init_m3ua();
696
697 f_M3UA_send(0, ts_M3UA_REG_REQ({ts_M3UA_rkey(id:='00000099'O, dpc:='aabbcc'O)}));
698 f_M3UA_exp(0, tr_M3UA_REG_RSP({tr_M3UA_reg_res(id:='00000099'O, status:=c_M3UA_REGSTS_ERR_EPERM,
699 rctx:=?)}));
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100700
701 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200702}
703
704/* Send RKM registration; expect OK as RCTX does match config */
705testcase TC_rkm_reg_static_permitted() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700706 var OCT3 dpc := int2oct(f_m3ua_cli_config(0).point_code, 3); // must match config
707 var OCT4 rctx := int2oct(f_m3ua_cli_config(0).routing_ctx, 4); // must match config
Harald Welte0db44132019-10-17 11:09:05 +0200708
709 f_init_m3ua();
710
711 f_M3UA_send(0, ts_M3UA_REG_REQ({ts_M3UA_rkey(id:='10000099'O, dpc:=dpc, rctx:=rctx)}));
712 f_M3UA_exp(0, tr_M3UA_REG_RSP({tr_M3UA_reg_res(id:='10000099'O, status:=c_M3UA_REGSTS_SUCCESS,
713 rctx:=rctx)}));
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100714
715 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200716}
717
718/* Send RKM registration; expect OK as dynamic not permitted */
719testcase TC_rkm_reg_dynamic_permitted() runs on RAW_M3UA_CT {
720 f_init_common();
721 f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation dynamic-permitted");
722 f_init_m3ua();
723
724 f_M3UA_send(0, ts_M3UA_REG_REQ({ts_M3UA_rkey(id:='20000099'O, dpc:='aabbcc'O)}));
725 f_M3UA_exp(0, tr_M3UA_REG_RSP({tr_M3UA_reg_res(id:='20000099'O, status:=c_M3UA_REGSTS_SUCCESS,
726 rctx:=?)}));
727
728 f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation static-only");
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100729
730 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200731}
732
733/* try to de-register a routing key that was never registered -> error */
734testcase TC_rkm_unreg_never_registered() runs on RAW_M3UA_CT {
735 f_init_m3ua();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700736 var octetstring rctx := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
737 f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(rctx)));
Harald Welte0db44132019-10-17 11:09:05 +0200738 f_M3UA_exp(0, tr_M3UA_DEREG_RSP({tr_M3UA_dereg_res(?,c_m3UA_DEREGSTS_ERR_NOT_REG)}));
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100739 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200740}
741
742/* try to de-register a routing key that is invalid (non-existant) -> error */
743testcase TC_rkm_unreg_invalid() runs on RAW_M3UA_CT {
744 f_init_m3ua();
745 f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(int2oct(1234,4))));
746 f_M3UA_exp(0, tr_M3UA_DEREG_RSP({tr_M3UA_dereg_res(?,c_m3UA_DEREGSTS_ERR_INVAL_RCTX)}));
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100747 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200748}
749
Oliver Smith326d78e2021-07-23 10:42:10 +0200750/* try to de-register a routing key that was registered -> OK */
Harald Welte0db44132019-10-17 11:09:05 +0200751testcase TC_rkm_unreg_registered() runs on RAW_M3UA_CT {
Oliver Smith326d78e2021-07-23 10:42:10 +0200752 var OCT3 dpc := int2oct(123, 3);
753 var OCT4 rctx := int2oct(1234, 4);
754
755 f_init_common();
756 f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation dynamic-permitted");
Harald Welte0db44132019-10-17 11:09:05 +0200757 f_init_m3ua();
Oliver Smith326d78e2021-07-23 10:42:10 +0200758
759 /* first register the routing key */
760 f_M3UA_rkm_register(id:='30000099'O, dpc:=dpc, rctx:=rctx);
761
762 /* then try to de-register */
763 f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(rctx)));
Harald Welte0db44132019-10-17 11:09:05 +0200764 f_M3UA_exp(0, tr_M3UA_DEREG_RSP({tr_M3UA_dereg_res(?,c_m3UA_DEREGSTS_SUCCESS)}));
Oliver Smith326d78e2021-07-23 10:42:10 +0200765
766 f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation static-only");
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100767 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200768}
769
770/* try to de-register a routing key for an active ASP -> ERROR */
771testcase TC_rkm_unreg_active() runs on RAW_M3UA_CT {
Oliver Smithee022232021-07-23 11:01:06 +0200772 var OCT3 dpc := int2oct(123, 3);
773 var OCT4 rctx := int2oct(1234, 4);
Harald Welte0db44132019-10-17 11:09:05 +0200774
Oliver Smithee022232021-07-23 11:01:06 +0200775 f_init_common();
776 f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation dynamic-permitted");
Harald Welte0db44132019-10-17 11:09:05 +0200777 f_init_m3ua();
778
779 /* first register the routing key */
780 f_M3UA_rkm_register(id:='30000099'O, dpc:=dpc, rctx:=rctx);
781
782 /* then activate the ASP */
783 f_M3UA_asp_up_act(0);
Oliver Smithee022232021-07-23 11:01:06 +0200784 f_M3UA_exp(0, tr_M3UA_DAVA({*}, rctx));
785 f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_ACTIVE, *));
786 f_M3UA_exp(0, tr_M3UA_DAVA({*}, *));
Harald Welte0db44132019-10-17 11:09:05 +0200787
Oliver Smithee022232021-07-23 11:01:06 +0200788 /* then try to de-register -> ERR_ASP_ACTIVE */
Harald Welte0db44132019-10-17 11:09:05 +0200789 f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(rctx)));
790 f_M3UA_exp(0, tr_M3UA_DEREG_RSP({tr_M3UA_dereg_res(?,c_m3UA_DEREGSTS_ERR_ASP_ACTIVE)}));
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100791
Oliver Smithee022232021-07-23 11:01:06 +0200792 /* deactivate ASP and properly de-register to clean up */
793 f_M3UA_asp_inact(0);
794 f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(rctx)));
795 f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_PENDING, *));
796 f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_PENDING, *));
797 f_M3UA_exp(0, tr_M3UA_DEREG_RSP({tr_M3UA_dereg_res(?,c_m3UA_DEREGSTS_SUCCESS)}));
798
799 f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation static-only");
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100800 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200801}
802
Harald Welte829dac42019-11-05 16:55:30 +0100803/***********************************************************************
804 * Test the STP in M3UA ASP role (we are SG)
805 ***********************************************************************/
806
807/* expect/perform an inbound ASP-UP procedure */
808friend function f_M3UA_CLNT_asp_up(integer idx, template OCT4 aspid := omit) runs on RAW_M3UA_CT {
809 f_M3UA_exp(idx, tr_M3UA_ASPUP(aspid));
Harald Welte3e5f05e2023-04-15 20:02:52 +0800810 /* there might have been multiple re-transmissions that have queued up in the ATS between
811 * the SCTP connection establishment and this function execution, so let's flush those copies. */
812 f_M3UA_flush(idx, tr_M3UA_ASPUP(aspid));
Harald Welte829dac42019-11-05 16:55:30 +0100813 f_M3UA_send(idx, ts_M3UA_ASPUP_ACK);
814}
815
816/* expect/perform an inbound ASP-ACTIVATE procedure */
817friend function f_M3UA_CLNT_asp_act(integer idx, template M3UA_Traffic_Mode_Type tmt := omit,
818 template (omit) OCT4 rctx := omit) runs on RAW_M3UA_CT {
819 f_M3UA_exp(idx, tr_M3UA_ASPAC(tmt, rctx));
820 f_M3UA_send(idx, ts_M3UA_ASPAC_ACK(tmt, rctx));
821}
822
823/* expect/perform inbound ASP-UP and ASP-ACT, optionally send interemittent NOTIFY */
824friend function f_M3UA_CLNT_asp_up_act(integer idx, template M3UA_Traffic_Mode_Type tmt := omit,
825 template OCT4 rctx := omit,
826 template (omit) OCT2 ntfy_after_up := c_M3UA_ST_I_AS_INACTIVE,
827 template (omit) OCT2 ntfy_after_act := c_M3UA_ST_I_AS_ACTIVE)
828runs on RAW_M3UA_CT {
829 f_M3UA_CLNT_asp_up(idx, omit);
830 if (not istemplatekind(ntfy_after_up, "omit")) {
831 f_M3UA_send(idx, ts_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, ntfy_after_up, rctx));
832 }
833 f_M3UA_CLNT_asp_act(idx, tmt, rctx);
834 if (not istemplatekind(ntfy_after_act, "omit")) {
835 f_M3UA_send(idx, ts_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, ntfy_after_act, rctx));
836 }
837}
838
839
840/* Expect inbound connection from ASP/SCTP-client, followed by ASP-UP */
841testcase TC_clnt_connect_asp_up() runs on RAW_M3UA_CT {
842 f_init_m3ua();
843 f_init_m3ua_srv();
844
845 f_M3UA_CLNT_asp_up(M3UA_SRV(0));
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100846
847 f_clear_m3ua();
Harald Welte829dac42019-11-05 16:55:30 +0100848}
849
850/* Expect inbound connection from ASP/SCTP-client, followed by ASP-UP + ASP-ACT */
851testcase TC_clnt_asp_act() runs on RAW_M3UA_CT {
852 f_init_m3ua();
853 f_init_m3ua_srv();
854
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700855 var OCT4 rctx := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
856 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100857
858 f_clear_m3ua();
Harald Welte829dac42019-11-05 16:55:30 +0100859}
860
Harald Welte53050cd2019-12-01 20:49:01 +0100861/* Expect inbound connection from ASP/SCTP-client, followed by ASP-UP + ASP-ACT */
862testcase TC_clnt_asp_act_tmt_loadshare() runs on RAW_M3UA_CT {
863 f_init_common();
864 f_vty_config2(VTY, {"cs7 instance 0", "as as-client m3ua"}, "traffic-mode loadshare");
865 f_init_m3ua();
866 f_init_m3ua_srv();
867
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700868 var OCT4 rctx := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
869 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), tmt := c_M3UA_TMT_loadshare, rctx := rctx);
Harald Welte53050cd2019-12-01 20:49:01 +0100870
871 f_clear_m3ua();
872}
873
Harald Welte829dac42019-11-05 16:55:30 +0100874/* Test traffic being routed through "server" side STP (M3UA SG), coming back in "client"
875 * side STP (M3UA ASP) */
876testcase TC_clnt_sg_to_asp() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700877 var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
878 var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
879 var OCT4 rctx_receiver := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
880 var OCT4 pc_receiver := int2oct(f_m3ua_srv_config(0).point_code, 4);
Harald Welte829dac42019-11-05 16:55:30 +0100881
882 f_init_m3ua();
883 f_M3UA_asp_up_act(0);
884
885 f_init_m3ua_srv();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700886 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx_receiver);
Harald Welte829dac42019-11-05 16:55:30 +0100887
888 f_sleep(1.0);
889
890 /* verify traffic is routed from sender to [sole] receiver */
891 f_test_traffic(0, rctx_sender, pc_sender, M3UA_SRV(0), rctx_receiver, pc_receiver);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100892
893 f_clear_m3ua();
Harald Welte829dac42019-11-05 16:55:30 +0100894}
895
896/* Test traffic being routed through "client" side STP (M3UA ASP), coming back in "server"
897 * side STP (M3UA SG) */
898testcase TC_clnt_asp_to_sg() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700899 var OCT4 rctx_sender := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
900 var OCT4 pc_sender := int2oct(f_m3ua_srv_config(0).point_code, 4);
901 var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
902 var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(0).point_code, 4);
Harald Welte829dac42019-11-05 16:55:30 +0100903
904 f_init_m3ua();
905 f_M3UA_asp_up_act(0);
906
907 f_init_m3ua_srv();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700908 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx_sender);
Harald Welte829dac42019-11-05 16:55:30 +0100909
910 f_sleep(1.0);
911
912 /* verify traffic is routed from sender to [sole] receiver */
913 f_test_traffic(M3UA_SRV(0), rctx_sender, pc_sender, 0, rctx_receiver, pc_receiver);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100914 f_clear_m3ua();
Harald Welte829dac42019-11-05 16:55:30 +0100915}
916
Harald Welte6baf5e72023-04-15 20:30:52 +0800917/* Test traffic being routed through "server" side STP (M3UA SG), coming back in "client"
918 * side STP (M3UA ASP) which has no routing context set */
919testcase TC_clnt_sg_to_asp_norctx() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700920 var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
921 var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
922 var OCT4 pc_receiver := int2oct(f_m3ua_srv_config(1).point_code, 4);
923 var OCT4 pc_receiver2 := int2oct(f_m3ua_srv_config(2).point_code, 4);
Harald Welte6baf5e72023-04-15 20:30:52 +0800924
925 /* activate the sender side (ATS is client to STP in SG role) */
926 f_init_m3ua();
927 f_M3UA_asp_up_act(0);
928
929 /* activate the receiver side (ATS is server to STP in ASP role) */
930 f_init_m3ua_srv();
931 f_M3UA_CLNT_asp_up_act(M3UA_SRV(1), rctx := omit);
932 /* activate another instance of STP in ASP role with no routing context */
933 f_M3UA_CLNT_asp_up_act(M3UA_SRV(2), rctx := omit);
934
935 f_sleep(1.0);
936
937 /* verify traffic is routed from sender to [sole] receiver for each PC */
938 f_test_traffic(0, rctx_sender, pc_sender, M3UA_SRV(1), omit, pc_receiver);
939 f_test_traffic(0, rctx_sender, pc_sender, M3UA_SRV(2), omit, pc_receiver2);
940
941 f_clear_m3ua();
942}
943
944/* Test traffic being routed through "server" side STP (M3UA SG), coming back in "client"
945 * side STP (M3UA ASP) which has no routing context set */
946testcase TC_clnt_asp_to_sg_norctx() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700947 var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
948 var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(0).point_code, 4);
949 var OCT4 pc_sender := int2oct(f_m3ua_srv_config(1).point_code, 4);
950 var OCT4 pc_sender2 := int2oct(f_m3ua_srv_config(2).point_code, 4);
Harald Welte6baf5e72023-04-15 20:30:52 +0800951
952 /* activate the sender side (ATS is client to STP in SG role) */
953 f_init_m3ua();
954 f_M3UA_asp_up_act(0);
955
956 /* activate the receiver side (ATS is server to STP in ASP role) */
957 f_init_m3ua_srv();
958 f_M3UA_CLNT_asp_up_act(M3UA_SRV(1), rctx := omit);
959 /* activate another instance of STP in ASP role with no routing context */
960 f_M3UA_CLNT_asp_up_act(M3UA_SRV(2), rctx := omit);
961
962 f_sleep(1.0);
963
964 /* verify traffic is routed from sender to [sole] receiver for each PC */
965 f_test_traffic(M3UA_SRV(1), omit, pc_sender, 0, rctx_receiver, pc_receiver);
966 f_test_traffic(M3UA_SRV(2), omit, pc_sender2, 0, rctx_receiver, pc_receiver);
967
968 f_clear_m3ua();
969}
970
Harald Welte27cfb7a2021-02-08 09:58:28 +0100971/* Test if ASPAC / ASPIA of one ASP generates DAVA / DUNA on other ASP */
972testcase TC_ssnm_aspac_dava_aspia_duna() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700973 var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
974 var integer pc0 := f_m3ua_cli_config(1).point_code;
Harald Welte27cfb7a2021-02-08 09:58:28 +0100975
976 f_init_m3ua(ignore_ssnm := false);
977 /* activate the first ASP */
978 f_M3UA_asp_up_act(0);
979
980 /* activate the second ASP */
981 f_M3UA_asp_up_act(1, c_M3UA_TMT_override, omit);
982 /* expect DAVA for PC of second ASP on first ASP */
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700983 f_M3UA_exp(0, tr_M3UA_DAVA({ts_M3UA_PC(pc0, 0)}, rctx0));
Harald Welte27cfb7a2021-02-08 09:58:28 +0100984 /* TODO: expect no DAVA on second ASP */
985
986 /* deactivate the second ASP */
987 f_M3UA_asp_inact(1);
988 /* expect DUNA for PC of second ASP on first ASP */
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700989 f_M3UA_exp(0, tr_M3UA_DUNA({ts_M3UA_PC(pc0, 0)}, rctx0));
Harald Welte27cfb7a2021-02-08 09:58:28 +0100990 /* TODO: expect no DUNA on second ASP */
991
992 f_clear_m3ua();
993}
994
995/* Test if DAVA/DUNA sent from SG to ASP-role STP gets forwarded to other ASP */
996testcase TC_ssnm_distribution_dava_duna() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700997 var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
998 var OCT4 rctxS0 := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
Harald Welte27cfb7a2021-02-08 09:58:28 +0100999 /* some random point code whose availability we advertise */
1000 var template (value) M3UA_Point_Code adv_pc := ts_M3UA_PC(1234, 0);
1001
1002 f_init_m3ua(ignore_ssnm := false);
1003
1004 /* activate the first ASP */
1005 f_M3UA_asp_up_act(0);
1006
1007 /* activate SG-role ASP (ASP on STP) */
1008 f_init_m3ua_srv();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001009 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctxS0);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001010
1011 /* transmit a DAVA to the remote ASP */
1012 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAVA({adv_pc}, rctxS0));
1013 /* expect that to show up on other ASP */
1014 f_M3UA_exp(0, tr_M3UA_DAVA({adv_pc}, rctx0));
1015
1016 /* transmit a DUNA to the remote ASP */
1017 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DUNA({adv_pc}, rctxS0));
1018 /* expect that to show up on other ASP */
1019 f_M3UA_exp(0, tr_M3UA_DUNA({adv_pc}, rctx0));
1020}
1021
1022/* Test if DAVA/DUNA sent from SG to ASP-role STP gets forwarded to other ASP */
1023testcase TC_ssnm_distribution_dava_duna_multipc() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001024 var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
1025 var OCT4 rctxS0 := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001026 /* some random point code whose availability we advertise */
1027 var template (value) M3UA_Point_Codes adv_pcs := { ts_M3UA_PC(1234, 0), ts_M3UA_PC(5678, 0) };
1028
1029 f_init_m3ua(ignore_ssnm := false);
1030
1031 /* activate the first ASP */
1032 f_M3UA_asp_up_act(0);
1033
1034 /* activate SG-role ASP (ASP on STP) */
1035 f_init_m3ua_srv();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001036 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctxS0);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001037
1038 /* transmit a DAVA to the remote ASP */
1039 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAVA(adv_pcs, rctxS0));
1040 /* expect that to show up on other ASP */
1041 f_M3UA_exp(0, tr_M3UA_DAVA(adv_pcs, rctx0));
1042
1043 /* transmit a DUNA to the remote ASP */
1044 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DUNA(adv_pcs, rctxS0));
1045 /* expect that to show up on other ASP */
1046 f_M3UA_exp(0, tr_M3UA_DUNA(adv_pcs, rctx0));
1047}
1048
1049/* Test if DUPU sent from SG to ASP-role STP gets forwarded to other ASP */
1050testcase TC_ssnm_distribution_dupu() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001051 var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
1052 var OCT4 rctxS0 := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001053 /* some random point code whose availability we advertise */
1054 var template (value) M3UA_Point_Code adv_pc := ts_M3UA_PC(1234, 0);
1055
1056 f_init_m3ua(ignore_ssnm := false);
1057
1058 /* activate the first ASP */
1059 f_M3UA_asp_up_act(0);
1060
1061 /* activate SG-role ASP (ASP on STP) */
1062 f_init_m3ua_srv();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001063 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctxS0);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001064
1065 /* transmit a DUPU to the remote ASP */
1066 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DUPU({adv_pc}, '0102'O, 'ABCD'O, rctxS0));
1067 /* expect that to show up on other ASP */
1068 f_M3UA_exp(0, tr_M3UA_DUPU({adv_pc}, '0102'O, 'ABCD'O, rctx0));
1069}
1070
1071/* Test if SCON sent from SG to ASP-role STP gets forwarded to other ASP */
1072testcase TC_ssnm_distribution_scon() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001073 var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
1074 var OCT4 rctxS0 := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001075 /* some random point code whose availability we advertise */
1076 var template (value) M3UA_Point_Code adv_pc := ts_M3UA_PC(1234, 0);
1077
1078 f_init_m3ua(ignore_ssnm := false);
1079
1080 /* activate the first ASP */
1081 f_M3UA_asp_up_act(0);
1082
1083 /* activate SG-role ASP (ASP on STP) */
1084 f_init_m3ua_srv();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001085 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctxS0);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001086
1087 /* transmit a SCON to the remote ASP */
1088 f_M3UA_send(M3UA_SRV(0), ts_M3UA_SCON({adv_pc}, rctxS0));
1089 /* expect that to show up on other ASP */
1090 f_M3UA_exp(0, tr_M3UA_SCON({adv_pc}, rctx0));
1091}
Harald Welte829dac42019-11-05 16:55:30 +01001092
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +07001093private function f_asp_cfg_str(charstring asp_name, in M3uaConfig cfg)
1094return charstring {
1095 var charstring str;
1096
1097 str := "asp " & asp_name;
1098 str := str & " " & int2str(cfg.local_port);
1099 str := str & " " & int2str(cfg.remote_port);
1100 str := str & " m3ua";
1101
1102 if (cfg.use_tcp) {
1103 str := str & " tcp";
1104 }
1105
1106 return str;
1107}
1108
Harald Welte30cb4002021-05-13 20:51:37 +02001109private function f_quirk(charstring quirk) runs on RAW_M3UA_CT {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +07001110 var charstring asp_cfg_str := f_asp_cfg_str("asp-client0", f_m3ua_srv_config(0));
1111 f_vty_config2(VTY, {"cs7 instance 0", asp_cfg_str}, "quirk " & quirk);
Harald Welte30cb4002021-05-13 20:51:37 +02001112}
1113
1114private function f_no_quirk(charstring quirk) runs on RAW_M3UA_CT {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +07001115 var charstring asp_cfg_str := f_asp_cfg_str("asp-client0", f_m3ua_srv_config(0));
1116 f_vty_config2(VTY, {"cs7 instance 0", asp_cfg_str}, "no quirk " & quirk);
Harald Welte30cb4002021-05-13 20:51:37 +02001117}
1118
1119/* quirk 'no_notify': Expect inbound connection from ASP/SCTP-client, followed by ASP-UP + ASP-ACT */
1120testcase TC_clnt_quirk_no_notify_asp_act() runs on RAW_M3UA_CT {
1121 f_init_m3ua();
1122 f_quirk("no_notify");
1123 f_init_m3ua_srv();
1124
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001125 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := int2oct(f_m3ua_srv_config(0).routing_ctx, 4),
Harald Welte30cb4002021-05-13 20:51:37 +02001126 ntfy_after_up := omit, ntfy_after_act := omit);
1127 f_no_quirk("no_notify");
1128 f_clear_m3ua();
1129}
1130
Harald Welte5ef25532021-05-13 21:10:25 +02001131/* ensure that DAUD is not supported in ASP role, as required by RFC */
1132testcase TC_clnt_no_daud_in_asp() runs on RAW_M3UA_CT {
1133 f_init_m3ua();
1134 f_no_quirk("daud_in_asp");
1135 f_init_m3ua_srv();
1136
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001137 var OCT4 rctx := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
1138 var integer pc := f_m3ua_srv_config(0).point_code;
Harald Welte5ef25532021-05-13 21:10:25 +02001139
1140 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx);
1141
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001142 var template (value) M3UA_Point_Codes aff_pcs := { ts_M3UA_PC(pc) };
Harald Welte5ef25532021-05-13 21:10:25 +02001143 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAUD(aff_pcs));
1144 f_M3UA_exp(M3UA_SRV(0), tr_M3UA_ERR('00000004'O, omit));
1145 setverdict(pass);
1146
1147 f_clear_m3ua();
1148}
1149
1150/* quirk 'daud_in_asp': allowing inbound DAUD from SG in ASP role */
1151testcase TC_clnt_quirk_daud_in_asp() runs on RAW_M3UA_CT {
1152 f_init_m3ua();
1153 f_quirk("daud_in_asp");
1154 f_init_m3ua_srv();
1155
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001156 var OCT4 rctx := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
1157 var integer pc := f_m3ua_srv_config(0).point_code;
Harald Welte5ef25532021-05-13 21:10:25 +02001158
1159 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx);
1160
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001161 var template (value) M3UA_Point_Codes aff_pcs := { ts_M3UA_PC(pc) };
Harald Welte5ef25532021-05-13 21:10:25 +02001162 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAUD(aff_pcs));
1163 f_M3UA_exp(M3UA_SRV(0), tr_M3UA_DAVA(aff_pcs));
1164 setverdict(pass);
1165
1166 f_no_quirk("daud_in_asp");
1167 f_clear_m3ua();
1168}
Harald Welte0db44132019-10-17 11:09:05 +02001169
Harald Welte261aea72021-05-13 21:23:29 +02001170/* Expect a normal ASP to reject any [S]SNM messages in ASP-INACTIVE state */
1171testcase TC_clnt_no_snm_inactive() runs on RAW_M3UA_CT {
1172 f_init_m3ua();
1173 f_quirk("no_notify");
1174 f_quirk("daud_in_asp");
1175 f_no_quirk("snm_inactive");
1176 f_init_m3ua_srv();
1177
1178 /* bring ASP only UP (into INACTIVE state), but not ACTIVE! */
1179 f_M3UA_CLNT_asp_up(M3UA_SRV(0));
1180 f_M3UA_exp(M3UA_SRV(0), tr_M3UA_ASPAC(*, *));
1181
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001182 var template (value) M3UA_Point_Codes aff_pcs := { ts_M3UA_PC(f_m3ua_srv_config(0).point_code) };
Harald Welte261aea72021-05-13 21:23:29 +02001183 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAUD(aff_pcs));
1184 f_M3UA_exp(M3UA_SRV(0), tr_M3UA_ERR('00000006'O, omit));
1185 setverdict(pass);
1186
1187 f_no_quirk("no_notify");
1188 f_no_quirk("daud_in_asp");
1189 f_clear_m3ua();
1190}
1191
1192/* quirk 'snm_inactive': Process [S]SNM in ASP-INACTIVE state */
1193testcase TC_clnt_quirk_snm_inactive() runs on RAW_M3UA_CT {
1194 f_init_m3ua();
1195 f_quirk("no_notify");
1196 f_quirk("daud_in_asp");
1197 f_quirk("snm_inactive");
1198 f_init_m3ua_srv();
1199
1200 /* bring ASP only UP (into INACTIVE state), but not ACTIVE! */
1201 f_M3UA_CLNT_asp_up(M3UA_SRV(0));
1202 f_M3UA_exp(M3UA_SRV(0), tr_M3UA_ASPAC(*, *));
1203
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001204 var template (value) M3UA_Point_Codes aff_pcs := { ts_M3UA_PC(f_m3ua_srv_config(0).point_code) };
Harald Welte261aea72021-05-13 21:23:29 +02001205 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAUD(aff_pcs));
1206 f_M3UA_exp(M3UA_SRV(0), tr_M3UA_DAVA(aff_pcs));
1207 setverdict(pass);
1208
1209 f_no_quirk("no_notify");
1210 f_no_quirk("daud_in_asp");
1211 f_no_quirk("snm_inactive");
1212 f_clear_m3ua();
1213}
1214
Vadim Yanitskiy88f429d2024-03-04 02:03:52 +07001215private function f_TC_m3ua_tcp(integer idx_a, integer idx_b) runs on RAW_M3UA_CT {
1216 var M3uaConfig cfg_a := mp_m3ua_configs[idx_a];
1217 var M3uaConfig cfg_b := mp_m3ua_configs[idx_b];
1218 var OCT4 rctx_a := int2oct(cfg_a.routing_ctx, 4);
1219 var OCT4 rctx_b := int2oct(cfg_b.routing_ctx, 4);
1220 var OCT4 pc_a := int2oct(cfg_a.point_code, 4);
1221 var OCT4 pc_b := int2oct(cfg_b.point_code, 4);
1222
1223 /* establish connection with ASP 'A' */
1224 if (idx_a < NR_M3UA) {
1225 f_M3UA_asp_up_act(idx_a, rctx := rctx_a);
1226 } else {
1227 f_M3UA_CLNT_asp_up_act(idx_a, rctx := rctx_a);
1228 }
1229
1230 /* establish connection with ASP 'B' */
1231 if (idx_b < NR_M3UA) {
1232 f_M3UA_asp_up_act(idx_b, rctx := rctx_b);
1233 } else {
1234 f_M3UA_CLNT_asp_up_act(idx_b, rctx := rctx_b);
1235 }
1236
1237 /* In the case when ASP[idx_b] is configured as the client (i.e. osmo-stp connects to
1238 * the testsuite; idx_b >= NR_M3UA), in f_M3UA_CLNT_asp_up_act() we're expecting to
1239 * receive ASPACT and then sending ASPACT_ACK to it. Right after that, we're sending
1240 * some random data via ASP[idx_a], which we then expect to receive via ASP[idx_b].
1241 *
1242 * There is a chance that the random data sent via ASP[idx_a] would reach osmo-stp
1243 * earlier than the ASPUP_ACK we sent for ASP[idx_b]. This is happening most of the
1244 * times when running TC_m3ua_tcp_cli_srv. Using f_sleep() helps to avoid this. */
1245 f_sleep(1.0);
1246
1247 /* M3UA/A -> M3UA/B */
1248 f_test_traffic(idx_a, rctx_a, pc_a,
1249 idx_b, rctx_b, pc_b);
1250 /* M3UA/B -> M3UA/A */
1251 f_test_traffic(idx_b, rctx_b, pc_b,
1252 idx_a, rctx_a, pc_a);
1253
1254 f_clear_m3ua();
1255}
1256
1257/* test routing between M3UA/SCTP (client) and M3UA/TCP (client) */
1258testcase TC_m3ua_tcp_cli() runs on RAW_M3UA_CT {
1259 f_init_m3ua();
1260 f_TC_m3ua_tcp(0, 3); /* 'asp-sender' <-> 'asp-sender-tcp' */
1261}
1262
1263/* test routing between M3UA/SCTP (client) and M3UA/TCP (server) */
1264testcase TC_m3ua_tcp_cli_srv() runs on RAW_M3UA_CT {
1265 f_init_m3ua();
1266 f_init_m3ua_srv();
1267 f_TC_m3ua_tcp(0, M3UA_SRV(3)); /* 'asp-sender' <-> 'asp-client-tcp' */
1268}
1269
1270/* test routing between M3UA/SCTP (server) and M3UA/TCP (server) */
1271testcase TC_m3ua_tcp_srv() runs on RAW_M3UA_CT {
1272 f_init_m3ua();
1273 f_init_m3ua_srv();
1274 f_TC_m3ua_tcp(M3UA_SRV(0), M3UA_SRV(3)); /* 'asp-client' <-> 'asp-client-tcp' */
1275}
1276
1277/* test routing between M3UA/SCTP (server) and M3UA/TCP (client) */
1278testcase TC_m3ua_tcp_srv_cli() runs on RAW_M3UA_CT {
1279 f_init_m3ua();
1280 f_init_m3ua_srv();
1281 f_TC_m3ua_tcp(M3UA_SRV(0), 3); /* 'asp-client' <-> 'asp-sender-tcp' */
1282}
1283
Harald Welte261aea72021-05-13 21:23:29 +02001284
Harald Welte0db44132019-10-17 11:09:05 +02001285control {
1286 /* M3UA Tests */
1287 execute( TC_connect_asp_up() );
1288 execute( TC_beat() );
1289 execute( TC_beat_payload() );
1290 execute( TC_asp_act() );
1291 execute( TC_asp_act_override() );
1292 execute( TC_asp_act_loadshare() );
1293 execute( TC_asp_act_broadcast() );
1294 execute( TC_tmt_override() );
1295 execute( TC_tmt_loadshare() );
1296 execute( TC_tmt_broadcast() );
Harald Welte15a85012020-06-13 16:35:45 +02001297 execute( TC_act_rctx_data_no_rctx() );
Harald Welte0db44132019-10-17 11:09:05 +02001298
Vadim Yanitskiy88f429d2024-03-04 02:03:52 +07001299 execute( TC_m3ua_tcp_cli() );
1300 execute( TC_m3ua_tcp_cli_srv() );
1301 execute( TC_m3ua_tcp_srv() );
1302 execute( TC_m3ua_tcp_srv_cli() );
1303
Harald Welte0db44132019-10-17 11:09:05 +02001304 /* M3UA RKM tests */
1305 execute( TC_rkm_reg_static_notpermitted() );
1306 execute( TC_rkm_reg_static_permitted() );
1307 execute( TC_rkm_reg_dynamic_permitted() );
Pau Espin Pedrol6b1b0ff2021-11-16 19:24:53 +01001308 execute( TC_rkm_unreg_never_registered() );
1309
Harald Welte0db44132019-10-17 11:09:05 +02001310 execute( TC_rkm_unreg_invalid() );
1311 execute( TC_rkm_unreg_registered() );
1312 execute( TC_rkm_unreg_active() );
1313 /* TODO: test RKM with unsupported routing keys: NA, SI, OPC */
1314 /* TODO: register/unregister multiple routing contexts in one message; including mixed
1315 success/failure situations */
Harald Welte829dac42019-11-05 16:55:30 +01001316
1317 /* Test STP as SCTP client + M3UA ASP role */
1318 execute( TC_clnt_connect_asp_up() );
1319 execute( TC_clnt_asp_act() );
1320 execute( TC_clnt_sg_to_asp() );
1321 execute( TC_clnt_asp_to_sg() );
Harald Welte53050cd2019-12-01 20:49:01 +01001322
Harald Welte6baf5e72023-04-15 20:30:52 +08001323 execute( TC_clnt_sg_to_asp_norctx() );
1324 execute( TC_clnt_asp_to_sg_norctx() );
1325
Pau Espin Pedrol6b1b0ff2021-11-16 19:24:53 +01001326 execute( TC_clnt_quirk_no_notify_asp_act() );
1327 execute( TC_clnt_no_daud_in_asp() );
1328 execute( TC_clnt_quirk_daud_in_asp() );
1329 execute( TC_clnt_no_snm_inactive() );
1330 execute( TC_clnt_quirk_snm_inactive() );
1331
Harald Welte30cb4002021-05-13 20:51:37 +02001332
Harald Welte27cfb7a2021-02-08 09:58:28 +01001333 /* M3UA SSNM tests */
1334 execute( TC_ssnm_aspac_dava_aspia_duna() );
1335 execute( TC_ssnm_distribution_dava_duna() );
1336 execute( TC_ssnm_distribution_dava_duna_multipc() );
1337 execute( TC_ssnm_distribution_dupu() );
1338 execute( TC_ssnm_distribution_scon() );
1339
Harald Welte53050cd2019-12-01 20:49:01 +01001340 /* put this one last as it changes the stp side config */
1341 execute( TC_clnt_asp_act_tmt_loadshare() );
Harald Welte0db44132019-10-17 11:09:05 +02001342}
1343
1344
1345
1346}