blob: 83256259127e1deac8b48f005010bce12c85aaec [file] [log] [blame]
Harald Weltef6dd64d2017-11-19 12:09:51 +01001module MSC_Tests {
2
Harald Welte34b5a952019-05-27 11:54:11 +02003/* Osmocom MSC test suite in in TTCN-3
4 * (C) 2017-2019 Harald Welte <laforge@gnumonks.org>
5 * (C) 2018-2019 sysmocom - s.f.m.c. GmbH
6 * (C) 2018-2019 Vadim Yanitskiy <axilirator@gmail.com>
7 * All rights reserved.
8 *
9 * Released under the terms of GNU General Public License, Version 2 or
10 * (at your option) any later version.
11 *
12 * SPDX-License-Identifier: GPL-2.0-or-later
13 */
14
Harald Weltee13cfb22019-04-23 16:52:02 +020015friend module MSC_Tests_Iu;
16
Harald Weltef6dd64d2017-11-19 12:09:51 +010017import from General_Types all;
18import from Osmocom_Types all;
19
20import from M3UA_Types all;
21import from M3UA_Emulation all;
22
23import from MTP3asp_Types all;
24import from MTP3asp_PortType all;
25
26import from SCCPasp_Types all;
27import from SCCP_Types all;
28import from SCCP_Emulation all;
29
30import from SCTPasp_Types all;
31import from SCTPasp_PortType all;
32
Harald Weltea49e36e2018-01-21 19:29:33 +010033import from Osmocom_CTRL_Functions all;
34import from Osmocom_CTRL_Types all;
35import from Osmocom_CTRL_Adapter all;
36
Harald Welte3ca1c902018-01-24 18:51:27 +010037import from TELNETasp_PortType all;
38import from Osmocom_VTY_Functions all;
39
Harald Weltea49e36e2018-01-21 19:29:33 +010040import from MNCC_Emulation all;
Harald Welte2bb825f2018-01-22 11:31:18 +010041import from MNCC_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +010042
Harald Welte4aa970c2018-01-26 10:38:09 +010043import from MGCP_Emulation all;
44import from MGCP_Types all;
45import from MGCP_Templates all;
46import from SDP_Types all;
47
Harald Weltea49e36e2018-01-21 19:29:33 +010048import from GSUP_Emulation all;
49import from GSUP_Types all;
50import from IPA_Emulation all;
51
Harald Weltef6dd64d2017-11-19 12:09:51 +010052import from BSSAP_Types all;
Harald Welte6811d102019-04-14 22:23:14 +020053import from RAN_Adapter all;
Harald Weltea49e36e2018-01-21 19:29:33 +010054import from BSSAP_CodecPort all;
55import from BSSMAP_Templates all;
Harald Welte6811d102019-04-14 22:23:14 +020056import from RAN_Emulation all;
Harald Weltea49e36e2018-01-21 19:29:33 +010057import from BSC_ConnectionHandler all;
Harald Weltee13cfb22019-04-23 16:52:02 +020058import from RANAP_Templates all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010059
Harald Welte4263c522018-12-06 11:56:27 +010060import from SGsAP_Templates all;
61import from SGsAP_Types all;
62import from SGsAP_Emulation all;
63
Harald Weltea49e36e2018-01-21 19:29:33 +010064import from MobileL3_Types all;
65import from MobileL3_CommonIE_Types all;
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +070066import from MobileL3_SMS_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +010067import from L3_Templates all;
Harald Welte158a7ca2018-02-16 18:11:31 +010068import from L3_Common all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010069
Harald Weltef640a012018-04-14 17:49:21 +020070import from SMPP_Types all;
71import from SMPP_Templates all;
72import from SMPP_Emulation all;
73
Stefan Sperlingc307e682018-06-14 15:15:46 +020074import from SCCP_Templates all;
75
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +070076import from SS_Types all;
77import from SS_Templates all;
78import from USSD_Helpers all;
Harald Welte4263c522018-12-06 11:56:27 +010079import from DNS_Helpers all;
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +070080
Philipp Maier948747b2019-04-02 15:22:33 +020081import from TCCConversion_Functions all;
82
Harald Welte9b751a62019-04-14 17:39:29 +020083const integer NUM_BSC := 3;
Harald Weltef6dd64d2017-11-19 12:09:51 +010084
Harald Welte4263c522018-12-06 11:56:27 +010085/* Needed for SGsAP SMS */
86import from MobileL3_SMS_Types all;
87
Harald Weltea4ca4462018-02-09 00:17:14 +010088type component MTC_CT extends CTRL_Adapter_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +010089 var boolean g_initialized := false;
Harald Weltea49e36e2018-01-21 19:29:33 +010090
Harald Welte6811d102019-04-14 22:23:14 +020091 var RAN_Adapter g_bssap[NUM_BSC];
Harald Weltea4ca4462018-02-09 00:17:14 +010092
Harald Weltea49e36e2018-01-21 19:29:33 +010093 /* no 'adapter_CT' for MNCC or GSUP */
94 var MNCC_Emulation_CT vc_MNCC;
Harald Welte4aa970c2018-01-26 10:38:09 +010095 var MGCP_Emulation_CT vc_MGCP;
Harald Weltea49e36e2018-01-21 19:29:33 +010096 var GSUP_Emulation_CT vc_GSUP;
97 var IPA_Emulation_CT vc_GSUP_IPA;
Harald Weltef640a012018-04-14 17:49:21 +020098 var SMPP_Emulation_CT vc_SMPP;
Harald Welte4263c522018-12-06 11:56:27 +010099 var SGsAP_Emulation_CT vc_SGsAP;
Harald Weltea49e36e2018-01-21 19:29:33 +0100100
101 /* only to get events from IPA underneath GSUP */
102 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte3ca1c902018-01-24 18:51:27 +0100103 /* VTY to MSC */
104 port TELNETasp_PT MSCVTY;
Philipp Maier328d1662018-03-07 10:40:27 +0100105
106 /* A port to directly send BSSAP messages. This port is used for
107 * tests that require low level access to sen arbitrary BSSAP
108 * messages. Run f_init_bssap_direct() to connect and initialize */
109 port BSSAP_CODEC_PT BSSAP_DIRECT;
110
111 /* When BSSAP messages are directly sent, then the connection
112 * handler is not active, which means that also no guard timer is
113 * set up. The following timer will serve as a replacement */
114 timer Tguard_direct := 60.0;
Pau Espin Pedrola42745c2020-01-10 18:03:28 +0100115
116 /* Configure T(tias) over VTY, seconds */
117 var integer g_msc_sccp_timer_ias := 7 * 60;
118 /* Configure T(tiar) over VTY, seconds */
119 var integer g_msc_sccp_timer_iar := 15 * 60;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100120}
121
122modulepar {
Harald Weltea49e36e2018-01-21 19:29:33 +0100123 /* remote parameters of IUT */
124 charstring mp_msc_ip := "127.0.0.1";
125 integer mp_msc_ctrl_port := 4255;
126 integer mp_msc_vty_port := 4254;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100127
Harald Weltea49e36e2018-01-21 19:29:33 +0100128 /* local parameters of emulated HLR */
Philipp Maier9b690e42018-12-21 11:50:03 +0100129 boolean mp_mm_info := false;
Harald Weltea49e36e2018-01-21 19:29:33 +0100130 charstring mp_hlr_ip := "127.0.0.1";
131 integer mp_hlr_port := 4222;
Harald Welte6126fb02018-01-27 20:08:24 +0100132 charstring mp_mgw_ip := "127.0.0.1";
133 integer mp_mgw_port := 2427;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100134
Harald Weltea49e36e2018-01-21 19:29:33 +0100135 charstring mp_msc_mncc := "/tmp/mncc";
Harald Weltea4ca4462018-02-09 00:17:14 +0100136
Harald Weltef640a012018-04-14 17:49:21 +0200137 integer mp_msc_smpp_port := 2775;
138 charstring mp_smpp_system_id := "msc_tester";
139 charstring mp_smpp_password := "osmocom1";
Harald Welte4263c522018-12-06 11:56:27 +0100140 charstring mp_mme_name := "mmec01.mmegi0001.mme.epc.mnc070.mcc901.3gppnetwork.org";
141 charstring mp_vlr_name := "vlr.example.net";
Harald Weltef640a012018-04-14 17:49:21 +0200142
Harald Welte6811d102019-04-14 22:23:14 +0200143 RAN_Configurations mp_bssap_cfg := {
Philipp Maier75932982018-03-27 14:52:35 +0200144 {
145 sccp_service_type := "mtp3_itu",
146 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
147 own_pc := 185,
148 own_ssn := 254,
149 peer_pc := 187,
150 peer_ssn := 254,
151 sio := '83'O,
152 rctx := 0
153 },
154 {
155 sccp_service_type := "mtp3_itu",
156 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
157 own_pc := 186,
158 own_ssn := 254,
159 peer_pc := 187,
160 peer_ssn := 254,
161 sio := '83'O,
162 rctx := 1
163 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100164 };
Harald Weltef6dd64d2017-11-19 12:09:51 +0100165}
166
Philipp Maier328d1662018-03-07 10:40:27 +0100167/* altstep for the global guard timer (only used when BSSAP_DIRECT
168 * is used for communication */
169private altstep as_Tguard_direct() runs on MTC_CT {
170 [] Tguard_direct.timeout {
171 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200172 mtc.stop;
Philipp Maier328d1662018-03-07 10:40:27 +0100173 }
174}
Harald Weltef6dd64d2017-11-19 12:09:51 +0100175
Neels Hofmeyr2ca1ab42019-03-08 03:45:43 +0100176private altstep as_optional_cc_rel(CallParameters cpars, boolean respond := false) runs on BSC_ConnHdlr {
177 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id))) {
178 if (respond) {
179 var BIT1 tid_remote := '1'B;
180 if (cpars.mo_call) {
181 tid_remote := '0'B;
182 }
183 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id, tid_remote)));
184 }
185 }
Neels Hofmeyrde76f052019-02-26 05:02:46 +0100186}
187
Harald Weltef640a012018-04-14 17:49:21 +0200188function f_init_smpp(charstring id) runs on MTC_CT {
189 id := id & "-SMPP";
190 var EsmePars pars := {
191 mode := MODE_TRANSCEIVER,
192 bind := {
193 system_id := mp_smpp_system_id,
194 password := mp_smpp_password,
195 system_type := "MSC_Tests",
196 interface_version := hex2int('34'H),
197 addr_ton := unknown,
198 addr_npi := unknown,
199 address_range := ""
200 },
201 esme_role := true
202 }
203
204 vc_SMPP := SMPP_Emulation_CT.create(id);
205 map(vc_SMPP:SMPP_PORT, system:SMPP_PORT);
Harald Welte4698a4c2020-08-18 22:57:52 +0200206 vc_SMPP.start(SMPP_Emulation.main_client(pars, mp_msc_ip, mp_msc_smpp_port, "", 0));
Harald Weltef640a012018-04-14 17:49:21 +0200207}
208
209
Harald Weltea49e36e2018-01-21 19:29:33 +0100210function f_init_mncc(charstring id) runs on MTC_CT {
211 id := id & "-MNCC";
212 var MnccOps ops := {
213 create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
214 unitdata_cb := refers(MNCC_Emulation.DummyUnitdataCallback)
215 }
216
217 vc_MNCC := MNCC_Emulation_CT.create(id);
218 map(vc_MNCC:MNCC, system:MNCC_CODEC_PT);
219 vc_MNCC.start(MNCC_Emulation.main(ops, id, mp_msc_mncc));
Harald Weltef6dd64d2017-11-19 12:09:51 +0100220}
221
Harald Welte4aa970c2018-01-26 10:38:09 +0100222function f_init_mgcp(charstring id) runs on MTC_CT {
223 id := id & "-MGCP";
224 var MGCPOps ops := {
225 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
226 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
227 }
228 var MGCP_conn_parameters pars := {
Harald Welte6126fb02018-01-27 20:08:24 +0100229 callagent_ip := mp_msc_ip,
Harald Welte4aa970c2018-01-26 10:38:09 +0100230 callagent_udp_port := -1,
Harald Welte6126fb02018-01-27 20:08:24 +0100231 mgw_ip := mp_mgw_ip,
Pau Espin Pedrol1a026a52019-06-18 17:21:52 +0200232 mgw_udp_port := mp_mgw_port,
233 multi_conn_mode := false
Harald Welte4aa970c2018-01-26 10:38:09 +0100234 }
235
236 vc_MGCP := MGCP_Emulation_CT.create(id);
237 map(vc_MGCP:MGCP, system:MGCP_CODEC_PT);
238 vc_MGCP.start(MGCP_Emulation.main(ops, pars, id));
239}
240
Philipp Maierc09a1312019-04-09 16:05:26 +0200241function ForwardUnitdataCallback(PDU_SGsAP msg)
242runs on SGsAP_Emulation_CT return template PDU_SGsAP {
243 SGsAP_CLIENT.send(msg);
244 return omit;
245}
246
Harald Welte4263c522018-12-06 11:56:27 +0100247function f_init_sgsap(charstring id) runs on MTC_CT {
248 id := id & "-SGsAP";
249 var SGsAPOps ops := {
250 create_cb := refers(SGsAP_Emulation.ExpectedCreateCallback),
Philipp Maierc09a1312019-04-09 16:05:26 +0200251 unitdata_cb := refers(ForwardUnitdataCallback)
Harald Welte4263c522018-12-06 11:56:27 +0100252 }
253 var SGsAP_conn_parameters pars := {
254 remote_ip := mp_msc_ip,
255 remote_sctp_port := 29118,
256 local_ip := "",
257 local_sctp_port := -1
258 }
259
260 vc_SGsAP := SGsAP_Emulation_CT.create(id);
261 map(vc_SGsAP:SGsAP, system:SGsAP_CODEC_PT);
262 vc_SGsAP.start(SGsAP_Emulation.main(ops, pars, id));
263}
264
265
Harald Weltea49e36e2018-01-21 19:29:33 +0100266function f_init_gsup(charstring id) runs on MTC_CT {
267 id := id & "-GSUP";
268 var GsupOps ops := {
269 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
270 }
271
272 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
273 vc_GSUP := GSUP_Emulation_CT.create(id);
274
275 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
276 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
277 /* we use this hack to get events like ASP_IPA_EVENT_UP */
278 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
279
280 vc_GSUP.start(GSUP_Emulation.main(ops, id));
281 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
282
283 /* wait for incoming connection to GSUP port before proceeding */
284 timer T := 10.0;
285 T.start;
286 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700287 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Weltea49e36e2018-01-21 19:29:33 +0100288 [] T.timeout {
Harald Welte458fd372018-03-21 11:26:23 +0100289 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200290 mtc.stop
Harald Weltea49e36e2018-01-21 19:29:33 +0100291 }
292 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100293}
294
Pau Espin Pedrola65697d2019-05-21 12:54:39 +0200295function 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 +0100296
297 if (g_initialized == true) {
298 return;
299 }
300 g_initialized := true;
301
Philipp Maier75932982018-03-27 14:52:35 +0200302 if (num_bsc > NUM_BSC) {
Daniel Willmannafce8662018-07-06 23:11:32 +0200303 testcase.stop("excess number of BSC instances requested");
Philipp Maier75932982018-03-27 14:52:35 +0200304 }
305
306 for (var integer i := 0; i < num_bsc; i := i + 1) {
307 if (isbound(mp_bssap_cfg[i])) {
Pau Espin Pedrola65697d2019-05-21 12:54:39 +0200308 var RanOps ranops := BSC_RanOps;
309 ranops.use_osmux := osmux;
310 f_ran_adapter_init(g_bssap[i], mp_bssap_cfg[i], "MSC_Test_" & int2str(i), ranops);
Harald Welte3ca0ce12019-04-23 17:18:48 +0200311 f_ran_adapter_start(g_bssap[i]);
Philipp Maier75932982018-03-27 14:52:35 +0200312 } else {
Daniel Willmannafce8662018-07-06 23:11:32 +0200313 testcase.stop("missing BSSAP configuration");
Philipp Maier75932982018-03-27 14:52:35 +0200314 }
315 }
316
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +0100317 f_ipa_ctrl_start_client(mp_msc_ip, mp_msc_ctrl_port);
Harald Weltea49e36e2018-01-21 19:29:33 +0100318 f_init_mncc("MSC_Test");
Harald Welte4aa970c2018-01-26 10:38:09 +0100319 f_init_mgcp("MSC_Test");
Philipp Maierc09a1312019-04-09 16:05:26 +0200320
321 if (gsup == true) {
322 f_init_gsup("MSC_Test");
323 }
Harald Weltef640a012018-04-14 17:49:21 +0200324 f_init_smpp("MSC_Test");
Philipp Maier57865482019-01-07 18:33:13 +0100325
Philipp Maier8e07a4a2019-02-14 18:23:28 +0100326 if (sgsap == true) {
Philipp Maier57865482019-01-07 18:33:13 +0100327 f_init_sgsap("MSC_Test");
328 }
Harald Welte3ca1c902018-01-24 18:51:27 +0100329
330 map(self:MSCVTY, system:MSCVTY);
331 f_vty_set_prompts(MSCVTY);
332 f_vty_transceive(MSCVTY, "enable");
Harald Welteb14c77a2018-01-25 17:25:44 +0100333
334 /* set some defaults */
335 f_vty_config(MSCVTY, "network", "authentication optional");
336 f_vty_config(MSCVTY, "msc", "assign-tmsi");
Oliver Smith1d118ff2019-07-03 10:57:35 +0200337 f_vty_config(MSCVTY, "msc", "check-imei-rqd 0");
Harald Welteb14c77a2018-01-25 17:25:44 +0100338 f_vty_config(MSCVTY, "network", "encryption a5 0");
Pau Espin Pedrola42745c2020-01-10 18:03:28 +0100339 f_vty_config(MSCVTY, "cs7 instance 0", "sccp-timer ias " & int2str(g_msc_sccp_timer_ias));
340 f_vty_config(MSCVTY, "cs7 instance 0", "sccp-timer iar " & int2str(g_msc_sccp_timer_iar));
Pau Espin Pedrol9a732a42020-09-15 15:56:33 +0200341 if (osmux) {
342 f_vty_config(MSCVTY, "msc", "osmux on");
343 } else {
344 f_vty_config(MSCVTY, "msc", "osmux off");
Pau Espin Pedrol3dd33bc2019-05-31 17:51:20 +0200345 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100346}
347
Philipp Maier328d1662018-03-07 10:40:27 +0100348/* Initialize for a direct connection to BSSAP. This function is an alternative
349 * to f_init() when the high level functions of the BSC_ConnectionHandler are
350 * not needed. */
351function f_init_bssap_direct() runs on MTC_CT {
Harald Welte3ca0ce12019-04-23 17:18:48 +0200352 f_ran_adapter_init(g_bssap[0], mp_bssap_cfg[0], "MSC_Test", omit);
Philipp Maier75932982018-03-27 14:52:35 +0200353 connect(g_bssap[0].vc_SCCP:SCCP_SP_PORT, self:BSSAP_DIRECT);
Philipp Maier328d1662018-03-07 10:40:27 +0100354
355 /* Start guard timer and activate it as default */
356 Tguard_direct.start
357 activate(as_Tguard_direct());
358}
359
Harald Weltea49e36e2018-01-21 19:29:33 +0100360type function void_fn(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100361
Harald Weltea49e36e2018-01-21 19:29:33 +0100362/* FIXME: move into BSC_ConnectionHandler? */
Harald Welte9b751a62019-04-14 17:39:29 +0200363function f_init_pars(integer imsi_suffix, boolean sgsap := false, boolean gsup := true, integer ran_idx := 0,
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200364 boolean ran_is_geran := true, boolean use_osmux := false, OCT4 gsup_sid := '20000101'O,
365 boolean verify_cell_id := true)
Harald Weltef9abf8d2019-04-21 13:07:17 +0200366runs on MTC_CT return BSC_ConnHdlrPars {
Harald Weltede371492018-01-27 23:44:41 +0100367 var BSC_ConnHdlrNetworkPars net_pars := {
368 kc_support := '0A'O, /* A5/1 and A5/3 enabled */
369 expect_tmsi := true,
370 expect_auth := false,
Oliver Smith1d118ff2019-07-03 10:57:35 +0200371 expect_ciph := false,
372 expect_imei := false,
373 expect_imei_early := false,
374 check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
375 check_imei_error := false
Harald Weltede371492018-01-27 23:44:41 +0100376 };
Harald Weltea49e36e2018-01-21 19:29:33 +0100377 var BSC_ConnHdlrPars pars := {
Harald Weltef9abf8d2019-04-21 13:07:17 +0200378 sccp_addr_own := g_bssap[ran_idx].sccp_addr_own,
379 sccp_addr_peer := g_bssap[ran_idx].sccp_addr_peer,
Harald Welteedbab812018-03-18 16:02:25 +0100380 cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42)),
Harald Welte81b7f9d2018-01-24 19:06:24 +0100381 imei := f_gen_imei(imsi_suffix),
382 imsi := f_gen_imsi(imsi_suffix),
383 msisdn := f_gen_msisdn(imsi_suffix),
Harald Welte256571e2018-01-24 18:47:19 +0100384 tmsi := omit,
Harald Welte9de84792018-01-28 01:06:35 +0100385 cm1 := valueof(ts_CM1),
Harald Welte82600572018-01-21 20:54:08 +0100386 cm2 := valueof(ts_CM2_default),
Harald Welte16114282018-01-24 22:41:21 +0100387 cm3 := omit,
Harald Weltede371492018-01-27 23:44:41 +0100388 vec := omit,
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100389 net := net_pars,
Philipp Maieraeb29a82018-11-08 17:40:53 +0100390 send_early_cm := true,
391 ipa_ctrl_ip := mp_msc_ip,
392 ipa_ctrl_port := mp_msc_ctrl_port,
Philipp Maier9b690e42018-12-21 11:50:03 +0100393 ipa_ctrl_enable := true,
Philipp Maier57865482019-01-07 18:33:13 +0100394 mm_info := mp_mm_info,
Philipp Maierc09a1312019-04-09 16:05:26 +0200395 sgsap_enable := sgsap,
Harald Weltef9abf8d2019-04-21 13:07:17 +0200396 gsup_enable := gsup,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +0100397 gsup_sid := gsup_sid,
Harald Weltec1f937a2019-04-21 21:19:23 +0200398 ran_idx := ran_idx,
Harald Welte9b751a62019-04-14 17:39:29 +0200399 use_umts_aka := false,
Pau Espin Pedrola65697d2019-05-21 12:54:39 +0200400 ran_is_geran := ran_is_geran,
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200401 use_osmux := use_osmux,
Pau Espin Pedrol833174e2020-09-03 16:46:02 +0200402 use_ipv6 := false,
Pau Espin Pedrol174fac22021-02-26 13:20:10 +0100403 verify_cell_id := verify_cell_id
Harald Weltea49e36e2018-01-21 19:29:33 +0100404 };
Harald Weltee13cfb22019-04-23 16:52:02 +0200405 if (not ran_is_geran) {
406 pars.use_umts_aka := true;
407 pars.net.expect_auth := true;
408 }
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100409 return pars;
410}
411
Neels Hofmeyr0ac63152019-05-07 01:20:17 +0200412function f_start_handler_with_pars(void_fn fn, BSC_ConnHdlrPars pars, integer bssap_idx := 0) runs on MTC_CT return BSC_ConnHdlr {
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100413 var BSC_ConnHdlr vc_conn;
Neels Hofmeyr0ac63152019-05-07 01:20:17 +0200414 var charstring id := testcasename() & int2str(bssap_idx);
Harald Weltea49e36e2018-01-21 19:29:33 +0100415
416 vc_conn := BSC_ConnHdlr.create(id);
417 /* BSSMAP part / A interface */
Neels Hofmeyr0ac63152019-05-07 01:20:17 +0200418 connect(vc_conn:BSSAP, g_bssap[pars.ran_idx + bssap_idx].vc_RAN:CLIENT);
419 connect(vc_conn:BSSAP_PROC, g_bssap[pars.ran_idx + bssap_idx].vc_RAN:PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100420 /* MNCC part */
421 connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
422 connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);
Harald Welte4aa970c2018-01-26 10:38:09 +0100423 /* MGCP part */
424 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
425 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100426 /* GSUP part */
Philipp Maierc09a1312019-04-09 16:05:26 +0200427 if (pars.gsup_enable == true) {
428 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
429 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
430 }
Harald Weltef640a012018-04-14 17:49:21 +0200431 /* SMPP part */
432 connect(vc_conn:SMPP, vc_SMPP:SMPP_CLIENT);
433 connect(vc_conn:SMPP_PROC, vc_SMPP:SMPP_PROC);
Harald Welte4263c522018-12-06 11:56:27 +0100434 /* SGs part */
Philipp Maier8e07a4a2019-02-14 18:23:28 +0100435 if (pars.sgsap_enable == true) {
Philipp Maier57865482019-01-07 18:33:13 +0100436 connect(vc_conn:SGsAP, vc_SGsAP:SGsAP_CLIENT);
437 connect(vc_conn:SGsAP_PROC, vc_SGsAP:SGsAP_PROC);
438 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100439
Harald Weltea10db902018-01-27 12:44:49 +0100440 /* We cannot use vc_conn.start(f_init_handler(fn, id, pars)); as we cannot have
441 * a stand-alone 'derefers()' call, see https://www.eclipse.org/forums/index.php/t/1091364/ */
Harald Weltea49e36e2018-01-21 19:29:33 +0100442 vc_conn.start(derefers(fn)(id, pars));
443 return vc_conn;
444}
445
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200446function f_start_handler(void_fn fn, integer imsi_suffix, integer ran_idx := 0, boolean ran_is_geran := true, boolean use_osmux := false,
447 boolean verify_cell_id := true)
Harald Welte9b751a62019-04-14 17:39:29 +0200448runs on MTC_CT return BSC_ConnHdlr {
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200449 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 +0100450}
451
Harald Weltea49e36e2018-01-21 19:29:33 +0100452private function f_tc_lu_imsi_noauth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100453 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100454 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100455}
Harald Weltea49e36e2018-01-21 19:29:33 +0100456testcase TC_lu_imsi_noauth_tmsi() runs on MTC_CT {
457 var BSC_ConnHdlr vc_conn;
458 f_init();
459
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100460 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi), 1);
Harald Weltea49e36e2018-01-21 19:29:33 +0100461 vc_conn.done;
462}
463
464private function f_tc_lu_imsi_noauth_notmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100465 pars.net.expect_tmsi := false;
Harald Weltea10db902018-01-27 12:44:49 +0100466 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100467 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100468}
Harald Weltea49e36e2018-01-21 19:29:33 +0100469testcase TC_lu_imsi_noauth_notmsi() runs on MTC_CT {
470 var BSC_ConnHdlr vc_conn;
471 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100472 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
Harald Weltea49e36e2018-01-21 19:29:33 +0100473
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100474 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi), 2);
Harald Weltea49e36e2018-01-21 19:29:33 +0100475 vc_conn.done;
476}
477
478/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
Harald Weltee13cfb22019-04-23 16:52:02 +0200479friend function f_tc_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100480 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100481 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
482
483 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +0200484 f_cl3_or_initial_ue(l3_lu);
Neels Hofmeyrd076c522019-11-28 01:00:52 +0100485 f_mm_common();
Harald Weltea49e36e2018-01-21 19:29:33 +0100486 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
487 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
488 alt {
Harald Welte5946b332018-03-18 23:32:21 +0100489 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej(int2oct(23,1)))) {
490 f_expect_clear();
491 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100492 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
493 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
Daniel Willmannafce8662018-07-06 23:11:32 +0200494 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100495 }
496 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100497}
498testcase TC_lu_imsi_reject() runs on MTC_CT {
499 var BSC_ConnHdlr vc_conn;
500 f_init();
501
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200502 vc_conn := f_start_handler(refers(f_tc_lu_imsi_reject), 3, verify_cell_id := false);
Harald Weltea49e36e2018-01-21 19:29:33 +0100503 vc_conn.done;
504}
505
Harald Weltee13cfb22019-04-23 16:52:02 +0200506
507
Harald Weltea49e36e2018-01-21 19:29:33 +0100508/* Do LU by IMSI, timeout on GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +0200509friend function f_tc_lu_imsi_timeout_gsup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100510 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100511 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
512
513 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +0200514 f_cl3_or_initial_ue(l3_lu);
Neels Hofmeyrd076c522019-11-28 01:00:52 +0100515 f_mm_common();
Harald Weltea49e36e2018-01-21 19:29:33 +0100516 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
517 /* Normally the HLR would need to respond here, but we decide to force a timeout here */
518 alt {
519 /* FIXME: Expect specific reject cause */
Harald Welte5946b332018-03-18 23:32:21 +0100520 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
521 f_expect_clear();
522 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100523 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
524 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
Daniel Willmannafce8662018-07-06 23:11:32 +0200525 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100526 }
527 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100528}
529testcase TC_lu_imsi_timeout_gsup() runs on MTC_CT {
530 var BSC_ConnHdlr vc_conn;
531 f_init();
532
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200533 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_gsup), 4, verify_cell_id := false);
Harald Weltea49e36e2018-01-21 19:29:33 +0100534 vc_conn.done;
535}
536
Harald Weltee13cfb22019-04-23 16:52:02 +0200537
Harald Welte7b1b2812018-01-22 21:23:06 +0100538private function f_tc_lu_imsi_auth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100539 pars.net.expect_auth := true;
Harald Weltea10db902018-01-27 12:44:49 +0100540 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100541 f_perform_lu();
Harald Welte7b1b2812018-01-22 21:23:06 +0100542}
543testcase TC_lu_imsi_auth_tmsi() runs on MTC_CT {
544 var BSC_ConnHdlr vc_conn;
545 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100546 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte7b1b2812018-01-22 21:23:06 +0100547
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100548 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi), 5);
Harald Welte7b1b2812018-01-22 21:23:06 +0100549 vc_conn.done;
550}
551
Harald Weltee13cfb22019-04-23 16:52:02 +0200552
553friend function f_tc_lu_imsi_auth3g_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Welte8a397ae2019-04-21 22:03:37 +0200554 pars.net.expect_auth := true;
555 pars.use_umts_aka := true;
556 f_init_handler(pars);
557 f_perform_lu();
558}
559testcase TC_lu_imsi_auth3g_tmsi() runs on MTC_CT {
560 var BSC_ConnHdlr vc_conn;
561 f_init();
562 f_vty_config(MSCVTY, "network", "authentication required");
563
564 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth3g_tmsi), 1005);
565 vc_conn.done;
566}
Harald Weltea49e36e2018-01-21 19:29:33 +0100567
Pau Espin Pedrold3d54a92019-12-17 17:02:54 +0100568/* Proceed with LU but never receive an TMSI Realloc from MS after LU Accept (OS#4337).
569 * TS 24.008 sec 4.3.1.5 states MSC should simply release all MM connections.
570 */
571friend function f_tc_lu_imsi_timeout_tmsi_realloc(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
572
573 f_init_handler(pars);
574
575 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
576 var PDU_DTAP_MT dtap_mt;
577
578 /* tell GSUP dispatcher to send this IMSI to us */
579 f_create_gsup_expect(hex2str(g_pars.imsi));
580
581 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
582 if (g_pars.ran_is_geran) {
583 f_bssap_compl_l3(l3_lu);
584 if (g_pars.send_early_cm) {
585 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
586 }
587 } else {
588 f_ranap_initial_ue(l3_lu);
589 }
590
591 f_mm_imei_early();
592 f_mm_common();
593 f_msc_lu_hlr();
594 f_mm_imei();
595
596 alt {
597 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) -> value dtap_mt {}
598 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
599 setverdict(fail, "Expected LU ACK, but received LU REJ");
600 mtc.stop;
601 }
602 }
603
604 /* currently (due to bug OS#4337), an extra LU reject is received before
605 terminating the connection. Enabling following line makes the test
606 pass: */
607 //f_expect_lu_reject('16'O); /* Cause: congestion */
608
609 /* f_expect_lu_reject() already waits for T"-1" (X1, 5 seconds), but give some
610 extra time to avoid race conditons... */
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200611 f_expect_clear(7.0, verify_vlr_cell_id := false);
Pau Espin Pedrold3d54a92019-12-17 17:02:54 +0100612
613 setverdict(pass);
614}
615testcase TC_lu_imsi_timeout_tmsi_realloc() runs on MTC_CT {
616 var BSC_ConnHdlr vc_conn;
617 f_init();
618
619 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_tmsi_realloc), 5);
620 vc_conn.done;
621}
622
Harald Weltee13cfb22019-04-23 16:52:02 +0200623
Harald Weltea49e36e2018-01-21 19:29:33 +0100624/* Send CM SERVICE REQ for IMSI that has never performed LU before */
Harald Weltee13cfb22019-04-23 16:52:02 +0200625friend function f_tc_cmserv_imsi_unknown(charstring id, BSC_ConnHdlrPars pars)
Harald Weltea49e36e2018-01-21 19:29:33 +0100626runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100627 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100628
629 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welteedbab812018-03-18 16:02:25 +0100630 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100631 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltea49e36e2018-01-21 19:29:33 +0100632
633 f_create_gsup_expect(hex2str(g_pars.imsi));
634
635 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200636 f_cl3_or_initial_ue(l3_info);
Harald Welteb7817992019-05-09 13:15:39 +0200637 f_mm_auth();
Harald Weltea49e36e2018-01-21 19:29:33 +0100638
639 timer T := 10.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100640 T.start;
641 alt {
Harald Weltea49e36e2018-01-21 19:29:33 +0100642 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
643 //[] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC)) { }
Daniel Willmannafce8662018-07-06 23:11:32 +0200644 [] BSSAP.receive {
645 setverdict(fail, "Received unexpected BSSAP");
646 mtc.stop;
647 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100648 [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
649 setverdict(fail, "Unexpected GSUP UL REQ");
Daniel Willmannafce8662018-07-06 23:11:32 +0200650 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100651 }
Daniel Willmannafce8662018-07-06 23:11:32 +0200652 [] T.timeout {
Neels Hofmeyrf1c3c212020-08-19 13:15:32 +0000653 setverdict(fail, "Timeout waiting for CM SERV REJ");
Daniel Willmannafce8662018-07-06 23:11:32 +0200654 mtc.stop;
655 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100656 }
657
Harald Welte1ddc7162018-01-27 14:25:46 +0100658 f_expect_clear();
Harald Weltef6dd64d2017-11-19 12:09:51 +0100659}
Harald Weltea49e36e2018-01-21 19:29:33 +0100660testcase TC_cmserv_imsi_unknown() runs on MTC_CT {
661 var BSC_ConnHdlr vc_conn;
662 f_init();
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200663 vc_conn := f_start_handler(refers(f_tc_cmserv_imsi_unknown), 6, verify_cell_id := false);
Harald Weltea49e36e2018-01-21 19:29:33 +0100664 vc_conn.done;
665}
666
Harald Weltee13cfb22019-04-23 16:52:02 +0200667
Neels Hofmeyr13737fb2020-08-19 13:16:14 +0000668/* Send CM SERVICE REQ for TMSI that has never performed LU before */
669friend function f_tc_cmserv_tmsi_unknown(charstring id, BSC_ConnHdlrPars pars)
670runs on BSC_ConnHdlr {
671 f_init_handler(pars);
672
673 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('57111111'O));
674 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42));
675 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
676
677 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
678 f_cl3_or_initial_ue(l3_info);
679 f_mm_auth();
680
681 timer T := 10.0;
682 T.start;
683 alt {
684 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
685 [] BSSAP.receive {
686 setverdict(fail, "Received unexpected BSSAP");
687 mtc.stop;
688 }
689 [] T.timeout {
690 setverdict(fail, "Timeout waiting for CM SERV REJ");
691 mtc.stop;
692 }
693 }
694
695 f_expect_clear();
696}
697testcase TC_cmserv_tmsi_unknown() runs on MTC_CT {
698 var BSC_ConnHdlr vc_conn;
699 f_init();
700 vc_conn := f_start_handler(refers(f_tc_cmserv_tmsi_unknown), 57, verify_cell_id := false);
701 vc_conn.done;
702}
703
Neels Hofmeyr14d0b132020-08-19 13:49:05 +0000704/* Send Paging Response for IMSI that has never performed LU before */
705friend function f_tc_paging_response_imsi_unknown(charstring id, BSC_ConnHdlrPars pars)
706runs on BSC_ConnHdlr {
707 f_init_handler(pars);
708
709 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
710 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42));
711 var PDU_ML3_MS_NW l3_info := valueof(ts_PAG_RESP(mi));
712
713 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
714 f_cl3_or_initial_ue(l3_info);
715
716 /* The Paging Response gets rejected by a direct Clear Command */
717 f_expect_clear();
718}
719testcase TC_paging_response_imsi_unknown() runs on MTC_CT {
720 var BSC_ConnHdlr vc_conn;
721 f_init();
722 vc_conn := f_start_handler(refers(f_tc_paging_response_imsi_unknown), 58, verify_cell_id := false);
723 vc_conn.done;
724}
725
726/* Send Paging Response for TMSI that has never performed LU before */
727friend function f_tc_paging_response_tmsi_unknown(charstring id, BSC_ConnHdlrPars pars)
728runs on BSC_ConnHdlr {
729 f_init_handler(pars);
730
731 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('59111111'O));
732 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42));
733 var PDU_ML3_MS_NW l3_info := valueof(ts_PAG_RESP(mi));
734
735 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
736 f_cl3_or_initial_ue(l3_info);
737
738 /* The Paging Response gets rejected by a direct Clear Command */
739 f_expect_clear();
740}
741testcase TC_paging_response_tmsi_unknown() runs on MTC_CT {
742 var BSC_ConnHdlr vc_conn;
743 f_init();
744 vc_conn := f_start_handler(refers(f_tc_paging_response_tmsi_unknown), 59, verify_cell_id := false);
745 vc_conn.done;
746}
747
Neels Hofmeyr13737fb2020-08-19 13:16:14 +0000748
Harald Weltee13cfb22019-04-23 16:52:02 +0200749friend function f_tc_lu_and_mo_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100750 f_init_handler(pars);
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +0200751 var CallParameters cpars := valueof(t_CallParams);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100752 f_perform_lu();
Harald Welteb71901a2018-01-26 19:16:05 +0100753 f_mo_call(cpars);
Harald Welte2bb825f2018-01-22 11:31:18 +0100754}
755testcase TC_lu_and_mo_call() runs on MTC_CT {
756 var BSC_ConnHdlr vc_conn;
757 f_init();
758
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100759 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_call), 7);
Harald Welte071ed732018-01-23 19:53:52 +0100760 vc_conn.done;
761}
Pau Espin Pedrol833174e2020-09-03 16:46:02 +0200762friend function f_tc_lu_and_mo_call_ipv6(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
763 f_init_handler(pars);
764 var CallParameters cpars := valueof(t_CallParams);
765 cpars.mgw_conn_1.mgw_rtp_ip := "::1";
766 cpars.mgw_conn_2.mgw_rtp_ip := "::2";
767 cpars.bss_rtp_ip := "::3";
768 f_perform_lu();
769 f_mo_call(cpars);
770}
771testcase TC_lu_and_mo_call_ipv6() runs on MTC_CT {
772 var BSC_ConnHdlr vc_conn;
773 f_init();
774
775 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_call_ipv6), 7);
776 vc_conn.done;
777}
Harald Welte071ed732018-01-23 19:53:52 +0100778
Pau Espin Pedrola42745c2020-01-10 18:03:28 +0100779/* Verify T(iar) triggers and releases the channel */
780friend function f_lu_and_mo_call_sccp_tiar_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
781 timer T_wait_iar := int2float(5 + 1); /* g_msc_sccp_timer_iar + Give extra time (+1 sec) */
782 f_init_handler(pars);
783 var CallParameters cpars := valueof(t_CallParams);
784 f_perform_lu();
785 f_mo_call_establish(cpars);
786
787 /* Expect the channel cleared upon T(iar) triggered: */
788 T_wait_iar.start;
789 alt {
790 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
791 T_wait_iar.stop
792 setverdict(pass);
793 }
Pau Espin Pedrola42745c2020-01-10 18:03:28 +0100794 [] T_wait_iar.timeout {
795 setverdict(fail, "Timeout waiting for T(iar) triggered SCCP RSLD");
796 mtc.stop;
797 }
798 }
Harald Welte4a3fa712020-08-19 08:57:33 +0200799 /* DLCX for both directions; if we don't do this, we might receive either of the two during
800 * shutdown causing race conditions */
801 MGCP.receive(tr_DLCX(?));
802 MGCP.receive(tr_DLCX(?));
Pau Espin Pedrola42745c2020-01-10 18:03:28 +0100803
804 setverdict(pass);
805}
806testcase TC_lu_and_mo_call_sccp_tiar_timeout() runs on MTC_CT {
807 var BSC_ConnHdlr vc_conn;
808
809 /* Set T(iar) in MSC low enough that it will trigger before other side
810 has time to keep alive with a T(ias). Keep recommended ratio of
811 T(iar) >= T(ias)*2 */
812 g_msc_sccp_timer_ias := 2;
813 g_msc_sccp_timer_iar := 5;
814
815 f_init();
816
817 vc_conn := f_start_handler(refers(f_lu_and_mo_call_sccp_tiar_timeout), 89);
818 vc_conn.done;
819}
820
Harald Weltee13cfb22019-04-23 16:52:02 +0200821
Harald Welte071ed732018-01-23 19:53:52 +0100822/* Test LU (with authentication enabled), where HLR times out sending SAI response */
Harald Weltee13cfb22019-04-23 16:52:02 +0200823friend function f_tc_lu_auth_sai_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100824 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100825
826 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
827 var PDU_DTAP_MT dtap_mt;
828
829 /* tell GSUP dispatcher to send this IMSI to us */
830 f_create_gsup_expect(hex2str(g_pars.imsi));
831
832 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200833 f_cl3_or_initial_ue(l3_lu);
Harald Welte071ed732018-01-23 19:53:52 +0100834
835 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +0200836 if (pars.ran_is_geran) {
837 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
838 }
Harald Welte071ed732018-01-23 19:53:52 +0100839
840 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
841 /* The HLR would normally return an auth vector here, but we fail to do so. */
842
843 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100844 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100845}
846testcase TC_lu_auth_sai_timeout() runs on MTC_CT {
847 var BSC_ConnHdlr vc_conn;
848 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100849 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100850
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200851 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_timeout), 8, verify_cell_id := false);
Harald Welte071ed732018-01-23 19:53:52 +0100852 vc_conn.done;
853}
854
Harald Weltee13cfb22019-04-23 16:52:02 +0200855
Harald Welte071ed732018-01-23 19:53:52 +0100856/* Test LU (with authentication enabled), where HLR rejects sending SAI error */
Harald Weltee13cfb22019-04-23 16:52:02 +0200857friend function f_tc_lu_auth_sai_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100858 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100859
860 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
861 var PDU_DTAP_MT dtap_mt;
862
863 /* tell GSUP dispatcher to send this IMSI to us */
864 f_create_gsup_expect(hex2str(g_pars.imsi));
865
866 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200867 f_cl3_or_initial_ue(l3_lu);
Harald Welte071ed732018-01-23 19:53:52 +0100868
869 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +0200870 if (pars.ran_is_geran) {
871 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
872 }
Harald Welte071ed732018-01-23 19:53:52 +0100873
874 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
875 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 13));
876
877 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100878 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100879}
880testcase TC_lu_auth_sai_err() runs on MTC_CT {
881 var BSC_ConnHdlr vc_conn;
882 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100883 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100884
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200885 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_err), 9, verify_cell_id := false);
Harald Welte2bb825f2018-01-22 11:31:18 +0100886 vc_conn.done;
887}
Harald Weltea49e36e2018-01-21 19:29:33 +0100888
Harald Weltee13cfb22019-04-23 16:52:02 +0200889
Harald Weltebc881782018-01-23 20:09:15 +0100890/* Test LU but BSC will send a clear request in the middle */
891private function f_tc_lu_clear_request(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100892 f_init_handler(pars);
Harald Weltebc881782018-01-23 20:09:15 +0100893
894 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
895 var PDU_DTAP_MT dtap_mt;
896
897 /* tell GSUP dispatcher to send this IMSI to us */
898 f_create_gsup_expect(hex2str(g_pars.imsi));
899
900 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200901 f_cl3_or_initial_ue(l3_lu);
Harald Welte79f1e452020-08-18 22:55:02 +0200902 f_expect_common_id();
Harald Weltebc881782018-01-23 20:09:15 +0100903
904 /* Send Early Classmark, just for the fun of it */
905 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
906
907 f_sleep(1.0);
908 /* send clear request in the middle of the LU */
909 BSSAP.send(ts_BSSMAP_ClearRequest(0));
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200910 alt {
911 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { repeat; }
912 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {}
913 }
Harald Weltebc881782018-01-23 20:09:15 +0100914 BSSAP.send(ts_BSSMAP_ClearComplete);
Harald Welte89a32492018-01-27 19:07:28 +0100915 alt {
916 /* See https://osmocom.org/issues/2862 */
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200917 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
918 setverdict(fail, "Got a second Clear Command, only one expected");
Daniel Willmannafce8662018-07-06 23:11:32 +0200919 mtc.stop;
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200920 repeat;
921 }
Harald Welte6811d102019-04-14 22:23:14 +0200922 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte89a32492018-01-27 19:07:28 +0100923 }
Harald Weltebc881782018-01-23 20:09:15 +0100924 setverdict(pass);
925}
926testcase TC_lu_clear_request() runs on MTC_CT {
927 var BSC_ConnHdlr vc_conn;
928 f_init();
929
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100930 vc_conn := f_start_handler(refers(f_tc_lu_clear_request), 10);
Harald Weltebc881782018-01-23 20:09:15 +0100931 vc_conn.done;
932}
933
Vadim Yanitskiy109e7552021-02-05 05:36:02 +0100934/* Test reaction on Clear Request during a MO Call */
935friend function f_TC_mo_mt_call_clear_request(charstring id, BSC_ConnHdlrPars pars)
936runs on BSC_ConnHdlr {
937 var CallParameters cpars := valueof(t_CallParams);
938 var MNCC_PDU mncc_pdu;
939 timer T := 2.0;
940
941 f_init_handler(pars);
942
943 f_perform_lu();
944
945 /* HACK: reducing code duplication ('66'H - MO, '68'H - MT) */
946 if (pars.imsi == '262420002532766'H)
947 { f_mo_call_establish(cpars); }
948 else
949 { f_mt_call_establish(cpars); }
950
951 /* Hold the line for a while... */
952 f_sleep(2.0);
953
954 /* BSC sends BSSMAP Clear Request (e.g. due to RR failure) */
955 BSSAP.send(ts_BSSMAP_ClearRequest(1));
956
957 /* Expect (optional) CC RELEASE and Clear Command */
958 var default ccrel := activate(as_optional_cc_rel(cpars));
959 f_expect_clear();
960 deactivate(ccrel);
961
962 /* Expect RELease indication on the MNCC socket */
963 T.start;
964 alt {
965 [] MNCC.receive(tr_MNCC_REL_ind(cpars.mncc_callref)) -> value mncc_pdu {
966 log("Rx MNCC REL.ind, cause := ", mncc_pdu.u.signal.cause);
967 setverdict(pass);
968 }
969 [] MNCC.receive(MNCC_PDU:?) -> value mncc_pdu {
970 setverdict(fail, "Rx unexpected MNCC PDU: ", mncc_pdu);
971 }
972 [] T.timeout {
973 setverdict(fail, "Timeout waiting for MNCC REL.ind");
974 }
975 }
976}
977testcase TC_mo_call_clear_request() runs on MTC_CT {
978 var BSC_ConnHdlr vc_conn;
979
980 f_init();
981
982 vc_conn := f_start_handler(refers(f_TC_mo_mt_call_clear_request), 2532766); // '66'H - MO
983 vc_conn.done;
984}
985testcase TC_mt_call_clear_request() runs on MTC_CT {
986 var BSC_ConnHdlr vc_conn;
987
988 f_init();
989
990 vc_conn := f_start_handler(refers(f_TC_mo_mt_call_clear_request), 2532768); // '68'H - MT
991 vc_conn.done;
992}
993
Harald Welte66af9e62018-01-24 17:28:21 +0100994/* Test LU but BSC will send a clear request in the middle */
Harald Weltee13cfb22019-04-23 16:52:02 +0200995friend function f_tc_lu_disconnect(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100996 f_init_handler(pars);
Harald Welte66af9e62018-01-24 17:28:21 +0100997
998 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
999 var PDU_DTAP_MT dtap_mt;
1000
1001 /* tell GSUP dispatcher to send this IMSI to us */
1002 f_create_gsup_expect(hex2str(g_pars.imsi));
1003
1004 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001005 f_cl3_or_initial_ue(l3_lu);
Harald Welte66af9e62018-01-24 17:28:21 +01001006
1007 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +02001008 if (pars.ran_is_geran) {
1009 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1010 }
Harald Welte66af9e62018-01-24 17:28:21 +01001011
1012 f_sleep(1.0);
1013 /* send clear request in the middle of the LU */
Harald Welte6811d102019-04-14 22:23:14 +02001014 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Harald Welte66af9e62018-01-24 17:28:21 +01001015 setverdict(pass);
Neels Hofmeyrbb825c92019-03-06 15:35:50 +01001016 f_sleep(1.0);
Harald Welte66af9e62018-01-24 17:28:21 +01001017}
1018testcase TC_lu_disconnect() runs on MTC_CT {
1019 var BSC_ConnHdlr vc_conn;
1020 f_init();
1021
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001022 vc_conn := f_start_handler(refers(f_tc_lu_disconnect), 11);
Harald Welte66af9e62018-01-24 17:28:21 +01001023 vc_conn.done;
1024}
1025
Harald Welteba7b6d92018-01-23 21:32:34 +01001026/* Test LU but with illegal mobile identity type = IMEI */
Harald Weltee13cfb22019-04-23 16:52:02 +02001027friend function f_tc_lu_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001028 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +01001029
Harald Welte256571e2018-01-24 18:47:19 +01001030 var PDU_ML3_MS_NW l3_lu := f_build_lu_imei(g_pars.imei)
Harald Welteba7b6d92018-01-23 21:32:34 +01001031 var PDU_DTAP_MT dtap_mt;
1032
1033 /* tell GSUP dispatcher to send this IMSI to us */
1034 f_create_gsup_expect(hex2str(g_pars.imsi));
1035
1036 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001037 f_cl3_or_initial_ue(l3_lu);
Harald Welteba7b6d92018-01-23 21:32:34 +01001038
1039 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +02001040 if (pars.ran_is_geran) {
1041 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1042 }
Harald Welteba7b6d92018-01-23 21:32:34 +01001043 /* wait for LU reject, ignore any ID REQ */
1044 alt {
1045 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
1046 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req)) { repeat; }
1047 }
1048 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +01001049 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +01001050}
1051testcase TC_lu_by_imei() runs on MTC_CT {
1052 var BSC_ConnHdlr vc_conn;
1053 f_init();
1054
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001055 vc_conn := f_start_handler(refers(f_tc_lu_by_imei), 12, verify_cell_id := false);
Harald Welteba7b6d92018-01-23 21:32:34 +01001056 vc_conn.done;
1057}
1058
Harald Weltee13cfb22019-04-23 16:52:02 +02001059
Harald Welteba7b6d92018-01-23 21:32:34 +01001060/* Test LU by TMSI with unknown TMSI, expect (and answer) ID REQ. */
1061private function f_tc_lu_tmsi_noauth_unknown(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Stefan Sperling04fc4bc2018-06-25 17:44:57 +02001062 /* We piggyback a test for an MSC crash on overlong IMSI (OS#2864) onto this test. */
1063 var hexstring overlong_imsi := '012345789ABCDEF0123456789ABCDEF'H;
Harald Weltea10db902018-01-27 12:44:49 +01001064 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +01001065
1066 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('01020304'O); /* FIXME: Random */
1067 var PDU_DTAP_MT dtap_mt;
1068
1069 /* tell GSUP dispatcher to send this IMSI to us */
1070 f_create_gsup_expect(hex2str(g_pars.imsi));
1071
1072 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001073 f_cl3_or_initial_ue(l3_lu);
Harald Welteba7b6d92018-01-23 21:32:34 +01001074
1075 /* Send Early Classmark, just for the fun of it */
1076 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1077
1078 /* Wait for + respond to ID REQ (IMSI) */
Oliver Smith32898452019-07-09 12:32:35 +02001079 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req(CM_ID_TYPE_IMSI)));
Stefan Sperling04fc4bc2018-06-25 17:44:57 +02001080 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 +01001081 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
Harald Welte79f1e452020-08-18 22:55:02 +02001082 f_expect_common_id();
Harald Welteba7b6d92018-01-23 21:32:34 +01001083
1084 /* Expect MSC to do UpdateLocation to HLR; respond to it */
1085 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1086 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
1087 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
1088 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1089
1090 alt {
Harald Welte7ec4fa82018-01-27 10:57:40 +01001091 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
1092 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
1093 }
Harald Welteba7b6d92018-01-23 21:32:34 +01001094 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1095 setverdict(fail, "Expected LU ACK, but received REJ");
Daniel Willmannafce8662018-07-06 23:11:32 +02001096 mtc.stop;
Harald Welteba7b6d92018-01-23 21:32:34 +01001097 }
1098 }
1099
Philipp Maier9b690e42018-12-21 11:50:03 +01001100 /* Wait for MM-Information (if enabled) */
1101 f_expect_mm_info();
1102
Harald Welteba7b6d92018-01-23 21:32:34 +01001103 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +01001104 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +01001105}
1106testcase TC_lu_by_tmsi_noauth_unknown() runs on MTC_CT {
1107 var BSC_ConnHdlr vc_conn;
1108 f_init();
1109
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001110 vc_conn := f_start_handler(refers(f_tc_lu_tmsi_noauth_unknown), 13);
Harald Welteba7b6d92018-01-23 21:32:34 +01001111 vc_conn.done;
1112}
1113
Neels Hofmeyrfc06c732020-08-19 12:52:28 +00001114/* Test LU by unknown TMSI, while the IMSI is already attached: osmo-msc should switch to the attached vlr_subscr. */
1115private function f_tc_attached_imsi_lu_unknown_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1116 f_init_handler(pars);
1117
1118 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('56111111'O);
1119 var PDU_DTAP_MT dtap_mt;
1120
1121 /* tell GSUP dispatcher to send this IMSI to us */
1122 f_create_gsup_expect(hex2str(g_pars.imsi));
1123
1124 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
1125 f_cl3_or_initial_ue(l3_lu);
1126
1127 /* Send Early Classmark, just for the fun of it */
1128 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1129
1130 /* Wait for + respond to ID REQ (IMSI) */
1131 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req(CM_ID_TYPE_IMSI)));
1132 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
1133 f_expect_common_id();
1134
1135 /* Expect MSC to do UpdateLocation to HLR; respond to it */
1136 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1137 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
1138 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
1139 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1140
1141 alt {
1142 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
1143 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
1144 }
1145 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1146 setverdict(fail, "Expected LU ACK, but received REJ");
1147 mtc.stop;
1148 }
1149 }
1150
1151 /* Wait for MM-Information (if enabled) */
1152 f_expect_mm_info();
1153
1154 /* wait for normal teardown */
1155 f_expect_clear();
1156
1157 /* Now the same IMSI is still attached in the VLR, and a LU with an unknown TMSI reveals the same IMSI only
1158 * later during ID Response. osmo-msc first creates a new vlr_subscr for the unknown TMSI, and as soon as the
1159 * IMSI becomes known, must notice that this IMSI is still regarded as attached, and must not create evil twins.
1160 */
1161
1162 /* (since the TMSI Reallocation happened, we could do this with exactly the same TMSI as above, but for test
1163 * readability just use a different one.) */
1164 l3_lu := f_build_lu_tmsi('56222222'O);
1165 f_cl3_or_initial_ue(l3_lu);
1166
1167 /* Wait for + respond to ID REQ (IMSI) */
1168 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req(CM_ID_TYPE_IMSI)));
1169 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
1170 f_expect_common_id();
1171
1172 /* Expect MSC to do UpdateLocation to HLR; respond to it */
1173 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1174 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
1175 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
1176 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1177
1178 alt {
1179 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
1180 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
1181 }
1182 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1183 setverdict(fail, "Expected LU ACK, but received REJ");
1184 mtc.stop;
1185 }
1186 }
1187
1188 /* Wait for MM-Information (if enabled) */
1189 f_expect_mm_info();
1190
1191 /* wait for normal teardown */
1192 f_expect_clear();
1193}
1194testcase TC_attached_imsi_lu_unknown_tmsi() runs on MTC_CT {
1195 var BSC_ConnHdlr vc_conn;
1196 f_init();
1197
1198 vc_conn := f_start_handler(refers(f_tc_attached_imsi_lu_unknown_tmsi), 56);
1199 vc_conn.done;
1200}
1201
Harald Welte4d15fa72020-08-19 08:58:28 +02001202friend function f_imsi_detach_by_imsi() runs on BSC_ConnHdlr {
Harald Welte45164da2018-01-24 12:51:27 +01001203 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1204
1205 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001206 f_cl3_or_initial_ue(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
Harald Welte45164da2018-01-24 12:51:27 +01001207
1208 /* Send Early Classmark, just for the fun of it? */
Harald Welte4d15fa72020-08-19 08:58:28 +02001209 if (g_pars.ran_is_geran) {
Harald Weltee13cfb22019-04-23 16:52:02 +02001210 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1211 }
Harald Welte45164da2018-01-24 12:51:27 +01001212
1213 /* wait for normal teardown */
Harald Welte4d15fa72020-08-19 08:58:28 +02001214 f_expect_clear(verify_vlr_cell_id := false);
1215}
1216
1217
1218/* Test IMSI DETACH (MI=IMSI) */
1219friend function f_tc_imsi_detach_by_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1220 f_init_handler(pars);
1221
1222 f_imsi_detach_by_imsi();
Harald Welte45164da2018-01-24 12:51:27 +01001223}
1224testcase TC_imsi_detach_by_imsi() runs on MTC_CT {
1225 var BSC_ConnHdlr vc_conn;
1226 f_init();
1227
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001228 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imsi), 14, verify_cell_id := false);
Harald Welte45164da2018-01-24 12:51:27 +01001229 vc_conn.done;
1230}
1231
Harald Weltee13cfb22019-04-23 16:52:02 +02001232
Harald Welte45164da2018-01-24 12:51:27 +01001233/* Test IMSI DETACH (MI=TMSI) */
Harald Weltee13cfb22019-04-23 16:52:02 +02001234friend function f_tc_imsi_detach_by_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001235 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001236
1237 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('01020304'O));
1238
1239 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001240 f_cl3_or_initial_ue(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
Harald Welte45164da2018-01-24 12:51:27 +01001241
1242 /* Send Early Classmark, just for the fun of it? */
Harald Weltee13cfb22019-04-23 16:52:02 +02001243 if (pars.ran_is_geran) {
1244 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1245 }
Harald Welte45164da2018-01-24 12:51:27 +01001246
1247 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +01001248 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001249}
1250testcase TC_imsi_detach_by_tmsi() runs on MTC_CT {
1251 var BSC_ConnHdlr vc_conn;
1252 f_init();
1253
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001254 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_tmsi), 15, verify_cell_id := false);
Harald Welte45164da2018-01-24 12:51:27 +01001255 vc_conn.done;
1256}
1257
Harald Weltee13cfb22019-04-23 16:52:02 +02001258
Harald Welte45164da2018-01-24 12:51:27 +01001259/* Test IMSI DETACH (MI=IMEI), which is illegal */
Harald Weltee13cfb22019-04-23 16:52:02 +02001260friend function f_tc_imsi_detach_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001261 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001262
Harald Welte256571e2018-01-24 18:47:19 +01001263 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte45164da2018-01-24 12:51:27 +01001264
1265 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001266 f_cl3_or_initial_ue(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
Harald Welte45164da2018-01-24 12:51:27 +01001267
1268 /* Send Early Classmark, just for the fun of it? */
Harald Weltee13cfb22019-04-23 16:52:02 +02001269 if (pars.ran_is_geran) {
1270 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1271 }
Harald Welte45164da2018-01-24 12:51:27 +01001272
1273 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +01001274 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001275}
1276testcase TC_imsi_detach_by_imei() runs on MTC_CT {
1277 var BSC_ConnHdlr vc_conn;
1278 f_init();
1279
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001280 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imei), 16, verify_cell_id := false);
Harald Welte45164da2018-01-24 12:51:27 +01001281 vc_conn.done;
1282}
1283
1284
1285/* helper function for an emergency call. caller passes in mobile identity to use */
1286private function f_emerg_call(MobileIdentityLV mi) runs on BSC_ConnHdlr {
Harald Welte0bef21e2018-02-10 09:48:23 +01001287 var CallParameters cpars := valueof(t_CallParams('112'H, 0));
1288 cpars.emergency := true;
Harald Welte45164da2018-01-24 12:51:27 +01001289
Harald Welte0bef21e2018-02-10 09:48:23 +01001290 f_mo_call(cpars);
Harald Welte45164da2018-01-24 12:51:27 +01001291}
1292
1293/* establish an emergency call by IMEI, no SIM inserted (and hence no IMSI) */
Harald Weltee13cfb22019-04-23 16:52:02 +02001294friend function f_tc_emerg_call_imei_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001295 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001296
Harald Welte256571e2018-01-24 18:47:19 +01001297 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001298 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001299 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +01001300 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ('05'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +01001301 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001302}
1303testcase TC_emerg_call_imei_reject() 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_emerg_call_imei_reject), 17, verify_cell_id := false);
Harald Welte45164da2018-01-24 12:51:27 +01001308 vc_conn.done;
1309}
1310
Harald Weltee13cfb22019-04-23 16:52:02 +02001311
Harald Welted5b91402018-01-24 18:48:16 +01001312/* establish an emergency call by IMSI, SIM inserted (and hence IMSI) */
Harald Weltee13cfb22019-04-23 16:52:02 +02001313friend function f_tc_emerg_call_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001314 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001315 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001316 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001317 /* Then issue emergency call identified by IMSI */
1318 f_emerg_call(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
1319}
1320testcase TC_emerg_call_imsi() runs on MTC_CT {
1321 var BSC_ConnHdlr vc_conn;
1322 f_init();
1323
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001324 vc_conn := f_start_handler(refers(f_tc_emerg_call_imsi), 18);
Harald Welte45164da2018-01-24 12:51:27 +01001325 vc_conn.done;
1326}
1327
Harald Weltee13cfb22019-04-23 16:52:02 +02001328
Harald Welte45164da2018-01-24 12:51:27 +01001329/* CM Service Request for VGCS -> reject */
1330private function f_tc_cm_serv_req_vgcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001331 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001332
1333 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001334 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001335
1336 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001337 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VGCS, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001338 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +01001339 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001340 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001341}
1342testcase TC_cm_serv_req_vgcs_reject() runs on MTC_CT {
1343 var BSC_ConnHdlr vc_conn;
1344 f_init();
1345
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001346 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vgcs_reject), 19);
Harald Welte45164da2018-01-24 12:51:27 +01001347 vc_conn.done;
1348}
1349
1350/* CM Service Request for VBS -> reject */
1351private function f_tc_cm_serv_req_vbs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001352 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001353
1354 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001355 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001356
1357 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001358 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VBS, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001359 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +01001360 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001361 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001362}
1363testcase TC_cm_serv_req_vbs_reject() runs on MTC_CT {
1364 var BSC_ConnHdlr vc_conn;
1365 f_init();
1366
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001367 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vbs_reject), 20);
Harald Welte45164da2018-01-24 12:51:27 +01001368 vc_conn.done;
1369}
1370
1371/* CM Service Request for LCS -> reject */
1372private function f_tc_cm_serv_req_lcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001373 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001374
1375 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001376 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001377
1378 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001379 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_LCS, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001380 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +01001381 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001382 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001383}
1384testcase TC_cm_serv_req_lcs_reject() runs on MTC_CT {
1385 var BSC_ConnHdlr vc_conn;
1386 f_init();
1387
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001388 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_lcs_reject), 21);
Harald Welte45164da2018-01-24 12:51:27 +01001389 vc_conn.done;
1390}
1391
Harald Welte0195ab12018-01-24 21:50:20 +01001392/* CM Re-Establishment Request */
1393private function f_tc_cm_reest_req_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001394 f_init_handler(pars);
Harald Welte0195ab12018-01-24 21:50:20 +01001395
1396 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001397 f_perform_lu();
Harald Welte0195ab12018-01-24 21:50:20 +01001398
1399 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1400 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REEST_REQ(0, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001401 f_cl3_or_initial_ue(l3_info);
Harald Welte0195ab12018-01-24 21:50:20 +01001402 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001403 f_expect_clear();
Harald Welte0195ab12018-01-24 21:50:20 +01001404}
1405testcase TC_cm_reest_req_reject() runs on MTC_CT {
1406 var BSC_ConnHdlr vc_conn;
1407 f_init();
Harald Welte0195ab12018-01-24 21:50:20 +01001408
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001409 vc_conn := f_start_handler(refers(f_tc_cm_reest_req_reject), 22);
Harald Welte0195ab12018-01-24 21:50:20 +01001410 vc_conn.done;
1411}
1412
Harald Weltec638f4d2018-01-24 22:00:36 +01001413/* Test LU (with authentication enabled), with wrong response from MS */
1414private function f_tc_lu_auth_2G_fail(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001415 f_init_handler(pars);
Harald Weltec638f4d2018-01-24 22:00:36 +01001416
1417 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
1418
1419 /* tell GSUP dispatcher to send this IMSI to us */
1420 f_create_gsup_expect(hex2str(g_pars.imsi));
1421
1422 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001423 f_cl3_or_initial_ue(l3_lu);
Harald Weltec638f4d2018-01-24 22:00:36 +01001424
1425 /* Send Early Classmark, just for the fun of it */
1426 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1427
1428 var AuthVector vec := f_gen_auth_vec_2g();
1429 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(vec.rand, vec.sres, vec.kc));
1430 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
1431 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
1432
1433 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(vec.rand)));
1434 /* Send back wrong auth response */
1435 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G('00000000'O)));
1436
1437 /* Expect GSUP AUTH FAIL REP to HLR */
1438 GSUP.receive(tr_GSUP_AUTH_FAIL_IND(g_pars.imsi));
1439
1440 /* Expect LU REJECT with Cause == Illegal MS */
1441 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej('03'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +01001442 f_expect_clear();
Harald Weltec638f4d2018-01-24 22:00:36 +01001443}
1444testcase TC_lu_auth_2G_fail() runs on MTC_CT {
1445 var BSC_ConnHdlr vc_conn;
1446 f_init();
1447 f_vty_config(MSCVTY, "network", "authentication required");
Harald Weltec638f4d2018-01-24 22:00:36 +01001448
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001449 vc_conn := f_start_handler(refers(f_tc_lu_auth_2G_fail), 23, verify_cell_id := false);
Harald Weltec638f4d2018-01-24 22:00:36 +01001450 vc_conn.done;
1451}
1452
Harald Weltede371492018-01-27 23:44:41 +01001453/* A5/1 + A5/3 permitted on network side, and MS capable to do it */
Harald Welte16114282018-01-24 22:41:21 +01001454private 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 +01001455 pars.net.expect_auth := true;
1456 pars.net.expect_ciph := true;
Harald Weltea10db902018-01-27 12:44:49 +01001457 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001458 f_perform_lu();
Harald Welte16114282018-01-24 22:41:21 +01001459}
1460testcase TC_lu_imsi_auth_tmsi_encr_13_13() runs on MTC_CT {
1461 var BSC_ConnHdlr vc_conn;
1462 f_init();
1463 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte16114282018-01-24 22:41:21 +01001464 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1465
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001466 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_13), 24);
Harald Welte16114282018-01-24 22:41:21 +01001467 vc_conn.done;
1468}
1469
Harald Welte1af6ea82018-01-25 18:33:15 +01001470/* Test Complete L3 without payload */
1471private function f_tc_cl3_no_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001472 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001473
1474 /* Send Complete L3 Info with empty L3 frame */
1475 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1476 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, ''O))));
1477
Harald Weltef466eb42018-01-27 14:26:54 +01001478 timer T := 5.0;
1479 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001480 alt {
Harald Welte6811d102019-04-14 22:23:14 +02001481 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte1af6ea82018-01-25 18:33:15 +01001482 /* Expect LU REJECT with Cause == Illegal MS */
Harald Weltebdb3c452018-03-18 22:43:06 +01001483 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
Harald Welte6811d102019-04-14 22:23:14 +02001484 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001485 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001486 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001487 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Daniel Willmannafce8662018-07-06 23:11:32 +02001488 mtc.stop;
Harald Weltef466eb42018-01-27 14:26:54 +01001489 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001490 }
1491 setverdict(pass);
1492}
1493testcase TC_cl3_no_payload() runs on MTC_CT {
1494 var BSC_ConnHdlr vc_conn;
1495 f_init();
1496
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001497 vc_conn := f_start_handler(refers(f_tc_cl3_no_payload), 25);
Harald Welte1af6ea82018-01-25 18:33:15 +01001498 vc_conn.done;
1499}
1500
1501/* Test Complete L3 with random payload */
1502private function f_tc_cl3_rnd_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001503 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001504
Daniel Willmannaa14a382018-07-26 08:29:45 +02001505 /* length is limited by PDU_BSSAP length field which includes some
1506 * other fields beside l3info payload. So payl can only be 240 bytes
1507 * Since rnd() returns values < 1 multiply with 241
1508 */
1509 var integer len := float2int(rnd() * 241.0);
Harald Welte1af6ea82018-01-25 18:33:15 +01001510 var octetstring payl := f_rnd_octstring(len);
1511
1512 /* Send Complete L3 Info with empty L3 frame */
1513 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1514 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, payl))));
1515
Harald Weltef466eb42018-01-27 14:26:54 +01001516 timer T := 5.0;
1517 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001518 alt {
1519 /* Immediate disconnect */
Harald Welte6811d102019-04-14 22:23:14 +02001520 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte1af6ea82018-01-25 18:33:15 +01001521 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
Harald Welte6811d102019-04-14 22:23:14 +02001522 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001523 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001524 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001525 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Daniel Willmannafce8662018-07-06 23:11:32 +02001526 mtc.stop;
Harald Weltef466eb42018-01-27 14:26:54 +01001527 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001528 }
1529 setverdict(pass);
1530}
1531testcase TC_cl3_rnd_payload() runs on MTC_CT {
1532 var BSC_ConnHdlr vc_conn;
1533 f_init();
1534
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001535 vc_conn := f_start_handler(refers(f_tc_cl3_rnd_payload), 26);
Harald Welte1af6ea82018-01-25 18:33:15 +01001536 vc_conn.done;
1537}
1538
Harald Welte116e4332018-01-26 22:17:48 +01001539/* Test Complete L3 with random payload */
Harald Weltee13cfb22019-04-23 16:52:02 +02001540friend function f_tc_establish_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001541 f_init_handler(pars);
Harald Welte116e4332018-01-26 22:17:48 +01001542
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001543 f_perform_lu();
Harald Welte116e4332018-01-26 22:17:48 +01001544
Harald Welteb9e86fa2018-04-09 18:18:31 +02001545 f_establish_fully();
Daniel Willmann898a7e02018-05-17 12:16:16 +02001546 f_expect_clear(10.0);
Harald Welte116e4332018-01-26 22:17:48 +01001547}
1548testcase TC_establish_and_nothing() runs on MTC_CT {
1549 var BSC_ConnHdlr vc_conn;
1550 f_init();
1551
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001552 vc_conn := f_start_handler(refers(f_tc_establish_and_nothing), 27);
Harald Welte116e4332018-01-26 22:17:48 +01001553 vc_conn.done;
1554}
1555
Harald Weltee13cfb22019-04-23 16:52:02 +02001556
Harald Welte12510c52018-01-26 22:26:24 +01001557/* Test MO Call SETUP with no response from MNCC */
Harald Weltee13cfb22019-04-23 16:52:02 +02001558friend function f_tc_mo_setup_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Philipp Maier109e6aa2018-10-17 10:53:32 +02001559 f_init_handler(pars, 190.0);
Harald Weltea10db902018-01-27 12:44:49 +01001560
Harald Welte12510c52018-01-26 22:26:24 +01001561 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001562 cpars.mgw_conn_2.resp := 0;
1563 cpars.stop_after_cc_setup := true;
1564
1565 f_vty_config(MSCVTY, "msc", "mncc guard-timeout 20");
Harald Welte12510c52018-01-26 22:26:24 +01001566
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001567 f_perform_lu();
Harald Welte12510c52018-01-26 22:26:24 +01001568
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001569 f_mo_call_establish(cpars);
Harald Welte12510c52018-01-26 22:26:24 +01001570
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001571 var default ccrel := activate(as_optional_cc_rel(cpars));
1572
Philipp Maier109e6aa2018-10-17 10:53:32 +02001573 f_expect_clear(185.0);
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001574
1575 deactivate(ccrel);
1576
1577 f_sleep(1.0);
Harald Welte12510c52018-01-26 22:26:24 +01001578}
1579testcase TC_mo_setup_and_nothing() runs on MTC_CT {
1580 var BSC_ConnHdlr vc_conn;
1581 f_init();
1582
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001583 vc_conn := f_start_handler(refers(f_tc_mo_setup_and_nothing), 28);
Harald Welte12510c52018-01-26 22:26:24 +01001584 vc_conn.done;
1585}
1586
Harald Weltee13cfb22019-04-23 16:52:02 +02001587
Harald Welte3ab88002018-01-26 22:37:25 +01001588/* Test MO Call with no response to RAN-side CRCX */
Harald Weltee13cfb22019-04-23 16:52:02 +02001589friend function f_tc_mo_crcx_ran_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001590 f_init_handler(pars);
Harald Welte3ab88002018-01-26 22:37:25 +01001591 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1592 var MNCC_PDU mncc;
1593 var MgcpCommand mgcp_cmd;
1594
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001595 f_perform_lu();
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001596 /* Do not respond to the second CRCX */
1597 cpars.mgw_conn_2.resp := 0;
1598 f_mo_call_establish(cpars);
Harald Welte3ab88002018-01-26 22:37:25 +01001599
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001600 var default ccrel := activate(as_optional_cc_rel(cpars));
Harald Welte3ab88002018-01-26 22:37:25 +01001601
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001602 f_expect_clear(60.0);
Harald Welte3ab88002018-01-26 22:37:25 +01001603
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001604 deactivate(ccrel);
Harald Welte3ab88002018-01-26 22:37:25 +01001605}
1606testcase TC_mo_crcx_ran_timeout() runs on MTC_CT {
1607 var BSC_ConnHdlr vc_conn;
1608 f_init();
1609
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001610 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_timeout), 29);
Harald Welte3ab88002018-01-26 22:37:25 +01001611 vc_conn.done;
1612}
1613
Harald Weltee13cfb22019-04-23 16:52:02 +02001614
Harald Welte0cc82d92018-01-26 22:52:34 +01001615/* Test MO Call with reject to RAN-side CRCX */
Harald Weltee13cfb22019-04-23 16:52:02 +02001616friend function f_tc_mo_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001617 f_init_handler(pars);
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001618
Harald Welte0cc82d92018-01-26 22:52:34 +01001619 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001620
1621 /* Respond with error for the first CRCX */
1622 cpars.mgw_conn_1.resp := -1;
Harald Welte0cc82d92018-01-26 22:52:34 +01001623
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001624 f_perform_lu();
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001625 f_mo_call_establish(cpars);
Harald Welte0cc82d92018-01-26 22:52:34 +01001626
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001627 var default ccrel := activate(as_optional_cc_rel(cpars));
1628 f_expect_clear(60.0);
1629 deactivate(ccrel);
Harald Welte0cc82d92018-01-26 22:52:34 +01001630}
1631testcase TC_mo_crcx_ran_reject() runs on MTC_CT {
1632 var BSC_ConnHdlr vc_conn;
1633 f_init();
1634
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001635 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_reject), 30);
Harald Welte0cc82d92018-01-26 22:52:34 +01001636 vc_conn.done;
1637}
1638
Harald Welte3ab88002018-01-26 22:37:25 +01001639
Harald Welte812f7a42018-01-27 00:49:18 +01001640/* helper function to start a MT call: MNCC SETUP; Paging; DChan est.; DTAP SETUP */
1641private function f_mt_call_start(inout CallParameters cpars) runs on BSC_ConnHdlr {
1642 var MNCC_PDU mncc;
1643 var MgcpCommand mgcp_cmd;
Harald Welte812f7a42018-01-27 00:49:18 +01001644
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001645 f_perform_lu();
Vadim Yanitskiyae747742020-01-10 00:23:10 +01001646 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Harald Welte812f7a42018-01-27 00:49:18 +01001647
1648 /* Allocate call reference and send SETUP via MNCC to MSC */
1649 cpars.mncc_callref := f_rnd_int(2147483648);
1650 MNCC.send(ts_MNCC_SETUP_req(cpars.mncc_callref, hex2str(g_pars.msisdn),
1651 hex2str(cpars.called_party), hex2str(g_pars.imsi)));
1652
1653 /* MSC->BSC: expect PAGING from MSC */
Harald Weltee035e3e2019-04-21 17:32:05 +02001654 f_expect_paging();
1655
Harald Welte812f7a42018-01-27 00:49:18 +01001656 /* MS -> MSC: PAGING RESPONSE */
Harald Welteb9e86fa2018-04-09 18:18:31 +02001657 f_establish_fully(EST_TYPE_PAG_RESP);
Harald Welte812f7a42018-01-27 00:49:18 +01001658
1659 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1660
1661 /* MSC->MS: SETUP */
1662 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party)));
1663}
1664
1665/* Test MT Call */
Harald Weltee13cfb22019-04-23 16:52:02 +02001666friend function f_tc_mt_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001667 f_init_handler(pars);
Harald Welte812f7a42018-01-27 00:49:18 +01001668 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1669 var MNCC_PDU mncc;
1670 var MgcpCommand mgcp_cmd;
1671
1672 f_mt_call_start(cpars);
1673
1674 /* MS->MSC: CALL CONFIRMED */
1675 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1676
1677 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1678
1679 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1680 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001681
1682 /* Detect if the received CRCX is a wildcarded CRCX request. If yes,
1683 * set an endpoint name that fits the pattern. If not, just use the
1684 * endpoint name from the request */
1685 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
1686 cpars.mgcp_ep := "rtpbridge/1@mgw";
1687 } else {
1688 cpars.mgcp_ep := mgcp_cmd.line.ep;
1689 }
1690
Harald Welte812f7a42018-01-27 00:49:18 +01001691 /* Respond to CRCX with error */
1692 var MgcpResponse mgcp_rsp := {
1693 line := {
1694 code := "542",
1695 trans_id := mgcp_cmd.line.trans_id,
1696 string := "FORCED_FAIL"
1697 },
Harald Welte812f7a42018-01-27 00:49:18 +01001698 sdp := omit
1699 }
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001700 var MgcpParameter mgcp_rsp_param := {
1701 code := "Z",
1702 val := cpars.mgcp_ep
1703 };
1704 mgcp_rsp.params[0] := mgcp_rsp_param;
Harald Welte812f7a42018-01-27 00:49:18 +01001705 MGCP.send(mgcp_rsp);
1706
1707 timer T := 30.0;
1708 T.start;
1709 alt {
Daniel Willmannafce8662018-07-06 23:11:32 +02001710 [] T.timeout {
1711 setverdict(fail, "Timeout waiting for channel release");
1712 mtc.stop;
1713 }
Harald Welte812f7a42018-01-27 00:49:18 +01001714 [] MNCC.receive { repeat; }
1715 [] GSUP.receive { repeat; }
1716 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1717 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1718 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1719 repeat;
1720 }
1721 [] MGCP.receive { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001722 [] as_clear_cmd_compl_disc();
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001723 [] as_optional_cc_rel(cpars);
Harald Welte812f7a42018-01-27 00:49:18 +01001724 }
1725}
1726testcase TC_mt_crcx_ran_reject() runs on MTC_CT {
1727 var BSC_ConnHdlr vc_conn;
1728 f_init();
1729
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001730 vc_conn := f_start_handler(refers(f_tc_mt_crcx_ran_reject), 31);
Harald Welte812f7a42018-01-27 00:49:18 +01001731 vc_conn.done;
1732}
1733
1734
Harald Weltee13cfb22019-04-23 16:52:02 +02001735
Harald Welte812f7a42018-01-27 00:49:18 +01001736/* Test MT Call T310 timer */
Harald Weltee13cfb22019-04-23 16:52:02 +02001737friend function f_tc_mt_t310(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Welte812f7a42018-01-27 00:49:18 +01001738 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
Harald Welte812f7a42018-01-27 00:49:18 +01001739 var MgcpCommand mgcp_cmd;
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001740 var PDU_BSSAP bssap;
1741 timer T310;
Harald Welte812f7a42018-01-27 00:49:18 +01001742
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001743 f_init_handler(pars);
1744
1745 /* Initiate a MT call, establish connection */
Harald Welte812f7a42018-01-27 00:49:18 +01001746 f_mt_call_start(cpars);
1747
1748 /* MS->MSC: CALL CONFIRMED */
1749 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1750 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1751
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001752 /* NOTE: MSC is expected to start T310 here */
Harald Welte812f7a42018-01-27 00:49:18 +01001753
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001754 /* MSC->MGW: CRCX (first) */
1755 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1756 f_handle_crcx(cpars, mgcp_cmd); /* MSC<-MGW: OK */
1757
1758 /* BSC->BSC: BSSMAP ASSIGNMENT REQ */
1759 BSSAP.receive(tr_BSSMAP_AssignmentReq(omit, ?)) -> value bssap;
1760 BSSAP.send(ts_BSSMAP_AssignmentComplete(omit,
1761 aoip := f_ts_BSSMAP_IE_AoIP_TLA(cpars.bss_rtp_ip, cpars.bss_rtp_port),
1762 speechCodec := ts_BSSMAP_IE_SpeechCodec({ ts_CodecFR })));
1763
1764 /* MSC->MGW: MDCX */
1765 MGCP.receive(tr_MDCX) -> value mgcp_cmd;
1766 MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgw_conn_1.mgcp_connection_id,
1767 sdp := omit));
1768
1769 /* MSC->MGW: CRCX (second) */
1770 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1771 f_handle_crcx(cpars, mgcp_cmd); /* MSC<-MGW: OK */
1772 MNCC.receive(tr_MNCC_RTP_CREATE(cpars.mncc_callref));
1773
1774 /* Reschedule the guard timeout */
1775 g_Tguard.start(30.0 + 10.0);
1776
1777 /* NOTE: the BSC is expected to respond with CC ALERTING at this state, so
1778 * the MSC would stop T310. However, the idea is to verify T310 expiration
1779 * here, so grab some popcorn and wait for MNCC DISC.ind. */
1780 T310.start(30.0 + 2.0);
Harald Welte812f7a42018-01-27 00:49:18 +01001781 alt {
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001782 [] T310.timeout {
1783 setverdict(fail, "Timeout waiting for MNCC DISC.ind due to T310");
Daniel Willmannafce8662018-07-06 23:11:32 +02001784 mtc.stop;
1785 }
Harald Welte812f7a42018-01-27 00:49:18 +01001786 [] MNCC.receive(tr_MNCC_DISC_ind(cpars.mncc_callref)) {
1787 MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(23))));
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001788 log("Rx MNCC DISC.ind, T310.read yelds ", T310.read);
1789 setverdict(pass);
Harald Welte812f7a42018-01-27 00:49:18 +01001790 }
1791 }
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001792
Harald Welte812f7a42018-01-27 00:49:18 +01001793 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));
1794 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001795 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id, '1'B)));
Harald Welte812f7a42018-01-27 00:49:18 +01001796
1797 alt {
Harald Welte812f7a42018-01-27 00:49:18 +01001798 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1799 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01001800 // FIXME: f_create_mgcp_delete_ep(cpars.mgcp_ep);
Harald Welte812f7a42018-01-27 00:49:18 +01001801 repeat;
1802 }
Harald Welte5946b332018-03-18 23:32:21 +01001803 [] as_clear_cmd_compl_disc();
Harald Welte812f7a42018-01-27 00:49:18 +01001804 }
1805}
1806testcase TC_mt_t310() runs on MTC_CT {
1807 var BSC_ConnHdlr vc_conn;
1808 f_init();
1809
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001810 vc_conn := f_start_handler(refers(f_tc_mt_t310), 32);
Harald Welte812f7a42018-01-27 00:49:18 +01001811 vc_conn.done;
1812}
1813
Harald Weltee13cfb22019-04-23 16:52:02 +02001814
Harald Welte167458a2018-01-27 15:58:16 +01001815/* Perform successful LU + MO call, then GSUP LocationCancel. Subscriber must be denied CM SERV */
Harald Weltee13cfb22019-04-23 16:52:02 +02001816friend function f_tc_gsup_cancel(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Welte167458a2018-01-27 15:58:16 +01001817 f_init_handler(pars);
1818 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Harald Welte167458a2018-01-27 15:58:16 +01001819
1820 /* Location Update to make subscriber known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001821 f_perform_lu();
Harald Welte167458a2018-01-27 15:58:16 +01001822
1823 /* First MO call should succeed */
1824 f_mo_call(cpars);
1825
1826 /* Cancel the subscriber in the VLR */
1827 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1828 alt {
1829 [] GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi)) { }
1830 [] GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi)) {
1831 setverdict(fail, "Received GSUP Location Cancel Error");
Daniel Willmannafce8662018-07-06 23:11:32 +02001832 mtc.stop;
Harald Welte167458a2018-01-27 15:58:16 +01001833 }
1834 }
1835
1836 /* Follow-up transactions should fail */
1837 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1838 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001839 f_cl3_or_initial_ue(l3_info);
Harald Welte167458a2018-01-27 15:58:16 +01001840 alt {
1841 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
1842 [] BSSAP.receive {
1843 setverdict(fail, "Received unexpected BSSAP instead of CM SERV REJ");
Daniel Willmannafce8662018-07-06 23:11:32 +02001844 mtc.stop;
Harald Welte167458a2018-01-27 15:58:16 +01001845 }
1846 }
Neels Hofmeyr0f7429a2019-03-07 22:28:41 +01001847
1848 f_expect_clear();
Harald Welte167458a2018-01-27 15:58:16 +01001849 setverdict(pass);
1850}
1851testcase TC_gsup_cancel() runs on MTC_CT {
1852 var BSC_ConnHdlr vc_conn;
1853 f_init();
1854
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001855 vc_conn := f_start_handler(refers(f_tc_gsup_cancel), 33, verify_cell_id := false);
Harald Welte167458a2018-01-27 15:58:16 +01001856 vc_conn.done;
1857}
1858
Harald Weltee13cfb22019-04-23 16:52:02 +02001859
Harald Welte9de84792018-01-28 01:06:35 +01001860/* A5/1 only permitted on network side, and MS capable to do it */
1861private function f_tc_lu_imsi_auth_tmsi_encr_1_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1862 pars.net.expect_auth := true;
1863 pars.net.expect_ciph := true;
1864 pars.net.kc_support := '02'O; /* A5/1 only */
1865 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001866 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001867}
1868testcase TC_lu_imsi_auth_tmsi_encr_1_13() runs on MTC_CT {
1869 var BSC_ConnHdlr vc_conn;
1870 f_init();
1871 f_vty_config(MSCVTY, "network", "authentication required");
1872 f_vty_config(MSCVTY, "network", "encryption a5 1");
1873
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001874 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_1_13), 34);
Harald Welte9de84792018-01-28 01:06:35 +01001875 vc_conn.done;
1876}
1877
1878/* A5/3 only permitted on network side, and MS capable to do it */
1879private function f_tc_lu_imsi_auth_tmsi_encr_3_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1880 pars.net.expect_auth := true;
1881 pars.net.expect_ciph := true;
1882 pars.net.kc_support := '08'O; /* A5/3 only */
1883 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001884 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001885}
1886testcase TC_lu_imsi_auth_tmsi_encr_3_13() runs on MTC_CT {
1887 var BSC_ConnHdlr vc_conn;
1888 f_init();
1889 f_vty_config(MSCVTY, "network", "authentication required");
1890 f_vty_config(MSCVTY, "network", "encryption a5 3");
1891
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001892 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_13), 35);
Harald Welte9de84792018-01-28 01:06:35 +01001893 vc_conn.done;
1894}
1895
1896/* A5/3 only permitted on network side, and MS with only A5/1 support */
1897private function f_tc_lu_imsi_auth_tmsi_encr_3_1(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1898 pars.net.expect_auth := true;
1899 pars.net.expect_ciph := true;
1900 pars.net.kc_support := '08'O; /* A5/3 only */
1901 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1902 f_init_handler(pars, 15.0);
1903
1904 /* cannot use f_perform_lu() as we expect a reject */
1905 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1906 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +02001907 f_cl3_or_initial_ue(l3_lu);
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001908 if (pars.send_early_cm) {
1909 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1910 } else {
1911 pars.cm1.esind := '0'B;
1912 }
Harald Welte9de84792018-01-28 01:06:35 +01001913 f_mm_auth();
1914 alt {
Daniel Willmann52918e52018-09-20 14:39:09 +02001915 [] BSSAP.receive(tr_BSSMAP_ClassmarkReq) {
1916 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1917 repeat;
1918 }
Harald Welte5946b332018-03-18 23:32:21 +01001919 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1920 f_expect_clear();
1921 }
Harald Welte9de84792018-01-28 01:06:35 +01001922 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1923 setverdict(fail, "CipherModeCommand despite no A5 intersection");
Daniel Willmannafce8662018-07-06 23:11:32 +02001924 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001925 }
1926 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001927 setverdict(fail, "Unknown/unexpected BSSAP received");
Daniel Willmannafce8662018-07-06 23:11:32 +02001928 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001929 }
1930 }
1931 setverdict(pass);
1932}
1933testcase TC_lu_imsi_auth_tmsi_encr_3_1() runs on MTC_CT {
1934 var BSC_ConnHdlr vc_conn;
1935 f_init();
1936 f_vty_config(MSCVTY, "network", "authentication required");
1937 f_vty_config(MSCVTY, "network", "encryption a5 3");
1938
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001939 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 +01001940 vc_conn.done;
1941}
1942testcase TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() runs on MTC_CT {
1943 var BSC_ConnHdlrPars pars;
1944 var BSC_ConnHdlr vc_conn;
1945 f_init();
1946 f_vty_config(MSCVTY, "network", "authentication required");
1947 f_vty_config(MSCVTY, "network", "encryption a5 3");
1948
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001949 pars := f_init_pars(361, verify_cell_id := false);
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001950 pars.send_early_cm := false;
1951 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 +01001952 vc_conn.done;
1953}
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01001954testcase TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() runs on MTC_CT {
1955 var BSC_ConnHdlr vc_conn;
1956 f_init();
1957 f_vty_config(MSCVTY, "network", "authentication required");
1958 f_vty_config(MSCVTY, "network", "encryption a5 3");
1959
1960 /* Make sure the MSC category is on DEBUG level to trigger the log
1961 * message that is reported in OS#2947 to trigger the segfault */
1962 f_vty_config(MSCVTY, "log stderr", "logging level msc debug");
1963
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001964 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 +01001965 vc_conn.done;
1966}
Harald Welte9de84792018-01-28 01:06:35 +01001967
1968/* A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
1969private function f_tc_lu_imsi_auth_tmsi_encr_13_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1970 pars.net.expect_auth := true;
1971 pars.net.expect_ciph := true;
1972 pars.net.kc_support := '0A'O; /* A5/1 + A5/3 */
1973 pars.cm1.a5_1 := '1'B;
1974 pars.cm2.a5_1 := '1'B;
1975 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1976 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
1977 f_init_handler(pars, 15.0);
1978
1979 /* cannot use f_perform_lu() as we expect a reject */
1980 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1981 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +02001982 f_cl3_or_initial_ue(l3_lu);
Harald Welte9de84792018-01-28 01:06:35 +01001983 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1984 f_mm_auth();
1985 alt {
Harald Welte5946b332018-03-18 23:32:21 +01001986 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1987 f_expect_clear();
1988 }
Harald Welte9de84792018-01-28 01:06:35 +01001989 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1990 setverdict(fail, "CipherModeCommand despite no A5 intersection");
Daniel Willmannafce8662018-07-06 23:11:32 +02001991 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001992 }
1993 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001994 setverdict(fail, "Unknown/unexpected BSSAP received");
Daniel Willmannafce8662018-07-06 23:11:32 +02001995 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001996 }
1997 }
1998 setverdict(pass);
1999}
2000testcase TC_lu_imsi_auth_tmsi_encr_13_2() 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 1 3");
2005
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02002006 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 +01002007 vc_conn.done;
2008}
2009
2010/* A5/0 + A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
2011private function f_tc_lu_imsi_auth_tmsi_encr_013_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2012 pars.net.expect_auth := true;
2013 pars.net.expect_ciph := true;
2014 pars.net.kc_support := '0B'O; /* A5/1 + A5/3 */
2015 pars.cm1.a5_1 := '1'B;
2016 pars.cm2.a5_1 := '1'B;
2017 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
2018 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
2019 f_init_handler(pars, 15.0);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01002020 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01002021}
2022testcase TC_lu_imsi_auth_tmsi_encr_013_2() runs on MTC_CT {
2023 var BSC_ConnHdlr vc_conn;
2024 f_init();
2025 f_vty_config(MSCVTY, "network", "authentication required");
2026 f_vty_config(MSCVTY, "network", "encryption a5 0 1 3");
2027
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01002028 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_013_2), 38);
Harald Welte9de84792018-01-28 01:06:35 +01002029 vc_conn.done;
2030}
2031
Harald Welte33ec09b2018-02-10 15:34:46 +01002032/* LU followed by MT call (including paging) */
Neels Hofmeyr8fe8a902019-11-03 05:51:03 +01002033friend function f_tc_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Welte33ec09b2018-02-10 15:34:46 +01002034 f_init_handler(pars);
Stefan Sperling26d57be2018-11-12 17:03:26 +01002035 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Pau Espin Pedrola65697d2019-05-21 12:54:39 +02002036 cpars.use_osmux := pars.use_osmux;
Harald Welte33ec09b2018-02-10 15:34:46 +01002037
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01002038 f_perform_lu();
Harald Welte33ec09b2018-02-10 15:34:46 +01002039 f_mt_call(cpars);
2040}
2041testcase TC_lu_and_mt_call() runs on MTC_CT {
2042 var BSC_ConnHdlr vc_conn;
2043 f_init();
2044
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01002045 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call), 39);
Harald Welte33ec09b2018-02-10 15:34:46 +01002046 vc_conn.done;
2047}
2048
Pau Espin Pedrola65697d2019-05-21 12:54:39 +02002049testcase TC_lu_and_mt_call_osmux() runs on MTC_CT {
2050 var BSC_ConnHdlr vc_conn;
2051 f_init(1, false, true, true);
Pau Espin Pedrola65697d2019-05-21 12:54:39 +02002052
2053 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call), 39, 0, true, true);
2054 vc_conn.done;
2055}
2056
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02002057/* LU followed by MT call (including paging) */
2058friend function f_tc_lu_and_mt_call_ipv6(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2059 f_init_handler(pars);
2060 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
2061 cpars.mgw_conn_1.mgw_rtp_ip := "::1";
2062 cpars.mgw_conn_2.mgw_rtp_ip := "::2";
2063 cpars.bss_rtp_ip := "::3";
Pau Espin Pedrol563b3d02020-09-09 20:19:52 +02002064 cpars.mncc_rtp_ip := "::9";
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02002065 f_perform_lu();
2066 f_mt_call(cpars);
2067}
2068testcase TC_lu_and_mt_call_ipv6() runs on MTC_CT {
2069 var BSC_ConnHdlr vc_conn;
2070 f_init();
2071
2072 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call_ipv6), 39);
2073 vc_conn.done;
2074}
2075
Neels Hofmeyrb58d9742019-11-27 18:44:54 +01002076/* MT call while already Paging */
2077friend function f_tc_lu_and_mt_call_already_paging(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2078 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
2079 var SmsParameters spars := valueof(t_SmsPars);
2080 var OCT4 tmsi;
2081
2082 f_init_handler(pars);
2083
2084 /* Perform location update */
2085 f_perform_lu();
2086
2087 /* register an 'expect' for given IMSI (+TMSI) */
2088 if (isvalue(g_pars.tmsi)) {
2089 tmsi := g_pars.tmsi;
2090 } else {
2091 tmsi := 'FFFFFFFF'O;
2092 }
2093 f_ran_register_imsi(g_pars.imsi, tmsi);
2094
2095 log("start Paging by an SMS");
2096 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
2097
2098 /* MSC->BSC: expect PAGING from MSC */
2099 f_expect_paging();
2100
2101 log("MNCC signals MT call, before Paging Response");
2102 f_mt_call_initate(cpars);
2103 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
2104
2105 f_sleep(0.5);
2106 log("phone answers Paging, expecting both SMS and MT call to be established");
2107 f_establish_fully(EST_TYPE_PAG_RESP);
2108 spars.tp.ud := 'C8329BFD064D9B53'O;
2109 interleave {
2110 [] BSSAP.receive(f_mt_sms_deliver_pdu(spars)) {
2111 log("Got SMS-DELIVER");
2112 };
2113 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party))) {
2114 log("Got CC Setup");
2115 };
2116 }
2117 setverdict(pass);
2118 log("success, tear down");
2119 var default ccrel := activate(as_optional_cc_rel(cpars));
2120 if (g_pars.ran_is_geran) {
2121 BSSAP.send(ts_BSSMAP_ClearRequest(0));
2122 } else {
2123 BSSAP.send(ts_RANAP_IuReleaseRequest(ts_RanapCause_om_intervention));
2124 }
2125 f_expect_clear();
2126 deactivate(ccrel);
2127 f_vty_sms_clear(hex2str(g_pars.imsi));
2128}
2129testcase TC_lu_and_mt_call_already_paging() runs on MTC_CT {
2130 var BSC_ConnHdlrPars pars;
2131 var BSC_ConnHdlr vc_conn;
2132 f_init();
2133 pars := f_init_pars(391);
2134 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_call_already_paging), pars);
2135 vc_conn.done;
2136}
2137
Daniel Willmann8b084372018-02-04 13:35:26 +01002138/* Test MO Call SETUP with DTMF */
2139private function f_tc_mo_setup_dtmf_dup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2140 f_init_handler(pars);
2141 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Daniel Willmann8b084372018-02-04 13:35:26 +01002142
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01002143 f_perform_lu();
Daniel Willmann8b084372018-02-04 13:35:26 +01002144 f_mo_seq_dtmf_dup(cpars);
2145}
2146testcase TC_mo_setup_and_dtmf_dup() runs on MTC_CT {
2147 var BSC_ConnHdlr vc_conn;
2148 f_init();
2149
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01002150 vc_conn := f_start_handler(refers(f_tc_mo_setup_dtmf_dup), 39);
Daniel Willmann8b084372018-02-04 13:35:26 +01002151 vc_conn.done;
2152}
Harald Welte9de84792018-01-28 01:06:35 +01002153
Philipp Maier328d1662018-03-07 10:40:27 +01002154testcase TC_cr_before_reset() runs on MTC_CT {
2155 timer T := 4.0;
2156 var boolean reset_ack_seen := false;
2157 f_init_bssap_direct();
2158
Harald Welte3ca0ce12019-04-23 17:18:48 +02002159 f_ran_adapter_start(g_bssap[0]);
Daniel Willmann42d1d5b2018-08-07 15:18:41 +02002160
Daniel Willmanne8018962018-08-21 14:18:00 +02002161 f_sleep(3.0);
2162
Philipp Maier328d1662018-03-07 10:40:27 +01002163 /* Make a blind connection attemt, to trigger the deadlock condition */
Philipp Maier75932982018-03-27 14:52:35 +02002164 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 +01002165
2166 /* Send a BSSMAP reset */
Philipp Maier75932982018-03-27 14:52:35 +02002167 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 +01002168 T.start
2169 alt {
2170 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_ResetAck)) {
2171 reset_ack_seen := true;
2172 repeat;
2173 }
2174
2175 /* Acknowledge MSC sided reset requests */
2176 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) {
Philipp Maier75932982018-03-27 14:52:35 +02002177 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 +01002178 repeat;
2179 }
2180
2181 /* Ignore all other messages (e.g CR from the connection request) */
2182 [] BSSAP_DIRECT.receive { repeat }
2183
2184 /* If we got no BSSMAP RESET ACK back, then the MSC entered the
2185 * deadlock situation. The MSC is then unable to respond to any
2186 * further BSSMAP RESET or any other sort of traffic. */
2187 [reset_ack_seen == true] T.timeout { setverdict(pass) }
2188 [reset_ack_seen == false] T.timeout {
2189 setverdict(fail, "no BSSMAP RESET ACK seen!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002190 mtc.stop;
Philipp Maier328d1662018-03-07 10:40:27 +01002191 }
Pau Espin Pedrol7e9178d2019-12-17 17:52:17 +01002192 }
Philipp Maier328d1662018-03-07 10:40:27 +01002193}
Harald Welte9de84792018-01-28 01:06:35 +01002194
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002195/* Test MO Call with no response to RAN-side CRCX or DTAP Release */
Harald Weltee13cfb22019-04-23 16:52:02 +02002196friend function f_tc_mo_release_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002197 f_init_handler(pars);
2198 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
2199 var MNCC_PDU mncc;
2200 var MgcpCommand mgcp_cmd;
2201
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02002202 /* Do not respond to the second CRCX */
2203 cpars.mgw_conn_2.resp := 0;
2204
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002205 f_perform_lu();
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02002206 f_mo_call_establish(cpars);
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002207
Neels Hofmeyrde76f052019-02-26 05:02:46 +01002208 var default ccrel := activate(as_optional_cc_rel(cpars));
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002209
2210 f_expect_clear(60.0);
Neels Hofmeyrde76f052019-02-26 05:02:46 +01002211
2212 deactivate(ccrel);
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002213}
2214testcase TC_mo_release_timeout() runs on MTC_CT {
2215 var BSC_ConnHdlr vc_conn;
2216 f_init();
2217
2218 vc_conn := f_start_handler(refers(f_tc_mo_release_timeout), 40);
2219 vc_conn.done;
2220}
2221
Harald Welte12510c52018-01-26 22:26:24 +01002222
Philipp Maier2a98a732018-03-19 16:06:12 +01002223/* LU followed by MT call (including paging) */
2224private function f_tc_lu_and_mt_call_no_dlcx_resp(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2225 f_init_handler(pars);
Stefan Sperling26d57be2018-11-12 17:03:26 +01002226 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Philipp Maier2a98a732018-03-19 16:06:12 +01002227
2228 /* Intentionally disable the CRCX response */
2229 cpars.mgw_drop_dlcx := true;
2230
2231 /* Perform location update and call */
2232 f_perform_lu();
2233 f_mt_call(cpars);
2234}
2235testcase TC_lu_and_mt_call_no_dlcx_resp() runs on MTC_CT {
2236 var BSC_ConnHdlr vc_conn;
2237 f_init();
2238
2239 /* Perform an almost normal looking locationupdate + mt-call, but do
2240 * not respond to the DLCX at the end of the call */
2241 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call_no_dlcx_resp), 41);
2242 vc_conn.done;
2243
2244 /* Wait a guard period until the MGCP layer in the MSC times out,
2245 * if the MSC is vulnerable to the use-after-free situation that is
2246 * fixed by I78f1b6a9149488a4ad3f120c1e190a83c07d4b89 then it should
2247 * segfault now */
2248 f_sleep(6.0);
2249
2250 /* Run the init procedures once more. If the MSC has crashed, this
2251 * this will fail */
2252 f_init();
2253}
Harald Welte45164da2018-01-24 12:51:27 +01002254
Philipp Maier75932982018-03-27 14:52:35 +02002255/* Two BSSMAP resets from two different BSCs */
2256testcase TC_reset_two() runs on MTC_CT {
2257 var BSC_ConnHdlr vc_conn;
2258 f_init(2);
2259 f_sleep(2.0);
2260 setverdict(pass);
2261}
2262
Harald Weltee13cfb22019-04-23 16:52:02 +02002263/* Two BSSMAP resets from two different BSCs plus one IuCS RANAP Reset */
2264testcase TC_reset_two_1iu() runs on MTC_CT {
2265 var BSC_ConnHdlr vc_conn;
2266 f_init(3);
2267 f_sleep(2.0);
2268 setverdict(pass);
2269}
2270
Harald Weltef640a012018-04-14 17:49:21 +02002271/***********************************************************************
2272 * SMS Testing
2273 ***********************************************************************/
2274
Harald Weltef45efeb2018-04-09 18:19:24 +02002275/* LU followed by MO SMS */
Harald Weltee13cfb22019-04-23 16:52:02 +02002276friend function f_tc_lu_and_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltef45efeb2018-04-09 18:19:24 +02002277 var SmsParameters spars := valueof(t_SmsPars);
2278
2279 f_init_handler(pars);
2280
2281 /* Perform location update and call */
2282 f_perform_lu();
2283
2284 f_establish_fully(EST_TYPE_MO_SMS);
2285
2286 //spars.exp_rp_err := 96; /* invalid mandatory information */
2287 f_mo_sms(spars);
2288
2289 f_expect_clear();
2290}
2291testcase TC_lu_and_mo_sms() runs on MTC_CT {
2292 var BSC_ConnHdlr vc_conn;
2293 f_init();
2294 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_sms), 42);
2295 vc_conn.done;
2296}
2297
Harald Weltee13cfb22019-04-23 16:52:02 +02002298
Harald Weltef45efeb2018-04-09 18:19:24 +02002299private function f_vty_sms_send(charstring imsi, charstring msisdn, charstring text)
Neels Hofmeyr6aaeccf2019-03-06 15:32:26 +01002300runs on BSC_ConnHdlr {
Harald Weltef45efeb2018-04-09 18:19:24 +02002301 f_vty_transceive(MSCVTY, "subscriber imsi "&imsi&" sms sender msisdn "&msisdn&" send "&text);
2302}
2303
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01002304/* Remove still pending SMS */
2305private function f_vty_sms_clear(charstring imsi)
2306runs on BSC_ConnHdlr {
2307 f_vty_transceive(MSCVTY, "subscriber imsi " & imsi & " sms delete-all");
2308 f_vty_transceive(MSCVTY, "sms-queue clear");
2309}
2310
Harald Weltef45efeb2018-04-09 18:19:24 +02002311/* LU followed by MT SMS */
Harald Weltee13cfb22019-04-23 16:52:02 +02002312friend function f_tc_lu_and_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltef45efeb2018-04-09 18:19:24 +02002313 var SmsParameters spars := valueof(t_SmsPars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002314
2315 f_init_handler(pars);
2316
2317 /* Perform location update and call */
2318 f_perform_lu();
2319
2320 /* register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002321 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Harald Weltef45efeb2018-04-09 18:19:24 +02002322
Neels Hofmeyr6aaeccf2019-03-06 15:32:26 +01002323 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
Harald Weltef45efeb2018-04-09 18:19:24 +02002324
2325 /* MSC->BSC: expect PAGING from MSC */
Harald Weltee035e3e2019-04-21 17:32:05 +02002326 f_expect_paging();
2327
Harald Weltef45efeb2018-04-09 18:19:24 +02002328 /* Establish DTAP / BSSAP / SCCP connection */
2329 f_establish_fully(EST_TYPE_PAG_RESP);
2330
2331 spars.tp.ud := 'C8329BFD064D9B53'O;
2332 f_mt_sms(spars);
2333
2334 f_expect_clear();
2335}
2336testcase TC_lu_and_mt_sms() runs on MTC_CT {
2337 var BSC_ConnHdlrPars pars;
2338 var BSC_ConnHdlr vc_conn;
2339 f_init();
2340 pars := f_init_pars(43);
2341 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_sms), pars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002342 vc_conn.done;
2343}
2344
Neels Hofmeyrb58d9742019-11-27 18:44:54 +01002345/* SMS added while already Paging */
2346friend function f_tc_lu_and_mt_sms_already_paging(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2347 var SmsParameters spars := valueof(t_SmsPars);
2348 var OCT4 tmsi;
2349
2350 f_init_handler(pars);
2351
2352 f_perform_lu();
2353
2354 /* register an 'expect' for given IMSI (+TMSI) */
2355 if (isvalue(g_pars.tmsi)) {
2356 tmsi := g_pars.tmsi;
2357 } else {
2358 tmsi := 'FFFFFFFF'O;
2359 }
2360 f_ran_register_imsi(g_pars.imsi, tmsi);
2361
2362 log("first SMS");
2363 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
2364
2365 /* MSC->BSC: expect PAGING from MSC */
2366 f_expect_paging();
2367
2368 log("second SMS");
2369 /* Now osmo-msc is in state "Paging pending", make sure that another SMS to be sent at this time just joins in
2370 * with the pending paging. Another SMS: */
2371 f_vty_sms_send(hex2str(pars.imsi), "2342", "Another SMS");
2372
2373 /* Establish DTAP / BSSAP / SCCP connection */
2374 f_establish_fully(EST_TYPE_PAG_RESP);
2375
2376 spars.tp.ud := 'C8329BFD064D9B53'O;
2377 f_mt_sms(spars);
2378
2379 spars.tp.ud := '41F79B8E2ECB41D3E614'O;
2380 f_mt_sms(spars);
2381
2382 f_expect_clear();
2383}
2384testcase TC_lu_and_mt_sms_already_paging() runs on MTC_CT {
2385 var BSC_ConnHdlrPars pars;
2386 var BSC_ConnHdlr vc_conn;
2387 f_init();
2388 pars := f_init_pars(44);
2389 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_sms_already_paging), pars);
2390 vc_conn.done;
2391}
Harald Weltee13cfb22019-04-23 16:52:02 +02002392
Philipp Maier3983e702018-11-22 19:01:33 +01002393/* Paging for MT SMS but no response */
Harald Weltee13cfb22019-04-23 16:52:02 +02002394friend 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 +01002395 var SmsParameters spars := valueof(t_SmsPars);
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002396
Philipp Maier3983e702018-11-22 19:01:33 +01002397 f_init_handler(pars, 150.0);
2398
2399 /* Perform location update */
2400 f_perform_lu();
2401
2402 /* register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002403 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Philipp Maier3983e702018-11-22 19:01:33 +01002404
Neels Hofmeyr6aaeccf2019-03-06 15:32:26 +01002405 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
2406
Neels Hofmeyr16237742019-03-06 15:34:01 +01002407 /* Expect the MSC to page exactly once */
Harald Weltee13cfb22019-04-23 16:52:02 +02002408 f_expect_paging();
Philipp Maier3983e702018-11-22 19:01:33 +01002409
2410 /* Wait some time to make sure the MSC is not delivering any further
2411 * paging messages or anything else that could be unexpected. */
2412 timer T := 20.0;
2413 T.start
2414 alt {
Vadim Yanitskiyda774592020-01-15 10:33:47 +07002415 [pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
2416 setverdict(fail, "paging seems not to stop!");
2417 mtc.stop;
Philipp Maier3983e702018-11-22 19:01:33 +01002418 }
Vadim Yanitskiyda774592020-01-15 10:33:47 +07002419 [not pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
2420 setverdict(fail, "paging seems not to stop!");
2421 mtc.stop;
Harald Weltee13cfb22019-04-23 16:52:02 +02002422 }
Vadim Yanitskiyda774592020-01-15 10:33:47 +07002423 [] BSSAP.receive {
2424 setverdict(fail, "unexpected BSSAP message received");
2425 self.stop;
Philipp Maier3983e702018-11-22 19:01:33 +01002426 }
Vadim Yanitskiyda774592020-01-15 10:33:47 +07002427 [] T.timeout {
2428 setverdict(pass);
Philipp Maier3983e702018-11-22 19:01:33 +01002429 }
2430 }
2431
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01002432 f_vty_sms_clear(hex2str(g_pars.imsi));
2433
Philipp Maier3983e702018-11-22 19:01:33 +01002434 setverdict(pass);
2435}
2436testcase TC_lu_and_mt_sms_paging_and_nothing() runs on MTC_CT {
2437 var BSC_ConnHdlrPars pars;
2438 var BSC_ConnHdlr vc_conn;
2439 f_init();
Philipp Maiera99ad262019-01-22 15:35:42 +01002440 pars := f_init_pars(1843);
Philipp Maier3983e702018-11-22 19:01:33 +01002441 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 +01002442 vc_conn.done;
2443}
2444
Alexander Couzensfc02f242019-09-12 03:43:18 +02002445/* LU followed by MT SMS with repeated paging */
2446friend function f_tc_lu_and_mt_sms_paging_repeated(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2447 var SmsParameters spars := valueof(t_SmsPars);
Alexander Couzensfc02f242019-09-12 03:43:18 +02002448
2449 f_init_handler(pars);
2450
2451 /* Perform location update and call */
2452 f_perform_lu();
2453
2454 /* register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002455 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Alexander Couzensfc02f242019-09-12 03:43:18 +02002456
2457 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
2458
Neels Hofmeyrc3accec2019-11-28 01:09:47 +01002459 log("Expecting first Paging");
Alexander Couzensfc02f242019-09-12 03:43:18 +02002460 /* MSC->BSC: expect PAGING from MSC */
2461 f_expect_paging();
2462
Neels Hofmeyrc3accec2019-11-28 01:09:47 +01002463 if (g_pars.ran_is_geran) {
2464 log("GERAN: expect no further Paging");
2465 } else {
2466 log("UTRAN: expect more Paging");
2467 }
2468
2469 timer T := 5.0;
2470 T.start;
2471 alt {
2472 [g_pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
2473 setverdict(fail, "GERAN should not repeat Paging, but received a second Paging");
2474 mtc.stop;
2475 }
2476 [not g_pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
2477 log("UTRAN: second Paging received, as expected");
2478 setverdict(pass);
2479 }
2480 [] T.timeout {
2481 if (g_pars.ran_is_geran) {
2482 log("GERAN: No further Paging received, as expected");
2483 setverdict(pass);
2484 } else {
2485 setverdict(fail, "UTRAN: Expected a second Paging");
2486 mtc.stop;
2487 }
2488 }
2489 }
Alexander Couzensfc02f242019-09-12 03:43:18 +02002490
2491 /* Establish DTAP / BSSAP / SCCP connection */
2492 f_establish_fully(EST_TYPE_PAG_RESP);
2493
2494 spars.tp.ud := 'C8329BFD064D9B53'O;
2495 f_mt_sms(spars);
2496
2497 f_expect_clear();
2498}
2499testcase TC_lu_and_mt_sms_paging_repeated() runs on MTC_CT {
2500 var BSC_ConnHdlrPars pars;
2501 var BSC_ConnHdlr vc_conn;
2502 f_init();
2503 pars := f_init_pars(1844);
2504 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_sms_paging_repeated), pars);
2505 vc_conn.done;
2506}
Harald Weltee13cfb22019-04-23 16:52:02 +02002507
Harald Weltef640a012018-04-14 17:49:21 +02002508/* mobile originated SMS from MS/BTS/BSC side to SMPP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002509friend function f_tc_smpp_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltef640a012018-04-14 17:49:21 +02002510 var SmsParameters spars := valueof(t_SmsPars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002511
Harald Weltef640a012018-04-14 17:49:21 +02002512 f_init_handler(pars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002513
Harald Weltef640a012018-04-14 17:49:21 +02002514 /* Perform location update so IMSI is known + registered in MSC/VLR */
2515 f_perform_lu();
Harald Weltef640a012018-04-14 17:49:21 +02002516
Vadim Yanitskiy2d3f8462020-01-15 11:44:12 +07002517 /* MS/UE submits a MO SMS */
2518 f_establish_fully(EST_TYPE_MO_SMS);
2519 f_mo_sms_submit(spars);
Harald Weltef640a012018-04-14 17:49:21 +02002520
2521 var SMPP_PDU smpp;
2522 var template SMPP_PDU tr_smpp := tr_SMPP(c_SMPP_command_id_deliver_sm, ESME_ROK);
2523 tr_smpp.body.deliver_sm := {
2524 service_type := "CMT",
2525 source_addr_ton := network_specific,
2526 source_addr_npi := isdn,
2527 source_addr := hex2str(pars.msisdn),
2528 dest_addr_ton := f_sm_ton_from_gsm(spars.tp.da.tP_DA_NoPad.tP_TypeOfNumber),
2529 dest_addr_npi := f_sm_npi_from_gsm(spars.tp.da.tP_DA_NoPad.tP_NumberingPlanID),
2530 destination_addr := hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue),
2531 esm_class := '00000001'B,
2532 protocol_id := 0,
2533 priority_flag := 0,
2534 schedule_delivery_time := "",
2535 replace_if_present := 0,
2536 data_coding := '00000001'B,
2537 sm_default_msg_id := 0,
2538 sm_length := ?,
2539 short_message := spars.tp.ud,
2540 opt_pars := {
2541 {
2542 tag := user_message_reference,
2543 len := 2,
2544 opt_value := {
2545 int2_val := oct2int(spars.tp.msg_ref)
2546 }
2547 }
2548 }
2549 };
2550 alt {
2551 [] SMPP.receive(tr_smpp) -> value smpp {
2552 SMPP.send(ts_SMPP_DELIVER_SM_resp(ESME_ROK, smpp.header.seq_num));
2553 }
2554 [] SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK)) { repeat; }
2555 }
2556
Vadim Yanitskiy2d3f8462020-01-15 11:44:12 +07002557 /* MSC terminates the SMS transaction with RP-ACK */
2558 f_mo_sms_wait_rp_ack(spars);
2559
Harald Weltef640a012018-04-14 17:49:21 +02002560 f_expect_clear();
2561}
2562testcase TC_smpp_mo_sms() runs on MTC_CT {
2563 var BSC_ConnHdlr vc_conn;
2564 f_init();
2565 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "default-route");
2566 vc_conn := f_start_handler(refers(f_tc_smpp_mo_sms), 44);
2567 vc_conn.done;
2568 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "no default-route");
2569}
2570
Vadim Yanitskiy33820762020-01-15 11:26:07 +07002571/* Test case for OS#4351: make sure that RP-ERROR from ESME is properly sent to the MS/UE */
2572friend function f_tc_smpp_mo_sms_rp_error(charstring id, BSC_ConnHdlrPars pars)
2573runs on BSC_ConnHdlr {
2574 var SmsParameters spars := valueof(t_SmsPars);
2575 var SMPP_PDU smpp_pdu;
2576 timer T := 3.0;
2577
2578 f_init_handler(pars);
2579
2580 /* Perform location update */
2581 f_perform_lu();
2582
2583 /* MS/UE submits a MO SMS */
2584 f_establish_fully(EST_TYPE_MO_SMS);
2585 f_mo_sms_submit(spars);
2586
2587 /* ESME responds with an error (Invalid Destination Address) */
2588 T.start;
2589 alt {
2590 [] SMPP.receive(tr_SMPP(c_SMPP_command_id_deliver_sm, ESME_ROK, body := ?)) -> value smpp_pdu {
2591 SMPP.send(ts_SMPP_DELIVER_SM_resp(ESME_RINVDSTADR, smpp_pdu.header.seq_num));
2592 }
2593 [] SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK)) { repeat; }
2594 [] T.timeout {
2595 setverdict(fail, "Timeout waiting for SMPP DELIVER-SM");
2596 mtc.stop;
2597 }
2598 }
2599
2600 /* Expect RP-ERROR on BSSAP interface */
2601 spars.exp_rp_err := 1; /* FIXME: GSM411_RP_CAUSE_MO_NUM_UNASSIGNED */
2602 f_mo_sms_wait_rp_ack(spars);
2603
2604 f_expect_clear();
2605}
2606testcase TC_smpp_mo_sms_rp_error() runs on MTC_CT {
2607 var BSC_ConnHdlr vc_conn;
2608 f_init();
2609 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "default-route");
2610 vc_conn := f_start_handler(refers(f_tc_smpp_mo_sms_rp_error), 45);
2611 vc_conn.done;
2612 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "no default-route");
2613}
2614
Harald Weltee13cfb22019-04-23 16:52:02 +02002615
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002616/* Test MO-SMS from MS/BTS/BSC towards HLR (via GSUP) */
Harald Weltee13cfb22019-04-23 16:52:02 +02002617friend function f_tc_gsup_mo_sms(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002618runs on BSC_ConnHdlr {
2619 var SmsParameters spars := valueof(t_SmsPars);
2620 var GSUP_PDU gsup_msg_rx;
2621 var octetstring sm_tpdu;
2622
2623 f_init_handler(pars);
2624
2625 /* We need to inspect GSUP activity */
2626 f_create_gsup_expect(hex2str(g_pars.imsi));
2627
2628 /* Perform location update */
2629 f_perform_lu();
2630
2631 /* Send CM Service Request for SMS */
2632 f_establish_fully(EST_TYPE_MO_SMS);
2633
2634 /* Prepare expected SM-RP-UI (SM TPDU) */
2635 enc_TPDU_RP_DATA_MS_SGSN_fast(
2636 valueof(ts_SMS_SUBMIT(spars.tp.msg_ref,
2637 spars.tp.da, spars.tp.pid, spars.tp.dcs,
2638 spars.tp.udl, spars.tp.ud)),
2639 sm_tpdu);
2640
2641 var template GSUP_PDU mo_forwardSM := tr_GSUP_MO_FORWARD_SM_REQ(
2642 imsi := g_pars.imsi,
2643 sm_rp_mr := spars.rp.msg_ref,
Vadim Yanitskiy04dd5f72019-12-13 15:45:44 +09002644 /* SM-RP-DA: SMSC address */
2645 sm_rp_da := tr_GSUP_SM_RP_DA_SMSC_ADDR(t_GSUP_SM_RP_Addr(
2646 number := spars.rp.smsc_addr.rP_NumberDigits,
2647 npi := spars.rp.smsc_addr.rP_NumberingPlanIdentification,
2648 ton := spars.rp.smsc_addr.rP_TypeOfNumber,
2649 ext := spars.rp.smsc_addr.rP_Ext)),
2650 /* SM-RP-OA: subscriber's MSISDN (filled in by MSC) */
2651 sm_rp_oa := tr_GSUP_SM_RP_OA_MSISDN(t_GSUP_SM_RP_Addr(
2652 number := g_pars.msisdn,
2653 /* NOTE: MSISDN in g_pars lacks this info, assuming defaults */
2654 npi := '0001'B, ton := '001'B, ext := '1'B)),
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002655 /* TODO: can we use decmatch here? */
2656 sm_rp_ui := sm_tpdu
2657 );
2658
2659 /* Submit an SMS on DTAP and expect MO-forwardSM-Req on GSUP */
2660 f_mo_sms_submit(spars);
2661 alt {
2662 [] GSUP.receive(mo_forwardSM) -> value gsup_msg_rx {
Vadim Yanitskiya358dd42020-01-15 10:42:47 +07002663 log("RX MO-forwardSM-Req: ", gsup_msg_rx);
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002664 setverdict(pass);
2665 }
2666 [] GSUP.receive {
2667 log("RX unexpected GSUP message");
2668 setverdict(fail);
2669 mtc.stop;
2670 }
2671 }
2672
2673 /* Trigger RP-ACK by sending MO-forwardSM-Res */
2674 GSUP.send(valueof(ts_GSUP_MO_FORWARD_SM_RES(
2675 imsi := g_pars.imsi,
2676 sm_rp_mr := spars.rp.msg_ref)));
2677 /* Expect RP-ACK on DTAP */
2678 f_mo_sms_wait_rp_ack(spars);
2679
2680 f_expect_clear();
2681}
2682testcase TC_gsup_mo_sms() runs on MTC_CT {
2683 var BSC_ConnHdlr vc_conn;
2684 f_init();
2685 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2686 vc_conn := f_start_handler(refers(f_tc_gsup_mo_sms), 88);
2687 vc_conn.done;
2688 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2689}
2690
Harald Weltee13cfb22019-04-23 16:52:02 +02002691
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07002692/* Test MO-SMMA from MS/BTS/BSC towards HLR (via GSUP) */
Harald Weltee13cfb22019-04-23 16:52:02 +02002693friend function f_tc_gsup_mo_smma(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07002694runs on BSC_ConnHdlr {
2695 var SmsParameters spars := valueof(t_SmsPars);
2696 var GSUP_PDU gsup_msg_rx;
2697
2698 f_init_handler(pars);
2699
2700 /* We need to inspect GSUP activity */
2701 f_create_gsup_expect(hex2str(g_pars.imsi));
2702
2703 /* Perform location update */
2704 f_perform_lu();
2705
2706 /* Send CM Service Request for SMS */
2707 f_establish_fully(EST_TYPE_MO_SMS);
2708
2709 var template GSUP_PDU mo_ReadyForSM := tr_GSUP_MO_READY_FOR_SM_REQ(
2710 imsi := g_pars.imsi,
2711 sm_rp_mr := spars.rp.msg_ref,
2712 sm_alert_rsn := GSUP_SM_ALERT_RSN_TYPE_MEM_AVAIL
2713 );
2714
2715 /* Submit an SMS on DTAP and expect MO-forwardSM-Req on GSUP */
2716 f_mo_smma(spars);
2717 alt {
2718 [] GSUP.receive(mo_ReadyForSM) -> value gsup_msg_rx {
Vadim Yanitskiya358dd42020-01-15 10:42:47 +07002719 log("RX MO-ReadyForSM-Req: ", gsup_msg_rx);
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07002720 setverdict(pass);
2721 }
2722 [] GSUP.receive {
2723 log("RX unexpected GSUP message");
2724 setverdict(fail);
2725 mtc.stop;
2726 }
2727 }
2728
2729 /* Trigger RP-ACK by sending MO-forwardSM-Res */
2730 GSUP.send(valueof(ts_GSUP_MO_READY_FOR_SM_RES(
2731 imsi := g_pars.imsi,
2732 sm_rp_mr := spars.rp.msg_ref)));
2733 /* Expect RP-ACK on DTAP */
2734 f_mo_sms_wait_rp_ack(spars);
2735
2736 f_expect_clear();
2737}
2738testcase TC_gsup_mo_smma() runs on MTC_CT {
2739 var BSC_ConnHdlr vc_conn;
2740 f_init();
2741 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2742 vc_conn := f_start_handler(refers(f_tc_gsup_mo_smma), 89);
2743 vc_conn.done;
2744 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2745}
2746
Harald Weltee13cfb22019-04-23 16:52:02 +02002747
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002748/* Helper for sending MT SMS over GSUP */
2749private function f_gsup_forwardSM_req(SmsParameters spars, OCT1 mms := '00'O)
2750runs on BSC_ConnHdlr {
Vadim Yanitskiya52347c2019-12-12 17:32:33 +09002751 var GSUP_SM_RP_Addr msisdn := valueof(t_GSUP_SM_RP_Addr(g_pars.msisdn));
Vadim Yanitskiy04dd5f72019-12-13 15:45:44 +09002752 var GSUP_SM_RP_Addr smsc := valueof(t_GSUP_SM_RP_Addr(
2753 number := spars.rp.smsc_addr.rP_NumberDigits,
2754 npi := spars.rp.smsc_addr.rP_NumberingPlanIdentification,
2755 ton := spars.rp.smsc_addr.rP_TypeOfNumber,
2756 ext := spars.rp.smsc_addr.rP_Ext));
Vadim Yanitskiya52347c2019-12-12 17:32:33 +09002757
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002758 GSUP.send(ts_GSUP_MT_FORWARD_SM_REQ(
2759 imsi := g_pars.imsi,
2760 /* NOTE: MSC should assign RP-MR itself */
2761 sm_rp_mr := 'FF'O,
Vadim Yanitskiya52347c2019-12-12 17:32:33 +09002762 sm_rp_da := valueof(ts_GSUP_SM_RP_DA_MSISDN(msisdn)),
Vadim Yanitskiy04dd5f72019-12-13 15:45:44 +09002763 sm_rp_oa := valueof(ts_GSUP_SM_RP_OA_SMSC_ADDR(smsc)),
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002764 /* Encoded SMS TPDU (taken from Wireshark)
2765 * FIXME: we should encode spars somehow */
2766 sm_rp_ui := '00068021436500008111328130858200'O,
2767 sm_rp_mms := mms
2768 ));
2769}
2770
2771/* Test successful MT-SMS (RP-ACK) over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002772friend function f_tc_gsup_mt_sms_ack(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002773runs on BSC_ConnHdlr {
2774 var SmsParameters spars := valueof(t_SmsPars);
2775
2776 f_init_handler(pars);
2777
2778 /* We need to inspect GSUP activity */
2779 f_create_gsup_expect(hex2str(g_pars.imsi));
2780
2781 /* Perform location update */
2782 f_perform_lu();
2783
2784 /* Register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002785 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002786
2787 var template GSUP_PDU mt_forwardSM_res := tr_GSUP_MT_FORWARD_SM_RES(
2788 imsi := g_pars.imsi,
2789 /* NOTE: MSC should assign RP-MR itself */
2790 sm_rp_mr := ?
2791 );
2792
2793 /* Submit a MT SMS on GSUP */
2794 f_gsup_forwardSM_req(spars);
2795
2796 /* Expect Paging Request and Establish DTAP / BSSAP / SCCP connection */
Harald Weltee035e3e2019-04-21 17:32:05 +02002797 f_expect_paging();
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002798 f_establish_fully(EST_TYPE_PAG_RESP);
2799
2800 /* Wait for MT SMS on DTAP */
2801 f_mt_sms_expect(spars);
2802
2803 /* Send RP-ACK and expect MT-forwardSM-Res on GSUP */
2804 f_mt_sms_send_rp_ack(spars);
2805 alt {
2806 [] GSUP.receive(mt_forwardSM_res) {
2807 log("RX MT-forwardSM-Res (RP-ACK)");
2808 setverdict(pass);
2809 }
2810 [] GSUP.receive {
2811 log("RX unexpected GSUP message");
2812 setverdict(fail);
2813 mtc.stop;
2814 }
2815 }
2816
2817 f_expect_clear();
2818}
2819testcase TC_gsup_mt_sms_ack() runs on MTC_CT {
2820 var BSC_ConnHdlrPars pars;
2821 var BSC_ConnHdlr vc_conn;
2822 f_init();
2823 pars := f_init_pars(90);
2824 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2825 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_sms_ack), pars);
2826 vc_conn.done;
2827 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2828}
2829
Harald Weltee13cfb22019-04-23 16:52:02 +02002830
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002831/* Test rejected MT-SMS (RP-ERROR) over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002832friend function f_tc_gsup_mt_sms_err(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002833runs on BSC_ConnHdlr {
2834 var SmsParameters spars := valueof(t_SmsPars);
2835 var OCT1 sm_rp_cause := '78'O; /* dummy RP-Cause value */
2836
2837 f_init_handler(pars);
2838
2839 /* We need to inspect GSUP activity */
2840 f_create_gsup_expect(hex2str(g_pars.imsi));
2841
2842 /* Perform location update */
2843 f_perform_lu();
2844
2845 /* Register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002846 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002847
2848 var template GSUP_PDU mt_forwardSM_err := tr_GSUP_MT_FORWARD_SM_ERR(
2849 imsi := g_pars.imsi,
2850 /* NOTE: MSC should assign RP-MR itself */
2851 sm_rp_mr := ?,
2852 sm_rp_cause := sm_rp_cause
2853 );
2854
2855 /* Submit a MT SMS on GSUP */
2856 f_gsup_forwardSM_req(spars);
2857
2858 /* Expect Paging Request and Establish DTAP / BSSAP / SCCP connection */
Harald Weltee035e3e2019-04-21 17:32:05 +02002859 f_expect_paging();
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002860 f_establish_fully(EST_TYPE_PAG_RESP);
2861
2862 /* Wait for MT SMS on DTAP */
2863 f_mt_sms_expect(spars);
2864
2865 /* Send RP-ERROR and expect MT-forwardSM-Err on GSUP */
2866 f_mt_sms_send_rp_error(spars, oct2int(sm_rp_cause));
2867 alt {
2868 [] GSUP.receive(mt_forwardSM_err) {
2869 log("RX MT-forwardSM-Err (RP-ERROR)");
2870 setverdict(pass);
2871 mtc.stop;
2872 }
2873 [] GSUP.receive {
2874 log("RX unexpected GSUP message");
2875 setverdict(fail);
2876 mtc.stop;
2877 }
2878 }
2879
2880 f_expect_clear();
2881}
2882testcase TC_gsup_mt_sms_err() runs on MTC_CT {
2883 var BSC_ConnHdlrPars pars;
2884 var BSC_ConnHdlr vc_conn;
2885 f_init();
2886 pars := f_init_pars(91);
2887 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2888 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_sms_err), pars);
2889 vc_conn.done;
2890 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2891}
2892
Harald Weltee13cfb22019-04-23 16:52:02 +02002893
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002894/* Test SM-RP-MR assignment for MT-SMS over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002895friend function f_tc_gsup_mt_sms_rp_mr(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002896runs on BSC_ConnHdlr {
2897 var SmsParameters spars1 := valueof(t_SmsPars); /* 1st SMS */
2898 var SmsParameters spars2 := valueof(t_SmsPars); /* 2nd SMS */
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 Yanitskiybe1ff4b2019-01-18 15:04:13 +07002910
2911 /* Submit the 1st MT SMS on GSUP */
2912 log("TX MT-forwardSM-Req for the 1st SMS");
2913 f_gsup_forwardSM_req(spars1);
2914
2915 /* Expect Paging Request and Establish DTAP / BSSAP / SCCP connection */
Harald Weltee035e3e2019-04-21 17:32:05 +02002916 f_expect_paging();
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002917 f_establish_fully(EST_TYPE_PAG_RESP);
2918
2919 /* Wait for 1st MT SMS on DTAP */
2920 f_mt_sms_expect(spars1);
2921 log("RX the 1st SMS on DTAP, DTAP TID is ", spars1.tid,
2922 ", SM-RP-MR is ", spars1.rp.msg_ref);
2923
2924 /* Submit the 2nd MT SMS on GSUP */
2925 log("TX MT-forwardSM-Req for the 2nd SMS");
2926 f_gsup_forwardSM_req(spars2);
2927
2928 /* Wait for 2nd MT SMS on DTAP */
2929 f_mt_sms_expect(spars2);
2930 log("RX the 2nd SMS on DTAP, DTAP TID is ", spars2.tid,
2931 ", SM-RP-MR is ", spars2.rp.msg_ref);
2932
2933 /* Both transaction IDs shall be different */
2934 if (spars1.tid == spars2.tid) {
2935 log("Both DTAP transaction IDs shall be different");
2936 setverdict(fail);
2937 }
2938
2939 /* Both SM-RP-MR values shall be different */
2940 if (spars1.rp.msg_ref == spars2.rp.msg_ref) {
2941 log("Both SM-RP-MR values shall be different");
2942 setverdict(fail);
2943 }
2944
2945 /* Both SM-RP-MR values shall be assigned */
2946 if (spars1.rp.msg_ref == 'FF'O) {
2947 log("Unassigned SM-RP-MR value for the 1st SMS");
2948 setverdict(fail);
2949 }
2950 if (spars2.rp.msg_ref == 'FF'O) {
2951 log("Unassigned SM-RP-MR value for the 2nd SMS");
2952 setverdict(fail);
2953 }
2954
2955 /* Send the 1st RP-ACK and expect MT-forwardSM-Res on GSUP */
2956 f_mt_sms_send_rp_ack(spars1);
2957 alt {
2958 [] GSUP.receive(tr_GSUP_MT_FORWARD_SM_RES(
2959 imsi := g_pars.imsi,
2960 sm_rp_mr := spars1.rp.msg_ref
2961 )) {
2962 log("RX MT-forwardSM-Res (RP-ACK)");
2963 setverdict(pass);
2964 }
2965 [] GSUP.receive {
2966 log("RX unexpected GSUP message");
2967 setverdict(fail);
2968 mtc.stop;
2969 }
2970 }
2971
2972 /* Send the 2nd RP-ACK and expect MT-forwardSM-Res on GSUP */
2973 f_mt_sms_send_rp_ack(spars2);
2974 alt {
2975 [] GSUP.receive(tr_GSUP_MT_FORWARD_SM_RES(
2976 imsi := g_pars.imsi,
2977 sm_rp_mr := spars2.rp.msg_ref
2978 )) {
2979 log("RX MT-forwardSM-Res (RP-ACK)");
2980 setverdict(pass);
2981 }
2982 [] GSUP.receive {
2983 log("RX unexpected GSUP message");
2984 setverdict(fail);
2985 mtc.stop;
2986 }
2987 }
2988
2989 f_expect_clear();
2990}
2991testcase TC_gsup_mt_sms_rp_mr() runs on MTC_CT {
2992 var BSC_ConnHdlrPars pars;
2993 var BSC_ConnHdlr vc_conn;
2994 f_init();
2995 pars := f_init_pars(92);
2996 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2997 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_sms_rp_mr), pars);
2998 vc_conn.done;
2999 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
3000}
3001
Harald Weltee13cfb22019-04-23 16:52:02 +02003002
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07003003/* Test SM-RP-MR assignment for MT-SMS over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02003004friend function f_tc_gsup_mo_mt_sms_rp_mr(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07003005runs on BSC_ConnHdlr {
3006 var SmsParameters spars_mo := valueof(t_SmsPars); /* MO SMMA */
3007 var SmsParameters spars_mt := valueof(t_SmsPars); /* MT SMS */
3008
3009 f_init_handler(pars);
3010
3011 /* We need to inspect GSUP activity */
3012 f_create_gsup_expect(hex2str(g_pars.imsi));
3013
3014 /* Perform location update */
3015 f_perform_lu();
3016
3017 /* Register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01003018 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07003019
3020 /* Send CM Service Request for MO SMMA */
3021 f_establish_fully(EST_TYPE_MO_SMS);
3022
3023 /* Submit MO SMMA on DTAP */
3024 log("Submit MO SMMA on DTAP, SM-RP-MR is '00'O");
3025 spars_mo.rp.msg_ref := '00'O;
3026 f_mo_smma(spars_mo);
3027
3028 /* Expect MO-forwardSM-Req for MO SMMA on GSUP */
3029 alt {
3030 [] GSUP.receive(tr_GSUP_MO_READY_FOR_SM_REQ(
3031 imsi := g_pars.imsi,
3032 sm_rp_mr := spars_mo.rp.msg_ref,
3033 sm_alert_rsn := GSUP_SM_ALERT_RSN_TYPE_MEM_AVAIL
3034 )) {
3035 log("RX MO-ReadyForSM-Req, SM-RP-MR is '00'O");
3036 setverdict(pass);
3037 }
3038 [] GSUP.receive {
3039 log("RX unexpected GSUP message");
3040 setverdict(fail);
3041 mtc.stop;
3042 }
3043 }
3044
3045 /* Submit MT SMS on GSUP */
3046 log("TX MT-forwardSM-Req for the MT SMS");
3047 f_gsup_forwardSM_req(spars_mt);
3048
3049 /* Wait for MT SMS on DTAP */
3050 f_mt_sms_expect(spars_mt);
3051 log("RX MT SMS on DTAP, DTAP TID is ", spars_mt.tid,
3052 ", SM-RP-MR is ", spars_mt.rp.msg_ref);
3053
3054 /* Both SM-RP-MR values shall be different */
3055 if (spars_mo.rp.msg_ref == spars_mt.rp.msg_ref) {
3056 log("Both SM-RP-MR values shall be different");
3057 setverdict(fail);
3058 }
3059
3060 /* SM-RP-MR value for MT SMS shall be assigned */
3061 if (spars_mt.rp.msg_ref == 'FF'O) {
3062 log("Unassigned SM-RP-MR value for the MT SMS");
3063 setverdict(fail);
3064 }
3065
3066 /* Trigger RP-ACK for MO SMMA by sending MO-forwardSM-Res */
3067 GSUP.send(valueof(ts_GSUP_MO_READY_FOR_SM_RES(
3068 imsi := g_pars.imsi,
3069 sm_rp_mr := spars_mo.rp.msg_ref)));
3070 /* Expect RP-ACK for MO SMMA on DTAP */
3071 f_mo_sms_wait_rp_ack(spars_mo);
3072
3073 /* Send RP-ACK for MT SMS and expect MT-forwardSM-Res on GSUP */
3074 f_mt_sms_send_rp_ack(spars_mt);
3075 alt {
3076 [] GSUP.receive(tr_GSUP_MT_FORWARD_SM_RES(
3077 imsi := g_pars.imsi,
3078 sm_rp_mr := spars_mt.rp.msg_ref
3079 )) {
3080 log("RX MT-forwardSM-Res (RP-ACK)");
3081 setverdict(pass);
3082 }
3083 [] GSUP.receive {
3084 log("RX unexpected GSUP message");
3085 setverdict(fail);
3086 mtc.stop;
3087 }
3088 }
3089
3090 f_expect_clear();
3091}
3092testcase TC_gsup_mo_mt_sms_rp_mr() runs on MTC_CT {
3093 var BSC_ConnHdlrPars pars;
3094 var BSC_ConnHdlr vc_conn;
3095 f_init();
3096 pars := f_init_pars(93);
3097 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
3098 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mo_mt_sms_rp_mr), pars);
3099 vc_conn.done;
3100 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
3101}
3102
Harald Weltee13cfb22019-04-23 16:52:02 +02003103
Vadim Yanitskiy1cd11a02018-12-03 02:43:35 +07003104/* Test multi-part MT-SMS over GSUP */
3105private function f_tc_gsup_mt_multi_part_sms(charstring id, BSC_ConnHdlrPars pars)
3106runs on BSC_ConnHdlr {
3107 var SmsParameters spars := valueof(t_SmsPars);
3108
3109 f_init_handler(pars);
3110
3111 /* We need to inspect GSUP activity */
3112 f_create_gsup_expect(hex2str(g_pars.imsi));
3113
3114 /* Perform location update */
3115 f_perform_lu();
3116
3117 /* Register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01003118 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy1cd11a02018-12-03 02:43:35 +07003119
3120 var template GSUP_PDU mt_forwardSM_res := tr_GSUP_MT_FORWARD_SM_RES(
3121 imsi := g_pars.imsi,
3122 /* NOTE: MSC should assign RP-MR itself */
3123 sm_rp_mr := ?
3124 );
3125
3126 /* Send 4 messages (NOTE: SM-RP-UI remains unchanged) */
3127 for (var integer i := 3; i >= 0; i := i-1) {
3128 /* Submit a MT SMS on GSUP (MMS is decremented) */
3129 f_gsup_forwardSM_req(spars, int2oct(i, 1));
3130
3131 /* Expect Paging Request and Establish connection */
3132 if (i == 3) { /* ... only once! */
Harald Weltee13cfb22019-04-23 16:52:02 +02003133 f_expect_paging();
Vadim Yanitskiy1cd11a02018-12-03 02:43:35 +07003134 f_establish_fully(EST_TYPE_PAG_RESP);
3135 }
3136
3137 /* Wait for MT SMS on DTAP */
3138 f_mt_sms_expect(spars);
3139
3140 /* Send RP-ACK and expect MT-forwardSM-Res on GSUP */
3141 f_mt_sms_send_rp_ack(spars);
3142 alt {
3143 [] GSUP.receive(mt_forwardSM_res) {
3144 log("RX MT-forwardSM-Res (RP-ACK)");
3145 setverdict(pass);
3146 }
3147 [] GSUP.receive {
3148 log("RX unexpected GSUP message");
3149 setverdict(fail);
3150 mtc.stop;
3151 }
3152 }
3153
3154 /* Keep some 'distance' between transmissions */
3155 f_sleep(1.5);
3156 }
3157
3158 f_expect_clear();
3159}
3160testcase TC_gsup_mt_multi_part_sms() runs on MTC_CT {
3161 var BSC_ConnHdlrPars pars;
3162 var BSC_ConnHdlr vc_conn;
3163 f_init();
3164 pars := f_init_pars(91);
3165 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
3166 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_multi_part_sms), pars);
3167 vc_conn.done;
3168 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
3169}
3170
Harald Weltef640a012018-04-14 17:49:21 +02003171/* convert GSM L3 TON to SMPP_TON enum */
3172function f_sm_ton_from_gsm(BIT3 ton) return SMPP_TON {
3173 select (ton) {
3174 case ('000'B) { return unknown; }
3175 case ('001'B) { return international; }
3176 case ('010'B) { return national; }
3177 case ('011'B) { return network_specific; }
3178 case ('100'B) { return subscriber_number; }
3179 case ('101'B) { return alphanumeric; }
3180 case ('110'B) { return abbreviated; }
3181 }
3182 setverdict(fail, "Unknown TON ", ton);
Daniel Willmannafce8662018-07-06 23:11:32 +02003183 mtc.stop;
Harald Weltef640a012018-04-14 17:49:21 +02003184}
3185/* convert GSM L3 NPI to SMPP_NPI enum */
3186function f_sm_npi_from_gsm(BIT4 npi) return SMPP_NPI {
3187 select (npi) {
3188 case ('0000'B) { return unknown; }
3189 case ('0001'B) { return isdn; }
3190 case ('0011'B) { return data; }
3191 case ('0100'B) { return telex; }
3192 case ('0110'B) { return land_mobile; }
3193 case ('1000'B) { return national; }
3194 case ('1001'B) { return private_; }
3195 case ('1010'B) { return ermes; }
3196 }
3197 setverdict(fail, "Unknown NPI ", npi);
Daniel Willmannafce8662018-07-06 23:11:32 +02003198 mtc.stop;
Harald Weltef640a012018-04-14 17:49:21 +02003199}
3200
3201/* build a SMPP_SM from SmsParameters */
3202function f_mt_sm_from_spars(SmsParameters spars)
3203runs on BSC_ConnHdlr return SMPP_SM {
3204 var SMPP_SM sm := {
3205 service_type := "CMT",
3206 source_addr_ton := f_sm_ton_from_gsm(spars.tp.da.tP_DA_NoPad.tP_TypeOfNumber),
3207 source_addr_npi := f_sm_npi_from_gsm(spars.tp.da.tP_DA_NoPad.tP_NumberingPlanID),
3208 source_addr := hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue),
3209 dest_addr_ton := international,
3210 dest_addr_npi := isdn,
3211 destination_addr := hex2str(g_pars.msisdn),
3212 esm_class := '00000001'B,
3213 protocol_id := 0,
3214 priority_flag := 0,
3215 schedule_delivery_time := "",
3216 validity_period := "",
3217 registered_delivery := '00000000'B,
3218 replace_if_present := 0,
3219 data_coding := '00000001'B,
3220 sm_default_msg_id := 0,
3221 sm_length := spars.tp.udl,
3222 short_message := spars.tp.ud,
3223 opt_pars := {}
3224 };
3225 return sm;
3226}
3227
3228/* helper function to encode SMS from 'spars', send it via SMPP to MSC; receive it on MS side */
3229private function f_smpp_mt_sms(SmsParameters spars, boolean trans_mode) runs on BSC_ConnHdlr {
3230 var SMPP_SM sm := f_mt_sm_from_spars(spars);
3231 if (trans_mode) {
3232 sm.esm_class := '00000010'B;
3233 }
3234
3235 /* actually cause MSC to send a SMS via SUBMIT-SM from SMPP side */
3236 SMPP.send(ts_SMPP_SUBMIT_SM(sm));
3237 if (not match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
3238 /* if we're not in SMPP transaction mode, we expect the SMPP-level ACK
3239 * before we expect the SMS delivery on the BSC/radio side */
3240 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
3241 }
3242
3243 /* MSC->BSC: expect PAGING from MSC */
Harald Weltee035e3e2019-04-21 17:32:05 +02003244 f_expect_paging();
Harald Weltef640a012018-04-14 17:49:21 +02003245 /* Establish DTAP / BSSAP / SCCP connection */
3246 f_establish_fully(EST_TYPE_PAG_RESP);
3247 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
3248
3249 f_mt_sms(spars);
3250
3251 if (match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
3252 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
3253 }
3254 f_expect_clear();
3255}
3256
3257/* mobile terminated SMS, from SMPP to BSC/BTS/MS */
3258private function f_tc_smpp_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
3259 f_init_handler(pars);
3260
3261 /* Perform location update so IMSI is known + registered in MSC/VLR */
3262 f_perform_lu();
3263 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
3264
3265 /* register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01003266 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Harald Weltef640a012018-04-14 17:49:21 +02003267
3268 var SmsParameters spars := valueof(t_SmsPars);
3269 /* TODO: test with more intelligent user data; test different coding schemes */
3270 spars.tp.ud := '00'O;
3271 spars.tp.udl := 1;
3272
3273 /* first test the non-transaction store+forward mode */
3274 f_smpp_mt_sms(spars, false);
3275
3276 /* then test the transaction mode */
3277 f_smpp_mt_sms(spars, true);
3278}
3279testcase TC_smpp_mt_sms() runs on MTC_CT {
3280 var BSC_ConnHdlr vc_conn;
3281 f_init();
3282 vc_conn := f_start_handler(refers(f_tc_smpp_mt_sms), 45);
3283 vc_conn.done;
3284}
3285
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003286/***********************************************************************
3287 * USSD Testing
3288 ***********************************************************************/
3289
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003290private altstep as_unexp_gsup_or_bssap_msg()
3291runs on BSC_ConnHdlr {
3292 [] GSUP.receive {
3293 setverdict(fail, "Unknown/unexpected GSUP received");
3294 self.stop;
3295 }
3296 [] BSSAP.receive {
3297 setverdict(fail, "Unknown/unexpected BSSAP message received");
3298 self.stop;
3299 }
3300}
3301
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003302private function f_expect_gsup_msg(template GSUP_PDU msg,
3303 float T_val := 2.0)
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003304runs on BSC_ConnHdlr return GSUP_PDU {
3305 var GSUP_PDU gsup_msg_complete;
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003306 timer T := T_val;
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003307
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003308 T.start;
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003309 alt {
3310 [] GSUP.receive(msg) -> value gsup_msg_complete {
3311 setverdict(pass);
3312 }
3313 /* We don't expect anything else */
3314 [] as_unexp_gsup_or_bssap_msg();
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003315 [] T.timeout {
3316 setverdict(fail, "Timeout waiting for GSUP message: ", msg);
3317 }
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003318 }
3319
3320 return gsup_msg_complete;
3321}
3322
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003323private function f_expect_mt_dtap_msg(template PDU_ML3_NW_MS msg,
3324 float T_val := 2.0)
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003325runs on BSC_ConnHdlr return PDU_ML3_NW_MS {
3326 var PDU_DTAP_MT bssap_msg_complete;
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003327 timer T := T_val;
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003328
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003329 T.start;
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003330 alt {
3331 [] BSSAP.receive(tr_PDU_DTAP_MT(msg)) -> value bssap_msg_complete {
3332 setverdict(pass);
3333 }
3334 /* We don't expect anything else */
3335 [] as_unexp_gsup_or_bssap_msg();
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003336 [] T.timeout {
3337 setverdict(fail, "Timeout waiting for BSSAP message: ", msg);
3338 }
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003339 }
3340
3341 return bssap_msg_complete.dtap;
3342}
3343
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003344/* LU followed by MO USSD request */
Harald Weltee13cfb22019-04-23 16:52:02 +02003345friend function f_tc_lu_and_mo_ussd_single_request(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003346runs on BSC_ConnHdlr {
3347 f_init_handler(pars);
3348
3349 /* Perform location update */
3350 f_perform_lu();
3351
3352 /* Send CM Service Request for SS/USSD */
3353 f_establish_fully(EST_TYPE_SS_ACT);
3354
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003355 /* We need to inspect GSUP activity */
3356 f_create_gsup_expect(hex2str(g_pars.imsi));
3357
3358 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3359 invoke_id := 5, /* Phone may not start from 0 or 1 */
3360 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3361 ussd_string := "*#100#"
3362 );
3363
3364 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
3365 invoke_id := 5, /* InvokeID shall be the same for both REQ and RSP */
3366 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3367 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
3368 )
3369
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003370 /* Compose a new SS/REGISTER message with request */
3371 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
3372 tid := 1, /* We just need a single transaction */
3373 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003374 facility := valueof(facility_req)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003375 );
3376
3377 /* Compose SS/RELEASE_COMPLETE template with expected response */
3378 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
3379 tid := 1, /* Response should arrive within the same transaction */
3380 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003381 facility := valueof(facility_rsp)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003382 );
3383
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003384 /* Compose expected MSC -> HLR message */
3385 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
3386 imsi := g_pars.imsi,
3387 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3388 ss := valueof(facility_req)
3389 );
3390
3391 /* To be used for sending response with correct session ID */
3392 var GSUP_PDU gsup_req_complete;
3393
3394 /* Request own number */
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003395 BSSAP.send(ts_PDU_DTAP_MO(ussd_req));
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003396 /* Expect GSUP message containing the SS payload */
3397 gsup_req_complete := f_expect_gsup_msg(gsup_req);
3398
3399 /* Compose the response from HLR using received session ID */
3400 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
3401 imsi := g_pars.imsi,
3402 sid := gsup_req_complete.ies[1].val.session_id,
3403 state := OSMO_GSUP_SESSION_STATE_END,
3404 ss := valueof(facility_rsp)
3405 );
3406
3407 /* Finally, HLR terminates the session */
3408 GSUP.send(gsup_rsp);
3409 /* Expect RELEASE_COMPLETE message with the response */
3410 f_expect_mt_dtap_msg(ussd_rsp);
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003411
3412 f_expect_clear();
3413}
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003414testcase TC_lu_and_mo_ussd_single_request() runs on MTC_CT {
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003415 var BSC_ConnHdlr vc_conn;
3416 f_init();
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003417 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_single_request), 46);
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003418 vc_conn.done;
3419}
3420
Harald Weltee13cfb22019-04-23 16:52:02 +02003421
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003422/* LU followed by MT USSD notification */
Harald Weltee13cfb22019-04-23 16:52:02 +02003423friend function f_tc_lu_and_mt_ussd_notification(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003424runs on BSC_ConnHdlr {
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003425 timer T := 5.0;
3426
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003427 f_init_handler(pars);
3428
3429 /* Perform location update */
3430 f_perform_lu();
3431
Harald Welte6811d102019-04-14 22:23:14 +02003432 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003433
3434 /* We need to inspect GSUP activity */
3435 f_create_gsup_expect(hex2str(g_pars.imsi));
3436
3437 /* Facility IE with network-originated USSD notification */
3438 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3439 op_code := SS_OP_CODE_USS_NOTIFY,
3440 ussd_string := "Mahlzeit!"
3441 );
3442
3443 /* Facility IE with acknowledgment to the USSD notification */
3444 var template OCTN facility_rsp := enc_SS_FacilityInformation(
3445 /* In case of USSD notification, Return Result is empty */
3446 valueof(ts_SS_USSD_FACILITY_RETURN_RESULT_EMPTY())
3447 );
3448
3449 /* Compose a new MT SS/REGISTER message with USSD notification */
3450 var template PDU_ML3_NW_MS ussd_ntf := tr_ML3_MT_SS_REGISTER(
3451 tid := 0, /* FIXME: most likely, it should be 0 */
3452 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3453 facility := valueof(facility_req)
3454 );
3455
3456 /* Compose HLR -> MSC GSUP message */
3457 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
3458 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003459 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003460 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3461 ss := valueof(facility_req)
3462 );
3463
3464 /* Send it to MSC and expect Paging Request */
3465 GSUP.send(gsup_req);
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003466 T.start;
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003467 alt {
Harald Weltee13cfb22019-04-23 16:52:02 +02003468 [pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
3469 setverdict(pass);
3470 }
Harald Welte62113fc2019-05-09 13:04:02 +02003471 [not pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003472 setverdict(pass);
3473 }
3474 /* We don't expect anything else */
3475 [] as_unexp_gsup_or_bssap_msg();
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003476 [] T.timeout {
3477 setverdict(fail, "Timeout waiting for Paging Request");
3478 }
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003479 }
3480
3481 /* Send Paging Response and expect USSD notification */
3482 f_establish_fully(EST_TYPE_PAG_RESP);
3483 /* Expect MT REGISTER message with USSD notification */
3484 f_expect_mt_dtap_msg(ussd_ntf);
3485
3486 /* Compose a new MO SS/FACILITY message with empty response */
3487 var template (value) PDU_ML3_MS_NW ussd_rsp := ts_ML3_MO_SS_FACILITY(
3488 tid := 0, /* FIXME: it shall match the request tid */
3489 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3490 facility := valueof(facility_rsp)
3491 );
3492
3493 /* Compose expected MSC -> HLR GSUP message */
3494 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_REQ(
3495 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003496 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003497 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
3498 ss := valueof(facility_rsp)
3499 );
3500
3501 /* MS sends response to the notification */
3502 BSSAP.send(ts_PDU_DTAP_MO(ussd_rsp));
3503 /* Expect GSUP message containing the SS payload */
3504 f_expect_gsup_msg(gsup_rsp);
3505
3506 /* Compose expected MT SS/RELEASE COMPLETE message */
3507 var template PDU_ML3_NW_MS ussd_term := tr_ML3_MT_SS_RELEASE_COMPLETE(
3508 tid := 0, /* FIXME: it shall match the request tid */
3509 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3510 facility := omit
3511 );
3512
3513 /* Compose MSC -> HLR GSUP message */
3514 var template GSUP_PDU gsup_term := ts_GSUP_PROC_SS_REQ(
3515 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003516 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003517 state := OSMO_GSUP_SESSION_STATE_END
3518 );
3519
3520 /* Finally, HLR terminates the session */
3521 GSUP.send(gsup_term)
3522 /* Expect MT RELEASE COMPLETE without Facility IE */
3523 f_expect_mt_dtap_msg(ussd_term);
3524
3525 f_expect_clear();
3526}
3527testcase TC_lu_and_mt_ussd_notification() runs on MTC_CT {
3528 var BSC_ConnHdlr vc_conn;
3529 f_init();
3530 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_ussd_notification), 47);
3531 vc_conn.done;
3532}
3533
Harald Weltee13cfb22019-04-23 16:52:02 +02003534
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003535/* LU followed by MT call and MO USSD request during this call */
Harald Weltee13cfb22019-04-23 16:52:02 +02003536friend function f_tc_lu_and_mo_ussd_during_mt_call(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003537runs on BSC_ConnHdlr {
3538 f_init_handler(pars);
3539
3540 /* Call parameters taken from f_tc_lu_and_mt_call */
3541 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003542
3543 /* Perform location update */
3544 f_perform_lu();
3545
3546 /* Establish a MT call */
3547 f_mt_call_establish(cpars);
3548
3549 /* Hold the call for some time */
3550 f_sleep(1.0);
3551
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003552 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3553 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3554 ussd_string := "*#100#"
3555 );
3556
3557 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
3558 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3559 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
3560 )
3561
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003562 /* Compose a new SS/REGISTER message with request */
3563 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
3564 tid := 1, /* We just need a single transaction */
3565 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003566 facility := valueof(facility_req)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003567 );
3568
3569 /* Compose SS/RELEASE_COMPLETE template with expected response */
3570 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
3571 tid := 1, /* Response should arrive within the same transaction */
3572 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003573 facility := valueof(facility_rsp)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003574 );
3575
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003576 /* Compose expected MSC -> HLR message */
3577 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
3578 imsi := g_pars.imsi,
3579 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3580 ss := valueof(facility_req)
3581 );
3582
3583 /* To be used for sending response with correct session ID */
3584 var GSUP_PDU gsup_req_complete;
3585
3586 /* Request own number */
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003587 BSSAP.send(ts_PDU_DTAP_MO(ussd_req));
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003588 /* Expect GSUP message containing the SS payload */
3589 gsup_req_complete := f_expect_gsup_msg(gsup_req);
3590
3591 /* Compose the response from HLR using received session ID */
3592 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
3593 imsi := g_pars.imsi,
3594 sid := gsup_req_complete.ies[1].val.session_id,
3595 state := OSMO_GSUP_SESSION_STATE_END,
3596 ss := valueof(facility_rsp)
3597 );
3598
3599 /* Finally, HLR terminates the session */
3600 GSUP.send(gsup_rsp);
3601 /* Expect RELEASE_COMPLETE message with the response */
3602 f_expect_mt_dtap_msg(ussd_rsp);
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003603
3604 /* Hold the call for some time */
3605 f_sleep(1.0);
3606
3607 /* Release the call (does Clear Complete itself) */
3608 f_call_hangup(cpars, true);
3609}
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003610testcase TC_lu_and_mo_ussd_during_mt_call() runs on MTC_CT {
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003611 var BSC_ConnHdlr vc_conn;
3612 f_init();
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003613 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_during_mt_call), 48);
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003614 vc_conn.done;
3615}
3616
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003617/* BSSMAP Clear Request in the middle of a call, see OS#3062 */
Harald Weltee13cfb22019-04-23 16:52:02 +02003618friend function f_tc_mo_cc_bssmap_clear(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003619 f_init_handler(pars);
3620 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02003621 cpars.ran_clear_when_alerting := true;
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003622
3623 f_perform_lu();
3624
Neels Hofmeyrde76f052019-02-26 05:02:46 +01003625 var default ccrel := activate(as_optional_cc_rel(cpars));
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02003626 f_mo_call_establish(cpars);
3627 f_expect_clear()
Neels Hofmeyrde76f052019-02-26 05:02:46 +01003628 deactivate(ccrel);
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003629
3630 f_sleep(1.0);
3631}
3632testcase TC_mo_cc_bssmap_clear() runs on MTC_CT {
3633 var BSC_ConnHdlr vc_conn;
3634 f_init();
3635
3636 vc_conn := f_start_handler(refers(f_tc_mo_cc_bssmap_clear), 43);
3637 vc_conn.done;
3638}
3639
Harald Weltee13cfb22019-04-23 16:52:02 +02003640
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003641/* LU followed by MT call and MT USSD request during this call */
Harald Weltee13cfb22019-04-23 16:52:02 +02003642friend function f_tc_lu_and_mt_ussd_during_mt_call(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003643runs on BSC_ConnHdlr {
3644 f_init_handler(pars);
3645
3646 /* Call parameters taken from f_tc_lu_and_mt_call */
3647 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003648
3649 /* Perform location update */
3650 f_perform_lu();
3651
3652 /* Establish a MT call */
3653 f_mt_call_establish(cpars);
3654
3655 /* Hold the call for some time */
3656 f_sleep(1.0);
3657
3658 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3659 op_code := SS_OP_CODE_USS_REQUEST,
3660 ussd_string := "Please type anything..."
3661 );
3662
3663 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
3664 op_code := SS_OP_CODE_USS_REQUEST,
3665 ussd_string := "Nope."
3666 )
3667
3668 /* Compose MT SS/REGISTER message with network-originated request */
3669 var template (value) PDU_ML3_NW_MS ussd_req := ts_ML3_MT_SS_REGISTER(
3670 tid := 0, /* FIXME: most likely, it should be 0 */
3671 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3672 facility := valueof(facility_req)
3673 );
3674
3675 /* Compose HLR -> MSC GSUP message */
3676 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
3677 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003678 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003679 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3680 ss := valueof(facility_req)
3681 );
3682
3683 /* Send it to MSC */
3684 GSUP.send(gsup_req);
3685 /* Expect MT REGISTER message with USSD request */
3686 f_expect_mt_dtap_msg(ussd_req);
3687
3688 /* Compose a new MO SS/FACILITY message with response */
3689 var template (value) PDU_ML3_MS_NW ussd_rsp := ts_ML3_MO_SS_FACILITY(
3690 tid := 0, /* FIXME: it shall match the request tid */
3691 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3692 facility := valueof(facility_rsp)
3693 );
3694
3695 /* Compose expected MSC -> HLR GSUP message */
3696 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_REQ(
3697 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003698 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003699 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
3700 ss := valueof(facility_rsp)
3701 );
3702
3703 /* MS sends response */
3704 BSSAP.send(ts_PDU_DTAP_MO(ussd_rsp));
3705 f_expect_gsup_msg(gsup_rsp);
3706
3707 /* Compose expected MT SS/RELEASE COMPLETE message */
3708 var template PDU_ML3_NW_MS ussd_term := tr_ML3_MT_SS_RELEASE_COMPLETE(
3709 tid := 0, /* FIXME: it shall match the request tid */
3710 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3711 facility := omit
3712 );
3713
3714 /* Compose MSC -> HLR GSUP message */
3715 var template GSUP_PDU gsup_term := ts_GSUP_PROC_SS_REQ(
3716 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003717 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003718 state := OSMO_GSUP_SESSION_STATE_END
3719 );
3720
3721 /* Finally, HLR terminates the session */
3722 GSUP.send(gsup_term);
3723 /* Expect MT RELEASE COMPLETE without Facility IE */
3724 f_expect_mt_dtap_msg(ussd_term);
3725
3726 /* Hold the call for some time */
3727 f_sleep(1.0);
3728
3729 /* Release the call (does Clear Complete itself) */
3730 f_call_hangup(cpars, true);
3731}
3732testcase TC_lu_and_mt_ussd_during_mt_call() runs on MTC_CT {
3733 var BSC_ConnHdlr vc_conn;
3734 f_init();
3735 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_ussd_during_mt_call), 49);
3736 vc_conn.done;
3737}
3738
Harald Weltee13cfb22019-04-23 16:52:02 +02003739
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07003740/* LU followed by MO USSD request and MO Release during transaction */
Harald Weltee13cfb22019-04-23 16:52:02 +02003741friend function f_tc_lu_and_mo_ussd_mo_release(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07003742runs on BSC_ConnHdlr {
3743 f_init_handler(pars);
3744
3745 /* Perform location update */
3746 f_perform_lu();
3747
3748 /* Send CM Service Request for SS/USSD */
3749 f_establish_fully(EST_TYPE_SS_ACT);
3750
3751 /* We need to inspect GSUP activity */
3752 f_create_gsup_expect(hex2str(g_pars.imsi));
3753
3754 var template OCTN facility_ms_req := f_USSD_FACILITY_IE_INVOKE(
3755 invoke_id := 1, /* Initial request */
3756 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3757 ussd_string := "*6766*266#"
3758 );
3759
3760 var template OCTN facility_net_req := f_USSD_FACILITY_IE_INVOKE(
3761 invoke_id := 2, /* Counter request */
3762 op_code := SS_OP_CODE_USS_REQUEST,
3763 ussd_string := "Password?!?"
3764 )
3765
3766 /* Compose MO SS/REGISTER message with request */
3767 var template (value) PDU_ML3_MS_NW ussd_ms_req := ts_ML3_MO_SS_REGISTER(
3768 tid := 1, /* We just need a single transaction */
3769 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3770 facility := valueof(facility_ms_req)
3771 );
3772
3773 /* Compose expected MSC -> HLR message */
3774 var template GSUP_PDU gsup_ms_req := tr_GSUP_PROC_SS_REQ(
3775 imsi := g_pars.imsi,
3776 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3777 ss := valueof(facility_ms_req)
3778 );
3779
3780 /* To be used for sending response with correct session ID */
3781 var GSUP_PDU gsup_ms_req_complete;
3782
3783 /* Initiate a new transaction */
3784 BSSAP.send(ts_PDU_DTAP_MO(ussd_ms_req));
3785 /* Expect GSUP request with original Facility IE */
3786 gsup_ms_req_complete := f_expect_gsup_msg(gsup_ms_req);
3787
3788 /* Compose the response from HLR using received session ID */
3789 var template (value) GSUP_PDU gsup_net_req := ts_GSUP_PROC_SS_REQ(
3790 imsi := g_pars.imsi,
3791 sid := gsup_ms_req_complete.ies[1].val.session_id,
3792 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
3793 ss := valueof(facility_net_req)
3794 );
3795
3796 /* Compose expected MT SS/FACILITY template with counter request */
3797 var template PDU_ML3_NW_MS ussd_net_req := tr_ML3_MT_SS_FACILITY(
3798 tid := 1, /* Response should arrive within the same transaction */
3799 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3800 facility := valueof(facility_net_req)
3801 );
3802
3803 /* Send response over GSUP */
3804 GSUP.send(gsup_net_req);
3805 /* Expect MT SS/FACILITY message with counter request */
3806 f_expect_mt_dtap_msg(ussd_net_req);
3807
3808 /* Compose MO SS/RELEASE COMPLETE */
3809 var template (value) PDU_ML3_MS_NW ussd_abort := ts_ML3_MO_SS_RELEASE_COMPLETE(
3810 tid := 1, /* Response should arrive within the same transaction */
3811 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3812 facility := omit
3813 /* TODO: cause? */
3814 );
3815
3816 /* Compose expected HLR -> MSC abort message */
3817 var template GSUP_PDU gsup_abort := tr_GSUP_PROC_SS_REQ(
3818 imsi := g_pars.imsi,
3819 sid := gsup_ms_req_complete.ies[1].val.session_id,
3820 state := OSMO_GSUP_SESSION_STATE_END
3821 );
3822
3823 /* Abort transaction */
3824 BSSAP.send(ts_PDU_DTAP_MO(ussd_abort));
3825 /* Expect GSUP message indicating abort */
3826 f_expect_gsup_msg(gsup_abort);
3827
3828 f_expect_clear();
3829}
3830testcase TC_lu_and_mo_ussd_mo_release() runs on MTC_CT {
3831 var BSC_ConnHdlr vc_conn;
3832 f_init();
3833 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_mo_release), 50);
3834 vc_conn.done;
3835}
3836
Harald Weltee13cfb22019-04-23 16:52:02 +02003837
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003838/* LU followed by MO USSD request and MT Release due to timeout */
Harald Weltee13cfb22019-04-23 16:52:02 +02003839friend function f_tc_lu_and_ss_session_timeout(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003840runs on BSC_ConnHdlr {
3841 f_init_handler(pars);
3842
3843 /* Perform location update */
3844 f_perform_lu();
3845
3846 /* Send CM Service Request for SS/USSD */
3847 f_establish_fully(EST_TYPE_SS_ACT);
3848
3849 /* We need to inspect GSUP activity */
3850 f_create_gsup_expect(hex2str(g_pars.imsi));
3851
3852 var template OCTN facility_ms_req := f_USSD_FACILITY_IE_INVOKE(
3853 invoke_id := 1,
3854 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3855 ussd_string := "#release_me");
3856
3857 /* Compose MO SS/REGISTER message with request */
3858 var template (value) PDU_ML3_MS_NW ussd_ms_req := ts_ML3_MO_SS_REGISTER(
3859 tid := 1, /* An arbitrary transaction identifier */
3860 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3861 facility := valueof(facility_ms_req));
3862
3863 /* Compose expected MSC -> HLR message */
3864 var template GSUP_PDU gsup_ms_req := tr_GSUP_PROC_SS_REQ(
3865 imsi := g_pars.imsi,
3866 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3867 ss := valueof(facility_ms_req));
3868
3869 /* To be used for sending response with correct session ID */
3870 var GSUP_PDU gsup_ms_req_complete;
3871
3872 /* Initiate a new SS transaction */
3873 BSSAP.send(ts_PDU_DTAP_MO(ussd_ms_req));
3874 /* Expect GSUP request with original Facility IE */
3875 gsup_ms_req_complete := f_expect_gsup_msg(gsup_ms_req);
3876
3877 /* Don't respond, wait for timeout */
3878 f_sleep(3.0);
3879
3880 var template PDU_ML3_NW_MS dtap_rel := tr_ML3_MT_SS_RELEASE_COMPLETE(
3881 tid := 1, /* Should match the request's tid */
3882 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3883 cause := *, /* TODO: expect some specific value */
3884 facility := omit);
3885
3886 var template GSUP_PDU gsup_rel := tr_GSUP_PROC_SS_ERR(
3887 imsi := g_pars.imsi,
3888 sid := gsup_ms_req_complete.ies[1].val.session_id,
3889 state := OSMO_GSUP_SESSION_STATE_END,
3890 cause := ?); /* TODO: expect some specific value */
3891
3892 /* Expect release on both interfaces */
3893 interleave {
3894 [] BSSAP.receive(tr_PDU_DTAP_MT(dtap_rel)) { };
3895 [] GSUP.receive(gsup_rel) { };
3896 }
3897
3898 f_expect_clear();
3899 setverdict(pass);
3900}
3901testcase TC_lu_and_ss_session_timeout() runs on MTC_CT {
3902 var BSC_ConnHdlr vc_conn;
3903 f_init();
Vadim Yanitskiy36d28dd2018-12-03 02:45:45 +07003904 f_vty_config(MSCVTY, "msc", "ncss guard-timeout 3");
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003905 vc_conn := f_start_handler(refers(f_tc_lu_and_ss_session_timeout), 51);
3906 vc_conn.done;
Vadim Yanitskiy36d28dd2018-12-03 02:45:45 +07003907 f_vty_config(MSCVTY, "msc", "ncss guard-timeout 0");
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003908}
3909
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07003910/* MT (network-originated) USSD for unknown subscriber */
3911friend function f_tc_mt_ussd_for_unknown_subscr(charstring id, BSC_ConnHdlrPars pars)
3912runs on BSC_ConnHdlr {
3913 var hexstring imsi := '000000000000000'H; /* Some unknown IMSI */
3914 var OCT4 sid := '20000222'O;
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07003915
3916 f_init_handler(pars);
3917 f_ran_register_imsi(imsi, 'FFFFFFFF'O);
3918 f_create_gsup_expect(hex2str(imsi));
3919
3920 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
3921 imsi := imsi,
3922 sid := sid,
3923 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3924 ss := f_rnd_octstring(23)
3925 );
3926
3927 /* Error with cause GMM_CAUSE_IMSI_UNKNOWN */
3928 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_ERR(
3929 imsi := imsi,
3930 sid := sid,
3931 state := OSMO_GSUP_SESSION_STATE_END,
3932 cause := 2 /* FIXME: introduce an enumerated type! */
3933 );
3934
3935 /* Initiate a MT USSD notification */
3936 GSUP.send(gsup_req);
3937
3938 /* Expect GSUP PROC_SS_ERROR message */
Vadim Yanitskiy851798c2019-06-15 14:22:28 +07003939 f_expect_gsup_msg(gsup_rsp);
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07003940}
3941testcase TC_mt_ussd_for_unknown_subscr() runs on MTC_CT {
3942 var BSC_ConnHdlr vc_conn;
3943 f_init();
3944 vc_conn := f_start_handler(refers(f_tc_mt_ussd_for_unknown_subscr), 0);
3945 vc_conn.done;
3946}
3947
Vadim Yanitskiyc3c07d42019-06-17 23:00:44 +07003948/* MO (mobile-originated) SS/USSD for unknown transaction */
3949friend function f_tc_mo_ussd_for_unknown_trans(charstring id, BSC_ConnHdlrPars pars)
3950runs on BSC_ConnHdlr {
3951 f_init_handler(pars);
3952
Vadim Yanitskiy70d15bf2020-01-09 22:51:01 +01003953 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyc3c07d42019-06-17 23:00:44 +07003954 f_create_gsup_expect(hex2str(g_pars.imsi));
3955
3956 /* Perform location update */
3957 f_perform_lu();
3958
3959 /* Send CM Service Request for SS/USSD */
3960 f_establish_fully(EST_TYPE_SS_ACT);
3961
3962 /* GSM 04.80 FACILITY message for a non-existing transaction */
3963 var template (value) PDU_ML3_MS_NW mo_ss_fac := ts_ML3_MO_SS_FACILITY(
3964 tid := 1, /* An arbitrary transaction identifier */
3965 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3966 facility := f_rnd_octstring(23) /* We don't care about the Facility IE */
3967 );
3968
3969 /* GSM 04.80 RELEASE COMPLETE message for a non-existing transaction */
3970 var template (value) PDU_ML3_MS_NW mo_ss_rel := ts_ML3_MO_SS_RELEASE_COMPLETE(
3971 tid := 1, /* An arbitrary transaction identifier */
3972 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3973 facility := f_rnd_octstring(23) /* We don't care about the Facility IE */
3974 );
3975
3976 /* Expected response from the network */
3977 var template PDU_ML3_NW_MS mt_ss_rel := tr_ML3_MT_SS_RELEASE_COMPLETE(
3978 tid := 1, /* Same as in the FACILITY message */
3979 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3980 facility := omit
3981 );
3982
3983 /* Send GSM 04.80 FACILITY for non-existing transaction */
3984 BSSAP.send(ts_PDU_DTAP_MO(mo_ss_fac));
3985
3986 /* Expect GSM 04.80 RELEASE COMPLETE message */
3987 f_expect_mt_dtap_msg(mt_ss_rel);
3988 f_expect_clear();
3989
3990 /* Send another CM Service Request for SS/USSD */
3991 f_establish_fully(EST_TYPE_SS_ACT);
3992
3993 /* Send GSM 04.80 RELEASE COMPLETE for non-existing transaction */
3994 BSSAP.send(ts_PDU_DTAP_MO(mo_ss_rel));
3995
3996 /* Expect GSM 04.80 RELEASE COMPLETE message */
3997 f_expect_mt_dtap_msg(mt_ss_rel);
3998 f_expect_clear();
3999}
4000testcase TC_mo_ussd_for_unknown_trans() runs on MTC_CT {
4001 var BSC_ConnHdlr vc_conn;
4002 f_init();
4003 vc_conn := f_start_handler(refers(f_tc_mo_ussd_for_unknown_trans), 111);
4004 vc_conn.done;
4005}
4006
Vadim Yanitskiyd612d282019-06-15 14:46:03 +07004007/* MT (network-originated) USSD for unknown session */
4008friend function f_tc_proc_ss_for_unknown_session(charstring id, BSC_ConnHdlrPars pars)
4009runs on BSC_ConnHdlr {
4010 var OCT4 sid := '20000333'O;
4011
4012 f_init_handler(pars);
4013
4014 /* Perform location update */
4015 f_perform_lu();
4016
Vadim Yanitskiy70d15bf2020-01-09 22:51:01 +01004017 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyd612d282019-06-15 14:46:03 +07004018 f_create_gsup_expect(hex2str(g_pars.imsi));
4019
4020 /* Request referencing a non-existing SS session */
4021 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
4022 imsi := g_pars.imsi,
4023 sid := sid,
4024 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
4025 ss := f_rnd_octstring(23)
4026 );
4027
4028 /* Error with some cause value */
4029 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_ERR(
4030 imsi := g_pars.imsi,
4031 sid := sid,
4032 state := OSMO_GSUP_SESSION_STATE_END,
4033 cause := ? /* FIXME: introduce an enumerated type! */
4034 );
4035
4036 /* Initiate a MT USSD notification */
4037 GSUP.send(gsup_req);
4038
4039 /* Expect GSUP PROC_SS_ERROR message */
4040 f_expect_gsup_msg(gsup_rsp);
4041}
4042testcase TC_proc_ss_for_unknown_session() runs on MTC_CT {
4043 var BSC_ConnHdlr vc_conn;
4044 f_init();
4045 vc_conn := f_start_handler(refers(f_tc_proc_ss_for_unknown_session), 110);
4046 vc_conn.done;
4047}
4048
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07004049/* MT (network-originated) USSD and no response to Paging Request */
4050friend function f_tc_proc_ss_paging_fail(charstring id, BSC_ConnHdlrPars pars)
4051runs on BSC_ConnHdlr {
4052 timer TP := 2.0; /* Paging timer */
4053
4054 f_init_handler(pars);
4055
4056 /* Perform location update */
4057 f_perform_lu();
4058
Vadim Yanitskiy70d15bf2020-01-09 22:51:01 +01004059 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07004060 f_create_gsup_expect(hex2str(g_pars.imsi));
4061
4062 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
4063 imsi := g_pars.imsi,
4064 sid := '20000444'O,
4065 state := OSMO_GSUP_SESSION_STATE_BEGIN,
4066 ss := f_rnd_octstring(23)
4067 );
4068
4069 /* Error with some cause value */
4070 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_ERR(
4071 imsi := g_pars.imsi,
4072 sid := '20000444'O,
4073 state := OSMO_GSUP_SESSION_STATE_END,
4074 cause := ? /* FIXME: introduce an enumerated type! */
4075 );
4076
4077 /* Initiate a MT USSD notification */
4078 GSUP.send(gsup_req);
4079
4080 /* Send it to MSC and expect Paging Request */
4081 TP.start;
4082 alt {
4083 [pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
4084 setverdict(pass);
4085 }
4086 [not pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
4087 setverdict(pass);
4088 }
4089 /* We don't expect anything else */
4090 [] as_unexp_gsup_or_bssap_msg();
4091 [] TP.timeout {
4092 setverdict(fail, "Timeout waiting for Paging Request");
4093 }
4094 }
4095
Vadim Yanitskiyd24b5252019-10-02 00:04:51 +07004096 /* Wait up to 20 seconds for GSUP PROC_SS_ERROR message.
4097 * OsmoMSC waits for Paging Response 10 seconds by default. */
4098 f_expect_gsup_msg(gsup_rsp, T_val := 20.0);
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07004099}
4100testcase TC_proc_ss_paging_fail() runs on MTC_CT {
4101 var BSC_ConnHdlr vc_conn;
4102 f_init();
4103 vc_conn := f_start_handler(refers(f_tc_proc_ss_paging_fail), 101);
4104 vc_conn.done;
4105}
4106
Vadim Yanitskiy29ba8d62019-06-16 15:19:41 +07004107/* MT (network-originated) USSD followed by immediate abort */
4108friend function f_tc_proc_ss_abort(charstring id, BSC_ConnHdlrPars pars)
4109runs on BSC_ConnHdlr {
4110 var octetstring facility := f_rnd_octstring(23);
4111 var OCT4 sid := '20000555'O;
4112 timer TP := 2.0;
4113
4114 f_init_handler(pars);
4115
4116 /* Perform location update */
4117 f_perform_lu();
4118
Vadim Yanitskiy70d15bf2020-01-09 22:51:01 +01004119 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy29ba8d62019-06-16 15:19:41 +07004120 f_create_gsup_expect(hex2str(g_pars.imsi));
4121
4122 /* PROC_SS_REQ initiates a mobile-originated SS/USSD session */
4123 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
4124 imsi := g_pars.imsi, sid := sid,
4125 state := OSMO_GSUP_SESSION_STATE_BEGIN,
4126 ss := facility
4127 );
4128
4129 /* On the MS side, we expect GSM 04.80 REGISTER message */
4130 var template PDU_ML3_NW_MS dtap_reg := tr_ML3_MT_SS_REGISTER(
4131 tid := 0, /* Most likely, it should be 0 */
4132 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
4133 facility := facility
4134 );
4135
4136 /* PROC_SS_ERR with SESSION_STATE_END terminates the SS/USSD session */
4137 var template (value) GSUP_PDU gsup_abort := ts_GSUP_PROC_SS_ERR(
4138 imsi := g_pars.imsi, sid := sid,
4139 state := OSMO_GSUP_SESSION_STATE_END,
4140 cause := 0 /* FIXME: introduce an enumerated type! */
4141 );
4142
4143 /* On the MS side, we expect GSM 04.80 REGISTER message */
4144 var template PDU_ML3_NW_MS dtap_rel := tr_ML3_MT_SS_RELEASE_COMPLETE(
4145 tid := 0, /* Most likely, it should be 0 */
4146 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
4147 cause := *, /* FIXME: expect some specific cause value */
4148 facility := omit
4149 );
4150
4151 /* Initiate a MT USSD with random payload */
4152 GSUP.send(gsup_req);
4153
4154 /* Expect Paging Request */
4155 TP.start;
4156 alt {
4157 [pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
4158 setverdict(pass);
4159 }
4160 [not pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
4161 setverdict(pass);
4162 }
4163 /* We don't expect anything else */
4164 [] as_unexp_gsup_or_bssap_msg();
4165 [] TP.timeout {
4166 setverdict(fail, "Timeout waiting for Paging Request");
4167 }
4168 }
4169
4170 /* Send Paging Response and establish connection */
4171 f_establish_fully(EST_TYPE_PAG_RESP);
4172 /* Expect MT REGISTER message with random facility */
4173 f_expect_mt_dtap_msg(dtap_reg);
4174
4175 /* HLR/EUSE decides to abort the session even
4176 * before getting any response from the MS */
4177 /* Initiate a MT USSD with random payload */
4178 GSUP.send(gsup_abort);
4179
4180 /* Expect RELEASE COMPLETE on ths MS side */
4181 f_expect_mt_dtap_msg(dtap_rel);
4182
4183 f_expect_clear();
4184}
4185testcase TC_proc_ss_abort() runs on MTC_CT {
4186 var BSC_ConnHdlr vc_conn;
4187 f_init();
4188 vc_conn := f_start_handler(refers(f_tc_proc_ss_abort), 102);
4189 vc_conn.done;
4190}
4191
Harald Weltee13cfb22019-04-23 16:52:02 +02004192
Vadim Yanitskiy1c9754d2020-01-07 21:56:55 +01004193/* Verify multiple concurrent MO SS/USSD transactions
4194 * (one subscriber - one transaction) */
4195testcase TC_multi_lu_and_mo_ussd() runs on MTC_CT {
4196 var BSC_ConnHdlr vc_conn[16];
4197 var integer i;
4198
4199 f_init();
4200
4201 for (i := 0; i < sizeof(vc_conn); i := i + 1) {
4202 vc_conn[i] := f_start_handler(refers(f_tc_lu_and_mo_ussd_single_request), 210 + i);
4203 }
4204
4205 for (i := 0; i < sizeof(vc_conn); i := i + 1) {
4206 vc_conn[i].done;
4207 }
4208}
4209
4210/* Verify multiple concurrent MT SS/USSD transactions
4211 * (one subscriber - one transaction) */
4212testcase TC_multi_lu_and_mt_ussd() runs on MTC_CT {
4213 var BSC_ConnHdlr vc_conn[16];
4214 var integer i;
4215 var OCT4 sid;
4216
4217 f_init();
4218
4219 for (i := 0; i < sizeof(vc_conn); i := i + 1) {
4220 sid := '200001'O & int2oct(i, 1); /* All transactions must use different session ID */
4221 vc_conn[i] := f_start_handler_with_pars(refers(f_tc_lu_and_mt_ussd_notification),
4222 f_init_pars(226 + i, gsup_sid := sid));
4223 }
4224
4225 for (i := 0; i < sizeof(vc_conn); i := i + 1) {
4226 vc_conn[i].done;
4227 }
4228}
4229
4230
Stefan Sperling89eb1f32018-12-17 15:06:20 +01004231/* A5/1 only permitted on network side; attempt an invalid CIPHER MODE COMPLETE with A5/3 which MSC should reject. */
4232private function f_tc_cipher_complete_with_invalid_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4233 pars.net.expect_auth := true;
4234 pars.net.expect_ciph := true;
4235 pars.net.kc_support := '02'O; /* A5/1 only */
4236 f_init_handler(pars);
4237
4238 g_pars.vec := f_gen_auth_vec_2g();
4239
4240 /* Can't use f_perform_lu() directly. Code below is based on it. */
4241
4242 /* tell GSUP dispatcher to send this IMSI to us */
4243 f_create_gsup_expect(hex2str(g_pars.imsi));
4244
4245 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
4246 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
Harald Weltedceacc72019-04-21 20:58:35 +02004247 f_cl3_or_initial_ue(l3_lu);
Stefan Sperling89eb1f32018-12-17 15:06:20 +01004248
4249 f_mm_auth();
4250
4251 var OCT1 a5_net := f_alg_mask_from_cm(g_pars.cm2);
4252 var OCT1 a5_intersect := g_pars.net.kc_support and4b a5_net;
4253 alt {
4254 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(a5_intersect, g_pars.vec.kc)) {
4255 BSSAP.send(ts_BSSMAP_CipherModeCompl(int2oct(4 /* "accept" A5/3 */, 1)));
4256 }
4257 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc)) {
4258 setverdict(fail, "Wrong ciphering algorithm mask in CiphModCmd");
4259 mtc.stop;
4260 }
4261 [] BSSAP.receive {
4262 setverdict(fail, "Unknown/unexpected BSSAP received");
4263 mtc.stop;
4264 }
4265 }
Harald Welte79f1e452020-08-18 22:55:02 +02004266 f_expect_common_id();
Stefan Sperling89eb1f32018-12-17 15:06:20 +01004267
4268 /* Expect LU reject from MSC. */
4269 alt {
4270 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
4271 setverdict(pass);
4272 }
4273 [] BSSAP.receive {
4274 setverdict(fail, "Unknown/unexpected BSSAP received");
4275 mtc.stop;
4276 }
4277 }
Stefan Sperlingc620b352018-12-18 17:23:36 +01004278 f_expect_clear();
Stefan Sperling89eb1f32018-12-17 15:06:20 +01004279}
4280
4281testcase TC_cipher_complete_with_invalid_cipher() runs on MTC_CT {
4282 var BSC_ConnHdlr vc_conn;
4283 f_init();
4284 f_vty_config(MSCVTY, "network", "encryption a5 1");
4285
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02004286 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 +01004287 vc_conn.done;
4288}
4289
Harald Welteb2284bd2019-05-10 11:30:43 +02004290/* Location Update with invalid (non-matching) MCC/MNC reported on BSSMAP level from BSC */
4291friend function f_tc_lu_with_invalid_mcc_mnc(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4292 f_init_handler(pars);
4293
4294 /* tell GSUP dispatcher to send this IMSI to us */
4295 f_create_gsup_expect(hex2str(g_pars.imsi));
4296
4297 /* modify the cell ID which will be used to construct the COMPLELTE L3 or InitialUE */
4298 g_pars.cell_id := valueof(ts_CellId_CGI('333'H, '22'H, 23, 42));
4299
4300 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
4301 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
4302 f_cl3_or_initial_ue(l3_lu);
Harald Welte79f1e452020-08-18 22:55:02 +02004303 f_expect_common_id();
Harald Welteb2284bd2019-05-10 11:30:43 +02004304
4305 /* Expect LU reject from MSC. */
4306 alt {
4307 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
4308 setverdict(pass);
4309 }
4310 [] BSSAP.receive {
4311 setverdict(fail, "Unknown/unexpected BSSAP received");
4312 mtc.stop;
4313 }
4314 }
4315 f_expect_clear();
4316}
4317testcase TC_lu_with_invalid_mcc_mnc() runs on MTC_CT {
4318 var BSC_ConnHdlr vc_conn;
4319 f_init();
4320 vc_conn := f_start_handler(refers(f_tc_lu_with_invalid_mcc_mnc), 54);
4321 vc_conn.done;
4322}
4323
Stefan Sperlinga2d59c62018-12-18 16:32:44 +01004324private function f_tc_cipher_complete_without_alg(charstring id, BSC_ConnHdlrPars pars, octetstring kc_support) runs on BSC_ConnHdlr {
4325 pars.net.expect_auth := true;
4326 pars.net.expect_ciph := true;
4327 pars.net.kc_support := kc_support;
4328 f_init_handler(pars);
4329
4330 g_pars.vec := f_gen_auth_vec_2g();
4331
4332 /* Can't use f_perform_lu() directly. Code below is based on it. */
4333
4334 /* tell GSUP dispatcher to send this IMSI to us */
4335 f_create_gsup_expect(hex2str(g_pars.imsi));
4336
4337 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
4338 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
4339 f_cl3_or_initial_ue(l3_lu);
4340
4341 f_mm_auth();
4342
4343 var OCT1 a5_net := f_alg_mask_from_cm(g_pars.cm2);
4344 var OCT1 a5_intersect := g_pars.net.kc_support and4b a5_net;
4345 alt {
4346 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(a5_intersect, g_pars.vec.kc)) {
4347 BSSAP.send(ts_BSSMAP_CipherModeComplAlg(omit));
4348 }
4349 [] BSSAP.receive(tr_BSSMAP_ClassmarkReq) {
4350 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
4351 repeat;
4352 }
4353 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc)) {
4354 setverdict(fail, "Wrong ciphering algorithm mask in CiphModCmd");
4355 mtc.stop;
4356 }
4357 [] BSSAP.receive {
4358 setverdict(fail, "Unknown/unexpected BSSAP received");
4359 mtc.stop;
4360 }
4361 }
Harald Welte79f1e452020-08-18 22:55:02 +02004362 f_expect_common_id();
Stefan Sperlinga2d59c62018-12-18 16:32:44 +01004363
4364 /* TODO: Verify MSC is using the best cipher available! How? */
4365
4366 f_msc_lu_hlr();
4367 f_accept_reject_lu();
4368 f_expect_clear();
4369 setverdict(pass);
4370}
4371
4372/* A5/1 only permitted on network side; attempt CIPHER MODE COMPLETE without specifying the accepted algorithm. */
4373private function f_tc_cipher_complete_1_without_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4374 f_tc_cipher_complete_without_alg(id, pars, '02'O /* A5/1 only */);
4375}
4376
4377/* A5/3 only permitted on network side; attempt CIPHER MODE COMPLETE without specifying the accepted algorithm. */
4378private function f_tc_cipher_complete_3_without_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4379 f_tc_cipher_complete_without_alg(id, pars, '08'O /* A5/3 only */);
4380}
4381
4382/* A5/1 + A5/3 permitted on network side; attempt CIPHER MODE COMPLETE without specifying the accepted algorithm. */
4383private function f_tc_cipher_complete_13_without_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4384 f_tc_cipher_complete_without_alg(id, pars, '0A'O /* A5/1 and A5/3 enabled */);
4385}
4386
4387testcase TC_cipher_complete_1_without_cipher() runs on MTC_CT {
4388 var BSC_ConnHdlr vc_conn;
4389 f_init();
4390 f_vty_config(MSCVTY, "network", "encryption a5 1");
4391
4392 vc_conn := f_start_handler(refers(f_tc_cipher_complete_1_without_cipher), 53);
4393 vc_conn.done;
4394}
4395
4396testcase TC_cipher_complete_3_without_cipher() runs on MTC_CT {
4397 var BSC_ConnHdlr vc_conn;
4398 f_init();
4399 f_vty_config(MSCVTY, "network", "encryption a5 3");
4400
4401 vc_conn := f_start_handler(refers(f_tc_cipher_complete_3_without_cipher), 54);
4402 vc_conn.done;
4403}
4404
4405testcase TC_cipher_complete_13_without_cipher() runs on MTC_CT {
4406 var BSC_ConnHdlr vc_conn;
4407 f_init();
4408 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
4409
4410 vc_conn := f_start_handler(refers(f_tc_cipher_complete_13_without_cipher), 55);
4411 vc_conn.done;
4412}
Harald Welteb2284bd2019-05-10 11:30:43 +02004413
Harald Weltef640a012018-04-14 17:49:21 +02004414/* TODO (SMS):
4415 * different user data lengths
4416 * SMPP transaction mode with unsuccessful delivery
4417 * queued MT-SMS with no paging response + later delivery
4418 * different data coding schemes
4419 * multi-part SMS
4420 * user-data headers
4421 * TP-PID for SMS to SIM
4422 * behavior if SMS memory is full + RP-SMMA
4423 * delivery reports
4424 * SMPP osmocom extensions
4425 * more-messages-to-send
4426 * SMS during ongoing call (SACCH/SAPI3)
4427 */
4428
4429/* TODO (General):
Harald Welteba7b6d92018-01-23 21:32:34 +01004430 * continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
4431 * malformed messages (missing IE, invalid message type): properly rejected?
4432 * MT call while LU or is ongoing: Do we use existing lchan or page while lchan active?
4433 * 3G/2G auth permutations
4434 * encryption algorithms vs. classmark vs. vty config
Harald Welteba7b6d92018-01-23 21:32:34 +01004435 * send new transaction after/during clear (like SMS, ...)
Harald Welte45164da2018-01-24 12:51:27 +01004436 * too long L3 INFO in DTAP
4437 * too long / padded BSSAP
4438 * too long / short TLV values
Harald Welteba7b6d92018-01-23 21:32:34 +01004439 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01004440
Harald Weltee13cfb22019-04-23 16:52:02 +02004441/***********************************************************************
4442 * SGsAP Testing
4443 ***********************************************************************/
4444
Philipp Maier948747b2019-04-02 15:22:33 +02004445/* Check if a subscriber exists in the VLR */
4446private function f_ctrl_subscr_in_vlr(charstring imsi_or_msisdn) runs on BSC_ConnHdlr return boolean {
4447
4448 var CtrlValue active_subsribers;
4449 var integer rc;
4450 active_subsribers := f_ctrl_get(IPA_CTRL, "subscriber-list-active-v1");
4451
4452 rc := f_strstr(active_subsribers, imsi_or_msisdn);
4453 if (rc < 0) {
4454 return false;
4455 }
4456
4457 return true;
4458}
4459
Harald Welte4263c522018-12-06 11:56:27 +01004460/* Perform a location updatye at the A-Interface and run some checks to confirm
4461 * that everything is back to normal. */
4462private function f_sgsap_bssmap_screening() runs on BSC_ConnHdlr {
4463 var SmsParameters spars := valueof(t_SmsPars);
4464
4465 /* Perform a location update, the SGs association is expected to fall
4466 * back to NULL */
4467 f_perform_lu();
4468 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4469
4470 /* Trigger a paging request and expect the paging on BSSMAP, this is
4471 * to make sure that pagings are sent throught the A-Interface again
4472 * and not throught the SGs interface.*/
Harald Welte6811d102019-04-14 22:23:14 +02004473 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Harald Welte4263c522018-12-06 11:56:27 +01004474 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4475
4476 alt {
Harald Weltee13cfb22019-04-23 16:52:02 +02004477 [g_pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)); {
4478 setverdict(pass);
4479 }
Harald Welte62113fc2019-05-09 13:04:02 +02004480 [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 +01004481 setverdict(pass);
4482 }
4483 [] SGsAP.receive {
4484 setverdict(fail, "Received unexpected message on SGs");
4485 }
4486 }
4487
4488 /* Send an SMS to make sure that also payload messages are routed
4489 * throught the A-Interface again */
4490 f_establish_fully(EST_TYPE_MO_SMS);
4491 f_mo_sms(spars);
4492 f_expect_clear();
4493}
4494
4495private function f_tc_sgsap_reset(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4496 var charstring vlr_name;
4497 f_init_handler(pars);
4498
4499 vlr_name := f_sgsap_reset_mme(mp_mme_name);
4500 log("VLR name: ", vlr_name);
4501 setverdict(pass);
Neels Hofmeyrc0b520d2019-03-06 15:35:50 +01004502 f_sleep(1.0);
Harald Welte4263c522018-12-06 11:56:27 +01004503}
4504
4505testcase TC_sgsap_reset() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004506 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004507 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004508 f_init(1, true);
4509 pars := f_init_pars(11810, true);
4510 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_reset), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004511 vc_conn.done;
4512}
4513
4514/* like f_mm_auth() but for SGs */
4515function f_mm_auth_sgs() runs on BSC_ConnHdlr {
4516 if (g_pars.net.expect_auth) {
4517 g_pars.vec := f_gen_auth_vec_3g();
4518 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
4519 g_pars.vec.sres,
4520 g_pars.vec.kc,
4521 g_pars.vec.ik,
4522 g_pars.vec.ck,
4523 g_pars.vec.autn,
4524 g_pars.vec.res));
4525 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
4526 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
4527 SGsAP.receive(tr_ML3_MT_MM_AUTH_REQ_3G(g_pars.vec.rand, g_pars.vec.autn));
4528 SGsAP.send(ts_ML3_MT_MM_AUTH_RESP_3G(g_pars.vec.sres, g_pars.vec.res));
4529 }
4530}
4531
4532/* like f_perform_lu(), but on SGs rather than BSSAP */
4533function f_sgs_perform_lu() runs on BSC_ConnHdlr {
4534 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4535 var PDU_SGsAP lur;
4536 var PDU_SGsAP lua;
4537 var PDU_SGsAP mm_info;
4538 var octetstring mm_info_dtap;
4539
4540 /* tell GSUP dispatcher to send this IMSI to us */
4541 f_create_gsup_expect(hex2str(g_pars.imsi));
4542
4543 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
Pau Espin Pedrol3768a6f2021-04-28 14:24:23 +02004544 ts_SGsAP_LAI('901'H, '70'H, 2342),
4545 ts_SGsAP_TAI('901'H, '70'H, 555)));
Harald Welte4263c522018-12-06 11:56:27 +01004546 /* Old LAI, if MS sends it */
4547 /* TMSI status, if MS has no valid TMSI */
4548 /* IMEISV, if it supports "automatic device detection" */
4549 /* TAI, if available in MME */
4550 /* E-CGI, if available in MME */
4551 SGsAP.send(lur);
4552
4553 /* FIXME: is this really done over SGs? The Ue is already authenticated
4554 * via the MME ... */
4555 f_mm_auth_sgs();
4556
4557 /* Expect MSC to perform LU with HLR */
4558 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
4559 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
4560 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
4561 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
4562
4563 alt {
4564 [] SGsAP.receive(tr_SGsAP_LU_ACCEPT(g_pars.imsi, ?)) -> value lua {
4565 if (isvalue(lua.sGsAP_LOCATION_UPDATE_ACCEPT.newTMSIorIMSI.iD.iD.tmsi_ptmsi.octets)) {
4566 g_pars.tmsi :=lua.sGsAP_LOCATION_UPDATE_ACCEPT.newTMSIorIMSI.iD.iD.tmsi_ptmsi.octets
4567 SGsAP.send(ts_SGsAP_TMSI_REALL_CMPL(g_pars.imsi));
4568 }
4569 setverdict(pass);
4570 }
4571 [] SGsAP.receive(tr_SGsAP_LU_REJECT(g_pars.imsi, ?, ?)) {
4572 setverdict(fail, "Received LU-REJECT instead of ACCEPT");
4573 }
4574 [] SGsAP.receive {
4575 setverdict(fail, "Received unexpected message on SGs");
4576 }
4577 }
4578
4579 /* Check MM information */
4580 if (mp_mm_info == true) {
4581 SGsAP.receive(tr_SGsAP_MM_INFO_REQ(g_pars.imsi, ?)) -> value mm_info;
4582 mm_info_dtap := '0532'O & mm_info.sGsAP_MM_INFORMATION_REQUEST.mM_Information.information;
4583 if (not match(dec_PDU_ML3_NW_MS(mm_info_dtap), tr_ML3_MT_MM_Info)) {
4584 setverdict(fail, "Unexpected MM Information");
4585 }
4586 }
4587
4588 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4589}
4590
4591private function f_tc_sgsap_lu(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4592 f_init_handler(pars);
4593 f_sgs_perform_lu();
4594 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4595
4596 f_sgsap_bssmap_screening();
4597
4598 setverdict(pass);
4599}
4600testcase TC_sgsap_lu() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004601 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004602 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004603 f_init(1, true);
4604 pars := f_init_pars(11811, true);
4605 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004606 vc_conn.done;
4607}
4608
4609/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
4610private function f_tc_sgsap_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4611 f_init_handler(pars);
4612 var PDU_SGsAP lur;
4613
4614 f_create_gsup_expect(hex2str(g_pars.imsi));
4615 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4616 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
4617 ts_SGsAP_LAI('901'H, '70'H, 2342)));
4618 SGsAP.send(lur);
4619
4620 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
4621 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
4622 alt {
4623 [] SGsAP.receive(tr_SGsAP_LU_REJECT(g_pars.imsi, ?, ?)) {
4624 setverdict(pass);
4625 }
4626 [] SGsAP.receive(tr_SGsAP_LU_ACCEPT(g_pars.imsi, ?)) {
4627 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
4628 mtc.stop;
4629 }
4630 [] SGsAP.receive {
4631 setverdict(fail, "Received unexpected message on SGs");
4632 }
4633 }
4634
4635 f_sgsap_bssmap_screening();
4636
4637 setverdict(pass);
4638}
4639testcase TC_sgsap_lu_imsi_reject() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004640 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004641 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004642 f_init(1, true);
4643 pars := f_init_pars(11812, true);
Harald Welte4263c522018-12-06 11:56:27 +01004644
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004645 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu_imsi_reject), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004646 vc_conn.done;
4647}
4648
4649/* Do LU by IMSI, but then remain silent so that Ts6-1 times out */
4650private function f_tc_sgsap_lu_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4651 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4652 var PDU_SGsAP lur;
4653
4654 f_init_handler(pars);
4655
4656 /* tell GSUP dispatcher to send this IMSI to us */
4657 f_create_gsup_expect(hex2str(g_pars.imsi));
4658
4659 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
4660 ts_SGsAP_LAI('901'H, '70'H, 2342)));
4661 /* Old LAI, if MS sends it */
4662 /* TMSI status, if MS has no valid TMSI */
4663 /* IMEISV, if it supports "automatic device detection" */
4664 /* TAI, if available in MME */
4665 /* E-CGI, if available in MME */
4666 SGsAP.send(lur);
4667
4668 /* FIXME: is this really done over SGs? The Ue is already authenticated
4669 * via the MME ... */
4670 f_mm_auth_sgs();
4671
4672 /* Expect MSC to perform LU with HLR */
4673 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
4674 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
4675 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
4676 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
4677
4678 alt {
4679 [] SGsAP.receive(tr_SGsAP_LU_ACCEPT(g_pars.imsi, ?)) {
4680 setverdict(pass);
4681 }
4682 [] SGsAP.receive(tr_SGsAP_LU_REJECT(g_pars.imsi, ?, ?)) {
4683 setverdict(fail, "Received LU-REJECT instead of ACCEPT");
4684 }
4685 [] SGsAP.receive {
4686 setverdict(fail, "Received unexpected message on SGs");
4687 }
4688 }
4689
4690 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4691
4692 /* Wait until the VLR has abort the TMSI reallocation procedure */
4693 f_sleep(45.0);
4694
4695 /* The outcome does not change the SGs state, see also 5.2.3.4 */
4696 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4697
4698 f_sgsap_bssmap_screening();
4699
4700 setverdict(pass);
4701}
4702testcase TC_sgsap_lu_and_nothing() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004703 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004704 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004705 f_init(1, true);
4706 pars := f_init_pars(11813, true);
Harald Welte4263c522018-12-06 11:56:27 +01004707
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004708 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu_and_nothing), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004709 vc_conn.done;
4710}
4711
4712private function f_tc_sgsap_expl_imsi_det_eps(charstring id, BSC_ConnHdlrPars pars)
4713runs on BSC_ConnHdlr {
4714 f_init_handler(pars);
4715 f_sgs_perform_lu();
4716 f_sleep(3.0);
4717
4718 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4719 SGsAP.send(ts_SGsAP_EPS_DETACH_IND(g_pars.imsi, mme_name, UE_initiated));
4720 SGsAP.receive(tr_SGsAP_EPS_DETACH_ACK(g_pars.imsi));
4721 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4722
4723 f_sgsap_bssmap_screening();
4724
4725 setverdict(pass);
4726}
4727testcase TC_sgsap_expl_imsi_det_eps() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004728 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004729 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004730 f_init(1, true);
4731 pars := f_init_pars(11814, true);
4732 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_expl_imsi_det_eps), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004733 vc_conn.done;
4734}
4735
Philipp Maierfc19f172019-03-21 11:17:54 +01004736private function f_tc_sgsap_impl_imsi_det_eps(charstring id, BSC_ConnHdlrPars pars)
4737runs on BSC_ConnHdlr {
4738 f_init_handler(pars);
4739 f_sgs_perform_lu();
4740 f_sleep(3.0);
4741
4742 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4743 SGsAP.send(ts_SGsAP_EPS_DETACH_IND(g_pars.imsi, mme_name, network_initiated));
4744 SGsAP.receive(tr_SGsAP_EPS_DETACH_ACK(g_pars.imsi));
4745 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4746
4747 f_sgsap_bssmap_screening();
4748
4749 setverdict(pass);
4750}
4751testcase TC_sgsap_impl_imsi_det_eps() runs on MTC_CT {
4752 var BSC_ConnHdlrPars pars;
4753 var BSC_ConnHdlr vc_conn;
4754 f_init(1, true);
4755 pars := f_init_pars(11814, true);
4756 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_impl_imsi_det_eps), pars);
4757 vc_conn.done;
4758}
4759
Harald Welte4263c522018-12-06 11:56:27 +01004760private function f_tc_sgsap_expl_imsi_det_noneps(charstring id, BSC_ConnHdlrPars pars)
4761runs on BSC_ConnHdlr {
4762 f_init_handler(pars);
4763 f_sgs_perform_lu();
4764 f_sleep(3.0);
4765
4766 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4767 SGsAP.send(ts_SGsAP_IMSI_DETACH_IND(g_pars.imsi, mme_name, combined_UE_initiated));
4768 SGsAP.receive(tr_SGsAP_IMSI_DETACH_ACK(g_pars.imsi));
Philipp Maierd08e7e72019-04-02 15:27:10 +02004769
4770 if (f_ctrl_subscr_in_vlr(hex2str(g_pars.imsi))) {
4771 setverdict(fail, "subscriber not removed from VLR");
4772 }
Harald Welte4263c522018-12-06 11:56:27 +01004773
4774 f_sgsap_bssmap_screening();
4775
4776 setverdict(pass);
4777}
4778testcase TC_sgsap_expl_imsi_det_noneps() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004779 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004780 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004781 f_init(1, true);
4782 pars := f_init_pars(11815, true);
4783 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_expl_imsi_det_noneps), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004784 vc_conn.done;
4785}
4786
Philipp Maier5d812702019-03-21 10:51:26 +01004787private function f_tc_sgsap_impl_imsi_det_noneps(charstring id, BSC_ConnHdlrPars pars)
4788runs on BSC_ConnHdlr {
4789 f_init_handler(pars);
4790 f_sgs_perform_lu();
4791 f_sleep(3.0);
4792
4793 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4794 SGsAP.send(ts_SGsAP_IMSI_DETACH_IND(g_pars.imsi, mme_name, implicit_network_initiated));
4795 SGsAP.receive(tr_SGsAP_IMSI_DETACH_ACK(g_pars.imsi));
4796
4797 if (f_ctrl_subscr_in_vlr(hex2str(g_pars.imsi))) {
4798 setverdict(fail, "subscriber not removed from VLR");
4799 }
4800
4801 f_sgsap_bssmap_screening();
4802
4803 setverdict(pass);
4804}
4805testcase TC_sgsap_impl_imsi_det_noneps() runs on MTC_CT {
4806 var BSC_ConnHdlrPars pars;
4807 var BSC_ConnHdlr vc_conn;
4808 f_init(1, true);
4809 pars := f_init_pars(11815, true);
4810 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_impl_imsi_det_noneps), pars);
4811 vc_conn.done;
4812}
4813
Harald Welte4263c522018-12-06 11:56:27 +01004814/* Trigger a paging request via VTY and send a paging reject in response */
4815private function f_tc_sgsap_paging_rej(charstring id, BSC_ConnHdlrPars pars)
4816runs on BSC_ConnHdlr {
4817 f_init_handler(pars);
4818 f_sgs_perform_lu();
4819 f_sleep(1.0);
4820
4821 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4822 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
4823 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4824 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4825
4826 /* Initiate paging via VTY */
4827 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4828 alt {
4829 [] SGsAP.receive(exp_resp) {
4830 setverdict(pass);
4831 }
4832 [] SGsAP.receive {
4833 setverdict(fail, "Received unexpected message on SGs");
4834 }
4835 }
4836
4837 /* Now reject the paging */
4838 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, IMSI_unknown));
4839
4840 /* Wait for the states inside the MSC to settle and check the state
4841 * of the SGs Association */
4842 f_sleep(1.0);
4843 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4844
4845 /* FIXME: At the moment we send an IMSI_unknown as cause code, which is fine,
4846 * but we also need to cover tha case where the cause code indicates an
4847 * "IMSI detached for EPS services". In those cases the VLR is expected to
4848 * try paging on tha A/Iu interface. This will be another testcase similar to
4849 * this one, but extended with checks for the presence of the A/Iu paging
4850 * messages. */
4851
4852 f_sgsap_bssmap_screening();
4853
4854 setverdict(pass);
4855}
4856testcase TC_sgsap_paging_rej() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004857 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004858 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004859 f_init(1, true);
4860 pars := f_init_pars(11816, true);
4861 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_rej), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004862 vc_conn.done;
4863}
4864
4865/* Trigger a paging request via VTY and send a paging reject that indicates
4866 * that the subscriber intentionally rejected the call. */
4867private function f_tc_sgsap_paging_subscr_rej(charstring id, BSC_ConnHdlrPars pars)
4868runs on BSC_ConnHdlr {
4869 f_init_handler(pars);
4870 f_sgs_perform_lu();
4871 f_sleep(1.0);
4872
4873 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4874 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
4875 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4876 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4877
4878 /* Initiate paging via VTY */
4879 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4880 alt {
4881 [] SGsAP.receive(exp_resp) {
4882 setverdict(pass);
4883 }
4884 [] SGsAP.receive {
4885 setverdict(fail, "Received unexpected message on SGs");
4886 }
4887 }
4888
4889 /* Now reject the paging */
4890 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, user_rejected_mobile_terminating_CS_fallback_call));
4891
4892 /* Wait for the states inside the MSC to settle and check the state
4893 * of the SGs Association */
4894 f_sleep(1.0);
4895 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4896
4897 /* FIXME: The VLR is supposed to trigger an User Determined User Busy (UDUB) as specified
4898 * in 3GPP TS 24.082, this is not yet implemented in the MSC or in this tests, we need
4899 * to check back how this works and how it can be tested */
4900
4901 f_sgsap_bssmap_screening();
4902
4903 setverdict(pass);
4904}
4905testcase TC_sgsap_paging_subscr_rej() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004906 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004907 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004908 f_init(1, true);
4909 pars := f_init_pars(11817, true);
4910 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_subscr_rej), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004911 vc_conn.done;
4912}
4913
4914/* Trigger a paging request via VTY and send an UE unreacable messge in response */
4915private function f_tc_sgsap_paging_ue_unr(charstring id, BSC_ConnHdlrPars pars)
4916runs on BSC_ConnHdlr {
4917 f_init_handler(pars);
4918 f_sgs_perform_lu();
4919 f_sleep(1.0);
4920
4921 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4922 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
4923 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4924 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4925
4926 /* Initiate paging via VTY */
4927 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4928 alt {
4929 [] SGsAP.receive(exp_resp) {
4930 setverdict(pass);
4931 }
4932 [] SGsAP.receive {
4933 setverdict(fail, "Received unexpected message on SGs");
4934 }
4935 }
4936
4937 /* Now pretend that the UE is unreachable */
4938 SGsAP.send(ts_SGsAP_UE_UNREACHABLE(g_pars.imsi, UE_unreachable));
4939
4940 /* Wait for the states inside the MSC to settle and check the state
4941 * of the SGs Association. */
4942 f_sleep(1.0);
4943 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4944
4945 f_sgsap_bssmap_screening();
4946
4947 setverdict(pass);
4948}
4949testcase TC_sgsap_paging_ue_unr() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004950 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004951 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004952 f_init(1, true);
4953 pars := f_init_pars(11818, true);
4954 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_ue_unr), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004955 vc_conn.done;
4956}
4957
4958/* Trigger a paging request via VTY but don't respond to it */
4959private function f_tc_sgsap_paging_and_nothing(charstring id, BSC_ConnHdlrPars pars)
4960runs on BSC_ConnHdlr {
4961 f_init_handler(pars);
4962 f_sgs_perform_lu();
4963 f_sleep(1.0);
4964
4965 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4966 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 +02004967 var template PDU_SGsAP exp_serv_abrt := ts_SGsAP_SERVICE_ABORT_REQ(g_pars.imsi);
Harald Welte4263c522018-12-06 11:56:27 +01004968 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4969 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4970
4971 /* Initiate paging via VTY */
4972 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4973 alt {
4974 [] SGsAP.receive(exp_resp) {
4975 setverdict(pass);
4976 }
4977 [] SGsAP.receive {
4978 setverdict(fail, "Received unexpected message on SGs");
4979 }
4980 }
4981
Philipp Maier34218102019-09-24 09:15:49 +02004982 /* While we are doing nothing, expect an SGsAP-SERVICE-ABORT-REQUEST
4983 * after some time */
4984 timer T := 10.0;
4985 T.start
4986 alt {
4987 [] SGsAP.receive(exp_serv_abrt)
4988 {
4989 setverdict(pass);
4990 }
4991 [] SGsAP.receive {
4992 setverdict(fail, "unexpected SGsAP message received");
4993 self.stop;
4994 }
4995 [] T.timeout {
4996 setverdict(fail, "MSC did not send SGsAP-SERVICE-ABORT-REQUEST");
4997 self.stop;
4998 }
4999 }
5000
5001 /* The SGs association must remain unchanged. */
Harald Welte4263c522018-12-06 11:56:27 +01005002 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5003
5004 f_sgsap_bssmap_screening();
5005
5006 setverdict(pass);
5007}
5008testcase TC_sgsap_paging_and_nothing() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005009 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005010 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005011 f_init(1, true);
5012 pars := f_init_pars(11819, true);
5013 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_and_nothing), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005014 vc_conn.done;
5015}
5016
5017/* Trigger a paging request via VTY and slip in an LU */
5018private function f_tc_sgsap_paging_and_lu(charstring id, BSC_ConnHdlrPars pars)
5019runs on BSC_ConnHdlr {
5020 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5021 f_init_handler(pars);
5022
5023 /* First we prepar the situation, where the SGs association is in state
5024 * NULL and the confirmed by radio contact indicator is set to false
5025 * as well. This can be archived by performing an SGs LU and then
5026 * resetting the VLR */
5027 f_sgs_perform_lu();
5028 f_sgsap_reset_mme(mp_mme_name);
5029 f_sleep(1.0);
5030 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
5031
5032 /* Perform a paging, expect the paging messages on the SGs interface */
5033 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
5034 alt {
5035 [] SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit)) {
5036 setverdict(pass);
5037 }
5038 [] SGsAP.receive {
5039 setverdict(fail, "Received unexpected message on SGs");
5040 }
5041 }
5042
5043 /* Perform the LU as normal */
5044 f_sgs_perform_lu();
5045 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5046
5047 /* Expect a new paging request right after the LU */
5048 alt {
5049 [] SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit)) {
5050 setverdict(pass);
5051 }
5052 [] SGsAP.receive {
5053 setverdict(fail, "Received unexpected message on SGs");
5054 }
5055 }
5056
5057 /* Test is done now, lets round everything up by rejecting the paging
5058 * cleanly. */
5059 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, user_rejected_mobile_terminating_CS_fallback_call));
5060 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5061
5062 f_sgsap_bssmap_screening();
5063
5064 setverdict(pass);
5065}
5066testcase TC_sgsap_paging_and_lu() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005067 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005068 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005069 f_init(1, true);
5070 pars := f_init_pars(11820, true);
5071 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_and_lu), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005072 vc_conn.done;
5073}
5074
5075/* Send unexpected unit-data through the SGs interface */
5076private function f_tc_sgsap_unexp_ud(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5077 f_init_handler(pars);
5078 f_sleep(1.0);
5079
5080 /* This simulates what happens when a subscriber without SGs
5081 * association gets unitdata via the SGs interface. */
5082
5083 /* Make sure the subscriber exists and the SGs association
5084 * is in NULL state */
5085 f_perform_lu();
5086 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
5087
5088 /* Send some random unit data, the MSC/VLR should send a release
5089 * immediately. */
5090 SGsAP.send(ts_SGsAP_UL_UD(pars.imsi,'1234'O));
5091 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, IMSI_detached_for_EPS_nonEPS_services));
5092
5093 f_sgsap_bssmap_screening();
5094
5095 setverdict(pass);
5096}
5097testcase TC_sgsap_unexp_ud() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005098 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005099 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005100 f_init(1, true);
5101 pars := f_init_pars(11821, true);
5102 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_unexp_ud), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005103 vc_conn.done;
5104}
5105
5106/* Send unsolicited unit-data through the SGs interface */
5107private function f_tc_sgsap_unsol_ud(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5108 f_init_handler(pars);
5109 f_sleep(1.0);
5110
5111 /* This simulates what happens when the MME attempts to send unitdata
5112 * to a subscriber that is completely unknown to the VLR */
5113
5114 /* Send some random unit data, the MSC/VLR should send a release
5115 * immediately. */
5116 SGsAP.send(ts_SGsAP_UL_UD(pars.imsi,'1234'O));
5117 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, IMSI_unknown));
5118
5119 f_sgsap_bssmap_screening();
5120
Harald Welte4d15fa72020-08-19 08:58:28 +02005121 /* clean-up VLR state about this subscriber */
5122 f_imsi_detach_by_imsi();
5123
Harald Welte4263c522018-12-06 11:56:27 +01005124 setverdict(pass);
5125}
5126testcase TC_sgsap_unsol_ud() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005127 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005128 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005129 f_init(1, true);
5130 pars := f_init_pars(11822, true);
5131 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_unsol_ud), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005132 vc_conn.done;
5133}
5134
5135private altstep as_other_sms_sgs() runs on BSC_ConnHdlr {
5136 /* FIXME: Match an actual payload (second questionmark), the type is
5137 * octetstring, how do we use a tr_PDU_DTAP_MT here? */
5138 [] SGsAP.receive(tr_SGsAP_DL_UD(?,?)) {
5139 setverdict(fail, "Unexpected SMS related PDU from MSC");
5140 mtc.stop;
5141 }
5142}
5143
5144/* receive a MT-SMS delivered from the MSC/SMSC over an already existing SGsAP connection */
5145function f_mt_sms_sgs(inout SmsParameters spars)
5146runs on BSC_ConnHdlr {
5147 var template (value) TPDU_RP_DATA_MS_SGSN tp_mo;
5148 var template (value) RPDU_MS_SGSN rp_mo;
5149 var template (value) PDU_ML3_MS_NW l3_mo;
5150
5151 var template TPDU_RP_DATA_SGSN_MS tp_mt;
5152 var template RPDU_SGSN_MS rp_mt;
5153 var template PDU_ML3_NW_MS l3_mt;
5154
5155 var PDU_ML3_NW_MS sgsap_l3_mt;
5156
5157 var default d := activate(as_other_sms_sgs());
5158
5159 /* Expect CP-DATA(RP-DATA(SMS-DELIVER)) */
5160 tp_mt := tr_SMS_DELIVER(?, spars.tp.ud, spars.tp.pid, spars.tp.dcs, ?);
Vadim Yanitskiy04dd5f72019-12-13 15:45:44 +09005161 rp_mt := tr_RP_DATA_MT(?, spars.rp.smsc_addr, omit, tp_mt);
Harald Welte4263c522018-12-06 11:56:27 +01005162 l3_mt := tr_ML3_MT_SMS(?, c_TIF_ORIG, tr_CP_DATA_MT(rp_mt));
5163
5164 SGsAP.receive(l3_mt) -> value sgsap_l3_mt;
5165
5166 /* Extract relevant identifiers */
5167 spars.tid := bit2int(sgsap_l3_mt.tiOrSkip.transactionId.tio);
5168 spars.rp.msg_ref := sgsap_l3_mt.msgs.sms.cP_DATA.cP_User_Data.cP_RPDU.rP_DATA_SGSN_MS.rP_MessageReference;
5169
5170 /* send CP-ACK for CP-DATA just received */
5171 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_REPL, ts_CP_ACK_MO);
5172
5173 SGsAP.send(l3_mo);
5174
5175 /* send RP-ACK for RP-DATA */
5176 rp_mo := ts_RP_ACK_MO(spars.rp.msg_ref);
5177 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_REPL, ts_CP_DATA_MO(rp_mo));
5178
5179 SGsAP.send(l3_mo);
5180
5181 /* expect CP-ACK for CP-DATA(RP-ACK) just sent */
5182 l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_ORIG, tr_CP_ACK_MT);
5183
5184 SGsAP.receive(l3_mt);
5185
5186 deactivate(d);
5187
5188 setverdict(pass);
5189}
5190
5191/* submit a MO-SMS to MSC/SMSC over an already existing SGsAP connection */
5192function f_mo_sms_sgs(inout SmsParameters spars)
5193runs on BSC_ConnHdlr {
5194 var template (value) TPDU_RP_DATA_MS_SGSN tp_mo;
5195 var template (value) RPDU_MS_SGSN rp_mo;
5196 var template (value) PDU_ML3_MS_NW l3_mo;
5197
5198 var template TPDU_RP_DATA_SGSN_MS tp_mt;
5199 var template RPDU_SGSN_MS rp_mt;
5200 var template PDU_ML3_NW_MS l3_mt;
5201
5202 var default d := activate(as_other_sms_sgs());
5203
5204 /* just in case this is routed to SMPP.. */
5205 f_create_smpp_expect(hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue));
5206
5207 tp_mo := ts_SMS_SUBMIT(spars.tp.msg_ref, spars.tp.da, spars.tp.pid, spars.tp.dcs,
5208 spars.tp.udl, spars.tp.ud);
Vadim Yanitskiy437b5a62019-12-15 14:13:39 +09005209 rp_mo := ts_RP_DATA_MO(spars.rp.msg_ref, omit, spars.rp.smsc_addr, tp_mo);
Harald Welte4263c522018-12-06 11:56:27 +01005210 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_DATA_MO(rp_mo));
5211
5212 SGsAP.send(l3_mo);
5213
5214 /* receive CP-ACK for CP-DATA above */
5215 SGsAP.receive(tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_ACK_MT));
5216
5217 if (ispresent(spars.exp_rp_err)) {
5218 /* expect an RP-ERROR message from MSC with given cause */
5219 rp_mt := tr_RP_ERROR_MT(spars.rp.msg_ref, spars.exp_rp_err);
5220 l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_DATA_MT(rp_mt));
5221 SGsAP.receive(l3_mt);
5222 /* send CP-ACK for CP-DATA just received */
5223 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_ACK_MO);
5224 SGsAP.send(l3_mo);
5225 } else {
5226 /* expect RP-ACK for RP-DATA */
5227 rp_mt := tr_RP_ACK_MT(spars.rp.msg_ref);
5228 l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_DATA_MT(rp_mt));
5229 SGsAP.receive(l3_mt);
5230 /* send CP-ACO for CP-DATA just received */
5231 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_ACK_MO);
5232 SGsAP.send(l3_mo);
5233 }
5234
5235 deactivate(d);
5236
5237 setverdict(pass);
5238}
5239
5240private function f_vty_sms_send_conn_hdlr(charstring imsi, charstring msisdn, charstring text)
5241runs on BSC_ConnHdlr {
5242 f_vty_transceive(MSCVTY, "subscriber imsi "&imsi&" sms sender msisdn "&msisdn&" send "&text);
5243}
5244
5245/* Send a MT SMS via SGs interface */
5246private function f_tc_sgsap_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5247 f_init_handler(pars);
5248 f_sgs_perform_lu();
5249 f_sleep(1.0);
5250 var SmsParameters spars := valueof(t_SmsPars);
5251 spars.tp.ud := 'C8329BFD064D9B53'O;
5252
5253 /* Trigger SMS via VTY */
5254 f_vty_sms_send_conn_hdlr(hex2str(pars.imsi), "2342", "Hello SMS");
5255 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5256
5257 /* Expect a paging request and respond accordingly with a service request */
5258 SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, SMS_indicator, omit));
5259 SGsAP.send(ts_SGsAP_SERVICE_REQ(pars.imsi, SMS_indicator, EMM_CONNECTED));
5260
5261 /* Connection is now live, receive the MT-SMS */
5262 f_mt_sms_sgs(spars);
5263
5264 /* Expect a concluding release from the MSC */
5265 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, omit));
5266
5267 /* Make sure that subscriber is still present and the SGs association is in tact (ref-counting) */
5268 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5269
5270 f_sgsap_bssmap_screening();
5271
5272 setverdict(pass);
5273}
5274testcase TC_sgsap_mt_sms() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005275 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005276 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005277 f_init(1, true);
5278 pars := f_init_pars(11823, true);
5279 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mt_sms), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005280 vc_conn.done;
5281}
5282
5283/* Send a MO SMS via SGs interface */
5284private function f_tc_sgsap_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5285 f_init_handler(pars);
5286 f_sgs_perform_lu();
5287 f_sleep(1.0);
5288 var SmsParameters spars := valueof(t_SmsPars);
5289 spars.tp.ud := 'C8329BFD064D9B53'O;
5290
5291 /* Send the MO-SMS */
5292 f_mo_sms_sgs(spars);
5293
5294 /* Expect a concluding release from the MSC/VLR */
5295 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, omit));
5296
5297 /* Make sure that subscriber is still present and the SGs association is in tact (ref-counting) */
5298 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5299
5300 setverdict(pass);
5301
5302 f_sgsap_bssmap_screening()
5303}
5304testcase TC_sgsap_mo_sms() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005305 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005306 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005307 f_init(1, true);
5308 pars := f_init_pars(11824, true);
5309 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mo_sms), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005310 vc_conn.done;
5311}
5312
5313/* Trigger sending of an MT sms via VTY but never respond to anything */
5314private function f_tc_sgsap_mt_sms_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5315 f_init_handler(pars, 170.0);
5316 f_sgs_perform_lu();
5317 f_sleep(1.0);
5318
5319 var SmsParameters spars := valueof(t_SmsPars);
5320 spars.tp.ud := 'C8329BFD064D9B53'O;
5321 var integer page_count := 0;
5322 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5323 var template PDU_SGsAP exp_pag_req := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, SMS_indicator, omit);
5324 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
5325 exp_pag_req.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
5326
5327 /* Trigger SMS via VTY */
5328 f_vty_sms_send_conn_hdlr(hex2str(pars.imsi), "2342", "Hello SMS");
5329
Neels Hofmeyr16237742019-03-06 15:34:01 +01005330 /* Expect the MSC/VLR to page exactly once */
5331 SGsAP.receive(exp_pag_req);
Harald Welte4263c522018-12-06 11:56:27 +01005332
5333 /* Wait some time to make sure the MSC is not delivering any further
5334 * paging messages or anything else that could be unexpected. */
5335 timer T := 20.0;
5336 T.start
5337 alt {
5338 [] SGsAP.receive(exp_pag_req)
5339 {
5340 setverdict(fail, "paging seems not to stop!");
5341 mtc.stop;
5342 }
5343 [] SGsAP.receive {
5344 setverdict(fail, "unexpected SGsAP message received");
5345 self.stop;
5346 }
5347 [] T.timeout {
5348 setverdict(pass);
5349 }
5350 }
5351
5352 /* Even on a failed paging the SGs Association should stay intact */
5353 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5354
Philipp Maier26bdb8c2019-09-24 09:21:12 +02005355 /* Make sure that the SMS we just inserted is cleared and the
5356 * subscriber is expired. This is necessary because otherwise the MSC
5357 * might re-try the SMS delivery and disturb the following tests. */
Harald Welte4263c522018-12-06 11:56:27 +01005358
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01005359 f_vty_sms_clear(hex2str(g_pars.imsi));
5360
Harald Welte4263c522018-12-06 11:56:27 +01005361 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " expire");
5362
5363 setverdict(pass);
Neels Hofmeyrb0f82342019-03-06 15:36:51 +01005364
5365 f_sgsap_bssmap_screening();
Harald Welte4263c522018-12-06 11:56:27 +01005366}
5367testcase TC_sgsap_mt_sms_and_nothing() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005368 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005369 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005370 f_init(1, true);
5371 pars := f_init_pars(11825, true);
5372 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mt_sms_and_nothing), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005373 vc_conn.done;
5374}
5375
5376/* Trigger sending of an MT sms via VTY but reject the paging immediately */
5377private function f_tc_sgsap_mt_sms_and_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5378 f_init_handler(pars, 150.0);
5379 f_sgs_perform_lu();
5380 f_sleep(1.0);
5381
5382 var SmsParameters spars := valueof(t_SmsPars);
5383 spars.tp.ud := 'C8329BFD064D9B53'O;
5384 var integer page_count := 0;
5385 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5386 var template PDU_SGsAP exp_pag_req := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, SMS_indicator, omit);
5387 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
5388 exp_pag_req.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
5389
5390 /* Trigger SMS via VTY */
5391 f_vty_sms_send_conn_hdlr(hex2str(pars.imsi), "2342", "Hello SMS");
5392
5393 /* Expect a paging request and reject it immediately */
5394 SGsAP.receive(exp_pag_req);
5395 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, IMSI_unknown));
5396
5397 /* The MSC/VLR should no longer try to page once the paging has been
5398 * rejected. Wait some time and check if there are no unexpected
5399 * messages on the SGs interface. */
5400 timer T := 20.0;
5401 T.start
5402 alt {
5403 [] SGsAP.receive(exp_pag_req)
5404 {
5405 setverdict(fail, "paging seems not to stop!");
5406 mtc.stop;
5407 }
5408 [] SGsAP.receive {
5409 setverdict(fail, "unexpected SGsAP message received");
5410 self.stop;
5411 }
5412 [] T.timeout {
5413 setverdict(pass);
5414 }
5415 }
5416
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01005417 f_vty_sms_clear(hex2str(g_pars.imsi));
5418
Harald Welte4263c522018-12-06 11:56:27 +01005419 /* A rejected paging with IMSI_unknown (see above) should always send
5420 * the SGs association to NULL. */
5421 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
5422
5423 f_sgsap_bssmap_screening();
5424
Harald Welte4263c522018-12-06 11:56:27 +01005425 setverdict(pass);
5426}
5427testcase TC_sgsap_mt_sms_and_reject() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005428 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005429 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005430 f_init(1, true);
5431 pars := f_init_pars(11826, true);
5432 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mt_sms_and_reject), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005433 vc_conn.done;
5434}
5435
Pau Espin Pedrol3acd19e2021-04-28 12:59:52 +02005436/* Perform an MT CSFB call including LU */
Harald Welte4263c522018-12-06 11:56:27 +01005437private function f_mt_lu_and_csfb_call(charstring id, BSC_ConnHdlrPars pars, boolean bssmap_lu) runs on BSC_ConnHdlr {
5438 f_init_handler(pars);
5439
5440 /* Be sure that the BSSMAP reset is done before we begin. */
5441 f_sleep(2.0);
5442
5443 /* Testcase variation: See what happens when we do a regular BSSMAP
5444 * LU first (this should not hurt in any way!) */
5445 if (bssmap_lu) {
5446 f_perform_lu();
5447 }
5448
5449 f_sgs_perform_lu();
5450 f_sleep(1.0);
5451
5452 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5453 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Harald Welte4263c522018-12-06 11:56:27 +01005454
5455 /* Initiate a call via MNCC interface */
5456 f_mt_call_initate(cpars);
5457
5458 /* Expect a paging request and respond accordingly with a service request */
5459 SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit));
5460 SGsAP.send(ts_SGsAP_SERVICE_REQ(pars.imsi, CS_call_indicator, EMM_CONNECTED));
5461
5462 /* Complete the call, hold it for some time and then tear it down */
5463 f_mt_call_complete(cpars);
5464 f_sleep(3.0);
Harald Welte4c422b72019-02-17 16:27:10 +01005465 f_call_hangup(cpars, true, is_csfb := true);
Harald Welte4263c522018-12-06 11:56:27 +01005466
5467 /* Make sure that subscriber is still present and the SGs association is in tact (ref-counting) */
5468 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5469
Harald Welte4263c522018-12-06 11:56:27 +01005470 /* Test for successful return by triggering a paging, when the paging
5471 * request is received via SGs, we can be sure that the MSC/VLR has
5472 * recognized that the UE is now back on 4G */
5473 f_sleep(1.0);
5474 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
5475 alt {
5476 [] SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit)) {
5477 setverdict(pass);
5478 }
5479 [] SGsAP.receive {
5480 setverdict(fail, "Received unexpected message on SGs");
5481 }
5482 }
5483
5484 f_sgsap_bssmap_screening();
5485
5486 setverdict(pass);
5487}
5488
5489/* Perform a regular BSSAP LU first, do a SGSAP LU and then make a CSFB call */
5490private function f_tc_bssap_lu_sgsap_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5491 f_mt_lu_and_csfb_call(id, pars, true);
5492}
5493testcase TC_bssap_lu_sgsap_lu_and_mt_call() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005494 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005495 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005496 f_init(1, true);
5497 pars := f_init_pars(118139, true);
Harald Welte4263c522018-12-06 11:56:27 +01005498
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005499 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 +01005500 vc_conn.done;
5501}
5502
Harald Welte4263c522018-12-06 11:56:27 +01005503/* Perform a SGSAP LU and then make a CSFB call */
5504private function f_tc_sgsap_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5505 f_mt_lu_and_csfb_call(id, pars, false);
5506}
5507testcase TC_sgsap_lu_and_mt_call() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005508 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005509 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005510 f_init(1, true);
5511 pars := f_init_pars(11827, true);
Harald Welte4263c522018-12-06 11:56:27 +01005512
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005513 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu_and_mt_call), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005514 vc_conn.done;
5515}
5516
Philipp Maier628c0052019-04-09 17:36:57 +02005517/* Simulate an HLR/VLR failure */
5518private function f_tc_sgsap_vlr_failure(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5519 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
5520 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5521
5522 var PDU_SGsAP lur;
5523
5524 f_init_handler(pars);
5525
5526 /* Attempt location update (which is expected to fail) */
5527 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
5528 ts_SGsAP_LAI('901'H, '70'H, 2342)));
5529 SGsAP.send(lur);
5530
5531 /* Respond to SGsAP-RESET-INDICATION from VLR */
5532 alt {
5533 [] SGsAP.receive(tr_SGsAP_RESET_IND_VLR(vlr_name)); {
5534 SGsAP.send(valueof(ts_SGsAP_RESET_ACK_MME(mme_name)));
5535 setverdict(pass);
5536 }
5537 [] SGsAP.receive {
5538 setverdict(fail, "Received unexpected message on SGs");
5539 }
5540 }
5541
5542 f_sleep(1.0);
5543 setverdict(pass);
5544}
5545testcase TC_sgsap_vlr_failure() runs on MTC_CT {
5546 var BSC_ConnHdlrPars pars;
5547 var BSC_ConnHdlr vc_conn;
5548 f_init(1, true, false);
5549 pars := f_init_pars(11811, true, false);
5550 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_vlr_failure), pars);
5551 vc_conn.done;
5552}
5553
Harald Welte4263c522018-12-06 11:56:27 +01005554/* SGs TODO:
5555 * LU attempt for IMSI without NAM_PS in HLR
5556 * LU attempt with AUTH FAIL due to invalid RES/SRES
5557 * LU attempt with no response from HLR (VLR should timeout + LU REJ)
5558 * LU attempt with new TMSI but without TMSI REALL CMPL baco to VLR
5559 * implicit IMSI detach from EPS
5560 * implicit IMSI detach from non-EPS
5561 * MM INFO
5562 *
5563 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01005564
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005565private function f_tc_ho_inter_bsc_unknown_cell(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5566 f_init_handler(pars);
5567 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005568
5569 f_perform_lu();
5570 f_mo_call_establish(cpars);
5571
5572 f_sleep(1.0);
5573
5574 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
5575 var BssmapCause cause := enum2int(cause_val);
5576
5577 var template BSSMAP_FIELD_CellIdentificationList cil;
5578 cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('023'H, '42'H, 999) } };
5579
5580 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
5581 BSSAP.receive(tr_BSSMAP_HandoverRequiredReject);
5582
5583 f_call_hangup(cpars, true);
5584}
5585testcase TC_ho_inter_bsc_unknown_cell() runs on MTC_CT {
5586 var BSC_ConnHdlr vc_conn;
5587 f_init();
5588
5589 vc_conn := f_start_handler(refers(f_tc_ho_inter_bsc_unknown_cell), 53);
5590 vc_conn.done;
5591}
5592
5593private altstep as_mgcp_ack_all_mdcx(CallParameters cpars) runs on BSC_ConnHdlr {
5594 var MgcpCommand mgcp_cmd;
5595 [] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02005596 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 +02005597 hex2str(cpars.mgcp_call_id), "42",
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02005598 cpars.mgw_conn_2.mgw_rtp_port,
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005599 { int2str(cpars.rtp_payload_type) },
5600 { valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
5601 cpars.rtp_sdp_format)),
5602 valueof(ts_SDP_ptime(20)) }));
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02005603 MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgw_conn_2.mgcp_connection_id, sdp));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005604 repeat;
5605 }
5606}
5607
5608private function f_tc_ho_inter_bsc0(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02005609 var CallParameters cpars;
5610
5611 cpars := valueof(t_CallParams('12345'H, 0));
5612 if (pars.use_ipv6) {
5613 cpars.mgw_conn_1.mgw_rtp_ip := "::1";
5614 cpars.mgw_conn_2.mgw_rtp_ip := "::2";
5615 cpars.bss_rtp_ip := "::3";
5616 }
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005617
5618 f_init_handler(pars);
5619
5620 f_vty_transceive(MSCVTY, "configure terminal");
5621 f_vty_transceive(MSCVTY, "msc");
5622 f_vty_transceive(MSCVTY, "neighbor a cgi 262 42 23 42 ran-pc 0.24.1");
5623 f_vty_transceive(MSCVTY, "neighbor a lac 5 ran-pc 0.24.2");
5624 f_vty_transceive(MSCVTY, "exit");
5625 f_vty_transceive(MSCVTY, "exit");
5626
5627 f_perform_lu();
5628 f_mo_call_establish(cpars);
5629
5630 f_sleep(1.0);
5631
5632 var default ack_mdcx := activate(as_mgcp_ack_all_mdcx(cpars));
5633
5634 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
5635 var BssmapCause cause := enum2int(cause_val);
5636
5637 var template BSSMAP_FIELD_CellIdentificationList cil;
5638 cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('023'H, '42'H, 5) } };
5639
5640 /* old BSS sends Handover Required */
5641 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
5642
5643 /* Now the action goes on in f_tc_ho_inter_bsc1() */
5644
5645 /* MSC forwards the RR Handover Command to old BSS */
5646 var PDU_BSSAP ho_command;
5647 BSSAP.receive(tr_BSSMAP_HandoverCommand) -> value ho_command;
5648
5649 log("GOT HandoverCommand", ho_command);
5650
5651 BSSAP.receive(tr_BSSMAP_HandoverSucceeded);
5652
5653 /* f_tc_ho_inter_bsc1() completes Handover, then expecting a Clear here. */
5654 f_expect_clear();
5655
5656 log("FIRST inter-BSC Handover done");
5657
5658
5659 /* ------------------------ */
5660
5661 /* Ok, that went well, now the other BSC is handovering back here --
5662 * from now on this here is the new BSS. */
5663 f_create_bssmap_exp_handoverRequest(193);
5664
5665 var PDU_BSSAP ho_request;
5666 BSSAP.receive(tr_BSSMAP_HandoverRequest) -> value ho_request;
5667
5668 /* new BSS composes a RR Handover Command */
5669 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5670 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02005671 var BSSMAP_IE_AoIP_TransportLayerAddress tla tla :=
5672 valueof(f_ts_BSSMAP_IE_AoIP_TLA(cpars.bss_rtp_ip, cpars.bss_rtp_port));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005673 BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
5674 tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
5675
5676 /* Now f_tc_ho_inter_bsc1() expects HandoverCommand */
5677
5678 f_sleep(0.5);
5679
5680 /* Notify that the MS is now over here */
5681
5682 BSSAP.send(ts_BSSMAP_HandoverDetect);
5683 f_sleep(0.1);
5684 BSSAP.send(ts_BSSMAP_HandoverComplete);
5685
5686 f_sleep(3.0);
5687
5688 deactivate(ack_mdcx);
5689
5690 var default ccrel := activate(as_optional_cc_rel(cpars, true));
5691
5692 /* blatant cheating */
5693 var N_Sd_Array last_n_sd := f_bssmap_last_n_sd();
5694 last_n_sd[0] := 3;
5695 f_bssmap_continue_after_n_sd(last_n_sd);
5696
5697 f_call_hangup(cpars, true);
5698 f_sleep(1.0);
5699 deactivate(ccrel);
5700
5701 setverdict(pass);
5702}
5703private function f_tc_ho_inter_bsc1(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02005704 var charstring bss_rtp_ip;
5705 if (pars.use_ipv6) {
5706 bss_rtp_ip := "::8";
5707 } else {
5708 bss_rtp_ip := "1.2.3.4";
5709 }
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005710 f_init_handler(pars);
5711 f_create_bssmap_exp_handoverRequest(194);
5712
5713 var PDU_BSSAP ho_request;
5714 BSSAP.receive(tr_BSSMAP_HandoverRequest) -> value ho_request;
5715
5716 /* new BSS composes a RR Handover Command */
5717 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5718 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02005719 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
5720 valueof(f_ts_BSSMAP_IE_AoIP_TLA(bss_rtp_ip, 2342));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005721 BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
5722 tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
5723
5724 /* Now f_tc_ho_inter_bsc0() expects HandoverCommand */
5725
5726 f_sleep(0.5);
5727
5728 /* Notify that the MS is now over here */
5729
5730 BSSAP.send(ts_BSSMAP_HandoverDetect);
5731 f_sleep(0.1);
5732 BSSAP.send(ts_BSSMAP_HandoverComplete);
5733
5734 f_sleep(3.0);
5735
5736 /* Now I'd like to f_call_hangup() but we don't know any cpars here. So
5737 * ... handover back to the first BSC :P */
5738
5739 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
5740 var BssmapCause cause := enum2int(cause_val);
5741
5742 var template BSSMAP_FIELD_CellIdentificationList cil;
5743 cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('262'H, '42'H, 23) } };
5744
5745 /* old BSS sends Handover Required */
5746 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
5747
5748 /* Now the action goes on in f_tc_ho_inter_bsc0() */
5749
5750 /* MSC forwards the RR Handover Command to old BSS */
5751 var PDU_BSSAP ho_command;
5752 BSSAP.receive(tr_BSSMAP_HandoverCommand) -> value ho_command;
5753
5754 log("GOT HandoverCommand", ho_command);
5755
5756 BSSAP.receive(tr_BSSMAP_HandoverSucceeded);
5757
5758 /* f_tc_ho_inter_bsc1() completes Handover, then expecting a Clear here. */
5759 f_expect_clear();
5760 setverdict(pass);
5761}
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02005762function f_tc_ho_inter_bsc_main(boolean use_ipv6 := false) runs on MTC_CT {
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005763 var BSC_ConnHdlr vc_conn0;
5764 var BSC_ConnHdlr vc_conn1;
5765 f_init(2);
5766
5767 var BSC_ConnHdlrPars pars0 := f_init_pars(53);
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02005768 pars0.use_ipv6 := use_ipv6;
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005769 var BSC_ConnHdlrPars pars1 := f_init_pars(53);
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02005770 pars1.use_ipv6 := use_ipv6;
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005771
5772 vc_conn0 := f_start_handler_with_pars(refers(f_tc_ho_inter_bsc0), pars0, 0);
5773 vc_conn1 := f_start_handler_with_pars(refers(f_tc_ho_inter_bsc1), pars1, 1);
5774 vc_conn0.done;
5775 vc_conn1.done;
5776}
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02005777testcase TC_ho_inter_bsc() runs on MTC_CT {
5778 f_tc_ho_inter_bsc_main(false);
5779}
5780testcase TC_ho_inter_bsc_ipv6() runs on MTC_CT {
5781 f_tc_ho_inter_bsc_main(true);
5782}
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005783
5784function f_ML3_patch_seq_nr_MS_NW(in uint2_t seq_nr, inout octetstring enc_l3) {
5785 log("MS_NW patching N(SD)=", seq_nr, " into dtap ", enc_l3);
5786 enc_l3[2] := (enc_l3[2] and4b '3f'O) or4b bit2oct(int2bit(seq_nr, 8) << 6);
5787 log("MS_NW patched enc_l3: ", enc_l3);
5788}
5789
5790private function f_tc_ho_inter_msc_out(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02005791 var CallParameters cpars;
5792
5793 cpars := valueof(t_CallParams('12345'H, 0));
5794 if (pars.use_ipv6) {
5795 cpars.mgw_conn_1.mgw_rtp_ip := "::1";
5796 cpars.mgw_conn_2.mgw_rtp_ip := "::2";
5797 cpars.bss_rtp_ip := "::3";
5798 }
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005799 var hexstring ho_number := f_gen_msisdn(99999);
5800
5801 f_init_handler(pars);
5802
5803 f_create_mncc_expect(hex2str(ho_number));
5804
5805 f_vty_transceive(MSCVTY, "configure terminal");
5806 f_vty_transceive(MSCVTY, "msc");
5807 f_vty_transceive(MSCVTY, "neighbor a cgi 017 017 1 1 msc-ipa-name msc-017-017-1");
5808 f_vty_transceive(MSCVTY, "exit");
5809 f_vty_transceive(MSCVTY, "exit");
5810
5811 f_perform_lu();
5812 f_mo_call_establish(cpars);
5813
5814 f_sleep(1.0);
5815
5816 var default ack_mdcx := activate(as_mgcp_ack_all_mdcx(cpars));
5817
5818 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
5819 var BssmapCause cause := enum2int(cause_val);
5820
5821 var template BSSMAP_FIELD_CellIdentificationList cil;
5822 cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('017'H, '017'H, 1) } };
5823
5824 /* old BSS sends Handover Required */
5825 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
5826
5827 /* The target cell 017-017 LAC 1 is configured to be a remote MSC of name "msc-017-017-1".
5828 * This MSC tries to reach the other MSC via GSUP. */
5829
5830 var octetstring remote_msc_name := '6D73632D3031372D3031372D3100'O; /* "msc-017-017-1\0" as octetstring */
5831 var GSUP_PDU prep_ho_req;
5832 GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_REQUEST,
5833 pars.imsi, destination_name := remote_msc_name)) -> value prep_ho_req;
5834
5835 var GSUP_IeValue source_name_ie;
5836 f_gsup_find_ie(prep_ho_req, OSMO_GSUP_SOURCE_NAME_IE, source_name_ie);
5837 var octetstring local_msc_name := source_name_ie.source_name;
5838
5839 /* Remote MSC has figured out its BSC and signals success */
5840 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5841 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5842 var PDU_BSSAP ho_req_ack := valueof(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
5843 aoIPTransportLayer := omit,
5844 speechCodec := ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
5845 GSUP.send(ts_GSUP_E_PrepareHandoverResult(
5846 pars.imsi,
5847 ho_number,
5848 remote_msc_name, local_msc_name,
5849 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006, enc_PDU_BSSAP(ho_req_ack)))));
5850
5851 /* MSC forwards the RR Handover Command to old BSS */
5852 BSSAP.receive(tr_BSSMAP_HandoverCommand);
5853
5854 /* The MS shows up at remote new BSS */
5855
5856 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST,
5857 pars.imsi, remote_msc_name, local_msc_name,
5858 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
5859 enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverDetect))))));
5860 BSSAP.receive(tr_BSSMAP_HandoverSucceeded);
5861 f_sleep(0.1);
5862
5863 /* Save the MS sequence counters for use on the other connection */
5864 var N_Sd_Array last_n_sd := f_bssmap_last_n_sd();
5865
5866 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_REQUEST,
5867 pars.imsi, remote_msc_name, local_msc_name,
5868 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
5869 enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverComplete))))));
5870
5871 /* The local BSS conn clears, all communication goes via remote MSC now */
5872 f_expect_clear();
5873
5874 /**********************************/
5875 /* Play through some signalling across the inter-MSC link.
5876 * This is a copy of f_tc_lu_and_mo_ussd_single_request() translated into GSUP AN-APDUs. */
5877
5878 if (false) {
5879 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
5880 invoke_id := 5, /* Phone may not start from 0 or 1 */
5881 op_code := SS_OP_CODE_PROCESS_USS_REQ,
5882 ussd_string := "*#100#"
5883 );
5884
5885 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
5886 invoke_id := 5, /* InvokeID shall be the same for both REQ and RSP */
5887 op_code := SS_OP_CODE_PROCESS_USS_REQ,
5888 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
5889 )
5890
5891 /* Compose a new SS/REGISTER message with request */
5892 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
5893 tid := 1, /* We just need a single transaction */
5894 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
5895 facility := valueof(facility_req)
5896 );
5897 var PDU_ML3_MS_NW ussd_req_v := valueof(ussd_req);
5898
5899 /* Compose SS/RELEASE_COMPLETE template with expected response */
5900 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
5901 tid := 1, /* Response should arrive within the same transaction */
5902 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
5903 facility := valueof(facility_rsp)
5904 );
5905
5906 /* Compose expected MSC -> HLR message */
5907 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
5908 imsi := g_pars.imsi,
5909 state := OSMO_GSUP_SESSION_STATE_BEGIN,
5910 ss := valueof(facility_req)
5911 );
5912
5913 /* To be used for sending response with correct session ID */
5914 var GSUP_PDU gsup_req_complete;
5915
5916 /* Request own number */
5917 /* From remote MSC instead of BSSAP directly */
5918 /* Patch the correct N_SD value into the message. */
5919 var octetstring l3_enc := enc_PDU_ML3_MS_NW(ussd_req_v);
5920 var RAN_Emulation.ConnectionData cd;
5921 f_ML3_patch_seq_nr_MS_NW(f_next_n_sd(last_n_sd, f_ML3_n_sd_idx(ussd_req_v)), l3_enc);
5922 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST,
5923 pars.imsi, remote_msc_name, local_msc_name,
5924 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
5925 enc_PDU_BSSAP(valueof(ts_BSSAP_DTAP(l3_enc)))
5926 ))
5927 ));
5928
5929 /* Expect GSUP message containing the SS payload */
5930 gsup_req_complete := f_expect_gsup_msg(gsup_req);
5931
5932 /* Compose the response from HLR using received session ID */
5933 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
5934 imsi := g_pars.imsi,
5935 sid := gsup_req_complete.ies[1].val.session_id,
5936 state := OSMO_GSUP_SESSION_STATE_END,
5937 ss := valueof(facility_rsp)
5938 );
5939
5940 /* Finally, HLR terminates the session */
5941 GSUP.send(gsup_rsp);
5942
5943 /* The USSD response goes out to remote MSC, on GSUP E instead of BSSAP */
5944 var GSUP_PDU gsup_ussd_rsp;
5945 GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST,
5946 pars.imsi, destination_name := remote_msc_name)) -> value gsup_ussd_rsp;
5947
5948 var GSUP_IeValue an_apdu;
5949 if (not f_gsup_find_ie(gsup_ussd_rsp, OSMO_GSUP_AN_APDU_IE, an_apdu)) {
5950 setverdict(fail, "No AN-APDU in received GSUP message. Expected USSD response in DTAP, got", gsup_ussd_rsp);
5951 mtc.stop;
5952 }
5953 var PDU_BSSAP bssap_dtap_mt := dec_PDU_BSSAP(an_apdu.an_apdu.pdu);
5954 var PDU_ML3_NW_MS dtap_mt := dec_PDU_ML3_NW_MS(bssap_dtap_mt.pdu.dtap);
5955 log("Expecting", ussd_rsp);
5956 log("Got", dtap_mt);
5957 if (not match(dtap_mt, ussd_rsp)) {
5958 setverdict(fail, "Unexpected GSUP message. Expected USSD response in DTAP, got", gsup_ussd_rsp);
5959 mtc.stop;
5960 }
5961 }
5962 /**********************************/
5963
5964
5965 /* inter-MSC handover back to the first MSC */
5966 f_create_bssmap_exp_handoverRequest(193);
5967 cil := { cIl_CGI := { ts_BSSMAP_CI_CGI('262'H, '42'H, 23, 42) } };
5968
5969 /* old BSS sends Handover Required, via inter-MSC E link: like
5970 * BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
5971 * but via GSUP */
5972 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_REQUEST,
5973 pars.imsi, remote_msc_name, local_msc_name,
5974 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
5975 enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverRequired(cause, cil)))
5976 ))
5977 ));
5978
5979 /* MSC asks local BSS to prepare Handover to it */
5980 BSSAP.receive(tr_BSSMAP_HandoverRequest);
5981
5982 /* Make sure the new BSSAP conn continues with the correct N_SD sequence numbers */
5983 f_bssmap_continue_after_n_sd(last_n_sd);
5984
5985 /* new BSS composes a RR Handover Command */
5986 rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5987 rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02005988 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
5989 valueof(f_ts_BSSMAP_IE_AoIP_TLA(cpars.bss_rtp_ip, cpars.bss_rtp_port));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005990 BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
5991 tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
5992
5993 /* HandoverCommand goes out via remote MSC-I */
5994 var GSUP_PDU prep_subsq_ho_res;
5995 GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_RESULT,
5996 pars.imsi, destination_name := remote_msc_name)) -> value prep_subsq_ho_res;
5997
5998 /* MS shows up at the local BSS */
5999 BSSAP.send(ts_BSSMAP_HandoverDetect);
6000 f_sleep(0.1);
6001 BSSAP.send(ts_BSSMAP_HandoverComplete);
6002
6003 /* Handover Succeeded message */
6004 GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST,
6005 pars.imsi, destination_name := remote_msc_name));
6006
6007 /* MS has handovered to here, Clear Command goes out via remote MSC-I -- in form of a GSUP Close. */
6008 GSUP.receive(tr_GSUP_E_NO_PDU(OSMO_GSUP_MSGT_E_CLOSE,
6009 pars.imsi, destination_name := remote_msc_name));
6010
6011 /* Handover ends successfully. Call goes on for a little longer and then we hang up. */
6012
6013 f_sleep(1.0);
6014 deactivate(ack_mdcx);
6015
6016 /* FIXME: the inter-MSC call has put a number of MNCC messages in the queue, which above code should expect and
6017 * clear out. The f_call_hangup() expects an MNCC_REL_IND, so, for the time being, just clear the MNCC messages
6018 * before starting the call hangup. Instead of this, the individual messages should be tested for above. */
6019 MNCC.clear;
6020
6021 var default ccrel := activate(as_optional_cc_rel(cpars, true));
6022 f_call_hangup(cpars, true);
6023 f_sleep(1.0);
6024 deactivate(ccrel);
6025
6026 setverdict(pass);
6027}
6028testcase TC_ho_inter_msc_out() runs on MTC_CT {
6029 var BSC_ConnHdlr vc_conn;
6030 f_init(1);
6031
6032 var BSC_ConnHdlrPars pars := f_init_pars(54);
6033
6034 vc_conn := f_start_handler_with_pars(refers(f_tc_ho_inter_msc_out), pars, 0);
6035 vc_conn.done;
6036}
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02006037testcase TC_ho_inter_msc_out_ipv6() runs on MTC_CT {
6038 var BSC_ConnHdlr vc_conn;
6039 f_init(1);
6040
6041 var BSC_ConnHdlrPars pars := f_init_pars(54);
6042 pars.use_ipv6 := true;
6043
6044 vc_conn := f_start_handler_with_pars(refers(f_tc_ho_inter_msc_out), pars, 0);
6045 vc_conn.done;
6046}
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006047
Oliver Smith1d118ff2019-07-03 10:57:35 +02006048private function f_tc_lu_imsi_auth_tmsi_check_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6049 pars.net.expect_auth := true;
6050 pars.net.expect_imei := true;
6051 f_init_handler(pars);
6052 f_perform_lu();
6053}
6054testcase TC_lu_imsi_auth_tmsi_check_imei() runs on MTC_CT {
6055 var BSC_ConnHdlr vc_conn;
6056 f_init();
6057 f_vty_config(MSCVTY, "network", "authentication required");
6058 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
6059
6060 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei), 5);
6061 vc_conn.done;
6062}
6063
6064private function f_tc_lu_imsi_auth3g_tmsi_check_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6065 pars.net.expect_auth := true;
6066 pars.use_umts_aka := true;
6067 pars.net.expect_imei := true;
6068 f_init_handler(pars);
6069 f_perform_lu();
6070}
6071testcase TC_lu_imsi_auth3g_tmsi_check_imei() runs on MTC_CT {
6072 var BSC_ConnHdlr vc_conn;
6073 f_init();
6074 f_vty_config(MSCVTY, "network", "authentication required");
6075 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
6076
6077 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth3g_tmsi_check_imei), 5);
6078 vc_conn.done;
6079}
6080
6081private function f_tc_lu_imsi_noauth_tmsi_check_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6082 pars.net.expect_imei := true;
6083 f_init_handler(pars);
6084 f_perform_lu();
6085}
6086testcase TC_lu_imsi_noauth_tmsi_check_imei() runs on MTC_CT {
6087 var BSC_ConnHdlr vc_conn;
6088 f_init();
6089 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
6090
6091 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi_check_imei), 5);
6092 vc_conn.done;
6093}
6094
6095private function f_tc_lu_imsi_noauth_notmsi_check_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6096 pars.net.expect_tmsi := false;
6097 pars.net.expect_imei := true;
6098 f_init_handler(pars);
6099 f_perform_lu();
6100}
6101testcase TC_lu_imsi_noauth_notmsi_check_imei() runs on MTC_CT {
6102 var BSC_ConnHdlr vc_conn;
6103 f_init();
6104 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
6105 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
6106
6107 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi_check_imei), 5);
6108 vc_conn.done;
6109}
6110
6111private function f_tc_lu_imsi_auth_tmsi_check_imei_nack(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6112 var PDU_ML3_MS_NW l3_lu;
Oliver Smith1d118ff2019-07-03 10:57:35 +02006113
6114 pars.net.expect_auth := true;
6115 pars.net.expect_imei := true;
6116 pars.net.check_imei_result := OSMO_GSUP_IMEI_RESULT_NACK;
6117 f_init_handler(pars);
6118
6119 /* Cannot use f_perform_lu() as we expect a reject */
6120 l3_lu := f_build_lu_imsi(g_pars.imsi)
6121 f_create_gsup_expect(hex2str(g_pars.imsi));
6122 f_bssap_compl_l3(l3_lu);
6123 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
6124
6125 f_mm_common();
6126 f_msc_lu_hlr();
6127 f_mm_imei();
Oliver Smith91bfa1c2019-07-19 15:01:15 +02006128 f_expect_lu_reject();
Oliver Smith690d60f2019-07-23 13:09:08 +02006129 f_expect_clear();
Oliver Smith1d118ff2019-07-03 10:57:35 +02006130}
6131testcase TC_lu_imsi_auth_tmsi_check_imei_nack() runs on MTC_CT {
6132 var BSC_ConnHdlr vc_conn;
6133 f_init();
6134 f_vty_config(MSCVTY, "network", "authentication required");
6135 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
6136
6137 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_nack), 5);
6138 vc_conn.done;
6139}
6140
6141private function f_tc_lu_imsi_auth_tmsi_check_imei_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6142 var PDU_ML3_MS_NW l3_lu;
Oliver Smith1d118ff2019-07-03 10:57:35 +02006143
6144 pars.net.expect_auth := true;
6145 pars.net.expect_imei := true;
6146 pars.net.check_imei_error := true;
6147 f_init_handler(pars);
6148
6149 /* Cannot use f_perform_lu() as we expect a reject */
6150 l3_lu := f_build_lu_imsi(g_pars.imsi)
6151 f_create_gsup_expect(hex2str(g_pars.imsi));
6152 f_bssap_compl_l3(l3_lu);
6153 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
6154
6155 f_mm_common();
6156 f_msc_lu_hlr();
6157 f_mm_imei();
Oliver Smith91bfa1c2019-07-19 15:01:15 +02006158 f_expect_lu_reject();
Oliver Smith690d60f2019-07-23 13:09:08 +02006159 f_expect_clear();
Oliver Smith1d118ff2019-07-03 10:57:35 +02006160}
6161testcase TC_lu_imsi_auth_tmsi_check_imei_err() runs on MTC_CT {
6162 var BSC_ConnHdlr vc_conn;
6163 f_init();
6164 f_vty_config(MSCVTY, "network", "authentication required");
6165 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
6166
6167 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_err), 5);
6168 vc_conn.done;
6169}
6170
6171private function f_tc_lu_imsi_auth_tmsi_check_imei_early(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6172 pars.net.expect_auth := true;
6173 pars.net.expect_imei_early := true;
6174 f_init_handler(pars);
6175 f_perform_lu();
6176}
6177testcase TC_lu_imsi_auth_tmsi_check_imei_early() runs on MTC_CT {
6178 var BSC_ConnHdlr vc_conn;
6179 f_init();
6180 f_vty_config(MSCVTY, "network", "authentication required");
6181 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
6182
6183 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_early), 5);
6184 vc_conn.done;
6185}
6186
6187private function f_tc_lu_imsi_auth3g_tmsi_check_imei_early(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6188 pars.net.expect_auth := true;
6189 pars.use_umts_aka := true;
6190 pars.net.expect_imei_early := true;
6191 f_init_handler(pars);
6192 f_perform_lu();
6193}
6194testcase TC_lu_imsi_auth3g_tmsi_check_imei_early() runs on MTC_CT {
6195 var BSC_ConnHdlr vc_conn;
6196 f_init();
6197 f_vty_config(MSCVTY, "network", "authentication required");
6198 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
6199
6200 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth3g_tmsi_check_imei_early), 5);
6201 vc_conn.done;
6202}
6203
6204private function f_tc_lu_imsi_noauth_tmsi_check_imei_early(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6205 pars.net.expect_imei_early := true;
6206 f_init_handler(pars);
6207 f_perform_lu();
6208}
6209testcase TC_lu_imsi_noauth_tmsi_check_imei_early() runs on MTC_CT {
6210 var BSC_ConnHdlr vc_conn;
6211 f_init();
6212 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
6213
6214 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi_check_imei_early), 5);
6215 vc_conn.done;
6216}
6217
6218private function f_tc_lu_imsi_noauth_notmsi_check_imei_early(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6219 pars.net.expect_tmsi := false;
6220 pars.net.expect_imei_early := true;
6221 f_init_handler(pars);
6222 f_perform_lu();
6223}
6224testcase TC_lu_imsi_noauth_notmsi_check_imei_early() runs on MTC_CT {
6225 var BSC_ConnHdlr vc_conn;
6226 f_init();
6227 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
6228 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
6229
6230 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi_check_imei_early), 5);
6231 vc_conn.done;
6232}
6233
6234private function f_tc_lu_imsi_auth_tmsi_check_imei_early_nack(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6235 var PDU_ML3_MS_NW l3_lu;
Oliver Smith1d118ff2019-07-03 10:57:35 +02006236
6237 pars.net.expect_auth := true;
6238 pars.net.expect_imei_early := true;
6239 pars.net.check_imei_result := OSMO_GSUP_IMEI_RESULT_NACK;
6240 f_init_handler(pars);
6241
6242 /* Cannot use f_perform_lu() as we expect a reject */
6243 l3_lu := f_build_lu_imsi(g_pars.imsi)
6244 f_create_gsup_expect(hex2str(g_pars.imsi));
6245 f_bssap_compl_l3(l3_lu);
6246 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
6247
6248 f_mm_imei_early();
Oliver Smith91bfa1c2019-07-19 15:01:15 +02006249 f_expect_lu_reject();
Oliver Smith690d60f2019-07-23 13:09:08 +02006250 f_expect_clear();
Oliver Smith1d118ff2019-07-03 10:57:35 +02006251}
6252testcase TC_lu_imsi_auth_tmsi_check_imei_early_nack() runs on MTC_CT {
6253 var BSC_ConnHdlr vc_conn;
6254 f_init();
6255 f_vty_config(MSCVTY, "network", "authentication required");
6256 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
6257
6258 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_early_nack), 5);
6259 vc_conn.done;
6260}
6261
6262private function f_tc_lu_imsi_auth_tmsi_check_imei_early_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6263 var PDU_ML3_MS_NW l3_lu;
Oliver Smith1d118ff2019-07-03 10:57:35 +02006264
6265 pars.net.expect_auth := true;
6266 pars.net.expect_imei_early := true;
6267 pars.net.check_imei_error := true;
6268 f_init_handler(pars);
6269
6270 /* Cannot use f_perform_lu() as we expect a reject */
6271 l3_lu := f_build_lu_imsi(g_pars.imsi)
6272 f_create_gsup_expect(hex2str(g_pars.imsi));
6273 f_bssap_compl_l3(l3_lu);
6274 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
6275
6276 f_mm_imei_early();
Oliver Smith91bfa1c2019-07-19 15:01:15 +02006277 f_expect_lu_reject();
Oliver Smith690d60f2019-07-23 13:09:08 +02006278 f_expect_clear();
Oliver Smith1d118ff2019-07-03 10:57:35 +02006279}
6280testcase TC_lu_imsi_auth_tmsi_check_imei_early_err() runs on MTC_CT {
6281 var BSC_ConnHdlr vc_conn;
6282 f_init();
6283 f_vty_config(MSCVTY, "network", "authentication required");
6284 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
6285
6286 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_early_err), 5);
6287 vc_conn.done;
6288}
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006289
Neels Hofmeyr8df69622019-11-02 19:16:03 +01006290friend function f_tc_invalid_mgcp_crash(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6291 f_init_handler(pars);
6292 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
6293
6294 /* Set invalid IP address so that osmo-msc discards the rtp_stream and MGCP endpoint FSM instances in the middle
6295 * of successful MGCP response dispatch. If things aren't safeguarded, the on_success() in osmo_mgcpc_ep_fsm
6296 * will cause a use-after-free after that event dispatch. */
6297 cpars.mgw_conn_1.mgw_rtp_ip := "0.0.0.0";
6298 cpars.mgw_conn_2.mgw_rtp_ip := "0.0.0.0";
6299 cpars.rtp_sdp_format := "FOO/8000";
6300 cpars.expect_release := true;
6301
6302 f_perform_lu();
6303 f_mo_call_establish(cpars);
6304}
6305testcase TC_invalid_mgcp_crash() runs on MTC_CT {
6306 var BSC_ConnHdlr vc_conn;
6307 f_init();
6308
6309 vc_conn := f_start_handler(refers(f_tc_invalid_mgcp_crash), 7);
6310 vc_conn.done;
6311}
6312
Vadim Yanitskiyeddebaa2019-12-28 17:45:34 +01006313friend function f_tc_mm_id_resp_no_identity(charstring id, BSC_ConnHdlrPars pars)
6314runs on BSC_ConnHdlr {
6315 pars.tmsi := 'FFFFFFFF'O;
6316 f_init_handler(pars);
6317
6318 f_create_gsup_expect(hex2str(g_pars.imsi));
6319
6320 /* Initiate Location Updating using an unknown TMSI */
6321 f_bssap_compl_l3(f_build_lu_tmsi(pars.tmsi));
6322
6323 /* Expect an Identity Request, send response with no identity */
6324 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req(CM_ID_TYPE_IMSI)));
6325 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp({
6326 lengthIndicator := 1,
6327 mobileIdentityV := {
6328 typeOfIdentity := '000'B,
6329 oddEvenInd_identity := {
6330 no_identity := {
6331 oddevenIndicator := '0'B,
6332 fillerDigits := '00000'H
6333 }
6334 }
6335 }
6336 })));
6337
6338 f_expect_lu_reject();
6339 f_expect_clear();
6340}
6341testcase TC_mm_id_resp_no_identity() runs on MTC_CT {
6342 var BSC_ConnHdlr vc_conn;
6343
6344 f_init();
6345
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02006346 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 +01006347 vc_conn.done;
6348}
6349
Vadim Yanitskiy25219062020-01-21 01:41:33 +07006350/* Verify the case when T3212 expires during Paging procedure, just before the receipt
6351 * of Paging Response. This used to provoke a NULL-pointer dereference in old versions
6352 * of OsmoMSC, but apparently the bug has been fixed, and we're safe now. */
6353friend function f_tc_lu_and_expire_while_paging(charstring id, BSC_ConnHdlrPars pars)
6354runs on BSC_ConnHdlr {
6355 var charstring imsi := hex2str(pars.imsi);
6356
6357 f_init_handler(pars);
6358
6359 /* Perform location update */
6360 f_perform_lu();
6361
6362 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
6363 f_create_gsup_expect(hex2str(g_pars.imsi));
6364
6365 /* Initiate paging procedure from the VTY */
6366 f_vty_transceive(MSCVTY, "subscriber imsi " & imsi & " paging");
6367 f_expect_paging();
6368
6369 /* Emulate T3212 expiration during paging (we don't want to wait, right?) */
6370 f_vty_transceive(MSCVTY, "subscriber imsi " & imsi & " expire");
6371
6372 /* MS sends PAGING RESPONSE, *old* OsmoMSC crashes here... */
6373 f_establish_fully(EST_TYPE_PAG_RESP);
6374
6375 /* The recent OsmoMSC keeps subscriber in its VLR unless the Paging is completed.
6376 * In this case we do not send anything and just wait for a Clear Command. */
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02006377 f_expect_clear(verify_vlr_cell_id := false);
Vadim Yanitskiy25219062020-01-21 01:41:33 +07006378}
6379testcase TC_lu_and_expire_while_paging() runs on MTC_CT {
6380 var BSC_ConnHdlr vc_conn;
6381
6382 f_init();
6383
6384 vc_conn := f_start_handler(refers(f_tc_lu_and_expire_while_paging), 7);
6385 vc_conn.done;
6386}
6387
Harald Weltef6dd64d2017-11-19 12:09:51 +01006388control {
Philipp Maier328d1662018-03-07 10:40:27 +01006389 execute( TC_cr_before_reset() );
Harald Weltea49e36e2018-01-21 19:29:33 +01006390 execute( TC_lu_imsi_noauth_tmsi() );
Harald Welted2328a22018-01-27 14:27:16 +01006391 execute( TC_lu_imsi_noauth_notmsi() );
Harald Weltea49e36e2018-01-21 19:29:33 +01006392 execute( TC_lu_imsi_reject() );
6393 execute( TC_lu_imsi_timeout_gsup() );
Harald Welted2328a22018-01-27 14:27:16 +01006394 execute( TC_lu_imsi_auth_tmsi() );
Harald Welte8a397ae2019-04-21 22:03:37 +02006395 execute( TC_lu_imsi_auth3g_tmsi() );
Pau Espin Pedrold3d54a92019-12-17 17:02:54 +01006396 execute( TC_lu_imsi_timeout_tmsi_realloc() );
Harald Welted2328a22018-01-27 14:27:16 +01006397 execute( TC_cmserv_imsi_unknown() );
Neels Hofmeyr13737fb2020-08-19 13:16:14 +00006398 execute( TC_cmserv_tmsi_unknown() );
Harald Welte2bb825f2018-01-22 11:31:18 +01006399 execute( TC_lu_and_mo_call() );
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02006400 execute( TC_lu_and_mo_call_ipv6() );
Pau Espin Pedrola42745c2020-01-10 18:03:28 +01006401 execute( TC_lu_and_mo_call_sccp_tiar_timeout() );
Harald Welte071ed732018-01-23 19:53:52 +01006402 execute( TC_lu_auth_sai_timeout() );
6403 execute( TC_lu_auth_sai_err() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01006404 execute( TC_lu_clear_request() );
Vadim Yanitskiy109e7552021-02-05 05:36:02 +01006405 execute( TC_mo_call_clear_request() );
6406 execute( TC_mt_call_clear_request() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01006407 execute( TC_lu_disconnect() );
6408 execute( TC_lu_by_imei() );
6409 execute( TC_lu_by_tmsi_noauth_unknown() );
Neels Hofmeyrfc06c732020-08-19 12:52:28 +00006410 execute( TC_attached_imsi_lu_unknown_tmsi() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01006411 execute( TC_imsi_detach_by_imsi() );
6412 execute( TC_imsi_detach_by_tmsi() );
6413 execute( TC_imsi_detach_by_imei() );
6414 execute( TC_emerg_call_imei_reject() );
6415 execute( TC_emerg_call_imsi() );
6416 execute( TC_cm_serv_req_vgcs_reject() );
6417 execute( TC_cm_serv_req_vbs_reject() );
6418 execute( TC_cm_serv_req_lcs_reject() );
Harald Welte0195ab12018-01-24 21:50:20 +01006419 execute( TC_cm_reest_req_reject() );
Harald Welte1af6ea82018-01-25 18:33:15 +01006420 execute( TC_lu_auth_2G_fail() );
6421 execute( TC_lu_imsi_auth_tmsi_encr_13_13() );
6422 execute( TC_cl3_no_payload() );
6423 execute( TC_cl3_rnd_payload() );
Harald Welte1852a842018-01-26 22:53:36 +01006424 execute( TC_establish_and_nothing() );
6425 execute( TC_mo_setup_and_nothing() );
6426 execute( TC_mo_crcx_ran_timeout() );
6427 execute( TC_mo_crcx_ran_reject() );
Harald Welted2328a22018-01-27 14:27:16 +01006428 execute( TC_mt_crcx_ran_reject() );
Daniel Willmann8b084372018-02-04 13:35:26 +01006429 execute( TC_mo_setup_and_dtmf_dup() );
Vadim Yanitskiyb56701e2021-02-05 01:54:07 +01006430 execute( TC_mt_t310() );
Harald Welte167458a2018-01-27 15:58:16 +01006431 execute( TC_gsup_cancel() );
Harald Welte9de84792018-01-28 01:06:35 +01006432 execute( TC_lu_imsi_auth_tmsi_encr_1_13() );
6433 execute( TC_lu_imsi_auth_tmsi_encr_3_13() );
6434 execute( TC_lu_imsi_auth_tmsi_encr_3_1() );
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01006435 execute( TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() );
Harald Welte9de84792018-01-28 01:06:35 +01006436 execute( TC_lu_imsi_auth_tmsi_encr_13_2() );
6437 execute( TC_lu_imsi_auth_tmsi_encr_013_2() );
Philipp Maier94f3f1b2018-03-15 18:54:13 +01006438 execute( TC_mo_release_timeout() );
Philipp Maier2a98a732018-03-19 16:06:12 +01006439 execute( TC_lu_and_mt_call_no_dlcx_resp() );
Philipp Maier75932982018-03-27 14:52:35 +02006440 execute( TC_reset_two() );
Harald Welte33ec09b2018-02-10 15:34:46 +01006441
6442 execute( TC_lu_and_mt_call() );
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02006443 execute( TC_lu_and_mt_call_ipv6() );
Neels Hofmeyrb58d9742019-11-27 18:44:54 +01006444 execute( TC_lu_and_mt_call_already_paging() );
Pau Espin Pedrol9a732a42020-09-15 15:56:33 +02006445 execute( TC_lu_and_mt_call_osmux() );
Harald Welte33ec09b2018-02-10 15:34:46 +01006446
Harald Weltef45efeb2018-04-09 18:19:24 +02006447 execute( TC_lu_and_mo_sms() );
6448 execute( TC_lu_and_mt_sms() );
Neels Hofmeyrb58d9742019-11-27 18:44:54 +01006449 execute( TC_lu_and_mt_sms_already_paging() );
Philipp Maier3983e702018-11-22 19:01:33 +01006450 execute( TC_lu_and_mt_sms_paging_and_nothing() );
Alexander Couzensfc02f242019-09-12 03:43:18 +02006451 execute( TC_lu_and_mt_sms_paging_repeated() );
Harald Weltef640a012018-04-14 17:49:21 +02006452 execute( TC_smpp_mo_sms() );
Vadim Yanitskiy33820762020-01-15 11:26:07 +07006453 execute( TC_smpp_mo_sms_rp_error() );
Harald Weltef640a012018-04-14 17:49:21 +02006454 execute( TC_smpp_mt_sms() );
Harald Weltef45efeb2018-04-09 18:19:24 +02006455
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07006456 execute( TC_gsup_mo_sms() );
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07006457 execute( TC_gsup_mo_smma() );
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07006458 execute( TC_gsup_mt_sms_ack() );
6459 execute( TC_gsup_mt_sms_err() );
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07006460 execute( TC_gsup_mt_sms_rp_mr() );
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07006461 execute( TC_gsup_mo_mt_sms_rp_mr() );
Vadim Yanitskiya2a8a112019-07-08 20:04:32 +07006462 execute( TC_gsup_mt_multi_part_sms() );
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07006463
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07006464 execute( TC_lu_and_mo_ussd_single_request() );
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07006465 execute( TC_lu_and_mt_ussd_notification() );
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07006466 execute( TC_lu_and_mo_ussd_during_mt_call() );
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07006467 execute( TC_lu_and_mt_ussd_during_mt_call() );
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07006468 execute( TC_lu_and_mo_ussd_mo_release() );
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07006469 execute( TC_lu_and_ss_session_timeout() );
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07006470
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07006471 execute( TC_mt_ussd_for_unknown_subscr() );
Vadim Yanitskiyc3c07d42019-06-17 23:00:44 +07006472 execute( TC_mo_ussd_for_unknown_trans() );
Vadim Yanitskiyd612d282019-06-15 14:46:03 +07006473 execute( TC_proc_ss_for_unknown_session() );
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07006474 execute( TC_proc_ss_paging_fail() );
Vadim Yanitskiy29ba8d62019-06-16 15:19:41 +07006475 execute( TC_proc_ss_abort() );
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07006476
Vadim Yanitskiy1c9754d2020-01-07 21:56:55 +01006477 execute( TC_multi_lu_and_mo_ussd() );
6478 execute( TC_multi_lu_and_mt_ussd() );
6479
Stefan Sperling89eb1f32018-12-17 15:06:20 +01006480 execute( TC_cipher_complete_with_invalid_cipher() );
Stefan Sperlinga2d59c62018-12-18 16:32:44 +01006481 execute( TC_cipher_complete_1_without_cipher() );
6482 execute( TC_cipher_complete_3_without_cipher() );
6483 execute( TC_cipher_complete_13_without_cipher() );
Harald Welteb2284bd2019-05-10 11:30:43 +02006484 execute( TC_lu_with_invalid_mcc_mnc() );
Stefan Sperling89eb1f32018-12-17 15:06:20 +01006485
Harald Welte4263c522018-12-06 11:56:27 +01006486 execute( TC_sgsap_reset() );
6487 execute( TC_sgsap_lu() );
6488 execute( TC_sgsap_lu_imsi_reject() );
6489 execute( TC_sgsap_lu_and_nothing() );
6490 execute( TC_sgsap_expl_imsi_det_eps() );
Philipp Maierfc19f172019-03-21 11:17:54 +01006491 execute( TC_sgsap_impl_imsi_det_eps() );
Harald Welte4263c522018-12-06 11:56:27 +01006492 execute( TC_sgsap_expl_imsi_det_noneps() );
Philipp Maier5d812702019-03-21 10:51:26 +01006493 execute( TC_sgsap_impl_imsi_det_noneps() );
Harald Welte4263c522018-12-06 11:56:27 +01006494 execute( TC_sgsap_paging_rej() );
6495 execute( TC_sgsap_paging_subscr_rej() );
6496 execute( TC_sgsap_paging_ue_unr() );
6497 execute( TC_sgsap_paging_and_nothing() );
6498 execute( TC_sgsap_paging_and_lu() );
6499 execute( TC_sgsap_mt_sms() );
6500 execute( TC_sgsap_mo_sms() );
6501 execute( TC_sgsap_mt_sms_and_nothing() );
6502 execute( TC_sgsap_mt_sms_and_reject() );
6503 execute( TC_sgsap_unexp_ud() );
6504 execute( TC_sgsap_unsol_ud() );
6505 execute( TC_bssap_lu_sgsap_lu_and_mt_call() );
6506 execute( TC_sgsap_lu_and_mt_call() );
Philipp Maier628c0052019-04-09 17:36:57 +02006507 execute( TC_sgsap_vlr_failure() );
Harald Welte4263c522018-12-06 11:56:27 +01006508
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006509 execute( TC_ho_inter_bsc_unknown_cell() );
6510 execute( TC_ho_inter_bsc() );
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02006511 execute( TC_ho_inter_bsc_ipv6() );
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006512
6513 execute( TC_ho_inter_msc_out() );
Pau Espin Pedrol833174e2020-09-03 16:46:02 +02006514 execute( TC_ho_inter_msc_out_ipv6() );
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006515
Oliver Smith1d118ff2019-07-03 10:57:35 +02006516 execute( TC_lu_imsi_auth_tmsi_check_imei() );
6517 execute( TC_lu_imsi_auth3g_tmsi_check_imei() );
6518 execute( TC_lu_imsi_noauth_tmsi_check_imei() );
6519 execute( TC_lu_imsi_noauth_notmsi_check_imei() );
6520 execute( TC_lu_imsi_auth_tmsi_check_imei_nack() );
6521 execute( TC_lu_imsi_auth_tmsi_check_imei_err() );
6522 execute( TC_lu_imsi_auth_tmsi_check_imei_early() );
6523 execute( TC_lu_imsi_auth3g_tmsi_check_imei_early() );
6524 execute( TC_lu_imsi_noauth_tmsi_check_imei_early() );
6525 execute( TC_lu_imsi_noauth_notmsi_check_imei_early() );
6526 execute( TC_lu_imsi_auth_tmsi_check_imei_early_nack() );
6527 execute( TC_lu_imsi_auth_tmsi_check_imei_early_err() );
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01006528 execute( TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() );
Pau Espin Pedrol609f1d62020-09-15 16:01:55 +02006529
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02006530 execute( TC_mo_cc_bssmap_clear() );
Neels Hofmeyr8df69622019-11-02 19:16:03 +01006531 execute( TC_invalid_mgcp_crash() );
Vadim Yanitskiyeddebaa2019-12-28 17:45:34 +01006532 execute( TC_mm_id_resp_no_identity() );
Vadim Yanitskiy25219062020-01-21 01:41:33 +07006533 execute( TC_lu_and_expire_while_paging() );
Pau Espin Pedrol174fac22021-02-26 13:20:10 +01006534 execute( TC_paging_response_imsi_unknown() );
6535 execute( TC_paging_response_tmsi_unknown() );
Harald Weltef6dd64d2017-11-19 12:09:51 +01006536}
6537
6538
6539}