blob: 7429c389b9a5aacaced5becda93a6045b6a3b92a [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;
21
22import from Osmocom_CTRL_Functions all;
23import from Osmocom_CTRL_Types all;
24import from Osmocom_CTRL_Adapter all;
25
26import from StatsD_Types all;
27import from StatsD_CodecPort all;
28import from StatsD_CodecPort_CtrlFunct all;
29import from StatsD_Checker all;
30
31import from Osmocom_VTY_Functions all;
32import from TELNETasp_PortType all;
33
34import from HNBAP_Templates all;
35import from HNBAP_PDU_Descriptions all;
36
37import from RUA_IEs all;
38import from RUA_Templates all;
39import from RUA_Emulation all;
40
41import from Iuh_Emulation all;
42
43import from RANAP_Types all;
44import from RANAP_PDU_Descriptions all;
45import from RANAP_PDU_Contents all;
46import from RANAP_IEs all;
47import from RANAP_Templates all;
48
49import from RAN_Adapter all;
50
51import from RAN_Adapter all;
52import from RAN_Emulation all;
53
54import from MGCP_Emulation all;
55import from MGCP_Types all;
56import from MGCP_Templates all;
57import from MGCP_CodecPort all;
58import from SDP_Types all;
59
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +020060import from PFCP_Types all;
61import from PFCP_Emulation all;
62import from PFCP_Templates all;
63import from PFCP_CodecPort all;
64
Daniel Willmann19b8d902022-01-05 09:12:34 +010065modulepar {
66 /* IP address at which the HNodeB can be reached */
67 charstring mp_hnodeb_ip := "127.0.0.1";
68 integer mp_hnodeb_port := -1;
69
70 /* IP address at which the test binds */
71 charstring mp_hnbgw_ip := "127.0.0.1";
72 integer mp_hnbgw_iuh_port := 29169;
73
74 charstring mp_mgw_ip := "127.0.0.1";
75 integer mp_mgw_port := 2427;
76
77 RAN_Configuration mp_msc_cfg := {
78 transport := RANAP_TRANSPORT_IuCS,
79 sccp_service_type := "mtp3_itu",
80 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
81 own_pc := 188, /* 0.23.4 first MSC emulation */
82 own_ssn := 142,
83 peer_pc := 189, /* 0.23.5 osmo-hnbgw */
84 peer_ssn := 142,
85 sio := '83'O,
86 rctx := 1
87 };
88 RAN_Configuration mp_sgsn_cfg := {
89 transport := RANAP_TRANSPORT_IuCS,
90 sccp_service_type := "mtp3_itu",
91 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
92 own_pc := 185, /* 0.23.1 first SGSN emulation */
93 own_ssn := 142,
94 peer_pc := 189, /* 0.23.5 osmo-hnbgw */
95 peer_ssn := 142,
96 sio := '83'O,
97 rctx := 2
98 };
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +020099
100 /* IP address at which we listen for PFCP to emulate a UPF in ttcn3 */
101 charstring mp_pfcp_ip_local := "127.0.0.1";
102
103 /* IP address from which the SUT (osmo-hnbgw) sends PFCP requests, and to which the ttcn3 UPF emulation sends
104 * PFCP responses. */
105 charstring mp_pfcp_ip_remote := "127.0.0.2";
Daniel Willmann19b8d902022-01-05 09:12:34 +0100106}
107
108function MSC_UnitdataCallback(RANAP_PDU ranap) runs on RAN_Emulation_CT return template RANAP_PDU {
109 // TODO: Actually implement unitdata handling
110 return ts_RANAP_Reset(ts_RanapCause_om_intervention, cs_domain);
111}
112
113const RanOps MSC_RanOps := {
114 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
115 ranap_unitdata_cb := refers(MSC_UnitdataCallback),
116 ps_domain := false,
117 decode_dtap := false,
118 role_ms := false,
119 protocol := RAN_PROTOCOL_RANAP,
120 transport := RANAP_TRANSPORT_IuCS,
121 use_osmux := false,
Eric Wild6e511ce2022-04-02 21:35:56 +0200122 bssap_reset_retries := 1,
Daniel Willmann19b8d902022-01-05 09:12:34 +0100123 sccp_addr_local := omit,
124 sccp_addr_peer := omit
125}
126
127type record CrcxResponse {
128 integer resp,
129 HostName mgw_rtp_ip,
130 PortNumber mgw_rtp_port,
131 MgcpConnectionId mgcp_connection_id
132}
133type record MgcpParameters {
134 integer got_crcx_count,
135 integer got_dlcx_count,
136 MgcpCallId mgcp_call_id optional,
137 MgcpEndpoint mgcp_ep,
138 CrcxResponse mgw_conn_1,
139 CrcxResponse mgw_conn_2,
140 uint7_t rtp_payload_type,
141 charstring rtp_sdp_format,
142 HostName hnb_rtp_ip,
143 PortNumber hnb_rtp_port,
144 HostName cn_rtp_ip,
145 PortNumber cn_rtp_port,
146 boolean use_osmux,
147 integer got_osmux_count
148}
149
150template (value) MgcpParameters t_MgcpParams := {
151 got_crcx_count := 0,
152 got_dlcx_count := 0,
153 mgcp_call_id := omit,
154 mgcp_ep := "rtpbridge/1@mgw",
155 mgw_conn_1 := {
156 resp := 1,
157 mgw_rtp_ip := "127.1.2.1",
158 mgw_rtp_port := 10000,
159 mgcp_connection_id := '11111'H
160 },
161 mgw_conn_2 := {
162 resp := 1,
163 mgw_rtp_ip := "127.1.2.2",
164 mgw_rtp_port := 20000,
165 mgcp_connection_id := '22222'H
166 },
167 rtp_payload_type := 23,
168 rtp_sdp_format := "FOO",
169 hnb_rtp_ip := "127.1.1.1",
170 hnb_rtp_port := 10001,
171 cn_rtp_ip := "127.1.3.1",
172 cn_rtp_port := 20001,
173 use_osmux := false,
174 got_osmux_count := 0
175}
176
177type record TestHdlrParams {
178 integer hnb_idx,
179 hexstring imsi,
180 boolean ps_domain,
181 MgcpParameters mgcp_pars optional,
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200182 HnbConfig hnb optional,
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +0200183 boolean separate_sccp_cr,
184 charstring pfcp_local_addr
Daniel Willmann19b8d902022-01-05 09:12:34 +0100185}
186
187/* We extend:
188 * RUA_ConnHdlr (for the Iuh side, emulating the HNB)
189 * RAN_ConnHdlr (for the Iu side, emulating the MSC)
190 * MGCP_ConnHdlr (for the MGCP side, emulating the MGW)
191 */
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +0200192type component ConnHdlr extends RAN_ConnHdlr, MGCP_ConnHdlr, RUA_ConnHdlr, PFCP_ConnHdlr {
Daniel Willmann19b8d902022-01-05 09:12:34 +0100193 var integer g_sccp_conn_id;
194 var TestHdlrParams g_pars;
195 timer g_Tguard;
196}
197
198
199const MGCPOps MSC_MGCPOps := {
200 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
201 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
202}
203
204function f_create_ranap_exp(octetstring l3_enc) runs on ConnHdlr {
205 BSSAP_PROC.call(RAN_register:{l3_enc, self}) {
206 [] BSSAP_PROC.getreply(RAN_register:{?, ?}) {};
207 }
208}
209
210
211const integer NUM_HNB := 1;
212
Daniel Willmann19b8d902022-01-05 09:12:34 +0100213type record HnbConfig {
214 LocationAreaIdentification lai,
215 integer sac
216}
217
218type component test_CT extends CTRL_Adapter_CT {
219 var boolean g_initialized := false;
220
221 /********************* Iu side */
222 var RAN_Adapter g_msc;
223 var RAN_Adapter g_sgsn;
224 /* SGSN IuPS missing */
225
226 /********************* Iuh side */
227 var HnbConfig g_hnb_cfg[NUM_HNB];
228 var Iuh_Emulation_CT vc_Iuh[NUM_HNB];
229 var RUA_Emulation_CT vc_RUA[NUM_HNB];
230 port HNBAP_PT HNBAP[NUM_HNB];
231
232 var MGCP_Emulation_CT vc_MGCP;
233 port TELNETasp_PT HNBGWVTY;
234 /* global test case guard timer (actual timeout value is set in f_init()) */
235 timer T_guard := 30.0;
236}
237
238/* global altstep for global guard timer; */
239altstep as_Tguard() runs on test_CT {
240 [] T_guard.timeout {
241 setverdict(fail, "Timeout of T_guard");
242 mtc.stop;
243 }
244}
245
246friend function f_logp(TELNETasp_PT pt, charstring log_msg)
247{
248 // log on TTCN3 log output
249 log(log_msg);
250 // log in stderr log
251 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
252}
253
254function f_init_vty(charstring id := "foo") runs on test_CT {
255 if (HNBGWVTY.checkstate("Mapped")) {
256 /* skip initialization if already executed once */
257 return;
258 }
259 map(self:HNBGWVTY, system:HNBGWVTY);
260 f_vty_set_prompts(HNBGWVTY);
261 f_vty_transceive(HNBGWVTY, "enable");
262}
263
264function f_init_mgcp(charstring id) runs on test_CT {
265 id := id & "-MGCP";
266 var MGCPOps ops := {
267 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
268 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
269 }
270 var MGCP_conn_parameters pars := {
271 callagent_ip := mp_hnbgw_ip,
272 callagent_udp_port := -1,
273 mgw_ip := mp_mgw_ip,
274 mgw_udp_port := mp_mgw_port,
275 multi_conn_mode := false
276 }
277
278 vc_MGCP := MGCP_Emulation_CT.create(id);
279 map(vc_MGCP:MGCP, system:MGCP_CODEC_PT);
280 vc_MGCP.start(MGCP_Emulation.main(ops, pars, id));
281}
282
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +0200283function f_init_pfcp(charstring id) runs on ConnHdlr {
284 id := id & "-PFCP";
285
286 var PFCP_Emulation_Cfg pfcp_cfg := {
287 pfcp_bind_ip := mp_pfcp_ip_local,
288 pfcp_bind_port := PFCP_PORT,
289 pfcp_remote_ip := mp_pfcp_ip_remote,
290 pfcp_remote_port := PFCP_PORT,
291 role := UPF
292 };
293
294 vc_PFCP := PFCP_Emulation_CT.create(id) alive;
295 connect(self:PFCP, vc_PFCP:CLIENT);
296 connect(self:PFCP_PROC, vc_PFCP:CLIENT_PROC);
297 vc_PFCP.start(PFCP_Emulation.main(pfcp_cfg));
298}
299
Daniel Willmann19b8d902022-01-05 09:12:34 +0100300function f_init_hnodeb(charstring id, integer hnb_idx, RuaOps rua_ops) runs on test_CT {
301 id := id & "-Iuh" & int2str(hnb_idx);
302
303 /* Iuh lower layer (RUA/HNBAP demux) */
304 var Iuh_conn_parameters iuh_pars;
305 iuh_pars.remote_ip := mp_hnbgw_ip;
306 iuh_pars.remote_sctp_port := mp_hnbgw_iuh_port;
307 iuh_pars.local_ip := mp_hnodeb_ip;
308 iuh_pars.local_sctp_port := mp_hnodeb_port + hnb_idx;
309 vc_Iuh[hnb_idx] := Iuh_Emulation_CT.create(id);
310 connect(self:HNBAP[hnb_idx], vc_Iuh[hnb_idx]:HNBAP);
311
312 vc_RUA[hnb_idx] := RUA_Emulation_CT.create(id & "-RUA");
313 connect(vc_RUA[hnb_idx]:RUA, vc_Iuh[hnb_idx]:RUA);
314
315 /* Start Iuh side components */
316 vc_Iuh[hnb_idx].start(Iuh_Emulation.main(iuh_pars, id));
317 vc_RUA[hnb_idx].start(RUA_Emulation.main(rua_ops, id & "-RUA"));
318}
319
320/* global initialization function */
Neels Hofmeyr82e79b02022-06-08 00:08:09 +0200321function f_init(charstring id := "HNBGW", float guard_timeout := 30.0) runs on test_CT {
Daniel Willmann19b8d902022-01-05 09:12:34 +0100322
323 g_hnb_cfg[0] := {
324 lai := {
325 mcc_mnc := '00101'H,
326 lac := 2342
327 },
328 sac := 55
329 }
330 T_guard.start(guard_timeout);
331 activate(as_Tguard());
332
333 /* RUA/RANAP emulation on top of lower-layer Iuh */
334 var RuaOps rua_ops := {
335 create_cb := refers(IuhRanapCreateCallback),
336 unitdata_cb := refers(IuhRanapUnitdataCallback)
337 };
338 for (var integer i := 0; i < NUM_HNB; i := i+1) {
339 f_init_hnodeb(testcasename(), i, rua_ops);
340 }
341
342 /* MSC emulation */
343 var RanOps ranops := {
344 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
345 ranap_unitdata_cb := omit,
346 ps_domain := false,
347 decode_dtap := false,
348 role_ms := false,
349 protocol := RAN_PROTOCOL_RANAP,
350 transport := RANAP_TRANSPORT_IuCS,
351 use_osmux := false,
Eric Wild6e511ce2022-04-02 21:35:56 +0200352 bssap_reset_retries := 1,
Daniel Willmann19b8d902022-01-05 09:12:34 +0100353 sccp_addr_local := omit,
354 sccp_addr_peer := omit
355 };
356 f_ran_adapter_init(g_msc, mp_msc_cfg, "HNBGW_Test", ranops);
357 f_ran_adapter_start(g_msc);
358
359 /* SGSN emulation */
360 ranops.ps_domain := true;
361 f_ran_adapter_init(g_sgsn, mp_sgsn_cfg, "HNBGW_Test", ranops);
362 f_ran_adapter_start(g_sgsn);
363
364 f_init_mgcp(id);
365 f_init_vty("VirtHNBGW");
366}
367
368friend function f_shutdown_helper() runs on test_CT {
369 all component.stop;
370 setverdict(pass);
371 mtc.stop;
372}
373
374/* helper function to start all of the simulated hNodeBs */
375function f_start_hnbs() runs on test_CT {
376 for (var integer i:= 0; i < NUM_HNB; i := i+1) {
377 f_hnbap_register(i);
378 }
379}
380
381/***********************************************************************
382 * code running in test_CT, preparing start of per-UE ConnHdlr
383 ***********************************************************************/
384
385/* inbound RUA connection establishment on Iuh side */
386function IuhRanapCreateCallback(ContextId context_id, RUA_IEs.CN_DomainIndicator domain, charstring id)
387runs on RUA_Emulation_CT return RUA_ConnHdlr {
388 log("CreateCallback");
389 return null;
390}
391
392/* inbound RUA connectionless data on Iuh side */
393function IuhRanapUnitdataCallback(RANAP_PDU ranap)
394runs on RUA_Emulation_CT return template RANAP_PDU {
395 log("UnitdataCallback");
396 return omit;
397}
398
399private function f_start_handler_create(TestHdlrParams pars) runs on test_CT return ConnHdlr {
400 var ConnHdlr vc_conn;
401 var charstring id := testcasename() & int2str(pars.hnb_idx);
402
403 vc_conn := ConnHdlr.create(id);
404
405 /* Iuh RUA part */
406 connect(vc_conn:RUA, vc_RUA[pars.hnb_idx]:CLIENT);
407
408 if (pars.ps_domain) {
409 /* SGSN side */
410 connect(vc_conn:BSSAP, g_sgsn.vc_RAN:CLIENT);
411 connect(vc_conn:BSSAP_PROC, g_sgsn.vc_RAN:PROC);
412 } else {
413 /* MSC side */
414 connect(vc_conn:BSSAP, g_msc.vc_RAN:CLIENT);
415 connect(vc_conn:BSSAP_PROC, g_msc.vc_RAN:PROC);
416 }
417 /* MGCP part */
418 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
419 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
420
421 return vc_conn;
422}
423
424private function f_start_handler_run(ConnHdlr vc_conn, void_fn fn, TestHdlrParams pars) runs on test_CT {
425 var charstring id := testcasename(); // & int2str(pars.ran_idx);
426 /* We cannot use vc_conn.start(f_init_handler(fn, id, pars)); as we cannot have
427 * a stand-alone 'derefers()' call, see https://www.eclipse.org/forums/index.php/t/1091364/ */
428 pars.hnb := g_hnb_cfg[pars.hnb_idx];
429 pars.mgcp_pars := valueof(t_MgcpParams);
430 vc_conn.start(derefers(fn)(id, pars));
431}
432
433function f_start_handler_with_pars(void_fn fn, template (value) TestHdlrParams pars)
434runs on test_CT return ConnHdlr {
435 var ConnHdlr vc_conn;
436 vc_conn := f_start_handler_create(valueof(pars));
437 f_start_handler_run(vc_conn, fn, valueof(pars));
438 return vc_conn;
439}
440
441/***********************************************************************
442 * code running inside per-UE ConnHdlr
443 ***********************************************************************/
444
445type function void_fn(charstring id, TestHdlrParams pars) runs on ConnHdlr;
446
447function f_init_handler(TestHdlrParams pars, float t_guard := 20.0) runs on ConnHdlr {
448 /* make parameters available via component variable */
449 g_pars := pars;
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +0200450
451 f_init_pfcp(testcasename());
452
Daniel Willmann19b8d902022-01-05 09:12:34 +0100453 /* start guard timer and activate it as default */
454 g_Tguard.start(t_guard);
455 activate(as_Tguard_ConnHdlr());
456
457 /* TODO: CTRL? */
458 /* TODO: VTY? */
459}
460
461/* global altstep for global guard timer; */
462private altstep as_Tguard_ConnHdlr() runs on ConnHdlr {
463 [] g_Tguard.timeout {
464 setverdict(fail, "Timeout of T_guard");
465 mtc.stop;
466 }
467}
468
469/* send RANAP on Iuh and expect it to show up on Iu */
470function f_iuh2iu(template (present) RANAP_PDU tx, template RANAP_PDU exp_rx := omit)
471runs on ConnHdlr return RANAP_PDU {
472 var RANAP_PDU rx;
473 timer T := 5.0;
474
475 if (istemplatekind(exp_rx, "omit")) {
476 exp_rx := tx;
477 }
478
479 RUA.send(tx);
480 T.start;
481
482 alt {
483 [] BSSAP.receive(exp_rx) -> value rx {
484 setverdict(pass);
485 }
486 [] T.timeout {
487 setverdict(fail, "Timeout waiting for Iu ", exp_rx);
488 }
489 }
490 return rx;
491}
492
493/* send RANAP on Iu and expect it to show up on Iuh */
494function f_iu2iuh(template (present) RANAP_PDU tx, template RANAP_PDU exp_rx := omit)
495runs on ConnHdlr return RANAP_PDU {
496 var RANAP_PDU rx;
497 timer T := 5.0;
498
499 if (istemplatekind(exp_rx, "omit")) {
500 exp_rx := tx;
501 }
502
503 BSSAP.send(tx);
504 T.start;
505
506 alt {
507 [] RUA.receive(exp_rx) -> value rx {
508 setverdict(pass);
509 }
510 [] T.timeout {
511 setverdict(fail, "Timeout waiting for Iuh ", exp_rx);
512 }
513 }
514 return rx;
515}
516
517/* send RANAP on Iuh and expect it to show up on Iu */
518function f_iuh2iu_connect(template (present) RANAP_PDU tx, template RANAP_PDU exp_rx := omit)
519runs on ConnHdlr return RANAP_PDU {
520 var RANAP_PDU rx;
521 timer T := 5.0;
522
523 if (istemplatekind(exp_rx, "omit")) {
524 exp_rx := tx;
525 }
526
527 /* create an expect on the Iu side for the random NAS portion */
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200528 if (g_pars.separate_sccp_cr) {
529 f_ran_register_sccp_cr_without_payload();
530 } else {
531 var template (omit) octetstring nas := f_ranap_extract_l3(valueof(tx));
532 f_ran_register_exp(valueof(nas));
533 }
Daniel Willmann19b8d902022-01-05 09:12:34 +0100534
535 /* send it via Iuh (creating a RUA connection) */
536 RUA.send(RUA_Conn_Req:{g_pars.ps_domain, tx});
537
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200538 if (g_pars.separate_sccp_cr) {
539 /* Acknowledge the empty SCCP CR. RAN_Emulation does the confirmation, no need to respond. */
540 BSSAP.receive(tr_RANAP_Conn_Req());
541 }
542
Daniel Willmann19b8d902022-01-05 09:12:34 +0100543 /* expect to receive it on the Iu side */
544 T.start;
545 alt {
546 [] BSSAP.receive(exp_rx) -> value rx {
547 setverdict(pass);
548 }
549 [] T.timeout {
550 setverdict(fail, "Timeout waiting for Iu ", exp_rx);
551 }
552 }
553 return rx;
554}
555
556function f_iuh2iu_disconnect(template (present) RANAP_PDU tx, RUA_IEs.Cause cause,
557 template RANAP_PDU exp_rx := omit)
558runs on ConnHdlr return RANAP_PDU {
559 var RANAP_PDU rx
560 timer T := 5.0;
561
562 if (istemplatekind(exp_rx, "omit")) {
563 exp_rx := tx;
564 }
565
566 /* send it via Iuh (creating a RUA connection) */
567 RUA.send(RUA_Disc_Req:{tx, cause});
568
569 /* expect to receive it on the Iu side */
570 T.start;
571 alt {
572 [] BSSAP.receive(exp_rx) -> value rx {
573 }
574 [] T.timeout {
575 setverdict(fail, "Timeout waiting for Iu ", exp_rx);
576 return rx;
577 }
578 }
579
580 /* expect disconnect on the Iu side */
581 alt {
582 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
583 setverdict(pass);
584 }
585 [] T.timeout {
586 setverdict(fail, "Timeout waiting for Iu disconnect");
587 return rx;
588 }
589
590 }
591 return rx;
592}
593
594/* build a RANAP InitialUE based on the TestHdlrParams */
595friend function f_build_initial_ue(TestHdlrParams pars) return RANAP_PDU {
596 var LAI lai := {
597 pLMNidentity := hex2oct(pars.hnb.lai.mcc_mnc),
598 lAC := int2oct(pars.hnb.lai.lac, 2),
599 iE_Extensions := omit
600 };
601 var SAI sai := {
602 pLMNidentity := lai.pLMNidentity,
603 lAC := lai.lAC,
604 sAC := int2oct(pars.hnb.sac, 2),
605 iE_Extensions := omit
606 }
607 var octetstring nas := f_rnd_octstring(10);
608 var IuSignallingConnectionIdentifier sigc_id := int2bit(f_rnd_int(1000), 24);
609 var GlobalRNC_ID grnc_id := {
610 pLMNidentity := lai.pLMNidentity,
611 rNC_ID := 2342
612 }
613
614 if (pars.ps_domain) {
615 var RAC rac := '00'O;
616 return valueof(ts_RANAP_initialUE_PS(lai, rac, sai, nas, sigc_id, grnc_id));
617 } else {
618 return valueof(ts_RANAP_initialUE_CS(lai, sai, nas, sigc_id, grnc_id));
619 }
620}
621
622/* build a RANAP RAB AssignmentResponse based on the TestHdlrParams */
623friend function f_build_rab_ass_resp(TestHdlrParams pars) return RANAP_PDU {
624 var template RAB_SetupOrModifiedList rab_sml;
625
626 rab_sml := ts_RAB_SMdL(t_RAB_id(23), f_ts_RAB_TLA("192.168.1.23"), t_RAB_binding_port(1234));
627
628 return valueof(ts_RANAP_RabAssResp(rab_sml));
629}
630
631
632/***********************************************************************
633 * HNBAP Testing
634 ***********************************************************************/
635
636
637function f_hnbap_register(integer hnb_idx := 0) runs on test_CT
638{
639 timer T := 2.0;
640
641 HNBAP[hnb_idx].send(tr_HNBAP_HNBRegisterRequest(char2oct("TTCN3 HNodeB"),
642 '00F110'O,
643 int2bit(1 + hnb_idx, 28),
644 int2oct(2, 2),
645 int2oct(3, 1),
646 int2oct(4, 2)));
647
648 T.start;
649 alt {
650 [] HNBAP[hnb_idx].receive(tr_HNBAP_HNBRegisterAccept(?)) {
651 setverdict(pass);
652 }
653 [] HNBAP[hnb_idx].receive(IUHEM_Event:?) {
654 repeat;
655 }
656 [] T.timeout {
657 setverdict(fail, "Timeout waiting for HNB Register Accept");
658 }
659 }
660}
661
662testcase TC_hnb_register() runs on test_CT {
663 f_init();
664 f_hnbap_register(0);
665 f_shutdown_helper();
666}
667
668/***********************************************************************
669 * RUA / RANAP Testing
670 ***********************************************************************/
671
672private template (value) TestHdlrParams
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200673t_pars(integer imsi_suffix, boolean ps_domain := false, integer hnb_idx := 0,
674 boolean separate_sccp_cr := false) := {
Daniel Willmann19b8d902022-01-05 09:12:34 +0100675 hnb_idx := hnb_idx,
676 imsi := f_gen_imsi(imsi_suffix),
677 ps_domain := ps_domain,
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200678 hnb := omit, /* filled in later */
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +0200679 separate_sccp_cr := separate_sccp_cr,
680 pfcp_local_addr := mp_pfcp_ip_local
Daniel Willmann19b8d902022-01-05 09:12:34 +0100681}
682
683/* Create an Iuh connection; send InitialUE; expect it to appear on new SCCP conenction */
684friend function f_tc_initial_ue(charstring id, TestHdlrParams pars) runs on ConnHdlr {
685 f_init_handler(pars);
686 var RANAP_PDU tx := f_build_initial_ue(g_pars);
687 f_iuh2iu_connect(tx);
688}
689testcase TC_ranap_cs_initial_ue() runs on test_CT {
690 var ConnHdlr vc_conn;
691
692 f_init();
693 f_start_hnbs();
694
695 vc_conn := f_start_handler_with_pars(refers(f_tc_initial_ue), t_pars(1));
696 vc_conn.done;
697}
698testcase TC_ranap_ps_initial_ue() runs on test_CT {
699 var ConnHdlr vc_conn;
700
701 f_init();
702 f_start_hnbs();
703
704 vc_conn := f_start_handler_with_pars(refers(f_tc_initial_ue), t_pars(2, true));
705 vc_conn.done;
706}
707
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +0200708private function f_vty_set_sccp_cr_max_payload_len(TELNETasp_PT pt, integer val := 999999)
709{
710 f_vty_enter_config(pt);
711 f_vty_transceive(pt, "hnbgw");
712 f_vty_transceive(pt, "sccp cr max-payload-len " & int2str(val));
713 f_vty_transceive(pt, "end");
714}
715
716testcase TC_ranap_cs_initial_ue_empty_cr() runs on test_CT {
717 var ConnHdlr vc_conn;
718
719 f_init();
720 f_start_hnbs();
721
722 f_vty_set_sccp_cr_max_payload_len(HNBGWVTY, 0);
723
724 vc_conn := f_start_handler_with_pars(refers(f_tc_initial_ue), t_pars(1, separate_sccp_cr := true));
725 vc_conn.done;
726
727 /* reset */
728 f_vty_set_sccp_cr_max_payload_len(HNBGWVTY);
729}
730testcase TC_ranap_ps_initial_ue_empty_cr() runs on test_CT {
731 var ConnHdlr vc_conn;
732
733 f_init();
734 f_start_hnbs();
735
736 f_vty_set_sccp_cr_max_payload_len(HNBGWVTY, 0);
737
738 vc_conn := f_start_handler_with_pars(refers(f_tc_initial_ue), t_pars(2, true, separate_sccp_cr := true));
739 vc_conn.done;
740
741 /* reset */
742 f_vty_set_sccp_cr_max_payload_len(HNBGWVTY);
743}
744
Daniel Willmann19b8d902022-01-05 09:12:34 +0100745/* Reply to a received CRCX with an OK (or the reply configured in cpars), using the given parameters.
746 * Return true when an OK reply was sent, false otherwise.
747 * Count occurrence of Osmux, include Osmux parameters in the reply if necessary. */
748function f_handle_crcx(inout MgcpParameters pars, MgcpCommand mgcp_cmd) return template MgcpResponse {
749 var CrcxResponse conn := pars.mgw_conn_1;
750 if (pars.got_crcx_count > 0) {
751 conn := pars.mgw_conn_2;
752 }
753 pars.got_crcx_count := pars.got_crcx_count + 1;
754
755 var MgcpMessage mgcp_msg := {
756 command := mgcp_cmd
757 }
758 var template MgcpResponse mgcp_resp;
759 var MgcpOsmuxCID osmux_cid;
760 var MgcpCallId call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
761 if (ispresent(pars.mgcp_call_id)) {
762 if (pars.mgcp_call_id != call_id) {
763 setverdict(fail, "CRCX contained unexpected call id. Expected:", pars.mgcp_call_id, " got:", call_id);
764 mtc.stop;
765 }
766 } else {
767 pars.mgcp_call_id := call_id;
768 }
769
770 /* When the endpoint contains a wildcard we keep the endpoint
771 * identifier we have set up in pars. Otherwise we use the
772 * endpoint name that the call agent has supplied */
773 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard) == false) {
774 pars.mgcp_ep := mgcp_cmd.line.ep;
775 }
776
777 if (conn.resp == -1) {
778 /* Reply with rror */
779 var MgcpResponse mgcp_rsp := {
780 line := {
781 code := "542",
782 trans_id := mgcp_cmd.line.trans_id,
783 string := "FORCED_FAIL"
784 },
785 sdp := omit
786
787 }
788 var MgcpParameter mgcp_rsp_param := {
789 code := "Z",
790 val := pars.mgcp_ep
791 };
792 mgcp_rsp.params[0] := mgcp_rsp_param;
793 return mgcp_rsp;
794 }
795
796 if (conn.resp == 0) {
797 /* Do not reply at all */
798 return omit;
799 }
800
801 if (conn.resp != 1) {
802 setverdict(fail, "Unexpected value for pars.mgw_conn_*.resp, expect -1, 0 or 1");
803 mtc.stop;
804 }
805
806 var SDP_Message sdp := valueof(ts_SDP(conn.mgw_rtp_ip, conn.mgw_rtp_ip,
807 hex2str(pars.mgcp_call_id), "42",
808 conn.mgw_rtp_port,
809 { int2str(pars.rtp_payload_type) },
810 { valueof(ts_SDP_rtpmap(pars.rtp_payload_type,
811 pars.rtp_sdp_format)),
812 valueof(ts_SDP_ptime(20)) }));
813
814 if (f_mgcp_contains_par(mgcp_msg, "X-OSMUX")) {
815 if (not pars.use_osmux) {
816 setverdict(fail, "MSC sent X-Osmux parameter in MGCP, but not expecting any Osmux");
817 mtc.stop;
818 }
819 pars.got_osmux_count := pars.got_osmux_count + 1;
820 /* we expect MSC to use wildcard here, i.e. osmux_cid == -1 */
821 osmux_cid := f_MgcpCmd_extract_osmux_cid(mgcp_cmd);
822 log("f_handle_crcx(): got Osmux CID: ", osmux_cid);
823 if (osmux_cid != -1) {
824 setverdict(fail, "MSC using unexpected CID " & int2str(osmux_cid) & " != -1");
825 mtc.stop;
826 }
827
828 osmux_cid := 0;
829 mgcp_resp := ts_CRCX_ACK_osmux(mgcp_cmd.line.trans_id, conn.mgcp_connection_id, osmux_cid, sdp);
830 } else {
831 mgcp_resp := ts_CRCX_ACK(mgcp_cmd.line.trans_id, conn.mgcp_connection_id, sdp);
832 }
833
834 f_mgcp_par_append(mgcp_resp.params, ts_MgcpParSpecEP(pars.mgcp_ep));
835
836 return mgcp_resp;
837}
838
Daniel Willmann3e15b7b2022-02-21 17:07:02 +0100839friend function f_create_rab(inout MgcpParameters pars) runs on ConnHdlr {
840 f_rab_ass_req(pars);
841 f_rab_ass_resp(pars);
842}
843
844friend function f_rab_ass_req(inout MgcpParameters pars) runs on ConnHdlr {
Daniel Willmann19b8d902022-01-05 09:12:34 +0100845 var MgcpCommand mgcp_cmd;
846 var RANAP_PDU tx;
847 var template RAB_SetupOrModifyList rab_sml;
Daniel Willmann19b8d902022-01-05 09:12:34 +0100848 timer T := 5.0;
849
850 /* Send RAB Assignment Request */
851 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));
852 tx := valueof(ts_RANAP_RabAssReq(rab_sml));
853 BSSAP.send(tx);
854 T.start;
855
856 /* Handle MGCP CRCX */
857 alt {
858 [] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
859 log("CRCX1", mgcp_cmd);
860 var template MgcpResponse mgcp_rsp := f_handle_crcx(pars, mgcp_cmd);
861 MGCP.send(valueof(mgcp_rsp));
862 }
863 [] T.timeout {
864 setverdict(fail, "Timeout waiting for MGCP");
865 }
866 }
867
868 /* Expect RAB Assignment Request with IP/port from CRCX ACK via Iuh */
869 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));
870 tx := valueof(ts_RANAP_RabAssReq(rab_sml));
871
872 alt {
873 [] RUA.receive(tx) {
874 setverdict(pass);
875 }
876 [] T.timeout {
877 setverdict(fail, "Timeout waiting for Iuh ", tx);
878 }
879 }
Daniel Willmann3e15b7b2022-02-21 17:07:02 +0100880}
881
882friend function f_rab_ass_resp(inout MgcpParameters pars) runs on ConnHdlr {
883 var MgcpCommand mgcp_cmd;
884 var RANAP_PDU tx;
885 var template RAB_SetupOrModifiedList rab_smdl;
886 timer T := 5.0;
Daniel Willmann19b8d902022-01-05 09:12:34 +0100887
888 /* Send back RAB Assignment Response via Iuh */
889 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));
890 tx := valueof(ts_RANAP_RabAssResp(rab_smdl));
891 RUA.send(tx);
892 T.start;
893
894 interleave {
895 /* Expect MDCX with IP/port from RAB Assignment Response */
896 [] MGCP.receive(tr_MDCX(tr_SDP(pars.hnb_rtp_ip, pars.hnb_rtp_port))) -> value mgcp_cmd {
897 log("MDCX1", mgcp_cmd);
898 /* Verify SDP of MDCX */
899 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,
900 { int2str(pars.rtp_payload_type) }, { valueof(ts_SDP_rtpmap(pars.rtp_payload_type, pars.rtp_sdp_format)), valueof(ts_SDP_ptime(20)) } ));
901 var template MgcpResponse mgcp_rsp := ts_MDCX_ACK(mgcp_cmd.line.trans_id, pars.mgw_conn_1.mgcp_connection_id, sdp);
902 MGCP.send(valueof(mgcp_rsp));
903 }
904 /* Handle CRCX for second leg of endpoint, answer with IP/port */
905 [] MGCP.receive(tr_CRCX(pars.mgcp_ep, tr_SDP(pars.cn_rtp_ip, pars.cn_rtp_port))) -> value mgcp_cmd {
906 log("CRCX2", mgcp_cmd);
907 /* Verify SDP of CRCX */
908 var template MgcpResponse mgcp_rsp := f_handle_crcx(pars, mgcp_cmd);
909 MGCP.send(valueof(mgcp_rsp));
910 }
911 }
912
913 /* Expect RAB Assignment Response with IP/port from second CRCX ACK */
914 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));
915 tx := valueof(ts_RANAP_RabAssResp(rab_smdl));
916
917 alt {
918 [] BSSAP.receive(tx) {
919 setverdict(pass);
920 }
921 [] T.timeout {
922 setverdict(fail, "Timeout waiting for Iuh ", tx);
923 }
924 }
925}
926
927private altstep as_mgcp_dlcx(inout TestHdlrParams pars) runs on ConnHdlr {
928 var MgcpCommand mgcp_cmd;
929
930 [] MGCP.receive(tr_DLCX(pars.mgcp_pars.mgcp_ep)) -> value mgcp_cmd {
931 log("DLCX", mgcp_cmd);
932 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
933 pars.mgcp_pars.got_dlcx_count := pars.mgcp_pars.got_dlcx_count + 1;
Daniel Willmann3e15b7b2022-02-21 17:07:02 +0100934 if (pars.mgcp_pars.got_dlcx_count != pars.mgcp_pars.got_crcx_count) {
Daniel Willmann19b8d902022-01-05 09:12:34 +0100935 repeat;
936 }
937 setverdict(pass);
938 }
939}
940
941friend function f_tc_rab_assignment(charstring id, TestHdlrParams pars) runs on ConnHdlr {
942 var MgcpCommand mgcp_cmd;
943 var RANAP_PDU tx;
944 timer T := 5.0;
945
946 f_init_handler(pars);
947 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
948
949 tx := f_build_initial_ue(g_pars);
950 f_iuh2iu_connect(tx);
951
952 f_create_rab(pars.mgcp_pars);
953
954 /* Send Iu Release */
955 tx := valueof(ts_RANAP_IuReleaseCommand(ts_RanapCause_om_intervention));
956 f_iu2iuh(tx);
957
958 T.start;
959 alt {
960 [] as_mgcp_dlcx(pars) {}
961 [] T.timeout {
962 setverdict(fail, "Timeout waiting for DLCX");
963 }
964 }
965
966 tx := valueof(ts_RANAP_IuReleaseComplete());
967 f_iuh2iu(tx);
968}
969
970testcase TC_rab_assignment() runs on test_CT {
971 var ConnHdlr vc_conn;
972 f_init();
973 f_start_hnbs();
974
975 vc_conn := f_start_handler_with_pars(refers(f_tc_rab_assignment), t_pars(3));
976 vc_conn.done;
977}
978
Daniel Willmann3e15b7b2022-02-21 17:07:02 +0100979friend function f_tc_rab_assign_fail(charstring id, TestHdlrParams pars) runs on ConnHdlr {
980 var MgcpCommand mgcp_cmd;
981 var RANAP_PDU tx;
982 timer T := 5.0;
983
984 f_init_handler(pars);
985 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
986
987 tx := f_build_initial_ue(g_pars);
988 f_iuh2iu_connect(tx);
989
990 f_rab_ass_req(pars.mgcp_pars);
991
992 /* Send RAB failed list in response */
993 tx := valueof(ts_RANAP_RabAssResp(rab_fl := ts_RAB_FL(t_RAB_id(23), ts_RanapCause_om_intervention)));
994 f_iuh2iu(tx);
995
996 T.start;
997 alt {
998 [] as_mgcp_dlcx(pars) {}
999 [] T.timeout {
1000 setverdict(fail, "Timeout waiting for DLCX");
1001 }
1002 }
1003}
1004
1005testcase TC_rab_assign_fail() runs on test_CT {
1006 var ConnHdlr vc_conn;
1007 f_init();
1008 f_start_hnbs();
1009
1010 vc_conn := f_start_handler_with_pars(refers(f_tc_rab_assign_fail), t_pars(4));
1011 vc_conn.done;
1012}
1013
Daniel Willmann19b8d902022-01-05 09:12:34 +01001014friend function f_tc_rab_release(charstring id, TestHdlrParams pars) runs on ConnHdlr {
1015 var MgcpCommand mgcp_cmd;
1016 var RANAP_PDU tx;
1017 timer T := 15.0;
1018
1019 f_init_handler(pars);
1020 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1021
1022 tx := f_build_initial_ue(g_pars);
1023 f_iuh2iu_connect(tx);
1024
1025 f_create_rab(pars.mgcp_pars);
1026
1027 /* Send RAB Release */
Daniel Willmann9e789be2022-02-22 13:30:51 +01001028 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 +01001029 BSSAP.send(tx);
1030
1031 T.start;
1032
1033 alt {
1034 [] as_mgcp_dlcx(pars) {}
1035 [] T.timeout {
1036 setverdict(fail, "Timeout waiting for DLCX");
1037 }
1038 }
1039
1040 alt {
1041 [] RUA.receive(tx) {
1042 setverdict(pass);
1043 }
1044 [] T.timeout {
1045 setverdict(fail, "Timeout waiting for Iuh ", tx);
1046 }
1047 }
1048
1049}
1050
1051testcase TC_rab_release() runs on test_CT {
1052 var ConnHdlr vc_conn;
1053 f_init();
1054 f_start_hnbs();
1055
1056 vc_conn := f_start_handler_with_pars(refers(f_tc_rab_release), t_pars(5));
1057 vc_conn.done;
1058}
1059
Daniel Willmann37c877f2022-02-22 16:47:06 +01001060friend function f_tc_rab_assign_mgcp_to(charstring id, TestHdlrParams pars) runs on ConnHdlr {
1061 var MgcpCommand mgcp_cmd;
1062 var RANAP_PDU tx;
1063 var template RAB_SetupOrModifyList rab_sml;
1064 timer T := 15.0;
1065
1066 T.start;
1067 f_init_handler(pars);
1068 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1069
1070 tx := f_build_initial_ue(g_pars);
1071 f_iuh2iu_connect(tx);
1072
1073
1074 /* Send RAB Assignment Request */
1075 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));
1076 tx := valueof(ts_RANAP_RabAssReq(rab_sml));
1077 BSSAP.send(tx);
1078
1079 /* Ignore MGCP CRCX */
1080 alt {
1081 [] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
1082 log("Ignoreing CRCX1", mgcp_cmd);
1083 repeat;
1084 }
1085 [] BSSAP.receive(tr_RANAP_IuReleaseRequest(?)) { }
1086 [] T.timeout {
1087 setverdict(fail, "Timeout waiting for IuRelease");
1088 }
1089 }
1090
1091 /* Send Iu Release */
1092 tx := valueof(ts_RANAP_IuReleaseCommand(ts_RanapCause_om_intervention));
1093 f_iu2iuh(tx);
1094
1095 tx := valueof(ts_RANAP_IuReleaseComplete());
1096 f_iuh2iu(tx);
1097}
1098
1099testcase TC_rab_assign_mgcp_to() runs on test_CT {
1100 var ConnHdlr vc_conn;
1101 f_init();
1102 f_start_hnbs();
1103
1104 vc_conn := f_start_handler_with_pars(refers(f_tc_rab_assign_mgcp_to), t_pars(6));
1105 vc_conn.done;
1106}
1107
Daniel Willmann19b8d902022-01-05 09:12:34 +01001108/* Create an Iuh connection; send InitialUE; transceive data both directions */
1109friend function f_tc_ranap_bidir(charstring id, TestHdlrParams pars) runs on ConnHdlr {
1110 f_init_handler(pars);
1111
1112 /* HNB -> MSC: InitialUE */
1113 f_iuh2iu_connect(f_build_initial_ue(g_pars));
1114
1115 /* MSC <- HNB: DirectTransfer */
1116 f_iu2iuh(ts_RANAP_DirectTransfer(f_rnd_octstring(10)));
1117 /* MSC -> HNB: DirectTransfer */
1118 f_iuh2iu(ts_RANAP_DirectTransfer(f_rnd_octstring(10)));
1119
1120 /* HNB <- MSC: CommonID */
1121 f_iu2iuh(ts_RANAP_CommonId(hex2oct(pars.imsi)));
1122}
1123testcase TC_ranap_cs_bidir() runs on test_CT {
1124 var ConnHdlr vc_conn;
1125
1126 f_init();
1127 f_start_hnbs();
1128
1129 vc_conn := f_start_handler_with_pars(refers(f_tc_ranap_bidir), t_pars(3));
1130 vc_conn.done;
1131}
1132testcase TC_ranap_ps_bidir() runs on test_CT {
1133 var ConnHdlr vc_conn;
1134
1135 f_init();
1136 f_start_hnbs();
1137
1138 vc_conn := f_start_handler_with_pars(refers(f_tc_ranap_bidir), t_pars(4, true));
1139 vc_conn.done;
1140}
1141
1142
1143private function f_tc_ranap_mo_disconnect(charstring id, TestHdlrParams pars) runs on ConnHdlr {
1144 f_init_handler(pars);
1145
1146 /* HNB -> MSC: InitialUE */
1147 f_iuh2iu_connect(f_build_initial_ue(g_pars));
1148
1149 /* MSC <- HNB: DirectTransfer */
1150 f_iu2iuh(ts_RANAP_DirectTransfer(f_rnd_octstring(10)));
1151 /* MSC -> HNB: DirectTransfer */
1152 f_iuh2iu(ts_RANAP_DirectTransfer(f_rnd_octstring(10)));
1153
1154 /* MSC <- HNB: RUA disconnect */
1155 f_iuh2iu_disconnect(ts_RANAP_IuReleaseComplete, RUA_IEs.Cause:{misc:=processing_overload});
1156}
1157testcase TC_ranap_cs_mo_disconnect() runs on test_CT {
1158 var ConnHdlr vc_conn;
1159
1160 f_init();
1161 f_start_hnbs();
1162
1163 vc_conn := f_start_handler_with_pars(refers(f_tc_ranap_mo_disconnect), t_pars(5));
1164 vc_conn.done;
1165}
1166testcase TC_ranap_ps_mo_disconnect() runs on test_CT {
1167 var ConnHdlr vc_conn;
1168
1169 f_init();
1170 f_start_hnbs();
1171
1172 vc_conn := f_start_handler_with_pars(refers(f_tc_ranap_mo_disconnect), t_pars(6));
1173 vc_conn.done;
1174}
1175
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001176type record FTeid {
1177 HostName addr,
1178 OCT4 teid
1179}
1180
1181type record FTeids {
1182 FTeid local,
1183 FTeid remote
1184}
Daniel Willmann19b8d902022-01-05 09:12:34 +01001185
1186
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001187/* 'local' and 'remote' refer to the GTP information from the UPF's point of view:
1188 * HNB UPF CN
1189 * access.remote <---> access.local | core.local <---> core.remote
1190 */
1191type record GtpParameters {
1192 FTeids core,
1193 FTeids access
1194}
1195
1196/* HNB UPF CN
1197 * access.remote <---> access.local | core.local <---> core.remote
1198 * 127.0.0.4 127.0.0.3 127.0.0.2 127.0.0.1
1199 * 0x44004400 0x30303030 0x22002200 0x10101010
1200 */
1201template GtpParameters t_GtpParameters := {
1202 core := {
1203 local := {
1204 addr := "127.0.0.2",
1205 teid := '22002200'O
1206 },
1207 remote := {
1208 addr := "127.0.0.1",
1209 teid := '10101010'O
1210 }
1211 },
1212 access := {
1213 local := {
1214 addr := "127.0.0.3",
1215 teid := '30303030'O
1216 },
1217 remote := {
1218 addr := "127.0.0.4",
1219 teid := '44004400'O
1220 }
1221 }
1222}
1223
1224friend function f_tc_ps_rab_assignment(charstring id, TestHdlrParams pars) runs on ConnHdlr {
1225 var RANAP_PDU tx;
1226 var RANAP_PDU rx;
1227 timer T := 5.0;
1228
1229 f_init_handler(pars);
1230
1231 f_pfcp_register();
1232
1233 var PDU_PFCP m;
1234 var Node_ID upf_node_id := valueof(ts_PFCP_Node_ID_fqdn("\07osmocom\03org"));
1235
1236 PFCP.receive(tr_PFCP_Assoc_Setup_Req()) -> value m;
1237 PFCP.send(ts_PFCP_Assoc_Setup_Resp(m.sequence_number, upf_node_id,
1238 ts_PFCP_Cause(REQUEST_ACCEPTED), 1234));
1239
1240 tx := f_build_initial_ue(g_pars);
1241 f_iuh2iu_connect(tx);
1242
1243 var GtpParameters gtp_pars := valueof(t_GtpParameters);
1244 var template RAB_SetupOrModifyList rab_sml;
1245
1246 /* Send RAB Assignment Request */
1247 rab_sml := ts_RAB_SML_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.core.remote.addr), gtp_pars.core.remote.teid);
1248 tx := valueof(ts_RANAP_RabAssReq(rab_sml));
1249 BSSAP.send(tx);
1250
1251 /* Expect PFCP Session Establishment Request. */
1252 PFCP.receive(tr_PFCP_Session_Est_Req()) -> value m;
1253 var F_SEID hnbgw_f_seid := m.message_body.pfcp_session_establishment_request.CP_F_SEID;
1254 var PFCP_Session_Establishment_Request serq := m.message_body.pfcp_session_establishment_request;
1255
1256 /* Acting as UPF, invent a new PFCP SEID to send to HNBGW. Respond to the Session Establishment.
1257 * The PFCP response must have the same sequence_number as the request. */
1258 var F_SEID up_f_seid := valueof(ts_PFCP_F_SEID_ipv4("127.0.0.1", '1111111111111111'O));
1259 var template PDU_PFCP r := ts_PFCP_Session_Est_Resp(m.sequence_number, upf_node_id, hnbgw_f_seid.seid);
1260 r.message_body.pfcp_session_establishment_response := {
1261 offending_ie := omit,
1262 UP_F_SEID := up_f_seid,
1263 created_PDR_list := {
1264 ts_PFCP_Created_PDR(pdr_id := serq.create_PDR_list[0].grouped_ie.pdr_id,
1265 local_F_TEID := ts_PFCP_F_TEID_ipv4(gtp_pars.core.local.teid,
1266 gtp_pars.core.local.addr)),
1267 ts_PFCP_Created_PDR(pdr_id := serq.create_PDR_list[1].grouped_ie.pdr_id,
1268 local_F_TEID := ts_PFCP_F_TEID_ipv4(gtp_pars.access.local.teid,
1269 gtp_pars.access.local.addr))
1270 },
1271 load_control_information := omit,
1272 overload_control_information := omit,
1273 node_list := omit,
1274 failed_rule_id := omit,
1275 created_traffic_endpoint_list := omit
1276 };
1277 PFCP.send(r);
1278
1279 /* Expect on Iuh: RAB Assignment Request with IP/port from PFCP Session Est Resp */
1280 rab_sml := ts_RAB_SML_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.access.local.addr),
1281 gtp_pars.access.local.teid);
1282 rx := valueof(ts_RANAP_RabAssReq(rab_sml));
1283 RUA.receive(rx);
1284
1285 /* Send back RAB Assignment Response via Iuh */
1286 var template RAB_SetupOrModifiedList rab_smdl;
1287 rab_smdl := ts_RAB_SMdL_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.access.remote.addr),
1288 gtp_pars.access.remote.teid);
1289 tx := valueof(ts_RANAP_RabAssResp(rab_smdl));
1290 RUA.send(tx);
1291 T.start;
1292
1293 PFCP.receive(tr_PFCP_Session_Mod_Req(up_f_seid.seid)) -> value m;
1294 r := ts_PFCP_Session_Mod_Resp(m.sequence_number, hnbgw_f_seid.seid);
1295 PFCP.send(r);
1296
1297 rab_smdl := ts_RAB_SMdL_ps(t_RAB_id(23), f_ts_RAB_TLA(gtp_pars.core.local.addr), gtp_pars.core.local.teid);
1298 BSSAP.receive(tr_RANAP_RabAssResp(rab_smdl));
1299
1300 f_sleep(2.0);
1301 tx := valueof(ts_RANAP_IuReleaseCommand(ts_RanapCause_om_intervention));
1302 f_iu2iuh(tx);
1303
1304 tx := valueof(ts_RANAP_IuReleaseComplete());
1305 f_iuh2iu(tx);
1306
1307 PFCP.receive(tr_PFCP_Session_Del_Req(up_f_seid.seid)) -> value m;
1308 PFCP.send(ts_PFCP_Session_Del_Resp(m.sequence_number, hnbgw_f_seid.seid));
1309
1310 f_sleep(2.0);
1311}
1312
1313testcase TC_ps_rab_assignment() runs on test_CT {
1314 var ConnHdlr vc_conn;
1315 f_init();
1316 f_start_hnbs();
1317 f_sleep(1.0);
1318
1319 vc_conn := f_start_handler_with_pars(refers(f_tc_ps_rab_assignment), t_pars(7, ps_domain := true));
1320 vc_conn.done;
1321}
Daniel Willmann19b8d902022-01-05 09:12:34 +01001322
1323control {
1324 execute(TC_hnb_register());
1325 execute(TC_ranap_cs_initial_ue());
1326 execute(TC_ranap_ps_initial_ue());
Neels Hofmeyrf0b9ed12022-06-07 17:46:32 +02001327 execute(TC_ranap_cs_initial_ue_empty_cr());
1328 execute(TC_ranap_ps_initial_ue_empty_cr());
Daniel Willmann19b8d902022-01-05 09:12:34 +01001329 execute(TC_ranap_cs_bidir());
1330 execute(TC_ranap_ps_bidir());
1331 execute(TC_rab_assignment());
1332 execute(TC_rab_release());
Daniel Willmann3e15b7b2022-02-21 17:07:02 +01001333 execute(TC_rab_assign_fail());
Daniel Willmann37c877f2022-02-22 16:47:06 +01001334 execute(TC_rab_assign_mgcp_to());
Daniel Willmann19b8d902022-01-05 09:12:34 +01001335 execute(TC_ranap_cs_mo_disconnect());
1336 execute(TC_ranap_ps_mo_disconnect());
Neels Hofmeyra56e8fd2022-05-08 01:16:55 +02001337 execute(TC_ps_rab_assignment());
Daniel Willmann19b8d902022-01-05 09:12:34 +01001338}
1339
1340}