blob: 59dd1ee21d560d983cfa7cb95009bcbfd27d2ce1 [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;
27
28import from Osmocom_CTRL_Functions all;
29import from Osmocom_CTRL_Types all;
30import from Osmocom_CTRL_Adapter all;
31
32import from StatsD_Types all;
33import from StatsD_CodecPort all;
34import from StatsD_CodecPort_CtrlFunct all;
35import from StatsD_Checker all;
36
37import from Osmocom_VTY_Functions all;
38import from TELNETasp_PortType all;
39
40import from HNBAP_Templates all;
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +010041import from RUA_IEs all;
42import from RUA_Templates all;
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +010043
44import from HNBGW_ConnectionHandler all;
45import from Iuh_Emulation all;
46
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +010047import from HNBLLIF_CodecPort all;
48import from HNBLLIF_Types all;
49import from HNBLLIF_Templates all;
50
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +010051modulepar {
52 /* IP address at which the HNodeB can be reached */
53 charstring mp_hnodeb_ip := "127.0.0.1";
54
55 /* IP address at which the test binds */
56 charstring mp_hnbgw_iuh_ip := "127.0.0.1";
57 integer mp_hnbgw_iuh_port := 29169;
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +010058
59 charstring mp_hnbllif_sk_path := HNBLL_SOCK_DEFAULT;
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +010060}
61
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +010062const hexstring ranap_cm_service_req := '001340400000060003400100000f40060000f11028b6003a40080000f110ffffffff0010400e0d052411035758a605f44e9d4aef004f400300001c0056400500f1100017'H;
63const hexstring ranap_auth_req := '00144032000002001040262505120217dc146aeac56cb5ff6d5fb51f47f19220108ca5a6d0c8110000b9e9272498872764003b400100'H;
64const hexstring ranap_auth_resp := '001440140000010010400d0c0554ccbdd0302104002f3ae4'H;
65const hexstring ranap_paging := '000e401e0000030003400100001740095000010100000000f10040400500b6cf4773'H;
66const hexstring iu_release_compl := '20010003000000'H;
67
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +010068type component test_CT extends CTRL_Adapter_CT {
69 port TELNETasp_PT HNBVTY;
70
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +010071 /* HNBLLIF Interface of HNodeB */
72 port HNBLLIF_CODEC_PT LLSK;
73 var integer g_llsk_conn_id;
74
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +010075 /* global test case guard timer (actual timeout value is set in f_init()) */
76 timer T_guard := 30.0;
77}
78
79/* global altstep for global guard timer; */
80altstep as_Tguard() runs on test_CT {
81 [] T_guard.timeout {
82 setverdict(fail, "Timeout of T_guard");
83 mtc.stop;
84 }
85}
86
87friend function f_logp(TELNETasp_PT pt, charstring log_msg)
88{
89 // log on TTCN3 log output
90 log(log_msg);
91 // log in stderr log
92 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
93}
94
95function f_init_vty(charstring id := "foo") runs on test_CT {
96 if (HNBVTY.checkstate("Mapped")) {
97 /* skip initialization if already executed once */
98 return;
99 }
100 map(self:HNBVTY, system:HNBVTY);
101 f_vty_set_prompts(HNBVTY);
102 f_vty_transceive(HNBVTY, "enable");
103}
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100104
105private function f_init_hnbllif() runs on test_CT {
106 map(self:LLSK, system:LLSK);
107 f_start_hnbllif(LLSK, testcasename(), mp_hnbllif_sk_path, g_llsk_conn_id);
108}
109
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100110/* global initialization function */
111function f_init(float guard_timeout := 30.0) runs on test_CT {
112 var integer bssap_idx;
113
114 T_guard.start(guard_timeout);
115 activate(as_Tguard());
116
117 f_init_vty("VirtHNBGW");
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100118}
119
120friend function f_shutdown_helper() runs on test_CT {
121 all component.stop;
122 setverdict(pass);
123 mtc.stop;
124}
125
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100126private function f_gen_test_hdlr_pars() runs on test_CT return TestHdlrParams {
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100127
128 var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100129 pars.hnbllif_sk_path := mp_hnbllif_sk_path;
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100130 pars.hnodeb_addr := mp_hnodeb_ip;
131 pars.hnbgw_addr := mp_hnbgw_iuh_ip;
132 pars.hnbgw_port := mp_hnbgw_iuh_port;
133 return pars;
134}
135
136type function void_fn(charstring id) runs on HNBGW_ConnHdlr;
137
138/* helper function to create and connect a HNBGW_ConnHdlr component */
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100139private function f_connect_handler(inout HNBGW_ConnHdlr vc_conn, TestHdlrParams pars) runs on test_CT {
140 if (pars.hnbllif_sk_path != "") {
141 map(vc_conn:LLSK, system:LLSK);
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100142 }
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100143}
144
145function f_start_handler_create(TestHdlrParams pars)
146runs on test_CT return HNBGW_ConnHdlr {
147 var charstring id := testcasename();
148 var HNBGW_ConnHdlr vc_conn;
149 vc_conn := HNBGW_ConnHdlr.create(id);
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100150 f_connect_handler(vc_conn, pars);
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100151 return vc_conn;
152}
153
154function f_start_handler_run(HNBGW_ConnHdlr vc_conn, void_fn fn, TestHdlrParams pars)
155runs on test_CT return HNBGW_ConnHdlr {
156 var charstring id := testcasename();
157 /* Emit a marker to appear in the SUT's own logging output */
158 f_logp(HNBVTY, id & "() start");
159 vc_conn.start(f_handler_init(fn, id, pars));
160 return vc_conn;
161}
162
163function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars_tmpl := omit)
164runs on test_CT return HNBGW_ConnHdlr {
165 var TestHdlrParams pars;
166 if (isvalue(pars)) {
167 pars := valueof(pars_tmpl);
168 } else {
169 pars := valueof(f_gen_test_hdlr_pars());
170 }
171 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
172}
173
174/* first function inside ConnHdlr component; sets g_pars + starts function */
175private function f_handler_init(void_fn fn, charstring id, TestHdlrParams pars)
176runs on HNBGW_ConnHdlr {
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100177 f_HNBGW_ConnHdlr_init(id, pars);
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100178 HNBAP.receive(IUHEM_Event:{up_down:=IUHEM_EVENT_UP}); /* Wait for HNB to connect to us */
179 fn.apply(id);
180}
181
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100182private function f_tc_hnb_register_request_accept(charstring id) runs on HNBGW_ConnHdlr {
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100183 f_handle_hnbap_hnb_register_req();
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100184 LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONFIGURE_IND(g_pars.mcc, g_pars.mnc, g_pars.cell_identity,
185 g_pars.lac, g_pars.rac, g_pars.sac, g_pars.rnc_id)));
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100186 f_sleep(1.0);
187}
188testcase TC_hnb_register_request_accept() runs on test_CT {
189 var HNBGW_ConnHdlr vc_conn;
190
191 f_init();
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100192 vc_conn := f_start_handler(refers(f_tc_hnb_register_request_accept));
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100193 vc_conn.done;
194 f_shutdown_helper();
195}
196
197private function f_tc_hnb_register_reject(charstring id) runs on HNBGW_ConnHdlr {
198 HNBAP.receive(tr_HNBAP_HNBRegisterRequest(char2oct(g_pars.hNB_Identity_Info),
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100199 f_enc_mcc_mnc(g_pars.mcc, g_pars.mnc),
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100200 int2bit(g_pars.cell_identity, 28),
201 int2oct(g_pars.lac, 2),
202 int2oct(g_pars.rac, 1),
203 int2oct(g_pars.sac, 2)
204 ));
205 HNBAP.send(ts_HNBAP_HNBRegisterReject(ts_HnbapCause(overload)));
206 f_sleep(1.0);
207}
208testcase TC_hnb_register_request_reject() runs on test_CT {
209 var HNBGW_ConnHdlr vc_conn;
210
211 f_init();
212 vc_conn := f_start_handler(refers(f_tc_hnb_register_reject));
213 vc_conn.done;
214 f_shutdown_helper();
215}
216
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100217private function f_tc_mo_conn(charstring id) runs on HNBGW_ConnHdlr {
218 const integer context_id := 30;
219 const bitstring context_id_bstr := '000000000000000000011110'B; /* encoded context_id */
220 const Establishment_Cause est_cause := normal_call;
221 f_handle_hnbap_hnb_register_req();
222
223 LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONFIGURE_IND(g_pars.mcc, g_pars.mnc, g_pars.cell_identity,
224 g_pars.lac, g_pars.rac, g_pars.sac, g_pars.rnc_id)));
225
226 /* Now an UE attempts CM Service Request: */
227 LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_ESTABLISH_REQ(context_id, 1, enum2int(est_cause), hex2oct(ranap_cm_service_req))));
228 /* The related RUA Connect + RANAP message is received on Iuh: */
229 RUA.receive(tr_RUA_Connect(ps_domain, context_id_bstr, est_cause, hex2oct(ranap_cm_service_req)));
230
231 /* Now HNBGW answers with RUA-DirectTransfer(RANAP-AuthenticationRequest) */
232 RUA.send(ts_RUA_DirectTransfer(ps_domain, context_id_bstr, hex2oct(ranap_auth_req)));
233
234 /* Now on LLSK first the Conn establishment is confirmed and then we receive data */
235 LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONN_ESTABLISH_CNF(context_id, 1, 0)));
236 LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONN_DATA_IND(context_id, 1, hex2oct(ranap_auth_req))));
237
238 /* UE answers with RANAPAuthenticationResponse: */
239 LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_DATA_REQ(context_id, 1, hex2oct(ranap_auth_resp))));
240 RUA.receive(tr_RUA_DirectTransfer(ps_domain, context_id_bstr, hex2oct(ranap_auth_resp)));
241
242 /* UE sends Iu Release Complete to release the conn */
243 LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_RELEASE_REQ(context_id, 1, 0, 0, hex2oct(iu_release_compl))));
244 RUA.receive(tr_RUA_Disconnect(ps_domain, context_id_bstr, ts_RUA_Cause(normal), hex2oct(iu_release_compl)));
245}
246testcase TC_mo_conn() runs on test_CT {
247 var HNBGW_ConnHdlr vc_conn;
248
249 f_init();
250 vc_conn := f_start_handler(refers(f_tc_mo_conn));
251 vc_conn.done;
252 f_shutdown_helper();
253}
254
255
256private function f_tc_paging(charstring id) runs on HNBGW_ConnHdlr {
257 const integer context_id := 30;
258 const bitstring context_id_bstr := '000000000000000000011110'B; /* encoded context_id */
259 f_handle_hnbap_hnb_register_req();
260
261 LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONFIGURE_IND(g_pars.mcc, g_pars.mnc, g_pars.cell_identity,
262 g_pars.lac, g_pars.rac, g_pars.sac, g_pars.rnc_id)));
263
264 /* HNBGW sends RUA-ConnectionlessTransfer(RANAP-Paging) */
265 RUA.send(ts_RUA_ConnectionlessTransfer(hex2oct(ranap_paging)));
266
267 LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_UNITDATA_IND(hex2oct(ranap_paging))));
268
269 /* Here it would continue with UE-side answers with RUA-Connect(RANAP-PagingResponse) */
270}
271testcase TC_paging() runs on test_CT {
272 var HNBGW_ConnHdlr vc_conn;
273
274 f_init();
275 vc_conn := f_start_handler(refers(f_tc_paging));
276 vc_conn.done;
277 f_shutdown_helper();
278}
279
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100280control {
281 execute( TC_hnb_register_request_accept() );
282 execute( TC_hnb_register_request_reject() );
Pau Espin Pedrola6bbb8c2021-11-24 17:00:03 +0100283 execute( TC_mo_conn() );
284 execute( TC_paging() );
Pau Espin Pedrolb54acca2021-11-22 20:35:44 +0100285}
286
287}