Pau Espin Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 1 | module 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 | |
| 23 | import from Misc_Helpers all; |
| 24 | import from General_Types all; |
| 25 | import from Osmocom_Types all; |
| 26 | import from IPL4asp_Types all; |
| 27 | |
| 28 | import from Osmocom_CTRL_Functions all; |
| 29 | import from Osmocom_CTRL_Types all; |
| 30 | import from Osmocom_CTRL_Adapter all; |
| 31 | |
| 32 | import from StatsD_Types all; |
| 33 | import from StatsD_CodecPort all; |
| 34 | import from StatsD_CodecPort_CtrlFunct all; |
| 35 | import from StatsD_Checker all; |
| 36 | |
| 37 | import from Osmocom_VTY_Functions all; |
| 38 | import from TELNETasp_PortType all; |
| 39 | |
| 40 | import from HNBAP_Templates all; |
Pau Espin Pedrol | a6bbb8c | 2021-11-24 17:00:03 +0100 | [diff] [blame^] | 41 | import from RUA_IEs all; |
| 42 | import from RUA_Templates all; |
Pau Espin Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 43 | |
| 44 | import from HNBGW_ConnectionHandler all; |
| 45 | import from Iuh_Emulation all; |
| 46 | |
Pau Espin Pedrol | a6bbb8c | 2021-11-24 17:00:03 +0100 | [diff] [blame^] | 47 | import from HNBLLIF_CodecPort all; |
| 48 | import from HNBLLIF_Types all; |
| 49 | import from HNBLLIF_Templates all; |
| 50 | |
Pau Espin Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 51 | modulepar { |
| 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 Pedrol | a6bbb8c | 2021-11-24 17:00:03 +0100 | [diff] [blame^] | 58 | |
| 59 | charstring mp_hnbllif_sk_path := HNBLL_SOCK_DEFAULT; |
Pau Espin Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 60 | } |
| 61 | |
Pau Espin Pedrol | a6bbb8c | 2021-11-24 17:00:03 +0100 | [diff] [blame^] | 62 | const hexstring ranap_cm_service_req := '001340400000060003400100000f40060000f11028b6003a40080000f110ffffffff0010400e0d052411035758a605f44e9d4aef004f400300001c0056400500f1100017'H; |
| 63 | const hexstring ranap_auth_req := '00144032000002001040262505120217dc146aeac56cb5ff6d5fb51f47f19220108ca5a6d0c8110000b9e9272498872764003b400100'H; |
| 64 | const hexstring ranap_auth_resp := '001440140000010010400d0c0554ccbdd0302104002f3ae4'H; |
| 65 | const hexstring ranap_paging := '000e401e0000030003400100001740095000010100000000f10040400500b6cf4773'H; |
| 66 | const hexstring iu_release_compl := '20010003000000'H; |
| 67 | |
Pau Espin Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 68 | type component test_CT extends CTRL_Adapter_CT { |
| 69 | port TELNETasp_PT HNBVTY; |
| 70 | |
Pau Espin Pedrol | a6bbb8c | 2021-11-24 17:00:03 +0100 | [diff] [blame^] | 71 | /* HNBLLIF Interface of HNodeB */ |
| 72 | port HNBLLIF_CODEC_PT LLSK; |
| 73 | var integer g_llsk_conn_id; |
| 74 | |
Pau Espin Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 75 | /* 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; */ |
| 80 | altstep as_Tguard() runs on test_CT { |
| 81 | [] T_guard.timeout { |
| 82 | setverdict(fail, "Timeout of T_guard"); |
| 83 | mtc.stop; |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | friend 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 | |
| 95 | function 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 Pedrol | a6bbb8c | 2021-11-24 17:00:03 +0100 | [diff] [blame^] | 104 | |
| 105 | private 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 Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 110 | /* global initialization function */ |
| 111 | function 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 Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 118 | } |
| 119 | |
| 120 | friend function f_shutdown_helper() runs on test_CT { |
| 121 | all component.stop; |
| 122 | setverdict(pass); |
| 123 | mtc.stop; |
| 124 | } |
| 125 | |
Pau Espin Pedrol | a6bbb8c | 2021-11-24 17:00:03 +0100 | [diff] [blame^] | 126 | private function f_gen_test_hdlr_pars() runs on test_CT return TestHdlrParams { |
Pau Espin Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 127 | |
| 128 | var TestHdlrParams pars := valueof(t_def_TestHdlrPars); |
Pau Espin Pedrol | a6bbb8c | 2021-11-24 17:00:03 +0100 | [diff] [blame^] | 129 | pars.hnbllif_sk_path := mp_hnbllif_sk_path; |
Pau Espin Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 130 | 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 | |
| 136 | type function void_fn(charstring id) runs on HNBGW_ConnHdlr; |
| 137 | |
| 138 | /* helper function to create and connect a HNBGW_ConnHdlr component */ |
Pau Espin Pedrol | a6bbb8c | 2021-11-24 17:00:03 +0100 | [diff] [blame^] | 139 | private 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 Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 142 | } |
Pau Espin Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 143 | } |
| 144 | |
| 145 | function f_start_handler_create(TestHdlrParams pars) |
| 146 | runs 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 Pedrol | a6bbb8c | 2021-11-24 17:00:03 +0100 | [diff] [blame^] | 150 | f_connect_handler(vc_conn, pars); |
Pau Espin Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 151 | return vc_conn; |
| 152 | } |
| 153 | |
| 154 | function f_start_handler_run(HNBGW_ConnHdlr vc_conn, void_fn fn, TestHdlrParams pars) |
| 155 | runs 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 | |
| 163 | function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars_tmpl := omit) |
| 164 | runs 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 */ |
| 175 | private function f_handler_init(void_fn fn, charstring id, TestHdlrParams pars) |
| 176 | runs on HNBGW_ConnHdlr { |
Pau Espin Pedrol | a6bbb8c | 2021-11-24 17:00:03 +0100 | [diff] [blame^] | 177 | f_HNBGW_ConnHdlr_init(id, pars); |
Pau Espin Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 178 | HNBAP.receive(IUHEM_Event:{up_down:=IUHEM_EVENT_UP}); /* Wait for HNB to connect to us */ |
| 179 | fn.apply(id); |
| 180 | } |
| 181 | |
Pau Espin Pedrol | a6bbb8c | 2021-11-24 17:00:03 +0100 | [diff] [blame^] | 182 | private function f_tc_hnb_register_request_accept(charstring id) runs on HNBGW_ConnHdlr { |
Pau Espin Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 183 | f_handle_hnbap_hnb_register_req(); |
Pau Espin Pedrol | a6bbb8c | 2021-11-24 17:00:03 +0100 | [diff] [blame^] | 184 | 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 Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 186 | f_sleep(1.0); |
| 187 | } |
| 188 | testcase TC_hnb_register_request_accept() runs on test_CT { |
| 189 | var HNBGW_ConnHdlr vc_conn; |
| 190 | |
| 191 | f_init(); |
Pau Espin Pedrol | a6bbb8c | 2021-11-24 17:00:03 +0100 | [diff] [blame^] | 192 | vc_conn := f_start_handler(refers(f_tc_hnb_register_request_accept)); |
Pau Espin Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 193 | vc_conn.done; |
| 194 | f_shutdown_helper(); |
| 195 | } |
| 196 | |
| 197 | private 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 Pedrol | a6bbb8c | 2021-11-24 17:00:03 +0100 | [diff] [blame^] | 199 | f_enc_mcc_mnc(g_pars.mcc, g_pars.mnc), |
Pau Espin Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 200 | 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 | } |
| 208 | testcase 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 Pedrol | a6bbb8c | 2021-11-24 17:00:03 +0100 | [diff] [blame^] | 217 | private 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 | } |
| 246 | testcase 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 | |
| 256 | private 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 | } |
| 271 | testcase 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 Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 280 | control { |
| 281 | execute( TC_hnb_register_request_accept() ); |
| 282 | execute( TC_hnb_register_request_reject() ); |
Pau Espin Pedrol | a6bbb8c | 2021-11-24 17:00:03 +0100 | [diff] [blame^] | 283 | execute( TC_mo_conn() ); |
| 284 | execute( TC_paging() ); |
Pau Espin Pedrol | b54acca | 2021-11-22 20:35:44 +0100 | [diff] [blame] | 285 | } |
| 286 | |
| 287 | } |