blob: 29f0bbb61dfb15d5ee3535a1f646c546b8d1577e [file] [log] [blame]
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +01001module HNB_Tests {
2
3/* Integration Tests for OsmoHNodeB
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 OsmoHNodB while emulating both multiple UE as
13 * well as the HNBGW. See README for more details.
14 *
15 * There are test cases that run in so-called 'handler mode' and test cases
16 * that run directly on top of the BSSAP and RSL CodecPorts. The "handler mode"
17 * tests abstract the multiplexing/demultiplexing of multiple SCCP connections
18 * and/or RSL channels and are hence suitable for higher-level test cases, while
19 * the "raw" tests directly on top of the CodecPorts are more suitable for lower-
20 * level testing.
21 */
22
23import from Misc_Helpers all;
24import from General_Types all;
25import from Osmocom_Types all;
26import from IPL4asp_Types all;
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +010027import from Native_Functions all;
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +010028
29import from Osmocom_CTRL_Functions all;
30import from Osmocom_CTRL_Types all;
31import from Osmocom_CTRL_Adapter all;
32
33import from StatsD_Types all;
34import from StatsD_CodecPort all;
35import from StatsD_CodecPort_CtrlFunct all;
36import from StatsD_Checker all;
37
38import from Osmocom_VTY_Functions all;
39import from TELNETasp_PortType all;
40
41import from HNBAP_Templates all;
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +010042import from RUA_IEs all;
43import from RUA_Templates all;
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +010044
45import from HNBGW_ConnectionHandler all;
46import from Iuh_Emulation all;
47
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +010048import from RTP_Types all;
49import from RTP_Emulation all;
50
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +010051import from HNBLLIF_CodecPort all;
52import from HNBLLIF_Types all;
53import from HNBLLIF_Templates all;
54
Pau Espin Pedrol9e183722021-12-02 20:12:25 +010055import from GTPU_Types all;
Pau Espin Pedrol4b090c92024-02-29 19:47:07 +010056import from GTPv1U_Templates all;
Pau Espin Pedrol9e183722021-12-02 20:12:25 +010057import from GTP_Emulation all;
58
Pau Espin Pedrol58a69df2021-12-21 14:48:23 +010059import from IuUP_Types all;
60
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +010061modulepar {
62 /* IP address at which the HNodeB can be reached */
63 charstring mp_hnodeb_ip := "127.0.0.1";
64
65 /* IP address at which the test binds */
66 charstring mp_hnbgw_iuh_ip := "127.0.0.1";
67 integer mp_hnbgw_iuh_port := 29169;
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +010068
69 charstring mp_hnbllif_sk_path := HNBLL_SOCK_DEFAULT;
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +010070}
71
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +010072const hexstring ranap_cm_service_req := '001340400000060003400100000f40060000f11028b6003a40080000f110ffffffff0010400e0d052411035758a605f44e9d4aef004f400300001c0056400500f1100017'H;
73const hexstring ranap_auth_req := '00144032000002001040262505120217dc146aeac56cb5ff6d5fb51f47f19220108ca5a6d0c8110000b9e9272498872764003b400100'H;
74const hexstring ranap_auth_resp := '001440140000010010400d0c0554ccbdd0302104002f3ae4'H;
75const hexstring ranap_paging := '000e401e0000030003400100001740095000010100000000f10040400500b6cf4773'H;
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +010076const hexstring ranap_rab_ass_req := '0000005900000100364052000001003500487824cd80102fa7201a2c0000f44c080a028000514000272028140067400000222814003c40000000503d02000227c03500010a0901a200000000000000000000000000401f4a0000400100'H;
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +010077const hexstring iu_release_compl := '20010003000000'H;
78
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +010079type component test_CT extends CTRL_Adapter_CT {
80 port TELNETasp_PT HNBVTY;
81
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +010082 /* HNBLLIF Interface of HNodeB */
83 port HNBLLIF_CODEC_PT LLSK;
84 var integer g_llsk_conn_id;
85
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +010086 /* global test case guard timer (actual timeout value is set in f_init()) */
87 timer T_guard := 30.0;
88}
89
90/* global altstep for global guard timer; */
91altstep as_Tguard() runs on test_CT {
92 [] T_guard.timeout {
93 setverdict(fail, "Timeout of T_guard");
94 mtc.stop;
95 }
96}
97
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +010098function f_init_vty(charstring id := "foo") runs on test_CT {
99 if (HNBVTY.checkstate("Mapped")) {
100 /* skip initialization if already executed once */
101 return;
102 }
103 map(self:HNBVTY, system:HNBVTY);
104 f_vty_set_prompts(HNBVTY);
105 f_vty_transceive(HNBVTY, "enable");
106}
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100107
Pau Espin Pedrol85e18532022-06-09 11:49:33 +0200108private function f_init_hnbllif(TestHdlrParams pars) runs on test_CT {
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100109 map(self:LLSK, system:LLSK);
Pau Espin Pedrol85e18532022-06-09 11:49:33 +0200110 f_start_hnbllif(LLSK, testcasename(), pars, g_llsk_conn_id);
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100111}
112
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100113/* global initialization function */
114function f_init(float guard_timeout := 30.0) runs on test_CT {
115 var integer bssap_idx;
116
117 T_guard.start(guard_timeout);
118 activate(as_Tguard());
119
120 f_init_vty("VirtHNBGW");
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100121}
122
123friend function f_shutdown_helper() runs on test_CT {
124 all component.stop;
125 setverdict(pass);
126 mtc.stop;
127}
128
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100129private function f_gen_test_hdlr_pars() runs on test_CT return TestHdlrParams {
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100130
131 var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100132 pars.hnbllif_sk_path := mp_hnbllif_sk_path;
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100133 pars.hnodeb_addr := mp_hnodeb_ip;
134 pars.hnbgw_addr := mp_hnbgw_iuh_ip;
135 pars.hnbgw_port := mp_hnbgw_iuh_port;
136 return pars;
137}
138
139type function void_fn(charstring id) runs on HNBGW_ConnHdlr;
140
141/* helper function to create and connect a HNBGW_ConnHdlr component */
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100142private function f_connect_handler(inout HNBGW_ConnHdlr vc_conn, TestHdlrParams pars) runs on test_CT {
143 if (pars.hnbllif_sk_path != "") {
144 map(vc_conn:LLSK, system:LLSK);
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100145 }
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100146}
147
148function f_start_handler_create(TestHdlrParams pars)
149runs on test_CT return HNBGW_ConnHdlr {
150 var charstring id := testcasename();
151 var HNBGW_ConnHdlr vc_conn;
Pau Espin Pedrol36fc3682024-03-12 11:21:41 +0100152 vc_conn := HNBGW_ConnHdlr.create(id) alive;
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100153 f_connect_handler(vc_conn, pars);
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100154 return vc_conn;
155}
156
157function f_start_handler_run(HNBGW_ConnHdlr vc_conn, void_fn fn, TestHdlrParams pars)
158runs on test_CT return HNBGW_ConnHdlr {
159 var charstring id := testcasename();
160 /* Emit a marker to appear in the SUT's own logging output */
161 f_logp(HNBVTY, id & "() start");
162 vc_conn.start(f_handler_init(fn, id, pars));
163 return vc_conn;
164}
165
166function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars_tmpl := omit)
167runs on test_CT return HNBGW_ConnHdlr {
168 var TestHdlrParams pars;
Pau Espin Pedrolc22fb5f2022-06-09 14:34:47 +0200169 if (istemplatekind(pars_tmpl, "omit")) {
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100170 pars := valueof(f_gen_test_hdlr_pars());
Pau Espin Pedrolc22fb5f2022-06-09 14:34:47 +0200171 } else {
172 pars := valueof(pars_tmpl);
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100173 }
174 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
175}
176
177/* first function inside ConnHdlr component; sets g_pars + starts function */
178private function f_handler_init(void_fn fn, charstring id, TestHdlrParams pars)
179runs on HNBGW_ConnHdlr {
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100180 f_HNBGW_ConnHdlr_init(id, pars);
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100181 HNBAP.receive(IUHEM_Event:{up_down:=IUHEM_EVENT_UP}); /* Wait for HNB to connect to us */
182 fn.apply(id);
183}
184
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100185private function f_tc_hnb_register_request_accept(charstring id) runs on HNBGW_ConnHdlr {
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100186 f_handle_hnbap_hnb_register_req();
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100187 LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONFIGURE_IND(g_pars.mcc, g_pars.mnc, g_pars.cell_identity,
188 g_pars.lac, g_pars.rac, g_pars.sac, g_pars.rnc_id)));
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100189 f_sleep(1.0);
190}
191testcase TC_hnb_register_request_accept() runs on test_CT {
192 var HNBGW_ConnHdlr vc_conn;
193
194 f_init();
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100195 vc_conn := f_start_handler(refers(f_tc_hnb_register_request_accept));
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100196 vc_conn.done;
197 f_shutdown_helper();
198}
199
200private function f_tc_hnb_register_reject(charstring id) runs on HNBGW_ConnHdlr {
201 HNBAP.receive(tr_HNBAP_HNBRegisterRequest(char2oct(g_pars.hNB_Identity_Info),
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100202 f_enc_mcc_mnc(g_pars.mcc, g_pars.mnc),
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100203 int2bit(g_pars.cell_identity, 28),
204 int2oct(g_pars.lac, 2),
205 int2oct(g_pars.rac, 1),
206 int2oct(g_pars.sac, 2)
207 ));
208 HNBAP.send(ts_HNBAP_HNBRegisterReject(ts_HnbapCause(overload)));
209 f_sleep(1.0);
210}
211testcase TC_hnb_register_request_reject() runs on test_CT {
212 var HNBGW_ConnHdlr vc_conn;
213
214 f_init();
215 vc_conn := f_start_handler(refers(f_tc_hnb_register_reject));
216 vc_conn.done;
217 f_shutdown_helper();
218}
219
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100220private function f_tc_mo_conn(charstring id) runs on HNBGW_ConnHdlr {
221 const integer context_id := 30;
222 const bitstring context_id_bstr := '000000000000000000011110'B; /* encoded context_id */
223 const Establishment_Cause est_cause := normal_call;
224 f_handle_hnbap_hnb_register_req();
225
226 LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONFIGURE_IND(g_pars.mcc, g_pars.mnc, g_pars.cell_identity,
227 g_pars.lac, g_pars.rac, g_pars.sac, g_pars.rnc_id)));
228
229 /* Now an UE attempts CM Service Request: */
230 LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_ESTABLISH_REQ(context_id, 1, enum2int(est_cause), hex2oct(ranap_cm_service_req))));
231 /* The related RUA Connect + RANAP message is received on Iuh: */
232 RUA.receive(tr_RUA_Connect(ps_domain, context_id_bstr, est_cause, hex2oct(ranap_cm_service_req)));
233
234 /* Now HNBGW answers with RUA-DirectTransfer(RANAP-AuthenticationRequest) */
235 RUA.send(ts_RUA_DirectTransfer(ps_domain, context_id_bstr, hex2oct(ranap_auth_req)));
236
237 /* Now on LLSK first the Conn establishment is confirmed and then we receive data */
238 LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONN_ESTABLISH_CNF(context_id, 1, 0)));
239 LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONN_DATA_IND(context_id, 1, hex2oct(ranap_auth_req))));
240
241 /* UE answers with RANAPAuthenticationResponse: */
242 LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_DATA_REQ(context_id, 1, hex2oct(ranap_auth_resp))));
243 RUA.receive(tr_RUA_DirectTransfer(ps_domain, context_id_bstr, hex2oct(ranap_auth_resp)));
244
245 /* UE sends Iu Release Complete to release the conn */
246 LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_RELEASE_REQ(context_id, 1, 0, 0, hex2oct(iu_release_compl))));
247 RUA.receive(tr_RUA_Disconnect(ps_domain, context_id_bstr, ts_RUA_Cause(normal), hex2oct(iu_release_compl)));
248}
249testcase TC_mo_conn() runs on test_CT {
250 var HNBGW_ConnHdlr vc_conn;
251
252 f_init();
253 vc_conn := f_start_handler(refers(f_tc_mo_conn));
254 vc_conn.done;
255 f_shutdown_helper();
256}
257
258
259private function f_tc_paging(charstring id) runs on HNBGW_ConnHdlr {
260 const integer context_id := 30;
261 const bitstring context_id_bstr := '000000000000000000011110'B; /* encoded context_id */
262 f_handle_hnbap_hnb_register_req();
263
264 LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONFIGURE_IND(g_pars.mcc, g_pars.mnc, g_pars.cell_identity,
265 g_pars.lac, g_pars.rac, g_pars.sac, g_pars.rnc_id)));
266
267 /* HNBGW sends RUA-ConnectionlessTransfer(RANAP-Paging) */
268 RUA.send(ts_RUA_ConnectionlessTransfer(hex2oct(ranap_paging)));
269
270 LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_UNITDATA_IND(hex2oct(ranap_paging))));
271
272 /* Here it would continue with UE-side answers with RUA-Connect(RANAP-PagingResponse) */
273}
274testcase TC_paging() runs on test_CT {
275 var HNBGW_ConnHdlr vc_conn;
276
277 f_init();
278 vc_conn := f_start_handler(refers(f_tc_paging));
279 vc_conn.done;
280 f_shutdown_helper();
281}
282
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +0100283private function f_tc_cs_mo_call(charstring id) runs on HNBGW_ConnHdlr {
284 const integer context_id := 30;
285 const bitstring context_id_bstr := '000000000000000000011110'B; /* encoded context_id */
286 const Establishment_Cause est_cause := normal_call;
287 var HNBLLIF_send_data sd;
288 var PDU_RTP rtp_pdu;
289 var octetstring rtp_payload;
290 var HostName hnodeb_rtp_addr;
291 var PortNumber hnodeb_rtp_port;
292 timer Tu;
Pau Espin Pedrol25142452021-12-14 18:43:46 +0100293 var uint32_t audio_conn_id;
Pau Espin Pedrol58a69df2021-12-21 14:48:23 +0100294 var IuUP_FQC fqc := IuUP_FQC_GOOD;
Pau Espin Pedroldef56572022-06-09 11:55:06 +0200295 var template (omit) HNBLLIF_AUDIO_RFCIs rfcis_tpl := omit;
296
297 if (g_pars.hnbllif_sapi_audio_version >= 1) {
298 var HNBLLIF_AUDIO_RFCIs rfcis;
299 /* generate some unordered RFCI list of 3 elements (the default): */
300 rfcis[0] := 1; rfcis[1] := 2; rfcis[2] := 0;
301 for (var integer i := 3; i < HNBLLIF_MAX_RFCIS; i := i + 1) {
302 rfcis[i] := 0;
303 }
304 rfcis_tpl := rfcis;
305 }
Pau Espin Pedrol58a69df2021-12-21 14:48:23 +0100306
307 rtp_payload := f_rnd_octstring(6);
308 f_HNBGW_rtpem_activate(rtp_payload);
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +0100309
310 f_handle_hnbap_hnb_register_req();
311
312 LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONFIGURE_IND(g_pars.mcc, g_pars.mnc, g_pars.cell_identity,
313 g_pars.lac, g_pars.rac, g_pars.sac, g_pars.rnc_id)));
314
315 /* Now an UE attempts CM Service Request: */
316 LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_ESTABLISH_REQ(context_id, 0, enum2int(est_cause), hex2oct(ranap_cm_service_req))));
317 /* The related RUA Connect + RANAP message is received on Iuh: */
318 RUA.receive(tr_RUA_Connect(cs_domain, context_id_bstr, est_cause, hex2oct(ranap_cm_service_req)));
319
320 /* Now HNBGW answers with RUA-DirectTransfer(RANAP-RabASsReq) */
321 RUA.send(ts_RUA_DirectTransfer(cs_domain, context_id_bstr, hex2oct(ranap_rab_ass_req)));
322
323 /* Now on LLSK first the Conn establishment is confirmed and then we receive data */
324 LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONN_ESTABLISH_CNF(context_id, 0, 0)));
325 LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONN_DATA_IND(context_id, 0, hex2oct(ranap_rab_ass_req))));
326
327 /* Now LLSK provides the remote TransportLayerAddress from RabAssReq and asks SUT to provide a local address: */
328 LLSK.send(f_llsk_tx(ts_HNBLLIF_AUDIO_CONN_ESTABLISH_REQ(context_id, g_pars.hnbgw_rtp_port, HNBLL_IF_ADDR_TYPE_IPV4,
Pau Espin Pedroldef56572022-06-09 11:55:06 +0200329 f_HNBLLIF_Addr(HNBLL_IF_ADDR_TYPE_IPV4, g_pars.hnbgw_addr),
330 rfci := rfcis_tpl)));
Pau Espin Pedrol25142452021-12-14 18:43:46 +0100331 LLSK.receive(f_llsk_rx(tr_HNBLLIF_AUDIO_CONN_ESTABLISH_CNF(context_id, ?, 0, ?, HNBLL_IF_ADDR_TYPE_IPV4, ?))) -> value sd;
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +0100332
Pau Espin Pedrol25142452021-12-14 18:43:46 +0100333 audio_conn_id := sd.data.u.audio.u.conn_establish.u.cnf.audio_conn_id;
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +0100334 hnodeb_rtp_addr := f_inet_ntoa(sd.data.u.audio.u.conn_establish.u.cnf.local_addr);
335 if (not match(g_pars.hnodeb_addr, hnodeb_rtp_addr)) {
336 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "hnodeb RTP local address doesn't match expectations");
337 }
338 hnodeb_rtp_port := sd.data.u.audio.u.conn_establish.u.cnf.local_rtp_port;
Pau Espin Pedrol58a69df2021-12-21 14:48:23 +0100339 f_HNBGW_rtpem_connect(hnodeb_rtp_addr, hnodeb_rtp_port);
340
341 /* We should eventually receive some RTP/IUUP from the HNBGW once Init phase goes on: */
342 Tu.start(2.0);
343 alt {
344 [] LLSK.receive(f_llsk_rx(tr_HNBLLIF_AUDIO_CONN_DATA_IND(audio_conn_id, ?, enum2int(fqc), ?, rtp_payload)));
345 [] Tu.timeout {
346 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for Downlink speech frames");
347 }
348 }
349 Tu.stop;
350 f_rtpem_mode(RTPEM_CTRL, RTPEM_MODE_RXONLY);
351
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +0100352 /* Make sure that Uplink frames are received at the HNBGW */
353 RTPEM_DATA.clear;
Pau Espin Pedrol58a69df2021-12-21 14:48:23 +0100354 LLSK.send(f_llsk_tx(ts_HNBLLIF_AUDIO_CONN_DATA_REQ(audio_conn_id, 1, enum2int(fqc), 0, rtp_payload)));
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +0100355 Tu.start(2.0);
356 alt {
357 [] RTPEM_DATA.receive(PDU_RTP:?) -> value rtp_pdu {
358 if (rtp_pdu.data != rtp_payload) {
359 log("Unexpected RTP payload received!");
360 repeat;
361 }
362 }
363 [] RTPEM_DATA.receive { repeat; }
364 [] Tu.timeout {
365 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for Uplink speech frames");
366 }
367 }
368 Tu.stop;
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +0100369
370 f_rtpem_mode(RTPEM_CTRL, RTPEM_MODE_NONE);
Pau Espin Pedrol58a69df2021-12-21 14:48:23 +0100371 f_sleep(0.5); /* give some time to RTP_Emu to stop sending RTP packets... */
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +0100372
Pau Espin Pedrol25142452021-12-14 18:43:46 +0100373 LLSK.send(f_llsk_tx(ts_HNBLLIF_AUDIO_CONN_RELEASE_REQ(audio_conn_id)));
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +0100374
375 /* UE sends Iu Release Complete to release the conn */
376 LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_RELEASE_REQ(context_id, 0, 0, 0, hex2oct(iu_release_compl))));
377 RUA.receive(tr_RUA_Disconnect(cs_domain, context_id_bstr, ts_RUA_Cause(normal), hex2oct(iu_release_compl)));
378}
379testcase TC_cs_mo_call() runs on test_CT {
380 var HNBGW_ConnHdlr vc_conn;
381
382 f_init();
383 vc_conn := f_start_handler(refers(f_tc_cs_mo_call));
384 vc_conn.done;
385 f_shutdown_helper();
386}
Pau Espin Pedroldef56572022-06-09 11:55:06 +0200387/* Same as TC_cs_mo_call, but using AUDIO SAPI version 0 (no rfci param
388 * in HNBLLIF_AUDIO_conn_establish_req) */
389testcase TC_cs_mo_call_audio_v0() runs on test_CT {
390 var HNBGW_ConnHdlr vc_conn;
391 var TestHdlrParams pars;
392
393 f_init();
394 pars := valueof(f_gen_test_hdlr_pars());
395 pars.hnbllif_sapi_audio_version := 0;
396 vc_conn := f_start_handler(refers(f_tc_cs_mo_call), pars);
397 vc_conn.done;
398 f_shutdown_helper();
399}
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +0100400
Pau Espin Pedrol9e183722021-12-02 20:12:25 +0100401private function f_tc_ps_mo_gtp_ping_pong(charstring id) runs on HNBGW_ConnHdlr {
402 const integer context_id := 30;
403 const bitstring context_id_bstr := '000000000000000000011110'B; /* encoded context_id */
404 const Establishment_Cause est_cause := normal_call;
405 var uint32_t remote_tei := 8888;
406 var uint32_t local_tei;
407 var octetstring gtp_payload := f_rnd_octstring(40);
408 var HNBLLIF_send_data sd;
Pau Espin Pedrol25142452021-12-14 18:43:46 +0100409 var uint32_t gtp_conn_id;
Pau Espin Pedrol9e183722021-12-02 20:12:25 +0100410
411 f_gtp_register_teid(int2oct(remote_tei, 4));
412
413 f_handle_hnbap_hnb_register_req();
414
415 LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONFIGURE_IND(g_pars.mcc, g_pars.mnc, g_pars.cell_identity,
416 g_pars.lac, g_pars.rac, g_pars.sac, g_pars.rnc_id)));
417
418 /* Now an UE attempts CM Service Request: */
419 LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_ESTABLISH_REQ(context_id, 1, enum2int(est_cause), hex2oct(ranap_cm_service_req))));
420 /* The related RUA Connect + RANAP message is received on Iuh: */
421 RUA.receive(tr_RUA_Connect(ps_domain, context_id_bstr, est_cause, hex2oct(ranap_cm_service_req)));
422
423 /* Now HNBGW answers with RUA-DirectTransfer(RANAP-RabASsReq) */
424 RUA.send(ts_RUA_DirectTransfer(ps_domain, context_id_bstr, hex2oct(ranap_rab_ass_req)));
425
426 /* Now on LLSK first the Conn establishment is confirmed and then we receive data */
427 LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONN_ESTABLISH_CNF(context_id, 1, 0)));
428 LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONN_DATA_IND(context_id, 1, hex2oct(ranap_rab_ass_req))));
429
430 /* Now LLSK provides the remote TransportLayerAddress from RabAssReq and asks SUT to provide a local address: */
431 LLSK.send(f_llsk_tx(ts_HNBLLIF_GTP_CONN_ESTABLISH_REQ(context_id, remote_tei, HNBLL_IF_ADDR_TYPE_IPV4,
432 f_HNBLLIF_Addr(HNBLL_IF_ADDR_TYPE_IPV4, g_pars.hnbgw_addr))));
Pau Espin Pedrol25142452021-12-14 18:43:46 +0100433 LLSK.receive(f_llsk_rx(tr_HNBLLIF_GTP_CONN_ESTABLISH_CNF(context_id, ?, ?, 0,
Pau Espin Pedrol9e183722021-12-02 20:12:25 +0100434 HNBLL_IF_ADDR_TYPE_IPV4, ?))) -> value sd;
Pau Espin Pedrol25142452021-12-14 18:43:46 +0100435 gtp_conn_id := sd.data.u.gtp.u.conn_establish.u.cnf.gtp_conn_id;
Pau Espin Pedrol9e183722021-12-02 20:12:25 +0100436 local_tei := sd.data.u.gtp.u.conn_establish.u.cnf.local_tei;
437
438 /* Forward GTP data in both directions */
Pau Espin Pedrol25142452021-12-14 18:43:46 +0100439 LLSK.send(f_llsk_tx(ts_HNBLLIF_GTP_CONN_DATA_REQ(gtp_conn_id, gtp_payload)));
Pau Espin Pedrol9e183722021-12-02 20:12:25 +0100440 GTP.receive(tr_GTPU_GPDU(ts_GtpPeerU(g_pars.hnodeb_addr), int2oct(remote_tei, 4), gtp_payload));
441 f_gtpu_send(local_tei, gtp_payload);
Pau Espin Pedrol25142452021-12-14 18:43:46 +0100442 LLSK.receive(f_llsk_rx(tr_HNBLLIF_GTP_CONN_DATA_IND(gtp_conn_id, gtp_payload)));
Pau Espin Pedrol9e183722021-12-02 20:12:25 +0100443
444 /* Done, release GTP conn */
Pau Espin Pedrol25142452021-12-14 18:43:46 +0100445 LLSK.send(f_llsk_tx(ts_HNBLLIF_GTP_CONN_RELEASE_REQ(gtp_conn_id)));
Pau Espin Pedrol9e183722021-12-02 20:12:25 +0100446
447 /* UE sends Iu Release Complete to release the conn */
448 LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_RELEASE_REQ(context_id, 1, 0, 0, hex2oct(iu_release_compl))));
449 RUA.receive(tr_RUA_Disconnect(ps_domain, context_id_bstr, ts_RUA_Cause(normal), hex2oct(iu_release_compl)));
450}
451testcase TC_ps_mo_gtp_ping_pong() runs on test_CT {
452 var HNBGW_ConnHdlr vc_conn;
453
454 f_init();
455 vc_conn := f_start_handler(refers(f_tc_ps_mo_gtp_ping_pong));
456 vc_conn.done;
457 f_shutdown_helper();
458}
459
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100460control {
461 execute( TC_hnb_register_request_accept() );
462 execute( TC_hnb_register_request_reject() );
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100463 execute( TC_mo_conn() );
464 execute( TC_paging() );
Pau Espin Pedroldef56572022-06-09 11:55:06 +0200465 execute( TC_cs_mo_call_audio_v0() );
Pau Espin Pedrol32fb54e2021-11-29 16:21:26 +0100466 execute( TC_cs_mo_call() );
Pau Espin Pedrol9e183722021-12-02 20:12:25 +0100467 execute( TC_ps_mo_gtp_ping_pong() );
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100468}
469
470}