blob: d59d16513f6200b83002e72fc944582c0a8232a2 [file] [log] [blame]
Harald Weltef6dd64d2017-11-19 12:09:51 +01001module MSC_Tests {
2
Harald Welte34b5a952019-05-27 11:54:11 +02003/* Osmocom MSC test suite in in TTCN-3
4 * (C) 2017-2019 Harald Welte <laforge@gnumonks.org>
5 * (C) 2018-2019 sysmocom - s.f.m.c. GmbH
6 * (C) 2018-2019 Vadim Yanitskiy <axilirator@gmail.com>
7 * All rights reserved.
8 *
9 * Released under the terms of GNU General Public License, Version 2 or
10 * (at your option) any later version.
11 *
12 * SPDX-License-Identifier: GPL-2.0-or-later
13 */
14
Harald Weltee13cfb22019-04-23 16:52:02 +020015friend module MSC_Tests_Iu;
16
Harald Weltef6dd64d2017-11-19 12:09:51 +010017import from General_Types all;
18import from Osmocom_Types all;
19
20import from M3UA_Types all;
21import from M3UA_Emulation all;
22
23import from MTP3asp_Types all;
24import from MTP3asp_PortType all;
25
26import from SCCPasp_Types all;
27import from SCCP_Types all;
28import from SCCP_Emulation all;
29
30import from SCTPasp_Types all;
31import from SCTPasp_PortType all;
32
Harald Weltea49e36e2018-01-21 19:29:33 +010033import from Osmocom_CTRL_Functions all;
34import from Osmocom_CTRL_Types all;
35import from Osmocom_CTRL_Adapter all;
36
Harald Welte3ca1c902018-01-24 18:51:27 +010037import from TELNETasp_PortType all;
38import from Osmocom_VTY_Functions all;
39
Harald Weltea49e36e2018-01-21 19:29:33 +010040import from MNCC_Emulation all;
Harald Welte2bb825f2018-01-22 11:31:18 +010041import from MNCC_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +010042
Harald Welte4aa970c2018-01-26 10:38:09 +010043import from MGCP_Emulation all;
44import from MGCP_Types all;
45import from MGCP_Templates all;
46import from SDP_Types all;
47
Harald Weltea49e36e2018-01-21 19:29:33 +010048import from GSUP_Emulation all;
49import from GSUP_Types all;
50import from IPA_Emulation all;
51
Harald Weltef6dd64d2017-11-19 12:09:51 +010052import from BSSAP_Types all;
Harald Welte6811d102019-04-14 22:23:14 +020053import from RAN_Adapter all;
Harald Weltea49e36e2018-01-21 19:29:33 +010054import from BSSAP_CodecPort all;
55import from BSSMAP_Templates all;
Harald Welte6811d102019-04-14 22:23:14 +020056import from RAN_Emulation all;
Harald Weltea49e36e2018-01-21 19:29:33 +010057import from BSC_ConnectionHandler all;
Harald Weltee13cfb22019-04-23 16:52:02 +020058import from RANAP_Templates all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010059
Harald Welte4263c522018-12-06 11:56:27 +010060import from SGsAP_Templates all;
61import from SGsAP_Types all;
62import from SGsAP_Emulation all;
63
Harald Weltea49e36e2018-01-21 19:29:33 +010064import from MobileL3_Types all;
65import from MobileL3_CommonIE_Types all;
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +070066import from MobileL3_SMS_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +010067import from L3_Templates all;
Harald Welte158a7ca2018-02-16 18:11:31 +010068import from L3_Common all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010069
Harald Weltef640a012018-04-14 17:49:21 +020070import from SMPP_Types all;
71import from SMPP_Templates all;
72import from SMPP_Emulation all;
73
Stefan Sperlingc307e682018-06-14 15:15:46 +020074import from SCCP_Templates all;
75
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +070076import from SS_Types all;
77import from SS_Templates all;
78import from USSD_Helpers all;
Harald Welte4263c522018-12-06 11:56:27 +010079import from DNS_Helpers all;
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +070080
Philipp Maier948747b2019-04-02 15:22:33 +020081import from TCCConversion_Functions all;
82
Harald Welte9b751a62019-04-14 17:39:29 +020083const integer NUM_BSC := 3;
Harald Weltef6dd64d2017-11-19 12:09:51 +010084
Harald Welte4263c522018-12-06 11:56:27 +010085/* Needed for SGsAP SMS */
86import from MobileL3_SMS_Types all;
87
Harald Weltea4ca4462018-02-09 00:17:14 +010088type component MTC_CT extends CTRL_Adapter_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +010089 var boolean g_initialized := false;
Harald Weltea49e36e2018-01-21 19:29:33 +010090
Harald Welte6811d102019-04-14 22:23:14 +020091 var RAN_Adapter g_bssap[NUM_BSC];
Harald Weltea4ca4462018-02-09 00:17:14 +010092
Harald Weltea49e36e2018-01-21 19:29:33 +010093 /* no 'adapter_CT' for MNCC or GSUP */
94 var MNCC_Emulation_CT vc_MNCC;
Harald Welte4aa970c2018-01-26 10:38:09 +010095 var MGCP_Emulation_CT vc_MGCP;
Harald Weltea49e36e2018-01-21 19:29:33 +010096 var GSUP_Emulation_CT vc_GSUP;
97 var IPA_Emulation_CT vc_GSUP_IPA;
Harald Weltef640a012018-04-14 17:49:21 +020098 var SMPP_Emulation_CT vc_SMPP;
Harald Welte4263c522018-12-06 11:56:27 +010099 var SGsAP_Emulation_CT vc_SGsAP;
Harald Weltea49e36e2018-01-21 19:29:33 +0100100
101 /* only to get events from IPA underneath GSUP */
102 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte3ca1c902018-01-24 18:51:27 +0100103 /* VTY to MSC */
104 port TELNETasp_PT MSCVTY;
Philipp Maier328d1662018-03-07 10:40:27 +0100105
106 /* A port to directly send BSSAP messages. This port is used for
107 * tests that require low level access to sen arbitrary BSSAP
108 * messages. Run f_init_bssap_direct() to connect and initialize */
109 port BSSAP_CODEC_PT BSSAP_DIRECT;
110
111 /* When BSSAP messages are directly sent, then the connection
112 * handler is not active, which means that also no guard timer is
113 * set up. The following timer will serve as a replacement */
114 timer Tguard_direct := 60.0;
Pau Espin Pedrola42745c2020-01-10 18:03:28 +0100115
116 /* Configure T(tias) over VTY, seconds */
117 var integer g_msc_sccp_timer_ias := 7 * 60;
118 /* Configure T(tiar) over VTY, seconds */
119 var integer g_msc_sccp_timer_iar := 15 * 60;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100120}
121
122modulepar {
Harald Weltea49e36e2018-01-21 19:29:33 +0100123 /* remote parameters of IUT */
124 charstring mp_msc_ip := "127.0.0.1";
125 integer mp_msc_ctrl_port := 4255;
126 integer mp_msc_vty_port := 4254;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100127
Harald Weltea49e36e2018-01-21 19:29:33 +0100128 /* local parameters of emulated HLR */
Philipp Maier9b690e42018-12-21 11:50:03 +0100129 boolean mp_mm_info := false;
Harald Weltea49e36e2018-01-21 19:29:33 +0100130 charstring mp_hlr_ip := "127.0.0.1";
131 integer mp_hlr_port := 4222;
Harald Welte6126fb02018-01-27 20:08:24 +0100132 charstring mp_mgw_ip := "127.0.0.1";
133 integer mp_mgw_port := 2427;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100134
Harald Weltea49e36e2018-01-21 19:29:33 +0100135 charstring mp_msc_mncc := "/tmp/mncc";
Harald Weltea4ca4462018-02-09 00:17:14 +0100136
Harald Weltef640a012018-04-14 17:49:21 +0200137 integer mp_msc_smpp_port := 2775;
138 charstring mp_smpp_system_id := "msc_tester";
139 charstring mp_smpp_password := "osmocom1";
Harald Welte4263c522018-12-06 11:56:27 +0100140 charstring mp_mme_name := "mmec01.mmegi0001.mme.epc.mnc070.mcc901.3gppnetwork.org";
141 charstring mp_vlr_name := "vlr.example.net";
Harald Weltef640a012018-04-14 17:49:21 +0200142
Pau Espin Pedrol690d6592019-05-31 17:56:32 +0200143 /* Whether to enable osmux tests. Can be dropped completely and enable
144 unconditionally once new version of osmo-msc is released (current
145 version: 1.3.1) */
146 boolean mp_enable_osmux_test := true;
147
Harald Welte6811d102019-04-14 22:23:14 +0200148 RAN_Configurations mp_bssap_cfg := {
Philipp Maier75932982018-03-27 14:52:35 +0200149 {
150 sccp_service_type := "mtp3_itu",
151 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
152 own_pc := 185,
153 own_ssn := 254,
154 peer_pc := 187,
155 peer_ssn := 254,
156 sio := '83'O,
157 rctx := 0
158 },
159 {
160 sccp_service_type := "mtp3_itu",
161 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
162 own_pc := 186,
163 own_ssn := 254,
164 peer_pc := 187,
165 peer_ssn := 254,
166 sio := '83'O,
167 rctx := 1
168 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100169 };
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200170
171 boolean mp_enable_cell_id_test := true;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100172}
173
Philipp Maier328d1662018-03-07 10:40:27 +0100174/* altstep for the global guard timer (only used when BSSAP_DIRECT
175 * is used for communication */
176private altstep as_Tguard_direct() runs on MTC_CT {
177 [] Tguard_direct.timeout {
178 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200179 mtc.stop;
Philipp Maier328d1662018-03-07 10:40:27 +0100180 }
181}
Harald Weltef6dd64d2017-11-19 12:09:51 +0100182
Neels Hofmeyr2ca1ab42019-03-08 03:45:43 +0100183private altstep as_optional_cc_rel(CallParameters cpars, boolean respond := false) runs on BSC_ConnHdlr {
184 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id))) {
185 if (respond) {
186 var BIT1 tid_remote := '1'B;
187 if (cpars.mo_call) {
188 tid_remote := '0'B;
189 }
190 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id, tid_remote)));
191 }
192 }
Neels Hofmeyrde76f052019-02-26 05:02:46 +0100193}
194
Harald Weltef640a012018-04-14 17:49:21 +0200195function f_init_smpp(charstring id) runs on MTC_CT {
196 id := id & "-SMPP";
197 var EsmePars pars := {
198 mode := MODE_TRANSCEIVER,
199 bind := {
200 system_id := mp_smpp_system_id,
201 password := mp_smpp_password,
202 system_type := "MSC_Tests",
203 interface_version := hex2int('34'H),
204 addr_ton := unknown,
205 addr_npi := unknown,
206 address_range := ""
207 },
208 esme_role := true
209 }
210
211 vc_SMPP := SMPP_Emulation_CT.create(id);
212 map(vc_SMPP:SMPP_PORT, system:SMPP_PORT);
213 vc_SMPP.start(SMPP_Emulation.main_client(pars, mp_msc_ip, mp_msc_smpp_port, "", -1));
214}
215
216
Harald Weltea49e36e2018-01-21 19:29:33 +0100217function f_init_mncc(charstring id) runs on MTC_CT {
218 id := id & "-MNCC";
219 var MnccOps ops := {
220 create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
221 unitdata_cb := refers(MNCC_Emulation.DummyUnitdataCallback)
222 }
223
224 vc_MNCC := MNCC_Emulation_CT.create(id);
225 map(vc_MNCC:MNCC, system:MNCC_CODEC_PT);
226 vc_MNCC.start(MNCC_Emulation.main(ops, id, mp_msc_mncc));
Harald Weltef6dd64d2017-11-19 12:09:51 +0100227}
228
Harald Welte4aa970c2018-01-26 10:38:09 +0100229function f_init_mgcp(charstring id) runs on MTC_CT {
230 id := id & "-MGCP";
231 var MGCPOps ops := {
232 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
233 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
234 }
235 var MGCP_conn_parameters pars := {
Harald Welte6126fb02018-01-27 20:08:24 +0100236 callagent_ip := mp_msc_ip,
Harald Welte4aa970c2018-01-26 10:38:09 +0100237 callagent_udp_port := -1,
Harald Welte6126fb02018-01-27 20:08:24 +0100238 mgw_ip := mp_mgw_ip,
Pau Espin Pedrol1a026a52019-06-18 17:21:52 +0200239 mgw_udp_port := mp_mgw_port,
240 multi_conn_mode := false
Harald Welte4aa970c2018-01-26 10:38:09 +0100241 }
242
243 vc_MGCP := MGCP_Emulation_CT.create(id);
244 map(vc_MGCP:MGCP, system:MGCP_CODEC_PT);
245 vc_MGCP.start(MGCP_Emulation.main(ops, pars, id));
246}
247
Philipp Maierc09a1312019-04-09 16:05:26 +0200248function ForwardUnitdataCallback(PDU_SGsAP msg)
249runs on SGsAP_Emulation_CT return template PDU_SGsAP {
250 SGsAP_CLIENT.send(msg);
251 return omit;
252}
253
Harald Welte4263c522018-12-06 11:56:27 +0100254function f_init_sgsap(charstring id) runs on MTC_CT {
255 id := id & "-SGsAP";
256 var SGsAPOps ops := {
257 create_cb := refers(SGsAP_Emulation.ExpectedCreateCallback),
Philipp Maierc09a1312019-04-09 16:05:26 +0200258 unitdata_cb := refers(ForwardUnitdataCallback)
Harald Welte4263c522018-12-06 11:56:27 +0100259 }
260 var SGsAP_conn_parameters pars := {
261 remote_ip := mp_msc_ip,
262 remote_sctp_port := 29118,
263 local_ip := "",
264 local_sctp_port := -1
265 }
266
267 vc_SGsAP := SGsAP_Emulation_CT.create(id);
268 map(vc_SGsAP:SGsAP, system:SGsAP_CODEC_PT);
269 vc_SGsAP.start(SGsAP_Emulation.main(ops, pars, id));
270}
271
272
Harald Weltea49e36e2018-01-21 19:29:33 +0100273function f_init_gsup(charstring id) runs on MTC_CT {
274 id := id & "-GSUP";
275 var GsupOps ops := {
276 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
277 }
278
279 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
280 vc_GSUP := GSUP_Emulation_CT.create(id);
281
282 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
283 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
284 /* we use this hack to get events like ASP_IPA_EVENT_UP */
285 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
286
287 vc_GSUP.start(GSUP_Emulation.main(ops, id));
288 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
289
290 /* wait for incoming connection to GSUP port before proceeding */
291 timer T := 10.0;
292 T.start;
293 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700294 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Weltea49e36e2018-01-21 19:29:33 +0100295 [] T.timeout {
Harald Welte458fd372018-03-21 11:26:23 +0100296 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200297 mtc.stop
Harald Weltea49e36e2018-01-21 19:29:33 +0100298 }
299 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100300}
301
Pau Espin Pedrola65697d2019-05-21 12:54:39 +0200302function f_init(integer num_bsc := 1, boolean sgsap := false, boolean gsup := true, boolean osmux := false) runs on MTC_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +0100303
304 if (g_initialized == true) {
305 return;
306 }
307 g_initialized := true;
308
Philipp Maier75932982018-03-27 14:52:35 +0200309 if (num_bsc > NUM_BSC) {
Daniel Willmannafce8662018-07-06 23:11:32 +0200310 testcase.stop("excess number of BSC instances requested");
Philipp Maier75932982018-03-27 14:52:35 +0200311 }
312
313 for (var integer i := 0; i < num_bsc; i := i + 1) {
314 if (isbound(mp_bssap_cfg[i])) {
Pau Espin Pedrola65697d2019-05-21 12:54:39 +0200315 var RanOps ranops := BSC_RanOps;
316 ranops.use_osmux := osmux;
317 f_ran_adapter_init(g_bssap[i], mp_bssap_cfg[i], "MSC_Test_" & int2str(i), ranops);
Harald Welte3ca0ce12019-04-23 17:18:48 +0200318 f_ran_adapter_start(g_bssap[i]);
Philipp Maier75932982018-03-27 14:52:35 +0200319 } else {
Daniel Willmannafce8662018-07-06 23:11:32 +0200320 testcase.stop("missing BSSAP configuration");
Philipp Maier75932982018-03-27 14:52:35 +0200321 }
322 }
323
Harald Weltea49e36e2018-01-21 19:29:33 +0100324 f_ipa_ctrl_start(mp_msc_ip, mp_msc_ctrl_port);
325 f_init_mncc("MSC_Test");
Harald Welte4aa970c2018-01-26 10:38:09 +0100326 f_init_mgcp("MSC_Test");
Philipp Maierc09a1312019-04-09 16:05:26 +0200327
328 if (gsup == true) {
329 f_init_gsup("MSC_Test");
330 }
Harald Weltef640a012018-04-14 17:49:21 +0200331 f_init_smpp("MSC_Test");
Philipp Maier57865482019-01-07 18:33:13 +0100332
Philipp Maier8e07a4a2019-02-14 18:23:28 +0100333 if (sgsap == true) {
Philipp Maier57865482019-01-07 18:33:13 +0100334 f_init_sgsap("MSC_Test");
335 }
Harald Welte3ca1c902018-01-24 18:51:27 +0100336
337 map(self:MSCVTY, system:MSCVTY);
338 f_vty_set_prompts(MSCVTY);
339 f_vty_transceive(MSCVTY, "enable");
Harald Welteb14c77a2018-01-25 17:25:44 +0100340
341 /* set some defaults */
342 f_vty_config(MSCVTY, "network", "authentication optional");
343 f_vty_config(MSCVTY, "msc", "assign-tmsi");
Oliver Smith1d118ff2019-07-03 10:57:35 +0200344 f_vty_config(MSCVTY, "msc", "check-imei-rqd 0");
Harald Welteb14c77a2018-01-25 17:25:44 +0100345 f_vty_config(MSCVTY, "network", "encryption a5 0");
Pau Espin Pedrola42745c2020-01-10 18:03:28 +0100346 f_vty_config(MSCVTY, "cs7 instance 0", "sccp-timer ias " & int2str(g_msc_sccp_timer_ias));
347 f_vty_config(MSCVTY, "cs7 instance 0", "sccp-timer iar " & int2str(g_msc_sccp_timer_iar));
Pau Espin Pedrol690d6592019-05-31 17:56:32 +0200348 if (mp_enable_osmux_test) {
349 if (osmux) {
350 f_vty_config(MSCVTY, "msc", "osmux on");
351 } else {
352 f_vty_config(MSCVTY, "msc", "osmux off");
353 }
Pau Espin Pedrol3dd33bc2019-05-31 17:51:20 +0200354 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100355}
356
Philipp Maier328d1662018-03-07 10:40:27 +0100357/* Initialize for a direct connection to BSSAP. This function is an alternative
358 * to f_init() when the high level functions of the BSC_ConnectionHandler are
359 * not needed. */
360function f_init_bssap_direct() runs on MTC_CT {
Harald Welte3ca0ce12019-04-23 17:18:48 +0200361 f_ran_adapter_init(g_bssap[0], mp_bssap_cfg[0], "MSC_Test", omit);
Philipp Maier75932982018-03-27 14:52:35 +0200362 connect(g_bssap[0].vc_SCCP:SCCP_SP_PORT, self:BSSAP_DIRECT);
Philipp Maier328d1662018-03-07 10:40:27 +0100363
364 /* Start guard timer and activate it as default */
365 Tguard_direct.start
366 activate(as_Tguard_direct());
367}
368
Harald Weltea49e36e2018-01-21 19:29:33 +0100369type function void_fn(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100370
Harald Weltea49e36e2018-01-21 19:29:33 +0100371/* FIXME: move into BSC_ConnectionHandler? */
Harald Welte9b751a62019-04-14 17:39:29 +0200372function f_init_pars(integer imsi_suffix, boolean sgsap := false, boolean gsup := true, integer ran_idx := 0,
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200373 boolean ran_is_geran := true, boolean use_osmux := false, OCT4 gsup_sid := '20000101'O,
374 boolean verify_cell_id := true)
Harald Weltef9abf8d2019-04-21 13:07:17 +0200375runs on MTC_CT return BSC_ConnHdlrPars {
Harald Weltede371492018-01-27 23:44:41 +0100376 var BSC_ConnHdlrNetworkPars net_pars := {
377 kc_support := '0A'O, /* A5/1 and A5/3 enabled */
378 expect_tmsi := true,
379 expect_auth := false,
Oliver Smith1d118ff2019-07-03 10:57:35 +0200380 expect_ciph := false,
381 expect_imei := false,
382 expect_imei_early := false,
383 check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
384 check_imei_error := false
Harald Weltede371492018-01-27 23:44:41 +0100385 };
Harald Weltea49e36e2018-01-21 19:29:33 +0100386 var BSC_ConnHdlrPars pars := {
Harald Weltef9abf8d2019-04-21 13:07:17 +0200387 sccp_addr_own := g_bssap[ran_idx].sccp_addr_own,
388 sccp_addr_peer := g_bssap[ran_idx].sccp_addr_peer,
Harald Welteedbab812018-03-18 16:02:25 +0100389 cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42)),
Harald Welte81b7f9d2018-01-24 19:06:24 +0100390 imei := f_gen_imei(imsi_suffix),
391 imsi := f_gen_imsi(imsi_suffix),
392 msisdn := f_gen_msisdn(imsi_suffix),
Harald Welte256571e2018-01-24 18:47:19 +0100393 tmsi := omit,
Harald Welte9de84792018-01-28 01:06:35 +0100394 cm1 := valueof(ts_CM1),
Harald Welte82600572018-01-21 20:54:08 +0100395 cm2 := valueof(ts_CM2_default),
Harald Welte16114282018-01-24 22:41:21 +0100396 cm3 := omit,
Harald Weltede371492018-01-27 23:44:41 +0100397 vec := omit,
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100398 net := net_pars,
Philipp Maieraeb29a82018-11-08 17:40:53 +0100399 send_early_cm := true,
400 ipa_ctrl_ip := mp_msc_ip,
401 ipa_ctrl_port := mp_msc_ctrl_port,
Philipp Maier9b690e42018-12-21 11:50:03 +0100402 ipa_ctrl_enable := true,
Philipp Maier57865482019-01-07 18:33:13 +0100403 mm_info := mp_mm_info,
Philipp Maierc09a1312019-04-09 16:05:26 +0200404 sgsap_enable := sgsap,
Harald Weltef9abf8d2019-04-21 13:07:17 +0200405 gsup_enable := gsup,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +0100406 gsup_sid := gsup_sid,
Harald Weltec1f937a2019-04-21 21:19:23 +0200407 ran_idx := ran_idx,
Harald Welte9b751a62019-04-14 17:39:29 +0200408 use_umts_aka := false,
Pau Espin Pedrola65697d2019-05-21 12:54:39 +0200409 ran_is_geran := ran_is_geran,
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200410 use_osmux := use_osmux,
411 verify_cell_id := mp_enable_cell_id_test and verify_cell_id
Harald Weltea49e36e2018-01-21 19:29:33 +0100412 };
Harald Weltee13cfb22019-04-23 16:52:02 +0200413 if (not ran_is_geran) {
414 pars.use_umts_aka := true;
415 pars.net.expect_auth := true;
416 }
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100417 return pars;
418}
419
Neels Hofmeyr0ac63152019-05-07 01:20:17 +0200420function f_start_handler_with_pars(void_fn fn, BSC_ConnHdlrPars pars, integer bssap_idx := 0) runs on MTC_CT return BSC_ConnHdlr {
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100421 var BSC_ConnHdlr vc_conn;
Neels Hofmeyr0ac63152019-05-07 01:20:17 +0200422 var charstring id := testcasename() & int2str(bssap_idx);
Harald Weltea49e36e2018-01-21 19:29:33 +0100423
424 vc_conn := BSC_ConnHdlr.create(id);
425 /* BSSMAP part / A interface */
Neels Hofmeyr0ac63152019-05-07 01:20:17 +0200426 connect(vc_conn:BSSAP, g_bssap[pars.ran_idx + bssap_idx].vc_RAN:CLIENT);
427 connect(vc_conn:BSSAP_PROC, g_bssap[pars.ran_idx + bssap_idx].vc_RAN:PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100428 /* MNCC part */
429 connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
430 connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);
Harald Welte4aa970c2018-01-26 10:38:09 +0100431 /* MGCP part */
432 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
433 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100434 /* GSUP part */
Philipp Maierc09a1312019-04-09 16:05:26 +0200435 if (pars.gsup_enable == true) {
436 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
437 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
438 }
Harald Weltef640a012018-04-14 17:49:21 +0200439 /* SMPP part */
440 connect(vc_conn:SMPP, vc_SMPP:SMPP_CLIENT);
441 connect(vc_conn:SMPP_PROC, vc_SMPP:SMPP_PROC);
Harald Welte4263c522018-12-06 11:56:27 +0100442 /* SGs part */
Philipp Maier8e07a4a2019-02-14 18:23:28 +0100443 if (pars.sgsap_enable == true) {
Philipp Maier57865482019-01-07 18:33:13 +0100444 connect(vc_conn:SGsAP, vc_SGsAP:SGsAP_CLIENT);
445 connect(vc_conn:SGsAP_PROC, vc_SGsAP:SGsAP_PROC);
446 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100447
Harald Weltea10db902018-01-27 12:44:49 +0100448 /* We cannot use vc_conn.start(f_init_handler(fn, id, pars)); as we cannot have
449 * a stand-alone 'derefers()' call, see https://www.eclipse.org/forums/index.php/t/1091364/ */
Harald Weltea49e36e2018-01-21 19:29:33 +0100450 vc_conn.start(derefers(fn)(id, pars));
451 return vc_conn;
452}
453
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200454function f_start_handler(void_fn fn, integer imsi_suffix, integer ran_idx := 0, boolean ran_is_geran := true, boolean use_osmux := false,
455 boolean verify_cell_id := true)
Harald Welte9b751a62019-04-14 17:39:29 +0200456runs on MTC_CT return BSC_ConnHdlr {
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200457 return f_start_handler_with_pars(fn, f_init_pars(imsi_suffix, ran_idx := ran_idx, ran_is_geran := ran_is_geran, use_osmux := use_osmux, verify_cell_id := verify_cell_id));
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100458}
459
Harald Weltea49e36e2018-01-21 19:29:33 +0100460private function f_tc_lu_imsi_noauth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100461 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100462 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100463}
Harald Weltea49e36e2018-01-21 19:29:33 +0100464testcase TC_lu_imsi_noauth_tmsi() runs on MTC_CT {
465 var BSC_ConnHdlr vc_conn;
466 f_init();
467
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100468 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi), 1);
Harald Weltea49e36e2018-01-21 19:29:33 +0100469 vc_conn.done;
470}
471
472private function f_tc_lu_imsi_noauth_notmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100473 pars.net.expect_tmsi := false;
Harald Weltea10db902018-01-27 12:44:49 +0100474 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100475 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100476}
Harald Weltea49e36e2018-01-21 19:29:33 +0100477testcase TC_lu_imsi_noauth_notmsi() runs on MTC_CT {
478 var BSC_ConnHdlr vc_conn;
479 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100480 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
Harald Weltea49e36e2018-01-21 19:29:33 +0100481
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100482 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi), 2);
Harald Weltea49e36e2018-01-21 19:29:33 +0100483 vc_conn.done;
484}
485
486/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
Harald Weltee13cfb22019-04-23 16:52:02 +0200487friend function f_tc_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100488 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100489 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
490
491 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +0200492 f_cl3_or_initial_ue(l3_lu);
Neels Hofmeyrd076c522019-11-28 01:00:52 +0100493 f_mm_common();
Harald Weltea49e36e2018-01-21 19:29:33 +0100494 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
495 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
496 alt {
Harald Welte5946b332018-03-18 23:32:21 +0100497 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej(int2oct(23,1)))) {
498 f_expect_clear();
499 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100500 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
501 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
Daniel Willmannafce8662018-07-06 23:11:32 +0200502 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100503 }
504 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100505}
506testcase TC_lu_imsi_reject() runs on MTC_CT {
507 var BSC_ConnHdlr vc_conn;
508 f_init();
509
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200510 vc_conn := f_start_handler(refers(f_tc_lu_imsi_reject), 3, verify_cell_id := false);
Harald Weltea49e36e2018-01-21 19:29:33 +0100511 vc_conn.done;
512}
513
Harald Weltee13cfb22019-04-23 16:52:02 +0200514
515
Harald Weltea49e36e2018-01-21 19:29:33 +0100516/* Do LU by IMSI, timeout on GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +0200517friend function f_tc_lu_imsi_timeout_gsup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100518 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100519 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
520
521 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +0200522 f_cl3_or_initial_ue(l3_lu);
Neels Hofmeyrd076c522019-11-28 01:00:52 +0100523 f_mm_common();
Harald Weltea49e36e2018-01-21 19:29:33 +0100524 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
525 /* Normally the HLR would need to respond here, but we decide to force a timeout here */
526 alt {
527 /* FIXME: Expect specific reject cause */
Harald Welte5946b332018-03-18 23:32:21 +0100528 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
529 f_expect_clear();
530 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100531 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
532 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
Daniel Willmannafce8662018-07-06 23:11:32 +0200533 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100534 }
535 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100536}
537testcase TC_lu_imsi_timeout_gsup() runs on MTC_CT {
538 var BSC_ConnHdlr vc_conn;
539 f_init();
540
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200541 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_gsup), 4, verify_cell_id := false);
Harald Weltea49e36e2018-01-21 19:29:33 +0100542 vc_conn.done;
543}
544
Harald Weltee13cfb22019-04-23 16:52:02 +0200545
Harald Welte7b1b2812018-01-22 21:23:06 +0100546private function f_tc_lu_imsi_auth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100547 pars.net.expect_auth := true;
Harald Weltea10db902018-01-27 12:44:49 +0100548 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100549 f_perform_lu();
Harald Welte7b1b2812018-01-22 21:23:06 +0100550}
551testcase TC_lu_imsi_auth_tmsi() runs on MTC_CT {
552 var BSC_ConnHdlr vc_conn;
553 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100554 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte7b1b2812018-01-22 21:23:06 +0100555
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100556 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi), 5);
Harald Welte7b1b2812018-01-22 21:23:06 +0100557 vc_conn.done;
558}
559
Harald Weltee13cfb22019-04-23 16:52:02 +0200560
561friend function f_tc_lu_imsi_auth3g_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Welte8a397ae2019-04-21 22:03:37 +0200562 pars.net.expect_auth := true;
563 pars.use_umts_aka := true;
564 f_init_handler(pars);
565 f_perform_lu();
566}
567testcase TC_lu_imsi_auth3g_tmsi() runs on MTC_CT {
568 var BSC_ConnHdlr vc_conn;
569 f_init();
570 f_vty_config(MSCVTY, "network", "authentication required");
571
572 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth3g_tmsi), 1005);
573 vc_conn.done;
574}
Harald Weltea49e36e2018-01-21 19:29:33 +0100575
Pau Espin Pedrold3d54a92019-12-17 17:02:54 +0100576/* Proceed with LU but never receive an TMSI Realloc from MS after LU Accept (OS#4337).
577 * TS 24.008 sec 4.3.1.5 states MSC should simply release all MM connections.
578 */
579friend function f_tc_lu_imsi_timeout_tmsi_realloc(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
580
581 f_init_handler(pars);
582
583 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
584 var PDU_DTAP_MT dtap_mt;
585
586 /* tell GSUP dispatcher to send this IMSI to us */
587 f_create_gsup_expect(hex2str(g_pars.imsi));
588
589 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
590 if (g_pars.ran_is_geran) {
591 f_bssap_compl_l3(l3_lu);
592 if (g_pars.send_early_cm) {
593 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
594 }
595 } else {
596 f_ranap_initial_ue(l3_lu);
597 }
598
599 f_mm_imei_early();
600 f_mm_common();
601 f_msc_lu_hlr();
602 f_mm_imei();
603
604 alt {
605 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) -> value dtap_mt {}
606 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
607 setverdict(fail, "Expected LU ACK, but received LU REJ");
608 mtc.stop;
609 }
610 }
611
612 /* currently (due to bug OS#4337), an extra LU reject is received before
613 terminating the connection. Enabling following line makes the test
614 pass: */
615 //f_expect_lu_reject('16'O); /* Cause: congestion */
616
617 /* f_expect_lu_reject() already waits for T"-1" (X1, 5 seconds), but give some
618 extra time to avoid race conditons... */
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200619 f_expect_clear(7.0, verify_vlr_cell_id := false);
Pau Espin Pedrold3d54a92019-12-17 17:02:54 +0100620
621 setverdict(pass);
622}
623testcase TC_lu_imsi_timeout_tmsi_realloc() runs on MTC_CT {
624 var BSC_ConnHdlr vc_conn;
625 f_init();
626
627 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_tmsi_realloc), 5);
628 vc_conn.done;
629}
630
Harald Weltee13cfb22019-04-23 16:52:02 +0200631
Harald Weltea49e36e2018-01-21 19:29:33 +0100632/* Send CM SERVICE REQ for IMSI that has never performed LU before */
Harald Weltee13cfb22019-04-23 16:52:02 +0200633friend function f_tc_cmserv_imsi_unknown(charstring id, BSC_ConnHdlrPars pars)
Harald Weltea49e36e2018-01-21 19:29:33 +0100634runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100635 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100636
637 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welteedbab812018-03-18 16:02:25 +0100638 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100639 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltea49e36e2018-01-21 19:29:33 +0100640
641 f_create_gsup_expect(hex2str(g_pars.imsi));
642
643 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200644 f_cl3_or_initial_ue(l3_info);
Harald Welteb7817992019-05-09 13:15:39 +0200645 f_mm_auth();
Harald Weltea49e36e2018-01-21 19:29:33 +0100646
647 timer T := 10.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100648 T.start;
649 alt {
Harald Weltea49e36e2018-01-21 19:29:33 +0100650 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
651 //[] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC)) { }
Daniel Willmannafce8662018-07-06 23:11:32 +0200652 [] BSSAP.receive {
653 setverdict(fail, "Received unexpected BSSAP");
654 mtc.stop;
655 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100656 [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
657 setverdict(fail, "Unexpected GSUP UL REQ");
Daniel Willmannafce8662018-07-06 23:11:32 +0200658 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100659 }
Daniel Willmannafce8662018-07-06 23:11:32 +0200660 [] T.timeout {
661 setverdict(fail, "Timeout waiting for CM SERV REQ");
662 mtc.stop;
663 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100664 }
665
Harald Welte1ddc7162018-01-27 14:25:46 +0100666 f_expect_clear();
Harald Weltef6dd64d2017-11-19 12:09:51 +0100667}
Harald Weltea49e36e2018-01-21 19:29:33 +0100668testcase TC_cmserv_imsi_unknown() runs on MTC_CT {
669 var BSC_ConnHdlr vc_conn;
670 f_init();
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200671 vc_conn := f_start_handler(refers(f_tc_cmserv_imsi_unknown), 6, verify_cell_id := false);
Harald Weltea49e36e2018-01-21 19:29:33 +0100672 vc_conn.done;
673}
674
Harald Weltee13cfb22019-04-23 16:52:02 +0200675
676friend function f_tc_lu_and_mo_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100677 f_init_handler(pars);
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +0200678 var CallParameters cpars := valueof(t_CallParams);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100679 f_perform_lu();
Harald Welteb71901a2018-01-26 19:16:05 +0100680 f_mo_call(cpars);
Harald Welte2bb825f2018-01-22 11:31:18 +0100681}
682testcase TC_lu_and_mo_call() runs on MTC_CT {
683 var BSC_ConnHdlr vc_conn;
684 f_init();
685
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100686 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_call), 7);
Harald Welte071ed732018-01-23 19:53:52 +0100687 vc_conn.done;
688}
689
Pau Espin Pedrola42745c2020-01-10 18:03:28 +0100690/* Verify T(iar) triggers and releases the channel */
691friend function f_lu_and_mo_call_sccp_tiar_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
692 timer T_wait_iar := int2float(5 + 1); /* g_msc_sccp_timer_iar + Give extra time (+1 sec) */
693 f_init_handler(pars);
694 var CallParameters cpars := valueof(t_CallParams);
695 f_perform_lu();
696 f_mo_call_establish(cpars);
697
698 /* Expect the channel cleared upon T(iar) triggered: */
699 T_wait_iar.start;
700 alt {
701 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
702 T_wait_iar.stop
703 setverdict(pass);
704 }
705 [] MGCP.receive(tr_DLCX(?)) { repeat; }
706 [] T_wait_iar.timeout {
707 setverdict(fail, "Timeout waiting for T(iar) triggered SCCP RSLD");
708 mtc.stop;
709 }
710 }
711
712 setverdict(pass);
713}
714testcase TC_lu_and_mo_call_sccp_tiar_timeout() runs on MTC_CT {
715 var BSC_ConnHdlr vc_conn;
716
717 /* Set T(iar) in MSC low enough that it will trigger before other side
718 has time to keep alive with a T(ias). Keep recommended ratio of
719 T(iar) >= T(ias)*2 */
720 g_msc_sccp_timer_ias := 2;
721 g_msc_sccp_timer_iar := 5;
722
723 f_init();
724
725 vc_conn := f_start_handler(refers(f_lu_and_mo_call_sccp_tiar_timeout), 89);
726 vc_conn.done;
727}
728
Harald Weltee13cfb22019-04-23 16:52:02 +0200729
Harald Welte071ed732018-01-23 19:53:52 +0100730/* Test LU (with authentication enabled), where HLR times out sending SAI response */
Harald Weltee13cfb22019-04-23 16:52:02 +0200731friend function f_tc_lu_auth_sai_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100732 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100733
734 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
735 var PDU_DTAP_MT dtap_mt;
736
737 /* tell GSUP dispatcher to send this IMSI to us */
738 f_create_gsup_expect(hex2str(g_pars.imsi));
739
740 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200741 f_cl3_or_initial_ue(l3_lu);
Harald Welte071ed732018-01-23 19:53:52 +0100742
743 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +0200744 if (pars.ran_is_geran) {
745 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
746 }
Harald Welte071ed732018-01-23 19:53:52 +0100747
748 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
749 /* The HLR would normally return an auth vector here, but we fail to do so. */
750
751 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100752 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100753}
754testcase TC_lu_auth_sai_timeout() runs on MTC_CT {
755 var BSC_ConnHdlr vc_conn;
756 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100757 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100758
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200759 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_timeout), 8, verify_cell_id := false);
Harald Welte071ed732018-01-23 19:53:52 +0100760 vc_conn.done;
761}
762
Harald Weltee13cfb22019-04-23 16:52:02 +0200763
Harald Welte071ed732018-01-23 19:53:52 +0100764/* Test LU (with authentication enabled), where HLR rejects sending SAI error */
Harald Weltee13cfb22019-04-23 16:52:02 +0200765friend function f_tc_lu_auth_sai_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100766 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100767
768 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
769 var PDU_DTAP_MT dtap_mt;
770
771 /* tell GSUP dispatcher to send this IMSI to us */
772 f_create_gsup_expect(hex2str(g_pars.imsi));
773
774 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200775 f_cl3_or_initial_ue(l3_lu);
Harald Welte071ed732018-01-23 19:53:52 +0100776
777 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +0200778 if (pars.ran_is_geran) {
779 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
780 }
Harald Welte071ed732018-01-23 19:53:52 +0100781
782 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
783 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 13));
784
785 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100786 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100787}
788testcase TC_lu_auth_sai_err() runs on MTC_CT {
789 var BSC_ConnHdlr vc_conn;
790 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100791 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100792
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200793 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_err), 9, verify_cell_id := false);
Harald Welte2bb825f2018-01-22 11:31:18 +0100794 vc_conn.done;
795}
Harald Weltea49e36e2018-01-21 19:29:33 +0100796
Harald Weltee13cfb22019-04-23 16:52:02 +0200797
Harald Weltebc881782018-01-23 20:09:15 +0100798/* Test LU but BSC will send a clear request in the middle */
799private function f_tc_lu_clear_request(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100800 f_init_handler(pars);
Harald Weltebc881782018-01-23 20:09:15 +0100801
802 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
803 var PDU_DTAP_MT dtap_mt;
804
805 /* tell GSUP dispatcher to send this IMSI to us */
806 f_create_gsup_expect(hex2str(g_pars.imsi));
807
808 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200809 f_cl3_or_initial_ue(l3_lu);
Harald Weltebc881782018-01-23 20:09:15 +0100810
811 /* Send Early Classmark, just for the fun of it */
812 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
813
814 f_sleep(1.0);
815 /* send clear request in the middle of the LU */
816 BSSAP.send(ts_BSSMAP_ClearRequest(0));
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200817 alt {
818 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { repeat; }
819 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {}
820 }
Harald Weltebc881782018-01-23 20:09:15 +0100821 BSSAP.send(ts_BSSMAP_ClearComplete);
Harald Welte89a32492018-01-27 19:07:28 +0100822 alt {
823 /* See https://osmocom.org/issues/2862 */
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200824 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
825 setverdict(fail, "Got a second Clear Command, only one expected");
Daniel Willmannafce8662018-07-06 23:11:32 +0200826 mtc.stop;
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200827 repeat;
828 }
Harald Welte6811d102019-04-14 22:23:14 +0200829 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte89a32492018-01-27 19:07:28 +0100830 }
Harald Weltebc881782018-01-23 20:09:15 +0100831 setverdict(pass);
832}
833testcase TC_lu_clear_request() runs on MTC_CT {
834 var BSC_ConnHdlr vc_conn;
835 f_init();
836
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100837 vc_conn := f_start_handler(refers(f_tc_lu_clear_request), 10);
Harald Weltebc881782018-01-23 20:09:15 +0100838 vc_conn.done;
839}
840
Harald Welte66af9e62018-01-24 17:28:21 +0100841/* Test LU but BSC will send a clear request in the middle */
Harald Weltee13cfb22019-04-23 16:52:02 +0200842friend function f_tc_lu_disconnect(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100843 f_init_handler(pars);
Harald Welte66af9e62018-01-24 17:28:21 +0100844
845 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
846 var PDU_DTAP_MT dtap_mt;
847
848 /* tell GSUP dispatcher to send this IMSI to us */
849 f_create_gsup_expect(hex2str(g_pars.imsi));
850
851 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200852 f_cl3_or_initial_ue(l3_lu);
Harald Welte66af9e62018-01-24 17:28:21 +0100853
854 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +0200855 if (pars.ran_is_geran) {
856 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
857 }
Harald Welte66af9e62018-01-24 17:28:21 +0100858
859 f_sleep(1.0);
860 /* send clear request in the middle of the LU */
Harald Welte6811d102019-04-14 22:23:14 +0200861 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Harald Welte66af9e62018-01-24 17:28:21 +0100862 setverdict(pass);
Neels Hofmeyrbb825c92019-03-06 15:35:50 +0100863 f_sleep(1.0);
Harald Welte66af9e62018-01-24 17:28:21 +0100864}
865testcase TC_lu_disconnect() runs on MTC_CT {
866 var BSC_ConnHdlr vc_conn;
867 f_init();
868
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100869 vc_conn := f_start_handler(refers(f_tc_lu_disconnect), 11);
Harald Welte66af9e62018-01-24 17:28:21 +0100870 vc_conn.done;
871}
872
Harald Welteba7b6d92018-01-23 21:32:34 +0100873/* Test LU but with illegal mobile identity type = IMEI */
Harald Weltee13cfb22019-04-23 16:52:02 +0200874friend function f_tc_lu_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100875 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100876
Harald Welte256571e2018-01-24 18:47:19 +0100877 var PDU_ML3_MS_NW l3_lu := f_build_lu_imei(g_pars.imei)
Harald Welteba7b6d92018-01-23 21:32:34 +0100878 var PDU_DTAP_MT dtap_mt;
879
880 /* tell GSUP dispatcher to send this IMSI to us */
881 f_create_gsup_expect(hex2str(g_pars.imsi));
882
883 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200884 f_cl3_or_initial_ue(l3_lu);
Harald Welteba7b6d92018-01-23 21:32:34 +0100885
886 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +0200887 if (pars.ran_is_geran) {
888 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
889 }
Harald Welteba7b6d92018-01-23 21:32:34 +0100890 /* wait for LU reject, ignore any ID REQ */
891 alt {
892 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
893 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req)) { repeat; }
894 }
895 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100896 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100897}
898testcase TC_lu_by_imei() runs on MTC_CT {
899 var BSC_ConnHdlr vc_conn;
900 f_init();
901
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200902 vc_conn := f_start_handler(refers(f_tc_lu_by_imei), 12, verify_cell_id := false);
Harald Welteba7b6d92018-01-23 21:32:34 +0100903 vc_conn.done;
904}
905
Harald Weltee13cfb22019-04-23 16:52:02 +0200906
Harald Welteba7b6d92018-01-23 21:32:34 +0100907/* Test LU by TMSI with unknown TMSI, expect (and answer) ID REQ. */
908private function f_tc_lu_tmsi_noauth_unknown(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Stefan Sperling04fc4bc2018-06-25 17:44:57 +0200909 /* We piggyback a test for an MSC crash on overlong IMSI (OS#2864) onto this test. */
910 var hexstring overlong_imsi := '012345789ABCDEF0123456789ABCDEF'H;
Harald Weltea10db902018-01-27 12:44:49 +0100911 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100912
913 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('01020304'O); /* FIXME: Random */
914 var PDU_DTAP_MT dtap_mt;
915
916 /* tell GSUP dispatcher to send this IMSI to us */
917 f_create_gsup_expect(hex2str(g_pars.imsi));
918
919 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200920 f_cl3_or_initial_ue(l3_lu);
Harald Welteba7b6d92018-01-23 21:32:34 +0100921
922 /* Send Early Classmark, just for the fun of it */
923 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
924
925 /* Wait for + respond to ID REQ (IMSI) */
Oliver Smith32898452019-07-09 12:32:35 +0200926 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req(CM_ID_TYPE_IMSI)));
Stefan Sperling04fc4bc2018-06-25 17:44:57 +0200927 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(overlong_imsi))); /* test for OS#2864 */
Harald Welteba7b6d92018-01-23 21:32:34 +0100928 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
929
930 /* Expect MSC to do UpdateLocation to HLR; respond to it */
931 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
932 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
933 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
934 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
935
936 alt {
Harald Welte7ec4fa82018-01-27 10:57:40 +0100937 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
938 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
939 }
Harald Welteba7b6d92018-01-23 21:32:34 +0100940 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
941 setverdict(fail, "Expected LU ACK, but received REJ");
Daniel Willmannafce8662018-07-06 23:11:32 +0200942 mtc.stop;
Harald Welteba7b6d92018-01-23 21:32:34 +0100943 }
944 }
945
Philipp Maier9b690e42018-12-21 11:50:03 +0100946 /* Wait for MM-Information (if enabled) */
947 f_expect_mm_info();
948
Harald Welteba7b6d92018-01-23 21:32:34 +0100949 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100950 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100951}
952testcase TC_lu_by_tmsi_noauth_unknown() runs on MTC_CT {
953 var BSC_ConnHdlr vc_conn;
954 f_init();
955
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100956 vc_conn := f_start_handler(refers(f_tc_lu_tmsi_noauth_unknown), 13);
Harald Welteba7b6d92018-01-23 21:32:34 +0100957 vc_conn.done;
958}
959
960
Harald Welte45164da2018-01-24 12:51:27 +0100961/* Test IMSI DETACH (MI=IMSI) */
Harald Weltee13cfb22019-04-23 16:52:02 +0200962friend function f_tc_imsi_detach_by_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100963 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100964
965 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
966
967 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200968 f_cl3_or_initial_ue(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
Harald Welte45164da2018-01-24 12:51:27 +0100969
970 /* Send Early Classmark, just for the fun of it? */
Harald Weltee13cfb22019-04-23 16:52:02 +0200971 if (pars.ran_is_geran) {
972 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
973 }
Harald Welte45164da2018-01-24 12:51:27 +0100974
975 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100976 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100977}
978testcase TC_imsi_detach_by_imsi() runs on MTC_CT {
979 var BSC_ConnHdlr vc_conn;
980 f_init();
981
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200982 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imsi), 14, verify_cell_id := false);
Harald Welte45164da2018-01-24 12:51:27 +0100983 vc_conn.done;
984}
985
Harald Weltee13cfb22019-04-23 16:52:02 +0200986
Harald Welte45164da2018-01-24 12:51:27 +0100987/* Test IMSI DETACH (MI=TMSI) */
Harald Weltee13cfb22019-04-23 16:52:02 +0200988friend function f_tc_imsi_detach_by_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100989 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100990
991 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('01020304'O));
992
993 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200994 f_cl3_or_initial_ue(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
Harald Welte45164da2018-01-24 12:51:27 +0100995
996 /* Send Early Classmark, just for the fun of it? */
Harald Weltee13cfb22019-04-23 16:52:02 +0200997 if (pars.ran_is_geran) {
998 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
999 }
Harald Welte45164da2018-01-24 12:51:27 +01001000
1001 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +01001002 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001003}
1004testcase TC_imsi_detach_by_tmsi() runs on MTC_CT {
1005 var BSC_ConnHdlr vc_conn;
1006 f_init();
1007
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001008 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_tmsi), 15, verify_cell_id := false);
Harald Welte45164da2018-01-24 12:51:27 +01001009 vc_conn.done;
1010}
1011
Harald Weltee13cfb22019-04-23 16:52:02 +02001012
Harald Welte45164da2018-01-24 12:51:27 +01001013/* Test IMSI DETACH (MI=IMEI), which is illegal */
Harald Weltee13cfb22019-04-23 16:52:02 +02001014friend function f_tc_imsi_detach_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001015 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001016
Harald Welte256571e2018-01-24 18:47:19 +01001017 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte45164da2018-01-24 12:51:27 +01001018
1019 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001020 f_cl3_or_initial_ue(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
Harald Welte45164da2018-01-24 12:51:27 +01001021
1022 /* Send Early Classmark, just for the fun of it? */
Harald Weltee13cfb22019-04-23 16:52:02 +02001023 if (pars.ran_is_geran) {
1024 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1025 }
Harald Welte45164da2018-01-24 12:51:27 +01001026
1027 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +01001028 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001029}
1030testcase TC_imsi_detach_by_imei() runs on MTC_CT {
1031 var BSC_ConnHdlr vc_conn;
1032 f_init();
1033
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001034 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imei), 16, verify_cell_id := false);
Harald Welte45164da2018-01-24 12:51:27 +01001035 vc_conn.done;
1036}
1037
1038
1039/* helper function for an emergency call. caller passes in mobile identity to use */
1040private function f_emerg_call(MobileIdentityLV mi) runs on BSC_ConnHdlr {
Harald Welte0bef21e2018-02-10 09:48:23 +01001041 var CallParameters cpars := valueof(t_CallParams('112'H, 0));
1042 cpars.emergency := true;
Harald Welte45164da2018-01-24 12:51:27 +01001043
Harald Welte0bef21e2018-02-10 09:48:23 +01001044 f_mo_call(cpars);
Harald Welte45164da2018-01-24 12:51:27 +01001045}
1046
1047/* establish an emergency call by IMEI, no SIM inserted (and hence no IMSI) */
Harald Weltee13cfb22019-04-23 16:52:02 +02001048friend function f_tc_emerg_call_imei_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001049 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001050
Harald Welte256571e2018-01-24 18:47:19 +01001051 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001052 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001053 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +01001054 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ('05'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +01001055 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001056}
1057testcase TC_emerg_call_imei_reject() runs on MTC_CT {
1058 var BSC_ConnHdlr vc_conn;
1059 f_init();
1060
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001061 vc_conn := f_start_handler(refers(f_tc_emerg_call_imei_reject), 17, verify_cell_id := false);
Harald Welte45164da2018-01-24 12:51:27 +01001062 vc_conn.done;
1063}
1064
Harald Weltee13cfb22019-04-23 16:52:02 +02001065
Harald Welted5b91402018-01-24 18:48:16 +01001066/* establish an emergency call by IMSI, SIM inserted (and hence IMSI) */
Harald Weltee13cfb22019-04-23 16:52:02 +02001067friend function f_tc_emerg_call_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001068 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001069 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001070 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001071 /* Then issue emergency call identified by IMSI */
1072 f_emerg_call(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
1073}
1074testcase TC_emerg_call_imsi() runs on MTC_CT {
1075 var BSC_ConnHdlr vc_conn;
1076 f_init();
1077
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001078 vc_conn := f_start_handler(refers(f_tc_emerg_call_imsi), 18);
Harald Welte45164da2018-01-24 12:51:27 +01001079 vc_conn.done;
1080}
1081
Harald Weltee13cfb22019-04-23 16:52:02 +02001082
Harald Welte45164da2018-01-24 12:51:27 +01001083/* CM Service Request for VGCS -> reject */
1084private function f_tc_cm_serv_req_vgcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001085 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001086
1087 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001088 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001089
1090 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001091 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VGCS, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001092 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +01001093 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001094 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001095}
1096testcase TC_cm_serv_req_vgcs_reject() runs on MTC_CT {
1097 var BSC_ConnHdlr vc_conn;
1098 f_init();
1099
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001100 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vgcs_reject), 19);
Harald Welte45164da2018-01-24 12:51:27 +01001101 vc_conn.done;
1102}
1103
1104/* CM Service Request for VBS -> reject */
1105private function f_tc_cm_serv_req_vbs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001106 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001107
1108 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001109 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001110
1111 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001112 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VBS, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001113 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +01001114 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001115 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001116}
1117testcase TC_cm_serv_req_vbs_reject() runs on MTC_CT {
1118 var BSC_ConnHdlr vc_conn;
1119 f_init();
1120
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001121 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vbs_reject), 20);
Harald Welte45164da2018-01-24 12:51:27 +01001122 vc_conn.done;
1123}
1124
1125/* CM Service Request for LCS -> reject */
1126private function f_tc_cm_serv_req_lcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001127 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001128
1129 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001130 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001131
1132 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001133 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_LCS, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001134 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +01001135 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001136 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001137}
1138testcase TC_cm_serv_req_lcs_reject() runs on MTC_CT {
1139 var BSC_ConnHdlr vc_conn;
1140 f_init();
1141
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001142 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_lcs_reject), 21);
Harald Welte45164da2018-01-24 12:51:27 +01001143 vc_conn.done;
1144}
1145
Harald Welte0195ab12018-01-24 21:50:20 +01001146/* CM Re-Establishment Request */
1147private function f_tc_cm_reest_req_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001148 f_init_handler(pars);
Harald Welte0195ab12018-01-24 21:50:20 +01001149
1150 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001151 f_perform_lu();
Harald Welte0195ab12018-01-24 21:50:20 +01001152
1153 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1154 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REEST_REQ(0, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001155 f_cl3_or_initial_ue(l3_info);
Harald Welte0195ab12018-01-24 21:50:20 +01001156 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001157 f_expect_clear();
Harald Welte0195ab12018-01-24 21:50:20 +01001158}
1159testcase TC_cm_reest_req_reject() runs on MTC_CT {
1160 var BSC_ConnHdlr vc_conn;
1161 f_init();
Harald Welte0195ab12018-01-24 21:50:20 +01001162
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001163 vc_conn := f_start_handler(refers(f_tc_cm_reest_req_reject), 22);
Harald Welte0195ab12018-01-24 21:50:20 +01001164 vc_conn.done;
1165}
1166
Harald Weltec638f4d2018-01-24 22:00:36 +01001167/* Test LU (with authentication enabled), with wrong response from MS */
1168private function f_tc_lu_auth_2G_fail(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001169 f_init_handler(pars);
Harald Weltec638f4d2018-01-24 22:00:36 +01001170
1171 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
1172
1173 /* tell GSUP dispatcher to send this IMSI to us */
1174 f_create_gsup_expect(hex2str(g_pars.imsi));
1175
1176 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001177 f_cl3_or_initial_ue(l3_lu);
Harald Weltec638f4d2018-01-24 22:00:36 +01001178
1179 /* Send Early Classmark, just for the fun of it */
1180 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1181
1182 var AuthVector vec := f_gen_auth_vec_2g();
1183 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(vec.rand, vec.sres, vec.kc));
1184 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
1185 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
1186
1187 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(vec.rand)));
1188 /* Send back wrong auth response */
1189 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G('00000000'O)));
1190
1191 /* Expect GSUP AUTH FAIL REP to HLR */
1192 GSUP.receive(tr_GSUP_AUTH_FAIL_IND(g_pars.imsi));
1193
1194 /* Expect LU REJECT with Cause == Illegal MS */
1195 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej('03'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +01001196 f_expect_clear();
Harald Weltec638f4d2018-01-24 22:00:36 +01001197}
1198testcase TC_lu_auth_2G_fail() runs on MTC_CT {
1199 var BSC_ConnHdlr vc_conn;
1200 f_init();
1201 f_vty_config(MSCVTY, "network", "authentication required");
Harald Weltec638f4d2018-01-24 22:00:36 +01001202
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001203 vc_conn := f_start_handler(refers(f_tc_lu_auth_2G_fail), 23, verify_cell_id := false);
Harald Weltec638f4d2018-01-24 22:00:36 +01001204 vc_conn.done;
1205}
1206
Harald Weltede371492018-01-27 23:44:41 +01001207/* A5/1 + A5/3 permitted on network side, and MS capable to do it */
Harald Welte16114282018-01-24 22:41:21 +01001208private function f_tc_lu_imsi_auth_tmsi_encr_13_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +01001209 pars.net.expect_auth := true;
1210 pars.net.expect_ciph := true;
Harald Weltea10db902018-01-27 12:44:49 +01001211 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001212 f_perform_lu();
Harald Welte16114282018-01-24 22:41:21 +01001213}
1214testcase TC_lu_imsi_auth_tmsi_encr_13_13() runs on MTC_CT {
1215 var BSC_ConnHdlr vc_conn;
1216 f_init();
1217 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte16114282018-01-24 22:41:21 +01001218 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1219
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001220 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_13), 24);
Harald Welte16114282018-01-24 22:41:21 +01001221 vc_conn.done;
1222}
1223
Harald Welte1af6ea82018-01-25 18:33:15 +01001224/* Test Complete L3 without payload */
1225private function f_tc_cl3_no_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001226 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001227
1228 /* Send Complete L3 Info with empty L3 frame */
1229 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1230 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, ''O))));
1231
Harald Weltef466eb42018-01-27 14:26:54 +01001232 timer T := 5.0;
1233 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001234 alt {
Harald Welte6811d102019-04-14 22:23:14 +02001235 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte1af6ea82018-01-25 18:33:15 +01001236 /* Expect LU REJECT with Cause == Illegal MS */
Harald Weltebdb3c452018-03-18 22:43:06 +01001237 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
Harald Welte6811d102019-04-14 22:23:14 +02001238 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001239 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001240 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001241 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Daniel Willmannafce8662018-07-06 23:11:32 +02001242 mtc.stop;
Harald Weltef466eb42018-01-27 14:26:54 +01001243 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001244 }
1245 setverdict(pass);
1246}
1247testcase TC_cl3_no_payload() runs on MTC_CT {
1248 var BSC_ConnHdlr vc_conn;
1249 f_init();
1250
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001251 vc_conn := f_start_handler(refers(f_tc_cl3_no_payload), 25);
Harald Welte1af6ea82018-01-25 18:33:15 +01001252 vc_conn.done;
1253}
1254
1255/* Test Complete L3 with random payload */
1256private function f_tc_cl3_rnd_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001257 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001258
Daniel Willmannaa14a382018-07-26 08:29:45 +02001259 /* length is limited by PDU_BSSAP length field which includes some
1260 * other fields beside l3info payload. So payl can only be 240 bytes
1261 * Since rnd() returns values < 1 multiply with 241
1262 */
1263 var integer len := float2int(rnd() * 241.0);
Harald Welte1af6ea82018-01-25 18:33:15 +01001264 var octetstring payl := f_rnd_octstring(len);
1265
1266 /* Send Complete L3 Info with empty L3 frame */
1267 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1268 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, payl))));
1269
Harald Weltef466eb42018-01-27 14:26:54 +01001270 timer T := 5.0;
1271 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001272 alt {
1273 /* Immediate disconnect */
Harald Welte6811d102019-04-14 22:23:14 +02001274 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte1af6ea82018-01-25 18:33:15 +01001275 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
Harald Welte6811d102019-04-14 22:23:14 +02001276 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001277 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001278 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001279 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Daniel Willmannafce8662018-07-06 23:11:32 +02001280 mtc.stop;
Harald Weltef466eb42018-01-27 14:26:54 +01001281 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001282 }
1283 setverdict(pass);
1284}
1285testcase TC_cl3_rnd_payload() runs on MTC_CT {
1286 var BSC_ConnHdlr vc_conn;
1287 f_init();
1288
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001289 vc_conn := f_start_handler(refers(f_tc_cl3_rnd_payload), 26);
Harald Welte1af6ea82018-01-25 18:33:15 +01001290 vc_conn.done;
1291}
1292
Harald Welte116e4332018-01-26 22:17:48 +01001293/* Test Complete L3 with random payload */
Harald Weltee13cfb22019-04-23 16:52:02 +02001294friend function f_tc_establish_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001295 f_init_handler(pars);
Harald Welte116e4332018-01-26 22:17:48 +01001296
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001297 f_perform_lu();
Harald Welte116e4332018-01-26 22:17:48 +01001298
Harald Welteb9e86fa2018-04-09 18:18:31 +02001299 f_establish_fully();
Daniel Willmann898a7e02018-05-17 12:16:16 +02001300 f_expect_clear(10.0);
Harald Welte116e4332018-01-26 22:17:48 +01001301}
1302testcase TC_establish_and_nothing() runs on MTC_CT {
1303 var BSC_ConnHdlr vc_conn;
1304 f_init();
1305
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001306 vc_conn := f_start_handler(refers(f_tc_establish_and_nothing), 27);
Harald Welte116e4332018-01-26 22:17:48 +01001307 vc_conn.done;
1308}
1309
Harald Weltee13cfb22019-04-23 16:52:02 +02001310
Harald Welte12510c52018-01-26 22:26:24 +01001311/* Test MO Call SETUP with no response from MNCC */
Harald Weltee13cfb22019-04-23 16:52:02 +02001312friend function f_tc_mo_setup_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Philipp Maier109e6aa2018-10-17 10:53:32 +02001313 f_init_handler(pars, 190.0);
Harald Weltea10db902018-01-27 12:44:49 +01001314
Harald Welte12510c52018-01-26 22:26:24 +01001315 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001316 cpars.mgw_conn_2.resp := 0;
1317 cpars.stop_after_cc_setup := true;
1318
1319 f_vty_config(MSCVTY, "msc", "mncc guard-timeout 20");
Harald Welte12510c52018-01-26 22:26:24 +01001320
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001321 f_perform_lu();
Harald Welte12510c52018-01-26 22:26:24 +01001322
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001323 f_mo_call_establish(cpars);
Harald Welte12510c52018-01-26 22:26:24 +01001324
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001325 var default ccrel := activate(as_optional_cc_rel(cpars));
1326
Philipp Maier109e6aa2018-10-17 10:53:32 +02001327 f_expect_clear(185.0);
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001328
1329 deactivate(ccrel);
1330
1331 f_sleep(1.0);
Harald Welte12510c52018-01-26 22:26:24 +01001332}
1333testcase TC_mo_setup_and_nothing() runs on MTC_CT {
1334 var BSC_ConnHdlr vc_conn;
1335 f_init();
1336
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001337 vc_conn := f_start_handler(refers(f_tc_mo_setup_and_nothing), 28);
Harald Welte12510c52018-01-26 22:26:24 +01001338 vc_conn.done;
1339}
1340
Harald Weltee13cfb22019-04-23 16:52:02 +02001341
Harald Welte3ab88002018-01-26 22:37:25 +01001342/* Test MO Call with no response to RAN-side CRCX */
Harald Weltee13cfb22019-04-23 16:52:02 +02001343friend function f_tc_mo_crcx_ran_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001344 f_init_handler(pars);
Harald Welte3ab88002018-01-26 22:37:25 +01001345 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1346 var MNCC_PDU mncc;
1347 var MgcpCommand mgcp_cmd;
1348
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001349 f_perform_lu();
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001350 /* Do not respond to the second CRCX */
1351 cpars.mgw_conn_2.resp := 0;
1352 f_mo_call_establish(cpars);
Harald Welte3ab88002018-01-26 22:37:25 +01001353
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001354 var default ccrel := activate(as_optional_cc_rel(cpars));
Harald Welte3ab88002018-01-26 22:37:25 +01001355
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001356 f_expect_clear(60.0);
Harald Welte3ab88002018-01-26 22:37:25 +01001357
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001358 deactivate(ccrel);
Harald Welte3ab88002018-01-26 22:37:25 +01001359}
1360testcase TC_mo_crcx_ran_timeout() runs on MTC_CT {
1361 var BSC_ConnHdlr vc_conn;
1362 f_init();
1363
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001364 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_timeout), 29);
Harald Welte3ab88002018-01-26 22:37:25 +01001365 vc_conn.done;
1366}
1367
Harald Weltee13cfb22019-04-23 16:52:02 +02001368
Harald Welte0cc82d92018-01-26 22:52:34 +01001369/* Test MO Call with reject to RAN-side CRCX */
Harald Weltee13cfb22019-04-23 16:52:02 +02001370friend function f_tc_mo_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001371 f_init_handler(pars);
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001372
Harald Welte0cc82d92018-01-26 22:52:34 +01001373 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001374
1375 /* Respond with error for the first CRCX */
1376 cpars.mgw_conn_1.resp := -1;
Harald Welte0cc82d92018-01-26 22:52:34 +01001377
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001378 f_perform_lu();
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001379 f_mo_call_establish(cpars);
Harald Welte0cc82d92018-01-26 22:52:34 +01001380
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001381 var default ccrel := activate(as_optional_cc_rel(cpars));
1382 f_expect_clear(60.0);
1383 deactivate(ccrel);
Harald Welte0cc82d92018-01-26 22:52:34 +01001384}
1385testcase TC_mo_crcx_ran_reject() runs on MTC_CT {
1386 var BSC_ConnHdlr vc_conn;
1387 f_init();
1388
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001389 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_reject), 30);
Harald Welte0cc82d92018-01-26 22:52:34 +01001390 vc_conn.done;
1391}
1392
Harald Welte3ab88002018-01-26 22:37:25 +01001393
Harald Welte812f7a42018-01-27 00:49:18 +01001394/* helper function to start a MT call: MNCC SETUP; Paging; DChan est.; DTAP SETUP */
1395private function f_mt_call_start(inout CallParameters cpars) runs on BSC_ConnHdlr {
1396 var MNCC_PDU mncc;
1397 var MgcpCommand mgcp_cmd;
Harald Welte812f7a42018-01-27 00:49:18 +01001398
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001399 f_perform_lu();
Vadim Yanitskiyae747742020-01-10 00:23:10 +01001400 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Harald Welte812f7a42018-01-27 00:49:18 +01001401
1402 /* Allocate call reference and send SETUP via MNCC to MSC */
1403 cpars.mncc_callref := f_rnd_int(2147483648);
1404 MNCC.send(ts_MNCC_SETUP_req(cpars.mncc_callref, hex2str(g_pars.msisdn),
1405 hex2str(cpars.called_party), hex2str(g_pars.imsi)));
1406
1407 /* MSC->BSC: expect PAGING from MSC */
Harald Weltee035e3e2019-04-21 17:32:05 +02001408 f_expect_paging();
1409
Harald Welte812f7a42018-01-27 00:49:18 +01001410 /* MS -> MSC: PAGING RESPONSE */
Harald Welteb9e86fa2018-04-09 18:18:31 +02001411 f_establish_fully(EST_TYPE_PAG_RESP);
Harald Welte812f7a42018-01-27 00:49:18 +01001412
1413 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1414
1415 /* MSC->MS: SETUP */
1416 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party)));
1417}
1418
1419/* Test MT Call */
Harald Weltee13cfb22019-04-23 16:52:02 +02001420friend function f_tc_mt_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001421 f_init_handler(pars);
Harald Welte812f7a42018-01-27 00:49:18 +01001422 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1423 var MNCC_PDU mncc;
1424 var MgcpCommand mgcp_cmd;
1425
1426 f_mt_call_start(cpars);
1427
1428 /* MS->MSC: CALL CONFIRMED */
1429 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1430
1431 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1432
1433 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1434 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001435
1436 /* Detect if the received CRCX is a wildcarded CRCX request. If yes,
1437 * set an endpoint name that fits the pattern. If not, just use the
1438 * endpoint name from the request */
1439 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
1440 cpars.mgcp_ep := "rtpbridge/1@mgw";
1441 } else {
1442 cpars.mgcp_ep := mgcp_cmd.line.ep;
1443 }
1444
Harald Welte812f7a42018-01-27 00:49:18 +01001445 /* Respond to CRCX with error */
1446 var MgcpResponse mgcp_rsp := {
1447 line := {
1448 code := "542",
1449 trans_id := mgcp_cmd.line.trans_id,
1450 string := "FORCED_FAIL"
1451 },
Harald Welte812f7a42018-01-27 00:49:18 +01001452 sdp := omit
1453 }
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001454 var MgcpParameter mgcp_rsp_param := {
1455 code := "Z",
1456 val := cpars.mgcp_ep
1457 };
1458 mgcp_rsp.params[0] := mgcp_rsp_param;
Harald Welte812f7a42018-01-27 00:49:18 +01001459 MGCP.send(mgcp_rsp);
1460
1461 timer T := 30.0;
1462 T.start;
1463 alt {
Daniel Willmannafce8662018-07-06 23:11:32 +02001464 [] T.timeout {
1465 setverdict(fail, "Timeout waiting for channel release");
1466 mtc.stop;
1467 }
Harald Welte812f7a42018-01-27 00:49:18 +01001468 [] MNCC.receive { repeat; }
1469 [] GSUP.receive { repeat; }
1470 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1471 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1472 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1473 repeat;
1474 }
1475 [] MGCP.receive { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001476 [] as_clear_cmd_compl_disc();
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001477 [] as_optional_cc_rel(cpars);
Harald Welte812f7a42018-01-27 00:49:18 +01001478 }
1479}
1480testcase TC_mt_crcx_ran_reject() runs on MTC_CT {
1481 var BSC_ConnHdlr vc_conn;
1482 f_init();
1483
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001484 vc_conn := f_start_handler(refers(f_tc_mt_crcx_ran_reject), 31);
Harald Welte812f7a42018-01-27 00:49:18 +01001485 vc_conn.done;
1486}
1487
1488
Harald Weltee13cfb22019-04-23 16:52:02 +02001489
Harald Welte812f7a42018-01-27 00:49:18 +01001490/* Test MT Call T310 timer */
Harald Weltee13cfb22019-04-23 16:52:02 +02001491friend function f_tc_mt_t310(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltead2952e2018-01-27 14:12:46 +01001492 f_init_handler(pars, 200.0);
Harald Welte812f7a42018-01-27 00:49:18 +01001493 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1494 var MNCC_PDU mncc;
1495 var MgcpCommand mgcp_cmd;
1496
1497 f_mt_call_start(cpars);
1498
1499 /* MS->MSC: CALL CONFIRMED */
1500 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1501 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1502
1503 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1504 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1505 cpars.mgcp_ep := mgcp_cmd.line.ep;
1506 /* FIXME: Respond to CRCX */
1507
1508 /* old libosmocore T310 default timeout is 180s. so let's wait 190 */
1509 timer T := 190.0;
1510 T.start;
1511 alt {
Daniel Willmannafce8662018-07-06 23:11:32 +02001512 [] T.timeout {
1513 setverdict(fail, "Timeout waiting for T310");
1514 mtc.stop;
1515 }
Harald Welte812f7a42018-01-27 00:49:18 +01001516 [] MNCC.receive(tr_MNCC_DISC_ind(cpars.mncc_callref)) {
1517 MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(23))));
1518 }
1519 }
1520 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));
1521 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1522 /* FIXME: We're sending this with TIflag 0: allocated by sender, which is wrong */
1523 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1524
1525 alt {
Harald Welte812f7a42018-01-27 00:49:18 +01001526 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1527 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1528 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1529 repeat;
1530 }
Harald Welte5946b332018-03-18 23:32:21 +01001531 [] as_clear_cmd_compl_disc();
Harald Welte812f7a42018-01-27 00:49:18 +01001532 }
1533}
1534testcase TC_mt_t310() runs on MTC_CT {
1535 var BSC_ConnHdlr vc_conn;
1536 f_init();
1537
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001538 vc_conn := f_start_handler(refers(f_tc_mt_t310), 32);
Harald Welte812f7a42018-01-27 00:49:18 +01001539 vc_conn.done;
1540}
1541
Harald Weltee13cfb22019-04-23 16:52:02 +02001542
Harald Welte167458a2018-01-27 15:58:16 +01001543/* Perform successful LU + MO call, then GSUP LocationCancel. Subscriber must be denied CM SERV */
Harald Weltee13cfb22019-04-23 16:52:02 +02001544friend function f_tc_gsup_cancel(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Welte167458a2018-01-27 15:58:16 +01001545 f_init_handler(pars);
1546 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Harald Welte167458a2018-01-27 15:58:16 +01001547
1548 /* Location Update to make subscriber known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001549 f_perform_lu();
Harald Welte167458a2018-01-27 15:58:16 +01001550
1551 /* First MO call should succeed */
1552 f_mo_call(cpars);
1553
1554 /* Cancel the subscriber in the VLR */
1555 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1556 alt {
1557 [] GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi)) { }
1558 [] GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi)) {
1559 setverdict(fail, "Received GSUP Location Cancel Error");
Daniel Willmannafce8662018-07-06 23:11:32 +02001560 mtc.stop;
Harald Welte167458a2018-01-27 15:58:16 +01001561 }
1562 }
1563
1564 /* Follow-up transactions should fail */
1565 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1566 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001567 f_cl3_or_initial_ue(l3_info);
Harald Welte167458a2018-01-27 15:58:16 +01001568 alt {
1569 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
1570 [] BSSAP.receive {
1571 setverdict(fail, "Received unexpected BSSAP instead of CM SERV REJ");
Daniel Willmannafce8662018-07-06 23:11:32 +02001572 mtc.stop;
Harald Welte167458a2018-01-27 15:58:16 +01001573 }
1574 }
Neels Hofmeyr0f7429a2019-03-07 22:28:41 +01001575
1576 f_expect_clear();
Harald Welte167458a2018-01-27 15:58:16 +01001577 setverdict(pass);
1578}
1579testcase TC_gsup_cancel() runs on MTC_CT {
1580 var BSC_ConnHdlr vc_conn;
1581 f_init();
1582
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001583 vc_conn := f_start_handler(refers(f_tc_gsup_cancel), 33, verify_cell_id := false);
Harald Welte167458a2018-01-27 15:58:16 +01001584 vc_conn.done;
1585}
1586
Harald Weltee13cfb22019-04-23 16:52:02 +02001587
Harald Welte9de84792018-01-28 01:06:35 +01001588/* A5/1 only permitted on network side, and MS capable to do it */
1589private function f_tc_lu_imsi_auth_tmsi_encr_1_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1590 pars.net.expect_auth := true;
1591 pars.net.expect_ciph := true;
1592 pars.net.kc_support := '02'O; /* A5/1 only */
1593 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001594 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001595}
1596testcase TC_lu_imsi_auth_tmsi_encr_1_13() runs on MTC_CT {
1597 var BSC_ConnHdlr vc_conn;
1598 f_init();
1599 f_vty_config(MSCVTY, "network", "authentication required");
1600 f_vty_config(MSCVTY, "network", "encryption a5 1");
1601
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001602 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_1_13), 34);
Harald Welte9de84792018-01-28 01:06:35 +01001603 vc_conn.done;
1604}
1605
1606/* A5/3 only permitted on network side, and MS capable to do it */
1607private function f_tc_lu_imsi_auth_tmsi_encr_3_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1608 pars.net.expect_auth := true;
1609 pars.net.expect_ciph := true;
1610 pars.net.kc_support := '08'O; /* A5/3 only */
1611 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001612 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001613}
1614testcase TC_lu_imsi_auth_tmsi_encr_3_13() runs on MTC_CT {
1615 var BSC_ConnHdlr vc_conn;
1616 f_init();
1617 f_vty_config(MSCVTY, "network", "authentication required");
1618 f_vty_config(MSCVTY, "network", "encryption a5 3");
1619
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001620 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_13), 35);
Harald Welte9de84792018-01-28 01:06:35 +01001621 vc_conn.done;
1622}
1623
1624/* A5/3 only permitted on network side, and MS with only A5/1 support */
1625private function f_tc_lu_imsi_auth_tmsi_encr_3_1(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1626 pars.net.expect_auth := true;
1627 pars.net.expect_ciph := true;
1628 pars.net.kc_support := '08'O; /* A5/3 only */
1629 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1630 f_init_handler(pars, 15.0);
1631
1632 /* cannot use f_perform_lu() as we expect a reject */
1633 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1634 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +02001635 f_cl3_or_initial_ue(l3_lu);
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001636 if (pars.send_early_cm) {
1637 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1638 } else {
1639 pars.cm1.esind := '0'B;
1640 }
Harald Welte9de84792018-01-28 01:06:35 +01001641 f_mm_auth();
1642 alt {
Daniel Willmann52918e52018-09-20 14:39:09 +02001643 [] BSSAP.receive(tr_BSSMAP_ClassmarkReq) {
1644 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1645 repeat;
1646 }
Harald Welte5946b332018-03-18 23:32:21 +01001647 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1648 f_expect_clear();
1649 }
Harald Welte9de84792018-01-28 01:06:35 +01001650 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1651 setverdict(fail, "CipherModeCommand despite no A5 intersection");
Daniel Willmannafce8662018-07-06 23:11:32 +02001652 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001653 }
1654 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001655 setverdict(fail, "Unknown/unexpected BSSAP received");
Daniel Willmannafce8662018-07-06 23:11:32 +02001656 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001657 }
1658 }
1659 setverdict(pass);
1660}
1661testcase TC_lu_imsi_auth_tmsi_encr_3_1() runs on MTC_CT {
1662 var BSC_ConnHdlr vc_conn;
1663 f_init();
1664 f_vty_config(MSCVTY, "network", "authentication required");
1665 f_vty_config(MSCVTY, "network", "encryption a5 3");
1666
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001667 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 360, verify_cell_id := false);
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001668 vc_conn.done;
1669}
1670testcase TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() runs on MTC_CT {
1671 var BSC_ConnHdlrPars pars;
1672 var BSC_ConnHdlr vc_conn;
1673 f_init();
1674 f_vty_config(MSCVTY, "network", "authentication required");
1675 f_vty_config(MSCVTY, "network", "encryption a5 3");
1676
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001677 pars := f_init_pars(361, verify_cell_id := false);
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001678 pars.send_early_cm := false;
1679 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), pars);
Harald Welte9de84792018-01-28 01:06:35 +01001680 vc_conn.done;
1681}
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01001682testcase TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() runs on MTC_CT {
1683 var BSC_ConnHdlr vc_conn;
1684 f_init();
1685 f_vty_config(MSCVTY, "network", "authentication required");
1686 f_vty_config(MSCVTY, "network", "encryption a5 3");
1687
1688 /* Make sure the MSC category is on DEBUG level to trigger the log
1689 * message that is reported in OS#2947 to trigger the segfault */
1690 f_vty_config(MSCVTY, "log stderr", "logging level msc debug");
1691
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001692 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 362, verify_cell_id := false);
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01001693 vc_conn.done;
1694}
Harald Welte9de84792018-01-28 01:06:35 +01001695
1696/* A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
1697private function f_tc_lu_imsi_auth_tmsi_encr_13_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1698 pars.net.expect_auth := true;
1699 pars.net.expect_ciph := true;
1700 pars.net.kc_support := '0A'O; /* A5/1 + A5/3 */
1701 pars.cm1.a5_1 := '1'B;
1702 pars.cm2.a5_1 := '1'B;
1703 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1704 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
1705 f_init_handler(pars, 15.0);
1706
1707 /* cannot use f_perform_lu() as we expect a reject */
1708 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1709 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +02001710 f_cl3_or_initial_ue(l3_lu);
Harald Welte9de84792018-01-28 01:06:35 +01001711 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1712 f_mm_auth();
1713 alt {
Harald Welte5946b332018-03-18 23:32:21 +01001714 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1715 f_expect_clear();
1716 }
Harald Welte9de84792018-01-28 01:06:35 +01001717 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1718 setverdict(fail, "CipherModeCommand despite no A5 intersection");
Daniel Willmannafce8662018-07-06 23:11:32 +02001719 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001720 }
1721 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001722 setverdict(fail, "Unknown/unexpected BSSAP received");
Daniel Willmannafce8662018-07-06 23:11:32 +02001723 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001724 }
1725 }
1726 setverdict(pass);
1727}
1728testcase TC_lu_imsi_auth_tmsi_encr_13_2() runs on MTC_CT {
1729 var BSC_ConnHdlr vc_conn;
1730 f_init();
1731 f_vty_config(MSCVTY, "network", "authentication required");
1732 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1733
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001734 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_2), 37, verify_cell_id := false);
Harald Welte9de84792018-01-28 01:06:35 +01001735 vc_conn.done;
1736}
1737
1738/* A5/0 + A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
1739private function f_tc_lu_imsi_auth_tmsi_encr_013_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1740 pars.net.expect_auth := true;
1741 pars.net.expect_ciph := true;
1742 pars.net.kc_support := '0B'O; /* A5/1 + A5/3 */
1743 pars.cm1.a5_1 := '1'B;
1744 pars.cm2.a5_1 := '1'B;
1745 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1746 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
1747 f_init_handler(pars, 15.0);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001748 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001749}
1750testcase TC_lu_imsi_auth_tmsi_encr_013_2() runs on MTC_CT {
1751 var BSC_ConnHdlr vc_conn;
1752 f_init();
1753 f_vty_config(MSCVTY, "network", "authentication required");
1754 f_vty_config(MSCVTY, "network", "encryption a5 0 1 3");
1755
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001756 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_013_2), 38);
Harald Welte9de84792018-01-28 01:06:35 +01001757 vc_conn.done;
1758}
1759
Harald Welte33ec09b2018-02-10 15:34:46 +01001760/* LU followed by MT call (including paging) */
Neels Hofmeyr8fe8a902019-11-03 05:51:03 +01001761friend function f_tc_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Welte33ec09b2018-02-10 15:34:46 +01001762 f_init_handler(pars);
Stefan Sperling26d57be2018-11-12 17:03:26 +01001763 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Pau Espin Pedrola65697d2019-05-21 12:54:39 +02001764 cpars.use_osmux := pars.use_osmux;
Harald Welte33ec09b2018-02-10 15:34:46 +01001765
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001766 f_perform_lu();
Harald Welte33ec09b2018-02-10 15:34:46 +01001767 f_mt_call(cpars);
1768}
1769testcase TC_lu_and_mt_call() runs on MTC_CT {
1770 var BSC_ConnHdlr vc_conn;
1771 f_init();
1772
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001773 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call), 39);
Harald Welte33ec09b2018-02-10 15:34:46 +01001774 vc_conn.done;
1775}
1776
Pau Espin Pedrola65697d2019-05-21 12:54:39 +02001777testcase TC_lu_and_mt_call_osmux() runs on MTC_CT {
1778 var BSC_ConnHdlr vc_conn;
1779 f_init(1, false, true, true);
Pau Espin Pedrola65697d2019-05-21 12:54:39 +02001780
1781 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call), 39, 0, true, true);
1782 vc_conn.done;
1783}
1784
Neels Hofmeyrb58d9742019-11-27 18:44:54 +01001785/* MT call while already Paging */
1786friend function f_tc_lu_and_mt_call_already_paging(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1787 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1788 var SmsParameters spars := valueof(t_SmsPars);
1789 var OCT4 tmsi;
1790
1791 f_init_handler(pars);
1792
1793 /* Perform location update */
1794 f_perform_lu();
1795
1796 /* register an 'expect' for given IMSI (+TMSI) */
1797 if (isvalue(g_pars.tmsi)) {
1798 tmsi := g_pars.tmsi;
1799 } else {
1800 tmsi := 'FFFFFFFF'O;
1801 }
1802 f_ran_register_imsi(g_pars.imsi, tmsi);
1803
1804 log("start Paging by an SMS");
1805 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
1806
1807 /* MSC->BSC: expect PAGING from MSC */
1808 f_expect_paging();
1809
1810 log("MNCC signals MT call, before Paging Response");
1811 f_mt_call_initate(cpars);
1812 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
1813
1814 f_sleep(0.5);
1815 log("phone answers Paging, expecting both SMS and MT call to be established");
1816 f_establish_fully(EST_TYPE_PAG_RESP);
1817 spars.tp.ud := 'C8329BFD064D9B53'O;
1818 interleave {
1819 [] BSSAP.receive(f_mt_sms_deliver_pdu(spars)) {
1820 log("Got SMS-DELIVER");
1821 };
1822 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party))) {
1823 log("Got CC Setup");
1824 };
1825 }
1826 setverdict(pass);
1827 log("success, tear down");
1828 var default ccrel := activate(as_optional_cc_rel(cpars));
1829 if (g_pars.ran_is_geran) {
1830 BSSAP.send(ts_BSSMAP_ClearRequest(0));
1831 } else {
1832 BSSAP.send(ts_RANAP_IuReleaseRequest(ts_RanapCause_om_intervention));
1833 }
1834 f_expect_clear();
1835 deactivate(ccrel);
1836 f_vty_sms_clear(hex2str(g_pars.imsi));
1837}
1838testcase TC_lu_and_mt_call_already_paging() runs on MTC_CT {
1839 var BSC_ConnHdlrPars pars;
1840 var BSC_ConnHdlr vc_conn;
1841 f_init();
1842 pars := f_init_pars(391);
1843 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_call_already_paging), pars);
1844 vc_conn.done;
1845}
1846
Daniel Willmann8b084372018-02-04 13:35:26 +01001847/* Test MO Call SETUP with DTMF */
1848private function f_tc_mo_setup_dtmf_dup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1849 f_init_handler(pars);
1850 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Daniel Willmann8b084372018-02-04 13:35:26 +01001851
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001852 f_perform_lu();
Daniel Willmann8b084372018-02-04 13:35:26 +01001853 f_mo_seq_dtmf_dup(cpars);
1854}
1855testcase TC_mo_setup_and_dtmf_dup() runs on MTC_CT {
1856 var BSC_ConnHdlr vc_conn;
1857 f_init();
1858
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001859 vc_conn := f_start_handler(refers(f_tc_mo_setup_dtmf_dup), 39);
Daniel Willmann8b084372018-02-04 13:35:26 +01001860 vc_conn.done;
1861}
Harald Welte9de84792018-01-28 01:06:35 +01001862
Philipp Maier328d1662018-03-07 10:40:27 +01001863testcase TC_cr_before_reset() runs on MTC_CT {
1864 timer T := 4.0;
1865 var boolean reset_ack_seen := false;
1866 f_init_bssap_direct();
1867
Harald Welte3ca0ce12019-04-23 17:18:48 +02001868 f_ran_adapter_start(g_bssap[0]);
Daniel Willmann42d1d5b2018-08-07 15:18:41 +02001869
Daniel Willmanne8018962018-08-21 14:18:00 +02001870 f_sleep(3.0);
1871
Philipp Maier328d1662018-03-07 10:40:27 +01001872 /* Make a blind connection attemt, to trigger the deadlock condition */
Philipp Maier75932982018-03-27 14:52:35 +02001873 BSSAP_DIRECT.send(ts_BSSAP_CONNECT_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own, 1, omit));
Philipp Maier328d1662018-03-07 10:40:27 +01001874
1875 /* Send a BSSMAP reset */
Philipp Maier75932982018-03-27 14:52:35 +02001876 BSSAP_DIRECT.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own, ts_BSSMAP_Reset(0)));
Philipp Maier328d1662018-03-07 10:40:27 +01001877 T.start
1878 alt {
1879 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_ResetAck)) {
1880 reset_ack_seen := true;
1881 repeat;
1882 }
1883
1884 /* Acknowledge MSC sided reset requests */
1885 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) {
Philipp Maier75932982018-03-27 14:52:35 +02001886 BSSAP_DIRECT.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own, ts_BSSMAP_ResetAck));
Philipp Maier328d1662018-03-07 10:40:27 +01001887 repeat;
1888 }
1889
1890 /* Ignore all other messages (e.g CR from the connection request) */
1891 [] BSSAP_DIRECT.receive { repeat }
1892
1893 /* If we got no BSSMAP RESET ACK back, then the MSC entered the
1894 * deadlock situation. The MSC is then unable to respond to any
1895 * further BSSMAP RESET or any other sort of traffic. */
1896 [reset_ack_seen == true] T.timeout { setverdict(pass) }
1897 [reset_ack_seen == false] T.timeout {
1898 setverdict(fail, "no BSSMAP RESET ACK seen!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001899 mtc.stop;
Philipp Maier328d1662018-03-07 10:40:27 +01001900 }
Pau Espin Pedrol7e9178d2019-12-17 17:52:17 +01001901 }
Philipp Maier328d1662018-03-07 10:40:27 +01001902}
Harald Welte9de84792018-01-28 01:06:35 +01001903
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001904/* Test MO Call with no response to RAN-side CRCX or DTAP Release */
Harald Weltee13cfb22019-04-23 16:52:02 +02001905friend function f_tc_mo_release_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001906 f_init_handler(pars);
1907 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1908 var MNCC_PDU mncc;
1909 var MgcpCommand mgcp_cmd;
1910
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001911 /* Do not respond to the second CRCX */
1912 cpars.mgw_conn_2.resp := 0;
1913
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001914 f_perform_lu();
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001915 f_mo_call_establish(cpars);
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001916
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001917 var default ccrel := activate(as_optional_cc_rel(cpars));
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001918
1919 f_expect_clear(60.0);
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001920
1921 deactivate(ccrel);
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001922}
1923testcase TC_mo_release_timeout() runs on MTC_CT {
1924 var BSC_ConnHdlr vc_conn;
1925 f_init();
1926
1927 vc_conn := f_start_handler(refers(f_tc_mo_release_timeout), 40);
1928 vc_conn.done;
1929}
1930
Harald Welte12510c52018-01-26 22:26:24 +01001931
Philipp Maier2a98a732018-03-19 16:06:12 +01001932/* LU followed by MT call (including paging) */
1933private function f_tc_lu_and_mt_call_no_dlcx_resp(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1934 f_init_handler(pars);
Stefan Sperling26d57be2018-11-12 17:03:26 +01001935 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Philipp Maier2a98a732018-03-19 16:06:12 +01001936
1937 /* Intentionally disable the CRCX response */
1938 cpars.mgw_drop_dlcx := true;
1939
1940 /* Perform location update and call */
1941 f_perform_lu();
1942 f_mt_call(cpars);
1943}
1944testcase TC_lu_and_mt_call_no_dlcx_resp() runs on MTC_CT {
1945 var BSC_ConnHdlr vc_conn;
1946 f_init();
1947
1948 /* Perform an almost normal looking locationupdate + mt-call, but do
1949 * not respond to the DLCX at the end of the call */
1950 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call_no_dlcx_resp), 41);
1951 vc_conn.done;
1952
1953 /* Wait a guard period until the MGCP layer in the MSC times out,
1954 * if the MSC is vulnerable to the use-after-free situation that is
1955 * fixed by I78f1b6a9149488a4ad3f120c1e190a83c07d4b89 then it should
1956 * segfault now */
1957 f_sleep(6.0);
1958
1959 /* Run the init procedures once more. If the MSC has crashed, this
1960 * this will fail */
1961 f_init();
1962}
Harald Welte45164da2018-01-24 12:51:27 +01001963
Philipp Maier75932982018-03-27 14:52:35 +02001964/* Two BSSMAP resets from two different BSCs */
1965testcase TC_reset_two() runs on MTC_CT {
1966 var BSC_ConnHdlr vc_conn;
1967 f_init(2);
1968 f_sleep(2.0);
1969 setverdict(pass);
1970}
1971
Harald Weltee13cfb22019-04-23 16:52:02 +02001972/* Two BSSMAP resets from two different BSCs plus one IuCS RANAP Reset */
1973testcase TC_reset_two_1iu() runs on MTC_CT {
1974 var BSC_ConnHdlr vc_conn;
1975 f_init(3);
1976 f_sleep(2.0);
1977 setverdict(pass);
1978}
1979
Harald Weltef640a012018-04-14 17:49:21 +02001980/***********************************************************************
1981 * SMS Testing
1982 ***********************************************************************/
1983
Harald Weltef45efeb2018-04-09 18:19:24 +02001984/* LU followed by MO SMS */
Harald Weltee13cfb22019-04-23 16:52:02 +02001985friend function f_tc_lu_and_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltef45efeb2018-04-09 18:19:24 +02001986 var SmsParameters spars := valueof(t_SmsPars);
1987
1988 f_init_handler(pars);
1989
1990 /* Perform location update and call */
1991 f_perform_lu();
1992
1993 f_establish_fully(EST_TYPE_MO_SMS);
1994
1995 //spars.exp_rp_err := 96; /* invalid mandatory information */
1996 f_mo_sms(spars);
1997
1998 f_expect_clear();
1999}
2000testcase TC_lu_and_mo_sms() runs on MTC_CT {
2001 var BSC_ConnHdlr vc_conn;
2002 f_init();
2003 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_sms), 42);
2004 vc_conn.done;
2005}
2006
Harald Weltee13cfb22019-04-23 16:52:02 +02002007
Harald Weltef45efeb2018-04-09 18:19:24 +02002008private function f_vty_sms_send(charstring imsi, charstring msisdn, charstring text)
Neels Hofmeyr6aaeccf2019-03-06 15:32:26 +01002009runs on BSC_ConnHdlr {
Harald Weltef45efeb2018-04-09 18:19:24 +02002010 f_vty_transceive(MSCVTY, "subscriber imsi "&imsi&" sms sender msisdn "&msisdn&" send "&text);
2011}
2012
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01002013/* Remove still pending SMS */
2014private function f_vty_sms_clear(charstring imsi)
2015runs on BSC_ConnHdlr {
2016 f_vty_transceive(MSCVTY, "subscriber imsi " & imsi & " sms delete-all");
2017 f_vty_transceive(MSCVTY, "sms-queue clear");
2018}
2019
Harald Weltef45efeb2018-04-09 18:19:24 +02002020/* LU followed by MT SMS */
Harald Weltee13cfb22019-04-23 16:52:02 +02002021friend function f_tc_lu_and_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltef45efeb2018-04-09 18:19:24 +02002022 var SmsParameters spars := valueof(t_SmsPars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002023
2024 f_init_handler(pars);
2025
2026 /* Perform location update and call */
2027 f_perform_lu();
2028
2029 /* register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002030 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Harald Weltef45efeb2018-04-09 18:19:24 +02002031
Neels Hofmeyr6aaeccf2019-03-06 15:32:26 +01002032 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
Harald Weltef45efeb2018-04-09 18:19:24 +02002033
2034 /* MSC->BSC: expect PAGING from MSC */
Harald Weltee035e3e2019-04-21 17:32:05 +02002035 f_expect_paging();
2036
Harald Weltef45efeb2018-04-09 18:19:24 +02002037 /* Establish DTAP / BSSAP / SCCP connection */
2038 f_establish_fully(EST_TYPE_PAG_RESP);
2039
2040 spars.tp.ud := 'C8329BFD064D9B53'O;
2041 f_mt_sms(spars);
2042
2043 f_expect_clear();
2044}
2045testcase TC_lu_and_mt_sms() runs on MTC_CT {
2046 var BSC_ConnHdlrPars pars;
2047 var BSC_ConnHdlr vc_conn;
2048 f_init();
2049 pars := f_init_pars(43);
2050 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_sms), pars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002051 vc_conn.done;
2052}
2053
Neels Hofmeyrb58d9742019-11-27 18:44:54 +01002054/* SMS added while already Paging */
2055friend function f_tc_lu_and_mt_sms_already_paging(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2056 var SmsParameters spars := valueof(t_SmsPars);
2057 var OCT4 tmsi;
2058
2059 f_init_handler(pars);
2060
2061 f_perform_lu();
2062
2063 /* register an 'expect' for given IMSI (+TMSI) */
2064 if (isvalue(g_pars.tmsi)) {
2065 tmsi := g_pars.tmsi;
2066 } else {
2067 tmsi := 'FFFFFFFF'O;
2068 }
2069 f_ran_register_imsi(g_pars.imsi, tmsi);
2070
2071 log("first SMS");
2072 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
2073
2074 /* MSC->BSC: expect PAGING from MSC */
2075 f_expect_paging();
2076
2077 log("second SMS");
2078 /* Now osmo-msc is in state "Paging pending", make sure that another SMS to be sent at this time just joins in
2079 * with the pending paging. Another SMS: */
2080 f_vty_sms_send(hex2str(pars.imsi), "2342", "Another SMS");
2081
2082 /* Establish DTAP / BSSAP / SCCP connection */
2083 f_establish_fully(EST_TYPE_PAG_RESP);
2084
2085 spars.tp.ud := 'C8329BFD064D9B53'O;
2086 f_mt_sms(spars);
2087
2088 spars.tp.ud := '41F79B8E2ECB41D3E614'O;
2089 f_mt_sms(spars);
2090
2091 f_expect_clear();
2092}
2093testcase TC_lu_and_mt_sms_already_paging() runs on MTC_CT {
2094 var BSC_ConnHdlrPars pars;
2095 var BSC_ConnHdlr vc_conn;
2096 f_init();
2097 pars := f_init_pars(44);
2098 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_sms_already_paging), pars);
2099 vc_conn.done;
2100}
Harald Weltee13cfb22019-04-23 16:52:02 +02002101
Philipp Maier3983e702018-11-22 19:01:33 +01002102/* Paging for MT SMS but no response */
Harald Weltee13cfb22019-04-23 16:52:02 +02002103friend function f_tc_lu_and_mt_sms_paging_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Philipp Maier3983e702018-11-22 19:01:33 +01002104 var SmsParameters spars := valueof(t_SmsPars);
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002105
Philipp Maier3983e702018-11-22 19:01:33 +01002106 f_init_handler(pars, 150.0);
2107
2108 /* Perform location update */
2109 f_perform_lu();
2110
2111 /* register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002112 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Philipp Maier3983e702018-11-22 19:01:33 +01002113
Neels Hofmeyr6aaeccf2019-03-06 15:32:26 +01002114 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
2115
Neels Hofmeyr16237742019-03-06 15:34:01 +01002116 /* Expect the MSC to page exactly once */
Harald Weltee13cfb22019-04-23 16:52:02 +02002117 f_expect_paging();
Philipp Maier3983e702018-11-22 19:01:33 +01002118
2119 /* Wait some time to make sure the MSC is not delivering any further
2120 * paging messages or anything else that could be unexpected. */
2121 timer T := 20.0;
2122 T.start
2123 alt {
Vadim Yanitskiyda774592020-01-15 10:33:47 +07002124 [pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
2125 setverdict(fail, "paging seems not to stop!");
2126 mtc.stop;
Philipp Maier3983e702018-11-22 19:01:33 +01002127 }
Vadim Yanitskiyda774592020-01-15 10:33:47 +07002128 [not pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
2129 setverdict(fail, "paging seems not to stop!");
2130 mtc.stop;
Harald Weltee13cfb22019-04-23 16:52:02 +02002131 }
Vadim Yanitskiyda774592020-01-15 10:33:47 +07002132 [] BSSAP.receive {
2133 setverdict(fail, "unexpected BSSAP message received");
2134 self.stop;
Philipp Maier3983e702018-11-22 19:01:33 +01002135 }
Vadim Yanitskiyda774592020-01-15 10:33:47 +07002136 [] T.timeout {
2137 setverdict(pass);
Philipp Maier3983e702018-11-22 19:01:33 +01002138 }
2139 }
2140
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01002141 f_vty_sms_clear(hex2str(g_pars.imsi));
2142
Philipp Maier3983e702018-11-22 19:01:33 +01002143 setverdict(pass);
2144}
2145testcase TC_lu_and_mt_sms_paging_and_nothing() runs on MTC_CT {
2146 var BSC_ConnHdlrPars pars;
2147 var BSC_ConnHdlr vc_conn;
2148 f_init();
Philipp Maiera99ad262019-01-22 15:35:42 +01002149 pars := f_init_pars(1843);
Philipp Maier3983e702018-11-22 19:01:33 +01002150 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_sms_paging_and_nothing), pars);
Philipp Maier3983e702018-11-22 19:01:33 +01002151 vc_conn.done;
2152}
2153
Alexander Couzensfc02f242019-09-12 03:43:18 +02002154/* LU followed by MT SMS with repeated paging */
2155friend function f_tc_lu_and_mt_sms_paging_repeated(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2156 var SmsParameters spars := valueof(t_SmsPars);
Alexander Couzensfc02f242019-09-12 03:43:18 +02002157
2158 f_init_handler(pars);
2159
2160 /* Perform location update and call */
2161 f_perform_lu();
2162
2163 /* register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002164 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Alexander Couzensfc02f242019-09-12 03:43:18 +02002165
2166 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
2167
Neels Hofmeyrc3accec2019-11-28 01:09:47 +01002168 log("Expecting first Paging");
Alexander Couzensfc02f242019-09-12 03:43:18 +02002169 /* MSC->BSC: expect PAGING from MSC */
2170 f_expect_paging();
2171
Neels Hofmeyrc3accec2019-11-28 01:09:47 +01002172 if (g_pars.ran_is_geran) {
2173 log("GERAN: expect no further Paging");
2174 } else {
2175 log("UTRAN: expect more Paging");
2176 }
2177
2178 timer T := 5.0;
2179 T.start;
2180 alt {
2181 [g_pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
2182 setverdict(fail, "GERAN should not repeat Paging, but received a second Paging");
2183 mtc.stop;
2184 }
2185 [not g_pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
2186 log("UTRAN: second Paging received, as expected");
2187 setverdict(pass);
2188 }
2189 [] T.timeout {
2190 if (g_pars.ran_is_geran) {
2191 log("GERAN: No further Paging received, as expected");
2192 setverdict(pass);
2193 } else {
2194 setverdict(fail, "UTRAN: Expected a second Paging");
2195 mtc.stop;
2196 }
2197 }
2198 }
Alexander Couzensfc02f242019-09-12 03:43:18 +02002199
2200 /* Establish DTAP / BSSAP / SCCP connection */
2201 f_establish_fully(EST_TYPE_PAG_RESP);
2202
2203 spars.tp.ud := 'C8329BFD064D9B53'O;
2204 f_mt_sms(spars);
2205
2206 f_expect_clear();
2207}
2208testcase TC_lu_and_mt_sms_paging_repeated() runs on MTC_CT {
2209 var BSC_ConnHdlrPars pars;
2210 var BSC_ConnHdlr vc_conn;
2211 f_init();
2212 pars := f_init_pars(1844);
2213 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_sms_paging_repeated), pars);
2214 vc_conn.done;
2215}
Harald Weltee13cfb22019-04-23 16:52:02 +02002216
Harald Weltef640a012018-04-14 17:49:21 +02002217/* mobile originated SMS from MS/BTS/BSC side to SMPP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002218friend function f_tc_smpp_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltef640a012018-04-14 17:49:21 +02002219 var SmsParameters spars := valueof(t_SmsPars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002220
Harald Weltef640a012018-04-14 17:49:21 +02002221 f_init_handler(pars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002222
Harald Weltef640a012018-04-14 17:49:21 +02002223 /* Perform location update so IMSI is known + registered in MSC/VLR */
2224 f_perform_lu();
Harald Weltef640a012018-04-14 17:49:21 +02002225
Vadim Yanitskiy2d3f8462020-01-15 11:44:12 +07002226 /* MS/UE submits a MO SMS */
2227 f_establish_fully(EST_TYPE_MO_SMS);
2228 f_mo_sms_submit(spars);
Harald Weltef640a012018-04-14 17:49:21 +02002229
2230 var SMPP_PDU smpp;
2231 var template SMPP_PDU tr_smpp := tr_SMPP(c_SMPP_command_id_deliver_sm, ESME_ROK);
2232 tr_smpp.body.deliver_sm := {
2233 service_type := "CMT",
2234 source_addr_ton := network_specific,
2235 source_addr_npi := isdn,
2236 source_addr := hex2str(pars.msisdn),
2237 dest_addr_ton := f_sm_ton_from_gsm(spars.tp.da.tP_DA_NoPad.tP_TypeOfNumber),
2238 dest_addr_npi := f_sm_npi_from_gsm(spars.tp.da.tP_DA_NoPad.tP_NumberingPlanID),
2239 destination_addr := hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue),
2240 esm_class := '00000001'B,
2241 protocol_id := 0,
2242 priority_flag := 0,
2243 schedule_delivery_time := "",
2244 replace_if_present := 0,
2245 data_coding := '00000001'B,
2246 sm_default_msg_id := 0,
2247 sm_length := ?,
2248 short_message := spars.tp.ud,
2249 opt_pars := {
2250 {
2251 tag := user_message_reference,
2252 len := 2,
2253 opt_value := {
2254 int2_val := oct2int(spars.tp.msg_ref)
2255 }
2256 }
2257 }
2258 };
2259 alt {
2260 [] SMPP.receive(tr_smpp) -> value smpp {
2261 SMPP.send(ts_SMPP_DELIVER_SM_resp(ESME_ROK, smpp.header.seq_num));
2262 }
2263 [] SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK)) { repeat; }
2264 }
2265
Vadim Yanitskiy2d3f8462020-01-15 11:44:12 +07002266 /* MSC terminates the SMS transaction with RP-ACK */
2267 f_mo_sms_wait_rp_ack(spars);
2268
Harald Weltef640a012018-04-14 17:49:21 +02002269 f_expect_clear();
2270}
2271testcase TC_smpp_mo_sms() runs on MTC_CT {
2272 var BSC_ConnHdlr vc_conn;
2273 f_init();
2274 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "default-route");
2275 vc_conn := f_start_handler(refers(f_tc_smpp_mo_sms), 44);
2276 vc_conn.done;
2277 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "no default-route");
2278}
2279
Vadim Yanitskiy33820762020-01-15 11:26:07 +07002280/* Test case for OS#4351: make sure that RP-ERROR from ESME is properly sent to the MS/UE */
2281friend function f_tc_smpp_mo_sms_rp_error(charstring id, BSC_ConnHdlrPars pars)
2282runs on BSC_ConnHdlr {
2283 var SmsParameters spars := valueof(t_SmsPars);
2284 var SMPP_PDU smpp_pdu;
2285 timer T := 3.0;
2286
2287 f_init_handler(pars);
2288
2289 /* Perform location update */
2290 f_perform_lu();
2291
2292 /* MS/UE submits a MO SMS */
2293 f_establish_fully(EST_TYPE_MO_SMS);
2294 f_mo_sms_submit(spars);
2295
2296 /* ESME responds with an error (Invalid Destination Address) */
2297 T.start;
2298 alt {
2299 [] SMPP.receive(tr_SMPP(c_SMPP_command_id_deliver_sm, ESME_ROK, body := ?)) -> value smpp_pdu {
2300 SMPP.send(ts_SMPP_DELIVER_SM_resp(ESME_RINVDSTADR, smpp_pdu.header.seq_num));
2301 }
2302 [] SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK)) { repeat; }
2303 [] T.timeout {
2304 setverdict(fail, "Timeout waiting for SMPP DELIVER-SM");
2305 mtc.stop;
2306 }
2307 }
2308
2309 /* Expect RP-ERROR on BSSAP interface */
2310 spars.exp_rp_err := 1; /* FIXME: GSM411_RP_CAUSE_MO_NUM_UNASSIGNED */
2311 f_mo_sms_wait_rp_ack(spars);
2312
2313 f_expect_clear();
2314}
2315testcase TC_smpp_mo_sms_rp_error() runs on MTC_CT {
2316 var BSC_ConnHdlr vc_conn;
2317 f_init();
2318 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "default-route");
2319 vc_conn := f_start_handler(refers(f_tc_smpp_mo_sms_rp_error), 45);
2320 vc_conn.done;
2321 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "no default-route");
2322}
2323
Harald Weltee13cfb22019-04-23 16:52:02 +02002324
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002325/* Test MO-SMS from MS/BTS/BSC towards HLR (via GSUP) */
Harald Weltee13cfb22019-04-23 16:52:02 +02002326friend function f_tc_gsup_mo_sms(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002327runs on BSC_ConnHdlr {
2328 var SmsParameters spars := valueof(t_SmsPars);
2329 var GSUP_PDU gsup_msg_rx;
2330 var octetstring sm_tpdu;
2331
2332 f_init_handler(pars);
2333
2334 /* We need to inspect GSUP activity */
2335 f_create_gsup_expect(hex2str(g_pars.imsi));
2336
2337 /* Perform location update */
2338 f_perform_lu();
2339
2340 /* Send CM Service Request for SMS */
2341 f_establish_fully(EST_TYPE_MO_SMS);
2342
2343 /* Prepare expected SM-RP-UI (SM TPDU) */
2344 enc_TPDU_RP_DATA_MS_SGSN_fast(
2345 valueof(ts_SMS_SUBMIT(spars.tp.msg_ref,
2346 spars.tp.da, spars.tp.pid, spars.tp.dcs,
2347 spars.tp.udl, spars.tp.ud)),
2348 sm_tpdu);
2349
2350 var template GSUP_PDU mo_forwardSM := tr_GSUP_MO_FORWARD_SM_REQ(
2351 imsi := g_pars.imsi,
2352 sm_rp_mr := spars.rp.msg_ref,
Vadim Yanitskiy04dd5f72019-12-13 15:45:44 +09002353 /* SM-RP-DA: SMSC address */
2354 sm_rp_da := tr_GSUP_SM_RP_DA_SMSC_ADDR(t_GSUP_SM_RP_Addr(
2355 number := spars.rp.smsc_addr.rP_NumberDigits,
2356 npi := spars.rp.smsc_addr.rP_NumberingPlanIdentification,
2357 ton := spars.rp.smsc_addr.rP_TypeOfNumber,
2358 ext := spars.rp.smsc_addr.rP_Ext)),
2359 /* SM-RP-OA: subscriber's MSISDN (filled in by MSC) */
2360 sm_rp_oa := tr_GSUP_SM_RP_OA_MSISDN(t_GSUP_SM_RP_Addr(
2361 number := g_pars.msisdn,
2362 /* NOTE: MSISDN in g_pars lacks this info, assuming defaults */
2363 npi := '0001'B, ton := '001'B, ext := '1'B)),
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002364 /* TODO: can we use decmatch here? */
2365 sm_rp_ui := sm_tpdu
2366 );
2367
2368 /* Submit an SMS on DTAP and expect MO-forwardSM-Req on GSUP */
2369 f_mo_sms_submit(spars);
2370 alt {
2371 [] GSUP.receive(mo_forwardSM) -> value gsup_msg_rx {
Vadim Yanitskiya358dd42020-01-15 10:42:47 +07002372 log("RX MO-forwardSM-Req: ", gsup_msg_rx);
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002373 setverdict(pass);
2374 }
2375 [] GSUP.receive {
2376 log("RX unexpected GSUP message");
2377 setverdict(fail);
2378 mtc.stop;
2379 }
2380 }
2381
2382 /* Trigger RP-ACK by sending MO-forwardSM-Res */
2383 GSUP.send(valueof(ts_GSUP_MO_FORWARD_SM_RES(
2384 imsi := g_pars.imsi,
2385 sm_rp_mr := spars.rp.msg_ref)));
2386 /* Expect RP-ACK on DTAP */
2387 f_mo_sms_wait_rp_ack(spars);
2388
2389 f_expect_clear();
2390}
2391testcase TC_gsup_mo_sms() runs on MTC_CT {
2392 var BSC_ConnHdlr vc_conn;
2393 f_init();
2394 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2395 vc_conn := f_start_handler(refers(f_tc_gsup_mo_sms), 88);
2396 vc_conn.done;
2397 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2398}
2399
Harald Weltee13cfb22019-04-23 16:52:02 +02002400
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07002401/* Test MO-SMMA from MS/BTS/BSC towards HLR (via GSUP) */
Harald Weltee13cfb22019-04-23 16:52:02 +02002402friend function f_tc_gsup_mo_smma(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07002403runs on BSC_ConnHdlr {
2404 var SmsParameters spars := valueof(t_SmsPars);
2405 var GSUP_PDU gsup_msg_rx;
2406
2407 f_init_handler(pars);
2408
2409 /* We need to inspect GSUP activity */
2410 f_create_gsup_expect(hex2str(g_pars.imsi));
2411
2412 /* Perform location update */
2413 f_perform_lu();
2414
2415 /* Send CM Service Request for SMS */
2416 f_establish_fully(EST_TYPE_MO_SMS);
2417
2418 var template GSUP_PDU mo_ReadyForSM := tr_GSUP_MO_READY_FOR_SM_REQ(
2419 imsi := g_pars.imsi,
2420 sm_rp_mr := spars.rp.msg_ref,
2421 sm_alert_rsn := GSUP_SM_ALERT_RSN_TYPE_MEM_AVAIL
2422 );
2423
2424 /* Submit an SMS on DTAP and expect MO-forwardSM-Req on GSUP */
2425 f_mo_smma(spars);
2426 alt {
2427 [] GSUP.receive(mo_ReadyForSM) -> value gsup_msg_rx {
Vadim Yanitskiya358dd42020-01-15 10:42:47 +07002428 log("RX MO-ReadyForSM-Req: ", gsup_msg_rx);
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07002429 setverdict(pass);
2430 }
2431 [] GSUP.receive {
2432 log("RX unexpected GSUP message");
2433 setverdict(fail);
2434 mtc.stop;
2435 }
2436 }
2437
2438 /* Trigger RP-ACK by sending MO-forwardSM-Res */
2439 GSUP.send(valueof(ts_GSUP_MO_READY_FOR_SM_RES(
2440 imsi := g_pars.imsi,
2441 sm_rp_mr := spars.rp.msg_ref)));
2442 /* Expect RP-ACK on DTAP */
2443 f_mo_sms_wait_rp_ack(spars);
2444
2445 f_expect_clear();
2446}
2447testcase TC_gsup_mo_smma() runs on MTC_CT {
2448 var BSC_ConnHdlr vc_conn;
2449 f_init();
2450 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2451 vc_conn := f_start_handler(refers(f_tc_gsup_mo_smma), 89);
2452 vc_conn.done;
2453 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2454}
2455
Harald Weltee13cfb22019-04-23 16:52:02 +02002456
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002457/* Helper for sending MT SMS over GSUP */
2458private function f_gsup_forwardSM_req(SmsParameters spars, OCT1 mms := '00'O)
2459runs on BSC_ConnHdlr {
Vadim Yanitskiya52347c2019-12-12 17:32:33 +09002460 var GSUP_SM_RP_Addr msisdn := valueof(t_GSUP_SM_RP_Addr(g_pars.msisdn));
Vadim Yanitskiy04dd5f72019-12-13 15:45:44 +09002461 var GSUP_SM_RP_Addr smsc := valueof(t_GSUP_SM_RP_Addr(
2462 number := spars.rp.smsc_addr.rP_NumberDigits,
2463 npi := spars.rp.smsc_addr.rP_NumberingPlanIdentification,
2464 ton := spars.rp.smsc_addr.rP_TypeOfNumber,
2465 ext := spars.rp.smsc_addr.rP_Ext));
Vadim Yanitskiya52347c2019-12-12 17:32:33 +09002466
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002467 GSUP.send(ts_GSUP_MT_FORWARD_SM_REQ(
2468 imsi := g_pars.imsi,
2469 /* NOTE: MSC should assign RP-MR itself */
2470 sm_rp_mr := 'FF'O,
Vadim Yanitskiya52347c2019-12-12 17:32:33 +09002471 sm_rp_da := valueof(ts_GSUP_SM_RP_DA_MSISDN(msisdn)),
Vadim Yanitskiy04dd5f72019-12-13 15:45:44 +09002472 sm_rp_oa := valueof(ts_GSUP_SM_RP_OA_SMSC_ADDR(smsc)),
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002473 /* Encoded SMS TPDU (taken from Wireshark)
2474 * FIXME: we should encode spars somehow */
2475 sm_rp_ui := '00068021436500008111328130858200'O,
2476 sm_rp_mms := mms
2477 ));
2478}
2479
2480/* Test successful MT-SMS (RP-ACK) over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002481friend function f_tc_gsup_mt_sms_ack(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002482runs on BSC_ConnHdlr {
2483 var SmsParameters spars := valueof(t_SmsPars);
2484
2485 f_init_handler(pars);
2486
2487 /* We need to inspect GSUP activity */
2488 f_create_gsup_expect(hex2str(g_pars.imsi));
2489
2490 /* Perform location update */
2491 f_perform_lu();
2492
2493 /* Register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002494 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002495
2496 var template GSUP_PDU mt_forwardSM_res := tr_GSUP_MT_FORWARD_SM_RES(
2497 imsi := g_pars.imsi,
2498 /* NOTE: MSC should assign RP-MR itself */
2499 sm_rp_mr := ?
2500 );
2501
2502 /* Submit a MT SMS on GSUP */
2503 f_gsup_forwardSM_req(spars);
2504
2505 /* Expect Paging Request and Establish DTAP / BSSAP / SCCP connection */
Harald Weltee035e3e2019-04-21 17:32:05 +02002506 f_expect_paging();
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002507 f_establish_fully(EST_TYPE_PAG_RESP);
2508
2509 /* Wait for MT SMS on DTAP */
2510 f_mt_sms_expect(spars);
2511
2512 /* Send RP-ACK and expect MT-forwardSM-Res on GSUP */
2513 f_mt_sms_send_rp_ack(spars);
2514 alt {
2515 [] GSUP.receive(mt_forwardSM_res) {
2516 log("RX MT-forwardSM-Res (RP-ACK)");
2517 setverdict(pass);
2518 }
2519 [] GSUP.receive {
2520 log("RX unexpected GSUP message");
2521 setverdict(fail);
2522 mtc.stop;
2523 }
2524 }
2525
2526 f_expect_clear();
2527}
2528testcase TC_gsup_mt_sms_ack() runs on MTC_CT {
2529 var BSC_ConnHdlrPars pars;
2530 var BSC_ConnHdlr vc_conn;
2531 f_init();
2532 pars := f_init_pars(90);
2533 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2534 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_sms_ack), pars);
2535 vc_conn.done;
2536 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2537}
2538
Harald Weltee13cfb22019-04-23 16:52:02 +02002539
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002540/* Test rejected MT-SMS (RP-ERROR) over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002541friend function f_tc_gsup_mt_sms_err(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002542runs on BSC_ConnHdlr {
2543 var SmsParameters spars := valueof(t_SmsPars);
2544 var OCT1 sm_rp_cause := '78'O; /* dummy RP-Cause value */
2545
2546 f_init_handler(pars);
2547
2548 /* We need to inspect GSUP activity */
2549 f_create_gsup_expect(hex2str(g_pars.imsi));
2550
2551 /* Perform location update */
2552 f_perform_lu();
2553
2554 /* Register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002555 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002556
2557 var template GSUP_PDU mt_forwardSM_err := tr_GSUP_MT_FORWARD_SM_ERR(
2558 imsi := g_pars.imsi,
2559 /* NOTE: MSC should assign RP-MR itself */
2560 sm_rp_mr := ?,
2561 sm_rp_cause := sm_rp_cause
2562 );
2563
2564 /* Submit a MT SMS on GSUP */
2565 f_gsup_forwardSM_req(spars);
2566
2567 /* Expect Paging Request and Establish DTAP / BSSAP / SCCP connection */
Harald Weltee035e3e2019-04-21 17:32:05 +02002568 f_expect_paging();
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002569 f_establish_fully(EST_TYPE_PAG_RESP);
2570
2571 /* Wait for MT SMS on DTAP */
2572 f_mt_sms_expect(spars);
2573
2574 /* Send RP-ERROR and expect MT-forwardSM-Err on GSUP */
2575 f_mt_sms_send_rp_error(spars, oct2int(sm_rp_cause));
2576 alt {
2577 [] GSUP.receive(mt_forwardSM_err) {
2578 log("RX MT-forwardSM-Err (RP-ERROR)");
2579 setverdict(pass);
2580 mtc.stop;
2581 }
2582 [] GSUP.receive {
2583 log("RX unexpected GSUP message");
2584 setverdict(fail);
2585 mtc.stop;
2586 }
2587 }
2588
2589 f_expect_clear();
2590}
2591testcase TC_gsup_mt_sms_err() runs on MTC_CT {
2592 var BSC_ConnHdlrPars pars;
2593 var BSC_ConnHdlr vc_conn;
2594 f_init();
2595 pars := f_init_pars(91);
2596 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2597 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_sms_err), pars);
2598 vc_conn.done;
2599 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2600}
2601
Harald Weltee13cfb22019-04-23 16:52:02 +02002602
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002603/* Test SM-RP-MR assignment for MT-SMS over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002604friend function f_tc_gsup_mt_sms_rp_mr(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002605runs on BSC_ConnHdlr {
2606 var SmsParameters spars1 := valueof(t_SmsPars); /* 1st SMS */
2607 var SmsParameters spars2 := valueof(t_SmsPars); /* 2nd SMS */
2608
2609 f_init_handler(pars);
2610
2611 /* We need to inspect GSUP activity */
2612 f_create_gsup_expect(hex2str(g_pars.imsi));
2613
2614 /* Perform location update */
2615 f_perform_lu();
2616
2617 /* Register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002618 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002619
2620 /* Submit the 1st MT SMS on GSUP */
2621 log("TX MT-forwardSM-Req for the 1st SMS");
2622 f_gsup_forwardSM_req(spars1);
2623
2624 /* Expect Paging Request and Establish DTAP / BSSAP / SCCP connection */
Harald Weltee035e3e2019-04-21 17:32:05 +02002625 f_expect_paging();
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002626 f_establish_fully(EST_TYPE_PAG_RESP);
2627
2628 /* Wait for 1st MT SMS on DTAP */
2629 f_mt_sms_expect(spars1);
2630 log("RX the 1st SMS on DTAP, DTAP TID is ", spars1.tid,
2631 ", SM-RP-MR is ", spars1.rp.msg_ref);
2632
2633 /* Submit the 2nd MT SMS on GSUP */
2634 log("TX MT-forwardSM-Req for the 2nd SMS");
2635 f_gsup_forwardSM_req(spars2);
2636
2637 /* Wait for 2nd MT SMS on DTAP */
2638 f_mt_sms_expect(spars2);
2639 log("RX the 2nd SMS on DTAP, DTAP TID is ", spars2.tid,
2640 ", SM-RP-MR is ", spars2.rp.msg_ref);
2641
2642 /* Both transaction IDs shall be different */
2643 if (spars1.tid == spars2.tid) {
2644 log("Both DTAP transaction IDs shall be different");
2645 setverdict(fail);
2646 }
2647
2648 /* Both SM-RP-MR values shall be different */
2649 if (spars1.rp.msg_ref == spars2.rp.msg_ref) {
2650 log("Both SM-RP-MR values shall be different");
2651 setverdict(fail);
2652 }
2653
2654 /* Both SM-RP-MR values shall be assigned */
2655 if (spars1.rp.msg_ref == 'FF'O) {
2656 log("Unassigned SM-RP-MR value for the 1st SMS");
2657 setverdict(fail);
2658 }
2659 if (spars2.rp.msg_ref == 'FF'O) {
2660 log("Unassigned SM-RP-MR value for the 2nd SMS");
2661 setverdict(fail);
2662 }
2663
2664 /* Send the 1st RP-ACK and expect MT-forwardSM-Res on GSUP */
2665 f_mt_sms_send_rp_ack(spars1);
2666 alt {
2667 [] GSUP.receive(tr_GSUP_MT_FORWARD_SM_RES(
2668 imsi := g_pars.imsi,
2669 sm_rp_mr := spars1.rp.msg_ref
2670 )) {
2671 log("RX MT-forwardSM-Res (RP-ACK)");
2672 setverdict(pass);
2673 }
2674 [] GSUP.receive {
2675 log("RX unexpected GSUP message");
2676 setverdict(fail);
2677 mtc.stop;
2678 }
2679 }
2680
2681 /* Send the 2nd RP-ACK and expect MT-forwardSM-Res on GSUP */
2682 f_mt_sms_send_rp_ack(spars2);
2683 alt {
2684 [] GSUP.receive(tr_GSUP_MT_FORWARD_SM_RES(
2685 imsi := g_pars.imsi,
2686 sm_rp_mr := spars2.rp.msg_ref
2687 )) {
2688 log("RX MT-forwardSM-Res (RP-ACK)");
2689 setverdict(pass);
2690 }
2691 [] GSUP.receive {
2692 log("RX unexpected GSUP message");
2693 setverdict(fail);
2694 mtc.stop;
2695 }
2696 }
2697
2698 f_expect_clear();
2699}
2700testcase TC_gsup_mt_sms_rp_mr() runs on MTC_CT {
2701 var BSC_ConnHdlrPars pars;
2702 var BSC_ConnHdlr vc_conn;
2703 f_init();
2704 pars := f_init_pars(92);
2705 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2706 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_sms_rp_mr), pars);
2707 vc_conn.done;
2708 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2709}
2710
Harald Weltee13cfb22019-04-23 16:52:02 +02002711
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07002712/* Test SM-RP-MR assignment for MT-SMS over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002713friend function f_tc_gsup_mo_mt_sms_rp_mr(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07002714runs on BSC_ConnHdlr {
2715 var SmsParameters spars_mo := valueof(t_SmsPars); /* MO SMMA */
2716 var SmsParameters spars_mt := valueof(t_SmsPars); /* MT SMS */
2717
2718 f_init_handler(pars);
2719
2720 /* We need to inspect GSUP activity */
2721 f_create_gsup_expect(hex2str(g_pars.imsi));
2722
2723 /* Perform location update */
2724 f_perform_lu();
2725
2726 /* Register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002727 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07002728
2729 /* Send CM Service Request for MO SMMA */
2730 f_establish_fully(EST_TYPE_MO_SMS);
2731
2732 /* Submit MO SMMA on DTAP */
2733 log("Submit MO SMMA on DTAP, SM-RP-MR is '00'O");
2734 spars_mo.rp.msg_ref := '00'O;
2735 f_mo_smma(spars_mo);
2736
2737 /* Expect MO-forwardSM-Req for MO SMMA on GSUP */
2738 alt {
2739 [] GSUP.receive(tr_GSUP_MO_READY_FOR_SM_REQ(
2740 imsi := g_pars.imsi,
2741 sm_rp_mr := spars_mo.rp.msg_ref,
2742 sm_alert_rsn := GSUP_SM_ALERT_RSN_TYPE_MEM_AVAIL
2743 )) {
2744 log("RX MO-ReadyForSM-Req, SM-RP-MR is '00'O");
2745 setverdict(pass);
2746 }
2747 [] GSUP.receive {
2748 log("RX unexpected GSUP message");
2749 setverdict(fail);
2750 mtc.stop;
2751 }
2752 }
2753
2754 /* Submit MT SMS on GSUP */
2755 log("TX MT-forwardSM-Req for the MT SMS");
2756 f_gsup_forwardSM_req(spars_mt);
2757
2758 /* Wait for MT SMS on DTAP */
2759 f_mt_sms_expect(spars_mt);
2760 log("RX MT SMS on DTAP, DTAP TID is ", spars_mt.tid,
2761 ", SM-RP-MR is ", spars_mt.rp.msg_ref);
2762
2763 /* Both SM-RP-MR values shall be different */
2764 if (spars_mo.rp.msg_ref == spars_mt.rp.msg_ref) {
2765 log("Both SM-RP-MR values shall be different");
2766 setverdict(fail);
2767 }
2768
2769 /* SM-RP-MR value for MT SMS shall be assigned */
2770 if (spars_mt.rp.msg_ref == 'FF'O) {
2771 log("Unassigned SM-RP-MR value for the MT SMS");
2772 setverdict(fail);
2773 }
2774
2775 /* Trigger RP-ACK for MO SMMA by sending MO-forwardSM-Res */
2776 GSUP.send(valueof(ts_GSUP_MO_READY_FOR_SM_RES(
2777 imsi := g_pars.imsi,
2778 sm_rp_mr := spars_mo.rp.msg_ref)));
2779 /* Expect RP-ACK for MO SMMA on DTAP */
2780 f_mo_sms_wait_rp_ack(spars_mo);
2781
2782 /* Send RP-ACK for MT SMS and expect MT-forwardSM-Res on GSUP */
2783 f_mt_sms_send_rp_ack(spars_mt);
2784 alt {
2785 [] GSUP.receive(tr_GSUP_MT_FORWARD_SM_RES(
2786 imsi := g_pars.imsi,
2787 sm_rp_mr := spars_mt.rp.msg_ref
2788 )) {
2789 log("RX MT-forwardSM-Res (RP-ACK)");
2790 setverdict(pass);
2791 }
2792 [] GSUP.receive {
2793 log("RX unexpected GSUP message");
2794 setverdict(fail);
2795 mtc.stop;
2796 }
2797 }
2798
2799 f_expect_clear();
2800}
2801testcase TC_gsup_mo_mt_sms_rp_mr() runs on MTC_CT {
2802 var BSC_ConnHdlrPars pars;
2803 var BSC_ConnHdlr vc_conn;
2804 f_init();
2805 pars := f_init_pars(93);
2806 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2807 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mo_mt_sms_rp_mr), pars);
2808 vc_conn.done;
2809 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2810}
2811
Harald Weltee13cfb22019-04-23 16:52:02 +02002812
Vadim Yanitskiy1cd11a02018-12-03 02:43:35 +07002813/* Test multi-part MT-SMS over GSUP */
2814private function f_tc_gsup_mt_multi_part_sms(charstring id, BSC_ConnHdlrPars pars)
2815runs on BSC_ConnHdlr {
2816 var SmsParameters spars := valueof(t_SmsPars);
2817
2818 f_init_handler(pars);
2819
2820 /* We need to inspect GSUP activity */
2821 f_create_gsup_expect(hex2str(g_pars.imsi));
2822
2823 /* Perform location update */
2824 f_perform_lu();
2825
2826 /* Register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002827 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy1cd11a02018-12-03 02:43:35 +07002828
2829 var template GSUP_PDU mt_forwardSM_res := tr_GSUP_MT_FORWARD_SM_RES(
2830 imsi := g_pars.imsi,
2831 /* NOTE: MSC should assign RP-MR itself */
2832 sm_rp_mr := ?
2833 );
2834
2835 /* Send 4 messages (NOTE: SM-RP-UI remains unchanged) */
2836 for (var integer i := 3; i >= 0; i := i-1) {
2837 /* Submit a MT SMS on GSUP (MMS is decremented) */
2838 f_gsup_forwardSM_req(spars, int2oct(i, 1));
2839
2840 /* Expect Paging Request and Establish connection */
2841 if (i == 3) { /* ... only once! */
Harald Weltee13cfb22019-04-23 16:52:02 +02002842 f_expect_paging();
Vadim Yanitskiy1cd11a02018-12-03 02:43:35 +07002843 f_establish_fully(EST_TYPE_PAG_RESP);
2844 }
2845
2846 /* Wait for MT SMS on DTAP */
2847 f_mt_sms_expect(spars);
2848
2849 /* Send RP-ACK and expect MT-forwardSM-Res on GSUP */
2850 f_mt_sms_send_rp_ack(spars);
2851 alt {
2852 [] GSUP.receive(mt_forwardSM_res) {
2853 log("RX MT-forwardSM-Res (RP-ACK)");
2854 setverdict(pass);
2855 }
2856 [] GSUP.receive {
2857 log("RX unexpected GSUP message");
2858 setverdict(fail);
2859 mtc.stop;
2860 }
2861 }
2862
2863 /* Keep some 'distance' between transmissions */
2864 f_sleep(1.5);
2865 }
2866
2867 f_expect_clear();
2868}
2869testcase TC_gsup_mt_multi_part_sms() runs on MTC_CT {
2870 var BSC_ConnHdlrPars pars;
2871 var BSC_ConnHdlr vc_conn;
2872 f_init();
2873 pars := f_init_pars(91);
2874 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2875 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_multi_part_sms), pars);
2876 vc_conn.done;
2877 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2878}
2879
Harald Weltef640a012018-04-14 17:49:21 +02002880/* convert GSM L3 TON to SMPP_TON enum */
2881function f_sm_ton_from_gsm(BIT3 ton) return SMPP_TON {
2882 select (ton) {
2883 case ('000'B) { return unknown; }
2884 case ('001'B) { return international; }
2885 case ('010'B) { return national; }
2886 case ('011'B) { return network_specific; }
2887 case ('100'B) { return subscriber_number; }
2888 case ('101'B) { return alphanumeric; }
2889 case ('110'B) { return abbreviated; }
2890 }
2891 setverdict(fail, "Unknown TON ", ton);
Daniel Willmannafce8662018-07-06 23:11:32 +02002892 mtc.stop;
Harald Weltef640a012018-04-14 17:49:21 +02002893}
2894/* convert GSM L3 NPI to SMPP_NPI enum */
2895function f_sm_npi_from_gsm(BIT4 npi) return SMPP_NPI {
2896 select (npi) {
2897 case ('0000'B) { return unknown; }
2898 case ('0001'B) { return isdn; }
2899 case ('0011'B) { return data; }
2900 case ('0100'B) { return telex; }
2901 case ('0110'B) { return land_mobile; }
2902 case ('1000'B) { return national; }
2903 case ('1001'B) { return private_; }
2904 case ('1010'B) { return ermes; }
2905 }
2906 setverdict(fail, "Unknown NPI ", npi);
Daniel Willmannafce8662018-07-06 23:11:32 +02002907 mtc.stop;
Harald Weltef640a012018-04-14 17:49:21 +02002908}
2909
2910/* build a SMPP_SM from SmsParameters */
2911function f_mt_sm_from_spars(SmsParameters spars)
2912runs on BSC_ConnHdlr return SMPP_SM {
2913 var SMPP_SM sm := {
2914 service_type := "CMT",
2915 source_addr_ton := f_sm_ton_from_gsm(spars.tp.da.tP_DA_NoPad.tP_TypeOfNumber),
2916 source_addr_npi := f_sm_npi_from_gsm(spars.tp.da.tP_DA_NoPad.tP_NumberingPlanID),
2917 source_addr := hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue),
2918 dest_addr_ton := international,
2919 dest_addr_npi := isdn,
2920 destination_addr := hex2str(g_pars.msisdn),
2921 esm_class := '00000001'B,
2922 protocol_id := 0,
2923 priority_flag := 0,
2924 schedule_delivery_time := "",
2925 validity_period := "",
2926 registered_delivery := '00000000'B,
2927 replace_if_present := 0,
2928 data_coding := '00000001'B,
2929 sm_default_msg_id := 0,
2930 sm_length := spars.tp.udl,
2931 short_message := spars.tp.ud,
2932 opt_pars := {}
2933 };
2934 return sm;
2935}
2936
2937/* helper function to encode SMS from 'spars', send it via SMPP to MSC; receive it on MS side */
2938private function f_smpp_mt_sms(SmsParameters spars, boolean trans_mode) runs on BSC_ConnHdlr {
2939 var SMPP_SM sm := f_mt_sm_from_spars(spars);
2940 if (trans_mode) {
2941 sm.esm_class := '00000010'B;
2942 }
2943
2944 /* actually cause MSC to send a SMS via SUBMIT-SM from SMPP side */
2945 SMPP.send(ts_SMPP_SUBMIT_SM(sm));
2946 if (not match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
2947 /* if we're not in SMPP transaction mode, we expect the SMPP-level ACK
2948 * before we expect the SMS delivery on the BSC/radio side */
2949 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
2950 }
2951
2952 /* MSC->BSC: expect PAGING from MSC */
Harald Weltee035e3e2019-04-21 17:32:05 +02002953 f_expect_paging();
Harald Weltef640a012018-04-14 17:49:21 +02002954 /* Establish DTAP / BSSAP / SCCP connection */
2955 f_establish_fully(EST_TYPE_PAG_RESP);
2956 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
2957
2958 f_mt_sms(spars);
2959
2960 if (match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
2961 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
2962 }
2963 f_expect_clear();
2964}
2965
2966/* mobile terminated SMS, from SMPP to BSC/BTS/MS */
2967private function f_tc_smpp_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2968 f_init_handler(pars);
2969
2970 /* Perform location update so IMSI is known + registered in MSC/VLR */
2971 f_perform_lu();
2972 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
2973
2974 /* register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002975 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Harald Weltef640a012018-04-14 17:49:21 +02002976
2977 var SmsParameters spars := valueof(t_SmsPars);
2978 /* TODO: test with more intelligent user data; test different coding schemes */
2979 spars.tp.ud := '00'O;
2980 spars.tp.udl := 1;
2981
2982 /* first test the non-transaction store+forward mode */
2983 f_smpp_mt_sms(spars, false);
2984
2985 /* then test the transaction mode */
2986 f_smpp_mt_sms(spars, true);
2987}
2988testcase TC_smpp_mt_sms() runs on MTC_CT {
2989 var BSC_ConnHdlr vc_conn;
2990 f_init();
2991 vc_conn := f_start_handler(refers(f_tc_smpp_mt_sms), 45);
2992 vc_conn.done;
2993}
2994
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002995/***********************************************************************
2996 * USSD Testing
2997 ***********************************************************************/
2998
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07002999private altstep as_unexp_gsup_or_bssap_msg()
3000runs on BSC_ConnHdlr {
3001 [] GSUP.receive {
3002 setverdict(fail, "Unknown/unexpected GSUP received");
3003 self.stop;
3004 }
3005 [] BSSAP.receive {
3006 setverdict(fail, "Unknown/unexpected BSSAP message received");
3007 self.stop;
3008 }
3009}
3010
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003011private function f_expect_gsup_msg(template GSUP_PDU msg,
3012 float T_val := 2.0)
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003013runs on BSC_ConnHdlr return GSUP_PDU {
3014 var GSUP_PDU gsup_msg_complete;
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003015 timer T := T_val;
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003016
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003017 T.start;
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003018 alt {
3019 [] GSUP.receive(msg) -> value gsup_msg_complete {
3020 setverdict(pass);
3021 }
3022 /* We don't expect anything else */
3023 [] as_unexp_gsup_or_bssap_msg();
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003024 [] T.timeout {
3025 setverdict(fail, "Timeout waiting for GSUP message: ", msg);
3026 }
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003027 }
3028
3029 return gsup_msg_complete;
3030}
3031
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003032private function f_expect_mt_dtap_msg(template PDU_ML3_NW_MS msg,
3033 float T_val := 2.0)
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003034runs on BSC_ConnHdlr return PDU_ML3_NW_MS {
3035 var PDU_DTAP_MT bssap_msg_complete;
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003036 timer T := T_val;
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003037
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003038 T.start;
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003039 alt {
3040 [] BSSAP.receive(tr_PDU_DTAP_MT(msg)) -> value bssap_msg_complete {
3041 setverdict(pass);
3042 }
3043 /* We don't expect anything else */
3044 [] as_unexp_gsup_or_bssap_msg();
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003045 [] T.timeout {
3046 setverdict(fail, "Timeout waiting for BSSAP message: ", msg);
3047 }
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003048 }
3049
3050 return bssap_msg_complete.dtap;
3051}
3052
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003053/* LU followed by MO USSD request */
Harald Weltee13cfb22019-04-23 16:52:02 +02003054friend function f_tc_lu_and_mo_ussd_single_request(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003055runs on BSC_ConnHdlr {
3056 f_init_handler(pars);
3057
3058 /* Perform location update */
3059 f_perform_lu();
3060
3061 /* Send CM Service Request for SS/USSD */
3062 f_establish_fully(EST_TYPE_SS_ACT);
3063
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003064 /* We need to inspect GSUP activity */
3065 f_create_gsup_expect(hex2str(g_pars.imsi));
3066
3067 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3068 invoke_id := 5, /* Phone may not start from 0 or 1 */
3069 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3070 ussd_string := "*#100#"
3071 );
3072
3073 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
3074 invoke_id := 5, /* InvokeID shall be the same for both REQ and RSP */
3075 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3076 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
3077 )
3078
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003079 /* Compose a new SS/REGISTER message with request */
3080 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
3081 tid := 1, /* We just need a single transaction */
3082 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003083 facility := valueof(facility_req)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003084 );
3085
3086 /* Compose SS/RELEASE_COMPLETE template with expected response */
3087 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
3088 tid := 1, /* Response should arrive within the same transaction */
3089 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003090 facility := valueof(facility_rsp)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003091 );
3092
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003093 /* Compose expected MSC -> HLR message */
3094 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
3095 imsi := g_pars.imsi,
3096 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3097 ss := valueof(facility_req)
3098 );
3099
3100 /* To be used for sending response with correct session ID */
3101 var GSUP_PDU gsup_req_complete;
3102
3103 /* Request own number */
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003104 BSSAP.send(ts_PDU_DTAP_MO(ussd_req));
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003105 /* Expect GSUP message containing the SS payload */
3106 gsup_req_complete := f_expect_gsup_msg(gsup_req);
3107
3108 /* Compose the response from HLR using received session ID */
3109 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
3110 imsi := g_pars.imsi,
3111 sid := gsup_req_complete.ies[1].val.session_id,
3112 state := OSMO_GSUP_SESSION_STATE_END,
3113 ss := valueof(facility_rsp)
3114 );
3115
3116 /* Finally, HLR terminates the session */
3117 GSUP.send(gsup_rsp);
3118 /* Expect RELEASE_COMPLETE message with the response */
3119 f_expect_mt_dtap_msg(ussd_rsp);
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003120
3121 f_expect_clear();
3122}
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003123testcase TC_lu_and_mo_ussd_single_request() runs on MTC_CT {
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003124 var BSC_ConnHdlr vc_conn;
3125 f_init();
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003126 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_single_request), 46);
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003127 vc_conn.done;
3128}
3129
Harald Weltee13cfb22019-04-23 16:52:02 +02003130
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003131/* LU followed by MT USSD notification */
Harald Weltee13cfb22019-04-23 16:52:02 +02003132friend function f_tc_lu_and_mt_ussd_notification(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003133runs on BSC_ConnHdlr {
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003134 timer T := 5.0;
3135
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003136 f_init_handler(pars);
3137
3138 /* Perform location update */
3139 f_perform_lu();
3140
Harald Welte6811d102019-04-14 22:23:14 +02003141 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003142
3143 /* We need to inspect GSUP activity */
3144 f_create_gsup_expect(hex2str(g_pars.imsi));
3145
3146 /* Facility IE with network-originated USSD notification */
3147 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3148 op_code := SS_OP_CODE_USS_NOTIFY,
3149 ussd_string := "Mahlzeit!"
3150 );
3151
3152 /* Facility IE with acknowledgment to the USSD notification */
3153 var template OCTN facility_rsp := enc_SS_FacilityInformation(
3154 /* In case of USSD notification, Return Result is empty */
3155 valueof(ts_SS_USSD_FACILITY_RETURN_RESULT_EMPTY())
3156 );
3157
3158 /* Compose a new MT SS/REGISTER message with USSD notification */
3159 var template PDU_ML3_NW_MS ussd_ntf := tr_ML3_MT_SS_REGISTER(
3160 tid := 0, /* FIXME: most likely, it should be 0 */
3161 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3162 facility := valueof(facility_req)
3163 );
3164
3165 /* Compose HLR -> MSC GSUP message */
3166 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
3167 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003168 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003169 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3170 ss := valueof(facility_req)
3171 );
3172
3173 /* Send it to MSC and expect Paging Request */
3174 GSUP.send(gsup_req);
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003175 T.start;
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003176 alt {
Harald Weltee13cfb22019-04-23 16:52:02 +02003177 [pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
3178 setverdict(pass);
3179 }
Harald Welte62113fc2019-05-09 13:04:02 +02003180 [not pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003181 setverdict(pass);
3182 }
3183 /* We don't expect anything else */
3184 [] as_unexp_gsup_or_bssap_msg();
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003185 [] T.timeout {
3186 setverdict(fail, "Timeout waiting for Paging Request");
3187 }
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003188 }
3189
3190 /* Send Paging Response and expect USSD notification */
3191 f_establish_fully(EST_TYPE_PAG_RESP);
3192 /* Expect MT REGISTER message with USSD notification */
3193 f_expect_mt_dtap_msg(ussd_ntf);
3194
3195 /* Compose a new MO SS/FACILITY message with empty response */
3196 var template (value) PDU_ML3_MS_NW ussd_rsp := ts_ML3_MO_SS_FACILITY(
3197 tid := 0, /* FIXME: it shall match the request tid */
3198 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3199 facility := valueof(facility_rsp)
3200 );
3201
3202 /* Compose expected MSC -> HLR GSUP message */
3203 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_REQ(
3204 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003205 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003206 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
3207 ss := valueof(facility_rsp)
3208 );
3209
3210 /* MS sends response to the notification */
3211 BSSAP.send(ts_PDU_DTAP_MO(ussd_rsp));
3212 /* Expect GSUP message containing the SS payload */
3213 f_expect_gsup_msg(gsup_rsp);
3214
3215 /* Compose expected MT SS/RELEASE COMPLETE message */
3216 var template PDU_ML3_NW_MS ussd_term := tr_ML3_MT_SS_RELEASE_COMPLETE(
3217 tid := 0, /* FIXME: it shall match the request tid */
3218 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3219 facility := omit
3220 );
3221
3222 /* Compose MSC -> HLR GSUP message */
3223 var template GSUP_PDU gsup_term := ts_GSUP_PROC_SS_REQ(
3224 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003225 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003226 state := OSMO_GSUP_SESSION_STATE_END
3227 );
3228
3229 /* Finally, HLR terminates the session */
3230 GSUP.send(gsup_term)
3231 /* Expect MT RELEASE COMPLETE without Facility IE */
3232 f_expect_mt_dtap_msg(ussd_term);
3233
3234 f_expect_clear();
3235}
3236testcase TC_lu_and_mt_ussd_notification() runs on MTC_CT {
3237 var BSC_ConnHdlr vc_conn;
3238 f_init();
3239 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_ussd_notification), 47);
3240 vc_conn.done;
3241}
3242
Harald Weltee13cfb22019-04-23 16:52:02 +02003243
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003244/* LU followed by MT call and MO USSD request during this call */
Harald Weltee13cfb22019-04-23 16:52:02 +02003245friend function f_tc_lu_and_mo_ussd_during_mt_call(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003246runs on BSC_ConnHdlr {
3247 f_init_handler(pars);
3248
3249 /* Call parameters taken from f_tc_lu_and_mt_call */
3250 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003251
3252 /* Perform location update */
3253 f_perform_lu();
3254
3255 /* Establish a MT call */
3256 f_mt_call_establish(cpars);
3257
3258 /* Hold the call for some time */
3259 f_sleep(1.0);
3260
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003261 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3262 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3263 ussd_string := "*#100#"
3264 );
3265
3266 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
3267 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3268 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
3269 )
3270
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003271 /* Compose a new SS/REGISTER message with request */
3272 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
3273 tid := 1, /* We just need a single transaction */
3274 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003275 facility := valueof(facility_req)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003276 );
3277
3278 /* Compose SS/RELEASE_COMPLETE template with expected response */
3279 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
3280 tid := 1, /* Response should arrive within the same transaction */
3281 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003282 facility := valueof(facility_rsp)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003283 );
3284
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003285 /* Compose expected MSC -> HLR message */
3286 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
3287 imsi := g_pars.imsi,
3288 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3289 ss := valueof(facility_req)
3290 );
3291
3292 /* To be used for sending response with correct session ID */
3293 var GSUP_PDU gsup_req_complete;
3294
3295 /* Request own number */
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003296 BSSAP.send(ts_PDU_DTAP_MO(ussd_req));
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003297 /* Expect GSUP message containing the SS payload */
3298 gsup_req_complete := f_expect_gsup_msg(gsup_req);
3299
3300 /* Compose the response from HLR using received session ID */
3301 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
3302 imsi := g_pars.imsi,
3303 sid := gsup_req_complete.ies[1].val.session_id,
3304 state := OSMO_GSUP_SESSION_STATE_END,
3305 ss := valueof(facility_rsp)
3306 );
3307
3308 /* Finally, HLR terminates the session */
3309 GSUP.send(gsup_rsp);
3310 /* Expect RELEASE_COMPLETE message with the response */
3311 f_expect_mt_dtap_msg(ussd_rsp);
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003312
3313 /* Hold the call for some time */
3314 f_sleep(1.0);
3315
3316 /* Release the call (does Clear Complete itself) */
3317 f_call_hangup(cpars, true);
3318}
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003319testcase TC_lu_and_mo_ussd_during_mt_call() runs on MTC_CT {
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003320 var BSC_ConnHdlr vc_conn;
3321 f_init();
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003322 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_during_mt_call), 48);
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003323 vc_conn.done;
3324}
3325
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003326/* BSSMAP Clear Request in the middle of a call, see OS#3062 */
Harald Weltee13cfb22019-04-23 16:52:02 +02003327friend function f_tc_mo_cc_bssmap_clear(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003328 f_init_handler(pars);
3329 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02003330 cpars.ran_clear_when_alerting := true;
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003331
3332 f_perform_lu();
3333
Neels Hofmeyrde76f052019-02-26 05:02:46 +01003334 var default ccrel := activate(as_optional_cc_rel(cpars));
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02003335 f_mo_call_establish(cpars);
3336 f_expect_clear()
Neels Hofmeyrde76f052019-02-26 05:02:46 +01003337 deactivate(ccrel);
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003338
3339 f_sleep(1.0);
3340}
3341testcase TC_mo_cc_bssmap_clear() runs on MTC_CT {
3342 var BSC_ConnHdlr vc_conn;
3343 f_init();
3344
3345 vc_conn := f_start_handler(refers(f_tc_mo_cc_bssmap_clear), 43);
3346 vc_conn.done;
3347}
3348
Harald Weltee13cfb22019-04-23 16:52:02 +02003349
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003350/* LU followed by MT call and MT USSD request during this call */
Harald Weltee13cfb22019-04-23 16:52:02 +02003351friend function f_tc_lu_and_mt_ussd_during_mt_call(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003352runs on BSC_ConnHdlr {
3353 f_init_handler(pars);
3354
3355 /* Call parameters taken from f_tc_lu_and_mt_call */
3356 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003357
3358 /* Perform location update */
3359 f_perform_lu();
3360
3361 /* Establish a MT call */
3362 f_mt_call_establish(cpars);
3363
3364 /* Hold the call for some time */
3365 f_sleep(1.0);
3366
3367 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3368 op_code := SS_OP_CODE_USS_REQUEST,
3369 ussd_string := "Please type anything..."
3370 );
3371
3372 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
3373 op_code := SS_OP_CODE_USS_REQUEST,
3374 ussd_string := "Nope."
3375 )
3376
3377 /* Compose MT SS/REGISTER message with network-originated request */
3378 var template (value) PDU_ML3_NW_MS ussd_req := ts_ML3_MT_SS_REGISTER(
3379 tid := 0, /* FIXME: most likely, it should be 0 */
3380 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3381 facility := valueof(facility_req)
3382 );
3383
3384 /* Compose HLR -> MSC GSUP message */
3385 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
3386 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003387 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003388 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3389 ss := valueof(facility_req)
3390 );
3391
3392 /* Send it to MSC */
3393 GSUP.send(gsup_req);
3394 /* Expect MT REGISTER message with USSD request */
3395 f_expect_mt_dtap_msg(ussd_req);
3396
3397 /* Compose a new MO SS/FACILITY message with response */
3398 var template (value) PDU_ML3_MS_NW ussd_rsp := ts_ML3_MO_SS_FACILITY(
3399 tid := 0, /* FIXME: it shall match the request tid */
3400 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3401 facility := valueof(facility_rsp)
3402 );
3403
3404 /* Compose expected MSC -> HLR GSUP message */
3405 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_REQ(
3406 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003407 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003408 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
3409 ss := valueof(facility_rsp)
3410 );
3411
3412 /* MS sends response */
3413 BSSAP.send(ts_PDU_DTAP_MO(ussd_rsp));
3414 f_expect_gsup_msg(gsup_rsp);
3415
3416 /* Compose expected MT SS/RELEASE COMPLETE message */
3417 var template PDU_ML3_NW_MS ussd_term := tr_ML3_MT_SS_RELEASE_COMPLETE(
3418 tid := 0, /* FIXME: it shall match the request tid */
3419 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3420 facility := omit
3421 );
3422
3423 /* Compose MSC -> HLR GSUP message */
3424 var template GSUP_PDU gsup_term := ts_GSUP_PROC_SS_REQ(
3425 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003426 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003427 state := OSMO_GSUP_SESSION_STATE_END
3428 );
3429
3430 /* Finally, HLR terminates the session */
3431 GSUP.send(gsup_term);
3432 /* Expect MT RELEASE COMPLETE without Facility IE */
3433 f_expect_mt_dtap_msg(ussd_term);
3434
3435 /* Hold the call for some time */
3436 f_sleep(1.0);
3437
3438 /* Release the call (does Clear Complete itself) */
3439 f_call_hangup(cpars, true);
3440}
3441testcase TC_lu_and_mt_ussd_during_mt_call() runs on MTC_CT {
3442 var BSC_ConnHdlr vc_conn;
3443 f_init();
3444 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_ussd_during_mt_call), 49);
3445 vc_conn.done;
3446}
3447
Harald Weltee13cfb22019-04-23 16:52:02 +02003448
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07003449/* LU followed by MO USSD request and MO Release during transaction */
Harald Weltee13cfb22019-04-23 16:52:02 +02003450friend function f_tc_lu_and_mo_ussd_mo_release(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07003451runs on BSC_ConnHdlr {
3452 f_init_handler(pars);
3453
3454 /* Perform location update */
3455 f_perform_lu();
3456
3457 /* Send CM Service Request for SS/USSD */
3458 f_establish_fully(EST_TYPE_SS_ACT);
3459
3460 /* We need to inspect GSUP activity */
3461 f_create_gsup_expect(hex2str(g_pars.imsi));
3462
3463 var template OCTN facility_ms_req := f_USSD_FACILITY_IE_INVOKE(
3464 invoke_id := 1, /* Initial request */
3465 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3466 ussd_string := "*6766*266#"
3467 );
3468
3469 var template OCTN facility_net_req := f_USSD_FACILITY_IE_INVOKE(
3470 invoke_id := 2, /* Counter request */
3471 op_code := SS_OP_CODE_USS_REQUEST,
3472 ussd_string := "Password?!?"
3473 )
3474
3475 /* Compose MO SS/REGISTER message with request */
3476 var template (value) PDU_ML3_MS_NW ussd_ms_req := ts_ML3_MO_SS_REGISTER(
3477 tid := 1, /* We just need a single transaction */
3478 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3479 facility := valueof(facility_ms_req)
3480 );
3481
3482 /* Compose expected MSC -> HLR message */
3483 var template GSUP_PDU gsup_ms_req := tr_GSUP_PROC_SS_REQ(
3484 imsi := g_pars.imsi,
3485 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3486 ss := valueof(facility_ms_req)
3487 );
3488
3489 /* To be used for sending response with correct session ID */
3490 var GSUP_PDU gsup_ms_req_complete;
3491
3492 /* Initiate a new transaction */
3493 BSSAP.send(ts_PDU_DTAP_MO(ussd_ms_req));
3494 /* Expect GSUP request with original Facility IE */
3495 gsup_ms_req_complete := f_expect_gsup_msg(gsup_ms_req);
3496
3497 /* Compose the response from HLR using received session ID */
3498 var template (value) GSUP_PDU gsup_net_req := ts_GSUP_PROC_SS_REQ(
3499 imsi := g_pars.imsi,
3500 sid := gsup_ms_req_complete.ies[1].val.session_id,
3501 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
3502 ss := valueof(facility_net_req)
3503 );
3504
3505 /* Compose expected MT SS/FACILITY template with counter request */
3506 var template PDU_ML3_NW_MS ussd_net_req := tr_ML3_MT_SS_FACILITY(
3507 tid := 1, /* Response should arrive within the same transaction */
3508 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3509 facility := valueof(facility_net_req)
3510 );
3511
3512 /* Send response over GSUP */
3513 GSUP.send(gsup_net_req);
3514 /* Expect MT SS/FACILITY message with counter request */
3515 f_expect_mt_dtap_msg(ussd_net_req);
3516
3517 /* Compose MO SS/RELEASE COMPLETE */
3518 var template (value) PDU_ML3_MS_NW ussd_abort := ts_ML3_MO_SS_RELEASE_COMPLETE(
3519 tid := 1, /* Response should arrive within the same transaction */
3520 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3521 facility := omit
3522 /* TODO: cause? */
3523 );
3524
3525 /* Compose expected HLR -> MSC abort message */
3526 var template GSUP_PDU gsup_abort := tr_GSUP_PROC_SS_REQ(
3527 imsi := g_pars.imsi,
3528 sid := gsup_ms_req_complete.ies[1].val.session_id,
3529 state := OSMO_GSUP_SESSION_STATE_END
3530 );
3531
3532 /* Abort transaction */
3533 BSSAP.send(ts_PDU_DTAP_MO(ussd_abort));
3534 /* Expect GSUP message indicating abort */
3535 f_expect_gsup_msg(gsup_abort);
3536
3537 f_expect_clear();
3538}
3539testcase TC_lu_and_mo_ussd_mo_release() runs on MTC_CT {
3540 var BSC_ConnHdlr vc_conn;
3541 f_init();
3542 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_mo_release), 50);
3543 vc_conn.done;
3544}
3545
Harald Weltee13cfb22019-04-23 16:52:02 +02003546
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003547/* LU followed by MO USSD request and MT Release due to timeout */
Harald Weltee13cfb22019-04-23 16:52:02 +02003548friend function f_tc_lu_and_ss_session_timeout(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003549runs on BSC_ConnHdlr {
3550 f_init_handler(pars);
3551
3552 /* Perform location update */
3553 f_perform_lu();
3554
3555 /* Send CM Service Request for SS/USSD */
3556 f_establish_fully(EST_TYPE_SS_ACT);
3557
3558 /* We need to inspect GSUP activity */
3559 f_create_gsup_expect(hex2str(g_pars.imsi));
3560
3561 var template OCTN facility_ms_req := f_USSD_FACILITY_IE_INVOKE(
3562 invoke_id := 1,
3563 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3564 ussd_string := "#release_me");
3565
3566 /* Compose MO SS/REGISTER message with request */
3567 var template (value) PDU_ML3_MS_NW ussd_ms_req := ts_ML3_MO_SS_REGISTER(
3568 tid := 1, /* An arbitrary transaction identifier */
3569 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3570 facility := valueof(facility_ms_req));
3571
3572 /* Compose expected MSC -> HLR message */
3573 var template GSUP_PDU gsup_ms_req := tr_GSUP_PROC_SS_REQ(
3574 imsi := g_pars.imsi,
3575 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3576 ss := valueof(facility_ms_req));
3577
3578 /* To be used for sending response with correct session ID */
3579 var GSUP_PDU gsup_ms_req_complete;
3580
3581 /* Initiate a new SS transaction */
3582 BSSAP.send(ts_PDU_DTAP_MO(ussd_ms_req));
3583 /* Expect GSUP request with original Facility IE */
3584 gsup_ms_req_complete := f_expect_gsup_msg(gsup_ms_req);
3585
3586 /* Don't respond, wait for timeout */
3587 f_sleep(3.0);
3588
3589 var template PDU_ML3_NW_MS dtap_rel := tr_ML3_MT_SS_RELEASE_COMPLETE(
3590 tid := 1, /* Should match the request's tid */
3591 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3592 cause := *, /* TODO: expect some specific value */
3593 facility := omit);
3594
3595 var template GSUP_PDU gsup_rel := tr_GSUP_PROC_SS_ERR(
3596 imsi := g_pars.imsi,
3597 sid := gsup_ms_req_complete.ies[1].val.session_id,
3598 state := OSMO_GSUP_SESSION_STATE_END,
3599 cause := ?); /* TODO: expect some specific value */
3600
3601 /* Expect release on both interfaces */
3602 interleave {
3603 [] BSSAP.receive(tr_PDU_DTAP_MT(dtap_rel)) { };
3604 [] GSUP.receive(gsup_rel) { };
3605 }
3606
3607 f_expect_clear();
3608 setverdict(pass);
3609}
3610testcase TC_lu_and_ss_session_timeout() runs on MTC_CT {
3611 var BSC_ConnHdlr vc_conn;
3612 f_init();
Vadim Yanitskiy36d28dd2018-12-03 02:45:45 +07003613 f_vty_config(MSCVTY, "msc", "ncss guard-timeout 3");
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003614 vc_conn := f_start_handler(refers(f_tc_lu_and_ss_session_timeout), 51);
3615 vc_conn.done;
Vadim Yanitskiy36d28dd2018-12-03 02:45:45 +07003616 f_vty_config(MSCVTY, "msc", "ncss guard-timeout 0");
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003617}
3618
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07003619/* MT (network-originated) USSD for unknown subscriber */
3620friend function f_tc_mt_ussd_for_unknown_subscr(charstring id, BSC_ConnHdlrPars pars)
3621runs on BSC_ConnHdlr {
3622 var hexstring imsi := '000000000000000'H; /* Some unknown IMSI */
3623 var OCT4 sid := '20000222'O;
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07003624
3625 f_init_handler(pars);
3626 f_ran_register_imsi(imsi, 'FFFFFFFF'O);
3627 f_create_gsup_expect(hex2str(imsi));
3628
3629 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
3630 imsi := imsi,
3631 sid := sid,
3632 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3633 ss := f_rnd_octstring(23)
3634 );
3635
3636 /* Error with cause GMM_CAUSE_IMSI_UNKNOWN */
3637 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_ERR(
3638 imsi := imsi,
3639 sid := sid,
3640 state := OSMO_GSUP_SESSION_STATE_END,
3641 cause := 2 /* FIXME: introduce an enumerated type! */
3642 );
3643
3644 /* Initiate a MT USSD notification */
3645 GSUP.send(gsup_req);
3646
3647 /* Expect GSUP PROC_SS_ERROR message */
Vadim Yanitskiy851798c2019-06-15 14:22:28 +07003648 f_expect_gsup_msg(gsup_rsp);
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07003649}
3650testcase TC_mt_ussd_for_unknown_subscr() runs on MTC_CT {
3651 var BSC_ConnHdlr vc_conn;
3652 f_init();
3653 vc_conn := f_start_handler(refers(f_tc_mt_ussd_for_unknown_subscr), 0);
3654 vc_conn.done;
3655}
3656
Vadim Yanitskiyc3c07d42019-06-17 23:00:44 +07003657/* MO (mobile-originated) SS/USSD for unknown transaction */
3658friend function f_tc_mo_ussd_for_unknown_trans(charstring id, BSC_ConnHdlrPars pars)
3659runs on BSC_ConnHdlr {
3660 f_init_handler(pars);
3661
Vadim Yanitskiy70d15bf2020-01-09 22:51:01 +01003662 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyc3c07d42019-06-17 23:00:44 +07003663 f_create_gsup_expect(hex2str(g_pars.imsi));
3664
3665 /* Perform location update */
3666 f_perform_lu();
3667
3668 /* Send CM Service Request for SS/USSD */
3669 f_establish_fully(EST_TYPE_SS_ACT);
3670
3671 /* GSM 04.80 FACILITY message for a non-existing transaction */
3672 var template (value) PDU_ML3_MS_NW mo_ss_fac := ts_ML3_MO_SS_FACILITY(
3673 tid := 1, /* An arbitrary transaction identifier */
3674 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3675 facility := f_rnd_octstring(23) /* We don't care about the Facility IE */
3676 );
3677
3678 /* GSM 04.80 RELEASE COMPLETE message for a non-existing transaction */
3679 var template (value) PDU_ML3_MS_NW mo_ss_rel := ts_ML3_MO_SS_RELEASE_COMPLETE(
3680 tid := 1, /* An arbitrary transaction identifier */
3681 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3682 facility := f_rnd_octstring(23) /* We don't care about the Facility IE */
3683 );
3684
3685 /* Expected response from the network */
3686 var template PDU_ML3_NW_MS mt_ss_rel := tr_ML3_MT_SS_RELEASE_COMPLETE(
3687 tid := 1, /* Same as in the FACILITY message */
3688 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3689 facility := omit
3690 );
3691
3692 /* Send GSM 04.80 FACILITY for non-existing transaction */
3693 BSSAP.send(ts_PDU_DTAP_MO(mo_ss_fac));
3694
3695 /* Expect GSM 04.80 RELEASE COMPLETE message */
3696 f_expect_mt_dtap_msg(mt_ss_rel);
3697 f_expect_clear();
3698
3699 /* Send another CM Service Request for SS/USSD */
3700 f_establish_fully(EST_TYPE_SS_ACT);
3701
3702 /* Send GSM 04.80 RELEASE COMPLETE for non-existing transaction */
3703 BSSAP.send(ts_PDU_DTAP_MO(mo_ss_rel));
3704
3705 /* Expect GSM 04.80 RELEASE COMPLETE message */
3706 f_expect_mt_dtap_msg(mt_ss_rel);
3707 f_expect_clear();
3708}
3709testcase TC_mo_ussd_for_unknown_trans() runs on MTC_CT {
3710 var BSC_ConnHdlr vc_conn;
3711 f_init();
3712 vc_conn := f_start_handler(refers(f_tc_mo_ussd_for_unknown_trans), 111);
3713 vc_conn.done;
3714}
3715
Vadim Yanitskiyd612d282019-06-15 14:46:03 +07003716/* MT (network-originated) USSD for unknown session */
3717friend function f_tc_proc_ss_for_unknown_session(charstring id, BSC_ConnHdlrPars pars)
3718runs on BSC_ConnHdlr {
3719 var OCT4 sid := '20000333'O;
3720
3721 f_init_handler(pars);
3722
3723 /* Perform location update */
3724 f_perform_lu();
3725
Vadim Yanitskiy70d15bf2020-01-09 22:51:01 +01003726 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyd612d282019-06-15 14:46:03 +07003727 f_create_gsup_expect(hex2str(g_pars.imsi));
3728
3729 /* Request referencing a non-existing SS session */
3730 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
3731 imsi := g_pars.imsi,
3732 sid := sid,
3733 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
3734 ss := f_rnd_octstring(23)
3735 );
3736
3737 /* Error with some cause value */
3738 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_ERR(
3739 imsi := g_pars.imsi,
3740 sid := sid,
3741 state := OSMO_GSUP_SESSION_STATE_END,
3742 cause := ? /* FIXME: introduce an enumerated type! */
3743 );
3744
3745 /* Initiate a MT USSD notification */
3746 GSUP.send(gsup_req);
3747
3748 /* Expect GSUP PROC_SS_ERROR message */
3749 f_expect_gsup_msg(gsup_rsp);
3750}
3751testcase TC_proc_ss_for_unknown_session() runs on MTC_CT {
3752 var BSC_ConnHdlr vc_conn;
3753 f_init();
3754 vc_conn := f_start_handler(refers(f_tc_proc_ss_for_unknown_session), 110);
3755 vc_conn.done;
3756}
3757
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003758/* MT (network-originated) USSD and no response to Paging Request */
3759friend function f_tc_proc_ss_paging_fail(charstring id, BSC_ConnHdlrPars pars)
3760runs on BSC_ConnHdlr {
3761 timer TP := 2.0; /* Paging timer */
3762
3763 f_init_handler(pars);
3764
3765 /* Perform location update */
3766 f_perform_lu();
3767
Vadim Yanitskiy70d15bf2020-01-09 22:51:01 +01003768 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003769 f_create_gsup_expect(hex2str(g_pars.imsi));
3770
3771 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
3772 imsi := g_pars.imsi,
3773 sid := '20000444'O,
3774 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3775 ss := f_rnd_octstring(23)
3776 );
3777
3778 /* Error with some cause value */
3779 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_ERR(
3780 imsi := g_pars.imsi,
3781 sid := '20000444'O,
3782 state := OSMO_GSUP_SESSION_STATE_END,
3783 cause := ? /* FIXME: introduce an enumerated type! */
3784 );
3785
3786 /* Initiate a MT USSD notification */
3787 GSUP.send(gsup_req);
3788
3789 /* Send it to MSC and expect Paging Request */
3790 TP.start;
3791 alt {
3792 [pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
3793 setverdict(pass);
3794 }
3795 [not pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
3796 setverdict(pass);
3797 }
3798 /* We don't expect anything else */
3799 [] as_unexp_gsup_or_bssap_msg();
3800 [] TP.timeout {
3801 setverdict(fail, "Timeout waiting for Paging Request");
3802 }
3803 }
3804
Vadim Yanitskiyd24b5252019-10-02 00:04:51 +07003805 /* Wait up to 20 seconds for GSUP PROC_SS_ERROR message.
3806 * OsmoMSC waits for Paging Response 10 seconds by default. */
3807 f_expect_gsup_msg(gsup_rsp, T_val := 20.0);
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003808}
3809testcase TC_proc_ss_paging_fail() runs on MTC_CT {
3810 var BSC_ConnHdlr vc_conn;
3811 f_init();
3812 vc_conn := f_start_handler(refers(f_tc_proc_ss_paging_fail), 101);
3813 vc_conn.done;
3814}
3815
Vadim Yanitskiy29ba8d62019-06-16 15:19:41 +07003816/* MT (network-originated) USSD followed by immediate abort */
3817friend function f_tc_proc_ss_abort(charstring id, BSC_ConnHdlrPars pars)
3818runs on BSC_ConnHdlr {
3819 var octetstring facility := f_rnd_octstring(23);
3820 var OCT4 sid := '20000555'O;
3821 timer TP := 2.0;
3822
3823 f_init_handler(pars);
3824
3825 /* Perform location update */
3826 f_perform_lu();
3827
Vadim Yanitskiy70d15bf2020-01-09 22:51:01 +01003828 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy29ba8d62019-06-16 15:19:41 +07003829 f_create_gsup_expect(hex2str(g_pars.imsi));
3830
3831 /* PROC_SS_REQ initiates a mobile-originated SS/USSD session */
3832 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
3833 imsi := g_pars.imsi, sid := sid,
3834 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3835 ss := facility
3836 );
3837
3838 /* On the MS side, we expect GSM 04.80 REGISTER message */
3839 var template PDU_ML3_NW_MS dtap_reg := tr_ML3_MT_SS_REGISTER(
3840 tid := 0, /* Most likely, it should be 0 */
3841 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3842 facility := facility
3843 );
3844
3845 /* PROC_SS_ERR with SESSION_STATE_END terminates the SS/USSD session */
3846 var template (value) GSUP_PDU gsup_abort := ts_GSUP_PROC_SS_ERR(
3847 imsi := g_pars.imsi, sid := sid,
3848 state := OSMO_GSUP_SESSION_STATE_END,
3849 cause := 0 /* FIXME: introduce an enumerated type! */
3850 );
3851
3852 /* On the MS side, we expect GSM 04.80 REGISTER message */
3853 var template PDU_ML3_NW_MS dtap_rel := tr_ML3_MT_SS_RELEASE_COMPLETE(
3854 tid := 0, /* Most likely, it should be 0 */
3855 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3856 cause := *, /* FIXME: expect some specific cause value */
3857 facility := omit
3858 );
3859
3860 /* Initiate a MT USSD with random payload */
3861 GSUP.send(gsup_req);
3862
3863 /* Expect Paging Request */
3864 TP.start;
3865 alt {
3866 [pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
3867 setverdict(pass);
3868 }
3869 [not pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
3870 setverdict(pass);
3871 }
3872 /* We don't expect anything else */
3873 [] as_unexp_gsup_or_bssap_msg();
3874 [] TP.timeout {
3875 setverdict(fail, "Timeout waiting for Paging Request");
3876 }
3877 }
3878
3879 /* Send Paging Response and establish connection */
3880 f_establish_fully(EST_TYPE_PAG_RESP);
3881 /* Expect MT REGISTER message with random facility */
3882 f_expect_mt_dtap_msg(dtap_reg);
3883
3884 /* HLR/EUSE decides to abort the session even
3885 * before getting any response from the MS */
3886 /* Initiate a MT USSD with random payload */
3887 GSUP.send(gsup_abort);
3888
3889 /* Expect RELEASE COMPLETE on ths MS side */
3890 f_expect_mt_dtap_msg(dtap_rel);
3891
3892 f_expect_clear();
3893}
3894testcase TC_proc_ss_abort() runs on MTC_CT {
3895 var BSC_ConnHdlr vc_conn;
3896 f_init();
3897 vc_conn := f_start_handler(refers(f_tc_proc_ss_abort), 102);
3898 vc_conn.done;
3899}
3900
Harald Weltee13cfb22019-04-23 16:52:02 +02003901
Vadim Yanitskiy1c9754d2020-01-07 21:56:55 +01003902/* Verify multiple concurrent MO SS/USSD transactions
3903 * (one subscriber - one transaction) */
3904testcase TC_multi_lu_and_mo_ussd() runs on MTC_CT {
3905 var BSC_ConnHdlr vc_conn[16];
3906 var integer i;
3907
3908 f_init();
3909
3910 for (i := 0; i < sizeof(vc_conn); i := i + 1) {
3911 vc_conn[i] := f_start_handler(refers(f_tc_lu_and_mo_ussd_single_request), 210 + i);
3912 }
3913
3914 for (i := 0; i < sizeof(vc_conn); i := i + 1) {
3915 vc_conn[i].done;
3916 }
3917}
3918
3919/* Verify multiple concurrent MT SS/USSD transactions
3920 * (one subscriber - one transaction) */
3921testcase TC_multi_lu_and_mt_ussd() runs on MTC_CT {
3922 var BSC_ConnHdlr vc_conn[16];
3923 var integer i;
3924 var OCT4 sid;
3925
3926 f_init();
3927
3928 for (i := 0; i < sizeof(vc_conn); i := i + 1) {
3929 sid := '200001'O & int2oct(i, 1); /* All transactions must use different session ID */
3930 vc_conn[i] := f_start_handler_with_pars(refers(f_tc_lu_and_mt_ussd_notification),
3931 f_init_pars(226 + i, gsup_sid := sid));
3932 }
3933
3934 for (i := 0; i < sizeof(vc_conn); i := i + 1) {
3935 vc_conn[i].done;
3936 }
3937}
3938
3939
Stefan Sperling89eb1f32018-12-17 15:06:20 +01003940/* A5/1 only permitted on network side; attempt an invalid CIPHER MODE COMPLETE with A5/3 which MSC should reject. */
3941private function f_tc_cipher_complete_with_invalid_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
3942 pars.net.expect_auth := true;
3943 pars.net.expect_ciph := true;
3944 pars.net.kc_support := '02'O; /* A5/1 only */
3945 f_init_handler(pars);
3946
3947 g_pars.vec := f_gen_auth_vec_2g();
3948
3949 /* Can't use f_perform_lu() directly. Code below is based on it. */
3950
3951 /* tell GSUP dispatcher to send this IMSI to us */
3952 f_create_gsup_expect(hex2str(g_pars.imsi));
3953
3954 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
3955 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
Harald Weltedceacc72019-04-21 20:58:35 +02003956 f_cl3_or_initial_ue(l3_lu);
Stefan Sperling89eb1f32018-12-17 15:06:20 +01003957
3958 f_mm_auth();
3959
3960 var OCT1 a5_net := f_alg_mask_from_cm(g_pars.cm2);
3961 var OCT1 a5_intersect := g_pars.net.kc_support and4b a5_net;
3962 alt {
3963 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(a5_intersect, g_pars.vec.kc)) {
3964 BSSAP.send(ts_BSSMAP_CipherModeCompl(int2oct(4 /* "accept" A5/3 */, 1)));
3965 }
3966 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc)) {
3967 setverdict(fail, "Wrong ciphering algorithm mask in CiphModCmd");
3968 mtc.stop;
3969 }
3970 [] BSSAP.receive {
3971 setverdict(fail, "Unknown/unexpected BSSAP received");
3972 mtc.stop;
3973 }
3974 }
3975
3976 /* Expect LU reject from MSC. */
3977 alt {
3978 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
3979 setverdict(pass);
3980 }
3981 [] BSSAP.receive {
3982 setverdict(fail, "Unknown/unexpected BSSAP received");
3983 mtc.stop;
3984 }
3985 }
Stefan Sperlingc620b352018-12-18 17:23:36 +01003986 f_expect_clear();
Stefan Sperling89eb1f32018-12-17 15:06:20 +01003987}
3988
3989testcase TC_cipher_complete_with_invalid_cipher() runs on MTC_CT {
3990 var BSC_ConnHdlr vc_conn;
3991 f_init();
3992 f_vty_config(MSCVTY, "network", "encryption a5 1");
3993
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02003994 vc_conn := f_start_handler(refers(f_tc_cipher_complete_with_invalid_cipher), 52, verify_cell_id := false);
Stefan Sperling89eb1f32018-12-17 15:06:20 +01003995 vc_conn.done;
3996}
3997
Harald Welteb2284bd2019-05-10 11:30:43 +02003998/* Location Update with invalid (non-matching) MCC/MNC reported on BSSMAP level from BSC */
3999friend function f_tc_lu_with_invalid_mcc_mnc(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4000 f_init_handler(pars);
4001
4002 /* tell GSUP dispatcher to send this IMSI to us */
4003 f_create_gsup_expect(hex2str(g_pars.imsi));
4004
4005 /* modify the cell ID which will be used to construct the COMPLELTE L3 or InitialUE */
4006 g_pars.cell_id := valueof(ts_CellId_CGI('333'H, '22'H, 23, 42));
4007
4008 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
4009 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
4010 f_cl3_or_initial_ue(l3_lu);
4011
4012 /* Expect LU reject from MSC. */
4013 alt {
4014 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
4015 setverdict(pass);
4016 }
4017 [] BSSAP.receive {
4018 setverdict(fail, "Unknown/unexpected BSSAP received");
4019 mtc.stop;
4020 }
4021 }
4022 f_expect_clear();
4023}
4024testcase TC_lu_with_invalid_mcc_mnc() runs on MTC_CT {
4025 var BSC_ConnHdlr vc_conn;
4026 f_init();
4027 vc_conn := f_start_handler(refers(f_tc_lu_with_invalid_mcc_mnc), 54);
4028 vc_conn.done;
4029}
4030
Stefan Sperlinga2d59c62018-12-18 16:32:44 +01004031private function f_tc_cipher_complete_without_alg(charstring id, BSC_ConnHdlrPars pars, octetstring kc_support) runs on BSC_ConnHdlr {
4032 pars.net.expect_auth := true;
4033 pars.net.expect_ciph := true;
4034 pars.net.kc_support := kc_support;
4035 f_init_handler(pars);
4036
4037 g_pars.vec := f_gen_auth_vec_2g();
4038
4039 /* Can't use f_perform_lu() directly. Code below is based on it. */
4040
4041 /* tell GSUP dispatcher to send this IMSI to us */
4042 f_create_gsup_expect(hex2str(g_pars.imsi));
4043
4044 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
4045 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
4046 f_cl3_or_initial_ue(l3_lu);
4047
4048 f_mm_auth();
4049
4050 var OCT1 a5_net := f_alg_mask_from_cm(g_pars.cm2);
4051 var OCT1 a5_intersect := g_pars.net.kc_support and4b a5_net;
4052 alt {
4053 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(a5_intersect, g_pars.vec.kc)) {
4054 BSSAP.send(ts_BSSMAP_CipherModeComplAlg(omit));
4055 }
4056 [] BSSAP.receive(tr_BSSMAP_ClassmarkReq) {
4057 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
4058 repeat;
4059 }
4060 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc)) {
4061 setverdict(fail, "Wrong ciphering algorithm mask in CiphModCmd");
4062 mtc.stop;
4063 }
4064 [] BSSAP.receive {
4065 setverdict(fail, "Unknown/unexpected BSSAP received");
4066 mtc.stop;
4067 }
4068 }
4069
4070 /* TODO: Verify MSC is using the best cipher available! How? */
4071
4072 f_msc_lu_hlr();
4073 f_accept_reject_lu();
4074 f_expect_clear();
4075 setverdict(pass);
4076}
4077
4078/* A5/1 only permitted on network side; attempt CIPHER MODE COMPLETE without specifying the accepted algorithm. */
4079private function f_tc_cipher_complete_1_without_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4080 f_tc_cipher_complete_without_alg(id, pars, '02'O /* A5/1 only */);
4081}
4082
4083/* A5/3 only permitted on network side; attempt CIPHER MODE COMPLETE without specifying the accepted algorithm. */
4084private function f_tc_cipher_complete_3_without_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4085 f_tc_cipher_complete_without_alg(id, pars, '08'O /* A5/3 only */);
4086}
4087
4088/* A5/1 + A5/3 permitted on network side; attempt CIPHER MODE COMPLETE without specifying the accepted algorithm. */
4089private function f_tc_cipher_complete_13_without_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4090 f_tc_cipher_complete_without_alg(id, pars, '0A'O /* A5/1 and A5/3 enabled */);
4091}
4092
4093testcase TC_cipher_complete_1_without_cipher() runs on MTC_CT {
4094 var BSC_ConnHdlr vc_conn;
4095 f_init();
4096 f_vty_config(MSCVTY, "network", "encryption a5 1");
4097
4098 vc_conn := f_start_handler(refers(f_tc_cipher_complete_1_without_cipher), 53);
4099 vc_conn.done;
4100}
4101
4102testcase TC_cipher_complete_3_without_cipher() runs on MTC_CT {
4103 var BSC_ConnHdlr vc_conn;
4104 f_init();
4105 f_vty_config(MSCVTY, "network", "encryption a5 3");
4106
4107 vc_conn := f_start_handler(refers(f_tc_cipher_complete_3_without_cipher), 54);
4108 vc_conn.done;
4109}
4110
4111testcase TC_cipher_complete_13_without_cipher() runs on MTC_CT {
4112 var BSC_ConnHdlr vc_conn;
4113 f_init();
4114 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
4115
4116 vc_conn := f_start_handler(refers(f_tc_cipher_complete_13_without_cipher), 55);
4117 vc_conn.done;
4118}
Harald Welteb2284bd2019-05-10 11:30:43 +02004119
Harald Weltef640a012018-04-14 17:49:21 +02004120/* TODO (SMS):
4121 * different user data lengths
4122 * SMPP transaction mode with unsuccessful delivery
4123 * queued MT-SMS with no paging response + later delivery
4124 * different data coding schemes
4125 * multi-part SMS
4126 * user-data headers
4127 * TP-PID for SMS to SIM
4128 * behavior if SMS memory is full + RP-SMMA
4129 * delivery reports
4130 * SMPP osmocom extensions
4131 * more-messages-to-send
4132 * SMS during ongoing call (SACCH/SAPI3)
4133 */
4134
4135/* TODO (General):
Harald Welteba7b6d92018-01-23 21:32:34 +01004136 * continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
4137 * malformed messages (missing IE, invalid message type): properly rejected?
4138 * MT call while LU or is ongoing: Do we use existing lchan or page while lchan active?
4139 * 3G/2G auth permutations
4140 * encryption algorithms vs. classmark vs. vty config
Harald Welteba7b6d92018-01-23 21:32:34 +01004141 * send new transaction after/during clear (like SMS, ...)
Harald Welte45164da2018-01-24 12:51:27 +01004142 * too long L3 INFO in DTAP
4143 * too long / padded BSSAP
4144 * too long / short TLV values
Harald Welteba7b6d92018-01-23 21:32:34 +01004145 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01004146
Harald Weltee13cfb22019-04-23 16:52:02 +02004147/***********************************************************************
4148 * SGsAP Testing
4149 ***********************************************************************/
4150
Philipp Maier948747b2019-04-02 15:22:33 +02004151/* Check if a subscriber exists in the VLR */
4152private function f_ctrl_subscr_in_vlr(charstring imsi_or_msisdn) runs on BSC_ConnHdlr return boolean {
4153
4154 var CtrlValue active_subsribers;
4155 var integer rc;
4156 active_subsribers := f_ctrl_get(IPA_CTRL, "subscriber-list-active-v1");
4157
4158 rc := f_strstr(active_subsribers, imsi_or_msisdn);
4159 if (rc < 0) {
4160 return false;
4161 }
4162
4163 return true;
4164}
4165
Harald Welte4263c522018-12-06 11:56:27 +01004166/* Perform a location updatye at the A-Interface and run some checks to confirm
4167 * that everything is back to normal. */
4168private function f_sgsap_bssmap_screening() runs on BSC_ConnHdlr {
4169 var SmsParameters spars := valueof(t_SmsPars);
4170
4171 /* Perform a location update, the SGs association is expected to fall
4172 * back to NULL */
4173 f_perform_lu();
4174 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4175
4176 /* Trigger a paging request and expect the paging on BSSMAP, this is
4177 * to make sure that pagings are sent throught the A-Interface again
4178 * and not throught the SGs interface.*/
Harald Welte6811d102019-04-14 22:23:14 +02004179 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Harald Welte4263c522018-12-06 11:56:27 +01004180 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4181
4182 alt {
Harald Weltee13cfb22019-04-23 16:52:02 +02004183 [g_pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)); {
4184 setverdict(pass);
4185 }
Harald Welte62113fc2019-05-09 13:04:02 +02004186 [not g_pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
Harald Welte4263c522018-12-06 11:56:27 +01004187 setverdict(pass);
4188 }
4189 [] SGsAP.receive {
4190 setverdict(fail, "Received unexpected message on SGs");
4191 }
4192 }
4193
4194 /* Send an SMS to make sure that also payload messages are routed
4195 * throught the A-Interface again */
4196 f_establish_fully(EST_TYPE_MO_SMS);
4197 f_mo_sms(spars);
4198 f_expect_clear();
4199}
4200
4201private function f_tc_sgsap_reset(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4202 var charstring vlr_name;
4203 f_init_handler(pars);
4204
4205 vlr_name := f_sgsap_reset_mme(mp_mme_name);
4206 log("VLR name: ", vlr_name);
4207 setverdict(pass);
Neels Hofmeyrc0b520d2019-03-06 15:35:50 +01004208 f_sleep(1.0);
Harald Welte4263c522018-12-06 11:56:27 +01004209}
4210
4211testcase TC_sgsap_reset() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004212 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004213 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004214 f_init(1, true);
4215 pars := f_init_pars(11810, true);
4216 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_reset), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004217 vc_conn.done;
4218}
4219
4220/* like f_mm_auth() but for SGs */
4221function f_mm_auth_sgs() runs on BSC_ConnHdlr {
4222 if (g_pars.net.expect_auth) {
4223 g_pars.vec := f_gen_auth_vec_3g();
4224 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
4225 g_pars.vec.sres,
4226 g_pars.vec.kc,
4227 g_pars.vec.ik,
4228 g_pars.vec.ck,
4229 g_pars.vec.autn,
4230 g_pars.vec.res));
4231 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
4232 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
4233 SGsAP.receive(tr_ML3_MT_MM_AUTH_REQ_3G(g_pars.vec.rand, g_pars.vec.autn));
4234 SGsAP.send(ts_ML3_MT_MM_AUTH_RESP_3G(g_pars.vec.sres, g_pars.vec.res));
4235 }
4236}
4237
4238/* like f_perform_lu(), but on SGs rather than BSSAP */
4239function f_sgs_perform_lu() runs on BSC_ConnHdlr {
4240 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4241 var PDU_SGsAP lur;
4242 var PDU_SGsAP lua;
4243 var PDU_SGsAP mm_info;
4244 var octetstring mm_info_dtap;
4245
4246 /* tell GSUP dispatcher to send this IMSI to us */
4247 f_create_gsup_expect(hex2str(g_pars.imsi));
4248
4249 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
4250 ts_SGsAP_LAI('901'H, '70'H, 2342)));
4251 /* Old LAI, if MS sends it */
4252 /* TMSI status, if MS has no valid TMSI */
4253 /* IMEISV, if it supports "automatic device detection" */
4254 /* TAI, if available in MME */
4255 /* E-CGI, if available in MME */
4256 SGsAP.send(lur);
4257
4258 /* FIXME: is this really done over SGs? The Ue is already authenticated
4259 * via the MME ... */
4260 f_mm_auth_sgs();
4261
4262 /* Expect MSC to perform LU with HLR */
4263 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
4264 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
4265 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
4266 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
4267
4268 alt {
4269 [] SGsAP.receive(tr_SGsAP_LU_ACCEPT(g_pars.imsi, ?)) -> value lua {
4270 if (isvalue(lua.sGsAP_LOCATION_UPDATE_ACCEPT.newTMSIorIMSI.iD.iD.tmsi_ptmsi.octets)) {
4271 g_pars.tmsi :=lua.sGsAP_LOCATION_UPDATE_ACCEPT.newTMSIorIMSI.iD.iD.tmsi_ptmsi.octets
4272 SGsAP.send(ts_SGsAP_TMSI_REALL_CMPL(g_pars.imsi));
4273 }
4274 setverdict(pass);
4275 }
4276 [] SGsAP.receive(tr_SGsAP_LU_REJECT(g_pars.imsi, ?, ?)) {
4277 setverdict(fail, "Received LU-REJECT instead of ACCEPT");
4278 }
4279 [] SGsAP.receive {
4280 setverdict(fail, "Received unexpected message on SGs");
4281 }
4282 }
4283
4284 /* Check MM information */
4285 if (mp_mm_info == true) {
4286 SGsAP.receive(tr_SGsAP_MM_INFO_REQ(g_pars.imsi, ?)) -> value mm_info;
4287 mm_info_dtap := '0532'O & mm_info.sGsAP_MM_INFORMATION_REQUEST.mM_Information.information;
4288 if (not match(dec_PDU_ML3_NW_MS(mm_info_dtap), tr_ML3_MT_MM_Info)) {
4289 setverdict(fail, "Unexpected MM Information");
4290 }
4291 }
4292
4293 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4294}
4295
4296private function f_tc_sgsap_lu(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4297 f_init_handler(pars);
4298 f_sgs_perform_lu();
4299 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4300
4301 f_sgsap_bssmap_screening();
4302
4303 setverdict(pass);
4304}
4305testcase TC_sgsap_lu() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004306 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004307 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004308 f_init(1, true);
4309 pars := f_init_pars(11811, true);
4310 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004311 vc_conn.done;
4312}
4313
4314/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
4315private function f_tc_sgsap_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4316 f_init_handler(pars);
4317 var PDU_SGsAP lur;
4318
4319 f_create_gsup_expect(hex2str(g_pars.imsi));
4320 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4321 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
4322 ts_SGsAP_LAI('901'H, '70'H, 2342)));
4323 SGsAP.send(lur);
4324
4325 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
4326 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
4327 alt {
4328 [] SGsAP.receive(tr_SGsAP_LU_REJECT(g_pars.imsi, ?, ?)) {
4329 setverdict(pass);
4330 }
4331 [] SGsAP.receive(tr_SGsAP_LU_ACCEPT(g_pars.imsi, ?)) {
4332 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
4333 mtc.stop;
4334 }
4335 [] SGsAP.receive {
4336 setverdict(fail, "Received unexpected message on SGs");
4337 }
4338 }
4339
4340 f_sgsap_bssmap_screening();
4341
4342 setverdict(pass);
4343}
4344testcase TC_sgsap_lu_imsi_reject() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004345 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004346 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004347 f_init(1, true);
4348 pars := f_init_pars(11812, true);
Harald Welte4263c522018-12-06 11:56:27 +01004349
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004350 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu_imsi_reject), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004351 vc_conn.done;
4352}
4353
4354/* Do LU by IMSI, but then remain silent so that Ts6-1 times out */
4355private function f_tc_sgsap_lu_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4356 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4357 var PDU_SGsAP lur;
4358
4359 f_init_handler(pars);
4360
4361 /* tell GSUP dispatcher to send this IMSI to us */
4362 f_create_gsup_expect(hex2str(g_pars.imsi));
4363
4364 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
4365 ts_SGsAP_LAI('901'H, '70'H, 2342)));
4366 /* Old LAI, if MS sends it */
4367 /* TMSI status, if MS has no valid TMSI */
4368 /* IMEISV, if it supports "automatic device detection" */
4369 /* TAI, if available in MME */
4370 /* E-CGI, if available in MME */
4371 SGsAP.send(lur);
4372
4373 /* FIXME: is this really done over SGs? The Ue is already authenticated
4374 * via the MME ... */
4375 f_mm_auth_sgs();
4376
4377 /* Expect MSC to perform LU with HLR */
4378 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
4379 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
4380 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
4381 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
4382
4383 alt {
4384 [] SGsAP.receive(tr_SGsAP_LU_ACCEPT(g_pars.imsi, ?)) {
4385 setverdict(pass);
4386 }
4387 [] SGsAP.receive(tr_SGsAP_LU_REJECT(g_pars.imsi, ?, ?)) {
4388 setverdict(fail, "Received LU-REJECT instead of ACCEPT");
4389 }
4390 [] SGsAP.receive {
4391 setverdict(fail, "Received unexpected message on SGs");
4392 }
4393 }
4394
4395 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4396
4397 /* Wait until the VLR has abort the TMSI reallocation procedure */
4398 f_sleep(45.0);
4399
4400 /* The outcome does not change the SGs state, see also 5.2.3.4 */
4401 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4402
4403 f_sgsap_bssmap_screening();
4404
4405 setverdict(pass);
4406}
4407testcase TC_sgsap_lu_and_nothing() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004408 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004409 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004410 f_init(1, true);
4411 pars := f_init_pars(11813, true);
Harald Welte4263c522018-12-06 11:56:27 +01004412
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004413 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu_and_nothing), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004414 vc_conn.done;
4415}
4416
4417private function f_tc_sgsap_expl_imsi_det_eps(charstring id, BSC_ConnHdlrPars pars)
4418runs on BSC_ConnHdlr {
4419 f_init_handler(pars);
4420 f_sgs_perform_lu();
4421 f_sleep(3.0);
4422
4423 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4424 SGsAP.send(ts_SGsAP_EPS_DETACH_IND(g_pars.imsi, mme_name, UE_initiated));
4425 SGsAP.receive(tr_SGsAP_EPS_DETACH_ACK(g_pars.imsi));
4426 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4427
4428 f_sgsap_bssmap_screening();
4429
4430 setverdict(pass);
4431}
4432testcase TC_sgsap_expl_imsi_det_eps() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004433 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004434 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004435 f_init(1, true);
4436 pars := f_init_pars(11814, true);
4437 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_expl_imsi_det_eps), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004438 vc_conn.done;
4439}
4440
Philipp Maierfc19f172019-03-21 11:17:54 +01004441private function f_tc_sgsap_impl_imsi_det_eps(charstring id, BSC_ConnHdlrPars pars)
4442runs on BSC_ConnHdlr {
4443 f_init_handler(pars);
4444 f_sgs_perform_lu();
4445 f_sleep(3.0);
4446
4447 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4448 SGsAP.send(ts_SGsAP_EPS_DETACH_IND(g_pars.imsi, mme_name, network_initiated));
4449 SGsAP.receive(tr_SGsAP_EPS_DETACH_ACK(g_pars.imsi));
4450 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4451
4452 f_sgsap_bssmap_screening();
4453
4454 setverdict(pass);
4455}
4456testcase TC_sgsap_impl_imsi_det_eps() runs on MTC_CT {
4457 var BSC_ConnHdlrPars pars;
4458 var BSC_ConnHdlr vc_conn;
4459 f_init(1, true);
4460 pars := f_init_pars(11814, true);
4461 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_impl_imsi_det_eps), pars);
4462 vc_conn.done;
4463}
4464
Harald Welte4263c522018-12-06 11:56:27 +01004465private function f_tc_sgsap_expl_imsi_det_noneps(charstring id, BSC_ConnHdlrPars pars)
4466runs on BSC_ConnHdlr {
4467 f_init_handler(pars);
4468 f_sgs_perform_lu();
4469 f_sleep(3.0);
4470
4471 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4472 SGsAP.send(ts_SGsAP_IMSI_DETACH_IND(g_pars.imsi, mme_name, combined_UE_initiated));
4473 SGsAP.receive(tr_SGsAP_IMSI_DETACH_ACK(g_pars.imsi));
Philipp Maierd08e7e72019-04-02 15:27:10 +02004474
4475 if (f_ctrl_subscr_in_vlr(hex2str(g_pars.imsi))) {
4476 setverdict(fail, "subscriber not removed from VLR");
4477 }
Harald Welte4263c522018-12-06 11:56:27 +01004478
4479 f_sgsap_bssmap_screening();
4480
4481 setverdict(pass);
4482}
4483testcase TC_sgsap_expl_imsi_det_noneps() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004484 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004485 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004486 f_init(1, true);
4487 pars := f_init_pars(11815, true);
4488 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_expl_imsi_det_noneps), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004489 vc_conn.done;
4490}
4491
Philipp Maier5d812702019-03-21 10:51:26 +01004492private function f_tc_sgsap_impl_imsi_det_noneps(charstring id, BSC_ConnHdlrPars pars)
4493runs on BSC_ConnHdlr {
4494 f_init_handler(pars);
4495 f_sgs_perform_lu();
4496 f_sleep(3.0);
4497
4498 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4499 SGsAP.send(ts_SGsAP_IMSI_DETACH_IND(g_pars.imsi, mme_name, implicit_network_initiated));
4500 SGsAP.receive(tr_SGsAP_IMSI_DETACH_ACK(g_pars.imsi));
4501
4502 if (f_ctrl_subscr_in_vlr(hex2str(g_pars.imsi))) {
4503 setverdict(fail, "subscriber not removed from VLR");
4504 }
4505
4506 f_sgsap_bssmap_screening();
4507
4508 setverdict(pass);
4509}
4510testcase TC_sgsap_impl_imsi_det_noneps() runs on MTC_CT {
4511 var BSC_ConnHdlrPars pars;
4512 var BSC_ConnHdlr vc_conn;
4513 f_init(1, true);
4514 pars := f_init_pars(11815, true);
4515 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_impl_imsi_det_noneps), pars);
4516 vc_conn.done;
4517}
4518
Harald Welte4263c522018-12-06 11:56:27 +01004519/* Trigger a paging request via VTY and send a paging reject in response */
4520private function f_tc_sgsap_paging_rej(charstring id, BSC_ConnHdlrPars pars)
4521runs on BSC_ConnHdlr {
4522 f_init_handler(pars);
4523 f_sgs_perform_lu();
4524 f_sleep(1.0);
4525
4526 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4527 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
4528 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4529 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4530
4531 /* Initiate paging via VTY */
4532 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4533 alt {
4534 [] SGsAP.receive(exp_resp) {
4535 setverdict(pass);
4536 }
4537 [] SGsAP.receive {
4538 setverdict(fail, "Received unexpected message on SGs");
4539 }
4540 }
4541
4542 /* Now reject the paging */
4543 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, IMSI_unknown));
4544
4545 /* Wait for the states inside the MSC to settle and check the state
4546 * of the SGs Association */
4547 f_sleep(1.0);
4548 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4549
4550 /* FIXME: At the moment we send an IMSI_unknown as cause code, which is fine,
4551 * but we also need to cover tha case where the cause code indicates an
4552 * "IMSI detached for EPS services". In those cases the VLR is expected to
4553 * try paging on tha A/Iu interface. This will be another testcase similar to
4554 * this one, but extended with checks for the presence of the A/Iu paging
4555 * messages. */
4556
4557 f_sgsap_bssmap_screening();
4558
4559 setverdict(pass);
4560}
4561testcase TC_sgsap_paging_rej() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004562 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004563 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004564 f_init(1, true);
4565 pars := f_init_pars(11816, true);
4566 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_rej), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004567 vc_conn.done;
4568}
4569
4570/* Trigger a paging request via VTY and send a paging reject that indicates
4571 * that the subscriber intentionally rejected the call. */
4572private function f_tc_sgsap_paging_subscr_rej(charstring id, BSC_ConnHdlrPars pars)
4573runs on BSC_ConnHdlr {
4574 f_init_handler(pars);
4575 f_sgs_perform_lu();
4576 f_sleep(1.0);
4577
4578 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4579 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
4580 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4581 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4582
4583 /* Initiate paging via VTY */
4584 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4585 alt {
4586 [] SGsAP.receive(exp_resp) {
4587 setverdict(pass);
4588 }
4589 [] SGsAP.receive {
4590 setverdict(fail, "Received unexpected message on SGs");
4591 }
4592 }
4593
4594 /* Now reject the paging */
4595 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, user_rejected_mobile_terminating_CS_fallback_call));
4596
4597 /* Wait for the states inside the MSC to settle and check the state
4598 * of the SGs Association */
4599 f_sleep(1.0);
4600 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4601
4602 /* FIXME: The VLR is supposed to trigger an User Determined User Busy (UDUB) as specified
4603 * in 3GPP TS 24.082, this is not yet implemented in the MSC or in this tests, we need
4604 * to check back how this works and how it can be tested */
4605
4606 f_sgsap_bssmap_screening();
4607
4608 setverdict(pass);
4609}
4610testcase TC_sgsap_paging_subscr_rej() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004611 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004612 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004613 f_init(1, true);
4614 pars := f_init_pars(11817, true);
4615 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_subscr_rej), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004616 vc_conn.done;
4617}
4618
4619/* Trigger a paging request via VTY and send an UE unreacable messge in response */
4620private function f_tc_sgsap_paging_ue_unr(charstring id, BSC_ConnHdlrPars pars)
4621runs on BSC_ConnHdlr {
4622 f_init_handler(pars);
4623 f_sgs_perform_lu();
4624 f_sleep(1.0);
4625
4626 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4627 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
4628 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4629 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4630
4631 /* Initiate paging via VTY */
4632 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4633 alt {
4634 [] SGsAP.receive(exp_resp) {
4635 setverdict(pass);
4636 }
4637 [] SGsAP.receive {
4638 setverdict(fail, "Received unexpected message on SGs");
4639 }
4640 }
4641
4642 /* Now pretend that the UE is unreachable */
4643 SGsAP.send(ts_SGsAP_UE_UNREACHABLE(g_pars.imsi, UE_unreachable));
4644
4645 /* Wait for the states inside the MSC to settle and check the state
4646 * of the SGs Association. */
4647 f_sleep(1.0);
4648 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4649
4650 f_sgsap_bssmap_screening();
4651
4652 setverdict(pass);
4653}
4654testcase TC_sgsap_paging_ue_unr() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004655 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004656 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004657 f_init(1, true);
4658 pars := f_init_pars(11818, true);
4659 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_ue_unr), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004660 vc_conn.done;
4661}
4662
4663/* Trigger a paging request via VTY but don't respond to it */
4664private function f_tc_sgsap_paging_and_nothing(charstring id, BSC_ConnHdlrPars pars)
4665runs on BSC_ConnHdlr {
4666 f_init_handler(pars);
4667 f_sgs_perform_lu();
4668 f_sleep(1.0);
4669
4670 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4671 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
Philipp Maier34218102019-09-24 09:15:49 +02004672 var template PDU_SGsAP exp_serv_abrt := ts_SGsAP_SERVICE_ABORT_REQ(g_pars.imsi);
Harald Welte4263c522018-12-06 11:56:27 +01004673 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4674 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4675
4676 /* Initiate paging via VTY */
4677 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4678 alt {
4679 [] SGsAP.receive(exp_resp) {
4680 setverdict(pass);
4681 }
4682 [] SGsAP.receive {
4683 setverdict(fail, "Received unexpected message on SGs");
4684 }
4685 }
4686
Philipp Maier34218102019-09-24 09:15:49 +02004687 /* While we are doing nothing, expect an SGsAP-SERVICE-ABORT-REQUEST
4688 * after some time */
4689 timer T := 10.0;
4690 T.start
4691 alt {
4692 [] SGsAP.receive(exp_serv_abrt)
4693 {
4694 setverdict(pass);
4695 }
4696 [] SGsAP.receive {
4697 setverdict(fail, "unexpected SGsAP message received");
4698 self.stop;
4699 }
4700 [] T.timeout {
4701 setverdict(fail, "MSC did not send SGsAP-SERVICE-ABORT-REQUEST");
4702 self.stop;
4703 }
4704 }
4705
4706 /* The SGs association must remain unchanged. */
Harald Welte4263c522018-12-06 11:56:27 +01004707 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4708
4709 f_sgsap_bssmap_screening();
4710
4711 setverdict(pass);
4712}
4713testcase TC_sgsap_paging_and_nothing() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004714 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004715 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004716 f_init(1, true);
4717 pars := f_init_pars(11819, true);
4718 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_and_nothing), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004719 vc_conn.done;
4720}
4721
4722/* Trigger a paging request via VTY and slip in an LU */
4723private function f_tc_sgsap_paging_and_lu(charstring id, BSC_ConnHdlrPars pars)
4724runs on BSC_ConnHdlr {
4725 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4726 f_init_handler(pars);
4727
4728 /* First we prepar the situation, where the SGs association is in state
4729 * NULL and the confirmed by radio contact indicator is set to false
4730 * as well. This can be archived by performing an SGs LU and then
4731 * resetting the VLR */
4732 f_sgs_perform_lu();
4733 f_sgsap_reset_mme(mp_mme_name);
4734 f_sleep(1.0);
4735 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4736
4737 /* Perform a paging, expect the paging messages on the SGs interface */
4738 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4739 alt {
4740 [] SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit)) {
4741 setverdict(pass);
4742 }
4743 [] SGsAP.receive {
4744 setverdict(fail, "Received unexpected message on SGs");
4745 }
4746 }
4747
4748 /* Perform the LU as normal */
4749 f_sgs_perform_lu();
4750 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4751
4752 /* Expect a new paging request right after the LU */
4753 alt {
4754 [] SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit)) {
4755 setverdict(pass);
4756 }
4757 [] SGsAP.receive {
4758 setverdict(fail, "Received unexpected message on SGs");
4759 }
4760 }
4761
4762 /* Test is done now, lets round everything up by rejecting the paging
4763 * cleanly. */
4764 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, user_rejected_mobile_terminating_CS_fallback_call));
4765 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4766
4767 f_sgsap_bssmap_screening();
4768
4769 setverdict(pass);
4770}
4771testcase TC_sgsap_paging_and_lu() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004772 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004773 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004774 f_init(1, true);
4775 pars := f_init_pars(11820, true);
4776 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_and_lu), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004777 vc_conn.done;
4778}
4779
4780/* Send unexpected unit-data through the SGs interface */
4781private function f_tc_sgsap_unexp_ud(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4782 f_init_handler(pars);
4783 f_sleep(1.0);
4784
4785 /* This simulates what happens when a subscriber without SGs
4786 * association gets unitdata via the SGs interface. */
4787
4788 /* Make sure the subscriber exists and the SGs association
4789 * is in NULL state */
4790 f_perform_lu();
4791 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4792
4793 /* Send some random unit data, the MSC/VLR should send a release
4794 * immediately. */
4795 SGsAP.send(ts_SGsAP_UL_UD(pars.imsi,'1234'O));
4796 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, IMSI_detached_for_EPS_nonEPS_services));
4797
4798 f_sgsap_bssmap_screening();
4799
4800 setverdict(pass);
4801}
4802testcase TC_sgsap_unexp_ud() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004803 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004804 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004805 f_init(1, true);
4806 pars := f_init_pars(11821, true);
4807 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_unexp_ud), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004808 vc_conn.done;
4809}
4810
4811/* Send unsolicited unit-data through the SGs interface */
4812private function f_tc_sgsap_unsol_ud(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4813 f_init_handler(pars);
4814 f_sleep(1.0);
4815
4816 /* This simulates what happens when the MME attempts to send unitdata
4817 * to a subscriber that is completely unknown to the VLR */
4818
4819 /* Send some random unit data, the MSC/VLR should send a release
4820 * immediately. */
4821 SGsAP.send(ts_SGsAP_UL_UD(pars.imsi,'1234'O));
4822 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, IMSI_unknown));
4823
4824 f_sgsap_bssmap_screening();
4825
4826 setverdict(pass);
4827}
4828testcase TC_sgsap_unsol_ud() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004829 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004830 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004831 f_init(1, true);
4832 pars := f_init_pars(11822, true);
4833 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_unsol_ud), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004834 vc_conn.done;
4835}
4836
4837private altstep as_other_sms_sgs() runs on BSC_ConnHdlr {
4838 /* FIXME: Match an actual payload (second questionmark), the type is
4839 * octetstring, how do we use a tr_PDU_DTAP_MT here? */
4840 [] SGsAP.receive(tr_SGsAP_DL_UD(?,?)) {
4841 setverdict(fail, "Unexpected SMS related PDU from MSC");
4842 mtc.stop;
4843 }
4844}
4845
4846/* receive a MT-SMS delivered from the MSC/SMSC over an already existing SGsAP connection */
4847function f_mt_sms_sgs(inout SmsParameters spars)
4848runs on BSC_ConnHdlr {
4849 var template (value) TPDU_RP_DATA_MS_SGSN tp_mo;
4850 var template (value) RPDU_MS_SGSN rp_mo;
4851 var template (value) PDU_ML3_MS_NW l3_mo;
4852
4853 var template TPDU_RP_DATA_SGSN_MS tp_mt;
4854 var template RPDU_SGSN_MS rp_mt;
4855 var template PDU_ML3_NW_MS l3_mt;
4856
4857 var PDU_ML3_NW_MS sgsap_l3_mt;
4858
4859 var default d := activate(as_other_sms_sgs());
4860
4861 /* Expect CP-DATA(RP-DATA(SMS-DELIVER)) */
4862 tp_mt := tr_SMS_DELIVER(?, spars.tp.ud, spars.tp.pid, spars.tp.dcs, ?);
Vadim Yanitskiy04dd5f72019-12-13 15:45:44 +09004863 rp_mt := tr_RP_DATA_MT(?, spars.rp.smsc_addr, omit, tp_mt);
Harald Welte4263c522018-12-06 11:56:27 +01004864 l3_mt := tr_ML3_MT_SMS(?, c_TIF_ORIG, tr_CP_DATA_MT(rp_mt));
4865
4866 SGsAP.receive(l3_mt) -> value sgsap_l3_mt;
4867
4868 /* Extract relevant identifiers */
4869 spars.tid := bit2int(sgsap_l3_mt.tiOrSkip.transactionId.tio);
4870 spars.rp.msg_ref := sgsap_l3_mt.msgs.sms.cP_DATA.cP_User_Data.cP_RPDU.rP_DATA_SGSN_MS.rP_MessageReference;
4871
4872 /* send CP-ACK for CP-DATA just received */
4873 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_REPL, ts_CP_ACK_MO);
4874
4875 SGsAP.send(l3_mo);
4876
4877 /* send RP-ACK for RP-DATA */
4878 rp_mo := ts_RP_ACK_MO(spars.rp.msg_ref);
4879 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_REPL, ts_CP_DATA_MO(rp_mo));
4880
4881 SGsAP.send(l3_mo);
4882
4883 /* expect CP-ACK for CP-DATA(RP-ACK) just sent */
4884 l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_ORIG, tr_CP_ACK_MT);
4885
4886 SGsAP.receive(l3_mt);
4887
4888 deactivate(d);
4889
4890 setverdict(pass);
4891}
4892
4893/* submit a MO-SMS to MSC/SMSC over an already existing SGsAP connection */
4894function f_mo_sms_sgs(inout SmsParameters spars)
4895runs on BSC_ConnHdlr {
4896 var template (value) TPDU_RP_DATA_MS_SGSN tp_mo;
4897 var template (value) RPDU_MS_SGSN rp_mo;
4898 var template (value) PDU_ML3_MS_NW l3_mo;
4899
4900 var template TPDU_RP_DATA_SGSN_MS tp_mt;
4901 var template RPDU_SGSN_MS rp_mt;
4902 var template PDU_ML3_NW_MS l3_mt;
4903
4904 var default d := activate(as_other_sms_sgs());
4905
4906 /* just in case this is routed to SMPP.. */
4907 f_create_smpp_expect(hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue));
4908
4909 tp_mo := ts_SMS_SUBMIT(spars.tp.msg_ref, spars.tp.da, spars.tp.pid, spars.tp.dcs,
4910 spars.tp.udl, spars.tp.ud);
Vadim Yanitskiy437b5a62019-12-15 14:13:39 +09004911 rp_mo := ts_RP_DATA_MO(spars.rp.msg_ref, omit, spars.rp.smsc_addr, tp_mo);
Harald Welte4263c522018-12-06 11:56:27 +01004912 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_DATA_MO(rp_mo));
4913
4914 SGsAP.send(l3_mo);
4915
4916 /* receive CP-ACK for CP-DATA above */
4917 SGsAP.receive(tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_ACK_MT));
4918
4919 if (ispresent(spars.exp_rp_err)) {
4920 /* expect an RP-ERROR message from MSC with given cause */
4921 rp_mt := tr_RP_ERROR_MT(spars.rp.msg_ref, spars.exp_rp_err);
4922 l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_DATA_MT(rp_mt));
4923 SGsAP.receive(l3_mt);
4924 /* send CP-ACK for CP-DATA just received */
4925 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_ACK_MO);
4926 SGsAP.send(l3_mo);
4927 } else {
4928 /* expect RP-ACK for RP-DATA */
4929 rp_mt := tr_RP_ACK_MT(spars.rp.msg_ref);
4930 l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_DATA_MT(rp_mt));
4931 SGsAP.receive(l3_mt);
4932 /* send CP-ACO for CP-DATA just received */
4933 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_ACK_MO);
4934 SGsAP.send(l3_mo);
4935 }
4936
4937 deactivate(d);
4938
4939 setverdict(pass);
4940}
4941
4942private function f_vty_sms_send_conn_hdlr(charstring imsi, charstring msisdn, charstring text)
4943runs on BSC_ConnHdlr {
4944 f_vty_transceive(MSCVTY, "subscriber imsi "&imsi&" sms sender msisdn "&msisdn&" send "&text);
4945}
4946
4947/* Send a MT SMS via SGs interface */
4948private function f_tc_sgsap_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4949 f_init_handler(pars);
4950 f_sgs_perform_lu();
4951 f_sleep(1.0);
4952 var SmsParameters spars := valueof(t_SmsPars);
4953 spars.tp.ud := 'C8329BFD064D9B53'O;
4954
4955 /* Trigger SMS via VTY */
4956 f_vty_sms_send_conn_hdlr(hex2str(pars.imsi), "2342", "Hello SMS");
4957 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4958
4959 /* Expect a paging request and respond accordingly with a service request */
4960 SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, SMS_indicator, omit));
4961 SGsAP.send(ts_SGsAP_SERVICE_REQ(pars.imsi, SMS_indicator, EMM_CONNECTED));
4962
4963 /* Connection is now live, receive the MT-SMS */
4964 f_mt_sms_sgs(spars);
4965
4966 /* Expect a concluding release from the MSC */
4967 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, omit));
4968
4969 /* Make sure that subscriber is still present and the SGs association is in tact (ref-counting) */
4970 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4971
4972 f_sgsap_bssmap_screening();
4973
4974 setverdict(pass);
4975}
4976testcase TC_sgsap_mt_sms() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004977 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004978 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004979 f_init(1, true);
4980 pars := f_init_pars(11823, true);
4981 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mt_sms), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004982 vc_conn.done;
4983}
4984
4985/* Send a MO SMS via SGs interface */
4986private function f_tc_sgsap_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4987 f_init_handler(pars);
4988 f_sgs_perform_lu();
4989 f_sleep(1.0);
4990 var SmsParameters spars := valueof(t_SmsPars);
4991 spars.tp.ud := 'C8329BFD064D9B53'O;
4992
4993 /* Send the MO-SMS */
4994 f_mo_sms_sgs(spars);
4995
4996 /* Expect a concluding release from the MSC/VLR */
4997 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, omit));
4998
4999 /* Make sure that subscriber is still present and the SGs association is in tact (ref-counting) */
5000 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5001
5002 setverdict(pass);
5003
5004 f_sgsap_bssmap_screening()
5005}
5006testcase TC_sgsap_mo_sms() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005007 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005008 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005009 f_init(1, true);
5010 pars := f_init_pars(11824, true);
5011 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mo_sms), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005012 vc_conn.done;
5013}
5014
5015/* Trigger sending of an MT sms via VTY but never respond to anything */
5016private function f_tc_sgsap_mt_sms_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5017 f_init_handler(pars, 170.0);
5018 f_sgs_perform_lu();
5019 f_sleep(1.0);
5020
5021 var SmsParameters spars := valueof(t_SmsPars);
5022 spars.tp.ud := 'C8329BFD064D9B53'O;
5023 var integer page_count := 0;
5024 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5025 var template PDU_SGsAP exp_pag_req := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, SMS_indicator, omit);
5026 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
5027 exp_pag_req.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
5028
5029 /* Trigger SMS via VTY */
5030 f_vty_sms_send_conn_hdlr(hex2str(pars.imsi), "2342", "Hello SMS");
5031
Neels Hofmeyr16237742019-03-06 15:34:01 +01005032 /* Expect the MSC/VLR to page exactly once */
5033 SGsAP.receive(exp_pag_req);
Harald Welte4263c522018-12-06 11:56:27 +01005034
5035 /* Wait some time to make sure the MSC is not delivering any further
5036 * paging messages or anything else that could be unexpected. */
5037 timer T := 20.0;
5038 T.start
5039 alt {
5040 [] SGsAP.receive(exp_pag_req)
5041 {
5042 setverdict(fail, "paging seems not to stop!");
5043 mtc.stop;
5044 }
5045 [] SGsAP.receive {
5046 setverdict(fail, "unexpected SGsAP message received");
5047 self.stop;
5048 }
5049 [] T.timeout {
5050 setverdict(pass);
5051 }
5052 }
5053
5054 /* Even on a failed paging the SGs Association should stay intact */
5055 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5056
Philipp Maier26bdb8c2019-09-24 09:21:12 +02005057 /* Make sure that the SMS we just inserted is cleared and the
5058 * subscriber is expired. This is necessary because otherwise the MSC
5059 * might re-try the SMS delivery and disturb the following tests. */
Harald Welte4263c522018-12-06 11:56:27 +01005060
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01005061 f_vty_sms_clear(hex2str(g_pars.imsi));
5062
Harald Welte4263c522018-12-06 11:56:27 +01005063 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " expire");
5064
5065 setverdict(pass);
Neels Hofmeyrb0f82342019-03-06 15:36:51 +01005066
5067 f_sgsap_bssmap_screening();
Harald Welte4263c522018-12-06 11:56:27 +01005068}
5069testcase TC_sgsap_mt_sms_and_nothing() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005070 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005071 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005072 f_init(1, true);
5073 pars := f_init_pars(11825, true);
5074 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mt_sms_and_nothing), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005075 vc_conn.done;
5076}
5077
5078/* Trigger sending of an MT sms via VTY but reject the paging immediately */
5079private function f_tc_sgsap_mt_sms_and_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5080 f_init_handler(pars, 150.0);
5081 f_sgs_perform_lu();
5082 f_sleep(1.0);
5083
5084 var SmsParameters spars := valueof(t_SmsPars);
5085 spars.tp.ud := 'C8329BFD064D9B53'O;
5086 var integer page_count := 0;
5087 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5088 var template PDU_SGsAP exp_pag_req := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, SMS_indicator, omit);
5089 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
5090 exp_pag_req.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
5091
5092 /* Trigger SMS via VTY */
5093 f_vty_sms_send_conn_hdlr(hex2str(pars.imsi), "2342", "Hello SMS");
5094
5095 /* Expect a paging request and reject it immediately */
5096 SGsAP.receive(exp_pag_req);
5097 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, IMSI_unknown));
5098
5099 /* The MSC/VLR should no longer try to page once the paging has been
5100 * rejected. Wait some time and check if there are no unexpected
5101 * messages on the SGs interface. */
5102 timer T := 20.0;
5103 T.start
5104 alt {
5105 [] SGsAP.receive(exp_pag_req)
5106 {
5107 setverdict(fail, "paging seems not to stop!");
5108 mtc.stop;
5109 }
5110 [] SGsAP.receive {
5111 setverdict(fail, "unexpected SGsAP message received");
5112 self.stop;
5113 }
5114 [] T.timeout {
5115 setverdict(pass);
5116 }
5117 }
5118
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01005119 f_vty_sms_clear(hex2str(g_pars.imsi));
5120
Harald Welte4263c522018-12-06 11:56:27 +01005121 /* A rejected paging with IMSI_unknown (see above) should always send
5122 * the SGs association to NULL. */
5123 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
5124
5125 f_sgsap_bssmap_screening();
5126
Harald Welte4263c522018-12-06 11:56:27 +01005127 setverdict(pass);
5128}
5129testcase TC_sgsap_mt_sms_and_reject() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005130 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005131 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005132 f_init(1, true);
5133 pars := f_init_pars(11826, true);
5134 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mt_sms_and_reject), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005135 vc_conn.done;
5136}
5137
5138/* Perform an MT CSDB call including LU */
5139private function f_mt_lu_and_csfb_call(charstring id, BSC_ConnHdlrPars pars, boolean bssmap_lu) runs on BSC_ConnHdlr {
5140 f_init_handler(pars);
5141
5142 /* Be sure that the BSSMAP reset is done before we begin. */
5143 f_sleep(2.0);
5144
5145 /* Testcase variation: See what happens when we do a regular BSSMAP
5146 * LU first (this should not hurt in any way!) */
5147 if (bssmap_lu) {
5148 f_perform_lu();
5149 }
5150
5151 f_sgs_perform_lu();
5152 f_sleep(1.0);
5153
5154 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5155 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Harald Welte4263c522018-12-06 11:56:27 +01005156
5157 /* Initiate a call via MNCC interface */
5158 f_mt_call_initate(cpars);
5159
5160 /* Expect a paging request and respond accordingly with a service request */
5161 SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit));
5162 SGsAP.send(ts_SGsAP_SERVICE_REQ(pars.imsi, CS_call_indicator, EMM_CONNECTED));
5163
5164 /* Complete the call, hold it for some time and then tear it down */
5165 f_mt_call_complete(cpars);
5166 f_sleep(3.0);
Harald Welte4c422b72019-02-17 16:27:10 +01005167 f_call_hangup(cpars, true, is_csfb := true);
Harald Welte4263c522018-12-06 11:56:27 +01005168
5169 /* Make sure that subscriber is still present and the SGs association is in tact (ref-counting) */
5170 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5171
Harald Welte4263c522018-12-06 11:56:27 +01005172 /* Test for successful return by triggering a paging, when the paging
5173 * request is received via SGs, we can be sure that the MSC/VLR has
5174 * recognized that the UE is now back on 4G */
5175 f_sleep(1.0);
5176 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
5177 alt {
5178 [] SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit)) {
5179 setverdict(pass);
5180 }
5181 [] SGsAP.receive {
5182 setverdict(fail, "Received unexpected message on SGs");
5183 }
5184 }
5185
5186 f_sgsap_bssmap_screening();
5187
5188 setverdict(pass);
5189}
5190
5191/* Perform a regular BSSAP LU first, do a SGSAP LU and then make a CSFB call */
5192private function f_tc_bssap_lu_sgsap_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5193 f_mt_lu_and_csfb_call(id, pars, true);
5194}
5195testcase TC_bssap_lu_sgsap_lu_and_mt_call() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005196 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005197 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005198 f_init(1, true);
5199 pars := f_init_pars(118139, true);
Harald Welte4263c522018-12-06 11:56:27 +01005200
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005201 vc_conn := f_start_handler_with_pars(refers(f_tc_bssap_lu_sgsap_lu_and_mt_call), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005202 vc_conn.done;
5203}
5204
Harald Welte4263c522018-12-06 11:56:27 +01005205/* Perform a SGSAP LU and then make a CSFB call */
5206private function f_tc_sgsap_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5207 f_mt_lu_and_csfb_call(id, pars, false);
5208}
5209testcase TC_sgsap_lu_and_mt_call() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005210 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005211 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005212 f_init(1, true);
5213 pars := f_init_pars(11827, true);
Harald Welte4263c522018-12-06 11:56:27 +01005214
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005215 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu_and_mt_call), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005216 vc_conn.done;
5217}
5218
Philipp Maier628c0052019-04-09 17:36:57 +02005219/* Simulate an HLR/VLR failure */
5220private function f_tc_sgsap_vlr_failure(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5221 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
5222 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5223
5224 var PDU_SGsAP lur;
5225
5226 f_init_handler(pars);
5227
5228 /* Attempt location update (which is expected to fail) */
5229 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
5230 ts_SGsAP_LAI('901'H, '70'H, 2342)));
5231 SGsAP.send(lur);
5232
5233 /* Respond to SGsAP-RESET-INDICATION from VLR */
5234 alt {
5235 [] SGsAP.receive(tr_SGsAP_RESET_IND_VLR(vlr_name)); {
5236 SGsAP.send(valueof(ts_SGsAP_RESET_ACK_MME(mme_name)));
5237 setverdict(pass);
5238 }
5239 [] SGsAP.receive {
5240 setverdict(fail, "Received unexpected message on SGs");
5241 }
5242 }
5243
5244 f_sleep(1.0);
5245 setverdict(pass);
5246}
5247testcase TC_sgsap_vlr_failure() runs on MTC_CT {
5248 var BSC_ConnHdlrPars pars;
5249 var BSC_ConnHdlr vc_conn;
5250 f_init(1, true, false);
5251 pars := f_init_pars(11811, true, false);
5252 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_vlr_failure), pars);
5253 vc_conn.done;
5254}
5255
Harald Welte4263c522018-12-06 11:56:27 +01005256/* SGs TODO:
5257 * LU attempt for IMSI without NAM_PS in HLR
5258 * LU attempt with AUTH FAIL due to invalid RES/SRES
5259 * LU attempt with no response from HLR (VLR should timeout + LU REJ)
5260 * LU attempt with new TMSI but without TMSI REALL CMPL baco to VLR
5261 * implicit IMSI detach from EPS
5262 * implicit IMSI detach from non-EPS
5263 * MM INFO
5264 *
5265 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01005266
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005267private function f_tc_ho_inter_bsc_unknown_cell(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5268 f_init_handler(pars);
5269 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005270
5271 f_perform_lu();
5272 f_mo_call_establish(cpars);
5273
5274 f_sleep(1.0);
5275
5276 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
5277 var BssmapCause cause := enum2int(cause_val);
5278
5279 var template BSSMAP_FIELD_CellIdentificationList cil;
5280 cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('023'H, '42'H, 999) } };
5281
5282 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
5283 BSSAP.receive(tr_BSSMAP_HandoverRequiredReject);
5284
5285 f_call_hangup(cpars, true);
5286}
5287testcase TC_ho_inter_bsc_unknown_cell() runs on MTC_CT {
5288 var BSC_ConnHdlr vc_conn;
5289 f_init();
5290
5291 vc_conn := f_start_handler(refers(f_tc_ho_inter_bsc_unknown_cell), 53);
5292 vc_conn.done;
5293}
5294
5295private altstep as_mgcp_ack_all_mdcx(CallParameters cpars) runs on BSC_ConnHdlr {
5296 var MgcpCommand mgcp_cmd;
5297 [] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02005298 var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_conn_2.mgw_rtp_ip, cpars.mgw_conn_2.mgw_rtp_ip,
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005299 hex2str(cpars.mgcp_call_id), "42",
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02005300 cpars.mgw_conn_2.mgw_rtp_port,
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005301 { int2str(cpars.rtp_payload_type) },
5302 { valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
5303 cpars.rtp_sdp_format)),
5304 valueof(ts_SDP_ptime(20)) }));
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02005305 MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgw_conn_2.mgcp_connection_id, sdp));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005306 repeat;
5307 }
5308}
5309
5310private function f_tc_ho_inter_bsc0(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5311 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005312
5313 f_init_handler(pars);
5314
5315 f_vty_transceive(MSCVTY, "configure terminal");
5316 f_vty_transceive(MSCVTY, "msc");
5317 f_vty_transceive(MSCVTY, "neighbor a cgi 262 42 23 42 ran-pc 0.24.1");
5318 f_vty_transceive(MSCVTY, "neighbor a lac 5 ran-pc 0.24.2");
5319 f_vty_transceive(MSCVTY, "exit");
5320 f_vty_transceive(MSCVTY, "exit");
5321
5322 f_perform_lu();
5323 f_mo_call_establish(cpars);
5324
5325 f_sleep(1.0);
5326
5327 var default ack_mdcx := activate(as_mgcp_ack_all_mdcx(cpars));
5328
5329 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
5330 var BssmapCause cause := enum2int(cause_val);
5331
5332 var template BSSMAP_FIELD_CellIdentificationList cil;
5333 cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('023'H, '42'H, 5) } };
5334
5335 /* old BSS sends Handover Required */
5336 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
5337
5338 /* Now the action goes on in f_tc_ho_inter_bsc1() */
5339
5340 /* MSC forwards the RR Handover Command to old BSS */
5341 var PDU_BSSAP ho_command;
5342 BSSAP.receive(tr_BSSMAP_HandoverCommand) -> value ho_command;
5343
5344 log("GOT HandoverCommand", ho_command);
5345
5346 BSSAP.receive(tr_BSSMAP_HandoverSucceeded);
5347
5348 /* f_tc_ho_inter_bsc1() completes Handover, then expecting a Clear here. */
5349 f_expect_clear();
5350
5351 log("FIRST inter-BSC Handover done");
5352
5353
5354 /* ------------------------ */
5355
5356 /* Ok, that went well, now the other BSC is handovering back here --
5357 * from now on this here is the new BSS. */
5358 f_create_bssmap_exp_handoverRequest(193);
5359
5360 var PDU_BSSAP ho_request;
5361 BSSAP.receive(tr_BSSMAP_HandoverRequest) -> value ho_request;
5362
5363 /* new BSS composes a RR Handover Command */
5364 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5365 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5366 var BSSMAP_IE_AoIP_TransportLayerAddress tla := valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
5367 BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
5368 tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
5369
5370 /* Now f_tc_ho_inter_bsc1() expects HandoverCommand */
5371
5372 f_sleep(0.5);
5373
5374 /* Notify that the MS is now over here */
5375
5376 BSSAP.send(ts_BSSMAP_HandoverDetect);
5377 f_sleep(0.1);
5378 BSSAP.send(ts_BSSMAP_HandoverComplete);
5379
5380 f_sleep(3.0);
5381
5382 deactivate(ack_mdcx);
5383
5384 var default ccrel := activate(as_optional_cc_rel(cpars, true));
5385
5386 /* blatant cheating */
5387 var N_Sd_Array last_n_sd := f_bssmap_last_n_sd();
5388 last_n_sd[0] := 3;
5389 f_bssmap_continue_after_n_sd(last_n_sd);
5390
5391 f_call_hangup(cpars, true);
5392 f_sleep(1.0);
5393 deactivate(ccrel);
5394
5395 setverdict(pass);
5396}
5397private function f_tc_ho_inter_bsc1(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5398 f_init_handler(pars);
5399 f_create_bssmap_exp_handoverRequest(194);
5400
5401 var PDU_BSSAP ho_request;
5402 BSSAP.receive(tr_BSSMAP_HandoverRequest) -> value ho_request;
5403
5404 /* new BSS composes a RR Handover Command */
5405 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5406 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5407 var BSSMAP_IE_AoIP_TransportLayerAddress tla := valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
5408 BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
5409 tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
5410
5411 /* Now f_tc_ho_inter_bsc0() expects HandoverCommand */
5412
5413 f_sleep(0.5);
5414
5415 /* Notify that the MS is now over here */
5416
5417 BSSAP.send(ts_BSSMAP_HandoverDetect);
5418 f_sleep(0.1);
5419 BSSAP.send(ts_BSSMAP_HandoverComplete);
5420
5421 f_sleep(3.0);
5422
5423 /* Now I'd like to f_call_hangup() but we don't know any cpars here. So
5424 * ... handover back to the first BSC :P */
5425
5426 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
5427 var BssmapCause cause := enum2int(cause_val);
5428
5429 var template BSSMAP_FIELD_CellIdentificationList cil;
5430 cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('262'H, '42'H, 23) } };
5431
5432 /* old BSS sends Handover Required */
5433 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
5434
5435 /* Now the action goes on in f_tc_ho_inter_bsc0() */
5436
5437 /* MSC forwards the RR Handover Command to old BSS */
5438 var PDU_BSSAP ho_command;
5439 BSSAP.receive(tr_BSSMAP_HandoverCommand) -> value ho_command;
5440
5441 log("GOT HandoverCommand", ho_command);
5442
5443 BSSAP.receive(tr_BSSMAP_HandoverSucceeded);
5444
5445 /* f_tc_ho_inter_bsc1() completes Handover, then expecting a Clear here. */
5446 f_expect_clear();
5447 setverdict(pass);
5448}
5449testcase TC_ho_inter_bsc() runs on MTC_CT {
5450 var BSC_ConnHdlr vc_conn0;
5451 var BSC_ConnHdlr vc_conn1;
5452 f_init(2);
5453
5454 var BSC_ConnHdlrPars pars0 := f_init_pars(53);
5455 var BSC_ConnHdlrPars pars1 := f_init_pars(53);
5456
5457 vc_conn0 := f_start_handler_with_pars(refers(f_tc_ho_inter_bsc0), pars0, 0);
5458 vc_conn1 := f_start_handler_with_pars(refers(f_tc_ho_inter_bsc1), pars1, 1);
5459 vc_conn0.done;
5460 vc_conn1.done;
5461}
5462
5463function f_ML3_patch_seq_nr_MS_NW(in uint2_t seq_nr, inout octetstring enc_l3) {
5464 log("MS_NW patching N(SD)=", seq_nr, " into dtap ", enc_l3);
5465 enc_l3[2] := (enc_l3[2] and4b '3f'O) or4b bit2oct(int2bit(seq_nr, 8) << 6);
5466 log("MS_NW patched enc_l3: ", enc_l3);
5467}
5468
5469private function f_tc_ho_inter_msc_out(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5470 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005471 var hexstring ho_number := f_gen_msisdn(99999);
5472
5473 f_init_handler(pars);
5474
5475 f_create_mncc_expect(hex2str(ho_number));
5476
5477 f_vty_transceive(MSCVTY, "configure terminal");
5478 f_vty_transceive(MSCVTY, "msc");
5479 f_vty_transceive(MSCVTY, "neighbor a cgi 017 017 1 1 msc-ipa-name msc-017-017-1");
5480 f_vty_transceive(MSCVTY, "exit");
5481 f_vty_transceive(MSCVTY, "exit");
5482
5483 f_perform_lu();
5484 f_mo_call_establish(cpars);
5485
5486 f_sleep(1.0);
5487
5488 var default ack_mdcx := activate(as_mgcp_ack_all_mdcx(cpars));
5489
5490 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
5491 var BssmapCause cause := enum2int(cause_val);
5492
5493 var template BSSMAP_FIELD_CellIdentificationList cil;
5494 cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('017'H, '017'H, 1) } };
5495
5496 /* old BSS sends Handover Required */
5497 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
5498
5499 /* The target cell 017-017 LAC 1 is configured to be a remote MSC of name "msc-017-017-1".
5500 * This MSC tries to reach the other MSC via GSUP. */
5501
5502 var octetstring remote_msc_name := '6D73632D3031372D3031372D3100'O; /* "msc-017-017-1\0" as octetstring */
5503 var GSUP_PDU prep_ho_req;
5504 GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_REQUEST,
5505 pars.imsi, destination_name := remote_msc_name)) -> value prep_ho_req;
5506
5507 var GSUP_IeValue source_name_ie;
5508 f_gsup_find_ie(prep_ho_req, OSMO_GSUP_SOURCE_NAME_IE, source_name_ie);
5509 var octetstring local_msc_name := source_name_ie.source_name;
5510
5511 /* Remote MSC has figured out its BSC and signals success */
5512 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5513 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5514 var PDU_BSSAP ho_req_ack := valueof(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
5515 aoIPTransportLayer := omit,
5516 speechCodec := ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
5517 GSUP.send(ts_GSUP_E_PrepareHandoverResult(
5518 pars.imsi,
5519 ho_number,
5520 remote_msc_name, local_msc_name,
5521 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006, enc_PDU_BSSAP(ho_req_ack)))));
5522
5523 /* MSC forwards the RR Handover Command to old BSS */
5524 BSSAP.receive(tr_BSSMAP_HandoverCommand);
5525
5526 /* The MS shows up at remote new BSS */
5527
5528 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST,
5529 pars.imsi, remote_msc_name, local_msc_name,
5530 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
5531 enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverDetect))))));
5532 BSSAP.receive(tr_BSSMAP_HandoverSucceeded);
5533 f_sleep(0.1);
5534
5535 /* Save the MS sequence counters for use on the other connection */
5536 var N_Sd_Array last_n_sd := f_bssmap_last_n_sd();
5537
5538 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_REQUEST,
5539 pars.imsi, remote_msc_name, local_msc_name,
5540 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
5541 enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverComplete))))));
5542
5543 /* The local BSS conn clears, all communication goes via remote MSC now */
5544 f_expect_clear();
5545
5546 /**********************************/
5547 /* Play through some signalling across the inter-MSC link.
5548 * This is a copy of f_tc_lu_and_mo_ussd_single_request() translated into GSUP AN-APDUs. */
5549
5550 if (false) {
5551 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
5552 invoke_id := 5, /* Phone may not start from 0 or 1 */
5553 op_code := SS_OP_CODE_PROCESS_USS_REQ,
5554 ussd_string := "*#100#"
5555 );
5556
5557 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
5558 invoke_id := 5, /* InvokeID shall be the same for both REQ and RSP */
5559 op_code := SS_OP_CODE_PROCESS_USS_REQ,
5560 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
5561 )
5562
5563 /* Compose a new SS/REGISTER message with request */
5564 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
5565 tid := 1, /* We just need a single transaction */
5566 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
5567 facility := valueof(facility_req)
5568 );
5569 var PDU_ML3_MS_NW ussd_req_v := valueof(ussd_req);
5570
5571 /* Compose SS/RELEASE_COMPLETE template with expected response */
5572 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
5573 tid := 1, /* Response should arrive within the same transaction */
5574 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
5575 facility := valueof(facility_rsp)
5576 );
5577
5578 /* Compose expected MSC -> HLR message */
5579 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
5580 imsi := g_pars.imsi,
5581 state := OSMO_GSUP_SESSION_STATE_BEGIN,
5582 ss := valueof(facility_req)
5583 );
5584
5585 /* To be used for sending response with correct session ID */
5586 var GSUP_PDU gsup_req_complete;
5587
5588 /* Request own number */
5589 /* From remote MSC instead of BSSAP directly */
5590 /* Patch the correct N_SD value into the message. */
5591 var octetstring l3_enc := enc_PDU_ML3_MS_NW(ussd_req_v);
5592 var RAN_Emulation.ConnectionData cd;
5593 f_ML3_patch_seq_nr_MS_NW(f_next_n_sd(last_n_sd, f_ML3_n_sd_idx(ussd_req_v)), l3_enc);
5594 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST,
5595 pars.imsi, remote_msc_name, local_msc_name,
5596 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
5597 enc_PDU_BSSAP(valueof(ts_BSSAP_DTAP(l3_enc)))
5598 ))
5599 ));
5600
5601 /* Expect GSUP message containing the SS payload */
5602 gsup_req_complete := f_expect_gsup_msg(gsup_req);
5603
5604 /* Compose the response from HLR using received session ID */
5605 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
5606 imsi := g_pars.imsi,
5607 sid := gsup_req_complete.ies[1].val.session_id,
5608 state := OSMO_GSUP_SESSION_STATE_END,
5609 ss := valueof(facility_rsp)
5610 );
5611
5612 /* Finally, HLR terminates the session */
5613 GSUP.send(gsup_rsp);
5614
5615 /* The USSD response goes out to remote MSC, on GSUP E instead of BSSAP */
5616 var GSUP_PDU gsup_ussd_rsp;
5617 GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST,
5618 pars.imsi, destination_name := remote_msc_name)) -> value gsup_ussd_rsp;
5619
5620 var GSUP_IeValue an_apdu;
5621 if (not f_gsup_find_ie(gsup_ussd_rsp, OSMO_GSUP_AN_APDU_IE, an_apdu)) {
5622 setverdict(fail, "No AN-APDU in received GSUP message. Expected USSD response in DTAP, got", gsup_ussd_rsp);
5623 mtc.stop;
5624 }
5625 var PDU_BSSAP bssap_dtap_mt := dec_PDU_BSSAP(an_apdu.an_apdu.pdu);
5626 var PDU_ML3_NW_MS dtap_mt := dec_PDU_ML3_NW_MS(bssap_dtap_mt.pdu.dtap);
5627 log("Expecting", ussd_rsp);
5628 log("Got", dtap_mt);
5629 if (not match(dtap_mt, ussd_rsp)) {
5630 setverdict(fail, "Unexpected GSUP message. Expected USSD response in DTAP, got", gsup_ussd_rsp);
5631 mtc.stop;
5632 }
5633 }
5634 /**********************************/
5635
5636
5637 /* inter-MSC handover back to the first MSC */
5638 f_create_bssmap_exp_handoverRequest(193);
5639 cil := { cIl_CGI := { ts_BSSMAP_CI_CGI('262'H, '42'H, 23, 42) } };
5640
5641 /* old BSS sends Handover Required, via inter-MSC E link: like
5642 * BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
5643 * but via GSUP */
5644 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_REQUEST,
5645 pars.imsi, remote_msc_name, local_msc_name,
5646 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
5647 enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverRequired(cause, cil)))
5648 ))
5649 ));
5650
5651 /* MSC asks local BSS to prepare Handover to it */
5652 BSSAP.receive(tr_BSSMAP_HandoverRequest);
5653
5654 /* Make sure the new BSSAP conn continues with the correct N_SD sequence numbers */
5655 f_bssmap_continue_after_n_sd(last_n_sd);
5656
5657 /* new BSS composes a RR Handover Command */
5658 rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5659 rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5660 var BSSMAP_IE_AoIP_TransportLayerAddress tla := valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
5661 BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
5662 tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
5663
5664 /* HandoverCommand goes out via remote MSC-I */
5665 var GSUP_PDU prep_subsq_ho_res;
5666 GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_RESULT,
5667 pars.imsi, destination_name := remote_msc_name)) -> value prep_subsq_ho_res;
5668
5669 /* MS shows up at the local BSS */
5670 BSSAP.send(ts_BSSMAP_HandoverDetect);
5671 f_sleep(0.1);
5672 BSSAP.send(ts_BSSMAP_HandoverComplete);
5673
5674 /* Handover Succeeded message */
5675 GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST,
5676 pars.imsi, destination_name := remote_msc_name));
5677
5678 /* MS has handovered to here, Clear Command goes out via remote MSC-I -- in form of a GSUP Close. */
5679 GSUP.receive(tr_GSUP_E_NO_PDU(OSMO_GSUP_MSGT_E_CLOSE,
5680 pars.imsi, destination_name := remote_msc_name));
5681
5682 /* Handover ends successfully. Call goes on for a little longer and then we hang up. */
5683
5684 f_sleep(1.0);
5685 deactivate(ack_mdcx);
5686
5687 /* FIXME: the inter-MSC call has put a number of MNCC messages in the queue, which above code should expect and
5688 * clear out. The f_call_hangup() expects an MNCC_REL_IND, so, for the time being, just clear the MNCC messages
5689 * before starting the call hangup. Instead of this, the individual messages should be tested for above. */
5690 MNCC.clear;
5691
5692 var default ccrel := activate(as_optional_cc_rel(cpars, true));
5693 f_call_hangup(cpars, true);
5694 f_sleep(1.0);
5695 deactivate(ccrel);
5696
5697 setverdict(pass);
5698}
5699testcase TC_ho_inter_msc_out() runs on MTC_CT {
5700 var BSC_ConnHdlr vc_conn;
5701 f_init(1);
5702
5703 var BSC_ConnHdlrPars pars := f_init_pars(54);
5704
5705 vc_conn := f_start_handler_with_pars(refers(f_tc_ho_inter_msc_out), pars, 0);
5706 vc_conn.done;
5707}
5708
Oliver Smith1d118ff2019-07-03 10:57:35 +02005709private function f_tc_lu_imsi_auth_tmsi_check_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5710 pars.net.expect_auth := true;
5711 pars.net.expect_imei := true;
5712 f_init_handler(pars);
5713 f_perform_lu();
5714}
5715testcase TC_lu_imsi_auth_tmsi_check_imei() runs on MTC_CT {
5716 var BSC_ConnHdlr vc_conn;
5717 f_init();
5718 f_vty_config(MSCVTY, "network", "authentication required");
5719 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
5720
5721 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei), 5);
5722 vc_conn.done;
5723}
5724
5725private function f_tc_lu_imsi_auth3g_tmsi_check_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5726 pars.net.expect_auth := true;
5727 pars.use_umts_aka := true;
5728 pars.net.expect_imei := true;
5729 f_init_handler(pars);
5730 f_perform_lu();
5731}
5732testcase TC_lu_imsi_auth3g_tmsi_check_imei() runs on MTC_CT {
5733 var BSC_ConnHdlr vc_conn;
5734 f_init();
5735 f_vty_config(MSCVTY, "network", "authentication required");
5736 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
5737
5738 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth3g_tmsi_check_imei), 5);
5739 vc_conn.done;
5740}
5741
5742private function f_tc_lu_imsi_noauth_tmsi_check_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5743 pars.net.expect_imei := true;
5744 f_init_handler(pars);
5745 f_perform_lu();
5746}
5747testcase TC_lu_imsi_noauth_tmsi_check_imei() runs on MTC_CT {
5748 var BSC_ConnHdlr vc_conn;
5749 f_init();
5750 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
5751
5752 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi_check_imei), 5);
5753 vc_conn.done;
5754}
5755
5756private function f_tc_lu_imsi_noauth_notmsi_check_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5757 pars.net.expect_tmsi := false;
5758 pars.net.expect_imei := true;
5759 f_init_handler(pars);
5760 f_perform_lu();
5761}
5762testcase TC_lu_imsi_noauth_notmsi_check_imei() runs on MTC_CT {
5763 var BSC_ConnHdlr vc_conn;
5764 f_init();
5765 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
5766 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
5767
5768 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi_check_imei), 5);
5769 vc_conn.done;
5770}
5771
5772private function f_tc_lu_imsi_auth_tmsi_check_imei_nack(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5773 var PDU_ML3_MS_NW l3_lu;
Oliver Smith1d118ff2019-07-03 10:57:35 +02005774
5775 pars.net.expect_auth := true;
5776 pars.net.expect_imei := true;
5777 pars.net.check_imei_result := OSMO_GSUP_IMEI_RESULT_NACK;
5778 f_init_handler(pars);
5779
5780 /* Cannot use f_perform_lu() as we expect a reject */
5781 l3_lu := f_build_lu_imsi(g_pars.imsi)
5782 f_create_gsup_expect(hex2str(g_pars.imsi));
5783 f_bssap_compl_l3(l3_lu);
5784 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
5785
5786 f_mm_common();
5787 f_msc_lu_hlr();
5788 f_mm_imei();
Oliver Smith91bfa1c2019-07-19 15:01:15 +02005789 f_expect_lu_reject();
Oliver Smith690d60f2019-07-23 13:09:08 +02005790 f_expect_clear();
Oliver Smith1d118ff2019-07-03 10:57:35 +02005791}
5792testcase TC_lu_imsi_auth_tmsi_check_imei_nack() runs on MTC_CT {
5793 var BSC_ConnHdlr vc_conn;
5794 f_init();
5795 f_vty_config(MSCVTY, "network", "authentication required");
5796 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
5797
5798 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_nack), 5);
5799 vc_conn.done;
5800}
5801
5802private function f_tc_lu_imsi_auth_tmsi_check_imei_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5803 var PDU_ML3_MS_NW l3_lu;
Oliver Smith1d118ff2019-07-03 10:57:35 +02005804
5805 pars.net.expect_auth := true;
5806 pars.net.expect_imei := true;
5807 pars.net.check_imei_error := true;
5808 f_init_handler(pars);
5809
5810 /* Cannot use f_perform_lu() as we expect a reject */
5811 l3_lu := f_build_lu_imsi(g_pars.imsi)
5812 f_create_gsup_expect(hex2str(g_pars.imsi));
5813 f_bssap_compl_l3(l3_lu);
5814 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
5815
5816 f_mm_common();
5817 f_msc_lu_hlr();
5818 f_mm_imei();
Oliver Smith91bfa1c2019-07-19 15:01:15 +02005819 f_expect_lu_reject();
Oliver Smith690d60f2019-07-23 13:09:08 +02005820 f_expect_clear();
Oliver Smith1d118ff2019-07-03 10:57:35 +02005821}
5822testcase TC_lu_imsi_auth_tmsi_check_imei_err() runs on MTC_CT {
5823 var BSC_ConnHdlr vc_conn;
5824 f_init();
5825 f_vty_config(MSCVTY, "network", "authentication required");
5826 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
5827
5828 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_err), 5);
5829 vc_conn.done;
5830}
5831
5832private function f_tc_lu_imsi_auth_tmsi_check_imei_early(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5833 pars.net.expect_auth := true;
5834 pars.net.expect_imei_early := true;
5835 f_init_handler(pars);
5836 f_perform_lu();
5837}
5838testcase TC_lu_imsi_auth_tmsi_check_imei_early() runs on MTC_CT {
5839 var BSC_ConnHdlr vc_conn;
5840 f_init();
5841 f_vty_config(MSCVTY, "network", "authentication required");
5842 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
5843
5844 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_early), 5);
5845 vc_conn.done;
5846}
5847
5848private function f_tc_lu_imsi_auth3g_tmsi_check_imei_early(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5849 pars.net.expect_auth := true;
5850 pars.use_umts_aka := true;
5851 pars.net.expect_imei_early := true;
5852 f_init_handler(pars);
5853 f_perform_lu();
5854}
5855testcase TC_lu_imsi_auth3g_tmsi_check_imei_early() runs on MTC_CT {
5856 var BSC_ConnHdlr vc_conn;
5857 f_init();
5858 f_vty_config(MSCVTY, "network", "authentication required");
5859 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
5860
5861 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth3g_tmsi_check_imei_early), 5);
5862 vc_conn.done;
5863}
5864
5865private function f_tc_lu_imsi_noauth_tmsi_check_imei_early(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5866 pars.net.expect_imei_early := true;
5867 f_init_handler(pars);
5868 f_perform_lu();
5869}
5870testcase TC_lu_imsi_noauth_tmsi_check_imei_early() runs on MTC_CT {
5871 var BSC_ConnHdlr vc_conn;
5872 f_init();
5873 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
5874
5875 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi_check_imei_early), 5);
5876 vc_conn.done;
5877}
5878
5879private function f_tc_lu_imsi_noauth_notmsi_check_imei_early(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5880 pars.net.expect_tmsi := false;
5881 pars.net.expect_imei_early := true;
5882 f_init_handler(pars);
5883 f_perform_lu();
5884}
5885testcase TC_lu_imsi_noauth_notmsi_check_imei_early() runs on MTC_CT {
5886 var BSC_ConnHdlr vc_conn;
5887 f_init();
5888 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
5889 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
5890
5891 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi_check_imei_early), 5);
5892 vc_conn.done;
5893}
5894
5895private function f_tc_lu_imsi_auth_tmsi_check_imei_early_nack(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5896 var PDU_ML3_MS_NW l3_lu;
Oliver Smith1d118ff2019-07-03 10:57:35 +02005897
5898 pars.net.expect_auth := true;
5899 pars.net.expect_imei_early := true;
5900 pars.net.check_imei_result := OSMO_GSUP_IMEI_RESULT_NACK;
5901 f_init_handler(pars);
5902
5903 /* Cannot use f_perform_lu() as we expect a reject */
5904 l3_lu := f_build_lu_imsi(g_pars.imsi)
5905 f_create_gsup_expect(hex2str(g_pars.imsi));
5906 f_bssap_compl_l3(l3_lu);
5907 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
5908
5909 f_mm_imei_early();
Oliver Smith91bfa1c2019-07-19 15:01:15 +02005910 f_expect_lu_reject();
Oliver Smith690d60f2019-07-23 13:09:08 +02005911 f_expect_clear();
Oliver Smith1d118ff2019-07-03 10:57:35 +02005912}
5913testcase TC_lu_imsi_auth_tmsi_check_imei_early_nack() runs on MTC_CT {
5914 var BSC_ConnHdlr vc_conn;
5915 f_init();
5916 f_vty_config(MSCVTY, "network", "authentication required");
5917 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
5918
5919 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_early_nack), 5);
5920 vc_conn.done;
5921}
5922
5923private function f_tc_lu_imsi_auth_tmsi_check_imei_early_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5924 var PDU_ML3_MS_NW l3_lu;
Oliver Smith1d118ff2019-07-03 10:57:35 +02005925
5926 pars.net.expect_auth := true;
5927 pars.net.expect_imei_early := true;
5928 pars.net.check_imei_error := true;
5929 f_init_handler(pars);
5930
5931 /* Cannot use f_perform_lu() as we expect a reject */
5932 l3_lu := f_build_lu_imsi(g_pars.imsi)
5933 f_create_gsup_expect(hex2str(g_pars.imsi));
5934 f_bssap_compl_l3(l3_lu);
5935 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
5936
5937 f_mm_imei_early();
Oliver Smith91bfa1c2019-07-19 15:01:15 +02005938 f_expect_lu_reject();
Oliver Smith690d60f2019-07-23 13:09:08 +02005939 f_expect_clear();
Oliver Smith1d118ff2019-07-03 10:57:35 +02005940}
5941testcase TC_lu_imsi_auth_tmsi_check_imei_early_err() runs on MTC_CT {
5942 var BSC_ConnHdlr vc_conn;
5943 f_init();
5944 f_vty_config(MSCVTY, "network", "authentication required");
5945 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
5946
5947 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_early_err), 5);
5948 vc_conn.done;
5949}
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005950
Neels Hofmeyr8df69622019-11-02 19:16:03 +01005951friend function f_tc_invalid_mgcp_crash(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5952 f_init_handler(pars);
5953 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
5954
5955 /* Set invalid IP address so that osmo-msc discards the rtp_stream and MGCP endpoint FSM instances in the middle
5956 * of successful MGCP response dispatch. If things aren't safeguarded, the on_success() in osmo_mgcpc_ep_fsm
5957 * will cause a use-after-free after that event dispatch. */
5958 cpars.mgw_conn_1.mgw_rtp_ip := "0.0.0.0";
5959 cpars.mgw_conn_2.mgw_rtp_ip := "0.0.0.0";
5960 cpars.rtp_sdp_format := "FOO/8000";
5961 cpars.expect_release := true;
5962
5963 f_perform_lu();
5964 f_mo_call_establish(cpars);
5965}
5966testcase TC_invalid_mgcp_crash() runs on MTC_CT {
5967 var BSC_ConnHdlr vc_conn;
5968 f_init();
5969
5970 vc_conn := f_start_handler(refers(f_tc_invalid_mgcp_crash), 7);
5971 vc_conn.done;
5972}
5973
Vadim Yanitskiyeddebaa2019-12-28 17:45:34 +01005974friend function f_tc_mm_id_resp_no_identity(charstring id, BSC_ConnHdlrPars pars)
5975runs on BSC_ConnHdlr {
5976 pars.tmsi := 'FFFFFFFF'O;
5977 f_init_handler(pars);
5978
5979 f_create_gsup_expect(hex2str(g_pars.imsi));
5980
5981 /* Initiate Location Updating using an unknown TMSI */
5982 f_bssap_compl_l3(f_build_lu_tmsi(pars.tmsi));
5983
5984 /* Expect an Identity Request, send response with no identity */
5985 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req(CM_ID_TYPE_IMSI)));
5986 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp({
5987 lengthIndicator := 1,
5988 mobileIdentityV := {
5989 typeOfIdentity := '000'B,
5990 oddEvenInd_identity := {
5991 no_identity := {
5992 oddevenIndicator := '0'B,
5993 fillerDigits := '00000'H
5994 }
5995 }
5996 }
5997 })));
5998
5999 f_expect_lu_reject();
6000 f_expect_clear();
6001}
6002testcase TC_mm_id_resp_no_identity() runs on MTC_CT {
6003 var BSC_ConnHdlr vc_conn;
6004
6005 f_init();
6006
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02006007 vc_conn := f_start_handler(refers(f_tc_mm_id_resp_no_identity), 7, verify_cell_id := false);
Vadim Yanitskiyeddebaa2019-12-28 17:45:34 +01006008 vc_conn.done;
6009}
6010
Vadim Yanitskiy25219062020-01-21 01:41:33 +07006011/* Verify the case when T3212 expires during Paging procedure, just before the receipt
6012 * of Paging Response. This used to provoke a NULL-pointer dereference in old versions
6013 * of OsmoMSC, but apparently the bug has been fixed, and we're safe now. */
6014friend function f_tc_lu_and_expire_while_paging(charstring id, BSC_ConnHdlrPars pars)
6015runs on BSC_ConnHdlr {
6016 var charstring imsi := hex2str(pars.imsi);
6017
6018 f_init_handler(pars);
6019
6020 /* Perform location update */
6021 f_perform_lu();
6022
6023 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
6024 f_create_gsup_expect(hex2str(g_pars.imsi));
6025
6026 /* Initiate paging procedure from the VTY */
6027 f_vty_transceive(MSCVTY, "subscriber imsi " & imsi & " paging");
6028 f_expect_paging();
6029
6030 /* Emulate T3212 expiration during paging (we don't want to wait, right?) */
6031 f_vty_transceive(MSCVTY, "subscriber imsi " & imsi & " expire");
6032
6033 /* MS sends PAGING RESPONSE, *old* OsmoMSC crashes here... */
6034 f_establish_fully(EST_TYPE_PAG_RESP);
6035
6036 /* The recent OsmoMSC keeps subscriber in its VLR unless the Paging is completed.
6037 * In this case we do not send anything and just wait for a Clear Command. */
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02006038 f_expect_clear(verify_vlr_cell_id := false);
Vadim Yanitskiy25219062020-01-21 01:41:33 +07006039}
6040testcase TC_lu_and_expire_while_paging() runs on MTC_CT {
6041 var BSC_ConnHdlr vc_conn;
6042
6043 f_init();
6044
6045 vc_conn := f_start_handler(refers(f_tc_lu_and_expire_while_paging), 7);
6046 vc_conn.done;
6047}
6048
Harald Weltef6dd64d2017-11-19 12:09:51 +01006049control {
Philipp Maier328d1662018-03-07 10:40:27 +01006050 execute( TC_cr_before_reset() );
Harald Weltea49e36e2018-01-21 19:29:33 +01006051 execute( TC_lu_imsi_noauth_tmsi() );
Harald Welted2328a22018-01-27 14:27:16 +01006052 execute( TC_lu_imsi_noauth_notmsi() );
Harald Weltea49e36e2018-01-21 19:29:33 +01006053 execute( TC_lu_imsi_reject() );
6054 execute( TC_lu_imsi_timeout_gsup() );
Harald Welted2328a22018-01-27 14:27:16 +01006055 execute( TC_lu_imsi_auth_tmsi() );
Harald Welte8a397ae2019-04-21 22:03:37 +02006056 execute( TC_lu_imsi_auth3g_tmsi() );
Pau Espin Pedrold3d54a92019-12-17 17:02:54 +01006057 execute( TC_lu_imsi_timeout_tmsi_realloc() );
Harald Welted2328a22018-01-27 14:27:16 +01006058 execute( TC_cmserv_imsi_unknown() );
Harald Welte2bb825f2018-01-22 11:31:18 +01006059 execute( TC_lu_and_mo_call() );
Pau Espin Pedrola42745c2020-01-10 18:03:28 +01006060 execute( TC_lu_and_mo_call_sccp_tiar_timeout() );
Harald Welte071ed732018-01-23 19:53:52 +01006061 execute( TC_lu_auth_sai_timeout() );
6062 execute( TC_lu_auth_sai_err() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01006063 execute( TC_lu_clear_request() );
6064 execute( TC_lu_disconnect() );
6065 execute( TC_lu_by_imei() );
6066 execute( TC_lu_by_tmsi_noauth_unknown() );
6067 execute( TC_imsi_detach_by_imsi() );
6068 execute( TC_imsi_detach_by_tmsi() );
6069 execute( TC_imsi_detach_by_imei() );
6070 execute( TC_emerg_call_imei_reject() );
6071 execute( TC_emerg_call_imsi() );
6072 execute( TC_cm_serv_req_vgcs_reject() );
6073 execute( TC_cm_serv_req_vbs_reject() );
6074 execute( TC_cm_serv_req_lcs_reject() );
Harald Welte0195ab12018-01-24 21:50:20 +01006075 execute( TC_cm_reest_req_reject() );
Harald Welte1af6ea82018-01-25 18:33:15 +01006076 execute( TC_lu_auth_2G_fail() );
6077 execute( TC_lu_imsi_auth_tmsi_encr_13_13() );
6078 execute( TC_cl3_no_payload() );
6079 execute( TC_cl3_rnd_payload() );
Harald Welte1852a842018-01-26 22:53:36 +01006080 execute( TC_establish_and_nothing() );
6081 execute( TC_mo_setup_and_nothing() );
6082 execute( TC_mo_crcx_ran_timeout() );
6083 execute( TC_mo_crcx_ran_reject() );
Harald Welted2328a22018-01-27 14:27:16 +01006084 execute( TC_mt_crcx_ran_reject() );
Daniel Willmann8b084372018-02-04 13:35:26 +01006085 execute( TC_mo_setup_and_dtmf_dup() );
Harald Welteaa54cf82018-01-30 08:15:32 +01006086 //execute( TC_mt_t310() );
Harald Welte167458a2018-01-27 15:58:16 +01006087 execute( TC_gsup_cancel() );
Harald Welte9de84792018-01-28 01:06:35 +01006088 execute( TC_lu_imsi_auth_tmsi_encr_1_13() );
6089 execute( TC_lu_imsi_auth_tmsi_encr_3_13() );
6090 execute( TC_lu_imsi_auth_tmsi_encr_3_1() );
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01006091 execute( TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() );
Harald Welte9de84792018-01-28 01:06:35 +01006092 execute( TC_lu_imsi_auth_tmsi_encr_13_2() );
6093 execute( TC_lu_imsi_auth_tmsi_encr_013_2() );
Philipp Maier94f3f1b2018-03-15 18:54:13 +01006094 execute( TC_mo_release_timeout() );
Philipp Maier2a98a732018-03-19 16:06:12 +01006095 execute( TC_lu_and_mt_call_no_dlcx_resp() );
Philipp Maier75932982018-03-27 14:52:35 +02006096 execute( TC_reset_two() );
Harald Welte33ec09b2018-02-10 15:34:46 +01006097
6098 execute( TC_lu_and_mt_call() );
Neels Hofmeyrb58d9742019-11-27 18:44:54 +01006099 execute( TC_lu_and_mt_call_already_paging() );
Harald Welte33ec09b2018-02-10 15:34:46 +01006100
Harald Weltef45efeb2018-04-09 18:19:24 +02006101 execute( TC_lu_and_mo_sms() );
6102 execute( TC_lu_and_mt_sms() );
Neels Hofmeyrb58d9742019-11-27 18:44:54 +01006103 execute( TC_lu_and_mt_sms_already_paging() );
Philipp Maier3983e702018-11-22 19:01:33 +01006104 execute( TC_lu_and_mt_sms_paging_and_nothing() );
Alexander Couzensfc02f242019-09-12 03:43:18 +02006105 execute( TC_lu_and_mt_sms_paging_repeated() );
Harald Weltef640a012018-04-14 17:49:21 +02006106 execute( TC_smpp_mo_sms() );
Vadim Yanitskiy33820762020-01-15 11:26:07 +07006107 execute( TC_smpp_mo_sms_rp_error() );
Harald Weltef640a012018-04-14 17:49:21 +02006108 execute( TC_smpp_mt_sms() );
Harald Weltef45efeb2018-04-09 18:19:24 +02006109
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07006110 execute( TC_gsup_mo_sms() );
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07006111 execute( TC_gsup_mo_smma() );
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07006112 execute( TC_gsup_mt_sms_ack() );
6113 execute( TC_gsup_mt_sms_err() );
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07006114 execute( TC_gsup_mt_sms_rp_mr() );
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07006115 execute( TC_gsup_mo_mt_sms_rp_mr() );
Vadim Yanitskiya2a8a112019-07-08 20:04:32 +07006116 execute( TC_gsup_mt_multi_part_sms() );
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07006117
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07006118 execute( TC_lu_and_mo_ussd_single_request() );
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07006119 execute( TC_lu_and_mt_ussd_notification() );
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07006120 execute( TC_lu_and_mo_ussd_during_mt_call() );
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07006121 execute( TC_lu_and_mt_ussd_during_mt_call() );
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07006122 execute( TC_lu_and_mo_ussd_mo_release() );
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07006123 execute( TC_lu_and_ss_session_timeout() );
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07006124
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07006125 execute( TC_mt_ussd_for_unknown_subscr() );
Vadim Yanitskiyc3c07d42019-06-17 23:00:44 +07006126 execute( TC_mo_ussd_for_unknown_trans() );
Vadim Yanitskiyd612d282019-06-15 14:46:03 +07006127 execute( TC_proc_ss_for_unknown_session() );
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07006128 execute( TC_proc_ss_paging_fail() );
Vadim Yanitskiy29ba8d62019-06-16 15:19:41 +07006129 execute( TC_proc_ss_abort() );
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07006130
Vadim Yanitskiy1c9754d2020-01-07 21:56:55 +01006131 execute( TC_multi_lu_and_mo_ussd() );
6132 execute( TC_multi_lu_and_mt_ussd() );
6133
Stefan Sperling89eb1f32018-12-17 15:06:20 +01006134 execute( TC_cipher_complete_with_invalid_cipher() );
Stefan Sperlinga2d59c62018-12-18 16:32:44 +01006135 execute( TC_cipher_complete_1_without_cipher() );
6136 execute( TC_cipher_complete_3_without_cipher() );
6137 execute( TC_cipher_complete_13_without_cipher() );
Harald Welteb2284bd2019-05-10 11:30:43 +02006138 execute( TC_lu_with_invalid_mcc_mnc() );
Stefan Sperling89eb1f32018-12-17 15:06:20 +01006139
Harald Welte4263c522018-12-06 11:56:27 +01006140 execute( TC_sgsap_reset() );
6141 execute( TC_sgsap_lu() );
6142 execute( TC_sgsap_lu_imsi_reject() );
6143 execute( TC_sgsap_lu_and_nothing() );
6144 execute( TC_sgsap_expl_imsi_det_eps() );
Philipp Maierfc19f172019-03-21 11:17:54 +01006145 execute( TC_sgsap_impl_imsi_det_eps() );
Harald Welte4263c522018-12-06 11:56:27 +01006146 execute( TC_sgsap_expl_imsi_det_noneps() );
Philipp Maier5d812702019-03-21 10:51:26 +01006147 execute( TC_sgsap_impl_imsi_det_noneps() );
Harald Welte4263c522018-12-06 11:56:27 +01006148 execute( TC_sgsap_paging_rej() );
6149 execute( TC_sgsap_paging_subscr_rej() );
6150 execute( TC_sgsap_paging_ue_unr() );
6151 execute( TC_sgsap_paging_and_nothing() );
6152 execute( TC_sgsap_paging_and_lu() );
6153 execute( TC_sgsap_mt_sms() );
6154 execute( TC_sgsap_mo_sms() );
6155 execute( TC_sgsap_mt_sms_and_nothing() );
6156 execute( TC_sgsap_mt_sms_and_reject() );
6157 execute( TC_sgsap_unexp_ud() );
6158 execute( TC_sgsap_unsol_ud() );
6159 execute( TC_bssap_lu_sgsap_lu_and_mt_call() );
6160 execute( TC_sgsap_lu_and_mt_call() );
Philipp Maier628c0052019-04-09 17:36:57 +02006161 execute( TC_sgsap_vlr_failure() );
Harald Welte4263c522018-12-06 11:56:27 +01006162
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006163 execute( TC_ho_inter_bsc_unknown_cell() );
6164 execute( TC_ho_inter_bsc() );
6165
6166 execute( TC_ho_inter_msc_out() );
6167
Oliver Smith1d118ff2019-07-03 10:57:35 +02006168 execute( TC_lu_imsi_auth_tmsi_check_imei() );
6169 execute( TC_lu_imsi_auth3g_tmsi_check_imei() );
6170 execute( TC_lu_imsi_noauth_tmsi_check_imei() );
6171 execute( TC_lu_imsi_noauth_notmsi_check_imei() );
6172 execute( TC_lu_imsi_auth_tmsi_check_imei_nack() );
6173 execute( TC_lu_imsi_auth_tmsi_check_imei_err() );
6174 execute( TC_lu_imsi_auth_tmsi_check_imei_early() );
6175 execute( TC_lu_imsi_auth3g_tmsi_check_imei_early() );
6176 execute( TC_lu_imsi_noauth_tmsi_check_imei_early() );
6177 execute( TC_lu_imsi_noauth_notmsi_check_imei_early() );
6178 execute( TC_lu_imsi_auth_tmsi_check_imei_early_nack() );
6179 execute( TC_lu_imsi_auth_tmsi_check_imei_early_err() );
6180
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01006181 /* Run this last: at the time of writing this test crashes the MSC */
6182 execute( TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() );
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02006183 execute( TC_mo_cc_bssmap_clear() );
Pau Espin Pedrol690d6592019-05-31 17:56:32 +02006184 if (mp_enable_osmux_test) {
6185 execute( TC_lu_and_mt_call_osmux() );
6186 }
Neels Hofmeyr8df69622019-11-02 19:16:03 +01006187 execute( TC_invalid_mgcp_crash() );
Vadim Yanitskiyeddebaa2019-12-28 17:45:34 +01006188 execute( TC_mm_id_resp_no_identity() );
Vadim Yanitskiy25219062020-01-21 01:41:33 +07006189 execute( TC_lu_and_expire_while_paging() );
Harald Weltef6dd64d2017-11-19 12:09:51 +01006190}
6191
6192
6193}