blob: 96cd2681fdbb343fcd10ce99763da763e2b85705 [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
329 if (lengthof(mp_local_m3ua_ip) == 0 ) {
330 setverdict(fail, "Empty local address trying to bind SCTP socket: ",
331 mp_local_m3ua_ip);
332 mtc.stop;
333 }
334
335 if (lengthof(mp_local_m3ua_ip) > 1) {
336 opt_add_local_addrs.sctpAdditionalLocalAddresses := substr(mp_local_m3ua_ip, 1,
337 lengthof(mp_local_m3ua_ip) - 1); //{mp_local_m3ua_ip};
338 opt_list := {opt_add_local_addrs};
339 }
340
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700341 if (mp_m3ua_configs[i].use_tcp) {
342 res := M3UA_CodecPort_CtrlFunct.f_IPL4_listen(M3UA[i], mp_local_m3ua_ip[0], m3cfg.local_port,
343 {tcp:={}});
344 } else {
345 res := M3UA_CodecPort_CtrlFunct.f_IPL4_listen(M3UA[i], mp_local_m3ua_ip[0], m3cfg.local_port,
346 {sctp:=valueof(ts_SCTP)}, opt_list);
347 }
Harald Welte829dac42019-11-05 16:55:30 +0100348 if (not ispresent(res.connId)) {
349 setverdict(fail, "Could not bind M3UA socket, check your configuration");
Pau Espin Pedrolb51c0872020-08-21 13:42:30 +0200350 mtc.stop;
Harald Welte829dac42019-11-05 16:55:30 +0100351 }
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700352 if (mp_m3ua_configs[i].use_tcp) {
353 M3UA_CodecPort.f_set_tcp_segmentation(M3UA[i], res.connId);
354 }
Harald Welte829dac42019-11-05 16:55:30 +0100355}
356
Harald Welte27cfb7a2021-02-08 09:58:28 +0100357friend function f_init_m3ua(boolean ignore_ssnm := true) runs on RAW_M3UA_CT {
Harald Welte0db44132019-10-17 11:09:05 +0200358 var integer i;
359
360 f_init_common();
361
362 activate(as_m3ua_sctp());
Harald Welte27cfb7a2021-02-08 09:58:28 +0100363 if (ignore_ssnm) {
364 activate(as_m3ua_ssnm_ignore());
365 }
Harald Welte0db44132019-10-17 11:09:05 +0200366
367 for (i := 0; i < NR_M3UA; i:=i+1) {
368 map(self:M3UA[i], system:M3UA_CODEC_PT);
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700369 if (mp_m3ua_configs[i].use_tcp) {
370 f_M3UA_connect_tcp(i);
371 } else {
372 f_M3UA_connect_sctp(i);
373 }
Harald Welte0db44132019-10-17 11:09:05 +0200374 }
375}
376
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100377friend function f_clear_m3ua() runs on RAW_M3UA_CT {
378 var integer i;
379
380 log("Clearing M3UA...");
381
382 for (i := 0; i < NR_M3UA; i:=i+1) {
383 f_M3UA_close(i);
384 }
385 /* Wait for recovery timer to trigger and shutdown all AS: */
386 f_sleep(int2float(mp_recovery_timeout_msec)/1000.0 + 0.5);
387 setverdict(pass, "M3UA cleared");
388}
389
Harald Welte829dac42019-11-05 16:55:30 +0100390friend function f_init_m3ua_srv() runs on RAW_M3UA_CT {
391 var integer i;
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700392 var PortEvent port_evt;
Harald Welte829dac42019-11-05 16:55:30 +0100393
394 for (i := NR_M3UA; i < NR_M3UA+NR_M3UA_SRV; i:=i+1) {
395 map(self:M3UA[i], system:M3UA_CODEC_PT);
396 /* bind+ listen */
397 f_M3UA_listen(i);
398 /* wait for accept() */
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700399 M3UA[i].receive(tr_ConnOpened) -> value port_evt {
400 g_m3ua_conn_id[i] := port_evt.connOpened.connId;
Harald Welte829dac42019-11-05 16:55:30 +0100401 }
402 }
403}
404
405
406/***********************************************************************
407 * Test the STP in M3UA SG role (we are ASP)
408 ***********************************************************************/
409
Harald Welte0db44132019-10-17 11:09:05 +0200410/* perform an outbound ASP-UP procedure */
411friend function f_M3UA_asp_up(integer idx, template (omit) OCT4 aspid := omit) runs on RAW_M3UA_CT {
412 f_M3UA_send(idx, ts_M3UA_ASPUP(aspid));
413 f_M3UA_exp(idx, tr_M3UA_ASPUP_ACK);
414}
415
416/* perform an outbound BEAT procedure */
417friend function f_M3UA_beat(integer idx, template (omit) octetstring hbd) runs on RAW_M3UA_CT {
418 if (istemplatekind(hbd, "omit")) {
419 f_M3UA_send(idx, ts_M3UA_BEAT(omit));
420 f_M3UA_exp(idx, tr_M3UA_BEAT_ACK(omit));
421 } else {
422 f_M3UA_send(idx, ts_M3UA_BEAT(ts_M3UA_hb_data(hbd)));
423 f_M3UA_exp(idx, tr_M3UA_BEAT_ACK(tr_M3UA_hb_data(hbd)));
424 }
425}
426
427/* perform an outbound ASP-ACTIVATE procedure */
428friend function f_M3UA_asp_act(integer idx, template (omit) M3UA_Traffic_Mode_Type tmt := omit,
429 template (omit) OCT4 rctx := omit) runs on RAW_M3UA_CT {
430 f_M3UA_send(idx, ts_M3UA_ASPAC(tmt, rctx));
431 f_M3UA_exp(idx, tr_M3UA_ASPAC_ACK(tmt, rctx));
432}
433
Harald Welte27cfb7a2021-02-08 09:58:28 +0100434/* perform an outbound ASP-INACTIVATE procedure */
435friend function f_M3UA_asp_inact(integer idx, template (omit) OCT4 rctx := omit) runs on RAW_M3UA_CT {
436 f_M3UA_send(idx, ts_M3UA_ASPIA(rctx));
437 f_M3UA_exp(idx, tr_M3UA_ASPIA_ACK(rctx));
438}
439
Harald Welte0db44132019-10-17 11:09:05 +0200440/* perform outbound ASP-UP and ASP-ACT, optionally expect interemittent NOTIFY */
441friend function f_M3UA_asp_up_act(integer idx, template (omit) M3UA_Traffic_Mode_Type tmt := omit,
442 template (omit) OCT4 rctx := omit,
443 template (omit) OCT2 ntfy_after_up := c_M3UA_ST_I_AS_INACTIVE,
444 template (omit) OCT2 ntfy_after_act := c_M3UA_ST_I_AS_ACTIVE)
445runs on RAW_M3UA_CT {
446 f_M3UA_asp_up(idx, omit);
447 if (not istemplatekind(ntfy_after_up, "omit")) {
448 f_M3UA_exp(idx, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, ntfy_after_up, *));
449 }
450 f_M3UA_asp_act(idx, tmt, rctx);
451 if (not istemplatekind(ntfy_after_act, "omit")) {
452 f_M3UA_exp(idx, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, ntfy_after_act, *));
453 }
454}
455
456
457/* Test the ASP-UP procedure */
458testcase TC_connect_asp_up() runs on RAW_M3UA_CT {
459 f_init_m3ua();
460 f_M3UA_asp_up(0);
461 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 +0100462 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200463}
464
465/* Test the heartbeat procedure without optional heartbeat data payload */
466testcase TC_beat() runs on RAW_M3UA_CT {
467 f_init_m3ua();
468 f_M3UA_asp_up(0);
469 f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_INACTIVE, *));
470 f_M3UA_beat(0, omit);
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 with optional heartbeat data payload */
475testcase TC_beat_payload() 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, 'a1a2a3a4a5'O);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100480 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200481}
482
483/* Test the ASP-ACTIVATE procedure (without traffic-mode or routing ctx) */
484testcase TC_asp_act() runs on RAW_M3UA_CT {
485 f_init_m3ua();
486 f_M3UA_asp_up_act(0);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100487 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200488}
489
490/* Test the ASP-ACTIVATE procedure with traffic-mode override */
491testcase TC_asp_act_override() runs on RAW_M3UA_CT {
492 f_init_m3ua();
493 f_M3UA_asp_up_act(0, c_M3UA_TMT_override, omit);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100494 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200495}
496
497/* Test the ASP-ACTIVATE procedure with traffic-mode override */
498testcase TC_asp_act_loadshare() runs on RAW_M3UA_CT {
499 f_init_m3ua();
500 f_M3UA_asp_up_act(0, c_M3UA_TMT_loadshare, omit);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100501 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200502}
503
504/* Test the ASP-ACTIVATE procedure with traffic-mode broadcast */
505testcase TC_asp_act_broadcast() runs on RAW_M3UA_CT {
506 f_init_m3ua();
507 f_M3UA_asp_up_act(0, c_M3UA_TMT_broadcast, omit);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100508 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200509}
510
Harald Welte15a85012020-06-13 16:35:45 +0200511/* test whether the STP accepts M3UA DATA without Routing Context IE */
512testcase TC_act_rctx_data_no_rctx() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700513 var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
514 var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
515 var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(1).routing_ctx, 4);
516 var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(1).point_code, 4);
Harald Welte15a85012020-06-13 16:35:45 +0200517
518 f_init_m3ua();
519 /* bring up the sender specifying a routing context */
520
521 f_M3UA_asp_up_act(0, rctx := rctx_sender);
522 f_M3UA_asp_up_act(1);
523
524 /* check if DATA is accepted without Routing Context IE */
525 f_test_traffic(0, omit, pc_sender, 1, rctx_receiver, pc_receiver);
526
527 f_clear_m3ua();
528}
529
Harald Welte0db44132019-10-17 11:09:05 +0200530/* Test if traffic is routed from idx_tx/pc_tx to idx_rx/pc_rx */
531private function f_test_traffic(integer idx_tx, template (omit) OCT4 rctx_sender, OCT4 pc_tx,
532 integer idx_rx, template (omit) OCT4 rctx_receiver, OCT4 pc_rx,
533 OCT1 si := '23'O, OCT1 ni := '00'O, OCT1 mp := '00'O, OCT1 sls := '00'O)
534runs on RAW_M3UA_CT {
Harald Welte67881ae2022-04-12 22:52:47 +0200535 var octetstring data := f_rnd_octstring_rnd_len(100);
Harald Welte0db44132019-10-17 11:09:05 +0200536 f_M3UA_send(idx_tx, ts_M3UA_DATA(rctx_sender,
537 ts_M3UA_protocol_data(pc_tx, pc_rx, si, ni, mp, sls, data)), 1);
538 f_M3UA_exp(idx_rx, tr_M3UA_DATA(rctx_receiver,
539 tr_M3UA_protocol_data(pc_tx, pc_rx, si, ni, mp, sls, data)));
540}
541
542
543/* test "traffic-mode override" behavior */
544testcase TC_tmt_override() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700545 var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
546 var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
547 var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(1).routing_ctx, 4);
548 var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(1).point_code, 4);
Harald Welte0db44132019-10-17 11:09:05 +0200549
550 f_init_m3ua();
551
552 /* bring up the 'sender' side (single ASP in AS) */
553 f_M3UA_asp_up_act(0, omit, omit);
554
555 /* activate the first 'receiver' side ASP */
556 f_M3UA_asp_up_act(1, c_M3UA_TMT_override, rctx_receiver);
557
558 /* verify traffic is routed from sender to [sole] receiver */
559 f_test_traffic(0, rctx_sender, pc_sender, 1, rctx_receiver, pc_receiver);
560
561 /* activate the second 'receiver' side ASP (no NOTIFY as AS state doesn't change) */
562 f_M3UA_asp_up_act(2, c_M3UA_TMT_override, rctx_receiver, omit, omit);
563
564 /* we expect a NOTIFY to the *other* ASP Other/Alternat-ASP-Active */
565 f_M3UA_exp(1, tr_M3UA_NOTIFY(c_M3UA_ST_T_OTHER, c_M3UA_ST_I_ALTERNATE_ASP, *));
566
567 /* verify traffic is routed from sender to new receiver */
568 f_test_traffic(0, rctx_sender, pc_sender, 2, rctx_receiver, pc_receiver);
569
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100570 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200571}
572
573private altstep as_count_rx(integer idx, template (present) PDU_M3UA exp, inout integer counter)
574runs on RAW_M3UA_CT {
575 [] M3UA[idx].receive(t_M3UA_RecvFrom(exp)) {
576 counter := counter + 1;
577 }
578}
579
580/* test "traffic-mode load-share" behavior */
581testcase TC_tmt_loadshare() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700582 var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
583 var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
584 var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(1).routing_ctx, 4);
585 var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(1).point_code, 4);
Harald Welte0db44132019-10-17 11:09:05 +0200586 var integer i;
587
588 f_init_m3ua();
589
590 /* FIXME: configure the STP via VTY to set traffic-mode */
591
592 /* bring up the 'sender' side (single ASP in AS) */
593 f_M3UA_asp_up_act(0, omit, rctx_sender);
594
595 /* activate the first 'receiver' side ASP */
Harald Welte0db44132019-10-17 11:09:05 +0200596 f_M3UA_asp_up_act(1, c_M3UA_TMT_loadshare, omit); // TODO: rctx
597
598 /* verify traffic is routed from sender to [sole] receiver */
599 for (i := 0; i < 10; i := i+1) {
600 f_test_traffic(0, rctx_sender, pc_sender, 1, rctx_receiver, pc_receiver);
601 }
602
603 /* activate the second 'receiver' side ASP (no NOTIFY) */
604 f_M3UA_asp_up_act(2, c_M3UA_TMT_loadshare, omit, omit, omit); // TODO: rctx
605
606 /* verify traffic is routed from sender to new receiver */
607 const integer iter_per_asp := 5;
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +0700608 var integer num_rx[NR_M3UA] := { 0, 0, 0, 0 };
Harald Welte0db44132019-10-17 11:09:05 +0200609 for (i := 0; i < 2*iter_per_asp; i := i+1) {
Harald Welte67881ae2022-04-12 22:52:47 +0200610 var octetstring data := f_rnd_octstring_rnd_len(100);
Harald Welte0db44132019-10-17 11:09:05 +0200611 var template (value) M3UA_Protocol_Data tx_pd;
612 var template (present) M3UA_Protocol_Data rx_pd;
613 tx_pd := ts_M3UA_protocol_data(pc_sender, pc_receiver, '23'O, '00'O, '00'O, '00'O, data);
614 rx_pd := tr_M3UA_protocol_data(pc_sender, pc_receiver, '23'O, '00'O, '00'O, '00'O, data);
615 f_M3UA_send(0, ts_M3UA_DATA(rctx_sender, tx_pd), 1);
616 alt {
Pau Espin Pedrol4d915782020-08-21 12:24:35 +0200617 [] as_count_rx(1, tr_M3UA_DATA(rctx_receiver, rx_pd), num_rx[1]);
618 [] as_count_rx(2, tr_M3UA_DATA(rctx_receiver, rx_pd), num_rx[2]);
Harald Welte0db44132019-10-17 11:09:05 +0200619 }
620 }
621 /* FIXME: check for extraneous messages? */
622 for (i := 1; i <= 2; i := i+1) {
623 if (num_rx[i] != iter_per_asp) {
Harald Welteb9f7bbb2019-10-29 09:07:11 +0100624 setverdict(fail, "Received ", num_rx[i], " out of expected ", iter_per_asp,
625 "M3UA DATA messages at M3UA port ", i);
Harald Welte0db44132019-10-17 11:09:05 +0200626 }
627 }
628 setverdict(pass);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100629
630 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200631}
632
633/* test "traffic-mode broadcast" behavior */
634testcase TC_tmt_broadcast() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700635 var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
636 var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
637 var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(1).routing_ctx, 4);
638 var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(1).point_code, 4);
Harald Welte0db44132019-10-17 11:09:05 +0200639 var integer i;
640
641 f_init_m3ua();
642
643 /* FIXME: configure the STP via VTY to set traffic-mode */
644
645 /* bring up the 'sender' side (single ASP in AS) */
646 f_M3UA_asp_up_act(0, omit, omit); // TODO: rctx
647
648 /* activate the first 'receiver' side ASP */
Harald Welte0db44132019-10-17 11:09:05 +0200649 f_M3UA_asp_up_act(1, c_M3UA_TMT_broadcast, omit); // TODO: rctx
650
651 /* verify traffic is routed from sender to [sole] receiver */
652 for (i := 0; i < 10; i := i+1) {
653 f_test_traffic(0, rctx_sender, pc_sender, 1, rctx_receiver, pc_receiver);
654 }
655
656 /* activate the second 'receiver' side ASP */
657 f_M3UA_asp_up_act(2, c_M3UA_TMT_broadcast, omit, omit, omit); // TODO: rctx
658
659 /* verify traffic is routed from sender to new receiver */
660 for (i := 0; i < 10; i := i+1) {
Harald Welte67881ae2022-04-12 22:52:47 +0200661 var octetstring data := f_rnd_octstring_rnd_len(100);
Harald Welte0db44132019-10-17 11:09:05 +0200662 var template (value) M3UA_Protocol_Data tx_pd;
663 var template (present) M3UA_Protocol_Data rx_pd;
664 tx_pd := ts_M3UA_protocol_data(pc_sender, pc_receiver, '23'O, '00'O, '00'O, '00'O, data);
665 rx_pd := tr_M3UA_protocol_data(pc_sender, pc_receiver, '23'O, '00'O, '00'O, '00'O, data);
666 f_M3UA_send(0, ts_M3UA_DATA(rctx_sender, tx_pd), 1);
667 /* each message must be received both on 1 and 2 */
668 f_M3UA_exp(1, tr_M3UA_DATA(rctx_receiver, rx_pd));
669 f_M3UA_exp(2, tr_M3UA_DATA(rctx_receiver, rx_pd));
670 }
671 setverdict(pass);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100672
673 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200674}
675
676private function f_M3UA_rkm_register(OCT4 id, OCT3 dpc, OCT4 rctx,
677 template (present) OCT4 exp_status := c_M3UA_REGSTS_SUCCESS)
678runs on RAW_M3UA_CT
679{
680 f_M3UA_send(0, ts_M3UA_REG_REQ({ts_M3UA_rkey(id:=id, dpc:=dpc, rctx:=rctx)}));
681 f_M3UA_exp(0, tr_M3UA_REG_RSP({tr_M3UA_reg_res(id:=id, status:=exp_status, rctx:=rctx)}));
682}
683
684/* Send RKM registration; expect -EPERM as RCTX doesn't match config and dynamic not permitted */
685testcase TC_rkm_reg_static_notpermitted() runs on RAW_M3UA_CT {
686 f_init_m3ua();
687
688 f_M3UA_send(0, ts_M3UA_REG_REQ({ts_M3UA_rkey(id:='00000099'O, dpc:='aabbcc'O)}));
689 f_M3UA_exp(0, tr_M3UA_REG_RSP({tr_M3UA_reg_res(id:='00000099'O, status:=c_M3UA_REGSTS_ERR_EPERM,
690 rctx:=?)}));
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100691
692 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200693}
694
695/* Send RKM registration; expect OK as RCTX does match config */
696testcase TC_rkm_reg_static_permitted() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700697 var OCT3 dpc := int2oct(f_m3ua_cli_config(0).point_code, 3); // must match config
698 var OCT4 rctx := int2oct(f_m3ua_cli_config(0).routing_ctx, 4); // must match config
Harald Welte0db44132019-10-17 11:09:05 +0200699
700 f_init_m3ua();
701
702 f_M3UA_send(0, ts_M3UA_REG_REQ({ts_M3UA_rkey(id:='10000099'O, dpc:=dpc, rctx:=rctx)}));
703 f_M3UA_exp(0, tr_M3UA_REG_RSP({tr_M3UA_reg_res(id:='10000099'O, status:=c_M3UA_REGSTS_SUCCESS,
704 rctx:=rctx)}));
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100705
706 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200707}
708
709/* Send RKM registration; expect OK as dynamic not permitted */
710testcase TC_rkm_reg_dynamic_permitted() runs on RAW_M3UA_CT {
711 f_init_common();
712 f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation dynamic-permitted");
713 f_init_m3ua();
714
715 f_M3UA_send(0, ts_M3UA_REG_REQ({ts_M3UA_rkey(id:='20000099'O, dpc:='aabbcc'O)}));
716 f_M3UA_exp(0, tr_M3UA_REG_RSP({tr_M3UA_reg_res(id:='20000099'O, status:=c_M3UA_REGSTS_SUCCESS,
717 rctx:=?)}));
718
719 f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation static-only");
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100720
721 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200722}
723
724/* try to de-register a routing key that was never registered -> error */
725testcase TC_rkm_unreg_never_registered() runs on RAW_M3UA_CT {
726 f_init_m3ua();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700727 var octetstring rctx := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
728 f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(rctx)));
Harald Welte0db44132019-10-17 11:09:05 +0200729 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 +0100730 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200731}
732
733/* try to de-register a routing key that is invalid (non-existant) -> error */
734testcase TC_rkm_unreg_invalid() runs on RAW_M3UA_CT {
735 f_init_m3ua();
736 f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(int2oct(1234,4))));
737 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 +0100738 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200739}
740
Oliver Smith326d78e2021-07-23 10:42:10 +0200741/* try to de-register a routing key that was registered -> OK */
Harald Welte0db44132019-10-17 11:09:05 +0200742testcase TC_rkm_unreg_registered() runs on RAW_M3UA_CT {
Oliver Smith326d78e2021-07-23 10:42:10 +0200743 var OCT3 dpc := int2oct(123, 3);
744 var OCT4 rctx := int2oct(1234, 4);
745
746 f_init_common();
747 f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation dynamic-permitted");
Harald Welte0db44132019-10-17 11:09:05 +0200748 f_init_m3ua();
Oliver Smith326d78e2021-07-23 10:42:10 +0200749
750 /* first register the routing key */
751 f_M3UA_rkm_register(id:='30000099'O, dpc:=dpc, rctx:=rctx);
752
753 /* then try to de-register */
754 f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(rctx)));
Harald Welte0db44132019-10-17 11:09:05 +0200755 f_M3UA_exp(0, tr_M3UA_DEREG_RSP({tr_M3UA_dereg_res(?,c_m3UA_DEREGSTS_SUCCESS)}));
Oliver Smith326d78e2021-07-23 10:42:10 +0200756
757 f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation static-only");
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100758 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200759}
760
761/* try to de-register a routing key for an active ASP -> ERROR */
762testcase TC_rkm_unreg_active() runs on RAW_M3UA_CT {
Oliver Smithee022232021-07-23 11:01:06 +0200763 var OCT3 dpc := int2oct(123, 3);
764 var OCT4 rctx := int2oct(1234, 4);
Harald Welte0db44132019-10-17 11:09:05 +0200765
Oliver Smithee022232021-07-23 11:01:06 +0200766 f_init_common();
767 f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation dynamic-permitted");
Harald Welte0db44132019-10-17 11:09:05 +0200768 f_init_m3ua();
769
770 /* first register the routing key */
771 f_M3UA_rkm_register(id:='30000099'O, dpc:=dpc, rctx:=rctx);
772
773 /* then activate the ASP */
774 f_M3UA_asp_up_act(0);
Oliver Smithee022232021-07-23 11:01:06 +0200775 f_M3UA_exp(0, tr_M3UA_DAVA({*}, rctx));
776 f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_ACTIVE, *));
777 f_M3UA_exp(0, tr_M3UA_DAVA({*}, *));
Harald Welte0db44132019-10-17 11:09:05 +0200778
Oliver Smithee022232021-07-23 11:01:06 +0200779 /* then try to de-register -> ERR_ASP_ACTIVE */
Harald Welte0db44132019-10-17 11:09:05 +0200780 f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(rctx)));
781 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 +0100782
Oliver Smithee022232021-07-23 11:01:06 +0200783 /* deactivate ASP and properly de-register to clean up */
784 f_M3UA_asp_inact(0);
785 f_M3UA_send(0, ts_M3UA_DEREG_REQ(ts_M3UA_routing_ctx(rctx)));
786 f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_PENDING, *));
787 f_M3UA_exp(0, tr_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, c_M3UA_ST_I_AS_PENDING, *));
788 f_M3UA_exp(0, tr_M3UA_DEREG_RSP({tr_M3UA_dereg_res(?,c_m3UA_DEREGSTS_SUCCESS)}));
789
790 f_vty_config2(VTY, {"cs7 instance 0"}, "xua rkm routing-key-allocation static-only");
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100791 f_clear_m3ua();
Harald Welte0db44132019-10-17 11:09:05 +0200792}
793
Harald Welte829dac42019-11-05 16:55:30 +0100794/***********************************************************************
795 * Test the STP in M3UA ASP role (we are SG)
796 ***********************************************************************/
797
798/* expect/perform an inbound ASP-UP procedure */
799friend function f_M3UA_CLNT_asp_up(integer idx, template OCT4 aspid := omit) runs on RAW_M3UA_CT {
800 f_M3UA_exp(idx, tr_M3UA_ASPUP(aspid));
Harald Welte3e5f05e2023-04-15 20:02:52 +0800801 /* there might have been multiple re-transmissions that have queued up in the ATS between
802 * the SCTP connection establishment and this function execution, so let's flush those copies. */
803 f_M3UA_flush(idx, tr_M3UA_ASPUP(aspid));
Harald Welte829dac42019-11-05 16:55:30 +0100804 f_M3UA_send(idx, ts_M3UA_ASPUP_ACK);
805}
806
807/* expect/perform an inbound ASP-ACTIVATE procedure */
808friend function f_M3UA_CLNT_asp_act(integer idx, template M3UA_Traffic_Mode_Type tmt := omit,
809 template (omit) OCT4 rctx := omit) runs on RAW_M3UA_CT {
810 f_M3UA_exp(idx, tr_M3UA_ASPAC(tmt, rctx));
811 f_M3UA_send(idx, ts_M3UA_ASPAC_ACK(tmt, rctx));
812}
813
814/* expect/perform inbound ASP-UP and ASP-ACT, optionally send interemittent NOTIFY */
815friend function f_M3UA_CLNT_asp_up_act(integer idx, template M3UA_Traffic_Mode_Type tmt := omit,
816 template OCT4 rctx := omit,
817 template (omit) OCT2 ntfy_after_up := c_M3UA_ST_I_AS_INACTIVE,
818 template (omit) OCT2 ntfy_after_act := c_M3UA_ST_I_AS_ACTIVE)
819runs on RAW_M3UA_CT {
820 f_M3UA_CLNT_asp_up(idx, omit);
821 if (not istemplatekind(ntfy_after_up, "omit")) {
822 f_M3UA_send(idx, ts_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, ntfy_after_up, rctx));
823 }
824 f_M3UA_CLNT_asp_act(idx, tmt, rctx);
825 if (not istemplatekind(ntfy_after_act, "omit")) {
826 f_M3UA_send(idx, ts_M3UA_NOTIFY(c_M3UA_ST_T_STATE_CHG, ntfy_after_act, rctx));
827 }
828}
829
830
831/* Expect inbound connection from ASP/SCTP-client, followed by ASP-UP */
832testcase TC_clnt_connect_asp_up() runs on RAW_M3UA_CT {
833 f_init_m3ua();
834 f_init_m3ua_srv();
835
836 f_M3UA_CLNT_asp_up(M3UA_SRV(0));
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100837
838 f_clear_m3ua();
Harald Welte829dac42019-11-05 16:55:30 +0100839}
840
841/* Expect inbound connection from ASP/SCTP-client, followed by ASP-UP + ASP-ACT */
842testcase TC_clnt_asp_act() runs on RAW_M3UA_CT {
843 f_init_m3ua();
844 f_init_m3ua_srv();
845
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700846 var OCT4 rctx := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
847 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100848
849 f_clear_m3ua();
Harald Welte829dac42019-11-05 16:55:30 +0100850}
851
Harald Welte53050cd2019-12-01 20:49:01 +0100852/* Expect inbound connection from ASP/SCTP-client, followed by ASP-UP + ASP-ACT */
853testcase TC_clnt_asp_act_tmt_loadshare() runs on RAW_M3UA_CT {
854 f_init_common();
855 f_vty_config2(VTY, {"cs7 instance 0", "as as-client m3ua"}, "traffic-mode loadshare");
856 f_init_m3ua();
857 f_init_m3ua_srv();
858
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700859 var OCT4 rctx := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
860 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), tmt := c_M3UA_TMT_loadshare, rctx := rctx);
Harald Welte53050cd2019-12-01 20:49:01 +0100861
862 f_clear_m3ua();
863}
864
Harald Welte829dac42019-11-05 16:55:30 +0100865/* Test traffic being routed through "server" side STP (M3UA SG), coming back in "client"
866 * side STP (M3UA ASP) */
867testcase TC_clnt_sg_to_asp() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700868 var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
869 var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
870 var OCT4 rctx_receiver := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
871 var OCT4 pc_receiver := int2oct(f_m3ua_srv_config(0).point_code, 4);
Harald Welte829dac42019-11-05 16:55:30 +0100872
873 f_init_m3ua();
874 f_M3UA_asp_up_act(0);
875
876 f_init_m3ua_srv();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700877 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx_receiver);
Harald Welte829dac42019-11-05 16:55:30 +0100878
879 f_sleep(1.0);
880
881 /* verify traffic is routed from sender to [sole] receiver */
882 f_test_traffic(0, rctx_sender, pc_sender, M3UA_SRV(0), rctx_receiver, pc_receiver);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100883
884 f_clear_m3ua();
Harald Welte829dac42019-11-05 16:55:30 +0100885}
886
887/* Test traffic being routed through "client" side STP (M3UA ASP), coming back in "server"
888 * side STP (M3UA SG) */
889testcase TC_clnt_asp_to_sg() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700890 var OCT4 rctx_sender := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
891 var OCT4 pc_sender := int2oct(f_m3ua_srv_config(0).point_code, 4);
892 var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
893 var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(0).point_code, 4);
Harald Welte829dac42019-11-05 16:55:30 +0100894
895 f_init_m3ua();
896 f_M3UA_asp_up_act(0);
897
898 f_init_m3ua_srv();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700899 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx_sender);
Harald Welte829dac42019-11-05 16:55:30 +0100900
901 f_sleep(1.0);
902
903 /* verify traffic is routed from sender to [sole] receiver */
904 f_test_traffic(M3UA_SRV(0), rctx_sender, pc_sender, 0, rctx_receiver, pc_receiver);
Pau Espin Pedrol05726dd2019-11-06 15:55:57 +0100905 f_clear_m3ua();
Harald Welte829dac42019-11-05 16:55:30 +0100906}
907
Harald Welte6baf5e72023-04-15 20:30:52 +0800908/* Test traffic being routed through "server" side STP (M3UA SG), coming back in "client"
909 * side STP (M3UA ASP) which has no routing context set */
910testcase TC_clnt_sg_to_asp_norctx() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700911 var OCT4 rctx_sender := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
912 var OCT4 pc_sender := int2oct(f_m3ua_cli_config(0).point_code, 4);
913 var OCT4 pc_receiver := int2oct(f_m3ua_srv_config(1).point_code, 4);
914 var OCT4 pc_receiver2 := int2oct(f_m3ua_srv_config(2).point_code, 4);
Harald Welte6baf5e72023-04-15 20:30:52 +0800915
916 /* activate the sender side (ATS is client to STP in SG role) */
917 f_init_m3ua();
918 f_M3UA_asp_up_act(0);
919
920 /* activate the receiver side (ATS is server to STP in ASP role) */
921 f_init_m3ua_srv();
922 f_M3UA_CLNT_asp_up_act(M3UA_SRV(1), rctx := omit);
923 /* activate another instance of STP in ASP role with no routing context */
924 f_M3UA_CLNT_asp_up_act(M3UA_SRV(2), rctx := omit);
925
926 f_sleep(1.0);
927
928 /* verify traffic is routed from sender to [sole] receiver for each PC */
929 f_test_traffic(0, rctx_sender, pc_sender, M3UA_SRV(1), omit, pc_receiver);
930 f_test_traffic(0, rctx_sender, pc_sender, M3UA_SRV(2), omit, pc_receiver2);
931
932 f_clear_m3ua();
933}
934
935/* Test traffic being routed through "server" side STP (M3UA SG), coming back in "client"
936 * side STP (M3UA ASP) which has no routing context set */
937testcase TC_clnt_asp_to_sg_norctx() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700938 var OCT4 rctx_receiver := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
939 var OCT4 pc_receiver := int2oct(f_m3ua_cli_config(0).point_code, 4);
940 var OCT4 pc_sender := int2oct(f_m3ua_srv_config(1).point_code, 4);
941 var OCT4 pc_sender2 := int2oct(f_m3ua_srv_config(2).point_code, 4);
Harald Welte6baf5e72023-04-15 20:30:52 +0800942
943 /* activate the sender side (ATS is client to STP in SG role) */
944 f_init_m3ua();
945 f_M3UA_asp_up_act(0);
946
947 /* activate the receiver side (ATS is server to STP in ASP role) */
948 f_init_m3ua_srv();
949 f_M3UA_CLNT_asp_up_act(M3UA_SRV(1), rctx := omit);
950 /* activate another instance of STP in ASP role with no routing context */
951 f_M3UA_CLNT_asp_up_act(M3UA_SRV(2), rctx := omit);
952
953 f_sleep(1.0);
954
955 /* verify traffic is routed from sender to [sole] receiver for each PC */
956 f_test_traffic(M3UA_SRV(1), omit, pc_sender, 0, rctx_receiver, pc_receiver);
957 f_test_traffic(M3UA_SRV(2), omit, pc_sender2, 0, rctx_receiver, pc_receiver);
958
959 f_clear_m3ua();
960}
961
Harald Welte27cfb7a2021-02-08 09:58:28 +0100962/* Test if ASPAC / ASPIA of one ASP generates DAVA / DUNA on other ASP */
963testcase TC_ssnm_aspac_dava_aspia_duna() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700964 var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
965 var integer pc0 := f_m3ua_cli_config(1).point_code;
Harald Welte27cfb7a2021-02-08 09:58:28 +0100966
967 f_init_m3ua(ignore_ssnm := false);
968 /* activate the first ASP */
969 f_M3UA_asp_up_act(0);
970
971 /* activate the second ASP */
972 f_M3UA_asp_up_act(1, c_M3UA_TMT_override, omit);
973 /* expect DAVA for PC of second ASP on first ASP */
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700974 f_M3UA_exp(0, tr_M3UA_DAVA({ts_M3UA_PC(pc0, 0)}, rctx0));
Harald Welte27cfb7a2021-02-08 09:58:28 +0100975 /* TODO: expect no DAVA on second ASP */
976
977 /* deactivate the second ASP */
978 f_M3UA_asp_inact(1);
979 /* expect DUNA for PC of second ASP on first ASP */
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700980 f_M3UA_exp(0, tr_M3UA_DUNA({ts_M3UA_PC(pc0, 0)}, rctx0));
Harald Welte27cfb7a2021-02-08 09:58:28 +0100981 /* TODO: expect no DUNA on second ASP */
982
983 f_clear_m3ua();
984}
985
986/* Test if DAVA/DUNA sent from SG to ASP-role STP gets forwarded to other ASP */
987testcase TC_ssnm_distribution_dava_duna() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +0700988 var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
989 var OCT4 rctxS0 := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
Harald Welte27cfb7a2021-02-08 09:58:28 +0100990 /* some random point code whose availability we advertise */
991 var template (value) M3UA_Point_Code adv_pc := ts_M3UA_PC(1234, 0);
992
993 f_init_m3ua(ignore_ssnm := false);
994
995 /* activate the first ASP */
996 f_M3UA_asp_up_act(0);
997
998 /* activate SG-role ASP (ASP on STP) */
999 f_init_m3ua_srv();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001000 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctxS0);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001001
1002 /* transmit a DAVA to the remote ASP */
1003 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAVA({adv_pc}, rctxS0));
1004 /* expect that to show up on other ASP */
1005 f_M3UA_exp(0, tr_M3UA_DAVA({adv_pc}, rctx0));
1006
1007 /* transmit a DUNA to the remote ASP */
1008 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DUNA({adv_pc}, rctxS0));
1009 /* expect that to show up on other ASP */
1010 f_M3UA_exp(0, tr_M3UA_DUNA({adv_pc}, rctx0));
1011}
1012
1013/* Test if DAVA/DUNA sent from SG to ASP-role STP gets forwarded to other ASP */
1014testcase TC_ssnm_distribution_dava_duna_multipc() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001015 var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
1016 var OCT4 rctxS0 := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001017 /* some random point code whose availability we advertise */
1018 var template (value) M3UA_Point_Codes adv_pcs := { ts_M3UA_PC(1234, 0), ts_M3UA_PC(5678, 0) };
1019
1020 f_init_m3ua(ignore_ssnm := false);
1021
1022 /* activate the first ASP */
1023 f_M3UA_asp_up_act(0);
1024
1025 /* activate SG-role ASP (ASP on STP) */
1026 f_init_m3ua_srv();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001027 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctxS0);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001028
1029 /* transmit a DAVA to the remote ASP */
1030 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAVA(adv_pcs, rctxS0));
1031 /* expect that to show up on other ASP */
1032 f_M3UA_exp(0, tr_M3UA_DAVA(adv_pcs, rctx0));
1033
1034 /* transmit a DUNA to the remote ASP */
1035 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DUNA(adv_pcs, rctxS0));
1036 /* expect that to show up on other ASP */
1037 f_M3UA_exp(0, tr_M3UA_DUNA(adv_pcs, rctx0));
1038}
1039
1040/* Test if DUPU sent from SG to ASP-role STP gets forwarded to other ASP */
1041testcase TC_ssnm_distribution_dupu() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001042 var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
1043 var OCT4 rctxS0 := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001044 /* some random point code whose availability we advertise */
1045 var template (value) M3UA_Point_Code adv_pc := ts_M3UA_PC(1234, 0);
1046
1047 f_init_m3ua(ignore_ssnm := false);
1048
1049 /* activate the first ASP */
1050 f_M3UA_asp_up_act(0);
1051
1052 /* activate SG-role ASP (ASP on STP) */
1053 f_init_m3ua_srv();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001054 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctxS0);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001055
1056 /* transmit a DUPU to the remote ASP */
1057 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DUPU({adv_pc}, '0102'O, 'ABCD'O, rctxS0));
1058 /* expect that to show up on other ASP */
1059 f_M3UA_exp(0, tr_M3UA_DUPU({adv_pc}, '0102'O, 'ABCD'O, rctx0));
1060}
1061
1062/* Test if SCON sent from SG to ASP-role STP gets forwarded to other ASP */
1063testcase TC_ssnm_distribution_scon() runs on RAW_M3UA_CT {
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001064 var OCT4 rctx0 := int2oct(f_m3ua_cli_config(0).routing_ctx, 4);
1065 var OCT4 rctxS0 := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001066 /* some random point code whose availability we advertise */
1067 var template (value) M3UA_Point_Code adv_pc := ts_M3UA_PC(1234, 0);
1068
1069 f_init_m3ua(ignore_ssnm := false);
1070
1071 /* activate the first ASP */
1072 f_M3UA_asp_up_act(0);
1073
1074 /* activate SG-role ASP (ASP on STP) */
1075 f_init_m3ua_srv();
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001076 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctxS0);
Harald Welte27cfb7a2021-02-08 09:58:28 +01001077
1078 /* transmit a SCON to the remote ASP */
1079 f_M3UA_send(M3UA_SRV(0), ts_M3UA_SCON({adv_pc}, rctxS0));
1080 /* expect that to show up on other ASP */
1081 f_M3UA_exp(0, tr_M3UA_SCON({adv_pc}, rctx0));
1082}
Harald Welte829dac42019-11-05 16:55:30 +01001083
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +07001084private function f_asp_cfg_str(charstring asp_name, in M3uaConfig cfg)
1085return charstring {
1086 var charstring str;
1087
1088 str := "asp " & asp_name;
1089 str := str & " " & int2str(cfg.local_port);
1090 str := str & " " & int2str(cfg.remote_port);
1091 str := str & " m3ua";
1092
1093 if (cfg.use_tcp) {
1094 str := str & " tcp";
1095 }
1096
1097 return str;
1098}
1099
Harald Welte30cb4002021-05-13 20:51:37 +02001100private function f_quirk(charstring quirk) runs on RAW_M3UA_CT {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +07001101 var charstring asp_cfg_str := f_asp_cfg_str("asp-client0", f_m3ua_srv_config(0));
1102 f_vty_config2(VTY, {"cs7 instance 0", asp_cfg_str}, "quirk " & quirk);
Harald Welte30cb4002021-05-13 20:51:37 +02001103}
1104
1105private function f_no_quirk(charstring quirk) runs on RAW_M3UA_CT {
Vadim Yanitskiy36b7b5d2024-03-01 01:52:24 +07001106 var charstring asp_cfg_str := f_asp_cfg_str("asp-client0", f_m3ua_srv_config(0));
1107 f_vty_config2(VTY, {"cs7 instance 0", asp_cfg_str}, "no quirk " & quirk);
Harald Welte30cb4002021-05-13 20:51:37 +02001108}
1109
1110/* quirk 'no_notify': Expect inbound connection from ASP/SCTP-client, followed by ASP-UP + ASP-ACT */
1111testcase TC_clnt_quirk_no_notify_asp_act() runs on RAW_M3UA_CT {
1112 f_init_m3ua();
1113 f_quirk("no_notify");
1114 f_init_m3ua_srv();
1115
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001116 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 +02001117 ntfy_after_up := omit, ntfy_after_act := omit);
1118 f_no_quirk("no_notify");
1119 f_clear_m3ua();
1120}
1121
Harald Welte5ef25532021-05-13 21:10:25 +02001122/* ensure that DAUD is not supported in ASP role, as required by RFC */
1123testcase TC_clnt_no_daud_in_asp() runs on RAW_M3UA_CT {
1124 f_init_m3ua();
1125 f_no_quirk("daud_in_asp");
1126 f_init_m3ua_srv();
1127
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001128 var OCT4 rctx := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
1129 var integer pc := f_m3ua_srv_config(0).point_code;
Harald Welte5ef25532021-05-13 21:10:25 +02001130
1131 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx);
1132
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001133 var template (value) M3UA_Point_Codes aff_pcs := { ts_M3UA_PC(pc) };
Harald Welte5ef25532021-05-13 21:10:25 +02001134 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAUD(aff_pcs));
1135 f_M3UA_exp(M3UA_SRV(0), tr_M3UA_ERR('00000004'O, omit));
1136 setverdict(pass);
1137
1138 f_clear_m3ua();
1139}
1140
1141/* quirk 'daud_in_asp': allowing inbound DAUD from SG in ASP role */
1142testcase TC_clnt_quirk_daud_in_asp() runs on RAW_M3UA_CT {
1143 f_init_m3ua();
1144 f_quirk("daud_in_asp");
1145 f_init_m3ua_srv();
1146
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001147 var OCT4 rctx := int2oct(f_m3ua_srv_config(0).routing_ctx, 4);
1148 var integer pc := f_m3ua_srv_config(0).point_code;
Harald Welte5ef25532021-05-13 21:10:25 +02001149
1150 f_M3UA_CLNT_asp_up_act(M3UA_SRV(0), rctx := rctx);
1151
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001152 var template (value) M3UA_Point_Codes aff_pcs := { ts_M3UA_PC(pc) };
Harald Welte5ef25532021-05-13 21:10:25 +02001153 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAUD(aff_pcs));
1154 f_M3UA_exp(M3UA_SRV(0), tr_M3UA_DAVA(aff_pcs));
1155 setverdict(pass);
1156
1157 f_no_quirk("daud_in_asp");
1158 f_clear_m3ua();
1159}
Harald Welte0db44132019-10-17 11:09:05 +02001160
Harald Welte261aea72021-05-13 21:23:29 +02001161/* Expect a normal ASP to reject any [S]SNM messages in ASP-INACTIVE state */
1162testcase TC_clnt_no_snm_inactive() runs on RAW_M3UA_CT {
1163 f_init_m3ua();
1164 f_quirk("no_notify");
1165 f_quirk("daud_in_asp");
1166 f_no_quirk("snm_inactive");
1167 f_init_m3ua_srv();
1168
1169 /* bring ASP only UP (into INACTIVE state), but not ACTIVE! */
1170 f_M3UA_CLNT_asp_up(M3UA_SRV(0));
1171 f_M3UA_exp(M3UA_SRV(0), tr_M3UA_ASPAC(*, *));
1172
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001173 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 +02001174 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAUD(aff_pcs));
1175 f_M3UA_exp(M3UA_SRV(0), tr_M3UA_ERR('00000006'O, omit));
1176 setverdict(pass);
1177
1178 f_no_quirk("no_notify");
1179 f_no_quirk("daud_in_asp");
1180 f_clear_m3ua();
1181}
1182
1183/* quirk 'snm_inactive': Process [S]SNM in ASP-INACTIVE state */
1184testcase TC_clnt_quirk_snm_inactive() runs on RAW_M3UA_CT {
1185 f_init_m3ua();
1186 f_quirk("no_notify");
1187 f_quirk("daud_in_asp");
1188 f_quirk("snm_inactive");
1189 f_init_m3ua_srv();
1190
1191 /* bring ASP only UP (into INACTIVE state), but not ACTIVE! */
1192 f_M3UA_CLNT_asp_up(M3UA_SRV(0));
1193 f_M3UA_exp(M3UA_SRV(0), tr_M3UA_ASPAC(*, *));
1194
Vadim Yanitskiy84ec42b2024-03-02 00:07:52 +07001195 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 +02001196 f_M3UA_send(M3UA_SRV(0), ts_M3UA_DAUD(aff_pcs));
1197 f_M3UA_exp(M3UA_SRV(0), tr_M3UA_DAVA(aff_pcs));
1198 setverdict(pass);
1199
1200 f_no_quirk("no_notify");
1201 f_no_quirk("daud_in_asp");
1202 f_no_quirk("snm_inactive");
1203 f_clear_m3ua();
1204}
1205
1206
Harald Welte0db44132019-10-17 11:09:05 +02001207control {
1208 /* M3UA Tests */
1209 execute( TC_connect_asp_up() );
1210 execute( TC_beat() );
1211 execute( TC_beat_payload() );
1212 execute( TC_asp_act() );
1213 execute( TC_asp_act_override() );
1214 execute( TC_asp_act_loadshare() );
1215 execute( TC_asp_act_broadcast() );
1216 execute( TC_tmt_override() );
1217 execute( TC_tmt_loadshare() );
1218 execute( TC_tmt_broadcast() );
Harald Welte15a85012020-06-13 16:35:45 +02001219 execute( TC_act_rctx_data_no_rctx() );
Harald Welte0db44132019-10-17 11:09:05 +02001220
1221 /* M3UA RKM tests */
1222 execute( TC_rkm_reg_static_notpermitted() );
1223 execute( TC_rkm_reg_static_permitted() );
1224 execute( TC_rkm_reg_dynamic_permitted() );
Pau Espin Pedrol6b1b0ff2021-11-16 19:24:53 +01001225 execute( TC_rkm_unreg_never_registered() );
1226
Harald Welte0db44132019-10-17 11:09:05 +02001227 execute( TC_rkm_unreg_invalid() );
1228 execute( TC_rkm_unreg_registered() );
1229 execute( TC_rkm_unreg_active() );
1230 /* TODO: test RKM with unsupported routing keys: NA, SI, OPC */
1231 /* TODO: register/unregister multiple routing contexts in one message; including mixed
1232 success/failure situations */
Harald Welte829dac42019-11-05 16:55:30 +01001233
1234 /* Test STP as SCTP client + M3UA ASP role */
1235 execute( TC_clnt_connect_asp_up() );
1236 execute( TC_clnt_asp_act() );
1237 execute( TC_clnt_sg_to_asp() );
1238 execute( TC_clnt_asp_to_sg() );
Harald Welte53050cd2019-12-01 20:49:01 +01001239
Harald Welte6baf5e72023-04-15 20:30:52 +08001240 execute( TC_clnt_sg_to_asp_norctx() );
1241 execute( TC_clnt_asp_to_sg_norctx() );
1242
Pau Espin Pedrol6b1b0ff2021-11-16 19:24:53 +01001243 execute( TC_clnt_quirk_no_notify_asp_act() );
1244 execute( TC_clnt_no_daud_in_asp() );
1245 execute( TC_clnt_quirk_daud_in_asp() );
1246 execute( TC_clnt_no_snm_inactive() );
1247 execute( TC_clnt_quirk_snm_inactive() );
1248
Harald Welte30cb4002021-05-13 20:51:37 +02001249
Harald Welte27cfb7a2021-02-08 09:58:28 +01001250 /* M3UA SSNM tests */
1251 execute( TC_ssnm_aspac_dava_aspia_duna() );
1252 execute( TC_ssnm_distribution_dava_duna() );
1253 execute( TC_ssnm_distribution_dava_duna_multipc() );
1254 execute( TC_ssnm_distribution_dupu() );
1255 execute( TC_ssnm_distribution_scon() );
1256
Harald Welte53050cd2019-12-01 20:49:01 +01001257 /* put this one last as it changes the stp side config */
1258 execute( TC_clnt_asp_act_tmt_loadshare() );
Harald Welte0db44132019-10-17 11:09:05 +02001259}
1260
1261
1262
1263}