blob: 24b3ae1e2b8c1c57eb3cd445e1a8054aeeb2d564 [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;
36
37import from STP_Tests_Common all;
38
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +070039private const integer NR_M3UA := 4; /* number of M3UA clients in ATS */
40private const integer NR_M3UA_SRV := 4; /* number of M3UA servres in ATS */
Harald Welte829dac42019-11-05 16:55:30 +010041
Harald Welte1c4e9842021-02-07 23:03:28 +010042modulepar {
43 /* STP-side IP addresses */
44 HostList mp_stp_m3ua_ip := { "127.0.0.1", "::1" };
45 /* local IP addresses */
46 HostList mp_local_m3ua_ip := { "127.0.0.1", "::1" };
47 M3uaConfigs mp_m3ua_configs := {
48 /* as-sender: One ASP within AS */
49 {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +070050 use_tcp := false,
51 remote_port := 2905,
52 local_port := 9999,
Harald Welte1c4e9842021-02-07 23:03:28 +010053 point_code := 23,
54 routing_ctx := 1023
55 },
56 /* as-receiver: Two ASP within AS */
57 {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +070058 use_tcp := false,
59 remote_port := 2905,
60 local_port := 10000,
Harald Welte1c4e9842021-02-07 23:03:28 +010061 point_code := 42,
62 routing_ctx := 1042
63 }, {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +070064 use_tcp := false,
65 remote_port := 2905,
66 local_port := 10001,
Harald Welte1c4e9842021-02-07 23:03:28 +010067 point_code := 42,
68 routing_ctx := 1042
69 },
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +070070 /* as-sender-tcp: One ASP within AS */
71 {
72 use_tcp := true,
73 remote_port := 2905,
74 local_port := 9999,
75 point_code := 123,
76 routing_ctx := 1123
77 },
Harald Welte1c4e9842021-02-07 23:03:28 +010078 /* as-client: One ASP within AS */
79 {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +070080 use_tcp := false,
81 remote_port := 2906,
82 local_port := 10002,
Harald Welte1c4e9842021-02-07 23:03:28 +010083 point_code := 55,
84 routing_ctx := 1055
Harald Welte6baf5e72023-04-15 20:30:52 +080085 },
86 /* as-client60-norctx */
87 {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +070088 use_tcp := false,
89 remote_port := 2907,
90 local_port := 11060,
Harald Welte6baf5e72023-04-15 20:30:52 +080091 point_code := 60,
92 routing_ctx := -
93 },
94 /* as-client61-norctx */
95 {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +070096 use_tcp := false,
97 remote_port := 2907,
98 local_port := 11061,
Harald Welte6baf5e72023-04-15 20:30:52 +080099 point_code := 61,
100 routing_ctx := -
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700101 },
102 /* as-client-tcp: One ASP within AS */
103 {
104 use_tcp := true,
105 remote_port := 2906,
106 local_port := 10002,
107 point_code := 155,
108 routing_ctx := 1155
Harald Welte1c4e9842021-02-07 23:03:28 +0100109 }
110 };
111 integer mp_recovery_timeout_msec := 2000;
112 charstring mp_sccp_service_type := "mtp3_itu";
113}
114
115type record M3uaConfig {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700116 /* use TCP (true) or SCTP (false) */
117 boolean use_tcp,
118 /* STP-side SCTP (or TCP) port for M3UA */
119 integer remote_port,
Harald Welte1c4e9842021-02-07 23:03:28 +0100120 /* local M3UA base port on TTCN3 side */
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700121 integer local_port,
Harald Welte1c4e9842021-02-07 23:03:28 +0100122 /* point code routed via this M3U */
123 integer point_code,
124 /* associated routing context */
125 integer routing_ctx
126};
127type record length (NR_M3UA+NR_M3UA_SRV) of M3uaConfig M3uaConfigs;
128
Harald Welte829dac42019-11-05 16:55:30 +0100129private function M3UA_SRV(integer idx) return integer {
130 return NR_M3UA+idx;
131}
Harald Welte0db44132019-10-17 11:09:05 +0200132
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700133private function f_m3ua_cli_config(integer idx) return M3uaConfig {
134 if (idx < 0 or idx >= NR_M3UA) {
135 setverdict(fail, "f_m3ua_cli_config(): unexpected idx");
136 Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
137 }
138 return mp_m3ua_configs[idx];
139}
140
141private function f_m3ua_srv_config(integer idx) return M3uaConfig {
142 if (idx < 0 or idx >= NR_M3UA_SRV) {
143 setverdict(fail, "f_m3ua_srv_config(): unexpected idx");
144 Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
145 }
146 return mp_m3ua_configs[M3UA_SRV(idx)];
147}
148
Harald Welte0db44132019-10-17 11:09:05 +0200149type component RAW_M3UA_CT extends Test_CT {
Harald Welte829dac42019-11-05 16:55:30 +0100150 port M3UA_CODEC_PT M3UA[NR_M3UA+NR_M3UA_SRV];
151 var integer g_m3ua_conn_id[NR_M3UA+NR_M3UA_SRV];
Harald Welte0db44132019-10-17 11:09:05 +0200152}
153
154private template PortEvent tr_SctpAssocChange := {
155 sctpEvent := {
156 sctpAssocChange := ?
157 }
158}
159private template PortEvent tr_SctpPeerAddrChange := {
160 sctpEvent := {
161 sctpPeerAddrChange := ?
162 }
163}
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700164private template PortEvent tr_ConnOpened := {
Harald Welte829dac42019-11-05 16:55:30 +0100165 connOpened := ?
166}
167
Harald Welte0db44132019-10-17 11:09:05 +0200168
169private altstep as_m3ua_sctp() runs on RAW_M3UA_CT {
170 [] any from M3UA.receive(tr_SctpAssocChange) { repeat; }
171 [] any from M3UA.receive(tr_SctpPeerAddrChange) { repeat; }
172}
173
Harald Welte42bcc442021-02-07 21:26:30 +0100174private altstep as_m3ua_ssnm_ignore() runs on RAW_M3UA_CT {
175 var M3UA_RecvFrom rx;
176 [] any from M3UA.receive(t_M3UA_RecvFrom(tr_M3UA_SSNM)) -> value rx {
177 log("Ignoring M3UA SSNM", rx);
178 repeat;
179 }
180}
181
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700182friend function f_M3UA_send(integer idx, template (present) PDU_M3UA msg, integer stream := 0)
Harald Welte0db44132019-10-17 11:09:05 +0200183runs on RAW_M3UA_CT {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700184 if (mp_m3ua_configs[idx].use_tcp) {
185 M3UA[idx].send(t_M3UA_Send(g_m3ua_conn_id[idx], msg, omit));
186 } else {
187 M3UA[idx].send(t_M3UA_Send(g_m3ua_conn_id[idx], msg, stream));
188 }
Harald Welte0db44132019-10-17 11:09:05 +0200189}
190
191friend function f_M3UA_exp(integer idx, template (present) PDU_M3UA msg) runs on RAW_M3UA_CT {
192 var M3UA_RecvFrom rx;
Harald Welte30812592021-02-08 09:50:46 +0100193 timer T := 5.0;
194 T.start;
Harald Welte0db44132019-10-17 11:09:05 +0200195 alt {
196 [] M3UA[idx].receive(t_M3UA_RecvFrom(msg)) {
197 setverdict(pass);
198 }
199 [] M3UA[idx].receive(t_M3UA_RecvFrom(?)) -> value rx {
200 setverdict(fail, "Received unexpected M3UA[", idx, "] ", rx,
201 "while waiting for ", msg);
202 mtc.stop;
203 }
Harald Welte30812592021-02-08 09:50:46 +0100204 [] T.timeout {
205 setverdict(fail, "Timeout waiting for M3UA[", idx, "] ", msg);
206 mtc.stop;
207 }
Harald Welte0db44132019-10-17 11:09:05 +0200208 }
209}
210
Harald Welte3e5f05e2023-04-15 20:02:52 +0800211/* flush any number of queued messages matching 'msg' */
212friend function f_M3UA_flush(integer idx, template (present) PDU_M3UA msg) runs on RAW_M3UA_CT {
213 var M3UA_RecvFrom rx;
214 timer T := 0.01;
215 T.start;
216 alt {
217 /* this should normally be possible with something like M3UA[idx].check(receive(...)) but somehow
218 * TITAN complains about the 'check' token, so it looks that feature of TTCN3 is not supported? */
219 [] M3UA[idx].receive(t_M3UA_RecvFrom(msg)) {
220 repeat;
221 }
222 [] T.timeout {
223 }
224 }
225}
226
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200227private template (value) Socket ts_Socket(HostName hostName, PortNumber portNumber) := {
228 hostName := hostName,
229 portNumber := portNumber
230};
231
232private template (value) SctpTuple ts_SCTP(template (omit) integer ppid := 3,
233 template (omit) integer stream := 0,
234 template (omit) SocketList remSocks := omit) := {
235 sinfo_stream := stream,
236 sinfo_ppid := ppid,
237 remSocks := remSocks,
238 assocId := omit
239};
240
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700241friend function f_M3UA_connect_sctp(integer i) runs on RAW_M3UA_CT {
Harald Welte0db44132019-10-17 11:09:05 +0200242 var Result res;
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200243 var Option opt_add_local_addrs;
244 var OptionList opt_list := {};
245 var template SocketList opt_add_remote_addrs;
Harald Welte1c4e9842021-02-07 23:03:28 +0100246 var M3uaConfig m3cfg := mp_m3ua_configs[i];
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200247
248 if (lengthof(mp_local_m3ua_ip) == 0 or lengthof(mp_stp_m3ua_ip) == 0) {
249 setverdict(fail, "Empty local or remote address trying to connect SCTP socket: ",
250 mp_local_m3ua_ip, " / ", mp_stp_m3ua_ip);
251 mtc.stop;
252 }
253
254 if (lengthof(mp_local_m3ua_ip) > 1) {
255 opt_add_local_addrs.sctpAdditionalLocalAddresses := substr(mp_local_m3ua_ip, 1,
256 lengthof(mp_local_m3ua_ip) - 1); //{mp_local_m3ua_ip};
257 opt_list := {opt_add_local_addrs};
258 }
259
260 if (lengthof(mp_stp_m3ua_ip) > 1) {
261 for (var integer j := 1; j < lengthof(mp_stp_m3ua_ip); j := j + 1) {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700262 var Socket sk := valueof(ts_Socket(mp_stp_m3ua_ip[j], m3cfg.remote_port));
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200263 opt_add_remote_addrs[j - 1] := sk;
264 }
265 } else {
266 opt_add_remote_addrs := omit;
267 }
268
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700269 res := M3UA_CodecPort_CtrlFunct.f_IPL4_connect(M3UA[i], mp_stp_m3ua_ip[0], m3cfg.remote_port,
270 mp_local_m3ua_ip[0], m3cfg.local_port, 0,
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200271 {sctp:=valueof(ts_SCTP(3, 0, opt_add_remote_addrs))},
272 opt_list);
Harald Welte0db44132019-10-17 11:09:05 +0200273 if (not ispresent(res.connId)) {
274 setverdict(fail, "Could not connect M3UA socket, check your configuration");
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200275 mtc.stop;
Harald Welte0db44132019-10-17 11:09:05 +0200276 }
277 g_m3ua_conn_id[i] := res.connId;
278}
279
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700280friend function f_M3UA_connect_tcp(integer i) runs on RAW_M3UA_CT {
281 var M3uaConfig m3cfg := mp_m3ua_configs[i];
282 var Result res;
283
284 /* XXX: M3UA-over-TCP is not supported by osmo-stp <= 1.8.1 */
285 if (not Misc_Helpers.f_osmo_repo_is("nightly")) {
286 log("Not connect()ing m3cfg := ", m3cfg, " (not supported by IUT)");
287 g_m3ua_conn_id[i] := -1;
288 return;
289 }
290
291 if (lengthof(mp_local_m3ua_ip) == 0 or lengthof(mp_stp_m3ua_ip) == 0) {
292 setverdict(fail, "Empty local or remote address trying to connect TCP socket: ",
293 mp_local_m3ua_ip, " / ", mp_stp_m3ua_ip);
294 mtc.stop;
295 }
296
297 res := M3UA_CodecPort_CtrlFunct.f_IPL4_connect(M3UA[i], mp_stp_m3ua_ip[0], m3cfg.remote_port,
298 mp_local_m3ua_ip[0], m3cfg.local_port, 0,
299 {tcp:={}});
300 if (not ispresent(res.connId)) {
301 setverdict(fail, "Could not connect M3UA socket, check your configuration");
302 mtc.stop;
303 }
304 g_m3ua_conn_id[i] := res.connId;
305 M3UA_CodecPort.f_set_tcp_segmentation(M3UA[i], res.connId);
306}
307
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100308friend function f_M3UA_close(integer i) runs on RAW_M3UA_CT {
309 var Result res;
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700310 if (g_m3ua_conn_id[i] < 0) {
311 log("Not close()ing m3cfg := ", mp_m3ua_configs[i], " (not connected)");
312 /* not connected */
313 return;
314 }
315 if (mp_m3ua_configs[i].use_tcp) {
316 res := M3UA_CodecPort_CtrlFunct.f_IPL4_close(M3UA[i], g_m3ua_conn_id[i], {tcp:={}});
317 } else {
318 res := M3UA_CodecPort_CtrlFunct.f_IPL4_close(M3UA[i], g_m3ua_conn_id[i], {sctp:=valueof(ts_SCTP)});
319 }
320 g_m3ua_conn_id[i] := -1;
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100321}
322
Harald Welte829dac42019-11-05 16:55:30 +0100323friend function f_M3UA_listen(integer i) runs on RAW_M3UA_CT {
324 var Result res;
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200325 var Option opt_add_local_addrs;
326 var OptionList opt_list := {};
Harald Welte1c4e9842021-02-07 23:03:28 +0100327 var M3uaConfig m3cfg := mp_m3ua_configs[i];
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200328
Vadim Yanitskiy7b541af2024-03-07 18:21:17 +0700329 /* XXX: M3UA-over-TCP is not supported by osmo-stp <= 1.8.1 */
330 if (not Misc_Helpers.f_osmo_repo_is("nightly") and m3cfg.use_tcp) {
331 log("Not listen()ing m3cfg := ", m3cfg, " (not supported by IUT)");
332 return;
333 }
334
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200335 if (lengthof(mp_local_m3ua_ip) == 0 ) {
336 setverdict(fail, "Empty local address trying to bind SCTP socket: ",
337 mp_local_m3ua_ip);
338 mtc.stop;
339 }
340
341 if (lengthof(mp_local_m3ua_ip) > 1) {
342 opt_add_local_addrs.sctpAdditionalLocalAddresses := substr(mp_local_m3ua_ip, 1,
343 lengthof(mp_local_m3ua_ip) - 1); //{mp_local_m3ua_ip};
344 opt_list := {opt_add_local_addrs};
345 }
346
Vadim Yanitskiyf5878122024-03-07 18:19:00 +0700347 if (m3cfg.use_tcp) {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700348 res := M3UA_CodecPort_CtrlFunct.f_IPL4_listen(M3UA[i], mp_local_m3ua_ip[0], m3cfg.local_port,
349 {tcp:={}});
350 } else {
351 res := M3UA_CodecPort_CtrlFunct.f_IPL4_listen(M3UA[i], mp_local_m3ua_ip[0], m3cfg.local_port,
352 {sctp:=valueof(ts_SCTP)}, opt_list);
353 }
Harald Welte829dac42019-11-05 16:55:30 +0100354 if (not ispresent(res.connId)) {
355 setverdict(fail, "Could not bind M3UA socket, check your configuration");
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200356 mtc.stop;
Harald Welte829dac42019-11-05 16:55:30 +0100357 }
Vadim Yanitskiyf5878122024-03-07 18:19:00 +0700358 if (m3cfg.use_tcp) {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700359 M3UA_CodecPort.f_set_tcp_segmentation(M3UA[i], res.connId);
360 }
Harald Welte829dac42019-11-05 16:55:30 +0100361}
362
Harald Welte27cfb7a2021-02-08 09:58:28 +0100363friend function f_init_m3ua(boolean ignore_ssnm := true) runs on RAW_M3UA_CT {
Harald Welte0db44132019-10-17 11:09:05 +0200364 var integer i;
365
366 f_init_common();
367
368 activate(as_m3ua_sctp());
Harald Welte27cfb7a2021-02-08 09:58:28 +0100369 if (ignore_ssnm) {
370 activate(as_m3ua_ssnm_ignore());
371 }
Harald Welte0db44132019-10-17 11:09:05 +0200372
373 for (i := 0; i < NR_M3UA; i:=i+1) {
Vadim Yanitskiy7b541af2024-03-07 18:21:17 +0700374 /* XXX: M3UA-over-TCP is not supported by osmo-stp <= 1.8.1 */
375 if (not Misc_Helpers.f_osmo_repo_is("nightly") and mp_m3ua_configs[i].use_tcp) {
376 log("Not connect()ing m3cfg := ", mp_m3ua_configs[i], " (not supported by IUT)");
377 g_m3ua_conn_id[i] := -1;
378 continue;
379 }
Harald Welte0db44132019-10-17 11:09:05 +0200380 map(self:M3UA[i], system:M3UA_CODEC_PT);
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700381 if (mp_m3ua_configs[i].use_tcp) {
382 f_M3UA_connect_tcp(i);
383 } else {
384 f_M3UA_connect_sctp(i);
385 }
Harald Welte0db44132019-10-17 11:09:05 +0200386 }
387}
388
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100389friend function f_clear_m3ua() runs on RAW_M3UA_CT {
390 var integer i;
391
392 log("Clearing M3UA...");
393
394 for (i := 0; i < NR_M3UA; i:=i+1) {
395 f_M3UA_close(i);
396 }
397 /* Wait for recovery timer to trigger and shutdown all AS: */
398 f_sleep(int2float(mp_recovery_timeout_msec)/1000.0 + 0.5);
399 setverdict(pass, "M3UA cleared");
400}
401
Harald Welte829dac42019-11-05 16:55:30 +0100402friend function f_init_m3ua_srv() runs on RAW_M3UA_CT {
403 var integer i;
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700404 var PortEvent port_evt;
Harald Welte829dac42019-11-05 16:55:30 +0100405
406 for (i := NR_M3UA; i < NR_M3UA+NR_M3UA_SRV; i:=i+1) {
Vadim Yanitskiy7b541af2024-03-07 18:21:17 +0700407 /* XXX: M3UA-over-TCP is not supported by osmo-stp <= 1.8.1 */
408 if (not Misc_Helpers.f_osmo_repo_is("nightly") and mp_m3ua_configs[i].use_tcp) {
409 log("Not listen()ing m3cfg := ", mp_m3ua_configs[i], " (not supported by IUT)");
410 g_m3ua_conn_id[i] := -1;
411 continue;
412 }
Harald Welte829dac42019-11-05 16:55:30 +0100413 map(self:M3UA[i], system:M3UA_CODEC_PT);
414 /* bind+ listen */
415 f_M3UA_listen(i);
416 /* wait for accept() */
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700417 M3UA[i].receive(tr_ConnOpened) -> value port_evt {
418 g_m3ua_conn_id[i] := port_evt.connOpened.connId;
Harald Welte829dac42019-11-05 16:55:30 +0100419 }
420 }
421}
422
423
424/***********************************************************************
425 * Test the STP in M3UA SG role (we are ASP)
426 ***********************************************************************/
427
Harald Welte0db44132019-10-17 11:09:05 +0200428/* perform an outbound ASP-UP procedure */
429friend function f_M3UA_asp_up(integer idx, template (omit) OCT4 aspid := omit) runs on RAW_M3UA_CT {
430 f_M3UA_send(idx, ts_M3UA_ASPUP(aspid));
431 f_M3UA_exp(idx, tr_M3UA_ASPUP_ACK);
432}
433
434/* perform an outbound BEAT procedure */
435friend function f_M3UA_beat(integer idx, template (omit) octetstring hbd) runs on RAW_M3UA_CT {
436 if (istemplatekind(hbd, "omit")) {
437 f_M3UA_send(idx, ts_M3UA_BEAT(omit));
438 f_M3UA_exp(idx, tr_M3UA_BEAT_ACK(omit));
439 } else {
440 f_M3UA_send(idx, ts_M3UA_BEAT(ts_M3UA_hb_data(hbd)));
441 f_M3UA_exp(idx, tr_M3UA_BEAT_ACK(tr_M3UA_hb_data(hbd)));
442 }
443}
444
445/* perform an outbound ASP-ACTIVATE procedure */
446friend function f_M3UA_asp_act(integer idx, template (omit) M3UA_Traffic_Mode_Type tmt := omit,
447 template (omit) OCT4 rctx := omit) runs on RAW_M3UA_CT {
448 f_M3UA_send(idx, ts_M3UA_ASPAC(tmt, rctx));
449 f_M3UA_exp(idx, tr_M3UA_ASPAC_ACK(tmt, rctx));
450}
451
Harald Welte27cfb7a2021-02-08 09:58:28 +0100452/* perform an outbound ASP-INACTIVATE procedure */
453friend function f_M3UA_asp_inact(integer idx, template (omit) OCT4 rctx := omit) runs on RAW_M3UA_CT {
454 f_M3UA_send(idx, ts_M3UA_ASPIA(rctx));
455 f_M3UA_exp(idx, tr_M3UA_ASPIA_ACK(rctx));
456}
457
Harald Welte0db44132019-10-17 11:09:05 +0200458/* perform outbound ASP-UP and ASP-ACT, optionally expect interemittent NOTIFY */
459friend function f_M3UA_asp_up_act(integer idx, template (omit) M3UA_Traffic_Mode_Type tmt := omit,
460 template (omit) OCT4 rctx := omit,
461 template (omit) OCT2 ntfy_after_up := c_M3UA_ST_I_AS_INACTIVE,
462 template (omit) OCT2 ntfy_after_act := c_M3UA_ST_I_AS_ACTIVE)
463runs on RAW_M3UA_CT {
464 f_M3UA_asp_up(idx, omit);
465 if (not istemplatekind(ntfy_after_up, "omit")) {
466 f_M3UA_exp(idx, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, ntfy_after_up, *));
467 }
468 f_M3UA_asp_act(idx, tmt, rctx);
469 if (not istemplatekind(ntfy_after_act, "omit")) {
470 f_M3UA_exp(idx, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, ntfy_after_act, *));
471 }
472}
473
474
475/* Test the ASP-UP procedure */
476testcase TC_connect_asp_up() runs on RAW_M3UA_CT {
477 f_init_m3ua();
478 f_M3UA_asp_up(0);
479 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 +0100480 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200481}
482
483/* Test the heartbeat procedure without optional heartbeat data payload */
484testcase TC_beat() 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, omit);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100489 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200490}
491
492/* Test the heartbeat procedure with optional heartbeat data payload */
493testcase TC_beat_payload() runs on RAW_M3UA_CT {
494 f_init_m3ua();
495 f_M3UA_asp_up(0);
496 f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_INACTIVE, *));
497 f_M3UA_beat(0, 'a1a2a3a4a5'O);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100498 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200499}
500
501/* Test the ASP-ACTIVATE procedure (without traffic-mode or routing ctx) */
502testcase TC_asp_act() runs on RAW_M3UA_CT {
503 f_init_m3ua();
504 f_M3UA_asp_up_act(0);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100505 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200506}
507
508/* Test the ASP-ACTIVATE procedure with traffic-mode override */
509testcase TC_asp_act_override() runs on RAW_M3UA_CT {
510 f_init_m3ua();
511 f_M3UA_asp_up_act(0, c_M3UA_TMT_override, omit);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100512 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200513}
514
515/* Test the ASP-ACTIVATE procedure with traffic-mode override */
516testcase TC_asp_act_loadshare() runs on RAW_M3UA_CT {
517 f_init_m3ua();
518 f_M3UA_asp_up_act(0, c_M3UA_TMT_loadshare, omit);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100519 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200520}
521
522/* Test the ASP-ACTIVATE procedure with traffic-mode broadcast */
523testcase TC_asp_act_broadcast() runs on RAW_M3UA_CT {
524 f_init_m3ua();
525 f_M3UA_asp_up_act(0, c_M3UA_TMT_broadcast, omit);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100526 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200527}
528
Harald Welte15a85012020-06-13 16:35:45 +0200529/* test whether the STP accepts M3UA DATA without Routing Context IE */
530testcase TC_act_rctx_data_no_rctx() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700531 var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
532 var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
533 var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(1).routing_ctx, 4);
534 var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(1).point_code, 4);
Harald Welte15a85012020-06-13 16:35:45 +0200535
536 f_init_m3ua();
537 /* bring up the sender specifying a routing context */
538
539 f_M3UA_asp_up_act(0, rctx := rctx_sender);
540 f_M3UA_asp_up_act(1);
541
542 /* check if DATA is accepted without Routing Context IE */
543 f_test_traffic(0, omit, pc_sender, 1, rctx_receiver, pc_receiver);
544
545 f_clear_m3ua();
546}
547
Harald Welte0db44132019-10-17 11:09:05 +0200548/* Test if traffic is routed from idx_tx/pc_tx to idx_rx/pc_rx */
549private function f_test_traffic(integer idx_tx, template (omit) OCT4 rctx_sender, OCT4 pc_tx,
550 integer idx_rx, template (omit) OCT4 rctx_receiver, OCT4 pc_rx,
551 OCT1 si := '23'O, OCT1 ni := '00'O, OCT1 mp := '00'O, OCT1 sls := '00'O)
552runs on RAW_M3UA_CT {
Harald Welte67881ae2022-04-12 22:52:47 +0200553 var octetstring data := f_rnd_octstring_rnd_len(100);
Harald Welte0db44132019-10-17 11:09:05 +0200554 f_M3UA_send(idx_tx, ts_M3UA_DATA(rctx_sender,
555 ts_M3UA_protocol_data(pc_tx, pc_rx, si, ni, mp, sls, data)), 1);
556 f_M3UA_exp(idx_rx, tr_M3UA_DATA(rctx_receiver,
557 tr_M3UA_protocol_data(pc_tx, pc_rx, si, ni, mp, sls, data)));
558}
559
560
561/* test "traffic-mode override" behavior */
562testcase TC_tmt_override() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700563 var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
564 var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
565 var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(1).routing_ctx, 4);
566 var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(1).point_code, 4);
Harald Welte0db44132019-10-17 11:09:05 +0200567
568 f_init_m3ua();
569
570 /* bring up the 'sender' side (single ASP in AS) */
571 f_M3UA_asp_up_act(0, omit, omit);
572
573 /* activate the first 'receiver' side ASP */
574 f_M3UA_asp_up_act(1, c_M3UA_TMT_override, rctx_receiver);
575
576 /* verify traffic is routed from sender to [sole] receiver */
577 f_test_traffic(0, rctx_sender, pc_sender, 1, rctx_receiver, pc_receiver);
578
579 /* activate the second 'receiver' side ASP (no NOTIFY as AS state doesn't change) */
580 f_M3UA_asp_up_act(2, c_M3UA_TMT_override, rctx_receiver, omit, omit);
581
582 /* we expect a NOTIFY to the *other* ASP Other/Alternat-ASP-Active */
583 f_M3UA_exp(1, tr_M3UA_NOTIFY(c_M3UA_ST_T_OTHER, c_M3UA_ST_I_ALTERNATE_ASP, *));
584
585 /* verify traffic is routed from sender to new receiver */
586 f_test_traffic(0, rctx_sender, pc_sender, 2, rctx_receiver, pc_receiver);
587
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100588 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200589}
590
591private altstep as_count_rx(integer idx, template (present) PDU_M3UA exp, inout integer counter)
592runs on RAW_M3UA_CT {
593 [] M3UA[idx].receive(t_M3UA_RecvFrom(exp)) {
594 counter := counter + 1;
595 }
596}
597
598/* test "traffic-mode load-share" behavior */
599testcase TC_tmt_loadshare() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700600 var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
601 var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
602 var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(1).routing_ctx, 4);
603 var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(1).point_code, 4);
Harald Welte0db44132019-10-17 11:09:05 +0200604 var integer i;
605
606 f_init_m3ua();
607
608 /* FIXME: configure the STP via VTY to set traffic-mode */
609
610 /* bring up the 'sender' side (single ASP in AS) */
611 f_M3UA_asp_up_act(0, omit, rctx_sender);
612
613 /* activate the first 'receiver' side ASP */
Harald Welte0db44132019-10-17 11:09:05 +0200614 f_M3UA_asp_up_act(1, c_M3UA_TMT_loadshare, omit); // TODO: rctx
615
616 /* verify traffic is routed from sender to [sole] receiver */
617 for (i := 0; i < 10; i := i+1) {
618 f_test_traffic(0, rctx_sender, pc_sender, 1, rctx_receiver, pc_receiver);
619 }
620
621 /* activate the second 'receiver' side ASP (no NOTIFY) */
622 f_M3UA_asp_up_act(2, c_M3UA_TMT_loadshare, omit, omit, omit); // TODO: rctx
623
624 /* verify traffic is routed from sender to new receiver */
625 const integer iter_per_asp := 5;
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700626 var integer num_rx[NR_M3UA] := { 0, 0, 0, 0 };
Harald Welte0db44132019-10-17 11:09:05 +0200627 for (i := 0; i < 2*iter_per_asp; i := i+1) {
Harald Welte67881ae2022-04-12 22:52:47 +0200628 var octetstring data := f_rnd_octstring_rnd_len(100);
Harald Welte0db44132019-10-17 11:09:05 +0200629 var template (value) M3UA_Protocol_Data tx_pd;
630 var template (present) M3UA_Protocol_Data rx_pd;
631 tx_pd := ts_M3UA_protocol_data(pc_sender, pc_receiver, '23'O, '00'O, '00'O, '00'O, data);
632 rx_pd := tr_M3UA_protocol_data(pc_sender, pc_receiver, '23'O, '00'O, '00'O, '00'O, data);
633 f_M3UA_send(0, ts_M3UA_DATA(rctx_sender, tx_pd), 1);
634 alt {
Pau Espin Pedrol4d915782020-08-21 12:24:35 +0200635 [] as_count_rx(1, tr_M3UA_DATA(rctx_receiver, rx_pd), num_rx[1]);
636 [] as_count_rx(2, tr_M3UA_DATA(rctx_receiver, rx_pd), num_rx[2]);
Harald Welte0db44132019-10-17 11:09:05 +0200637 }
638 }
639 /* FIXME: check for extraneous messages? */
640 for (i := 1; i <= 2; i := i+1) {
641 if (num_rx[i] != iter_per_asp) {
Harald Welteb9f7bbb2019-10-29 09:07:11 +0100642 setverdict(fail, "Received ", num_rx[i], " out of expected ", iter_per_asp,
643 "M3UA DATA messages at M3UA port ", i);
Harald Welte0db44132019-10-17 11:09:05 +0200644 }
645 }
646 setverdict(pass);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100647
648 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200649}
650
651/* test "traffic-mode broadcast" behavior */
652testcase TC_tmt_broadcast() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700653 var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
654 var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
655 var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(1).routing_ctx, 4);
656 var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(1).point_code, 4);
Harald Welte0db44132019-10-17 11:09:05 +0200657 var integer i;
658
659 f_init_m3ua();
660
661 /* FIXME: configure the STP via VTY to set traffic-mode */
662
663 /* bring up the 'sender' side (single ASP in AS) */
664 f_M3UA_asp_up_act(0, omit, omit); // TODO: rctx
665
666 /* activate the first 'receiver' side ASP */
Harald Welte0db44132019-10-17 11:09:05 +0200667 f_M3UA_asp_up_act(1, c_M3UA_TMT_broadcast, omit); // TODO: rctx
668
669 /* verify traffic is routed from sender to [sole] receiver */
670 for (i := 0; i < 10; i := i+1) {
671 f_test_traffic(0, rctx_sender, pc_sender, 1, rctx_receiver, pc_receiver);
672 }
673
674 /* activate the second 'receiver' side ASP */
675 f_M3UA_asp_up_act(2, c_M3UA_TMT_broadcast, omit, omit, omit); // TODO: rctx
676
677 /* verify traffic is routed from sender to new receiver */
678 for (i := 0; i < 10; i := i+1) {
Harald Welte67881ae2022-04-12 22:52:47 +0200679 var octetstring data := f_rnd_octstring_rnd_len(100);
Harald Welte0db44132019-10-17 11:09:05 +0200680 var template (value) M3UA_Protocol_Data tx_pd;
681 var template (present) M3UA_Protocol_Data rx_pd;
682 tx_pd := ts_M3UA_protocol_data(pc_sender, pc_receiver, '23'O, '00'O, '00'O, '00'O, data);
683 rx_pd := tr_M3UA_protocol_data(pc_sender, pc_receiver, '23'O, '00'O, '00'O, '00'O, data);
684 f_M3UA_send(0, ts_M3UA_DATA(rctx_sender, tx_pd), 1);
685 /* each message must be received both on 1 and 2 */
686 f_M3UA_exp(1, tr_M3UA_DATA(rctx_receiver, rx_pd));
687 f_M3UA_exp(2, tr_M3UA_DATA(rctx_receiver, rx_pd));
688 }
689 setverdict(pass);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100690
691 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200692}
693
694private function f_M3UA_rkm_register(OCT4 id, OCT3 dpc, OCT4 rctx,
695 template (present) OCT4 exp_status := c_M3UA_REGSTS_SUCCESS)
696runs on RAW_M3UA_CT
697{
698 f_M3UA_send(0, ts_M3UA_REG_REQ({ts_M3UA_rkey(id:=id, dpc:=dpc, rctx:=rctx)}));
699 f_M3UA_exp(0, tr_M3UA_REG_RSP({tr_M3UA_reg_res(id:=id, status:=exp_status, rctx:=rctx)}));
700}
701
702/* Send RKM registration; expect -EPERM as RCTX doesn't match config and dynamic not permitted */
703testcase TC_rkm_reg_static_notpermitted() runs on RAW_M3UA_CT {
704 f_init_m3ua();
705
706 f_M3UA_send(0, ts_M3UA_REG_REQ({ts_M3UA_rkey(id:='00000099'O, dpc:='aabbcc'O)}));
707 f_M3UA_exp(0, tr_M3UA_REG_RSP({tr_M3UA_reg_res(id:='00000099'O, status:=c_M3UA_REGSTS_ERR_EPERM,
708 rctx:=?)}));
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100709
710 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200711}
712
713/* Send RKM registration; expect OK as RCTX does match config */
714testcase TC_rkm_reg_static_permitted() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700715 var OCT3 dpc := int2oct(f_m3ua_cli_config(0).point_code, 3); // must match config
716 var OCT4 rctx := int2oct(f_m3ua_cli_config(0).routing_ctx, 4); // must match config
Harald Welte0db44132019-10-17 11:09:05 +0200717
718 f_init_m3ua();
719
720 f_M3UA_send(0, ts_M3UA_REG_REQ({ts_M3UA_rkey(id:='10000099'O, dpc:=dpc, rctx:=rctx)}));
721 f_M3UA_exp(0, tr_M3UA_REG_RSP({tr_M3UA_reg_res(id:='10000099'O, status:=c_M3UA_REGSTS_SUCCESS,
722 rctx:=rctx)}));
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100723
724 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200725}
726
727/* Send RKM registration; expect OK as dynamic not permitted */
728testcase TC_rkm_reg_dynamic_permitted() runs on RAW_M3UA_CT {
729 f_init_common();
730 f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation dynamic-permitted");
731 f_init_m3ua();
732
733 f_M3UA_send(0, ts_M3UA_REG_REQ({ts_M3UA_rkey(id:='20000099'O, dpc:='aabbcc'O)}));
734 f_M3UA_exp(0, tr_M3UA_REG_RSP({tr_M3UA_reg_res(id:='20000099'O, status:=c_M3UA_REGSTS_SUCCESS,
735 rctx:=?)}));
736
737 f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation static-only");
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100738
739 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200740}
741
742/* try to de-register a routing key that was never registered -> error */
743testcase TC_rkm_unreg_never_registered() runs on RAW_M3UA_CT {
744 f_init_m3ua();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700745 var octetstring rctx := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
746 f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(rctx)));
Harald Welte0db44132019-10-17 11:09:05 +0200747 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 +0100748 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200749}
750
751/* try to de-register a routing key that is invalid (non-existant) -> error */
752testcase TC_rkm_unreg_invalid() runs on RAW_M3UA_CT {
753 f_init_m3ua();
754 f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(int2oct(1234,4))));
755 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 +0100756 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200757}
758
Oliver Smith326d78e2021-07-23 10:42:10 +0200759/* try to de-register a routing key that was registered -> OK */
Harald Welte0db44132019-10-17 11:09:05 +0200760testcase TC_rkm_unreg_registered() runs on RAW_M3UA_CT {
Oliver Smith326d78e2021-07-23 10:42:10 +0200761 var OCT3 dpc := int2oct(123, 3);
762 var OCT4 rctx := int2oct(1234, 4);
763
764 f_init_common();
765 f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation dynamic-permitted");
Harald Welte0db44132019-10-17 11:09:05 +0200766 f_init_m3ua();
Oliver Smith326d78e2021-07-23 10:42:10 +0200767
768 /* first register the routing key */
769 f_M3UA_rkm_register(id:='30000099'O, dpc:=dpc, rctx:=rctx);
770
771 /* then try to de-register */
772 f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(rctx)));
Harald Welte0db44132019-10-17 11:09:05 +0200773 f_M3UA_exp(0, tr_M3UA_DEREG_RSP({tr_M3UA_dereg_res(?,c_m3UA_DEREGSTS_SUCCESS)}));
Oliver Smith326d78e2021-07-23 10:42:10 +0200774
775 f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation static-only");
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100776 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200777}
778
779/* try to de-register a routing key for an active ASP -> ERROR */
780testcase TC_rkm_unreg_active() runs on RAW_M3UA_CT {
Oliver Smithee022232021-07-23 11:01:06 +0200781 var OCT3 dpc := int2oct(123, 3);
782 var OCT4 rctx := int2oct(1234, 4);
Harald Welte0db44132019-10-17 11:09:05 +0200783
Oliver Smithee022232021-07-23 11:01:06 +0200784 f_init_common();
785 f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation dynamic-permitted");
Harald Welte0db44132019-10-17 11:09:05 +0200786 f_init_m3ua();
787
788 /* first register the routing key */
789 f_M3UA_rkm_register(id:='30000099'O, dpc:=dpc, rctx:=rctx);
790
791 /* then activate the ASP */
792 f_M3UA_asp_up_act(0);
Oliver Smithee022232021-07-23 11:01:06 +0200793 f_M3UA_exp(0, tr_M3UA_DAVA({*}, rctx));
794 f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_ACTIVE, *));
795 f_M3UA_exp(0, tr_M3UA_DAVA({*}, *));
Harald Welte0db44132019-10-17 11:09:05 +0200796
Oliver Smithee022232021-07-23 11:01:06 +0200797 /* then try to de-register -> ERR_ASP_ACTIVE */
Harald Welte0db44132019-10-17 11:09:05 +0200798 f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(rctx)));
799 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 +0100800
Oliver Smithee022232021-07-23 11:01:06 +0200801 /* deactivate ASP and properly de-register to clean up */
802 f_M3UA_asp_inact(0);
803 f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(rctx)));
804 f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_PENDING, *));
805 f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_PENDING, *));
806 f_M3UA_exp(0, tr_M3UA_DEREG_RSP({tr_M3UA_dereg_res(?,c_m3UA_DEREGSTS_SUCCESS)}));
807
808 f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation static-only");
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100809 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200810}
811
Harald Welte829dac42019-11-05 16:55:30 +0100812/***********************************************************************
813 * Test the STP in M3UA ASP role (we are SG)
814 ***********************************************************************/
815
816/* expect/perform an inbound ASP-UP procedure */
817friend function f_M3UA_CLNT_asp_up(integer idx, template OCT4 aspid := omit) runs on RAW_M3UA_CT {
818 f_M3UA_exp(idx, tr_M3UA_ASPUP(aspid));
Harald Welte3e5f05e2023-04-15 20:02:52 +0800819 /* there might have been multiple re-transmissions that have queued up in the ATS between
820 * the SCTP connection establishment and this function execution, so let's flush those copies. */
821 f_M3UA_flush(idx, tr_M3UA_ASPUP(aspid));
Harald Welte829dac42019-11-05 16:55:30 +0100822 f_M3UA_send(idx, ts_M3UA_ASPUP_ACK);
823}
824
825/* expect/perform an inbound ASP-ACTIVATE procedure */
826friend function f_M3UA_CLNT_asp_act(integer idx, template M3UA_Traffic_Mode_Type tmt := omit,
827 template (omit) OCT4 rctx := omit) runs on RAW_M3UA_CT {
828 f_M3UA_exp(idx, tr_M3UA_ASPAC(tmt, rctx));
829 f_M3UA_send(idx, ts_M3UA_ASPAC_ACK(tmt, rctx));
830}
831
832/* expect/perform inbound ASP-UP and ASP-ACT, optionally send interemittent NOTIFY */
833friend function f_M3UA_CLNT_asp_up_act(integer idx, template M3UA_Traffic_Mode_Type tmt := omit,
834 template OCT4 rctx := omit,
835 template (omit) OCT2 ntfy_after_up := c_M3UA_ST_I_AS_INACTIVE,
836 template (omit) OCT2 ntfy_after_act := c_M3UA_ST_I_AS_ACTIVE)
837runs on RAW_M3UA_CT {
838 f_M3UA_CLNT_asp_up(idx, omit);
839 if (not istemplatekind(ntfy_after_up, "omit")) {
840 f_M3UA_send(idx, ts_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, ntfy_after_up, rctx));
841 }
842 f_M3UA_CLNT_asp_act(idx, tmt, rctx);
843 if (not istemplatekind(ntfy_after_act, "omit")) {
844 f_M3UA_send(idx, ts_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, ntfy_after_act, rctx));
845 }
846}
847
848
849/* Expect inbound connection from ASP/SCTP-client, followed by ASP-UP */
850testcase TC_clnt_connect_asp_up() runs on RAW_M3UA_CT {
851 f_init_m3ua();
852 f_init_m3ua_srv();
853
854 f_M3UA_CLNT_asp_up(M3UA_SRV(0));
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100855
856 f_clear_m3ua();
Harald Welte829dac42019-11-05 16:55:30 +0100857}
858
859/* Expect inbound connection from ASP/SCTP-client, followed by ASP-UP + ASP-ACT */
860testcase TC_clnt_asp_act() runs on RAW_M3UA_CT {
861 f_init_m3ua();
862 f_init_m3ua_srv();
863
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700864 var OCT4 rctx := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
865 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100866
867 f_clear_m3ua();
Harald Welte829dac42019-11-05 16:55:30 +0100868}
869
Harald Welte53050cd2019-12-01 20:49:01 +0100870/* Expect inbound connection from ASP/SCTP-client, followed by ASP-UP + ASP-ACT */
871testcase TC_clnt_asp_act_tmt_loadshare() runs on RAW_M3UA_CT {
872 f_init_common();
873 f_vty_config2(VTY, {"cs7 instance 0", "as as-client m3ua"}, "traffic-mode loadshare");
874 f_init_m3ua();
875 f_init_m3ua_srv();
876
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700877 var OCT4 rctx := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
878 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), tmt := c_M3UA_TMT_loadshare, rctx := rctx);
Harald Welte53050cd2019-12-01 20:49:01 +0100879
880 f_clear_m3ua();
881}
882
Harald Welte829dac42019-11-05 16:55:30 +0100883/* Test traffic being routed through "server" side STP (M3UA SG), coming back in "client"
884 * side STP (M3UA ASP) */
885testcase TC_clnt_sg_to_asp() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700886 var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
887 var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
888 var OCT4 rctx_receiver := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
889 var OCT4 pc_receiver := int2oct(f_m3ua_srv_config(0).point_code, 4);
Harald Welte829dac42019-11-05 16:55:30 +0100890
891 f_init_m3ua();
892 f_M3UA_asp_up_act(0);
893
894 f_init_m3ua_srv();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700895 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx_receiver);
Harald Welte829dac42019-11-05 16:55:30 +0100896
897 f_sleep(1.0);
898
899 /* verify traffic is routed from sender to [sole] receiver */
900 f_test_traffic(0, rctx_sender, pc_sender, M3UA_SRV(0), rctx_receiver, pc_receiver);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100901
902 f_clear_m3ua();
Harald Welte829dac42019-11-05 16:55:30 +0100903}
904
905/* Test traffic being routed through "client" side STP (M3UA ASP), coming back in "server"
906 * side STP (M3UA SG) */
907testcase TC_clnt_asp_to_sg() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700908 var OCT4 rctx_sender := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
909 var OCT4 pc_sender := int2oct(f_m3ua_srv_config(0).point_code, 4);
910 var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
911 var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(0).point_code, 4);
Harald Welte829dac42019-11-05 16:55:30 +0100912
913 f_init_m3ua();
914 f_M3UA_asp_up_act(0);
915
916 f_init_m3ua_srv();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700917 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx_sender);
Harald Welte829dac42019-11-05 16:55:30 +0100918
919 f_sleep(1.0);
920
921 /* verify traffic is routed from sender to [sole] receiver */
922 f_test_traffic(M3UA_SRV(0), rctx_sender, pc_sender, 0, rctx_receiver, pc_receiver);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100923 f_clear_m3ua();
Harald Welte829dac42019-11-05 16:55:30 +0100924}
925
Harald Welte6baf5e72023-04-15 20:30:52 +0800926/* Test traffic being routed through "server" side STP (M3UA SG), coming back in "client"
927 * side STP (M3UA ASP) which has no routing context set */
928testcase TC_clnt_sg_to_asp_norctx() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700929 var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
930 var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
931 var OCT4 pc_receiver := int2oct(f_m3ua_srv_config(1).point_code, 4);
932 var OCT4 pc_receiver2 := int2oct(f_m3ua_srv_config(2).point_code, 4);
Harald Welte6baf5e72023-04-15 20:30:52 +0800933
934 /* activate the sender side (ATS is client to STP in SG role) */
935 f_init_m3ua();
936 f_M3UA_asp_up_act(0);
937
938 /* activate the receiver side (ATS is server to STP in ASP role) */
939 f_init_m3ua_srv();
940 f_M3UA_CLNT_asp_up_act(M3UA_SRV(1), rctx := omit);
941 /* activate another instance of STP in ASP role with no routing context */
942 f_M3UA_CLNT_asp_up_act(M3UA_SRV(2), rctx := omit);
943
944 f_sleep(1.0);
945
946 /* verify traffic is routed from sender to [sole] receiver for each PC */
947 f_test_traffic(0, rctx_sender, pc_sender, M3UA_SRV(1), omit, pc_receiver);
948 f_test_traffic(0, rctx_sender, pc_sender, M3UA_SRV(2), omit, pc_receiver2);
949
950 f_clear_m3ua();
951}
952
953/* Test traffic being routed through "server" side STP (M3UA SG), coming back in "client"
954 * side STP (M3UA ASP) which has no routing context set */
955testcase TC_clnt_asp_to_sg_norctx() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700956 var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
957 var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(0).point_code, 4);
958 var OCT4 pc_sender := int2oct(f_m3ua_srv_config(1).point_code, 4);
959 var OCT4 pc_sender2 := int2oct(f_m3ua_srv_config(2).point_code, 4);
Harald Welte6baf5e72023-04-15 20:30:52 +0800960
961 /* activate the sender side (ATS is client to STP in SG role) */
962 f_init_m3ua();
963 f_M3UA_asp_up_act(0);
964
965 /* activate the receiver side (ATS is server to STP in ASP role) */
966 f_init_m3ua_srv();
967 f_M3UA_CLNT_asp_up_act(M3UA_SRV(1), rctx := omit);
968 /* activate another instance of STP in ASP role with no routing context */
969 f_M3UA_CLNT_asp_up_act(M3UA_SRV(2), rctx := omit);
970
971 f_sleep(1.0);
972
973 /* verify traffic is routed from sender to [sole] receiver for each PC */
974 f_test_traffic(M3UA_SRV(1), omit, pc_sender, 0, rctx_receiver, pc_receiver);
975 f_test_traffic(M3UA_SRV(2), omit, pc_sender2, 0, rctx_receiver, pc_receiver);
976
977 f_clear_m3ua();
978}
979
Harald Welte27cfb7a2021-02-08 09:58:28 +0100980/* Test if ASPAC / ASPIA of one ASP generates DAVA / DUNA on other ASP */
981testcase TC_ssnm_aspac_dava_aspia_duna() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700982 var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
983 var integer pc0 := f_m3ua_cli_config(1).point_code;
Harald Welte27cfb7a2021-02-08 09:58:28 +0100984
985 f_init_m3ua(ignore_ssnm := false);
986 /* activate the first ASP */
987 f_M3UA_asp_up_act(0);
988
989 /* activate the second ASP */
990 f_M3UA_asp_up_act(1, c_M3UA_TMT_override, omit);
991 /* expect DAVA for PC of second ASP on first ASP */
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700992 f_M3UA_exp(0, tr_M3UA_DAVA({ts_M3UA_PC(pc0, 0)}, rctx0));
Harald Welte27cfb7a2021-02-08 09:58:28 +0100993 /* TODO: expect no DAVA on second ASP */
994
995 /* deactivate the second ASP */
996 f_M3UA_asp_inact(1);
997 /* expect DUNA for PC of second ASP on first ASP */
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700998 f_M3UA_exp(0, tr_M3UA_DUNA({ts_M3UA_PC(pc0, 0)}, rctx0));
Harald Welte27cfb7a2021-02-08 09:58:28 +0100999 /* TODO: expect no DUNA on second ASP */
1000
1001 f_clear_m3ua();
1002}
1003
1004/* Test if DAVA/DUNA sent from SG to ASP-role STP gets forwarded to other ASP */
1005testcase TC_ssnm_distribution_dava_duna() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001006 var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
1007 var OCT4 rctxS0 := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001008 /* some random point code whose availability we advertise */
1009 var template (value) M3UA_Point_Code adv_pc := ts_M3UA_PC(1234, 0);
1010
1011 f_init_m3ua(ignore_ssnm := false);
1012
1013 /* activate the first ASP */
1014 f_M3UA_asp_up_act(0);
1015
1016 /* activate SG-role ASP (ASP on STP) */
1017 f_init_m3ua_srv();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001018 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctxS0);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001019
1020 /* transmit a DAVA to the remote ASP */
1021 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAVA({adv_pc}, rctxS0));
1022 /* expect that to show up on other ASP */
1023 f_M3UA_exp(0, tr_M3UA_DAVA({adv_pc}, rctx0));
1024
1025 /* transmit a DUNA to the remote ASP */
1026 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DUNA({adv_pc}, rctxS0));
1027 /* expect that to show up on other ASP */
1028 f_M3UA_exp(0, tr_M3UA_DUNA({adv_pc}, rctx0));
1029}
1030
1031/* Test if DAVA/DUNA sent from SG to ASP-role STP gets forwarded to other ASP */
1032testcase TC_ssnm_distribution_dava_duna_multipc() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001033 var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
1034 var OCT4 rctxS0 := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001035 /* some random point code whose availability we advertise */
1036 var template (value) M3UA_Point_Codes adv_pcs := { ts_M3UA_PC(1234, 0), ts_M3UA_PC(5678, 0) };
1037
1038 f_init_m3ua(ignore_ssnm := false);
1039
1040 /* activate the first ASP */
1041 f_M3UA_asp_up_act(0);
1042
1043 /* activate SG-role ASP (ASP on STP) */
1044 f_init_m3ua_srv();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001045 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctxS0);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001046
1047 /* transmit a DAVA to the remote ASP */
1048 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAVA(adv_pcs, rctxS0));
1049 /* expect that to show up on other ASP */
1050 f_M3UA_exp(0, tr_M3UA_DAVA(adv_pcs, rctx0));
1051
1052 /* transmit a DUNA to the remote ASP */
1053 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DUNA(adv_pcs, rctxS0));
1054 /* expect that to show up on other ASP */
1055 f_M3UA_exp(0, tr_M3UA_DUNA(adv_pcs, rctx0));
1056}
1057
1058/* Test if DUPU sent from SG to ASP-role STP gets forwarded to other ASP */
1059testcase TC_ssnm_distribution_dupu() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001060 var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
1061 var OCT4 rctxS0 := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001062 /* some random point code whose availability we advertise */
1063 var template (value) M3UA_Point_Code adv_pc := ts_M3UA_PC(1234, 0);
1064
1065 f_init_m3ua(ignore_ssnm := false);
1066
1067 /* activate the first ASP */
1068 f_M3UA_asp_up_act(0);
1069
1070 /* activate SG-role ASP (ASP on STP) */
1071 f_init_m3ua_srv();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001072 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctxS0);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001073
1074 /* transmit a DUPU to the remote ASP */
1075 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DUPU({adv_pc}, '0102'O, 'ABCD'O, rctxS0));
1076 /* expect that to show up on other ASP */
1077 f_M3UA_exp(0, tr_M3UA_DUPU({adv_pc}, '0102'O, 'ABCD'O, rctx0));
1078}
1079
1080/* Test if SCON sent from SG to ASP-role STP gets forwarded to other ASP */
1081testcase TC_ssnm_distribution_scon() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001082 var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
1083 var OCT4 rctxS0 := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001084 /* some random point code whose availability we advertise */
1085 var template (value) M3UA_Point_Code adv_pc := ts_M3UA_PC(1234, 0);
1086
1087 f_init_m3ua(ignore_ssnm := false);
1088
1089 /* activate the first ASP */
1090 f_M3UA_asp_up_act(0);
1091
1092 /* activate SG-role ASP (ASP on STP) */
1093 f_init_m3ua_srv();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001094 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctxS0);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001095
1096 /* transmit a SCON to the remote ASP */
1097 f_M3UA_send(M3UA_SRV(0), ts_M3UA_SCON({adv_pc}, rctxS0));
1098 /* expect that to show up on other ASP */
1099 f_M3UA_exp(0, tr_M3UA_SCON({adv_pc}, rctx0));
1100}
Harald Welte829dac42019-11-05 16:55:30 +01001101
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +07001102private function f_asp_cfg_str(charstring asp_name, in M3uaConfig cfg)
1103return charstring {
1104 var charstring str;
1105
1106 str := "asp " & asp_name;
1107 str := str & " " & int2str(cfg.local_port);
1108 str := str & " " & int2str(cfg.remote_port);
1109 str := str & " m3ua";
1110
1111 if (cfg.use_tcp) {
1112 str := str & " tcp";
1113 }
1114
1115 return str;
1116}
1117
Harald Welte30cb4002021-05-13 20:51:37 +02001118private function f_quirk(charstring quirk) runs on RAW_M3UA_CT {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +07001119 var charstring asp_cfg_str := f_asp_cfg_str("asp-client0", f_m3ua_srv_config(0));
1120 f_vty_config2(VTY, {"cs7 instance 0", asp_cfg_str}, "quirk " & quirk);
Harald Welte30cb4002021-05-13 20:51:37 +02001121}
1122
1123private function f_no_quirk(charstring quirk) runs on RAW_M3UA_CT {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +07001124 var charstring asp_cfg_str := f_asp_cfg_str("asp-client0", f_m3ua_srv_config(0));
1125 f_vty_config2(VTY, {"cs7 instance 0", asp_cfg_str}, "no quirk " & quirk);
Harald Welte30cb4002021-05-13 20:51:37 +02001126}
1127
1128/* quirk 'no_notify': Expect inbound connection from ASP/SCTP-client, followed by ASP-UP + ASP-ACT */
1129testcase TC_clnt_quirk_no_notify_asp_act() runs on RAW_M3UA_CT {
1130 f_init_m3ua();
1131 f_quirk("no_notify");
1132 f_init_m3ua_srv();
1133
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001134 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 +02001135 ntfy_after_up := omit, ntfy_after_act := omit);
1136 f_no_quirk("no_notify");
1137 f_clear_m3ua();
1138}
1139
Harald Welte5ef25532021-05-13 21:10:25 +02001140/* ensure that DAUD is not supported in ASP role, as required by RFC */
1141testcase TC_clnt_no_daud_in_asp() runs on RAW_M3UA_CT {
1142 f_init_m3ua();
1143 f_no_quirk("daud_in_asp");
1144 f_init_m3ua_srv();
1145
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001146 var OCT4 rctx := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
1147 var integer pc := f_m3ua_srv_config(0).point_code;
Harald Welte5ef25532021-05-13 21:10:25 +02001148
1149 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx);
1150
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001151 var template (value) M3UA_Point_Codes aff_pcs := { ts_M3UA_PC(pc) };
Harald Welte5ef25532021-05-13 21:10:25 +02001152 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAUD(aff_pcs));
1153 f_M3UA_exp(M3UA_SRV(0), tr_M3UA_ERR('00000004'O, omit));
1154 setverdict(pass);
1155
1156 f_clear_m3ua();
1157}
1158
1159/* quirk 'daud_in_asp': allowing inbound DAUD from SG in ASP role */
1160testcase TC_clnt_quirk_daud_in_asp() runs on RAW_M3UA_CT {
1161 f_init_m3ua();
1162 f_quirk("daud_in_asp");
1163 f_init_m3ua_srv();
1164
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001165 var OCT4 rctx := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
1166 var integer pc := f_m3ua_srv_config(0).point_code;
Harald Welte5ef25532021-05-13 21:10:25 +02001167
1168 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx);
1169
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001170 var template (value) M3UA_Point_Codes aff_pcs := { ts_M3UA_PC(pc) };
Harald Welte5ef25532021-05-13 21:10:25 +02001171 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAUD(aff_pcs));
1172 f_M3UA_exp(M3UA_SRV(0), tr_M3UA_DAVA(aff_pcs));
1173 setverdict(pass);
1174
1175 f_no_quirk("daud_in_asp");
1176 f_clear_m3ua();
1177}
Harald Welte0db44132019-10-17 11:09:05 +02001178
Harald Welte261aea72021-05-13 21:23:29 +02001179/* Expect a normal ASP to reject any [S]SNM messages in ASP-INACTIVE state */
1180testcase TC_clnt_no_snm_inactive() runs on RAW_M3UA_CT {
1181 f_init_m3ua();
1182 f_quirk("no_notify");
1183 f_quirk("daud_in_asp");
1184 f_no_quirk("snm_inactive");
1185 f_init_m3ua_srv();
1186
1187 /* bring ASP only UP (into INACTIVE state), but not ACTIVE! */
1188 f_M3UA_CLNT_asp_up(M3UA_SRV(0));
1189 f_M3UA_exp(M3UA_SRV(0), tr_M3UA_ASPAC(*, *));
1190
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001191 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 +02001192 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAUD(aff_pcs));
1193 f_M3UA_exp(M3UA_SRV(0), tr_M3UA_ERR('00000006'O, omit));
1194 setverdict(pass);
1195
1196 f_no_quirk("no_notify");
1197 f_no_quirk("daud_in_asp");
1198 f_clear_m3ua();
1199}
1200
1201/* quirk 'snm_inactive': Process [S]SNM in ASP-INACTIVE state */
1202testcase TC_clnt_quirk_snm_inactive() runs on RAW_M3UA_CT {
1203 f_init_m3ua();
1204 f_quirk("no_notify");
1205 f_quirk("daud_in_asp");
1206 f_quirk("snm_inactive");
1207 f_init_m3ua_srv();
1208
1209 /* bring ASP only UP (into INACTIVE state), but not ACTIVE! */
1210 f_M3UA_CLNT_asp_up(M3UA_SRV(0));
1211 f_M3UA_exp(M3UA_SRV(0), tr_M3UA_ASPAC(*, *));
1212
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001213 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 +02001214 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAUD(aff_pcs));
1215 f_M3UA_exp(M3UA_SRV(0), tr_M3UA_DAVA(aff_pcs));
1216 setverdict(pass);
1217
1218 f_no_quirk("no_notify");
1219 f_no_quirk("daud_in_asp");
1220 f_no_quirk("snm_inactive");
1221 f_clear_m3ua();
1222}
1223
Vadim Yanitskiy88f429d2024-03-04 02:03:52 +07001224private function f_TC_m3ua_tcp(integer idx_a, integer idx_b) runs on RAW_M3UA_CT {
1225 var M3uaConfig cfg_a := mp_m3ua_configs[idx_a];
1226 var M3uaConfig cfg_b := mp_m3ua_configs[idx_b];
1227 var OCT4 rctx_a := int2oct(cfg_a.routing_ctx, 4);
1228 var OCT4 rctx_b := int2oct(cfg_b.routing_ctx, 4);
1229 var OCT4 pc_a := int2oct(cfg_a.point_code, 4);
1230 var OCT4 pc_b := int2oct(cfg_b.point_code, 4);
1231
1232 /* establish connection with ASP 'A' */
1233 if (idx_a < NR_M3UA) {
1234 f_M3UA_asp_up_act(idx_a, rctx := rctx_a);
1235 } else {
1236 f_M3UA_CLNT_asp_up_act(idx_a, rctx := rctx_a);
1237 }
1238
1239 /* establish connection with ASP 'B' */
1240 if (idx_b < NR_M3UA) {
1241 f_M3UA_asp_up_act(idx_b, rctx := rctx_b);
1242 } else {
1243 f_M3UA_CLNT_asp_up_act(idx_b, rctx := rctx_b);
1244 }
1245
1246 /* In the case when ASP[idx_b] is configured as the client (i.e. osmo-stp connects to
1247 * the testsuite; idx_b >= NR_M3UA), in f_M3UA_CLNT_asp_up_act() we're expecting to
1248 * receive ASPACT and then sending ASPACT_ACK to it. Right after that, we're sending
1249 * some random data via ASP[idx_a], which we then expect to receive via ASP[idx_b].
1250 *
1251 * There is a chance that the random data sent via ASP[idx_a] would reach osmo-stp
1252 * earlier than the ASPUP_ACK we sent for ASP[idx_b]. This is happening most of the
1253 * times when running TC_m3ua_tcp_cli_srv. Using f_sleep() helps to avoid this. */
1254 f_sleep(1.0);
1255
1256 /* M3UA/A -> M3UA/B */
1257 f_test_traffic(idx_a, rctx_a, pc_a,
1258 idx_b, rctx_b, pc_b);
1259 /* M3UA/B -> M3UA/A */
1260 f_test_traffic(idx_b, rctx_b, pc_b,
1261 idx_a, rctx_a, pc_a);
1262
1263 f_clear_m3ua();
1264}
1265
1266/* test routing between M3UA/SCTP (client) and M3UA/TCP (client) */
1267testcase TC_m3ua_tcp_cli() runs on RAW_M3UA_CT {
1268 f_init_m3ua();
1269 f_TC_m3ua_tcp(0, 3); /* 'asp-sender' <-> 'asp-sender-tcp' */
1270}
1271
1272/* test routing between M3UA/SCTP (client) and M3UA/TCP (server) */
1273testcase TC_m3ua_tcp_cli_srv() runs on RAW_M3UA_CT {
1274 f_init_m3ua();
1275 f_init_m3ua_srv();
1276 f_TC_m3ua_tcp(0, M3UA_SRV(3)); /* 'asp-sender' <-> 'asp-client-tcp' */
1277}
1278
1279/* test routing between M3UA/SCTP (server) and M3UA/TCP (server) */
1280testcase TC_m3ua_tcp_srv() runs on RAW_M3UA_CT {
1281 f_init_m3ua();
1282 f_init_m3ua_srv();
1283 f_TC_m3ua_tcp(M3UA_SRV(0), M3UA_SRV(3)); /* 'asp-client' <-> 'asp-client-tcp' */
1284}
1285
1286/* test routing between M3UA/SCTP (server) and M3UA/TCP (client) */
1287testcase TC_m3ua_tcp_srv_cli() runs on RAW_M3UA_CT {
1288 f_init_m3ua();
1289 f_init_m3ua_srv();
1290 f_TC_m3ua_tcp(M3UA_SRV(0), 3); /* 'asp-client' <-> 'asp-sender-tcp' */
1291}
1292
Harald Welte261aea72021-05-13 21:23:29 +02001293
Harald Welte0db44132019-10-17 11:09:05 +02001294control {
1295 /* M3UA Tests */
1296 execute( TC_connect_asp_up() );
1297 execute( TC_beat() );
1298 execute( TC_beat_payload() );
1299 execute( TC_asp_act() );
1300 execute( TC_asp_act_override() );
1301 execute( TC_asp_act_loadshare() );
1302 execute( TC_asp_act_broadcast() );
1303 execute( TC_tmt_override() );
1304 execute( TC_tmt_loadshare() );
1305 execute( TC_tmt_broadcast() );
Harald Welte15a85012020-06-13 16:35:45 +02001306 execute( TC_act_rctx_data_no_rctx() );
Harald Welte0db44132019-10-17 11:09:05 +02001307
Vadim Yanitskiy88f429d2024-03-04 02:03:52 +07001308 execute( TC_m3ua_tcp_cli() );
1309 execute( TC_m3ua_tcp_cli_srv() );
1310 execute( TC_m3ua_tcp_srv() );
1311 execute( TC_m3ua_tcp_srv_cli() );
1312
Harald Welte0db44132019-10-17 11:09:05 +02001313 /* M3UA RKM tests */
1314 execute( TC_rkm_reg_static_notpermitted() );
1315 execute( TC_rkm_reg_static_permitted() );
1316 execute( TC_rkm_reg_dynamic_permitted() );
Pau Espin Pedrol6b1b0ff2021-11-16 19:24:53 +01001317 execute( TC_rkm_unreg_never_registered() );
1318
Harald Welte0db44132019-10-17 11:09:05 +02001319 execute( TC_rkm_unreg_invalid() );
1320 execute( TC_rkm_unreg_registered() );
1321 execute( TC_rkm_unreg_active() );
1322 /* TODO: test RKM with unsupported routing keys: NA, SI, OPC */
1323 /* TODO: register/unregister multiple routing contexts in one message; including mixed
1324 success/failure situations */
Harald Welte829dac42019-11-05 16:55:30 +01001325
1326 /* Test STP as SCTP client + M3UA ASP role */
1327 execute( TC_clnt_connect_asp_up() );
1328 execute( TC_clnt_asp_act() );
1329 execute( TC_clnt_sg_to_asp() );
1330 execute( TC_clnt_asp_to_sg() );
Harald Welte53050cd2019-12-01 20:49:01 +01001331
Harald Welte6baf5e72023-04-15 20:30:52 +08001332 execute( TC_clnt_sg_to_asp_norctx() );
1333 execute( TC_clnt_asp_to_sg_norctx() );
1334
Pau Espin Pedrol6b1b0ff2021-11-16 19:24:53 +01001335 execute( TC_clnt_quirk_no_notify_asp_act() );
1336 execute( TC_clnt_no_daud_in_asp() );
1337 execute( TC_clnt_quirk_daud_in_asp() );
1338 execute( TC_clnt_no_snm_inactive() );
1339 execute( TC_clnt_quirk_snm_inactive() );
1340
Harald Welte30cb4002021-05-13 20:51:37 +02001341
Harald Welte27cfb7a2021-02-08 09:58:28 +01001342 /* M3UA SSNM tests */
1343 execute( TC_ssnm_aspac_dava_aspia_duna() );
1344 execute( TC_ssnm_distribution_dava_duna() );
1345 execute( TC_ssnm_distribution_dava_duna_multipc() );
1346 execute( TC_ssnm_distribution_dupu() );
1347 execute( TC_ssnm_distribution_scon() );
1348
Harald Welte53050cd2019-12-01 20:49:01 +01001349 /* put this one last as it changes the stp side config */
1350 execute( TC_clnt_asp_act_tmt_loadshare() );
Harald Welte0db44132019-10-17 11:09:05 +02001351}
1352
1353
1354
1355}