blob: ee4ea05a51c15d48b0a621b91206059873f227d3 [file] [log] [blame]
Harald Weltef6dd64d2017-11-19 12:09:51 +01001module MSC_Tests {
2
Harald Welte34b5a952019-05-27 11:54:11 +02003/* Osmocom MSC test suite in in TTCN-3
4 * (C) 2017-2019 Harald Welte <laforge@gnumonks.org>
5 * (C) 2018-2019 sysmocom - s.f.m.c. GmbH
6 * (C) 2018-2019 Vadim Yanitskiy <axilirator@gmail.com>
7 * All rights reserved.
8 *
9 * Released under the terms of GNU General Public License, Version 2 or
10 * (at your option) any later version.
11 *
12 * SPDX-License-Identifier: GPL-2.0-or-later
13 */
14
Harald Weltee13cfb22019-04-23 16:52:02 +020015friend module MSC_Tests_Iu;
16
Harald Weltef6dd64d2017-11-19 12:09:51 +010017import from General_Types all;
18import from Osmocom_Types all;
19
20import from M3UA_Types all;
21import from M3UA_Emulation all;
22
23import from MTP3asp_Types all;
24import from MTP3asp_PortType all;
25
26import from SCCPasp_Types all;
27import from SCCP_Types all;
28import from SCCP_Emulation all;
29
30import from SCTPasp_Types all;
31import from SCTPasp_PortType all;
32
Harald Weltea49e36e2018-01-21 19:29:33 +010033import from Osmocom_CTRL_Functions all;
34import from Osmocom_CTRL_Types all;
35import from Osmocom_CTRL_Adapter all;
36
Harald Welte3ca1c902018-01-24 18:51:27 +010037import from TELNETasp_PortType all;
38import from Osmocom_VTY_Functions all;
39
Harald Weltea49e36e2018-01-21 19:29:33 +010040import from MNCC_Emulation all;
Harald Welte2bb825f2018-01-22 11:31:18 +010041import from MNCC_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +010042
Harald Welte4aa970c2018-01-26 10:38:09 +010043import from MGCP_Emulation all;
44import from MGCP_Types all;
45import from MGCP_Templates all;
46import from SDP_Types all;
47
Harald Weltea49e36e2018-01-21 19:29:33 +010048import from GSUP_Emulation all;
49import from GSUP_Types all;
50import from IPA_Emulation all;
51
Harald Weltef6dd64d2017-11-19 12:09:51 +010052import from BSSAP_Types all;
Harald Welte6811d102019-04-14 22:23:14 +020053import from RAN_Adapter all;
Harald Weltea49e36e2018-01-21 19:29:33 +010054import from BSSAP_CodecPort all;
55import from BSSMAP_Templates all;
Harald Welte6811d102019-04-14 22:23:14 +020056import from RAN_Emulation all;
Harald Weltea49e36e2018-01-21 19:29:33 +010057import from BSC_ConnectionHandler all;
Harald Weltee13cfb22019-04-23 16:52:02 +020058import from RANAP_Templates all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010059
Harald Welte4263c522018-12-06 11:56:27 +010060import from SGsAP_Templates all;
61import from SGsAP_Types all;
62import from SGsAP_Emulation all;
63
Harald Weltea49e36e2018-01-21 19:29:33 +010064import from MobileL3_Types all;
65import from MobileL3_CommonIE_Types all;
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +070066import from MobileL3_SMS_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +010067import from L3_Templates all;
Harald Welte158a7ca2018-02-16 18:11:31 +010068import from L3_Common all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010069
Harald Weltef640a012018-04-14 17:49:21 +020070import from SMPP_Types all;
71import from SMPP_Templates all;
72import from SMPP_Emulation all;
73
Stefan Sperlingc307e682018-06-14 15:15:46 +020074import from SCCP_Templates all;
75
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +070076import from SS_Types all;
77import from SS_Templates all;
78import from USSD_Helpers all;
Harald Welte4263c522018-12-06 11:56:27 +010079import from DNS_Helpers all;
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +070080
Philipp Maier948747b2019-04-02 15:22:33 +020081import from TCCConversion_Functions all;
82
Harald Welte9b751a62019-04-14 17:39:29 +020083const integer NUM_BSC := 3;
Harald Weltef6dd64d2017-11-19 12:09:51 +010084
Harald Welte4263c522018-12-06 11:56:27 +010085/* Needed for SGsAP SMS */
86import from MobileL3_SMS_Types all;
87
Harald Weltea4ca4462018-02-09 00:17:14 +010088type component MTC_CT extends CTRL_Adapter_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +010089 var boolean g_initialized := false;
Harald Weltea49e36e2018-01-21 19:29:33 +010090
Harald Welte6811d102019-04-14 22:23:14 +020091 var RAN_Adapter g_bssap[NUM_BSC];
Harald Weltea4ca4462018-02-09 00:17:14 +010092
Harald Weltea49e36e2018-01-21 19:29:33 +010093 /* no 'adapter_CT' for MNCC or GSUP */
94 var MNCC_Emulation_CT vc_MNCC;
Harald Welte4aa970c2018-01-26 10:38:09 +010095 var MGCP_Emulation_CT vc_MGCP;
Harald Weltea49e36e2018-01-21 19:29:33 +010096 var GSUP_Emulation_CT vc_GSUP;
97 var IPA_Emulation_CT vc_GSUP_IPA;
Harald Weltef640a012018-04-14 17:49:21 +020098 var SMPP_Emulation_CT vc_SMPP;
Harald Welte4263c522018-12-06 11:56:27 +010099 var SGsAP_Emulation_CT vc_SGsAP;
Harald Weltea49e36e2018-01-21 19:29:33 +0100100
101 /* only to get events from IPA underneath GSUP */
102 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte3ca1c902018-01-24 18:51:27 +0100103 /* VTY to MSC */
104 port TELNETasp_PT MSCVTY;
Philipp Maier328d1662018-03-07 10:40:27 +0100105
106 /* A port to directly send BSSAP messages. This port is used for
107 * tests that require low level access to sen arbitrary BSSAP
108 * messages. Run f_init_bssap_direct() to connect and initialize */
109 port BSSAP_CODEC_PT BSSAP_DIRECT;
110
111 /* When BSSAP messages are directly sent, then the connection
112 * handler is not active, which means that also no guard timer is
113 * set up. The following timer will serve as a replacement */
114 timer Tguard_direct := 60.0;
Pau Espin Pedrola42745c2020-01-10 18:03:28 +0100115
116 /* Configure T(tias) over VTY, seconds */
117 var integer g_msc_sccp_timer_ias := 7 * 60;
118 /* Configure T(tiar) over VTY, seconds */
119 var integer g_msc_sccp_timer_iar := 15 * 60;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100120}
121
122modulepar {
Harald Weltea49e36e2018-01-21 19:29:33 +0100123 /* remote parameters of IUT */
124 charstring mp_msc_ip := "127.0.0.1";
125 integer mp_msc_ctrl_port := 4255;
126 integer mp_msc_vty_port := 4254;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100127
Harald Weltea49e36e2018-01-21 19:29:33 +0100128 /* local parameters of emulated HLR */
Philipp Maier9b690e42018-12-21 11:50:03 +0100129 boolean mp_mm_info := false;
Harald Weltea49e36e2018-01-21 19:29:33 +0100130 charstring mp_hlr_ip := "127.0.0.1";
131 integer mp_hlr_port := 4222;
Harald Welte6126fb02018-01-27 20:08:24 +0100132 charstring mp_mgw_ip := "127.0.0.1";
133 integer mp_mgw_port := 2427;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100134
Harald Weltea49e36e2018-01-21 19:29:33 +0100135 charstring mp_msc_mncc := "/tmp/mncc";
Harald Weltea4ca4462018-02-09 00:17:14 +0100136
Harald Weltef640a012018-04-14 17:49:21 +0200137 integer mp_msc_smpp_port := 2775;
138 charstring mp_smpp_system_id := "msc_tester";
139 charstring mp_smpp_password := "osmocom1";
Harald Welte4263c522018-12-06 11:56:27 +0100140 charstring mp_mme_name := "mmec01.mmegi0001.mme.epc.mnc070.mcc901.3gppnetwork.org";
141 charstring mp_vlr_name := "vlr.example.net";
Harald Weltef640a012018-04-14 17:49:21 +0200142
Pau Espin Pedrol690d6592019-05-31 17:56:32 +0200143 /* Whether to enable osmux tests. Can be dropped completely and enable
144 unconditionally once new version of osmo-msc is released (current
145 version: 1.3.1) */
146 boolean mp_enable_osmux_test := true;
147
Harald Welte6811d102019-04-14 22:23:14 +0200148 RAN_Configurations mp_bssap_cfg := {
Philipp Maier75932982018-03-27 14:52:35 +0200149 {
150 sccp_service_type := "mtp3_itu",
151 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
152 own_pc := 185,
153 own_ssn := 254,
154 peer_pc := 187,
155 peer_ssn := 254,
156 sio := '83'O,
157 rctx := 0
158 },
159 {
160 sccp_service_type := "mtp3_itu",
161 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
162 own_pc := 186,
163 own_ssn := 254,
164 peer_pc := 187,
165 peer_ssn := 254,
166 sio := '83'O,
167 rctx := 1
168 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100169 };
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200170
171 boolean mp_enable_cell_id_test := true;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100172}
173
Philipp Maier328d1662018-03-07 10:40:27 +0100174/* altstep for the global guard timer (only used when BSSAP_DIRECT
175 * is used for communication */
176private altstep as_Tguard_direct() runs on MTC_CT {
177 [] Tguard_direct.timeout {
178 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200179 mtc.stop;
Philipp Maier328d1662018-03-07 10:40:27 +0100180 }
181}
Harald Weltef6dd64d2017-11-19 12:09:51 +0100182
Neels Hofmeyr2ca1ab42019-03-08 03:45:43 +0100183private altstep as_optional_cc_rel(CallParameters cpars, boolean respond := false) runs on BSC_ConnHdlr {
184 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id))) {
185 if (respond) {
186 var BIT1 tid_remote := '1'B;
187 if (cpars.mo_call) {
188 tid_remote := '0'B;
189 }
190 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id, tid_remote)));
191 }
192 }
Neels Hofmeyrde76f052019-02-26 05:02:46 +0100193}
194
Harald Weltef640a012018-04-14 17:49:21 +0200195function f_init_smpp(charstring id) runs on MTC_CT {
196 id := id & "-SMPP";
197 var EsmePars pars := {
198 mode := MODE_TRANSCEIVER,
199 bind := {
200 system_id := mp_smpp_system_id,
201 password := mp_smpp_password,
202 system_type := "MSC_Tests",
203 interface_version := hex2int('34'H),
204 addr_ton := unknown,
205 addr_npi := unknown,
206 address_range := ""
207 },
208 esme_role := true
209 }
210
211 vc_SMPP := SMPP_Emulation_CT.create(id);
212 map(vc_SMPP:SMPP_PORT, system:SMPP_PORT);
Harald Welte4698a4c2020-08-18 22:57:52 +0200213 vc_SMPP.start(SMPP_Emulation.main_client(pars, mp_msc_ip, mp_msc_smpp_port, "", 0));
Harald Weltef640a012018-04-14 17:49:21 +0200214}
215
216
Harald Weltea49e36e2018-01-21 19:29:33 +0100217function f_init_mncc(charstring id) runs on MTC_CT {
218 id := id & "-MNCC";
219 var MnccOps ops := {
220 create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
221 unitdata_cb := refers(MNCC_Emulation.DummyUnitdataCallback)
222 }
223
224 vc_MNCC := MNCC_Emulation_CT.create(id);
225 map(vc_MNCC:MNCC, system:MNCC_CODEC_PT);
226 vc_MNCC.start(MNCC_Emulation.main(ops, id, mp_msc_mncc));
Harald Weltef6dd64d2017-11-19 12:09:51 +0100227}
228
Harald Welte4aa970c2018-01-26 10:38:09 +0100229function f_init_mgcp(charstring id) runs on MTC_CT {
230 id := id & "-MGCP";
231 var MGCPOps ops := {
232 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
233 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
234 }
235 var MGCP_conn_parameters pars := {
Harald Welte6126fb02018-01-27 20:08:24 +0100236 callagent_ip := mp_msc_ip,
Harald Welte4aa970c2018-01-26 10:38:09 +0100237 callagent_udp_port := -1,
Harald Welte6126fb02018-01-27 20:08:24 +0100238 mgw_ip := mp_mgw_ip,
Pau Espin Pedrol1a026a52019-06-18 17:21:52 +0200239 mgw_udp_port := mp_mgw_port,
240 multi_conn_mode := false
Harald Welte4aa970c2018-01-26 10:38:09 +0100241 }
242
243 vc_MGCP := MGCP_Emulation_CT.create(id);
244 map(vc_MGCP:MGCP, system:MGCP_CODEC_PT);
245 vc_MGCP.start(MGCP_Emulation.main(ops, pars, id));
246}
247
Philipp Maierc09a1312019-04-09 16:05:26 +0200248function ForwardUnitdataCallback(PDU_SGsAP msg)
249runs on SGsAP_Emulation_CT return template PDU_SGsAP {
250 SGsAP_CLIENT.send(msg);
251 return omit;
252}
253
Harald Welte4263c522018-12-06 11:56:27 +0100254function f_init_sgsap(charstring id) runs on MTC_CT {
255 id := id & "-SGsAP";
256 var SGsAPOps ops := {
257 create_cb := refers(SGsAP_Emulation.ExpectedCreateCallback),
Philipp Maierc09a1312019-04-09 16:05:26 +0200258 unitdata_cb := refers(ForwardUnitdataCallback)
Harald Welte4263c522018-12-06 11:56:27 +0100259 }
260 var SGsAP_conn_parameters pars := {
261 remote_ip := mp_msc_ip,
262 remote_sctp_port := 29118,
263 local_ip := "",
264 local_sctp_port := -1
265 }
266
267 vc_SGsAP := SGsAP_Emulation_CT.create(id);
268 map(vc_SGsAP:SGsAP, system:SGsAP_CODEC_PT);
269 vc_SGsAP.start(SGsAP_Emulation.main(ops, pars, id));
270}
271
272
Harald Weltea49e36e2018-01-21 19:29:33 +0100273function f_init_gsup(charstring id) runs on MTC_CT {
274 id := id & "-GSUP";
275 var GsupOps ops := {
276 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
277 }
278
279 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
280 vc_GSUP := GSUP_Emulation_CT.create(id);
281
282 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
283 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
284 /* we use this hack to get events like ASP_IPA_EVENT_UP */
285 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
286
287 vc_GSUP.start(GSUP_Emulation.main(ops, id));
288 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
289
290 /* wait for incoming connection to GSUP port before proceeding */
291 timer T := 10.0;
292 T.start;
293 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700294 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Weltea49e36e2018-01-21 19:29:33 +0100295 [] T.timeout {
Harald Welte458fd372018-03-21 11:26:23 +0100296 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200297 mtc.stop
Harald Weltea49e36e2018-01-21 19:29:33 +0100298 }
299 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100300}
301
Pau Espin Pedrola65697d2019-05-21 12:54:39 +0200302function f_init(integer num_bsc := 1, boolean sgsap := false, boolean gsup := true, boolean osmux := false) runs on MTC_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +0100303
304 if (g_initialized == true) {
305 return;
306 }
307 g_initialized := true;
308
Philipp Maier75932982018-03-27 14:52:35 +0200309 if (num_bsc > NUM_BSC) {
Daniel Willmannafce8662018-07-06 23:11:32 +0200310 testcase.stop("excess number of BSC instances requested");
Philipp Maier75932982018-03-27 14:52:35 +0200311 }
312
313 for (var integer i := 0; i < num_bsc; i := i + 1) {
314 if (isbound(mp_bssap_cfg[i])) {
Pau Espin Pedrola65697d2019-05-21 12:54:39 +0200315 var RanOps ranops := BSC_RanOps;
316 ranops.use_osmux := osmux;
317 f_ran_adapter_init(g_bssap[i], mp_bssap_cfg[i], "MSC_Test_" & int2str(i), ranops);
Harald Welte3ca0ce12019-04-23 17:18:48 +0200318 f_ran_adapter_start(g_bssap[i]);
Philipp Maier75932982018-03-27 14:52:35 +0200319 } else {
Daniel Willmannafce8662018-07-06 23:11:32 +0200320 testcase.stop("missing BSSAP configuration");
Philipp Maier75932982018-03-27 14:52:35 +0200321 }
322 }
323
Harald Weltea49e36e2018-01-21 19:29:33 +0100324 f_ipa_ctrl_start(mp_msc_ip, mp_msc_ctrl_port);
325 f_init_mncc("MSC_Test");
Harald Welte4aa970c2018-01-26 10:38:09 +0100326 f_init_mgcp("MSC_Test");
Philipp Maierc09a1312019-04-09 16:05:26 +0200327
328 if (gsup == true) {
329 f_init_gsup("MSC_Test");
330 }
Harald Weltef640a012018-04-14 17:49:21 +0200331 f_init_smpp("MSC_Test");
Philipp Maier57865482019-01-07 18:33:13 +0100332
Philipp Maier8e07a4a2019-02-14 18:23:28 +0100333 if (sgsap == true) {
Philipp Maier57865482019-01-07 18:33:13 +0100334 f_init_sgsap("MSC_Test");
335 }
Harald Welte3ca1c902018-01-24 18:51:27 +0100336
337 map(self:MSCVTY, system:MSCVTY);
338 f_vty_set_prompts(MSCVTY);
339 f_vty_transceive(MSCVTY, "enable");
Harald Welteb14c77a2018-01-25 17:25:44 +0100340
341 /* set some defaults */
342 f_vty_config(MSCVTY, "network", "authentication optional");
343 f_vty_config(MSCVTY, "msc", "assign-tmsi");
Oliver Smith1d118ff2019-07-03 10:57:35 +0200344 f_vty_config(MSCVTY, "msc", "check-imei-rqd 0");
Harald Welteb14c77a2018-01-25 17:25:44 +0100345 f_vty_config(MSCVTY, "network", "encryption a5 0");
Pau Espin Pedrola42745c2020-01-10 18:03:28 +0100346 f_vty_config(MSCVTY, "cs7 instance 0", "sccp-timer ias " & int2str(g_msc_sccp_timer_ias));
347 f_vty_config(MSCVTY, "cs7 instance 0", "sccp-timer iar " & int2str(g_msc_sccp_timer_iar));
Pau Espin Pedrol690d6592019-05-31 17:56:32 +0200348 if (mp_enable_osmux_test) {
349 if (osmux) {
350 f_vty_config(MSCVTY, "msc", "osmux on");
351 } else {
352 f_vty_config(MSCVTY, "msc", "osmux off");
353 }
Pau Espin Pedrol3dd33bc2019-05-31 17:51:20 +0200354 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100355}
356
Philipp Maier328d1662018-03-07 10:40:27 +0100357/* Initialize for a direct connection to BSSAP. This function is an alternative
358 * to f_init() when the high level functions of the BSC_ConnectionHandler are
359 * not needed. */
360function f_init_bssap_direct() runs on MTC_CT {
Harald Welte3ca0ce12019-04-23 17:18:48 +0200361 f_ran_adapter_init(g_bssap[0], mp_bssap_cfg[0], "MSC_Test", omit);
Philipp Maier75932982018-03-27 14:52:35 +0200362 connect(g_bssap[0].vc_SCCP:SCCP_SP_PORT, self:BSSAP_DIRECT);
Philipp Maier328d1662018-03-07 10:40:27 +0100363
364 /* Start guard timer and activate it as default */
365 Tguard_direct.start
366 activate(as_Tguard_direct());
367}
368
Harald Weltea49e36e2018-01-21 19:29:33 +0100369type function void_fn(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100370
Harald Weltea49e36e2018-01-21 19:29:33 +0100371/* FIXME: move into BSC_ConnectionHandler? */
Harald Welte9b751a62019-04-14 17:39:29 +0200372function f_init_pars(integer imsi_suffix, boolean sgsap := false, boolean gsup := true, integer ran_idx := 0,
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200373 boolean ran_is_geran := true, boolean use_osmux := false, OCT4 gsup_sid := '20000101'O,
374 boolean verify_cell_id := true)
Harald Weltef9abf8d2019-04-21 13:07:17 +0200375runs on MTC_CT return BSC_ConnHdlrPars {
Harald Weltede371492018-01-27 23:44:41 +0100376 var BSC_ConnHdlrNetworkPars net_pars := {
377 kc_support := '0A'O, /* A5/1 and A5/3 enabled */
378 expect_tmsi := true,
379 expect_auth := false,
Oliver Smith1d118ff2019-07-03 10:57:35 +0200380 expect_ciph := false,
381 expect_imei := false,
382 expect_imei_early := false,
383 check_imei_result := OSMO_GSUP_IMEI_RESULT_ACK,
384 check_imei_error := false
Harald Weltede371492018-01-27 23:44:41 +0100385 };
Harald Weltea49e36e2018-01-21 19:29:33 +0100386 var BSC_ConnHdlrPars pars := {
Harald Weltef9abf8d2019-04-21 13:07:17 +0200387 sccp_addr_own := g_bssap[ran_idx].sccp_addr_own,
388 sccp_addr_peer := g_bssap[ran_idx].sccp_addr_peer,
Harald Welteedbab812018-03-18 16:02:25 +0100389 cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42)),
Harald Welte81b7f9d2018-01-24 19:06:24 +0100390 imei := f_gen_imei(imsi_suffix),
391 imsi := f_gen_imsi(imsi_suffix),
392 msisdn := f_gen_msisdn(imsi_suffix),
Harald Welte256571e2018-01-24 18:47:19 +0100393 tmsi := omit,
Harald Welte9de84792018-01-28 01:06:35 +0100394 cm1 := valueof(ts_CM1),
Harald Welte82600572018-01-21 20:54:08 +0100395 cm2 := valueof(ts_CM2_default),
Harald Welte16114282018-01-24 22:41:21 +0100396 cm3 := omit,
Harald Weltede371492018-01-27 23:44:41 +0100397 vec := omit,
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100398 net := net_pars,
Philipp Maieraeb29a82018-11-08 17:40:53 +0100399 send_early_cm := true,
400 ipa_ctrl_ip := mp_msc_ip,
401 ipa_ctrl_port := mp_msc_ctrl_port,
Philipp Maier9b690e42018-12-21 11:50:03 +0100402 ipa_ctrl_enable := true,
Philipp Maier57865482019-01-07 18:33:13 +0100403 mm_info := mp_mm_info,
Philipp Maierc09a1312019-04-09 16:05:26 +0200404 sgsap_enable := sgsap,
Harald Weltef9abf8d2019-04-21 13:07:17 +0200405 gsup_enable := gsup,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +0100406 gsup_sid := gsup_sid,
Harald Weltec1f937a2019-04-21 21:19:23 +0200407 ran_idx := ran_idx,
Harald Welte9b751a62019-04-14 17:39:29 +0200408 use_umts_aka := false,
Pau Espin Pedrola65697d2019-05-21 12:54:39 +0200409 ran_is_geran := ran_is_geran,
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200410 use_osmux := use_osmux,
411 verify_cell_id := mp_enable_cell_id_test and verify_cell_id
Harald Weltea49e36e2018-01-21 19:29:33 +0100412 };
Harald Weltee13cfb22019-04-23 16:52:02 +0200413 if (not ran_is_geran) {
414 pars.use_umts_aka := true;
415 pars.net.expect_auth := true;
416 }
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100417 return pars;
418}
419
Neels Hofmeyr0ac63152019-05-07 01:20:17 +0200420function f_start_handler_with_pars(void_fn fn, BSC_ConnHdlrPars pars, integer bssap_idx := 0) runs on MTC_CT return BSC_ConnHdlr {
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100421 var BSC_ConnHdlr vc_conn;
Neels Hofmeyr0ac63152019-05-07 01:20:17 +0200422 var charstring id := testcasename() & int2str(bssap_idx);
Harald Weltea49e36e2018-01-21 19:29:33 +0100423
424 vc_conn := BSC_ConnHdlr.create(id);
425 /* BSSMAP part / A interface */
Neels Hofmeyr0ac63152019-05-07 01:20:17 +0200426 connect(vc_conn:BSSAP, g_bssap[pars.ran_idx + bssap_idx].vc_RAN:CLIENT);
427 connect(vc_conn:BSSAP_PROC, g_bssap[pars.ran_idx + bssap_idx].vc_RAN:PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100428 /* MNCC part */
429 connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
430 connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);
Harald Welte4aa970c2018-01-26 10:38:09 +0100431 /* MGCP part */
432 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
433 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100434 /* GSUP part */
Philipp Maierc09a1312019-04-09 16:05:26 +0200435 if (pars.gsup_enable == true) {
436 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
437 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
438 }
Harald Weltef640a012018-04-14 17:49:21 +0200439 /* SMPP part */
440 connect(vc_conn:SMPP, vc_SMPP:SMPP_CLIENT);
441 connect(vc_conn:SMPP_PROC, vc_SMPP:SMPP_PROC);
Harald Welte4263c522018-12-06 11:56:27 +0100442 /* SGs part */
Philipp Maier8e07a4a2019-02-14 18:23:28 +0100443 if (pars.sgsap_enable == true) {
Philipp Maier57865482019-01-07 18:33:13 +0100444 connect(vc_conn:SGsAP, vc_SGsAP:SGsAP_CLIENT);
445 connect(vc_conn:SGsAP_PROC, vc_SGsAP:SGsAP_PROC);
446 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100447
Harald Weltea10db902018-01-27 12:44:49 +0100448 /* We cannot use vc_conn.start(f_init_handler(fn, id, pars)); as we cannot have
449 * a stand-alone 'derefers()' call, see https://www.eclipse.org/forums/index.php/t/1091364/ */
Harald Weltea49e36e2018-01-21 19:29:33 +0100450 vc_conn.start(derefers(fn)(id, pars));
451 return vc_conn;
452}
453
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200454function f_start_handler(void_fn fn, integer imsi_suffix, integer ran_idx := 0, boolean ran_is_geran := true, boolean use_osmux := false,
455 boolean verify_cell_id := true)
Harald Welte9b751a62019-04-14 17:39:29 +0200456runs on MTC_CT return BSC_ConnHdlr {
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200457 return f_start_handler_with_pars(fn, f_init_pars(imsi_suffix, ran_idx := ran_idx, ran_is_geran := ran_is_geran, use_osmux := use_osmux, verify_cell_id := verify_cell_id));
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100458}
459
Harald Weltea49e36e2018-01-21 19:29:33 +0100460private function f_tc_lu_imsi_noauth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100461 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100462 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100463}
Harald Weltea49e36e2018-01-21 19:29:33 +0100464testcase TC_lu_imsi_noauth_tmsi() runs on MTC_CT {
465 var BSC_ConnHdlr vc_conn;
466 f_init();
467
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100468 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi), 1);
Harald Weltea49e36e2018-01-21 19:29:33 +0100469 vc_conn.done;
470}
471
472private function f_tc_lu_imsi_noauth_notmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100473 pars.net.expect_tmsi := false;
Harald Weltea10db902018-01-27 12:44:49 +0100474 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100475 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100476}
Harald Weltea49e36e2018-01-21 19:29:33 +0100477testcase TC_lu_imsi_noauth_notmsi() runs on MTC_CT {
478 var BSC_ConnHdlr vc_conn;
479 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100480 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
Harald Weltea49e36e2018-01-21 19:29:33 +0100481
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100482 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi), 2);
Harald Weltea49e36e2018-01-21 19:29:33 +0100483 vc_conn.done;
484}
485
486/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
Harald Weltee13cfb22019-04-23 16:52:02 +0200487friend function f_tc_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100488 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100489 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
490
491 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +0200492 f_cl3_or_initial_ue(l3_lu);
Neels Hofmeyrd076c522019-11-28 01:00:52 +0100493 f_mm_common();
Harald Weltea49e36e2018-01-21 19:29:33 +0100494 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
495 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
496 alt {
Harald Welte5946b332018-03-18 23:32:21 +0100497 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej(int2oct(23,1)))) {
498 f_expect_clear();
499 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100500 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
501 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
Daniel Willmannafce8662018-07-06 23:11:32 +0200502 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100503 }
504 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100505}
506testcase TC_lu_imsi_reject() runs on MTC_CT {
507 var BSC_ConnHdlr vc_conn;
508 f_init();
509
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200510 vc_conn := f_start_handler(refers(f_tc_lu_imsi_reject), 3, verify_cell_id := false);
Harald Weltea49e36e2018-01-21 19:29:33 +0100511 vc_conn.done;
512}
513
Harald Weltee13cfb22019-04-23 16:52:02 +0200514
515
Harald Weltea49e36e2018-01-21 19:29:33 +0100516/* Do LU by IMSI, timeout on GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +0200517friend function f_tc_lu_imsi_timeout_gsup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100518 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100519 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
520
521 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +0200522 f_cl3_or_initial_ue(l3_lu);
Neels Hofmeyrd076c522019-11-28 01:00:52 +0100523 f_mm_common();
Harald Weltea49e36e2018-01-21 19:29:33 +0100524 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
525 /* Normally the HLR would need to respond here, but we decide to force a timeout here */
526 alt {
527 /* FIXME: Expect specific reject cause */
Harald Welte5946b332018-03-18 23:32:21 +0100528 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
529 f_expect_clear();
530 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100531 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
532 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
Daniel Willmannafce8662018-07-06 23:11:32 +0200533 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100534 }
535 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100536}
537testcase TC_lu_imsi_timeout_gsup() runs on MTC_CT {
538 var BSC_ConnHdlr vc_conn;
539 f_init();
540
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200541 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_gsup), 4, verify_cell_id := false);
Harald Weltea49e36e2018-01-21 19:29:33 +0100542 vc_conn.done;
543}
544
Harald Weltee13cfb22019-04-23 16:52:02 +0200545
Harald Welte7b1b2812018-01-22 21:23:06 +0100546private function f_tc_lu_imsi_auth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100547 pars.net.expect_auth := true;
Harald Weltea10db902018-01-27 12:44:49 +0100548 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100549 f_perform_lu();
Harald Welte7b1b2812018-01-22 21:23:06 +0100550}
551testcase TC_lu_imsi_auth_tmsi() runs on MTC_CT {
552 var BSC_ConnHdlr vc_conn;
553 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100554 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte7b1b2812018-01-22 21:23:06 +0100555
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100556 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi), 5);
Harald Welte7b1b2812018-01-22 21:23:06 +0100557 vc_conn.done;
558}
559
Harald Weltee13cfb22019-04-23 16:52:02 +0200560
561friend function f_tc_lu_imsi_auth3g_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Welte8a397ae2019-04-21 22:03:37 +0200562 pars.net.expect_auth := true;
563 pars.use_umts_aka := true;
564 f_init_handler(pars);
565 f_perform_lu();
566}
567testcase TC_lu_imsi_auth3g_tmsi() runs on MTC_CT {
568 var BSC_ConnHdlr vc_conn;
569 f_init();
570 f_vty_config(MSCVTY, "network", "authentication required");
571
572 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth3g_tmsi), 1005);
573 vc_conn.done;
574}
Harald Weltea49e36e2018-01-21 19:29:33 +0100575
Pau Espin Pedrold3d54a92019-12-17 17:02:54 +0100576/* Proceed with LU but never receive an TMSI Realloc from MS after LU Accept (OS#4337).
577 * TS 24.008 sec 4.3.1.5 states MSC should simply release all MM connections.
578 */
579friend function f_tc_lu_imsi_timeout_tmsi_realloc(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
580
581 f_init_handler(pars);
582
583 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
584 var PDU_DTAP_MT dtap_mt;
585
586 /* tell GSUP dispatcher to send this IMSI to us */
587 f_create_gsup_expect(hex2str(g_pars.imsi));
588
589 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
590 if (g_pars.ran_is_geran) {
591 f_bssap_compl_l3(l3_lu);
592 if (g_pars.send_early_cm) {
593 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
594 }
595 } else {
596 f_ranap_initial_ue(l3_lu);
597 }
598
599 f_mm_imei_early();
600 f_mm_common();
601 f_msc_lu_hlr();
602 f_mm_imei();
603
604 alt {
605 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) -> value dtap_mt {}
606 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
607 setverdict(fail, "Expected LU ACK, but received LU REJ");
608 mtc.stop;
609 }
610 }
611
612 /* currently (due to bug OS#4337), an extra LU reject is received before
613 terminating the connection. Enabling following line makes the test
614 pass: */
615 //f_expect_lu_reject('16'O); /* Cause: congestion */
616
617 /* f_expect_lu_reject() already waits for T"-1" (X1, 5 seconds), but give some
618 extra time to avoid race conditons... */
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200619 f_expect_clear(7.0, verify_vlr_cell_id := false);
Pau Espin Pedrold3d54a92019-12-17 17:02:54 +0100620
621 setverdict(pass);
622}
623testcase TC_lu_imsi_timeout_tmsi_realloc() runs on MTC_CT {
624 var BSC_ConnHdlr vc_conn;
625 f_init();
626
627 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_tmsi_realloc), 5);
628 vc_conn.done;
629}
630
Harald Weltee13cfb22019-04-23 16:52:02 +0200631
Harald Weltea49e36e2018-01-21 19:29:33 +0100632/* Send CM SERVICE REQ for IMSI that has never performed LU before */
Harald Weltee13cfb22019-04-23 16:52:02 +0200633friend function f_tc_cmserv_imsi_unknown(charstring id, BSC_ConnHdlrPars pars)
Harald Weltea49e36e2018-01-21 19:29:33 +0100634runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100635 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100636
637 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welteedbab812018-03-18 16:02:25 +0100638 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100639 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltea49e36e2018-01-21 19:29:33 +0100640
641 f_create_gsup_expect(hex2str(g_pars.imsi));
642
643 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200644 f_cl3_or_initial_ue(l3_info);
Harald Welteb7817992019-05-09 13:15:39 +0200645 f_mm_auth();
Harald Weltea49e36e2018-01-21 19:29:33 +0100646
647 timer T := 10.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100648 T.start;
649 alt {
Harald Weltea49e36e2018-01-21 19:29:33 +0100650 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
651 //[] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC)) { }
Daniel Willmannafce8662018-07-06 23:11:32 +0200652 [] BSSAP.receive {
653 setverdict(fail, "Received unexpected BSSAP");
654 mtc.stop;
655 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100656 [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
657 setverdict(fail, "Unexpected GSUP UL REQ");
Daniel Willmannafce8662018-07-06 23:11:32 +0200658 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100659 }
Daniel Willmannafce8662018-07-06 23:11:32 +0200660 [] T.timeout {
Neels Hofmeyrf1c3c212020-08-19 13:15:32 +0000661 setverdict(fail, "Timeout waiting for CM SERV REJ");
Daniel Willmannafce8662018-07-06 23:11:32 +0200662 mtc.stop;
663 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100664 }
665
Harald Welte1ddc7162018-01-27 14:25:46 +0100666 f_expect_clear();
Harald Weltef6dd64d2017-11-19 12:09:51 +0100667}
Harald Weltea49e36e2018-01-21 19:29:33 +0100668testcase TC_cmserv_imsi_unknown() runs on MTC_CT {
669 var BSC_ConnHdlr vc_conn;
670 f_init();
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200671 vc_conn := f_start_handler(refers(f_tc_cmserv_imsi_unknown), 6, verify_cell_id := false);
Harald Weltea49e36e2018-01-21 19:29:33 +0100672 vc_conn.done;
673}
674
Harald Weltee13cfb22019-04-23 16:52:02 +0200675
Neels Hofmeyr13737fb2020-08-19 13:16:14 +0000676/* Send CM SERVICE REQ for TMSI that has never performed LU before */
677friend function f_tc_cmserv_tmsi_unknown(charstring id, BSC_ConnHdlrPars pars)
678runs on BSC_ConnHdlr {
679 f_init_handler(pars);
680
681 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('57111111'O));
682 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42));
683 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
684
685 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
686 f_cl3_or_initial_ue(l3_info);
687 f_mm_auth();
688
689 timer T := 10.0;
690 T.start;
691 alt {
692 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
693 [] BSSAP.receive {
694 setverdict(fail, "Received unexpected BSSAP");
695 mtc.stop;
696 }
697 [] T.timeout {
698 setverdict(fail, "Timeout waiting for CM SERV REJ");
699 mtc.stop;
700 }
701 }
702
703 f_expect_clear();
704}
705testcase TC_cmserv_tmsi_unknown() runs on MTC_CT {
706 var BSC_ConnHdlr vc_conn;
707 f_init();
708 vc_conn := f_start_handler(refers(f_tc_cmserv_tmsi_unknown), 57, verify_cell_id := false);
709 vc_conn.done;
710}
711
712
Harald Weltee13cfb22019-04-23 16:52:02 +0200713friend function f_tc_lu_and_mo_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100714 f_init_handler(pars);
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +0200715 var CallParameters cpars := valueof(t_CallParams);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100716 f_perform_lu();
Harald Welteb71901a2018-01-26 19:16:05 +0100717 f_mo_call(cpars);
Harald Welte2bb825f2018-01-22 11:31:18 +0100718}
719testcase TC_lu_and_mo_call() runs on MTC_CT {
720 var BSC_ConnHdlr vc_conn;
721 f_init();
722
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100723 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_call), 7);
Harald Welte071ed732018-01-23 19:53:52 +0100724 vc_conn.done;
725}
726
Pau Espin Pedrola42745c2020-01-10 18:03:28 +0100727/* Verify T(iar) triggers and releases the channel */
728friend function f_lu_and_mo_call_sccp_tiar_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
729 timer T_wait_iar := int2float(5 + 1); /* g_msc_sccp_timer_iar + Give extra time (+1 sec) */
730 f_init_handler(pars);
731 var CallParameters cpars := valueof(t_CallParams);
732 f_perform_lu();
733 f_mo_call_establish(cpars);
734
735 /* Expect the channel cleared upon T(iar) triggered: */
736 T_wait_iar.start;
737 alt {
738 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
739 T_wait_iar.stop
740 setverdict(pass);
741 }
Pau Espin Pedrola42745c2020-01-10 18:03:28 +0100742 [] T_wait_iar.timeout {
743 setverdict(fail, "Timeout waiting for T(iar) triggered SCCP RSLD");
744 mtc.stop;
745 }
746 }
Harald Welte4a3fa712020-08-19 08:57:33 +0200747 /* DLCX for both directions; if we don't do this, we might receive either of the two during
748 * shutdown causing race conditions */
749 MGCP.receive(tr_DLCX(?));
750 MGCP.receive(tr_DLCX(?));
Pau Espin Pedrola42745c2020-01-10 18:03:28 +0100751
752 setverdict(pass);
753}
754testcase TC_lu_and_mo_call_sccp_tiar_timeout() runs on MTC_CT {
755 var BSC_ConnHdlr vc_conn;
756
757 /* Set T(iar) in MSC low enough that it will trigger before other side
758 has time to keep alive with a T(ias). Keep recommended ratio of
759 T(iar) >= T(ias)*2 */
760 g_msc_sccp_timer_ias := 2;
761 g_msc_sccp_timer_iar := 5;
762
763 f_init();
764
765 vc_conn := f_start_handler(refers(f_lu_and_mo_call_sccp_tiar_timeout), 89);
766 vc_conn.done;
767}
768
Harald Weltee13cfb22019-04-23 16:52:02 +0200769
Harald Welte071ed732018-01-23 19:53:52 +0100770/* Test LU (with authentication enabled), where HLR times out sending SAI response */
Harald Weltee13cfb22019-04-23 16:52:02 +0200771friend function f_tc_lu_auth_sai_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100772 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100773
774 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
775 var PDU_DTAP_MT dtap_mt;
776
777 /* tell GSUP dispatcher to send this IMSI to us */
778 f_create_gsup_expect(hex2str(g_pars.imsi));
779
780 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200781 f_cl3_or_initial_ue(l3_lu);
Harald Welte071ed732018-01-23 19:53:52 +0100782
783 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +0200784 if (pars.ran_is_geran) {
785 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
786 }
Harald Welte071ed732018-01-23 19:53:52 +0100787
788 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
789 /* The HLR would normally return an auth vector here, but we fail to do so. */
790
791 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100792 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100793}
794testcase TC_lu_auth_sai_timeout() runs on MTC_CT {
795 var BSC_ConnHdlr vc_conn;
796 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100797 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100798
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200799 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_timeout), 8, verify_cell_id := false);
Harald Welte071ed732018-01-23 19:53:52 +0100800 vc_conn.done;
801}
802
Harald Weltee13cfb22019-04-23 16:52:02 +0200803
Harald Welte071ed732018-01-23 19:53:52 +0100804/* Test LU (with authentication enabled), where HLR rejects sending SAI error */
Harald Weltee13cfb22019-04-23 16:52:02 +0200805friend function f_tc_lu_auth_sai_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100806 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100807
808 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
809 var PDU_DTAP_MT dtap_mt;
810
811 /* tell GSUP dispatcher to send this IMSI to us */
812 f_create_gsup_expect(hex2str(g_pars.imsi));
813
814 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200815 f_cl3_or_initial_ue(l3_lu);
Harald Welte071ed732018-01-23 19:53:52 +0100816
817 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +0200818 if (pars.ran_is_geran) {
819 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
820 }
Harald Welte071ed732018-01-23 19:53:52 +0100821
822 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
823 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 13));
824
825 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100826 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100827}
828testcase TC_lu_auth_sai_err() runs on MTC_CT {
829 var BSC_ConnHdlr vc_conn;
830 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100831 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100832
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200833 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_err), 9, verify_cell_id := false);
Harald Welte2bb825f2018-01-22 11:31:18 +0100834 vc_conn.done;
835}
Harald Weltea49e36e2018-01-21 19:29:33 +0100836
Harald Weltee13cfb22019-04-23 16:52:02 +0200837
Harald Weltebc881782018-01-23 20:09:15 +0100838/* Test LU but BSC will send a clear request in the middle */
839private function f_tc_lu_clear_request(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100840 f_init_handler(pars);
Harald Weltebc881782018-01-23 20:09:15 +0100841
842 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
843 var PDU_DTAP_MT dtap_mt;
844
845 /* tell GSUP dispatcher to send this IMSI to us */
846 f_create_gsup_expect(hex2str(g_pars.imsi));
847
848 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200849 f_cl3_or_initial_ue(l3_lu);
Harald Welte79f1e452020-08-18 22:55:02 +0200850 f_expect_common_id();
Harald Weltebc881782018-01-23 20:09:15 +0100851
852 /* Send Early Classmark, just for the fun of it */
853 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
854
855 f_sleep(1.0);
856 /* send clear request in the middle of the LU */
857 BSSAP.send(ts_BSSMAP_ClearRequest(0));
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200858 alt {
859 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { repeat; }
860 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {}
861 }
Harald Weltebc881782018-01-23 20:09:15 +0100862 BSSAP.send(ts_BSSMAP_ClearComplete);
Harald Welte89a32492018-01-27 19:07:28 +0100863 alt {
864 /* See https://osmocom.org/issues/2862 */
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200865 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
866 setverdict(fail, "Got a second Clear Command, only one expected");
Daniel Willmannafce8662018-07-06 23:11:32 +0200867 mtc.stop;
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200868 repeat;
869 }
Harald Welte6811d102019-04-14 22:23:14 +0200870 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte89a32492018-01-27 19:07:28 +0100871 }
Harald Weltebc881782018-01-23 20:09:15 +0100872 setverdict(pass);
873}
874testcase TC_lu_clear_request() runs on MTC_CT {
875 var BSC_ConnHdlr vc_conn;
876 f_init();
877
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100878 vc_conn := f_start_handler(refers(f_tc_lu_clear_request), 10);
Harald Weltebc881782018-01-23 20:09:15 +0100879 vc_conn.done;
880}
881
Harald Welte66af9e62018-01-24 17:28:21 +0100882/* Test LU but BSC will send a clear request in the middle */
Harald Weltee13cfb22019-04-23 16:52:02 +0200883friend function f_tc_lu_disconnect(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100884 f_init_handler(pars);
Harald Welte66af9e62018-01-24 17:28:21 +0100885
886 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
887 var PDU_DTAP_MT dtap_mt;
888
889 /* tell GSUP dispatcher to send this IMSI to us */
890 f_create_gsup_expect(hex2str(g_pars.imsi));
891
892 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200893 f_cl3_or_initial_ue(l3_lu);
Harald Welte66af9e62018-01-24 17:28:21 +0100894
895 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +0200896 if (pars.ran_is_geran) {
897 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
898 }
Harald Welte66af9e62018-01-24 17:28:21 +0100899
900 f_sleep(1.0);
901 /* send clear request in the middle of the LU */
Harald Welte6811d102019-04-14 22:23:14 +0200902 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Harald Welte66af9e62018-01-24 17:28:21 +0100903 setverdict(pass);
Neels Hofmeyrbb825c92019-03-06 15:35:50 +0100904 f_sleep(1.0);
Harald Welte66af9e62018-01-24 17:28:21 +0100905}
906testcase TC_lu_disconnect() runs on MTC_CT {
907 var BSC_ConnHdlr vc_conn;
908 f_init();
909
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100910 vc_conn := f_start_handler(refers(f_tc_lu_disconnect), 11);
Harald Welte66af9e62018-01-24 17:28:21 +0100911 vc_conn.done;
912}
913
Harald Welteba7b6d92018-01-23 21:32:34 +0100914/* Test LU but with illegal mobile identity type = IMEI */
Harald Weltee13cfb22019-04-23 16:52:02 +0200915friend function f_tc_lu_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100916 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100917
Harald Welte256571e2018-01-24 18:47:19 +0100918 var PDU_ML3_MS_NW l3_lu := f_build_lu_imei(g_pars.imei)
Harald Welteba7b6d92018-01-23 21:32:34 +0100919 var PDU_DTAP_MT dtap_mt;
920
921 /* tell GSUP dispatcher to send this IMSI to us */
922 f_create_gsup_expect(hex2str(g_pars.imsi));
923
924 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200925 f_cl3_or_initial_ue(l3_lu);
Harald Welteba7b6d92018-01-23 21:32:34 +0100926
927 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +0200928 if (pars.ran_is_geran) {
929 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
930 }
Harald Welteba7b6d92018-01-23 21:32:34 +0100931 /* wait for LU reject, ignore any ID REQ */
932 alt {
933 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
934 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req)) { repeat; }
935 }
936 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100937 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100938}
939testcase TC_lu_by_imei() runs on MTC_CT {
940 var BSC_ConnHdlr vc_conn;
941 f_init();
942
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +0200943 vc_conn := f_start_handler(refers(f_tc_lu_by_imei), 12, verify_cell_id := false);
Harald Welteba7b6d92018-01-23 21:32:34 +0100944 vc_conn.done;
945}
946
Harald Weltee13cfb22019-04-23 16:52:02 +0200947
Harald Welteba7b6d92018-01-23 21:32:34 +0100948/* Test LU by TMSI with unknown TMSI, expect (and answer) ID REQ. */
949private function f_tc_lu_tmsi_noauth_unknown(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Stefan Sperling04fc4bc2018-06-25 17:44:57 +0200950 /* We piggyback a test for an MSC crash on overlong IMSI (OS#2864) onto this test. */
951 var hexstring overlong_imsi := '012345789ABCDEF0123456789ABCDEF'H;
Harald Weltea10db902018-01-27 12:44:49 +0100952 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100953
954 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('01020304'O); /* FIXME: Random */
955 var PDU_DTAP_MT dtap_mt;
956
957 /* tell GSUP dispatcher to send this IMSI to us */
958 f_create_gsup_expect(hex2str(g_pars.imsi));
959
960 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200961 f_cl3_or_initial_ue(l3_lu);
Harald Welteba7b6d92018-01-23 21:32:34 +0100962
963 /* Send Early Classmark, just for the fun of it */
964 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
965
966 /* Wait for + respond to ID REQ (IMSI) */
Oliver Smith32898452019-07-09 12:32:35 +0200967 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req(CM_ID_TYPE_IMSI)));
Stefan Sperling04fc4bc2018-06-25 17:44:57 +0200968 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 +0100969 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
Harald Welte79f1e452020-08-18 22:55:02 +0200970 f_expect_common_id();
Harald Welteba7b6d92018-01-23 21:32:34 +0100971
972 /* Expect MSC to do UpdateLocation to HLR; respond to it */
973 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
974 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
975 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
976 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
977
978 alt {
Harald Welte7ec4fa82018-01-27 10:57:40 +0100979 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
980 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
981 }
Harald Welteba7b6d92018-01-23 21:32:34 +0100982 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
983 setverdict(fail, "Expected LU ACK, but received REJ");
Daniel Willmannafce8662018-07-06 23:11:32 +0200984 mtc.stop;
Harald Welteba7b6d92018-01-23 21:32:34 +0100985 }
986 }
987
Philipp Maier9b690e42018-12-21 11:50:03 +0100988 /* Wait for MM-Information (if enabled) */
989 f_expect_mm_info();
990
Harald Welteba7b6d92018-01-23 21:32:34 +0100991 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100992 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100993}
994testcase TC_lu_by_tmsi_noauth_unknown() runs on MTC_CT {
995 var BSC_ConnHdlr vc_conn;
996 f_init();
997
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100998 vc_conn := f_start_handler(refers(f_tc_lu_tmsi_noauth_unknown), 13);
Harald Welteba7b6d92018-01-23 21:32:34 +0100999 vc_conn.done;
1000}
1001
Neels Hofmeyrfc06c732020-08-19 12:52:28 +00001002/* Test LU by unknown TMSI, while the IMSI is already attached: osmo-msc should switch to the attached vlr_subscr. */
1003private function f_tc_attached_imsi_lu_unknown_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1004 f_init_handler(pars);
1005
1006 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('56111111'O);
1007 var PDU_DTAP_MT dtap_mt;
1008
1009 /* tell GSUP dispatcher to send this IMSI to us */
1010 f_create_gsup_expect(hex2str(g_pars.imsi));
1011
1012 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
1013 f_cl3_or_initial_ue(l3_lu);
1014
1015 /* Send Early Classmark, just for the fun of it */
1016 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1017
1018 /* Wait for + respond to ID REQ (IMSI) */
1019 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req(CM_ID_TYPE_IMSI)));
1020 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
1021 f_expect_common_id();
1022
1023 /* Expect MSC to do UpdateLocation to HLR; respond to it */
1024 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1025 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
1026 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
1027 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1028
1029 alt {
1030 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
1031 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
1032 }
1033 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1034 setverdict(fail, "Expected LU ACK, but received REJ");
1035 mtc.stop;
1036 }
1037 }
1038
1039 /* Wait for MM-Information (if enabled) */
1040 f_expect_mm_info();
1041
1042 /* wait for normal teardown */
1043 f_expect_clear();
1044
1045 /* Now the same IMSI is still attached in the VLR, and a LU with an unknown TMSI reveals the same IMSI only
1046 * later during ID Response. osmo-msc first creates a new vlr_subscr for the unknown TMSI, and as soon as the
1047 * IMSI becomes known, must notice that this IMSI is still regarded as attached, and must not create evil twins.
1048 */
1049
1050 /* (since the TMSI Reallocation happened, we could do this with exactly the same TMSI as above, but for test
1051 * readability just use a different one.) */
1052 l3_lu := f_build_lu_tmsi('56222222'O);
1053 f_cl3_or_initial_ue(l3_lu);
1054
1055 /* Wait for + respond to ID REQ (IMSI) */
1056 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req(CM_ID_TYPE_IMSI)));
1057 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
1058 f_expect_common_id();
1059
1060 /* Expect MSC to do UpdateLocation to HLR; respond to it */
1061 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1062 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
1063 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
1064 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1065
1066 alt {
1067 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
1068 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
1069 }
1070 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1071 setverdict(fail, "Expected LU ACK, but received REJ");
1072 mtc.stop;
1073 }
1074 }
1075
1076 /* Wait for MM-Information (if enabled) */
1077 f_expect_mm_info();
1078
1079 /* wait for normal teardown */
1080 f_expect_clear();
1081}
1082testcase TC_attached_imsi_lu_unknown_tmsi() runs on MTC_CT {
1083 var BSC_ConnHdlr vc_conn;
1084 f_init();
1085
1086 vc_conn := f_start_handler(refers(f_tc_attached_imsi_lu_unknown_tmsi), 56);
1087 vc_conn.done;
1088}
1089
Harald Welte4d15fa72020-08-19 08:58:28 +02001090friend function f_imsi_detach_by_imsi() runs on BSC_ConnHdlr {
Harald Welte45164da2018-01-24 12:51:27 +01001091 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1092
1093 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001094 f_cl3_or_initial_ue(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
Harald Welte45164da2018-01-24 12:51:27 +01001095
1096 /* Send Early Classmark, just for the fun of it? */
Harald Welte4d15fa72020-08-19 08:58:28 +02001097 if (g_pars.ran_is_geran) {
Harald Weltee13cfb22019-04-23 16:52:02 +02001098 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1099 }
Harald Welte45164da2018-01-24 12:51:27 +01001100
1101 /* wait for normal teardown */
Harald Welte4d15fa72020-08-19 08:58:28 +02001102 f_expect_clear(verify_vlr_cell_id := false);
1103}
1104
1105
1106/* Test IMSI DETACH (MI=IMSI) */
1107friend function f_tc_imsi_detach_by_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1108 f_init_handler(pars);
1109
1110 f_imsi_detach_by_imsi();
Harald Welte45164da2018-01-24 12:51:27 +01001111}
1112testcase TC_imsi_detach_by_imsi() runs on MTC_CT {
1113 var BSC_ConnHdlr vc_conn;
1114 f_init();
1115
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001116 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imsi), 14, verify_cell_id := false);
Harald Welte45164da2018-01-24 12:51:27 +01001117 vc_conn.done;
1118}
1119
Harald Weltee13cfb22019-04-23 16:52:02 +02001120
Harald Welte45164da2018-01-24 12:51:27 +01001121/* Test IMSI DETACH (MI=TMSI) */
Harald Weltee13cfb22019-04-23 16:52:02 +02001122friend function f_tc_imsi_detach_by_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001123 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001124
1125 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('01020304'O));
1126
1127 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001128 f_cl3_or_initial_ue(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
Harald Welte45164da2018-01-24 12:51:27 +01001129
1130 /* Send Early Classmark, just for the fun of it? */
Harald Weltee13cfb22019-04-23 16:52:02 +02001131 if (pars.ran_is_geran) {
1132 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1133 }
Harald Welte45164da2018-01-24 12:51:27 +01001134
1135 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +01001136 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001137}
1138testcase TC_imsi_detach_by_tmsi() runs on MTC_CT {
1139 var BSC_ConnHdlr vc_conn;
1140 f_init();
1141
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001142 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_tmsi), 15, verify_cell_id := false);
Harald Welte45164da2018-01-24 12:51:27 +01001143 vc_conn.done;
1144}
1145
Harald Weltee13cfb22019-04-23 16:52:02 +02001146
Harald Welte45164da2018-01-24 12:51:27 +01001147/* Test IMSI DETACH (MI=IMEI), which is illegal */
Harald Weltee13cfb22019-04-23 16:52:02 +02001148friend function f_tc_imsi_detach_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001149 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001150
Harald Welte256571e2018-01-24 18:47:19 +01001151 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte45164da2018-01-24 12:51:27 +01001152
1153 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001154 f_cl3_or_initial_ue(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
Harald Welte45164da2018-01-24 12:51:27 +01001155
1156 /* Send Early Classmark, just for the fun of it? */
Harald Weltee13cfb22019-04-23 16:52:02 +02001157 if (pars.ran_is_geran) {
1158 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1159 }
Harald Welte45164da2018-01-24 12:51:27 +01001160
1161 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +01001162 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001163}
1164testcase TC_imsi_detach_by_imei() runs on MTC_CT {
1165 var BSC_ConnHdlr vc_conn;
1166 f_init();
1167
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001168 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imei), 16, verify_cell_id := false);
Harald Welte45164da2018-01-24 12:51:27 +01001169 vc_conn.done;
1170}
1171
1172
1173/* helper function for an emergency call. caller passes in mobile identity to use */
1174private function f_emerg_call(MobileIdentityLV mi) runs on BSC_ConnHdlr {
Harald Welte0bef21e2018-02-10 09:48:23 +01001175 var CallParameters cpars := valueof(t_CallParams('112'H, 0));
1176 cpars.emergency := true;
Harald Welte45164da2018-01-24 12:51:27 +01001177
Harald Welte0bef21e2018-02-10 09:48:23 +01001178 f_mo_call(cpars);
Harald Welte45164da2018-01-24 12:51:27 +01001179}
1180
1181/* establish an emergency call by IMEI, no SIM inserted (and hence no IMSI) */
Harald Weltee13cfb22019-04-23 16:52:02 +02001182friend function f_tc_emerg_call_imei_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001183 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001184
Harald Welte256571e2018-01-24 18:47:19 +01001185 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001186 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001187 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +01001188 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ('05'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +01001189 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001190}
1191testcase TC_emerg_call_imei_reject() runs on MTC_CT {
1192 var BSC_ConnHdlr vc_conn;
1193 f_init();
1194
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001195 vc_conn := f_start_handler(refers(f_tc_emerg_call_imei_reject), 17, verify_cell_id := false);
Harald Welte45164da2018-01-24 12:51:27 +01001196 vc_conn.done;
1197}
1198
Harald Weltee13cfb22019-04-23 16:52:02 +02001199
Harald Welted5b91402018-01-24 18:48:16 +01001200/* establish an emergency call by IMSI, SIM inserted (and hence IMSI) */
Harald Weltee13cfb22019-04-23 16:52:02 +02001201friend function f_tc_emerg_call_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001202 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001203 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001204 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001205 /* Then issue emergency call identified by IMSI */
1206 f_emerg_call(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
1207}
1208testcase TC_emerg_call_imsi() runs on MTC_CT {
1209 var BSC_ConnHdlr vc_conn;
1210 f_init();
1211
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001212 vc_conn := f_start_handler(refers(f_tc_emerg_call_imsi), 18);
Harald Welte45164da2018-01-24 12:51:27 +01001213 vc_conn.done;
1214}
1215
Harald Weltee13cfb22019-04-23 16:52:02 +02001216
Harald Welte45164da2018-01-24 12:51:27 +01001217/* CM Service Request for VGCS -> reject */
1218private function f_tc_cm_serv_req_vgcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001219 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001220
1221 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001222 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001223
1224 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001225 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VGCS, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001226 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +01001227 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001228 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001229}
1230testcase TC_cm_serv_req_vgcs_reject() runs on MTC_CT {
1231 var BSC_ConnHdlr vc_conn;
1232 f_init();
1233
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001234 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vgcs_reject), 19);
Harald Welte45164da2018-01-24 12:51:27 +01001235 vc_conn.done;
1236}
1237
1238/* CM Service Request for VBS -> reject */
1239private function f_tc_cm_serv_req_vbs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001240 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001241
1242 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001243 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001244
1245 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001246 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VBS, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001247 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +01001248 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001249 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001250}
1251testcase TC_cm_serv_req_vbs_reject() runs on MTC_CT {
1252 var BSC_ConnHdlr vc_conn;
1253 f_init();
1254
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001255 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vbs_reject), 20);
Harald Welte45164da2018-01-24 12:51:27 +01001256 vc_conn.done;
1257}
1258
1259/* CM Service Request for LCS -> reject */
1260private function f_tc_cm_serv_req_lcs_reject(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
1263 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001264 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001265
1266 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001267 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_LCS, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001268 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +01001269 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001270 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001271}
1272testcase TC_cm_serv_req_lcs_reject() runs on MTC_CT {
1273 var BSC_ConnHdlr vc_conn;
1274 f_init();
1275
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001276 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_lcs_reject), 21);
Harald Welte45164da2018-01-24 12:51:27 +01001277 vc_conn.done;
1278}
1279
Harald Welte0195ab12018-01-24 21:50:20 +01001280/* CM Re-Establishment Request */
1281private function f_tc_cm_reest_req_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001282 f_init_handler(pars);
Harald Welte0195ab12018-01-24 21:50:20 +01001283
1284 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001285 f_perform_lu();
Harald Welte0195ab12018-01-24 21:50:20 +01001286
1287 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1288 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REEST_REQ(0, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001289 f_cl3_or_initial_ue(l3_info);
Harald Welte0195ab12018-01-24 21:50:20 +01001290 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001291 f_expect_clear();
Harald Welte0195ab12018-01-24 21:50:20 +01001292}
1293testcase TC_cm_reest_req_reject() runs on MTC_CT {
1294 var BSC_ConnHdlr vc_conn;
1295 f_init();
Harald Welte0195ab12018-01-24 21:50:20 +01001296
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001297 vc_conn := f_start_handler(refers(f_tc_cm_reest_req_reject), 22);
Harald Welte0195ab12018-01-24 21:50:20 +01001298 vc_conn.done;
1299}
1300
Harald Weltec638f4d2018-01-24 22:00:36 +01001301/* Test LU (with authentication enabled), with wrong response from MS */
1302private function f_tc_lu_auth_2G_fail(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001303 f_init_handler(pars);
Harald Weltec638f4d2018-01-24 22:00:36 +01001304
1305 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
1306
1307 /* tell GSUP dispatcher to send this IMSI to us */
1308 f_create_gsup_expect(hex2str(g_pars.imsi));
1309
1310 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001311 f_cl3_or_initial_ue(l3_lu);
Harald Weltec638f4d2018-01-24 22:00:36 +01001312
1313 /* Send Early Classmark, just for the fun of it */
1314 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1315
1316 var AuthVector vec := f_gen_auth_vec_2g();
1317 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(vec.rand, vec.sres, vec.kc));
1318 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
1319 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
1320
1321 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(vec.rand)));
1322 /* Send back wrong auth response */
1323 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G('00000000'O)));
1324
1325 /* Expect GSUP AUTH FAIL REP to HLR */
1326 GSUP.receive(tr_GSUP_AUTH_FAIL_IND(g_pars.imsi));
1327
1328 /* Expect LU REJECT with Cause == Illegal MS */
1329 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej('03'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +01001330 f_expect_clear();
Harald Weltec638f4d2018-01-24 22:00:36 +01001331}
1332testcase TC_lu_auth_2G_fail() runs on MTC_CT {
1333 var BSC_ConnHdlr vc_conn;
1334 f_init();
1335 f_vty_config(MSCVTY, "network", "authentication required");
Harald Weltec638f4d2018-01-24 22:00:36 +01001336
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001337 vc_conn := f_start_handler(refers(f_tc_lu_auth_2G_fail), 23, verify_cell_id := false);
Harald Weltec638f4d2018-01-24 22:00:36 +01001338 vc_conn.done;
1339}
1340
Harald Weltede371492018-01-27 23:44:41 +01001341/* A5/1 + A5/3 permitted on network side, and MS capable to do it */
Harald Welte16114282018-01-24 22:41:21 +01001342private 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 +01001343 pars.net.expect_auth := true;
1344 pars.net.expect_ciph := true;
Harald Weltea10db902018-01-27 12:44:49 +01001345 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001346 f_perform_lu();
Harald Welte16114282018-01-24 22:41:21 +01001347}
1348testcase TC_lu_imsi_auth_tmsi_encr_13_13() runs on MTC_CT {
1349 var BSC_ConnHdlr vc_conn;
1350 f_init();
1351 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte16114282018-01-24 22:41:21 +01001352 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1353
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001354 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_13), 24);
Harald Welte16114282018-01-24 22:41:21 +01001355 vc_conn.done;
1356}
1357
Harald Welte1af6ea82018-01-25 18:33:15 +01001358/* Test Complete L3 without payload */
1359private function f_tc_cl3_no_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001360 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001361
1362 /* Send Complete L3 Info with empty L3 frame */
1363 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1364 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, ''O))));
1365
Harald Weltef466eb42018-01-27 14:26:54 +01001366 timer T := 5.0;
1367 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001368 alt {
Harald Welte6811d102019-04-14 22:23:14 +02001369 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte1af6ea82018-01-25 18:33:15 +01001370 /* Expect LU REJECT with Cause == Illegal MS */
Harald Weltebdb3c452018-03-18 22:43:06 +01001371 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
Harald Welte6811d102019-04-14 22:23:14 +02001372 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001373 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001374 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001375 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Daniel Willmannafce8662018-07-06 23:11:32 +02001376 mtc.stop;
Harald Weltef466eb42018-01-27 14:26:54 +01001377 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001378 }
1379 setverdict(pass);
1380}
1381testcase TC_cl3_no_payload() runs on MTC_CT {
1382 var BSC_ConnHdlr vc_conn;
1383 f_init();
1384
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001385 vc_conn := f_start_handler(refers(f_tc_cl3_no_payload), 25);
Harald Welte1af6ea82018-01-25 18:33:15 +01001386 vc_conn.done;
1387}
1388
1389/* Test Complete L3 with random payload */
1390private function f_tc_cl3_rnd_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001391 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001392
Daniel Willmannaa14a382018-07-26 08:29:45 +02001393 /* length is limited by PDU_BSSAP length field which includes some
1394 * other fields beside l3info payload. So payl can only be 240 bytes
1395 * Since rnd() returns values < 1 multiply with 241
1396 */
1397 var integer len := float2int(rnd() * 241.0);
Harald Welte1af6ea82018-01-25 18:33:15 +01001398 var octetstring payl := f_rnd_octstring(len);
1399
1400 /* Send Complete L3 Info with empty L3 frame */
1401 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1402 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, payl))));
1403
Harald Weltef466eb42018-01-27 14:26:54 +01001404 timer T := 5.0;
1405 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001406 alt {
1407 /* Immediate disconnect */
Harald Welte6811d102019-04-14 22:23:14 +02001408 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte1af6ea82018-01-25 18:33:15 +01001409 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
Harald Welte6811d102019-04-14 22:23:14 +02001410 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001411 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001412 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001413 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Daniel Willmannafce8662018-07-06 23:11:32 +02001414 mtc.stop;
Harald Weltef466eb42018-01-27 14:26:54 +01001415 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001416 }
1417 setverdict(pass);
1418}
1419testcase TC_cl3_rnd_payload() runs on MTC_CT {
1420 var BSC_ConnHdlr vc_conn;
1421 f_init();
1422
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001423 vc_conn := f_start_handler(refers(f_tc_cl3_rnd_payload), 26);
Harald Welte1af6ea82018-01-25 18:33:15 +01001424 vc_conn.done;
1425}
1426
Harald Welte116e4332018-01-26 22:17:48 +01001427/* Test Complete L3 with random payload */
Harald Weltee13cfb22019-04-23 16:52:02 +02001428friend function f_tc_establish_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001429 f_init_handler(pars);
Harald Welte116e4332018-01-26 22:17:48 +01001430
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001431 f_perform_lu();
Harald Welte116e4332018-01-26 22:17:48 +01001432
Harald Welteb9e86fa2018-04-09 18:18:31 +02001433 f_establish_fully();
Daniel Willmann898a7e02018-05-17 12:16:16 +02001434 f_expect_clear(10.0);
Harald Welte116e4332018-01-26 22:17:48 +01001435}
1436testcase TC_establish_and_nothing() runs on MTC_CT {
1437 var BSC_ConnHdlr vc_conn;
1438 f_init();
1439
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001440 vc_conn := f_start_handler(refers(f_tc_establish_and_nothing), 27);
Harald Welte116e4332018-01-26 22:17:48 +01001441 vc_conn.done;
1442}
1443
Harald Weltee13cfb22019-04-23 16:52:02 +02001444
Harald Welte12510c52018-01-26 22:26:24 +01001445/* Test MO Call SETUP with no response from MNCC */
Harald Weltee13cfb22019-04-23 16:52:02 +02001446friend function f_tc_mo_setup_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Philipp Maier109e6aa2018-10-17 10:53:32 +02001447 f_init_handler(pars, 190.0);
Harald Weltea10db902018-01-27 12:44:49 +01001448
Harald Welte12510c52018-01-26 22:26:24 +01001449 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001450 cpars.mgw_conn_2.resp := 0;
1451 cpars.stop_after_cc_setup := true;
1452
1453 f_vty_config(MSCVTY, "msc", "mncc guard-timeout 20");
Harald Welte12510c52018-01-26 22:26:24 +01001454
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001455 f_perform_lu();
Harald Welte12510c52018-01-26 22:26:24 +01001456
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001457 f_mo_call_establish(cpars);
Harald Welte12510c52018-01-26 22:26:24 +01001458
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001459 var default ccrel := activate(as_optional_cc_rel(cpars));
1460
Philipp Maier109e6aa2018-10-17 10:53:32 +02001461 f_expect_clear(185.0);
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001462
1463 deactivate(ccrel);
1464
1465 f_sleep(1.0);
Harald Welte12510c52018-01-26 22:26:24 +01001466}
1467testcase TC_mo_setup_and_nothing() runs on MTC_CT {
1468 var BSC_ConnHdlr vc_conn;
1469 f_init();
1470
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001471 vc_conn := f_start_handler(refers(f_tc_mo_setup_and_nothing), 28);
Harald Welte12510c52018-01-26 22:26:24 +01001472 vc_conn.done;
1473}
1474
Harald Weltee13cfb22019-04-23 16:52:02 +02001475
Harald Welte3ab88002018-01-26 22:37:25 +01001476/* Test MO Call with no response to RAN-side CRCX */
Harald Weltee13cfb22019-04-23 16:52:02 +02001477friend function f_tc_mo_crcx_ran_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001478 f_init_handler(pars);
Harald Welte3ab88002018-01-26 22:37:25 +01001479 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1480 var MNCC_PDU mncc;
1481 var MgcpCommand mgcp_cmd;
1482
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001483 f_perform_lu();
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001484 /* Do not respond to the second CRCX */
1485 cpars.mgw_conn_2.resp := 0;
1486 f_mo_call_establish(cpars);
Harald Welte3ab88002018-01-26 22:37:25 +01001487
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001488 var default ccrel := activate(as_optional_cc_rel(cpars));
Harald Welte3ab88002018-01-26 22:37:25 +01001489
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001490 f_expect_clear(60.0);
Harald Welte3ab88002018-01-26 22:37:25 +01001491
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001492 deactivate(ccrel);
Harald Welte3ab88002018-01-26 22:37:25 +01001493}
1494testcase TC_mo_crcx_ran_timeout() runs on MTC_CT {
1495 var BSC_ConnHdlr vc_conn;
1496 f_init();
1497
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001498 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_timeout), 29);
Harald Welte3ab88002018-01-26 22:37:25 +01001499 vc_conn.done;
1500}
1501
Harald Weltee13cfb22019-04-23 16:52:02 +02001502
Harald Welte0cc82d92018-01-26 22:52:34 +01001503/* Test MO Call with reject to RAN-side CRCX */
Harald Weltee13cfb22019-04-23 16:52:02 +02001504friend function f_tc_mo_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001505 f_init_handler(pars);
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001506
Harald Welte0cc82d92018-01-26 22:52:34 +01001507 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001508
1509 /* Respond with error for the first CRCX */
1510 cpars.mgw_conn_1.resp := -1;
Harald Welte0cc82d92018-01-26 22:52:34 +01001511
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001512 f_perform_lu();
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001513 f_mo_call_establish(cpars);
Harald Welte0cc82d92018-01-26 22:52:34 +01001514
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02001515 var default ccrel := activate(as_optional_cc_rel(cpars));
1516 f_expect_clear(60.0);
1517 deactivate(ccrel);
Harald Welte0cc82d92018-01-26 22:52:34 +01001518}
1519testcase TC_mo_crcx_ran_reject() runs on MTC_CT {
1520 var BSC_ConnHdlr vc_conn;
1521 f_init();
1522
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001523 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_reject), 30);
Harald Welte0cc82d92018-01-26 22:52:34 +01001524 vc_conn.done;
1525}
1526
Harald Welte3ab88002018-01-26 22:37:25 +01001527
Harald Welte812f7a42018-01-27 00:49:18 +01001528/* helper function to start a MT call: MNCC SETUP; Paging; DChan est.; DTAP SETUP */
1529private function f_mt_call_start(inout CallParameters cpars) runs on BSC_ConnHdlr {
1530 var MNCC_PDU mncc;
1531 var MgcpCommand mgcp_cmd;
Harald Welte812f7a42018-01-27 00:49:18 +01001532
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001533 f_perform_lu();
Vadim Yanitskiyae747742020-01-10 00:23:10 +01001534 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Harald Welte812f7a42018-01-27 00:49:18 +01001535
1536 /* Allocate call reference and send SETUP via MNCC to MSC */
1537 cpars.mncc_callref := f_rnd_int(2147483648);
1538 MNCC.send(ts_MNCC_SETUP_req(cpars.mncc_callref, hex2str(g_pars.msisdn),
1539 hex2str(cpars.called_party), hex2str(g_pars.imsi)));
1540
1541 /* MSC->BSC: expect PAGING from MSC */
Harald Weltee035e3e2019-04-21 17:32:05 +02001542 f_expect_paging();
1543
Harald Welte812f7a42018-01-27 00:49:18 +01001544 /* MS -> MSC: PAGING RESPONSE */
Harald Welteb9e86fa2018-04-09 18:18:31 +02001545 f_establish_fully(EST_TYPE_PAG_RESP);
Harald Welte812f7a42018-01-27 00:49:18 +01001546
1547 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1548
1549 /* MSC->MS: SETUP */
1550 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party)));
1551}
1552
1553/* Test MT Call */
Harald Weltee13cfb22019-04-23 16:52:02 +02001554friend function f_tc_mt_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001555 f_init_handler(pars);
Harald Welte812f7a42018-01-27 00:49:18 +01001556 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1557 var MNCC_PDU mncc;
1558 var MgcpCommand mgcp_cmd;
1559
1560 f_mt_call_start(cpars);
1561
1562 /* MS->MSC: CALL CONFIRMED */
1563 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1564
1565 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1566
1567 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1568 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001569
1570 /* Detect if the received CRCX is a wildcarded CRCX request. If yes,
1571 * set an endpoint name that fits the pattern. If not, just use the
1572 * endpoint name from the request */
1573 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
1574 cpars.mgcp_ep := "rtpbridge/1@mgw";
1575 } else {
1576 cpars.mgcp_ep := mgcp_cmd.line.ep;
1577 }
1578
Harald Welte812f7a42018-01-27 00:49:18 +01001579 /* Respond to CRCX with error */
1580 var MgcpResponse mgcp_rsp := {
1581 line := {
1582 code := "542",
1583 trans_id := mgcp_cmd.line.trans_id,
1584 string := "FORCED_FAIL"
1585 },
Harald Welte812f7a42018-01-27 00:49:18 +01001586 sdp := omit
1587 }
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001588 var MgcpParameter mgcp_rsp_param := {
1589 code := "Z",
1590 val := cpars.mgcp_ep
1591 };
1592 mgcp_rsp.params[0] := mgcp_rsp_param;
Harald Welte812f7a42018-01-27 00:49:18 +01001593 MGCP.send(mgcp_rsp);
1594
1595 timer T := 30.0;
1596 T.start;
1597 alt {
Daniel Willmannafce8662018-07-06 23:11:32 +02001598 [] T.timeout {
1599 setverdict(fail, "Timeout waiting for channel release");
1600 mtc.stop;
1601 }
Harald Welte812f7a42018-01-27 00:49:18 +01001602 [] MNCC.receive { repeat; }
1603 [] GSUP.receive { repeat; }
1604 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1605 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1606 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1607 repeat;
1608 }
1609 [] MGCP.receive { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001610 [] as_clear_cmd_compl_disc();
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001611 [] as_optional_cc_rel(cpars);
Harald Welte812f7a42018-01-27 00:49:18 +01001612 }
1613}
1614testcase TC_mt_crcx_ran_reject() runs on MTC_CT {
1615 var BSC_ConnHdlr vc_conn;
1616 f_init();
1617
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001618 vc_conn := f_start_handler(refers(f_tc_mt_crcx_ran_reject), 31);
Harald Welte812f7a42018-01-27 00:49:18 +01001619 vc_conn.done;
1620}
1621
1622
Harald Weltee13cfb22019-04-23 16:52:02 +02001623
Harald Welte812f7a42018-01-27 00:49:18 +01001624/* Test MT Call T310 timer */
Harald Weltee13cfb22019-04-23 16:52:02 +02001625friend function f_tc_mt_t310(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltead2952e2018-01-27 14:12:46 +01001626 f_init_handler(pars, 200.0);
Harald Welte812f7a42018-01-27 00:49:18 +01001627 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1628 var MNCC_PDU mncc;
1629 var MgcpCommand mgcp_cmd;
1630
1631 f_mt_call_start(cpars);
1632
1633 /* MS->MSC: CALL CONFIRMED */
1634 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1635 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1636
1637 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1638 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1639 cpars.mgcp_ep := mgcp_cmd.line.ep;
1640 /* FIXME: Respond to CRCX */
1641
1642 /* old libosmocore T310 default timeout is 180s. so let's wait 190 */
1643 timer T := 190.0;
1644 T.start;
1645 alt {
Daniel Willmannafce8662018-07-06 23:11:32 +02001646 [] T.timeout {
1647 setverdict(fail, "Timeout waiting for T310");
1648 mtc.stop;
1649 }
Harald Welte812f7a42018-01-27 00:49:18 +01001650 [] MNCC.receive(tr_MNCC_DISC_ind(cpars.mncc_callref)) {
1651 MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(23))));
1652 }
1653 }
1654 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));
1655 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1656 /* FIXME: We're sending this with TIflag 0: allocated by sender, which is wrong */
1657 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1658
1659 alt {
Harald Welte812f7a42018-01-27 00:49:18 +01001660 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1661 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1662 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1663 repeat;
1664 }
Harald Welte5946b332018-03-18 23:32:21 +01001665 [] as_clear_cmd_compl_disc();
Harald Welte812f7a42018-01-27 00:49:18 +01001666 }
1667}
1668testcase TC_mt_t310() runs on MTC_CT {
1669 var BSC_ConnHdlr vc_conn;
1670 f_init();
1671
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001672 vc_conn := f_start_handler(refers(f_tc_mt_t310), 32);
Harald Welte812f7a42018-01-27 00:49:18 +01001673 vc_conn.done;
1674}
1675
Harald Weltee13cfb22019-04-23 16:52:02 +02001676
Harald Welte167458a2018-01-27 15:58:16 +01001677/* Perform successful LU + MO call, then GSUP LocationCancel. Subscriber must be denied CM SERV */
Harald Weltee13cfb22019-04-23 16:52:02 +02001678friend function f_tc_gsup_cancel(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Welte167458a2018-01-27 15:58:16 +01001679 f_init_handler(pars);
1680 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Harald Welte167458a2018-01-27 15:58:16 +01001681
1682 /* Location Update to make subscriber known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001683 f_perform_lu();
Harald Welte167458a2018-01-27 15:58:16 +01001684
1685 /* First MO call should succeed */
1686 f_mo_call(cpars);
1687
1688 /* Cancel the subscriber in the VLR */
1689 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1690 alt {
1691 [] GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi)) { }
1692 [] GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi)) {
1693 setverdict(fail, "Received GSUP Location Cancel Error");
Daniel Willmannafce8662018-07-06 23:11:32 +02001694 mtc.stop;
Harald Welte167458a2018-01-27 15:58:16 +01001695 }
1696 }
1697
1698 /* Follow-up transactions should fail */
1699 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1700 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001701 f_cl3_or_initial_ue(l3_info);
Harald Welte167458a2018-01-27 15:58:16 +01001702 alt {
1703 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
1704 [] BSSAP.receive {
1705 setverdict(fail, "Received unexpected BSSAP instead of CM SERV REJ");
Daniel Willmannafce8662018-07-06 23:11:32 +02001706 mtc.stop;
Harald Welte167458a2018-01-27 15:58:16 +01001707 }
1708 }
Neels Hofmeyr0f7429a2019-03-07 22:28:41 +01001709
1710 f_expect_clear();
Harald Welte167458a2018-01-27 15:58:16 +01001711 setverdict(pass);
1712}
1713testcase TC_gsup_cancel() runs on MTC_CT {
1714 var BSC_ConnHdlr vc_conn;
1715 f_init();
1716
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001717 vc_conn := f_start_handler(refers(f_tc_gsup_cancel), 33, verify_cell_id := false);
Harald Welte167458a2018-01-27 15:58:16 +01001718 vc_conn.done;
1719}
1720
Harald Weltee13cfb22019-04-23 16:52:02 +02001721
Harald Welte9de84792018-01-28 01:06:35 +01001722/* A5/1 only permitted on network side, and MS capable to do it */
1723private function f_tc_lu_imsi_auth_tmsi_encr_1_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1724 pars.net.expect_auth := true;
1725 pars.net.expect_ciph := true;
1726 pars.net.kc_support := '02'O; /* A5/1 only */
1727 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001728 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001729}
1730testcase TC_lu_imsi_auth_tmsi_encr_1_13() runs on MTC_CT {
1731 var BSC_ConnHdlr vc_conn;
1732 f_init();
1733 f_vty_config(MSCVTY, "network", "authentication required");
1734 f_vty_config(MSCVTY, "network", "encryption a5 1");
1735
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001736 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_1_13), 34);
Harald Welte9de84792018-01-28 01:06:35 +01001737 vc_conn.done;
1738}
1739
1740/* A5/3 only permitted on network side, and MS capable to do it */
1741private function f_tc_lu_imsi_auth_tmsi_encr_3_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1742 pars.net.expect_auth := true;
1743 pars.net.expect_ciph := true;
1744 pars.net.kc_support := '08'O; /* A5/3 only */
1745 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001746 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001747}
1748testcase TC_lu_imsi_auth_tmsi_encr_3_13() runs on MTC_CT {
1749 var BSC_ConnHdlr vc_conn;
1750 f_init();
1751 f_vty_config(MSCVTY, "network", "authentication required");
1752 f_vty_config(MSCVTY, "network", "encryption a5 3");
1753
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001754 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_13), 35);
Harald Welte9de84792018-01-28 01:06:35 +01001755 vc_conn.done;
1756}
1757
1758/* A5/3 only permitted on network side, and MS with only A5/1 support */
1759private function f_tc_lu_imsi_auth_tmsi_encr_3_1(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1760 pars.net.expect_auth := true;
1761 pars.net.expect_ciph := true;
1762 pars.net.kc_support := '08'O; /* A5/3 only */
1763 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1764 f_init_handler(pars, 15.0);
1765
1766 /* cannot use f_perform_lu() as we expect a reject */
1767 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1768 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +02001769 f_cl3_or_initial_ue(l3_lu);
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001770 if (pars.send_early_cm) {
1771 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1772 } else {
1773 pars.cm1.esind := '0'B;
1774 }
Harald Welte9de84792018-01-28 01:06:35 +01001775 f_mm_auth();
1776 alt {
Daniel Willmann52918e52018-09-20 14:39:09 +02001777 [] BSSAP.receive(tr_BSSMAP_ClassmarkReq) {
1778 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1779 repeat;
1780 }
Harald Welte5946b332018-03-18 23:32:21 +01001781 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1782 f_expect_clear();
1783 }
Harald Welte9de84792018-01-28 01:06:35 +01001784 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1785 setverdict(fail, "CipherModeCommand despite no A5 intersection");
Daniel Willmannafce8662018-07-06 23:11:32 +02001786 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001787 }
1788 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001789 setverdict(fail, "Unknown/unexpected BSSAP received");
Daniel Willmannafce8662018-07-06 23:11:32 +02001790 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001791 }
1792 }
1793 setverdict(pass);
1794}
1795testcase TC_lu_imsi_auth_tmsi_encr_3_1() runs on MTC_CT {
1796 var BSC_ConnHdlr vc_conn;
1797 f_init();
1798 f_vty_config(MSCVTY, "network", "authentication required");
1799 f_vty_config(MSCVTY, "network", "encryption a5 3");
1800
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001801 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 +01001802 vc_conn.done;
1803}
1804testcase TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() runs on MTC_CT {
1805 var BSC_ConnHdlrPars pars;
1806 var BSC_ConnHdlr vc_conn;
1807 f_init();
1808 f_vty_config(MSCVTY, "network", "authentication required");
1809 f_vty_config(MSCVTY, "network", "encryption a5 3");
1810
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001811 pars := f_init_pars(361, verify_cell_id := false);
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001812 pars.send_early_cm := false;
1813 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 +01001814 vc_conn.done;
1815}
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01001816testcase TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() runs on MTC_CT {
1817 var BSC_ConnHdlr vc_conn;
1818 f_init();
1819 f_vty_config(MSCVTY, "network", "authentication required");
1820 f_vty_config(MSCVTY, "network", "encryption a5 3");
1821
1822 /* Make sure the MSC category is on DEBUG level to trigger the log
1823 * message that is reported in OS#2947 to trigger the segfault */
1824 f_vty_config(MSCVTY, "log stderr", "logging level msc debug");
1825
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001826 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 +01001827 vc_conn.done;
1828}
Harald Welte9de84792018-01-28 01:06:35 +01001829
1830/* A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
1831private function f_tc_lu_imsi_auth_tmsi_encr_13_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1832 pars.net.expect_auth := true;
1833 pars.net.expect_ciph := true;
1834 pars.net.kc_support := '0A'O; /* A5/1 + A5/3 */
1835 pars.cm1.a5_1 := '1'B;
1836 pars.cm2.a5_1 := '1'B;
1837 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1838 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
1839 f_init_handler(pars, 15.0);
1840
1841 /* cannot use f_perform_lu() as we expect a reject */
1842 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1843 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +02001844 f_cl3_or_initial_ue(l3_lu);
Harald Welte9de84792018-01-28 01:06:35 +01001845 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1846 f_mm_auth();
1847 alt {
Harald Welte5946b332018-03-18 23:32:21 +01001848 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1849 f_expect_clear();
1850 }
Harald Welte9de84792018-01-28 01:06:35 +01001851 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1852 setverdict(fail, "CipherModeCommand despite no A5 intersection");
Daniel Willmannafce8662018-07-06 23:11:32 +02001853 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001854 }
1855 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001856 setverdict(fail, "Unknown/unexpected BSSAP received");
Daniel Willmannafce8662018-07-06 23:11:32 +02001857 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001858 }
1859 }
1860 setverdict(pass);
1861}
1862testcase TC_lu_imsi_auth_tmsi_encr_13_2() runs on MTC_CT {
1863 var BSC_ConnHdlr vc_conn;
1864 f_init();
1865 f_vty_config(MSCVTY, "network", "authentication required");
1866 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1867
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02001868 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 +01001869 vc_conn.done;
1870}
1871
1872/* A5/0 + A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
1873private function f_tc_lu_imsi_auth_tmsi_encr_013_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1874 pars.net.expect_auth := true;
1875 pars.net.expect_ciph := true;
1876 pars.net.kc_support := '0B'O; /* A5/1 + A5/3 */
1877 pars.cm1.a5_1 := '1'B;
1878 pars.cm2.a5_1 := '1'B;
1879 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1880 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
1881 f_init_handler(pars, 15.0);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001882 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001883}
1884testcase TC_lu_imsi_auth_tmsi_encr_013_2() runs on MTC_CT {
1885 var BSC_ConnHdlr vc_conn;
1886 f_init();
1887 f_vty_config(MSCVTY, "network", "authentication required");
1888 f_vty_config(MSCVTY, "network", "encryption a5 0 1 3");
1889
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001890 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_013_2), 38);
Harald Welte9de84792018-01-28 01:06:35 +01001891 vc_conn.done;
1892}
1893
Harald Welte33ec09b2018-02-10 15:34:46 +01001894/* LU followed by MT call (including paging) */
Neels Hofmeyr8fe8a902019-11-03 05:51:03 +01001895friend function f_tc_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Welte33ec09b2018-02-10 15:34:46 +01001896 f_init_handler(pars);
Stefan Sperling26d57be2018-11-12 17:03:26 +01001897 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Pau Espin Pedrola65697d2019-05-21 12:54:39 +02001898 cpars.use_osmux := pars.use_osmux;
Harald Welte33ec09b2018-02-10 15:34:46 +01001899
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001900 f_perform_lu();
Harald Welte33ec09b2018-02-10 15:34:46 +01001901 f_mt_call(cpars);
1902}
1903testcase TC_lu_and_mt_call() runs on MTC_CT {
1904 var BSC_ConnHdlr vc_conn;
1905 f_init();
1906
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001907 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call), 39);
Harald Welte33ec09b2018-02-10 15:34:46 +01001908 vc_conn.done;
1909}
1910
Pau Espin Pedrola65697d2019-05-21 12:54:39 +02001911testcase TC_lu_and_mt_call_osmux() runs on MTC_CT {
1912 var BSC_ConnHdlr vc_conn;
1913 f_init(1, false, true, true);
Pau Espin Pedrola65697d2019-05-21 12:54:39 +02001914
1915 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call), 39, 0, true, true);
1916 vc_conn.done;
1917}
1918
Neels Hofmeyrb58d9742019-11-27 18:44:54 +01001919/* MT call while already Paging */
1920friend function f_tc_lu_and_mt_call_already_paging(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1921 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1922 var SmsParameters spars := valueof(t_SmsPars);
1923 var OCT4 tmsi;
1924
1925 f_init_handler(pars);
1926
1927 /* Perform location update */
1928 f_perform_lu();
1929
1930 /* register an 'expect' for given IMSI (+TMSI) */
1931 if (isvalue(g_pars.tmsi)) {
1932 tmsi := g_pars.tmsi;
1933 } else {
1934 tmsi := 'FFFFFFFF'O;
1935 }
1936 f_ran_register_imsi(g_pars.imsi, tmsi);
1937
1938 log("start Paging by an SMS");
1939 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
1940
1941 /* MSC->BSC: expect PAGING from MSC */
1942 f_expect_paging();
1943
1944 log("MNCC signals MT call, before Paging Response");
1945 f_mt_call_initate(cpars);
1946 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
1947
1948 f_sleep(0.5);
1949 log("phone answers Paging, expecting both SMS and MT call to be established");
1950 f_establish_fully(EST_TYPE_PAG_RESP);
1951 spars.tp.ud := 'C8329BFD064D9B53'O;
1952 interleave {
1953 [] BSSAP.receive(f_mt_sms_deliver_pdu(spars)) {
1954 log("Got SMS-DELIVER");
1955 };
1956 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party))) {
1957 log("Got CC Setup");
1958 };
1959 }
1960 setverdict(pass);
1961 log("success, tear down");
1962 var default ccrel := activate(as_optional_cc_rel(cpars));
1963 if (g_pars.ran_is_geran) {
1964 BSSAP.send(ts_BSSMAP_ClearRequest(0));
1965 } else {
1966 BSSAP.send(ts_RANAP_IuReleaseRequest(ts_RanapCause_om_intervention));
1967 }
1968 f_expect_clear();
1969 deactivate(ccrel);
1970 f_vty_sms_clear(hex2str(g_pars.imsi));
1971}
1972testcase TC_lu_and_mt_call_already_paging() runs on MTC_CT {
1973 var BSC_ConnHdlrPars pars;
1974 var BSC_ConnHdlr vc_conn;
1975 f_init();
1976 pars := f_init_pars(391);
1977 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_call_already_paging), pars);
1978 vc_conn.done;
1979}
1980
Daniel Willmann8b084372018-02-04 13:35:26 +01001981/* Test MO Call SETUP with DTMF */
1982private function f_tc_mo_setup_dtmf_dup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1983 f_init_handler(pars);
1984 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Daniel Willmann8b084372018-02-04 13:35:26 +01001985
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001986 f_perform_lu();
Daniel Willmann8b084372018-02-04 13:35:26 +01001987 f_mo_seq_dtmf_dup(cpars);
1988}
1989testcase TC_mo_setup_and_dtmf_dup() runs on MTC_CT {
1990 var BSC_ConnHdlr vc_conn;
1991 f_init();
1992
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001993 vc_conn := f_start_handler(refers(f_tc_mo_setup_dtmf_dup), 39);
Daniel Willmann8b084372018-02-04 13:35:26 +01001994 vc_conn.done;
1995}
Harald Welte9de84792018-01-28 01:06:35 +01001996
Philipp Maier328d1662018-03-07 10:40:27 +01001997testcase TC_cr_before_reset() runs on MTC_CT {
1998 timer T := 4.0;
1999 var boolean reset_ack_seen := false;
2000 f_init_bssap_direct();
2001
Harald Welte3ca0ce12019-04-23 17:18:48 +02002002 f_ran_adapter_start(g_bssap[0]);
Daniel Willmann42d1d5b2018-08-07 15:18:41 +02002003
Daniel Willmanne8018962018-08-21 14:18:00 +02002004 f_sleep(3.0);
2005
Philipp Maier328d1662018-03-07 10:40:27 +01002006 /* Make a blind connection attemt, to trigger the deadlock condition */
Philipp Maier75932982018-03-27 14:52:35 +02002007 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 +01002008
2009 /* Send a BSSMAP reset */
Philipp Maier75932982018-03-27 14:52:35 +02002010 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 +01002011 T.start
2012 alt {
2013 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_ResetAck)) {
2014 reset_ack_seen := true;
2015 repeat;
2016 }
2017
2018 /* Acknowledge MSC sided reset requests */
2019 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) {
Philipp Maier75932982018-03-27 14:52:35 +02002020 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 +01002021 repeat;
2022 }
2023
2024 /* Ignore all other messages (e.g CR from the connection request) */
2025 [] BSSAP_DIRECT.receive { repeat }
2026
2027 /* If we got no BSSMAP RESET ACK back, then the MSC entered the
2028 * deadlock situation. The MSC is then unable to respond to any
2029 * further BSSMAP RESET or any other sort of traffic. */
2030 [reset_ack_seen == true] T.timeout { setverdict(pass) }
2031 [reset_ack_seen == false] T.timeout {
2032 setverdict(fail, "no BSSMAP RESET ACK seen!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002033 mtc.stop;
Philipp Maier328d1662018-03-07 10:40:27 +01002034 }
Pau Espin Pedrol7e9178d2019-12-17 17:52:17 +01002035 }
Philipp Maier328d1662018-03-07 10:40:27 +01002036}
Harald Welte9de84792018-01-28 01:06:35 +01002037
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002038/* Test MO Call with no response to RAN-side CRCX or DTAP Release */
Harald Weltee13cfb22019-04-23 16:52:02 +02002039friend function f_tc_mo_release_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002040 f_init_handler(pars);
2041 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
2042 var MNCC_PDU mncc;
2043 var MgcpCommand mgcp_cmd;
2044
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02002045 /* Do not respond to the second CRCX */
2046 cpars.mgw_conn_2.resp := 0;
2047
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002048 f_perform_lu();
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02002049 f_mo_call_establish(cpars);
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002050
Neels Hofmeyrde76f052019-02-26 05:02:46 +01002051 var default ccrel := activate(as_optional_cc_rel(cpars));
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002052
2053 f_expect_clear(60.0);
Neels Hofmeyrde76f052019-02-26 05:02:46 +01002054
2055 deactivate(ccrel);
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002056}
2057testcase TC_mo_release_timeout() runs on MTC_CT {
2058 var BSC_ConnHdlr vc_conn;
2059 f_init();
2060
2061 vc_conn := f_start_handler(refers(f_tc_mo_release_timeout), 40);
2062 vc_conn.done;
2063}
2064
Harald Welte12510c52018-01-26 22:26:24 +01002065
Philipp Maier2a98a732018-03-19 16:06:12 +01002066/* LU followed by MT call (including paging) */
2067private function f_tc_lu_and_mt_call_no_dlcx_resp(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2068 f_init_handler(pars);
Stefan Sperling26d57be2018-11-12 17:03:26 +01002069 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Philipp Maier2a98a732018-03-19 16:06:12 +01002070
2071 /* Intentionally disable the CRCX response */
2072 cpars.mgw_drop_dlcx := true;
2073
2074 /* Perform location update and call */
2075 f_perform_lu();
2076 f_mt_call(cpars);
2077}
2078testcase TC_lu_and_mt_call_no_dlcx_resp() runs on MTC_CT {
2079 var BSC_ConnHdlr vc_conn;
2080 f_init();
2081
2082 /* Perform an almost normal looking locationupdate + mt-call, but do
2083 * not respond to the DLCX at the end of the call */
2084 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call_no_dlcx_resp), 41);
2085 vc_conn.done;
2086
2087 /* Wait a guard period until the MGCP layer in the MSC times out,
2088 * if the MSC is vulnerable to the use-after-free situation that is
2089 * fixed by I78f1b6a9149488a4ad3f120c1e190a83c07d4b89 then it should
2090 * segfault now */
2091 f_sleep(6.0);
2092
2093 /* Run the init procedures once more. If the MSC has crashed, this
2094 * this will fail */
2095 f_init();
2096}
Harald Welte45164da2018-01-24 12:51:27 +01002097
Philipp Maier75932982018-03-27 14:52:35 +02002098/* Two BSSMAP resets from two different BSCs */
2099testcase TC_reset_two() runs on MTC_CT {
2100 var BSC_ConnHdlr vc_conn;
2101 f_init(2);
2102 f_sleep(2.0);
2103 setverdict(pass);
2104}
2105
Harald Weltee13cfb22019-04-23 16:52:02 +02002106/* Two BSSMAP resets from two different BSCs plus one IuCS RANAP Reset */
2107testcase TC_reset_two_1iu() runs on MTC_CT {
2108 var BSC_ConnHdlr vc_conn;
2109 f_init(3);
2110 f_sleep(2.0);
2111 setverdict(pass);
2112}
2113
Harald Weltef640a012018-04-14 17:49:21 +02002114/***********************************************************************
2115 * SMS Testing
2116 ***********************************************************************/
2117
Harald Weltef45efeb2018-04-09 18:19:24 +02002118/* LU followed by MO SMS */
Harald Weltee13cfb22019-04-23 16:52:02 +02002119friend function f_tc_lu_and_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltef45efeb2018-04-09 18:19:24 +02002120 var SmsParameters spars := valueof(t_SmsPars);
2121
2122 f_init_handler(pars);
2123
2124 /* Perform location update and call */
2125 f_perform_lu();
2126
2127 f_establish_fully(EST_TYPE_MO_SMS);
2128
2129 //spars.exp_rp_err := 96; /* invalid mandatory information */
2130 f_mo_sms(spars);
2131
2132 f_expect_clear();
2133}
2134testcase TC_lu_and_mo_sms() runs on MTC_CT {
2135 var BSC_ConnHdlr vc_conn;
2136 f_init();
2137 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_sms), 42);
2138 vc_conn.done;
2139}
2140
Harald Weltee13cfb22019-04-23 16:52:02 +02002141
Harald Weltef45efeb2018-04-09 18:19:24 +02002142private function f_vty_sms_send(charstring imsi, charstring msisdn, charstring text)
Neels Hofmeyr6aaeccf2019-03-06 15:32:26 +01002143runs on BSC_ConnHdlr {
Harald Weltef45efeb2018-04-09 18:19:24 +02002144 f_vty_transceive(MSCVTY, "subscriber imsi "&imsi&" sms sender msisdn "&msisdn&" send "&text);
2145}
2146
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01002147/* Remove still pending SMS */
2148private function f_vty_sms_clear(charstring imsi)
2149runs on BSC_ConnHdlr {
2150 f_vty_transceive(MSCVTY, "subscriber imsi " & imsi & " sms delete-all");
2151 f_vty_transceive(MSCVTY, "sms-queue clear");
2152}
2153
Harald Weltef45efeb2018-04-09 18:19:24 +02002154/* LU followed by MT SMS */
Harald Weltee13cfb22019-04-23 16:52:02 +02002155friend function f_tc_lu_and_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltef45efeb2018-04-09 18:19:24 +02002156 var SmsParameters spars := valueof(t_SmsPars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002157
2158 f_init_handler(pars);
2159
2160 /* Perform location update and call */
2161 f_perform_lu();
2162
2163 /* register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002164 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Harald Weltef45efeb2018-04-09 18:19:24 +02002165
Neels Hofmeyr6aaeccf2019-03-06 15:32:26 +01002166 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
Harald Weltef45efeb2018-04-09 18:19:24 +02002167
2168 /* MSC->BSC: expect PAGING from MSC */
Harald Weltee035e3e2019-04-21 17:32:05 +02002169 f_expect_paging();
2170
Harald Weltef45efeb2018-04-09 18:19:24 +02002171 /* Establish DTAP / BSSAP / SCCP connection */
2172 f_establish_fully(EST_TYPE_PAG_RESP);
2173
2174 spars.tp.ud := 'C8329BFD064D9B53'O;
2175 f_mt_sms(spars);
2176
2177 f_expect_clear();
2178}
2179testcase TC_lu_and_mt_sms() runs on MTC_CT {
2180 var BSC_ConnHdlrPars pars;
2181 var BSC_ConnHdlr vc_conn;
2182 f_init();
2183 pars := f_init_pars(43);
2184 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_sms), pars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002185 vc_conn.done;
2186}
2187
Neels Hofmeyrb58d9742019-11-27 18:44:54 +01002188/* SMS added while already Paging */
2189friend function f_tc_lu_and_mt_sms_already_paging(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2190 var SmsParameters spars := valueof(t_SmsPars);
2191 var OCT4 tmsi;
2192
2193 f_init_handler(pars);
2194
2195 f_perform_lu();
2196
2197 /* register an 'expect' for given IMSI (+TMSI) */
2198 if (isvalue(g_pars.tmsi)) {
2199 tmsi := g_pars.tmsi;
2200 } else {
2201 tmsi := 'FFFFFFFF'O;
2202 }
2203 f_ran_register_imsi(g_pars.imsi, tmsi);
2204
2205 log("first SMS");
2206 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
2207
2208 /* MSC->BSC: expect PAGING from MSC */
2209 f_expect_paging();
2210
2211 log("second SMS");
2212 /* Now osmo-msc is in state "Paging pending", make sure that another SMS to be sent at this time just joins in
2213 * with the pending paging. Another SMS: */
2214 f_vty_sms_send(hex2str(pars.imsi), "2342", "Another SMS");
2215
2216 /* Establish DTAP / BSSAP / SCCP connection */
2217 f_establish_fully(EST_TYPE_PAG_RESP);
2218
2219 spars.tp.ud := 'C8329BFD064D9B53'O;
2220 f_mt_sms(spars);
2221
2222 spars.tp.ud := '41F79B8E2ECB41D3E614'O;
2223 f_mt_sms(spars);
2224
2225 f_expect_clear();
2226}
2227testcase TC_lu_and_mt_sms_already_paging() runs on MTC_CT {
2228 var BSC_ConnHdlrPars pars;
2229 var BSC_ConnHdlr vc_conn;
2230 f_init();
2231 pars := f_init_pars(44);
2232 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_sms_already_paging), pars);
2233 vc_conn.done;
2234}
Harald Weltee13cfb22019-04-23 16:52:02 +02002235
Philipp Maier3983e702018-11-22 19:01:33 +01002236/* Paging for MT SMS but no response */
Harald Weltee13cfb22019-04-23 16:52:02 +02002237friend 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 +01002238 var SmsParameters spars := valueof(t_SmsPars);
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002239
Philipp Maier3983e702018-11-22 19:01:33 +01002240 f_init_handler(pars, 150.0);
2241
2242 /* Perform location update */
2243 f_perform_lu();
2244
2245 /* register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002246 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Philipp Maier3983e702018-11-22 19:01:33 +01002247
Neels Hofmeyr6aaeccf2019-03-06 15:32:26 +01002248 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
2249
Neels Hofmeyr16237742019-03-06 15:34:01 +01002250 /* Expect the MSC to page exactly once */
Harald Weltee13cfb22019-04-23 16:52:02 +02002251 f_expect_paging();
Philipp Maier3983e702018-11-22 19:01:33 +01002252
2253 /* Wait some time to make sure the MSC is not delivering any further
2254 * paging messages or anything else that could be unexpected. */
2255 timer T := 20.0;
2256 T.start
2257 alt {
Vadim Yanitskiyda774592020-01-15 10:33:47 +07002258 [pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
2259 setverdict(fail, "paging seems not to stop!");
2260 mtc.stop;
Philipp Maier3983e702018-11-22 19:01:33 +01002261 }
Vadim Yanitskiyda774592020-01-15 10:33:47 +07002262 [not pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
2263 setverdict(fail, "paging seems not to stop!");
2264 mtc.stop;
Harald Weltee13cfb22019-04-23 16:52:02 +02002265 }
Vadim Yanitskiyda774592020-01-15 10:33:47 +07002266 [] BSSAP.receive {
2267 setverdict(fail, "unexpected BSSAP message received");
2268 self.stop;
Philipp Maier3983e702018-11-22 19:01:33 +01002269 }
Vadim Yanitskiyda774592020-01-15 10:33:47 +07002270 [] T.timeout {
2271 setverdict(pass);
Philipp Maier3983e702018-11-22 19:01:33 +01002272 }
2273 }
2274
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01002275 f_vty_sms_clear(hex2str(g_pars.imsi));
2276
Philipp Maier3983e702018-11-22 19:01:33 +01002277 setverdict(pass);
2278}
2279testcase TC_lu_and_mt_sms_paging_and_nothing() runs on MTC_CT {
2280 var BSC_ConnHdlrPars pars;
2281 var BSC_ConnHdlr vc_conn;
2282 f_init();
Philipp Maiera99ad262019-01-22 15:35:42 +01002283 pars := f_init_pars(1843);
Philipp Maier3983e702018-11-22 19:01:33 +01002284 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 +01002285 vc_conn.done;
2286}
2287
Alexander Couzensfc02f242019-09-12 03:43:18 +02002288/* LU followed by MT SMS with repeated paging */
2289friend function f_tc_lu_and_mt_sms_paging_repeated(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2290 var SmsParameters spars := valueof(t_SmsPars);
Alexander Couzensfc02f242019-09-12 03:43:18 +02002291
2292 f_init_handler(pars);
2293
2294 /* Perform location update and call */
2295 f_perform_lu();
2296
2297 /* register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002298 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Alexander Couzensfc02f242019-09-12 03:43:18 +02002299
2300 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
2301
Neels Hofmeyrc3accec2019-11-28 01:09:47 +01002302 log("Expecting first Paging");
Alexander Couzensfc02f242019-09-12 03:43:18 +02002303 /* MSC->BSC: expect PAGING from MSC */
2304 f_expect_paging();
2305
Neels Hofmeyrc3accec2019-11-28 01:09:47 +01002306 if (g_pars.ran_is_geran) {
2307 log("GERAN: expect no further Paging");
2308 } else {
2309 log("UTRAN: expect more Paging");
2310 }
2311
2312 timer T := 5.0;
2313 T.start;
2314 alt {
2315 [g_pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
2316 setverdict(fail, "GERAN should not repeat Paging, but received a second Paging");
2317 mtc.stop;
2318 }
2319 [not g_pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
2320 log("UTRAN: second Paging received, as expected");
2321 setverdict(pass);
2322 }
2323 [] T.timeout {
2324 if (g_pars.ran_is_geran) {
2325 log("GERAN: No further Paging received, as expected");
2326 setverdict(pass);
2327 } else {
2328 setverdict(fail, "UTRAN: Expected a second Paging");
2329 mtc.stop;
2330 }
2331 }
2332 }
Alexander Couzensfc02f242019-09-12 03:43:18 +02002333
2334 /* Establish DTAP / BSSAP / SCCP connection */
2335 f_establish_fully(EST_TYPE_PAG_RESP);
2336
2337 spars.tp.ud := 'C8329BFD064D9B53'O;
2338 f_mt_sms(spars);
2339
2340 f_expect_clear();
2341}
2342testcase TC_lu_and_mt_sms_paging_repeated() runs on MTC_CT {
2343 var BSC_ConnHdlrPars pars;
2344 var BSC_ConnHdlr vc_conn;
2345 f_init();
2346 pars := f_init_pars(1844);
2347 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_sms_paging_repeated), pars);
2348 vc_conn.done;
2349}
Harald Weltee13cfb22019-04-23 16:52:02 +02002350
Harald Weltef640a012018-04-14 17:49:21 +02002351/* mobile originated SMS from MS/BTS/BSC side to SMPP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002352friend function f_tc_smpp_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltef640a012018-04-14 17:49:21 +02002353 var SmsParameters spars := valueof(t_SmsPars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002354
Harald Weltef640a012018-04-14 17:49:21 +02002355 f_init_handler(pars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002356
Harald Weltef640a012018-04-14 17:49:21 +02002357 /* Perform location update so IMSI is known + registered in MSC/VLR */
2358 f_perform_lu();
Harald Weltef640a012018-04-14 17:49:21 +02002359
Vadim Yanitskiy2d3f8462020-01-15 11:44:12 +07002360 /* MS/UE submits a MO SMS */
2361 f_establish_fully(EST_TYPE_MO_SMS);
2362 f_mo_sms_submit(spars);
Harald Weltef640a012018-04-14 17:49:21 +02002363
2364 var SMPP_PDU smpp;
2365 var template SMPP_PDU tr_smpp := tr_SMPP(c_SMPP_command_id_deliver_sm, ESME_ROK);
2366 tr_smpp.body.deliver_sm := {
2367 service_type := "CMT",
2368 source_addr_ton := network_specific,
2369 source_addr_npi := isdn,
2370 source_addr := hex2str(pars.msisdn),
2371 dest_addr_ton := f_sm_ton_from_gsm(spars.tp.da.tP_DA_NoPad.tP_TypeOfNumber),
2372 dest_addr_npi := f_sm_npi_from_gsm(spars.tp.da.tP_DA_NoPad.tP_NumberingPlanID),
2373 destination_addr := hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue),
2374 esm_class := '00000001'B,
2375 protocol_id := 0,
2376 priority_flag := 0,
2377 schedule_delivery_time := "",
2378 replace_if_present := 0,
2379 data_coding := '00000001'B,
2380 sm_default_msg_id := 0,
2381 sm_length := ?,
2382 short_message := spars.tp.ud,
2383 opt_pars := {
2384 {
2385 tag := user_message_reference,
2386 len := 2,
2387 opt_value := {
2388 int2_val := oct2int(spars.tp.msg_ref)
2389 }
2390 }
2391 }
2392 };
2393 alt {
2394 [] SMPP.receive(tr_smpp) -> value smpp {
2395 SMPP.send(ts_SMPP_DELIVER_SM_resp(ESME_ROK, smpp.header.seq_num));
2396 }
2397 [] SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK)) { repeat; }
2398 }
2399
Vadim Yanitskiy2d3f8462020-01-15 11:44:12 +07002400 /* MSC terminates the SMS transaction with RP-ACK */
2401 f_mo_sms_wait_rp_ack(spars);
2402
Harald Weltef640a012018-04-14 17:49:21 +02002403 f_expect_clear();
2404}
2405testcase TC_smpp_mo_sms() runs on MTC_CT {
2406 var BSC_ConnHdlr vc_conn;
2407 f_init();
2408 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "default-route");
2409 vc_conn := f_start_handler(refers(f_tc_smpp_mo_sms), 44);
2410 vc_conn.done;
2411 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "no default-route");
2412}
2413
Vadim Yanitskiy33820762020-01-15 11:26:07 +07002414/* Test case for OS#4351: make sure that RP-ERROR from ESME is properly sent to the MS/UE */
2415friend function f_tc_smpp_mo_sms_rp_error(charstring id, BSC_ConnHdlrPars pars)
2416runs on BSC_ConnHdlr {
2417 var SmsParameters spars := valueof(t_SmsPars);
2418 var SMPP_PDU smpp_pdu;
2419 timer T := 3.0;
2420
2421 f_init_handler(pars);
2422
2423 /* Perform location update */
2424 f_perform_lu();
2425
2426 /* MS/UE submits a MO SMS */
2427 f_establish_fully(EST_TYPE_MO_SMS);
2428 f_mo_sms_submit(spars);
2429
2430 /* ESME responds with an error (Invalid Destination Address) */
2431 T.start;
2432 alt {
2433 [] SMPP.receive(tr_SMPP(c_SMPP_command_id_deliver_sm, ESME_ROK, body := ?)) -> value smpp_pdu {
2434 SMPP.send(ts_SMPP_DELIVER_SM_resp(ESME_RINVDSTADR, smpp_pdu.header.seq_num));
2435 }
2436 [] SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK)) { repeat; }
2437 [] T.timeout {
2438 setverdict(fail, "Timeout waiting for SMPP DELIVER-SM");
2439 mtc.stop;
2440 }
2441 }
2442
2443 /* Expect RP-ERROR on BSSAP interface */
2444 spars.exp_rp_err := 1; /* FIXME: GSM411_RP_CAUSE_MO_NUM_UNASSIGNED */
2445 f_mo_sms_wait_rp_ack(spars);
2446
2447 f_expect_clear();
2448}
2449testcase TC_smpp_mo_sms_rp_error() runs on MTC_CT {
2450 var BSC_ConnHdlr vc_conn;
2451 f_init();
2452 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "default-route");
2453 vc_conn := f_start_handler(refers(f_tc_smpp_mo_sms_rp_error), 45);
2454 vc_conn.done;
2455 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "no default-route");
2456}
2457
Harald Weltee13cfb22019-04-23 16:52:02 +02002458
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002459/* Test MO-SMS from MS/BTS/BSC towards HLR (via GSUP) */
Harald Weltee13cfb22019-04-23 16:52:02 +02002460friend function f_tc_gsup_mo_sms(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002461runs on BSC_ConnHdlr {
2462 var SmsParameters spars := valueof(t_SmsPars);
2463 var GSUP_PDU gsup_msg_rx;
2464 var octetstring sm_tpdu;
2465
2466 f_init_handler(pars);
2467
2468 /* We need to inspect GSUP activity */
2469 f_create_gsup_expect(hex2str(g_pars.imsi));
2470
2471 /* Perform location update */
2472 f_perform_lu();
2473
2474 /* Send CM Service Request for SMS */
2475 f_establish_fully(EST_TYPE_MO_SMS);
2476
2477 /* Prepare expected SM-RP-UI (SM TPDU) */
2478 enc_TPDU_RP_DATA_MS_SGSN_fast(
2479 valueof(ts_SMS_SUBMIT(spars.tp.msg_ref,
2480 spars.tp.da, spars.tp.pid, spars.tp.dcs,
2481 spars.tp.udl, spars.tp.ud)),
2482 sm_tpdu);
2483
2484 var template GSUP_PDU mo_forwardSM := tr_GSUP_MO_FORWARD_SM_REQ(
2485 imsi := g_pars.imsi,
2486 sm_rp_mr := spars.rp.msg_ref,
Vadim Yanitskiy04dd5f72019-12-13 15:45:44 +09002487 /* SM-RP-DA: SMSC address */
2488 sm_rp_da := tr_GSUP_SM_RP_DA_SMSC_ADDR(t_GSUP_SM_RP_Addr(
2489 number := spars.rp.smsc_addr.rP_NumberDigits,
2490 npi := spars.rp.smsc_addr.rP_NumberingPlanIdentification,
2491 ton := spars.rp.smsc_addr.rP_TypeOfNumber,
2492 ext := spars.rp.smsc_addr.rP_Ext)),
2493 /* SM-RP-OA: subscriber's MSISDN (filled in by MSC) */
2494 sm_rp_oa := tr_GSUP_SM_RP_OA_MSISDN(t_GSUP_SM_RP_Addr(
2495 number := g_pars.msisdn,
2496 /* NOTE: MSISDN in g_pars lacks this info, assuming defaults */
2497 npi := '0001'B, ton := '001'B, ext := '1'B)),
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002498 /* TODO: can we use decmatch here? */
2499 sm_rp_ui := sm_tpdu
2500 );
2501
2502 /* Submit an SMS on DTAP and expect MO-forwardSM-Req on GSUP */
2503 f_mo_sms_submit(spars);
2504 alt {
2505 [] GSUP.receive(mo_forwardSM) -> value gsup_msg_rx {
Vadim Yanitskiya358dd42020-01-15 10:42:47 +07002506 log("RX MO-forwardSM-Req: ", gsup_msg_rx);
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002507 setverdict(pass);
2508 }
2509 [] GSUP.receive {
2510 log("RX unexpected GSUP message");
2511 setverdict(fail);
2512 mtc.stop;
2513 }
2514 }
2515
2516 /* Trigger RP-ACK by sending MO-forwardSM-Res */
2517 GSUP.send(valueof(ts_GSUP_MO_FORWARD_SM_RES(
2518 imsi := g_pars.imsi,
2519 sm_rp_mr := spars.rp.msg_ref)));
2520 /* Expect RP-ACK on DTAP */
2521 f_mo_sms_wait_rp_ack(spars);
2522
2523 f_expect_clear();
2524}
2525testcase TC_gsup_mo_sms() runs on MTC_CT {
2526 var BSC_ConnHdlr vc_conn;
2527 f_init();
2528 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2529 vc_conn := f_start_handler(refers(f_tc_gsup_mo_sms), 88);
2530 vc_conn.done;
2531 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2532}
2533
Harald Weltee13cfb22019-04-23 16:52:02 +02002534
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07002535/* Test MO-SMMA from MS/BTS/BSC towards HLR (via GSUP) */
Harald Weltee13cfb22019-04-23 16:52:02 +02002536friend function f_tc_gsup_mo_smma(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07002537runs on BSC_ConnHdlr {
2538 var SmsParameters spars := valueof(t_SmsPars);
2539 var GSUP_PDU gsup_msg_rx;
2540
2541 f_init_handler(pars);
2542
2543 /* We need to inspect GSUP activity */
2544 f_create_gsup_expect(hex2str(g_pars.imsi));
2545
2546 /* Perform location update */
2547 f_perform_lu();
2548
2549 /* Send CM Service Request for SMS */
2550 f_establish_fully(EST_TYPE_MO_SMS);
2551
2552 var template GSUP_PDU mo_ReadyForSM := tr_GSUP_MO_READY_FOR_SM_REQ(
2553 imsi := g_pars.imsi,
2554 sm_rp_mr := spars.rp.msg_ref,
2555 sm_alert_rsn := GSUP_SM_ALERT_RSN_TYPE_MEM_AVAIL
2556 );
2557
2558 /* Submit an SMS on DTAP and expect MO-forwardSM-Req on GSUP */
2559 f_mo_smma(spars);
2560 alt {
2561 [] GSUP.receive(mo_ReadyForSM) -> value gsup_msg_rx {
Vadim Yanitskiya358dd42020-01-15 10:42:47 +07002562 log("RX MO-ReadyForSM-Req: ", gsup_msg_rx);
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07002563 setverdict(pass);
2564 }
2565 [] GSUP.receive {
2566 log("RX unexpected GSUP message");
2567 setverdict(fail);
2568 mtc.stop;
2569 }
2570 }
2571
2572 /* Trigger RP-ACK by sending MO-forwardSM-Res */
2573 GSUP.send(valueof(ts_GSUP_MO_READY_FOR_SM_RES(
2574 imsi := g_pars.imsi,
2575 sm_rp_mr := spars.rp.msg_ref)));
2576 /* Expect RP-ACK on DTAP */
2577 f_mo_sms_wait_rp_ack(spars);
2578
2579 f_expect_clear();
2580}
2581testcase TC_gsup_mo_smma() runs on MTC_CT {
2582 var BSC_ConnHdlr vc_conn;
2583 f_init();
2584 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2585 vc_conn := f_start_handler(refers(f_tc_gsup_mo_smma), 89);
2586 vc_conn.done;
2587 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2588}
2589
Harald Weltee13cfb22019-04-23 16:52:02 +02002590
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002591/* Helper for sending MT SMS over GSUP */
2592private function f_gsup_forwardSM_req(SmsParameters spars, OCT1 mms := '00'O)
2593runs on BSC_ConnHdlr {
Vadim Yanitskiya52347c2019-12-12 17:32:33 +09002594 var GSUP_SM_RP_Addr msisdn := valueof(t_GSUP_SM_RP_Addr(g_pars.msisdn));
Vadim Yanitskiy04dd5f72019-12-13 15:45:44 +09002595 var GSUP_SM_RP_Addr smsc := valueof(t_GSUP_SM_RP_Addr(
2596 number := spars.rp.smsc_addr.rP_NumberDigits,
2597 npi := spars.rp.smsc_addr.rP_NumberingPlanIdentification,
2598 ton := spars.rp.smsc_addr.rP_TypeOfNumber,
2599 ext := spars.rp.smsc_addr.rP_Ext));
Vadim Yanitskiya52347c2019-12-12 17:32:33 +09002600
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002601 GSUP.send(ts_GSUP_MT_FORWARD_SM_REQ(
2602 imsi := g_pars.imsi,
2603 /* NOTE: MSC should assign RP-MR itself */
2604 sm_rp_mr := 'FF'O,
Vadim Yanitskiya52347c2019-12-12 17:32:33 +09002605 sm_rp_da := valueof(ts_GSUP_SM_RP_DA_MSISDN(msisdn)),
Vadim Yanitskiy04dd5f72019-12-13 15:45:44 +09002606 sm_rp_oa := valueof(ts_GSUP_SM_RP_OA_SMSC_ADDR(smsc)),
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002607 /* Encoded SMS TPDU (taken from Wireshark)
2608 * FIXME: we should encode spars somehow */
2609 sm_rp_ui := '00068021436500008111328130858200'O,
2610 sm_rp_mms := mms
2611 ));
2612}
2613
2614/* Test successful MT-SMS (RP-ACK) over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002615friend function f_tc_gsup_mt_sms_ack(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002616runs on BSC_ConnHdlr {
2617 var SmsParameters spars := valueof(t_SmsPars);
2618
2619 f_init_handler(pars);
2620
2621 /* We need to inspect GSUP activity */
2622 f_create_gsup_expect(hex2str(g_pars.imsi));
2623
2624 /* Perform location update */
2625 f_perform_lu();
2626
2627 /* Register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002628 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002629
2630 var template GSUP_PDU mt_forwardSM_res := tr_GSUP_MT_FORWARD_SM_RES(
2631 imsi := g_pars.imsi,
2632 /* NOTE: MSC should assign RP-MR itself */
2633 sm_rp_mr := ?
2634 );
2635
2636 /* Submit a MT SMS on GSUP */
2637 f_gsup_forwardSM_req(spars);
2638
2639 /* Expect Paging Request and Establish DTAP / BSSAP / SCCP connection */
Harald Weltee035e3e2019-04-21 17:32:05 +02002640 f_expect_paging();
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002641 f_establish_fully(EST_TYPE_PAG_RESP);
2642
2643 /* Wait for MT SMS on DTAP */
2644 f_mt_sms_expect(spars);
2645
2646 /* Send RP-ACK and expect MT-forwardSM-Res on GSUP */
2647 f_mt_sms_send_rp_ack(spars);
2648 alt {
2649 [] GSUP.receive(mt_forwardSM_res) {
2650 log("RX MT-forwardSM-Res (RP-ACK)");
2651 setverdict(pass);
2652 }
2653 [] GSUP.receive {
2654 log("RX unexpected GSUP message");
2655 setverdict(fail);
2656 mtc.stop;
2657 }
2658 }
2659
2660 f_expect_clear();
2661}
2662testcase TC_gsup_mt_sms_ack() runs on MTC_CT {
2663 var BSC_ConnHdlrPars pars;
2664 var BSC_ConnHdlr vc_conn;
2665 f_init();
2666 pars := f_init_pars(90);
2667 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2668 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_sms_ack), pars);
2669 vc_conn.done;
2670 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2671}
2672
Harald Weltee13cfb22019-04-23 16:52:02 +02002673
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002674/* Test rejected MT-SMS (RP-ERROR) over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002675friend function f_tc_gsup_mt_sms_err(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002676runs on BSC_ConnHdlr {
2677 var SmsParameters spars := valueof(t_SmsPars);
2678 var OCT1 sm_rp_cause := '78'O; /* dummy RP-Cause value */
2679
2680 f_init_handler(pars);
2681
2682 /* We need to inspect GSUP activity */
2683 f_create_gsup_expect(hex2str(g_pars.imsi));
2684
2685 /* Perform location update */
2686 f_perform_lu();
2687
2688 /* Register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002689 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002690
2691 var template GSUP_PDU mt_forwardSM_err := tr_GSUP_MT_FORWARD_SM_ERR(
2692 imsi := g_pars.imsi,
2693 /* NOTE: MSC should assign RP-MR itself */
2694 sm_rp_mr := ?,
2695 sm_rp_cause := sm_rp_cause
2696 );
2697
2698 /* Submit a MT SMS on GSUP */
2699 f_gsup_forwardSM_req(spars);
2700
2701 /* Expect Paging Request and Establish DTAP / BSSAP / SCCP connection */
Harald Weltee035e3e2019-04-21 17:32:05 +02002702 f_expect_paging();
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002703 f_establish_fully(EST_TYPE_PAG_RESP);
2704
2705 /* Wait for MT SMS on DTAP */
2706 f_mt_sms_expect(spars);
2707
2708 /* Send RP-ERROR and expect MT-forwardSM-Err on GSUP */
2709 f_mt_sms_send_rp_error(spars, oct2int(sm_rp_cause));
2710 alt {
2711 [] GSUP.receive(mt_forwardSM_err) {
2712 log("RX MT-forwardSM-Err (RP-ERROR)");
2713 setverdict(pass);
2714 mtc.stop;
2715 }
2716 [] GSUP.receive {
2717 log("RX unexpected GSUP message");
2718 setverdict(fail);
2719 mtc.stop;
2720 }
2721 }
2722
2723 f_expect_clear();
2724}
2725testcase TC_gsup_mt_sms_err() runs on MTC_CT {
2726 var BSC_ConnHdlrPars pars;
2727 var BSC_ConnHdlr vc_conn;
2728 f_init();
2729 pars := f_init_pars(91);
2730 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2731 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_sms_err), pars);
2732 vc_conn.done;
2733 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2734}
2735
Harald Weltee13cfb22019-04-23 16:52:02 +02002736
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002737/* Test SM-RP-MR assignment for MT-SMS over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002738friend function f_tc_gsup_mt_sms_rp_mr(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002739runs on BSC_ConnHdlr {
2740 var SmsParameters spars1 := valueof(t_SmsPars); /* 1st SMS */
2741 var SmsParameters spars2 := valueof(t_SmsPars); /* 2nd SMS */
2742
2743 f_init_handler(pars);
2744
2745 /* We need to inspect GSUP activity */
2746 f_create_gsup_expect(hex2str(g_pars.imsi));
2747
2748 /* Perform location update */
2749 f_perform_lu();
2750
2751 /* Register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002752 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002753
2754 /* Submit the 1st MT SMS on GSUP */
2755 log("TX MT-forwardSM-Req for the 1st SMS");
2756 f_gsup_forwardSM_req(spars1);
2757
2758 /* Expect Paging Request and Establish DTAP / BSSAP / SCCP connection */
Harald Weltee035e3e2019-04-21 17:32:05 +02002759 f_expect_paging();
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002760 f_establish_fully(EST_TYPE_PAG_RESP);
2761
2762 /* Wait for 1st MT SMS on DTAP */
2763 f_mt_sms_expect(spars1);
2764 log("RX the 1st SMS on DTAP, DTAP TID is ", spars1.tid,
2765 ", SM-RP-MR is ", spars1.rp.msg_ref);
2766
2767 /* Submit the 2nd MT SMS on GSUP */
2768 log("TX MT-forwardSM-Req for the 2nd SMS");
2769 f_gsup_forwardSM_req(spars2);
2770
2771 /* Wait for 2nd MT SMS on DTAP */
2772 f_mt_sms_expect(spars2);
2773 log("RX the 2nd SMS on DTAP, DTAP TID is ", spars2.tid,
2774 ", SM-RP-MR is ", spars2.rp.msg_ref);
2775
2776 /* Both transaction IDs shall be different */
2777 if (spars1.tid == spars2.tid) {
2778 log("Both DTAP transaction IDs shall be different");
2779 setverdict(fail);
2780 }
2781
2782 /* Both SM-RP-MR values shall be different */
2783 if (spars1.rp.msg_ref == spars2.rp.msg_ref) {
2784 log("Both SM-RP-MR values shall be different");
2785 setverdict(fail);
2786 }
2787
2788 /* Both SM-RP-MR values shall be assigned */
2789 if (spars1.rp.msg_ref == 'FF'O) {
2790 log("Unassigned SM-RP-MR value for the 1st SMS");
2791 setverdict(fail);
2792 }
2793 if (spars2.rp.msg_ref == 'FF'O) {
2794 log("Unassigned SM-RP-MR value for the 2nd SMS");
2795 setverdict(fail);
2796 }
2797
2798 /* Send the 1st RP-ACK and expect MT-forwardSM-Res on GSUP */
2799 f_mt_sms_send_rp_ack(spars1);
2800 alt {
2801 [] GSUP.receive(tr_GSUP_MT_FORWARD_SM_RES(
2802 imsi := g_pars.imsi,
2803 sm_rp_mr := spars1.rp.msg_ref
2804 )) {
2805 log("RX MT-forwardSM-Res (RP-ACK)");
2806 setverdict(pass);
2807 }
2808 [] GSUP.receive {
2809 log("RX unexpected GSUP message");
2810 setverdict(fail);
2811 mtc.stop;
2812 }
2813 }
2814
2815 /* Send the 2nd RP-ACK and expect MT-forwardSM-Res on GSUP */
2816 f_mt_sms_send_rp_ack(spars2);
2817 alt {
2818 [] GSUP.receive(tr_GSUP_MT_FORWARD_SM_RES(
2819 imsi := g_pars.imsi,
2820 sm_rp_mr := spars2.rp.msg_ref
2821 )) {
2822 log("RX MT-forwardSM-Res (RP-ACK)");
2823 setverdict(pass);
2824 }
2825 [] GSUP.receive {
2826 log("RX unexpected GSUP message");
2827 setverdict(fail);
2828 mtc.stop;
2829 }
2830 }
2831
2832 f_expect_clear();
2833}
2834testcase TC_gsup_mt_sms_rp_mr() runs on MTC_CT {
2835 var BSC_ConnHdlrPars pars;
2836 var BSC_ConnHdlr vc_conn;
2837 f_init();
2838 pars := f_init_pars(92);
2839 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2840 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_sms_rp_mr), pars);
2841 vc_conn.done;
2842 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2843}
2844
Harald Weltee13cfb22019-04-23 16:52:02 +02002845
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07002846/* Test SM-RP-MR assignment for MT-SMS over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002847friend function f_tc_gsup_mo_mt_sms_rp_mr(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07002848runs on BSC_ConnHdlr {
2849 var SmsParameters spars_mo := valueof(t_SmsPars); /* MO SMMA */
2850 var SmsParameters spars_mt := valueof(t_SmsPars); /* MT SMS */
2851
2852 f_init_handler(pars);
2853
2854 /* We need to inspect GSUP activity */
2855 f_create_gsup_expect(hex2str(g_pars.imsi));
2856
2857 /* Perform location update */
2858 f_perform_lu();
2859
2860 /* Register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002861 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07002862
2863 /* Send CM Service Request for MO SMMA */
2864 f_establish_fully(EST_TYPE_MO_SMS);
2865
2866 /* Submit MO SMMA on DTAP */
2867 log("Submit MO SMMA on DTAP, SM-RP-MR is '00'O");
2868 spars_mo.rp.msg_ref := '00'O;
2869 f_mo_smma(spars_mo);
2870
2871 /* Expect MO-forwardSM-Req for MO SMMA on GSUP */
2872 alt {
2873 [] GSUP.receive(tr_GSUP_MO_READY_FOR_SM_REQ(
2874 imsi := g_pars.imsi,
2875 sm_rp_mr := spars_mo.rp.msg_ref,
2876 sm_alert_rsn := GSUP_SM_ALERT_RSN_TYPE_MEM_AVAIL
2877 )) {
2878 log("RX MO-ReadyForSM-Req, SM-RP-MR is '00'O");
2879 setverdict(pass);
2880 }
2881 [] GSUP.receive {
2882 log("RX unexpected GSUP message");
2883 setverdict(fail);
2884 mtc.stop;
2885 }
2886 }
2887
2888 /* Submit MT SMS on GSUP */
2889 log("TX MT-forwardSM-Req for the MT SMS");
2890 f_gsup_forwardSM_req(spars_mt);
2891
2892 /* Wait for MT SMS on DTAP */
2893 f_mt_sms_expect(spars_mt);
2894 log("RX MT SMS on DTAP, DTAP TID is ", spars_mt.tid,
2895 ", SM-RP-MR is ", spars_mt.rp.msg_ref);
2896
2897 /* Both SM-RP-MR values shall be different */
2898 if (spars_mo.rp.msg_ref == spars_mt.rp.msg_ref) {
2899 log("Both SM-RP-MR values shall be different");
2900 setverdict(fail);
2901 }
2902
2903 /* SM-RP-MR value for MT SMS shall be assigned */
2904 if (spars_mt.rp.msg_ref == 'FF'O) {
2905 log("Unassigned SM-RP-MR value for the MT SMS");
2906 setverdict(fail);
2907 }
2908
2909 /* Trigger RP-ACK for MO SMMA by sending MO-forwardSM-Res */
2910 GSUP.send(valueof(ts_GSUP_MO_READY_FOR_SM_RES(
2911 imsi := g_pars.imsi,
2912 sm_rp_mr := spars_mo.rp.msg_ref)));
2913 /* Expect RP-ACK for MO SMMA on DTAP */
2914 f_mo_sms_wait_rp_ack(spars_mo);
2915
2916 /* Send RP-ACK for MT SMS and expect MT-forwardSM-Res on GSUP */
2917 f_mt_sms_send_rp_ack(spars_mt);
2918 alt {
2919 [] GSUP.receive(tr_GSUP_MT_FORWARD_SM_RES(
2920 imsi := g_pars.imsi,
2921 sm_rp_mr := spars_mt.rp.msg_ref
2922 )) {
2923 log("RX MT-forwardSM-Res (RP-ACK)");
2924 setverdict(pass);
2925 }
2926 [] GSUP.receive {
2927 log("RX unexpected GSUP message");
2928 setverdict(fail);
2929 mtc.stop;
2930 }
2931 }
2932
2933 f_expect_clear();
2934}
2935testcase TC_gsup_mo_mt_sms_rp_mr() runs on MTC_CT {
2936 var BSC_ConnHdlrPars pars;
2937 var BSC_ConnHdlr vc_conn;
2938 f_init();
2939 pars := f_init_pars(93);
2940 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2941 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mo_mt_sms_rp_mr), pars);
2942 vc_conn.done;
2943 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2944}
2945
Harald Weltee13cfb22019-04-23 16:52:02 +02002946
Vadim Yanitskiy1cd11a02018-12-03 02:43:35 +07002947/* Test multi-part MT-SMS over GSUP */
2948private function f_tc_gsup_mt_multi_part_sms(charstring id, BSC_ConnHdlrPars pars)
2949runs on BSC_ConnHdlr {
2950 var SmsParameters spars := valueof(t_SmsPars);
2951
2952 f_init_handler(pars);
2953
2954 /* We need to inspect GSUP activity */
2955 f_create_gsup_expect(hex2str(g_pars.imsi));
2956
2957 /* Perform location update */
2958 f_perform_lu();
2959
2960 /* Register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01002961 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy1cd11a02018-12-03 02:43:35 +07002962
2963 var template GSUP_PDU mt_forwardSM_res := tr_GSUP_MT_FORWARD_SM_RES(
2964 imsi := g_pars.imsi,
2965 /* NOTE: MSC should assign RP-MR itself */
2966 sm_rp_mr := ?
2967 );
2968
2969 /* Send 4 messages (NOTE: SM-RP-UI remains unchanged) */
2970 for (var integer i := 3; i >= 0; i := i-1) {
2971 /* Submit a MT SMS on GSUP (MMS is decremented) */
2972 f_gsup_forwardSM_req(spars, int2oct(i, 1));
2973
2974 /* Expect Paging Request and Establish connection */
2975 if (i == 3) { /* ... only once! */
Harald Weltee13cfb22019-04-23 16:52:02 +02002976 f_expect_paging();
Vadim Yanitskiy1cd11a02018-12-03 02:43:35 +07002977 f_establish_fully(EST_TYPE_PAG_RESP);
2978 }
2979
2980 /* Wait for MT SMS on DTAP */
2981 f_mt_sms_expect(spars);
2982
2983 /* Send RP-ACK and expect MT-forwardSM-Res on GSUP */
2984 f_mt_sms_send_rp_ack(spars);
2985 alt {
2986 [] GSUP.receive(mt_forwardSM_res) {
2987 log("RX MT-forwardSM-Res (RP-ACK)");
2988 setverdict(pass);
2989 }
2990 [] GSUP.receive {
2991 log("RX unexpected GSUP message");
2992 setverdict(fail);
2993 mtc.stop;
2994 }
2995 }
2996
2997 /* Keep some 'distance' between transmissions */
2998 f_sleep(1.5);
2999 }
3000
3001 f_expect_clear();
3002}
3003testcase TC_gsup_mt_multi_part_sms() runs on MTC_CT {
3004 var BSC_ConnHdlrPars pars;
3005 var BSC_ConnHdlr vc_conn;
3006 f_init();
3007 pars := f_init_pars(91);
3008 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
3009 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_multi_part_sms), pars);
3010 vc_conn.done;
3011 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
3012}
3013
Harald Weltef640a012018-04-14 17:49:21 +02003014/* convert GSM L3 TON to SMPP_TON enum */
3015function f_sm_ton_from_gsm(BIT3 ton) return SMPP_TON {
3016 select (ton) {
3017 case ('000'B) { return unknown; }
3018 case ('001'B) { return international; }
3019 case ('010'B) { return national; }
3020 case ('011'B) { return network_specific; }
3021 case ('100'B) { return subscriber_number; }
3022 case ('101'B) { return alphanumeric; }
3023 case ('110'B) { return abbreviated; }
3024 }
3025 setverdict(fail, "Unknown TON ", ton);
Daniel Willmannafce8662018-07-06 23:11:32 +02003026 mtc.stop;
Harald Weltef640a012018-04-14 17:49:21 +02003027}
3028/* convert GSM L3 NPI to SMPP_NPI enum */
3029function f_sm_npi_from_gsm(BIT4 npi) return SMPP_NPI {
3030 select (npi) {
3031 case ('0000'B) { return unknown; }
3032 case ('0001'B) { return isdn; }
3033 case ('0011'B) { return data; }
3034 case ('0100'B) { return telex; }
3035 case ('0110'B) { return land_mobile; }
3036 case ('1000'B) { return national; }
3037 case ('1001'B) { return private_; }
3038 case ('1010'B) { return ermes; }
3039 }
3040 setverdict(fail, "Unknown NPI ", npi);
Daniel Willmannafce8662018-07-06 23:11:32 +02003041 mtc.stop;
Harald Weltef640a012018-04-14 17:49:21 +02003042}
3043
3044/* build a SMPP_SM from SmsParameters */
3045function f_mt_sm_from_spars(SmsParameters spars)
3046runs on BSC_ConnHdlr return SMPP_SM {
3047 var SMPP_SM sm := {
3048 service_type := "CMT",
3049 source_addr_ton := f_sm_ton_from_gsm(spars.tp.da.tP_DA_NoPad.tP_TypeOfNumber),
3050 source_addr_npi := f_sm_npi_from_gsm(spars.tp.da.tP_DA_NoPad.tP_NumberingPlanID),
3051 source_addr := hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue),
3052 dest_addr_ton := international,
3053 dest_addr_npi := isdn,
3054 destination_addr := hex2str(g_pars.msisdn),
3055 esm_class := '00000001'B,
3056 protocol_id := 0,
3057 priority_flag := 0,
3058 schedule_delivery_time := "",
3059 validity_period := "",
3060 registered_delivery := '00000000'B,
3061 replace_if_present := 0,
3062 data_coding := '00000001'B,
3063 sm_default_msg_id := 0,
3064 sm_length := spars.tp.udl,
3065 short_message := spars.tp.ud,
3066 opt_pars := {}
3067 };
3068 return sm;
3069}
3070
3071/* helper function to encode SMS from 'spars', send it via SMPP to MSC; receive it on MS side */
3072private function f_smpp_mt_sms(SmsParameters spars, boolean trans_mode) runs on BSC_ConnHdlr {
3073 var SMPP_SM sm := f_mt_sm_from_spars(spars);
3074 if (trans_mode) {
3075 sm.esm_class := '00000010'B;
3076 }
3077
3078 /* actually cause MSC to send a SMS via SUBMIT-SM from SMPP side */
3079 SMPP.send(ts_SMPP_SUBMIT_SM(sm));
3080 if (not match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
3081 /* if we're not in SMPP transaction mode, we expect the SMPP-level ACK
3082 * before we expect the SMS delivery on the BSC/radio side */
3083 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
3084 }
3085
3086 /* MSC->BSC: expect PAGING from MSC */
Harald Weltee035e3e2019-04-21 17:32:05 +02003087 f_expect_paging();
Harald Weltef640a012018-04-14 17:49:21 +02003088 /* Establish DTAP / BSSAP / SCCP connection */
3089 f_establish_fully(EST_TYPE_PAG_RESP);
3090 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
3091
3092 f_mt_sms(spars);
3093
3094 if (match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
3095 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
3096 }
3097 f_expect_clear();
3098}
3099
3100/* mobile terminated SMS, from SMPP to BSC/BTS/MS */
3101private function f_tc_smpp_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
3102 f_init_handler(pars);
3103
3104 /* Perform location update so IMSI is known + registered in MSC/VLR */
3105 f_perform_lu();
3106 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
3107
3108 /* register an 'expect' for given IMSI (+TMSI) */
Vadim Yanitskiyae747742020-01-10 00:23:10 +01003109 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Harald Weltef640a012018-04-14 17:49:21 +02003110
3111 var SmsParameters spars := valueof(t_SmsPars);
3112 /* TODO: test with more intelligent user data; test different coding schemes */
3113 spars.tp.ud := '00'O;
3114 spars.tp.udl := 1;
3115
3116 /* first test the non-transaction store+forward mode */
3117 f_smpp_mt_sms(spars, false);
3118
3119 /* then test the transaction mode */
3120 f_smpp_mt_sms(spars, true);
3121}
3122testcase TC_smpp_mt_sms() runs on MTC_CT {
3123 var BSC_ConnHdlr vc_conn;
3124 f_init();
3125 vc_conn := f_start_handler(refers(f_tc_smpp_mt_sms), 45);
3126 vc_conn.done;
3127}
3128
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003129/***********************************************************************
3130 * USSD Testing
3131 ***********************************************************************/
3132
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003133private altstep as_unexp_gsup_or_bssap_msg()
3134runs on BSC_ConnHdlr {
3135 [] GSUP.receive {
3136 setverdict(fail, "Unknown/unexpected GSUP received");
3137 self.stop;
3138 }
3139 [] BSSAP.receive {
3140 setverdict(fail, "Unknown/unexpected BSSAP message received");
3141 self.stop;
3142 }
3143}
3144
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003145private function f_expect_gsup_msg(template GSUP_PDU msg,
3146 float T_val := 2.0)
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003147runs on BSC_ConnHdlr return GSUP_PDU {
3148 var GSUP_PDU gsup_msg_complete;
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003149 timer T := T_val;
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003150
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003151 T.start;
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003152 alt {
3153 [] GSUP.receive(msg) -> value gsup_msg_complete {
3154 setverdict(pass);
3155 }
3156 /* We don't expect anything else */
3157 [] as_unexp_gsup_or_bssap_msg();
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003158 [] T.timeout {
3159 setverdict(fail, "Timeout waiting for GSUP message: ", msg);
3160 }
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003161 }
3162
3163 return gsup_msg_complete;
3164}
3165
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003166private function f_expect_mt_dtap_msg(template PDU_ML3_NW_MS msg,
3167 float T_val := 2.0)
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003168runs on BSC_ConnHdlr return PDU_ML3_NW_MS {
3169 var PDU_DTAP_MT bssap_msg_complete;
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003170 timer T := T_val;
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003171
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003172 T.start;
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003173 alt {
3174 [] BSSAP.receive(tr_PDU_DTAP_MT(msg)) -> value bssap_msg_complete {
3175 setverdict(pass);
3176 }
3177 /* We don't expect anything else */
3178 [] as_unexp_gsup_or_bssap_msg();
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003179 [] T.timeout {
3180 setverdict(fail, "Timeout waiting for BSSAP message: ", msg);
3181 }
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07003182 }
3183
3184 return bssap_msg_complete.dtap;
3185}
3186
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003187/* LU followed by MO USSD request */
Harald Weltee13cfb22019-04-23 16:52:02 +02003188friend function f_tc_lu_and_mo_ussd_single_request(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003189runs on BSC_ConnHdlr {
3190 f_init_handler(pars);
3191
3192 /* Perform location update */
3193 f_perform_lu();
3194
3195 /* Send CM Service Request for SS/USSD */
3196 f_establish_fully(EST_TYPE_SS_ACT);
3197
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003198 /* We need to inspect GSUP activity */
3199 f_create_gsup_expect(hex2str(g_pars.imsi));
3200
3201 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3202 invoke_id := 5, /* Phone may not start from 0 or 1 */
3203 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3204 ussd_string := "*#100#"
3205 );
3206
3207 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
3208 invoke_id := 5, /* InvokeID shall be the same for both REQ and RSP */
3209 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3210 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
3211 )
3212
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003213 /* Compose a new SS/REGISTER message with request */
3214 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
3215 tid := 1, /* We just need a single transaction */
3216 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003217 facility := valueof(facility_req)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003218 );
3219
3220 /* Compose SS/RELEASE_COMPLETE template with expected response */
3221 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
3222 tid := 1, /* Response should arrive within the same transaction */
3223 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003224 facility := valueof(facility_rsp)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003225 );
3226
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003227 /* Compose expected MSC -> HLR message */
3228 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
3229 imsi := g_pars.imsi,
3230 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3231 ss := valueof(facility_req)
3232 );
3233
3234 /* To be used for sending response with correct session ID */
3235 var GSUP_PDU gsup_req_complete;
3236
3237 /* Request own number */
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003238 BSSAP.send(ts_PDU_DTAP_MO(ussd_req));
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003239 /* Expect GSUP message containing the SS payload */
3240 gsup_req_complete := f_expect_gsup_msg(gsup_req);
3241
3242 /* Compose the response from HLR using received session ID */
3243 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
3244 imsi := g_pars.imsi,
3245 sid := gsup_req_complete.ies[1].val.session_id,
3246 state := OSMO_GSUP_SESSION_STATE_END,
3247 ss := valueof(facility_rsp)
3248 );
3249
3250 /* Finally, HLR terminates the session */
3251 GSUP.send(gsup_rsp);
3252 /* Expect RELEASE_COMPLETE message with the response */
3253 f_expect_mt_dtap_msg(ussd_rsp);
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003254
3255 f_expect_clear();
3256}
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003257testcase TC_lu_and_mo_ussd_single_request() runs on MTC_CT {
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003258 var BSC_ConnHdlr vc_conn;
3259 f_init();
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003260 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_single_request), 46);
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003261 vc_conn.done;
3262}
3263
Harald Weltee13cfb22019-04-23 16:52:02 +02003264
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003265/* LU followed by MT USSD notification */
Harald Weltee13cfb22019-04-23 16:52:02 +02003266friend function f_tc_lu_and_mt_ussd_notification(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003267runs on BSC_ConnHdlr {
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003268 timer T := 5.0;
3269
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003270 f_init_handler(pars);
3271
3272 /* Perform location update */
3273 f_perform_lu();
3274
Harald Welte6811d102019-04-14 22:23:14 +02003275 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003276
3277 /* We need to inspect GSUP activity */
3278 f_create_gsup_expect(hex2str(g_pars.imsi));
3279
3280 /* Facility IE with network-originated USSD notification */
3281 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3282 op_code := SS_OP_CODE_USS_NOTIFY,
3283 ussd_string := "Mahlzeit!"
3284 );
3285
3286 /* Facility IE with acknowledgment to the USSD notification */
3287 var template OCTN facility_rsp := enc_SS_FacilityInformation(
3288 /* In case of USSD notification, Return Result is empty */
3289 valueof(ts_SS_USSD_FACILITY_RETURN_RESULT_EMPTY())
3290 );
3291
3292 /* Compose a new MT SS/REGISTER message with USSD notification */
3293 var template PDU_ML3_NW_MS ussd_ntf := tr_ML3_MT_SS_REGISTER(
3294 tid := 0, /* FIXME: most likely, it should be 0 */
3295 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3296 facility := valueof(facility_req)
3297 );
3298
3299 /* Compose HLR -> MSC GSUP message */
3300 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
3301 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003302 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003303 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3304 ss := valueof(facility_req)
3305 );
3306
3307 /* Send it to MSC and expect Paging Request */
3308 GSUP.send(gsup_req);
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003309 T.start;
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003310 alt {
Harald Weltee13cfb22019-04-23 16:52:02 +02003311 [pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
3312 setverdict(pass);
3313 }
Harald Welte62113fc2019-05-09 13:04:02 +02003314 [not pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003315 setverdict(pass);
3316 }
3317 /* We don't expect anything else */
3318 [] as_unexp_gsup_or_bssap_msg();
Vadim Yanitskiyd1e1ce52019-06-15 03:40:59 +07003319 [] T.timeout {
3320 setverdict(fail, "Timeout waiting for Paging Request");
3321 }
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003322 }
3323
3324 /* Send Paging Response and expect USSD notification */
3325 f_establish_fully(EST_TYPE_PAG_RESP);
3326 /* Expect MT REGISTER message with USSD notification */
3327 f_expect_mt_dtap_msg(ussd_ntf);
3328
3329 /* Compose a new MO SS/FACILITY message with empty response */
3330 var template (value) PDU_ML3_MS_NW ussd_rsp := ts_ML3_MO_SS_FACILITY(
3331 tid := 0, /* FIXME: it shall match the request tid */
3332 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3333 facility := valueof(facility_rsp)
3334 );
3335
3336 /* Compose expected MSC -> HLR GSUP message */
3337 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_REQ(
3338 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003339 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003340 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
3341 ss := valueof(facility_rsp)
3342 );
3343
3344 /* MS sends response to the notification */
3345 BSSAP.send(ts_PDU_DTAP_MO(ussd_rsp));
3346 /* Expect GSUP message containing the SS payload */
3347 f_expect_gsup_msg(gsup_rsp);
3348
3349 /* Compose expected MT SS/RELEASE COMPLETE message */
3350 var template PDU_ML3_NW_MS ussd_term := tr_ML3_MT_SS_RELEASE_COMPLETE(
3351 tid := 0, /* FIXME: it shall match the request tid */
3352 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3353 facility := omit
3354 );
3355
3356 /* Compose MSC -> HLR GSUP message */
3357 var template GSUP_PDU gsup_term := ts_GSUP_PROC_SS_REQ(
3358 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003359 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003360 state := OSMO_GSUP_SESSION_STATE_END
3361 );
3362
3363 /* Finally, HLR terminates the session */
3364 GSUP.send(gsup_term)
3365 /* Expect MT RELEASE COMPLETE without Facility IE */
3366 f_expect_mt_dtap_msg(ussd_term);
3367
3368 f_expect_clear();
3369}
3370testcase TC_lu_and_mt_ussd_notification() runs on MTC_CT {
3371 var BSC_ConnHdlr vc_conn;
3372 f_init();
3373 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_ussd_notification), 47);
3374 vc_conn.done;
3375}
3376
Harald Weltee13cfb22019-04-23 16:52:02 +02003377
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003378/* LU followed by MT call and MO USSD request during this call */
Harald Weltee13cfb22019-04-23 16:52:02 +02003379friend function f_tc_lu_and_mo_ussd_during_mt_call(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003380runs on BSC_ConnHdlr {
3381 f_init_handler(pars);
3382
3383 /* Call parameters taken from f_tc_lu_and_mt_call */
3384 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003385
3386 /* Perform location update */
3387 f_perform_lu();
3388
3389 /* Establish a MT call */
3390 f_mt_call_establish(cpars);
3391
3392 /* Hold the call for some time */
3393 f_sleep(1.0);
3394
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003395 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3396 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3397 ussd_string := "*#100#"
3398 );
3399
3400 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
3401 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3402 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
3403 )
3404
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003405 /* Compose a new SS/REGISTER message with request */
3406 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
3407 tid := 1, /* We just need a single transaction */
3408 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003409 facility := valueof(facility_req)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003410 );
3411
3412 /* Compose SS/RELEASE_COMPLETE template with expected response */
3413 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
3414 tid := 1, /* Response should arrive within the same transaction */
3415 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003416 facility := valueof(facility_rsp)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003417 );
3418
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003419 /* Compose expected MSC -> HLR message */
3420 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
3421 imsi := g_pars.imsi,
3422 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3423 ss := valueof(facility_req)
3424 );
3425
3426 /* To be used for sending response with correct session ID */
3427 var GSUP_PDU gsup_req_complete;
3428
3429 /* Request own number */
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003430 BSSAP.send(ts_PDU_DTAP_MO(ussd_req));
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003431 /* Expect GSUP message containing the SS payload */
3432 gsup_req_complete := f_expect_gsup_msg(gsup_req);
3433
3434 /* Compose the response from HLR using received session ID */
3435 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
3436 imsi := g_pars.imsi,
3437 sid := gsup_req_complete.ies[1].val.session_id,
3438 state := OSMO_GSUP_SESSION_STATE_END,
3439 ss := valueof(facility_rsp)
3440 );
3441
3442 /* Finally, HLR terminates the session */
3443 GSUP.send(gsup_rsp);
3444 /* Expect RELEASE_COMPLETE message with the response */
3445 f_expect_mt_dtap_msg(ussd_rsp);
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003446
3447 /* Hold the call for some time */
3448 f_sleep(1.0);
3449
3450 /* Release the call (does Clear Complete itself) */
3451 f_call_hangup(cpars, true);
3452}
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003453testcase TC_lu_and_mo_ussd_during_mt_call() runs on MTC_CT {
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003454 var BSC_ConnHdlr vc_conn;
3455 f_init();
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003456 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_during_mt_call), 48);
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003457 vc_conn.done;
3458}
3459
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003460/* BSSMAP Clear Request in the middle of a call, see OS#3062 */
Harald Weltee13cfb22019-04-23 16:52:02 +02003461friend function f_tc_mo_cc_bssmap_clear(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003462 f_init_handler(pars);
3463 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02003464 cpars.ran_clear_when_alerting := true;
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003465
3466 f_perform_lu();
3467
Neels Hofmeyrde76f052019-02-26 05:02:46 +01003468 var default ccrel := activate(as_optional_cc_rel(cpars));
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02003469 f_mo_call_establish(cpars);
3470 f_expect_clear()
Neels Hofmeyrde76f052019-02-26 05:02:46 +01003471 deactivate(ccrel);
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003472
3473 f_sleep(1.0);
3474}
3475testcase TC_mo_cc_bssmap_clear() runs on MTC_CT {
3476 var BSC_ConnHdlr vc_conn;
3477 f_init();
3478
3479 vc_conn := f_start_handler(refers(f_tc_mo_cc_bssmap_clear), 43);
3480 vc_conn.done;
3481}
3482
Harald Weltee13cfb22019-04-23 16:52:02 +02003483
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003484/* LU followed by MT call and MT USSD request during this call */
Harald Weltee13cfb22019-04-23 16:52:02 +02003485friend function f_tc_lu_and_mt_ussd_during_mt_call(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003486runs on BSC_ConnHdlr {
3487 f_init_handler(pars);
3488
3489 /* Call parameters taken from f_tc_lu_and_mt_call */
3490 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003491
3492 /* Perform location update */
3493 f_perform_lu();
3494
3495 /* Establish a MT call */
3496 f_mt_call_establish(cpars);
3497
3498 /* Hold the call for some time */
3499 f_sleep(1.0);
3500
3501 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3502 op_code := SS_OP_CODE_USS_REQUEST,
3503 ussd_string := "Please type anything..."
3504 );
3505
3506 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
3507 op_code := SS_OP_CODE_USS_REQUEST,
3508 ussd_string := "Nope."
3509 )
3510
3511 /* Compose MT SS/REGISTER message with network-originated request */
3512 var template (value) PDU_ML3_NW_MS ussd_req := ts_ML3_MT_SS_REGISTER(
3513 tid := 0, /* FIXME: most likely, it should be 0 */
3514 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3515 facility := valueof(facility_req)
3516 );
3517
3518 /* Compose HLR -> MSC GSUP message */
3519 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
3520 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003521 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003522 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3523 ss := valueof(facility_req)
3524 );
3525
3526 /* Send it to MSC */
3527 GSUP.send(gsup_req);
3528 /* Expect MT REGISTER message with USSD request */
3529 f_expect_mt_dtap_msg(ussd_req);
3530
3531 /* Compose a new MO SS/FACILITY message with response */
3532 var template (value) PDU_ML3_MS_NW ussd_rsp := ts_ML3_MO_SS_FACILITY(
3533 tid := 0, /* FIXME: it shall match the request tid */
3534 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3535 facility := valueof(facility_rsp)
3536 );
3537
3538 /* Compose expected MSC -> HLR GSUP message */
3539 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_REQ(
3540 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003541 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003542 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
3543 ss := valueof(facility_rsp)
3544 );
3545
3546 /* MS sends response */
3547 BSSAP.send(ts_PDU_DTAP_MO(ussd_rsp));
3548 f_expect_gsup_msg(gsup_rsp);
3549
3550 /* Compose expected MT SS/RELEASE COMPLETE message */
3551 var template PDU_ML3_NW_MS ussd_term := tr_ML3_MT_SS_RELEASE_COMPLETE(
3552 tid := 0, /* FIXME: it shall match the request tid */
3553 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3554 facility := omit
3555 );
3556
3557 /* Compose MSC -> HLR GSUP message */
3558 var template GSUP_PDU gsup_term := ts_GSUP_PROC_SS_REQ(
3559 imsi := g_pars.imsi,
Vadim Yanitskiy2dd96612020-01-07 21:48:29 +01003560 sid := g_pars.gsup_sid,
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003561 state := OSMO_GSUP_SESSION_STATE_END
3562 );
3563
3564 /* Finally, HLR terminates the session */
3565 GSUP.send(gsup_term);
3566 /* Expect MT RELEASE COMPLETE without Facility IE */
3567 f_expect_mt_dtap_msg(ussd_term);
3568
3569 /* Hold the call for some time */
3570 f_sleep(1.0);
3571
3572 /* Release the call (does Clear Complete itself) */
3573 f_call_hangup(cpars, true);
3574}
3575testcase TC_lu_and_mt_ussd_during_mt_call() runs on MTC_CT {
3576 var BSC_ConnHdlr vc_conn;
3577 f_init();
3578 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_ussd_during_mt_call), 49);
3579 vc_conn.done;
3580}
3581
Harald Weltee13cfb22019-04-23 16:52:02 +02003582
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07003583/* LU followed by MO USSD request and MO Release during transaction */
Harald Weltee13cfb22019-04-23 16:52:02 +02003584friend function f_tc_lu_and_mo_ussd_mo_release(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07003585runs on BSC_ConnHdlr {
3586 f_init_handler(pars);
3587
3588 /* Perform location update */
3589 f_perform_lu();
3590
3591 /* Send CM Service Request for SS/USSD */
3592 f_establish_fully(EST_TYPE_SS_ACT);
3593
3594 /* We need to inspect GSUP activity */
3595 f_create_gsup_expect(hex2str(g_pars.imsi));
3596
3597 var template OCTN facility_ms_req := f_USSD_FACILITY_IE_INVOKE(
3598 invoke_id := 1, /* Initial request */
3599 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3600 ussd_string := "*6766*266#"
3601 );
3602
3603 var template OCTN facility_net_req := f_USSD_FACILITY_IE_INVOKE(
3604 invoke_id := 2, /* Counter request */
3605 op_code := SS_OP_CODE_USS_REQUEST,
3606 ussd_string := "Password?!?"
3607 )
3608
3609 /* Compose MO SS/REGISTER message with request */
3610 var template (value) PDU_ML3_MS_NW ussd_ms_req := ts_ML3_MO_SS_REGISTER(
3611 tid := 1, /* We just need a single transaction */
3612 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3613 facility := valueof(facility_ms_req)
3614 );
3615
3616 /* Compose expected MSC -> HLR message */
3617 var template GSUP_PDU gsup_ms_req := tr_GSUP_PROC_SS_REQ(
3618 imsi := g_pars.imsi,
3619 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3620 ss := valueof(facility_ms_req)
3621 );
3622
3623 /* To be used for sending response with correct session ID */
3624 var GSUP_PDU gsup_ms_req_complete;
3625
3626 /* Initiate a new transaction */
3627 BSSAP.send(ts_PDU_DTAP_MO(ussd_ms_req));
3628 /* Expect GSUP request with original Facility IE */
3629 gsup_ms_req_complete := f_expect_gsup_msg(gsup_ms_req);
3630
3631 /* Compose the response from HLR using received session ID */
3632 var template (value) GSUP_PDU gsup_net_req := ts_GSUP_PROC_SS_REQ(
3633 imsi := g_pars.imsi,
3634 sid := gsup_ms_req_complete.ies[1].val.session_id,
3635 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
3636 ss := valueof(facility_net_req)
3637 );
3638
3639 /* Compose expected MT SS/FACILITY template with counter request */
3640 var template PDU_ML3_NW_MS ussd_net_req := tr_ML3_MT_SS_FACILITY(
3641 tid := 1, /* Response should arrive within the same transaction */
3642 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3643 facility := valueof(facility_net_req)
3644 );
3645
3646 /* Send response over GSUP */
3647 GSUP.send(gsup_net_req);
3648 /* Expect MT SS/FACILITY message with counter request */
3649 f_expect_mt_dtap_msg(ussd_net_req);
3650
3651 /* Compose MO SS/RELEASE COMPLETE */
3652 var template (value) PDU_ML3_MS_NW ussd_abort := ts_ML3_MO_SS_RELEASE_COMPLETE(
3653 tid := 1, /* Response should arrive within the same transaction */
3654 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3655 facility := omit
3656 /* TODO: cause? */
3657 );
3658
3659 /* Compose expected HLR -> MSC abort message */
3660 var template GSUP_PDU gsup_abort := tr_GSUP_PROC_SS_REQ(
3661 imsi := g_pars.imsi,
3662 sid := gsup_ms_req_complete.ies[1].val.session_id,
3663 state := OSMO_GSUP_SESSION_STATE_END
3664 );
3665
3666 /* Abort transaction */
3667 BSSAP.send(ts_PDU_DTAP_MO(ussd_abort));
3668 /* Expect GSUP message indicating abort */
3669 f_expect_gsup_msg(gsup_abort);
3670
3671 f_expect_clear();
3672}
3673testcase TC_lu_and_mo_ussd_mo_release() runs on MTC_CT {
3674 var BSC_ConnHdlr vc_conn;
3675 f_init();
3676 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_mo_release), 50);
3677 vc_conn.done;
3678}
3679
Harald Weltee13cfb22019-04-23 16:52:02 +02003680
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003681/* LU followed by MO USSD request and MT Release due to timeout */
Harald Weltee13cfb22019-04-23 16:52:02 +02003682friend function f_tc_lu_and_ss_session_timeout(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003683runs on BSC_ConnHdlr {
3684 f_init_handler(pars);
3685
3686 /* Perform location update */
3687 f_perform_lu();
3688
3689 /* Send CM Service Request for SS/USSD */
3690 f_establish_fully(EST_TYPE_SS_ACT);
3691
3692 /* We need to inspect GSUP activity */
3693 f_create_gsup_expect(hex2str(g_pars.imsi));
3694
3695 var template OCTN facility_ms_req := f_USSD_FACILITY_IE_INVOKE(
3696 invoke_id := 1,
3697 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3698 ussd_string := "#release_me");
3699
3700 /* Compose MO SS/REGISTER message with request */
3701 var template (value) PDU_ML3_MS_NW ussd_ms_req := ts_ML3_MO_SS_REGISTER(
3702 tid := 1, /* An arbitrary transaction identifier */
3703 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3704 facility := valueof(facility_ms_req));
3705
3706 /* Compose expected MSC -> HLR message */
3707 var template GSUP_PDU gsup_ms_req := tr_GSUP_PROC_SS_REQ(
3708 imsi := g_pars.imsi,
3709 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3710 ss := valueof(facility_ms_req));
3711
3712 /* To be used for sending response with correct session ID */
3713 var GSUP_PDU gsup_ms_req_complete;
3714
3715 /* Initiate a new SS transaction */
3716 BSSAP.send(ts_PDU_DTAP_MO(ussd_ms_req));
3717 /* Expect GSUP request with original Facility IE */
3718 gsup_ms_req_complete := f_expect_gsup_msg(gsup_ms_req);
3719
3720 /* Don't respond, wait for timeout */
3721 f_sleep(3.0);
3722
3723 var template PDU_ML3_NW_MS dtap_rel := tr_ML3_MT_SS_RELEASE_COMPLETE(
3724 tid := 1, /* Should match the request's tid */
3725 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3726 cause := *, /* TODO: expect some specific value */
3727 facility := omit);
3728
3729 var template GSUP_PDU gsup_rel := tr_GSUP_PROC_SS_ERR(
3730 imsi := g_pars.imsi,
3731 sid := gsup_ms_req_complete.ies[1].val.session_id,
3732 state := OSMO_GSUP_SESSION_STATE_END,
3733 cause := ?); /* TODO: expect some specific value */
3734
3735 /* Expect release on both interfaces */
3736 interleave {
3737 [] BSSAP.receive(tr_PDU_DTAP_MT(dtap_rel)) { };
3738 [] GSUP.receive(gsup_rel) { };
3739 }
3740
3741 f_expect_clear();
3742 setverdict(pass);
3743}
3744testcase TC_lu_and_ss_session_timeout() runs on MTC_CT {
3745 var BSC_ConnHdlr vc_conn;
3746 f_init();
Vadim Yanitskiy36d28dd2018-12-03 02:45:45 +07003747 f_vty_config(MSCVTY, "msc", "ncss guard-timeout 3");
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003748 vc_conn := f_start_handler(refers(f_tc_lu_and_ss_session_timeout), 51);
3749 vc_conn.done;
Vadim Yanitskiy36d28dd2018-12-03 02:45:45 +07003750 f_vty_config(MSCVTY, "msc", "ncss guard-timeout 0");
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003751}
3752
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07003753/* MT (network-originated) USSD for unknown subscriber */
3754friend function f_tc_mt_ussd_for_unknown_subscr(charstring id, BSC_ConnHdlrPars pars)
3755runs on BSC_ConnHdlr {
3756 var hexstring imsi := '000000000000000'H; /* Some unknown IMSI */
3757 var OCT4 sid := '20000222'O;
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07003758
3759 f_init_handler(pars);
3760 f_ran_register_imsi(imsi, 'FFFFFFFF'O);
3761 f_create_gsup_expect(hex2str(imsi));
3762
3763 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
3764 imsi := imsi,
3765 sid := sid,
3766 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3767 ss := f_rnd_octstring(23)
3768 );
3769
3770 /* Error with cause GMM_CAUSE_IMSI_UNKNOWN */
3771 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_ERR(
3772 imsi := imsi,
3773 sid := sid,
3774 state := OSMO_GSUP_SESSION_STATE_END,
3775 cause := 2 /* FIXME: introduce an enumerated type! */
3776 );
3777
3778 /* Initiate a MT USSD notification */
3779 GSUP.send(gsup_req);
3780
3781 /* Expect GSUP PROC_SS_ERROR message */
Vadim Yanitskiy851798c2019-06-15 14:22:28 +07003782 f_expect_gsup_msg(gsup_rsp);
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07003783}
3784testcase TC_mt_ussd_for_unknown_subscr() runs on MTC_CT {
3785 var BSC_ConnHdlr vc_conn;
3786 f_init();
3787 vc_conn := f_start_handler(refers(f_tc_mt_ussd_for_unknown_subscr), 0);
3788 vc_conn.done;
3789}
3790
Vadim Yanitskiyc3c07d42019-06-17 23:00:44 +07003791/* MO (mobile-originated) SS/USSD for unknown transaction */
3792friend function f_tc_mo_ussd_for_unknown_trans(charstring id, BSC_ConnHdlrPars pars)
3793runs on BSC_ConnHdlr {
3794 f_init_handler(pars);
3795
Vadim Yanitskiy70d15bf2020-01-09 22:51:01 +01003796 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyc3c07d42019-06-17 23:00:44 +07003797 f_create_gsup_expect(hex2str(g_pars.imsi));
3798
3799 /* Perform location update */
3800 f_perform_lu();
3801
3802 /* Send CM Service Request for SS/USSD */
3803 f_establish_fully(EST_TYPE_SS_ACT);
3804
3805 /* GSM 04.80 FACILITY message for a non-existing transaction */
3806 var template (value) PDU_ML3_MS_NW mo_ss_fac := ts_ML3_MO_SS_FACILITY(
3807 tid := 1, /* An arbitrary transaction identifier */
3808 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3809 facility := f_rnd_octstring(23) /* We don't care about the Facility IE */
3810 );
3811
3812 /* GSM 04.80 RELEASE COMPLETE message for a non-existing transaction */
3813 var template (value) PDU_ML3_MS_NW mo_ss_rel := ts_ML3_MO_SS_RELEASE_COMPLETE(
3814 tid := 1, /* An arbitrary transaction identifier */
3815 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3816 facility := f_rnd_octstring(23) /* We don't care about the Facility IE */
3817 );
3818
3819 /* Expected response from the network */
3820 var template PDU_ML3_NW_MS mt_ss_rel := tr_ML3_MT_SS_RELEASE_COMPLETE(
3821 tid := 1, /* Same as in the FACILITY message */
3822 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3823 facility := omit
3824 );
3825
3826 /* Send GSM 04.80 FACILITY for non-existing transaction */
3827 BSSAP.send(ts_PDU_DTAP_MO(mo_ss_fac));
3828
3829 /* Expect GSM 04.80 RELEASE COMPLETE message */
3830 f_expect_mt_dtap_msg(mt_ss_rel);
3831 f_expect_clear();
3832
3833 /* Send another CM Service Request for SS/USSD */
3834 f_establish_fully(EST_TYPE_SS_ACT);
3835
3836 /* Send GSM 04.80 RELEASE COMPLETE for non-existing transaction */
3837 BSSAP.send(ts_PDU_DTAP_MO(mo_ss_rel));
3838
3839 /* Expect GSM 04.80 RELEASE COMPLETE message */
3840 f_expect_mt_dtap_msg(mt_ss_rel);
3841 f_expect_clear();
3842}
3843testcase TC_mo_ussd_for_unknown_trans() runs on MTC_CT {
3844 var BSC_ConnHdlr vc_conn;
3845 f_init();
3846 vc_conn := f_start_handler(refers(f_tc_mo_ussd_for_unknown_trans), 111);
3847 vc_conn.done;
3848}
3849
Vadim Yanitskiyd612d282019-06-15 14:46:03 +07003850/* MT (network-originated) USSD for unknown session */
3851friend function f_tc_proc_ss_for_unknown_session(charstring id, BSC_ConnHdlrPars pars)
3852runs on BSC_ConnHdlr {
3853 var OCT4 sid := '20000333'O;
3854
3855 f_init_handler(pars);
3856
3857 /* Perform location update */
3858 f_perform_lu();
3859
Vadim Yanitskiy70d15bf2020-01-09 22:51:01 +01003860 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyd612d282019-06-15 14:46:03 +07003861 f_create_gsup_expect(hex2str(g_pars.imsi));
3862
3863 /* Request referencing a non-existing SS session */
3864 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
3865 imsi := g_pars.imsi,
3866 sid := sid,
3867 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
3868 ss := f_rnd_octstring(23)
3869 );
3870
3871 /* Error with some cause value */
3872 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_ERR(
3873 imsi := g_pars.imsi,
3874 sid := sid,
3875 state := OSMO_GSUP_SESSION_STATE_END,
3876 cause := ? /* FIXME: introduce an enumerated type! */
3877 );
3878
3879 /* Initiate a MT USSD notification */
3880 GSUP.send(gsup_req);
3881
3882 /* Expect GSUP PROC_SS_ERROR message */
3883 f_expect_gsup_msg(gsup_rsp);
3884}
3885testcase TC_proc_ss_for_unknown_session() runs on MTC_CT {
3886 var BSC_ConnHdlr vc_conn;
3887 f_init();
3888 vc_conn := f_start_handler(refers(f_tc_proc_ss_for_unknown_session), 110);
3889 vc_conn.done;
3890}
3891
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003892/* MT (network-originated) USSD and no response to Paging Request */
3893friend function f_tc_proc_ss_paging_fail(charstring id, BSC_ConnHdlrPars pars)
3894runs on BSC_ConnHdlr {
3895 timer TP := 2.0; /* Paging timer */
3896
3897 f_init_handler(pars);
3898
3899 /* Perform location update */
3900 f_perform_lu();
3901
Vadim Yanitskiy70d15bf2020-01-09 22:51:01 +01003902 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003903 f_create_gsup_expect(hex2str(g_pars.imsi));
3904
3905 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
3906 imsi := g_pars.imsi,
3907 sid := '20000444'O,
3908 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3909 ss := f_rnd_octstring(23)
3910 );
3911
3912 /* Error with some cause value */
3913 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_ERR(
3914 imsi := g_pars.imsi,
3915 sid := '20000444'O,
3916 state := OSMO_GSUP_SESSION_STATE_END,
3917 cause := ? /* FIXME: introduce an enumerated type! */
3918 );
3919
3920 /* Initiate a MT USSD notification */
3921 GSUP.send(gsup_req);
3922
3923 /* Send it to MSC and expect Paging Request */
3924 TP.start;
3925 alt {
3926 [pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
3927 setverdict(pass);
3928 }
3929 [not pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
3930 setverdict(pass);
3931 }
3932 /* We don't expect anything else */
3933 [] as_unexp_gsup_or_bssap_msg();
3934 [] TP.timeout {
3935 setverdict(fail, "Timeout waiting for Paging Request");
3936 }
3937 }
3938
Vadim Yanitskiyd24b5252019-10-02 00:04:51 +07003939 /* Wait up to 20 seconds for GSUP PROC_SS_ERROR message.
3940 * OsmoMSC waits for Paging Response 10 seconds by default. */
3941 f_expect_gsup_msg(gsup_rsp, T_val := 20.0);
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07003942}
3943testcase TC_proc_ss_paging_fail() runs on MTC_CT {
3944 var BSC_ConnHdlr vc_conn;
3945 f_init();
3946 vc_conn := f_start_handler(refers(f_tc_proc_ss_paging_fail), 101);
3947 vc_conn.done;
3948}
3949
Vadim Yanitskiy29ba8d62019-06-16 15:19:41 +07003950/* MT (network-originated) USSD followed by immediate abort */
3951friend function f_tc_proc_ss_abort(charstring id, BSC_ConnHdlrPars pars)
3952runs on BSC_ConnHdlr {
3953 var octetstring facility := f_rnd_octstring(23);
3954 var OCT4 sid := '20000555'O;
3955 timer TP := 2.0;
3956
3957 f_init_handler(pars);
3958
3959 /* Perform location update */
3960 f_perform_lu();
3961
Vadim Yanitskiy70d15bf2020-01-09 22:51:01 +01003962 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy29ba8d62019-06-16 15:19:41 +07003963 f_create_gsup_expect(hex2str(g_pars.imsi));
3964
3965 /* PROC_SS_REQ initiates a mobile-originated SS/USSD session */
3966 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
3967 imsi := g_pars.imsi, sid := sid,
3968 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3969 ss := facility
3970 );
3971
3972 /* On the MS side, we expect GSM 04.80 REGISTER message */
3973 var template PDU_ML3_NW_MS dtap_reg := tr_ML3_MT_SS_REGISTER(
3974 tid := 0, /* Most likely, it should be 0 */
3975 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3976 facility := facility
3977 );
3978
3979 /* PROC_SS_ERR with SESSION_STATE_END terminates the SS/USSD session */
3980 var template (value) GSUP_PDU gsup_abort := ts_GSUP_PROC_SS_ERR(
3981 imsi := g_pars.imsi, sid := sid,
3982 state := OSMO_GSUP_SESSION_STATE_END,
3983 cause := 0 /* FIXME: introduce an enumerated type! */
3984 );
3985
3986 /* On the MS side, we expect GSM 04.80 REGISTER message */
3987 var template PDU_ML3_NW_MS dtap_rel := tr_ML3_MT_SS_RELEASE_COMPLETE(
3988 tid := 0, /* Most likely, it should be 0 */
3989 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3990 cause := *, /* FIXME: expect some specific cause value */
3991 facility := omit
3992 );
3993
3994 /* Initiate a MT USSD with random payload */
3995 GSUP.send(gsup_req);
3996
3997 /* Expect Paging Request */
3998 TP.start;
3999 alt {
4000 [pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
4001 setverdict(pass);
4002 }
4003 [not pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
4004 setverdict(pass);
4005 }
4006 /* We don't expect anything else */
4007 [] as_unexp_gsup_or_bssap_msg();
4008 [] TP.timeout {
4009 setverdict(fail, "Timeout waiting for Paging Request");
4010 }
4011 }
4012
4013 /* Send Paging Response and establish connection */
4014 f_establish_fully(EST_TYPE_PAG_RESP);
4015 /* Expect MT REGISTER message with random facility */
4016 f_expect_mt_dtap_msg(dtap_reg);
4017
4018 /* HLR/EUSE decides to abort the session even
4019 * before getting any response from the MS */
4020 /* Initiate a MT USSD with random payload */
4021 GSUP.send(gsup_abort);
4022
4023 /* Expect RELEASE COMPLETE on ths MS side */
4024 f_expect_mt_dtap_msg(dtap_rel);
4025
4026 f_expect_clear();
4027}
4028testcase TC_proc_ss_abort() runs on MTC_CT {
4029 var BSC_ConnHdlr vc_conn;
4030 f_init();
4031 vc_conn := f_start_handler(refers(f_tc_proc_ss_abort), 102);
4032 vc_conn.done;
4033}
4034
Harald Weltee13cfb22019-04-23 16:52:02 +02004035
Vadim Yanitskiy1c9754d2020-01-07 21:56:55 +01004036/* Verify multiple concurrent MO SS/USSD transactions
4037 * (one subscriber - one transaction) */
4038testcase TC_multi_lu_and_mo_ussd() runs on MTC_CT {
4039 var BSC_ConnHdlr vc_conn[16];
4040 var integer i;
4041
4042 f_init();
4043
4044 for (i := 0; i < sizeof(vc_conn); i := i + 1) {
4045 vc_conn[i] := f_start_handler(refers(f_tc_lu_and_mo_ussd_single_request), 210 + i);
4046 }
4047
4048 for (i := 0; i < sizeof(vc_conn); i := i + 1) {
4049 vc_conn[i].done;
4050 }
4051}
4052
4053/* Verify multiple concurrent MT SS/USSD transactions
4054 * (one subscriber - one transaction) */
4055testcase TC_multi_lu_and_mt_ussd() runs on MTC_CT {
4056 var BSC_ConnHdlr vc_conn[16];
4057 var integer i;
4058 var OCT4 sid;
4059
4060 f_init();
4061
4062 for (i := 0; i < sizeof(vc_conn); i := i + 1) {
4063 sid := '200001'O & int2oct(i, 1); /* All transactions must use different session ID */
4064 vc_conn[i] := f_start_handler_with_pars(refers(f_tc_lu_and_mt_ussd_notification),
4065 f_init_pars(226 + i, gsup_sid := sid));
4066 }
4067
4068 for (i := 0; i < sizeof(vc_conn); i := i + 1) {
4069 vc_conn[i].done;
4070 }
4071}
4072
4073
Stefan Sperling89eb1f32018-12-17 15:06:20 +01004074/* A5/1 only permitted on network side; attempt an invalid CIPHER MODE COMPLETE with A5/3 which MSC should reject. */
4075private function f_tc_cipher_complete_with_invalid_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4076 pars.net.expect_auth := true;
4077 pars.net.expect_ciph := true;
4078 pars.net.kc_support := '02'O; /* A5/1 only */
4079 f_init_handler(pars);
4080
4081 g_pars.vec := f_gen_auth_vec_2g();
4082
4083 /* Can't use f_perform_lu() directly. Code below is based on it. */
4084
4085 /* tell GSUP dispatcher to send this IMSI to us */
4086 f_create_gsup_expect(hex2str(g_pars.imsi));
4087
4088 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
4089 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
Harald Weltedceacc72019-04-21 20:58:35 +02004090 f_cl3_or_initial_ue(l3_lu);
Stefan Sperling89eb1f32018-12-17 15:06:20 +01004091
4092 f_mm_auth();
4093
4094 var OCT1 a5_net := f_alg_mask_from_cm(g_pars.cm2);
4095 var OCT1 a5_intersect := g_pars.net.kc_support and4b a5_net;
4096 alt {
4097 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(a5_intersect, g_pars.vec.kc)) {
4098 BSSAP.send(ts_BSSMAP_CipherModeCompl(int2oct(4 /* "accept" A5/3 */, 1)));
4099 }
4100 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc)) {
4101 setverdict(fail, "Wrong ciphering algorithm mask in CiphModCmd");
4102 mtc.stop;
4103 }
4104 [] BSSAP.receive {
4105 setverdict(fail, "Unknown/unexpected BSSAP received");
4106 mtc.stop;
4107 }
4108 }
Harald Welte79f1e452020-08-18 22:55:02 +02004109 f_expect_common_id();
Stefan Sperling89eb1f32018-12-17 15:06:20 +01004110
4111 /* Expect LU reject from MSC. */
4112 alt {
4113 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
4114 setverdict(pass);
4115 }
4116 [] BSSAP.receive {
4117 setverdict(fail, "Unknown/unexpected BSSAP received");
4118 mtc.stop;
4119 }
4120 }
Stefan Sperlingc620b352018-12-18 17:23:36 +01004121 f_expect_clear();
Stefan Sperling89eb1f32018-12-17 15:06:20 +01004122}
4123
4124testcase TC_cipher_complete_with_invalid_cipher() runs on MTC_CT {
4125 var BSC_ConnHdlr vc_conn;
4126 f_init();
4127 f_vty_config(MSCVTY, "network", "encryption a5 1");
4128
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02004129 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 +01004130 vc_conn.done;
4131}
4132
Harald Welteb2284bd2019-05-10 11:30:43 +02004133/* Location Update with invalid (non-matching) MCC/MNC reported on BSSMAP level from BSC */
4134friend function f_tc_lu_with_invalid_mcc_mnc(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4135 f_init_handler(pars);
4136
4137 /* tell GSUP dispatcher to send this IMSI to us */
4138 f_create_gsup_expect(hex2str(g_pars.imsi));
4139
4140 /* modify the cell ID which will be used to construct the COMPLELTE L3 or InitialUE */
4141 g_pars.cell_id := valueof(ts_CellId_CGI('333'H, '22'H, 23, 42));
4142
4143 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
4144 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
4145 f_cl3_or_initial_ue(l3_lu);
Harald Welte79f1e452020-08-18 22:55:02 +02004146 f_expect_common_id();
Harald Welteb2284bd2019-05-10 11:30:43 +02004147
4148 /* Expect LU reject from MSC. */
4149 alt {
4150 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
4151 setverdict(pass);
4152 }
4153 [] BSSAP.receive {
4154 setverdict(fail, "Unknown/unexpected BSSAP received");
4155 mtc.stop;
4156 }
4157 }
4158 f_expect_clear();
4159}
4160testcase TC_lu_with_invalid_mcc_mnc() runs on MTC_CT {
4161 var BSC_ConnHdlr vc_conn;
4162 f_init();
4163 vc_conn := f_start_handler(refers(f_tc_lu_with_invalid_mcc_mnc), 54);
4164 vc_conn.done;
4165}
4166
Stefan Sperlinga2d59c62018-12-18 16:32:44 +01004167private function f_tc_cipher_complete_without_alg(charstring id, BSC_ConnHdlrPars pars, octetstring kc_support) runs on BSC_ConnHdlr {
4168 pars.net.expect_auth := true;
4169 pars.net.expect_ciph := true;
4170 pars.net.kc_support := kc_support;
4171 f_init_handler(pars);
4172
4173 g_pars.vec := f_gen_auth_vec_2g();
4174
4175 /* Can't use f_perform_lu() directly. Code below is based on it. */
4176
4177 /* tell GSUP dispatcher to send this IMSI to us */
4178 f_create_gsup_expect(hex2str(g_pars.imsi));
4179
4180 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
4181 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
4182 f_cl3_or_initial_ue(l3_lu);
4183
4184 f_mm_auth();
4185
4186 var OCT1 a5_net := f_alg_mask_from_cm(g_pars.cm2);
4187 var OCT1 a5_intersect := g_pars.net.kc_support and4b a5_net;
4188 alt {
4189 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(a5_intersect, g_pars.vec.kc)) {
4190 BSSAP.send(ts_BSSMAP_CipherModeComplAlg(omit));
4191 }
4192 [] BSSAP.receive(tr_BSSMAP_ClassmarkReq) {
4193 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
4194 repeat;
4195 }
4196 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc)) {
4197 setverdict(fail, "Wrong ciphering algorithm mask in CiphModCmd");
4198 mtc.stop;
4199 }
4200 [] BSSAP.receive {
4201 setverdict(fail, "Unknown/unexpected BSSAP received");
4202 mtc.stop;
4203 }
4204 }
Harald Welte79f1e452020-08-18 22:55:02 +02004205 f_expect_common_id();
Stefan Sperlinga2d59c62018-12-18 16:32:44 +01004206
4207 /* TODO: Verify MSC is using the best cipher available! How? */
4208
4209 f_msc_lu_hlr();
4210 f_accept_reject_lu();
4211 f_expect_clear();
4212 setverdict(pass);
4213}
4214
4215/* A5/1 only permitted on network side; attempt CIPHER MODE COMPLETE without specifying the accepted algorithm. */
4216private function f_tc_cipher_complete_1_without_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4217 f_tc_cipher_complete_without_alg(id, pars, '02'O /* A5/1 only */);
4218}
4219
4220/* A5/3 only permitted on network side; attempt CIPHER MODE COMPLETE without specifying the accepted algorithm. */
4221private function f_tc_cipher_complete_3_without_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4222 f_tc_cipher_complete_without_alg(id, pars, '08'O /* A5/3 only */);
4223}
4224
4225/* A5/1 + A5/3 permitted on network side; attempt CIPHER MODE COMPLETE without specifying the accepted algorithm. */
4226private function f_tc_cipher_complete_13_without_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4227 f_tc_cipher_complete_without_alg(id, pars, '0A'O /* A5/1 and A5/3 enabled */);
4228}
4229
4230testcase TC_cipher_complete_1_without_cipher() runs on MTC_CT {
4231 var BSC_ConnHdlr vc_conn;
4232 f_init();
4233 f_vty_config(MSCVTY, "network", "encryption a5 1");
4234
4235 vc_conn := f_start_handler(refers(f_tc_cipher_complete_1_without_cipher), 53);
4236 vc_conn.done;
4237}
4238
4239testcase TC_cipher_complete_3_without_cipher() runs on MTC_CT {
4240 var BSC_ConnHdlr vc_conn;
4241 f_init();
4242 f_vty_config(MSCVTY, "network", "encryption a5 3");
4243
4244 vc_conn := f_start_handler(refers(f_tc_cipher_complete_3_without_cipher), 54);
4245 vc_conn.done;
4246}
4247
4248testcase TC_cipher_complete_13_without_cipher() runs on MTC_CT {
4249 var BSC_ConnHdlr vc_conn;
4250 f_init();
4251 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
4252
4253 vc_conn := f_start_handler(refers(f_tc_cipher_complete_13_without_cipher), 55);
4254 vc_conn.done;
4255}
Harald Welteb2284bd2019-05-10 11:30:43 +02004256
Harald Weltef640a012018-04-14 17:49:21 +02004257/* TODO (SMS):
4258 * different user data lengths
4259 * SMPP transaction mode with unsuccessful delivery
4260 * queued MT-SMS with no paging response + later delivery
4261 * different data coding schemes
4262 * multi-part SMS
4263 * user-data headers
4264 * TP-PID for SMS to SIM
4265 * behavior if SMS memory is full + RP-SMMA
4266 * delivery reports
4267 * SMPP osmocom extensions
4268 * more-messages-to-send
4269 * SMS during ongoing call (SACCH/SAPI3)
4270 */
4271
4272/* TODO (General):
Harald Welteba7b6d92018-01-23 21:32:34 +01004273 * continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
4274 * malformed messages (missing IE, invalid message type): properly rejected?
4275 * MT call while LU or is ongoing: Do we use existing lchan or page while lchan active?
4276 * 3G/2G auth permutations
4277 * encryption algorithms vs. classmark vs. vty config
Harald Welteba7b6d92018-01-23 21:32:34 +01004278 * send new transaction after/during clear (like SMS, ...)
Harald Welte45164da2018-01-24 12:51:27 +01004279 * too long L3 INFO in DTAP
4280 * too long / padded BSSAP
4281 * too long / short TLV values
Harald Welteba7b6d92018-01-23 21:32:34 +01004282 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01004283
Harald Weltee13cfb22019-04-23 16:52:02 +02004284/***********************************************************************
4285 * SGsAP Testing
4286 ***********************************************************************/
4287
Philipp Maier948747b2019-04-02 15:22:33 +02004288/* Check if a subscriber exists in the VLR */
4289private function f_ctrl_subscr_in_vlr(charstring imsi_or_msisdn) runs on BSC_ConnHdlr return boolean {
4290
4291 var CtrlValue active_subsribers;
4292 var integer rc;
4293 active_subsribers := f_ctrl_get(IPA_CTRL, "subscriber-list-active-v1");
4294
4295 rc := f_strstr(active_subsribers, imsi_or_msisdn);
4296 if (rc < 0) {
4297 return false;
4298 }
4299
4300 return true;
4301}
4302
Harald Welte4263c522018-12-06 11:56:27 +01004303/* Perform a location updatye at the A-Interface and run some checks to confirm
4304 * that everything is back to normal. */
4305private function f_sgsap_bssmap_screening() runs on BSC_ConnHdlr {
4306 var SmsParameters spars := valueof(t_SmsPars);
4307
4308 /* Perform a location update, the SGs association is expected to fall
4309 * back to NULL */
4310 f_perform_lu();
4311 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4312
4313 /* Trigger a paging request and expect the paging on BSSMAP, this is
4314 * to make sure that pagings are sent throught the A-Interface again
4315 * and not throught the SGs interface.*/
Harald Welte6811d102019-04-14 22:23:14 +02004316 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Harald Welte4263c522018-12-06 11:56:27 +01004317 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4318
4319 alt {
Harald Weltee13cfb22019-04-23 16:52:02 +02004320 [g_pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)); {
4321 setverdict(pass);
4322 }
Harald Welte62113fc2019-05-09 13:04:02 +02004323 [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 +01004324 setverdict(pass);
4325 }
4326 [] SGsAP.receive {
4327 setverdict(fail, "Received unexpected message on SGs");
4328 }
4329 }
4330
4331 /* Send an SMS to make sure that also payload messages are routed
4332 * throught the A-Interface again */
4333 f_establish_fully(EST_TYPE_MO_SMS);
4334 f_mo_sms(spars);
4335 f_expect_clear();
4336}
4337
4338private function f_tc_sgsap_reset(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4339 var charstring vlr_name;
4340 f_init_handler(pars);
4341
4342 vlr_name := f_sgsap_reset_mme(mp_mme_name);
4343 log("VLR name: ", vlr_name);
4344 setverdict(pass);
Neels Hofmeyrc0b520d2019-03-06 15:35:50 +01004345 f_sleep(1.0);
Harald Welte4263c522018-12-06 11:56:27 +01004346}
4347
4348testcase TC_sgsap_reset() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004349 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004350 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004351 f_init(1, true);
4352 pars := f_init_pars(11810, true);
4353 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_reset), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004354 vc_conn.done;
4355}
4356
4357/* like f_mm_auth() but for SGs */
4358function f_mm_auth_sgs() runs on BSC_ConnHdlr {
4359 if (g_pars.net.expect_auth) {
4360 g_pars.vec := f_gen_auth_vec_3g();
4361 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
4362 g_pars.vec.sres,
4363 g_pars.vec.kc,
4364 g_pars.vec.ik,
4365 g_pars.vec.ck,
4366 g_pars.vec.autn,
4367 g_pars.vec.res));
4368 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
4369 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
4370 SGsAP.receive(tr_ML3_MT_MM_AUTH_REQ_3G(g_pars.vec.rand, g_pars.vec.autn));
4371 SGsAP.send(ts_ML3_MT_MM_AUTH_RESP_3G(g_pars.vec.sres, g_pars.vec.res));
4372 }
4373}
4374
4375/* like f_perform_lu(), but on SGs rather than BSSAP */
4376function f_sgs_perform_lu() runs on BSC_ConnHdlr {
4377 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4378 var PDU_SGsAP lur;
4379 var PDU_SGsAP lua;
4380 var PDU_SGsAP mm_info;
4381 var octetstring mm_info_dtap;
4382
4383 /* tell GSUP dispatcher to send this IMSI to us */
4384 f_create_gsup_expect(hex2str(g_pars.imsi));
4385
4386 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
4387 ts_SGsAP_LAI('901'H, '70'H, 2342)));
4388 /* Old LAI, if MS sends it */
4389 /* TMSI status, if MS has no valid TMSI */
4390 /* IMEISV, if it supports "automatic device detection" */
4391 /* TAI, if available in MME */
4392 /* E-CGI, if available in MME */
4393 SGsAP.send(lur);
4394
4395 /* FIXME: is this really done over SGs? The Ue is already authenticated
4396 * via the MME ... */
4397 f_mm_auth_sgs();
4398
4399 /* Expect MSC to perform LU with HLR */
4400 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
4401 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
4402 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
4403 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
4404
4405 alt {
4406 [] SGsAP.receive(tr_SGsAP_LU_ACCEPT(g_pars.imsi, ?)) -> value lua {
4407 if (isvalue(lua.sGsAP_LOCATION_UPDATE_ACCEPT.newTMSIorIMSI.iD.iD.tmsi_ptmsi.octets)) {
4408 g_pars.tmsi :=lua.sGsAP_LOCATION_UPDATE_ACCEPT.newTMSIorIMSI.iD.iD.tmsi_ptmsi.octets
4409 SGsAP.send(ts_SGsAP_TMSI_REALL_CMPL(g_pars.imsi));
4410 }
4411 setverdict(pass);
4412 }
4413 [] SGsAP.receive(tr_SGsAP_LU_REJECT(g_pars.imsi, ?, ?)) {
4414 setverdict(fail, "Received LU-REJECT instead of ACCEPT");
4415 }
4416 [] SGsAP.receive {
4417 setverdict(fail, "Received unexpected message on SGs");
4418 }
4419 }
4420
4421 /* Check MM information */
4422 if (mp_mm_info == true) {
4423 SGsAP.receive(tr_SGsAP_MM_INFO_REQ(g_pars.imsi, ?)) -> value mm_info;
4424 mm_info_dtap := '0532'O & mm_info.sGsAP_MM_INFORMATION_REQUEST.mM_Information.information;
4425 if (not match(dec_PDU_ML3_NW_MS(mm_info_dtap), tr_ML3_MT_MM_Info)) {
4426 setverdict(fail, "Unexpected MM Information");
4427 }
4428 }
4429
4430 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4431}
4432
4433private function f_tc_sgsap_lu(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4434 f_init_handler(pars);
4435 f_sgs_perform_lu();
4436 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4437
4438 f_sgsap_bssmap_screening();
4439
4440 setverdict(pass);
4441}
4442testcase TC_sgsap_lu() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004443 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004444 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004445 f_init(1, true);
4446 pars := f_init_pars(11811, true);
4447 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004448 vc_conn.done;
4449}
4450
4451/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
4452private function f_tc_sgsap_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4453 f_init_handler(pars);
4454 var PDU_SGsAP lur;
4455
4456 f_create_gsup_expect(hex2str(g_pars.imsi));
4457 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4458 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
4459 ts_SGsAP_LAI('901'H, '70'H, 2342)));
4460 SGsAP.send(lur);
4461
4462 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
4463 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
4464 alt {
4465 [] SGsAP.receive(tr_SGsAP_LU_REJECT(g_pars.imsi, ?, ?)) {
4466 setverdict(pass);
4467 }
4468 [] SGsAP.receive(tr_SGsAP_LU_ACCEPT(g_pars.imsi, ?)) {
4469 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
4470 mtc.stop;
4471 }
4472 [] SGsAP.receive {
4473 setverdict(fail, "Received unexpected message on SGs");
4474 }
4475 }
4476
4477 f_sgsap_bssmap_screening();
4478
4479 setverdict(pass);
4480}
4481testcase TC_sgsap_lu_imsi_reject() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004482 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004483 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004484 f_init(1, true);
4485 pars := f_init_pars(11812, true);
Harald Welte4263c522018-12-06 11:56:27 +01004486
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004487 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu_imsi_reject), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004488 vc_conn.done;
4489}
4490
4491/* Do LU by IMSI, but then remain silent so that Ts6-1 times out */
4492private function f_tc_sgsap_lu_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4493 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4494 var PDU_SGsAP lur;
4495
4496 f_init_handler(pars);
4497
4498 /* tell GSUP dispatcher to send this IMSI to us */
4499 f_create_gsup_expect(hex2str(g_pars.imsi));
4500
4501 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
4502 ts_SGsAP_LAI('901'H, '70'H, 2342)));
4503 /* Old LAI, if MS sends it */
4504 /* TMSI status, if MS has no valid TMSI */
4505 /* IMEISV, if it supports "automatic device detection" */
4506 /* TAI, if available in MME */
4507 /* E-CGI, if available in MME */
4508 SGsAP.send(lur);
4509
4510 /* FIXME: is this really done over SGs? The Ue is already authenticated
4511 * via the MME ... */
4512 f_mm_auth_sgs();
4513
4514 /* Expect MSC to perform LU with HLR */
4515 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
4516 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
4517 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
4518 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
4519
4520 alt {
4521 [] SGsAP.receive(tr_SGsAP_LU_ACCEPT(g_pars.imsi, ?)) {
4522 setverdict(pass);
4523 }
4524 [] SGsAP.receive(tr_SGsAP_LU_REJECT(g_pars.imsi, ?, ?)) {
4525 setverdict(fail, "Received LU-REJECT instead of ACCEPT");
4526 }
4527 [] SGsAP.receive {
4528 setverdict(fail, "Received unexpected message on SGs");
4529 }
4530 }
4531
4532 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4533
4534 /* Wait until the VLR has abort the TMSI reallocation procedure */
4535 f_sleep(45.0);
4536
4537 /* The outcome does not change the SGs state, see also 5.2.3.4 */
4538 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4539
4540 f_sgsap_bssmap_screening();
4541
4542 setverdict(pass);
4543}
4544testcase TC_sgsap_lu_and_nothing() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004545 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004546 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004547 f_init(1, true);
4548 pars := f_init_pars(11813, true);
Harald Welte4263c522018-12-06 11:56:27 +01004549
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004550 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu_and_nothing), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004551 vc_conn.done;
4552}
4553
4554private function f_tc_sgsap_expl_imsi_det_eps(charstring id, BSC_ConnHdlrPars pars)
4555runs on BSC_ConnHdlr {
4556 f_init_handler(pars);
4557 f_sgs_perform_lu();
4558 f_sleep(3.0);
4559
4560 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4561 SGsAP.send(ts_SGsAP_EPS_DETACH_IND(g_pars.imsi, mme_name, UE_initiated));
4562 SGsAP.receive(tr_SGsAP_EPS_DETACH_ACK(g_pars.imsi));
4563 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4564
4565 f_sgsap_bssmap_screening();
4566
4567 setverdict(pass);
4568}
4569testcase TC_sgsap_expl_imsi_det_eps() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004570 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004571 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004572 f_init(1, true);
4573 pars := f_init_pars(11814, true);
4574 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_expl_imsi_det_eps), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004575 vc_conn.done;
4576}
4577
Philipp Maierfc19f172019-03-21 11:17:54 +01004578private function f_tc_sgsap_impl_imsi_det_eps(charstring id, BSC_ConnHdlrPars pars)
4579runs on BSC_ConnHdlr {
4580 f_init_handler(pars);
4581 f_sgs_perform_lu();
4582 f_sleep(3.0);
4583
4584 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4585 SGsAP.send(ts_SGsAP_EPS_DETACH_IND(g_pars.imsi, mme_name, network_initiated));
4586 SGsAP.receive(tr_SGsAP_EPS_DETACH_ACK(g_pars.imsi));
4587 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4588
4589 f_sgsap_bssmap_screening();
4590
4591 setverdict(pass);
4592}
4593testcase TC_sgsap_impl_imsi_det_eps() runs on MTC_CT {
4594 var BSC_ConnHdlrPars pars;
4595 var BSC_ConnHdlr vc_conn;
4596 f_init(1, true);
4597 pars := f_init_pars(11814, true);
4598 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_impl_imsi_det_eps), pars);
4599 vc_conn.done;
4600}
4601
Harald Welte4263c522018-12-06 11:56:27 +01004602private function f_tc_sgsap_expl_imsi_det_noneps(charstring id, BSC_ConnHdlrPars pars)
4603runs on BSC_ConnHdlr {
4604 f_init_handler(pars);
4605 f_sgs_perform_lu();
4606 f_sleep(3.0);
4607
4608 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4609 SGsAP.send(ts_SGsAP_IMSI_DETACH_IND(g_pars.imsi, mme_name, combined_UE_initiated));
4610 SGsAP.receive(tr_SGsAP_IMSI_DETACH_ACK(g_pars.imsi));
Philipp Maierd08e7e72019-04-02 15:27:10 +02004611
4612 if (f_ctrl_subscr_in_vlr(hex2str(g_pars.imsi))) {
4613 setverdict(fail, "subscriber not removed from VLR");
4614 }
Harald Welte4263c522018-12-06 11:56:27 +01004615
4616 f_sgsap_bssmap_screening();
4617
4618 setverdict(pass);
4619}
4620testcase TC_sgsap_expl_imsi_det_noneps() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004621 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004622 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004623 f_init(1, true);
4624 pars := f_init_pars(11815, true);
4625 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_expl_imsi_det_noneps), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004626 vc_conn.done;
4627}
4628
Philipp Maier5d812702019-03-21 10:51:26 +01004629private function f_tc_sgsap_impl_imsi_det_noneps(charstring id, BSC_ConnHdlrPars pars)
4630runs on BSC_ConnHdlr {
4631 f_init_handler(pars);
4632 f_sgs_perform_lu();
4633 f_sleep(3.0);
4634
4635 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4636 SGsAP.send(ts_SGsAP_IMSI_DETACH_IND(g_pars.imsi, mme_name, implicit_network_initiated));
4637 SGsAP.receive(tr_SGsAP_IMSI_DETACH_ACK(g_pars.imsi));
4638
4639 if (f_ctrl_subscr_in_vlr(hex2str(g_pars.imsi))) {
4640 setverdict(fail, "subscriber not removed from VLR");
4641 }
4642
4643 f_sgsap_bssmap_screening();
4644
4645 setverdict(pass);
4646}
4647testcase TC_sgsap_impl_imsi_det_noneps() runs on MTC_CT {
4648 var BSC_ConnHdlrPars pars;
4649 var BSC_ConnHdlr vc_conn;
4650 f_init(1, true);
4651 pars := f_init_pars(11815, true);
4652 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_impl_imsi_det_noneps), pars);
4653 vc_conn.done;
4654}
4655
Harald Welte4263c522018-12-06 11:56:27 +01004656/* Trigger a paging request via VTY and send a paging reject in response */
4657private function f_tc_sgsap_paging_rej(charstring id, BSC_ConnHdlrPars pars)
4658runs on BSC_ConnHdlr {
4659 f_init_handler(pars);
4660 f_sgs_perform_lu();
4661 f_sleep(1.0);
4662
4663 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4664 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
4665 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4666 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4667
4668 /* Initiate paging via VTY */
4669 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4670 alt {
4671 [] SGsAP.receive(exp_resp) {
4672 setverdict(pass);
4673 }
4674 [] SGsAP.receive {
4675 setverdict(fail, "Received unexpected message on SGs");
4676 }
4677 }
4678
4679 /* Now reject the paging */
4680 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, IMSI_unknown));
4681
4682 /* Wait for the states inside the MSC to settle and check the state
4683 * of the SGs Association */
4684 f_sleep(1.0);
4685 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4686
4687 /* FIXME: At the moment we send an IMSI_unknown as cause code, which is fine,
4688 * but we also need to cover tha case where the cause code indicates an
4689 * "IMSI detached for EPS services". In those cases the VLR is expected to
4690 * try paging on tha A/Iu interface. This will be another testcase similar to
4691 * this one, but extended with checks for the presence of the A/Iu paging
4692 * messages. */
4693
4694 f_sgsap_bssmap_screening();
4695
4696 setverdict(pass);
4697}
4698testcase TC_sgsap_paging_rej() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004699 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004700 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004701 f_init(1, true);
4702 pars := f_init_pars(11816, true);
4703 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_rej), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004704 vc_conn.done;
4705}
4706
4707/* Trigger a paging request via VTY and send a paging reject that indicates
4708 * that the subscriber intentionally rejected the call. */
4709private function f_tc_sgsap_paging_subscr_rej(charstring id, BSC_ConnHdlrPars pars)
4710runs on BSC_ConnHdlr {
4711 f_init_handler(pars);
4712 f_sgs_perform_lu();
4713 f_sleep(1.0);
4714
4715 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4716 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
4717 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4718 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4719
4720 /* Initiate paging via VTY */
4721 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4722 alt {
4723 [] SGsAP.receive(exp_resp) {
4724 setverdict(pass);
4725 }
4726 [] SGsAP.receive {
4727 setverdict(fail, "Received unexpected message on SGs");
4728 }
4729 }
4730
4731 /* Now reject the paging */
4732 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, user_rejected_mobile_terminating_CS_fallback_call));
4733
4734 /* Wait for the states inside the MSC to settle and check the state
4735 * of the SGs Association */
4736 f_sleep(1.0);
4737 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4738
4739 /* FIXME: The VLR is supposed to trigger an User Determined User Busy (UDUB) as specified
4740 * in 3GPP TS 24.082, this is not yet implemented in the MSC or in this tests, we need
4741 * to check back how this works and how it can be tested */
4742
4743 f_sgsap_bssmap_screening();
4744
4745 setverdict(pass);
4746}
4747testcase TC_sgsap_paging_subscr_rej() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004748 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004749 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004750 f_init(1, true);
4751 pars := f_init_pars(11817, true);
4752 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_subscr_rej), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004753 vc_conn.done;
4754}
4755
4756/* Trigger a paging request via VTY and send an UE unreacable messge in response */
4757private function f_tc_sgsap_paging_ue_unr(charstring id, BSC_ConnHdlrPars pars)
4758runs on BSC_ConnHdlr {
4759 f_init_handler(pars);
4760 f_sgs_perform_lu();
4761 f_sleep(1.0);
4762
4763 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4764 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
4765 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4766 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4767
4768 /* Initiate paging via VTY */
4769 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4770 alt {
4771 [] SGsAP.receive(exp_resp) {
4772 setverdict(pass);
4773 }
4774 [] SGsAP.receive {
4775 setverdict(fail, "Received unexpected message on SGs");
4776 }
4777 }
4778
4779 /* Now pretend that the UE is unreachable */
4780 SGsAP.send(ts_SGsAP_UE_UNREACHABLE(g_pars.imsi, UE_unreachable));
4781
4782 /* Wait for the states inside the MSC to settle and check the state
4783 * of the SGs Association. */
4784 f_sleep(1.0);
4785 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4786
4787 f_sgsap_bssmap_screening();
4788
4789 setverdict(pass);
4790}
4791testcase TC_sgsap_paging_ue_unr() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004792 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004793 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004794 f_init(1, true);
4795 pars := f_init_pars(11818, true);
4796 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_ue_unr), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004797 vc_conn.done;
4798}
4799
4800/* Trigger a paging request via VTY but don't respond to it */
4801private function f_tc_sgsap_paging_and_nothing(charstring id, BSC_ConnHdlrPars pars)
4802runs on BSC_ConnHdlr {
4803 f_init_handler(pars);
4804 f_sgs_perform_lu();
4805 f_sleep(1.0);
4806
4807 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4808 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 +02004809 var template PDU_SGsAP exp_serv_abrt := ts_SGsAP_SERVICE_ABORT_REQ(g_pars.imsi);
Harald Welte4263c522018-12-06 11:56:27 +01004810 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4811 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4812
4813 /* Initiate paging via VTY */
4814 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4815 alt {
4816 [] SGsAP.receive(exp_resp) {
4817 setverdict(pass);
4818 }
4819 [] SGsAP.receive {
4820 setverdict(fail, "Received unexpected message on SGs");
4821 }
4822 }
4823
Philipp Maier34218102019-09-24 09:15:49 +02004824 /* While we are doing nothing, expect an SGsAP-SERVICE-ABORT-REQUEST
4825 * after some time */
4826 timer T := 10.0;
4827 T.start
4828 alt {
4829 [] SGsAP.receive(exp_serv_abrt)
4830 {
4831 setverdict(pass);
4832 }
4833 [] SGsAP.receive {
4834 setverdict(fail, "unexpected SGsAP message received");
4835 self.stop;
4836 }
4837 [] T.timeout {
4838 setverdict(fail, "MSC did not send SGsAP-SERVICE-ABORT-REQUEST");
4839 self.stop;
4840 }
4841 }
4842
4843 /* The SGs association must remain unchanged. */
Harald Welte4263c522018-12-06 11:56:27 +01004844 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4845
4846 f_sgsap_bssmap_screening();
4847
4848 setverdict(pass);
4849}
4850testcase TC_sgsap_paging_and_nothing() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004851 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004852 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004853 f_init(1, true);
4854 pars := f_init_pars(11819, true);
4855 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_and_nothing), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004856 vc_conn.done;
4857}
4858
4859/* Trigger a paging request via VTY and slip in an LU */
4860private function f_tc_sgsap_paging_and_lu(charstring id, BSC_ConnHdlrPars pars)
4861runs on BSC_ConnHdlr {
4862 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4863 f_init_handler(pars);
4864
4865 /* First we prepar the situation, where the SGs association is in state
4866 * NULL and the confirmed by radio contact indicator is set to false
4867 * as well. This can be archived by performing an SGs LU and then
4868 * resetting the VLR */
4869 f_sgs_perform_lu();
4870 f_sgsap_reset_mme(mp_mme_name);
4871 f_sleep(1.0);
4872 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4873
4874 /* Perform a paging, expect the paging messages on the SGs interface */
4875 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4876 alt {
4877 [] SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit)) {
4878 setverdict(pass);
4879 }
4880 [] SGsAP.receive {
4881 setverdict(fail, "Received unexpected message on SGs");
4882 }
4883 }
4884
4885 /* Perform the LU as normal */
4886 f_sgs_perform_lu();
4887 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4888
4889 /* Expect a new paging request right after the LU */
4890 alt {
4891 [] SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit)) {
4892 setverdict(pass);
4893 }
4894 [] SGsAP.receive {
4895 setverdict(fail, "Received unexpected message on SGs");
4896 }
4897 }
4898
4899 /* Test is done now, lets round everything up by rejecting the paging
4900 * cleanly. */
4901 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, user_rejected_mobile_terminating_CS_fallback_call));
4902 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4903
4904 f_sgsap_bssmap_screening();
4905
4906 setverdict(pass);
4907}
4908testcase TC_sgsap_paging_and_lu() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004909 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004910 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004911 f_init(1, true);
4912 pars := f_init_pars(11820, true);
4913 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_and_lu), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004914 vc_conn.done;
4915}
4916
4917/* Send unexpected unit-data through the SGs interface */
4918private function f_tc_sgsap_unexp_ud(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4919 f_init_handler(pars);
4920 f_sleep(1.0);
4921
4922 /* This simulates what happens when a subscriber without SGs
4923 * association gets unitdata via the SGs interface. */
4924
4925 /* Make sure the subscriber exists and the SGs association
4926 * is in NULL state */
4927 f_perform_lu();
4928 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4929
4930 /* Send some random unit data, the MSC/VLR should send a release
4931 * immediately. */
4932 SGsAP.send(ts_SGsAP_UL_UD(pars.imsi,'1234'O));
4933 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, IMSI_detached_for_EPS_nonEPS_services));
4934
4935 f_sgsap_bssmap_screening();
4936
4937 setverdict(pass);
4938}
4939testcase TC_sgsap_unexp_ud() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004940 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004941 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004942 f_init(1, true);
4943 pars := f_init_pars(11821, true);
4944 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_unexp_ud), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004945 vc_conn.done;
4946}
4947
4948/* Send unsolicited unit-data through the SGs interface */
4949private function f_tc_sgsap_unsol_ud(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4950 f_init_handler(pars);
4951 f_sleep(1.0);
4952
4953 /* This simulates what happens when the MME attempts to send unitdata
4954 * to a subscriber that is completely unknown to the VLR */
4955
4956 /* Send some random unit data, the MSC/VLR should send a release
4957 * immediately. */
4958 SGsAP.send(ts_SGsAP_UL_UD(pars.imsi,'1234'O));
4959 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, IMSI_unknown));
4960
4961 f_sgsap_bssmap_screening();
4962
Harald Welte4d15fa72020-08-19 08:58:28 +02004963 /* clean-up VLR state about this subscriber */
4964 f_imsi_detach_by_imsi();
4965
Harald Welte4263c522018-12-06 11:56:27 +01004966 setverdict(pass);
4967}
4968testcase TC_sgsap_unsol_ud() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004969 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004970 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004971 f_init(1, true);
4972 pars := f_init_pars(11822, true);
4973 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_unsol_ud), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004974 vc_conn.done;
4975}
4976
4977private altstep as_other_sms_sgs() runs on BSC_ConnHdlr {
4978 /* FIXME: Match an actual payload (second questionmark), the type is
4979 * octetstring, how do we use a tr_PDU_DTAP_MT here? */
4980 [] SGsAP.receive(tr_SGsAP_DL_UD(?,?)) {
4981 setverdict(fail, "Unexpected SMS related PDU from MSC");
4982 mtc.stop;
4983 }
4984}
4985
4986/* receive a MT-SMS delivered from the MSC/SMSC over an already existing SGsAP connection */
4987function f_mt_sms_sgs(inout SmsParameters spars)
4988runs on BSC_ConnHdlr {
4989 var template (value) TPDU_RP_DATA_MS_SGSN tp_mo;
4990 var template (value) RPDU_MS_SGSN rp_mo;
4991 var template (value) PDU_ML3_MS_NW l3_mo;
4992
4993 var template TPDU_RP_DATA_SGSN_MS tp_mt;
4994 var template RPDU_SGSN_MS rp_mt;
4995 var template PDU_ML3_NW_MS l3_mt;
4996
4997 var PDU_ML3_NW_MS sgsap_l3_mt;
4998
4999 var default d := activate(as_other_sms_sgs());
5000
5001 /* Expect CP-DATA(RP-DATA(SMS-DELIVER)) */
5002 tp_mt := tr_SMS_DELIVER(?, spars.tp.ud, spars.tp.pid, spars.tp.dcs, ?);
Vadim Yanitskiy04dd5f72019-12-13 15:45:44 +09005003 rp_mt := tr_RP_DATA_MT(?, spars.rp.smsc_addr, omit, tp_mt);
Harald Welte4263c522018-12-06 11:56:27 +01005004 l3_mt := tr_ML3_MT_SMS(?, c_TIF_ORIG, tr_CP_DATA_MT(rp_mt));
5005
5006 SGsAP.receive(l3_mt) -> value sgsap_l3_mt;
5007
5008 /* Extract relevant identifiers */
5009 spars.tid := bit2int(sgsap_l3_mt.tiOrSkip.transactionId.tio);
5010 spars.rp.msg_ref := sgsap_l3_mt.msgs.sms.cP_DATA.cP_User_Data.cP_RPDU.rP_DATA_SGSN_MS.rP_MessageReference;
5011
5012 /* send CP-ACK for CP-DATA just received */
5013 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_REPL, ts_CP_ACK_MO);
5014
5015 SGsAP.send(l3_mo);
5016
5017 /* send RP-ACK for RP-DATA */
5018 rp_mo := ts_RP_ACK_MO(spars.rp.msg_ref);
5019 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_REPL, ts_CP_DATA_MO(rp_mo));
5020
5021 SGsAP.send(l3_mo);
5022
5023 /* expect CP-ACK for CP-DATA(RP-ACK) just sent */
5024 l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_ORIG, tr_CP_ACK_MT);
5025
5026 SGsAP.receive(l3_mt);
5027
5028 deactivate(d);
5029
5030 setverdict(pass);
5031}
5032
5033/* submit a MO-SMS to MSC/SMSC over an already existing SGsAP connection */
5034function f_mo_sms_sgs(inout SmsParameters spars)
5035runs on BSC_ConnHdlr {
5036 var template (value) TPDU_RP_DATA_MS_SGSN tp_mo;
5037 var template (value) RPDU_MS_SGSN rp_mo;
5038 var template (value) PDU_ML3_MS_NW l3_mo;
5039
5040 var template TPDU_RP_DATA_SGSN_MS tp_mt;
5041 var template RPDU_SGSN_MS rp_mt;
5042 var template PDU_ML3_NW_MS l3_mt;
5043
5044 var default d := activate(as_other_sms_sgs());
5045
5046 /* just in case this is routed to SMPP.. */
5047 f_create_smpp_expect(hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue));
5048
5049 tp_mo := ts_SMS_SUBMIT(spars.tp.msg_ref, spars.tp.da, spars.tp.pid, spars.tp.dcs,
5050 spars.tp.udl, spars.tp.ud);
Vadim Yanitskiy437b5a62019-12-15 14:13:39 +09005051 rp_mo := ts_RP_DATA_MO(spars.rp.msg_ref, omit, spars.rp.smsc_addr, tp_mo);
Harald Welte4263c522018-12-06 11:56:27 +01005052 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_DATA_MO(rp_mo));
5053
5054 SGsAP.send(l3_mo);
5055
5056 /* receive CP-ACK for CP-DATA above */
5057 SGsAP.receive(tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_ACK_MT));
5058
5059 if (ispresent(spars.exp_rp_err)) {
5060 /* expect an RP-ERROR message from MSC with given cause */
5061 rp_mt := tr_RP_ERROR_MT(spars.rp.msg_ref, spars.exp_rp_err);
5062 l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_DATA_MT(rp_mt));
5063 SGsAP.receive(l3_mt);
5064 /* send CP-ACK for CP-DATA just received */
5065 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_ACK_MO);
5066 SGsAP.send(l3_mo);
5067 } else {
5068 /* expect RP-ACK for RP-DATA */
5069 rp_mt := tr_RP_ACK_MT(spars.rp.msg_ref);
5070 l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_DATA_MT(rp_mt));
5071 SGsAP.receive(l3_mt);
5072 /* send CP-ACO for CP-DATA just received */
5073 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_ACK_MO);
5074 SGsAP.send(l3_mo);
5075 }
5076
5077 deactivate(d);
5078
5079 setverdict(pass);
5080}
5081
5082private function f_vty_sms_send_conn_hdlr(charstring imsi, charstring msisdn, charstring text)
5083runs on BSC_ConnHdlr {
5084 f_vty_transceive(MSCVTY, "subscriber imsi "&imsi&" sms sender msisdn "&msisdn&" send "&text);
5085}
5086
5087/* Send a MT SMS via SGs interface */
5088private function f_tc_sgsap_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5089 f_init_handler(pars);
5090 f_sgs_perform_lu();
5091 f_sleep(1.0);
5092 var SmsParameters spars := valueof(t_SmsPars);
5093 spars.tp.ud := 'C8329BFD064D9B53'O;
5094
5095 /* Trigger SMS via VTY */
5096 f_vty_sms_send_conn_hdlr(hex2str(pars.imsi), "2342", "Hello SMS");
5097 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5098
5099 /* Expect a paging request and respond accordingly with a service request */
5100 SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, SMS_indicator, omit));
5101 SGsAP.send(ts_SGsAP_SERVICE_REQ(pars.imsi, SMS_indicator, EMM_CONNECTED));
5102
5103 /* Connection is now live, receive the MT-SMS */
5104 f_mt_sms_sgs(spars);
5105
5106 /* Expect a concluding release from the MSC */
5107 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, omit));
5108
5109 /* Make sure that subscriber is still present and the SGs association is in tact (ref-counting) */
5110 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5111
5112 f_sgsap_bssmap_screening();
5113
5114 setverdict(pass);
5115}
5116testcase TC_sgsap_mt_sms() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005117 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005118 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005119 f_init(1, true);
5120 pars := f_init_pars(11823, true);
5121 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mt_sms), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005122 vc_conn.done;
5123}
5124
5125/* Send a MO SMS via SGs interface */
5126private function f_tc_sgsap_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5127 f_init_handler(pars);
5128 f_sgs_perform_lu();
5129 f_sleep(1.0);
5130 var SmsParameters spars := valueof(t_SmsPars);
5131 spars.tp.ud := 'C8329BFD064D9B53'O;
5132
5133 /* Send the MO-SMS */
5134 f_mo_sms_sgs(spars);
5135
5136 /* Expect a concluding release from the MSC/VLR */
5137 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, omit));
5138
5139 /* Make sure that subscriber is still present and the SGs association is in tact (ref-counting) */
5140 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5141
5142 setverdict(pass);
5143
5144 f_sgsap_bssmap_screening()
5145}
5146testcase TC_sgsap_mo_sms() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005147 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005148 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005149 f_init(1, true);
5150 pars := f_init_pars(11824, true);
5151 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mo_sms), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005152 vc_conn.done;
5153}
5154
5155/* Trigger sending of an MT sms via VTY but never respond to anything */
5156private function f_tc_sgsap_mt_sms_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5157 f_init_handler(pars, 170.0);
5158 f_sgs_perform_lu();
5159 f_sleep(1.0);
5160
5161 var SmsParameters spars := valueof(t_SmsPars);
5162 spars.tp.ud := 'C8329BFD064D9B53'O;
5163 var integer page_count := 0;
5164 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5165 var template PDU_SGsAP exp_pag_req := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, SMS_indicator, omit);
5166 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
5167 exp_pag_req.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
5168
5169 /* Trigger SMS via VTY */
5170 f_vty_sms_send_conn_hdlr(hex2str(pars.imsi), "2342", "Hello SMS");
5171
Neels Hofmeyr16237742019-03-06 15:34:01 +01005172 /* Expect the MSC/VLR to page exactly once */
5173 SGsAP.receive(exp_pag_req);
Harald Welte4263c522018-12-06 11:56:27 +01005174
5175 /* Wait some time to make sure the MSC is not delivering any further
5176 * paging messages or anything else that could be unexpected. */
5177 timer T := 20.0;
5178 T.start
5179 alt {
5180 [] SGsAP.receive(exp_pag_req)
5181 {
5182 setverdict(fail, "paging seems not to stop!");
5183 mtc.stop;
5184 }
5185 [] SGsAP.receive {
5186 setverdict(fail, "unexpected SGsAP message received");
5187 self.stop;
5188 }
5189 [] T.timeout {
5190 setverdict(pass);
5191 }
5192 }
5193
5194 /* Even on a failed paging the SGs Association should stay intact */
5195 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5196
Philipp Maier26bdb8c2019-09-24 09:21:12 +02005197 /* Make sure that the SMS we just inserted is cleared and the
5198 * subscriber is expired. This is necessary because otherwise the MSC
5199 * might re-try the SMS delivery and disturb the following tests. */
Harald Welte4263c522018-12-06 11:56:27 +01005200
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01005201 f_vty_sms_clear(hex2str(g_pars.imsi));
5202
Harald Welte4263c522018-12-06 11:56:27 +01005203 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " expire");
5204
5205 setverdict(pass);
Neels Hofmeyrb0f82342019-03-06 15:36:51 +01005206
5207 f_sgsap_bssmap_screening();
Harald Welte4263c522018-12-06 11:56:27 +01005208}
5209testcase TC_sgsap_mt_sms_and_nothing() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005210 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005211 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005212 f_init(1, true);
5213 pars := f_init_pars(11825, true);
5214 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mt_sms_and_nothing), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005215 vc_conn.done;
5216}
5217
5218/* Trigger sending of an MT sms via VTY but reject the paging immediately */
5219private function f_tc_sgsap_mt_sms_and_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5220 f_init_handler(pars, 150.0);
5221 f_sgs_perform_lu();
5222 f_sleep(1.0);
5223
5224 var SmsParameters spars := valueof(t_SmsPars);
5225 spars.tp.ud := 'C8329BFD064D9B53'O;
5226 var integer page_count := 0;
5227 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5228 var template PDU_SGsAP exp_pag_req := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, SMS_indicator, omit);
5229 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
5230 exp_pag_req.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
5231
5232 /* Trigger SMS via VTY */
5233 f_vty_sms_send_conn_hdlr(hex2str(pars.imsi), "2342", "Hello SMS");
5234
5235 /* Expect a paging request and reject it immediately */
5236 SGsAP.receive(exp_pag_req);
5237 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, IMSI_unknown));
5238
5239 /* The MSC/VLR should no longer try to page once the paging has been
5240 * rejected. Wait some time and check if there are no unexpected
5241 * messages on the SGs interface. */
5242 timer T := 20.0;
5243 T.start
5244 alt {
5245 [] SGsAP.receive(exp_pag_req)
5246 {
5247 setverdict(fail, "paging seems not to stop!");
5248 mtc.stop;
5249 }
5250 [] SGsAP.receive {
5251 setverdict(fail, "unexpected SGsAP message received");
5252 self.stop;
5253 }
5254 [] T.timeout {
5255 setverdict(pass);
5256 }
5257 }
5258
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01005259 f_vty_sms_clear(hex2str(g_pars.imsi));
5260
Harald Welte4263c522018-12-06 11:56:27 +01005261 /* A rejected paging with IMSI_unknown (see above) should always send
5262 * the SGs association to NULL. */
5263 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
5264
5265 f_sgsap_bssmap_screening();
5266
Harald Welte4263c522018-12-06 11:56:27 +01005267 setverdict(pass);
5268}
5269testcase TC_sgsap_mt_sms_and_reject() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005270 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005271 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005272 f_init(1, true);
5273 pars := f_init_pars(11826, true);
5274 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mt_sms_and_reject), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005275 vc_conn.done;
5276}
5277
5278/* Perform an MT CSDB call including LU */
5279private function f_mt_lu_and_csfb_call(charstring id, BSC_ConnHdlrPars pars, boolean bssmap_lu) runs on BSC_ConnHdlr {
5280 f_init_handler(pars);
5281
5282 /* Be sure that the BSSMAP reset is done before we begin. */
5283 f_sleep(2.0);
5284
5285 /* Testcase variation: See what happens when we do a regular BSSMAP
5286 * LU first (this should not hurt in any way!) */
5287 if (bssmap_lu) {
5288 f_perform_lu();
5289 }
5290
5291 f_sgs_perform_lu();
5292 f_sleep(1.0);
5293
5294 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5295 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Harald Welte4263c522018-12-06 11:56:27 +01005296
5297 /* Initiate a call via MNCC interface */
5298 f_mt_call_initate(cpars);
5299
5300 /* Expect a paging request and respond accordingly with a service request */
5301 SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit));
5302 SGsAP.send(ts_SGsAP_SERVICE_REQ(pars.imsi, CS_call_indicator, EMM_CONNECTED));
5303
5304 /* Complete the call, hold it for some time and then tear it down */
5305 f_mt_call_complete(cpars);
5306 f_sleep(3.0);
Harald Welte4c422b72019-02-17 16:27:10 +01005307 f_call_hangup(cpars, true, is_csfb := true);
Harald Welte4263c522018-12-06 11:56:27 +01005308
5309 /* Make sure that subscriber is still present and the SGs association is in tact (ref-counting) */
5310 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
5311
Harald Welte4263c522018-12-06 11:56:27 +01005312 /* Test for successful return by triggering a paging, when the paging
5313 * request is received via SGs, we can be sure that the MSC/VLR has
5314 * recognized that the UE is now back on 4G */
5315 f_sleep(1.0);
5316 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
5317 alt {
5318 [] SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit)) {
5319 setverdict(pass);
5320 }
5321 [] SGsAP.receive {
5322 setverdict(fail, "Received unexpected message on SGs");
5323 }
5324 }
5325
5326 f_sgsap_bssmap_screening();
5327
5328 setverdict(pass);
5329}
5330
5331/* Perform a regular BSSAP LU first, do a SGSAP LU and then make a CSFB call */
5332private function f_tc_bssap_lu_sgsap_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5333 f_mt_lu_and_csfb_call(id, pars, true);
5334}
5335testcase TC_bssap_lu_sgsap_lu_and_mt_call() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005336 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005337 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005338 f_init(1, true);
5339 pars := f_init_pars(118139, true);
Harald Welte4263c522018-12-06 11:56:27 +01005340
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005341 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 +01005342 vc_conn.done;
5343}
5344
Harald Welte4263c522018-12-06 11:56:27 +01005345/* Perform a SGSAP LU and then make a CSFB call */
5346private function f_tc_sgsap_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5347 f_mt_lu_and_csfb_call(id, pars, false);
5348}
5349testcase TC_sgsap_lu_and_mt_call() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005350 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01005351 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005352 f_init(1, true);
5353 pars := f_init_pars(11827, true);
Harald Welte4263c522018-12-06 11:56:27 +01005354
Philipp Maier8e07a4a2019-02-14 18:23:28 +01005355 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu_and_mt_call), pars);
Harald Welte4263c522018-12-06 11:56:27 +01005356 vc_conn.done;
5357}
5358
Philipp Maier628c0052019-04-09 17:36:57 +02005359/* Simulate an HLR/VLR failure */
5360private function f_tc_sgsap_vlr_failure(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5361 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
5362 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
5363
5364 var PDU_SGsAP lur;
5365
5366 f_init_handler(pars);
5367
5368 /* Attempt location update (which is expected to fail) */
5369 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
5370 ts_SGsAP_LAI('901'H, '70'H, 2342)));
5371 SGsAP.send(lur);
5372
5373 /* Respond to SGsAP-RESET-INDICATION from VLR */
5374 alt {
5375 [] SGsAP.receive(tr_SGsAP_RESET_IND_VLR(vlr_name)); {
5376 SGsAP.send(valueof(ts_SGsAP_RESET_ACK_MME(mme_name)));
5377 setverdict(pass);
5378 }
5379 [] SGsAP.receive {
5380 setverdict(fail, "Received unexpected message on SGs");
5381 }
5382 }
5383
5384 f_sleep(1.0);
5385 setverdict(pass);
5386}
5387testcase TC_sgsap_vlr_failure() runs on MTC_CT {
5388 var BSC_ConnHdlrPars pars;
5389 var BSC_ConnHdlr vc_conn;
5390 f_init(1, true, false);
5391 pars := f_init_pars(11811, true, false);
5392 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_vlr_failure), pars);
5393 vc_conn.done;
5394}
5395
Harald Welte4263c522018-12-06 11:56:27 +01005396/* SGs TODO:
5397 * LU attempt for IMSI without NAM_PS in HLR
5398 * LU attempt with AUTH FAIL due to invalid RES/SRES
5399 * LU attempt with no response from HLR (VLR should timeout + LU REJ)
5400 * LU attempt with new TMSI but without TMSI REALL CMPL baco to VLR
5401 * implicit IMSI detach from EPS
5402 * implicit IMSI detach from non-EPS
5403 * MM INFO
5404 *
5405 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01005406
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005407private function f_tc_ho_inter_bsc_unknown_cell(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5408 f_init_handler(pars);
5409 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005410
5411 f_perform_lu();
5412 f_mo_call_establish(cpars);
5413
5414 f_sleep(1.0);
5415
5416 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
5417 var BssmapCause cause := enum2int(cause_val);
5418
5419 var template BSSMAP_FIELD_CellIdentificationList cil;
5420 cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('023'H, '42'H, 999) } };
5421
5422 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
5423 BSSAP.receive(tr_BSSMAP_HandoverRequiredReject);
5424
5425 f_call_hangup(cpars, true);
5426}
5427testcase TC_ho_inter_bsc_unknown_cell() runs on MTC_CT {
5428 var BSC_ConnHdlr vc_conn;
5429 f_init();
5430
5431 vc_conn := f_start_handler(refers(f_tc_ho_inter_bsc_unknown_cell), 53);
5432 vc_conn.done;
5433}
5434
5435private altstep as_mgcp_ack_all_mdcx(CallParameters cpars) runs on BSC_ConnHdlr {
5436 var MgcpCommand mgcp_cmd;
5437 [] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02005438 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 +02005439 hex2str(cpars.mgcp_call_id), "42",
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02005440 cpars.mgw_conn_2.mgw_rtp_port,
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005441 { int2str(cpars.rtp_payload_type) },
5442 { valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
5443 cpars.rtp_sdp_format)),
5444 valueof(ts_SDP_ptime(20)) }));
Neels Hofmeyr3c89a6b2019-10-15 16:54:37 +02005445 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 +02005446 repeat;
5447 }
5448}
5449
5450private function f_tc_ho_inter_bsc0(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5451 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005452
5453 f_init_handler(pars);
5454
5455 f_vty_transceive(MSCVTY, "configure terminal");
5456 f_vty_transceive(MSCVTY, "msc");
5457 f_vty_transceive(MSCVTY, "neighbor a cgi 262 42 23 42 ran-pc 0.24.1");
5458 f_vty_transceive(MSCVTY, "neighbor a lac 5 ran-pc 0.24.2");
5459 f_vty_transceive(MSCVTY, "exit");
5460 f_vty_transceive(MSCVTY, "exit");
5461
5462 f_perform_lu();
5463 f_mo_call_establish(cpars);
5464
5465 f_sleep(1.0);
5466
5467 var default ack_mdcx := activate(as_mgcp_ack_all_mdcx(cpars));
5468
5469 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
5470 var BssmapCause cause := enum2int(cause_val);
5471
5472 var template BSSMAP_FIELD_CellIdentificationList cil;
5473 cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('023'H, '42'H, 5) } };
5474
5475 /* old BSS sends Handover Required */
5476 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
5477
5478 /* Now the action goes on in f_tc_ho_inter_bsc1() */
5479
5480 /* MSC forwards the RR Handover Command to old BSS */
5481 var PDU_BSSAP ho_command;
5482 BSSAP.receive(tr_BSSMAP_HandoverCommand) -> value ho_command;
5483
5484 log("GOT HandoverCommand", ho_command);
5485
5486 BSSAP.receive(tr_BSSMAP_HandoverSucceeded);
5487
5488 /* f_tc_ho_inter_bsc1() completes Handover, then expecting a Clear here. */
5489 f_expect_clear();
5490
5491 log("FIRST inter-BSC Handover done");
5492
5493
5494 /* ------------------------ */
5495
5496 /* Ok, that went well, now the other BSC is handovering back here --
5497 * from now on this here is the new BSS. */
5498 f_create_bssmap_exp_handoverRequest(193);
5499
5500 var PDU_BSSAP ho_request;
5501 BSSAP.receive(tr_BSSMAP_HandoverRequest) -> value ho_request;
5502
5503 /* new BSS composes a RR Handover Command */
5504 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5505 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5506 var BSSMAP_IE_AoIP_TransportLayerAddress tla := valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
5507 BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
5508 tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
5509
5510 /* Now f_tc_ho_inter_bsc1() expects HandoverCommand */
5511
5512 f_sleep(0.5);
5513
5514 /* Notify that the MS is now over here */
5515
5516 BSSAP.send(ts_BSSMAP_HandoverDetect);
5517 f_sleep(0.1);
5518 BSSAP.send(ts_BSSMAP_HandoverComplete);
5519
5520 f_sleep(3.0);
5521
5522 deactivate(ack_mdcx);
5523
5524 var default ccrel := activate(as_optional_cc_rel(cpars, true));
5525
5526 /* blatant cheating */
5527 var N_Sd_Array last_n_sd := f_bssmap_last_n_sd();
5528 last_n_sd[0] := 3;
5529 f_bssmap_continue_after_n_sd(last_n_sd);
5530
5531 f_call_hangup(cpars, true);
5532 f_sleep(1.0);
5533 deactivate(ccrel);
5534
5535 setverdict(pass);
5536}
5537private function f_tc_ho_inter_bsc1(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5538 f_init_handler(pars);
5539 f_create_bssmap_exp_handoverRequest(194);
5540
5541 var PDU_BSSAP ho_request;
5542 BSSAP.receive(tr_BSSMAP_HandoverRequest) -> value ho_request;
5543
5544 /* new BSS composes a RR Handover Command */
5545 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5546 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5547 var BSSMAP_IE_AoIP_TransportLayerAddress tla := valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
5548 BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
5549 tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
5550
5551 /* Now f_tc_ho_inter_bsc0() expects HandoverCommand */
5552
5553 f_sleep(0.5);
5554
5555 /* Notify that the MS is now over here */
5556
5557 BSSAP.send(ts_BSSMAP_HandoverDetect);
5558 f_sleep(0.1);
5559 BSSAP.send(ts_BSSMAP_HandoverComplete);
5560
5561 f_sleep(3.0);
5562
5563 /* Now I'd like to f_call_hangup() but we don't know any cpars here. So
5564 * ... handover back to the first BSC :P */
5565
5566 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
5567 var BssmapCause cause := enum2int(cause_val);
5568
5569 var template BSSMAP_FIELD_CellIdentificationList cil;
5570 cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('262'H, '42'H, 23) } };
5571
5572 /* old BSS sends Handover Required */
5573 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
5574
5575 /* Now the action goes on in f_tc_ho_inter_bsc0() */
5576
5577 /* MSC forwards the RR Handover Command to old BSS */
5578 var PDU_BSSAP ho_command;
5579 BSSAP.receive(tr_BSSMAP_HandoverCommand) -> value ho_command;
5580
5581 log("GOT HandoverCommand", ho_command);
5582
5583 BSSAP.receive(tr_BSSMAP_HandoverSucceeded);
5584
5585 /* f_tc_ho_inter_bsc1() completes Handover, then expecting a Clear here. */
5586 f_expect_clear();
5587 setverdict(pass);
5588}
5589testcase TC_ho_inter_bsc() runs on MTC_CT {
5590 var BSC_ConnHdlr vc_conn0;
5591 var BSC_ConnHdlr vc_conn1;
5592 f_init(2);
5593
5594 var BSC_ConnHdlrPars pars0 := f_init_pars(53);
5595 var BSC_ConnHdlrPars pars1 := f_init_pars(53);
5596
5597 vc_conn0 := f_start_handler_with_pars(refers(f_tc_ho_inter_bsc0), pars0, 0);
5598 vc_conn1 := f_start_handler_with_pars(refers(f_tc_ho_inter_bsc1), pars1, 1);
5599 vc_conn0.done;
5600 vc_conn1.done;
5601}
5602
5603function f_ML3_patch_seq_nr_MS_NW(in uint2_t seq_nr, inout octetstring enc_l3) {
5604 log("MS_NW patching N(SD)=", seq_nr, " into dtap ", enc_l3);
5605 enc_l3[2] := (enc_l3[2] and4b '3f'O) or4b bit2oct(int2bit(seq_nr, 8) << 6);
5606 log("MS_NW patched enc_l3: ", enc_l3);
5607}
5608
5609private function f_tc_ho_inter_msc_out(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5610 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005611 var hexstring ho_number := f_gen_msisdn(99999);
5612
5613 f_init_handler(pars);
5614
5615 f_create_mncc_expect(hex2str(ho_number));
5616
5617 f_vty_transceive(MSCVTY, "configure terminal");
5618 f_vty_transceive(MSCVTY, "msc");
5619 f_vty_transceive(MSCVTY, "neighbor a cgi 017 017 1 1 msc-ipa-name msc-017-017-1");
5620 f_vty_transceive(MSCVTY, "exit");
5621 f_vty_transceive(MSCVTY, "exit");
5622
5623 f_perform_lu();
5624 f_mo_call_establish(cpars);
5625
5626 f_sleep(1.0);
5627
5628 var default ack_mdcx := activate(as_mgcp_ack_all_mdcx(cpars));
5629
5630 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
5631 var BssmapCause cause := enum2int(cause_val);
5632
5633 var template BSSMAP_FIELD_CellIdentificationList cil;
5634 cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('017'H, '017'H, 1) } };
5635
5636 /* old BSS sends Handover Required */
5637 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
5638
5639 /* The target cell 017-017 LAC 1 is configured to be a remote MSC of name "msc-017-017-1".
5640 * This MSC tries to reach the other MSC via GSUP. */
5641
5642 var octetstring remote_msc_name := '6D73632D3031372D3031372D3100'O; /* "msc-017-017-1\0" as octetstring */
5643 var GSUP_PDU prep_ho_req;
5644 GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_REQUEST,
5645 pars.imsi, destination_name := remote_msc_name)) -> value prep_ho_req;
5646
5647 var GSUP_IeValue source_name_ie;
5648 f_gsup_find_ie(prep_ho_req, OSMO_GSUP_SOURCE_NAME_IE, source_name_ie);
5649 var octetstring local_msc_name := source_name_ie.source_name;
5650
5651 /* Remote MSC has figured out its BSC and signals success */
5652 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5653 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5654 var PDU_BSSAP ho_req_ack := valueof(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
5655 aoIPTransportLayer := omit,
5656 speechCodec := ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
5657 GSUP.send(ts_GSUP_E_PrepareHandoverResult(
5658 pars.imsi,
5659 ho_number,
5660 remote_msc_name, local_msc_name,
5661 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006, enc_PDU_BSSAP(ho_req_ack)))));
5662
5663 /* MSC forwards the RR Handover Command to old BSS */
5664 BSSAP.receive(tr_BSSMAP_HandoverCommand);
5665
5666 /* The MS shows up at remote new BSS */
5667
5668 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST,
5669 pars.imsi, remote_msc_name, local_msc_name,
5670 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
5671 enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverDetect))))));
5672 BSSAP.receive(tr_BSSMAP_HandoverSucceeded);
5673 f_sleep(0.1);
5674
5675 /* Save the MS sequence counters for use on the other connection */
5676 var N_Sd_Array last_n_sd := f_bssmap_last_n_sd();
5677
5678 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_REQUEST,
5679 pars.imsi, remote_msc_name, local_msc_name,
5680 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
5681 enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverComplete))))));
5682
5683 /* The local BSS conn clears, all communication goes via remote MSC now */
5684 f_expect_clear();
5685
5686 /**********************************/
5687 /* Play through some signalling across the inter-MSC link.
5688 * This is a copy of f_tc_lu_and_mo_ussd_single_request() translated into GSUP AN-APDUs. */
5689
5690 if (false) {
5691 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
5692 invoke_id := 5, /* Phone may not start from 0 or 1 */
5693 op_code := SS_OP_CODE_PROCESS_USS_REQ,
5694 ussd_string := "*#100#"
5695 );
5696
5697 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
5698 invoke_id := 5, /* InvokeID shall be the same for both REQ and RSP */
5699 op_code := SS_OP_CODE_PROCESS_USS_REQ,
5700 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
5701 )
5702
5703 /* Compose a new SS/REGISTER message with request */
5704 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
5705 tid := 1, /* We just need a single transaction */
5706 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
5707 facility := valueof(facility_req)
5708 );
5709 var PDU_ML3_MS_NW ussd_req_v := valueof(ussd_req);
5710
5711 /* Compose SS/RELEASE_COMPLETE template with expected response */
5712 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
5713 tid := 1, /* Response should arrive within the same transaction */
5714 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
5715 facility := valueof(facility_rsp)
5716 );
5717
5718 /* Compose expected MSC -> HLR message */
5719 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
5720 imsi := g_pars.imsi,
5721 state := OSMO_GSUP_SESSION_STATE_BEGIN,
5722 ss := valueof(facility_req)
5723 );
5724
5725 /* To be used for sending response with correct session ID */
5726 var GSUP_PDU gsup_req_complete;
5727
5728 /* Request own number */
5729 /* From remote MSC instead of BSSAP directly */
5730 /* Patch the correct N_SD value into the message. */
5731 var octetstring l3_enc := enc_PDU_ML3_MS_NW(ussd_req_v);
5732 var RAN_Emulation.ConnectionData cd;
5733 f_ML3_patch_seq_nr_MS_NW(f_next_n_sd(last_n_sd, f_ML3_n_sd_idx(ussd_req_v)), l3_enc);
5734 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST,
5735 pars.imsi, remote_msc_name, local_msc_name,
5736 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
5737 enc_PDU_BSSAP(valueof(ts_BSSAP_DTAP(l3_enc)))
5738 ))
5739 ));
5740
5741 /* Expect GSUP message containing the SS payload */
5742 gsup_req_complete := f_expect_gsup_msg(gsup_req);
5743
5744 /* Compose the response from HLR using received session ID */
5745 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
5746 imsi := g_pars.imsi,
5747 sid := gsup_req_complete.ies[1].val.session_id,
5748 state := OSMO_GSUP_SESSION_STATE_END,
5749 ss := valueof(facility_rsp)
5750 );
5751
5752 /* Finally, HLR terminates the session */
5753 GSUP.send(gsup_rsp);
5754
5755 /* The USSD response goes out to remote MSC, on GSUP E instead of BSSAP */
5756 var GSUP_PDU gsup_ussd_rsp;
5757 GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST,
5758 pars.imsi, destination_name := remote_msc_name)) -> value gsup_ussd_rsp;
5759
5760 var GSUP_IeValue an_apdu;
5761 if (not f_gsup_find_ie(gsup_ussd_rsp, OSMO_GSUP_AN_APDU_IE, an_apdu)) {
5762 setverdict(fail, "No AN-APDU in received GSUP message. Expected USSD response in DTAP, got", gsup_ussd_rsp);
5763 mtc.stop;
5764 }
5765 var PDU_BSSAP bssap_dtap_mt := dec_PDU_BSSAP(an_apdu.an_apdu.pdu);
5766 var PDU_ML3_NW_MS dtap_mt := dec_PDU_ML3_NW_MS(bssap_dtap_mt.pdu.dtap);
5767 log("Expecting", ussd_rsp);
5768 log("Got", dtap_mt);
5769 if (not match(dtap_mt, ussd_rsp)) {
5770 setverdict(fail, "Unexpected GSUP message. Expected USSD response in DTAP, got", gsup_ussd_rsp);
5771 mtc.stop;
5772 }
5773 }
5774 /**********************************/
5775
5776
5777 /* inter-MSC handover back to the first MSC */
5778 f_create_bssmap_exp_handoverRequest(193);
5779 cil := { cIl_CGI := { ts_BSSMAP_CI_CGI('262'H, '42'H, 23, 42) } };
5780
5781 /* old BSS sends Handover Required, via inter-MSC E link: like
5782 * BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
5783 * but via GSUP */
5784 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_REQUEST,
5785 pars.imsi, remote_msc_name, local_msc_name,
5786 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
5787 enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverRequired(cause, cil)))
5788 ))
5789 ));
5790
5791 /* MSC asks local BSS to prepare Handover to it */
5792 BSSAP.receive(tr_BSSMAP_HandoverRequest);
5793
5794 /* Make sure the new BSSAP conn continues with the correct N_SD sequence numbers */
5795 f_bssmap_continue_after_n_sd(last_n_sd);
5796
5797 /* new BSS composes a RR Handover Command */
5798 rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5799 rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5800 var BSSMAP_IE_AoIP_TransportLayerAddress tla := valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
5801 BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
5802 tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
5803
5804 /* HandoverCommand goes out via remote MSC-I */
5805 var GSUP_PDU prep_subsq_ho_res;
5806 GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_RESULT,
5807 pars.imsi, destination_name := remote_msc_name)) -> value prep_subsq_ho_res;
5808
5809 /* MS shows up at the local BSS */
5810 BSSAP.send(ts_BSSMAP_HandoverDetect);
5811 f_sleep(0.1);
5812 BSSAP.send(ts_BSSMAP_HandoverComplete);
5813
5814 /* Handover Succeeded message */
5815 GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST,
5816 pars.imsi, destination_name := remote_msc_name));
5817
5818 /* MS has handovered to here, Clear Command goes out via remote MSC-I -- in form of a GSUP Close. */
5819 GSUP.receive(tr_GSUP_E_NO_PDU(OSMO_GSUP_MSGT_E_CLOSE,
5820 pars.imsi, destination_name := remote_msc_name));
5821
5822 /* Handover ends successfully. Call goes on for a little longer and then we hang up. */
5823
5824 f_sleep(1.0);
5825 deactivate(ack_mdcx);
5826
5827 /* FIXME: the inter-MSC call has put a number of MNCC messages in the queue, which above code should expect and
5828 * clear out. The f_call_hangup() expects an MNCC_REL_IND, so, for the time being, just clear the MNCC messages
5829 * before starting the call hangup. Instead of this, the individual messages should be tested for above. */
5830 MNCC.clear;
5831
5832 var default ccrel := activate(as_optional_cc_rel(cpars, true));
5833 f_call_hangup(cpars, true);
5834 f_sleep(1.0);
5835 deactivate(ccrel);
5836
5837 setverdict(pass);
5838}
5839testcase TC_ho_inter_msc_out() runs on MTC_CT {
5840 var BSC_ConnHdlr vc_conn;
5841 f_init(1);
5842
5843 var BSC_ConnHdlrPars pars := f_init_pars(54);
5844
5845 vc_conn := f_start_handler_with_pars(refers(f_tc_ho_inter_msc_out), pars, 0);
5846 vc_conn.done;
5847}
5848
Oliver Smith1d118ff2019-07-03 10:57:35 +02005849private function f_tc_lu_imsi_auth_tmsi_check_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5850 pars.net.expect_auth := true;
5851 pars.net.expect_imei := true;
5852 f_init_handler(pars);
5853 f_perform_lu();
5854}
5855testcase TC_lu_imsi_auth_tmsi_check_imei() runs on MTC_CT {
5856 var BSC_ConnHdlr vc_conn;
5857 f_init();
5858 f_vty_config(MSCVTY, "network", "authentication required");
5859 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
5860
5861 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei), 5);
5862 vc_conn.done;
5863}
5864
5865private function f_tc_lu_imsi_auth3g_tmsi_check_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5866 pars.net.expect_auth := true;
5867 pars.use_umts_aka := true;
5868 pars.net.expect_imei := true;
5869 f_init_handler(pars);
5870 f_perform_lu();
5871}
5872testcase TC_lu_imsi_auth3g_tmsi_check_imei() runs on MTC_CT {
5873 var BSC_ConnHdlr vc_conn;
5874 f_init();
5875 f_vty_config(MSCVTY, "network", "authentication required");
5876 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
5877
5878 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth3g_tmsi_check_imei), 5);
5879 vc_conn.done;
5880}
5881
5882private function f_tc_lu_imsi_noauth_tmsi_check_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5883 pars.net.expect_imei := true;
5884 f_init_handler(pars);
5885 f_perform_lu();
5886}
5887testcase TC_lu_imsi_noauth_tmsi_check_imei() runs on MTC_CT {
5888 var BSC_ConnHdlr vc_conn;
5889 f_init();
5890 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
5891
5892 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi_check_imei), 5);
5893 vc_conn.done;
5894}
5895
5896private function f_tc_lu_imsi_noauth_notmsi_check_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5897 pars.net.expect_tmsi := false;
5898 pars.net.expect_imei := true;
5899 f_init_handler(pars);
5900 f_perform_lu();
5901}
5902testcase TC_lu_imsi_noauth_notmsi_check_imei() runs on MTC_CT {
5903 var BSC_ConnHdlr vc_conn;
5904 f_init();
5905 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
5906 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
5907
5908 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi_check_imei), 5);
5909 vc_conn.done;
5910}
5911
5912private function f_tc_lu_imsi_auth_tmsi_check_imei_nack(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5913 var PDU_ML3_MS_NW l3_lu;
Oliver Smith1d118ff2019-07-03 10:57:35 +02005914
5915 pars.net.expect_auth := true;
5916 pars.net.expect_imei := true;
5917 pars.net.check_imei_result := OSMO_GSUP_IMEI_RESULT_NACK;
5918 f_init_handler(pars);
5919
5920 /* Cannot use f_perform_lu() as we expect a reject */
5921 l3_lu := f_build_lu_imsi(g_pars.imsi)
5922 f_create_gsup_expect(hex2str(g_pars.imsi));
5923 f_bssap_compl_l3(l3_lu);
5924 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
5925
5926 f_mm_common();
5927 f_msc_lu_hlr();
5928 f_mm_imei();
Oliver Smith91bfa1c2019-07-19 15:01:15 +02005929 f_expect_lu_reject();
Oliver Smith690d60f2019-07-23 13:09:08 +02005930 f_expect_clear();
Oliver Smith1d118ff2019-07-03 10:57:35 +02005931}
5932testcase TC_lu_imsi_auth_tmsi_check_imei_nack() runs on MTC_CT {
5933 var BSC_ConnHdlr vc_conn;
5934 f_init();
5935 f_vty_config(MSCVTY, "network", "authentication required");
5936 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
5937
5938 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_nack), 5);
5939 vc_conn.done;
5940}
5941
5942private function f_tc_lu_imsi_auth_tmsi_check_imei_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5943 var PDU_ML3_MS_NW l3_lu;
Oliver Smith1d118ff2019-07-03 10:57:35 +02005944
5945 pars.net.expect_auth := true;
5946 pars.net.expect_imei := true;
5947 pars.net.check_imei_error := true;
5948 f_init_handler(pars);
5949
5950 /* Cannot use f_perform_lu() as we expect a reject */
5951 l3_lu := f_build_lu_imsi(g_pars.imsi)
5952 f_create_gsup_expect(hex2str(g_pars.imsi));
5953 f_bssap_compl_l3(l3_lu);
5954 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
5955
5956 f_mm_common();
5957 f_msc_lu_hlr();
5958 f_mm_imei();
Oliver Smith91bfa1c2019-07-19 15:01:15 +02005959 f_expect_lu_reject();
Oliver Smith690d60f2019-07-23 13:09:08 +02005960 f_expect_clear();
Oliver Smith1d118ff2019-07-03 10:57:35 +02005961}
5962testcase TC_lu_imsi_auth_tmsi_check_imei_err() runs on MTC_CT {
5963 var BSC_ConnHdlr vc_conn;
5964 f_init();
5965 f_vty_config(MSCVTY, "network", "authentication required");
5966 f_vty_config(MSCVTY, "msc", "check-imei-rqd 1");
5967
5968 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_err), 5);
5969 vc_conn.done;
5970}
5971
5972private function f_tc_lu_imsi_auth_tmsi_check_imei_early(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5973 pars.net.expect_auth := true;
5974 pars.net.expect_imei_early := true;
5975 f_init_handler(pars);
5976 f_perform_lu();
5977}
5978testcase TC_lu_imsi_auth_tmsi_check_imei_early() runs on MTC_CT {
5979 var BSC_ConnHdlr vc_conn;
5980 f_init();
5981 f_vty_config(MSCVTY, "network", "authentication required");
5982 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
5983
5984 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_early), 5);
5985 vc_conn.done;
5986}
5987
5988private function f_tc_lu_imsi_auth3g_tmsi_check_imei_early(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
5989 pars.net.expect_auth := true;
5990 pars.use_umts_aka := true;
5991 pars.net.expect_imei_early := true;
5992 f_init_handler(pars);
5993 f_perform_lu();
5994}
5995testcase TC_lu_imsi_auth3g_tmsi_check_imei_early() runs on MTC_CT {
5996 var BSC_ConnHdlr vc_conn;
5997 f_init();
5998 f_vty_config(MSCVTY, "network", "authentication required");
5999 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
6000
6001 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth3g_tmsi_check_imei_early), 5);
6002 vc_conn.done;
6003}
6004
6005private function f_tc_lu_imsi_noauth_tmsi_check_imei_early(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6006 pars.net.expect_imei_early := true;
6007 f_init_handler(pars);
6008 f_perform_lu();
6009}
6010testcase TC_lu_imsi_noauth_tmsi_check_imei_early() runs on MTC_CT {
6011 var BSC_ConnHdlr vc_conn;
6012 f_init();
6013 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
6014
6015 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi_check_imei_early), 5);
6016 vc_conn.done;
6017}
6018
6019private function f_tc_lu_imsi_noauth_notmsi_check_imei_early(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6020 pars.net.expect_tmsi := false;
6021 pars.net.expect_imei_early := true;
6022 f_init_handler(pars);
6023 f_perform_lu();
6024}
6025testcase TC_lu_imsi_noauth_notmsi_check_imei_early() runs on MTC_CT {
6026 var BSC_ConnHdlr vc_conn;
6027 f_init();
6028 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
6029 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
6030
6031 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi_check_imei_early), 5);
6032 vc_conn.done;
6033}
6034
6035private function f_tc_lu_imsi_auth_tmsi_check_imei_early_nack(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6036 var PDU_ML3_MS_NW l3_lu;
Oliver Smith1d118ff2019-07-03 10:57:35 +02006037
6038 pars.net.expect_auth := true;
6039 pars.net.expect_imei_early := true;
6040 pars.net.check_imei_result := OSMO_GSUP_IMEI_RESULT_NACK;
6041 f_init_handler(pars);
6042
6043 /* Cannot use f_perform_lu() as we expect a reject */
6044 l3_lu := f_build_lu_imsi(g_pars.imsi)
6045 f_create_gsup_expect(hex2str(g_pars.imsi));
6046 f_bssap_compl_l3(l3_lu);
6047 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
6048
6049 f_mm_imei_early();
Oliver Smith91bfa1c2019-07-19 15:01:15 +02006050 f_expect_lu_reject();
Oliver Smith690d60f2019-07-23 13:09:08 +02006051 f_expect_clear();
Oliver Smith1d118ff2019-07-03 10:57:35 +02006052}
6053testcase TC_lu_imsi_auth_tmsi_check_imei_early_nack() runs on MTC_CT {
6054 var BSC_ConnHdlr vc_conn;
6055 f_init();
6056 f_vty_config(MSCVTY, "network", "authentication required");
6057 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
6058
6059 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_early_nack), 5);
6060 vc_conn.done;
6061}
6062
6063private function f_tc_lu_imsi_auth_tmsi_check_imei_early_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6064 var PDU_ML3_MS_NW l3_lu;
Oliver Smith1d118ff2019-07-03 10:57:35 +02006065
6066 pars.net.expect_auth := true;
6067 pars.net.expect_imei_early := true;
6068 pars.net.check_imei_error := true;
6069 f_init_handler(pars);
6070
6071 /* Cannot use f_perform_lu() as we expect a reject */
6072 l3_lu := f_build_lu_imsi(g_pars.imsi)
6073 f_create_gsup_expect(hex2str(g_pars.imsi));
6074 f_bssap_compl_l3(l3_lu);
6075 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
6076
6077 f_mm_imei_early();
Oliver Smith91bfa1c2019-07-19 15:01:15 +02006078 f_expect_lu_reject();
Oliver Smith690d60f2019-07-23 13:09:08 +02006079 f_expect_clear();
Oliver Smith1d118ff2019-07-03 10:57:35 +02006080}
6081testcase TC_lu_imsi_auth_tmsi_check_imei_early_err() runs on MTC_CT {
6082 var BSC_ConnHdlr vc_conn;
6083 f_init();
6084 f_vty_config(MSCVTY, "network", "authentication required");
6085 f_vty_config(MSCVTY, "msc", "check-imei-rqd early");
6086
6087 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_check_imei_early_err), 5);
6088 vc_conn.done;
6089}
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006090
Neels Hofmeyr8df69622019-11-02 19:16:03 +01006091friend function f_tc_invalid_mgcp_crash(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
6092 f_init_handler(pars);
6093 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
6094
6095 /* Set invalid IP address so that osmo-msc discards the rtp_stream and MGCP endpoint FSM instances in the middle
6096 * of successful MGCP response dispatch. If things aren't safeguarded, the on_success() in osmo_mgcpc_ep_fsm
6097 * will cause a use-after-free after that event dispatch. */
6098 cpars.mgw_conn_1.mgw_rtp_ip := "0.0.0.0";
6099 cpars.mgw_conn_2.mgw_rtp_ip := "0.0.0.0";
6100 cpars.rtp_sdp_format := "FOO/8000";
6101 cpars.expect_release := true;
6102
6103 f_perform_lu();
6104 f_mo_call_establish(cpars);
6105}
6106testcase TC_invalid_mgcp_crash() runs on MTC_CT {
6107 var BSC_ConnHdlr vc_conn;
6108 f_init();
6109
6110 vc_conn := f_start_handler(refers(f_tc_invalid_mgcp_crash), 7);
6111 vc_conn.done;
6112}
6113
Vadim Yanitskiyeddebaa2019-12-28 17:45:34 +01006114friend function f_tc_mm_id_resp_no_identity(charstring id, BSC_ConnHdlrPars pars)
6115runs on BSC_ConnHdlr {
6116 pars.tmsi := 'FFFFFFFF'O;
6117 f_init_handler(pars);
6118
6119 f_create_gsup_expect(hex2str(g_pars.imsi));
6120
6121 /* Initiate Location Updating using an unknown TMSI */
6122 f_bssap_compl_l3(f_build_lu_tmsi(pars.tmsi));
6123
6124 /* Expect an Identity Request, send response with no identity */
6125 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req(CM_ID_TYPE_IMSI)));
6126 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp({
6127 lengthIndicator := 1,
6128 mobileIdentityV := {
6129 typeOfIdentity := '000'B,
6130 oddEvenInd_identity := {
6131 no_identity := {
6132 oddevenIndicator := '0'B,
6133 fillerDigits := '00000'H
6134 }
6135 }
6136 }
6137 })));
6138
6139 f_expect_lu_reject();
6140 f_expect_clear();
6141}
6142testcase TC_mm_id_resp_no_identity() runs on MTC_CT {
6143 var BSC_ConnHdlr vc_conn;
6144
6145 f_init();
6146
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02006147 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 +01006148 vc_conn.done;
6149}
6150
Vadim Yanitskiy25219062020-01-21 01:41:33 +07006151/* Verify the case when T3212 expires during Paging procedure, just before the receipt
6152 * of Paging Response. This used to provoke a NULL-pointer dereference in old versions
6153 * of OsmoMSC, but apparently the bug has been fixed, and we're safe now. */
6154friend function f_tc_lu_and_expire_while_paging(charstring id, BSC_ConnHdlrPars pars)
6155runs on BSC_ConnHdlr {
6156 var charstring imsi := hex2str(pars.imsi);
6157
6158 f_init_handler(pars);
6159
6160 /* Perform location update */
6161 f_perform_lu();
6162
6163 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
6164 f_create_gsup_expect(hex2str(g_pars.imsi));
6165
6166 /* Initiate paging procedure from the VTY */
6167 f_vty_transceive(MSCVTY, "subscriber imsi " & imsi & " paging");
6168 f_expect_paging();
6169
6170 /* Emulate T3212 expiration during paging (we don't want to wait, right?) */
6171 f_vty_transceive(MSCVTY, "subscriber imsi " & imsi & " expire");
6172
6173 /* MS sends PAGING RESPONSE, *old* OsmoMSC crashes here... */
6174 f_establish_fully(EST_TYPE_PAG_RESP);
6175
6176 /* The recent OsmoMSC keeps subscriber in its VLR unless the Paging is completed.
6177 * In this case we do not send anything and just wait for a Clear Command. */
Neels Hofmeyr4e18ccc2020-06-24 19:08:17 +02006178 f_expect_clear(verify_vlr_cell_id := false);
Vadim Yanitskiy25219062020-01-21 01:41:33 +07006179}
6180testcase TC_lu_and_expire_while_paging() runs on MTC_CT {
6181 var BSC_ConnHdlr vc_conn;
6182
6183 f_init();
6184
6185 vc_conn := f_start_handler(refers(f_tc_lu_and_expire_while_paging), 7);
6186 vc_conn.done;
6187}
6188
Harald Weltef6dd64d2017-11-19 12:09:51 +01006189control {
Philipp Maier328d1662018-03-07 10:40:27 +01006190 execute( TC_cr_before_reset() );
Harald Weltea49e36e2018-01-21 19:29:33 +01006191 execute( TC_lu_imsi_noauth_tmsi() );
Harald Welted2328a22018-01-27 14:27:16 +01006192 execute( TC_lu_imsi_noauth_notmsi() );
Harald Weltea49e36e2018-01-21 19:29:33 +01006193 execute( TC_lu_imsi_reject() );
6194 execute( TC_lu_imsi_timeout_gsup() );
Harald Welted2328a22018-01-27 14:27:16 +01006195 execute( TC_lu_imsi_auth_tmsi() );
Harald Welte8a397ae2019-04-21 22:03:37 +02006196 execute( TC_lu_imsi_auth3g_tmsi() );
Pau Espin Pedrold3d54a92019-12-17 17:02:54 +01006197 execute( TC_lu_imsi_timeout_tmsi_realloc() );
Harald Welted2328a22018-01-27 14:27:16 +01006198 execute( TC_cmserv_imsi_unknown() );
Neels Hofmeyr13737fb2020-08-19 13:16:14 +00006199 execute( TC_cmserv_tmsi_unknown() );
Harald Welte2bb825f2018-01-22 11:31:18 +01006200 execute( TC_lu_and_mo_call() );
Pau Espin Pedrola42745c2020-01-10 18:03:28 +01006201 execute( TC_lu_and_mo_call_sccp_tiar_timeout() );
Harald Welte071ed732018-01-23 19:53:52 +01006202 execute( TC_lu_auth_sai_timeout() );
6203 execute( TC_lu_auth_sai_err() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01006204 execute( TC_lu_clear_request() );
6205 execute( TC_lu_disconnect() );
6206 execute( TC_lu_by_imei() );
6207 execute( TC_lu_by_tmsi_noauth_unknown() );
Neels Hofmeyrfc06c732020-08-19 12:52:28 +00006208 execute( TC_attached_imsi_lu_unknown_tmsi() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01006209 execute( TC_imsi_detach_by_imsi() );
6210 execute( TC_imsi_detach_by_tmsi() );
6211 execute( TC_imsi_detach_by_imei() );
6212 execute( TC_emerg_call_imei_reject() );
6213 execute( TC_emerg_call_imsi() );
6214 execute( TC_cm_serv_req_vgcs_reject() );
6215 execute( TC_cm_serv_req_vbs_reject() );
6216 execute( TC_cm_serv_req_lcs_reject() );
Harald Welte0195ab12018-01-24 21:50:20 +01006217 execute( TC_cm_reest_req_reject() );
Harald Welte1af6ea82018-01-25 18:33:15 +01006218 execute( TC_lu_auth_2G_fail() );
6219 execute( TC_lu_imsi_auth_tmsi_encr_13_13() );
6220 execute( TC_cl3_no_payload() );
6221 execute( TC_cl3_rnd_payload() );
Harald Welte1852a842018-01-26 22:53:36 +01006222 execute( TC_establish_and_nothing() );
6223 execute( TC_mo_setup_and_nothing() );
6224 execute( TC_mo_crcx_ran_timeout() );
6225 execute( TC_mo_crcx_ran_reject() );
Harald Welted2328a22018-01-27 14:27:16 +01006226 execute( TC_mt_crcx_ran_reject() );
Daniel Willmann8b084372018-02-04 13:35:26 +01006227 execute( TC_mo_setup_and_dtmf_dup() );
Harald Welteaa54cf82018-01-30 08:15:32 +01006228 //execute( TC_mt_t310() );
Harald Welte167458a2018-01-27 15:58:16 +01006229 execute( TC_gsup_cancel() );
Harald Welte9de84792018-01-28 01:06:35 +01006230 execute( TC_lu_imsi_auth_tmsi_encr_1_13() );
6231 execute( TC_lu_imsi_auth_tmsi_encr_3_13() );
6232 execute( TC_lu_imsi_auth_tmsi_encr_3_1() );
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01006233 execute( TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() );
Harald Welte9de84792018-01-28 01:06:35 +01006234 execute( TC_lu_imsi_auth_tmsi_encr_13_2() );
6235 execute( TC_lu_imsi_auth_tmsi_encr_013_2() );
Philipp Maier94f3f1b2018-03-15 18:54:13 +01006236 execute( TC_mo_release_timeout() );
Philipp Maier2a98a732018-03-19 16:06:12 +01006237 execute( TC_lu_and_mt_call_no_dlcx_resp() );
Philipp Maier75932982018-03-27 14:52:35 +02006238 execute( TC_reset_two() );
Harald Welte33ec09b2018-02-10 15:34:46 +01006239
6240 execute( TC_lu_and_mt_call() );
Neels Hofmeyrb58d9742019-11-27 18:44:54 +01006241 execute( TC_lu_and_mt_call_already_paging() );
Harald Welte33ec09b2018-02-10 15:34:46 +01006242
Harald Weltef45efeb2018-04-09 18:19:24 +02006243 execute( TC_lu_and_mo_sms() );
6244 execute( TC_lu_and_mt_sms() );
Neels Hofmeyrb58d9742019-11-27 18:44:54 +01006245 execute( TC_lu_and_mt_sms_already_paging() );
Philipp Maier3983e702018-11-22 19:01:33 +01006246 execute( TC_lu_and_mt_sms_paging_and_nothing() );
Alexander Couzensfc02f242019-09-12 03:43:18 +02006247 execute( TC_lu_and_mt_sms_paging_repeated() );
Harald Weltef640a012018-04-14 17:49:21 +02006248 execute( TC_smpp_mo_sms() );
Vadim Yanitskiy33820762020-01-15 11:26:07 +07006249 execute( TC_smpp_mo_sms_rp_error() );
Harald Weltef640a012018-04-14 17:49:21 +02006250 execute( TC_smpp_mt_sms() );
Harald Weltef45efeb2018-04-09 18:19:24 +02006251
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07006252 execute( TC_gsup_mo_sms() );
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07006253 execute( TC_gsup_mo_smma() );
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07006254 execute( TC_gsup_mt_sms_ack() );
6255 execute( TC_gsup_mt_sms_err() );
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07006256 execute( TC_gsup_mt_sms_rp_mr() );
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07006257 execute( TC_gsup_mo_mt_sms_rp_mr() );
Vadim Yanitskiya2a8a112019-07-08 20:04:32 +07006258 execute( TC_gsup_mt_multi_part_sms() );
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07006259
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07006260 execute( TC_lu_and_mo_ussd_single_request() );
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07006261 execute( TC_lu_and_mt_ussd_notification() );
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07006262 execute( TC_lu_and_mo_ussd_during_mt_call() );
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07006263 execute( TC_lu_and_mt_ussd_during_mt_call() );
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07006264 execute( TC_lu_and_mo_ussd_mo_release() );
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07006265 execute( TC_lu_and_ss_session_timeout() );
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07006266
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07006267 execute( TC_mt_ussd_for_unknown_subscr() );
Vadim Yanitskiyc3c07d42019-06-17 23:00:44 +07006268 execute( TC_mo_ussd_for_unknown_trans() );
Vadim Yanitskiyd612d282019-06-15 14:46:03 +07006269 execute( TC_proc_ss_for_unknown_session() );
Vadim Yanitskiye5f4ed92019-06-16 02:36:33 +07006270 execute( TC_proc_ss_paging_fail() );
Vadim Yanitskiy29ba8d62019-06-16 15:19:41 +07006271 execute( TC_proc_ss_abort() );
Vadim Yanitskiy0e6c9f52019-06-15 01:01:28 +07006272
Vadim Yanitskiy1c9754d2020-01-07 21:56:55 +01006273 execute( TC_multi_lu_and_mo_ussd() );
6274 execute( TC_multi_lu_and_mt_ussd() );
6275
Stefan Sperling89eb1f32018-12-17 15:06:20 +01006276 execute( TC_cipher_complete_with_invalid_cipher() );
Stefan Sperlinga2d59c62018-12-18 16:32:44 +01006277 execute( TC_cipher_complete_1_without_cipher() );
6278 execute( TC_cipher_complete_3_without_cipher() );
6279 execute( TC_cipher_complete_13_without_cipher() );
Harald Welteb2284bd2019-05-10 11:30:43 +02006280 execute( TC_lu_with_invalid_mcc_mnc() );
Stefan Sperling89eb1f32018-12-17 15:06:20 +01006281
Harald Welte4263c522018-12-06 11:56:27 +01006282 execute( TC_sgsap_reset() );
6283 execute( TC_sgsap_lu() );
6284 execute( TC_sgsap_lu_imsi_reject() );
6285 execute( TC_sgsap_lu_and_nothing() );
6286 execute( TC_sgsap_expl_imsi_det_eps() );
Philipp Maierfc19f172019-03-21 11:17:54 +01006287 execute( TC_sgsap_impl_imsi_det_eps() );
Harald Welte4263c522018-12-06 11:56:27 +01006288 execute( TC_sgsap_expl_imsi_det_noneps() );
Philipp Maier5d812702019-03-21 10:51:26 +01006289 execute( TC_sgsap_impl_imsi_det_noneps() );
Harald Welte4263c522018-12-06 11:56:27 +01006290 execute( TC_sgsap_paging_rej() );
6291 execute( TC_sgsap_paging_subscr_rej() );
6292 execute( TC_sgsap_paging_ue_unr() );
6293 execute( TC_sgsap_paging_and_nothing() );
6294 execute( TC_sgsap_paging_and_lu() );
6295 execute( TC_sgsap_mt_sms() );
6296 execute( TC_sgsap_mo_sms() );
6297 execute( TC_sgsap_mt_sms_and_nothing() );
6298 execute( TC_sgsap_mt_sms_and_reject() );
6299 execute( TC_sgsap_unexp_ud() );
6300 execute( TC_sgsap_unsol_ud() );
6301 execute( TC_bssap_lu_sgsap_lu_and_mt_call() );
6302 execute( TC_sgsap_lu_and_mt_call() );
Philipp Maier628c0052019-04-09 17:36:57 +02006303 execute( TC_sgsap_vlr_failure() );
Harald Welte4263c522018-12-06 11:56:27 +01006304
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02006305 execute( TC_ho_inter_bsc_unknown_cell() );
6306 execute( TC_ho_inter_bsc() );
6307
6308 execute( TC_ho_inter_msc_out() );
6309
Oliver Smith1d118ff2019-07-03 10:57:35 +02006310 execute( TC_lu_imsi_auth_tmsi_check_imei() );
6311 execute( TC_lu_imsi_auth3g_tmsi_check_imei() );
6312 execute( TC_lu_imsi_noauth_tmsi_check_imei() );
6313 execute( TC_lu_imsi_noauth_notmsi_check_imei() );
6314 execute( TC_lu_imsi_auth_tmsi_check_imei_nack() );
6315 execute( TC_lu_imsi_auth_tmsi_check_imei_err() );
6316 execute( TC_lu_imsi_auth_tmsi_check_imei_early() );
6317 execute( TC_lu_imsi_auth3g_tmsi_check_imei_early() );
6318 execute( TC_lu_imsi_noauth_tmsi_check_imei_early() );
6319 execute( TC_lu_imsi_noauth_notmsi_check_imei_early() );
6320 execute( TC_lu_imsi_auth_tmsi_check_imei_early_nack() );
6321 execute( TC_lu_imsi_auth_tmsi_check_imei_early_err() );
6322
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01006323 /* Run this last: at the time of writing this test crashes the MSC */
6324 execute( TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() );
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02006325 execute( TC_mo_cc_bssmap_clear() );
Pau Espin Pedrol690d6592019-05-31 17:56:32 +02006326 if (mp_enable_osmux_test) {
6327 execute( TC_lu_and_mt_call_osmux() );
6328 }
Neels Hofmeyr8df69622019-11-02 19:16:03 +01006329 execute( TC_invalid_mgcp_crash() );
Vadim Yanitskiyeddebaa2019-12-28 17:45:34 +01006330 execute( TC_mm_id_resp_no_identity() );
Vadim Yanitskiy25219062020-01-21 01:41:33 +07006331 execute( TC_lu_and_expire_while_paging() );
Harald Weltef6dd64d2017-11-19 12:09:51 +01006332}
6333
6334
6335}