blob: 698c1a24a3cf4ea5db9e2975ad839a517760be36 [file] [log] [blame]
Daniel Willmann19b8d902022-01-05 09:12:34 +01001module HNBGW_Tests {
2
3/* Integration Tests for OsmoHNBGW
4 * (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
5 * All rights reserved.
6 *
7 * Released under the terms of GNU General Public License, Version 2 or
8 * (at your option) any later version.
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 *
12 * This test suite tests OsmoHNBGW while emulating the hNodeB as well as MSC, SGSN, MGW
13 * See README for more details.
14 */
15
16import from Misc_Helpers all;
17import from General_Types all;
18import from GSM_Types all;
19import from Osmocom_Types all;
20import from IPL4asp_Types all;
Neels Hofmeyr1e311462023-01-11 01:19:12 +010021import from Native_Functions all;
Daniel Willmann19b8d902022-01-05 09:12:34 +010022
23import from Osmocom_CTRL_Functions all;
24import from Osmocom_CTRL_Types all;
25import from Osmocom_CTRL_Adapter all;
26
27import from StatsD_Types all;
28import from StatsD_CodecPort all;
29import from StatsD_CodecPort_CtrlFunct all;
30import from StatsD_Checker all;
31
32import from Osmocom_VTY_Functions all;
33import from TELNETasp_PortType all;
34
35import from HNBAP_Templates all;
36import from HNBAP_PDU_Descriptions all;
37
38import from RUA_IEs all;
39import from RUA_Templates all;
40import from RUA_Emulation all;
41
42import from Iuh_Emulation all;
43
44import from RANAP_Types all;
45import from RANAP_PDU_Descriptions all;
46import from RANAP_PDU_Contents all;
47import from RANAP_IEs all;
48import from RANAP_Templates all;
49
50import from RAN_Adapter all;
Daniel Willmann19b8d902022-01-05 09:12:34 +010051import from RAN_Emulation all;
52
53import from MGCP_Emulation all;
54import from MGCP_Types all;
55import from MGCP_Templates all;
56import from MGCP_CodecPort all;
57import from SDP_Types all;
58
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +020059import from PFCP_Types all;
60import from PFCP_Emulation all;
61import from PFCP_Templates all;
62import from PFCP_CodecPort all;
63
Daniel Willmann19b8d902022-01-05 09:12:34 +010064modulepar {
65 /* IP address at which the HNodeB can be reached */
66 charstring mp_hnodeb_ip := "127.0.0.1";
67 integer mp_hnodeb_port := -1;
68
69 /* IP address at which the test binds */
70 charstring mp_hnbgw_ip := "127.0.0.1";
71 integer mp_hnbgw_iuh_port := 29169;
72
73 charstring mp_mgw_ip := "127.0.0.1";
74 integer mp_mgw_port := 2427;
75
76 RAN_Configuration mp_msc_cfg := {
77 transport := RANAP_TRANSPORT_IuCS,
78 sccp_service_type := "mtp3_itu",
79 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
80 own_pc := 188, /* 0.23.4 first MSC emulation */
81 own_ssn := 142,
82 peer_pc := 189, /* 0.23.5 osmo-hnbgw */
83 peer_ssn := 142,
84 sio := '83'O,
85 rctx := 1
86 };
87 RAN_Configuration mp_sgsn_cfg := {
88 transport := RANAP_TRANSPORT_IuCS,
89 sccp_service_type := "mtp3_itu",
90 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
91 own_pc := 185, /* 0.23.1 first SGSN emulation */
92 own_ssn := 142,
93 peer_pc := 189, /* 0.23.5 osmo-hnbgw */
94 peer_ssn := 142,
95 sio := '83'O,
96 rctx := 2
97 };
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +020098
Neels Hofmeyrbacb74f2022-08-29 16:24:12 +020099 boolean mp_enable_pfcp_tests := false;
100
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +0200101 /* IP address at which we listen for PFCP to emulate a UPF in ttcn3 */
102 charstring mp_pfcp_ip_local := "127.0.0.1";
103
104 /* IP address from which the SUT (osmo-hnbgw) sends PFCP requests, and to which the ttcn3 UPF emulation sends
105 * PFCP responses. */
106 charstring mp_pfcp_ip_remote := "127.0.0.2";
Daniel Willmann19b8d902022-01-05 09:12:34 +0100107}
108
109function MSC_UnitdataCallback(RANAP_PDU ranap) runs on RAN_Emulation_CT return template RANAP_PDU {
110 // TODO: Actually implement unitdata handling
111 return ts_RANAP_Reset(ts_RanapCause_om_intervention, cs_domain);
112}
113
114const RanOps MSC_RanOps := {
115 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
116 ranap_unitdata_cb := refers(MSC_UnitdataCallback),
117 ps_domain := false,
118 decode_dtap := false,
119 role_ms := false,
120 protocol := RAN_PROTOCOL_RANAP,
121 transport := RANAP_TRANSPORT_IuCS,
122 use_osmux := false,
Eric Wild6e511ce2022-04-02 21:35:56 +0200123 bssap_reset_retries := 1,
Daniel Willmann19b8d902022-01-05 09:12:34 +0100124 sccp_addr_local := omit,
125 sccp_addr_peer := omit
126}
127
128type record CrcxResponse {
129 integer resp,
130 HostName mgw_rtp_ip,
131 PortNumber mgw_rtp_port,
132 MgcpConnectionId mgcp_connection_id
133}
134type record MgcpParameters {
135 integer got_crcx_count,
136 integer got_dlcx_count,
137 MgcpCallId mgcp_call_id optional,
138 MgcpEndpoint mgcp_ep,
139 CrcxResponse mgw_conn_1,
140 CrcxResponse mgw_conn_2,
141 uint7_t rtp_payload_type,
142 charstring rtp_sdp_format,
143 HostName hnb_rtp_ip,
144 PortNumber hnb_rtp_port,
145 HostName cn_rtp_ip,
146 PortNumber cn_rtp_port,
147 boolean use_osmux,
148 integer got_osmux_count
149}
150
151template (value) MgcpParameters t_MgcpParams := {
152 got_crcx_count := 0,
153 got_dlcx_count := 0,
154 mgcp_call_id := omit,
155 mgcp_ep := "rtpbridge/1@mgw",
156 mgw_conn_1 := {
157 resp := 1,
158 mgw_rtp_ip := "127.1.2.1",
159 mgw_rtp_port := 10000,
160 mgcp_connection_id := '11111'H
161 },
162 mgw_conn_2 := {
163 resp := 1,
164 mgw_rtp_ip := "127.1.2.2",
165 mgw_rtp_port := 20000,
166 mgcp_connection_id := '22222'H
167 },
168 rtp_payload_type := 23,
169 rtp_sdp_format := "FOO",
170 hnb_rtp_ip := "127.1.1.1",
171 hnb_rtp_port := 10001,
172 cn_rtp_ip := "127.1.3.1",
173 cn_rtp_port := 20001,
174 use_osmux := false,
175 got_osmux_count := 0
176}
177
178type record TestHdlrParams {
179 integer hnb_idx,
180 hexstring imsi,
181 boolean ps_domain,
182 MgcpParameters mgcp_pars optional,
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200183 HnbConfig hnb optional,
Neels Hofmeyrf2c95022023-04-19 01:24:39 +0200184 boolean expect_separate_sccp_cr,
185 integer tx_sccp_cr_data_len,
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +0200186 charstring pfcp_local_addr
Daniel Willmann19b8d902022-01-05 09:12:34 +0100187}
188
189/* We extend:
190 * RUA_ConnHdlr (for the Iuh side, emulating the HNB)
191 * RAN_ConnHdlr (for the Iu side, emulating the MSC)
192 * MGCP_ConnHdlr (for the MGCP side, emulating the MGW)
193 */
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +0200194type component ConnHdlr extends RAN_ConnHdlr, MGCP_ConnHdlr, RUA_ConnHdlr, PFCP_ConnHdlr {
Daniel Willmann19b8d902022-01-05 09:12:34 +0100195 var integer g_sccp_conn_id;
196 var TestHdlrParams g_pars;
197 timer g_Tguard;
Neels Hofmeyr72a8d622023-01-26 13:47:01 +0100198
199 port TELNETasp_PT HNBGWVTY;
Daniel Willmann19b8d902022-01-05 09:12:34 +0100200}
201
202
203const MGCPOps MSC_MGCPOps := {
204 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
205 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
206}
207
208function f_create_ranap_exp(octetstring l3_enc) runs on ConnHdlr {
209 BSSAP_PROC.call(RAN_register:{l3_enc, self}) {
210 [] BSSAP_PROC.getreply(RAN_register:{?, ?}) {};
211 }
212}
213
214
Daniel Willmannc79679a2022-08-23 17:48:39 +0200215const integer NUM_HNB := 2;
Daniel Willmann19b8d902022-01-05 09:12:34 +0100216
Daniel Willmann19b8d902022-01-05 09:12:34 +0100217type record HnbConfig {
218 LocationAreaIdentification lai,
219 integer sac
220}
221
222type component test_CT extends CTRL_Adapter_CT {
223 var boolean g_initialized := false;
224
225 /********************* Iu side */
226 var RAN_Adapter g_msc;
227 var RAN_Adapter g_sgsn;
228 /* SGSN IuPS missing */
229
230 /********************* Iuh side */
231 var HnbConfig g_hnb_cfg[NUM_HNB];
232 var Iuh_Emulation_CT vc_Iuh[NUM_HNB];
233 var RUA_Emulation_CT vc_RUA[NUM_HNB];
234 port HNBAP_PT HNBAP[NUM_HNB];
Pau Espin Pedrol83a49612022-09-12 21:11:05 +0200235 /* Number of HNBs to be used/started by the test */
236 var integer g_num_hnbs := NUM_HNB;
Daniel Willmann19b8d902022-01-05 09:12:34 +0100237
238 var MGCP_Emulation_CT vc_MGCP;
239 port TELNETasp_PT HNBGWVTY;
240 /* global test case guard timer (actual timeout value is set in f_init()) */
241 timer T_guard := 30.0;
242}
243
244/* global altstep for global guard timer; */
245altstep as_Tguard() runs on test_CT {
246 [] T_guard.timeout {
247 setverdict(fail, "Timeout of T_guard");
248 mtc.stop;
249 }
250}
251
252friend function f_logp(TELNETasp_PT pt, charstring log_msg)
253{
254 // log on TTCN3 log output
255 log(log_msg);
256 // log in stderr log
257 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
258}
259
260function f_init_vty(charstring id := "foo") runs on test_CT {
261 if (HNBGWVTY.checkstate("Mapped")) {
262 /* skip initialization if already executed once */
263 return;
264 }
265 map(self:HNBGWVTY, system:HNBGWVTY);
266 f_vty_set_prompts(HNBGWVTY);
267 f_vty_transceive(HNBGWVTY, "enable");
268}
269
270function f_init_mgcp(charstring id) runs on test_CT {
271 id := id & "-MGCP";
272 var MGCPOps ops := {
273 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
274 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
275 }
276 var MGCP_conn_parameters pars := {
277 callagent_ip := mp_hnbgw_ip,
278 callagent_udp_port := -1,
279 mgw_ip := mp_mgw_ip,
280 mgw_udp_port := mp_mgw_port,
281 multi_conn_mode := false
282 }
283
284 vc_MGCP := MGCP_Emulation_CT.create(id);
285 map(vc_MGCP:MGCP, system:MGCP_CODEC_PT);
286 vc_MGCP.start(MGCP_Emulation.main(ops, pars, id));
287}
288
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +0200289function f_init_pfcp(charstring id) runs on ConnHdlr {
290 id := id & "-PFCP";
291
292 var PFCP_Emulation_Cfg pfcp_cfg := {
293 pfcp_bind_ip := mp_pfcp_ip_local,
294 pfcp_bind_port := PFCP_PORT,
295 pfcp_remote_ip := mp_pfcp_ip_remote,
296 pfcp_remote_port := PFCP_PORT,
297 role := UPF
298 };
299
300 vc_PFCP := PFCP_Emulation_CT.create(id) alive;
301 connect(self:PFCP, vc_PFCP:CLIENT);
302 connect(self:PFCP_PROC, vc_PFCP:CLIENT_PROC);
303 vc_PFCP.start(PFCP_Emulation.main(pfcp_cfg));
304}
305
Daniel Willmann19b8d902022-01-05 09:12:34 +0100306function f_init_hnodeb(charstring id, integer hnb_idx, RuaOps rua_ops) runs on test_CT {
307 id := id & "-Iuh" & int2str(hnb_idx);
308
309 /* Iuh lower layer (RUA/HNBAP demux) */
310 var Iuh_conn_parameters iuh_pars;
311 iuh_pars.remote_ip := mp_hnbgw_ip;
312 iuh_pars.remote_sctp_port := mp_hnbgw_iuh_port;
313 iuh_pars.local_ip := mp_hnodeb_ip;
314 iuh_pars.local_sctp_port := mp_hnodeb_port + hnb_idx;
315 vc_Iuh[hnb_idx] := Iuh_Emulation_CT.create(id);
316 connect(self:HNBAP[hnb_idx], vc_Iuh[hnb_idx]:HNBAP);
317
318 vc_RUA[hnb_idx] := RUA_Emulation_CT.create(id & "-RUA");
319 connect(vc_RUA[hnb_idx]:RUA, vc_Iuh[hnb_idx]:RUA);
320
321 /* Start Iuh side components */
322 vc_Iuh[hnb_idx].start(Iuh_Emulation.main(iuh_pars, id));
323 vc_RUA[hnb_idx].start(RUA_Emulation.main(rua_ops, id & "-RUA"));
324}
325
326/* global initialization function */
Neels Hofmeyr82e79b02022-06-08 00:08:09 +0200327function f_init(charstring id := "HNBGW", float guard_timeout := 30.0) runs on test_CT {
Daniel Willmann19b8d902022-01-05 09:12:34 +0100328
Daniel Willmann19b8d902022-01-05 09:12:34 +0100329 T_guard.start(guard_timeout);
330 activate(as_Tguard());
331
332 /* RUA/RANAP emulation on top of lower-layer Iuh */
333 var RuaOps rua_ops := {
334 create_cb := refers(IuhRanapCreateCallback),
335 unitdata_cb := refers(IuhRanapUnitdataCallback)
336 };
Pau Espin Pedrol83a49612022-09-12 21:11:05 +0200337 for (var integer i := 0; i < g_num_hnbs; i := i+1) {
Daniel Willmannc79679a2022-08-23 17:48:39 +0200338 g_hnb_cfg[i] := {
339 lai := {
340 mcc_mnc := '00101'H,
341 lac := 2342 + i
342 },
343 sac := 55
344 };
Daniel Willmann19b8d902022-01-05 09:12:34 +0100345 f_init_hnodeb(testcasename(), i, rua_ops);
346 }
347
348 /* MSC emulation */
349 var RanOps ranops := {
350 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
351 ranap_unitdata_cb := omit,
352 ps_domain := false,
353 decode_dtap := false,
354 role_ms := false,
355 protocol := RAN_PROTOCOL_RANAP,
356 transport := RANAP_TRANSPORT_IuCS,
357 use_osmux := false,
Eric Wild6e511ce2022-04-02 21:35:56 +0200358 bssap_reset_retries := 1,
Daniel Willmann19b8d902022-01-05 09:12:34 +0100359 sccp_addr_local := omit,
360 sccp_addr_peer := omit
361 };
362 f_ran_adapter_init(g_msc, mp_msc_cfg, "HNBGW_Test", ranops);
363 f_ran_adapter_start(g_msc);
364
365 /* SGSN emulation */
366 ranops.ps_domain := true;
367 f_ran_adapter_init(g_sgsn, mp_sgsn_cfg, "HNBGW_Test", ranops);
368 f_ran_adapter_start(g_sgsn);
369
370 f_init_mgcp(id);
371 f_init_vty("VirtHNBGW");
372}
373
374friend function f_shutdown_helper() runs on test_CT {
375 all component.stop;
376 setverdict(pass);
377 mtc.stop;
378}
379
380/* helper function to start all of the simulated hNodeBs */
381function f_start_hnbs() runs on test_CT {
Pau Espin Pedrol83a49612022-09-12 21:11:05 +0200382 for (var integer i:= 0; i < g_num_hnbs; i := i+1) {
Daniel Willmannc79679a2022-08-23 17:48:39 +0200383 f_hnbap_register(i, i);
Daniel Willmann19b8d902022-01-05 09:12:34 +0100384 }
385}
386
387/***********************************************************************
388 * code running in test_CT, preparing start of per-UE ConnHdlr
389 ***********************************************************************/
390
391/* inbound RUA connection establishment on Iuh side */
392function IuhRanapCreateCallback(ContextId context_id, RUA_IEs.CN_DomainIndicator domain, charstring id)
393runs on RUA_Emulation_CT return RUA_ConnHdlr {
394 log("CreateCallback");
395 return null;
396}
397
398/* inbound RUA connectionless data on Iuh side */
399function IuhRanapUnitdataCallback(RANAP_PDU ranap)
400runs on RUA_Emulation_CT return template RANAP_PDU {
401 log("UnitdataCallback");
402 return omit;
403}
404
405private function f_start_handler_create(TestHdlrParams pars) runs on test_CT return ConnHdlr {
406 var ConnHdlr vc_conn;
407 var charstring id := testcasename() & int2str(pars.hnb_idx);
408
409 vc_conn := ConnHdlr.create(id);
410
411 /* Iuh RUA part */
412 connect(vc_conn:RUA, vc_RUA[pars.hnb_idx]:CLIENT);
413
414 if (pars.ps_domain) {
415 /* SGSN side */
416 connect(vc_conn:BSSAP, g_sgsn.vc_RAN:CLIENT);
417 connect(vc_conn:BSSAP_PROC, g_sgsn.vc_RAN:PROC);
418 } else {
419 /* MSC side */
420 connect(vc_conn:BSSAP, g_msc.vc_RAN:CLIENT);
421 connect(vc_conn:BSSAP_PROC, g_msc.vc_RAN:PROC);
422 }
423 /* MGCP part */
424 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
425 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
426
427 return vc_conn;
428}
429
430private function f_start_handler_run(ConnHdlr vc_conn, void_fn fn, TestHdlrParams pars) runs on test_CT {
431 var charstring id := testcasename(); // & int2str(pars.ran_idx);
432 /* We cannot use vc_conn.start(f_init_handler(fn, id, pars)); as we cannot have
433 * a stand-alone 'derefers()' call, see https://www.eclipse.org/forums/index.php/t/1091364/ */
434 pars.hnb := g_hnb_cfg[pars.hnb_idx];
435 pars.mgcp_pars := valueof(t_MgcpParams);
436 vc_conn.start(derefers(fn)(id, pars));
437}
438
439function f_start_handler_with_pars(void_fn fn, template (value) TestHdlrParams pars)
440runs on test_CT return ConnHdlr {
441 var ConnHdlr vc_conn;
442 vc_conn := f_start_handler_create(valueof(pars));
443 f_start_handler_run(vc_conn, fn, valueof(pars));
444 return vc_conn;
445}
446
447/***********************************************************************
448 * code running inside per-UE ConnHdlr
449 ***********************************************************************/
450
451type function void_fn(charstring id, TestHdlrParams pars) runs on ConnHdlr;
452
453function f_init_handler(TestHdlrParams pars, float t_guard := 20.0) runs on ConnHdlr {
454 /* make parameters available via component variable */
455 g_pars := pars;
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +0200456
457 f_init_pfcp(testcasename());
458
Daniel Willmann19b8d902022-01-05 09:12:34 +0100459 /* start guard timer and activate it as default */
460 g_Tguard.start(t_guard);
461 activate(as_Tguard_ConnHdlr());
462
Neels Hofmeyr72a8d622023-01-26 13:47:01 +0100463 map(self:HNBGWVTY, system:HNBGWVTY);
464 f_vty_set_prompts(HNBGWVTY);
465 f_vty_transceive(HNBGWVTY, "enable");
466
Daniel Willmann19b8d902022-01-05 09:12:34 +0100467 /* TODO: CTRL? */
Daniel Willmann19b8d902022-01-05 09:12:34 +0100468}
469
470/* global altstep for global guard timer; */
471private altstep as_Tguard_ConnHdlr() runs on ConnHdlr {
472 [] g_Tguard.timeout {
473 setverdict(fail, "Timeout of T_guard");
474 mtc.stop;
475 }
476}
477
Neels Hofmeyrdc416c92023-03-09 02:47:50 +0100478private function f_bssap_expect(template (present) RANAP_PDU exp_rx) runs on ConnHdlr return RANAP_PDU
479{
480 var RANAP_PDU rx;
481 timer T := 5.0;
482 T.start;
483 alt {
484 [] BSSAP.receive(exp_rx) -> value rx {
485 setverdict(pass);
486 }
487 [] BSSAP.receive(RANAP_PDU:?) {
488 setverdict(fail, "Got an unexpected RANAP message on BSSAP port, was waiting for ", exp_rx);
489 mtc.stop;
490 }
491 [] T.timeout {
492 setverdict(fail, "Timeout waiting for RANAP on BSSAP port: ", exp_rx);
493 mtc.stop;
494 }
495 }
496 T.stop;
497 return rx;
498}
499
Daniel Willmann19b8d902022-01-05 09:12:34 +0100500/* send RANAP on Iuh and expect it to show up on Iu */
501function f_iuh2iu(template (present) RANAP_PDU tx, template RANAP_PDU exp_rx := omit)
502runs on ConnHdlr return RANAP_PDU {
503 var RANAP_PDU rx;
504 timer T := 5.0;
505
506 if (istemplatekind(exp_rx, "omit")) {
507 exp_rx := tx;
508 }
509
510 RUA.send(tx);
Daniel Willmann19b8d902022-01-05 09:12:34 +0100511
Neels Hofmeyrdc416c92023-03-09 02:47:50 +0100512 return f_bssap_expect(exp_rx);
Daniel Willmann19b8d902022-01-05 09:12:34 +0100513}
514
515/* send RANAP on Iu and expect it to show up on Iuh */
516function f_iu2iuh(template (present) RANAP_PDU tx, template RANAP_PDU exp_rx := omit)
517runs on ConnHdlr return RANAP_PDU {
Daniel Willmann19b8d902022-01-05 09:12:34 +0100518 if (istemplatekind(exp_rx, "omit")) {
519 exp_rx := tx;
520 }
521
522 BSSAP.send(tx);
Daniel Willmann19b8d902022-01-05 09:12:34 +0100523
Neels Hofmeyr735b6562023-03-09 02:51:28 +0100524 return f_rua_expect(exp_rx)
525}
526
527/* expect to receive a specific RUA message on Iuh */
528private function f_rua_expect(template (present) RANAP_PDU exp_rx) runs on ConnHdlr return RANAP_PDU
529{
530 var RANAP_PDU rx;
531 timer T := 5.0;
532 T.start;
Daniel Willmann19b8d902022-01-05 09:12:34 +0100533 alt {
534 [] RUA.receive(exp_rx) -> value rx {
535 setverdict(pass);
536 }
Neels Hofmeyr735b6562023-03-09 02:51:28 +0100537 [] RUA.receive(RANAP_PDU:?) {
538 setverdict(fail, "Got an unexpected RUA message, was waiting for ", exp_rx);
539 mtc.stop;
540 }
Daniel Willmann19b8d902022-01-05 09:12:34 +0100541 [] T.timeout {
542 setverdict(fail, "Timeout waiting for Iuh ", exp_rx);
Neels Hofmeyr735b6562023-03-09 02:51:28 +0100543 mtc.stop;
Daniel Willmann19b8d902022-01-05 09:12:34 +0100544 }
545 }
Neels Hofmeyr735b6562023-03-09 02:51:28 +0100546 T.stop;
Daniel Willmann19b8d902022-01-05 09:12:34 +0100547 return rx;
548}
549
550/* send RANAP on Iuh and expect it to show up on Iu */
551function f_iuh2iu_connect(template (present) RANAP_PDU tx, template RANAP_PDU exp_rx := omit)
552runs on ConnHdlr return RANAP_PDU {
553 var RANAP_PDU rx;
554 timer T := 5.0;
555
556 if (istemplatekind(exp_rx, "omit")) {
557 exp_rx := tx;
558 }
559
560 /* create an expect on the Iu side for the random NAS portion */
Neels Hofmeyrf2c95022023-04-19 01:24:39 +0200561 if (g_pars.expect_separate_sccp_cr) {
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200562 f_ran_register_sccp_cr_without_payload();
563 } else {
564 var template (omit) octetstring nas := f_ranap_extract_l3(valueof(tx));
565 f_ran_register_exp(valueof(nas));
566 }
Daniel Willmann19b8d902022-01-05 09:12:34 +0100567
568 /* send it via Iuh (creating a RUA connection) */
569 RUA.send(RUA_Conn_Req:{g_pars.ps_domain, tx});
570
Neels Hofmeyrf2c95022023-04-19 01:24:39 +0200571 if (g_pars.expect_separate_sccp_cr) {
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200572 /* Acknowledge the empty SCCP CR. RAN_Emulation does the confirmation, no need to respond. */
573 BSSAP.receive(tr_RANAP_Conn_Req());
574 }
575
Daniel Willmann19b8d902022-01-05 09:12:34 +0100576 /* expect to receive it on the Iu side */
Neels Hofmeyrdc416c92023-03-09 02:47:50 +0100577 return f_bssap_expect(exp_rx);
Daniel Willmann19b8d902022-01-05 09:12:34 +0100578}
579
Neels Hofmeyr99b7d402023-02-20 14:26:31 +0100580/* 3GPP TS 48.006 9.2 Connection release:
581 *
582 * The MSC sends a SCCP released message. This message shall not contain
583 * any user data field.
584 *
585 * So what we expect normally is:
586 *
587 * HNBGW MSC
588 * RUA --id-Disconnect-------> | ---Data-Form-1(!)---> | Iu-ReleaseComplete
589 * | <--Released---------- | (no data)
590 *
591 * This function tests osmo-hnbgw behavior if the CN fails to send a RLSD:
592 * after some timeout, osmo-hnbgw should send a RLSD to the CN.
593 */
Daniel Willmann19b8d902022-01-05 09:12:34 +0100594function f_iuh2iu_disconnect(template (present) RANAP_PDU tx, RUA_IEs.Cause cause,
595 template RANAP_PDU exp_rx := omit)
596runs on ConnHdlr return RANAP_PDU {
597 var RANAP_PDU rx
Neels Hofmeyr99b7d402023-02-20 14:26:31 +0100598 timer T := 10.0;
Daniel Willmann19b8d902022-01-05 09:12:34 +0100599
600 if (istemplatekind(exp_rx, "omit")) {
601 exp_rx := tx;
602 }
603
604 /* send it via Iuh (creating a RUA connection) */
605 RUA.send(RUA_Disc_Req:{tx, cause});
606
607 /* expect to receive it on the Iu side */
Neels Hofmeyrdc416c92023-03-09 02:47:50 +0100608 rx := f_bssap_expect(exp_rx);
Daniel Willmann19b8d902022-01-05 09:12:34 +0100609
610 /* expect disconnect on the Iu side */
Neels Hofmeyrdc416c92023-03-09 02:47:50 +0100611 T.start;
Daniel Willmann19b8d902022-01-05 09:12:34 +0100612 alt {
613 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
614 setverdict(pass);
615 }
616 [] T.timeout {
617 setverdict(fail, "Timeout waiting for Iu disconnect");
618 return rx;
619 }
620
621 }
622 return rx;
623}
624
Neels Hofmeyrf2c95022023-04-19 01:24:39 +0200625private function f_build_initial_ue_with_nas(TestHdlrParams pars, octetstring nas)
626 return RANAP_PDU {
Daniel Willmann19b8d902022-01-05 09:12:34 +0100627 var LAI lai := {
628 pLMNidentity := hex2oct(pars.hnb.lai.mcc_mnc),
629 lAC := int2oct(pars.hnb.lai.lac, 2),
630 iE_Extensions := omit
631 };
632 var SAI sai := {
633 pLMNidentity := lai.pLMNidentity,
634 lAC := lai.lAC,
635 sAC := int2oct(pars.hnb.sac, 2),
636 iE_Extensions := omit
637 }
Daniel Willmann19b8d902022-01-05 09:12:34 +0100638 var IuSignallingConnectionIdentifier sigc_id := int2bit(f_rnd_int(1000), 24);
639 var GlobalRNC_ID grnc_id := {
640 pLMNidentity := lai.pLMNidentity,
641 rNC_ID := 2342
642 }
Neels Hofmeyrf2c95022023-04-19 01:24:39 +0200643 var template RANAP_PDU ret;
Daniel Willmann19b8d902022-01-05 09:12:34 +0100644 if (pars.ps_domain) {
645 var RAC rac := '00'O;
Neels Hofmeyrf2c95022023-04-19 01:24:39 +0200646 ret := ts_RANAP_initialUE_PS(lai, rac, sai, nas, sigc_id, grnc_id);
Daniel Willmann19b8d902022-01-05 09:12:34 +0100647 } else {
Neels Hofmeyrf2c95022023-04-19 01:24:39 +0200648 ret := ts_RANAP_initialUE_CS(lai, sai, nas, sigc_id, grnc_id);
Daniel Willmann19b8d902022-01-05 09:12:34 +0100649 }
Neels Hofmeyrf2c95022023-04-19 01:24:39 +0200650 return valueof(ret);
651}
652
653/* build a RANAP InitialUE based on the TestHdlrParams */
654friend function f_build_initial_ue(TestHdlrParams pars) return RANAP_PDU {
655
656 var octetstring nas;
657
658 if (pars.tx_sccp_cr_data_len == 0) {
659 nas := f_rnd_octstring(10);
660 } else {
661 /* The test asks for an exact number of Optional Data bytes. */
662
663 /* First see what size the RANAP part of the payload data is,
664 * to adjust the NAS PDU size to the size requested by the test (pars.tx_sccp_cr_data_len). */
665 var RANAP_PDU initial_ue := f_build_initial_ue_with_nas(pars, '00'O);
666
667 var octetstring ranap_plus_one_byte_nas := enc_RANAP_PDU(initial_ue);
668 var integer ranap_length := lengthof(ranap_plus_one_byte_nas) - 1;
669
670 log("ranap_plus_one_byte_nas = ", lengthof(ranap_plus_one_byte_nas), " bytes, ", initial_ue, " = ",
671 ranap_plus_one_byte_nas);
672 log("ranap_length = ", ranap_length);
673
674 /* SCCP CR has a payload length limit of 130 bytes. To trigger this limit, the RANAP + NAS PDU has to be
675 * > 130 bytes. It doesn't need to be 131 bytes in the NAS PDU alone, but let's just make it definitely
676 * large enough. To test for this limit, pars.tx_sccp_cr_data_len asks for a specific amount of data len. */
677 nas := f_rnd_octstring(pars.tx_sccp_cr_data_len - ranap_length);
678 }
679
680 var RANAP_PDU ret := f_build_initial_ue_with_nas(pars, nas);
681
682 if (pars.tx_sccp_cr_data_len != 0) {
683 for (var integer attempts := 0; attempts < 2; attempts := attempts + 1) {
684 var octetstring check_len := enc_RANAP_PDU(ret);
685 log("final RANAP PDU length = ", lengthof(check_len));
686 if (lengthof(check_len) == pars.tx_sccp_cr_data_len) {
687 return ret;
688 }
689 nas := f_rnd_octstring(lengthof(nas) + (pars.tx_sccp_cr_data_len - lengthof(check_len)));
690 log("that was off, changed NAS length to ", lengthof(nas), " and trying again");
691 ret := f_build_initial_ue_with_nas(pars, nas);
692 }
693 setverdict(fail, "Ended up with wrong Optional Data length");
694 mtc.stop;
695 }
696 return ret;
Daniel Willmann19b8d902022-01-05 09:12:34 +0100697}
698
699/* build a RANAP RAB AssignmentResponse based on the TestHdlrParams */
700friend function f_build_rab_ass_resp(TestHdlrParams pars) return RANAP_PDU {
701 var template RAB_SetupOrModifiedList rab_sml;
702
703 rab_sml := ts_RAB_SMdL(t_RAB_id(23), f_ts_RAB_TLA("192.168.1.23"), t_RAB_binding_port(1234));
704
705 return valueof(ts_RANAP_RabAssResp(rab_sml));
706}
707
708
709/***********************************************************************
710 * HNBAP Testing
711 ***********************************************************************/
712
713
Daniel Willmannc79679a2022-08-23 17:48:39 +0200714function f_hnbap_register(integer hnb_idx := 0, integer cell_id := 0, boolean expect_reject := false) runs on test_CT
Daniel Willmann19b8d902022-01-05 09:12:34 +0100715{
716 timer T := 2.0;
717
Daniel Willmann28209ec2022-08-24 09:58:07 +0200718 HNBAP[hnb_idx].send(ts_HNBAP_HNBRegisterRequest(char2oct("TTCN3 HNodeB"),
Daniel Willmann19b8d902022-01-05 09:12:34 +0100719 '00F110'O,
Daniel Willmannc79679a2022-08-23 17:48:39 +0200720 int2bit(1 + cell_id, 28),
Daniel Willmann19b8d902022-01-05 09:12:34 +0100721 int2oct(2, 2),
722 int2oct(3, 1),
723 int2oct(4, 2)));
724
725 T.start;
726 alt {
727 [] HNBAP[hnb_idx].receive(tr_HNBAP_HNBRegisterAccept(?)) {
Daniel Willmannc79679a2022-08-23 17:48:39 +0200728 if (expect_reject) {
729 setverdict(fail, "Rx HNB Register Accept while expecting reject");
730 } else {
731 setverdict(pass);
732 }
733 }
734 [] HNBAP[hnb_idx].receive(tr_HNBAP_HNBRegisterReject(?)) {
735 if (expect_reject) {
736 setverdict(pass);
737 } else {
738 setverdict(fail, "Rx HNB Register Reject while expecting accept");
739 }
Daniel Willmann19b8d902022-01-05 09:12:34 +0100740 }
741 [] HNBAP[hnb_idx].receive(IUHEM_Event:?) {
742 repeat;
743 }
744 [] T.timeout {
Daniel Willmannc79679a2022-08-23 17:48:39 +0200745 setverdict(fail, "Timeout waiting for HNB Register response");
Daniel Willmann19b8d902022-01-05 09:12:34 +0100746 }
747 }
748}
749
750testcase TC_hnb_register() runs on test_CT {
Pau Espin Pedrol83a49612022-09-12 21:11:05 +0200751 g_num_hnbs := 1;
Daniel Willmann19b8d902022-01-05 09:12:34 +0100752 f_init();
753 f_hnbap_register(0);
754 f_shutdown_helper();
755}
756
Pau Espin Pedrolacf4f222022-09-27 14:33:40 +0200757/* Try to register the same HNB from 2 different concurrent connections. Second
758 * one should be rejected. */
Daniel Willmannc79679a2022-08-23 17:48:39 +0200759testcase TC_hnb_register_duplicate() runs on test_CT {
Pau Espin Pedrol83a49612022-09-12 21:11:05 +0200760 g_num_hnbs := 2;
Daniel Willmannc79679a2022-08-23 17:48:39 +0200761 f_init();
762 f_hnbap_register(0);
763 f_hnbap_register(1, 0, expect_reject := true);
764 f_verify_talloc_count(HNBGWVTY, {"struct hnb_context"}, expect_count := 1);
765 f_shutdown_helper();
766}
767
Pau Espin Pedrolacf4f222022-09-27 14:33:40 +0200768/* Try to register the same HNB in the same connection already established, aka
769 * duplicate HNB Register Request. It should be accepted and new configuration
770 * applied. TS 25.469 8.2.4 */
771testcase TC_hnb_register_duplicate_reuse_sctp_assoc() runs on test_CT {
772 g_num_hnbs := 1;
773 f_init();
774 f_hnbap_register(0);
775 f_hnbap_register(0);
776 f_verify_talloc_count(HNBGWVTY, {"struct hnb_context"}, expect_count := 1);
777 f_shutdown_helper();
778}
779
Pau Espin Pedrolf0b9fa02022-09-12 13:31:07 +0200780/* Drop HNBAP conn (HNBAP DEREG) and reconnect it (HNBAP REG) using same SCTP association.
781 * Related: OS#5676, SYS#6113 */
782testcase TC_hnb_reregister_reuse_sctp_assoc() runs on test_CT {
783 g_num_hnbs := 1;
784 f_init();
785 f_hnbap_register(0);
786 HNBAP[0].send(ts_HNBAP_HNBDe_Register(ts_HnbapCause(unspecified)));
787 f_hnbap_register(0);
788 f_verify_talloc_count(HNBGWVTY, {"struct hnb_context"}, expect_count := 1);
789 f_shutdown_helper();
790}
791
Daniel Willmann19b8d902022-01-05 09:12:34 +0100792/***********************************************************************
793 * RUA / RANAP Testing
794 ***********************************************************************/
795
796private template (value) TestHdlrParams
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200797t_pars(integer imsi_suffix, boolean ps_domain := false, integer hnb_idx := 0,
Neels Hofmeyrf2c95022023-04-19 01:24:39 +0200798 boolean expect_separate_sccp_cr := false, integer tx_sccp_cr_data_len := 0) := {
Daniel Willmann19b8d902022-01-05 09:12:34 +0100799 hnb_idx := hnb_idx,
800 imsi := f_gen_imsi(imsi_suffix),
801 ps_domain := ps_domain,
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200802 hnb := omit, /* filled in later */
Neels Hofmeyrf2c95022023-04-19 01:24:39 +0200803 expect_separate_sccp_cr := expect_separate_sccp_cr,
804 tx_sccp_cr_data_len := tx_sccp_cr_data_len,
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +0200805 pfcp_local_addr := mp_pfcp_ip_local
Daniel Willmann19b8d902022-01-05 09:12:34 +0100806}
807
808/* Create an Iuh connection; send InitialUE; expect it to appear on new SCCP conenction */
809friend function f_tc_initial_ue(charstring id, TestHdlrParams pars) runs on ConnHdlr {
810 f_init_handler(pars);
811 var RANAP_PDU tx := f_build_initial_ue(g_pars);
812 f_iuh2iu_connect(tx);
813}
814testcase TC_ranap_cs_initial_ue() runs on test_CT {
815 var ConnHdlr vc_conn;
816
Pau Espin Pedrol83a49612022-09-12 21:11:05 +0200817 g_num_hnbs := 1;
Daniel Willmann19b8d902022-01-05 09:12:34 +0100818 f_init();
819 f_start_hnbs();
820
821 vc_conn := f_start_handler_with_pars(refers(f_tc_initial_ue), t_pars(1));
822 vc_conn.done;
823}
824testcase TC_ranap_ps_initial_ue() runs on test_CT {
825 var ConnHdlr vc_conn;
826
Pau Espin Pedrol83a49612022-09-12 21:11:05 +0200827 g_num_hnbs := 1;
Daniel Willmann19b8d902022-01-05 09:12:34 +0100828 f_init();
829 f_start_hnbs();
830
831 vc_conn := f_start_handler_with_pars(refers(f_tc_initial_ue), t_pars(2, true));
832 vc_conn.done;
833}
834
Neels Hofmeyrf2c95022023-04-19 01:24:39 +0200835private function f_vty_set_sccp_max_optional_data(TELNETasp_PT pt, integer val := -1)
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200836{
Neels Hofmeyrf2c95022023-04-19 01:24:39 +0200837 var charstring valstr;
838 if (val < 0) {
839 valstr := "standard";
840 } else {
841 valstr := int2str(val);
842 }
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200843 f_vty_enter_config(pt);
Neels Hofmeyrf2c95022023-04-19 01:24:39 +0200844 f_vty_transceive(pt, "cs7 instance 0");
845 f_vty_transceive(pt, "sccp max-optional-data " & valstr);
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200846 f_vty_transceive(pt, "end");
847}
848
849testcase TC_ranap_cs_initial_ue_empty_cr() runs on test_CT {
850 var ConnHdlr vc_conn;
851
Pau Espin Pedrol83a49612022-09-12 21:11:05 +0200852 g_num_hnbs := 1;
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200853 f_init();
854 f_start_hnbs();
855
Neels Hofmeyrf2c95022023-04-19 01:24:39 +0200856 f_vty_set_sccp_max_optional_data(HNBGWVTY, 0);
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200857
Neels Hofmeyrf2c95022023-04-19 01:24:39 +0200858 vc_conn := f_start_handler_with_pars(refers(f_tc_initial_ue), t_pars(1, expect_separate_sccp_cr := true));
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200859 vc_conn.done;
860
861 /* reset */
Neels Hofmeyrf2c95022023-04-19 01:24:39 +0200862 f_vty_set_sccp_max_optional_data(HNBGWVTY);
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200863}
864testcase TC_ranap_ps_initial_ue_empty_cr() runs on test_CT {
865 var ConnHdlr vc_conn;
866
Pau Espin Pedrol83a49612022-09-12 21:11:05 +0200867 g_num_hnbs := 1;
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200868 f_init();
869 f_start_hnbs();
870
Neels Hofmeyrf2c95022023-04-19 01:24:39 +0200871 f_vty_set_sccp_max_optional_data(HNBGWVTY, 0);
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200872
Neels Hofmeyrf2c95022023-04-19 01:24:39 +0200873 vc_conn := f_start_handler_with_pars(refers(f_tc_initial_ue), t_pars(2, true, expect_separate_sccp_cr := true));
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200874 vc_conn.done;
875
876 /* reset */
Neels Hofmeyrf2c95022023-04-19 01:24:39 +0200877 f_vty_set_sccp_max_optional_data(HNBGWVTY);
878}
879
880type record Testdata_CR_Limit {
881 integer data_len,
882 integer max_optional_data,
883 boolean expect_separate_sccp_cr
884};
885type record of Testdata_CR_Limit Testdata_CR_Limits;
886
887testcase TC_sccp_cr_limit() runs on test_CT {
888 g_num_hnbs := 1;
889 f_init();
890 f_start_hnbs();
891
892 const Testdata_CR_Limits tests := {
893 { data_len := 130, max_optional_data := -1, expect_separate_sccp_cr := false },
894 { data_len := 131, max_optional_data := -1, expect_separate_sccp_cr := true },
895
896 { data_len := 100, max_optional_data := 100, expect_separate_sccp_cr := false },
897 { data_len := 101, max_optional_data := 100, expect_separate_sccp_cr := true },
898
899 { data_len := 200, max_optional_data := 200, expect_separate_sccp_cr := false },
900 { data_len := 201, max_optional_data := 200, expect_separate_sccp_cr := true }
901 };
902
903 var integer csps;
904 for (csps := 0; csps < 2; csps := csps + 1) {
905 var boolean ps_domain := (csps > 0);
906
907 var integer i;
908 for (i := 0; i < lengthof(tests); i := i + 1) {
909 var Testdata_CR_Limit t := tests[i];
910 f_logp(HNBGWVTY,
911 "TEST PART TC_sccp_cr_limit ps_domain=" & f_bool2str(ps_domain)
912 & " data_len=" & int2str(t.data_len)
913 & " max_optional_data=" & int2str(t.max_optional_data)
914 & " expect_separate_sccp_cr=" & f_bool2str(t.expect_separate_sccp_cr)
915 );
916
917 f_vty_set_sccp_max_optional_data(HNBGWVTY, t.max_optional_data);
918 var ConnHdlr vc_conn;
919 vc_conn := f_start_handler_with_pars(refers(f_tc_initial_ue),
920 t_pars(100 + i,
921 ps_domain := ps_domain,
922 expect_separate_sccp_cr := t.expect_separate_sccp_cr,
923 tx_sccp_cr_data_len := t.data_len));
924 vc_conn.done;
925 }
926 }
927
928 /* reset */
929 f_vty_set_sccp_max_optional_data(HNBGWVTY);
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200930}
931
Daniel Willmann19b8d902022-01-05 09:12:34 +0100932/* Reply to a received CRCX with an OK (or the reply configured in cpars), using the given parameters.
933 * Return true when an OK reply was sent, false otherwise.
934 * Count occurrence of Osmux, include Osmux parameters in the reply if necessary. */
935function f_handle_crcx(inout MgcpParameters pars, MgcpCommand mgcp_cmd) return template MgcpResponse {
936 var CrcxResponse conn := pars.mgw_conn_1;
937 if (pars.got_crcx_count > 0) {
938 conn := pars.mgw_conn_2;
939 }
940 pars.got_crcx_count := pars.got_crcx_count + 1;
941
942 var MgcpMessage mgcp_msg := {
943 command := mgcp_cmd
944 }
945 var template MgcpResponse mgcp_resp;
946 var MgcpOsmuxCID osmux_cid;
947 var MgcpCallId call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
948 if (ispresent(pars.mgcp_call_id)) {
949 if (pars.mgcp_call_id != call_id) {
950 setverdict(fail, "CRCX contained unexpected call id. Expected:", pars.mgcp_call_id, " got:", call_id);
951 mtc.stop;
952 }
953 } else {
954 pars.mgcp_call_id := call_id;
955 }
956
957 /* When the endpoint contains a wildcard we keep the endpoint
958 * identifier we have set up in pars. Otherwise we use the
959 * endpoint name that the call agent has supplied */
960 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard) == false) {
961 pars.mgcp_ep := mgcp_cmd.line.ep;
962 }
963
964 if (conn.resp == -1) {
965 /* Reply with rror */
966 var MgcpResponse mgcp_rsp := {
967 line := {
968 code := "542",
969 trans_id := mgcp_cmd.line.trans_id,
970 string := "FORCED_FAIL"
971 },
972 sdp := omit
973
974 }
975 var MgcpParameter mgcp_rsp_param := {
976 code := "Z",
977 val := pars.mgcp_ep
978 };
979 mgcp_rsp.params[0] := mgcp_rsp_param;
980 return mgcp_rsp;
981 }
982
983 if (conn.resp == 0) {
984 /* Do not reply at all */
985 return omit;
986 }
987
988 if (conn.resp != 1) {
989 setverdict(fail, "Unexpected value for pars.mgw_conn_*.resp, expect -1, 0 or 1");
990 mtc.stop;
991 }
992
993 var SDP_Message sdp := valueof(ts_SDP(conn.mgw_rtp_ip, conn.mgw_rtp_ip,
994 hex2str(pars.mgcp_call_id), "42",
995 conn.mgw_rtp_port,
996 { int2str(pars.rtp_payload_type) },
997 { valueof(ts_SDP_rtpmap(pars.rtp_payload_type,
998 pars.rtp_sdp_format)),
999 valueof(ts_SDP_ptime(20)) }));
1000
1001 if (f_mgcp_contains_par(mgcp_msg, "X-OSMUX")) {
1002 if (not pars.use_osmux) {
1003 setverdict(fail, "MSC sent X-Osmux parameter in MGCP, but not expecting any Osmux");
1004 mtc.stop;
1005 }
1006 pars.got_osmux_count := pars.got_osmux_count + 1;
1007 /* we expect MSC to use wildcard here, i.e. osmux_cid == -1 */
1008 osmux_cid := f_MgcpCmd_extract_osmux_cid(mgcp_cmd);
1009 log("f_handle_crcx(): got Osmux CID: ", osmux_cid);
1010 if (osmux_cid != -1) {
1011 setverdict(fail, "MSC using unexpected CID " & int2str(osmux_cid) & " != -1");
1012 mtc.stop;
1013 }
1014
1015 osmux_cid := 0;
1016 mgcp_resp := ts_CRCX_ACK_osmux(mgcp_cmd.line.trans_id, conn.mgcp_connection_id, osmux_cid, sdp);
1017 } else {
1018 mgcp_resp := ts_CRCX_ACK(mgcp_cmd.line.trans_id, conn.mgcp_connection_id, sdp);
1019 }
1020
1021 f_mgcp_par_append(mgcp_resp.params, ts_MgcpParSpecEP(pars.mgcp_ep));
1022
1023 return mgcp_resp;
1024}
1025
Daniel Willmann3e15b7b2022-02-21 17:07:02 +01001026friend function f_create_rab(inout MgcpParameters pars) runs on ConnHdlr {
1027 f_rab_ass_req(pars);
1028 f_rab_ass_resp(pars);
1029}
1030
1031friend function f_rab_ass_req(inout MgcpParameters pars) runs on ConnHdlr {
Daniel Willmann19b8d902022-01-05 09:12:34 +01001032 var MgcpCommand mgcp_cmd;
1033 var RANAP_PDU tx;
1034 var template RAB_SetupOrModifyList rab_sml;
Daniel Willmann19b8d902022-01-05 09:12:34 +01001035 timer T := 5.0;
1036
1037 /* Send RAB Assignment Request */
1038 rab_sml := ts_RAB_SML(t_RAB_id(23), f_ts_RAB_TLA(pars.cn_rtp_ip), t_RAB_binding_port(pars.cn_rtp_port));
1039 tx := valueof(ts_RANAP_RabAssReq(rab_sml));
1040 BSSAP.send(tx);
1041 T.start;
1042
1043 /* Handle MGCP CRCX */
1044 alt {
1045 [] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
1046 log("CRCX1", mgcp_cmd);
1047 var template MgcpResponse mgcp_rsp := f_handle_crcx(pars, mgcp_cmd);
1048 MGCP.send(valueof(mgcp_rsp));
1049 }
1050 [] T.timeout {
1051 setverdict(fail, "Timeout waiting for MGCP");
1052 }
1053 }
Neels Hofmeyr735b6562023-03-09 02:51:28 +01001054 T.stop;
Daniel Willmann19b8d902022-01-05 09:12:34 +01001055
1056 /* Expect RAB Assignment Request with IP/port from CRCX ACK via Iuh */
1057 rab_sml := ts_RAB_SML(t_RAB_id(23), f_ts_RAB_TLA(pars.mgw_conn_1.mgw_rtp_ip), t_RAB_binding_port(pars.mgw_conn_1.mgw_rtp_port));
1058 tx := valueof(ts_RANAP_RabAssReq(rab_sml));
1059
Neels Hofmeyr735b6562023-03-09 02:51:28 +01001060 f_rua_expect(tx);
Daniel Willmann3e15b7b2022-02-21 17:07:02 +01001061}
1062
1063friend function f_rab_ass_resp(inout MgcpParameters pars) runs on ConnHdlr {
1064 var MgcpCommand mgcp_cmd;
1065 var RANAP_PDU tx;
1066 var template RAB_SetupOrModifiedList rab_smdl;
Daniel Willmann19b8d902022-01-05 09:12:34 +01001067
1068 /* Send back RAB Assignment Response via Iuh */
1069 rab_smdl := ts_RAB_SMdL(t_RAB_id(23), f_ts_RAB_TLA(pars.hnb_rtp_ip), t_RAB_binding_port(pars.hnb_rtp_port));
1070 tx := valueof(ts_RANAP_RabAssResp(rab_smdl));
1071 RUA.send(tx);
Daniel Willmann19b8d902022-01-05 09:12:34 +01001072
1073 interleave {
1074 /* Expect MDCX with IP/port from RAB Assignment Response */
1075 [] MGCP.receive(tr_MDCX(tr_SDP(pars.hnb_rtp_ip, pars.hnb_rtp_port))) -> value mgcp_cmd {
1076 log("MDCX1", mgcp_cmd);
1077 /* Verify SDP of MDCX */
1078 var SDP_Message sdp := valueof(ts_SDP(pars.mgw_conn_1.mgw_rtp_ip, pars.mgw_conn_1.mgw_rtp_ip, hex2str(pars.mgcp_call_id), "42", pars.mgw_conn_1.mgw_rtp_port,
1079 { int2str(pars.rtp_payload_type) }, { valueof(ts_SDP_rtpmap(pars.rtp_payload_type, pars.rtp_sdp_format)), valueof(ts_SDP_ptime(20)) } ));
1080 var template MgcpResponse mgcp_rsp := ts_MDCX_ACK(mgcp_cmd.line.trans_id, pars.mgw_conn_1.mgcp_connection_id, sdp);
1081 MGCP.send(valueof(mgcp_rsp));
1082 }
1083 /* Handle CRCX for second leg of endpoint, answer with IP/port */
1084 [] MGCP.receive(tr_CRCX(pars.mgcp_ep, tr_SDP(pars.cn_rtp_ip, pars.cn_rtp_port))) -> value mgcp_cmd {
1085 log("CRCX2", mgcp_cmd);
1086 /* Verify SDP of CRCX */
1087 var template MgcpResponse mgcp_rsp := f_handle_crcx(pars, mgcp_cmd);
1088 MGCP.send(valueof(mgcp_rsp));
1089 }
1090 }
1091
1092 /* Expect RAB Assignment Response with IP/port from second CRCX ACK */
1093 rab_smdl := ts_RAB_SMdL(t_RAB_id(23), f_ts_RAB_TLA(pars.mgw_conn_2.mgw_rtp_ip), t_RAB_binding_port(pars.mgw_conn_2.mgw_rtp_port));
1094 tx := valueof(ts_RANAP_RabAssResp(rab_smdl));
1095
Neels Hofmeyrdc416c92023-03-09 02:47:50 +01001096 f_bssap_expect(tx);
Daniel Willmann19b8d902022-01-05 09:12:34 +01001097}
1098
1099private altstep as_mgcp_dlcx(inout TestHdlrParams pars) runs on ConnHdlr {
1100 var MgcpCommand mgcp_cmd;
1101
1102 [] MGCP.receive(tr_DLCX(pars.mgcp_pars.mgcp_ep)) -> value mgcp_cmd {
1103 log("DLCX", mgcp_cmd);
1104 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1105 pars.mgcp_pars.got_dlcx_count := pars.mgcp_pars.got_dlcx_count + 1;
Daniel Willmann3e15b7b2022-02-21 17:07:02 +01001106 if (pars.mgcp_pars.got_dlcx_count != pars.mgcp_pars.got_crcx_count) {
Daniel Willmann19b8d902022-01-05 09:12:34 +01001107 repeat;
1108 }
1109 setverdict(pass);
1110 }
1111}
1112
1113friend function f_tc_rab_assignment(charstring id, TestHdlrParams pars) runs on ConnHdlr {
1114 var MgcpCommand mgcp_cmd;
1115 var RANAP_PDU tx;
1116 timer T := 5.0;
1117
1118 f_init_handler(pars);
1119 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1120
1121 tx := f_build_initial_ue(g_pars);
1122 f_iuh2iu_connect(tx);
1123
1124 f_create_rab(pars.mgcp_pars);
1125
1126 /* Send Iu Release */
1127 tx := valueof(ts_RANAP_IuReleaseCommand(ts_RanapCause_om_intervention));
1128 f_iu2iuh(tx);
1129
1130 T.start;
1131 alt {
1132 [] as_mgcp_dlcx(pars) {}
1133 [] T.timeout {
1134 setverdict(fail, "Timeout waiting for DLCX");
1135 }
1136 }
1137
1138 tx := valueof(ts_RANAP_IuReleaseComplete());
1139 f_iuh2iu(tx);
1140}
1141
1142testcase TC_rab_assignment() runs on test_CT {
1143 var ConnHdlr vc_conn;
Pau Espin Pedrol83a49612022-09-12 21:11:05 +02001144 g_num_hnbs := 1;
Daniel Willmann19b8d902022-01-05 09:12:34 +01001145 f_init();
1146 f_start_hnbs();
1147
1148 vc_conn := f_start_handler_with_pars(refers(f_tc_rab_assignment), t_pars(3));
1149 vc_conn.done;
1150}
1151
Daniel Willmann3e15b7b2022-02-21 17:07:02 +01001152friend function f_tc_rab_assign_fail(charstring id, TestHdlrParams pars) runs on ConnHdlr {
1153 var MgcpCommand mgcp_cmd;
1154 var RANAP_PDU tx;
1155 timer T := 5.0;
1156
1157 f_init_handler(pars);
1158 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1159
1160 tx := f_build_initial_ue(g_pars);
1161 f_iuh2iu_connect(tx);
1162
1163 f_rab_ass_req(pars.mgcp_pars);
1164
1165 /* Send RAB failed list in response */
1166 tx := valueof(ts_RANAP_RabAssResp(rab_fl := ts_RAB_FL(t_RAB_id(23), ts_RanapCause_om_intervention)));
1167 f_iuh2iu(tx);
1168
1169 T.start;
1170 alt {
1171 [] as_mgcp_dlcx(pars) {}
1172 [] T.timeout {
1173 setverdict(fail, "Timeout waiting for DLCX");
1174 }
1175 }
1176}
1177
1178testcase TC_rab_assign_fail() runs on test_CT {
1179 var ConnHdlr vc_conn;
Pau Espin Pedrol83a49612022-09-12 21:11:05 +02001180 g_num_hnbs := 1;
Daniel Willmann3e15b7b2022-02-21 17:07:02 +01001181 f_init();
1182 f_start_hnbs();
1183
1184 vc_conn := f_start_handler_with_pars(refers(f_tc_rab_assign_fail), t_pars(4));
1185 vc_conn.done;
1186}
1187
Daniel Willmann19b8d902022-01-05 09:12:34 +01001188friend function f_tc_rab_release(charstring id, TestHdlrParams pars) runs on ConnHdlr {
1189 var MgcpCommand mgcp_cmd;
1190 var RANAP_PDU tx;
1191 timer T := 15.0;
1192
1193 f_init_handler(pars);
1194 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1195
1196 tx := f_build_initial_ue(g_pars);
1197 f_iuh2iu_connect(tx);
1198
1199 f_create_rab(pars.mgcp_pars);
1200
1201 /* Send RAB Release */
Daniel Willmann9e789be2022-02-22 13:30:51 +01001202 tx := valueof(ts_RANAP_RabAssReq(rab_rl := ts_RAB_RL(t_RAB_id(23), ts_RanapCause_om_intervention)));
Daniel Willmann19b8d902022-01-05 09:12:34 +01001203 BSSAP.send(tx);
1204
1205 T.start;
1206
1207 alt {
1208 [] as_mgcp_dlcx(pars) {}
1209 [] T.timeout {
1210 setverdict(fail, "Timeout waiting for DLCX");
1211 }
1212 }
Neels Hofmeyr735b6562023-03-09 02:51:28 +01001213 T.stop;
Daniel Willmann19b8d902022-01-05 09:12:34 +01001214
Neels Hofmeyr735b6562023-03-09 02:51:28 +01001215 f_rua_expect(tx);
Daniel Willmann19b8d902022-01-05 09:12:34 +01001216}
1217
1218testcase TC_rab_release() runs on test_CT {
1219 var ConnHdlr vc_conn;
Pau Espin Pedrol83a49612022-09-12 21:11:05 +02001220 g_num_hnbs := 1;
Daniel Willmann19b8d902022-01-05 09:12:34 +01001221 f_init();
1222 f_start_hnbs();
1223
1224 vc_conn := f_start_handler_with_pars(refers(f_tc_rab_release), t_pars(5));
1225 vc_conn.done;
1226}
1227
Daniel Willmann37c877f2022-02-22 16:47:06 +01001228friend function f_tc_rab_assign_mgcp_to(charstring id, TestHdlrParams pars) runs on ConnHdlr {
1229 var MgcpCommand mgcp_cmd;
1230 var RANAP_PDU tx;
1231 var template RAB_SetupOrModifyList rab_sml;
1232 timer T := 15.0;
1233
1234 T.start;
1235 f_init_handler(pars);
1236 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1237
1238 tx := f_build_initial_ue(g_pars);
1239 f_iuh2iu_connect(tx);
1240
1241
1242 /* Send RAB Assignment Request */
1243 rab_sml := ts_RAB_SML(t_RAB_id(23), f_ts_RAB_TLA(pars.mgcp_pars.cn_rtp_ip), t_RAB_binding_port(pars.mgcp_pars.cn_rtp_port));
1244 tx := valueof(ts_RANAP_RabAssReq(rab_sml));
1245 BSSAP.send(tx);
1246
1247 /* Ignore MGCP CRCX */
1248 alt {
1249 [] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
1250 log("Ignoreing CRCX1", mgcp_cmd);
1251 repeat;
1252 }
1253 [] BSSAP.receive(tr_RANAP_IuReleaseRequest(?)) { }
1254 [] T.timeout {
1255 setverdict(fail, "Timeout waiting for IuRelease");
1256 }
1257 }
1258
1259 /* Send Iu Release */
1260 tx := valueof(ts_RANAP_IuReleaseCommand(ts_RanapCause_om_intervention));
1261 f_iu2iuh(tx);
1262
1263 tx := valueof(ts_RANAP_IuReleaseComplete());
1264 f_iuh2iu(tx);
1265}
1266
1267testcase TC_rab_assign_mgcp_to() runs on test_CT {
1268 var ConnHdlr vc_conn;
Pau Espin Pedrol83a49612022-09-12 21:11:05 +02001269 g_num_hnbs := 1;
Daniel Willmann37c877f2022-02-22 16:47:06 +01001270 f_init();
1271 f_start_hnbs();
1272
1273 vc_conn := f_start_handler_with_pars(refers(f_tc_rab_assign_mgcp_to), t_pars(6));
1274 vc_conn.done;
1275}
1276
Daniel Willmann19b8d902022-01-05 09:12:34 +01001277/* Create an Iuh connection; send InitialUE; transceive data both directions */
1278friend function f_tc_ranap_bidir(charstring id, TestHdlrParams pars) runs on ConnHdlr {
1279 f_init_handler(pars);
1280
1281 /* HNB -> MSC: InitialUE */
1282 f_iuh2iu_connect(f_build_initial_ue(g_pars));
1283
1284 /* MSC <- HNB: DirectTransfer */
1285 f_iu2iuh(ts_RANAP_DirectTransfer(f_rnd_octstring(10)));
1286 /* MSC -> HNB: DirectTransfer */
1287 f_iuh2iu(ts_RANAP_DirectTransfer(f_rnd_octstring(10)));
1288
1289 /* HNB <- MSC: CommonID */
1290 f_iu2iuh(ts_RANAP_CommonId(hex2oct(pars.imsi)));
1291}
1292testcase TC_ranap_cs_bidir() runs on test_CT {
1293 var ConnHdlr vc_conn;
Pau Espin Pedrol83a49612022-09-12 21:11:05 +02001294 g_num_hnbs := 1;
Daniel Willmann19b8d902022-01-05 09:12:34 +01001295 f_init();
1296 f_start_hnbs();
1297
1298 vc_conn := f_start_handler_with_pars(refers(f_tc_ranap_bidir), t_pars(3));
1299 vc_conn.done;
1300}
1301testcase TC_ranap_ps_bidir() runs on test_CT {
1302 var ConnHdlr vc_conn;
Pau Espin Pedrol83a49612022-09-12 21:11:05 +02001303 g_num_hnbs := 1;
Daniel Willmann19b8d902022-01-05 09:12:34 +01001304 f_init();
1305 f_start_hnbs();
1306
1307 vc_conn := f_start_handler_with_pars(refers(f_tc_ranap_bidir), t_pars(4, true));
1308 vc_conn.done;
1309}
1310
1311
1312private function f_tc_ranap_mo_disconnect(charstring id, TestHdlrParams pars) runs on ConnHdlr {
1313 f_init_handler(pars);
1314
1315 /* HNB -> MSC: InitialUE */
1316 f_iuh2iu_connect(f_build_initial_ue(g_pars));
1317
1318 /* MSC <- HNB: DirectTransfer */
1319 f_iu2iuh(ts_RANAP_DirectTransfer(f_rnd_octstring(10)));
1320 /* MSC -> HNB: DirectTransfer */
1321 f_iuh2iu(ts_RANAP_DirectTransfer(f_rnd_octstring(10)));
1322
1323 /* MSC <- HNB: RUA disconnect */
1324 f_iuh2iu_disconnect(ts_RANAP_IuReleaseComplete, RUA_IEs.Cause:{misc:=processing_overload});
1325}
1326testcase TC_ranap_cs_mo_disconnect() runs on test_CT {
1327 var ConnHdlr vc_conn;
Pau Espin Pedrol83a49612022-09-12 21:11:05 +02001328 g_num_hnbs := 1;
Daniel Willmann19b8d902022-01-05 09:12:34 +01001329 f_init();
1330 f_start_hnbs();
1331
1332 vc_conn := f_start_handler_with_pars(refers(f_tc_ranap_mo_disconnect), t_pars(5));
1333 vc_conn.done;
1334}
1335testcase TC_ranap_ps_mo_disconnect() runs on test_CT {
1336 var ConnHdlr vc_conn;
Pau Espin Pedrol83a49612022-09-12 21:11:05 +02001337 g_num_hnbs := 1;
Daniel Willmann19b8d902022-01-05 09:12:34 +01001338 f_init();
1339 f_start_hnbs();
1340
1341 vc_conn := f_start_handler_with_pars(refers(f_tc_ranap_mo_disconnect), t_pars(6));
1342 vc_conn.done;
1343}
1344
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001345type record FTeid {
1346 HostName addr,
1347 OCT4 teid
1348}
1349
1350type record FTeids {
1351 FTeid local,
1352 FTeid remote
1353}
Daniel Willmann19b8d902022-01-05 09:12:34 +01001354
1355
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001356/* 'local' and 'remote' refer to the GTP information from the UPF's point of view:
1357 * HNB UPF CN
1358 * access.remote <---> access.local | core.local <---> core.remote
1359 */
1360type record GtpParameters {
1361 FTeids core,
1362 FTeids access
1363}
1364
1365/* HNB UPF CN
1366 * access.remote <---> access.local | core.local <---> core.remote
1367 * 127.0.0.4 127.0.0.3 127.0.0.2 127.0.0.1
1368 * 0x44004400 0x30303030 0x22002200 0x10101010
1369 */
1370template GtpParameters t_GtpParameters := {
1371 core := {
1372 local := {
1373 addr := "127.0.0.2",
1374 teid := '22002200'O
1375 },
1376 remote := {
1377 addr := "127.0.0.1",
1378 teid := '10101010'O
1379 }
1380 },
1381 access := {
1382 local := {
1383 addr := "127.0.0.3",
1384 teid := '30303030'O
1385 },
1386 remote := {
1387 addr := "127.0.0.4",
1388 teid := '44004400'O
1389 }
1390 }
1391}
1392
Neels Hofmeyr65499282023-04-25 02:31:51 +02001393private function f_pfcp_expect(template (present) PDU_PFCP exp_rx, float wait_time := 5.0) runs on ConnHdlr return PDU_PFCP
Neels Hofmeyr6bbfe052023-03-09 02:51:46 +01001394{
1395 var PDU_PFCP rx;
Neels Hofmeyr65499282023-04-25 02:31:51 +02001396 timer T := wait_time;
Neels Hofmeyr6bbfe052023-03-09 02:51:46 +01001397 T.start;
1398 alt {
1399 [] PFCP.receive(exp_rx) -> value rx {
1400 setverdict(pass);
1401 }
1402 [] PFCP.receive(PDU_PFCP:?) {
1403 setverdict(fail, "Got an unexpected PFCP message, was waiting for ", exp_rx);
1404 mtc.stop;
1405 }
1406 [] T.timeout {
1407 setverdict(fail, "Timeout waiting for PFCP ", exp_rx);
1408 mtc.stop;
1409 }
1410 }
1411 T.stop;
1412 return rx;
1413}
1414
Neels Hofmeyrbacb74f2022-08-29 16:24:12 +02001415friend function f_tc_ps_rab_assignment_with_pfcp(charstring id, TestHdlrParams pars) runs on ConnHdlr {
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001416 var RANAP_PDU tx;
1417 var RANAP_PDU rx;
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001418
1419 f_init_handler(pars);
1420
1421 f_pfcp_register();
1422
1423 var PDU_PFCP m;
1424 var Node_ID upf_node_id := valueof(ts_PFCP_Node_ID_fqdn("\07osmocom\03org"));
1425
Neels Hofmeyr65499282023-04-25 02:31:51 +02001426 m := f_pfcp_expect(tr_PFCP_Assoc_Setup_Req(), wait_time := 15.0);
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001427 PFCP.send(ts_PFCP_Assoc_Setup_Resp(m.sequence_number, upf_node_id,
1428 ts_PFCP_Cause(REQUEST_ACCEPTED), 1234));
1429
1430 tx := f_build_initial_ue(g_pars);
1431 f_iuh2iu_connect(tx);
1432
1433 var GtpParameters gtp_pars := valueof(t_GtpParameters);
1434 var template RAB_SetupOrModifyList rab_sml;
1435
1436 /* Send RAB Assignment Request */
1437 rab_sml := ts_RAB_SML_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.core.remote.addr), gtp_pars.core.remote.teid);
1438 tx := valueof(ts_RANAP_RabAssReq(rab_sml));
1439 BSSAP.send(tx);
1440
1441 /* Expect PFCP Session Establishment Request. */
Neels Hofmeyr6bbfe052023-03-09 02:51:46 +01001442 m := f_pfcp_expect(tr_PFCP_Session_Est_Req());
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001443 var F_SEID hnbgw_f_seid := m.message_body.pfcp_session_establishment_request.CP_F_SEID;
1444 var PFCP_Session_Establishment_Request serq := m.message_body.pfcp_session_establishment_request;
1445
1446 /* Acting as UPF, invent a new PFCP SEID to send to HNBGW. Respond to the Session Establishment.
1447 * The PFCP response must have the same sequence_number as the request. */
Neels Hofmeyr1e311462023-01-11 01:19:12 +01001448 var F_SEID up_f_seid := valueof(ts_PFCP_F_SEID_ipv4(f_inet_addr("127.0.0.1"), '1111111111111111'O));
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001449 var template PDU_PFCP r := ts_PFCP_Session_Est_Resp(m.sequence_number, upf_node_id, hnbgw_f_seid.seid);
1450 r.message_body.pfcp_session_establishment_response := {
1451 offending_ie := omit,
1452 UP_F_SEID := up_f_seid,
1453 created_PDR_list := {
1454 ts_PFCP_Created_PDR(pdr_id := serq.create_PDR_list[0].grouped_ie.pdr_id,
1455 local_F_TEID := ts_PFCP_F_TEID_ipv4(gtp_pars.core.local.teid,
Neels Hofmeyr1e311462023-01-11 01:19:12 +01001456 f_inet_addr(gtp_pars.core.local.addr))),
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001457 ts_PFCP_Created_PDR(pdr_id := serq.create_PDR_list[1].grouped_ie.pdr_id,
1458 local_F_TEID := ts_PFCP_F_TEID_ipv4(gtp_pars.access.local.teid,
Neels Hofmeyr1e311462023-01-11 01:19:12 +01001459 f_inet_addr(gtp_pars.access.local.addr)))
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001460 },
1461 load_control_information := omit,
1462 overload_control_information := omit,
1463 node_list := omit,
1464 failed_rule_id := omit,
1465 created_traffic_endpoint_list := omit
1466 };
1467 PFCP.send(r);
1468
1469 /* Expect on Iuh: RAB Assignment Request with IP/port from PFCP Session Est Resp */
1470 rab_sml := ts_RAB_SML_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.access.local.addr),
1471 gtp_pars.access.local.teid);
1472 rx := valueof(ts_RANAP_RabAssReq(rab_sml));
Neels Hofmeyr735b6562023-03-09 02:51:28 +01001473 f_rua_expect(rx);
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001474
1475 /* Send back RAB Assignment Response via Iuh */
1476 var template RAB_SetupOrModifiedList rab_smdl;
1477 rab_smdl := ts_RAB_SMdL_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.access.remote.addr),
1478 gtp_pars.access.remote.teid);
1479 tx := valueof(ts_RANAP_RabAssResp(rab_smdl));
1480 RUA.send(tx);
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001481
Neels Hofmeyr6bbfe052023-03-09 02:51:46 +01001482 m := f_pfcp_expect(tr_PFCP_Session_Mod_Req(up_f_seid.seid));
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001483 r := ts_PFCP_Session_Mod_Resp(m.sequence_number, hnbgw_f_seid.seid);
1484 PFCP.send(r);
1485
1486 rab_smdl := ts_RAB_SMdL_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.core.local.addr), gtp_pars.core.local.teid);
Neels Hofmeyrdc416c92023-03-09 02:47:50 +01001487 f_bssap_expect(tr_RANAP_RabAssResp(rab_smdl));
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001488
1489 f_sleep(2.0);
1490 tx := valueof(ts_RANAP_IuReleaseCommand(ts_RanapCause_om_intervention));
1491 f_iu2iuh(tx);
1492
1493 tx := valueof(ts_RANAP_IuReleaseComplete());
1494 f_iuh2iu(tx);
1495
Neels Hofmeyr6bbfe052023-03-09 02:51:46 +01001496 m := f_pfcp_expect(tr_PFCP_Session_Del_Req(up_f_seid.seid));
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001497 PFCP.send(ts_PFCP_Session_Del_Resp(m.sequence_number, hnbgw_f_seid.seid));
1498
1499 f_sleep(2.0);
1500}
1501
Neels Hofmeyrbacb74f2022-08-29 16:24:12 +02001502testcase TC_ps_rab_assignment_with_pfcp() runs on test_CT {
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001503 var ConnHdlr vc_conn;
Pau Espin Pedrol83a49612022-09-12 21:11:05 +02001504 g_num_hnbs := 1;
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001505 f_init();
1506 f_start_hnbs();
1507 f_sleep(1.0);
1508
Neels Hofmeyrbacb74f2022-08-29 16:24:12 +02001509 vc_conn := f_start_handler_with_pars(refers(f_tc_ps_rab_assignment_with_pfcp), t_pars(7, ps_domain := true));
1510 vc_conn.done;
1511}
1512
1513altstep as_disallow_pfcp() runs on ConnHdlr {
1514 [] PFCP.receive(PDU_PFCP:?) {
1515 setverdict(fail, "Received PFCP message, but no PFCP communication expected");
1516 mtc.stop;
1517 }
1518}
1519
1520friend function f_tc_ps_rab_assignment_without_pfcp(charstring id, TestHdlrParams pars) runs on ConnHdlr {
1521 var RANAP_PDU tx;
1522 var RANAP_PDU rx;
1523 timer T := 5.0;
1524
1525 f_init_handler(pars);
1526
1527 f_pfcp_register();
1528 activate(as_disallow_pfcp());
1529
1530 tx := f_build_initial_ue(g_pars);
1531 f_iuh2iu_connect(tx);
1532
1533 var GtpParameters gtp_pars := valueof(t_GtpParameters);
1534 var template RAB_SetupOrModifyList rab_sml;
1535
1536 /* Send RAB Assignment Request */
1537 rab_sml := ts_RAB_SML_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.core.remote.addr), gtp_pars.core.remote.teid);
1538 tx := valueof(ts_RANAP_RabAssReq(rab_sml));
1539 BSSAP.send(tx);
1540
1541 /* Expect on Iuh: unmodified RAB Assignment Request */
1542 rx := valueof(ts_RANAP_RabAssReq(rab_sml));
Neels Hofmeyr735b6562023-03-09 02:51:28 +01001543 f_rua_expect(rx);
Neels Hofmeyrbacb74f2022-08-29 16:24:12 +02001544
1545 /* Send back RAB Assignment Response via Iuh */
1546 var template RAB_SetupOrModifiedList rab_smdl;
1547 rab_smdl := ts_RAB_SMdL_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.access.remote.addr),
1548 gtp_pars.access.remote.teid);
1549 tx := valueof(ts_RANAP_RabAssResp(rab_smdl));
1550 RUA.send(tx);
1551
1552 /* Expect on IuPS: unmodified RAB Assignment Response */
Neels Hofmeyrdc416c92023-03-09 02:47:50 +01001553 f_bssap_expect(tr_RANAP_RabAssResp(rab_smdl));
Neels Hofmeyrbacb74f2022-08-29 16:24:12 +02001554
1555 f_sleep(2.0);
1556 tx := valueof(ts_RANAP_IuReleaseCommand(ts_RanapCause_om_intervention));
1557 f_iu2iuh(tx);
1558
1559 tx := valueof(ts_RANAP_IuReleaseComplete());
1560 f_iuh2iu(tx);
1561
1562 f_sleep(2.0);
1563}
1564
1565testcase TC_ps_rab_assignment_without_pfcp() runs on test_CT {
1566 var ConnHdlr vc_conn;
1567 f_init();
1568 f_start_hnbs();
1569 f_sleep(1.0);
1570
1571 vc_conn := f_start_handler_with_pars(refers(f_tc_ps_rab_assignment_without_pfcp), t_pars(7, ps_domain := true));
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001572 vc_conn.done;
1573}
Daniel Willmann19b8d902022-01-05 09:12:34 +01001574
1575control {
1576 execute(TC_hnb_register());
Daniel Willmannc79679a2022-08-23 17:48:39 +02001577 execute(TC_hnb_register_duplicate());
Pau Espin Pedrolacf4f222022-09-27 14:33:40 +02001578 execute(TC_hnb_register_duplicate_reuse_sctp_assoc());
Daniel Willmann19b8d902022-01-05 09:12:34 +01001579 execute(TC_ranap_cs_initial_ue());
1580 execute(TC_ranap_ps_initial_ue());
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +02001581 execute(TC_ranap_cs_initial_ue_empty_cr());
1582 execute(TC_ranap_ps_initial_ue_empty_cr());
Daniel Willmann19b8d902022-01-05 09:12:34 +01001583 execute(TC_ranap_cs_bidir());
1584 execute(TC_ranap_ps_bidir());
1585 execute(TC_rab_assignment());
1586 execute(TC_rab_release());
Daniel Willmann3e15b7b2022-02-21 17:07:02 +01001587 execute(TC_rab_assign_fail());
Daniel Willmann37c877f2022-02-22 16:47:06 +01001588 execute(TC_rab_assign_mgcp_to());
Daniel Willmann19b8d902022-01-05 09:12:34 +01001589 execute(TC_ranap_cs_mo_disconnect());
1590 execute(TC_ranap_ps_mo_disconnect());
Neels Hofmeyrbacb74f2022-08-29 16:24:12 +02001591
1592 if (mp_enable_pfcp_tests) {
1593 execute(TC_ps_rab_assignment_with_pfcp());
1594 } else {
1595 execute(TC_ps_rab_assignment_without_pfcp());
1596 }
Pau Espin Pedrolf0b9fa02022-09-12 13:31:07 +02001597
1598 /* Run at the end since it makes osmo-hnbgw <= 1.3.0 crash: OS#5676 */
1599 execute(TC_hnb_reregister_reuse_sctp_assoc());
Daniel Willmann19b8d902022-01-05 09:12:34 +01001600}
1601
1602}