blob: e5c48bbbf48b3bd567e014b23e09bcdd36cb6000 [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;
Pau Espin Pedrole979c402021-04-28 17:29:54 +020019import from GSM_Types all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010020
21import from M3UA_Types all;
22import from M3UA_Emulation all;
23
24import from MTP3asp_Types all;
25import from MTP3asp_PortType all;
26
27import from SCCPasp_Types all;
28import from SCCP_Types all;
29import from SCCP_Emulation all;
30
31import from SCTPasp_Types all;
32import from SCTPasp_PortType all;
33
Harald Weltea49e36e2018-01-21 19:29:33 +010034import from Osmocom_CTRL_Functions all;
35import from Osmocom_CTRL_Types all;
36import from Osmocom_CTRL_Adapter all;
37
Harald Welte3ca1c902018-01-24 18:51:27 +010038import from TELNETasp_PortType all;
39import from Osmocom_VTY_Functions all;
40
Harald Weltea49e36e2018-01-21 19:29:33 +010041import from MNCC_Emulation all;
Harald Welte2bb825f2018-01-22 11:31:18 +010042import from MNCC_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +010043
Harald Welte4aa970c2018-01-26 10:38:09 +010044import from MGCP_Emulation all;
45import from MGCP_Types all;
46import from MGCP_Templates all;
47import from SDP_Types all;
48
Harald Weltea49e36e2018-01-21 19:29:33 +010049import from GSUP_Emulation all;
50import from GSUP_Types all;
51import from IPA_Emulation all;
52
Harald Weltef6dd64d2017-11-19 12:09:51 +010053import from BSSAP_Types all;
Harald Welte6811d102019-04-14 22:23:14 +020054import from RAN_Adapter all;
Harald Weltea49e36e2018-01-21 19:29:33 +010055import from BSSAP_CodecPort all;
56import from BSSMAP_Templates all;
Harald Welte6811d102019-04-14 22:23:14 +020057import from RAN_Emulation all;
Harald Weltea49e36e2018-01-21 19:29:33 +010058import from BSC_ConnectionHandler all;
Harald Weltee13cfb22019-04-23 16:52:02 +020059import from RANAP_Templates all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010060
Harald Welte4263c522018-12-06 11:56:27 +010061import from SGsAP_Templates all;
62import from SGsAP_Types all;
63import from SGsAP_Emulation all;
64
Harald Weltea49e36e2018-01-21 19:29:33 +010065import from MobileL3_Types all;
66import from MobileL3_CommonIE_Types all;
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +070067import from MobileL3_SMS_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +010068import from L3_Templates all;
Harald Welte158a7ca2018-02-16 18:11:31 +010069import from L3_Common all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010070
Harald Weltef640a012018-04-14 17:49:21 +020071import from SMPP_Types all;
72import from SMPP_Templates all;
73import from SMPP_Emulation all;
74
Stefan Sperlingc307e682018-06-14 15:15:46 +020075import from SCCP_Templates all;
76
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +070077import from SS_Types all;
78import from SS_Templates all;
79import from USSD_Helpers all;
Harald Welte4263c522018-12-06 11:56:27 +010080import from DNS_Helpers all;
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +070081
Philipp Maier948747b2019-04-02 15:22:33 +020082import from TCCConversion_Functions all;
83
Harald Welte9b751a62019-04-14 17:39:29 +020084const integer NUM_BSC := 3;
Harald Weltef6dd64d2017-11-19 12:09:51 +010085
Harald Welte4263c522018-12-06 11:56:27 +010086/* Needed for SGsAP SMS */
87import from MobileL3_SMS_Types all;
88
Harald Weltea4ca4462018-02-09 00:17:14 +010089type component MTC_CT extends CTRL_Adapter_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +010090 var boolean g_initialized := false;
Harald Weltea49e36e2018-01-21 19:29:33 +010091
Harald Welte6811d102019-04-14 22:23:14 +020092 var RAN_Adapter g_bssap[NUM_BSC];
Harald Weltea4ca4462018-02-09 00:17:14 +010093
Harald Weltea49e36e2018-01-21 19:29:33 +010094 /* no 'adapter_CT' for MNCC or GSUP */
95 var MNCC_Emulation_CT vc_MNCC;
Harald Welte4aa970c2018-01-26 10:38:09 +010096 var MGCP_Emulation_CT vc_MGCP;
Harald Weltea49e36e2018-01-21 19:29:33 +010097 var GSUP_Emulation_CT vc_GSUP;
98 var IPA_Emulation_CT vc_GSUP_IPA;
Harald Weltef640a012018-04-14 17:49:21 +020099 var SMPP_Emulation_CT vc_SMPP;
Harald Welte4263c522018-12-06 11:56:27 +0100100 var SGsAP_Emulation_CT vc_SGsAP;
Harald Weltea49e36e2018-01-21 19:29:33 +0100101
102 /* only to get events from IPA underneath GSUP */
103 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte3ca1c902018-01-24 18:51:27 +0100104 /* VTY to MSC */
105 port TELNETasp_PT MSCVTY;
Philipp Maier328d1662018-03-07 10:40:27 +0100106
107 /* A port to directly send BSSAP messages. This port is used for
108 * tests that require low level access to sen arbitrary BSSAP
109 * messages. Run f_init_bssap_direct() to connect and initialize */
110 port BSSAP_CODEC_PT BSSAP_DIRECT;
111
112 /* When BSSAP messages are directly sent, then the connection
113 * handler is not active, which means that also no guard timer is
114 * set up. The following timer will serve as a replacement */
115 timer Tguard_direct := 60.0;
Pau Espin Pedrola42745c2020-01-10 18:03:28 +0100116
117 /* Configure T(tias) over VTY, seconds */
118 var integer g_msc_sccp_timer_ias := 7 * 60;
119 /* Configure T(tiar) over VTY, seconds */
120 var integer g_msc_sccp_timer_iar := 15 * 60;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100121}
122
123modulepar {
Harald Weltea49e36e2018-01-21 19:29:33 +0100124 /* remote parameters of IUT */
125 charstring mp_msc_ip := "127.0.0.1";
126 integer mp_msc_ctrl_port := 4255;
127 integer mp_msc_vty_port := 4254;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100128
Harald Weltea49e36e2018-01-21 19:29:33 +0100129 /* local parameters of emulated HLR */
Philipp Maier9b690e42018-12-21 11:50:03 +0100130 boolean mp_mm_info := false;
Harald Weltea49e36e2018-01-21 19:29:33 +0100131 charstring mp_hlr_ip := "127.0.0.1";
132 integer mp_hlr_port := 4222;
Harald Welte6126fb02018-01-27 20:08:24 +0100133 charstring mp_mgw_ip := "127.0.0.1";
134 integer mp_mgw_port := 2427;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100135
Harald Weltea49e36e2018-01-21 19:29:33 +0100136 charstring mp_msc_mncc := "/tmp/mncc";
Harald Weltea4ca4462018-02-09 00:17:14 +0100137
Harald Weltef640a012018-04-14 17:49:21 +0200138 integer mp_msc_smpp_port := 2775;
139 charstring mp_smpp_system_id := "msc_tester";
140 charstring mp_smpp_password := "osmocom1";
Harald Welte4263c522018-12-06 11:56:27 +0100141 charstring mp_mme_name := "mmec01.mmegi0001.mme.epc.mnc070.mcc901.3gppnetwork.org";
142 charstring mp_vlr_name := "vlr.example.net";
Eric Wild49888a62022-03-30 03:16:11 +0200143 integer mp_bssap_reset_retries := 1;
Harald Weltef640a012018-04-14 17:49:21 +0200144
Harald Welte6811d102019-04-14 22:23:14 +0200145 RAN_Configurations mp_bssap_cfg := {
Philipp Maier75932982018-03-27 14:52:35 +0200146 {
147 sccp_service_type := "mtp3_itu",
148 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
149 own_pc := 185,
150 own_ssn := 254,
151 peer_pc := 187,
152 peer_ssn := 254,
153 sio := '83'O,
154 rctx := 0
155 },
156 {
157 sccp_service_type := "mtp3_itu",
158 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
159 own_pc := 186,
160 own_ssn := 254,
161 peer_pc := 187,
162 peer_ssn := 254,
163 sio := '83'O,
164 rctx := 1
165 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100166 };
Harald Weltef6dd64d2017-11-19 12:09:51 +0100167}
168
Philipp Maier328d1662018-03-07 10:40:27 +0100169/* altstep for the global guard timer (only used when BSSAP_DIRECT
170 * is used for communication */
171private altstep as_Tguard_direct() runs on MTC_CT {
172 [] Tguard_direct.timeout {
173 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200174 mtc.stop;
Philipp Maier328d1662018-03-07 10:40:27 +0100175 }
176}
Harald Weltef6dd64d2017-11-19 12:09:51 +0100177
Neels Hofmeyr2ca1ab42019-03-08 03:45:43 +0100178private altstep as_optional_cc_rel(CallParameters cpars, boolean respond := false) runs on BSC_ConnHdlr {
179 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id))) {
180 if (respond) {
181 var BIT1 tid_remote := '1'B;
182 if (cpars.mo_call) {
183 tid_remote := '0'B;
184 }
185 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id, tid_remote)));
186 }
187 }
Neels Hofmeyrde76f052019-02-26 05:02:46 +0100188}
189
Harald Weltef640a012018-04-14 17:49:21 +0200190function f_init_smpp(charstring id) runs on MTC_CT {
191 id := id & "-SMPP";
192 var EsmePars pars := {
193 mode := MODE_TRANSCEIVER,
194 bind := {
195 system_id := mp_smpp_system_id,
196 password := mp_smpp_password,
197 system_type := "MSC_Tests",
198 interface_version := hex2int('34'H),
199 addr_ton := unknown,
200 addr_npi := unknown,
201 address_range := ""
202 },
203 esme_role := true
204 }
205
206 vc_SMPP := SMPP_Emulation_CT.create(id);
207 map(vc_SMPP:SMPP_PORT, system:SMPP_PORT);
Harald Welte4698a4c2020-08-18 22:57:52 +0200208 vc_SMPP.start(SMPP_Emulation.main_client(pars, mp_msc_ip, mp_msc_smpp_port, "", 0));
Harald Weltef640a012018-04-14 17:49:21 +0200209}
210
211
Harald Weltea49e36e2018-01-21 19:29:33 +0100212function f_init_mncc(charstring id) runs on MTC_CT {
213 id := id & "-MNCC";
214 var MnccOps ops := {
215 create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
216 unitdata_cb := refers(MNCC_Emulation.DummyUnitdataCallback)
217 }
218
219 vc_MNCC := MNCC_Emulation_CT.create(id);
220 map(vc_MNCC:MNCC, system:MNCC_CODEC_PT);
221 vc_MNCC.start(MNCC_Emulation.main(ops, id, mp_msc_mncc));
Harald Weltef6dd64d2017-11-19 12:09:51 +0100222}
223
Harald Welte4aa970c2018-01-26 10:38:09 +0100224function f_init_mgcp(charstring id) runs on MTC_CT {
225 id := id & "-MGCP";
226 var MGCPOps ops := {
227 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
228 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
229 }
230 var MGCP_conn_parameters pars := {
Harald Welte6126fb02018-01-27 20:08:24 +0100231 callagent_ip := mp_msc_ip,
Harald Welte4aa970c2018-01-26 10:38:09 +0100232 callagent_udp_port := -1,
Harald Welte6126fb02018-01-27 20:08:24 +0100233 mgw_ip := mp_mgw_ip,
Pau Espin Pedrol1a026a52019-06-18 17:21:52 +0200234 mgw_udp_port := mp_mgw_port,
235 multi_conn_mode := false
Harald Welte4aa970c2018-01-26 10:38:09 +0100236 }
237
238 vc_MGCP := MGCP_Emulation_CT.create(id);
239 map(vc_MGCP:MGCP, system:MGCP_CODEC_PT);
240 vc_MGCP.start(MGCP_Emulation.main(ops, pars, id));
241}
242
Philipp Maierc09a1312019-04-09 16:05:26 +0200243function ForwardUnitdataCallback(PDU_SGsAP msg)
244runs on SGsAP_Emulation_CT return template PDU_SGsAP {
245 SGsAP_CLIENT.send(msg);
246 return omit;
247}
248
Harald Welte4263c522018-12-06 11:56:27 +0100249function f_init_sgsap(charstring id) runs on MTC_CT {
250 id := id & "-SGsAP";
251 var SGsAPOps ops := {
252 create_cb := refers(SGsAP_Emulation.ExpectedCreateCallback),
Philipp Maierc09a1312019-04-09 16:05:26 +0200253 unitdata_cb := refers(ForwardUnitdataCallback)
Harald Welte4263c522018-12-06 11:56:27 +0100254 }
255 var SGsAP_conn_parameters pars := {
256 remote_ip := mp_msc_ip,
257 remote_sctp_port := 29118,
258 local_ip := "",
259 local_sctp_port := -1
260 }
261
262 vc_SGsAP := SGsAP_Emulation_CT.create(id);
263 map(vc_SGsAP:SGsAP, system:SGsAP_CODEC_PT);
264 vc_SGsAP.start(SGsAP_Emulation.main(ops, pars, id));
265}
266
267
Harald Weltea49e36e2018-01-21 19:29:33 +0100268function f_init_gsup(charstring id) runs on MTC_CT {
269 id := id & "-GSUP";
270 var GsupOps ops := {
271 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
272 }
273
274 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
275 vc_GSUP := GSUP_Emulation_CT.create(id);
276
277 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
278 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
279 /* we use this hack to get events like ASP_IPA_EVENT_UP */
280 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
281
282 vc_GSUP.start(GSUP_Emulation.main(ops, id));
283 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
284
285 /* wait for incoming connection to GSUP port before proceeding */
286 timer T := 10.0;
287 T.start;
288 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700289 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Weltea49e36e2018-01-21 19:29:33 +0100290 [] T.timeout {
Harald Welte458fd372018-03-21 11:26:23 +0100291 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200292 mtc.stop
Harald Weltea49e36e2018-01-21 19:29:33 +0100293 }
294 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100295}
296
Pau Espin Pedrola65697d2019-05-21 12:54:39 +0200297function 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 +0100298
299 if (g_initialized == true) {
300 return;
301 }
302 g_initialized := true;
303
Philipp Maier75932982018-03-27 14:52:35 +0200304 if (num_bsc > NUM_BSC) {
Daniel Willmannafce8662018-07-06 23:11:32 +0200305 testcase.stop("excess number of BSC instances requested");
Philipp Maier75932982018-03-27 14:52:35 +0200306 }
307
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +0100308 f_ipa_ctrl_start_client(mp_msc_ip, mp_msc_ctrl_port);
Harald Welte3ca1c902018-01-24 18:51:27 +0100309
310 map(self:MSCVTY, system:MSCVTY);
311 f_vty_set_prompts(MSCVTY);
312 f_vty_transceive(MSCVTY, "enable");
Harald Welteb14c77a2018-01-25 17:25:44 +0100313
314 /* set some defaults */
315 f_vty_config(MSCVTY, "network", "authentication optional");
316 f_vty_config(MSCVTY, "msc", "assign-tmsi");
Oliver Smith1d118ff2019-07-03 10:57:35 +0200317 f_vty_config(MSCVTY, "msc", "check-imei-rqd 0");
Harald Welteb14c77a2018-01-25 17:25:44 +0100318 f_vty_config(MSCVTY, "network", "encryption a5 0");
Pau Espin Pedrola42745c2020-01-10 18:03:28 +0100319 f_vty_config(MSCVTY, "cs7 instance 0", "sccp-timer ias " & int2str(g_msc_sccp_timer_ias));
320 f_vty_config(MSCVTY, "cs7 instance 0", "sccp-timer iar " & int2str(g_msc_sccp_timer_iar));
Pau Espin Pedrol9a732a42020-09-15 15:56:33 +0200321 if (osmux) {
322 f_vty_config(MSCVTY, "msc", "osmux on");
323 } else {
324 f_vty_config(MSCVTY, "msc", "osmux off");
Pau Espin Pedrol3dd33bc2019-05-31 17:51:20 +0200325 }
Daniel Willmann08862152022-02-22 13:21:49 +0100326
Neels Hofmeyrc47ce852023-03-06 17:16:50 +0100327 /* Configure the MGCP timeout so that a failure to set up all RTP streams triggers within the time that we keep
328 * an otherwise established call open. */
329 f_vty_config(MSCVTY, "msc", "timer mgw X2 3");
330
Daniel Willmann08862152022-02-22 13:21:49 +0100331 for (var integer i := 0; i < num_bsc; i := i + 1) {
332 if (isbound(mp_bssap_cfg[i])) {
333 var RanOps ranops := BSC_RanOps;
334 ranops.use_osmux := osmux;
Eric Wild49888a62022-03-30 03:16:11 +0200335 ranops.bssap_reset_retries := mp_bssap_reset_retries;
Daniel Willmann08862152022-02-22 13:21:49 +0100336 f_ran_adapter_init(g_bssap[i], mp_bssap_cfg[i], "MSC_Test_" & int2str(i), ranops);
337 f_ran_adapter_start(g_bssap[i]);
338 } else {
339 testcase.stop("missing BSSAP configuration");
340 }
341 }
342
343 f_init_mncc("MSC_Test");
344 f_init_mgcp("MSC_Test");
345
346 if (gsup == true) {
347 f_init_gsup("MSC_Test");
348 }
349 f_init_smpp("MSC_Test");
350
351 if (sgsap == true) {
352 f_init_sgsap("MSC_Test");
353 }
354
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 */
Neels Hofmeyre860fc42022-10-05 01:15:54 +0200378 net_config := { "authentication optional", "encryption a5 0" },
379 expect_attach_success := true,
Harald Weltede371492018-01-27 23:44:41 +0100380 expect_tmsi := true,
Neels Hofmeyre860fc42022-10-05 01:15:54 +0200381 expect_auth_attempt := false,
382 hlr_has_auth_info := true,
Harald Weltede371492018-01-27 23:44:41 +0100383 expect_auth := false,
Oliver Smith1d118ff2019-07-03 10:57:35 +0200384 expect_ciph := false,
385 expect_imei := false,
386 expect_imei_early := false,
387 check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
388 check_imei_error := false
Harald Weltede371492018-01-27 23:44:41 +0100389 };
Harald Weltea49e36e2018-01-21 19:29:33 +0100390 var BSC_ConnHdlrPars pars := {
Harald Weltef9abf8d2019-04-21 13:07:17 +0200391 sccp_addr_own := g_bssap[ran_idx].sccp_addr_own,
392 sccp_addr_peer := g_bssap[ran_idx].sccp_addr_peer,
Harald Welteedbab812018-03-18 16:02:25 +0100393 cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42)),
Harald Welte81b7f9d2018-01-24 19:06:24 +0100394 imei := f_gen_imei(imsi_suffix),
395 imsi := f_gen_imsi(imsi_suffix),
396 msisdn := f_gen_msisdn(imsi_suffix),
Harald Welte256571e2018-01-24 18:47:19 +0100397 tmsi := omit,
Harald Welte9de84792018-01-28 01:06:35 +0100398 cm1 := valueof(ts_CM1),
Harald Welte82600572018-01-21 20:54:08 +0100399 cm2 := valueof(ts_CM2_default),
Harald Welte16114282018-01-24 22:41:21 +0100400 cm3 := omit,
Harald Weltede371492018-01-27 23:44:41 +0100401 vec := omit,
Neels Hofmeyrb00c5b02021-06-23 20:05:25 +0200402 vec_keep := false,
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100403 net := net_pars,
Philipp Maieraeb29a82018-11-08 17:40:53 +0100404 send_early_cm := true,
405 ipa_ctrl_ip := mp_msc_ip,
406 ipa_ctrl_port := mp_msc_ctrl_port,
Philipp Maier9b690e42018-12-21 11:50:03 +0100407 ipa_ctrl_enable := true,
Philipp Maier57865482019-01-07 18:33:13 +0100408 mm_info := mp_mm_info,
Philipp Maierc09a1312019-04-09 16:05:26 +0200409 sgsap_enable := sgsap,
Harald Weltef9abf8d2019-04-21 13:07:17 +0200410 gsup_enable := gsup,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +0100411 gsup_sid := gsup_sid,
Harald Weltec1f937a2019-04-21 21:19:23 +0200412 ran_idx := ran_idx,
Harald Welte9b751a62019-04-14 17:39:29 +0200413 use_umts_aka := false,
Pau Espin Pedrola65697d2019-05-21 12:54:39 +0200414 ran_is_geran := ran_is_geran,
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200415 use_osmux := use_osmux,
Pau Espin Pedrol833174e2020-09-03 16:46:02 +0200416 use_ipv6 := false,
Oliver Smith44424db2023-08-22 13:54:09 +0200417 use_csd := false,
Pau Espin Pedrole979c402021-04-28 17:29:54 +0200418 verify_cell_id := verify_cell_id,
419 common_id_last_eutran_plmn := omit
Harald Weltea49e36e2018-01-21 19:29:33 +0100420 };
Harald Weltee13cfb22019-04-23 16:52:02 +0200421 if (not ran_is_geran) {
422 pars.use_umts_aka := true;
423 pars.net.expect_auth := true;
424 }
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100425 return pars;
426}
427
Neels Hofmeyre1a1b632021-07-28 18:05:43 +0200428function f_start_handler_create(BSC_ConnHdlrPars pars) runs on MTC_CT return BSC_ConnHdlr {
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100429 var BSC_ConnHdlr vc_conn;
Neels Hofmeyr60122f82021-07-28 17:59:38 +0200430 var charstring id := testcasename() & int2str(pars.ran_idx);
Harald Weltea49e36e2018-01-21 19:29:33 +0100431
432 vc_conn := BSC_ConnHdlr.create(id);
Neels Hofmeyr60122f82021-07-28 17:59:38 +0200433
Harald Weltea49e36e2018-01-21 19:29:33 +0100434 /* BSSMAP part / A interface */
Neels Hofmeyr60122f82021-07-28 17:59:38 +0200435 connect(vc_conn:BSSAP, g_bssap[pars.ran_idx].vc_RAN:CLIENT);
436 connect(vc_conn:BSSAP_PROC, g_bssap[pars.ran_idx].vc_RAN:PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100437 /* MNCC part */
438 connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
439 connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);
Harald Welte4aa970c2018-01-26 10:38:09 +0100440 /* MGCP part */
441 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
442 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100443 /* GSUP part */
Philipp Maierc09a1312019-04-09 16:05:26 +0200444 if (pars.gsup_enable == true) {
445 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
446 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
447 }
Harald Weltef640a012018-04-14 17:49:21 +0200448 /* SMPP part */
449 connect(vc_conn:SMPP, vc_SMPP:SMPP_CLIENT);
450 connect(vc_conn:SMPP_PROC, vc_SMPP:SMPP_PROC);
Harald Welte4263c522018-12-06 11:56:27 +0100451 /* SGs part */
Philipp Maier8e07a4a2019-02-14 18:23:28 +0100452 if (pars.sgsap_enable == true) {
Philipp Maier57865482019-01-07 18:33:13 +0100453 connect(vc_conn:SGsAP, vc_SGsAP:SGsAP_CLIENT);
454 connect(vc_conn:SGsAP_PROC, vc_SGsAP:SGsAP_PROC);
455 }
Neels Hofmeyre1a1b632021-07-28 18:05:43 +0200456 return vc_conn;
457}
Harald Weltea49e36e2018-01-21 19:29:33 +0100458
Neels Hofmeyre1a1b632021-07-28 18:05:43 +0200459function f_start_handler_run(BSC_ConnHdlr vc_conn, void_fn fn, BSC_ConnHdlrPars pars) runs on MTC_CT {
460 var charstring id := testcasename() & int2str(pars.ran_idx);
Harald Weltea10db902018-01-27 12:44:49 +0100461 /* We cannot use vc_conn.start(f_init_handler(fn, id, pars)); as we cannot have
462 * a stand-alone 'derefers()' call, see https://www.eclipse.org/forums/index.php/t/1091364/ */
Harald Weltea49e36e2018-01-21 19:29:33 +0100463 vc_conn.start(derefers(fn)(id, pars));
Neels Hofmeyre1a1b632021-07-28 18:05:43 +0200464}
465
466function f_start_handler_with_pars(void_fn fn, BSC_ConnHdlrPars pars) runs on MTC_CT return BSC_ConnHdlr {
467 var BSC_ConnHdlr vc_conn;
468 vc_conn := f_start_handler_create(pars);
469 f_start_handler_run(vc_conn, fn, pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100470 return vc_conn;
471}
472
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200473function f_start_handler(void_fn fn, integer imsi_suffix, integer ran_idx := 0, boolean ran_is_geran := true, boolean use_osmux := false,
474 boolean verify_cell_id := true)
Harald Welte9b751a62019-04-14 17:39:29 +0200475runs on MTC_CT return BSC_ConnHdlr {
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200476 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 +0100477}
478
Harald Weltea49e36e2018-01-21 19:29:33 +0100479private function f_tc_lu_imsi_noauth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100480 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100481 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100482}
Harald Weltea49e36e2018-01-21 19:29:33 +0100483testcase TC_lu_imsi_noauth_tmsi() runs on MTC_CT {
484 var BSC_ConnHdlr vc_conn;
485 f_init();
486
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100487 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi), 1);
Harald Weltea49e36e2018-01-21 19:29:33 +0100488 vc_conn.done;
489}
490
491private function f_tc_lu_imsi_noauth_notmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100492 pars.net.expect_tmsi := false;
Harald Weltea10db902018-01-27 12:44:49 +0100493 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100494 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100495}
Harald Weltea49e36e2018-01-21 19:29:33 +0100496testcase TC_lu_imsi_noauth_notmsi() runs on MTC_CT {
497 var BSC_ConnHdlr vc_conn;
498 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100499 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
Harald Weltea49e36e2018-01-21 19:29:33 +0100500
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100501 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi), 2);
Harald Weltea49e36e2018-01-21 19:29:33 +0100502 vc_conn.done;
503}
504
505/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
Harald Weltee13cfb22019-04-23 16:52:02 +0200506friend function f_tc_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100507 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100508 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
509
510 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +0200511 f_cl3_or_initial_ue(l3_lu);
Neels Hofmeyrd076c522019-11-28 01:00:52 +0100512 f_mm_common();
Harald Weltea49e36e2018-01-21 19:29:33 +0100513 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
514 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
515 alt {
Harald Welte5946b332018-03-18 23:32:21 +0100516 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej(int2oct(23,1)))) {
517 f_expect_clear();
518 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100519 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
520 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
Daniel Willmannafce8662018-07-06 23:11:32 +0200521 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100522 }
523 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100524}
525testcase TC_lu_imsi_reject() runs on MTC_CT {
526 var BSC_ConnHdlr vc_conn;
527 f_init();
528
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200529 vc_conn := f_start_handler(refers(f_tc_lu_imsi_reject), 3, verify_cell_id := false);
Harald Weltea49e36e2018-01-21 19:29:33 +0100530 vc_conn.done;
531}
532
Harald Weltee13cfb22019-04-23 16:52:02 +0200533
534
Harald Weltea49e36e2018-01-21 19:29:33 +0100535/* Do LU by IMSI, timeout on GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +0200536friend function f_tc_lu_imsi_timeout_gsup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100537 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100538 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
539
540 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +0200541 f_cl3_or_initial_ue(l3_lu);
Neels Hofmeyrd076c522019-11-28 01:00:52 +0100542 f_mm_common();
Harald Weltea49e36e2018-01-21 19:29:33 +0100543 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
544 /* Normally the HLR would need to respond here, but we decide to force a timeout here */
545 alt {
546 /* FIXME: Expect specific reject cause */
Harald Welte5946b332018-03-18 23:32:21 +0100547 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
548 f_expect_clear();
549 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100550 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
551 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
Daniel Willmannafce8662018-07-06 23:11:32 +0200552 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100553 }
554 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100555}
556testcase TC_lu_imsi_timeout_gsup() runs on MTC_CT {
557 var BSC_ConnHdlr vc_conn;
558 f_init();
559
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200560 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_gsup), 4, verify_cell_id := false);
Harald Weltea49e36e2018-01-21 19:29:33 +0100561 vc_conn.done;
562}
563
Harald Weltee13cfb22019-04-23 16:52:02 +0200564
Harald Welte7b1b2812018-01-22 21:23:06 +0100565private function f_tc_lu_imsi_auth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100566 pars.net.expect_auth := true;
Harald Weltea10db902018-01-27 12:44:49 +0100567 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100568 f_perform_lu();
Harald Welte7b1b2812018-01-22 21:23:06 +0100569}
570testcase TC_lu_imsi_auth_tmsi() runs on MTC_CT {
571 var BSC_ConnHdlr vc_conn;
572 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100573 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte7b1b2812018-01-22 21:23:06 +0100574
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100575 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi), 5);
Harald Welte7b1b2812018-01-22 21:23:06 +0100576 vc_conn.done;
577}
578
Harald Weltee13cfb22019-04-23 16:52:02 +0200579
580friend function f_tc_lu_imsi_auth3g_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Welte8a397ae2019-04-21 22:03:37 +0200581 pars.net.expect_auth := true;
582 pars.use_umts_aka := true;
583 f_init_handler(pars);
584 f_perform_lu();
585}
586testcase TC_lu_imsi_auth3g_tmsi() runs on MTC_CT {
587 var BSC_ConnHdlr vc_conn;
588 f_init();
589 f_vty_config(MSCVTY, "network", "authentication required");
590
591 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth3g_tmsi), 1005);
592 vc_conn.done;
593}
Harald Weltea49e36e2018-01-21 19:29:33 +0100594
Pau Espin Pedrold3d54a92019-12-17 17:02:54 +0100595/* Proceed with LU but never receive an TMSI Realloc from MS after LU Accept (OS#4337).
596 * TS 24.008 sec 4.3.1.5 states MSC should simply release all MM connections.
597 */
598friend function f_tc_lu_imsi_timeout_tmsi_realloc(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
599
600 f_init_handler(pars);
601
602 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
603 var PDU_DTAP_MT dtap_mt;
604
605 /* tell GSUP dispatcher to send this IMSI to us */
606 f_create_gsup_expect(hex2str(g_pars.imsi));
607
608 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
609 if (g_pars.ran_is_geran) {
610 f_bssap_compl_l3(l3_lu);
611 if (g_pars.send_early_cm) {
612 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
613 }
614 } else {
615 f_ranap_initial_ue(l3_lu);
616 }
617
618 f_mm_imei_early();
619 f_mm_common();
620 f_msc_lu_hlr();
621 f_mm_imei();
622
623 alt {
624 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) -> value dtap_mt {}
625 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
626 setverdict(fail, "Expected LU ACK, but received LU REJ");
627 mtc.stop;
628 }
629 }
630
631 /* currently (due to bug OS#4337), an extra LU reject is received before
632 terminating the connection. Enabling following line makes the test
633 pass: */
634 //f_expect_lu_reject('16'O); /* Cause: congestion */
635
636 /* f_expect_lu_reject() already waits for T"-1" (X1, 5 seconds), but give some
637 extra time to avoid race conditons... */
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200638 f_expect_clear(7.0, verify_vlr_cell_id := false);
Pau Espin Pedrold3d54a92019-12-17 17:02:54 +0100639
640 setverdict(pass);
641}
642testcase TC_lu_imsi_timeout_tmsi_realloc() runs on MTC_CT {
643 var BSC_ConnHdlr vc_conn;
644 f_init();
645
646 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_tmsi_realloc), 5);
647 vc_conn.done;
648}
649
Harald Weltee13cfb22019-04-23 16:52:02 +0200650
Harald Weltea49e36e2018-01-21 19:29:33 +0100651/* Send CM SERVICE REQ for IMSI that has never performed LU before */
Harald Weltee13cfb22019-04-23 16:52:02 +0200652friend function f_tc_cmserv_imsi_unknown(charstring id, BSC_ConnHdlrPars pars)
Harald Weltea49e36e2018-01-21 19:29:33 +0100653runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100654 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100655
656 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welteedbab812018-03-18 16:02:25 +0100657 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100658 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltea49e36e2018-01-21 19:29:33 +0100659
660 f_create_gsup_expect(hex2str(g_pars.imsi));
661
662 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200663 f_cl3_or_initial_ue(l3_info);
Harald Welteb7817992019-05-09 13:15:39 +0200664 f_mm_auth();
Harald Weltea49e36e2018-01-21 19:29:33 +0100665
666 timer T := 10.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100667 T.start;
668 alt {
Harald Weltea49e36e2018-01-21 19:29:33 +0100669 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
670 //[] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC)) { }
Daniel Willmannafce8662018-07-06 23:11:32 +0200671 [] BSSAP.receive {
672 setverdict(fail, "Received unexpected BSSAP");
673 mtc.stop;
674 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100675 [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
676 setverdict(fail, "Unexpected GSUP UL REQ");
Daniel Willmannafce8662018-07-06 23:11:32 +0200677 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100678 }
Daniel Willmannafce8662018-07-06 23:11:32 +0200679 [] T.timeout {
Neels Hofmeyrf1c3c212020-08-19 13:15:32 +0000680 setverdict(fail, "Timeout waiting for CM SERV REJ");
Daniel Willmannafce8662018-07-06 23:11:32 +0200681 mtc.stop;
682 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100683 }
684
Harald Welte1ddc7162018-01-27 14:25:46 +0100685 f_expect_clear();
Harald Weltef6dd64d2017-11-19 12:09:51 +0100686}
Harald Weltea49e36e2018-01-21 19:29:33 +0100687testcase TC_cmserv_imsi_unknown() runs on MTC_CT {
688 var BSC_ConnHdlr vc_conn;
689 f_init();
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200690 vc_conn := f_start_handler(refers(f_tc_cmserv_imsi_unknown), 6, verify_cell_id := false);
Harald Weltea49e36e2018-01-21 19:29:33 +0100691 vc_conn.done;
692}
693
Harald Weltee13cfb22019-04-23 16:52:02 +0200694
Neels Hofmeyr13737fb2020-08-19 13:16:14 +0000695/* Send CM SERVICE REQ for TMSI that has never performed LU before */
696friend function f_tc_cmserv_tmsi_unknown(charstring id, BSC_ConnHdlrPars pars)
697runs on BSC_ConnHdlr {
698 f_init_handler(pars);
699
700 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('57111111'O));
701 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42));
702 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
703
704 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
705 f_cl3_or_initial_ue(l3_info);
706 f_mm_auth();
707
708 timer T := 10.0;
709 T.start;
710 alt {
711 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
712 [] BSSAP.receive {
713 setverdict(fail, "Received unexpected BSSAP");
714 mtc.stop;
715 }
716 [] T.timeout {
717 setverdict(fail, "Timeout waiting for CM SERV REJ");
718 mtc.stop;
719 }
720 }
721
722 f_expect_clear();
723}
724testcase TC_cmserv_tmsi_unknown() runs on MTC_CT {
725 var BSC_ConnHdlr vc_conn;
726 f_init();
727 vc_conn := f_start_handler(refers(f_tc_cmserv_tmsi_unknown), 57, verify_cell_id := false);
728 vc_conn.done;
729}
730
Neels Hofmeyr14d0b132020-08-19 13:49:05 +0000731/* Send Paging Response for IMSI that has never performed LU before */
732friend function f_tc_paging_response_imsi_unknown(charstring id, BSC_ConnHdlrPars pars)
733runs on BSC_ConnHdlr {
734 f_init_handler(pars);
735
736 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
737 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42));
738 var PDU_ML3_MS_NW l3_info := valueof(ts_PAG_RESP(mi));
739
740 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
741 f_cl3_or_initial_ue(l3_info);
742
743 /* The Paging Response gets rejected by a direct Clear Command */
744 f_expect_clear();
745}
746testcase TC_paging_response_imsi_unknown() runs on MTC_CT {
747 var BSC_ConnHdlr vc_conn;
748 f_init();
749 vc_conn := f_start_handler(refers(f_tc_paging_response_imsi_unknown), 58, verify_cell_id := false);
750 vc_conn.done;
751}
752
753/* Send Paging Response for TMSI that has never performed LU before */
754friend function f_tc_paging_response_tmsi_unknown(charstring id, BSC_ConnHdlrPars pars)
755runs on BSC_ConnHdlr {
756 f_init_handler(pars);
757
758 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('59111111'O));
759 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42));
760 var PDU_ML3_MS_NW l3_info := valueof(ts_PAG_RESP(mi));
761
762 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
763 f_cl3_or_initial_ue(l3_info);
764
765 /* The Paging Response gets rejected by a direct Clear Command */
766 f_expect_clear();
767}
768testcase TC_paging_response_tmsi_unknown() runs on MTC_CT {
769 var BSC_ConnHdlr vc_conn;
770 f_init();
771 vc_conn := f_start_handler(refers(f_tc_paging_response_tmsi_unknown), 59, verify_cell_id := false);
772 vc_conn.done;
773}
774
Neels Hofmeyr13737fb2020-08-19 13:16:14 +0000775
Harald Weltee13cfb22019-04-23 16:52:02 +0200776friend function f_tc_lu_and_mo_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100777 f_init_handler(pars);
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +0200778 var CallParameters cpars := valueof(t_CallParams);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100779 f_perform_lu();
Harald Welteb71901a2018-01-26 19:16:05 +0100780 f_mo_call(cpars);
Harald Welte2bb825f2018-01-22 11:31:18 +0100781}
782testcase TC_lu_and_mo_call() runs on MTC_CT {
783 var BSC_ConnHdlr vc_conn;
784 f_init();
785
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100786 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_call), 7);
Harald Welte071ed732018-01-23 19:53:52 +0100787 vc_conn.done;
788}
Pau Espin Pedrol833174e2020-09-03 16:46:02 +0200789friend function f_tc_lu_and_mo_call_ipv6(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
790 f_init_handler(pars);
791 var CallParameters cpars := valueof(t_CallParams);
792 cpars.mgw_conn_1.mgw_rtp_ip := "::1";
793 cpars.mgw_conn_2.mgw_rtp_ip := "::2";
794 cpars.bss_rtp_ip := "::3";
795 f_perform_lu();
796 f_mo_call(cpars);
797}
798testcase TC_lu_and_mo_call_ipv6() runs on MTC_CT {
799 var BSC_ConnHdlr vc_conn;
800 f_init();
801
802 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_call_ipv6), 7);
803 vc_conn.done;
804}
Harald Welte071ed732018-01-23 19:53:52 +0100805
Pau Espin Pedrola42745c2020-01-10 18:03:28 +0100806/* Verify T(iar) triggers and releases the channel */
807friend function f_lu_and_mo_call_sccp_tiar_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
808 timer T_wait_iar := int2float(5 + 1); /* g_msc_sccp_timer_iar + Give extra time (+1 sec) */
809 f_init_handler(pars);
810 var CallParameters cpars := valueof(t_CallParams);
811 f_perform_lu();
812 f_mo_call_establish(cpars);
813
814 /* Expect the channel cleared upon T(iar) triggered: */
815 T_wait_iar.start;
816 alt {
817 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
818 T_wait_iar.stop
819 setverdict(pass);
820 }
Pau Espin Pedrola42745c2020-01-10 18:03:28 +0100821 [] T_wait_iar.timeout {
822 setverdict(fail, "Timeout waiting for T(iar) triggered SCCP RSLD");
823 mtc.stop;
824 }
825 }
Harald Welte4a3fa712020-08-19 08:57:33 +0200826 /* DLCX for both directions; if we don't do this, we might receive either of the two during
827 * shutdown causing race conditions */
828 MGCP.receive(tr_DLCX(?));
829 MGCP.receive(tr_DLCX(?));
Pau Espin Pedrola42745c2020-01-10 18:03:28 +0100830
831 setverdict(pass);
832}
833testcase TC_lu_and_mo_call_sccp_tiar_timeout() runs on MTC_CT {
834 var BSC_ConnHdlr vc_conn;
835
836 /* Set T(iar) in MSC low enough that it will trigger before other side
837 has time to keep alive with a T(ias). Keep recommended ratio of
838 T(iar) >= T(ias)*2 */
839 g_msc_sccp_timer_ias := 2;
840 g_msc_sccp_timer_iar := 5;
841
842 f_init();
843
844 vc_conn := f_start_handler(refers(f_lu_and_mo_call_sccp_tiar_timeout), 89);
845 vc_conn.done;
846}
847
Harald Weltee13cfb22019-04-23 16:52:02 +0200848
Harald Welte071ed732018-01-23 19:53:52 +0100849/* Test LU (with authentication enabled), where HLR times out sending SAI response */
Harald Weltee13cfb22019-04-23 16:52:02 +0200850friend function f_tc_lu_auth_sai_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100851 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100852
853 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
854 var PDU_DTAP_MT dtap_mt;
855
856 /* tell GSUP dispatcher to send this IMSI to us */
857 f_create_gsup_expect(hex2str(g_pars.imsi));
858
859 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200860 f_cl3_or_initial_ue(l3_lu);
Harald Welte071ed732018-01-23 19:53:52 +0100861
862 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +0200863 if (pars.ran_is_geran) {
864 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
865 }
Harald Welte071ed732018-01-23 19:53:52 +0100866
867 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
868 /* The HLR would normally return an auth vector here, but we fail to do so. */
869
870 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100871 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100872}
873testcase TC_lu_auth_sai_timeout() runs on MTC_CT {
874 var BSC_ConnHdlr vc_conn;
875 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100876 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100877
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200878 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_timeout), 8, verify_cell_id := false);
Harald Welte071ed732018-01-23 19:53:52 +0100879 vc_conn.done;
880}
881
Harald Weltee13cfb22019-04-23 16:52:02 +0200882
Harald Welte071ed732018-01-23 19:53:52 +0100883/* Test LU (with authentication enabled), where HLR rejects sending SAI error */
Harald Weltee13cfb22019-04-23 16:52:02 +0200884friend function f_tc_lu_auth_sai_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100885 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100886
887 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
888 var PDU_DTAP_MT dtap_mt;
889
890 /* tell GSUP dispatcher to send this IMSI to us */
891 f_create_gsup_expect(hex2str(g_pars.imsi));
892
893 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200894 f_cl3_or_initial_ue(l3_lu);
Harald Welte071ed732018-01-23 19:53:52 +0100895
896 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +0200897 if (pars.ran_is_geran) {
898 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
899 }
Harald Welte071ed732018-01-23 19:53:52 +0100900
901 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
902 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 13));
903
904 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100905 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100906}
907testcase TC_lu_auth_sai_err() runs on MTC_CT {
908 var BSC_ConnHdlr vc_conn;
909 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100910 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100911
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200912 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_err), 9, verify_cell_id := false);
Harald Welte2bb825f2018-01-22 11:31:18 +0100913 vc_conn.done;
914}
Harald Weltea49e36e2018-01-21 19:29:33 +0100915
Harald Weltee13cfb22019-04-23 16:52:02 +0200916
Harald Weltebc881782018-01-23 20:09:15 +0100917/* Test LU but BSC will send a clear request in the middle */
918private function f_tc_lu_clear_request(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100919 f_init_handler(pars);
Harald Weltebc881782018-01-23 20:09:15 +0100920
921 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
922 var PDU_DTAP_MT dtap_mt;
923
924 /* tell GSUP dispatcher to send this IMSI to us */
925 f_create_gsup_expect(hex2str(g_pars.imsi));
926
927 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200928 f_cl3_or_initial_ue(l3_lu);
Harald Welte79f1e452020-08-18 22:55:02 +0200929 f_expect_common_id();
Harald Weltebc881782018-01-23 20:09:15 +0100930
931 /* Send Early Classmark, just for the fun of it */
932 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
933
934 f_sleep(1.0);
935 /* send clear request in the middle of the LU */
936 BSSAP.send(ts_BSSMAP_ClearRequest(0));
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200937 alt {
938 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { repeat; }
939 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {}
940 }
Harald Weltebc881782018-01-23 20:09:15 +0100941 BSSAP.send(ts_BSSMAP_ClearComplete);
Harald Welte89a32492018-01-27 19:07:28 +0100942 alt {
943 /* See https://osmocom.org/issues/2862 */
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200944 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
945 setverdict(fail, "Got a second Clear Command, only one expected");
Daniel Willmannafce8662018-07-06 23:11:32 +0200946 mtc.stop;
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200947 repeat;
948 }
Harald Welte6811d102019-04-14 22:23:14 +0200949 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte89a32492018-01-27 19:07:28 +0100950 }
Harald Weltebc881782018-01-23 20:09:15 +0100951 setverdict(pass);
952}
953testcase TC_lu_clear_request() runs on MTC_CT {
954 var BSC_ConnHdlr vc_conn;
955 f_init();
956
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100957 vc_conn := f_start_handler(refers(f_tc_lu_clear_request), 10);
Harald Weltebc881782018-01-23 20:09:15 +0100958 vc_conn.done;
959}
960
Vadim Yanitskiy109e7552021-02-05 05:36:02 +0100961/* Test reaction on Clear Request during a MO Call */
962friend function f_TC_mo_mt_call_clear_request(charstring id, BSC_ConnHdlrPars pars)
963runs on BSC_ConnHdlr {
964 var CallParameters cpars := valueof(t_CallParams);
965 var MNCC_PDU mncc_pdu;
966 timer T := 2.0;
967
968 f_init_handler(pars);
969
970 f_perform_lu();
971
972 /* HACK: reducing code duplication ('66'H - MO, '68'H - MT) */
973 if (pars.imsi == '262420002532766'H)
974 { f_mo_call_establish(cpars); }
975 else
976 { f_mt_call_establish(cpars); }
977
978 /* Hold the line for a while... */
979 f_sleep(2.0);
980
981 /* BSC sends BSSMAP Clear Request (e.g. due to RR failure) */
982 BSSAP.send(ts_BSSMAP_ClearRequest(1));
983
984 /* Expect (optional) CC RELEASE and Clear Command */
985 var default ccrel := activate(as_optional_cc_rel(cpars));
986 f_expect_clear();
987 deactivate(ccrel);
988
989 /* Expect RELease indication on the MNCC socket */
990 T.start;
991 alt {
992 [] MNCC.receive(tr_MNCC_REL_ind(cpars.mncc_callref)) -> value mncc_pdu {
993 log("Rx MNCC REL.ind, cause := ", mncc_pdu.u.signal.cause);
994 setverdict(pass);
995 }
996 [] MNCC.receive(MNCC_PDU:?) -> value mncc_pdu {
997 setverdict(fail, "Rx unexpected MNCC PDU: ", mncc_pdu);
998 }
999 [] T.timeout {
1000 setverdict(fail, "Timeout waiting for MNCC REL.ind");
1001 }
1002 }
1003}
1004testcase TC_mo_call_clear_request() runs on MTC_CT {
1005 var BSC_ConnHdlr vc_conn;
1006
1007 f_init();
1008
1009 vc_conn := f_start_handler(refers(f_TC_mo_mt_call_clear_request), 2532766); // '66'H - MO
1010 vc_conn.done;
1011}
1012testcase TC_mt_call_clear_request() runs on MTC_CT {
1013 var BSC_ConnHdlr vc_conn;
1014
1015 f_init();
1016
1017 vc_conn := f_start_handler(refers(f_TC_mo_mt_call_clear_request), 2532768); // '68'H - MT
1018 vc_conn.done;
1019}
1020
Harald Welte66af9e62018-01-24 17:28:21 +01001021/* Test LU but BSC will send a clear request in the middle */
Harald Weltee13cfb22019-04-23 16:52:02 +02001022friend function f_tc_lu_disconnect(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001023 f_init_handler(pars);
Harald Welte66af9e62018-01-24 17:28:21 +01001024
1025 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
1026 var PDU_DTAP_MT dtap_mt;
1027
1028 /* tell GSUP dispatcher to send this IMSI to us */
1029 f_create_gsup_expect(hex2str(g_pars.imsi));
1030
1031 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001032 f_cl3_or_initial_ue(l3_lu);
Harald Welte66af9e62018-01-24 17:28:21 +01001033
1034 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +02001035 if (pars.ran_is_geran) {
1036 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1037 }
Harald Welte66af9e62018-01-24 17:28:21 +01001038
1039 f_sleep(1.0);
1040 /* send clear request in the middle of the LU */
Harald Welte6811d102019-04-14 22:23:14 +02001041 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Harald Welte66af9e62018-01-24 17:28:21 +01001042 setverdict(pass);
Neels Hofmeyrbb825c92019-03-06 15:35:50 +01001043 f_sleep(1.0);
Harald Welte66af9e62018-01-24 17:28:21 +01001044}
1045testcase TC_lu_disconnect() runs on MTC_CT {
1046 var BSC_ConnHdlr vc_conn;
1047 f_init();
1048
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001049 vc_conn := f_start_handler(refers(f_tc_lu_disconnect), 11);
Harald Welte66af9e62018-01-24 17:28:21 +01001050 vc_conn.done;
1051}
1052
Harald Welteba7b6d92018-01-23 21:32:34 +01001053/* Test LU but with illegal mobile identity type = IMEI */
Harald Weltee13cfb22019-04-23 16:52:02 +02001054friend function f_tc_lu_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001055 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +01001056
Harald Welte256571e2018-01-24 18:47:19 +01001057 var PDU_ML3_MS_NW l3_lu := f_build_lu_imei(g_pars.imei)
Harald Welteba7b6d92018-01-23 21:32:34 +01001058 var PDU_DTAP_MT dtap_mt;
1059
1060 /* tell GSUP dispatcher to send this IMSI to us */
1061 f_create_gsup_expect(hex2str(g_pars.imsi));
1062
1063 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001064 f_cl3_or_initial_ue(l3_lu);
Harald Welteba7b6d92018-01-23 21:32:34 +01001065
1066 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +02001067 if (pars.ran_is_geran) {
1068 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1069 }
Harald Welteba7b6d92018-01-23 21:32:34 +01001070 /* wait for LU reject, ignore any ID REQ */
1071 alt {
1072 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
1073 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req)) { repeat; }
1074 }
1075 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +01001076 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +01001077}
1078testcase TC_lu_by_imei() runs on MTC_CT {
1079 var BSC_ConnHdlr vc_conn;
1080 f_init();
1081
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001082 vc_conn := f_start_handler(refers(f_tc_lu_by_imei), 12, verify_cell_id := false);
Harald Welteba7b6d92018-01-23 21:32:34 +01001083 vc_conn.done;
1084}
1085
Harald Weltee13cfb22019-04-23 16:52:02 +02001086
Harald Welteba7b6d92018-01-23 21:32:34 +01001087/* Test LU by TMSI with unknown TMSI, expect (and answer) ID REQ. */
1088private function f_tc_lu_tmsi_noauth_unknown(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Stefan Sperling04fc4bc2018-06-25 17:44:57 +02001089 /* We piggyback a test for an MSC crash on overlong IMSI (OS#2864) onto this test. */
1090 var hexstring overlong_imsi := '012345789ABCDEF0123456789ABCDEF'H;
Harald Weltea10db902018-01-27 12:44:49 +01001091 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +01001092
1093 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('01020304'O); /* FIXME: Random */
1094 var PDU_DTAP_MT dtap_mt;
1095
1096 /* tell GSUP dispatcher to send this IMSI to us */
1097 f_create_gsup_expect(hex2str(g_pars.imsi));
1098
1099 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001100 f_cl3_or_initial_ue(l3_lu);
Harald Welteba7b6d92018-01-23 21:32:34 +01001101
1102 /* Send Early Classmark, just for the fun of it */
1103 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1104
1105 /* Wait for + respond to ID REQ (IMSI) */
Oliver Smith32898452019-07-09 12:32:35 +02001106 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req(CM_ID_TYPE_IMSI)));
Stefan Sperling04fc4bc2018-06-25 17:44:57 +02001107 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 +01001108 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
Harald Welte79f1e452020-08-18 22:55:02 +02001109 f_expect_common_id();
Harald Welteba7b6d92018-01-23 21:32:34 +01001110
1111 /* Expect MSC to do UpdateLocation to HLR; respond to it */
1112 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1113 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
1114 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
1115 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1116
1117 alt {
Harald Welte7ec4fa82018-01-27 10:57:40 +01001118 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
1119 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
1120 }
Harald Welteba7b6d92018-01-23 21:32:34 +01001121 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1122 setverdict(fail, "Expected LU ACK, but received REJ");
Daniel Willmannafce8662018-07-06 23:11:32 +02001123 mtc.stop;
Harald Welteba7b6d92018-01-23 21:32:34 +01001124 }
1125 }
1126
Philipp Maier9b690e42018-12-21 11:50:03 +01001127 /* Wait for MM-Information (if enabled) */
1128 f_expect_mm_info();
1129
Harald Welteba7b6d92018-01-23 21:32:34 +01001130 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +01001131 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +01001132}
1133testcase TC_lu_by_tmsi_noauth_unknown() runs on MTC_CT {
1134 var BSC_ConnHdlr vc_conn;
1135 f_init();
1136
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001137 vc_conn := f_start_handler(refers(f_tc_lu_tmsi_noauth_unknown), 13);
Harald Welteba7b6d92018-01-23 21:32:34 +01001138 vc_conn.done;
1139}
1140
Neels Hofmeyrfc06c732020-08-19 12:52:28 +00001141/* Test LU by unknown TMSI, while the IMSI is already attached: osmo-msc should switch to the attached vlr_subscr. */
1142private function f_tc_attached_imsi_lu_unknown_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1143 f_init_handler(pars);
1144
1145 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('56111111'O);
1146 var PDU_DTAP_MT dtap_mt;
1147
1148 /* tell GSUP dispatcher to send this IMSI to us */
1149 f_create_gsup_expect(hex2str(g_pars.imsi));
1150
1151 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
1152 f_cl3_or_initial_ue(l3_lu);
1153
1154 /* Send Early Classmark, just for the fun of it */
1155 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1156
1157 /* Wait for + respond to ID REQ (IMSI) */
1158 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req(CM_ID_TYPE_IMSI)));
1159 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
1160 f_expect_common_id();
1161
1162 /* Expect MSC to do UpdateLocation to HLR; respond to it */
1163 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1164 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
1165 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
1166 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1167
1168 alt {
1169 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
1170 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
1171 }
1172 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1173 setverdict(fail, "Expected LU ACK, but received REJ");
1174 mtc.stop;
1175 }
1176 }
1177
1178 /* Wait for MM-Information (if enabled) */
1179 f_expect_mm_info();
1180
1181 /* wait for normal teardown */
Eric Wild85cc1612022-03-30 01:44:29 +02001182 f_expect_clear(verify_vlr_cell_id := false);
Neels Hofmeyrfc06c732020-08-19 12:52:28 +00001183
1184 /* Now the same IMSI is still attached in the VLR, and a LU with an unknown TMSI reveals the same IMSI only
1185 * later during ID Response. osmo-msc first creates a new vlr_subscr for the unknown TMSI, and as soon as the
1186 * IMSI becomes known, must notice that this IMSI is still regarded as attached, and must not create evil twins.
1187 */
1188
1189 /* (since the TMSI Reallocation happened, we could do this with exactly the same TMSI as above, but for test
1190 * readability just use a different one.) */
1191 l3_lu := f_build_lu_tmsi('56222222'O);
1192 f_cl3_or_initial_ue(l3_lu);
1193
1194 /* Wait for + respond to ID REQ (IMSI) */
1195 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req(CM_ID_TYPE_IMSI)));
1196 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
1197 f_expect_common_id();
1198
1199 /* Expect MSC to do UpdateLocation to HLR; respond to it */
1200 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1201 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
1202 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
1203 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1204
1205 alt {
1206 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
1207 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
1208 }
1209 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1210 setverdict(fail, "Expected LU ACK, but received REJ");
1211 mtc.stop;
1212 }
1213 }
1214
1215 /* Wait for MM-Information (if enabled) */
1216 f_expect_mm_info();
1217
1218 /* wait for normal teardown */
Eric Wild85cc1612022-03-30 01:44:29 +02001219 f_expect_clear(verify_vlr_cell_id := false);
Neels Hofmeyrfc06c732020-08-19 12:52:28 +00001220}
1221testcase TC_attached_imsi_lu_unknown_tmsi() runs on MTC_CT {
1222 var BSC_ConnHdlr vc_conn;
1223 f_init();
1224
1225 vc_conn := f_start_handler(refers(f_tc_attached_imsi_lu_unknown_tmsi), 56);
1226 vc_conn.done;
1227}
1228
Harald Welte4d15fa72020-08-19 08:58:28 +02001229friend function f_imsi_detach_by_imsi() runs on BSC_ConnHdlr {
Harald Welte45164da2018-01-24 12:51:27 +01001230 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1231
1232 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001233 f_cl3_or_initial_ue(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
Harald Welte45164da2018-01-24 12:51:27 +01001234
1235 /* Send Early Classmark, just for the fun of it? */
Harald Welte4d15fa72020-08-19 08:58:28 +02001236 if (g_pars.ran_is_geran) {
Harald Weltee13cfb22019-04-23 16:52:02 +02001237 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1238 }
Harald Welte45164da2018-01-24 12:51:27 +01001239
1240 /* wait for normal teardown */
Harald Welte4d15fa72020-08-19 08:58:28 +02001241 f_expect_clear(verify_vlr_cell_id := false);
1242}
1243
1244
1245/* Test IMSI DETACH (MI=IMSI) */
1246friend function f_tc_imsi_detach_by_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1247 f_init_handler(pars);
1248
1249 f_imsi_detach_by_imsi();
Harald Welte45164da2018-01-24 12:51:27 +01001250}
1251testcase TC_imsi_detach_by_imsi() runs on MTC_CT {
1252 var BSC_ConnHdlr vc_conn;
1253 f_init();
1254
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001255 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imsi), 14, verify_cell_id := false);
Harald Welte45164da2018-01-24 12:51:27 +01001256 vc_conn.done;
1257}
1258
Harald Weltee13cfb22019-04-23 16:52:02 +02001259
Harald Welte45164da2018-01-24 12:51:27 +01001260/* Test IMSI DETACH (MI=TMSI) */
Harald Weltee13cfb22019-04-23 16:52:02 +02001261friend function f_tc_imsi_detach_by_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001262 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001263
1264 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('01020304'O));
1265
1266 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001267 f_cl3_or_initial_ue(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
Harald Welte45164da2018-01-24 12:51:27 +01001268
1269 /* Send Early Classmark, just for the fun of it? */
Harald Weltee13cfb22019-04-23 16:52:02 +02001270 if (pars.ran_is_geran) {
1271 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1272 }
Harald Welte45164da2018-01-24 12:51:27 +01001273
1274 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +01001275 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001276}
1277testcase TC_imsi_detach_by_tmsi() runs on MTC_CT {
1278 var BSC_ConnHdlr vc_conn;
1279 f_init();
1280
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001281 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_tmsi), 15, verify_cell_id := false);
Harald Welte45164da2018-01-24 12:51:27 +01001282 vc_conn.done;
1283}
1284
Harald Weltee13cfb22019-04-23 16:52:02 +02001285
Harald Welte45164da2018-01-24 12:51:27 +01001286/* Test IMSI DETACH (MI=IMEI), which is illegal */
Harald Weltee13cfb22019-04-23 16:52:02 +02001287friend function f_tc_imsi_detach_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001288 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001289
Harald Welte256571e2018-01-24 18:47:19 +01001290 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte45164da2018-01-24 12:51:27 +01001291
1292 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001293 f_cl3_or_initial_ue(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
Harald Welte45164da2018-01-24 12:51:27 +01001294
1295 /* Send Early Classmark, just for the fun of it? */
Harald Weltee13cfb22019-04-23 16:52:02 +02001296 if (pars.ran_is_geran) {
1297 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1298 }
Harald Welte45164da2018-01-24 12:51:27 +01001299
1300 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +01001301 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001302}
1303testcase TC_imsi_detach_by_imei() runs on MTC_CT {
1304 var BSC_ConnHdlr vc_conn;
1305 f_init();
1306
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001307 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imei), 16, verify_cell_id := false);
Harald Welte45164da2018-01-24 12:51:27 +01001308 vc_conn.done;
1309}
1310
1311
1312/* helper function for an emergency call. caller passes in mobile identity to use */
1313private function f_emerg_call(MobileIdentityLV mi) runs on BSC_ConnHdlr {
Harald Welte0bef21e2018-02-10 09:48:23 +01001314 var CallParameters cpars := valueof(t_CallParams('112'H, 0));
1315 cpars.emergency := true;
Harald Welte45164da2018-01-24 12:51:27 +01001316
Harald Welte0bef21e2018-02-10 09:48:23 +01001317 f_mo_call(cpars);
Harald Welte45164da2018-01-24 12:51:27 +01001318}
1319
1320/* establish an emergency call by IMEI, no SIM inserted (and hence no IMSI) */
Harald Weltee13cfb22019-04-23 16:52:02 +02001321friend function f_tc_emerg_call_imei_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001322 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001323
Harald Welte256571e2018-01-24 18:47:19 +01001324 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001325 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001326 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +01001327 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ('05'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +01001328 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001329}
1330testcase TC_emerg_call_imei_reject() runs on MTC_CT {
1331 var BSC_ConnHdlr vc_conn;
1332 f_init();
1333
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001334 vc_conn := f_start_handler(refers(f_tc_emerg_call_imei_reject), 17, verify_cell_id := false);
Harald Welte45164da2018-01-24 12:51:27 +01001335 vc_conn.done;
1336}
1337
Harald Weltee13cfb22019-04-23 16:52:02 +02001338
Harald Welted5b91402018-01-24 18:48:16 +01001339/* establish an emergency call by IMSI, SIM inserted (and hence IMSI) */
Harald Weltee13cfb22019-04-23 16:52:02 +02001340friend function f_tc_emerg_call_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001341 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001342 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001343 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001344 /* Then issue emergency call identified by IMSI */
1345 f_emerg_call(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
1346}
1347testcase TC_emerg_call_imsi() runs on MTC_CT {
1348 var BSC_ConnHdlr vc_conn;
1349 f_init();
1350
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001351 vc_conn := f_start_handler(refers(f_tc_emerg_call_imsi), 18);
Harald Welte45164da2018-01-24 12:51:27 +01001352 vc_conn.done;
1353}
1354
Harald Weltee13cfb22019-04-23 16:52:02 +02001355
Harald Welte45164da2018-01-24 12:51:27 +01001356/* CM Service Request for VGCS -> reject */
1357private function f_tc_cm_serv_req_vgcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001358 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001359
1360 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001361 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001362
1363 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001364 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VGCS, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001365 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +01001366 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001367 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001368}
1369testcase TC_cm_serv_req_vgcs_reject() runs on MTC_CT {
1370 var BSC_ConnHdlr vc_conn;
1371 f_init();
1372
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001373 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vgcs_reject), 19);
Harald Welte45164da2018-01-24 12:51:27 +01001374 vc_conn.done;
1375}
1376
1377/* CM Service Request for VBS -> reject */
1378private function f_tc_cm_serv_req_vbs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001379 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001380
1381 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001382 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001383
1384 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001385 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VBS, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001386 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +01001387 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001388 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001389}
1390testcase TC_cm_serv_req_vbs_reject() runs on MTC_CT {
1391 var BSC_ConnHdlr vc_conn;
1392 f_init();
1393
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001394 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vbs_reject), 20);
Harald Welte45164da2018-01-24 12:51:27 +01001395 vc_conn.done;
1396}
1397
1398/* CM Service Request for LCS -> reject */
1399private function f_tc_cm_serv_req_lcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001400 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001401
1402 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001403 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001404
1405 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001406 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_LCS, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001407 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +01001408 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001409 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001410}
1411testcase TC_cm_serv_req_lcs_reject() runs on MTC_CT {
1412 var BSC_ConnHdlr vc_conn;
1413 f_init();
1414
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001415 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_lcs_reject), 21);
Harald Welte45164da2018-01-24 12:51:27 +01001416 vc_conn.done;
1417}
1418
Harald Welte0195ab12018-01-24 21:50:20 +01001419/* CM Re-Establishment Request */
1420private function f_tc_cm_reest_req_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001421 f_init_handler(pars);
Harald Welte0195ab12018-01-24 21:50:20 +01001422
1423 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001424 f_perform_lu();
Harald Welte0195ab12018-01-24 21:50:20 +01001425
1426 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1427 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REEST_REQ(0, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001428 f_cl3_or_initial_ue(l3_info);
Neels Hofmeyr49bbb512021-07-29 22:51:08 +02001429 /* Older osmo-msc returns: GSM48_REJECT_SRV_OPT_NOT_SUPPORTED = 32,
1430 * newer osmo-msc with CM Re-Establish support returns: GSM48_REJECT_CALL_CAN_NOT_BE_IDENTIFIED = 38 */
1431 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ( (int2oct(32,1), int2oct(38,1)) )));
Harald Welte1ddc7162018-01-27 14:25:46 +01001432 f_expect_clear();
Harald Welte0195ab12018-01-24 21:50:20 +01001433}
1434testcase TC_cm_reest_req_reject() runs on MTC_CT {
1435 var BSC_ConnHdlr vc_conn;
1436 f_init();
Harald Welte0195ab12018-01-24 21:50:20 +01001437
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001438 vc_conn := f_start_handler(refers(f_tc_cm_reest_req_reject), 22);
Harald Welte0195ab12018-01-24 21:50:20 +01001439 vc_conn.done;
1440}
1441
Harald Weltec638f4d2018-01-24 22:00:36 +01001442/* Test LU (with authentication enabled), with wrong response from MS */
1443private function f_tc_lu_auth_2G_fail(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001444 f_init_handler(pars);
Harald Weltec638f4d2018-01-24 22:00:36 +01001445
1446 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
1447
1448 /* tell GSUP dispatcher to send this IMSI to us */
1449 f_create_gsup_expect(hex2str(g_pars.imsi));
1450
1451 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001452 f_cl3_or_initial_ue(l3_lu);
Harald Weltec638f4d2018-01-24 22:00:36 +01001453
1454 /* Send Early Classmark, just for the fun of it */
1455 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1456
1457 var AuthVector vec := f_gen_auth_vec_2g();
1458 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(vec.rand, vec.sres, vec.kc));
1459 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
1460 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
1461
1462 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(vec.rand)));
1463 /* Send back wrong auth response */
1464 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G('00000000'O)));
1465
1466 /* Expect GSUP AUTH FAIL REP to HLR */
1467 GSUP.receive(tr_GSUP_AUTH_FAIL_IND(g_pars.imsi));
1468
1469 /* Expect LU REJECT with Cause == Illegal MS */
1470 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej('03'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +01001471 f_expect_clear();
Harald Weltec638f4d2018-01-24 22:00:36 +01001472}
1473testcase TC_lu_auth_2G_fail() runs on MTC_CT {
1474 var BSC_ConnHdlr vc_conn;
1475 f_init();
1476 f_vty_config(MSCVTY, "network", "authentication required");
Harald Weltec638f4d2018-01-24 22:00:36 +01001477
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001478 vc_conn := f_start_handler(refers(f_tc_lu_auth_2G_fail), 23, verify_cell_id := false);
Harald Weltec638f4d2018-01-24 22:00:36 +01001479 vc_conn.done;
1480}
1481
Harald Weltede371492018-01-27 23:44:41 +01001482/* A5/1 + A5/3 permitted on network side, and MS capable to do it */
Harald Welte16114282018-01-24 22:41:21 +01001483private 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 +01001484 pars.net.expect_auth := true;
1485 pars.net.expect_ciph := true;
Harald Weltea10db902018-01-27 12:44:49 +01001486 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001487 f_perform_lu();
Harald Welte16114282018-01-24 22:41:21 +01001488}
1489testcase TC_lu_imsi_auth_tmsi_encr_13_13() runs on MTC_CT {
1490 var BSC_ConnHdlr vc_conn;
1491 f_init();
1492 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte16114282018-01-24 22:41:21 +01001493 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1494
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001495 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_13), 24);
Harald Welte16114282018-01-24 22:41:21 +01001496 vc_conn.done;
1497}
1498
Harald Welte1af6ea82018-01-25 18:33:15 +01001499/* Test Complete L3 without payload */
1500private function f_tc_cl3_no_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001501 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001502
1503 /* Send Complete L3 Info with empty L3 frame */
1504 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1505 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, ''O))));
1506
Harald Weltef466eb42018-01-27 14:26:54 +01001507 timer T := 5.0;
1508 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001509 alt {
Harald Welte6811d102019-04-14 22:23:14 +02001510 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte1af6ea82018-01-25 18:33:15 +01001511 /* Expect LU REJECT with Cause == Illegal MS */
Harald Weltebdb3c452018-03-18 22:43:06 +01001512 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
Harald Welte6811d102019-04-14 22:23:14 +02001513 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001514 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001515 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001516 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Daniel Willmannafce8662018-07-06 23:11:32 +02001517 mtc.stop;
Harald Weltef466eb42018-01-27 14:26:54 +01001518 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001519 }
1520 setverdict(pass);
1521}
1522testcase TC_cl3_no_payload() runs on MTC_CT {
1523 var BSC_ConnHdlr vc_conn;
1524 f_init();
1525
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001526 vc_conn := f_start_handler(refers(f_tc_cl3_no_payload), 25);
Harald Welte1af6ea82018-01-25 18:33:15 +01001527 vc_conn.done;
1528}
1529
1530/* Test Complete L3 with random payload */
1531private function f_tc_cl3_rnd_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001532 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001533
Daniel Willmannaa14a382018-07-26 08:29:45 +02001534 /* length is limited by PDU_BSSAP length field which includes some
1535 * other fields beside l3info payload. So payl can only be 240 bytes
1536 * Since rnd() returns values < 1 multiply with 241
1537 */
1538 var integer len := float2int(rnd() * 241.0);
Harald Welte1af6ea82018-01-25 18:33:15 +01001539 var octetstring payl := f_rnd_octstring(len);
1540
1541 /* Send Complete L3 Info with empty L3 frame */
1542 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1543 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, payl))));
1544
Harald Weltef466eb42018-01-27 14:26:54 +01001545 timer T := 5.0;
1546 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001547 alt {
1548 /* Immediate disconnect */
Harald Welte6811d102019-04-14 22:23:14 +02001549 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte1af6ea82018-01-25 18:33:15 +01001550 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
Harald Welte6811d102019-04-14 22:23:14 +02001551 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001552 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001553 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001554 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Daniel Willmannafce8662018-07-06 23:11:32 +02001555 mtc.stop;
Harald Weltef466eb42018-01-27 14:26:54 +01001556 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001557 }
1558 setverdict(pass);
1559}
1560testcase TC_cl3_rnd_payload() runs on MTC_CT {
1561 var BSC_ConnHdlr vc_conn;
1562 f_init();
1563
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001564 vc_conn := f_start_handler(refers(f_tc_cl3_rnd_payload), 26);
Harald Welte1af6ea82018-01-25 18:33:15 +01001565 vc_conn.done;
1566}
1567
Harald Welte116e4332018-01-26 22:17:48 +01001568/* Test Complete L3 with random payload */
Harald Weltee13cfb22019-04-23 16:52:02 +02001569friend function f_tc_establish_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001570 f_init_handler(pars);
Harald Welte116e4332018-01-26 22:17:48 +01001571
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001572 f_perform_lu();
Harald Welte116e4332018-01-26 22:17:48 +01001573
Harald Welteb9e86fa2018-04-09 18:18:31 +02001574 f_establish_fully();
Daniel Willmann898a7e02018-05-17 12:16:16 +02001575 f_expect_clear(10.0);
Harald Welte116e4332018-01-26 22:17:48 +01001576}
1577testcase TC_establish_and_nothing() runs on MTC_CT {
1578 var BSC_ConnHdlr vc_conn;
1579 f_init();
1580
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001581 vc_conn := f_start_handler(refers(f_tc_establish_and_nothing), 27);
Harald Welte116e4332018-01-26 22:17:48 +01001582 vc_conn.done;
1583}
1584
Harald Weltee13cfb22019-04-23 16:52:02 +02001585
Harald Welte12510c52018-01-26 22:26:24 +01001586/* Test MO Call SETUP with no response from MNCC */
Harald Weltee13cfb22019-04-23 16:52:02 +02001587friend function f_tc_mo_setup_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Philipp Maier109e6aa2018-10-17 10:53:32 +02001588 f_init_handler(pars, 190.0);
Harald Weltea10db902018-01-27 12:44:49 +01001589
Harald Welte12510c52018-01-26 22:26:24 +01001590 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001591 cpars.mgw_conn_2.resp := 0;
1592 cpars.stop_after_cc_setup := true;
1593
1594 f_vty_config(MSCVTY, "msc", "mncc guard-timeout 20");
Harald Welte12510c52018-01-26 22:26:24 +01001595
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001596 f_perform_lu();
Harald Welte12510c52018-01-26 22:26:24 +01001597
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001598 f_mo_call_establish(cpars);
Harald Welte12510c52018-01-26 22:26:24 +01001599
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001600 var default ccrel := activate(as_optional_cc_rel(cpars));
1601
Philipp Maier109e6aa2018-10-17 10:53:32 +02001602 f_expect_clear(185.0);
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001603
1604 deactivate(ccrel);
1605
1606 f_sleep(1.0);
Harald Welte12510c52018-01-26 22:26:24 +01001607}
1608testcase TC_mo_setup_and_nothing() runs on MTC_CT {
1609 var BSC_ConnHdlr vc_conn;
1610 f_init();
1611
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001612 vc_conn := f_start_handler(refers(f_tc_mo_setup_and_nothing), 28);
Harald Welte12510c52018-01-26 22:26:24 +01001613 vc_conn.done;
1614}
1615
Harald Weltee13cfb22019-04-23 16:52:02 +02001616
Harald Welte3ab88002018-01-26 22:37:25 +01001617/* Test MO Call with no response to RAN-side CRCX */
Harald Weltee13cfb22019-04-23 16:52:02 +02001618friend function f_tc_mo_crcx_ran_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001619 f_init_handler(pars);
Harald Welte3ab88002018-01-26 22:37:25 +01001620 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1621 var MNCC_PDU mncc;
1622 var MgcpCommand mgcp_cmd;
1623
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001624 f_perform_lu();
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001625 /* Do not respond to the second CRCX */
1626 cpars.mgw_conn_2.resp := 0;
1627 f_mo_call_establish(cpars);
Harald Welte3ab88002018-01-26 22:37:25 +01001628
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001629 var default ccrel := activate(as_optional_cc_rel(cpars));
Harald Welte3ab88002018-01-26 22:37:25 +01001630
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001631 f_expect_clear(60.0);
Harald Welte3ab88002018-01-26 22:37:25 +01001632
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001633 deactivate(ccrel);
Harald Welte3ab88002018-01-26 22:37:25 +01001634}
1635testcase TC_mo_crcx_ran_timeout() runs on MTC_CT {
1636 var BSC_ConnHdlr vc_conn;
1637 f_init();
1638
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001639 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_timeout), 29);
Harald Welte3ab88002018-01-26 22:37:25 +01001640 vc_conn.done;
1641}
1642
Harald Weltee13cfb22019-04-23 16:52:02 +02001643
Harald Welte0cc82d92018-01-26 22:52:34 +01001644/* Test MO Call with reject to RAN-side CRCX */
Harald Weltee13cfb22019-04-23 16:52:02 +02001645friend function f_tc_mo_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001646 f_init_handler(pars);
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001647
Harald Welte0cc82d92018-01-26 22:52:34 +01001648 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001649
1650 /* Respond with error for the first CRCX */
1651 cpars.mgw_conn_1.resp := -1;
Harald Welte0cc82d92018-01-26 22:52:34 +01001652
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001653 f_perform_lu();
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001654 f_mo_call_establish(cpars);
Harald Welte0cc82d92018-01-26 22:52:34 +01001655
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001656 var default ccrel := activate(as_optional_cc_rel(cpars));
1657 f_expect_clear(60.0);
1658 deactivate(ccrel);
Harald Welte0cc82d92018-01-26 22:52:34 +01001659}
1660testcase TC_mo_crcx_ran_reject() runs on MTC_CT {
1661 var BSC_ConnHdlr vc_conn;
1662 f_init();
1663
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001664 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_reject), 30);
Harald Welte0cc82d92018-01-26 22:52:34 +01001665 vc_conn.done;
1666}
1667
Harald Welte3ab88002018-01-26 22:37:25 +01001668
Harald Welte812f7a42018-01-27 00:49:18 +01001669/* helper function to start a MT call: MNCC SETUP; Paging; DChan est.; DTAP SETUP */
1670private function f_mt_call_start(inout CallParameters cpars) runs on BSC_ConnHdlr {
1671 var MNCC_PDU mncc;
1672 var MgcpCommand mgcp_cmd;
Harald Welte812f7a42018-01-27 00:49:18 +01001673
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001674 f_perform_lu();
Vadim Yanitskiyae747742020-01-10 00:23:10 +01001675 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Harald Welte812f7a42018-01-27 00:49:18 +01001676
1677 /* Allocate call reference and send SETUP via MNCC to MSC */
1678 cpars.mncc_callref := f_rnd_int(2147483648);
1679 MNCC.send(ts_MNCC_SETUP_req(cpars.mncc_callref, hex2str(g_pars.msisdn),
1680 hex2str(cpars.called_party), hex2str(g_pars.imsi)));
1681
1682 /* MSC->BSC: expect PAGING from MSC */
Harald Weltee035e3e2019-04-21 17:32:05 +02001683 f_expect_paging();
1684
Harald Welte812f7a42018-01-27 00:49:18 +01001685 /* MS -> MSC: PAGING RESPONSE */
Harald Welteb9e86fa2018-04-09 18:18:31 +02001686 f_establish_fully(EST_TYPE_PAG_RESP);
Harald Welte812f7a42018-01-27 00:49:18 +01001687
1688 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1689
1690 /* MSC->MS: SETUP */
1691 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party)));
1692}
1693
1694/* Test MT Call */
Harald Weltee13cfb22019-04-23 16:52:02 +02001695friend function f_tc_mt_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001696 f_init_handler(pars);
Harald Welte812f7a42018-01-27 00:49:18 +01001697 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1698 var MNCC_PDU mncc;
1699 var MgcpCommand mgcp_cmd;
1700
1701 f_mt_call_start(cpars);
1702
1703 /* MS->MSC: CALL CONFIRMED */
1704 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1705
1706 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1707
1708 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1709 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001710
1711 /* Detect if the received CRCX is a wildcarded CRCX request. If yes,
1712 * set an endpoint name that fits the pattern. If not, just use the
1713 * endpoint name from the request */
1714 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
1715 cpars.mgcp_ep := "rtpbridge/1@mgw";
1716 } else {
1717 cpars.mgcp_ep := mgcp_cmd.line.ep;
1718 }
1719
Harald Welte812f7a42018-01-27 00:49:18 +01001720 /* Respond to CRCX with error */
1721 var MgcpResponse mgcp_rsp := {
1722 line := {
1723 code := "542",
1724 trans_id := mgcp_cmd.line.trans_id,
1725 string := "FORCED_FAIL"
1726 },
Harald Welte812f7a42018-01-27 00:49:18 +01001727 sdp := omit
1728 }
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001729 var MgcpParameter mgcp_rsp_param := {
1730 code := "Z",
1731 val := cpars.mgcp_ep
1732 };
1733 mgcp_rsp.params[0] := mgcp_rsp_param;
Harald Welte812f7a42018-01-27 00:49:18 +01001734 MGCP.send(mgcp_rsp);
1735
1736 timer T := 30.0;
1737 T.start;
1738 alt {
Daniel Willmannafce8662018-07-06 23:11:32 +02001739 [] T.timeout {
1740 setverdict(fail, "Timeout waiting for channel release");
1741 mtc.stop;
1742 }
Harald Welte812f7a42018-01-27 00:49:18 +01001743 [] MNCC.receive { repeat; }
1744 [] GSUP.receive { repeat; }
1745 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1746 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1747 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1748 repeat;
1749 }
1750 [] MGCP.receive { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001751 [] as_clear_cmd_compl_disc();
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001752 [] as_optional_cc_rel(cpars);
Harald Welte812f7a42018-01-27 00:49:18 +01001753 }
1754}
1755testcase TC_mt_crcx_ran_reject() runs on MTC_CT {
1756 var BSC_ConnHdlr vc_conn;
1757 f_init();
1758
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001759 vc_conn := f_start_handler(refers(f_tc_mt_crcx_ran_reject), 31);
Harald Welte812f7a42018-01-27 00:49:18 +01001760 vc_conn.done;
1761}
1762
1763
Harald Weltee13cfb22019-04-23 16:52:02 +02001764
Harald Welte812f7a42018-01-27 00:49:18 +01001765/* Test MT Call T310 timer */
Harald Weltee13cfb22019-04-23 16:52:02 +02001766friend function f_tc_mt_t310(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Welte812f7a42018-01-27 00:49:18 +01001767 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
Harald Welte812f7a42018-01-27 00:49:18 +01001768 var MgcpCommand mgcp_cmd;
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001769 var PDU_BSSAP bssap;
1770 timer T310;
Harald Welte812f7a42018-01-27 00:49:18 +01001771
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001772 f_init_handler(pars);
1773
Neels Hofmeyr05606152023-03-06 22:42:27 +01001774 /* Make sure X2 does not fire in this test. This test does not send a CN RTP port to osmo-msc, which will
1775 * trigger X2 timeout. We want to test T310, so make X2 significantly longer than T310=30s. */
1776 f_vty_config(MSCVTY, "msc", "timer mgw X2 40");
1777
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001778 /* Initiate a MT call, establish connection */
Harald Welte812f7a42018-01-27 00:49:18 +01001779 f_mt_call_start(cpars);
1780
1781 /* MS->MSC: CALL CONFIRMED */
1782 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1783 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1784
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001785 /* NOTE: MSC is expected to start T310 here */
Harald Welte812f7a42018-01-27 00:49:18 +01001786
Neels Hofmeyrd8a4aee2022-07-25 22:07:24 +02001787 interleave {
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001788 /* MSC->MGW: CRCX (first) */
Neels Hofmeyrd8a4aee2022-07-25 22:07:24 +02001789 [] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
1790 f_handle_crcx(cpars, mgcp_cmd); /* MSC<-MGW: OK */
1791 }
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001792
1793 /* BSC->BSC: BSSMAP ASSIGNMENT REQ */
Neels Hofmeyrd8a4aee2022-07-25 22:07:24 +02001794 [] BSSAP.receive(tr_BSSMAP_AssignmentReq(omit, ?)) -> value bssap {
1795 BSSAP.send(ts_BSSMAP_AssignmentComplete(omit,
1796 aoip := f_ts_BSSMAP_IE_AoIP_TLA(cpars.bss_rtp_ip, cpars.bss_rtp_port),
1797 speechCodec := ts_BSSMAP_IE_SpeechCodec({ ts_CodecFR })));
1798 }
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001799
1800 /* MSC->MGW: MDCX */
Neels Hofmeyrd8a4aee2022-07-25 22:07:24 +02001801 [] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
1802 MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgw_conn_1.mgcp_connection_id,
1803 sdp := omit));
1804 }
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001805
1806 /* MSC->MGW: CRCX (second) */
Neels Hofmeyrd8a4aee2022-07-25 22:07:24 +02001807 [] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
1808 f_handle_crcx(cpars, mgcp_cmd); /* MSC<-MGW: OK */
Neels Hofmeyrd8a4aee2022-07-25 22:07:24 +02001809 }
Neels Hofmeyrc29e6dc2022-08-09 02:38:10 +02001810
1811 [] MNCC.receive(tr_MNCC_RTP_CREATE(cpars.mncc_callref));
Neels Hofmeyrd8a4aee2022-07-25 22:07:24 +02001812 }
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001813
1814 /* Reschedule the guard timeout */
1815 g_Tguard.start(30.0 + 10.0);
1816
1817 /* NOTE: the BSC is expected to respond with CC ALERTING at this state, so
1818 * the MSC would stop T310. However, the idea is to verify T310 expiration
1819 * here, so grab some popcorn and wait for MNCC DISC.ind. */
1820 T310.start(30.0 + 2.0);
Neels Hofmeyre81ef422022-08-07 14:33:06 +02001821 var MNCC_PDU mncc_rx;
Harald Welte812f7a42018-01-27 00:49:18 +01001822 alt {
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001823 [] T310.timeout {
1824 setverdict(fail, "Timeout waiting for MNCC DISC.ind due to T310");
Daniel Willmannafce8662018-07-06 23:11:32 +02001825 mtc.stop;
1826 }
Harald Welte812f7a42018-01-27 00:49:18 +01001827 [] MNCC.receive(tr_MNCC_DISC_ind(cpars.mncc_callref)) {
1828 MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(23))));
Neels Hofmeyr13eeb552022-08-07 14:33:37 +02001829 log("Rx MNCC DISC.ind, T310.read yields ", T310.read);
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001830 setverdict(pass);
Harald Welte812f7a42018-01-27 00:49:18 +01001831 }
Neels Hofmeyre81ef422022-08-07 14:33:06 +02001832 [] MNCC.receive(MNCC_PDU:?) -> value mncc_rx {
1833 log("Rx ", mncc_rx);
1834 setverdict(fail, "Expected MNCC DISC.ind, got some other MNCC message instead");
1835 mtc.stop;
1836 }
Harald Welte812f7a42018-01-27 00:49:18 +01001837 }
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001838
Harald Welte812f7a42018-01-27 00:49:18 +01001839 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));
1840 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001841 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id, '1'B)));
Harald Welte812f7a42018-01-27 00:49:18 +01001842
1843 alt {
Harald Welte812f7a42018-01-27 00:49:18 +01001844 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1845 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001846 // FIXME: f_create_mgcp_delete_ep(cpars.mgcp_ep);
Harald Welte812f7a42018-01-27 00:49:18 +01001847 repeat;
1848 }
Harald Welte5946b332018-03-18 23:32:21 +01001849 [] as_clear_cmd_compl_disc();
Harald Welte812f7a42018-01-27 00:49:18 +01001850 }
1851}
1852testcase TC_mt_t310() runs on MTC_CT {
1853 var BSC_ConnHdlr vc_conn;
1854 f_init();
1855
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001856 vc_conn := f_start_handler(refers(f_tc_mt_t310), 32);
Harald Welte812f7a42018-01-27 00:49:18 +01001857 vc_conn.done;
1858}
1859
Harald Weltee13cfb22019-04-23 16:52:02 +02001860
Harald Welte167458a2018-01-27 15:58:16 +01001861/* Perform successful LU + MO call, then GSUP LocationCancel. Subscriber must be denied CM SERV */
Harald Weltee13cfb22019-04-23 16:52:02 +02001862friend function f_tc_gsup_cancel(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Welte167458a2018-01-27 15:58:16 +01001863 f_init_handler(pars);
1864 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Harald Welte167458a2018-01-27 15:58:16 +01001865
1866 /* Location Update to make subscriber known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001867 f_perform_lu();
Harald Welte167458a2018-01-27 15:58:16 +01001868
1869 /* First MO call should succeed */
1870 f_mo_call(cpars);
1871
1872 /* Cancel the subscriber in the VLR */
1873 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1874 alt {
1875 [] GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi)) { }
1876 [] GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi)) {
1877 setverdict(fail, "Received GSUP Location Cancel Error");
Daniel Willmannafce8662018-07-06 23:11:32 +02001878 mtc.stop;
Harald Welte167458a2018-01-27 15:58:16 +01001879 }
1880 }
1881
1882 /* Follow-up transactions should fail */
1883 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1884 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001885 f_cl3_or_initial_ue(l3_info);
Harald Welte167458a2018-01-27 15:58:16 +01001886 alt {
1887 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
1888 [] BSSAP.receive {
1889 setverdict(fail, "Received unexpected BSSAP instead of CM SERV REJ");
Daniel Willmannafce8662018-07-06 23:11:32 +02001890 mtc.stop;
Harald Welte167458a2018-01-27 15:58:16 +01001891 }
1892 }
Neels Hofmeyr0f7429a2019-03-07 22:28:41 +01001893
1894 f_expect_clear();
Harald Welte167458a2018-01-27 15:58:16 +01001895 setverdict(pass);
1896}
1897testcase TC_gsup_cancel() runs on MTC_CT {
1898 var BSC_ConnHdlr vc_conn;
1899 f_init();
1900
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001901 vc_conn := f_start_handler(refers(f_tc_gsup_cancel), 33, verify_cell_id := false);
Harald Welte167458a2018-01-27 15:58:16 +01001902 vc_conn.done;
1903}
1904
Harald Weltee13cfb22019-04-23 16:52:02 +02001905
Harald Welte9de84792018-01-28 01:06:35 +01001906/* A5/1 only permitted on network side, and MS capable to do it */
1907private function f_tc_lu_imsi_auth_tmsi_encr_1_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1908 pars.net.expect_auth := true;
1909 pars.net.expect_ciph := true;
1910 pars.net.kc_support := '02'O; /* A5/1 only */
1911 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001912 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001913}
1914testcase TC_lu_imsi_auth_tmsi_encr_1_13() runs on MTC_CT {
1915 var BSC_ConnHdlr vc_conn;
1916 f_init();
1917 f_vty_config(MSCVTY, "network", "authentication required");
1918 f_vty_config(MSCVTY, "network", "encryption a5 1");
1919
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001920 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_1_13), 34);
Harald Welte9de84792018-01-28 01:06:35 +01001921 vc_conn.done;
1922}
1923
1924/* A5/3 only permitted on network side, and MS capable to do it */
1925private function f_tc_lu_imsi_auth_tmsi_encr_3_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1926 pars.net.expect_auth := true;
1927 pars.net.expect_ciph := true;
1928 pars.net.kc_support := '08'O; /* A5/3 only */
1929 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001930 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001931}
1932testcase TC_lu_imsi_auth_tmsi_encr_3_13() runs on MTC_CT {
1933 var BSC_ConnHdlr vc_conn;
1934 f_init();
1935 f_vty_config(MSCVTY, "network", "authentication required");
1936 f_vty_config(MSCVTY, "network", "encryption a5 3");
1937
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001938 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_13), 35);
Harald Welte9de84792018-01-28 01:06:35 +01001939 vc_conn.done;
1940}
1941
1942/* A5/3 only permitted on network side, and MS with only A5/1 support */
1943private function f_tc_lu_imsi_auth_tmsi_encr_3_1(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1944 pars.net.expect_auth := true;
1945 pars.net.expect_ciph := true;
1946 pars.net.kc_support := '08'O; /* A5/3 only */
1947 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1948 f_init_handler(pars, 15.0);
1949
1950 /* cannot use f_perform_lu() as we expect a reject */
1951 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1952 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +02001953 f_cl3_or_initial_ue(l3_lu);
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001954 if (pars.send_early_cm) {
1955 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1956 } else {
1957 pars.cm1.esind := '0'B;
1958 }
Harald Welte9de84792018-01-28 01:06:35 +01001959 f_mm_auth();
1960 alt {
Daniel Willmann52918e52018-09-20 14:39:09 +02001961 [] BSSAP.receive(tr_BSSMAP_ClassmarkReq) {
1962 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1963 repeat;
1964 }
Harald Welte5946b332018-03-18 23:32:21 +01001965 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1966 f_expect_clear();
1967 }
Harald Welte9de84792018-01-28 01:06:35 +01001968 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1969 setverdict(fail, "CipherModeCommand despite no A5 intersection");
Daniel Willmannafce8662018-07-06 23:11:32 +02001970 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001971 }
1972 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001973 setverdict(fail, "Unknown/unexpected BSSAP received");
Daniel Willmannafce8662018-07-06 23:11:32 +02001974 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001975 }
1976 }
1977 setverdict(pass);
1978}
1979testcase TC_lu_imsi_auth_tmsi_encr_3_1() runs on MTC_CT {
1980 var BSC_ConnHdlr vc_conn;
1981 f_init();
1982 f_vty_config(MSCVTY, "network", "authentication required");
1983 f_vty_config(MSCVTY, "network", "encryption a5 3");
1984
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001985 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 +01001986 vc_conn.done;
1987}
1988testcase TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() runs on MTC_CT {
1989 var BSC_ConnHdlrPars pars;
1990 var BSC_ConnHdlr vc_conn;
1991 f_init();
1992 f_vty_config(MSCVTY, "network", "authentication required");
1993 f_vty_config(MSCVTY, "network", "encryption a5 3");
1994
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001995 pars := f_init_pars(361, verify_cell_id := false);
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001996 pars.send_early_cm := false;
1997 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 +01001998 vc_conn.done;
1999}
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01002000testcase TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() runs on MTC_CT {
2001 var BSC_ConnHdlr vc_conn;
2002 f_init();
2003 f_vty_config(MSCVTY, "network", "authentication required");
2004 f_vty_config(MSCVTY, "network", "encryption a5 3");
2005
2006 /* Make sure the MSC category is on DEBUG level to trigger the log
2007 * message that is reported in OS#2947 to trigger the segfault */
2008 f_vty_config(MSCVTY, "log stderr", "logging level msc debug");
2009
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02002010 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 +01002011 vc_conn.done;
2012}
Harald Welte9de84792018-01-28 01:06:35 +01002013
2014/* A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
2015private function f_tc_lu_imsi_auth_tmsi_encr_13_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2016 pars.net.expect_auth := true;
2017 pars.net.expect_ciph := true;
2018 pars.net.kc_support := '0A'O; /* A5/1 + A5/3 */
2019 pars.cm1.a5_1 := '1'B;
2020 pars.cm2.a5_1 := '1'B;
2021 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
2022 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
2023 f_init_handler(pars, 15.0);
2024
2025 /* cannot use f_perform_lu() as we expect a reject */
2026 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
2027 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +02002028 f_cl3_or_initial_ue(l3_lu);
Harald Welte9de84792018-01-28 01:06:35 +01002029 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
2030 f_mm_auth();
2031 alt {
Harald Welte5946b332018-03-18 23:32:21 +01002032 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
2033 f_expect_clear();
2034 }
Harald Welte9de84792018-01-28 01:06:35 +01002035 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
2036 setverdict(fail, "CipherModeCommand despite no A5 intersection");
Daniel Willmannafce8662018-07-06 23:11:32 +02002037 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01002038 }
2039 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01002040 setverdict(fail, "Unknown/unexpected BSSAP received");
Daniel Willmannafce8662018-07-06 23:11:32 +02002041 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01002042 }
2043 }
2044 setverdict(pass);
2045}
2046testcase TC_lu_imsi_auth_tmsi_encr_13_2() runs on MTC_CT {
2047 var BSC_ConnHdlr vc_conn;
2048 f_init();
2049 f_vty_config(MSCVTY, "network", "authentication required");
2050 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
2051
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02002052 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 +01002053 vc_conn.done;
2054}
2055
Eric Wild26f4a622021-05-17 15:27:05 +02002056/* A5/0 + A5/1 + A5/3 + a5/4 only permitted on network side, and MS with only A5/1 support */
2057private function f_tc_lu_imsi_auth_tmsi_encr_0134_1(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2058 pars.net.expect_auth := true;
2059 pars.net.expect_ciph := true;
2060 pars.net.kc_support := '03'O; /* A5/0 + A5/1 */
2061 pars.cm1.a5_1 := '0'B;
2062 pars.cm2.a5_1 := '0'B;
2063 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
2064 pars.cm2.classmarkInformationType2_oct5.a5_2 := '0'B;
2065 pars.cm2.classmarkInformationType2_oct5.cm3 := '0'B;
2066 pars.cm3 := omit;
2067 pars.use_umts_aka := true;
2068
2069 f_init_handler(pars, 15.0);
2070 f_perform_lu();
2071}
2072testcase TC_lu_imsi_auth_tmsi_encr_0134_1() runs on MTC_CT {
2073 var BSC_ConnHdlr vc_conn;
2074 f_init();
2075 f_vty_config(MSCVTY, "network", "authentication required");
2076 f_vty_config(MSCVTY, "network", "encryption a5 0 1 3 4");
2077
2078 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_0134_1), 39);
2079 vc_conn.done;
2080}
2081
2082/* A5/0 + A5/1 + A5/3 + a5/4 only permitted on network side, and MS with A5/3 + A5/4 support */
2083private function f_tc_lu_imsi_auth_tmsi_encr_0134_34(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2084 pars.net.expect_auth := true;
2085 pars.net.expect_ciph := true;
2086 pars.net.kc_support := '19'O; /* A5/3 + A5/4 */
2087 pars.cm1.a5_1 := '1'B;
2088 pars.cm2.a5_1 := '1'B;
2089 pars.cm2.classmarkInformationType2_oct5.a5_3 := '1'B;
2090 pars.cm2.classmarkInformationType2_oct5.a5_2 := '0'B;
2091 pars.cm2.classmarkInformationType2_oct5.cm3 := '1'B;
2092 pars.cm3 := valueof(ts_CM3_default);
2093 pars.use_umts_aka := true;
2094
2095 f_init_handler(pars, 15.0);
2096 f_perform_lu();
2097}
2098testcase TC_lu_imsi_auth_tmsi_encr_0134_34() runs on MTC_CT {
2099 var BSC_ConnHdlr vc_conn;
2100 f_init();
2101 f_vty_config(MSCVTY, "network", "authentication required");
2102 f_vty_config(MSCVTY, "network", "encryption a5 0 1 3 4");
2103
2104 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_0134_34), 40);
2105 vc_conn.done;
2106}
2107
2108/* A5/0 + A5/1 + A5/3 + a5/4 only permitted on network side, and MS with A5/3 support but no CM3 */
2109private function f_tc_lu_imsi_auth_tmsi_encr_0134_34_no_cm3(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2110 pars.net.expect_auth := true;
2111 pars.net.expect_ciph := true;
2112 pars.net.kc_support := '19'O; /* A5/3 + A5/4 */
2113 pars.cm1.a5_1 := '1'B;
2114 pars.cm2.a5_1 := '1'B;
2115 pars.cm2.classmarkInformationType2_oct5.a5_3 := '1'B;
2116 pars.cm2.classmarkInformationType2_oct5.a5_2 := '0'B;
2117 pars.cm2.classmarkInformationType2_oct5.cm3 := '0'B;
2118 pars.cm3 := omit;
2119 pars.use_umts_aka := true;
2120
2121 f_init_handler(pars, 15.0);
2122 f_perform_lu();
2123}
2124testcase TC_lu_imsi_auth_tmsi_encr_0134_34_no_cm3() runs on MTC_CT {
2125 var BSC_ConnHdlr vc_conn;
2126 f_init();
2127 f_vty_config(MSCVTY, "network", "authentication required");
2128 f_vty_config(MSCVTY, "network", "encryption a5 0 1 3 4");
2129
2130 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_0134_34_no_cm3), 41);
2131 vc_conn.done;
2132}
2133
Harald Welte9de84792018-01-28 01:06:35 +01002134/* A5/0 + A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
2135private function f_tc_lu_imsi_auth_tmsi_encr_013_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2136 pars.net.expect_auth := true;
2137 pars.net.expect_ciph := true;
2138 pars.net.kc_support := '0B'O; /* A5/1 + A5/3 */
2139 pars.cm1.a5_1 := '1'B;
2140 pars.cm2.a5_1 := '1'B;
2141 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
2142 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
2143 f_init_handler(pars, 15.0);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01002144 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01002145}
2146testcase TC_lu_imsi_auth_tmsi_encr_013_2() runs on MTC_CT {
2147 var BSC_ConnHdlr vc_conn;
2148 f_init();
2149 f_vty_config(MSCVTY, "network", "authentication required");
2150 f_vty_config(MSCVTY, "network", "encryption a5 0 1 3");
2151
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01002152 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_013_2), 38);
Harald Welte9de84792018-01-28 01:06:35 +01002153 vc_conn.done;
2154}
2155
Harald Welte33ec09b2018-02-10 15:34:46 +01002156/* LU followed by MT call (including paging) */
Neels Hofmeyr8fe8a902019-11-03 05:51:03 +01002157friend function f_tc_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Welte33ec09b2018-02-10 15:34:46 +01002158 f_init_handler(pars);
Stefan Sperling26d57be2018-11-12 17:03:26 +01002159 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Pau Espin Pedrola65697d2019-05-21 12:54:39 +02002160 cpars.use_osmux := pars.use_osmux;
Harald Welte33ec09b2018-02-10 15:34:46 +01002161
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01002162 f_perform_lu();
Harald Welte33ec09b2018-02-10 15:34:46 +01002163 f_mt_call(cpars);
2164}
2165testcase TC_lu_and_mt_call() runs on MTC_CT {
2166 var BSC_ConnHdlr vc_conn;
2167 f_init();
2168
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01002169 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call), 39);
Harald Welte33ec09b2018-02-10 15:34:46 +01002170 vc_conn.done;
2171}
2172
Pau Espin Pedrola65697d2019-05-21 12:54:39 +02002173testcase TC_lu_and_mt_call_osmux() runs on MTC_CT {
2174 var BSC_ConnHdlr vc_conn;
2175 f_init(1, false, true, true);
Pau Espin Pedrola65697d2019-05-21 12:54:39 +02002176
2177 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call), 39, 0, true, true);
2178 vc_conn.done;
2179}
2180
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02002181/* LU followed by MT call (including paging) */
2182friend function f_tc_lu_and_mt_call_ipv6(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2183 f_init_handler(pars);
2184 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
2185 cpars.mgw_conn_1.mgw_rtp_ip := "::1";
2186 cpars.mgw_conn_2.mgw_rtp_ip := "::2";
2187 cpars.bss_rtp_ip := "::3";
Pau Espin Pedrol563b3d02020-09-09 20:19:52 +02002188 cpars.mncc_rtp_ip := "::9";
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02002189 f_perform_lu();
2190 f_mt_call(cpars);
2191}
2192testcase TC_lu_and_mt_call_ipv6() runs on MTC_CT {
2193 var BSC_ConnHdlr vc_conn;
2194 f_init();
2195
2196 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call_ipv6), 39);
2197 vc_conn.done;
2198}
2199
Neels Hofmeyrb58d9742019-11-27 18:44:54 +01002200/* MT call while already Paging */
2201friend function f_tc_lu_and_mt_call_already_paging(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2202 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
2203 var SmsParameters spars := valueof(t_SmsPars);
2204 var OCT4 tmsi;
2205
2206 f_init_handler(pars);
2207
2208 /* Perform location update */
2209 f_perform_lu();
2210
2211 /* register an 'expect' for given IMSI (+TMSI) */
2212 if (isvalue(g_pars.tmsi)) {
2213 tmsi := g_pars.tmsi;
2214 } else {
2215 tmsi := 'FFFFFFFF'O;
2216 }
2217 f_ran_register_imsi(g_pars.imsi, tmsi);
2218
2219 log("start Paging by an SMS");
2220 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
2221
2222 /* MSC->BSC: expect PAGING from MSC */
2223 f_expect_paging();
2224
2225 log("MNCC signals MT call, before Paging Response");
Oliver Smith97dc91f2023-05-31 13:53:21 +02002226 f_mt_call_initiate(cpars);
Neels Hofmeyrb58d9742019-11-27 18:44:54 +01002227 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
2228
2229 f_sleep(0.5);
2230 log("phone answers Paging, expecting both SMS and MT call to be established");
2231 f_establish_fully(EST_TYPE_PAG_RESP);
2232 spars.tp.ud := 'C8329BFD064D9B53'O;
2233 interleave {
2234 [] BSSAP.receive(f_mt_sms_deliver_pdu(spars)) {
2235 log("Got SMS-DELIVER");
2236 };
2237 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party))) {
2238 log("Got CC Setup");
2239 };
2240 }
2241 setverdict(pass);
2242 log("success, tear down");
2243 var default ccrel := activate(as_optional_cc_rel(cpars));
2244 if (g_pars.ran_is_geran) {
2245 BSSAP.send(ts_BSSMAP_ClearRequest(0));
2246 } else {
2247 BSSAP.send(ts_RANAP_IuReleaseRequest(ts_RanapCause_om_intervention));
2248 }
2249 f_expect_clear();
2250 deactivate(ccrel);
2251 f_vty_sms_clear(hex2str(g_pars.imsi));
2252}
2253testcase TC_lu_and_mt_call_already_paging() runs on MTC_CT {
2254 var BSC_ConnHdlrPars pars;
2255 var BSC_ConnHdlr vc_conn;
2256 f_init();
2257 pars := f_init_pars(391);
2258 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_call_already_paging), pars);
2259 vc_conn.done;
2260}
2261
Daniel Willmann8b084372018-02-04 13:35:26 +01002262/* Test MO Call SETUP with DTMF */
2263private function f_tc_mo_setup_dtmf_dup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2264 f_init_handler(pars);
2265 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Daniel Willmann8b084372018-02-04 13:35:26 +01002266
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01002267 f_perform_lu();
Daniel Willmann8b084372018-02-04 13:35:26 +01002268 f_mo_seq_dtmf_dup(cpars);
2269}
2270testcase TC_mo_setup_and_dtmf_dup() runs on MTC_CT {
2271 var BSC_ConnHdlr vc_conn;
2272 f_init();
2273
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01002274 vc_conn := f_start_handler(refers(f_tc_mo_setup_dtmf_dup), 39);
Daniel Willmann8b084372018-02-04 13:35:26 +01002275 vc_conn.done;
2276}
Harald Welte9de84792018-01-28 01:06:35 +01002277
Philipp Maier328d1662018-03-07 10:40:27 +01002278testcase TC_cr_before_reset() runs on MTC_CT {
2279 timer T := 4.0;
2280 var boolean reset_ack_seen := false;
2281 f_init_bssap_direct();
2282
Harald Welte3ca0ce12019-04-23 17:18:48 +02002283 f_ran_adapter_start(g_bssap[0]);
Daniel Willmann42d1d5b2018-08-07 15:18:41 +02002284
Daniel Willmanne8018962018-08-21 14:18:00 +02002285 f_sleep(3.0);
2286
Philipp Maier328d1662018-03-07 10:40:27 +01002287 /* Make a blind connection attemt, to trigger the deadlock condition */
Philipp Maier75932982018-03-27 14:52:35 +02002288 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 +01002289
2290 /* Send a BSSMAP reset */
Philipp Maier75932982018-03-27 14:52:35 +02002291 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 +01002292 T.start
2293 alt {
2294 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_ResetAck)) {
2295 reset_ack_seen := true;
2296 repeat;
2297 }
2298
2299 /* Acknowledge MSC sided reset requests */
2300 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) {
Philipp Maier75932982018-03-27 14:52:35 +02002301 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 +01002302 repeat;
2303 }
2304
2305 /* Ignore all other messages (e.g CR from the connection request) */
2306 [] BSSAP_DIRECT.receive { repeat }
2307
2308 /* If we got no BSSMAP RESET ACK back, then the MSC entered the
2309 * deadlock situation. The MSC is then unable to respond to any
2310 * further BSSMAP RESET or any other sort of traffic. */
2311 [reset_ack_seen == true] T.timeout { setverdict(pass) }
2312 [reset_ack_seen == false] T.timeout {
2313 setverdict(fail, "no BSSMAP RESET ACK seen!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002314 mtc.stop;
Philipp Maier328d1662018-03-07 10:40:27 +01002315 }
Pau Espin Pedrol7e9178d2019-12-17 17:52:17 +01002316 }
Philipp Maier328d1662018-03-07 10:40:27 +01002317}
Harald Welte9de84792018-01-28 01:06:35 +01002318
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002319/* Test MO Call with no response to RAN-side CRCX or DTAP Release */
Harald Weltee13cfb22019-04-23 16:52:02 +02002320friend function f_tc_mo_release_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002321 f_init_handler(pars);
2322 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
2323 var MNCC_PDU mncc;
2324 var MgcpCommand mgcp_cmd;
2325
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02002326 /* Do not respond to the second CRCX */
2327 cpars.mgw_conn_2.resp := 0;
2328
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002329 f_perform_lu();
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02002330 f_mo_call_establish(cpars);
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002331
Neels Hofmeyrde76f052019-02-26 05:02:46 +01002332 var default ccrel := activate(as_optional_cc_rel(cpars));
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002333
2334 f_expect_clear(60.0);
Neels Hofmeyrde76f052019-02-26 05:02:46 +01002335
2336 deactivate(ccrel);
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002337}
2338testcase TC_mo_release_timeout() runs on MTC_CT {
2339 var BSC_ConnHdlr vc_conn;
2340 f_init();
2341
2342 vc_conn := f_start_handler(refers(f_tc_mo_release_timeout), 40);
2343 vc_conn.done;
2344}
2345
Harald Welte12510c52018-01-26 22:26:24 +01002346
Philipp Maier2a98a732018-03-19 16:06:12 +01002347/* LU followed by MT call (including paging) */
2348private function f_tc_lu_and_mt_call_no_dlcx_resp(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2349 f_init_handler(pars);
Stefan Sperling26d57be2018-11-12 17:03:26 +01002350 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Philipp Maier2a98a732018-03-19 16:06:12 +01002351
2352 /* Intentionally disable the CRCX response */
2353 cpars.mgw_drop_dlcx := true;
2354
2355 /* Perform location update and call */
2356 f_perform_lu();
2357 f_mt_call(cpars);
2358}
2359testcase TC_lu_and_mt_call_no_dlcx_resp() runs on MTC_CT {
2360 var BSC_ConnHdlr vc_conn;
2361 f_init();
2362
2363 /* Perform an almost normal looking locationupdate + mt-call, but do
2364 * not respond to the DLCX at the end of the call */
2365 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call_no_dlcx_resp), 41);
2366 vc_conn.done;
2367
2368 /* Wait a guard period until the MGCP layer in the MSC times out,
2369 * if the MSC is vulnerable to the use-after-free situation that is
2370 * fixed by I78f1b6a9149488a4ad3f120c1e190a83c07d4b89 then it should
2371 * segfault now */
2372 f_sleep(6.0);
2373
2374 /* Run the init procedures once more. If the MSC has crashed, this
2375 * this will fail */
2376 f_init();
2377}
Harald Welte45164da2018-01-24 12:51:27 +01002378
Philipp Maier75932982018-03-27 14:52:35 +02002379/* Two BSSMAP resets from two different BSCs */
2380testcase TC_reset_two() runs on MTC_CT {
2381 var BSC_ConnHdlr vc_conn;
2382 f_init(2);
2383 f_sleep(2.0);
2384 setverdict(pass);
2385}
2386
Harald Weltee13cfb22019-04-23 16:52:02 +02002387/* Two BSSMAP resets from two different BSCs plus one IuCS RANAP Reset */
2388testcase TC_reset_two_1iu() runs on MTC_CT {
2389 var BSC_ConnHdlr vc_conn;
2390 f_init(3);
2391 f_sleep(2.0);
2392 setverdict(pass);
2393}
2394
Harald Weltef640a012018-04-14 17:49:21 +02002395/***********************************************************************
2396 * SMS Testing
2397 ***********************************************************************/
2398
Harald Weltef45efeb2018-04-09 18:19:24 +02002399/* LU followed by MO SMS */
Harald Weltee13cfb22019-04-23 16:52:02 +02002400friend function f_tc_lu_and_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltef45efeb2018-04-09 18:19:24 +02002401 var SmsParameters spars := valueof(t_SmsPars);
2402
2403 f_init_handler(pars);
2404
2405 /* Perform location update and call */
2406 f_perform_lu();
2407
2408 f_establish_fully(EST_TYPE_MO_SMS);
2409
2410 //spars.exp_rp_err := 96; /* invalid mandatory information */
2411 f_mo_sms(spars);
2412
2413 f_expect_clear();
2414}
2415testcase TC_lu_and_mo_sms() runs on MTC_CT {
2416 var BSC_ConnHdlr vc_conn;
2417 f_init();
2418 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_sms), 42);
2419 vc_conn.done;
2420}
2421
Harald Weltee13cfb22019-04-23 16:52:02 +02002422
Harald Weltef45efeb2018-04-09 18:19:24 +02002423private function f_vty_sms_send(charstring imsi, charstring msisdn, charstring text)
Neels Hofmeyr6aaeccf2019-03-06 15:32:26 +01002424runs on BSC_ConnHdlr {
Harald Weltef45efeb2018-04-09 18:19:24 +02002425 f_vty_transceive(MSCVTY, "subscriber imsi "&imsi&" sms sender msisdn "&msisdn&" send "&text);
2426}
2427
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01002428/* Remove still pending SMS */
2429private function f_vty_sms_clear(charstring imsi)
2430runs on BSC_ConnHdlr {
2431 f_vty_transceive(MSCVTY, "subscriber imsi " & imsi & " sms delete-all");
2432 f_vty_transceive(MSCVTY, "sms-queue clear");
2433}
2434
Harald Weltef45efeb2018-04-09 18:19:24 +02002435/* LU followed by MT SMS */
Harald Weltee13cfb22019-04-23 16:52:02 +02002436friend function f_tc_lu_and_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltef45efeb2018-04-09 18:19:24 +02002437 var SmsParameters spars := valueof(t_SmsPars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002438
2439 f_init_handler(pars);
2440
2441 /* Perform location update and call */
2442 f_perform_lu();
2443
2444 /* register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002445 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Harald Weltef45efeb2018-04-09 18:19:24 +02002446
Neels Hofmeyr6aaeccf2019-03-06 15:32:26 +01002447 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
Harald Weltef45efeb2018-04-09 18:19:24 +02002448
2449 /* MSC->BSC: expect PAGING from MSC */
Harald Weltee035e3e2019-04-21 17:32:05 +02002450 f_expect_paging();
2451
Harald Weltef45efeb2018-04-09 18:19:24 +02002452 /* Establish DTAP / BSSAP / SCCP connection */
2453 f_establish_fully(EST_TYPE_PAG_RESP);
2454
2455 spars.tp.ud := 'C8329BFD064D9B53'O;
2456 f_mt_sms(spars);
2457
2458 f_expect_clear();
2459}
2460testcase TC_lu_and_mt_sms() runs on MTC_CT {
2461 var BSC_ConnHdlrPars pars;
2462 var BSC_ConnHdlr vc_conn;
2463 f_init();
2464 pars := f_init_pars(43);
2465 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_sms), pars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002466 vc_conn.done;
2467}
2468
Neels Hofmeyrb58d9742019-11-27 18:44:54 +01002469/* SMS added while already Paging */
2470friend function f_tc_lu_and_mt_sms_already_paging(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2471 var SmsParameters spars := valueof(t_SmsPars);
2472 var OCT4 tmsi;
2473
2474 f_init_handler(pars);
2475
2476 f_perform_lu();
2477
2478 /* register an 'expect' for given IMSI (+TMSI) */
2479 if (isvalue(g_pars.tmsi)) {
2480 tmsi := g_pars.tmsi;
2481 } else {
2482 tmsi := 'FFFFFFFF'O;
2483 }
2484 f_ran_register_imsi(g_pars.imsi, tmsi);
2485
2486 log("first SMS");
2487 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
2488
2489 /* MSC->BSC: expect PAGING from MSC */
2490 f_expect_paging();
2491
2492 log("second SMS");
2493 /* Now osmo-msc is in state "Paging pending", make sure that another SMS to be sent at this time just joins in
2494 * with the pending paging. Another SMS: */
2495 f_vty_sms_send(hex2str(pars.imsi), "2342", "Another SMS");
2496
2497 /* Establish DTAP / BSSAP / SCCP connection */
2498 f_establish_fully(EST_TYPE_PAG_RESP);
2499
2500 spars.tp.ud := 'C8329BFD064D9B53'O;
2501 f_mt_sms(spars);
2502
2503 spars.tp.ud := '41F79B8E2ECB41D3E614'O;
2504 f_mt_sms(spars);
2505
2506 f_expect_clear();
2507}
2508testcase TC_lu_and_mt_sms_already_paging() runs on MTC_CT {
2509 var BSC_ConnHdlrPars pars;
2510 var BSC_ConnHdlr vc_conn;
2511 f_init();
2512 pars := f_init_pars(44);
2513 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_sms_already_paging), pars);
2514 vc_conn.done;
2515}
Harald Weltee13cfb22019-04-23 16:52:02 +02002516
Philipp Maier3983e702018-11-22 19:01:33 +01002517/* Paging for MT SMS but no response */
Harald Weltee13cfb22019-04-23 16:52:02 +02002518friend 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 +01002519 var SmsParameters spars := valueof(t_SmsPars);
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002520
Philipp Maier3983e702018-11-22 19:01:33 +01002521 f_init_handler(pars, 150.0);
2522
2523 /* Perform location update */
2524 f_perform_lu();
2525
2526 /* register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002527 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Philipp Maier3983e702018-11-22 19:01:33 +01002528
Neels Hofmeyr6aaeccf2019-03-06 15:32:26 +01002529 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
2530
Neels Hofmeyr16237742019-03-06 15:34:01 +01002531 /* Expect the MSC to page exactly once */
Harald Weltee13cfb22019-04-23 16:52:02 +02002532 f_expect_paging();
Philipp Maier3983e702018-11-22 19:01:33 +01002533
2534 /* Wait some time to make sure the MSC is not delivering any further
2535 * paging messages or anything else that could be unexpected. */
2536 timer T := 20.0;
2537 T.start
2538 alt {
Vadim Yanitskiyda774592020-01-15 10:33:47 +07002539 [pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
2540 setverdict(fail, "paging seems not to stop!");
2541 mtc.stop;
Philipp Maier3983e702018-11-22 19:01:33 +01002542 }
Vadim Yanitskiyda774592020-01-15 10:33:47 +07002543 [not pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
2544 setverdict(fail, "paging seems not to stop!");
2545 mtc.stop;
Harald Weltee13cfb22019-04-23 16:52:02 +02002546 }
Vadim Yanitskiyda774592020-01-15 10:33:47 +07002547 [] BSSAP.receive {
2548 setverdict(fail, "unexpected BSSAP message received");
2549 self.stop;
Philipp Maier3983e702018-11-22 19:01:33 +01002550 }
Vadim Yanitskiyda774592020-01-15 10:33:47 +07002551 [] T.timeout {
2552 setverdict(pass);
Philipp Maier3983e702018-11-22 19:01:33 +01002553 }
2554 }
2555
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01002556 f_vty_sms_clear(hex2str(g_pars.imsi));
2557
Philipp Maier3983e702018-11-22 19:01:33 +01002558 setverdict(pass);
2559}
2560testcase TC_lu_and_mt_sms_paging_and_nothing() runs on MTC_CT {
2561 var BSC_ConnHdlrPars pars;
2562 var BSC_ConnHdlr vc_conn;
2563 f_init();
Philipp Maiera99ad262019-01-22 15:35:42 +01002564 pars := f_init_pars(1843);
Philipp Maier3983e702018-11-22 19:01:33 +01002565 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 +01002566 vc_conn.done;
2567}
2568
Alexander Couzensfc02f242019-09-12 03:43:18 +02002569/* LU followed by MT SMS with repeated paging */
2570friend function f_tc_lu_and_mt_sms_paging_repeated(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2571 var SmsParameters spars := valueof(t_SmsPars);
Alexander Couzensfc02f242019-09-12 03:43:18 +02002572
2573 f_init_handler(pars);
2574
2575 /* Perform location update and call */
2576 f_perform_lu();
2577
2578 /* register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002579 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Alexander Couzensfc02f242019-09-12 03:43:18 +02002580
2581 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
2582
Neels Hofmeyrc3accec2019-11-28 01:09:47 +01002583 log("Expecting first Paging");
Alexander Couzensfc02f242019-09-12 03:43:18 +02002584 /* MSC->BSC: expect PAGING from MSC */
2585 f_expect_paging();
2586
Neels Hofmeyrc3accec2019-11-28 01:09:47 +01002587 if (g_pars.ran_is_geran) {
2588 log("GERAN: expect no further Paging");
2589 } else {
2590 log("UTRAN: expect more Paging");
2591 }
2592
2593 timer T := 5.0;
2594 T.start;
2595 alt {
2596 [g_pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
2597 setverdict(fail, "GERAN should not repeat Paging, but received a second Paging");
2598 mtc.stop;
2599 }
2600 [not g_pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
2601 log("UTRAN: second Paging received, as expected");
2602 setverdict(pass);
2603 }
2604 [] T.timeout {
2605 if (g_pars.ran_is_geran) {
2606 log("GERAN: No further Paging received, as expected");
2607 setverdict(pass);
2608 } else {
2609 setverdict(fail, "UTRAN: Expected a second Paging");
2610 mtc.stop;
2611 }
2612 }
2613 }
Alexander Couzensfc02f242019-09-12 03:43:18 +02002614
2615 /* Establish DTAP / BSSAP / SCCP connection */
2616 f_establish_fully(EST_TYPE_PAG_RESP);
2617
2618 spars.tp.ud := 'C8329BFD064D9B53'O;
2619 f_mt_sms(spars);
2620
2621 f_expect_clear();
2622}
2623testcase TC_lu_and_mt_sms_paging_repeated() runs on MTC_CT {
2624 var BSC_ConnHdlrPars pars;
2625 var BSC_ConnHdlr vc_conn;
2626 f_init();
2627 pars := f_init_pars(1844);
2628 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_sms_paging_repeated), pars);
2629 vc_conn.done;
2630}
Harald Weltee13cfb22019-04-23 16:52:02 +02002631
Harald Weltef640a012018-04-14 17:49:21 +02002632/* mobile originated SMS from MS/BTS/BSC side to SMPP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002633friend function f_tc_smpp_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltef640a012018-04-14 17:49:21 +02002634 var SmsParameters spars := valueof(t_SmsPars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002635
Harald Weltef640a012018-04-14 17:49:21 +02002636 f_init_handler(pars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002637
Harald Weltef640a012018-04-14 17:49:21 +02002638 /* Perform location update so IMSI is known + registered in MSC/VLR */
2639 f_perform_lu();
Harald Weltef640a012018-04-14 17:49:21 +02002640
Vadim Yanitskiy2d3f8462020-01-15 11:44:12 +07002641 /* MS/UE submits a MO SMS */
2642 f_establish_fully(EST_TYPE_MO_SMS);
2643 f_mo_sms_submit(spars);
Harald Weltef640a012018-04-14 17:49:21 +02002644
2645 var SMPP_PDU smpp;
2646 var template SMPP_PDU tr_smpp := tr_SMPP(c_SMPP_command_id_deliver_sm, ESME_ROK);
2647 tr_smpp.body.deliver_sm := {
2648 service_type := "CMT",
2649 source_addr_ton := network_specific,
2650 source_addr_npi := isdn,
2651 source_addr := hex2str(pars.msisdn),
2652 dest_addr_ton := f_sm_ton_from_gsm(spars.tp.da.tP_DA_NoPad.tP_TypeOfNumber),
2653 dest_addr_npi := f_sm_npi_from_gsm(spars.tp.da.tP_DA_NoPad.tP_NumberingPlanID),
2654 destination_addr := hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue),
2655 esm_class := '00000001'B,
2656 protocol_id := 0,
2657 priority_flag := 0,
2658 schedule_delivery_time := "",
2659 replace_if_present := 0,
2660 data_coding := '00000001'B,
2661 sm_default_msg_id := 0,
2662 sm_length := ?,
2663 short_message := spars.tp.ud,
2664 opt_pars := {
2665 {
2666 tag := user_message_reference,
2667 len := 2,
2668 opt_value := {
2669 int2_val := oct2int(spars.tp.msg_ref)
2670 }
2671 }
2672 }
2673 };
2674 alt {
2675 [] SMPP.receive(tr_smpp) -> value smpp {
2676 SMPP.send(ts_SMPP_DELIVER_SM_resp(ESME_ROK, smpp.header.seq_num));
2677 }
2678 [] SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK)) { repeat; }
2679 }
2680
Vadim Yanitskiy2d3f8462020-01-15 11:44:12 +07002681 /* MSC terminates the SMS transaction with RP-ACK */
2682 f_mo_sms_wait_rp_ack(spars);
2683
Harald Weltef640a012018-04-14 17:49:21 +02002684 f_expect_clear();
2685}
2686testcase TC_smpp_mo_sms() runs on MTC_CT {
2687 var BSC_ConnHdlr vc_conn;
2688 f_init();
2689 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "default-route");
2690 vc_conn := f_start_handler(refers(f_tc_smpp_mo_sms), 44);
2691 vc_conn.done;
2692 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "no default-route");
2693}
2694
Vadim Yanitskiy33820762020-01-15 11:26:07 +07002695/* Test case for OS#4351: make sure that RP-ERROR from ESME is properly sent to the MS/UE */
2696friend function f_tc_smpp_mo_sms_rp_error(charstring id, BSC_ConnHdlrPars pars)
2697runs on BSC_ConnHdlr {
2698 var SmsParameters spars := valueof(t_SmsPars);
2699 var SMPP_PDU smpp_pdu;
2700 timer T := 3.0;
2701
2702 f_init_handler(pars);
2703
2704 /* Perform location update */
2705 f_perform_lu();
2706
2707 /* MS/UE submits a MO SMS */
2708 f_establish_fully(EST_TYPE_MO_SMS);
2709 f_mo_sms_submit(spars);
2710
2711 /* ESME responds with an error (Invalid Destination Address) */
2712 T.start;
2713 alt {
2714 [] SMPP.receive(tr_SMPP(c_SMPP_command_id_deliver_sm, ESME_ROK, body := ?)) -> value smpp_pdu {
2715 SMPP.send(ts_SMPP_DELIVER_SM_resp(ESME_RINVDSTADR, smpp_pdu.header.seq_num));
2716 }
2717 [] SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK)) { repeat; }
2718 [] T.timeout {
2719 setverdict(fail, "Timeout waiting for SMPP DELIVER-SM");
2720 mtc.stop;
2721 }
2722 }
2723
2724 /* Expect RP-ERROR on BSSAP interface */
2725 spars.exp_rp_err := 1; /* FIXME: GSM411_RP_CAUSE_MO_NUM_UNASSIGNED */
2726 f_mo_sms_wait_rp_ack(spars);
2727
2728 f_expect_clear();
2729}
2730testcase TC_smpp_mo_sms_rp_error() runs on MTC_CT {
2731 var BSC_ConnHdlr vc_conn;
2732 f_init();
2733 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "default-route");
2734 vc_conn := f_start_handler(refers(f_tc_smpp_mo_sms_rp_error), 45);
2735 vc_conn.done;
2736 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "no default-route");
2737}
2738
Harald Weltee13cfb22019-04-23 16:52:02 +02002739
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002740/* Test MO-SMS from MS/BTS/BSC towards HLR (via GSUP) */
Harald Weltee13cfb22019-04-23 16:52:02 +02002741friend function f_tc_gsup_mo_sms(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002742runs on BSC_ConnHdlr {
2743 var SmsParameters spars := valueof(t_SmsPars);
2744 var GSUP_PDU gsup_msg_rx;
2745 var octetstring sm_tpdu;
2746
2747 f_init_handler(pars);
2748
2749 /* We need to inspect GSUP activity */
2750 f_create_gsup_expect(hex2str(g_pars.imsi));
2751
2752 /* Perform location update */
2753 f_perform_lu();
2754
2755 /* Send CM Service Request for SMS */
2756 f_establish_fully(EST_TYPE_MO_SMS);
2757
2758 /* Prepare expected SM-RP-UI (SM TPDU) */
2759 enc_TPDU_RP_DATA_MS_SGSN_fast(
2760 valueof(ts_SMS_SUBMIT(spars.tp.msg_ref,
2761 spars.tp.da, spars.tp.pid, spars.tp.dcs,
2762 spars.tp.udl, spars.tp.ud)),
2763 sm_tpdu);
2764
2765 var template GSUP_PDU mo_forwardSM := tr_GSUP_MO_FORWARD_SM_REQ(
2766 imsi := g_pars.imsi,
2767 sm_rp_mr := spars.rp.msg_ref,
Vadim Yanitskiy04dd5f72019-12-13 15:45:44 +09002768 /* SM-RP-DA: SMSC address */
2769 sm_rp_da := tr_GSUP_SM_RP_DA_SMSC_ADDR(t_GSUP_SM_RP_Addr(
2770 number := spars.rp.smsc_addr.rP_NumberDigits,
2771 npi := spars.rp.smsc_addr.rP_NumberingPlanIdentification,
2772 ton := spars.rp.smsc_addr.rP_TypeOfNumber,
2773 ext := spars.rp.smsc_addr.rP_Ext)),
2774 /* SM-RP-OA: subscriber's MSISDN (filled in by MSC) */
2775 sm_rp_oa := tr_GSUP_SM_RP_OA_MSISDN(t_GSUP_SM_RP_Addr(
2776 number := g_pars.msisdn,
2777 /* NOTE: MSISDN in g_pars lacks this info, assuming defaults */
2778 npi := '0001'B, ton := '001'B, ext := '1'B)),
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002779 /* TODO: can we use decmatch here? */
2780 sm_rp_ui := sm_tpdu
2781 );
2782
2783 /* Submit an SMS on DTAP and expect MO-forwardSM-Req on GSUP */
2784 f_mo_sms_submit(spars);
2785 alt {
2786 [] GSUP.receive(mo_forwardSM) -> value gsup_msg_rx {
Vadim Yanitskiya358dd42020-01-15 10:42:47 +07002787 log("RX MO-forwardSM-Req: ", gsup_msg_rx);
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002788 setverdict(pass);
2789 }
2790 [] GSUP.receive {
2791 log("RX unexpected GSUP message");
2792 setverdict(fail);
2793 mtc.stop;
2794 }
2795 }
2796
2797 /* Trigger RP-ACK by sending MO-forwardSM-Res */
2798 GSUP.send(valueof(ts_GSUP_MO_FORWARD_SM_RES(
2799 imsi := g_pars.imsi,
2800 sm_rp_mr := spars.rp.msg_ref)));
2801 /* Expect RP-ACK on DTAP */
2802 f_mo_sms_wait_rp_ack(spars);
2803
2804 f_expect_clear();
2805}
2806testcase TC_gsup_mo_sms() runs on MTC_CT {
2807 var BSC_ConnHdlr vc_conn;
2808 f_init();
2809 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2810 vc_conn := f_start_handler(refers(f_tc_gsup_mo_sms), 88);
2811 vc_conn.done;
2812 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2813}
2814
Harald Weltee13cfb22019-04-23 16:52:02 +02002815
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07002816/* Test MO-SMMA from MS/BTS/BSC towards HLR (via GSUP) */
Harald Weltee13cfb22019-04-23 16:52:02 +02002817friend function f_tc_gsup_mo_smma(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07002818runs on BSC_ConnHdlr {
2819 var SmsParameters spars := valueof(t_SmsPars);
2820 var GSUP_PDU gsup_msg_rx;
2821
2822 f_init_handler(pars);
2823
2824 /* We need to inspect GSUP activity */
2825 f_create_gsup_expect(hex2str(g_pars.imsi));
2826
2827 /* Perform location update */
2828 f_perform_lu();
2829
2830 /* Send CM Service Request for SMS */
2831 f_establish_fully(EST_TYPE_MO_SMS);
2832
2833 var template GSUP_PDU mo_ReadyForSM := tr_GSUP_MO_READY_FOR_SM_REQ(
2834 imsi := g_pars.imsi,
2835 sm_rp_mr := spars.rp.msg_ref,
2836 sm_alert_rsn := GSUP_SM_ALERT_RSN_TYPE_MEM_AVAIL
2837 );
2838
2839 /* Submit an SMS on DTAP and expect MO-forwardSM-Req on GSUP */
2840 f_mo_smma(spars);
2841 alt {
2842 [] GSUP.receive(mo_ReadyForSM) -> value gsup_msg_rx {
Vadim Yanitskiya358dd42020-01-15 10:42:47 +07002843 log("RX MO-ReadyForSM-Req: ", gsup_msg_rx);
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07002844 setverdict(pass);
2845 }
2846 [] GSUP.receive {
2847 log("RX unexpected GSUP message");
2848 setverdict(fail);
2849 mtc.stop;
2850 }
2851 }
2852
2853 /* Trigger RP-ACK by sending MO-forwardSM-Res */
2854 GSUP.send(valueof(ts_GSUP_MO_READY_FOR_SM_RES(
2855 imsi := g_pars.imsi,
2856 sm_rp_mr := spars.rp.msg_ref)));
2857 /* Expect RP-ACK on DTAP */
2858 f_mo_sms_wait_rp_ack(spars);
2859
2860 f_expect_clear();
2861}
2862testcase TC_gsup_mo_smma() runs on MTC_CT {
2863 var BSC_ConnHdlr vc_conn;
2864 f_init();
2865 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2866 vc_conn := f_start_handler(refers(f_tc_gsup_mo_smma), 89);
2867 vc_conn.done;
2868 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2869}
2870
Harald Weltee13cfb22019-04-23 16:52:02 +02002871
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002872/* Helper for sending MT SMS over GSUP */
2873private function f_gsup_forwardSM_req(SmsParameters spars, OCT1 mms := '00'O)
2874runs on BSC_ConnHdlr {
Vadim Yanitskiya52347c2019-12-12 17:32:33 +09002875 var GSUP_SM_RP_Addr msisdn := valueof(t_GSUP_SM_RP_Addr(g_pars.msisdn));
Vadim Yanitskiy04dd5f72019-12-13 15:45:44 +09002876 var GSUP_SM_RP_Addr smsc := valueof(t_GSUP_SM_RP_Addr(
2877 number := spars.rp.smsc_addr.rP_NumberDigits,
2878 npi := spars.rp.smsc_addr.rP_NumberingPlanIdentification,
2879 ton := spars.rp.smsc_addr.rP_TypeOfNumber,
2880 ext := spars.rp.smsc_addr.rP_Ext));
Vadim Yanitskiya52347c2019-12-12 17:32:33 +09002881
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002882 GSUP.send(ts_GSUP_MT_FORWARD_SM_REQ(
2883 imsi := g_pars.imsi,
2884 /* NOTE: MSC should assign RP-MR itself */
2885 sm_rp_mr := 'FF'O,
Vadim Yanitskiya52347c2019-12-12 17:32:33 +09002886 sm_rp_da := valueof(ts_GSUP_SM_RP_DA_MSISDN(msisdn)),
Vadim Yanitskiy04dd5f72019-12-13 15:45:44 +09002887 sm_rp_oa := valueof(ts_GSUP_SM_RP_OA_SMSC_ADDR(smsc)),
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002888 /* Encoded SMS TPDU (taken from Wireshark)
2889 * FIXME: we should encode spars somehow */
2890 sm_rp_ui := '00068021436500008111328130858200'O,
2891 sm_rp_mms := mms
2892 ));
2893}
2894
2895/* Test successful MT-SMS (RP-ACK) over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002896friend function f_tc_gsup_mt_sms_ack(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002897runs on BSC_ConnHdlr {
2898 var SmsParameters spars := valueof(t_SmsPars);
2899
2900 f_init_handler(pars);
2901
2902 /* We need to inspect GSUP activity */
2903 f_create_gsup_expect(hex2str(g_pars.imsi));
2904
2905 /* Perform location update */
2906 f_perform_lu();
2907
2908 /* Register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002909 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002910
2911 var template GSUP_PDU mt_forwardSM_res := tr_GSUP_MT_FORWARD_SM_RES(
2912 imsi := g_pars.imsi,
2913 /* NOTE: MSC should assign RP-MR itself */
2914 sm_rp_mr := ?
2915 );
2916
2917 /* Submit a MT SMS on GSUP */
2918 f_gsup_forwardSM_req(spars);
2919
2920 /* Expect Paging Request and Establish DTAP / BSSAP / SCCP connection */
Harald Weltee035e3e2019-04-21 17:32:05 +02002921 f_expect_paging();
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002922 f_establish_fully(EST_TYPE_PAG_RESP);
2923
2924 /* Wait for MT SMS on DTAP */
2925 f_mt_sms_expect(spars);
2926
2927 /* Send RP-ACK and expect MT-forwardSM-Res on GSUP */
2928 f_mt_sms_send_rp_ack(spars);
2929 alt {
2930 [] GSUP.receive(mt_forwardSM_res) {
2931 log("RX MT-forwardSM-Res (RP-ACK)");
2932 setverdict(pass);
2933 }
2934 [] GSUP.receive {
2935 log("RX unexpected GSUP message");
2936 setverdict(fail);
2937 mtc.stop;
2938 }
2939 }
2940
2941 f_expect_clear();
2942}
2943testcase TC_gsup_mt_sms_ack() runs on MTC_CT {
2944 var BSC_ConnHdlrPars pars;
2945 var BSC_ConnHdlr vc_conn;
2946 f_init();
2947 pars := f_init_pars(90);
2948 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2949 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_sms_ack), pars);
2950 vc_conn.done;
2951 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2952}
2953
Harald Weltee13cfb22019-04-23 16:52:02 +02002954
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002955/* Test rejected MT-SMS (RP-ERROR) over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002956friend function f_tc_gsup_mt_sms_err(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002957runs on BSC_ConnHdlr {
2958 var SmsParameters spars := valueof(t_SmsPars);
2959 var OCT1 sm_rp_cause := '78'O; /* dummy RP-Cause value */
2960
2961 f_init_handler(pars);
2962
2963 /* We need to inspect GSUP activity */
2964 f_create_gsup_expect(hex2str(g_pars.imsi));
2965
2966 /* Perform location update */
2967 f_perform_lu();
2968
2969 /* Register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002970 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002971
2972 var template GSUP_PDU mt_forwardSM_err := tr_GSUP_MT_FORWARD_SM_ERR(
2973 imsi := g_pars.imsi,
2974 /* NOTE: MSC should assign RP-MR itself */
2975 sm_rp_mr := ?,
2976 sm_rp_cause := sm_rp_cause
2977 );
2978
2979 /* Submit a MT SMS on GSUP */
2980 f_gsup_forwardSM_req(spars);
2981
2982 /* Expect Paging Request and Establish DTAP / BSSAP / SCCP connection */
Harald Weltee035e3e2019-04-21 17:32:05 +02002983 f_expect_paging();
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002984 f_establish_fully(EST_TYPE_PAG_RESP);
2985
2986 /* Wait for MT SMS on DTAP */
2987 f_mt_sms_expect(spars);
2988
2989 /* Send RP-ERROR and expect MT-forwardSM-Err on GSUP */
2990 f_mt_sms_send_rp_error(spars, oct2int(sm_rp_cause));
2991 alt {
2992 [] GSUP.receive(mt_forwardSM_err) {
2993 log("RX MT-forwardSM-Err (RP-ERROR)");
2994 setverdict(pass);
2995 mtc.stop;
2996 }
2997 [] GSUP.receive {
2998 log("RX unexpected GSUP message");
2999 setverdict(fail);
3000 mtc.stop;
3001 }
3002 }
3003
3004 f_expect_clear();
3005}
3006testcase TC_gsup_mt_sms_err() runs on MTC_CT {
3007 var BSC_ConnHdlrPars pars;
3008 var BSC_ConnHdlr vc_conn;
3009 f_init();
3010 pars := f_init_pars(91);
3011 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
3012 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_sms_err), pars);
3013 vc_conn.done;
3014 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
3015}
3016
Harald Weltee13cfb22019-04-23 16:52:02 +02003017
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07003018/* Test SM-RP-MR assignment for MT-SMS over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02003019friend function f_tc_gsup_mt_sms_rp_mr(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07003020runs on BSC_ConnHdlr {
3021 var SmsParameters spars1 := valueof(t_SmsPars); /* 1st SMS */
3022 var SmsParameters spars2 := valueof(t_SmsPars); /* 2nd SMS */
3023
3024 f_init_handler(pars);
3025
3026 /* We need to inspect GSUP activity */
3027 f_create_gsup_expect(hex2str(g_pars.imsi));
3028
3029 /* Perform location update */
3030 f_perform_lu();
3031
3032 /* Register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01003033 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07003034
3035 /* Submit the 1st MT SMS on GSUP */
3036 log("TX MT-forwardSM-Req for the 1st SMS");
3037 f_gsup_forwardSM_req(spars1);
3038
3039 /* Expect Paging Request and Establish DTAP / BSSAP / SCCP connection */
Harald Weltee035e3e2019-04-21 17:32:05 +02003040 f_expect_paging();
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07003041 f_establish_fully(EST_TYPE_PAG_RESP);
3042
3043 /* Wait for 1st MT SMS on DTAP */
3044 f_mt_sms_expect(spars1);
3045 log("RX the 1st SMS on DTAP, DTAP TID is ", spars1.tid,
3046 ", SM-RP-MR is ", spars1.rp.msg_ref);
3047
3048 /* Submit the 2nd MT SMS on GSUP */
3049 log("TX MT-forwardSM-Req for the 2nd SMS");
3050 f_gsup_forwardSM_req(spars2);
3051
3052 /* Wait for 2nd MT SMS on DTAP */
3053 f_mt_sms_expect(spars2);
3054 log("RX the 2nd SMS on DTAP, DTAP TID is ", spars2.tid,
3055 ", SM-RP-MR is ", spars2.rp.msg_ref);
3056
3057 /* Both transaction IDs shall be different */
3058 if (spars1.tid == spars2.tid) {
3059 log("Both DTAP transaction IDs shall be different");
3060 setverdict(fail);
3061 }
3062
3063 /* Both SM-RP-MR values shall be different */
3064 if (spars1.rp.msg_ref == spars2.rp.msg_ref) {
3065 log("Both SM-RP-MR values shall be different");
3066 setverdict(fail);
3067 }
3068
3069 /* Both SM-RP-MR values shall be assigned */
3070 if (spars1.rp.msg_ref == 'FF'O) {
3071 log("Unassigned SM-RP-MR value for the 1st SMS");
3072 setverdict(fail);
3073 }
3074 if (spars2.rp.msg_ref == 'FF'O) {
3075 log("Unassigned SM-RP-MR value for the 2nd SMS");
3076 setverdict(fail);
3077 }
3078
3079 /* Send the 1st RP-ACK and expect MT-forwardSM-Res on GSUP */
3080 f_mt_sms_send_rp_ack(spars1);
3081 alt {
3082 [] GSUP.receive(tr_GSUP_MT_FORWARD_SM_RES(
3083 imsi := g_pars.imsi,
3084 sm_rp_mr := spars1.rp.msg_ref
3085 )) {
3086 log("RX MT-forwardSM-Res (RP-ACK)");
3087 setverdict(pass);
3088 }
3089 [] GSUP.receive {
3090 log("RX unexpected GSUP message");
3091 setverdict(fail);
3092 mtc.stop;
3093 }
3094 }
3095
3096 /* Send the 2nd RP-ACK and expect MT-forwardSM-Res on GSUP */
3097 f_mt_sms_send_rp_ack(spars2);
3098 alt {
3099 [] GSUP.receive(tr_GSUP_MT_FORWARD_SM_RES(
3100 imsi := g_pars.imsi,
3101 sm_rp_mr := spars2.rp.msg_ref
3102 )) {
3103 log("RX MT-forwardSM-Res (RP-ACK)");
3104 setverdict(pass);
3105 }
3106 [] GSUP.receive {
3107 log("RX unexpected GSUP message");
3108 setverdict(fail);
3109 mtc.stop;
3110 }
3111 }
3112
3113 f_expect_clear();
3114}
3115testcase TC_gsup_mt_sms_rp_mr() runs on MTC_CT {
3116 var BSC_ConnHdlrPars pars;
3117 var BSC_ConnHdlr vc_conn;
3118 f_init();
3119 pars := f_init_pars(92);
3120 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
3121 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_sms_rp_mr), pars);
3122 vc_conn.done;
3123 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
3124}
3125
Harald Weltee13cfb22019-04-23 16:52:02 +02003126
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07003127/* Test SM-RP-MR assignment for MT-SMS over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02003128friend function f_tc_gsup_mo_mt_sms_rp_mr(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07003129runs on BSC_ConnHdlr {
3130 var SmsParameters spars_mo := valueof(t_SmsPars); /* MO SMMA */
3131 var SmsParameters spars_mt := valueof(t_SmsPars); /* MT SMS */
3132
3133 f_init_handler(pars);
3134
3135 /* We need to inspect GSUP activity */
3136 f_create_gsup_expect(hex2str(g_pars.imsi));
3137
3138 /* Perform location update */
3139 f_perform_lu();
3140
3141 /* Register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01003142 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07003143
3144 /* Send CM Service Request for MO SMMA */
3145 f_establish_fully(EST_TYPE_MO_SMS);
3146
3147 /* Submit MO SMMA on DTAP */
3148 log("Submit MO SMMA on DTAP, SM-RP-MR is '00'O");
3149 spars_mo.rp.msg_ref := '00'O;
3150 f_mo_smma(spars_mo);
3151
3152 /* Expect MO-forwardSM-Req for MO SMMA on GSUP */
3153 alt {
3154 [] GSUP.receive(tr_GSUP_MO_READY_FOR_SM_REQ(
3155 imsi := g_pars.imsi,
3156 sm_rp_mr := spars_mo.rp.msg_ref,
3157 sm_alert_rsn := GSUP_SM_ALERT_RSN_TYPE_MEM_AVAIL
3158 )) {
3159 log("RX MO-ReadyForSM-Req, SM-RP-MR is '00'O");
3160 setverdict(pass);
3161 }
3162 [] GSUP.receive {
3163 log("RX unexpected GSUP message");
3164 setverdict(fail);
3165 mtc.stop;
3166 }
3167 }
3168
3169 /* Submit MT SMS on GSUP */
3170 log("TX MT-forwardSM-Req for the MT SMS");
3171 f_gsup_forwardSM_req(spars_mt);
3172
3173 /* Wait for MT SMS on DTAP */
3174 f_mt_sms_expect(spars_mt);
3175 log("RX MT SMS on DTAP, DTAP TID is ", spars_mt.tid,
3176 ", SM-RP-MR is ", spars_mt.rp.msg_ref);
3177
3178 /* Both SM-RP-MR values shall be different */
3179 if (spars_mo.rp.msg_ref == spars_mt.rp.msg_ref) {
3180 log("Both SM-RP-MR values shall be different");
3181 setverdict(fail);
3182 }
3183
3184 /* SM-RP-MR value for MT SMS shall be assigned */
3185 if (spars_mt.rp.msg_ref == 'FF'O) {
3186 log("Unassigned SM-RP-MR value for the MT SMS");
3187 setverdict(fail);
3188 }
3189
3190 /* Trigger RP-ACK for MO SMMA by sending MO-forwardSM-Res */
3191 GSUP.send(valueof(ts_GSUP_MO_READY_FOR_SM_RES(
3192 imsi := g_pars.imsi,
3193 sm_rp_mr := spars_mo.rp.msg_ref)));
3194 /* Expect RP-ACK for MO SMMA on DTAP */
3195 f_mo_sms_wait_rp_ack(spars_mo);
3196
3197 /* Send RP-ACK for MT SMS and expect MT-forwardSM-Res on GSUP */
3198 f_mt_sms_send_rp_ack(spars_mt);
3199 alt {
3200 [] GSUP.receive(tr_GSUP_MT_FORWARD_SM_RES(
3201 imsi := g_pars.imsi,
3202 sm_rp_mr := spars_mt.rp.msg_ref
3203 )) {
3204 log("RX MT-forwardSM-Res (RP-ACK)");
3205 setverdict(pass);
3206 }
3207 [] GSUP.receive {
3208 log("RX unexpected GSUP message");
3209 setverdict(fail);
3210 mtc.stop;
3211 }
3212 }
3213
3214 f_expect_clear();
3215}
3216testcase TC_gsup_mo_mt_sms_rp_mr() runs on MTC_CT {
3217 var BSC_ConnHdlrPars pars;
3218 var BSC_ConnHdlr vc_conn;
3219 f_init();
3220 pars := f_init_pars(93);
3221 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
3222 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mo_mt_sms_rp_mr), pars);
3223 vc_conn.done;
3224 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
3225}
3226
Harald Weltee13cfb22019-04-23 16:52:02 +02003227
Vadim Yanitskiy1cd11a02018-12-03 02:43:35 +07003228/* Test multi-part MT-SMS over GSUP */
3229private function f_tc_gsup_mt_multi_part_sms(charstring id, BSC_ConnHdlrPars pars)
3230runs on BSC_ConnHdlr {
3231 var SmsParameters spars := valueof(t_SmsPars);
3232
3233 f_init_handler(pars);
3234
3235 /* We need to inspect GSUP activity */
3236 f_create_gsup_expect(hex2str(g_pars.imsi));
3237
3238 /* Perform location update */
3239 f_perform_lu();
3240
3241 /* Register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01003242 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy1cd11a02018-12-03 02:43:35 +07003243
3244 var template GSUP_PDU mt_forwardSM_res := tr_GSUP_MT_FORWARD_SM_RES(
3245 imsi := g_pars.imsi,
3246 /* NOTE: MSC should assign RP-MR itself */
3247 sm_rp_mr := ?
3248 );
3249
3250 /* Send 4 messages (NOTE: SM-RP-UI remains unchanged) */
3251 for (var integer i := 3; i >= 0; i := i-1) {
3252 /* Submit a MT SMS on GSUP (MMS is decremented) */
3253 f_gsup_forwardSM_req(spars, int2oct(i, 1));
3254
3255 /* Expect Paging Request and Establish connection */
3256 if (i == 3) { /* ... only once! */
Harald Weltee13cfb22019-04-23 16:52:02 +02003257 f_expect_paging();
Vadim Yanitskiy1cd11a02018-12-03 02:43:35 +07003258 f_establish_fully(EST_TYPE_PAG_RESP);
3259 }
3260
3261 /* Wait for MT SMS on DTAP */
3262 f_mt_sms_expect(spars);
3263
3264 /* Send RP-ACK and expect MT-forwardSM-Res on GSUP */
3265 f_mt_sms_send_rp_ack(spars);
3266 alt {
3267 [] GSUP.receive(mt_forwardSM_res) {
3268 log("RX MT-forwardSM-Res (RP-ACK)");
3269 setverdict(pass);
3270 }
3271 [] GSUP.receive {
3272 log("RX unexpected GSUP message");
3273 setverdict(fail);
3274 mtc.stop;
3275 }
3276 }
3277
3278 /* Keep some 'distance' between transmissions */
3279 f_sleep(1.5);
3280 }
3281
3282 f_expect_clear();
3283}
3284testcase TC_gsup_mt_multi_part_sms() runs on MTC_CT {
3285 var BSC_ConnHdlrPars pars;
3286 var BSC_ConnHdlr vc_conn;
3287 f_init();
3288 pars := f_init_pars(91);
3289 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
3290 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_multi_part_sms), pars);
3291 vc_conn.done;
3292 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
3293}
3294
Harald Weltef640a012018-04-14 17:49:21 +02003295/* convert GSM L3 TON to SMPP_TON enum */
3296function f_sm_ton_from_gsm(BIT3 ton) return SMPP_TON {
3297 select (ton) {
3298 case ('000'B) { return unknown; }
3299 case ('001'B) { return international; }
3300 case ('010'B) { return national; }
3301 case ('011'B) { return network_specific; }
3302 case ('100'B) { return subscriber_number; }
3303 case ('101'B) { return alphanumeric; }
3304 case ('110'B) { return abbreviated; }
3305 }
3306 setverdict(fail, "Unknown TON ", ton);
Daniel Willmannafce8662018-07-06 23:11:32 +02003307 mtc.stop;
Harald Weltef640a012018-04-14 17:49:21 +02003308}
3309/* convert GSM L3 NPI to SMPP_NPI enum */
3310function f_sm_npi_from_gsm(BIT4 npi) return SMPP_NPI {
3311 select (npi) {
3312 case ('0000'B) { return unknown; }
3313 case ('0001'B) { return isdn; }
3314 case ('0011'B) { return data; }
3315 case ('0100'B) { return telex; }
3316 case ('0110'B) { return land_mobile; }
3317 case ('1000'B) { return national; }
3318 case ('1001'B) { return private_; }
3319 case ('1010'B) { return ermes; }
3320 }
3321 setverdict(fail, "Unknown NPI ", npi);
Daniel Willmannafce8662018-07-06 23:11:32 +02003322 mtc.stop;
Harald Weltef640a012018-04-14 17:49:21 +02003323}
3324
3325/* build a SMPP_SM from SmsParameters */
3326function f_mt_sm_from_spars(SmsParameters spars)
3327runs on BSC_ConnHdlr return SMPP_SM {
3328 var SMPP_SM sm := {
3329 service_type := "CMT",
3330 source_addr_ton := f_sm_ton_from_gsm(spars.tp.da.tP_DA_NoPad.tP_TypeOfNumber),
3331 source_addr_npi := f_sm_npi_from_gsm(spars.tp.da.tP_DA_NoPad.tP_NumberingPlanID),
3332 source_addr := hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue),
3333 dest_addr_ton := international,
3334 dest_addr_npi := isdn,
3335 destination_addr := hex2str(g_pars.msisdn),
3336 esm_class := '00000001'B,
3337 protocol_id := 0,
3338 priority_flag := 0,
3339 schedule_delivery_time := "",
3340 validity_period := "",
3341 registered_delivery := '00000000'B,
3342 replace_if_present := 0,
3343 data_coding := '00000001'B,
3344 sm_default_msg_id := 0,
3345 sm_length := spars.tp.udl,
3346 short_message := spars.tp.ud,
3347 opt_pars := {}
3348 };
3349 return sm;
3350}
3351
3352/* helper function to encode SMS from 'spars', send it via SMPP to MSC; receive it on MS side */
3353private function f_smpp_mt_sms(SmsParameters spars, boolean trans_mode) runs on BSC_ConnHdlr {
3354 var SMPP_SM sm := f_mt_sm_from_spars(spars);
3355 if (trans_mode) {
3356 sm.esm_class := '00000010'B;
3357 }
3358
3359 /* actually cause MSC to send a SMS via SUBMIT-SM from SMPP side */
3360 SMPP.send(ts_SMPP_SUBMIT_SM(sm));
3361 if (not match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
3362 /* if we're not in SMPP transaction mode, we expect the SMPP-level ACK
3363 * before we expect the SMS delivery on the BSC/radio side */
3364 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
3365 }
3366
3367 /* MSC->BSC: expect PAGING from MSC */
Harald Weltee035e3e2019-04-21 17:32:05 +02003368 f_expect_paging();
Harald Weltef640a012018-04-14 17:49:21 +02003369 /* Establish DTAP / BSSAP / SCCP connection */
3370 f_establish_fully(EST_TYPE_PAG_RESP);
3371 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
3372
3373 f_mt_sms(spars);
3374
3375 if (match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
3376 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
3377 }
3378 f_expect_clear();
3379}
3380
3381/* mobile terminated SMS, from SMPP to BSC/BTS/MS */
3382private function f_tc_smpp_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
3383 f_init_handler(pars);
3384
3385 /* Perform location update so IMSI is known + registered in MSC/VLR */
3386 f_perform_lu();
3387 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
3388
3389 /* register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01003390 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Harald Weltef640a012018-04-14 17:49:21 +02003391
3392 var SmsParameters spars := valueof(t_SmsPars);
3393 /* TODO: test with more intelligent user data; test different coding schemes */
3394 spars.tp.ud := '00'O;
3395 spars.tp.udl := 1;
3396
3397 /* first test the non-transaction store+forward mode */
3398 f_smpp_mt_sms(spars, false);
3399
3400 /* then test the transaction mode */
3401 f_smpp_mt_sms(spars, true);
3402}
3403testcase TC_smpp_mt_sms() runs on MTC_CT {
3404 var BSC_ConnHdlr vc_conn;
3405 f_init();
3406 vc_conn := f_start_handler(refers(f_tc_smpp_mt_sms), 45);
3407 vc_conn.done;
3408}
3409
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003410/***********************************************************************
3411 * USSD Testing
3412 ***********************************************************************/
3413
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003414private altstep as_unexp_gsup_or_bssap_msg()
3415runs on BSC_ConnHdlr {
3416 [] GSUP.receive {
3417 setverdict(fail, "Unknown/unexpected GSUP received");
3418 self.stop;
3419 }
3420 [] BSSAP.receive {
3421 setverdict(fail, "Unknown/unexpected BSSAP message received");
3422 self.stop;
3423 }
3424}
3425
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003426private function f_expect_gsup_msg(template GSUP_PDU msg,
3427 float T_val := 2.0)
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003428runs on BSC_ConnHdlr return GSUP_PDU {
3429 var GSUP_PDU gsup_msg_complete;
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003430 timer T := T_val;
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003431
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003432 T.start;
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003433 alt {
3434 [] GSUP.receive(msg) -> value gsup_msg_complete {
3435 setverdict(pass);
3436 }
3437 /* We don't expect anything else */
3438 [] as_unexp_gsup_or_bssap_msg();
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003439 [] T.timeout {
3440 setverdict(fail, "Timeout waiting for GSUP message: ", msg);
3441 }
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003442 }
3443
3444 return gsup_msg_complete;
3445}
3446
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003447private function f_expect_mt_dtap_msg(template PDU_ML3_NW_MS msg,
3448 float T_val := 2.0)
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003449runs on BSC_ConnHdlr return PDU_ML3_NW_MS {
3450 var PDU_DTAP_MT bssap_msg_complete;
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003451 timer T := T_val;
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003452
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003453 T.start;
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003454 alt {
3455 [] BSSAP.receive(tr_PDU_DTAP_MT(msg)) -> value bssap_msg_complete {
3456 setverdict(pass);
3457 }
3458 /* We don't expect anything else */
3459 [] as_unexp_gsup_or_bssap_msg();
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003460 [] T.timeout {
3461 setverdict(fail, "Timeout waiting for BSSAP message: ", msg);
3462 }
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003463 }
3464
3465 return bssap_msg_complete.dtap;
3466}
3467
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003468/* LU followed by MO USSD request */
Harald Weltee13cfb22019-04-23 16:52:02 +02003469friend function f_tc_lu_and_mo_ussd_single_request(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003470runs on BSC_ConnHdlr {
3471 f_init_handler(pars);
3472
3473 /* Perform location update */
3474 f_perform_lu();
3475
3476 /* Send CM Service Request for SS/USSD */
3477 f_establish_fully(EST_TYPE_SS_ACT);
3478
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003479 /* We need to inspect GSUP activity */
3480 f_create_gsup_expect(hex2str(g_pars.imsi));
3481
3482 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3483 invoke_id := 5, /* Phone may not start from 0 or 1 */
3484 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3485 ussd_string := "*#100#"
3486 );
3487
3488 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
3489 invoke_id := 5, /* InvokeID shall be the same for both REQ and RSP */
3490 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3491 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
3492 )
3493
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003494 /* Compose a new SS/REGISTER message with request */
3495 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
3496 tid := 1, /* We just need a single transaction */
3497 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003498 facility := valueof(facility_req)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003499 );
3500
3501 /* Compose SS/RELEASE_COMPLETE template with expected response */
3502 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
3503 tid := 1, /* Response should arrive within the same transaction */
3504 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003505 facility := valueof(facility_rsp)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003506 );
3507
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003508 /* Compose expected MSC -> HLR message */
3509 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
3510 imsi := g_pars.imsi,
3511 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3512 ss := valueof(facility_req)
3513 );
3514
3515 /* To be used for sending response with correct session ID */
3516 var GSUP_PDU gsup_req_complete;
3517
3518 /* Request own number */
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003519 BSSAP.send(ts_PDU_DTAP_MO(ussd_req));
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003520 /* Expect GSUP message containing the SS payload */
3521 gsup_req_complete := f_expect_gsup_msg(gsup_req);
3522
3523 /* Compose the response from HLR using received session ID */
3524 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
3525 imsi := g_pars.imsi,
3526 sid := gsup_req_complete.ies[1].val.session_id,
3527 state := OSMO_GSUP_SESSION_STATE_END,
3528 ss := valueof(facility_rsp)
3529 );
3530
3531 /* Finally, HLR terminates the session */
3532 GSUP.send(gsup_rsp);
3533 /* Expect RELEASE_COMPLETE message with the response */
3534 f_expect_mt_dtap_msg(ussd_rsp);
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003535
3536 f_expect_clear();
3537}
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003538testcase TC_lu_and_mo_ussd_single_request() runs on MTC_CT {
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003539 var BSC_ConnHdlr vc_conn;
3540 f_init();
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003541 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_single_request), 46);
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003542 vc_conn.done;
3543}
3544
Harald Weltee13cfb22019-04-23 16:52:02 +02003545
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003546/* LU followed by MT USSD notification */
Harald Weltee13cfb22019-04-23 16:52:02 +02003547friend function f_tc_lu_and_mt_ussd_notification(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003548runs on BSC_ConnHdlr {
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003549 timer T := 5.0;
3550
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003551 f_init_handler(pars);
3552
3553 /* Perform location update */
3554 f_perform_lu();
3555
Harald Welte6811d102019-04-14 22:23:14 +02003556 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003557
3558 /* We need to inspect GSUP activity */
3559 f_create_gsup_expect(hex2str(g_pars.imsi));
3560
3561 /* Facility IE with network-originated USSD notification */
3562 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3563 op_code := SS_OP_CODE_USS_NOTIFY,
3564 ussd_string := "Mahlzeit!"
3565 );
3566
3567 /* Facility IE with acknowledgment to the USSD notification */
3568 var template OCTN facility_rsp := enc_SS_FacilityInformation(
3569 /* In case of USSD notification, Return Result is empty */
3570 valueof(ts_SS_USSD_FACILITY_RETURN_RESULT_EMPTY())
3571 );
3572
3573 /* Compose a new MT SS/REGISTER message with USSD notification */
3574 var template PDU_ML3_NW_MS ussd_ntf := tr_ML3_MT_SS_REGISTER(
3575 tid := 0, /* FIXME: most likely, it should be 0 */
3576 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3577 facility := valueof(facility_req)
3578 );
3579
3580 /* Compose HLR -> MSC GSUP message */
3581 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
3582 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003583 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003584 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3585 ss := valueof(facility_req)
3586 );
3587
3588 /* Send it to MSC and expect Paging Request */
3589 GSUP.send(gsup_req);
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003590 T.start;
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003591 alt {
Harald Weltee13cfb22019-04-23 16:52:02 +02003592 [pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
3593 setverdict(pass);
3594 }
Harald Welte62113fc2019-05-09 13:04:02 +02003595 [not pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003596 setverdict(pass);
3597 }
3598 /* We don't expect anything else */
3599 [] as_unexp_gsup_or_bssap_msg();
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003600 [] T.timeout {
3601 setverdict(fail, "Timeout waiting for Paging Request");
3602 }
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003603 }
3604
3605 /* Send Paging Response and expect USSD notification */
3606 f_establish_fully(EST_TYPE_PAG_RESP);
3607 /* Expect MT REGISTER message with USSD notification */
3608 f_expect_mt_dtap_msg(ussd_ntf);
3609
3610 /* Compose a new MO SS/FACILITY message with empty response */
3611 var template (value) PDU_ML3_MS_NW ussd_rsp := ts_ML3_MO_SS_FACILITY(
3612 tid := 0, /* FIXME: it shall match the request tid */
3613 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3614 facility := valueof(facility_rsp)
3615 );
3616
3617 /* Compose expected MSC -> HLR GSUP message */
3618 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_REQ(
3619 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003620 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003621 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
3622 ss := valueof(facility_rsp)
3623 );
3624
3625 /* MS sends response to the notification */
3626 BSSAP.send(ts_PDU_DTAP_MO(ussd_rsp));
3627 /* Expect GSUP message containing the SS payload */
3628 f_expect_gsup_msg(gsup_rsp);
3629
3630 /* Compose expected MT SS/RELEASE COMPLETE message */
3631 var template PDU_ML3_NW_MS ussd_term := tr_ML3_MT_SS_RELEASE_COMPLETE(
3632 tid := 0, /* FIXME: it shall match the request tid */
3633 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3634 facility := omit
3635 );
3636
3637 /* Compose MSC -> HLR GSUP message */
3638 var template GSUP_PDU gsup_term := ts_GSUP_PROC_SS_REQ(
3639 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003640 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003641 state := OSMO_GSUP_SESSION_STATE_END
3642 );
3643
3644 /* Finally, HLR terminates the session */
3645 GSUP.send(gsup_term)
3646 /* Expect MT RELEASE COMPLETE without Facility IE */
3647 f_expect_mt_dtap_msg(ussd_term);
3648
3649 f_expect_clear();
3650}
3651testcase TC_lu_and_mt_ussd_notification() runs on MTC_CT {
3652 var BSC_ConnHdlr vc_conn;
3653 f_init();
3654 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_ussd_notification), 47);
3655 vc_conn.done;
3656}
3657
Harald Weltee13cfb22019-04-23 16:52:02 +02003658
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003659/* LU followed by MT call and MO USSD request during this call */
Harald Weltee13cfb22019-04-23 16:52:02 +02003660friend function f_tc_lu_and_mo_ussd_during_mt_call(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003661runs on BSC_ConnHdlr {
3662 f_init_handler(pars);
3663
3664 /* Call parameters taken from f_tc_lu_and_mt_call */
3665 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003666
3667 /* Perform location update */
3668 f_perform_lu();
3669
3670 /* Establish a MT call */
3671 f_mt_call_establish(cpars);
3672
3673 /* Hold the call for some time */
3674 f_sleep(1.0);
3675
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003676 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3677 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3678 ussd_string := "*#100#"
3679 );
3680
3681 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
3682 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3683 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
3684 )
3685
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003686 /* Compose a new SS/REGISTER message with request */
3687 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
3688 tid := 1, /* We just need a single transaction */
3689 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003690 facility := valueof(facility_req)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003691 );
3692
3693 /* Compose SS/RELEASE_COMPLETE template with expected response */
3694 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
3695 tid := 1, /* Response should arrive within the same transaction */
3696 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003697 facility := valueof(facility_rsp)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003698 );
3699
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003700 /* Compose expected MSC -> HLR message */
3701 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
3702 imsi := g_pars.imsi,
3703 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3704 ss := valueof(facility_req)
3705 );
3706
3707 /* To be used for sending response with correct session ID */
3708 var GSUP_PDU gsup_req_complete;
3709
3710 /* Request own number */
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003711 BSSAP.send(ts_PDU_DTAP_MO(ussd_req));
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003712 /* Expect GSUP message containing the SS payload */
3713 gsup_req_complete := f_expect_gsup_msg(gsup_req);
3714
3715 /* Compose the response from HLR using received session ID */
3716 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
3717 imsi := g_pars.imsi,
3718 sid := gsup_req_complete.ies[1].val.session_id,
3719 state := OSMO_GSUP_SESSION_STATE_END,
3720 ss := valueof(facility_rsp)
3721 );
3722
3723 /* Finally, HLR terminates the session */
3724 GSUP.send(gsup_rsp);
3725 /* Expect RELEASE_COMPLETE message with the response */
3726 f_expect_mt_dtap_msg(ussd_rsp);
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003727
3728 /* Hold the call for some time */
3729 f_sleep(1.0);
3730
3731 /* Release the call (does Clear Complete itself) */
3732 f_call_hangup(cpars, true);
3733}
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003734testcase TC_lu_and_mo_ussd_during_mt_call() runs on MTC_CT {
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003735 var BSC_ConnHdlr vc_conn;
3736 f_init();
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003737 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_during_mt_call), 48);
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003738 vc_conn.done;
3739}
3740
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003741/* BSSMAP Clear Request in the middle of a call, see OS#3062 */
Harald Weltee13cfb22019-04-23 16:52:02 +02003742friend function f_tc_mo_cc_bssmap_clear(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003743 f_init_handler(pars);
3744 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02003745 cpars.ran_clear_when_alerting := true;
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003746
3747 f_perform_lu();
3748
Neels Hofmeyrde76f052019-02-26 05:02:46 +01003749 var default ccrel := activate(as_optional_cc_rel(cpars));
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02003750 f_mo_call_establish(cpars);
3751 f_expect_clear()
Neels Hofmeyrde76f052019-02-26 05:02:46 +01003752 deactivate(ccrel);
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003753
3754 f_sleep(1.0);
3755}
3756testcase TC_mo_cc_bssmap_clear() runs on MTC_CT {
3757 var BSC_ConnHdlr vc_conn;
3758 f_init();
3759
3760 vc_conn := f_start_handler(refers(f_tc_mo_cc_bssmap_clear), 43);
3761 vc_conn.done;
3762}
3763
Harald Weltee13cfb22019-04-23 16:52:02 +02003764
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003765/* LU followed by MT call and MT USSD request during this call */
Harald Weltee13cfb22019-04-23 16:52:02 +02003766friend function f_tc_lu_and_mt_ussd_during_mt_call(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003767runs on BSC_ConnHdlr {
3768 f_init_handler(pars);
3769
3770 /* Call parameters taken from f_tc_lu_and_mt_call */
3771 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003772
3773 /* Perform location update */
3774 f_perform_lu();
3775
3776 /* Establish a MT call */
3777 f_mt_call_establish(cpars);
3778
3779 /* Hold the call for some time */
3780 f_sleep(1.0);
3781
3782 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3783 op_code := SS_OP_CODE_USS_REQUEST,
3784 ussd_string := "Please type anything..."
3785 );
3786
3787 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
3788 op_code := SS_OP_CODE_USS_REQUEST,
3789 ussd_string := "Nope."
3790 )
3791
3792 /* Compose MT SS/REGISTER message with network-originated request */
3793 var template (value) PDU_ML3_NW_MS ussd_req := ts_ML3_MT_SS_REGISTER(
3794 tid := 0, /* FIXME: most likely, it should be 0 */
3795 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3796 facility := valueof(facility_req)
3797 );
3798
3799 /* Compose HLR -> MSC GSUP message */
3800 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
3801 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003802 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003803 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3804 ss := valueof(facility_req)
3805 );
3806
3807 /* Send it to MSC */
3808 GSUP.send(gsup_req);
3809 /* Expect MT REGISTER message with USSD request */
3810 f_expect_mt_dtap_msg(ussd_req);
3811
3812 /* Compose a new MO SS/FACILITY message with response */
3813 var template (value) PDU_ML3_MS_NW ussd_rsp := ts_ML3_MO_SS_FACILITY(
3814 tid := 0, /* FIXME: it shall match the request tid */
3815 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3816 facility := valueof(facility_rsp)
3817 );
3818
3819 /* Compose expected MSC -> HLR GSUP message */
3820 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_REQ(
3821 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003822 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003823 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
3824 ss := valueof(facility_rsp)
3825 );
3826
3827 /* MS sends response */
3828 BSSAP.send(ts_PDU_DTAP_MO(ussd_rsp));
3829 f_expect_gsup_msg(gsup_rsp);
3830
3831 /* Compose expected MT SS/RELEASE COMPLETE message */
3832 var template PDU_ML3_NW_MS ussd_term := tr_ML3_MT_SS_RELEASE_COMPLETE(
3833 tid := 0, /* FIXME: it shall match the request tid */
3834 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3835 facility := omit
3836 );
3837
3838 /* Compose MSC -> HLR GSUP message */
3839 var template GSUP_PDU gsup_term := ts_GSUP_PROC_SS_REQ(
3840 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003841 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003842 state := OSMO_GSUP_SESSION_STATE_END
3843 );
3844
3845 /* Finally, HLR terminates the session */
3846 GSUP.send(gsup_term);
3847 /* Expect MT RELEASE COMPLETE without Facility IE */
3848 f_expect_mt_dtap_msg(ussd_term);
3849
3850 /* Hold the call for some time */
3851 f_sleep(1.0);
3852
3853 /* Release the call (does Clear Complete itself) */
3854 f_call_hangup(cpars, true);
3855}
3856testcase TC_lu_and_mt_ussd_during_mt_call() runs on MTC_CT {
3857 var BSC_ConnHdlr vc_conn;
3858 f_init();
3859 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_ussd_during_mt_call), 49);
3860 vc_conn.done;
3861}
3862
Harald Weltee13cfb22019-04-23 16:52:02 +02003863
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07003864/* LU followed by MO USSD request and MO Release during transaction */
Harald Weltee13cfb22019-04-23 16:52:02 +02003865friend function f_tc_lu_and_mo_ussd_mo_release(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07003866runs on BSC_ConnHdlr {
3867 f_init_handler(pars);
3868
3869 /* Perform location update */
3870 f_perform_lu();
3871
3872 /* Send CM Service Request for SS/USSD */
3873 f_establish_fully(EST_TYPE_SS_ACT);
3874
3875 /* We need to inspect GSUP activity */
3876 f_create_gsup_expect(hex2str(g_pars.imsi));
3877
3878 var template OCTN facility_ms_req := f_USSD_FACILITY_IE_INVOKE(
3879 invoke_id := 1, /* Initial request */
3880 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3881 ussd_string := "*6766*266#"
3882 );
3883
3884 var template OCTN facility_net_req := f_USSD_FACILITY_IE_INVOKE(
3885 invoke_id := 2, /* Counter request */
3886 op_code := SS_OP_CODE_USS_REQUEST,
3887 ussd_string := "Password?!?"
3888 )
3889
3890 /* Compose MO SS/REGISTER message with request */
3891 var template (value) PDU_ML3_MS_NW ussd_ms_req := ts_ML3_MO_SS_REGISTER(
3892 tid := 1, /* We just need a single transaction */
3893 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3894 facility := valueof(facility_ms_req)
3895 );
3896
3897 /* Compose expected MSC -> HLR message */
3898 var template GSUP_PDU gsup_ms_req := tr_GSUP_PROC_SS_REQ(
3899 imsi := g_pars.imsi,
3900 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3901 ss := valueof(facility_ms_req)
3902 );
3903
3904 /* To be used for sending response with correct session ID */
3905 var GSUP_PDU gsup_ms_req_complete;
3906
3907 /* Initiate a new transaction */
3908 BSSAP.send(ts_PDU_DTAP_MO(ussd_ms_req));
3909 /* Expect GSUP request with original Facility IE */
3910 gsup_ms_req_complete := f_expect_gsup_msg(gsup_ms_req);
3911
3912 /* Compose the response from HLR using received session ID */
3913 var template (value) GSUP_PDU gsup_net_req := ts_GSUP_PROC_SS_REQ(
3914 imsi := g_pars.imsi,
3915 sid := gsup_ms_req_complete.ies[1].val.session_id,
3916 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
3917 ss := valueof(facility_net_req)
3918 );
3919
3920 /* Compose expected MT SS/FACILITY template with counter request */
3921 var template PDU_ML3_NW_MS ussd_net_req := tr_ML3_MT_SS_FACILITY(
3922 tid := 1, /* Response should arrive within the same transaction */
3923 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3924 facility := valueof(facility_net_req)
3925 );
3926
3927 /* Send response over GSUP */
3928 GSUP.send(gsup_net_req);
3929 /* Expect MT SS/FACILITY message with counter request */
3930 f_expect_mt_dtap_msg(ussd_net_req);
3931
3932 /* Compose MO SS/RELEASE COMPLETE */
3933 var template (value) PDU_ML3_MS_NW ussd_abort := ts_ML3_MO_SS_RELEASE_COMPLETE(
3934 tid := 1, /* Response should arrive within the same transaction */
3935 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3936 facility := omit
3937 /* TODO: cause? */
3938 );
3939
3940 /* Compose expected HLR -> MSC abort message */
3941 var template GSUP_PDU gsup_abort := tr_GSUP_PROC_SS_REQ(
3942 imsi := g_pars.imsi,
3943 sid := gsup_ms_req_complete.ies[1].val.session_id,
3944 state := OSMO_GSUP_SESSION_STATE_END
3945 );
3946
3947 /* Abort transaction */
3948 BSSAP.send(ts_PDU_DTAP_MO(ussd_abort));
3949 /* Expect GSUP message indicating abort */
3950 f_expect_gsup_msg(gsup_abort);
3951
3952 f_expect_clear();
3953}
3954testcase TC_lu_and_mo_ussd_mo_release() runs on MTC_CT {
3955 var BSC_ConnHdlr vc_conn;
3956 f_init();
3957 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_mo_release), 50);
3958 vc_conn.done;
3959}
3960
Harald Weltee13cfb22019-04-23 16:52:02 +02003961
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003962/* LU followed by MO USSD request and MT Release due to timeout */
Harald Weltee13cfb22019-04-23 16:52:02 +02003963friend function f_tc_lu_and_ss_session_timeout(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003964runs on BSC_ConnHdlr {
3965 f_init_handler(pars);
3966
3967 /* Perform location update */
3968 f_perform_lu();
3969
3970 /* Send CM Service Request for SS/USSD */
3971 f_establish_fully(EST_TYPE_SS_ACT);
3972
3973 /* We need to inspect GSUP activity */
3974 f_create_gsup_expect(hex2str(g_pars.imsi));
3975
3976 var template OCTN facility_ms_req := f_USSD_FACILITY_IE_INVOKE(
3977 invoke_id := 1,
3978 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3979 ussd_string := "#release_me");
3980
3981 /* Compose MO SS/REGISTER message with request */
3982 var template (value) PDU_ML3_MS_NW ussd_ms_req := ts_ML3_MO_SS_REGISTER(
3983 tid := 1, /* An arbitrary transaction identifier */
3984 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3985 facility := valueof(facility_ms_req));
3986
3987 /* Compose expected MSC -> HLR message */
3988 var template GSUP_PDU gsup_ms_req := tr_GSUP_PROC_SS_REQ(
3989 imsi := g_pars.imsi,
3990 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3991 ss := valueof(facility_ms_req));
3992
3993 /* To be used for sending response with correct session ID */
3994 var GSUP_PDU gsup_ms_req_complete;
3995
3996 /* Initiate a new SS transaction */
3997 BSSAP.send(ts_PDU_DTAP_MO(ussd_ms_req));
3998 /* Expect GSUP request with original Facility IE */
3999 gsup_ms_req_complete := f_expect_gsup_msg(gsup_ms_req);
4000
4001 /* Don't respond, wait for timeout */
4002 f_sleep(3.0);
4003
4004 var template PDU_ML3_NW_MS dtap_rel := tr_ML3_MT_SS_RELEASE_COMPLETE(
4005 tid := 1, /* Should match the request's tid */
4006 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
4007 cause := *, /* TODO: expect some specific value */
4008 facility := omit);
4009
4010 var template GSUP_PDU gsup_rel := tr_GSUP_PROC_SS_ERR(
4011 imsi := g_pars.imsi,
4012 sid := gsup_ms_req_complete.ies[1].val.session_id,
4013 state := OSMO_GSUP_SESSION_STATE_END,
4014 cause := ?); /* TODO: expect some specific value */
4015
4016 /* Expect release on both interfaces */
4017 interleave {
4018 [] BSSAP.receive(tr_PDU_DTAP_MT(dtap_rel)) { };
4019 [] GSUP.receive(gsup_rel) { };
4020 }
4021
4022 f_expect_clear();
4023 setverdict(pass);
4024}
4025testcase TC_lu_and_ss_session_timeout() runs on MTC_CT {
4026 var BSC_ConnHdlr vc_conn;
4027 f_init();
Vadim Yanitskiy36d28dd2018-12-03 02:45:45 +07004028 f_vty_config(MSCVTY, "msc", "ncss guard-timeout 3");
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07004029 vc_conn := f_start_handler(refers(f_tc_lu_and_ss_session_timeout), 51);
4030 vc_conn.done;
Vadim Yanitskiy36d28dd2018-12-03 02:45:45 +07004031 f_vty_config(MSCVTY, "msc", "ncss guard-timeout 0");
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07004032}
4033
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07004034/* MT (network-originated) USSD for unknown subscriber */
4035friend function f_tc_mt_ussd_for_unknown_subscr(charstring id, BSC_ConnHdlrPars pars)
4036runs on BSC_ConnHdlr {
4037 var hexstring imsi := '000000000000000'H; /* Some unknown IMSI */
4038 var OCT4 sid := '20000222'O;
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07004039
4040 f_init_handler(pars);
4041 f_ran_register_imsi(imsi, 'FFFFFFFF'O);
4042 f_create_gsup_expect(hex2str(imsi));
4043
4044 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
4045 imsi := imsi,
4046 sid := sid,
4047 state := OSMO_GSUP_SESSION_STATE_BEGIN,
4048 ss := f_rnd_octstring(23)
4049 );
4050
4051 /* Error with cause GMM_CAUSE_IMSI_UNKNOWN */
4052 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_ERR(
4053 imsi := imsi,
4054 sid := sid,
4055 state := OSMO_GSUP_SESSION_STATE_END,
4056 cause := 2 /* FIXME: introduce an enumerated type! */
4057 );
4058
4059 /* Initiate a MT USSD notification */
4060 GSUP.send(gsup_req);
4061
4062 /* Expect GSUP PROC_SS_ERROR message */
Vadim Yanitskiy851798c2019-06-15 14:22:28 +07004063 f_expect_gsup_msg(gsup_rsp);
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07004064}
4065testcase TC_mt_ussd_for_unknown_subscr() runs on MTC_CT {
4066 var BSC_ConnHdlr vc_conn;
4067 f_init();
4068 vc_conn := f_start_handler(refers(f_tc_mt_ussd_for_unknown_subscr), 0);
4069 vc_conn.done;
4070}
4071
Vadim Yanitskiyc3c07d42019-06-17 23:00:44 +07004072/* MO (mobile-originated) SS/USSD for unknown transaction */
4073friend function f_tc_mo_ussd_for_unknown_trans(charstring id, BSC_ConnHdlrPars pars)
4074runs on BSC_ConnHdlr {
4075 f_init_handler(pars);
4076
Vadim Yanitskiy70d15bf2020-01-09 22:51:01 +01004077 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyc3c07d42019-06-17 23:00:44 +07004078 f_create_gsup_expect(hex2str(g_pars.imsi));
4079
4080 /* Perform location update */
4081 f_perform_lu();
4082
4083 /* Send CM Service Request for SS/USSD */
4084 f_establish_fully(EST_TYPE_SS_ACT);
4085
4086 /* GSM 04.80 FACILITY message for a non-existing transaction */
4087 var template (value) PDU_ML3_MS_NW mo_ss_fac := ts_ML3_MO_SS_FACILITY(
4088 tid := 1, /* An arbitrary transaction identifier */
4089 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
4090 facility := f_rnd_octstring(23) /* We don't care about the Facility IE */
4091 );
4092
4093 /* GSM 04.80 RELEASE COMPLETE message for a non-existing transaction */
4094 var template (value) PDU_ML3_MS_NW mo_ss_rel := ts_ML3_MO_SS_RELEASE_COMPLETE(
4095 tid := 1, /* An arbitrary transaction identifier */
4096 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
4097 facility := f_rnd_octstring(23) /* We don't care about the Facility IE */
4098 );
4099
4100 /* Expected response from the network */
4101 var template PDU_ML3_NW_MS mt_ss_rel := tr_ML3_MT_SS_RELEASE_COMPLETE(
4102 tid := 1, /* Same as in the FACILITY message */
4103 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
4104 facility := omit
4105 );
4106
4107 /* Send GSM 04.80 FACILITY for non-existing transaction */
4108 BSSAP.send(ts_PDU_DTAP_MO(mo_ss_fac));
4109
4110 /* Expect GSM 04.80 RELEASE COMPLETE message */
4111 f_expect_mt_dtap_msg(mt_ss_rel);
4112 f_expect_clear();
4113
4114 /* Send another CM Service Request for SS/USSD */
4115 f_establish_fully(EST_TYPE_SS_ACT);
4116
4117 /* Send GSM 04.80 RELEASE COMPLETE for non-existing transaction */
4118 BSSAP.send(ts_PDU_DTAP_MO(mo_ss_rel));
4119
4120 /* Expect GSM 04.80 RELEASE COMPLETE message */
4121 f_expect_mt_dtap_msg(mt_ss_rel);
4122 f_expect_clear();
4123}
4124testcase TC_mo_ussd_for_unknown_trans() runs on MTC_CT {
4125 var BSC_ConnHdlr vc_conn;
4126 f_init();
4127 vc_conn := f_start_handler(refers(f_tc_mo_ussd_for_unknown_trans), 111);
4128 vc_conn.done;
4129}
4130
Vadim Yanitskiyd612d282019-06-15 14:46:03 +07004131/* MT (network-originated) USSD for unknown session */
4132friend function f_tc_proc_ss_for_unknown_session(charstring id, BSC_ConnHdlrPars pars)
4133runs on BSC_ConnHdlr {
4134 var OCT4 sid := '20000333'O;
4135
4136 f_init_handler(pars);
4137
4138 /* Perform location update */
4139 f_perform_lu();
4140
Vadim Yanitskiy70d15bf2020-01-09 22:51:01 +01004141 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyd612d282019-06-15 14:46:03 +07004142 f_create_gsup_expect(hex2str(g_pars.imsi));
4143
4144 /* Request referencing a non-existing SS session */
4145 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
4146 imsi := g_pars.imsi,
4147 sid := sid,
4148 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
4149 ss := f_rnd_octstring(23)
4150 );
4151
4152 /* Error with some cause value */
4153 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_ERR(
4154 imsi := g_pars.imsi,
4155 sid := sid,
4156 state := OSMO_GSUP_SESSION_STATE_END,
4157 cause := ? /* FIXME: introduce an enumerated type! */
4158 );
4159
4160 /* Initiate a MT USSD notification */
4161 GSUP.send(gsup_req);
4162
4163 /* Expect GSUP PROC_SS_ERROR message */
4164 f_expect_gsup_msg(gsup_rsp);
4165}
4166testcase TC_proc_ss_for_unknown_session() runs on MTC_CT {
4167 var BSC_ConnHdlr vc_conn;
4168 f_init();
4169 vc_conn := f_start_handler(refers(f_tc_proc_ss_for_unknown_session), 110);
4170 vc_conn.done;
4171}
4172
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07004173/* MT (network-originated) USSD and no response to Paging Request */
4174friend function f_tc_proc_ss_paging_fail(charstring id, BSC_ConnHdlrPars pars)
4175runs on BSC_ConnHdlr {
4176 timer TP := 2.0; /* Paging timer */
4177
4178 f_init_handler(pars);
4179
4180 /* Perform location update */
4181 f_perform_lu();
4182
Vadim Yanitskiy70d15bf2020-01-09 22:51:01 +01004183 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07004184 f_create_gsup_expect(hex2str(g_pars.imsi));
4185
4186 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
4187 imsi := g_pars.imsi,
4188 sid := '20000444'O,
4189 state := OSMO_GSUP_SESSION_STATE_BEGIN,
4190 ss := f_rnd_octstring(23)
4191 );
4192
4193 /* Error with some cause value */
4194 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_ERR(
4195 imsi := g_pars.imsi,
4196 sid := '20000444'O,
4197 state := OSMO_GSUP_SESSION_STATE_END,
4198 cause := ? /* FIXME: introduce an enumerated type! */
4199 );
4200
4201 /* Initiate a MT USSD notification */
4202 GSUP.send(gsup_req);
4203
4204 /* Send it to MSC and expect Paging Request */
4205 TP.start;
4206 alt {
4207 [pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
4208 setverdict(pass);
4209 }
4210 [not pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
4211 setverdict(pass);
4212 }
4213 /* We don't expect anything else */
4214 [] as_unexp_gsup_or_bssap_msg();
4215 [] TP.timeout {
4216 setverdict(fail, "Timeout waiting for Paging Request");
4217 }
4218 }
4219
Vadim Yanitskiyd24b5252019-10-02 00:04:51 +07004220 /* Wait up to 20 seconds for GSUP PROC_SS_ERROR message.
4221 * OsmoMSC waits for Paging Response 10 seconds by default. */
4222 f_expect_gsup_msg(gsup_rsp, T_val := 20.0);
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07004223}
4224testcase TC_proc_ss_paging_fail() runs on MTC_CT {
4225 var BSC_ConnHdlr vc_conn;
4226 f_init();
4227 vc_conn := f_start_handler(refers(f_tc_proc_ss_paging_fail), 101);
4228 vc_conn.done;
4229}
4230
Vadim Yanitskiy29ba8d62019-06-16 15:19:41 +07004231/* MT (network-originated) USSD followed by immediate abort */
4232friend function f_tc_proc_ss_abort(charstring id, BSC_ConnHdlrPars pars)
4233runs on BSC_ConnHdlr {
4234 var octetstring facility := f_rnd_octstring(23);
4235 var OCT4 sid := '20000555'O;
4236 timer TP := 2.0;
4237
4238 f_init_handler(pars);
4239
4240 /* Perform location update */
4241 f_perform_lu();
4242
Vadim Yanitskiy70d15bf2020-01-09 22:51:01 +01004243 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy29ba8d62019-06-16 15:19:41 +07004244 f_create_gsup_expect(hex2str(g_pars.imsi));
4245
4246 /* PROC_SS_REQ initiates a mobile-originated SS/USSD session */
4247 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
4248 imsi := g_pars.imsi, sid := sid,
4249 state := OSMO_GSUP_SESSION_STATE_BEGIN,
4250 ss := facility
4251 );
4252
4253 /* On the MS side, we expect GSM 04.80 REGISTER message */
4254 var template PDU_ML3_NW_MS dtap_reg := tr_ML3_MT_SS_REGISTER(
4255 tid := 0, /* Most likely, it should be 0 */
4256 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
4257 facility := facility
4258 );
4259
4260 /* PROC_SS_ERR with SESSION_STATE_END terminates the SS/USSD session */
4261 var template (value) GSUP_PDU gsup_abort := ts_GSUP_PROC_SS_ERR(
4262 imsi := g_pars.imsi, sid := sid,
4263 state := OSMO_GSUP_SESSION_STATE_END,
4264 cause := 0 /* FIXME: introduce an enumerated type! */
4265 );
4266
4267 /* On the MS side, we expect GSM 04.80 REGISTER message */
4268 var template PDU_ML3_NW_MS dtap_rel := tr_ML3_MT_SS_RELEASE_COMPLETE(
4269 tid := 0, /* Most likely, it should be 0 */
4270 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
4271 cause := *, /* FIXME: expect some specific cause value */
4272 facility := omit
4273 );
4274
4275 /* Initiate a MT USSD with random payload */
4276 GSUP.send(gsup_req);
4277
4278 /* Expect Paging Request */
4279 TP.start;
4280 alt {
4281 [pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
4282 setverdict(pass);
4283 }
4284 [not pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
4285 setverdict(pass);
4286 }
4287 /* We don't expect anything else */
4288 [] as_unexp_gsup_or_bssap_msg();
4289 [] TP.timeout {
4290 setverdict(fail, "Timeout waiting for Paging Request");
4291 }
4292 }
4293
4294 /* Send Paging Response and establish connection */
4295 f_establish_fully(EST_TYPE_PAG_RESP);
4296 /* Expect MT REGISTER message with random facility */
4297 f_expect_mt_dtap_msg(dtap_reg);
4298
4299 /* HLR/EUSE decides to abort the session even
4300 * before getting any response from the MS */
4301 /* Initiate a MT USSD with random payload */
4302 GSUP.send(gsup_abort);
4303
4304 /* Expect RELEASE COMPLETE on ths MS side */
4305 f_expect_mt_dtap_msg(dtap_rel);
4306
4307 f_expect_clear();
4308}
4309testcase TC_proc_ss_abort() runs on MTC_CT {
4310 var BSC_ConnHdlr vc_conn;
4311 f_init();
4312 vc_conn := f_start_handler(refers(f_tc_proc_ss_abort), 102);
4313 vc_conn.done;
4314}
4315
Harald Weltee13cfb22019-04-23 16:52:02 +02004316
Vadim Yanitskiy1c9754d2020-01-07 21:56:55 +01004317/* Verify multiple concurrent MO SS/USSD transactions
4318 * (one subscriber - one transaction) */
4319testcase TC_multi_lu_and_mo_ussd() runs on MTC_CT {
4320 var BSC_ConnHdlr vc_conn[16];
4321 var integer i;
4322
4323 f_init();
4324
4325 for (i := 0; i < sizeof(vc_conn); i := i + 1) {
4326 vc_conn[i] := f_start_handler(refers(f_tc_lu_and_mo_ussd_single_request), 210 + i);
4327 }
4328
4329 for (i := 0; i < sizeof(vc_conn); i := i + 1) {
4330 vc_conn[i].done;
4331 }
4332}
4333
4334/* Verify multiple concurrent MT SS/USSD transactions
4335 * (one subscriber - one transaction) */
4336testcase TC_multi_lu_and_mt_ussd() runs on MTC_CT {
4337 var BSC_ConnHdlr vc_conn[16];
4338 var integer i;
4339 var OCT4 sid;
4340
4341 f_init();
4342
4343 for (i := 0; i < sizeof(vc_conn); i := i + 1) {
4344 sid := '200001'O & int2oct(i, 1); /* All transactions must use different session ID */
4345 vc_conn[i] := f_start_handler_with_pars(refers(f_tc_lu_and_mt_ussd_notification),
4346 f_init_pars(226 + i, gsup_sid := sid));
4347 }
4348
4349 for (i := 0; i < sizeof(vc_conn); i := i + 1) {
4350 vc_conn[i].done;
4351 }
4352}
4353
4354
Stefan Sperling89eb1f32018-12-17 15:06:20 +01004355/* A5/1 only permitted on network side; attempt an invalid CIPHER MODE COMPLETE with A5/3 which MSC should reject. */
4356private function f_tc_cipher_complete_with_invalid_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4357 pars.net.expect_auth := true;
4358 pars.net.expect_ciph := true;
4359 pars.net.kc_support := '02'O; /* A5/1 only */
4360 f_init_handler(pars);
4361
4362 g_pars.vec := f_gen_auth_vec_2g();
4363
4364 /* Can't use f_perform_lu() directly. Code below is based on it. */
4365
4366 /* tell GSUP dispatcher to send this IMSI to us */
4367 f_create_gsup_expect(hex2str(g_pars.imsi));
4368
4369 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
4370 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
Harald Weltedceacc72019-04-21 20:58:35 +02004371 f_cl3_or_initial_ue(l3_lu);
Stefan Sperling89eb1f32018-12-17 15:06:20 +01004372
4373 f_mm_auth();
4374
4375 var OCT1 a5_net := f_alg_mask_from_cm(g_pars.cm2);
4376 var OCT1 a5_intersect := g_pars.net.kc_support and4b a5_net;
4377 alt {
4378 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(a5_intersect, g_pars.vec.kc)) {
4379 BSSAP.send(ts_BSSMAP_CipherModeCompl(int2oct(4 /* "accept" A5/3 */, 1)));
4380 }
4381 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc)) {
4382 setverdict(fail, "Wrong ciphering algorithm mask in CiphModCmd");
4383 mtc.stop;
4384 }
4385 [] BSSAP.receive {
4386 setverdict(fail, "Unknown/unexpected BSSAP received");
4387 mtc.stop;
4388 }
4389 }
Harald Welte79f1e452020-08-18 22:55:02 +02004390 f_expect_common_id();
Stefan Sperling89eb1f32018-12-17 15:06:20 +01004391
4392 /* Expect LU reject from MSC. */
4393 alt {
4394 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
4395 setverdict(pass);
4396 }
4397 [] BSSAP.receive {
4398 setverdict(fail, "Unknown/unexpected BSSAP received");
4399 mtc.stop;
4400 }
4401 }
Stefan Sperlingc620b352018-12-18 17:23:36 +01004402 f_expect_clear();
Stefan Sperling89eb1f32018-12-17 15:06:20 +01004403}
4404
4405testcase TC_cipher_complete_with_invalid_cipher() runs on MTC_CT {
4406 var BSC_ConnHdlr vc_conn;
4407 f_init();
4408 f_vty_config(MSCVTY, "network", "encryption a5 1");
4409
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02004410 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 +01004411 vc_conn.done;
4412}
4413
Harald Welteb2284bd2019-05-10 11:30:43 +02004414/* Location Update with invalid (non-matching) MCC/MNC reported on BSSMAP level from BSC */
4415friend function f_tc_lu_with_invalid_mcc_mnc(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4416 f_init_handler(pars);
4417
4418 /* tell GSUP dispatcher to send this IMSI to us */
4419 f_create_gsup_expect(hex2str(g_pars.imsi));
4420
4421 /* modify the cell ID which will be used to construct the COMPLELTE L3 or InitialUE */
4422 g_pars.cell_id := valueof(ts_CellId_CGI('333'H, '22'H, 23, 42));
4423
4424 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
4425 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
4426 f_cl3_or_initial_ue(l3_lu);
Harald Welte79f1e452020-08-18 22:55:02 +02004427 f_expect_common_id();
Harald Welteb2284bd2019-05-10 11:30:43 +02004428
4429 /* Expect LU reject from MSC. */
4430 alt {
4431 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
4432 setverdict(pass);
4433 }
4434 [] BSSAP.receive {
4435 setverdict(fail, "Unknown/unexpected BSSAP received");
4436 mtc.stop;
4437 }
4438 }
Eric Wild85cc1612022-03-30 01:44:29 +02004439 f_expect_clear(verify_vlr_cell_id:=false);
Harald Welteb2284bd2019-05-10 11:30:43 +02004440}
4441testcase TC_lu_with_invalid_mcc_mnc() runs on MTC_CT {
4442 var BSC_ConnHdlr vc_conn;
4443 f_init();
4444 vc_conn := f_start_handler(refers(f_tc_lu_with_invalid_mcc_mnc), 54);
4445 vc_conn.done;
4446}
4447
Stefan Sperlinga2d59c62018-12-18 16:32:44 +01004448private function f_tc_cipher_complete_without_alg(charstring id, BSC_ConnHdlrPars pars, octetstring kc_support) runs on BSC_ConnHdlr {
4449 pars.net.expect_auth := true;
4450 pars.net.expect_ciph := true;
4451 pars.net.kc_support := kc_support;
4452 f_init_handler(pars);
4453
4454 g_pars.vec := f_gen_auth_vec_2g();
4455
4456 /* Can't use f_perform_lu() directly. Code below is based on it. */
4457
4458 /* tell GSUP dispatcher to send this IMSI to us */
4459 f_create_gsup_expect(hex2str(g_pars.imsi));
4460
4461 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
4462 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
4463 f_cl3_or_initial_ue(l3_lu);
4464
4465 f_mm_auth();
4466
4467 var OCT1 a5_net := f_alg_mask_from_cm(g_pars.cm2);
4468 var OCT1 a5_intersect := g_pars.net.kc_support and4b a5_net;
4469 alt {
4470 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(a5_intersect, g_pars.vec.kc)) {
4471 BSSAP.send(ts_BSSMAP_CipherModeComplAlg(omit));
4472 }
4473 [] BSSAP.receive(tr_BSSMAP_ClassmarkReq) {
4474 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
4475 repeat;
4476 }
4477 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc)) {
4478 setverdict(fail, "Wrong ciphering algorithm mask in CiphModCmd");
4479 mtc.stop;
4480 }
4481 [] BSSAP.receive {
4482 setverdict(fail, "Unknown/unexpected BSSAP received");
4483 mtc.stop;
4484 }
4485 }
Harald Welte79f1e452020-08-18 22:55:02 +02004486 f_expect_common_id();
Stefan Sperlinga2d59c62018-12-18 16:32:44 +01004487
4488 /* TODO: Verify MSC is using the best cipher available! How? */
4489
4490 f_msc_lu_hlr();
Neels Hofmeyre860fc42022-10-05 01:15:54 +02004491 as_accept_reject_lu();
Stefan Sperlinga2d59c62018-12-18 16:32:44 +01004492 f_expect_clear();
4493 setverdict(pass);
4494}
4495
4496/* A5/1 only permitted on network side; attempt CIPHER MODE COMPLETE without specifying the accepted algorithm. */
4497private function f_tc_cipher_complete_1_without_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4498 f_tc_cipher_complete_without_alg(id, pars, '02'O /* A5/1 only */);
4499}
4500
4501/* A5/3 only permitted on network side; attempt CIPHER MODE COMPLETE without specifying the accepted algorithm. */
4502private function f_tc_cipher_complete_3_without_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4503 f_tc_cipher_complete_without_alg(id, pars, '08'O /* A5/3 only */);
4504}
4505
4506/* A5/1 + A5/3 permitted on network side; attempt CIPHER MODE COMPLETE without specifying the accepted algorithm. */
4507private function f_tc_cipher_complete_13_without_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4508 f_tc_cipher_complete_without_alg(id, pars, '0A'O /* A5/1 and A5/3 enabled */);
4509}
4510
4511testcase TC_cipher_complete_1_without_cipher() runs on MTC_CT {
4512 var BSC_ConnHdlr vc_conn;
4513 f_init();
4514 f_vty_config(MSCVTY, "network", "encryption a5 1");
4515
4516 vc_conn := f_start_handler(refers(f_tc_cipher_complete_1_without_cipher), 53);
4517 vc_conn.done;
4518}
4519
4520testcase TC_cipher_complete_3_without_cipher() runs on MTC_CT {
4521 var BSC_ConnHdlr vc_conn;
4522 f_init();
4523 f_vty_config(MSCVTY, "network", "encryption a5 3");
4524
4525 vc_conn := f_start_handler(refers(f_tc_cipher_complete_3_without_cipher), 54);
4526 vc_conn.done;
4527}
4528
4529testcase TC_cipher_complete_13_without_cipher() runs on MTC_CT {
4530 var BSC_ConnHdlr vc_conn;
4531 f_init();
4532 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
4533
4534 vc_conn := f_start_handler(refers(f_tc_cipher_complete_13_without_cipher), 55);
4535 vc_conn.done;
4536}
Harald Welteb2284bd2019-05-10 11:30:43 +02004537
Harald Weltef640a012018-04-14 17:49:21 +02004538/* TODO (SMS):
4539 * different user data lengths
4540 * SMPP transaction mode with unsuccessful delivery
4541 * queued MT-SMS with no paging response + later delivery
4542 * different data coding schemes
4543 * multi-part SMS
4544 * user-data headers
4545 * TP-PID for SMS to SIM
4546 * behavior if SMS memory is full + RP-SMMA
4547 * delivery reports
4548 * SMPP osmocom extensions
4549 * more-messages-to-send
4550 * SMS during ongoing call (SACCH/SAPI3)
4551 */
4552
4553/* TODO (General):
Harald Welteba7b6d92018-01-23 21:32:34 +01004554 * continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
4555 * malformed messages (missing IE, invalid message type): properly rejected?
4556 * MT call while LU or is ongoing: Do we use existing lchan or page while lchan active?
4557 * 3G/2G auth permutations
4558 * encryption algorithms vs. classmark vs. vty config
Harald Welteba7b6d92018-01-23 21:32:34 +01004559 * send new transaction after/during clear (like SMS, ...)
Harald Welte45164da2018-01-24 12:51:27 +01004560 * too long L3 INFO in DTAP
4561 * too long / padded BSSAP
4562 * too long / short TLV values
Harald Welteba7b6d92018-01-23 21:32:34 +01004563 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01004564
Harald Weltee13cfb22019-04-23 16:52:02 +02004565/***********************************************************************
4566 * SGsAP Testing
4567 ***********************************************************************/
4568
Philipp Maier948747b2019-04-02 15:22:33 +02004569/* Check if a subscriber exists in the VLR */
4570private function f_ctrl_subscr_in_vlr(charstring imsi_or_msisdn) runs on BSC_ConnHdlr return boolean {
4571
4572 var CtrlValue active_subsribers;
4573 var integer rc;
4574 active_subsribers := f_ctrl_get(IPA_CTRL, "subscriber-list-active-v1");
4575
4576 rc := f_strstr(active_subsribers, imsi_or_msisdn);
4577 if (rc < 0) {
4578 return false;
4579 }
4580
4581 return true;
4582}
4583
Pau Espin Pedrolcefe9da2021-07-02 18:38:27 +02004584/* Perform a Location Update at the A-Interface and run some checks to confirm
Harald Welte4263c522018-12-06 11:56:27 +01004585 * that everything is back to normal. */
4586private function f_sgsap_bssmap_screening() runs on BSC_ConnHdlr {
4587 var SmsParameters spars := valueof(t_SmsPars);
4588
Pau Espin Pedrol7593a8a2021-07-02 18:55:16 +02004589 /* From now on, since we initiated LU from A-Interface, we expect no
4590 * LastEutranPLMNId on Common Id, since the SGs interface should be gone
4591 */
4592 g_pars.common_id_last_eutran_plmn := omit;
4593
Harald Welte4263c522018-12-06 11:56:27 +01004594 /* Perform a location update, the SGs association is expected to fall
4595 * back to NULL */
4596 f_perform_lu();
4597 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4598
4599 /* Trigger a paging request and expect the paging on BSSMAP, this is
4600 * to make sure that pagings are sent throught the A-Interface again
4601 * and not throught the SGs interface.*/
Harald Welte6811d102019-04-14 22:23:14 +02004602 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Harald Welte4263c522018-12-06 11:56:27 +01004603 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4604
4605 alt {
Harald Weltee13cfb22019-04-23 16:52:02 +02004606 [g_pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)); {
4607 setverdict(pass);
4608 }
Harald Welte62113fc2019-05-09 13:04:02 +02004609 [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 +01004610 setverdict(pass);
4611 }
4612 [] SGsAP.receive {
4613 setverdict(fail, "Received unexpected message on SGs");
4614 }
4615 }
4616
4617 /* Send an SMS to make sure that also payload messages are routed
4618 * throught the A-Interface again */
4619 f_establish_fully(EST_TYPE_MO_SMS);
4620 f_mo_sms(spars);
4621 f_expect_clear();
4622}
4623
4624private function f_tc_sgsap_reset(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4625 var charstring vlr_name;
4626 f_init_handler(pars);
4627
4628 vlr_name := f_sgsap_reset_mme(mp_mme_name);
4629 log("VLR name: ", vlr_name);
4630 setverdict(pass);
Neels Hofmeyrc0b520d2019-03-06 15:35:50 +01004631 f_sleep(1.0);
Harald Welte4263c522018-12-06 11:56:27 +01004632}
4633
4634testcase TC_sgsap_reset() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004635 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004636 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004637 f_init(1, true);
4638 pars := f_init_pars(11810, true);
4639 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_reset), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004640 vc_conn.done;
4641}
4642
4643/* like f_mm_auth() but for SGs */
4644function f_mm_auth_sgs() runs on BSC_ConnHdlr {
4645 if (g_pars.net.expect_auth) {
4646 g_pars.vec := f_gen_auth_vec_3g();
4647 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
4648 g_pars.vec.sres,
4649 g_pars.vec.kc,
4650 g_pars.vec.ik,
4651 g_pars.vec.ck,
4652 g_pars.vec.autn,
4653 g_pars.vec.res));
4654 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
4655 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
4656 SGsAP.receive(tr_ML3_MT_MM_AUTH_REQ_3G(g_pars.vec.rand, g_pars.vec.autn));
4657 SGsAP.send(ts_ML3_MT_MM_AUTH_RESP_3G(g_pars.vec.sres, g_pars.vec.res));
4658 }
4659}
4660
4661/* like f_perform_lu(), but on SGs rather than BSSAP */
4662function f_sgs_perform_lu() runs on BSC_ConnHdlr {
4663 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4664 var PDU_SGsAP lur;
4665 var PDU_SGsAP lua;
4666 var PDU_SGsAP mm_info;
4667 var octetstring mm_info_dtap;
Pau Espin Pedrole979c402021-04-28 17:29:54 +02004668 var GsmMcc mcc;
4669 var GsmMnc mnc;
4670 var template (omit) TrackingAreaIdentityValue tai := omit;
Harald Welte4263c522018-12-06 11:56:27 +01004671
4672 /* tell GSUP dispatcher to send this IMSI to us */
4673 f_create_gsup_expect(hex2str(g_pars.imsi));
Pau Espin Pedrole979c402021-04-28 17:29:54 +02004674 if (g_pars.common_id_last_eutran_plmn != omit) {
4675 f_dec_mcc_mnc(g_pars.common_id_last_eutran_plmn, mcc, mnc);
4676 tai := ts_SGsAP_TAI(mcc, mnc, 555);
4677 }
Harald Welte4263c522018-12-06 11:56:27 +01004678 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
Pau Espin Pedrol3768a6f2021-04-28 14:24:23 +02004679 ts_SGsAP_LAI('901'H, '70'H, 2342),
Pau Espin Pedrole979c402021-04-28 17:29:54 +02004680 tai));
Harald Welte4263c522018-12-06 11:56:27 +01004681 /* Old LAI, if MS sends it */
4682 /* TMSI status, if MS has no valid TMSI */
4683 /* IMEISV, if it supports "automatic device detection" */
4684 /* TAI, if available in MME */
4685 /* E-CGI, if available in MME */
4686 SGsAP.send(lur);
4687
4688 /* FIXME: is this really done over SGs? The Ue is already authenticated
4689 * via the MME ... */
4690 f_mm_auth_sgs();
4691
4692 /* Expect MSC to perform LU with HLR */
4693 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
4694 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
4695 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
4696 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
4697
4698 alt {
4699 [] SGsAP.receive(tr_SGsAP_LU_ACCEPT(g_pars.imsi, ?)) -> value lua {
4700 if (isvalue(lua.sGsAP_LOCATION_UPDATE_ACCEPT.newTMSIorIMSI.iD.iD.tmsi_ptmsi.octets)) {
4701 g_pars.tmsi :=lua.sGsAP_LOCATION_UPDATE_ACCEPT.newTMSIorIMSI.iD.iD.tmsi_ptmsi.octets
4702 SGsAP.send(ts_SGsAP_TMSI_REALL_CMPL(g_pars.imsi));
4703 }
4704 setverdict(pass);
4705 }
4706 [] SGsAP.receive(tr_SGsAP_LU_REJECT(g_pars.imsi, ?, ?)) {
4707 setverdict(fail, "Received LU-REJECT instead of ACCEPT");
4708 }
4709 [] SGsAP.receive {
4710 setverdict(fail, "Received unexpected message on SGs");
4711 }
4712 }
4713
4714 /* Check MM information */
4715 if (mp_mm_info == true) {
4716 SGsAP.receive(tr_SGsAP_MM_INFO_REQ(g_pars.imsi, ?)) -> value mm_info;
4717 mm_info_dtap := '0532'O & mm_info.sGsAP_MM_INFORMATION_REQUEST.mM_Information.information;
4718 if (not match(dec_PDU_ML3_NW_MS(mm_info_dtap), tr_ML3_MT_MM_Info)) {
4719 setverdict(fail, "Unexpected MM Information");
4720 }
4721 }
4722
4723 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4724}
4725
4726private function f_tc_sgsap_lu(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4727 f_init_handler(pars);
4728 f_sgs_perform_lu();
4729 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4730
4731 f_sgsap_bssmap_screening();
4732
4733 setverdict(pass);
4734}
4735testcase TC_sgsap_lu() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004736 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004737 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004738 f_init(1, true);
4739 pars := f_init_pars(11811, true);
Pau Espin Pedrole979c402021-04-28 17:29:54 +02004740 pars.common_id_last_eutran_plmn := f_enc_mcc_mnc('901'H, '70'H);
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004741 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004742 vc_conn.done;
4743}
4744
4745/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
4746private function f_tc_sgsap_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4747 f_init_handler(pars);
4748 var PDU_SGsAP lur;
4749
4750 f_create_gsup_expect(hex2str(g_pars.imsi));
4751 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4752 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
4753 ts_SGsAP_LAI('901'H, '70'H, 2342)));
4754 SGsAP.send(lur);
4755
4756 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
4757 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
4758 alt {
4759 [] SGsAP.receive(tr_SGsAP_LU_REJECT(g_pars.imsi, ?, ?)) {
4760 setverdict(pass);
4761 }
4762 [] SGsAP.receive(tr_SGsAP_LU_ACCEPT(g_pars.imsi, ?)) {
4763 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
4764 mtc.stop;
4765 }
4766 [] SGsAP.receive {
4767 setverdict(fail, "Received unexpected message on SGs");
4768 }
4769 }
4770
4771 f_sgsap_bssmap_screening();
4772
4773 setverdict(pass);
4774}
4775testcase TC_sgsap_lu_imsi_reject() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004776 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004777 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004778 f_init(1, true);
4779 pars := f_init_pars(11812, true);
Harald Welte4263c522018-12-06 11:56:27 +01004780
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004781 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu_imsi_reject), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004782 vc_conn.done;
4783}
4784
4785/* Do LU by IMSI, but then remain silent so that Ts6-1 times out */
4786private function f_tc_sgsap_lu_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4787 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4788 var PDU_SGsAP lur;
4789
4790 f_init_handler(pars);
4791
4792 /* tell GSUP dispatcher to send this IMSI to us */
4793 f_create_gsup_expect(hex2str(g_pars.imsi));
4794
4795 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
4796 ts_SGsAP_LAI('901'H, '70'H, 2342)));
4797 /* Old LAI, if MS sends it */
4798 /* TMSI status, if MS has no valid TMSI */
4799 /* IMEISV, if it supports "automatic device detection" */
4800 /* TAI, if available in MME */
4801 /* E-CGI, if available in MME */
4802 SGsAP.send(lur);
4803
4804 /* FIXME: is this really done over SGs? The Ue is already authenticated
4805 * via the MME ... */
4806 f_mm_auth_sgs();
4807
4808 /* Expect MSC to perform LU with HLR */
4809 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
4810 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
4811 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
4812 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
4813
4814 alt {
4815 [] SGsAP.receive(tr_SGsAP_LU_ACCEPT(g_pars.imsi, ?)) {
4816 setverdict(pass);
4817 }
4818 [] SGsAP.receive(tr_SGsAP_LU_REJECT(g_pars.imsi, ?, ?)) {
4819 setverdict(fail, "Received LU-REJECT instead of ACCEPT");
4820 }
4821 [] SGsAP.receive {
4822 setverdict(fail, "Received unexpected message on SGs");
4823 }
4824 }
4825
4826 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4827
4828 /* Wait until the VLR has abort the TMSI reallocation procedure */
4829 f_sleep(45.0);
4830
4831 /* The outcome does not change the SGs state, see also 5.2.3.4 */
4832 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4833
4834 f_sgsap_bssmap_screening();
4835
4836 setverdict(pass);
4837}
4838testcase TC_sgsap_lu_and_nothing() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004839 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004840 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004841 f_init(1, true);
4842 pars := f_init_pars(11813, true);
Harald Welte4263c522018-12-06 11:56:27 +01004843
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004844 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu_and_nothing), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004845 vc_conn.done;
4846}
4847
4848private function f_tc_sgsap_expl_imsi_det_eps(charstring id, BSC_ConnHdlrPars pars)
4849runs on BSC_ConnHdlr {
4850 f_init_handler(pars);
4851 f_sgs_perform_lu();
4852 f_sleep(3.0);
4853
4854 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4855 SGsAP.send(ts_SGsAP_EPS_DETACH_IND(g_pars.imsi, mme_name, UE_initiated));
4856 SGsAP.receive(tr_SGsAP_EPS_DETACH_ACK(g_pars.imsi));
4857 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4858
4859 f_sgsap_bssmap_screening();
4860
4861 setverdict(pass);
4862}
4863testcase TC_sgsap_expl_imsi_det_eps() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004864 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004865 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004866 f_init(1, true);
4867 pars := f_init_pars(11814, true);
Pau Espin Pedrole979c402021-04-28 17:29:54 +02004868 pars.common_id_last_eutran_plmn := f_enc_mcc_mnc('901'H, '70'H);
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004869 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_expl_imsi_det_eps), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004870 vc_conn.done;
4871}
4872
Philipp Maierfc19f172019-03-21 11:17:54 +01004873private function f_tc_sgsap_impl_imsi_det_eps(charstring id, BSC_ConnHdlrPars pars)
4874runs on BSC_ConnHdlr {
4875 f_init_handler(pars);
4876 f_sgs_perform_lu();
4877 f_sleep(3.0);
4878
4879 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4880 SGsAP.send(ts_SGsAP_EPS_DETACH_IND(g_pars.imsi, mme_name, network_initiated));
4881 SGsAP.receive(tr_SGsAP_EPS_DETACH_ACK(g_pars.imsi));
4882 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4883
4884 f_sgsap_bssmap_screening();
4885
4886 setverdict(pass);
4887}
4888testcase TC_sgsap_impl_imsi_det_eps() runs on MTC_CT {
4889 var BSC_ConnHdlrPars pars;
4890 var BSC_ConnHdlr vc_conn;
4891 f_init(1, true);
4892 pars := f_init_pars(11814, true);
Pau Espin Pedrole979c402021-04-28 17:29:54 +02004893 pars.common_id_last_eutran_plmn := f_enc_mcc_mnc('901'H, '70'H);
Philipp Maierfc19f172019-03-21 11:17:54 +01004894 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_impl_imsi_det_eps), pars);
4895 vc_conn.done;
4896}
4897
Harald Welte4263c522018-12-06 11:56:27 +01004898private function f_tc_sgsap_expl_imsi_det_noneps(charstring id, BSC_ConnHdlrPars pars)
4899runs on BSC_ConnHdlr {
4900 f_init_handler(pars);
4901 f_sgs_perform_lu();
4902 f_sleep(3.0);
4903
4904 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4905 SGsAP.send(ts_SGsAP_IMSI_DETACH_IND(g_pars.imsi, mme_name, combined_UE_initiated));
4906 SGsAP.receive(tr_SGsAP_IMSI_DETACH_ACK(g_pars.imsi));
Philipp Maierd08e7e72019-04-02 15:27:10 +02004907
4908 if (f_ctrl_subscr_in_vlr(hex2str(g_pars.imsi))) {
4909 setverdict(fail, "subscriber not removed from VLR");
4910 }
Harald Welte4263c522018-12-06 11:56:27 +01004911
4912 f_sgsap_bssmap_screening();
4913
4914 setverdict(pass);
4915}
4916testcase TC_sgsap_expl_imsi_det_noneps() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004917 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004918 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004919 f_init(1, true);
4920 pars := f_init_pars(11815, true);
Pau Espin Pedrole979c402021-04-28 17:29:54 +02004921 pars.common_id_last_eutran_plmn := f_enc_mcc_mnc('901'H, '70'H);
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004922 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_expl_imsi_det_noneps), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004923 vc_conn.done;
4924}
4925
Philipp Maier5d812702019-03-21 10:51:26 +01004926private function f_tc_sgsap_impl_imsi_det_noneps(charstring id, BSC_ConnHdlrPars pars)
4927runs on BSC_ConnHdlr {
4928 f_init_handler(pars);
4929 f_sgs_perform_lu();
4930 f_sleep(3.0);
4931
4932 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4933 SGsAP.send(ts_SGsAP_IMSI_DETACH_IND(g_pars.imsi, mme_name, implicit_network_initiated));
4934 SGsAP.receive(tr_SGsAP_IMSI_DETACH_ACK(g_pars.imsi));
4935
4936 if (f_ctrl_subscr_in_vlr(hex2str(g_pars.imsi))) {
4937 setverdict(fail, "subscriber not removed from VLR");
4938 }
4939
4940 f_sgsap_bssmap_screening();
4941
4942 setverdict(pass);
4943}
4944testcase TC_sgsap_impl_imsi_det_noneps() runs on MTC_CT {
4945 var BSC_ConnHdlrPars pars;
4946 var BSC_ConnHdlr vc_conn;
4947 f_init(1, true);
4948 pars := f_init_pars(11815, true);
Pau Espin Pedrole979c402021-04-28 17:29:54 +02004949 pars.common_id_last_eutran_plmn := f_enc_mcc_mnc('901'H, '70'H);
Philipp Maier5d812702019-03-21 10:51:26 +01004950 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_impl_imsi_det_noneps), pars);
4951 vc_conn.done;
4952}
4953
Harald Welte4263c522018-12-06 11:56:27 +01004954/* Trigger a paging request via VTY and send a paging reject in response */
4955private function f_tc_sgsap_paging_rej(charstring id, BSC_ConnHdlrPars pars)
4956runs on BSC_ConnHdlr {
4957 f_init_handler(pars);
4958 f_sgs_perform_lu();
4959 f_sleep(1.0);
4960
4961 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4962 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
4963 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4964 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4965
4966 /* Initiate paging via VTY */
4967 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4968 alt {
4969 [] SGsAP.receive(exp_resp) {
4970 setverdict(pass);
4971 }
4972 [] SGsAP.receive {
4973 setverdict(fail, "Received unexpected message on SGs");
4974 }
4975 }
4976
4977 /* Now reject the paging */
4978 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, IMSI_unknown));
4979
4980 /* Wait for the states inside the MSC to settle and check the state
4981 * of the SGs Association */
4982 f_sleep(1.0);
4983 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4984
4985 /* FIXME: At the moment we send an IMSI_unknown as cause code, which is fine,
4986 * but we also need to cover tha case where the cause code indicates an
4987 * "IMSI detached for EPS services". In those cases the VLR is expected to
4988 * try paging on tha A/Iu interface. This will be another testcase similar to
4989 * this one, but extended with checks for the presence of the A/Iu paging
4990 * messages. */
4991
4992 f_sgsap_bssmap_screening();
4993
4994 setverdict(pass);
4995}
4996testcase TC_sgsap_paging_rej() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004997 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004998 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004999 f_init(1, true);
5000 pars := f_init_pars(11816, true);
Pau Espin Pedrole979c402021-04-28 17:29:54 +02005001 pars.common_id_last_eutran_plmn := f_enc_mcc_mnc('901'H, '70'H);
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005002 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_rej), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005003 vc_conn.done;
5004}
5005
5006/* Trigger a paging request via VTY and send a paging reject that indicates
5007 * that the subscriber intentionally rejected the call. */
5008private function f_tc_sgsap_paging_subscr_rej(charstring id, BSC_ConnHdlrPars pars)
5009runs on BSC_ConnHdlr {
5010 f_init_handler(pars);
5011 f_sgs_perform_lu();
5012 f_sleep(1.0);
5013
5014 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5015 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
5016 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
5017 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
5018
5019 /* Initiate paging via VTY */
5020 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
5021 alt {
5022 [] SGsAP.receive(exp_resp) {
5023 setverdict(pass);
5024 }
5025 [] SGsAP.receive {
5026 setverdict(fail, "Received unexpected message on SGs");
5027 }
5028 }
5029
5030 /* Now reject the paging */
5031 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, user_rejected_mobile_terminating_CS_fallback_call));
5032
5033 /* Wait for the states inside the MSC to settle and check the state
5034 * of the SGs Association */
5035 f_sleep(1.0);
5036 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5037
5038 /* FIXME: The VLR is supposed to trigger an User Determined User Busy (UDUB) as specified
5039 * in 3GPP TS 24.082, this is not yet implemented in the MSC or in this tests, we need
5040 * to check back how this works and how it can be tested */
5041
5042 f_sgsap_bssmap_screening();
5043
5044 setverdict(pass);
5045}
5046testcase TC_sgsap_paging_subscr_rej() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005047 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005048 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005049 f_init(1, true);
5050 pars := f_init_pars(11817, true);
Pau Espin Pedrole979c402021-04-28 17:29:54 +02005051 pars.common_id_last_eutran_plmn := f_enc_mcc_mnc('901'H, '70'H);
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005052 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_subscr_rej), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005053 vc_conn.done;
5054}
5055
5056/* Trigger a paging request via VTY and send an UE unreacable messge in response */
5057private function f_tc_sgsap_paging_ue_unr(charstring id, BSC_ConnHdlrPars pars)
5058runs on BSC_ConnHdlr {
5059 f_init_handler(pars);
5060 f_sgs_perform_lu();
5061 f_sleep(1.0);
5062
5063 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5064 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
5065 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
5066 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
5067
5068 /* Initiate paging via VTY */
5069 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
5070 alt {
5071 [] SGsAP.receive(exp_resp) {
5072 setverdict(pass);
5073 }
5074 [] SGsAP.receive {
5075 setverdict(fail, "Received unexpected message on SGs");
5076 }
5077 }
5078
5079 /* Now pretend that the UE is unreachable */
5080 SGsAP.send(ts_SGsAP_UE_UNREACHABLE(g_pars.imsi, UE_unreachable));
5081
5082 /* Wait for the states inside the MSC to settle and check the state
5083 * of the SGs Association. */
5084 f_sleep(1.0);
5085 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5086
5087 f_sgsap_bssmap_screening();
5088
5089 setverdict(pass);
5090}
5091testcase TC_sgsap_paging_ue_unr() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005092 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005093 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005094 f_init(1, true);
5095 pars := f_init_pars(11818, true);
Pau Espin Pedrole979c402021-04-28 17:29:54 +02005096 pars.common_id_last_eutran_plmn := f_enc_mcc_mnc('901'H, '70'H);
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005097 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_ue_unr), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005098 vc_conn.done;
5099}
5100
5101/* Trigger a paging request via VTY but don't respond to it */
5102private function f_tc_sgsap_paging_and_nothing(charstring id, BSC_ConnHdlrPars pars)
5103runs on BSC_ConnHdlr {
5104 f_init_handler(pars);
5105 f_sgs_perform_lu();
5106 f_sleep(1.0);
5107
5108 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5109 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 +02005110 var template PDU_SGsAP exp_serv_abrt := ts_SGsAP_SERVICE_ABORT_REQ(g_pars.imsi);
Harald Welte4263c522018-12-06 11:56:27 +01005111 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
5112 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
5113
5114 /* Initiate paging via VTY */
5115 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
5116 alt {
5117 [] SGsAP.receive(exp_resp) {
5118 setverdict(pass);
5119 }
5120 [] SGsAP.receive {
5121 setverdict(fail, "Received unexpected message on SGs");
5122 }
5123 }
5124
Philipp Maier34218102019-09-24 09:15:49 +02005125 /* While we are doing nothing, expect an SGsAP-SERVICE-ABORT-REQUEST
5126 * after some time */
5127 timer T := 10.0;
5128 T.start
5129 alt {
5130 [] SGsAP.receive(exp_serv_abrt)
5131 {
5132 setverdict(pass);
5133 }
5134 [] SGsAP.receive {
5135 setverdict(fail, "unexpected SGsAP message received");
5136 self.stop;
5137 }
5138 [] T.timeout {
5139 setverdict(fail, "MSC did not send SGsAP-SERVICE-ABORT-REQUEST");
5140 self.stop;
5141 }
5142 }
5143
5144 /* The SGs association must remain unchanged. */
Harald Welte4263c522018-12-06 11:56:27 +01005145 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5146
5147 f_sgsap_bssmap_screening();
5148
5149 setverdict(pass);
5150}
5151testcase TC_sgsap_paging_and_nothing() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005152 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005153 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005154 f_init(1, true);
5155 pars := f_init_pars(11819, true);
Pau Espin Pedrole979c402021-04-28 17:29:54 +02005156 pars.common_id_last_eutran_plmn := f_enc_mcc_mnc('901'H, '70'H);
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005157 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_and_nothing), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005158 vc_conn.done;
5159}
5160
5161/* Trigger a paging request via VTY and slip in an LU */
5162private function f_tc_sgsap_paging_and_lu(charstring id, BSC_ConnHdlrPars pars)
5163runs on BSC_ConnHdlr {
5164 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5165 f_init_handler(pars);
5166
5167 /* First we prepar the situation, where the SGs association is in state
5168 * NULL and the confirmed by radio contact indicator is set to false
5169 * as well. This can be archived by performing an SGs LU and then
5170 * resetting the VLR */
5171 f_sgs_perform_lu();
5172 f_sgsap_reset_mme(mp_mme_name);
5173 f_sleep(1.0);
5174 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
5175
5176 /* Perform a paging, expect the paging messages on the SGs interface */
5177 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
5178 alt {
5179 [] SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit)) {
5180 setverdict(pass);
5181 }
5182 [] SGsAP.receive {
5183 setverdict(fail, "Received unexpected message on SGs");
5184 }
5185 }
5186
5187 /* Perform the LU as normal */
5188 f_sgs_perform_lu();
5189 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5190
5191 /* Expect a new paging request right after the LU */
5192 alt {
5193 [] SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit)) {
5194 setverdict(pass);
5195 }
5196 [] SGsAP.receive {
5197 setverdict(fail, "Received unexpected message on SGs");
5198 }
5199 }
5200
5201 /* Test is done now, lets round everything up by rejecting the paging
5202 * cleanly. */
5203 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, user_rejected_mobile_terminating_CS_fallback_call));
5204 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5205
5206 f_sgsap_bssmap_screening();
5207
5208 setverdict(pass);
5209}
5210testcase TC_sgsap_paging_and_lu() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005211 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005212 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005213 f_init(1, true);
5214 pars := f_init_pars(11820, true);
Pau Espin Pedrole979c402021-04-28 17:29:54 +02005215 pars.common_id_last_eutran_plmn := f_enc_mcc_mnc('901'H, '70'H);
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005216 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_and_lu), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005217 vc_conn.done;
5218}
5219
5220/* Send unexpected unit-data through the SGs interface */
5221private function f_tc_sgsap_unexp_ud(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5222 f_init_handler(pars);
5223 f_sleep(1.0);
5224
5225 /* This simulates what happens when a subscriber without SGs
5226 * association gets unitdata via the SGs interface. */
5227
5228 /* Make sure the subscriber exists and the SGs association
5229 * is in NULL state */
5230 f_perform_lu();
5231 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
5232
5233 /* Send some random unit data, the MSC/VLR should send a release
5234 * immediately. */
5235 SGsAP.send(ts_SGsAP_UL_UD(pars.imsi,'1234'O));
5236 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, IMSI_detached_for_EPS_nonEPS_services));
5237
5238 f_sgsap_bssmap_screening();
5239
5240 setverdict(pass);
5241}
5242testcase TC_sgsap_unexp_ud() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005243 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005244 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005245 f_init(1, true);
5246 pars := f_init_pars(11821, true);
5247 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_unexp_ud), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005248 vc_conn.done;
5249}
5250
5251/* Send unsolicited unit-data through the SGs interface */
5252private function f_tc_sgsap_unsol_ud(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5253 f_init_handler(pars);
5254 f_sleep(1.0);
5255
5256 /* This simulates what happens when the MME attempts to send unitdata
5257 * to a subscriber that is completely unknown to the VLR */
5258
5259 /* Send some random unit data, the MSC/VLR should send a release
5260 * immediately. */
5261 SGsAP.send(ts_SGsAP_UL_UD(pars.imsi,'1234'O));
5262 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, IMSI_unknown));
5263
5264 f_sgsap_bssmap_screening();
5265
Harald Welte4d15fa72020-08-19 08:58:28 +02005266 /* clean-up VLR state about this subscriber */
5267 f_imsi_detach_by_imsi();
5268
Harald Welte4263c522018-12-06 11:56:27 +01005269 setverdict(pass);
5270}
5271testcase TC_sgsap_unsol_ud() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005272 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005273 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005274 f_init(1, true);
5275 pars := f_init_pars(11822, true);
5276 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_unsol_ud), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005277 vc_conn.done;
5278}
5279
5280private altstep as_other_sms_sgs() runs on BSC_ConnHdlr {
5281 /* FIXME: Match an actual payload (second questionmark), the type is
5282 * octetstring, how do we use a tr_PDU_DTAP_MT here? */
5283 [] SGsAP.receive(tr_SGsAP_DL_UD(?,?)) {
5284 setverdict(fail, "Unexpected SMS related PDU from MSC");
5285 mtc.stop;
5286 }
5287}
5288
5289/* receive a MT-SMS delivered from the MSC/SMSC over an already existing SGsAP connection */
5290function f_mt_sms_sgs(inout SmsParameters spars)
5291runs on BSC_ConnHdlr {
5292 var template (value) TPDU_RP_DATA_MS_SGSN tp_mo;
5293 var template (value) RPDU_MS_SGSN rp_mo;
5294 var template (value) PDU_ML3_MS_NW l3_mo;
5295
5296 var template TPDU_RP_DATA_SGSN_MS tp_mt;
5297 var template RPDU_SGSN_MS rp_mt;
5298 var template PDU_ML3_NW_MS l3_mt;
5299
5300 var PDU_ML3_NW_MS sgsap_l3_mt;
5301
5302 var default d := activate(as_other_sms_sgs());
5303
5304 /* Expect CP-DATA(RP-DATA(SMS-DELIVER)) */
5305 tp_mt := tr_SMS_DELIVER(?, spars.tp.ud, spars.tp.pid, spars.tp.dcs, ?);
Vadim Yanitskiy04dd5f72019-12-13 15:45:44 +09005306 rp_mt := tr_RP_DATA_MT(?, spars.rp.smsc_addr, omit, tp_mt);
Harald Welte4263c522018-12-06 11:56:27 +01005307 l3_mt := tr_ML3_MT_SMS(?, c_TIF_ORIG, tr_CP_DATA_MT(rp_mt));
5308
5309 SGsAP.receive(l3_mt) -> value sgsap_l3_mt;
5310
5311 /* Extract relevant identifiers */
5312 spars.tid := bit2int(sgsap_l3_mt.tiOrSkip.transactionId.tio);
5313 spars.rp.msg_ref := sgsap_l3_mt.msgs.sms.cP_DATA.cP_User_Data.cP_RPDU.rP_DATA_SGSN_MS.rP_MessageReference;
5314
5315 /* send CP-ACK for CP-DATA just received */
5316 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_REPL, ts_CP_ACK_MO);
5317
5318 SGsAP.send(l3_mo);
5319
5320 /* send RP-ACK for RP-DATA */
5321 rp_mo := ts_RP_ACK_MO(spars.rp.msg_ref);
5322 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_REPL, ts_CP_DATA_MO(rp_mo));
5323
5324 SGsAP.send(l3_mo);
5325
5326 /* expect CP-ACK for CP-DATA(RP-ACK) just sent */
5327 l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_ORIG, tr_CP_ACK_MT);
5328
5329 SGsAP.receive(l3_mt);
5330
5331 deactivate(d);
5332
5333 setverdict(pass);
5334}
5335
5336/* submit a MO-SMS to MSC/SMSC over an already existing SGsAP connection */
5337function f_mo_sms_sgs(inout SmsParameters spars)
5338runs on BSC_ConnHdlr {
5339 var template (value) TPDU_RP_DATA_MS_SGSN tp_mo;
5340 var template (value) RPDU_MS_SGSN rp_mo;
5341 var template (value) PDU_ML3_MS_NW l3_mo;
5342
5343 var template TPDU_RP_DATA_SGSN_MS tp_mt;
5344 var template RPDU_SGSN_MS rp_mt;
5345 var template PDU_ML3_NW_MS l3_mt;
5346
5347 var default d := activate(as_other_sms_sgs());
5348
5349 /* just in case this is routed to SMPP.. */
5350 f_create_smpp_expect(hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue));
5351
5352 tp_mo := ts_SMS_SUBMIT(spars.tp.msg_ref, spars.tp.da, spars.tp.pid, spars.tp.dcs,
5353 spars.tp.udl, spars.tp.ud);
Vadim Yanitskiy437b5a62019-12-15 14:13:39 +09005354 rp_mo := ts_RP_DATA_MO(spars.rp.msg_ref, omit, spars.rp.smsc_addr, tp_mo);
Harald Welte4263c522018-12-06 11:56:27 +01005355 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_DATA_MO(rp_mo));
5356
5357 SGsAP.send(l3_mo);
5358
5359 /* receive CP-ACK for CP-DATA above */
5360 SGsAP.receive(tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_ACK_MT));
5361
5362 if (ispresent(spars.exp_rp_err)) {
5363 /* expect an RP-ERROR message from MSC with given cause */
5364 rp_mt := tr_RP_ERROR_MT(spars.rp.msg_ref, spars.exp_rp_err);
5365 l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_DATA_MT(rp_mt));
5366 SGsAP.receive(l3_mt);
5367 /* send CP-ACK for CP-DATA just received */
5368 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_ACK_MO);
5369 SGsAP.send(l3_mo);
5370 } else {
5371 /* expect RP-ACK for RP-DATA */
5372 rp_mt := tr_RP_ACK_MT(spars.rp.msg_ref);
5373 l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_DATA_MT(rp_mt));
5374 SGsAP.receive(l3_mt);
5375 /* send CP-ACO for CP-DATA just received */
5376 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_ACK_MO);
5377 SGsAP.send(l3_mo);
5378 }
5379
5380 deactivate(d);
5381
5382 setverdict(pass);
5383}
5384
5385private function f_vty_sms_send_conn_hdlr(charstring imsi, charstring msisdn, charstring text)
5386runs on BSC_ConnHdlr {
5387 f_vty_transceive(MSCVTY, "subscriber imsi "&imsi&" sms sender msisdn "&msisdn&" send "&text);
5388}
5389
5390/* Send a MT SMS via SGs interface */
5391private function f_tc_sgsap_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5392 f_init_handler(pars);
5393 f_sgs_perform_lu();
5394 f_sleep(1.0);
5395 var SmsParameters spars := valueof(t_SmsPars);
5396 spars.tp.ud := 'C8329BFD064D9B53'O;
5397
5398 /* Trigger SMS via VTY */
5399 f_vty_sms_send_conn_hdlr(hex2str(pars.imsi), "2342", "Hello SMS");
5400 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5401
5402 /* Expect a paging request and respond accordingly with a service request */
5403 SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, SMS_indicator, omit));
5404 SGsAP.send(ts_SGsAP_SERVICE_REQ(pars.imsi, SMS_indicator, EMM_CONNECTED));
5405
5406 /* Connection is now live, receive the MT-SMS */
5407 f_mt_sms_sgs(spars);
5408
5409 /* Expect a concluding release from the MSC */
5410 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, omit));
5411
5412 /* Make sure that subscriber is still present and the SGs association is in tact (ref-counting) */
5413 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5414
5415 f_sgsap_bssmap_screening();
5416
5417 setverdict(pass);
5418}
5419testcase TC_sgsap_mt_sms() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005420 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005421 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005422 f_init(1, true);
5423 pars := f_init_pars(11823, true);
Pau Espin Pedrole979c402021-04-28 17:29:54 +02005424 pars.common_id_last_eutran_plmn := f_enc_mcc_mnc('901'H, '70'H);
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005425 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mt_sms), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005426 vc_conn.done;
5427}
5428
5429/* Send a MO SMS via SGs interface */
5430private function f_tc_sgsap_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5431 f_init_handler(pars);
5432 f_sgs_perform_lu();
5433 f_sleep(1.0);
5434 var SmsParameters spars := valueof(t_SmsPars);
5435 spars.tp.ud := 'C8329BFD064D9B53'O;
5436
5437 /* Send the MO-SMS */
5438 f_mo_sms_sgs(spars);
5439
5440 /* Expect a concluding release from the MSC/VLR */
5441 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, omit));
5442
5443 /* Make sure that subscriber is still present and the SGs association is in tact (ref-counting) */
5444 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5445
5446 setverdict(pass);
5447
5448 f_sgsap_bssmap_screening()
5449}
5450testcase TC_sgsap_mo_sms() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005451 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005452 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005453 f_init(1, true);
5454 pars := f_init_pars(11824, true);
Pau Espin Pedrole979c402021-04-28 17:29:54 +02005455 pars.common_id_last_eutran_plmn := f_enc_mcc_mnc('901'H, '70'H);
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005456 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mo_sms), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005457 vc_conn.done;
5458}
5459
5460/* Trigger sending of an MT sms via VTY but never respond to anything */
5461private function f_tc_sgsap_mt_sms_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5462 f_init_handler(pars, 170.0);
5463 f_sgs_perform_lu();
5464 f_sleep(1.0);
5465
5466 var SmsParameters spars := valueof(t_SmsPars);
5467 spars.tp.ud := 'C8329BFD064D9B53'O;
5468 var integer page_count := 0;
5469 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5470 var template PDU_SGsAP exp_pag_req := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, SMS_indicator, omit);
5471 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
5472 exp_pag_req.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
5473
5474 /* Trigger SMS via VTY */
5475 f_vty_sms_send_conn_hdlr(hex2str(pars.imsi), "2342", "Hello SMS");
5476
Neels Hofmeyr16237742019-03-06 15:34:01 +01005477 /* Expect the MSC/VLR to page exactly once */
5478 SGsAP.receive(exp_pag_req);
Harald Welte4263c522018-12-06 11:56:27 +01005479
5480 /* Wait some time to make sure the MSC is not delivering any further
5481 * paging messages or anything else that could be unexpected. */
5482 timer T := 20.0;
5483 T.start
5484 alt {
5485 [] SGsAP.receive(exp_pag_req)
5486 {
5487 setverdict(fail, "paging seems not to stop!");
5488 mtc.stop;
5489 }
5490 [] SGsAP.receive {
5491 setverdict(fail, "unexpected SGsAP message received");
5492 self.stop;
5493 }
5494 [] T.timeout {
5495 setverdict(pass);
5496 }
5497 }
5498
5499 /* Even on a failed paging the SGs Association should stay intact */
5500 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5501
Philipp Maier26bdb8c2019-09-24 09:21:12 +02005502 /* Make sure that the SMS we just inserted is cleared and the
5503 * subscriber is expired. This is necessary because otherwise the MSC
5504 * might re-try the SMS delivery and disturb the following tests. */
Harald Welte4263c522018-12-06 11:56:27 +01005505
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01005506 f_vty_sms_clear(hex2str(g_pars.imsi));
5507
Harald Welte4263c522018-12-06 11:56:27 +01005508 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " expire");
5509
5510 setverdict(pass);
Neels Hofmeyrb0f82342019-03-06 15:36:51 +01005511
5512 f_sgsap_bssmap_screening();
Harald Welte4263c522018-12-06 11:56:27 +01005513}
5514testcase TC_sgsap_mt_sms_and_nothing() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005515 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005516 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005517 f_init(1, true);
5518 pars := f_init_pars(11825, true);
Pau Espin Pedrole979c402021-04-28 17:29:54 +02005519 pars.common_id_last_eutran_plmn := f_enc_mcc_mnc('901'H, '70'H);
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005520 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mt_sms_and_nothing), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005521 vc_conn.done;
5522}
5523
5524/* Trigger sending of an MT sms via VTY but reject the paging immediately */
5525private function f_tc_sgsap_mt_sms_and_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5526 f_init_handler(pars, 150.0);
5527 f_sgs_perform_lu();
5528 f_sleep(1.0);
5529
5530 var SmsParameters spars := valueof(t_SmsPars);
5531 spars.tp.ud := 'C8329BFD064D9B53'O;
5532 var integer page_count := 0;
5533 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5534 var template PDU_SGsAP exp_pag_req := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, SMS_indicator, omit);
5535 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
5536 exp_pag_req.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
5537
5538 /* Trigger SMS via VTY */
5539 f_vty_sms_send_conn_hdlr(hex2str(pars.imsi), "2342", "Hello SMS");
5540
5541 /* Expect a paging request and reject it immediately */
5542 SGsAP.receive(exp_pag_req);
5543 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, IMSI_unknown));
5544
5545 /* The MSC/VLR should no longer try to page once the paging has been
5546 * rejected. Wait some time and check if there are no unexpected
5547 * messages on the SGs interface. */
5548 timer T := 20.0;
5549 T.start
5550 alt {
5551 [] SGsAP.receive(exp_pag_req)
5552 {
5553 setverdict(fail, "paging seems not to stop!");
5554 mtc.stop;
5555 }
5556 [] SGsAP.receive {
5557 setverdict(fail, "unexpected SGsAP message received");
5558 self.stop;
5559 }
5560 [] T.timeout {
5561 setverdict(pass);
5562 }
5563 }
5564
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01005565 f_vty_sms_clear(hex2str(g_pars.imsi));
5566
Harald Welte4263c522018-12-06 11:56:27 +01005567 /* A rejected paging with IMSI_unknown (see above) should always send
5568 * the SGs association to NULL. */
5569 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
5570
5571 f_sgsap_bssmap_screening();
5572
Harald Welte4263c522018-12-06 11:56:27 +01005573 setverdict(pass);
5574}
5575testcase TC_sgsap_mt_sms_and_reject() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005576 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005577 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005578 f_init(1, true);
5579 pars := f_init_pars(11826, true);
Pau Espin Pedrole979c402021-04-28 17:29:54 +02005580 pars.common_id_last_eutran_plmn := f_enc_mcc_mnc('901'H, '70'H);
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005581 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mt_sms_and_reject), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005582 vc_conn.done;
5583}
5584
Pau Espin Pedrol3acd19e2021-04-28 12:59:52 +02005585/* Perform an MT CSFB call including LU */
Harald Welte4263c522018-12-06 11:56:27 +01005586private function f_mt_lu_and_csfb_call(charstring id, BSC_ConnHdlrPars pars, boolean bssmap_lu) runs on BSC_ConnHdlr {
5587 f_init_handler(pars);
5588
5589 /* Be sure that the BSSMAP reset is done before we begin. */
5590 f_sleep(2.0);
5591
5592 /* Testcase variation: See what happens when we do a regular BSSMAP
5593 * LU first (this should not hurt in any way!) */
5594 if (bssmap_lu) {
5595 f_perform_lu();
5596 }
Pau Espin Pedrole979c402021-04-28 17:29:54 +02005597 pars.common_id_last_eutran_plmn := f_enc_mcc_mnc('901'H, '70'H);
Harald Welte4263c522018-12-06 11:56:27 +01005598
5599 f_sgs_perform_lu();
5600 f_sleep(1.0);
5601
5602 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5603 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Harald Welte4263c522018-12-06 11:56:27 +01005604
5605 /* Initiate a call via MNCC interface */
Oliver Smith97dc91f2023-05-31 13:53:21 +02005606 f_mt_call_initiate(cpars);
Harald Welte4263c522018-12-06 11:56:27 +01005607
5608 /* Expect a paging request and respond accordingly with a service request */
5609 SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit));
5610 SGsAP.send(ts_SGsAP_SERVICE_REQ(pars.imsi, CS_call_indicator, EMM_CONNECTED));
5611
5612 /* Complete the call, hold it for some time and then tear it down */
5613 f_mt_call_complete(cpars);
5614 f_sleep(3.0);
Harald Welte4c422b72019-02-17 16:27:10 +01005615 f_call_hangup(cpars, true, is_csfb := true);
Harald Welte4263c522018-12-06 11:56:27 +01005616
5617 /* Make sure that subscriber is still present and the SGs association is in tact (ref-counting) */
5618 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5619
Harald Welte4263c522018-12-06 11:56:27 +01005620 /* Test for successful return by triggering a paging, when the paging
5621 * request is received via SGs, we can be sure that the MSC/VLR has
5622 * recognized that the UE is now back on 4G */
5623 f_sleep(1.0);
5624 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
5625 alt {
5626 [] SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit)) {
5627 setverdict(pass);
5628 }
5629 [] SGsAP.receive {
5630 setverdict(fail, "Received unexpected message on SGs");
5631 }
5632 }
5633
5634 f_sgsap_bssmap_screening();
5635
5636 setverdict(pass);
5637}
5638
5639/* Perform a regular BSSAP LU first, do a SGSAP LU and then make a CSFB call */
5640private function f_tc_bssap_lu_sgsap_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5641 f_mt_lu_and_csfb_call(id, pars, true);
5642}
5643testcase TC_bssap_lu_sgsap_lu_and_mt_call() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005644 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005645 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005646 f_init(1, true);
5647 pars := f_init_pars(118139, true);
Harald Welte4263c522018-12-06 11:56:27 +01005648
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005649 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 +01005650 vc_conn.done;
5651}
5652
Harald Welte4263c522018-12-06 11:56:27 +01005653/* Perform a SGSAP LU and then make a CSFB call */
5654private function f_tc_sgsap_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5655 f_mt_lu_and_csfb_call(id, pars, false);
5656}
5657testcase TC_sgsap_lu_and_mt_call() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005658 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005659 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005660 f_init(1, true);
5661 pars := f_init_pars(11827, true);
Harald Welte4263c522018-12-06 11:56:27 +01005662
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005663 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu_and_mt_call), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005664 vc_conn.done;
5665}
5666
Philipp Maier628c0052019-04-09 17:36:57 +02005667/* Simulate an HLR/VLR failure */
5668private function f_tc_sgsap_vlr_failure(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5669 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
5670 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5671
5672 var PDU_SGsAP lur;
5673
5674 f_init_handler(pars);
5675
5676 /* Attempt location update (which is expected to fail) */
5677 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
5678 ts_SGsAP_LAI('901'H, '70'H, 2342)));
5679 SGsAP.send(lur);
5680
5681 /* Respond to SGsAP-RESET-INDICATION from VLR */
5682 alt {
5683 [] SGsAP.receive(tr_SGsAP_RESET_IND_VLR(vlr_name)); {
5684 SGsAP.send(valueof(ts_SGsAP_RESET_ACK_MME(mme_name)));
5685 setverdict(pass);
5686 }
5687 [] SGsAP.receive {
5688 setverdict(fail, "Received unexpected message on SGs");
5689 }
5690 }
5691
5692 f_sleep(1.0);
5693 setverdict(pass);
5694}
5695testcase TC_sgsap_vlr_failure() runs on MTC_CT {
5696 var BSC_ConnHdlrPars pars;
5697 var BSC_ConnHdlr vc_conn;
5698 f_init(1, true, false);
5699 pars := f_init_pars(11811, true, false);
5700 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_vlr_failure), pars);
5701 vc_conn.done;
5702}
5703
Harald Welte4263c522018-12-06 11:56:27 +01005704/* SGs TODO:
5705 * LU attempt for IMSI without NAM_PS in HLR
5706 * LU attempt with AUTH FAIL due to invalid RES/SRES
5707 * LU attempt with no response from HLR (VLR should timeout + LU REJ)
5708 * LU attempt with new TMSI but without TMSI REALL CMPL baco to VLR
5709 * implicit IMSI detach from EPS
5710 * implicit IMSI detach from non-EPS
5711 * MM INFO
5712 *
5713 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01005714
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005715private function f_tc_ho_inter_bsc_unknown_cell(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5716 f_init_handler(pars);
5717 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005718
5719 f_perform_lu();
5720 f_mo_call_establish(cpars);
5721
5722 f_sleep(1.0);
5723
5724 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
5725 var BssmapCause cause := enum2int(cause_val);
5726
5727 var template BSSMAP_FIELD_CellIdentificationList cil;
5728 cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('023'H, '42'H, 999) } };
5729
5730 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
5731 BSSAP.receive(tr_BSSMAP_HandoverRequiredReject);
5732
5733 f_call_hangup(cpars, true);
5734}
5735testcase TC_ho_inter_bsc_unknown_cell() runs on MTC_CT {
5736 var BSC_ConnHdlr vc_conn;
5737 f_init();
5738
5739 vc_conn := f_start_handler(refers(f_tc_ho_inter_bsc_unknown_cell), 53);
5740 vc_conn.done;
5741}
5742
5743private altstep as_mgcp_ack_all_mdcx(CallParameters cpars) runs on BSC_ConnHdlr {
5744 var MgcpCommand mgcp_cmd;
5745 [] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
Neels Hofmeyr8913b9e2021-07-27 22:33:45 +02005746 var charstring conn_id;
5747 f_mgcp_find_param_entry(mgcp_cmd.params, "I", conn_id);
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02005748 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 +02005749 hex2str(cpars.mgcp_call_id), "42",
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02005750 cpars.mgw_conn_2.mgw_rtp_port,
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005751 { int2str(cpars.rtp_payload_type) },
5752 { valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
5753 cpars.rtp_sdp_format)),
5754 valueof(ts_SDP_ptime(20)) }));
Neels Hofmeyr8913b9e2021-07-27 22:33:45 +02005755 MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, str2hex(conn_id), sdp));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005756 repeat;
5757 }
5758}
5759
Neels Hofmeyr8853afb2021-07-27 22:34:15 +02005760private altstep as_mgcp_ack_all_dlcx(CallParameters cpars) runs on BSC_ConnHdlr {
5761 var MgcpCommand mgcp_cmd;
5762 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
5763 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
5764 repeat;
5765 }
5766}
5767
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005768private function f_tc_ho_inter_bsc0(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02005769 var CallParameters cpars;
5770
5771 cpars := valueof(t_CallParams('12345'H, 0));
5772 if (pars.use_ipv6) {
5773 cpars.mgw_conn_1.mgw_rtp_ip := "::1";
5774 cpars.mgw_conn_2.mgw_rtp_ip := "::2";
5775 cpars.bss_rtp_ip := "::3";
5776 }
Oliver Smith44424db2023-08-22 13:54:09 +02005777 if (pars.use_csd) {
5778 f_set_cpars_csd(cpars, "BS25T", '1'B, GSM48_BCAP_TR_TRANSP, GSM48_BCAP_UR_4800);
5779 }
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005780
5781 f_init_handler(pars);
5782
5783 f_vty_transceive(MSCVTY, "configure terminal");
5784 f_vty_transceive(MSCVTY, "msc");
5785 f_vty_transceive(MSCVTY, "neighbor a cgi 262 42 23 42 ran-pc 0.24.1");
Neels Hofmeyr2822d072021-06-23 03:20:32 +02005786 f_vty_transceive(MSCVTY, "neighbor a cgi 023 42 5 6 ran-pc 0.24.2");
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005787 f_vty_transceive(MSCVTY, "exit");
5788 f_vty_transceive(MSCVTY, "exit");
5789
5790 f_perform_lu();
5791 f_mo_call_establish(cpars);
5792
5793 f_sleep(1.0);
5794
5795 var default ack_mdcx := activate(as_mgcp_ack_all_mdcx(cpars));
5796
5797 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
5798 var BssmapCause cause := enum2int(cause_val);
5799
5800 var template BSSMAP_FIELD_CellIdentificationList cil;
Neels Hofmeyr2822d072021-06-23 03:20:32 +02005801 cil := { cIl_CGI := { ts_BSSMAP_CI_CGI('023'H, '42'H, 5, 6) } };
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005802
5803 /* old BSS sends Handover Required */
5804 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
5805
5806 /* Now the action goes on in f_tc_ho_inter_bsc1() */
5807
5808 /* MSC forwards the RR Handover Command to old BSS */
5809 var PDU_BSSAP ho_command;
5810 BSSAP.receive(tr_BSSMAP_HandoverCommand) -> value ho_command;
5811
5812 log("GOT HandoverCommand", ho_command);
5813
5814 BSSAP.receive(tr_BSSMAP_HandoverSucceeded);
5815
5816 /* f_tc_ho_inter_bsc1() completes Handover, then expecting a Clear here. */
5817 f_expect_clear();
5818
5819 log("FIRST inter-BSC Handover done");
5820
5821
5822 /* ------------------------ */
5823
5824 /* Ok, that went well, now the other BSC is handovering back here --
5825 * from now on this here is the new BSS. */
Andreas Eversberge5a6ef12023-07-28 10:45:20 +02005826 f_create_bssmap_exp_n_connect(193);
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005827
Neels Hofmeyr0d841d92021-06-21 22:27:21 +02005828 var template BSSMAP_IE_EncryptionInformation encryptionInformation;
5829 var template BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm;
5830 var template BSSMAP_IE_KC128 kC128;
5831 var OCT1 a5_perm_alg;
5832 f_get_expected_encryption(encryptionInformation, chosenEncryptionAlgorithm, kC128, a5_perm_alg);
Vadim Yanitskiyc5fcb892022-08-04 04:06:07 +07005833 var template PDU_BSSAP expect_ho_request := tr_BSSMAP_HandoverRequest(encryptionInformation,
5834 chosenEncryptionAlgorithm,
5835 kC128, codecList := ?);
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005836 var PDU_BSSAP ho_request;
Neels Hofmeyr0d841d92021-06-21 22:27:21 +02005837 alt {
5838 [] BSSAP.receive(expect_ho_request);
5839 [] BSSAP.receive(tr_BSSMAP_HandoverRequest) -> value ho_request {
5840 log("Error: Wrong handoverRequest received. Expected: ", expect_ho_request,
5841 " got ", ho_request);
5842 setverdict(fail, "Wrong handoverRequest received");
5843 mtc.stop;
5844 }
5845 }
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005846
5847 /* new BSS composes a RR Handover Command */
5848 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5849 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02005850 var BSSMAP_IE_AoIP_TransportLayerAddress tla tla :=
5851 valueof(f_ts_BSSMAP_IE_AoIP_TLA(cpars.bss_rtp_ip, cpars.bss_rtp_port));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005852 BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
5853 tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
5854
5855 /* Now f_tc_ho_inter_bsc1() expects HandoverCommand */
5856
5857 f_sleep(0.5);
5858
5859 /* Notify that the MS is now over here */
5860
5861 BSSAP.send(ts_BSSMAP_HandoverDetect);
5862 f_sleep(0.1);
5863 BSSAP.send(ts_BSSMAP_HandoverComplete);
5864
5865 f_sleep(3.0);
5866
5867 deactivate(ack_mdcx);
5868
5869 var default ccrel := activate(as_optional_cc_rel(cpars, true));
5870
5871 /* blatant cheating */
5872 var N_Sd_Array last_n_sd := f_bssmap_last_n_sd();
5873 last_n_sd[0] := 3;
5874 f_bssmap_continue_after_n_sd(last_n_sd);
5875
5876 f_call_hangup(cpars, true);
5877 f_sleep(1.0);
5878 deactivate(ccrel);
5879
5880 setverdict(pass);
5881}
5882private function f_tc_ho_inter_bsc1(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02005883 var charstring bss_rtp_ip;
5884 if (pars.use_ipv6) {
5885 bss_rtp_ip := "::8";
5886 } else {
5887 bss_rtp_ip := "1.2.3.4";
5888 }
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005889 f_init_handler(pars);
Andreas Eversberge5a6ef12023-07-28 10:45:20 +02005890 f_create_bssmap_exp_n_connect(194);
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005891
Neels Hofmeyr0d841d92021-06-21 22:27:21 +02005892 var template BSSMAP_IE_EncryptionInformation encryptionInformation;
5893 var template BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm;
5894 var template BSSMAP_IE_KC128 kC128;
5895 var OCT1 a5_perm_alg;
5896 f_get_expected_encryption(encryptionInformation, chosenEncryptionAlgorithm, kC128, a5_perm_alg);
Vadim Yanitskiyc5fcb892022-08-04 04:06:07 +07005897 var template PDU_BSSAP expect_ho_request := tr_BSSMAP_HandoverRequest(encryptionInformation,
5898 chosenEncryptionAlgorithm,
5899 kC128, codecList := ?);
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005900 var PDU_BSSAP ho_request;
Neels Hofmeyr0d841d92021-06-21 22:27:21 +02005901 alt {
5902 [] BSSAP.receive(expect_ho_request);
5903 [] BSSAP.receive(tr_BSSMAP_HandoverRequest) -> value ho_request {
5904 log("Error: Wrong handoverRequest received. Expected: ", expect_ho_request,
5905 " got ", ho_request);
5906 setverdict(fail, "Wrong handoverRequest received");
5907 mtc.stop;
5908 }
5909 }
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005910 /* new BSS composes a RR Handover Command */
5911 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5912 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02005913 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
5914 valueof(f_ts_BSSMAP_IE_AoIP_TLA(bss_rtp_ip, 2342));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005915 BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
5916 tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
5917
5918 /* Now f_tc_ho_inter_bsc0() expects HandoverCommand */
5919
5920 f_sleep(0.5);
5921
5922 /* Notify that the MS is now over here */
5923
5924 BSSAP.send(ts_BSSMAP_HandoverDetect);
5925 f_sleep(0.1);
5926 BSSAP.send(ts_BSSMAP_HandoverComplete);
5927
5928 f_sleep(3.0);
5929
5930 /* Now I'd like to f_call_hangup() but we don't know any cpars here. So
5931 * ... handover back to the first BSC :P */
5932
5933 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
5934 var BssmapCause cause := enum2int(cause_val);
5935
5936 var template BSSMAP_FIELD_CellIdentificationList cil;
Neels Hofmeyr2822d072021-06-23 03:20:32 +02005937 cil := { cIl_CGI := { ts_BSSMAP_CI_CGI('262'H, '42'H, 23, 42) } };
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005938
5939 /* old BSS sends Handover Required */
5940 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
5941
5942 /* Now the action goes on in f_tc_ho_inter_bsc0() */
5943
5944 /* MSC forwards the RR Handover Command to old BSS */
5945 var PDU_BSSAP ho_command;
5946 BSSAP.receive(tr_BSSMAP_HandoverCommand) -> value ho_command;
5947
5948 log("GOT HandoverCommand", ho_command);
5949
5950 BSSAP.receive(tr_BSSMAP_HandoverSucceeded);
5951
5952 /* f_tc_ho_inter_bsc1() completes Handover, then expecting a Clear here. */
5953 f_expect_clear();
5954 setverdict(pass);
5955}
Oliver Smith44424db2023-08-22 13:54:09 +02005956function f_tc_ho_inter_bsc_main(boolean use_ipv6 := false, integer a5_n := 0, boolean use_csd := false) runs on MTC_CT {
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005957 var BSC_ConnHdlr vc_conn0;
5958 var BSC_ConnHdlr vc_conn1;
5959 f_init(2);
5960
5961 var BSC_ConnHdlrPars pars0 := f_init_pars(53);
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02005962 pars0.use_ipv6 := use_ipv6;
Oliver Smith44424db2023-08-22 13:54:09 +02005963 pars0.use_csd := use_csd;
Neels Hofmeyr0d841d92021-06-21 22:27:21 +02005964 pars0.net.expect_ciph := a5_n > 0;
5965 pars0.net.expect_auth := pars0.net.expect_ciph;
5966 pars0.net.kc_support := bit2oct('00000001'B << a5_n);
5967 pars0.cm2.classmarkInformationType2_oct5.a5_3 := '1'B;
5968 pars0.cm2.classmarkInformationType2_oct5.a5_2 := '0'B;
5969 pars0.cm2.classmarkInformationType2_oct5.cm3 := '1'B;
5970 pars0.cm3 := valueof(ts_CM3_default);
5971 pars0.use_umts_aka := true;
5972 pars0.vec := f_gen_auth_vec_3g();
5973 pars0.vec_keep := true;
Neels Hofmeyr60122f82021-07-28 17:59:38 +02005974 pars0.ran_idx := 0;
Neels Hofmeyr0d841d92021-06-21 22:27:21 +02005975
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005976 var BSC_ConnHdlrPars pars1 := f_init_pars(53);
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02005977 pars1.use_ipv6 := use_ipv6;
Oliver Smith44424db2023-08-22 13:54:09 +02005978 pars1.use_csd := use_csd;
Neels Hofmeyr0d841d92021-06-21 22:27:21 +02005979 pars1.net.expect_ciph := pars0.net.expect_ciph;
5980 pars1.net.expect_auth := pars0.net.expect_ciph;
5981 pars1.net.kc_support := bit2oct('00000001'B << a5_n);
5982 pars1.cm2 := pars0.cm2;
5983 pars1.cm3 := pars0.cm3;
5984 pars1.use_umts_aka := true;
5985 /* Both components need the same auth vector info because we expect f_tc_ho_inter_bsc0's ciphering key to be
5986 * identical to the one that shows up in f_tc_ho_inter_bsc1. Can only do that by feeding in a vector to both
5987 * components and then not overwriting it in BSC_ConnectionHandler. */
5988 pars1.vec := pars0.vec;
5989 pars1.vec_keep := true;
Neels Hofmeyr60122f82021-07-28 17:59:38 +02005990 pars1.ran_idx := 1;
Neels Hofmeyr0d841d92021-06-21 22:27:21 +02005991
5992 if (a5_n > 0) {
5993 f_vty_config(MSCVTY, "network", "authentication required");
5994 }
5995 f_vty_config(MSCVTY, "network", "encryption a5 " & int2str(a5_n));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005996
Neels Hofmeyr60122f82021-07-28 17:59:38 +02005997 vc_conn0 := f_start_handler_with_pars(refers(f_tc_ho_inter_bsc0), pars0);
5998 vc_conn1 := f_start_handler_with_pars(refers(f_tc_ho_inter_bsc1), pars1);
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005999 vc_conn0.done;
6000 vc_conn1.done;
6001}
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02006002testcase TC_ho_inter_bsc() runs on MTC_CT {
Neels Hofmeyr0d841d92021-06-21 22:27:21 +02006003 f_tc_ho_inter_bsc_main(false, a5_n := 0);
6004}
6005testcase TC_ho_inter_bsc_a5_1() runs on MTC_CT {
6006 f_tc_ho_inter_bsc_main(false, a5_n := 1);
6007}
6008testcase TC_ho_inter_bsc_a5_3() runs on MTC_CT {
6009 f_tc_ho_inter_bsc_main(false, a5_n := 3);
6010}
6011testcase TC_ho_inter_bsc_a5_4() runs on MTC_CT {
6012 f_tc_ho_inter_bsc_main(false, a5_n := 4);
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02006013}
6014testcase TC_ho_inter_bsc_ipv6() runs on MTC_CT {
6015 f_tc_ho_inter_bsc_main(true);
6016}
Oliver Smith44424db2023-08-22 13:54:09 +02006017testcase TC_ho_inter_bsc_csd() runs on MTC_CT {
6018 f_tc_ho_inter_bsc_main(use_csd := true);
6019}
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006020
6021function f_ML3_patch_seq_nr_MS_NW(in uint2_t seq_nr, inout octetstring enc_l3) {
6022 log("MS_NW patching N(SD)=", seq_nr, " into dtap ", enc_l3);
6023 enc_l3[2] := (enc_l3[2] and4b '3f'O) or4b bit2oct(int2bit(seq_nr, 8) << 6);
6024 log("MS_NW patched enc_l3: ", enc_l3);
6025}
6026
6027private function f_tc_ho_inter_msc_out(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02006028 var CallParameters cpars;
Neels Hofmeyr906af102021-07-01 12:08:35 +02006029 var PDU_BSSAP ho_request;
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02006030
6031 cpars := valueof(t_CallParams('12345'H, 0));
6032 if (pars.use_ipv6) {
Oliver Smithbe922912023-08-23 15:27:37 +02006033 cpars.mgw_conn_1.mgw_rtp_ip := "::1";
6034 cpars.mgw_conn_2.mgw_rtp_ip := "::2";
6035 cpars.bss_rtp_ip := "::3";
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02006036 }
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006037 var hexstring ho_number := f_gen_msisdn(99999);
6038
6039 f_init_handler(pars);
6040
6041 f_create_mncc_expect(hex2str(ho_number));
6042
6043 f_vty_transceive(MSCVTY, "configure terminal");
6044 f_vty_transceive(MSCVTY, "msc");
6045 f_vty_transceive(MSCVTY, "neighbor a cgi 017 017 1 1 msc-ipa-name msc-017-017-1");
6046 f_vty_transceive(MSCVTY, "exit");
6047 f_vty_transceive(MSCVTY, "exit");
6048
6049 f_perform_lu();
6050 f_mo_call_establish(cpars);
6051
6052 f_sleep(1.0);
6053
6054 var default ack_mdcx := activate(as_mgcp_ack_all_mdcx(cpars));
6055
6056 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
6057 var BssmapCause cause := enum2int(cause_val);
6058
6059 var template BSSMAP_FIELD_CellIdentificationList cil;
Neels Hofmeyr36ebc332021-06-23 03:20:32 +02006060 cil := { cIl_CGI := { ts_BSSMAP_CI_CGI('017'H, '017'H, 1, 1) } };
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006061
6062 /* old BSS sends Handover Required */
6063 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
6064
6065 /* The target cell 017-017 LAC 1 is configured to be a remote MSC of name "msc-017-017-1".
6066 * This MSC tries to reach the other MSC via GSUP. */
6067
Neels Hofmeyr666d39a2021-06-21 22:27:21 +02006068 var template BSSMAP_IE_EncryptionInformation encryptionInformation;
6069 var template BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm;
6070 var template BSSMAP_IE_KC128 kC128;
6071 var OCT1 a5_perm_alg;
6072 f_get_expected_encryption(encryptionInformation, chosenEncryptionAlgorithm, kC128, a5_perm_alg);
Vadim Yanitskiyc5fcb892022-08-04 04:06:07 +07006073 var template PDU_BSSAP expect_ho_request := tr_BSSMAP_HandoverRequest(encryptionInformation,
6074 chosenEncryptionAlgorithm,
6075 kC128, codecList := ?);
Neels Hofmeyr666d39a2021-06-21 22:27:21 +02006076
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006077 var octetstring remote_msc_name := '6D73632D3031372D3031372D3100'O; /* "msc-017-017-1\0" as octetstring */
6078 var GSUP_PDU prep_ho_req;
Neels Hofmeyr666d39a2021-06-21 22:27:21 +02006079 alt {
6080 [] GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_REQUEST,
6081 pars.imsi, destination_name := remote_msc_name,
Neels Hofmeyrec2e1f72021-07-02 02:08:32 +02006082 an_apdu := t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006, pdu := ?))) -> value prep_ho_req;
Neels Hofmeyr666d39a2021-06-21 22:27:21 +02006083 [] GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_REQUEST)) {
6084 setverdict(fail, "Wrong OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_REQUEST message received");
6085 mtc.stop;
6086 }
6087 }
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006088
6089 var GSUP_IeValue source_name_ie;
6090 f_gsup_find_ie(prep_ho_req, OSMO_GSUP_SOURCE_NAME_IE, source_name_ie);
6091 var octetstring local_msc_name := source_name_ie.source_name;
6092
Neels Hofmeyrec2e1f72021-07-02 02:08:32 +02006093 /* Decode PDU to 1) match with expect_ho_request and 2) to forward the actual chosen encryption algorithm. */
Neels Hofmeyr906af102021-07-01 12:08:35 +02006094 var GSUP_IeValue an_apdu_ie;
6095 f_gsup_find_ie(prep_ho_req, OSMO_GSUP_AN_APDU_IE, an_apdu_ie);
6096 ho_request := dec_PDU_BSSAP(an_apdu_ie.an_apdu.pdu);
Neels Hofmeyrec2e1f72021-07-02 02:08:32 +02006097 if (not match(ho_request, expect_ho_request)) {
6098 setverdict(fail, "Wrong PDU in OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_REQUEST message received");
6099 mtc.stop;
6100 }
Neels Hofmeyr906af102021-07-01 12:08:35 +02006101
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006102 /* Remote MSC has figured out its BSC and signals success */
6103 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
6104 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
6105 var PDU_BSSAP ho_req_ack := valueof(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
Neels Hofmeyr906af102021-07-01 12:08:35 +02006106 aoIPTransportLayer := omit,
6107 speechCodec := ts_BSSMAP_IE_SpeechCodec({ts_CodecFR}),
6108 chosenEncryptionAlgorithm := ho_request.pdu.bssmap.handoverRequest.chosenEncryptionAlgorithm));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006109 GSUP.send(ts_GSUP_E_PrepareHandoverResult(
6110 pars.imsi,
6111 ho_number,
6112 remote_msc_name, local_msc_name,
6113 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006, enc_PDU_BSSAP(ho_req_ack)))));
6114
6115 /* MSC forwards the RR Handover Command to old BSS */
6116 BSSAP.receive(tr_BSSMAP_HandoverCommand);
6117
6118 /* The MS shows up at remote new BSS */
6119
6120 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST,
6121 pars.imsi, remote_msc_name, local_msc_name,
6122 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
6123 enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverDetect))))));
6124 BSSAP.receive(tr_BSSMAP_HandoverSucceeded);
6125 f_sleep(0.1);
6126
6127 /* Save the MS sequence counters for use on the other connection */
6128 var N_Sd_Array last_n_sd := f_bssmap_last_n_sd();
6129
6130 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_REQUEST,
6131 pars.imsi, remote_msc_name, local_msc_name,
6132 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
6133 enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverComplete))))));
6134
6135 /* The local BSS conn clears, all communication goes via remote MSC now */
6136 f_expect_clear();
6137
6138 /**********************************/
6139 /* Play through some signalling across the inter-MSC link.
6140 * This is a copy of f_tc_lu_and_mo_ussd_single_request() translated into GSUP AN-APDUs. */
6141
6142 if (false) {
6143 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
6144 invoke_id := 5, /* Phone may not start from 0 or 1 */
6145 op_code := SS_OP_CODE_PROCESS_USS_REQ,
6146 ussd_string := "*#100#"
6147 );
6148
6149 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
6150 invoke_id := 5, /* InvokeID shall be the same for both REQ and RSP */
6151 op_code := SS_OP_CODE_PROCESS_USS_REQ,
6152 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
6153 )
6154
6155 /* Compose a new SS/REGISTER message with request */
6156 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
6157 tid := 1, /* We just need a single transaction */
6158 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
6159 facility := valueof(facility_req)
6160 );
6161 var PDU_ML3_MS_NW ussd_req_v := valueof(ussd_req);
6162
6163 /* Compose SS/RELEASE_COMPLETE template with expected response */
6164 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
6165 tid := 1, /* Response should arrive within the same transaction */
6166 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
6167 facility := valueof(facility_rsp)
6168 );
6169
6170 /* Compose expected MSC -> HLR message */
6171 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
6172 imsi := g_pars.imsi,
6173 state := OSMO_GSUP_SESSION_STATE_BEGIN,
6174 ss := valueof(facility_req)
6175 );
6176
6177 /* To be used for sending response with correct session ID */
6178 var GSUP_PDU gsup_req_complete;
6179
6180 /* Request own number */
6181 /* From remote MSC instead of BSSAP directly */
6182 /* Patch the correct N_SD value into the message. */
6183 var octetstring l3_enc := enc_PDU_ML3_MS_NW(ussd_req_v);
6184 var RAN_Emulation.ConnectionData cd;
6185 f_ML3_patch_seq_nr_MS_NW(f_next_n_sd(last_n_sd, f_ML3_n_sd_idx(ussd_req_v)), l3_enc);
6186 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST,
6187 pars.imsi, remote_msc_name, local_msc_name,
6188 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
6189 enc_PDU_BSSAP(valueof(ts_BSSAP_DTAP(l3_enc)))
6190 ))
6191 ));
6192
6193 /* Expect GSUP message containing the SS payload */
6194 gsup_req_complete := f_expect_gsup_msg(gsup_req);
6195
6196 /* Compose the response from HLR using received session ID */
6197 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
6198 imsi := g_pars.imsi,
6199 sid := gsup_req_complete.ies[1].val.session_id,
6200 state := OSMO_GSUP_SESSION_STATE_END,
6201 ss := valueof(facility_rsp)
6202 );
6203
6204 /* Finally, HLR terminates the session */
6205 GSUP.send(gsup_rsp);
6206
6207 /* The USSD response goes out to remote MSC, on GSUP E instead of BSSAP */
6208 var GSUP_PDU gsup_ussd_rsp;
6209 GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST,
6210 pars.imsi, destination_name := remote_msc_name)) -> value gsup_ussd_rsp;
6211
6212 var GSUP_IeValue an_apdu;
6213 if (not f_gsup_find_ie(gsup_ussd_rsp, OSMO_GSUP_AN_APDU_IE, an_apdu)) {
6214 setverdict(fail, "No AN-APDU in received GSUP message. Expected USSD response in DTAP, got", gsup_ussd_rsp);
6215 mtc.stop;
6216 }
6217 var PDU_BSSAP bssap_dtap_mt := dec_PDU_BSSAP(an_apdu.an_apdu.pdu);
6218 var PDU_ML3_NW_MS dtap_mt := dec_PDU_ML3_NW_MS(bssap_dtap_mt.pdu.dtap);
6219 log("Expecting", ussd_rsp);
6220 log("Got", dtap_mt);
6221 if (not match(dtap_mt, ussd_rsp)) {
6222 setverdict(fail, "Unexpected GSUP message. Expected USSD response in DTAP, got", gsup_ussd_rsp);
6223 mtc.stop;
6224 }
6225 }
6226 /**********************************/
6227
6228
6229 /* inter-MSC handover back to the first MSC */
Andreas Eversberge5a6ef12023-07-28 10:45:20 +02006230 f_create_bssmap_exp_n_connect(193);
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006231 cil := { cIl_CGI := { ts_BSSMAP_CI_CGI('262'H, '42'H, 23, 42) } };
6232
6233 /* old BSS sends Handover Required, via inter-MSC E link: like
6234 * BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
6235 * but via GSUP */
6236 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_REQUEST,
6237 pars.imsi, remote_msc_name, local_msc_name,
6238 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
6239 enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverRequired(cause, cil)))
6240 ))
6241 ));
6242
6243 /* MSC asks local BSS to prepare Handover to it */
Neels Hofmeyr666d39a2021-06-21 22:27:21 +02006244 f_get_expected_encryption(encryptionInformation, chosenEncryptionAlgorithm, kC128, a5_perm_alg);
Vadim Yanitskiyc5fcb892022-08-04 04:06:07 +07006245 expect_ho_request := tr_BSSMAP_HandoverRequest(encryptionInformation,
6246 chosenEncryptionAlgorithm,
6247 kC128, codecList := ?);
Neels Hofmeyr666d39a2021-06-21 22:27:21 +02006248 alt {
Neels Hofmeyr906af102021-07-01 12:08:35 +02006249 [] BSSAP.receive(expect_ho_request) -> value ho_request;
Neels Hofmeyr666d39a2021-06-21 22:27:21 +02006250 [] BSSAP.receive(tr_BSSMAP_HandoverRequest) -> value ho_request {
6251 log("Error: Wrong handoverRequest received. Expected: ", expect_ho_request,
6252 " got ", ho_request);
6253 setverdict(fail, "Wrong handoverRequest received");
6254 mtc.stop;
6255 }
6256 }
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006257
6258 /* Make sure the new BSSAP conn continues with the correct N_SD sequence numbers */
6259 f_bssmap_continue_after_n_sd(last_n_sd);
6260
6261 /* new BSS composes a RR Handover Command */
6262 rr_ho_cmd := valueof(ts_RR_HandoverCommand);
6263 rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02006264 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
6265 valueof(f_ts_BSSMAP_IE_AoIP_TLA(cpars.bss_rtp_ip, cpars.bss_rtp_port));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006266 BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
Neels Hofmeyr906af102021-07-01 12:08:35 +02006267 tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR}),
6268 chosenEncryptionAlgorithm := ho_request.pdu.bssmap.handoverRequest.chosenEncryptionAlgorithm));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006269
6270 /* HandoverCommand goes out via remote MSC-I */
6271 var GSUP_PDU prep_subsq_ho_res;
6272 GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_RESULT,
6273 pars.imsi, destination_name := remote_msc_name)) -> value prep_subsq_ho_res;
6274
6275 /* MS shows up at the local BSS */
6276 BSSAP.send(ts_BSSMAP_HandoverDetect);
6277 f_sleep(0.1);
6278 BSSAP.send(ts_BSSMAP_HandoverComplete);
6279
6280 /* Handover Succeeded message */
6281 GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST,
6282 pars.imsi, destination_name := remote_msc_name));
6283
6284 /* MS has handovered to here, Clear Command goes out via remote MSC-I -- in form of a GSUP Close. */
6285 GSUP.receive(tr_GSUP_E_NO_PDU(OSMO_GSUP_MSGT_E_CLOSE,
6286 pars.imsi, destination_name := remote_msc_name));
6287
6288 /* Handover ends successfully. Call goes on for a little longer and then we hang up. */
6289
6290 f_sleep(1.0);
6291 deactivate(ack_mdcx);
6292
6293 /* FIXME: the inter-MSC call has put a number of MNCC messages in the queue, which above code should expect and
6294 * clear out. The f_call_hangup() expects an MNCC_REL_IND, so, for the time being, just clear the MNCC messages
6295 * before starting the call hangup. Instead of this, the individual messages should be tested for above. */
6296 MNCC.clear;
6297
6298 var default ccrel := activate(as_optional_cc_rel(cpars, true));
6299 f_call_hangup(cpars, true);
6300 f_sleep(1.0);
6301 deactivate(ccrel);
6302
6303 setverdict(pass);
6304}
Neels Hofmeyr666d39a2021-06-21 22:27:21 +02006305function f_tc_ho_inter_msc_out_a5(integer a5_n) runs on MTC_CT {
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006306 var BSC_ConnHdlr vc_conn;
6307 f_init(1);
6308
6309 var BSC_ConnHdlrPars pars := f_init_pars(54);
Neels Hofmeyr666d39a2021-06-21 22:27:21 +02006310 pars.net.expect_ciph := a5_n > 0;
6311 pars.net.expect_auth := pars.net.expect_ciph;
6312 pars.net.kc_support := bit2oct('00000001'B << a5_n);
6313 pars.cm2.classmarkInformationType2_oct5.a5_3 := '1'B;
6314 pars.cm2.classmarkInformationType2_oct5.a5_2 := '0'B;
6315 pars.cm2.classmarkInformationType2_oct5.cm3 := '1'B;
6316 pars.cm3 := valueof(ts_CM3_default);
6317 pars.use_umts_aka := true;
6318
6319 if (a5_n > 0) {
6320 f_vty_config(MSCVTY, "network", "authentication required");
6321 }
6322 f_vty_config(MSCVTY, "network", "encryption a5 " & int2str(a5_n));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006323
Neels Hofmeyr60122f82021-07-28 17:59:38 +02006324 vc_conn := f_start_handler_with_pars(refers(f_tc_ho_inter_msc_out), pars);
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006325 vc_conn.done;
6326}
Neels Hofmeyr666d39a2021-06-21 22:27:21 +02006327testcase TC_ho_inter_msc_out() runs on MTC_CT {
6328 f_tc_ho_inter_msc_out_a5(0);
6329}
6330testcase TC_ho_inter_msc_out_a5_1() runs on MTC_CT {
6331 f_tc_ho_inter_msc_out_a5(1);
6332}
6333testcase TC_ho_inter_msc_out_a5_3() runs on MTC_CT {
6334 f_tc_ho_inter_msc_out_a5(3);
6335}
6336testcase TC_ho_inter_msc_out_a5_4() runs on MTC_CT {
6337 f_tc_ho_inter_msc_out_a5(4);
6338}
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02006339testcase TC_ho_inter_msc_out_ipv6() runs on MTC_CT {
6340 var BSC_ConnHdlr vc_conn;
6341 f_init(1);
6342
6343 var BSC_ConnHdlrPars pars := f_init_pars(54);
6344 pars.use_ipv6 := true;
6345
Neels Hofmeyr60122f82021-07-28 17:59:38 +02006346 vc_conn := f_start_handler_with_pars(refers(f_tc_ho_inter_msc_out), pars);
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02006347 vc_conn.done;
6348}
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006349
Oliver Smith1d118ff2019-07-03 10:57:35 +02006350private function f_tc_lu_imsi_auth_tmsi_check_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6351 pars.net.expect_auth := true;
6352 pars.net.expect_imei := true;
6353 f_init_handler(pars);
6354 f_perform_lu();
6355}
6356testcase TC_lu_imsi_auth_tmsi_check_imei() runs on MTC_CT {
6357 var BSC_ConnHdlr vc_conn;
6358 f_init();
6359 f_vty_config(MSCVTY, "network", "authentication required");
6360 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
6361
6362 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei), 5);
6363 vc_conn.done;
6364}
6365
6366private function f_tc_lu_imsi_auth3g_tmsi_check_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6367 pars.net.expect_auth := true;
6368 pars.use_umts_aka := true;
6369 pars.net.expect_imei := true;
6370 f_init_handler(pars);
6371 f_perform_lu();
6372}
6373testcase TC_lu_imsi_auth3g_tmsi_check_imei() runs on MTC_CT {
6374 var BSC_ConnHdlr vc_conn;
6375 f_init();
6376 f_vty_config(MSCVTY, "network", "authentication required");
6377 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
6378
6379 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth3g_tmsi_check_imei), 5);
6380 vc_conn.done;
6381}
6382
6383private function f_tc_lu_imsi_noauth_tmsi_check_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6384 pars.net.expect_imei := true;
6385 f_init_handler(pars);
6386 f_perform_lu();
6387}
6388testcase TC_lu_imsi_noauth_tmsi_check_imei() runs on MTC_CT {
6389 var BSC_ConnHdlr vc_conn;
6390 f_init();
6391 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
6392
6393 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi_check_imei), 5);
6394 vc_conn.done;
6395}
6396
6397private function f_tc_lu_imsi_noauth_notmsi_check_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6398 pars.net.expect_tmsi := false;
6399 pars.net.expect_imei := true;
6400 f_init_handler(pars);
6401 f_perform_lu();
6402}
6403testcase TC_lu_imsi_noauth_notmsi_check_imei() runs on MTC_CT {
6404 var BSC_ConnHdlr vc_conn;
6405 f_init();
6406 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
6407 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
6408
6409 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi_check_imei), 5);
6410 vc_conn.done;
6411}
6412
6413private function f_tc_lu_imsi_auth_tmsi_check_imei_nack(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6414 var PDU_ML3_MS_NW l3_lu;
Oliver Smith1d118ff2019-07-03 10:57:35 +02006415
6416 pars.net.expect_auth := true;
6417 pars.net.expect_imei := true;
6418 pars.net.check_imei_result := OSMO_GSUP_IMEI_RESULT_NACK;
6419 f_init_handler(pars);
6420
6421 /* Cannot use f_perform_lu() as we expect a reject */
6422 l3_lu := f_build_lu_imsi(g_pars.imsi)
6423 f_create_gsup_expect(hex2str(g_pars.imsi));
6424 f_bssap_compl_l3(l3_lu);
6425 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
6426
6427 f_mm_common();
6428 f_msc_lu_hlr();
6429 f_mm_imei();
Oliver Smith91bfa1c2019-07-19 15:01:15 +02006430 f_expect_lu_reject();
Eric Wild85cc1612022-03-30 01:44:29 +02006431 f_expect_clear(verify_vlr_cell_id:=false);
Oliver Smith1d118ff2019-07-03 10:57:35 +02006432}
6433testcase TC_lu_imsi_auth_tmsi_check_imei_nack() runs on MTC_CT {
6434 var BSC_ConnHdlr vc_conn;
6435 f_init();
6436 f_vty_config(MSCVTY, "network", "authentication required");
6437 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
6438
6439 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_nack), 5);
6440 vc_conn.done;
6441}
6442
6443private function f_tc_lu_imsi_auth_tmsi_check_imei_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6444 var PDU_ML3_MS_NW l3_lu;
Oliver Smith1d118ff2019-07-03 10:57:35 +02006445
6446 pars.net.expect_auth := true;
6447 pars.net.expect_imei := true;
6448 pars.net.check_imei_error := true;
6449 f_init_handler(pars);
6450
6451 /* Cannot use f_perform_lu() as we expect a reject */
6452 l3_lu := f_build_lu_imsi(g_pars.imsi)
6453 f_create_gsup_expect(hex2str(g_pars.imsi));
6454 f_bssap_compl_l3(l3_lu);
6455 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
6456
6457 f_mm_common();
6458 f_msc_lu_hlr();
6459 f_mm_imei();
Oliver Smith91bfa1c2019-07-19 15:01:15 +02006460 f_expect_lu_reject();
Eric Wild85cc1612022-03-30 01:44:29 +02006461 f_expect_clear(verify_vlr_cell_id:=false);
Oliver Smith1d118ff2019-07-03 10:57:35 +02006462}
6463testcase TC_lu_imsi_auth_tmsi_check_imei_err() runs on MTC_CT {
6464 var BSC_ConnHdlr vc_conn;
6465 f_init();
6466 f_vty_config(MSCVTY, "network", "authentication required");
6467 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
6468
6469 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_err), 5);
6470 vc_conn.done;
6471}
6472
6473private function f_tc_lu_imsi_auth_tmsi_check_imei_early(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6474 pars.net.expect_auth := true;
6475 pars.net.expect_imei_early := true;
6476 f_init_handler(pars);
6477 f_perform_lu();
6478}
6479testcase TC_lu_imsi_auth_tmsi_check_imei_early() runs on MTC_CT {
6480 var BSC_ConnHdlr vc_conn;
6481 f_init();
6482 f_vty_config(MSCVTY, "network", "authentication required");
6483 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
6484
6485 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_early), 5);
6486 vc_conn.done;
6487}
6488
6489private function f_tc_lu_imsi_auth3g_tmsi_check_imei_early(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6490 pars.net.expect_auth := true;
6491 pars.use_umts_aka := true;
6492 pars.net.expect_imei_early := true;
6493 f_init_handler(pars);
6494 f_perform_lu();
6495}
6496testcase TC_lu_imsi_auth3g_tmsi_check_imei_early() runs on MTC_CT {
6497 var BSC_ConnHdlr vc_conn;
6498 f_init();
6499 f_vty_config(MSCVTY, "network", "authentication required");
6500 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
6501
6502 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth3g_tmsi_check_imei_early), 5);
6503 vc_conn.done;
6504}
6505
6506private function f_tc_lu_imsi_noauth_tmsi_check_imei_early(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6507 pars.net.expect_imei_early := true;
6508 f_init_handler(pars);
6509 f_perform_lu();
6510}
6511testcase TC_lu_imsi_noauth_tmsi_check_imei_early() runs on MTC_CT {
6512 var BSC_ConnHdlr vc_conn;
6513 f_init();
6514 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
6515
6516 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi_check_imei_early), 5);
6517 vc_conn.done;
6518}
6519
6520private function f_tc_lu_imsi_noauth_notmsi_check_imei_early(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6521 pars.net.expect_tmsi := false;
6522 pars.net.expect_imei_early := true;
6523 f_init_handler(pars);
6524 f_perform_lu();
6525}
6526testcase TC_lu_imsi_noauth_notmsi_check_imei_early() runs on MTC_CT {
6527 var BSC_ConnHdlr vc_conn;
6528 f_init();
6529 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
6530 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
6531
6532 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi_check_imei_early), 5);
6533 vc_conn.done;
6534}
6535
6536private function f_tc_lu_imsi_auth_tmsi_check_imei_early_nack(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6537 var PDU_ML3_MS_NW l3_lu;
Oliver Smith1d118ff2019-07-03 10:57:35 +02006538
6539 pars.net.expect_auth := true;
6540 pars.net.expect_imei_early := true;
6541 pars.net.check_imei_result := OSMO_GSUP_IMEI_RESULT_NACK;
6542 f_init_handler(pars);
6543
6544 /* Cannot use f_perform_lu() as we expect a reject */
6545 l3_lu := f_build_lu_imsi(g_pars.imsi)
6546 f_create_gsup_expect(hex2str(g_pars.imsi));
6547 f_bssap_compl_l3(l3_lu);
6548 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
6549
6550 f_mm_imei_early();
Oliver Smith91bfa1c2019-07-19 15:01:15 +02006551 f_expect_lu_reject();
Eric Wild85cc1612022-03-30 01:44:29 +02006552 f_expect_clear(verify_vlr_cell_id:=false);
Oliver Smith1d118ff2019-07-03 10:57:35 +02006553}
6554testcase TC_lu_imsi_auth_tmsi_check_imei_early_nack() runs on MTC_CT {
6555 var BSC_ConnHdlr vc_conn;
6556 f_init();
6557 f_vty_config(MSCVTY, "network", "authentication required");
6558 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
6559
6560 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_early_nack), 5);
6561 vc_conn.done;
6562}
6563
6564private function f_tc_lu_imsi_auth_tmsi_check_imei_early_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6565 var PDU_ML3_MS_NW l3_lu;
Oliver Smith1d118ff2019-07-03 10:57:35 +02006566
6567 pars.net.expect_auth := true;
6568 pars.net.expect_imei_early := true;
6569 pars.net.check_imei_error := true;
6570 f_init_handler(pars);
6571
6572 /* Cannot use f_perform_lu() as we expect a reject */
6573 l3_lu := f_build_lu_imsi(g_pars.imsi)
6574 f_create_gsup_expect(hex2str(g_pars.imsi));
6575 f_bssap_compl_l3(l3_lu);
6576 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
6577
6578 f_mm_imei_early();
Oliver Smith91bfa1c2019-07-19 15:01:15 +02006579 f_expect_lu_reject();
Eric Wild85cc1612022-03-30 01:44:29 +02006580 f_expect_clear(verify_vlr_cell_id:=false);
Oliver Smith1d118ff2019-07-03 10:57:35 +02006581}
6582testcase TC_lu_imsi_auth_tmsi_check_imei_early_err() runs on MTC_CT {
6583 var BSC_ConnHdlr vc_conn;
6584 f_init();
6585 f_vty_config(MSCVTY, "network", "authentication required");
6586 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
6587
6588 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_early_err), 5);
6589 vc_conn.done;
6590}
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006591
Neels Hofmeyr8df69622019-11-02 19:16:03 +01006592friend function f_tc_invalid_mgcp_crash(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6593 f_init_handler(pars);
6594 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
6595
6596 /* Set invalid IP address so that osmo-msc discards the rtp_stream and MGCP endpoint FSM instances in the middle
6597 * of successful MGCP response dispatch. If things aren't safeguarded, the on_success() in osmo_mgcpc_ep_fsm
6598 * will cause a use-after-free after that event dispatch. */
6599 cpars.mgw_conn_1.mgw_rtp_ip := "0.0.0.0";
6600 cpars.mgw_conn_2.mgw_rtp_ip := "0.0.0.0";
6601 cpars.rtp_sdp_format := "FOO/8000";
6602 cpars.expect_release := true;
6603
6604 f_perform_lu();
6605 f_mo_call_establish(cpars);
6606}
6607testcase TC_invalid_mgcp_crash() runs on MTC_CT {
6608 var BSC_ConnHdlr vc_conn;
6609 f_init();
6610
6611 vc_conn := f_start_handler(refers(f_tc_invalid_mgcp_crash), 7);
6612 vc_conn.done;
6613}
6614
Vadim Yanitskiyeddebaa2019-12-28 17:45:34 +01006615friend function f_tc_mm_id_resp_no_identity(charstring id, BSC_ConnHdlrPars pars)
6616runs on BSC_ConnHdlr {
6617 pars.tmsi := 'FFFFFFFF'O;
6618 f_init_handler(pars);
6619
6620 f_create_gsup_expect(hex2str(g_pars.imsi));
6621
6622 /* Initiate Location Updating using an unknown TMSI */
6623 f_bssap_compl_l3(f_build_lu_tmsi(pars.tmsi));
6624
6625 /* Expect an Identity Request, send response with no identity */
6626 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req(CM_ID_TYPE_IMSI)));
6627 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp({
6628 lengthIndicator := 1,
6629 mobileIdentityV := {
6630 typeOfIdentity := '000'B,
6631 oddEvenInd_identity := {
6632 no_identity := {
6633 oddevenIndicator := '0'B,
6634 fillerDigits := '00000'H
6635 }
6636 }
6637 }
6638 })));
6639
6640 f_expect_lu_reject();
6641 f_expect_clear();
6642}
6643testcase TC_mm_id_resp_no_identity() runs on MTC_CT {
6644 var BSC_ConnHdlr vc_conn;
6645
6646 f_init();
6647
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02006648 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 +01006649 vc_conn.done;
6650}
6651
Vadim Yanitskiy25219062020-01-21 01:41:33 +07006652/* Verify the case when T3212 expires during Paging procedure, just before the receipt
6653 * of Paging Response. This used to provoke a NULL-pointer dereference in old versions
6654 * of OsmoMSC, but apparently the bug has been fixed, and we're safe now. */
6655friend function f_tc_lu_and_expire_while_paging(charstring id, BSC_ConnHdlrPars pars)
6656runs on BSC_ConnHdlr {
6657 var charstring imsi := hex2str(pars.imsi);
6658
6659 f_init_handler(pars);
6660
6661 /* Perform location update */
6662 f_perform_lu();
6663
6664 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
6665 f_create_gsup_expect(hex2str(g_pars.imsi));
6666
6667 /* Initiate paging procedure from the VTY */
6668 f_vty_transceive(MSCVTY, "subscriber imsi " & imsi & " paging");
6669 f_expect_paging();
6670
6671 /* Emulate T3212 expiration during paging (we don't want to wait, right?) */
6672 f_vty_transceive(MSCVTY, "subscriber imsi " & imsi & " expire");
6673
6674 /* MS sends PAGING RESPONSE, *old* OsmoMSC crashes here... */
6675 f_establish_fully(EST_TYPE_PAG_RESP);
6676
6677 /* The recent OsmoMSC keeps subscriber in its VLR unless the Paging is completed.
6678 * In this case we do not send anything and just wait for a Clear Command. */
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02006679 f_expect_clear(verify_vlr_cell_id := false);
Vadim Yanitskiy25219062020-01-21 01:41:33 +07006680}
6681testcase TC_lu_and_expire_while_paging() runs on MTC_CT {
6682 var BSC_ConnHdlr vc_conn;
6683
6684 f_init();
6685
6686 vc_conn := f_start_handler(refers(f_tc_lu_and_expire_while_paging), 7);
6687 vc_conn.done;
6688}
6689
Neels Hofmeyr3ad76a42022-08-09 02:57:49 +02006690private altstep as_mncc_rx_rtp_create(CallParameters cpars) runs on BSC_ConnHdlr {
6691 [] MNCC.receive(tr_MNCC_RTP_CREATE(cpars.mncc_callref));
6692}
6693
Neels Hofmeyr4f099b42021-07-27 03:45:26 +02006694const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
6695const charstring REEST_CLEARED := "REEST_CLEARED";
6696
6697friend function f_tc_call_re_establishment_1(charstring id, BSC_ConnHdlrPars pars)
6698 runs on BSC_ConnHdlr {
6699 f_init_handler(pars, t_guard := 30.0);
6700
6701 f_perform_lu();
6702
6703 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
6704 f_mo_call_establish(cpars);
6705 f_sleep(3.0);
6706 COORD.send(REEST_LOST_CONNECTION);
6707 COORD.send(cpars);
6708 f_expect_clear(verify_vlr_cell_id := false);
6709 COORD.send(REEST_CLEARED);
6710}
6711
6712friend function f_tc_call_re_establishment_2(charstring id, BSC_ConnHdlrPars pars)
6713 runs on BSC_ConnHdlr {
6714 f_init_handler(pars, t_guard := 30.0);
6715 var CallParameters cpars;
6716
6717 COORD.receive(REEST_LOST_CONNECTION);
6718 COORD.receive(tr_CallParams) -> value cpars;
6719
6720 f_gsup_change_connhdlr(hex2str(g_pars.imsi));
6721 f_create_smpp_expect(hex2str(pars.msisdn));
6722
6723 /* The MS has lost the first channel and decides to show up on a new conn (on a nearby neighbor cell) to ask for
6724 * CM Re-Establishment. Send a Complete Layer 3 to osmo-msc with a CM Re-Establishment Request. */
6725 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
6726 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
6727 f_cl3_or_initial_ue(l3_info);
6728
6729 /* At this point the other test component should receive the Clear Command for the first A connection. */
6730
6731 /* This new connection continues with Authentication... */
6732 f_mm_common();
6733
6734 /* ...and with Assignment of a voice channel. */
6735 var template BSSMAP_IE_AoIP_TransportLayerAddress tla_ass :=
Neels Hofmeyr02d513e2022-07-25 22:07:24 +02006736 (f_tr_BSSMAP_IE_AoIP_TLA(cpars.mgw_conn_1.mgw_rtp_ip, ?),
6737 f_tr_BSSMAP_IE_AoIP_TLA(cpars.mgw_conn_2.mgw_rtp_ip, ?));
Neels Hofmeyr4f099b42021-07-27 03:45:26 +02006738 BSSAP.receive(tr_BSSMAP_AssignmentReq(omit, tla_ass));
6739 /* By this Assignment Request, the CM Re-Establishment Request is implicitly accepted. */
6740
6741 /* Send Assignment Complete from BSC */
6742 var template BSSMAP_IE_AoIP_TransportLayerAddress tla;
6743 tla := f_ts_BSSMAP_IE_AoIP_TLA(cpars.bss_rtp_ip, cpars.bss_rtp_port);
6744 var BSSMAP_IE_SpeechCodec codec;
6745 codec := valueof(ts_BSSMAP_IE_SpeechCodec({ts_CodecFR}));
6746
6747 /* Make really sure the other component is done with its MGCP */
6748 COORD.receive(REEST_CLEARED);
6749
6750 /* Transfer state for this call over to this test component so we can resolve MNCC and MGCP in this function. */
6751 f_mncc_change_connhdlr(cpars.mncc_callref);
6752 f_mgcp_change_connhdlr(cpars.mgcp_ep);
6753
6754 /* osmo-msc may redirect the MGW endpoint to the newly allocated channel.
6755 * Apparently osmo-msc currently also sends an MDCX to the CN side, just repeating the same configuration that
6756 * is already in use. This test accepts any number of or even lack of MDCX. */
6757 var default ack_mdcx := activate(as_mgcp_ack_all_mdcx(cpars));
Neels Hofmeyr3ad76a42022-08-09 02:57:49 +02006758 var default optional_rtp_create := activate(as_mncc_rx_rtp_create(cpars));
Neels Hofmeyr4f099b42021-07-27 03:45:26 +02006759
6760 BSSAP.send(ts_BSSMAP_AssignmentComplete(omit, tla, codec));
Neels Hofmeyr3ad76a42022-08-09 02:57:49 +02006761
Neels Hofmeyr4f099b42021-07-27 03:45:26 +02006762 /* The call has been fully re-established.
6763 * Let a bit of time pass before hanging up, for everything to settle. */
6764 f_sleep(3.0);
6765
Neels Hofmeyr3ad76a42022-08-09 02:57:49 +02006766 deactivate(optional_rtp_create);
Neels Hofmeyr4f099b42021-07-27 03:45:26 +02006767 deactivate(ack_mdcx);
6768
6769 /* Hang up the call and clear the new, second A connection */
6770 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx(cpars));
6771
6772 /* CC release. This is the proper MS initiated release sequence as shown by
6773 * https://git.osmocom.org/osmo-msc/tree/doc/sequence_charts/voice_call_full.msc?id=e53ecde83e4fb2470209e818e9ad76a2d6a19190
6774 * f_call_hangup() seems a bit mixed up, so here a "proper" sequence. Fix of f_call_hangup() pending. */
6775 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_DISC(cpars.transaction_id, '0'B, '0000000'B)));
6776 MNCC.receive(tr_MNCC_DISC_ind(cpars.mncc_callref));
6777 MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(23))));
6778 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
6779 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id, '0'B)));
6780 MNCC.receive(tr_MNCC_REL_cnf(cpars.mncc_callref, cause := *));
6781
6782 /* BSSAP clear */
6783 interleave {
6784 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
6785 BSSAP.send(ts_BSSMAP_ClearComplete);
6786 }
6787 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
6788 }
6789
6790 f_sleep(1.0);
6791 deactivate(ack_dlcx);
6792}
6793
6794testcase TC_call_re_establishment() runs on MTC_CT {
6795 var BSC_ConnHdlr vc_conn1;
6796 var BSC_ConnHdlr vc_conn2;
6797 f_init();
6798
6799 var BSC_ConnHdlrPars pars1 := f_init_pars(91);
6800 var BSC_ConnHdlrPars pars2 := pars1;
6801
6802 vc_conn1 := f_start_handler_create(pars1);
6803 vc_conn2 := f_start_handler_create(pars2);
6804 connect(vc_conn1:COORD, vc_conn2:COORD);
6805 f_start_handler_run(vc_conn1, refers(f_tc_call_re_establishment_1), pars1);
6806 f_start_handler_run(vc_conn2, refers(f_tc_call_re_establishment_2), pars2);
6807 vc_conn1.done;
6808 vc_conn2.done;
6809}
6810
Neels Hofmeyra9b2dcf2021-07-28 00:57:58 +02006811testcase TC_call_re_establishment_auth() runs on MTC_CT {
6812 var BSC_ConnHdlr vc_conn1;
6813 var BSC_ConnHdlr vc_conn2;
6814 f_init();
6815
6816 f_vty_config(MSCVTY, "network", "authentication required");
6817
6818 var BSC_ConnHdlrPars pars1 := f_init_pars(92);
6819 pars1.net.expect_auth := true;
6820 var BSC_ConnHdlrPars pars2 := pars1;
6821
6822 vc_conn1 := f_start_handler_create(pars1);
6823 vc_conn2 := f_start_handler_create(pars2);
6824 connect(vc_conn1:COORD, vc_conn2:COORD);
6825 f_start_handler_run(vc_conn1, refers(f_tc_call_re_establishment_1), pars1);
6826 f_start_handler_run(vc_conn2, refers(f_tc_call_re_establishment_2), pars2);
6827 vc_conn1.done;
6828 vc_conn2.done;
6829}
6830
Neels Hofmeyr48e4d7d2021-07-28 00:57:58 +02006831testcase TC_call_re_establishment_ciph() runs on MTC_CT {
6832 var BSC_ConnHdlr vc_conn1;
6833 var BSC_ConnHdlr vc_conn2;
6834 f_init();
6835
6836 f_vty_config(MSCVTY, "network", "authentication required");
6837 f_vty_config(MSCVTY, "network", "encryption a5 3");
6838
6839 var BSC_ConnHdlrPars pars1 := f_init_pars(92);
6840 pars1.net.expect_auth := true;
6841 pars1.net.expect_ciph := true;
6842 pars1.net.kc_support := '08'O; /* A5/3 only */
6843 var BSC_ConnHdlrPars pars2 := pars1;
6844
6845 vc_conn1 := f_start_handler_create(pars1);
6846 vc_conn2 := f_start_handler_create(pars2);
6847 connect(vc_conn1:COORD, vc_conn2:COORD);
6848 f_start_handler_run(vc_conn1, refers(f_tc_call_re_establishment_1), pars1);
6849 f_start_handler_run(vc_conn2, refers(f_tc_call_re_establishment_2), pars2);
6850 vc_conn1.done;
6851 vc_conn2.done;
6852}
6853
Neels Hofmeyr07ea7f22022-05-05 01:39:26 +02006854/* Establish a conn with a valid Mobile Identity. Then send a CM Service Request containing a mismatching Mobile
6855 * Identity on the same conn. Caused a crash, see OS#5532. */
6856friend function f_tc_cm_serv_wrong_mi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6857 f_init_handler(pars);
6858
6859 /* Set up a fully identified conn */
6860 f_perform_lu();
6861 f_establish_fully();
6862
6863 /* CM Serv Req with mismatching Mobile Identity */
6864 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(f_gen_imsi(99999))); /* ensure it is different from below*/
6865 BSSAP.send(ts_PDU_DTAP_MO(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, mi)));
6866 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ));
6867
6868 /* Cancel the first CM Service from f_establish_fully() */
6869 BSSAP.send(ts_BSSMAP_ClearRequest(0));
6870
6871 f_expect_clear();
6872}
6873testcase TC_cm_serv_wrong_mi() runs on MTC_CT {
6874 var BSC_ConnHdlr vc_conn;
6875 f_init();
6876 vc_conn := f_start_handler(refers(f_tc_cm_serv_wrong_mi), 94);
6877 vc_conn.done;
6878}
6879
Neels Hofmeyre860fc42022-10-05 01:15:54 +02006880/* a5 0 a5 0 a5 0 3 a5 0 3 a5 3 a5 3
6881 * HLR has auth info no yes no yes no yes
6882 *
6883 * test case index [0] [1] [2] [3] [4] [5]
6884 * authentication optional No auth No auth attempt auth, auth reject auth
6885 * (%) fall back to +ciph +ciph
6886 * no-auth
6887 *
6888 * [6] [7] [8] [9] [10] [11]
6889 * authentication mandatory reject auth reject auth reject auth
6890 * only +ciph +ciph
6891 *
6892 * (%): Arguably, when HLR has auth info, the MSC should use it. Current behavior of osmo-msc is to not attempt auth at
6893 * all. Related: OS#4830.
6894 */
6895type record of BSC_ConnHdlrNetworkPars rof_netpars;
6896
6897const rof_netpars auth_options_testcases := {
6898 {
6899 /* [0] auth optional, encr a5 0: no-auth" */
6900 kc_support := '01'O,
6901 net_config := { "authentication optional",
6902 "encryption a5 0" },
6903 expect_attach_success := true,
6904 expect_tmsi := true,
6905 expect_auth_attempt := false,
6906 hlr_has_auth_info := false,
6907 expect_auth := false,
6908 expect_ciph := false,
6909 expect_imei := false,
6910 expect_imei_early := false,
6911 check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
6912 check_imei_error := false
6913 },
6914 {
6915 /* [1] auth optional, encr a5 0, HLR HAS auth info: no-auth */
6916 kc_support := '01'O,
6917 net_config := { "authentication optional",
6918 "encryption a5 0" },
6919 expect_attach_success := true,
6920 expect_tmsi := true,
6921 expect_auth_attempt := false,
6922 hlr_has_auth_info := true,
6923 expect_auth := false,
6924 expect_ciph := false,
6925 expect_imei := false,
6926 expect_imei_early := false,
6927 check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
6928 check_imei_error := false
6929 },
6930 {
6931 /* [2] auth optional, encr a5 0 3, HLR has NO Auth Info: Fall back to no-auth" */
6932 kc_support := '09'O,
6933 net_config := { "authentication optional",
6934 "encryption a5 0 3" },
6935 expect_attach_success := true,
6936 expect_tmsi := true,
6937 expect_auth_attempt := true,
6938 hlr_has_auth_info := false,
6939 expect_auth := false,
6940 expect_ciph := false,
6941 expect_imei := false,
6942 expect_imei_early := false,
6943 check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
6944 check_imei_error := false
6945 },
6946 {
6947 /* [3] auth optional, encr a5 0 3, HLR HAS Auth Info: Use A5/3 */
6948 kc_support := '09'O,
6949 net_config := { "authentication optional",
6950 "encryption a5 0 3" },
6951 expect_attach_success := true,
6952 expect_tmsi := true,
6953 expect_auth_attempt := true,
6954 hlr_has_auth_info := true,
6955 expect_auth := true,
6956 expect_ciph := true,
6957 expect_imei := false,
6958 expect_imei_early := false,
6959 check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
6960 check_imei_error := false
6961 },
6962 {
6963 /* [4] auth optional, encr a5 3, HLR has NO Auth Info: reject.
6964 * Auth is required implicitly because ciph is required. */
6965 kc_support := '08'O,
6966 net_config := { "authentication optional",
6967 "encryption a5 3" },
6968 expect_attach_success := false,
6969 expect_tmsi := true,
6970 expect_auth_attempt := true,
6971 hlr_has_auth_info := false,
6972 expect_auth := false,
6973 expect_ciph := false,
6974 expect_imei := false,
6975 expect_imei_early := false,
6976 check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
6977 check_imei_error := false
6978 },
6979 {
6980 /* [5] auth optional, encr a5 3, HLR HAS Auth Info: auth + ciph.
6981 * Auth is required implicitly because ciph is required. */
6982 kc_support := '08'O,
6983 net_config := { "authentication optional",
6984 "encryption a5 3" },
6985 expect_attach_success := true,
6986 expect_tmsi := true,
6987 expect_auth_attempt := true,
6988 hlr_has_auth_info := true,
6989 expect_auth := true,
6990 expect_ciph := true,
6991 expect_imei := false,
6992 expect_imei_early := false,
6993 check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
6994 check_imei_error := false
6995 },
6996
6997 /* Same as above, but with 'authentication required' */
6998
6999 {
7000 /* [6] auth required, encr a5 0, HLR has NO auth info: reject */
7001 kc_support := '01'O,
7002 net_config := { "authentication required",
7003 "encryption a5 0" },
7004 expect_attach_success := false,
7005 expect_tmsi := true,
7006 expect_auth_attempt := true,
7007 hlr_has_auth_info := false,
7008 expect_auth := false,
7009 expect_ciph := false,
7010 expect_imei := false,
7011 expect_imei_early := false,
7012 check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
7013 check_imei_error := false
7014 },
7015 {
7016 /* [7] auth required, encr a5 0, HLR HAS auth info: do auth, no ciph" */
7017 kc_support := '01'O,
7018 net_config := { "authentication required",
7019 "encryption a5 0" },
7020 expect_attach_success := true,
7021 expect_tmsi := true,
7022 expect_auth_attempt := true,
7023 hlr_has_auth_info := true,
7024 expect_auth := true,
7025 expect_ciph := false,
7026 expect_imei := false,
7027 expect_imei_early := false,
7028 check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
7029 check_imei_error := false
7030 },
7031 {
7032 /* [8] auth required, encr a5 0 3, HLR has NO Auth Info: reject */
7033 kc_support := '09'O,
7034 net_config := { "authentication required",
7035 "encryption a5 0 3" },
7036 expect_attach_success := false,
7037 expect_tmsi := true,
7038 expect_auth_attempt := true,
7039 hlr_has_auth_info := false,
7040 expect_auth := false,
7041 expect_ciph := false,
7042 expect_imei := false,
7043 expect_imei_early := false,
7044 check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
7045 check_imei_error := false
7046 },
7047 {
7048 /* [9] auth required, encr a5 0 3, HLR HAS Auth Info: Use A5/3 */
7049 kc_support := '09'O,
7050 net_config := { "authentication required",
7051 "encryption a5 0 3" },
7052 expect_attach_success := true,
7053 expect_tmsi := true,
7054 expect_auth_attempt := true,
7055 hlr_has_auth_info := true,
7056 expect_auth := true,
7057 expect_ciph := true,
7058 expect_imei := false,
7059 expect_imei_early := false,
7060 check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
7061 check_imei_error := false
7062 },
7063 {
7064 /* [10] auth required, encr a5 3, HLR has NO Auth Info: reject. */
7065 kc_support := '08'O,
7066 net_config := { "authentication required",
7067 "encryption a5 3" },
7068 expect_attach_success := false,
7069 expect_tmsi := true,
7070 expect_auth_attempt := true,
7071 hlr_has_auth_info := false,
7072 expect_auth := false,
7073 expect_ciph := false,
7074 expect_imei := false,
7075 expect_imei_early := false,
7076 check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
7077 check_imei_error := false
7078 },
7079 {
7080 /* [11] auth required, encr a5 3, HLR HAS Auth Info: auth + ciph. */
7081 kc_support := '08'O,
7082 net_config := { "authentication required",
7083 "encryption a5 3" },
7084 expect_attach_success := true,
7085 expect_tmsi := true,
7086 expect_auth_attempt := true,
7087 hlr_has_auth_info := true,
7088 expect_auth := true,
7089 expect_ciph := true,
7090 expect_imei := false,
7091 expect_imei_early := false,
7092 check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
7093 check_imei_error := false
7094 }
7095};
7096
7097private function f_tc_auth_options(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
7098 f_init_handler(pars);
7099
7100 /* Location Updating */
7101 log(MSCVTY, "f_perform_lu() starting");
7102 f_perform_lu();
7103 log(MSCVTY, "f_perform_lu() done");
7104
7105 f_sleep(1.0);
7106
7107 if (not pars.net.expect_attach_success) {
7108 /* Expected above LU to fail. In order to test CM Service Request below, a LU has to succeed first. So
7109 * run another LU that will be successful. Careful not to load auth tokens into the VLR that may taint
7110 * the test for CM Service Request below. */
7111
7112 log(MSCVTY, "Running a successful LU so that CM Service Request can be tested");
7113 var BSC_ConnHdlrNetworkPars saved_net := g_pars.net;
7114 g_pars.net.kc_support := '01'O;
7115 g_pars.net.expect_attach_success := true;
7116 g_pars.net.expect_auth_attempt := false;
7117 g_pars.net.expect_auth := false;
7118 g_pars.net.expect_ciph := false;
7119 f_vty_config3(MSCVTY, {"network"}, {"authentication optional", "encryption a5 0"});
7120 f_perform_lu();
7121
7122 /* Reconfigure like it was before */
7123 g_pars.net := saved_net;
7124 f_vty_config3(MSCVTY, {"network"}, g_pars.net.net_config);
7125 log(MSCVTY, "Running a successful LU done");
7126 }
7127
7128 /* CM Service Request */
7129 log(MSCVTY, "f_establish_fully() starting");
7130 f_establish_fully();
7131 log(MSCVTY, "f_establish_fully() done");
7132 BSSAP.send(ts_BSSMAP_ClearRequest(0));
7133 f_expect_clear();
7134}
7135
7136function f_TC_auth_options(integer tc_i) runs on MTC_CT {
7137 f_init();
7138
7139 var BSC_ConnHdlrNetworkPars tc := auth_options_testcases[tc_i];
7140
7141 f_vty_config3(MSCVTY, {"network"}, tc.net_config);
7142
7143 var BSC_ConnHdlrPars pars := f_init_pars(42300 + tc_i);
7144 pars.net := tc;
7145
7146 var BSC_ConnHdlr vc_conn;
7147 vc_conn := f_start_handler_with_pars(refers(f_tc_auth_options), pars);
7148 vc_conn.done;
7149}
7150
7151testcase TC_auth_options_0() runs on MTC_CT {
7152 f_TC_auth_options(0);
7153}
7154
7155testcase TC_auth_options_1() runs on MTC_CT {
7156 f_TC_auth_options(1);
7157}
7158
7159testcase TC_auth_options_2() runs on MTC_CT {
7160 f_TC_auth_options(2);
7161}
7162
7163testcase TC_auth_options_3() runs on MTC_CT {
7164 f_TC_auth_options(3);
7165}
7166
7167testcase TC_auth_options_4() runs on MTC_CT {
7168 f_TC_auth_options(4);
7169}
7170
7171testcase TC_auth_options_5() runs on MTC_CT {
7172 f_TC_auth_options(5);
7173}
7174
7175testcase TC_auth_options_6() runs on MTC_CT {
7176 f_TC_auth_options(6);
7177}
7178
7179testcase TC_auth_options_7() runs on MTC_CT {
7180 f_TC_auth_options(7);
7181}
7182
7183testcase TC_auth_options_8() runs on MTC_CT {
7184 f_TC_auth_options(8);
7185}
7186
7187testcase TC_auth_options_9() runs on MTC_CT {
7188 f_TC_auth_options(9);
7189}
7190
7191testcase TC_auth_options_10() runs on MTC_CT {
7192 f_TC_auth_options(10);
7193}
7194
7195testcase TC_auth_options_11() runs on MTC_CT {
7196 f_TC_auth_options(11);
7197}
7198
Oliver Smithc4a0c3c2023-08-23 15:40:12 +02007199private function f_set_cpars_csd(inout CallParameters cpars, charstring bs_name, BIT1 async,
7200 GSM48_bcap_transp transp, GSM48_bcap_user_rate user_rate) {
Oliver Smith9c417f22023-07-07 13:25:11 +02007201 log("-----------------------------------------------");
Oliver Smithc4a0c3c2023-08-23 15:40:12 +02007202 log("CSD Bearer Service: " & bs_name);
Oliver Smith9c417f22023-07-07 13:25:11 +02007203 log("-----------------------------------------------");
Oliver Smith9c417f22023-07-07 13:25:11 +02007204
Oliver Smith92b280c2023-04-20 13:13:23 +02007205 cpars.csd := true;
Oliver Smithc4a0c3c2023-08-23 15:40:12 +02007206
Oliver Smith9c417f22023-07-07 13:25:11 +02007207 cpars.bearer_cap := valueof(ts_Bcap_csd);
7208 cpars.bearer_cap.octet6.synchronous_asynchronous := async;
7209 cpars.bearer_cap.octet6.connectionElement := int2bit(enum2int(transp), 2);
7210 cpars.bearer_cap.octet6.userRate := int2bit(enum2int(user_rate), 4);
7211
Oliver Smithc4a0c3c2023-08-23 15:40:12 +02007212 cpars.mncc_bearer_cap := valueof(ts_MNCC_bcap_data);
7213 cpars.mncc_bearer_cap.data.async := bit2int(async);
7214 cpars.mncc_bearer_cap.data.transp := transp;
7215 cpars.mncc_bearer_cap.data.user_rate := user_rate;
7216}
7217
7218friend function f_mo_csd(charstring bs_name, BIT1 async, GSM48_bcap_transp transp, GSM48_bcap_user_rate user_rate)
7219 runs on BSC_ConnHdlr {
7220 var CallParameters cpars := valueof(t_CallParams);
7221
7222 g_Tguard.start(20.0);
7223 f_set_cpars_csd(cpars, bs_name, async, transp, user_rate);
Oliver Smith92b280c2023-04-20 13:13:23 +02007224 f_perform_lu();
Oliver Smith98e24bc2023-07-07 12:36:59 +02007225 f_mo_call(cpars, 0.5);
Oliver Smith92b280c2023-04-20 13:13:23 +02007226}
Oliver Smith9c417f22023-07-07 13:25:11 +02007227
7228friend function f_tc_lu_and_mo_csd(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
7229 f_init_handler(pars);
7230
7231 f_mo_csd("BS21T", '1'B, GSM48_BCAP_TR_TRANSP, GSM48_BCAP_UR_300);
7232 f_mo_csd("BS22T", '1'B, GSM48_BCAP_TR_TRANSP, GSM48_BCAP_UR_1200);
7233 f_mo_csd("BS24T", '1'B, GSM48_BCAP_TR_TRANSP, GSM48_BCAP_UR_2400);
7234 f_mo_csd("BS25T", '1'B, GSM48_BCAP_TR_TRANSP, GSM48_BCAP_UR_4800);
7235 f_mo_csd("BS26T", '1'B, GSM48_BCAP_TR_TRANSP, GSM48_BCAP_UR_9600);
7236
7237 f_mo_csd("BS21NT", '1'B, GSM48_BCAP_TR_RLP, GSM48_BCAP_UR_300);
7238 f_mo_csd("BS22NT", '1'B, GSM48_BCAP_TR_RLP, GSM48_BCAP_UR_1200);
7239 f_mo_csd("BS24NT", '1'B, GSM48_BCAP_TR_RLP, GSM48_BCAP_UR_2400);
7240 f_mo_csd("BS25NT", '1'B, GSM48_BCAP_TR_RLP, GSM48_BCAP_UR_4800);
7241 f_mo_csd("BS26NT", '1'B, GSM48_BCAP_TR_RLP, GSM48_BCAP_UR_9600);
7242
7243 f_mo_csd("BS31T", '0'B, GSM48_BCAP_TR_TRANSP, GSM48_BCAP_UR_1200);
7244 f_mo_csd("BS32T", '0'B, GSM48_BCAP_TR_TRANSP, GSM48_BCAP_UR_2400);
7245 f_mo_csd("BS33T", '0'B, GSM48_BCAP_TR_TRANSP, GSM48_BCAP_UR_4800);
7246 f_mo_csd("BS34T", '0'B, GSM48_BCAP_TR_TRANSP, GSM48_BCAP_UR_9600);
7247}
Oliver Smith92b280c2023-04-20 13:13:23 +02007248testcase TC_lu_and_mo_csd() runs on MTC_CT {
7249 var BSC_ConnHdlr vc_conn;
7250 f_init();
7251
7252 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_csd), 7);
7253 vc_conn.done;
7254}
7255
Oliver Smith8cf75ab2023-06-21 16:19:51 +02007256friend function f_mt_csd(charstring bs_name, BIT1 async, GSM48_bcap_transp transp, GSM48_bcap_user_rate user_rate)
7257 runs on BSC_ConnHdlr {
Oliver Smithc1dd36a2023-05-31 13:52:24 +02007258 var CallParameters cpars := valueof(t_CallParams);
Oliver Smith8cf75ab2023-06-21 16:19:51 +02007259
Oliver Smithc4a0c3c2023-08-23 15:40:12 +02007260 g_Tguard.start(20.0);
7261 f_set_cpars_csd(cpars, bs_name, async, transp, user_rate);
Oliver Smithc1dd36a2023-05-31 13:52:24 +02007262 f_perform_lu();
Oliver Smith98e24bc2023-07-07 12:36:59 +02007263 f_mt_call(cpars, 0.5);
Oliver Smithc1dd36a2023-05-31 13:52:24 +02007264}
Oliver Smith8cf75ab2023-06-21 16:19:51 +02007265friend function f_tc_lu_and_mt_csd(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
7266 f_init_handler(pars);
7267
7268 f_mt_csd("BS21T", '1'B, GSM48_BCAP_TR_TRANSP, GSM48_BCAP_UR_300);
7269 f_mt_csd("BS22T", '1'B, GSM48_BCAP_TR_TRANSP, GSM48_BCAP_UR_1200);
7270 f_mt_csd("BS24T", '1'B, GSM48_BCAP_TR_TRANSP, GSM48_BCAP_UR_2400);
7271 f_mt_csd("BS25T", '1'B, GSM48_BCAP_TR_TRANSP, GSM48_BCAP_UR_4800);
7272 f_mt_csd("BS26T", '1'B, GSM48_BCAP_TR_TRANSP, GSM48_BCAP_UR_9600);
7273
7274 f_mt_csd("BS21NT", '1'B, GSM48_BCAP_TR_RLP, GSM48_BCAP_UR_300);
7275 f_mt_csd("BS22NT", '1'B, GSM48_BCAP_TR_RLP, GSM48_BCAP_UR_1200);
7276 f_mt_csd("BS24NT", '1'B, GSM48_BCAP_TR_RLP, GSM48_BCAP_UR_2400);
7277 f_mt_csd("BS25NT", '1'B, GSM48_BCAP_TR_RLP, GSM48_BCAP_UR_4800);
7278 f_mt_csd("BS26NT", '1'B, GSM48_BCAP_TR_RLP, GSM48_BCAP_UR_9600);
7279
7280 f_mt_csd("BS31T", '0'B, GSM48_BCAP_TR_TRANSP, GSM48_BCAP_UR_1200);
7281 f_mt_csd("BS32T", '0'B, GSM48_BCAP_TR_TRANSP, GSM48_BCAP_UR_2400);
7282 f_mt_csd("BS33T", '0'B, GSM48_BCAP_TR_TRANSP, GSM48_BCAP_UR_4800);
7283 f_mt_csd("BS34T", '0'B, GSM48_BCAP_TR_TRANSP, GSM48_BCAP_UR_9600);
7284}
Oliver Smithc1dd36a2023-05-31 13:52:24 +02007285testcase TC_lu_and_mt_csd() runs on MTC_CT {
7286 var BSC_ConnHdlr vc_conn;
7287 f_init();
7288
7289 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_csd), 7);
7290 vc_conn.done;
7291}
7292
Harald Weltef6dd64d2017-11-19 12:09:51 +01007293control {
Philipp Maier328d1662018-03-07 10:40:27 +01007294 execute( TC_cr_before_reset() );
Harald Weltea49e36e2018-01-21 19:29:33 +01007295 execute( TC_lu_imsi_noauth_tmsi() );
Harald Welted2328a22018-01-27 14:27:16 +01007296 execute( TC_lu_imsi_noauth_notmsi() );
Harald Weltea49e36e2018-01-21 19:29:33 +01007297 execute( TC_lu_imsi_reject() );
7298 execute( TC_lu_imsi_timeout_gsup() );
Harald Welted2328a22018-01-27 14:27:16 +01007299 execute( TC_lu_imsi_auth_tmsi() );
Harald Welte8a397ae2019-04-21 22:03:37 +02007300 execute( TC_lu_imsi_auth3g_tmsi() );
Pau Espin Pedrold3d54a92019-12-17 17:02:54 +01007301 execute( TC_lu_imsi_timeout_tmsi_realloc() );
Harald Welted2328a22018-01-27 14:27:16 +01007302 execute( TC_cmserv_imsi_unknown() );
Neels Hofmeyr13737fb2020-08-19 13:16:14 +00007303 execute( TC_cmserv_tmsi_unknown() );
Harald Welte2bb825f2018-01-22 11:31:18 +01007304 execute( TC_lu_and_mo_call() );
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02007305 execute( TC_lu_and_mo_call_ipv6() );
Pau Espin Pedrola42745c2020-01-10 18:03:28 +01007306 execute( TC_lu_and_mo_call_sccp_tiar_timeout() );
Harald Welte071ed732018-01-23 19:53:52 +01007307 execute( TC_lu_auth_sai_timeout() );
7308 execute( TC_lu_auth_sai_err() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01007309 execute( TC_lu_clear_request() );
Vadim Yanitskiy109e7552021-02-05 05:36:02 +01007310 execute( TC_mo_call_clear_request() );
7311 execute( TC_mt_call_clear_request() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01007312 execute( TC_lu_disconnect() );
7313 execute( TC_lu_by_imei() );
7314 execute( TC_lu_by_tmsi_noauth_unknown() );
Neels Hofmeyrfc06c732020-08-19 12:52:28 +00007315 execute( TC_attached_imsi_lu_unknown_tmsi() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01007316 execute( TC_imsi_detach_by_imsi() );
7317 execute( TC_imsi_detach_by_tmsi() );
7318 execute( TC_imsi_detach_by_imei() );
7319 execute( TC_emerg_call_imei_reject() );
7320 execute( TC_emerg_call_imsi() );
7321 execute( TC_cm_serv_req_vgcs_reject() );
7322 execute( TC_cm_serv_req_vbs_reject() );
7323 execute( TC_cm_serv_req_lcs_reject() );
Harald Welte0195ab12018-01-24 21:50:20 +01007324 execute( TC_cm_reest_req_reject() );
Harald Welte1af6ea82018-01-25 18:33:15 +01007325 execute( TC_lu_auth_2G_fail() );
7326 execute( TC_lu_imsi_auth_tmsi_encr_13_13() );
7327 execute( TC_cl3_no_payload() );
7328 execute( TC_cl3_rnd_payload() );
Harald Welte1852a842018-01-26 22:53:36 +01007329 execute( TC_establish_and_nothing() );
7330 execute( TC_mo_setup_and_nothing() );
7331 execute( TC_mo_crcx_ran_timeout() );
7332 execute( TC_mo_crcx_ran_reject() );
Harald Welted2328a22018-01-27 14:27:16 +01007333 execute( TC_mt_crcx_ran_reject() );
Daniel Willmann8b084372018-02-04 13:35:26 +01007334 execute( TC_mo_setup_and_dtmf_dup() );
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01007335 execute( TC_mt_t310() );
Harald Welte167458a2018-01-27 15:58:16 +01007336 execute( TC_gsup_cancel() );
Harald Welte9de84792018-01-28 01:06:35 +01007337 execute( TC_lu_imsi_auth_tmsi_encr_1_13() );
7338 execute( TC_lu_imsi_auth_tmsi_encr_3_13() );
7339 execute( TC_lu_imsi_auth_tmsi_encr_3_1() );
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01007340 execute( TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() );
Harald Welte9de84792018-01-28 01:06:35 +01007341 execute( TC_lu_imsi_auth_tmsi_encr_13_2() );
7342 execute( TC_lu_imsi_auth_tmsi_encr_013_2() );
Eric Wild26f4a622021-05-17 15:27:05 +02007343 execute( TC_lu_imsi_auth_tmsi_encr_0134_1() );
7344 execute( TC_lu_imsi_auth_tmsi_encr_0134_34() );
7345 execute( TC_lu_imsi_auth_tmsi_encr_0134_34_no_cm3() );
7346
Philipp Maier94f3f1b2018-03-15 18:54:13 +01007347 execute( TC_mo_release_timeout() );
Philipp Maier2a98a732018-03-19 16:06:12 +01007348 execute( TC_lu_and_mt_call_no_dlcx_resp() );
Philipp Maier75932982018-03-27 14:52:35 +02007349 execute( TC_reset_two() );
Harald Welte33ec09b2018-02-10 15:34:46 +01007350
7351 execute( TC_lu_and_mt_call() );
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02007352 execute( TC_lu_and_mt_call_ipv6() );
Neels Hofmeyrb58d9742019-11-27 18:44:54 +01007353 execute( TC_lu_and_mt_call_already_paging() );
Pau Espin Pedrol9a732a42020-09-15 15:56:33 +02007354 execute( TC_lu_and_mt_call_osmux() );
Harald Welte33ec09b2018-02-10 15:34:46 +01007355
Harald Weltef45efeb2018-04-09 18:19:24 +02007356 execute( TC_lu_and_mo_sms() );
7357 execute( TC_lu_and_mt_sms() );
Neels Hofmeyrb58d9742019-11-27 18:44:54 +01007358 execute( TC_lu_and_mt_sms_already_paging() );
Philipp Maier3983e702018-11-22 19:01:33 +01007359 execute( TC_lu_and_mt_sms_paging_and_nothing() );
Alexander Couzensfc02f242019-09-12 03:43:18 +02007360 execute( TC_lu_and_mt_sms_paging_repeated() );
Harald Weltef640a012018-04-14 17:49:21 +02007361 execute( TC_smpp_mo_sms() );
Vadim Yanitskiy33820762020-01-15 11:26:07 +07007362 execute( TC_smpp_mo_sms_rp_error() );
Harald Weltef640a012018-04-14 17:49:21 +02007363 execute( TC_smpp_mt_sms() );
Harald Weltef45efeb2018-04-09 18:19:24 +02007364
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07007365 execute( TC_gsup_mo_sms() );
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07007366 execute( TC_gsup_mo_smma() );
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07007367 execute( TC_gsup_mt_sms_ack() );
7368 execute( TC_gsup_mt_sms_err() );
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07007369 execute( TC_gsup_mt_sms_rp_mr() );
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07007370 execute( TC_gsup_mo_mt_sms_rp_mr() );
Vadim Yanitskiya2a8a112019-07-08 20:04:32 +07007371 execute( TC_gsup_mt_multi_part_sms() );
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07007372
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07007373 execute( TC_lu_and_mo_ussd_single_request() );
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07007374 execute( TC_lu_and_mt_ussd_notification() );
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07007375 execute( TC_lu_and_mo_ussd_during_mt_call() );
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07007376 execute( TC_lu_and_mt_ussd_during_mt_call() );
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07007377 execute( TC_lu_and_mo_ussd_mo_release() );
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07007378 execute( TC_lu_and_ss_session_timeout() );
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07007379
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07007380 execute( TC_mt_ussd_for_unknown_subscr() );
Vadim Yanitskiyc3c07d42019-06-17 23:00:44 +07007381 execute( TC_mo_ussd_for_unknown_trans() );
Vadim Yanitskiyd612d282019-06-15 14:46:03 +07007382 execute( TC_proc_ss_for_unknown_session() );
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07007383 execute( TC_proc_ss_paging_fail() );
Vadim Yanitskiy29ba8d62019-06-16 15:19:41 +07007384 execute( TC_proc_ss_abort() );
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07007385
Vadim Yanitskiy1c9754d2020-01-07 21:56:55 +01007386 execute( TC_multi_lu_and_mo_ussd() );
7387 execute( TC_multi_lu_and_mt_ussd() );
7388
Stefan Sperling89eb1f32018-12-17 15:06:20 +01007389 execute( TC_cipher_complete_with_invalid_cipher() );
Stefan Sperlinga2d59c62018-12-18 16:32:44 +01007390 execute( TC_cipher_complete_1_without_cipher() );
7391 execute( TC_cipher_complete_3_without_cipher() );
7392 execute( TC_cipher_complete_13_without_cipher() );
Harald Welteb2284bd2019-05-10 11:30:43 +02007393 execute( TC_lu_with_invalid_mcc_mnc() );
Stefan Sperling89eb1f32018-12-17 15:06:20 +01007394
Harald Welte4263c522018-12-06 11:56:27 +01007395 execute( TC_sgsap_reset() );
7396 execute( TC_sgsap_lu() );
7397 execute( TC_sgsap_lu_imsi_reject() );
7398 execute( TC_sgsap_lu_and_nothing() );
7399 execute( TC_sgsap_expl_imsi_det_eps() );
Philipp Maierfc19f172019-03-21 11:17:54 +01007400 execute( TC_sgsap_impl_imsi_det_eps() );
Harald Welte4263c522018-12-06 11:56:27 +01007401 execute( TC_sgsap_expl_imsi_det_noneps() );
Philipp Maier5d812702019-03-21 10:51:26 +01007402 execute( TC_sgsap_impl_imsi_det_noneps() );
Harald Welte4263c522018-12-06 11:56:27 +01007403 execute( TC_sgsap_paging_rej() );
7404 execute( TC_sgsap_paging_subscr_rej() );
7405 execute( TC_sgsap_paging_ue_unr() );
7406 execute( TC_sgsap_paging_and_nothing() );
7407 execute( TC_sgsap_paging_and_lu() );
7408 execute( TC_sgsap_mt_sms() );
7409 execute( TC_sgsap_mo_sms() );
7410 execute( TC_sgsap_mt_sms_and_nothing() );
7411 execute( TC_sgsap_mt_sms_and_reject() );
7412 execute( TC_sgsap_unexp_ud() );
7413 execute( TC_sgsap_unsol_ud() );
7414 execute( TC_bssap_lu_sgsap_lu_and_mt_call() );
7415 execute( TC_sgsap_lu_and_mt_call() );
Philipp Maier628c0052019-04-09 17:36:57 +02007416 execute( TC_sgsap_vlr_failure() );
Harald Welte4263c522018-12-06 11:56:27 +01007417
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02007418 execute( TC_ho_inter_bsc_unknown_cell() );
7419 execute( TC_ho_inter_bsc() );
Neels Hofmeyr0d841d92021-06-21 22:27:21 +02007420 execute( TC_ho_inter_bsc_a5_1() );
7421 execute( TC_ho_inter_bsc_a5_3() );
7422 execute( TC_ho_inter_bsc_a5_4() );
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02007423 execute( TC_ho_inter_bsc_ipv6() );
Oliver Smith44424db2023-08-22 13:54:09 +02007424 execute( TC_ho_inter_bsc_csd() );
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02007425
7426 execute( TC_ho_inter_msc_out() );
Neels Hofmeyr666d39a2021-06-21 22:27:21 +02007427 execute( TC_ho_inter_msc_out_a5_1() );
7428 execute( TC_ho_inter_msc_out_a5_3() );
7429 execute( TC_ho_inter_msc_out_a5_4() );
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02007430 execute( TC_ho_inter_msc_out_ipv6() );
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02007431
Oliver Smith1d118ff2019-07-03 10:57:35 +02007432 execute( TC_lu_imsi_auth_tmsi_check_imei() );
7433 execute( TC_lu_imsi_auth3g_tmsi_check_imei() );
7434 execute( TC_lu_imsi_noauth_tmsi_check_imei() );
7435 execute( TC_lu_imsi_noauth_notmsi_check_imei() );
7436 execute( TC_lu_imsi_auth_tmsi_check_imei_nack() );
7437 execute( TC_lu_imsi_auth_tmsi_check_imei_err() );
7438 execute( TC_lu_imsi_auth_tmsi_check_imei_early() );
7439 execute( TC_lu_imsi_auth3g_tmsi_check_imei_early() );
7440 execute( TC_lu_imsi_noauth_tmsi_check_imei_early() );
7441 execute( TC_lu_imsi_noauth_notmsi_check_imei_early() );
7442 execute( TC_lu_imsi_auth_tmsi_check_imei_early_nack() );
7443 execute( TC_lu_imsi_auth_tmsi_check_imei_early_err() );
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01007444 execute( TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() );
Pau Espin Pedrol609f1d62020-09-15 16:01:55 +02007445
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02007446 execute( TC_mo_cc_bssmap_clear() );
Neels Hofmeyr8df69622019-11-02 19:16:03 +01007447 execute( TC_invalid_mgcp_crash() );
Vadim Yanitskiyeddebaa2019-12-28 17:45:34 +01007448 execute( TC_mm_id_resp_no_identity() );
Vadim Yanitskiy25219062020-01-21 01:41:33 +07007449 execute( TC_lu_and_expire_while_paging() );
Pau Espin Pedrol174fac22021-02-26 13:20:10 +01007450 execute( TC_paging_response_imsi_unknown() );
7451 execute( TC_paging_response_tmsi_unknown() );
Neels Hofmeyr4f099b42021-07-27 03:45:26 +02007452
7453 execute( TC_call_re_establishment() );
Neels Hofmeyra9b2dcf2021-07-28 00:57:58 +02007454 execute( TC_call_re_establishment_auth() );
Neels Hofmeyr48e4d7d2021-07-28 00:57:58 +02007455 execute( TC_call_re_establishment_ciph() );
Neels Hofmeyr07ea7f22022-05-05 01:39:26 +02007456
7457 execute( TC_cm_serv_wrong_mi() );
Neels Hofmeyre860fc42022-10-05 01:15:54 +02007458
7459 execute( TC_auth_options_0() );
7460 execute( TC_auth_options_1() );
7461 execute( TC_auth_options_2() );
7462 execute( TC_auth_options_3() );
7463 execute( TC_auth_options_4() );
7464 execute( TC_auth_options_5() );
7465 execute( TC_auth_options_6() );
7466 execute( TC_auth_options_7() );
7467 execute( TC_auth_options_8() );
7468 execute( TC_auth_options_9() );
7469 execute( TC_auth_options_10() );
7470 execute( TC_auth_options_11() );
Oliver Smith92b280c2023-04-20 13:13:23 +02007471
7472 execute( TC_lu_and_mo_csd() );
Oliver Smithc1dd36a2023-05-31 13:52:24 +02007473 execute( TC_lu_and_mt_csd() );
Harald Weltef6dd64d2017-11-19 12:09:51 +01007474}
7475
7476
7477}