blob: b64b87242bf1a6cfeb28a203681ad05166a0abb1 [file] [log] [blame]
Harald Weltef6dd64d2017-11-19 12:09:51 +01001module MSC_Tests {
2
Harald Weltee13cfb22019-04-23 16:52:02 +02003friend module MSC_Tests_Iu;
4
Harald Weltef6dd64d2017-11-19 12:09:51 +01005import from General_Types all;
6import from Osmocom_Types all;
7
8import from M3UA_Types all;
9import from M3UA_Emulation all;
10
11import from MTP3asp_Types all;
12import from MTP3asp_PortType all;
13
14import from SCCPasp_Types all;
15import from SCCP_Types all;
16import from SCCP_Emulation all;
17
18import from SCTPasp_Types all;
19import from SCTPasp_PortType all;
20
Harald Weltea49e36e2018-01-21 19:29:33 +010021import from Osmocom_CTRL_Functions all;
22import from Osmocom_CTRL_Types all;
23import from Osmocom_CTRL_Adapter all;
24
Harald Welte3ca1c902018-01-24 18:51:27 +010025import from TELNETasp_PortType all;
26import from Osmocom_VTY_Functions all;
27
Harald Weltea49e36e2018-01-21 19:29:33 +010028import from MNCC_Emulation all;
Harald Welte2bb825f2018-01-22 11:31:18 +010029import from MNCC_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +010030
Harald Welte4aa970c2018-01-26 10:38:09 +010031import from MGCP_Emulation all;
32import from MGCP_Types all;
33import from MGCP_Templates all;
34import from SDP_Types all;
35
Harald Weltea49e36e2018-01-21 19:29:33 +010036import from GSUP_Emulation all;
37import from GSUP_Types all;
38import from IPA_Emulation all;
39
Harald Weltef6dd64d2017-11-19 12:09:51 +010040import from BSSAP_Types all;
Harald Welte6811d102019-04-14 22:23:14 +020041import from RAN_Adapter all;
Harald Weltea49e36e2018-01-21 19:29:33 +010042import from BSSAP_CodecPort all;
43import from BSSMAP_Templates all;
Harald Welte6811d102019-04-14 22:23:14 +020044import from RAN_Emulation all;
Harald Weltea49e36e2018-01-21 19:29:33 +010045import from BSC_ConnectionHandler all;
Harald Weltee13cfb22019-04-23 16:52:02 +020046import from RANAP_Templates all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010047
Harald Welte4263c522018-12-06 11:56:27 +010048import from SGsAP_Templates all;
49import from SGsAP_Types all;
50import from SGsAP_Emulation all;
51
Harald Weltea49e36e2018-01-21 19:29:33 +010052import from MobileL3_Types all;
53import from MobileL3_CommonIE_Types all;
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +070054import from MobileL3_SMS_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +010055import from L3_Templates all;
Harald Welte158a7ca2018-02-16 18:11:31 +010056import from L3_Common all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010057
Harald Weltef640a012018-04-14 17:49:21 +020058import from SMPP_Types all;
59import from SMPP_Templates all;
60import from SMPP_Emulation all;
61
Stefan Sperlingc307e682018-06-14 15:15:46 +020062import from SCCP_Templates all;
63
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +070064import from SS_Types all;
65import from SS_Templates all;
66import from USSD_Helpers all;
Harald Welte4263c522018-12-06 11:56:27 +010067import from DNS_Helpers all;
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +070068
Philipp Maier948747b2019-04-02 15:22:33 +020069import from TCCConversion_Functions all;
70
Harald Welte9b751a62019-04-14 17:39:29 +020071const integer NUM_BSC := 3;
Harald Welte6811d102019-04-14 22:23:14 +020072type record of RAN_Configuration RAN_Configurations;
Harald Weltef6dd64d2017-11-19 12:09:51 +010073
Harald Welte4263c522018-12-06 11:56:27 +010074/* Needed for SGsAP SMS */
75import from MobileL3_SMS_Types all;
76
Harald Weltea4ca4462018-02-09 00:17:14 +010077type component MTC_CT extends CTRL_Adapter_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +010078 var boolean g_initialized := false;
Harald Weltea49e36e2018-01-21 19:29:33 +010079
Harald Welte6811d102019-04-14 22:23:14 +020080 var RAN_Adapter g_bssap[NUM_BSC];
Harald Weltea4ca4462018-02-09 00:17:14 +010081
Harald Weltea49e36e2018-01-21 19:29:33 +010082 /* no 'adapter_CT' for MNCC or GSUP */
83 var MNCC_Emulation_CT vc_MNCC;
Harald Welte4aa970c2018-01-26 10:38:09 +010084 var MGCP_Emulation_CT vc_MGCP;
Harald Weltea49e36e2018-01-21 19:29:33 +010085 var GSUP_Emulation_CT vc_GSUP;
86 var IPA_Emulation_CT vc_GSUP_IPA;
Harald Weltef640a012018-04-14 17:49:21 +020087 var SMPP_Emulation_CT vc_SMPP;
Harald Welte4263c522018-12-06 11:56:27 +010088 var SGsAP_Emulation_CT vc_SGsAP;
Harald Weltea49e36e2018-01-21 19:29:33 +010089
90 /* only to get events from IPA underneath GSUP */
91 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte3ca1c902018-01-24 18:51:27 +010092 /* VTY to MSC */
93 port TELNETasp_PT MSCVTY;
Philipp Maier328d1662018-03-07 10:40:27 +010094
95 /* A port to directly send BSSAP messages. This port is used for
96 * tests that require low level access to sen arbitrary BSSAP
97 * messages. Run f_init_bssap_direct() to connect and initialize */
98 port BSSAP_CODEC_PT BSSAP_DIRECT;
99
100 /* When BSSAP messages are directly sent, then the connection
101 * handler is not active, which means that also no guard timer is
102 * set up. The following timer will serve as a replacement */
103 timer Tguard_direct := 60.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100104}
105
106modulepar {
Harald Weltea49e36e2018-01-21 19:29:33 +0100107 /* remote parameters of IUT */
108 charstring mp_msc_ip := "127.0.0.1";
109 integer mp_msc_ctrl_port := 4255;
110 integer mp_msc_vty_port := 4254;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100111
Harald Weltea49e36e2018-01-21 19:29:33 +0100112 /* local parameters of emulated HLR */
Philipp Maier9b690e42018-12-21 11:50:03 +0100113 boolean mp_mm_info := false;
Harald Weltea49e36e2018-01-21 19:29:33 +0100114 charstring mp_hlr_ip := "127.0.0.1";
115 integer mp_hlr_port := 4222;
Harald Welte6126fb02018-01-27 20:08:24 +0100116 charstring mp_mgw_ip := "127.0.0.1";
117 integer mp_mgw_port := 2427;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100118
Harald Weltea49e36e2018-01-21 19:29:33 +0100119 charstring mp_msc_mncc := "/tmp/mncc";
Harald Weltea4ca4462018-02-09 00:17:14 +0100120
Harald Weltef640a012018-04-14 17:49:21 +0200121 integer mp_msc_smpp_port := 2775;
122 charstring mp_smpp_system_id := "msc_tester";
123 charstring mp_smpp_password := "osmocom1";
Harald Welte4263c522018-12-06 11:56:27 +0100124 charstring mp_mme_name := "mmec01.mmegi0001.mme.epc.mnc070.mcc901.3gppnetwork.org";
125 charstring mp_vlr_name := "vlr.example.net";
Harald Weltef640a012018-04-14 17:49:21 +0200126
Harald Welte6811d102019-04-14 22:23:14 +0200127 RAN_Configurations mp_bssap_cfg := {
Philipp Maier75932982018-03-27 14:52:35 +0200128 {
129 sccp_service_type := "mtp3_itu",
130 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
131 own_pc := 185,
132 own_ssn := 254,
133 peer_pc := 187,
134 peer_ssn := 254,
135 sio := '83'O,
136 rctx := 0
137 },
138 {
139 sccp_service_type := "mtp3_itu",
140 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
141 own_pc := 186,
142 own_ssn := 254,
143 peer_pc := 187,
144 peer_ssn := 254,
145 sio := '83'O,
146 rctx := 1
147 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100148 };
Harald Weltef6dd64d2017-11-19 12:09:51 +0100149}
150
Philipp Maier328d1662018-03-07 10:40:27 +0100151/* altstep for the global guard timer (only used when BSSAP_DIRECT
152 * is used for communication */
153private altstep as_Tguard_direct() runs on MTC_CT {
154 [] Tguard_direct.timeout {
155 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200156 mtc.stop;
Philipp Maier328d1662018-03-07 10:40:27 +0100157 }
158}
Harald Weltef6dd64d2017-11-19 12:09:51 +0100159
Neels Hofmeyr2ca1ab42019-03-08 03:45:43 +0100160private altstep as_optional_cc_rel(CallParameters cpars, boolean respond := false) runs on BSC_ConnHdlr {
161 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id))) {
162 if (respond) {
163 var BIT1 tid_remote := '1'B;
164 if (cpars.mo_call) {
165 tid_remote := '0'B;
166 }
167 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id, tid_remote)));
168 }
169 }
Neels Hofmeyrde76f052019-02-26 05:02:46 +0100170}
171
Harald Weltef640a012018-04-14 17:49:21 +0200172function f_init_smpp(charstring id) runs on MTC_CT {
173 id := id & "-SMPP";
174 var EsmePars pars := {
175 mode := MODE_TRANSCEIVER,
176 bind := {
177 system_id := mp_smpp_system_id,
178 password := mp_smpp_password,
179 system_type := "MSC_Tests",
180 interface_version := hex2int('34'H),
181 addr_ton := unknown,
182 addr_npi := unknown,
183 address_range := ""
184 },
185 esme_role := true
186 }
187
188 vc_SMPP := SMPP_Emulation_CT.create(id);
189 map(vc_SMPP:SMPP_PORT, system:SMPP_PORT);
190 vc_SMPP.start(SMPP_Emulation.main_client(pars, mp_msc_ip, mp_msc_smpp_port, "", -1));
191}
192
193
Harald Weltea49e36e2018-01-21 19:29:33 +0100194function f_init_mncc(charstring id) runs on MTC_CT {
195 id := id & "-MNCC";
196 var MnccOps ops := {
197 create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
198 unitdata_cb := refers(MNCC_Emulation.DummyUnitdataCallback)
199 }
200
201 vc_MNCC := MNCC_Emulation_CT.create(id);
202 map(vc_MNCC:MNCC, system:MNCC_CODEC_PT);
203 vc_MNCC.start(MNCC_Emulation.main(ops, id, mp_msc_mncc));
Harald Weltef6dd64d2017-11-19 12:09:51 +0100204}
205
Harald Welte4aa970c2018-01-26 10:38:09 +0100206function f_init_mgcp(charstring id) runs on MTC_CT {
207 id := id & "-MGCP";
208 var MGCPOps ops := {
209 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
210 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
211 }
212 var MGCP_conn_parameters pars := {
Harald Welte6126fb02018-01-27 20:08:24 +0100213 callagent_ip := mp_msc_ip,
Harald Welte4aa970c2018-01-26 10:38:09 +0100214 callagent_udp_port := -1,
Harald Welte6126fb02018-01-27 20:08:24 +0100215 mgw_ip := mp_mgw_ip,
216 mgw_udp_port := mp_mgw_port
Harald Welte4aa970c2018-01-26 10:38:09 +0100217 }
218
219 vc_MGCP := MGCP_Emulation_CT.create(id);
220 map(vc_MGCP:MGCP, system:MGCP_CODEC_PT);
221 vc_MGCP.start(MGCP_Emulation.main(ops, pars, id));
222}
223
Philipp Maierc09a1312019-04-09 16:05:26 +0200224function ForwardUnitdataCallback(PDU_SGsAP msg)
225runs on SGsAP_Emulation_CT return template PDU_SGsAP {
226 SGsAP_CLIENT.send(msg);
227 return omit;
228}
229
Harald Welte4263c522018-12-06 11:56:27 +0100230function f_init_sgsap(charstring id) runs on MTC_CT {
231 id := id & "-SGsAP";
232 var SGsAPOps ops := {
233 create_cb := refers(SGsAP_Emulation.ExpectedCreateCallback),
Philipp Maierc09a1312019-04-09 16:05:26 +0200234 unitdata_cb := refers(ForwardUnitdataCallback)
Harald Welte4263c522018-12-06 11:56:27 +0100235 }
236 var SGsAP_conn_parameters pars := {
237 remote_ip := mp_msc_ip,
238 remote_sctp_port := 29118,
239 local_ip := "",
240 local_sctp_port := -1
241 }
242
243 vc_SGsAP := SGsAP_Emulation_CT.create(id);
244 map(vc_SGsAP:SGsAP, system:SGsAP_CODEC_PT);
245 vc_SGsAP.start(SGsAP_Emulation.main(ops, pars, id));
246}
247
248
Harald Weltea49e36e2018-01-21 19:29:33 +0100249function f_init_gsup(charstring id) runs on MTC_CT {
250 id := id & "-GSUP";
251 var GsupOps ops := {
252 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
253 }
254
255 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
256 vc_GSUP := GSUP_Emulation_CT.create(id);
257
258 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
259 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
260 /* we use this hack to get events like ASP_IPA_EVENT_UP */
261 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
262
263 vc_GSUP.start(GSUP_Emulation.main(ops, id));
264 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
265
266 /* wait for incoming connection to GSUP port before proceeding */
267 timer T := 10.0;
268 T.start;
269 alt {
270 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
271 [] T.timeout {
Harald Welte458fd372018-03-21 11:26:23 +0100272 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200273 mtc.stop
Harald Weltea49e36e2018-01-21 19:29:33 +0100274 }
275 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100276}
277
Philipp Maierc09a1312019-04-09 16:05:26 +0200278function f_init(integer num_bsc := 1, boolean sgsap := false, boolean gsup := true) runs on MTC_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +0100279
280 if (g_initialized == true) {
281 return;
282 }
283 g_initialized := true;
284
Philipp Maier75932982018-03-27 14:52:35 +0200285 if (num_bsc > NUM_BSC) {
Daniel Willmannafce8662018-07-06 23:11:32 +0200286 testcase.stop("excess number of BSC instances requested");
Philipp Maier75932982018-03-27 14:52:35 +0200287 }
288
289 for (var integer i := 0; i < num_bsc; i := i + 1) {
290 if (isbound(mp_bssap_cfg[i])) {
Harald Welte3ca0ce12019-04-23 17:18:48 +0200291 f_ran_adapter_init(g_bssap[i], mp_bssap_cfg[i], "MSC_Test_" & int2str(i), BSC_RanOps);
292 f_ran_adapter_start(g_bssap[i]);
Philipp Maier75932982018-03-27 14:52:35 +0200293 } else {
Daniel Willmannafce8662018-07-06 23:11:32 +0200294 testcase.stop("missing BSSAP configuration");
Philipp Maier75932982018-03-27 14:52:35 +0200295 }
296 }
297
Harald Weltea49e36e2018-01-21 19:29:33 +0100298 f_ipa_ctrl_start(mp_msc_ip, mp_msc_ctrl_port);
299 f_init_mncc("MSC_Test");
Harald Welte4aa970c2018-01-26 10:38:09 +0100300 f_init_mgcp("MSC_Test");
Philipp Maierc09a1312019-04-09 16:05:26 +0200301
302 if (gsup == true) {
303 f_init_gsup("MSC_Test");
304 }
Harald Weltef640a012018-04-14 17:49:21 +0200305 f_init_smpp("MSC_Test");
Philipp Maier57865482019-01-07 18:33:13 +0100306
Philipp Maier8e07a4a2019-02-14 18:23:28 +0100307 if (sgsap == true) {
Philipp Maier57865482019-01-07 18:33:13 +0100308 f_init_sgsap("MSC_Test");
309 }
Harald Welte3ca1c902018-01-24 18:51:27 +0100310
311 map(self:MSCVTY, system:MSCVTY);
312 f_vty_set_prompts(MSCVTY);
313 f_vty_transceive(MSCVTY, "enable");
Harald Welteb14c77a2018-01-25 17:25:44 +0100314
315 /* set some defaults */
316 f_vty_config(MSCVTY, "network", "authentication optional");
317 f_vty_config(MSCVTY, "msc", "assign-tmsi");
318 f_vty_config(MSCVTY, "network", "encryption a5 0");
Harald Weltef6dd64d2017-11-19 12:09:51 +0100319}
320
Philipp Maier328d1662018-03-07 10:40:27 +0100321/* Initialize for a direct connection to BSSAP. This function is an alternative
322 * to f_init() when the high level functions of the BSC_ConnectionHandler are
323 * not needed. */
324function f_init_bssap_direct() runs on MTC_CT {
Harald Welte3ca0ce12019-04-23 17:18:48 +0200325 f_ran_adapter_init(g_bssap[0], mp_bssap_cfg[0], "MSC_Test", omit);
Philipp Maier75932982018-03-27 14:52:35 +0200326 connect(g_bssap[0].vc_SCCP:SCCP_SP_PORT, self:BSSAP_DIRECT);
Philipp Maier328d1662018-03-07 10:40:27 +0100327
328 /* Start guard timer and activate it as default */
329 Tguard_direct.start
330 activate(as_Tguard_direct());
331}
332
Harald Weltea49e36e2018-01-21 19:29:33 +0100333type function void_fn(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100334
Harald Weltea49e36e2018-01-21 19:29:33 +0100335/* FIXME: move into BSC_ConnectionHandler? */
Harald Welte9b751a62019-04-14 17:39:29 +0200336function f_init_pars(integer imsi_suffix, boolean sgsap := false, boolean gsup := true, integer ran_idx := 0,
337 boolean ran_is_geran := true)
Harald Weltef9abf8d2019-04-21 13:07:17 +0200338runs on MTC_CT return BSC_ConnHdlrPars {
Harald Weltede371492018-01-27 23:44:41 +0100339 var BSC_ConnHdlrNetworkPars net_pars := {
340 kc_support := '0A'O, /* A5/1 and A5/3 enabled */
341 expect_tmsi := true,
342 expect_auth := false,
343 expect_ciph := false
344 };
Harald Weltea49e36e2018-01-21 19:29:33 +0100345 var BSC_ConnHdlrPars pars := {
Harald Weltef9abf8d2019-04-21 13:07:17 +0200346 sccp_addr_own := g_bssap[ran_idx].sccp_addr_own,
347 sccp_addr_peer := g_bssap[ran_idx].sccp_addr_peer,
Harald Welteedbab812018-03-18 16:02:25 +0100348 cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42)),
Harald Welte81b7f9d2018-01-24 19:06:24 +0100349 imei := f_gen_imei(imsi_suffix),
350 imsi := f_gen_imsi(imsi_suffix),
351 msisdn := f_gen_msisdn(imsi_suffix),
Harald Welte256571e2018-01-24 18:47:19 +0100352 tmsi := omit,
Harald Welte9de84792018-01-28 01:06:35 +0100353 cm1 := valueof(ts_CM1),
Harald Welte82600572018-01-21 20:54:08 +0100354 cm2 := valueof(ts_CM2_default),
Harald Welte16114282018-01-24 22:41:21 +0100355 cm3 := omit,
Harald Weltede371492018-01-27 23:44:41 +0100356 vec := omit,
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100357 net := net_pars,
Philipp Maieraeb29a82018-11-08 17:40:53 +0100358 send_early_cm := true,
359 ipa_ctrl_ip := mp_msc_ip,
360 ipa_ctrl_port := mp_msc_ctrl_port,
Philipp Maier9b690e42018-12-21 11:50:03 +0100361 ipa_ctrl_enable := true,
Philipp Maier57865482019-01-07 18:33:13 +0100362 mm_info := mp_mm_info,
Philipp Maierc09a1312019-04-09 16:05:26 +0200363 sgsap_enable := sgsap,
Harald Weltef9abf8d2019-04-21 13:07:17 +0200364 gsup_enable := gsup,
Harald Weltec1f937a2019-04-21 21:19:23 +0200365 ran_idx := ran_idx,
Harald Welte9b751a62019-04-14 17:39:29 +0200366 use_umts_aka := false,
367 ran_is_geran := ran_is_geran
Harald Weltea49e36e2018-01-21 19:29:33 +0100368 };
Harald Weltee13cfb22019-04-23 16:52:02 +0200369 if (not ran_is_geran) {
370 pars.use_umts_aka := true;
371 pars.net.expect_auth := true;
372 }
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100373 return pars;
374}
375
Neels Hofmeyr0ac63152019-05-07 01:20:17 +0200376function 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 +0100377 var BSC_ConnHdlr vc_conn;
Neels Hofmeyr0ac63152019-05-07 01:20:17 +0200378 var charstring id := testcasename() & int2str(bssap_idx);
Harald Weltea49e36e2018-01-21 19:29:33 +0100379
380 vc_conn := BSC_ConnHdlr.create(id);
381 /* BSSMAP part / A interface */
Neels Hofmeyr0ac63152019-05-07 01:20:17 +0200382 connect(vc_conn:BSSAP, g_bssap[pars.ran_idx + bssap_idx].vc_RAN:CLIENT);
383 connect(vc_conn:BSSAP_PROC, g_bssap[pars.ran_idx + bssap_idx].vc_RAN:PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100384 /* MNCC part */
385 connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
386 connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);
Harald Welte4aa970c2018-01-26 10:38:09 +0100387 /* MGCP part */
388 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
389 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100390 /* GSUP part */
Philipp Maierc09a1312019-04-09 16:05:26 +0200391 if (pars.gsup_enable == true) {
392 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
393 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
394 }
Harald Weltef640a012018-04-14 17:49:21 +0200395 /* SMPP part */
396 connect(vc_conn:SMPP, vc_SMPP:SMPP_CLIENT);
397 connect(vc_conn:SMPP_PROC, vc_SMPP:SMPP_PROC);
Harald Welte4263c522018-12-06 11:56:27 +0100398 /* SGs part */
Philipp Maier8e07a4a2019-02-14 18:23:28 +0100399 if (pars.sgsap_enable == true) {
Philipp Maier57865482019-01-07 18:33:13 +0100400 connect(vc_conn:SGsAP, vc_SGsAP:SGsAP_CLIENT);
401 connect(vc_conn:SGsAP_PROC, vc_SGsAP:SGsAP_PROC);
402 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100403
Harald Weltea10db902018-01-27 12:44:49 +0100404 /* We cannot use vc_conn.start(f_init_handler(fn, id, pars)); as we cannot have
405 * a stand-alone 'derefers()' call, see https://www.eclipse.org/forums/index.php/t/1091364/ */
Harald Weltea49e36e2018-01-21 19:29:33 +0100406 vc_conn.start(derefers(fn)(id, pars));
407 return vc_conn;
408}
409
Harald Welte9b751a62019-04-14 17:39:29 +0200410function f_start_handler(void_fn fn, integer imsi_suffix, integer ran_idx := 0, boolean ran_is_geran := true)
411runs on MTC_CT return BSC_ConnHdlr {
412 return f_start_handler_with_pars(fn, f_init_pars(imsi_suffix, ran_idx := ran_idx, ran_is_geran := ran_is_geran));
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100413}
414
Harald Weltea49e36e2018-01-21 19:29:33 +0100415private function f_tc_lu_imsi_noauth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100416 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100417 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100418}
Harald Weltea49e36e2018-01-21 19:29:33 +0100419testcase TC_lu_imsi_noauth_tmsi() runs on MTC_CT {
420 var BSC_ConnHdlr vc_conn;
421 f_init();
422
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100423 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi), 1);
Harald Weltea49e36e2018-01-21 19:29:33 +0100424 vc_conn.done;
425}
426
427private function f_tc_lu_imsi_noauth_notmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100428 pars.net.expect_tmsi := false;
Harald Weltea10db902018-01-27 12:44:49 +0100429 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100430 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100431}
Harald Weltea49e36e2018-01-21 19:29:33 +0100432testcase TC_lu_imsi_noauth_notmsi() runs on MTC_CT {
433 var BSC_ConnHdlr vc_conn;
434 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100435 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
Harald Weltea49e36e2018-01-21 19:29:33 +0100436
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100437 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi), 2);
Harald Weltea49e36e2018-01-21 19:29:33 +0100438 vc_conn.done;
439}
440
441/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
Harald Weltee13cfb22019-04-23 16:52:02 +0200442friend function f_tc_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100443 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100444 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
445
446 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +0200447 f_cl3_or_initial_ue(l3_lu);
Harald Welteb7817992019-05-09 13:15:39 +0200448 f_mm_auth();
Harald Weltea49e36e2018-01-21 19:29:33 +0100449 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
450 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
451 alt {
Harald Welte5946b332018-03-18 23:32:21 +0100452 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej(int2oct(23,1)))) {
453 f_expect_clear();
454 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100455 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
456 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
Daniel Willmannafce8662018-07-06 23:11:32 +0200457 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100458 }
459 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100460}
461testcase TC_lu_imsi_reject() runs on MTC_CT {
462 var BSC_ConnHdlr vc_conn;
463 f_init();
464
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100465 vc_conn := f_start_handler(refers(f_tc_lu_imsi_reject), 3);
Harald Weltea49e36e2018-01-21 19:29:33 +0100466 vc_conn.done;
467}
468
Harald Weltee13cfb22019-04-23 16:52:02 +0200469
470
Harald Weltea49e36e2018-01-21 19:29:33 +0100471/* Do LU by IMSI, timeout on GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +0200472friend function f_tc_lu_imsi_timeout_gsup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100473 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100474 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
475
476 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +0200477 f_cl3_or_initial_ue(l3_lu);
Harald Welteb7817992019-05-09 13:15:39 +0200478 f_mm_auth();
Harald Weltea49e36e2018-01-21 19:29:33 +0100479 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
480 /* Normally the HLR would need to respond here, but we decide to force a timeout here */
481 alt {
482 /* FIXME: Expect specific reject cause */
Harald Welte5946b332018-03-18 23:32:21 +0100483 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
484 f_expect_clear();
485 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100486 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
487 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
Daniel Willmannafce8662018-07-06 23:11:32 +0200488 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100489 }
490 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100491}
492testcase TC_lu_imsi_timeout_gsup() runs on MTC_CT {
493 var BSC_ConnHdlr vc_conn;
494 f_init();
495
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100496 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_gsup), 4);
Harald Weltea49e36e2018-01-21 19:29:33 +0100497 vc_conn.done;
498}
499
Harald Weltee13cfb22019-04-23 16:52:02 +0200500
Harald Welte7b1b2812018-01-22 21:23:06 +0100501private function f_tc_lu_imsi_auth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100502 pars.net.expect_auth := true;
Harald Weltea10db902018-01-27 12:44:49 +0100503 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100504 f_perform_lu();
Harald Welte7b1b2812018-01-22 21:23:06 +0100505}
506testcase TC_lu_imsi_auth_tmsi() runs on MTC_CT {
507 var BSC_ConnHdlr vc_conn;
508 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100509 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte7b1b2812018-01-22 21:23:06 +0100510
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100511 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi), 5);
Harald Welte7b1b2812018-01-22 21:23:06 +0100512 vc_conn.done;
513}
514
Harald Weltee13cfb22019-04-23 16:52:02 +0200515
516friend function f_tc_lu_imsi_auth3g_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Welte8a397ae2019-04-21 22:03:37 +0200517 pars.net.expect_auth := true;
518 pars.use_umts_aka := true;
519 f_init_handler(pars);
520 f_perform_lu();
521}
522testcase TC_lu_imsi_auth3g_tmsi() runs on MTC_CT {
523 var BSC_ConnHdlr vc_conn;
524 f_init();
525 f_vty_config(MSCVTY, "network", "authentication required");
526
527 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth3g_tmsi), 1005);
528 vc_conn.done;
529}
Harald Weltea49e36e2018-01-21 19:29:33 +0100530
Harald Weltee13cfb22019-04-23 16:52:02 +0200531
Harald Weltea49e36e2018-01-21 19:29:33 +0100532/* Send CM SERVICE REQ for IMSI that has never performed LU before */
Harald Weltee13cfb22019-04-23 16:52:02 +0200533friend function f_tc_cmserv_imsi_unknown(charstring id, BSC_ConnHdlrPars pars)
Harald Weltea49e36e2018-01-21 19:29:33 +0100534runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100535 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100536
537 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welteedbab812018-03-18 16:02:25 +0100538 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100539 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltea49e36e2018-01-21 19:29:33 +0100540
541 f_create_gsup_expect(hex2str(g_pars.imsi));
542
543 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200544 f_cl3_or_initial_ue(l3_info);
Harald Welteb7817992019-05-09 13:15:39 +0200545 f_mm_auth();
Harald Weltea49e36e2018-01-21 19:29:33 +0100546
547 timer T := 10.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100548 T.start;
549 alt {
Harald Weltea49e36e2018-01-21 19:29:33 +0100550 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
551 //[] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC)) { }
Daniel Willmannafce8662018-07-06 23:11:32 +0200552 [] BSSAP.receive {
553 setverdict(fail, "Received unexpected BSSAP");
554 mtc.stop;
555 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100556 [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
557 setverdict(fail, "Unexpected GSUP UL REQ");
Daniel Willmannafce8662018-07-06 23:11:32 +0200558 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100559 }
Daniel Willmannafce8662018-07-06 23:11:32 +0200560 [] T.timeout {
561 setverdict(fail, "Timeout waiting for CM SERV REQ");
562 mtc.stop;
563 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100564 }
565
Harald Welte1ddc7162018-01-27 14:25:46 +0100566 f_expect_clear();
Harald Weltef6dd64d2017-11-19 12:09:51 +0100567}
Harald Weltea49e36e2018-01-21 19:29:33 +0100568testcase TC_cmserv_imsi_unknown() runs on MTC_CT {
569 var BSC_ConnHdlr vc_conn;
570 f_init();
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100571 vc_conn := f_start_handler(refers(f_tc_cmserv_imsi_unknown), 6);
Harald Weltea49e36e2018-01-21 19:29:33 +0100572 vc_conn.done;
573}
574
Harald Weltee13cfb22019-04-23 16:52:02 +0200575
576friend function f_tc_lu_and_mo_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100577 f_init_handler(pars);
Harald Welteb71901a2018-01-26 19:16:05 +0100578 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
579 cpars.bss_rtp_port := 1110;
580 cpars.mgcp_connection_id_bss := '22222'H;
581 cpars.mgcp_connection_id_mss := '33333'H;
Philipp Maierf1e02bb2018-03-15 16:30:00 +0100582 cpars.mgcp_ep := "rtpbridge/1@mgw";
Harald Welte2bb825f2018-01-22 11:31:18 +0100583
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100584 f_perform_lu();
Harald Welteb71901a2018-01-26 19:16:05 +0100585 f_mo_call(cpars);
Harald Welte2bb825f2018-01-22 11:31:18 +0100586}
587testcase TC_lu_and_mo_call() runs on MTC_CT {
588 var BSC_ConnHdlr vc_conn;
589 f_init();
590
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100591 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_call), 7);
Harald Welte071ed732018-01-23 19:53:52 +0100592 vc_conn.done;
593}
594
Harald Weltee13cfb22019-04-23 16:52:02 +0200595
Harald Welte071ed732018-01-23 19:53:52 +0100596/* Test LU (with authentication enabled), where HLR times out sending SAI response */
Harald Weltee13cfb22019-04-23 16:52:02 +0200597friend function f_tc_lu_auth_sai_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100598 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100599
600 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
601 var PDU_DTAP_MT dtap_mt;
602
603 /* tell GSUP dispatcher to send this IMSI to us */
604 f_create_gsup_expect(hex2str(g_pars.imsi));
605
606 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200607 f_cl3_or_initial_ue(l3_lu);
Harald Welte071ed732018-01-23 19:53:52 +0100608
609 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +0200610 if (pars.ran_is_geran) {
611 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
612 }
Harald Welte071ed732018-01-23 19:53:52 +0100613
614 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
615 /* The HLR would normally return an auth vector here, but we fail to do so. */
616
617 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100618 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100619}
620testcase TC_lu_auth_sai_timeout() runs on MTC_CT {
621 var BSC_ConnHdlr vc_conn;
622 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100623 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100624
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100625 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_timeout), 8);
Harald Welte071ed732018-01-23 19:53:52 +0100626 vc_conn.done;
627}
628
Harald Weltee13cfb22019-04-23 16:52:02 +0200629
Harald Welte071ed732018-01-23 19:53:52 +0100630/* Test LU (with authentication enabled), where HLR rejects sending SAI error */
Harald Weltee13cfb22019-04-23 16:52:02 +0200631friend function f_tc_lu_auth_sai_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100632 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100633
634 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
635 var PDU_DTAP_MT dtap_mt;
636
637 /* tell GSUP dispatcher to send this IMSI to us */
638 f_create_gsup_expect(hex2str(g_pars.imsi));
639
640 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200641 f_cl3_or_initial_ue(l3_lu);
Harald Welte071ed732018-01-23 19:53:52 +0100642
643 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +0200644 if (pars.ran_is_geran) {
645 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
646 }
Harald Welte071ed732018-01-23 19:53:52 +0100647
648 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
649 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 13));
650
651 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100652 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100653}
654testcase TC_lu_auth_sai_err() runs on MTC_CT {
655 var BSC_ConnHdlr vc_conn;
656 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100657 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100658
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100659 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_err), 9);
Harald Welte2bb825f2018-01-22 11:31:18 +0100660 vc_conn.done;
661}
Harald Weltea49e36e2018-01-21 19:29:33 +0100662
Harald Weltee13cfb22019-04-23 16:52:02 +0200663
Harald Weltebc881782018-01-23 20:09:15 +0100664/* Test LU but BSC will send a clear request in the middle */
665private function f_tc_lu_clear_request(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100666 f_init_handler(pars);
Harald Weltebc881782018-01-23 20:09:15 +0100667
668 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
669 var PDU_DTAP_MT dtap_mt;
670
671 /* tell GSUP dispatcher to send this IMSI to us */
672 f_create_gsup_expect(hex2str(g_pars.imsi));
673
674 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200675 f_cl3_or_initial_ue(l3_lu);
Harald Weltebc881782018-01-23 20:09:15 +0100676
677 /* Send Early Classmark, just for the fun of it */
678 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
679
680 f_sleep(1.0);
681 /* send clear request in the middle of the LU */
682 BSSAP.send(ts_BSSMAP_ClearRequest(0));
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200683 alt {
684 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { repeat; }
685 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {}
686 }
Harald Weltebc881782018-01-23 20:09:15 +0100687 BSSAP.send(ts_BSSMAP_ClearComplete);
Harald Welte89a32492018-01-27 19:07:28 +0100688 alt {
689 /* See https://osmocom.org/issues/2862 */
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200690 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
691 setverdict(fail, "Got a second Clear Command, only one expected");
Daniel Willmannafce8662018-07-06 23:11:32 +0200692 mtc.stop;
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200693 repeat;
694 }
Harald Welte6811d102019-04-14 22:23:14 +0200695 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte89a32492018-01-27 19:07:28 +0100696 }
Harald Weltebc881782018-01-23 20:09:15 +0100697 setverdict(pass);
698}
699testcase TC_lu_clear_request() runs on MTC_CT {
700 var BSC_ConnHdlr vc_conn;
701 f_init();
702
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100703 vc_conn := f_start_handler(refers(f_tc_lu_clear_request), 10);
Harald Weltebc881782018-01-23 20:09:15 +0100704 vc_conn.done;
705}
706
Harald Welte66af9e62018-01-24 17:28:21 +0100707/* Test LU but BSC will send a clear request in the middle */
Harald Weltee13cfb22019-04-23 16:52:02 +0200708friend function f_tc_lu_disconnect(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100709 f_init_handler(pars);
Harald Welte66af9e62018-01-24 17:28:21 +0100710
711 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
712 var PDU_DTAP_MT dtap_mt;
713
714 /* tell GSUP dispatcher to send this IMSI to us */
715 f_create_gsup_expect(hex2str(g_pars.imsi));
716
717 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200718 f_cl3_or_initial_ue(l3_lu);
Harald Welte66af9e62018-01-24 17:28:21 +0100719
720 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +0200721 if (pars.ran_is_geran) {
722 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
723 }
Harald Welte66af9e62018-01-24 17:28:21 +0100724
725 f_sleep(1.0);
726 /* send clear request in the middle of the LU */
Harald Welte6811d102019-04-14 22:23:14 +0200727 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Harald Welte66af9e62018-01-24 17:28:21 +0100728 setverdict(pass);
Neels Hofmeyrbb825c92019-03-06 15:35:50 +0100729 f_sleep(1.0);
Harald Welte66af9e62018-01-24 17:28:21 +0100730}
731testcase TC_lu_disconnect() runs on MTC_CT {
732 var BSC_ConnHdlr vc_conn;
733 f_init();
734
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100735 vc_conn := f_start_handler(refers(f_tc_lu_disconnect), 11);
Harald Welte66af9e62018-01-24 17:28:21 +0100736 vc_conn.done;
737}
738
Harald Welteba7b6d92018-01-23 21:32:34 +0100739/* Test LU but with illegal mobile identity type = IMEI */
Harald Weltee13cfb22019-04-23 16:52:02 +0200740friend function f_tc_lu_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100741 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100742
Harald Welte256571e2018-01-24 18:47:19 +0100743 var PDU_ML3_MS_NW l3_lu := f_build_lu_imei(g_pars.imei)
Harald Welteba7b6d92018-01-23 21:32:34 +0100744 var PDU_DTAP_MT dtap_mt;
745
746 /* tell GSUP dispatcher to send this IMSI to us */
747 f_create_gsup_expect(hex2str(g_pars.imsi));
748
749 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200750 f_cl3_or_initial_ue(l3_lu);
Harald Welteba7b6d92018-01-23 21:32:34 +0100751
752 /* Send Early Classmark, just for the fun of it */
Harald Weltee13cfb22019-04-23 16:52:02 +0200753 if (pars.ran_is_geran) {
754 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
755 }
Harald Welteba7b6d92018-01-23 21:32:34 +0100756 /* wait for LU reject, ignore any ID REQ */
757 alt {
758 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
759 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req)) { repeat; }
760 }
761 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100762 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100763}
764testcase TC_lu_by_imei() runs on MTC_CT {
765 var BSC_ConnHdlr vc_conn;
766 f_init();
767
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100768 vc_conn := f_start_handler(refers(f_tc_lu_by_imei), 12);
Harald Welteba7b6d92018-01-23 21:32:34 +0100769 vc_conn.done;
770}
771
Harald Weltee13cfb22019-04-23 16:52:02 +0200772
Harald Welteba7b6d92018-01-23 21:32:34 +0100773/* Test LU by TMSI with unknown TMSI, expect (and answer) ID REQ. */
774private function f_tc_lu_tmsi_noauth_unknown(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Stefan Sperling04fc4bc2018-06-25 17:44:57 +0200775 /* We piggyback a test for an MSC crash on overlong IMSI (OS#2864) onto this test. */
776 var hexstring overlong_imsi := '012345789ABCDEF0123456789ABCDEF'H;
Harald Weltea10db902018-01-27 12:44:49 +0100777 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100778
779 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('01020304'O); /* FIXME: Random */
780 var PDU_DTAP_MT dtap_mt;
781
782 /* tell GSUP dispatcher to send this IMSI to us */
783 f_create_gsup_expect(hex2str(g_pars.imsi));
784
785 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200786 f_cl3_or_initial_ue(l3_lu);
Harald Welteba7b6d92018-01-23 21:32:34 +0100787
788 /* Send Early Classmark, just for the fun of it */
789 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
790
791 /* Wait for + respond to ID REQ (IMSI) */
792 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req('001'B)));
Stefan Sperling04fc4bc2018-06-25 17:44:57 +0200793 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 +0100794 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
795
796 /* Expect MSC to do UpdateLocation to HLR; respond to it */
797 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
798 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
799 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
800 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
801
802 alt {
Harald Welte7ec4fa82018-01-27 10:57:40 +0100803 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
804 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
805 }
Harald Welteba7b6d92018-01-23 21:32:34 +0100806 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
807 setverdict(fail, "Expected LU ACK, but received REJ");
Daniel Willmannafce8662018-07-06 23:11:32 +0200808 mtc.stop;
Harald Welteba7b6d92018-01-23 21:32:34 +0100809 }
810 }
811
Philipp Maier9b690e42018-12-21 11:50:03 +0100812 /* Wait for MM-Information (if enabled) */
813 f_expect_mm_info();
814
Harald Welteba7b6d92018-01-23 21:32:34 +0100815 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100816 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100817}
818testcase TC_lu_by_tmsi_noauth_unknown() runs on MTC_CT {
819 var BSC_ConnHdlr vc_conn;
820 f_init();
821
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100822 vc_conn := f_start_handler(refers(f_tc_lu_tmsi_noauth_unknown), 13);
Harald Welteba7b6d92018-01-23 21:32:34 +0100823 vc_conn.done;
824}
825
826
Harald Welte45164da2018-01-24 12:51:27 +0100827/* Test IMSI DETACH (MI=IMSI) */
Harald Weltee13cfb22019-04-23 16:52:02 +0200828friend function f_tc_imsi_detach_by_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100829 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100830
831 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
832
833 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200834 f_cl3_or_initial_ue(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
Harald Welte45164da2018-01-24 12:51:27 +0100835
836 /* Send Early Classmark, just for the fun of it? */
Harald Weltee13cfb22019-04-23 16:52:02 +0200837 if (pars.ran_is_geran) {
838 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
839 }
Harald Welte45164da2018-01-24 12:51:27 +0100840
841 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100842 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100843}
844testcase TC_imsi_detach_by_imsi() runs on MTC_CT {
845 var BSC_ConnHdlr vc_conn;
846 f_init();
847
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100848 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imsi), 14);
Harald Welte45164da2018-01-24 12:51:27 +0100849 vc_conn.done;
850}
851
Harald Weltee13cfb22019-04-23 16:52:02 +0200852
Harald Welte45164da2018-01-24 12:51:27 +0100853/* Test IMSI DETACH (MI=TMSI) */
Harald Weltee13cfb22019-04-23 16:52:02 +0200854friend function f_tc_imsi_detach_by_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100855 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100856
857 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('01020304'O));
858
859 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200860 f_cl3_or_initial_ue(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
Harald Welte45164da2018-01-24 12:51:27 +0100861
862 /* Send Early Classmark, just for the fun of it? */
Harald Weltee13cfb22019-04-23 16:52:02 +0200863 if (pars.ran_is_geran) {
864 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
865 }
Harald Welte45164da2018-01-24 12:51:27 +0100866
867 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100868 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100869}
870testcase TC_imsi_detach_by_tmsi() runs on MTC_CT {
871 var BSC_ConnHdlr vc_conn;
872 f_init();
873
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100874 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_tmsi), 15);
Harald Welte45164da2018-01-24 12:51:27 +0100875 vc_conn.done;
876}
877
Harald Weltee13cfb22019-04-23 16:52:02 +0200878
Harald Welte45164da2018-01-24 12:51:27 +0100879/* Test IMSI DETACH (MI=IMEI), which is illegal */
Harald Weltee13cfb22019-04-23 16:52:02 +0200880friend function f_tc_imsi_detach_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100881 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100882
Harald Welte256571e2018-01-24 18:47:19 +0100883 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte45164da2018-01-24 12:51:27 +0100884
885 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +0200886 f_cl3_or_initial_ue(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
Harald Welte45164da2018-01-24 12:51:27 +0100887
888 /* Send Early Classmark, just for the fun of it? */
Harald Weltee13cfb22019-04-23 16:52:02 +0200889 if (pars.ran_is_geran) {
890 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
891 }
Harald Welte45164da2018-01-24 12:51:27 +0100892
893 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100894 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100895}
896testcase TC_imsi_detach_by_imei() runs on MTC_CT {
897 var BSC_ConnHdlr vc_conn;
898 f_init();
899
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100900 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imei), 16);
Harald Welte45164da2018-01-24 12:51:27 +0100901 vc_conn.done;
902}
903
904
905/* helper function for an emergency call. caller passes in mobile identity to use */
906private function f_emerg_call(MobileIdentityLV mi) runs on BSC_ConnHdlr {
Harald Welte0bef21e2018-02-10 09:48:23 +0100907 var CallParameters cpars := valueof(t_CallParams('112'H, 0));
908 cpars.emergency := true;
Philipp Maierf1e02bb2018-03-15 16:30:00 +0100909 cpars.mgcp_ep := "rtpbridge/1@mgw";
Harald Welte45164da2018-01-24 12:51:27 +0100910
Harald Welte0bef21e2018-02-10 09:48:23 +0100911 f_mo_call(cpars);
Harald Welte45164da2018-01-24 12:51:27 +0100912}
913
914/* establish an emergency call by IMEI, no SIM inserted (and hence no IMSI) */
Harald Weltee13cfb22019-04-23 16:52:02 +0200915friend function f_tc_emerg_call_imei_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100916 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100917
Harald Welte256571e2018-01-24 18:47:19 +0100918 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100919 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Weltedceacc72019-04-21 20:58:35 +0200920 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +0100921 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ('05'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +0100922 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100923}
924testcase TC_emerg_call_imei_reject() runs on MTC_CT {
925 var BSC_ConnHdlr vc_conn;
926 f_init();
927
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100928 vc_conn := f_start_handler(refers(f_tc_emerg_call_imei_reject), 17);
Harald Welte45164da2018-01-24 12:51:27 +0100929 vc_conn.done;
930}
931
Harald Weltee13cfb22019-04-23 16:52:02 +0200932
Harald Welted5b91402018-01-24 18:48:16 +0100933/* establish an emergency call by IMSI, SIM inserted (and hence IMSI) */
Harald Weltee13cfb22019-04-23 16:52:02 +0200934friend function f_tc_emerg_call_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100935 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100936 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100937 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +0100938 /* Then issue emergency call identified by IMSI */
939 f_emerg_call(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
940}
941testcase TC_emerg_call_imsi() runs on MTC_CT {
942 var BSC_ConnHdlr vc_conn;
943 f_init();
944
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100945 vc_conn := f_start_handler(refers(f_tc_emerg_call_imsi), 18);
Harald Welte45164da2018-01-24 12:51:27 +0100946 vc_conn.done;
947}
948
Harald Weltee13cfb22019-04-23 16:52:02 +0200949
Harald Welte45164da2018-01-24 12:51:27 +0100950/* CM Service Request for VGCS -> reject */
951private function f_tc_cm_serv_req_vgcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100952 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100953
954 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100955 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +0100956
957 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100958 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VGCS, mi));
Harald Weltedceacc72019-04-21 20:58:35 +0200959 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +0100960 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100961 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100962}
963testcase TC_cm_serv_req_vgcs_reject() runs on MTC_CT {
964 var BSC_ConnHdlr vc_conn;
965 f_init();
966
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100967 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vgcs_reject), 19);
Harald Welte45164da2018-01-24 12:51:27 +0100968 vc_conn.done;
969}
970
971/* CM Service Request for VBS -> reject */
972private function f_tc_cm_serv_req_vbs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100973 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100974
975 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100976 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +0100977
978 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100979 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VBS, mi));
Harald Weltedceacc72019-04-21 20:58:35 +0200980 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +0100981 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100982 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100983}
984testcase TC_cm_serv_req_vbs_reject() runs on MTC_CT {
985 var BSC_ConnHdlr vc_conn;
986 f_init();
987
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100988 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vbs_reject), 20);
Harald Welte45164da2018-01-24 12:51:27 +0100989 vc_conn.done;
990}
991
992/* CM Service Request for LCS -> reject */
993private function f_tc_cm_serv_req_lcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100994 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100995
996 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100997 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +0100998
999 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001000 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_LCS, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001001 f_cl3_or_initial_ue(l3_info);
Harald Welte45164da2018-01-24 12:51:27 +01001002 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001003 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001004}
1005testcase TC_cm_serv_req_lcs_reject() runs on MTC_CT {
1006 var BSC_ConnHdlr vc_conn;
1007 f_init();
1008
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001009 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_lcs_reject), 21);
Harald Welte45164da2018-01-24 12:51:27 +01001010 vc_conn.done;
1011}
1012
Harald Welte0195ab12018-01-24 21:50:20 +01001013/* CM Re-Establishment Request */
1014private function f_tc_cm_reest_req_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001015 f_init_handler(pars);
Harald Welte0195ab12018-01-24 21:50:20 +01001016
1017 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001018 f_perform_lu();
Harald Welte0195ab12018-01-24 21:50:20 +01001019
1020 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1021 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REEST_REQ(0, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001022 f_cl3_or_initial_ue(l3_info);
Harald Welte0195ab12018-01-24 21:50:20 +01001023 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001024 f_expect_clear();
Harald Welte0195ab12018-01-24 21:50:20 +01001025}
1026testcase TC_cm_reest_req_reject() runs on MTC_CT {
1027 var BSC_ConnHdlr vc_conn;
1028 f_init();
Harald Welte0195ab12018-01-24 21:50:20 +01001029
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001030 vc_conn := f_start_handler(refers(f_tc_cm_reest_req_reject), 22);
Harald Welte0195ab12018-01-24 21:50:20 +01001031 vc_conn.done;
1032}
1033
Harald Weltec638f4d2018-01-24 22:00:36 +01001034/* Test LU (with authentication enabled), with wrong response from MS */
1035private function f_tc_lu_auth_2G_fail(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001036 f_init_handler(pars);
Harald Weltec638f4d2018-01-24 22:00:36 +01001037
1038 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
1039
1040 /* tell GSUP dispatcher to send this IMSI to us */
1041 f_create_gsup_expect(hex2str(g_pars.imsi));
1042
1043 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
Harald Weltedceacc72019-04-21 20:58:35 +02001044 f_cl3_or_initial_ue(l3_lu);
Harald Weltec638f4d2018-01-24 22:00:36 +01001045
1046 /* Send Early Classmark, just for the fun of it */
1047 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1048
1049 var AuthVector vec := f_gen_auth_vec_2g();
1050 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(vec.rand, vec.sres, vec.kc));
1051 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
1052 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
1053
1054 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(vec.rand)));
1055 /* Send back wrong auth response */
1056 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G('00000000'O)));
1057
1058 /* Expect GSUP AUTH FAIL REP to HLR */
1059 GSUP.receive(tr_GSUP_AUTH_FAIL_IND(g_pars.imsi));
1060
1061 /* Expect LU REJECT with Cause == Illegal MS */
1062 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej('03'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +01001063 f_expect_clear();
Harald Weltec638f4d2018-01-24 22:00:36 +01001064}
1065testcase TC_lu_auth_2G_fail() runs on MTC_CT {
1066 var BSC_ConnHdlr vc_conn;
1067 f_init();
1068 f_vty_config(MSCVTY, "network", "authentication required");
Harald Weltec638f4d2018-01-24 22:00:36 +01001069
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001070 vc_conn := f_start_handler(refers(f_tc_lu_auth_2G_fail), 23);
Harald Weltec638f4d2018-01-24 22:00:36 +01001071 vc_conn.done;
1072}
1073
Harald Weltede371492018-01-27 23:44:41 +01001074/* A5/1 + A5/3 permitted on network side, and MS capable to do it */
Harald Welte16114282018-01-24 22:41:21 +01001075private 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 +01001076 pars.net.expect_auth := true;
1077 pars.net.expect_ciph := true;
Harald Weltea10db902018-01-27 12:44:49 +01001078 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001079 f_perform_lu();
Harald Welte16114282018-01-24 22:41:21 +01001080}
1081testcase TC_lu_imsi_auth_tmsi_encr_13_13() runs on MTC_CT {
1082 var BSC_ConnHdlr vc_conn;
1083 f_init();
1084 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte16114282018-01-24 22:41:21 +01001085 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1086
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001087 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_13), 24);
Harald Welte16114282018-01-24 22:41:21 +01001088 vc_conn.done;
1089}
1090
Harald Welte1af6ea82018-01-25 18:33:15 +01001091/* Test Complete L3 without payload */
1092private function f_tc_cl3_no_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001093 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001094
1095 /* Send Complete L3 Info with empty L3 frame */
1096 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1097 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, ''O))));
1098
Harald Weltef466eb42018-01-27 14:26:54 +01001099 timer T := 5.0;
1100 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001101 alt {
Harald Welte6811d102019-04-14 22:23:14 +02001102 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte1af6ea82018-01-25 18:33:15 +01001103 /* Expect LU REJECT with Cause == Illegal MS */
Harald Weltebdb3c452018-03-18 22:43:06 +01001104 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
Harald Welte6811d102019-04-14 22:23:14 +02001105 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001106 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001107 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001108 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Daniel Willmannafce8662018-07-06 23:11:32 +02001109 mtc.stop;
Harald Weltef466eb42018-01-27 14:26:54 +01001110 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001111 }
1112 setverdict(pass);
1113}
1114testcase TC_cl3_no_payload() runs on MTC_CT {
1115 var BSC_ConnHdlr vc_conn;
1116 f_init();
1117
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001118 vc_conn := f_start_handler(refers(f_tc_cl3_no_payload), 25);
Harald Welte1af6ea82018-01-25 18:33:15 +01001119 vc_conn.done;
1120}
1121
1122/* Test Complete L3 with random payload */
1123private function f_tc_cl3_rnd_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001124 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001125
Daniel Willmannaa14a382018-07-26 08:29:45 +02001126 /* length is limited by PDU_BSSAP length field which includes some
1127 * other fields beside l3info payload. So payl can only be 240 bytes
1128 * Since rnd() returns values < 1 multiply with 241
1129 */
1130 var integer len := float2int(rnd() * 241.0);
Harald Welte1af6ea82018-01-25 18:33:15 +01001131 var octetstring payl := f_rnd_octstring(len);
1132
1133 /* Send Complete L3 Info with empty L3 frame */
1134 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1135 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, payl))));
1136
Harald Weltef466eb42018-01-27 14:26:54 +01001137 timer T := 5.0;
1138 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001139 alt {
1140 /* Immediate disconnect */
Harald Welte6811d102019-04-14 22:23:14 +02001141 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte1af6ea82018-01-25 18:33:15 +01001142 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
Harald Welte6811d102019-04-14 22:23:14 +02001143 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001144 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001145 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001146 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Daniel Willmannafce8662018-07-06 23:11:32 +02001147 mtc.stop;
Harald Weltef466eb42018-01-27 14:26:54 +01001148 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001149 }
1150 setverdict(pass);
1151}
1152testcase TC_cl3_rnd_payload() runs on MTC_CT {
1153 var BSC_ConnHdlr vc_conn;
1154 f_init();
1155
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001156 vc_conn := f_start_handler(refers(f_tc_cl3_rnd_payload), 26);
Harald Welte1af6ea82018-01-25 18:33:15 +01001157 vc_conn.done;
1158}
1159
Harald Welte116e4332018-01-26 22:17:48 +01001160/* Test Complete L3 with random payload */
Harald Weltee13cfb22019-04-23 16:52:02 +02001161friend function f_tc_establish_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001162 f_init_handler(pars);
Harald Welte116e4332018-01-26 22:17:48 +01001163
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001164 f_perform_lu();
Harald Welte116e4332018-01-26 22:17:48 +01001165
Harald Welteb9e86fa2018-04-09 18:18:31 +02001166 f_establish_fully();
Daniel Willmann898a7e02018-05-17 12:16:16 +02001167 f_expect_clear(10.0);
Harald Welte116e4332018-01-26 22:17:48 +01001168}
1169testcase TC_establish_and_nothing() runs on MTC_CT {
1170 var BSC_ConnHdlr vc_conn;
1171 f_init();
1172
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001173 vc_conn := f_start_handler(refers(f_tc_establish_and_nothing), 27);
Harald Welte116e4332018-01-26 22:17:48 +01001174 vc_conn.done;
1175}
1176
Harald Weltee13cfb22019-04-23 16:52:02 +02001177
Harald Welte12510c52018-01-26 22:26:24 +01001178/* Test MO Call SETUP with no response from MNCC */
Harald Weltee13cfb22019-04-23 16:52:02 +02001179friend function f_tc_mo_setup_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Philipp Maier109e6aa2018-10-17 10:53:32 +02001180 f_init_handler(pars, 190.0);
Harald Weltea10db902018-01-27 12:44:49 +01001181
Harald Welte12510c52018-01-26 22:26:24 +01001182 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1183
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001184 f_perform_lu();
Harald Welte12510c52018-01-26 22:26:24 +01001185
Harald Welteb9e86fa2018-04-09 18:18:31 +02001186 f_establish_fully();
Harald Welte12510c52018-01-26 22:26:24 +01001187 f_create_mncc_expect(hex2str(cpars.called_party));
1188 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1189
1190 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1191
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001192 var default ccrel := activate(as_optional_cc_rel(cpars));
1193
Philipp Maier109e6aa2018-10-17 10:53:32 +02001194 f_expect_clear(185.0);
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001195
1196 deactivate(ccrel);
1197
1198 f_sleep(1.0);
Harald Welte12510c52018-01-26 22:26:24 +01001199}
1200testcase TC_mo_setup_and_nothing() runs on MTC_CT {
1201 var BSC_ConnHdlr vc_conn;
1202 f_init();
1203
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001204 vc_conn := f_start_handler(refers(f_tc_mo_setup_and_nothing), 28);
Harald Welte12510c52018-01-26 22:26:24 +01001205 vc_conn.done;
1206}
1207
Harald Weltee13cfb22019-04-23 16:52:02 +02001208
Harald Welte3ab88002018-01-26 22:37:25 +01001209/* Test MO Call with no response to RAN-side CRCX */
Harald Weltee13cfb22019-04-23 16:52:02 +02001210friend function f_tc_mo_crcx_ran_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001211 f_init_handler(pars);
Harald Welte3ab88002018-01-26 22:37:25 +01001212 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1213 var MNCC_PDU mncc;
1214 var MgcpCommand mgcp_cmd;
1215
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001216 f_perform_lu();
Harald Welte3ab88002018-01-26 22:37:25 +01001217
Harald Welteb9e86fa2018-04-09 18:18:31 +02001218 f_establish_fully();
Harald Welte3ab88002018-01-26 22:37:25 +01001219 f_create_mncc_expect(hex2str(cpars.called_party));
1220 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1221
1222 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1223 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1224 cpars.mncc_callref := mncc.u.signal.callref;
1225 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1226 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1227
1228 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
Harald Welte1852a842018-01-26 22:53:36 +01001229 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1230 cpars.mgcp_ep := mgcp_cmd.line.ep;
Harald Welte3ab88002018-01-26 22:37:25 +01001231 /* never respond to this */
1232
Philipp Maier8e58f592018-03-14 11:10:56 +01001233 /* When the connection with the MGW fails, the MSC will first request
1234 * a release via call control. We will answer this request normally. */
1235 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1236 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1237
Harald Welte1ddc7162018-01-27 14:25:46 +01001238 f_expect_clear(30.0);
Harald Welte3ab88002018-01-26 22:37:25 +01001239}
1240testcase TC_mo_crcx_ran_timeout() runs on MTC_CT {
1241 var BSC_ConnHdlr vc_conn;
1242 f_init();
1243
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001244 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_timeout), 29);
Harald Welte3ab88002018-01-26 22:37:25 +01001245 vc_conn.done;
1246}
1247
Harald Weltee13cfb22019-04-23 16:52:02 +02001248
Harald Welte0cc82d92018-01-26 22:52:34 +01001249/* Test MO Call with reject to RAN-side CRCX */
Harald Weltee13cfb22019-04-23 16:52:02 +02001250friend function f_tc_mo_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001251 f_init_handler(pars);
Harald Welte0cc82d92018-01-26 22:52:34 +01001252 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1253 var MNCC_PDU mncc;
1254 var MgcpCommand mgcp_cmd;
1255
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001256 f_perform_lu();
Harald Welte0cc82d92018-01-26 22:52:34 +01001257
Harald Welteb9e86fa2018-04-09 18:18:31 +02001258 f_establish_fully();
Harald Welte0cc82d92018-01-26 22:52:34 +01001259 f_create_mncc_expect(hex2str(cpars.called_party));
1260 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1261
1262 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1263 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1264 cpars.mncc_callref := mncc.u.signal.callref;
1265 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1266 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1267
1268 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001269
1270 /* Detect if the received CRCX is a wildcarded CRCX request. If yes,
1271 * set an endpoint name that fits the pattern. If not, just use the
1272 * endpoint name from the request */
1273 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
1274 cpars.mgcp_ep := "rtpbridge/1@mgw";
1275 } else {
1276 cpars.mgcp_ep := mgcp_cmd.line.ep;
1277 }
1278
Harald Welte0cc82d92018-01-26 22:52:34 +01001279 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001280
Harald Welte0cc82d92018-01-26 22:52:34 +01001281 /* Respond to CRCX with error */
1282 var MgcpResponse mgcp_rsp := {
1283 line := {
1284 code := "542",
1285 trans_id := mgcp_cmd.line.trans_id,
1286 string := "FORCED_FAIL"
1287 },
Harald Welte0cc82d92018-01-26 22:52:34 +01001288 sdp := omit
1289 }
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001290 var MgcpParameter mgcp_rsp_param := {
1291 code := "Z",
1292 val := cpars.mgcp_ep
1293 };
1294 mgcp_rsp.params[0] := mgcp_rsp_param;
Harald Welte0cc82d92018-01-26 22:52:34 +01001295 MGCP.send(mgcp_rsp);
1296
1297 timer T := 30.0;
1298 T.start;
1299 alt {
Daniel Willmannafce8662018-07-06 23:11:32 +02001300 [] T.timeout {
1301 setverdict(fail, "Timeout waiting for channel release");
1302 mtc.stop;
1303 }
Daniel Willmann5868e622018-02-15 17:42:59 +01001304 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id))) {
1305 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1306 repeat;
1307 }
Harald Welte0cc82d92018-01-26 22:52:34 +01001308 [] MNCC.receive { repeat; }
1309 [] GSUP.receive { repeat; }
Philipp Maierc6e06f72018-04-11 18:12:23 +02001310 /* Note: As we did not respond properly to the CRCX from the MSC we
1311 * expect the MSC to omit any further MGCP operation (At least in the
1312 * the current implementation, there is no recovery mechanism implemented
1313 * and a DLCX can not be performed as the MSC does not know a specific
1314 * endpoint yet. */
Daniel Willmannafce8662018-07-06 23:11:32 +02001315 [] MGCP.receive {
1316 setverdict(fail, "Unexpected MGCP message");
1317 mtc.stop;
1318 }
Harald Welte5946b332018-03-18 23:32:21 +01001319 [] as_clear_cmd_compl_disc();
Harald Welte0cc82d92018-01-26 22:52:34 +01001320 }
1321}
1322testcase TC_mo_crcx_ran_reject() runs on MTC_CT {
1323 var BSC_ConnHdlr vc_conn;
1324 f_init();
1325
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001326 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_reject), 30);
Harald Welte0cc82d92018-01-26 22:52:34 +01001327 vc_conn.done;
1328}
1329
Harald Welte3ab88002018-01-26 22:37:25 +01001330
Harald Welte812f7a42018-01-27 00:49:18 +01001331/* helper function to start a MT call: MNCC SETUP; Paging; DChan est.; DTAP SETUP */
1332private function f_mt_call_start(inout CallParameters cpars) runs on BSC_ConnHdlr {
1333 var MNCC_PDU mncc;
1334 var MgcpCommand mgcp_cmd;
1335 var OCT4 tmsi;
1336
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001337 f_perform_lu();
Harald Welte812f7a42018-01-27 00:49:18 +01001338 if (isvalue(g_pars.tmsi)) {
1339 tmsi := g_pars.tmsi;
1340 } else {
1341 tmsi := 'FFFFFFFF'O;
1342 }
Harald Welte6811d102019-04-14 22:23:14 +02001343 f_ran_register_imsi(g_pars.imsi, tmsi);
Harald Welte812f7a42018-01-27 00:49:18 +01001344
1345 /* Allocate call reference and send SETUP via MNCC to MSC */
1346 cpars.mncc_callref := f_rnd_int(2147483648);
1347 MNCC.send(ts_MNCC_SETUP_req(cpars.mncc_callref, hex2str(g_pars.msisdn),
1348 hex2str(cpars.called_party), hex2str(g_pars.imsi)));
1349
1350 /* MSC->BSC: expect PAGING from MSC */
Harald Weltee035e3e2019-04-21 17:32:05 +02001351 f_expect_paging();
1352
Harald Welte812f7a42018-01-27 00:49:18 +01001353 /* MS -> MSC: PAGING RESPONSE */
Harald Welteb9e86fa2018-04-09 18:18:31 +02001354 f_establish_fully(EST_TYPE_PAG_RESP);
Harald Welte812f7a42018-01-27 00:49:18 +01001355
1356 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1357
1358 /* MSC->MS: SETUP */
1359 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party)));
1360}
1361
1362/* Test MT Call */
Harald Weltee13cfb22019-04-23 16:52:02 +02001363friend function f_tc_mt_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001364 f_init_handler(pars);
Harald Welte812f7a42018-01-27 00:49:18 +01001365 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1366 var MNCC_PDU mncc;
1367 var MgcpCommand mgcp_cmd;
1368
1369 f_mt_call_start(cpars);
1370
1371 /* MS->MSC: CALL CONFIRMED */
1372 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1373
1374 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1375
1376 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1377 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001378
1379 /* Detect if the received CRCX is a wildcarded CRCX request. If yes,
1380 * set an endpoint name that fits the pattern. If not, just use the
1381 * endpoint name from the request */
1382 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
1383 cpars.mgcp_ep := "rtpbridge/1@mgw";
1384 } else {
1385 cpars.mgcp_ep := mgcp_cmd.line.ep;
1386 }
1387
Harald Welte812f7a42018-01-27 00:49:18 +01001388 /* Respond to CRCX with error */
1389 var MgcpResponse mgcp_rsp := {
1390 line := {
1391 code := "542",
1392 trans_id := mgcp_cmd.line.trans_id,
1393 string := "FORCED_FAIL"
1394 },
Harald Welte812f7a42018-01-27 00:49:18 +01001395 sdp := omit
1396 }
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001397 var MgcpParameter mgcp_rsp_param := {
1398 code := "Z",
1399 val := cpars.mgcp_ep
1400 };
1401 mgcp_rsp.params[0] := mgcp_rsp_param;
Harald Welte812f7a42018-01-27 00:49:18 +01001402 MGCP.send(mgcp_rsp);
1403
1404 timer T := 30.0;
1405 T.start;
1406 alt {
Daniel Willmannafce8662018-07-06 23:11:32 +02001407 [] T.timeout {
1408 setverdict(fail, "Timeout waiting for channel release");
1409 mtc.stop;
1410 }
Harald Welte812f7a42018-01-27 00:49:18 +01001411 [] MNCC.receive { repeat; }
1412 [] GSUP.receive { repeat; }
1413 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1414 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1415 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1416 repeat;
1417 }
1418 [] MGCP.receive { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001419 [] as_clear_cmd_compl_disc();
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001420 [] as_optional_cc_rel(cpars);
Harald Welte812f7a42018-01-27 00:49:18 +01001421 }
1422}
1423testcase TC_mt_crcx_ran_reject() runs on MTC_CT {
1424 var BSC_ConnHdlr vc_conn;
1425 f_init();
1426
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001427 vc_conn := f_start_handler(refers(f_tc_mt_crcx_ran_reject), 31);
Harald Welte812f7a42018-01-27 00:49:18 +01001428 vc_conn.done;
1429}
1430
1431
Harald Weltee13cfb22019-04-23 16:52:02 +02001432
Harald Welte812f7a42018-01-27 00:49:18 +01001433/* Test MT Call T310 timer */
Harald Weltee13cfb22019-04-23 16:52:02 +02001434friend function f_tc_mt_t310(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltead2952e2018-01-27 14:12:46 +01001435 f_init_handler(pars, 200.0);
Harald Welte812f7a42018-01-27 00:49:18 +01001436 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1437 var MNCC_PDU mncc;
1438 var MgcpCommand mgcp_cmd;
1439
1440 f_mt_call_start(cpars);
1441
1442 /* MS->MSC: CALL CONFIRMED */
1443 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1444 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1445
1446 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1447 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1448 cpars.mgcp_ep := mgcp_cmd.line.ep;
1449 /* FIXME: Respond to CRCX */
1450
1451 /* old libosmocore T310 default timeout is 180s. so let's wait 190 */
1452 timer T := 190.0;
1453 T.start;
1454 alt {
Daniel Willmannafce8662018-07-06 23:11:32 +02001455 [] T.timeout {
1456 setverdict(fail, "Timeout waiting for T310");
1457 mtc.stop;
1458 }
Harald Welte812f7a42018-01-27 00:49:18 +01001459 [] MNCC.receive(tr_MNCC_DISC_ind(cpars.mncc_callref)) {
1460 MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(23))));
1461 }
1462 }
1463 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));
1464 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1465 /* FIXME: We're sending this with TIflag 0: allocated by sender, which is wrong */
1466 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1467
1468 alt {
Harald Welte812f7a42018-01-27 00:49:18 +01001469 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1470 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1471 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1472 repeat;
1473 }
Harald Welte5946b332018-03-18 23:32:21 +01001474 [] as_clear_cmd_compl_disc();
Harald Welte812f7a42018-01-27 00:49:18 +01001475 }
1476}
1477testcase TC_mt_t310() runs on MTC_CT {
1478 var BSC_ConnHdlr vc_conn;
1479 f_init();
1480
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001481 vc_conn := f_start_handler(refers(f_tc_mt_t310), 32);
Harald Welte812f7a42018-01-27 00:49:18 +01001482 vc_conn.done;
1483}
1484
Harald Weltee13cfb22019-04-23 16:52:02 +02001485
Harald Welte167458a2018-01-27 15:58:16 +01001486/* Perform successful LU + MO call, then GSUP LocationCancel. Subscriber must be denied CM SERV */
Harald Weltee13cfb22019-04-23 16:52:02 +02001487friend function f_tc_gsup_cancel(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Welte167458a2018-01-27 15:58:16 +01001488 f_init_handler(pars);
1489 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1490 cpars.bss_rtp_port := 1110;
1491 cpars.mgcp_connection_id_bss := '22222'H;
1492 cpars.mgcp_connection_id_mss := '33333'H;
Daniel Willmann9b0235b2018-07-24 12:13:34 +02001493 cpars.mgcp_ep := "rtpbridge/1@mgw";
Harald Welte167458a2018-01-27 15:58:16 +01001494
1495 /* Location Update to make subscriber known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001496 f_perform_lu();
Harald Welte167458a2018-01-27 15:58:16 +01001497
1498 /* First MO call should succeed */
1499 f_mo_call(cpars);
1500
1501 /* Cancel the subscriber in the VLR */
1502 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1503 alt {
1504 [] GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi)) { }
1505 [] GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi)) {
1506 setverdict(fail, "Received GSUP Location Cancel Error");
Daniel Willmannafce8662018-07-06 23:11:32 +02001507 mtc.stop;
Harald Welte167458a2018-01-27 15:58:16 +01001508 }
1509 }
1510
1511 /* Follow-up transactions should fail */
1512 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1513 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltedceacc72019-04-21 20:58:35 +02001514 f_cl3_or_initial_ue(l3_info);
Harald Welte167458a2018-01-27 15:58:16 +01001515 alt {
1516 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
1517 [] BSSAP.receive {
1518 setverdict(fail, "Received unexpected BSSAP instead of CM SERV REJ");
Daniel Willmannafce8662018-07-06 23:11:32 +02001519 mtc.stop;
Harald Welte167458a2018-01-27 15:58:16 +01001520 }
1521 }
Neels Hofmeyr0f7429a2019-03-07 22:28:41 +01001522
1523 f_expect_clear();
Harald Welte167458a2018-01-27 15:58:16 +01001524 setverdict(pass);
1525}
1526testcase TC_gsup_cancel() runs on MTC_CT {
1527 var BSC_ConnHdlr vc_conn;
1528 f_init();
1529
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001530 vc_conn := f_start_handler(refers(f_tc_gsup_cancel), 33);
Harald Welte167458a2018-01-27 15:58:16 +01001531 vc_conn.done;
1532}
1533
Harald Weltee13cfb22019-04-23 16:52:02 +02001534
Harald Welte9de84792018-01-28 01:06:35 +01001535/* A5/1 only permitted on network side, and MS capable to do it */
1536private function f_tc_lu_imsi_auth_tmsi_encr_1_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1537 pars.net.expect_auth := true;
1538 pars.net.expect_ciph := true;
1539 pars.net.kc_support := '02'O; /* A5/1 only */
1540 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001541 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001542}
1543testcase TC_lu_imsi_auth_tmsi_encr_1_13() runs on MTC_CT {
1544 var BSC_ConnHdlr vc_conn;
1545 f_init();
1546 f_vty_config(MSCVTY, "network", "authentication required");
1547 f_vty_config(MSCVTY, "network", "encryption a5 1");
1548
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001549 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_1_13), 34);
Harald Welte9de84792018-01-28 01:06:35 +01001550 vc_conn.done;
1551}
1552
1553/* A5/3 only permitted on network side, and MS capable to do it */
1554private function f_tc_lu_imsi_auth_tmsi_encr_3_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1555 pars.net.expect_auth := true;
1556 pars.net.expect_ciph := true;
1557 pars.net.kc_support := '08'O; /* A5/3 only */
1558 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001559 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001560}
1561testcase TC_lu_imsi_auth_tmsi_encr_3_13() runs on MTC_CT {
1562 var BSC_ConnHdlr vc_conn;
1563 f_init();
1564 f_vty_config(MSCVTY, "network", "authentication required");
1565 f_vty_config(MSCVTY, "network", "encryption a5 3");
1566
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001567 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_13), 35);
Harald Welte9de84792018-01-28 01:06:35 +01001568 vc_conn.done;
1569}
1570
1571/* A5/3 only permitted on network side, and MS with only A5/1 support */
1572private function f_tc_lu_imsi_auth_tmsi_encr_3_1(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1573 pars.net.expect_auth := true;
1574 pars.net.expect_ciph := true;
1575 pars.net.kc_support := '08'O; /* A5/3 only */
1576 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1577 f_init_handler(pars, 15.0);
1578
1579 /* cannot use f_perform_lu() as we expect a reject */
1580 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1581 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +02001582 f_cl3_or_initial_ue(l3_lu);
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001583 if (pars.send_early_cm) {
1584 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1585 } else {
1586 pars.cm1.esind := '0'B;
1587 }
Harald Welte9de84792018-01-28 01:06:35 +01001588 f_mm_auth();
1589 alt {
Daniel Willmann52918e52018-09-20 14:39:09 +02001590 [] BSSAP.receive(tr_BSSMAP_ClassmarkReq) {
1591 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1592 repeat;
1593 }
Harald Welte5946b332018-03-18 23:32:21 +01001594 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1595 f_expect_clear();
1596 }
Harald Welte9de84792018-01-28 01:06:35 +01001597 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1598 setverdict(fail, "CipherModeCommand despite no A5 intersection");
Daniel Willmannafce8662018-07-06 23:11:32 +02001599 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001600 }
1601 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001602 setverdict(fail, "Unknown/unexpected BSSAP received");
Daniel Willmannafce8662018-07-06 23:11:32 +02001603 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001604 }
1605 }
1606 setverdict(pass);
1607}
1608testcase TC_lu_imsi_auth_tmsi_encr_3_1() runs on MTC_CT {
1609 var BSC_ConnHdlr vc_conn;
1610 f_init();
1611 f_vty_config(MSCVTY, "network", "authentication required");
1612 f_vty_config(MSCVTY, "network", "encryption a5 3");
1613
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001614 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 360);
1615 vc_conn.done;
1616}
1617testcase TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() runs on MTC_CT {
1618 var BSC_ConnHdlrPars pars;
1619 var BSC_ConnHdlr vc_conn;
1620 f_init();
1621 f_vty_config(MSCVTY, "network", "authentication required");
1622 f_vty_config(MSCVTY, "network", "encryption a5 3");
1623
1624 pars := f_init_pars(361);
1625 pars.send_early_cm := false;
1626 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 +01001627 vc_conn.done;
1628}
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01001629testcase TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() runs on MTC_CT {
1630 var BSC_ConnHdlr vc_conn;
1631 f_init();
1632 f_vty_config(MSCVTY, "network", "authentication required");
1633 f_vty_config(MSCVTY, "network", "encryption a5 3");
1634
1635 /* Make sure the MSC category is on DEBUG level to trigger the log
1636 * message that is reported in OS#2947 to trigger the segfault */
1637 f_vty_config(MSCVTY, "log stderr", "logging level msc debug");
1638
1639 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 362);
1640 vc_conn.done;
1641}
Harald Welte9de84792018-01-28 01:06:35 +01001642
1643/* A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
1644private function f_tc_lu_imsi_auth_tmsi_encr_13_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1645 pars.net.expect_auth := true;
1646 pars.net.expect_ciph := true;
1647 pars.net.kc_support := '0A'O; /* A5/1 + A5/3 */
1648 pars.cm1.a5_1 := '1'B;
1649 pars.cm2.a5_1 := '1'B;
1650 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1651 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
1652 f_init_handler(pars, 15.0);
1653
1654 /* cannot use f_perform_lu() as we expect a reject */
1655 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1656 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Weltedceacc72019-04-21 20:58:35 +02001657 f_cl3_or_initial_ue(l3_lu);
Harald Welte9de84792018-01-28 01:06:35 +01001658 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1659 f_mm_auth();
1660 alt {
Harald Welte5946b332018-03-18 23:32:21 +01001661 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1662 f_expect_clear();
1663 }
Harald Welte9de84792018-01-28 01:06:35 +01001664 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1665 setverdict(fail, "CipherModeCommand despite no A5 intersection");
Daniel Willmannafce8662018-07-06 23:11:32 +02001666 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001667 }
1668 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001669 setverdict(fail, "Unknown/unexpected BSSAP received");
Daniel Willmannafce8662018-07-06 23:11:32 +02001670 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001671 }
1672 }
1673 setverdict(pass);
1674}
1675testcase TC_lu_imsi_auth_tmsi_encr_13_2() runs on MTC_CT {
1676 var BSC_ConnHdlr vc_conn;
1677 f_init();
1678 f_vty_config(MSCVTY, "network", "authentication required");
1679 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1680
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001681 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_2), 37);
Harald Welte9de84792018-01-28 01:06:35 +01001682 vc_conn.done;
1683}
1684
1685/* A5/0 + A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
1686private function f_tc_lu_imsi_auth_tmsi_encr_013_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1687 pars.net.expect_auth := true;
1688 pars.net.expect_ciph := true;
1689 pars.net.kc_support := '0B'O; /* A5/1 + A5/3 */
1690 pars.cm1.a5_1 := '1'B;
1691 pars.cm2.a5_1 := '1'B;
1692 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1693 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
1694 f_init_handler(pars, 15.0);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001695 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001696}
1697testcase TC_lu_imsi_auth_tmsi_encr_013_2() runs on MTC_CT {
1698 var BSC_ConnHdlr vc_conn;
1699 f_init();
1700 f_vty_config(MSCVTY, "network", "authentication required");
1701 f_vty_config(MSCVTY, "network", "encryption a5 0 1 3");
1702
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001703 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_013_2), 38);
Harald Welte9de84792018-01-28 01:06:35 +01001704 vc_conn.done;
1705}
1706
Harald Welte33ec09b2018-02-10 15:34:46 +01001707/* LU followed by MT call (including paging) */
1708private function f_tc_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1709 f_init_handler(pars);
Stefan Sperling26d57be2018-11-12 17:03:26 +01001710 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Harald Welte33ec09b2018-02-10 15:34:46 +01001711 cpars.bss_rtp_port := 1110;
1712 cpars.mgcp_connection_id_bss := '10004'H;
1713 cpars.mgcp_connection_id_mss := '10005'H;
1714
Philipp Maier4b2692d2018-03-14 16:37:48 +01001715 /* Note: This is an optional parameter. When the call-agent (MSC) does
1716 * supply a full endpoint name this setting will be overwritten. */
1717 cpars.mgcp_ep := "rtpbridge/1@mgw";
1718
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001719 f_perform_lu();
Harald Welte33ec09b2018-02-10 15:34:46 +01001720 f_mt_call(cpars);
1721}
1722testcase TC_lu_and_mt_call() runs on MTC_CT {
1723 var BSC_ConnHdlr vc_conn;
1724 f_init();
1725
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001726 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call), 39);
Harald Welte33ec09b2018-02-10 15:34:46 +01001727 vc_conn.done;
1728}
1729
Daniel Willmann8b084372018-02-04 13:35:26 +01001730/* Test MO Call SETUP with DTMF */
1731private function f_tc_mo_setup_dtmf_dup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1732 f_init_handler(pars);
1733 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1734 cpars.bss_rtp_port := 1110;
1735 cpars.mgcp_connection_id_bss := '22222'H;
1736 cpars.mgcp_connection_id_mss := '33333'H;
1737
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001738 f_perform_lu();
Daniel Willmann8b084372018-02-04 13:35:26 +01001739 f_mo_seq_dtmf_dup(cpars);
1740}
1741testcase TC_mo_setup_and_dtmf_dup() runs on MTC_CT {
1742 var BSC_ConnHdlr vc_conn;
1743 f_init();
1744
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001745 vc_conn := f_start_handler(refers(f_tc_mo_setup_dtmf_dup), 39);
Daniel Willmann8b084372018-02-04 13:35:26 +01001746 vc_conn.done;
1747}
Harald Welte9de84792018-01-28 01:06:35 +01001748
Philipp Maier328d1662018-03-07 10:40:27 +01001749testcase TC_cr_before_reset() runs on MTC_CT {
1750 timer T := 4.0;
1751 var boolean reset_ack_seen := false;
1752 f_init_bssap_direct();
1753
Harald Welte3ca0ce12019-04-23 17:18:48 +02001754 f_ran_adapter_start(g_bssap[0]);
Daniel Willmann42d1d5b2018-08-07 15:18:41 +02001755
Daniel Willmanne8018962018-08-21 14:18:00 +02001756 f_sleep(3.0);
1757
Philipp Maier328d1662018-03-07 10:40:27 +01001758 /* Make a blind connection attemt, to trigger the deadlock condition */
Philipp Maier75932982018-03-27 14:52:35 +02001759 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 +01001760
1761 /* Send a BSSMAP reset */
Philipp Maier75932982018-03-27 14:52:35 +02001762 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 +01001763 T.start
1764 alt {
1765 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_ResetAck)) {
1766 reset_ack_seen := true;
1767 repeat;
1768 }
1769
1770 /* Acknowledge MSC sided reset requests */
1771 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) {
Philipp Maier75932982018-03-27 14:52:35 +02001772 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 +01001773 repeat;
1774 }
1775
1776 /* Ignore all other messages (e.g CR from the connection request) */
1777 [] BSSAP_DIRECT.receive { repeat }
1778
1779 /* If we got no BSSMAP RESET ACK back, then the MSC entered the
1780 * deadlock situation. The MSC is then unable to respond to any
1781 * further BSSMAP RESET or any other sort of traffic. */
1782 [reset_ack_seen == true] T.timeout { setverdict(pass) }
1783 [reset_ack_seen == false] T.timeout {
1784 setverdict(fail, "no BSSMAP RESET ACK seen!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001785 mtc.stop;
Philipp Maier328d1662018-03-07 10:40:27 +01001786 }
1787 }
1788}
Harald Welte9de84792018-01-28 01:06:35 +01001789
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001790/* Test MO Call with no response to RAN-side CRCX or DTAP Release */
Harald Weltee13cfb22019-04-23 16:52:02 +02001791friend function f_tc_mo_release_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001792 f_init_handler(pars);
1793 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1794 var MNCC_PDU mncc;
1795 var MgcpCommand mgcp_cmd;
1796
1797 f_perform_lu();
1798
Harald Welteb9e86fa2018-04-09 18:18:31 +02001799 f_establish_fully();
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001800 f_create_mncc_expect(hex2str(cpars.called_party));
1801 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1802
1803 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1804 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1805 cpars.mncc_callref := mncc.u.signal.callref;
1806 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1807 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1808
1809 /* Drop CRCX */
1810 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1811
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001812 var default ccrel := activate(as_optional_cc_rel(cpars));
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001813
1814 f_expect_clear(60.0);
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001815
1816 deactivate(ccrel);
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001817}
1818testcase TC_mo_release_timeout() runs on MTC_CT {
1819 var BSC_ConnHdlr vc_conn;
1820 f_init();
1821
1822 vc_conn := f_start_handler(refers(f_tc_mo_release_timeout), 40);
1823 vc_conn.done;
1824}
1825
Harald Welte12510c52018-01-26 22:26:24 +01001826
Philipp Maier2a98a732018-03-19 16:06:12 +01001827/* LU followed by MT call (including paging) */
1828private function f_tc_lu_and_mt_call_no_dlcx_resp(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1829 f_init_handler(pars);
Stefan Sperling26d57be2018-11-12 17:03:26 +01001830 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Philipp Maier2a98a732018-03-19 16:06:12 +01001831 cpars.bss_rtp_port := 1110;
1832 cpars.mgcp_connection_id_bss := '10004'H;
1833 cpars.mgcp_connection_id_mss := '10005'H;
1834
1835 /* Note: This is an optional parameter. When the call-agent (MSC) does
1836 * supply a full endpoint name this setting will be overwritten. */
1837 cpars.mgcp_ep := "rtpbridge/1@mgw";
1838
1839 /* Intentionally disable the CRCX response */
1840 cpars.mgw_drop_dlcx := true;
1841
1842 /* Perform location update and call */
1843 f_perform_lu();
1844 f_mt_call(cpars);
1845}
1846testcase TC_lu_and_mt_call_no_dlcx_resp() runs on MTC_CT {
1847 var BSC_ConnHdlr vc_conn;
1848 f_init();
1849
1850 /* Perform an almost normal looking locationupdate + mt-call, but do
1851 * not respond to the DLCX at the end of the call */
1852 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call_no_dlcx_resp), 41);
1853 vc_conn.done;
1854
1855 /* Wait a guard period until the MGCP layer in the MSC times out,
1856 * if the MSC is vulnerable to the use-after-free situation that is
1857 * fixed by I78f1b6a9149488a4ad3f120c1e190a83c07d4b89 then it should
1858 * segfault now */
1859 f_sleep(6.0);
1860
1861 /* Run the init procedures once more. If the MSC has crashed, this
1862 * this will fail */
1863 f_init();
1864}
Harald Welte45164da2018-01-24 12:51:27 +01001865
Philipp Maier75932982018-03-27 14:52:35 +02001866/* Two BSSMAP resets from two different BSCs */
1867testcase TC_reset_two() runs on MTC_CT {
1868 var BSC_ConnHdlr vc_conn;
1869 f_init(2);
1870 f_sleep(2.0);
1871 setverdict(pass);
1872}
1873
Harald Weltee13cfb22019-04-23 16:52:02 +02001874/* Two BSSMAP resets from two different BSCs plus one IuCS RANAP Reset */
1875testcase TC_reset_two_1iu() runs on MTC_CT {
1876 var BSC_ConnHdlr vc_conn;
1877 f_init(3);
1878 f_sleep(2.0);
1879 setverdict(pass);
1880}
1881
Harald Weltef640a012018-04-14 17:49:21 +02001882/***********************************************************************
1883 * SMS Testing
1884 ***********************************************************************/
1885
Harald Weltef45efeb2018-04-09 18:19:24 +02001886/* LU followed by MO SMS */
Harald Weltee13cfb22019-04-23 16:52:02 +02001887friend function f_tc_lu_and_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltef45efeb2018-04-09 18:19:24 +02001888 var SmsParameters spars := valueof(t_SmsPars);
1889
1890 f_init_handler(pars);
1891
1892 /* Perform location update and call */
1893 f_perform_lu();
1894
1895 f_establish_fully(EST_TYPE_MO_SMS);
1896
1897 //spars.exp_rp_err := 96; /* invalid mandatory information */
1898 f_mo_sms(spars);
1899
1900 f_expect_clear();
1901}
1902testcase TC_lu_and_mo_sms() runs on MTC_CT {
1903 var BSC_ConnHdlr vc_conn;
1904 f_init();
1905 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_sms), 42);
1906 vc_conn.done;
1907}
1908
Harald Weltee13cfb22019-04-23 16:52:02 +02001909
Harald Weltef45efeb2018-04-09 18:19:24 +02001910private function f_vty_sms_send(charstring imsi, charstring msisdn, charstring text)
Neels Hofmeyr6aaeccf2019-03-06 15:32:26 +01001911runs on BSC_ConnHdlr {
Harald Weltef45efeb2018-04-09 18:19:24 +02001912 f_vty_transceive(MSCVTY, "subscriber imsi "&imsi&" sms sender msisdn "&msisdn&" send "&text);
1913}
1914
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01001915/* Remove still pending SMS */
1916private function f_vty_sms_clear(charstring imsi)
1917runs on BSC_ConnHdlr {
1918 f_vty_transceive(MSCVTY, "subscriber imsi " & imsi & " sms delete-all");
1919 f_vty_transceive(MSCVTY, "sms-queue clear");
1920}
1921
Harald Weltef45efeb2018-04-09 18:19:24 +02001922/* LU followed by MT SMS */
Harald Weltee13cfb22019-04-23 16:52:02 +02001923friend function f_tc_lu_and_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltef45efeb2018-04-09 18:19:24 +02001924 var SmsParameters spars := valueof(t_SmsPars);
1925 var OCT4 tmsi;
1926
1927 f_init_handler(pars);
1928
1929 /* Perform location update and call */
1930 f_perform_lu();
1931
1932 /* register an 'expect' for given IMSI (+TMSI) */
1933 if (isvalue(g_pars.tmsi)) {
1934 tmsi := g_pars.tmsi;
1935 } else {
1936 tmsi := 'FFFFFFFF'O;
1937 }
Harald Welte6811d102019-04-14 22:23:14 +02001938 f_ran_register_imsi(g_pars.imsi, tmsi);
Harald Weltef45efeb2018-04-09 18:19:24 +02001939
Neels Hofmeyr6aaeccf2019-03-06 15:32:26 +01001940 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
Harald Weltef45efeb2018-04-09 18:19:24 +02001941
1942 /* MSC->BSC: expect PAGING from MSC */
Harald Weltee035e3e2019-04-21 17:32:05 +02001943 f_expect_paging();
1944
Harald Weltef45efeb2018-04-09 18:19:24 +02001945 /* Establish DTAP / BSSAP / SCCP connection */
1946 f_establish_fully(EST_TYPE_PAG_RESP);
1947
1948 spars.tp.ud := 'C8329BFD064D9B53'O;
1949 f_mt_sms(spars);
1950
1951 f_expect_clear();
1952}
1953testcase TC_lu_and_mt_sms() runs on MTC_CT {
1954 var BSC_ConnHdlrPars pars;
1955 var BSC_ConnHdlr vc_conn;
1956 f_init();
1957 pars := f_init_pars(43);
1958 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_sms), pars);
Harald Weltef45efeb2018-04-09 18:19:24 +02001959 vc_conn.done;
1960}
1961
Harald Weltee13cfb22019-04-23 16:52:02 +02001962
Philipp Maier3983e702018-11-22 19:01:33 +01001963/* Paging for MT SMS but no response */
Harald Weltee13cfb22019-04-23 16:52:02 +02001964friend 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 +01001965 var SmsParameters spars := valueof(t_SmsPars);
1966 var OCT4 tmsi;
Philipp Maier3983e702018-11-22 19:01:33 +01001967 f_init_handler(pars, 150.0);
1968
1969 /* Perform location update */
1970 f_perform_lu();
1971
1972 /* register an 'expect' for given IMSI (+TMSI) */
1973 if (isvalue(g_pars.tmsi)) {
1974 tmsi := g_pars.tmsi;
1975 } else {
1976 tmsi := 'FFFFFFFF'O;
1977 }
Harald Welte6811d102019-04-14 22:23:14 +02001978 f_ran_register_imsi(g_pars.imsi, tmsi);
Philipp Maier3983e702018-11-22 19:01:33 +01001979
Neels Hofmeyr6aaeccf2019-03-06 15:32:26 +01001980 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
1981
Neels Hofmeyr16237742019-03-06 15:34:01 +01001982 /* Expect the MSC to page exactly once */
Harald Weltee13cfb22019-04-23 16:52:02 +02001983 f_expect_paging();
Philipp Maier3983e702018-11-22 19:01:33 +01001984
1985 /* Wait some time to make sure the MSC is not delivering any further
1986 * paging messages or anything else that could be unexpected. */
1987 timer T := 20.0;
1988 T.start
1989 alt {
Harald Weltee13cfb22019-04-23 16:52:02 +02001990 [pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi))
Philipp Maier3983e702018-11-22 19:01:33 +01001991 {
1992 setverdict(fail, "paging seems not to stop!");
1993 mtc.stop;
1994 }
Harald Welte62113fc2019-05-09 13:04:02 +02001995 [not pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
Harald Weltee13cfb22019-04-23 16:52:02 +02001996 setverdict(fail, "paging seems not to stop!");
1997 mtc.stop;
1998 }
Philipp Maier3983e702018-11-22 19:01:33 +01001999 [] BSSAP.receive {
2000 setverdict(fail, "unexpected BSSAP message received");
2001 self.stop;
2002 }
2003 [] T.timeout {
2004 setverdict(pass);
2005 }
2006 }
2007
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01002008 f_vty_sms_clear(hex2str(g_pars.imsi));
2009
Philipp Maier3983e702018-11-22 19:01:33 +01002010 setverdict(pass);
2011}
2012testcase TC_lu_and_mt_sms_paging_and_nothing() runs on MTC_CT {
2013 var BSC_ConnHdlrPars pars;
2014 var BSC_ConnHdlr vc_conn;
2015 f_init();
Philipp Maiera99ad262019-01-22 15:35:42 +01002016 pars := f_init_pars(1843);
Philipp Maier3983e702018-11-22 19:01:33 +01002017 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 +01002018 vc_conn.done;
2019}
2020
Harald Weltee13cfb22019-04-23 16:52:02 +02002021
Harald Weltef640a012018-04-14 17:49:21 +02002022/* mobile originated SMS from MS/BTS/BSC side to SMPP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002023friend function f_tc_smpp_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltef640a012018-04-14 17:49:21 +02002024 var SmsParameters spars := valueof(t_SmsPars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002025
Harald Weltef640a012018-04-14 17:49:21 +02002026 f_init_handler(pars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002027
Harald Weltef640a012018-04-14 17:49:21 +02002028 /* Perform location update so IMSI is known + registered in MSC/VLR */
2029 f_perform_lu();
2030 f_establish_fully(EST_TYPE_MO_SMS);
2031
2032 f_mo_sms(spars);
2033
2034 var SMPP_PDU smpp;
2035 var template SMPP_PDU tr_smpp := tr_SMPP(c_SMPP_command_id_deliver_sm, ESME_ROK);
2036 tr_smpp.body.deliver_sm := {
2037 service_type := "CMT",
2038 source_addr_ton := network_specific,
2039 source_addr_npi := isdn,
2040 source_addr := hex2str(pars.msisdn),
2041 dest_addr_ton := f_sm_ton_from_gsm(spars.tp.da.tP_DA_NoPad.tP_TypeOfNumber),
2042 dest_addr_npi := f_sm_npi_from_gsm(spars.tp.da.tP_DA_NoPad.tP_NumberingPlanID),
2043 destination_addr := hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue),
2044 esm_class := '00000001'B,
2045 protocol_id := 0,
2046 priority_flag := 0,
2047 schedule_delivery_time := "",
2048 replace_if_present := 0,
2049 data_coding := '00000001'B,
2050 sm_default_msg_id := 0,
2051 sm_length := ?,
2052 short_message := spars.tp.ud,
2053 opt_pars := {
2054 {
2055 tag := user_message_reference,
2056 len := 2,
2057 opt_value := {
2058 int2_val := oct2int(spars.tp.msg_ref)
2059 }
2060 }
2061 }
2062 };
2063 alt {
2064 [] SMPP.receive(tr_smpp) -> value smpp {
2065 SMPP.send(ts_SMPP_DELIVER_SM_resp(ESME_ROK, smpp.header.seq_num));
2066 }
2067 [] SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK)) { repeat; }
2068 }
2069
2070 f_expect_clear();
2071}
2072testcase TC_smpp_mo_sms() runs on MTC_CT {
2073 var BSC_ConnHdlr vc_conn;
2074 f_init();
2075 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "default-route");
2076 vc_conn := f_start_handler(refers(f_tc_smpp_mo_sms), 44);
2077 vc_conn.done;
2078 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "no default-route");
2079}
2080
Harald Weltee13cfb22019-04-23 16:52:02 +02002081
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002082/* Test MO-SMS from MS/BTS/BSC towards HLR (via GSUP) */
Harald Weltee13cfb22019-04-23 16:52:02 +02002083friend function f_tc_gsup_mo_sms(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002084runs on BSC_ConnHdlr {
2085 var SmsParameters spars := valueof(t_SmsPars);
2086 var GSUP_PDU gsup_msg_rx;
2087 var octetstring sm_tpdu;
2088
2089 f_init_handler(pars);
2090
2091 /* We need to inspect GSUP activity */
2092 f_create_gsup_expect(hex2str(g_pars.imsi));
2093
2094 /* Perform location update */
2095 f_perform_lu();
2096
2097 /* Send CM Service Request for SMS */
2098 f_establish_fully(EST_TYPE_MO_SMS);
2099
2100 /* Prepare expected SM-RP-UI (SM TPDU) */
2101 enc_TPDU_RP_DATA_MS_SGSN_fast(
2102 valueof(ts_SMS_SUBMIT(spars.tp.msg_ref,
2103 spars.tp.da, spars.tp.pid, spars.tp.dcs,
2104 spars.tp.udl, spars.tp.ud)),
2105 sm_tpdu);
2106
2107 var template GSUP_PDU mo_forwardSM := tr_GSUP_MO_FORWARD_SM_REQ(
2108 imsi := g_pars.imsi,
2109 sm_rp_mr := spars.rp.msg_ref,
2110 /* FIXME: extract SM-RP-DA from spars.rp.dest */
2111 sm_rp_da := tr_GSUP_SM_RP_DA_SMSC_ADDR(?),
2112 /* FIXME: MSISDN coding troubles */
2113 sm_rp_oa := tr_GSUP_SM_RP_OA_MSISDN(?),
2114 /* TODO: can we use decmatch here? */
2115 sm_rp_ui := sm_tpdu
2116 );
2117
2118 /* Submit an SMS on DTAP and expect MO-forwardSM-Req on GSUP */
2119 f_mo_sms_submit(spars);
2120 alt {
2121 [] GSUP.receive(mo_forwardSM) -> value gsup_msg_rx {
2122 log("RX MO-forwardSM-Req");
2123 log(gsup_msg_rx);
2124 setverdict(pass);
2125 }
2126 [] GSUP.receive {
2127 log("RX unexpected GSUP message");
2128 setverdict(fail);
2129 mtc.stop;
2130 }
2131 }
2132
2133 /* Trigger RP-ACK by sending MO-forwardSM-Res */
2134 GSUP.send(valueof(ts_GSUP_MO_FORWARD_SM_RES(
2135 imsi := g_pars.imsi,
2136 sm_rp_mr := spars.rp.msg_ref)));
2137 /* Expect RP-ACK on DTAP */
2138 f_mo_sms_wait_rp_ack(spars);
2139
2140 f_expect_clear();
2141}
2142testcase TC_gsup_mo_sms() runs on MTC_CT {
2143 var BSC_ConnHdlr vc_conn;
2144 f_init();
2145 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2146 vc_conn := f_start_handler(refers(f_tc_gsup_mo_sms), 88);
2147 vc_conn.done;
2148 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2149}
2150
Harald Weltee13cfb22019-04-23 16:52:02 +02002151
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07002152/* Test MO-SMMA from MS/BTS/BSC towards HLR (via GSUP) */
Harald Weltee13cfb22019-04-23 16:52:02 +02002153friend function f_tc_gsup_mo_smma(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07002154runs on BSC_ConnHdlr {
2155 var SmsParameters spars := valueof(t_SmsPars);
2156 var GSUP_PDU gsup_msg_rx;
2157
2158 f_init_handler(pars);
2159
2160 /* We need to inspect GSUP activity */
2161 f_create_gsup_expect(hex2str(g_pars.imsi));
2162
2163 /* Perform location update */
2164 f_perform_lu();
2165
2166 /* Send CM Service Request for SMS */
2167 f_establish_fully(EST_TYPE_MO_SMS);
2168
2169 var template GSUP_PDU mo_ReadyForSM := tr_GSUP_MO_READY_FOR_SM_REQ(
2170 imsi := g_pars.imsi,
2171 sm_rp_mr := spars.rp.msg_ref,
2172 sm_alert_rsn := GSUP_SM_ALERT_RSN_TYPE_MEM_AVAIL
2173 );
2174
2175 /* Submit an SMS on DTAP and expect MO-forwardSM-Req on GSUP */
2176 f_mo_smma(spars);
2177 alt {
2178 [] GSUP.receive(mo_ReadyForSM) -> value gsup_msg_rx {
2179 log("RX MO-ReadyForSM-Req");
2180 log(gsup_msg_rx);
2181 setverdict(pass);
2182 }
2183 [] GSUP.receive {
2184 log("RX unexpected GSUP message");
2185 setverdict(fail);
2186 mtc.stop;
2187 }
2188 }
2189
2190 /* Trigger RP-ACK by sending MO-forwardSM-Res */
2191 GSUP.send(valueof(ts_GSUP_MO_READY_FOR_SM_RES(
2192 imsi := g_pars.imsi,
2193 sm_rp_mr := spars.rp.msg_ref)));
2194 /* Expect RP-ACK on DTAP */
2195 f_mo_sms_wait_rp_ack(spars);
2196
2197 f_expect_clear();
2198}
2199testcase TC_gsup_mo_smma() runs on MTC_CT {
2200 var BSC_ConnHdlr vc_conn;
2201 f_init();
2202 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2203 vc_conn := f_start_handler(refers(f_tc_gsup_mo_smma), 89);
2204 vc_conn.done;
2205 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2206}
2207
Harald Weltee13cfb22019-04-23 16:52:02 +02002208
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002209/* Helper for sending MT SMS over GSUP */
2210private function f_gsup_forwardSM_req(SmsParameters spars, OCT1 mms := '00'O)
2211runs on BSC_ConnHdlr {
2212 GSUP.send(ts_GSUP_MT_FORWARD_SM_REQ(
2213 imsi := g_pars.imsi,
2214 /* NOTE: MSC should assign RP-MR itself */
2215 sm_rp_mr := 'FF'O,
2216 /* FIXME: extract SM-RP-DA from spars.rp.dest */
2217 /* TODO: fix encoding of ts_GSUP_SM_RP_DA_IMSI */
2218 sm_rp_da := valueof(ts_GSUP_SM_RP_DA_MSISDN(g_pars.msisdn)),
2219 sm_rp_oa := valueof(ts_GSUP_SM_RP_OA_SMSC_ADDR(g_pars.msisdn)),
2220 /* Encoded SMS TPDU (taken from Wireshark)
2221 * FIXME: we should encode spars somehow */
2222 sm_rp_ui := '00068021436500008111328130858200'O,
2223 sm_rp_mms := mms
2224 ));
2225}
2226
2227/* Test successful MT-SMS (RP-ACK) over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002228friend function f_tc_gsup_mt_sms_ack(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002229runs on BSC_ConnHdlr {
2230 var SmsParameters spars := valueof(t_SmsPars);
2231
2232 f_init_handler(pars);
2233
2234 /* We need to inspect GSUP activity */
2235 f_create_gsup_expect(hex2str(g_pars.imsi));
2236
2237 /* Perform location update */
2238 f_perform_lu();
2239
2240 /* Register an 'expect' for given IMSI (+TMSI) */
2241 if (isvalue(g_pars.tmsi)) {
Harald Welte6811d102019-04-14 22:23:14 +02002242 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002243 } else {
Harald Welte6811d102019-04-14 22:23:14 +02002244 f_ran_register_imsi(g_pars.imsi, 'FFFFFFFF'O);
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002245 }
2246
2247 var template GSUP_PDU mt_forwardSM_res := tr_GSUP_MT_FORWARD_SM_RES(
2248 imsi := g_pars.imsi,
2249 /* NOTE: MSC should assign RP-MR itself */
2250 sm_rp_mr := ?
2251 );
2252
2253 /* Submit a MT SMS on GSUP */
2254 f_gsup_forwardSM_req(spars);
2255
2256 /* Expect Paging Request and Establish DTAP / BSSAP / SCCP connection */
Harald Weltee035e3e2019-04-21 17:32:05 +02002257 f_expect_paging();
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002258 f_establish_fully(EST_TYPE_PAG_RESP);
2259
2260 /* Wait for MT SMS on DTAP */
2261 f_mt_sms_expect(spars);
2262
2263 /* Send RP-ACK and expect MT-forwardSM-Res on GSUP */
2264 f_mt_sms_send_rp_ack(spars);
2265 alt {
2266 [] GSUP.receive(mt_forwardSM_res) {
2267 log("RX MT-forwardSM-Res (RP-ACK)");
2268 setverdict(pass);
2269 }
2270 [] GSUP.receive {
2271 log("RX unexpected GSUP message");
2272 setverdict(fail);
2273 mtc.stop;
2274 }
2275 }
2276
2277 f_expect_clear();
2278}
2279testcase TC_gsup_mt_sms_ack() runs on MTC_CT {
2280 var BSC_ConnHdlrPars pars;
2281 var BSC_ConnHdlr vc_conn;
2282 f_init();
2283 pars := f_init_pars(90);
2284 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2285 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_sms_ack), pars);
2286 vc_conn.done;
2287 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2288}
2289
Harald Weltee13cfb22019-04-23 16:52:02 +02002290
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002291/* Test rejected MT-SMS (RP-ERROR) over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002292friend function f_tc_gsup_mt_sms_err(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002293runs on BSC_ConnHdlr {
2294 var SmsParameters spars := valueof(t_SmsPars);
2295 var OCT1 sm_rp_cause := '78'O; /* dummy RP-Cause value */
2296
2297 f_init_handler(pars);
2298
2299 /* We need to inspect GSUP activity */
2300 f_create_gsup_expect(hex2str(g_pars.imsi));
2301
2302 /* Perform location update */
2303 f_perform_lu();
2304
2305 /* Register an 'expect' for given IMSI (+TMSI) */
2306 if (isvalue(g_pars.tmsi)) {
Harald Welte6811d102019-04-14 22:23:14 +02002307 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002308 } else {
Harald Welte6811d102019-04-14 22:23:14 +02002309 f_ran_register_imsi(g_pars.imsi, 'FFFFFFFF'O);
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002310 }
2311
2312 var template GSUP_PDU mt_forwardSM_err := tr_GSUP_MT_FORWARD_SM_ERR(
2313 imsi := g_pars.imsi,
2314 /* NOTE: MSC should assign RP-MR itself */
2315 sm_rp_mr := ?,
2316 sm_rp_cause := sm_rp_cause
2317 );
2318
2319 /* Submit a MT SMS on GSUP */
2320 f_gsup_forwardSM_req(spars);
2321
2322 /* Expect Paging Request and Establish DTAP / BSSAP / SCCP connection */
Harald Weltee035e3e2019-04-21 17:32:05 +02002323 f_expect_paging();
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002324 f_establish_fully(EST_TYPE_PAG_RESP);
2325
2326 /* Wait for MT SMS on DTAP */
2327 f_mt_sms_expect(spars);
2328
2329 /* Send RP-ERROR and expect MT-forwardSM-Err on GSUP */
2330 f_mt_sms_send_rp_error(spars, oct2int(sm_rp_cause));
2331 alt {
2332 [] GSUP.receive(mt_forwardSM_err) {
2333 log("RX MT-forwardSM-Err (RP-ERROR)");
2334 setverdict(pass);
2335 mtc.stop;
2336 }
2337 [] GSUP.receive {
2338 log("RX unexpected GSUP message");
2339 setverdict(fail);
2340 mtc.stop;
2341 }
2342 }
2343
2344 f_expect_clear();
2345}
2346testcase TC_gsup_mt_sms_err() runs on MTC_CT {
2347 var BSC_ConnHdlrPars pars;
2348 var BSC_ConnHdlr vc_conn;
2349 f_init();
2350 pars := f_init_pars(91);
2351 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2352 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_sms_err), pars);
2353 vc_conn.done;
2354 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2355}
2356
Harald Weltee13cfb22019-04-23 16:52:02 +02002357
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002358/* Test SM-RP-MR assignment for MT-SMS over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002359friend function f_tc_gsup_mt_sms_rp_mr(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002360runs on BSC_ConnHdlr {
2361 var SmsParameters spars1 := valueof(t_SmsPars); /* 1st SMS */
2362 var SmsParameters spars2 := valueof(t_SmsPars); /* 2nd SMS */
2363
2364 f_init_handler(pars);
2365
2366 /* We need to inspect GSUP activity */
2367 f_create_gsup_expect(hex2str(g_pars.imsi));
2368
2369 /* Perform location update */
2370 f_perform_lu();
2371
2372 /* Register an 'expect' for given IMSI (+TMSI) */
2373 if (isvalue(g_pars.tmsi)) {
Harald Welte6811d102019-04-14 22:23:14 +02002374 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002375 } else {
Harald Welte6811d102019-04-14 22:23:14 +02002376 f_ran_register_imsi(g_pars.imsi, 'FFFFFFFF'O);
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002377 }
2378
2379 /* Submit the 1st MT SMS on GSUP */
2380 log("TX MT-forwardSM-Req for the 1st SMS");
2381 f_gsup_forwardSM_req(spars1);
2382
2383 /* Expect Paging Request and Establish DTAP / BSSAP / SCCP connection */
Harald Weltee035e3e2019-04-21 17:32:05 +02002384 f_expect_paging();
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002385 f_establish_fully(EST_TYPE_PAG_RESP);
2386
2387 /* Wait for 1st MT SMS on DTAP */
2388 f_mt_sms_expect(spars1);
2389 log("RX the 1st SMS on DTAP, DTAP TID is ", spars1.tid,
2390 ", SM-RP-MR is ", spars1.rp.msg_ref);
2391
2392 /* Submit the 2nd MT SMS on GSUP */
2393 log("TX MT-forwardSM-Req for the 2nd SMS");
2394 f_gsup_forwardSM_req(spars2);
2395
2396 /* Wait for 2nd MT SMS on DTAP */
2397 f_mt_sms_expect(spars2);
2398 log("RX the 2nd SMS on DTAP, DTAP TID is ", spars2.tid,
2399 ", SM-RP-MR is ", spars2.rp.msg_ref);
2400
2401 /* Both transaction IDs shall be different */
2402 if (spars1.tid == spars2.tid) {
2403 log("Both DTAP transaction IDs shall be different");
2404 setverdict(fail);
2405 }
2406
2407 /* Both SM-RP-MR values shall be different */
2408 if (spars1.rp.msg_ref == spars2.rp.msg_ref) {
2409 log("Both SM-RP-MR values shall be different");
2410 setverdict(fail);
2411 }
2412
2413 /* Both SM-RP-MR values shall be assigned */
2414 if (spars1.rp.msg_ref == 'FF'O) {
2415 log("Unassigned SM-RP-MR value for the 1st SMS");
2416 setverdict(fail);
2417 }
2418 if (spars2.rp.msg_ref == 'FF'O) {
2419 log("Unassigned SM-RP-MR value for the 2nd SMS");
2420 setverdict(fail);
2421 }
2422
2423 /* Send the 1st RP-ACK and expect MT-forwardSM-Res on GSUP */
2424 f_mt_sms_send_rp_ack(spars1);
2425 alt {
2426 [] GSUP.receive(tr_GSUP_MT_FORWARD_SM_RES(
2427 imsi := g_pars.imsi,
2428 sm_rp_mr := spars1.rp.msg_ref
2429 )) {
2430 log("RX MT-forwardSM-Res (RP-ACK)");
2431 setverdict(pass);
2432 }
2433 [] GSUP.receive {
2434 log("RX unexpected GSUP message");
2435 setverdict(fail);
2436 mtc.stop;
2437 }
2438 }
2439
2440 /* Send the 2nd RP-ACK and expect MT-forwardSM-Res on GSUP */
2441 f_mt_sms_send_rp_ack(spars2);
2442 alt {
2443 [] GSUP.receive(tr_GSUP_MT_FORWARD_SM_RES(
2444 imsi := g_pars.imsi,
2445 sm_rp_mr := spars2.rp.msg_ref
2446 )) {
2447 log("RX MT-forwardSM-Res (RP-ACK)");
2448 setverdict(pass);
2449 }
2450 [] GSUP.receive {
2451 log("RX unexpected GSUP message");
2452 setverdict(fail);
2453 mtc.stop;
2454 }
2455 }
2456
2457 f_expect_clear();
2458}
2459testcase TC_gsup_mt_sms_rp_mr() runs on MTC_CT {
2460 var BSC_ConnHdlrPars pars;
2461 var BSC_ConnHdlr vc_conn;
2462 f_init();
2463 pars := f_init_pars(92);
2464 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2465 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_sms_rp_mr), pars);
2466 vc_conn.done;
2467 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2468}
2469
Harald Weltee13cfb22019-04-23 16:52:02 +02002470
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07002471/* Test SM-RP-MR assignment for MT-SMS over GSUP */
Harald Weltee13cfb22019-04-23 16:52:02 +02002472friend function f_tc_gsup_mo_mt_sms_rp_mr(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07002473runs on BSC_ConnHdlr {
2474 var SmsParameters spars_mo := valueof(t_SmsPars); /* MO SMMA */
2475 var SmsParameters spars_mt := valueof(t_SmsPars); /* MT SMS */
2476
2477 f_init_handler(pars);
2478
2479 /* We need to inspect GSUP activity */
2480 f_create_gsup_expect(hex2str(g_pars.imsi));
2481
2482 /* Perform location update */
2483 f_perform_lu();
2484
2485 /* Register an 'expect' for given IMSI (+TMSI) */
2486 if (isvalue(g_pars.tmsi)) {
Harald Welte6811d102019-04-14 22:23:14 +02002487 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07002488 } else {
Harald Welte6811d102019-04-14 22:23:14 +02002489 f_ran_register_imsi(g_pars.imsi, 'FFFFFFFF'O);
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07002490 }
2491
2492 /* Send CM Service Request for MO SMMA */
2493 f_establish_fully(EST_TYPE_MO_SMS);
2494
2495 /* Submit MO SMMA on DTAP */
2496 log("Submit MO SMMA on DTAP, SM-RP-MR is '00'O");
2497 spars_mo.rp.msg_ref := '00'O;
2498 f_mo_smma(spars_mo);
2499
2500 /* Expect MO-forwardSM-Req for MO SMMA on GSUP */
2501 alt {
2502 [] GSUP.receive(tr_GSUP_MO_READY_FOR_SM_REQ(
2503 imsi := g_pars.imsi,
2504 sm_rp_mr := spars_mo.rp.msg_ref,
2505 sm_alert_rsn := GSUP_SM_ALERT_RSN_TYPE_MEM_AVAIL
2506 )) {
2507 log("RX MO-ReadyForSM-Req, SM-RP-MR is '00'O");
2508 setverdict(pass);
2509 }
2510 [] GSUP.receive {
2511 log("RX unexpected GSUP message");
2512 setverdict(fail);
2513 mtc.stop;
2514 }
2515 }
2516
2517 /* Submit MT SMS on GSUP */
2518 log("TX MT-forwardSM-Req for the MT SMS");
2519 f_gsup_forwardSM_req(spars_mt);
2520
2521 /* Wait for MT SMS on DTAP */
2522 f_mt_sms_expect(spars_mt);
2523 log("RX MT SMS on DTAP, DTAP TID is ", spars_mt.tid,
2524 ", SM-RP-MR is ", spars_mt.rp.msg_ref);
2525
2526 /* Both SM-RP-MR values shall be different */
2527 if (spars_mo.rp.msg_ref == spars_mt.rp.msg_ref) {
2528 log("Both SM-RP-MR values shall be different");
2529 setverdict(fail);
2530 }
2531
2532 /* SM-RP-MR value for MT SMS shall be assigned */
2533 if (spars_mt.rp.msg_ref == 'FF'O) {
2534 log("Unassigned SM-RP-MR value for the MT SMS");
2535 setverdict(fail);
2536 }
2537
2538 /* Trigger RP-ACK for MO SMMA by sending MO-forwardSM-Res */
2539 GSUP.send(valueof(ts_GSUP_MO_READY_FOR_SM_RES(
2540 imsi := g_pars.imsi,
2541 sm_rp_mr := spars_mo.rp.msg_ref)));
2542 /* Expect RP-ACK for MO SMMA on DTAP */
2543 f_mo_sms_wait_rp_ack(spars_mo);
2544
2545 /* Send RP-ACK for MT SMS and expect MT-forwardSM-Res on GSUP */
2546 f_mt_sms_send_rp_ack(spars_mt);
2547 alt {
2548 [] GSUP.receive(tr_GSUP_MT_FORWARD_SM_RES(
2549 imsi := g_pars.imsi,
2550 sm_rp_mr := spars_mt.rp.msg_ref
2551 )) {
2552 log("RX MT-forwardSM-Res (RP-ACK)");
2553 setverdict(pass);
2554 }
2555 [] GSUP.receive {
2556 log("RX unexpected GSUP message");
2557 setverdict(fail);
2558 mtc.stop;
2559 }
2560 }
2561
2562 f_expect_clear();
2563}
2564testcase TC_gsup_mo_mt_sms_rp_mr() runs on MTC_CT {
2565 var BSC_ConnHdlrPars pars;
2566 var BSC_ConnHdlr vc_conn;
2567 f_init();
2568 pars := f_init_pars(93);
2569 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2570 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mo_mt_sms_rp_mr), pars);
2571 vc_conn.done;
2572 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2573}
2574
Harald Weltee13cfb22019-04-23 16:52:02 +02002575
Vadim Yanitskiy1cd11a02018-12-03 02:43:35 +07002576/* Test multi-part MT-SMS over GSUP */
2577private function f_tc_gsup_mt_multi_part_sms(charstring id, BSC_ConnHdlrPars pars)
2578runs on BSC_ConnHdlr {
2579 var SmsParameters spars := valueof(t_SmsPars);
2580
2581 f_init_handler(pars);
2582
2583 /* We need to inspect GSUP activity */
2584 f_create_gsup_expect(hex2str(g_pars.imsi));
2585
2586 /* Perform location update */
2587 f_perform_lu();
2588
2589 /* Register an 'expect' for given IMSI (+TMSI) */
2590 if (isvalue(g_pars.tmsi)) {
Harald Welte6811d102019-04-14 22:23:14 +02002591 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy1cd11a02018-12-03 02:43:35 +07002592 } else {
Harald Welte6811d102019-04-14 22:23:14 +02002593 f_ran_register_imsi(g_pars.imsi, 'FFFFFFFF'O);
Vadim Yanitskiy1cd11a02018-12-03 02:43:35 +07002594 }
2595
2596 var template GSUP_PDU mt_forwardSM_res := tr_GSUP_MT_FORWARD_SM_RES(
2597 imsi := g_pars.imsi,
2598 /* NOTE: MSC should assign RP-MR itself */
2599 sm_rp_mr := ?
2600 );
2601
2602 /* Send 4 messages (NOTE: SM-RP-UI remains unchanged) */
2603 for (var integer i := 3; i >= 0; i := i-1) {
2604 /* Submit a MT SMS on GSUP (MMS is decremented) */
2605 f_gsup_forwardSM_req(spars, int2oct(i, 1));
2606
2607 /* Expect Paging Request and Establish connection */
2608 if (i == 3) { /* ... only once! */
Harald Weltee13cfb22019-04-23 16:52:02 +02002609 f_expect_paging();
Vadim Yanitskiy1cd11a02018-12-03 02:43:35 +07002610 f_establish_fully(EST_TYPE_PAG_RESP);
2611 }
2612
2613 /* Wait for MT SMS on DTAP */
2614 f_mt_sms_expect(spars);
2615
2616 /* Send RP-ACK and expect MT-forwardSM-Res on GSUP */
2617 f_mt_sms_send_rp_ack(spars);
2618 alt {
2619 [] GSUP.receive(mt_forwardSM_res) {
2620 log("RX MT-forwardSM-Res (RP-ACK)");
2621 setverdict(pass);
2622 }
2623 [] GSUP.receive {
2624 log("RX unexpected GSUP message");
2625 setverdict(fail);
2626 mtc.stop;
2627 }
2628 }
2629
2630 /* Keep some 'distance' between transmissions */
2631 f_sleep(1.5);
2632 }
2633
2634 f_expect_clear();
2635}
2636testcase TC_gsup_mt_multi_part_sms() runs on MTC_CT {
2637 var BSC_ConnHdlrPars pars;
2638 var BSC_ConnHdlr vc_conn;
2639 f_init();
2640 pars := f_init_pars(91);
2641 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2642 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_multi_part_sms), pars);
2643 vc_conn.done;
2644 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2645}
2646
Harald Weltef640a012018-04-14 17:49:21 +02002647/* convert GSM L3 TON to SMPP_TON enum */
2648function f_sm_ton_from_gsm(BIT3 ton) return SMPP_TON {
2649 select (ton) {
2650 case ('000'B) { return unknown; }
2651 case ('001'B) { return international; }
2652 case ('010'B) { return national; }
2653 case ('011'B) { return network_specific; }
2654 case ('100'B) { return subscriber_number; }
2655 case ('101'B) { return alphanumeric; }
2656 case ('110'B) { return abbreviated; }
2657 }
2658 setverdict(fail, "Unknown TON ", ton);
Daniel Willmannafce8662018-07-06 23:11:32 +02002659 mtc.stop;
Harald Weltef640a012018-04-14 17:49:21 +02002660}
2661/* convert GSM L3 NPI to SMPP_NPI enum */
2662function f_sm_npi_from_gsm(BIT4 npi) return SMPP_NPI {
2663 select (npi) {
2664 case ('0000'B) { return unknown; }
2665 case ('0001'B) { return isdn; }
2666 case ('0011'B) { return data; }
2667 case ('0100'B) { return telex; }
2668 case ('0110'B) { return land_mobile; }
2669 case ('1000'B) { return national; }
2670 case ('1001'B) { return private_; }
2671 case ('1010'B) { return ermes; }
2672 }
2673 setverdict(fail, "Unknown NPI ", npi);
Daniel Willmannafce8662018-07-06 23:11:32 +02002674 mtc.stop;
Harald Weltef640a012018-04-14 17:49:21 +02002675}
2676
2677/* build a SMPP_SM from SmsParameters */
2678function f_mt_sm_from_spars(SmsParameters spars)
2679runs on BSC_ConnHdlr return SMPP_SM {
2680 var SMPP_SM sm := {
2681 service_type := "CMT",
2682 source_addr_ton := f_sm_ton_from_gsm(spars.tp.da.tP_DA_NoPad.tP_TypeOfNumber),
2683 source_addr_npi := f_sm_npi_from_gsm(spars.tp.da.tP_DA_NoPad.tP_NumberingPlanID),
2684 source_addr := hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue),
2685 dest_addr_ton := international,
2686 dest_addr_npi := isdn,
2687 destination_addr := hex2str(g_pars.msisdn),
2688 esm_class := '00000001'B,
2689 protocol_id := 0,
2690 priority_flag := 0,
2691 schedule_delivery_time := "",
2692 validity_period := "",
2693 registered_delivery := '00000000'B,
2694 replace_if_present := 0,
2695 data_coding := '00000001'B,
2696 sm_default_msg_id := 0,
2697 sm_length := spars.tp.udl,
2698 short_message := spars.tp.ud,
2699 opt_pars := {}
2700 };
2701 return sm;
2702}
2703
2704/* helper function to encode SMS from 'spars', send it via SMPP to MSC; receive it on MS side */
2705private function f_smpp_mt_sms(SmsParameters spars, boolean trans_mode) runs on BSC_ConnHdlr {
2706 var SMPP_SM sm := f_mt_sm_from_spars(spars);
2707 if (trans_mode) {
2708 sm.esm_class := '00000010'B;
2709 }
2710
2711 /* actually cause MSC to send a SMS via SUBMIT-SM from SMPP side */
2712 SMPP.send(ts_SMPP_SUBMIT_SM(sm));
2713 if (not match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
2714 /* if we're not in SMPP transaction mode, we expect the SMPP-level ACK
2715 * before we expect the SMS delivery on the BSC/radio side */
2716 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
2717 }
2718
2719 /* MSC->BSC: expect PAGING from MSC */
Harald Weltee035e3e2019-04-21 17:32:05 +02002720 f_expect_paging();
Harald Weltef640a012018-04-14 17:49:21 +02002721 /* Establish DTAP / BSSAP / SCCP connection */
2722 f_establish_fully(EST_TYPE_PAG_RESP);
2723 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
2724
2725 f_mt_sms(spars);
2726
2727 if (match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
2728 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
2729 }
2730 f_expect_clear();
2731}
2732
2733/* mobile terminated SMS, from SMPP to BSC/BTS/MS */
2734private function f_tc_smpp_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2735 f_init_handler(pars);
2736
2737 /* Perform location update so IMSI is known + registered in MSC/VLR */
2738 f_perform_lu();
2739 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
2740
2741 /* register an 'expect' for given IMSI (+TMSI) */
2742 var OCT4 tmsi;
2743 if (isvalue(g_pars.tmsi)) {
2744 tmsi := g_pars.tmsi;
2745 } else {
2746 tmsi := 'FFFFFFFF'O;
2747 }
Harald Welte6811d102019-04-14 22:23:14 +02002748 f_ran_register_imsi(g_pars.imsi, tmsi);
Harald Weltef640a012018-04-14 17:49:21 +02002749
2750 var SmsParameters spars := valueof(t_SmsPars);
2751 /* TODO: test with more intelligent user data; test different coding schemes */
2752 spars.tp.ud := '00'O;
2753 spars.tp.udl := 1;
2754
2755 /* first test the non-transaction store+forward mode */
2756 f_smpp_mt_sms(spars, false);
2757
2758 /* then test the transaction mode */
2759 f_smpp_mt_sms(spars, true);
2760}
2761testcase TC_smpp_mt_sms() runs on MTC_CT {
2762 var BSC_ConnHdlr vc_conn;
2763 f_init();
2764 vc_conn := f_start_handler(refers(f_tc_smpp_mt_sms), 45);
2765 vc_conn.done;
2766}
2767
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002768/***********************************************************************
2769 * USSD Testing
2770 ***********************************************************************/
2771
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07002772private altstep as_unexp_gsup_or_bssap_msg()
2773runs on BSC_ConnHdlr {
2774 [] GSUP.receive {
2775 setverdict(fail, "Unknown/unexpected GSUP received");
2776 self.stop;
2777 }
2778 [] BSSAP.receive {
2779 setverdict(fail, "Unknown/unexpected BSSAP message received");
2780 self.stop;
2781 }
2782}
2783
2784private function f_expect_gsup_msg(template GSUP_PDU msg)
2785runs on BSC_ConnHdlr return GSUP_PDU {
2786 var GSUP_PDU gsup_msg_complete;
2787
2788 alt {
2789 [] GSUP.receive(msg) -> value gsup_msg_complete {
2790 setverdict(pass);
2791 }
2792 /* We don't expect anything else */
2793 [] as_unexp_gsup_or_bssap_msg();
2794 }
2795
2796 return gsup_msg_complete;
2797}
2798
2799private function f_expect_mt_dtap_msg(template PDU_ML3_NW_MS msg)
2800runs on BSC_ConnHdlr return PDU_ML3_NW_MS {
2801 var PDU_DTAP_MT bssap_msg_complete;
2802
2803 alt {
2804 [] BSSAP.receive(tr_PDU_DTAP_MT(msg)) -> value bssap_msg_complete {
2805 setverdict(pass);
2806 }
2807 /* We don't expect anything else */
2808 [] as_unexp_gsup_or_bssap_msg();
2809 }
2810
2811 return bssap_msg_complete.dtap;
2812}
2813
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002814/* LU followed by MO USSD request */
Harald Weltee13cfb22019-04-23 16:52:02 +02002815friend function f_tc_lu_and_mo_ussd_single_request(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002816runs on BSC_ConnHdlr {
2817 f_init_handler(pars);
2818
2819 /* Perform location update */
2820 f_perform_lu();
2821
2822 /* Send CM Service Request for SS/USSD */
2823 f_establish_fully(EST_TYPE_SS_ACT);
2824
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002825 /* We need to inspect GSUP activity */
2826 f_create_gsup_expect(hex2str(g_pars.imsi));
2827
2828 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
2829 invoke_id := 5, /* Phone may not start from 0 or 1 */
2830 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2831 ussd_string := "*#100#"
2832 );
2833
2834 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
2835 invoke_id := 5, /* InvokeID shall be the same for both REQ and RSP */
2836 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2837 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
2838 )
2839
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002840 /* Compose a new SS/REGISTER message with request */
2841 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
2842 tid := 1, /* We just need a single transaction */
2843 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002844 facility := valueof(facility_req)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002845 );
2846
2847 /* Compose SS/RELEASE_COMPLETE template with expected response */
2848 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
2849 tid := 1, /* Response should arrive within the same transaction */
2850 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002851 facility := valueof(facility_rsp)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002852 );
2853
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002854 /* Compose expected MSC -> HLR message */
2855 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
2856 imsi := g_pars.imsi,
2857 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2858 ss := valueof(facility_req)
2859 );
2860
2861 /* To be used for sending response with correct session ID */
2862 var GSUP_PDU gsup_req_complete;
2863
2864 /* Request own number */
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002865 BSSAP.send(ts_PDU_DTAP_MO(ussd_req));
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002866 /* Expect GSUP message containing the SS payload */
2867 gsup_req_complete := f_expect_gsup_msg(gsup_req);
2868
2869 /* Compose the response from HLR using received session ID */
2870 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
2871 imsi := g_pars.imsi,
2872 sid := gsup_req_complete.ies[1].val.session_id,
2873 state := OSMO_GSUP_SESSION_STATE_END,
2874 ss := valueof(facility_rsp)
2875 );
2876
2877 /* Finally, HLR terminates the session */
2878 GSUP.send(gsup_rsp);
2879 /* Expect RELEASE_COMPLETE message with the response */
2880 f_expect_mt_dtap_msg(ussd_rsp);
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002881
2882 f_expect_clear();
2883}
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002884testcase TC_lu_and_mo_ussd_single_request() runs on MTC_CT {
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002885 var BSC_ConnHdlr vc_conn;
2886 f_init();
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002887 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_single_request), 46);
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002888 vc_conn.done;
2889}
2890
Harald Weltee13cfb22019-04-23 16:52:02 +02002891
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07002892/* LU followed by MT USSD notification */
Harald Weltee13cfb22019-04-23 16:52:02 +02002893friend function f_tc_lu_and_mt_ussd_notification(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07002894runs on BSC_ConnHdlr {
2895 f_init_handler(pars);
2896
2897 /* Perform location update */
2898 f_perform_lu();
2899
Harald Welte6811d102019-04-14 22:23:14 +02002900 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07002901
2902 /* We need to inspect GSUP activity */
2903 f_create_gsup_expect(hex2str(g_pars.imsi));
2904
2905 /* Facility IE with network-originated USSD notification */
2906 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
2907 op_code := SS_OP_CODE_USS_NOTIFY,
2908 ussd_string := "Mahlzeit!"
2909 );
2910
2911 /* Facility IE with acknowledgment to the USSD notification */
2912 var template OCTN facility_rsp := enc_SS_FacilityInformation(
2913 /* In case of USSD notification, Return Result is empty */
2914 valueof(ts_SS_USSD_FACILITY_RETURN_RESULT_EMPTY())
2915 );
2916
2917 /* Compose a new MT SS/REGISTER message with USSD notification */
2918 var template PDU_ML3_NW_MS ussd_ntf := tr_ML3_MT_SS_REGISTER(
2919 tid := 0, /* FIXME: most likely, it should be 0 */
2920 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2921 facility := valueof(facility_req)
2922 );
2923
2924 /* Compose HLR -> MSC GSUP message */
2925 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
2926 imsi := g_pars.imsi,
2927 sid := '20000101'O,
2928 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2929 ss := valueof(facility_req)
2930 );
2931
2932 /* Send it to MSC and expect Paging Request */
2933 GSUP.send(gsup_req);
2934 alt {
Harald Weltee13cfb22019-04-23 16:52:02 +02002935 [pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
2936 setverdict(pass);
2937 }
Harald Welte62113fc2019-05-09 13:04:02 +02002938 [not pars.ran_is_geran] BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi))) {
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07002939 setverdict(pass);
2940 }
2941 /* We don't expect anything else */
2942 [] as_unexp_gsup_or_bssap_msg();
2943 }
2944
2945 /* Send Paging Response and expect USSD notification */
2946 f_establish_fully(EST_TYPE_PAG_RESP);
2947 /* Expect MT REGISTER message with USSD notification */
2948 f_expect_mt_dtap_msg(ussd_ntf);
2949
2950 /* Compose a new MO SS/FACILITY message with empty response */
2951 var template (value) PDU_ML3_MS_NW ussd_rsp := ts_ML3_MO_SS_FACILITY(
2952 tid := 0, /* FIXME: it shall match the request tid */
2953 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
2954 facility := valueof(facility_rsp)
2955 );
2956
2957 /* Compose expected MSC -> HLR GSUP message */
2958 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_REQ(
2959 imsi := g_pars.imsi,
2960 sid := '20000101'O,
2961 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
2962 ss := valueof(facility_rsp)
2963 );
2964
2965 /* MS sends response to the notification */
2966 BSSAP.send(ts_PDU_DTAP_MO(ussd_rsp));
2967 /* Expect GSUP message containing the SS payload */
2968 f_expect_gsup_msg(gsup_rsp);
2969
2970 /* Compose expected MT SS/RELEASE COMPLETE message */
2971 var template PDU_ML3_NW_MS ussd_term := tr_ML3_MT_SS_RELEASE_COMPLETE(
2972 tid := 0, /* FIXME: it shall match the request tid */
2973 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2974 facility := omit
2975 );
2976
2977 /* Compose MSC -> HLR GSUP message */
2978 var template GSUP_PDU gsup_term := ts_GSUP_PROC_SS_REQ(
2979 imsi := g_pars.imsi,
2980 sid := '20000101'O,
2981 state := OSMO_GSUP_SESSION_STATE_END
2982 );
2983
2984 /* Finally, HLR terminates the session */
2985 GSUP.send(gsup_term)
2986 /* Expect MT RELEASE COMPLETE without Facility IE */
2987 f_expect_mt_dtap_msg(ussd_term);
2988
2989 f_expect_clear();
2990}
2991testcase TC_lu_and_mt_ussd_notification() runs on MTC_CT {
2992 var BSC_ConnHdlr vc_conn;
2993 f_init();
2994 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_ussd_notification), 47);
2995 vc_conn.done;
2996}
2997
Harald Weltee13cfb22019-04-23 16:52:02 +02002998
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002999/* LU followed by MT call and MO USSD request during this call */
Harald Weltee13cfb22019-04-23 16:52:02 +02003000friend function f_tc_lu_and_mo_ussd_during_mt_call(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003001runs on BSC_ConnHdlr {
3002 f_init_handler(pars);
3003
3004 /* Call parameters taken from f_tc_lu_and_mt_call */
3005 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
3006 cpars.mgcp_connection_id_bss := '10004'H;
3007 cpars.mgcp_connection_id_mss := '10005'H;
3008 cpars.mgcp_ep := "rtpbridge/1@mgw";
3009 cpars.bss_rtp_port := 1110;
3010
3011 /* Perform location update */
3012 f_perform_lu();
3013
3014 /* Establish a MT call */
3015 f_mt_call_establish(cpars);
3016
3017 /* Hold the call for some time */
3018 f_sleep(1.0);
3019
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003020 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3021 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3022 ussd_string := "*#100#"
3023 );
3024
3025 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
3026 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3027 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
3028 )
3029
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003030 /* Compose a new SS/REGISTER message with request */
3031 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
3032 tid := 1, /* We just need a single transaction */
3033 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003034 facility := valueof(facility_req)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003035 );
3036
3037 /* Compose SS/RELEASE_COMPLETE template with expected response */
3038 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
3039 tid := 1, /* Response should arrive within the same transaction */
3040 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003041 facility := valueof(facility_rsp)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003042 );
3043
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003044 /* Compose expected MSC -> HLR message */
3045 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
3046 imsi := g_pars.imsi,
3047 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3048 ss := valueof(facility_req)
3049 );
3050
3051 /* To be used for sending response with correct session ID */
3052 var GSUP_PDU gsup_req_complete;
3053
3054 /* Request own number */
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003055 BSSAP.send(ts_PDU_DTAP_MO(ussd_req));
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003056 /* Expect GSUP message containing the SS payload */
3057 gsup_req_complete := f_expect_gsup_msg(gsup_req);
3058
3059 /* Compose the response from HLR using received session ID */
3060 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
3061 imsi := g_pars.imsi,
3062 sid := gsup_req_complete.ies[1].val.session_id,
3063 state := OSMO_GSUP_SESSION_STATE_END,
3064 ss := valueof(facility_rsp)
3065 );
3066
3067 /* Finally, HLR terminates the session */
3068 GSUP.send(gsup_rsp);
3069 /* Expect RELEASE_COMPLETE message with the response */
3070 f_expect_mt_dtap_msg(ussd_rsp);
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003071
3072 /* Hold the call for some time */
3073 f_sleep(1.0);
3074
3075 /* Release the call (does Clear Complete itself) */
3076 f_call_hangup(cpars, true);
3077}
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003078testcase TC_lu_and_mo_ussd_during_mt_call() runs on MTC_CT {
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003079 var BSC_ConnHdlr vc_conn;
3080 f_init();
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003081 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_during_mt_call), 48);
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003082 vc_conn.done;
3083}
3084
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003085/* BSSMAP Clear Request in the middle of a call, see OS#3062 */
Harald Weltee13cfb22019-04-23 16:52:02 +02003086friend function f_tc_mo_cc_bssmap_clear(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003087 f_init_handler(pars);
3088 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
3089 var MNCC_PDU mncc;
3090 var MgcpCommand mgcp_cmd;
3091
3092 f_perform_lu();
3093
3094 f_establish_fully();
3095 f_create_mncc_expect(hex2str(cpars.called_party));
3096 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
3097
3098 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
3099 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
3100 cpars.mncc_callref := mncc.u.signal.callref;
3101 log("mncc_callref=", cpars.mncc_callref);
3102 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
3103 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
3104
3105 MNCC.send(ts_MNCC_ALERT_req(cpars.mncc_callref));
3106 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(cpars.transaction_id)));
3107 MGCP.receive(tr_CRCX);
3108
3109 f_sleep(1.0);
Harald Weltee13cfb22019-04-23 16:52:02 +02003110 if (pars.ran_is_geran) {
3111 BSSAP.send(ts_BSSMAP_ClearRequest(0));
3112 } else {
3113 BSSAP.send(ts_RANAP_IuReleaseRequest(ts_RanapCause_om_intervention));
3114 }
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003115
Neels Hofmeyrde76f052019-02-26 05:02:46 +01003116 var default ccrel := activate(as_optional_cc_rel(cpars));
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003117
Harald Weltee13cfb22019-04-23 16:52:02 +02003118 if (pars.ran_is_geran) {
3119 interleave {
3120 [] MNCC.receive(tr_MNCC_REL_ind(?, ?)) { };
3121 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
Neels Hofmeyrde76f052019-02-26 05:02:46 +01003122 BSSAP.send(ts_BSSMAP_ClearComplete);
Harald Weltee13cfb22019-04-23 16:52:02 +02003123 };
3124 }
3125 } else {
3126 interleave {
3127 [] MNCC.receive(tr_MNCC_REL_ind(?, ?)) { };
3128 [] BSSAP.receive(tr_RANAP_IuReleaseCommand(?)) {
3129 BSSAP.send(ts_RANAP_IuReleaseComplete);
3130 };
3131 }
Neels Hofmeyrde76f052019-02-26 05:02:46 +01003132 }
3133
3134 deactivate(ccrel);
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003135
3136 f_sleep(1.0);
3137}
3138testcase TC_mo_cc_bssmap_clear() runs on MTC_CT {
3139 var BSC_ConnHdlr vc_conn;
3140 f_init();
3141
3142 vc_conn := f_start_handler(refers(f_tc_mo_cc_bssmap_clear), 43);
3143 vc_conn.done;
3144}
3145
Harald Weltee13cfb22019-04-23 16:52:02 +02003146
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003147/* LU followed by MT call and MT USSD request during this call */
Harald Weltee13cfb22019-04-23 16:52:02 +02003148friend function f_tc_lu_and_mt_ussd_during_mt_call(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003149runs on BSC_ConnHdlr {
3150 f_init_handler(pars);
3151
3152 /* Call parameters taken from f_tc_lu_and_mt_call */
3153 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
3154 cpars.mgcp_connection_id_bss := '10004'H;
3155 cpars.mgcp_connection_id_mss := '10005'H;
3156 cpars.mgcp_ep := "rtpbridge/1@mgw";
3157 cpars.bss_rtp_port := 1110;
3158
3159 /* Perform location update */
3160 f_perform_lu();
3161
3162 /* Establish a MT call */
3163 f_mt_call_establish(cpars);
3164
3165 /* Hold the call for some time */
3166 f_sleep(1.0);
3167
3168 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3169 op_code := SS_OP_CODE_USS_REQUEST,
3170 ussd_string := "Please type anything..."
3171 );
3172
3173 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
3174 op_code := SS_OP_CODE_USS_REQUEST,
3175 ussd_string := "Nope."
3176 )
3177
3178 /* Compose MT SS/REGISTER message with network-originated request */
3179 var template (value) PDU_ML3_NW_MS ussd_req := ts_ML3_MT_SS_REGISTER(
3180 tid := 0, /* FIXME: most likely, it should be 0 */
3181 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3182 facility := valueof(facility_req)
3183 );
3184
3185 /* Compose HLR -> MSC GSUP message */
3186 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
3187 imsi := g_pars.imsi,
3188 sid := '20000101'O,
3189 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3190 ss := valueof(facility_req)
3191 );
3192
3193 /* Send it to MSC */
3194 GSUP.send(gsup_req);
3195 /* Expect MT REGISTER message with USSD request */
3196 f_expect_mt_dtap_msg(ussd_req);
3197
3198 /* Compose a new MO SS/FACILITY message with response */
3199 var template (value) PDU_ML3_MS_NW ussd_rsp := ts_ML3_MO_SS_FACILITY(
3200 tid := 0, /* FIXME: it shall match the request tid */
3201 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3202 facility := valueof(facility_rsp)
3203 );
3204
3205 /* Compose expected MSC -> HLR GSUP message */
3206 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_REQ(
3207 imsi := g_pars.imsi,
3208 sid := '20000101'O,
3209 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
3210 ss := valueof(facility_rsp)
3211 );
3212
3213 /* MS sends response */
3214 BSSAP.send(ts_PDU_DTAP_MO(ussd_rsp));
3215 f_expect_gsup_msg(gsup_rsp);
3216
3217 /* Compose expected MT SS/RELEASE COMPLETE message */
3218 var template PDU_ML3_NW_MS ussd_term := tr_ML3_MT_SS_RELEASE_COMPLETE(
3219 tid := 0, /* FIXME: it shall match the request tid */
3220 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3221 facility := omit
3222 );
3223
3224 /* Compose MSC -> HLR GSUP message */
3225 var template GSUP_PDU gsup_term := ts_GSUP_PROC_SS_REQ(
3226 imsi := g_pars.imsi,
3227 sid := '20000101'O,
3228 state := OSMO_GSUP_SESSION_STATE_END
3229 );
3230
3231 /* Finally, HLR terminates the session */
3232 GSUP.send(gsup_term);
3233 /* Expect MT RELEASE COMPLETE without Facility IE */
3234 f_expect_mt_dtap_msg(ussd_term);
3235
3236 /* Hold the call for some time */
3237 f_sleep(1.0);
3238
3239 /* Release the call (does Clear Complete itself) */
3240 f_call_hangup(cpars, true);
3241}
3242testcase TC_lu_and_mt_ussd_during_mt_call() runs on MTC_CT {
3243 var BSC_ConnHdlr vc_conn;
3244 f_init();
3245 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_ussd_during_mt_call), 49);
3246 vc_conn.done;
3247}
3248
Harald Weltee13cfb22019-04-23 16:52:02 +02003249
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07003250/* LU followed by MO USSD request and MO Release during transaction */
Harald Weltee13cfb22019-04-23 16:52:02 +02003251friend function f_tc_lu_and_mo_ussd_mo_release(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07003252runs on BSC_ConnHdlr {
3253 f_init_handler(pars);
3254
3255 /* Perform location update */
3256 f_perform_lu();
3257
3258 /* Send CM Service Request for SS/USSD */
3259 f_establish_fully(EST_TYPE_SS_ACT);
3260
3261 /* We need to inspect GSUP activity */
3262 f_create_gsup_expect(hex2str(g_pars.imsi));
3263
3264 var template OCTN facility_ms_req := f_USSD_FACILITY_IE_INVOKE(
3265 invoke_id := 1, /* Initial request */
3266 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3267 ussd_string := "*6766*266#"
3268 );
3269
3270 var template OCTN facility_net_req := f_USSD_FACILITY_IE_INVOKE(
3271 invoke_id := 2, /* Counter request */
3272 op_code := SS_OP_CODE_USS_REQUEST,
3273 ussd_string := "Password?!?"
3274 )
3275
3276 /* Compose MO SS/REGISTER message with request */
3277 var template (value) PDU_ML3_MS_NW ussd_ms_req := ts_ML3_MO_SS_REGISTER(
3278 tid := 1, /* We just need a single transaction */
3279 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3280 facility := valueof(facility_ms_req)
3281 );
3282
3283 /* Compose expected MSC -> HLR message */
3284 var template GSUP_PDU gsup_ms_req := tr_GSUP_PROC_SS_REQ(
3285 imsi := g_pars.imsi,
3286 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3287 ss := valueof(facility_ms_req)
3288 );
3289
3290 /* To be used for sending response with correct session ID */
3291 var GSUP_PDU gsup_ms_req_complete;
3292
3293 /* Initiate a new transaction */
3294 BSSAP.send(ts_PDU_DTAP_MO(ussd_ms_req));
3295 /* Expect GSUP request with original Facility IE */
3296 gsup_ms_req_complete := f_expect_gsup_msg(gsup_ms_req);
3297
3298 /* Compose the response from HLR using received session ID */
3299 var template (value) GSUP_PDU gsup_net_req := ts_GSUP_PROC_SS_REQ(
3300 imsi := g_pars.imsi,
3301 sid := gsup_ms_req_complete.ies[1].val.session_id,
3302 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
3303 ss := valueof(facility_net_req)
3304 );
3305
3306 /* Compose expected MT SS/FACILITY template with counter request */
3307 var template PDU_ML3_NW_MS ussd_net_req := tr_ML3_MT_SS_FACILITY(
3308 tid := 1, /* Response should arrive within the same transaction */
3309 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3310 facility := valueof(facility_net_req)
3311 );
3312
3313 /* Send response over GSUP */
3314 GSUP.send(gsup_net_req);
3315 /* Expect MT SS/FACILITY message with counter request */
3316 f_expect_mt_dtap_msg(ussd_net_req);
3317
3318 /* Compose MO SS/RELEASE COMPLETE */
3319 var template (value) PDU_ML3_MS_NW ussd_abort := ts_ML3_MO_SS_RELEASE_COMPLETE(
3320 tid := 1, /* Response should arrive within the same transaction */
3321 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3322 facility := omit
3323 /* TODO: cause? */
3324 );
3325
3326 /* Compose expected HLR -> MSC abort message */
3327 var template GSUP_PDU gsup_abort := tr_GSUP_PROC_SS_REQ(
3328 imsi := g_pars.imsi,
3329 sid := gsup_ms_req_complete.ies[1].val.session_id,
3330 state := OSMO_GSUP_SESSION_STATE_END
3331 );
3332
3333 /* Abort transaction */
3334 BSSAP.send(ts_PDU_DTAP_MO(ussd_abort));
3335 /* Expect GSUP message indicating abort */
3336 f_expect_gsup_msg(gsup_abort);
3337
3338 f_expect_clear();
3339}
3340testcase TC_lu_and_mo_ussd_mo_release() runs on MTC_CT {
3341 var BSC_ConnHdlr vc_conn;
3342 f_init();
3343 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_mo_release), 50);
3344 vc_conn.done;
3345}
3346
Harald Weltee13cfb22019-04-23 16:52:02 +02003347
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003348/* LU followed by MO USSD request and MT Release due to timeout */
Harald Weltee13cfb22019-04-23 16:52:02 +02003349friend function f_tc_lu_and_ss_session_timeout(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003350runs on BSC_ConnHdlr {
3351 f_init_handler(pars);
3352
3353 /* Perform location update */
3354 f_perform_lu();
3355
3356 /* Send CM Service Request for SS/USSD */
3357 f_establish_fully(EST_TYPE_SS_ACT);
3358
3359 /* We need to inspect GSUP activity */
3360 f_create_gsup_expect(hex2str(g_pars.imsi));
3361
3362 var template OCTN facility_ms_req := f_USSD_FACILITY_IE_INVOKE(
3363 invoke_id := 1,
3364 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3365 ussd_string := "#release_me");
3366
3367 /* Compose MO SS/REGISTER message with request */
3368 var template (value) PDU_ML3_MS_NW ussd_ms_req := ts_ML3_MO_SS_REGISTER(
3369 tid := 1, /* An arbitrary transaction identifier */
3370 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3371 facility := valueof(facility_ms_req));
3372
3373 /* Compose expected MSC -> HLR message */
3374 var template GSUP_PDU gsup_ms_req := tr_GSUP_PROC_SS_REQ(
3375 imsi := g_pars.imsi,
3376 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3377 ss := valueof(facility_ms_req));
3378
3379 /* To be used for sending response with correct session ID */
3380 var GSUP_PDU gsup_ms_req_complete;
3381
3382 /* Initiate a new SS transaction */
3383 BSSAP.send(ts_PDU_DTAP_MO(ussd_ms_req));
3384 /* Expect GSUP request with original Facility IE */
3385 gsup_ms_req_complete := f_expect_gsup_msg(gsup_ms_req);
3386
3387 /* Don't respond, wait for timeout */
3388 f_sleep(3.0);
3389
3390 var template PDU_ML3_NW_MS dtap_rel := tr_ML3_MT_SS_RELEASE_COMPLETE(
3391 tid := 1, /* Should match the request's tid */
3392 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3393 cause := *, /* TODO: expect some specific value */
3394 facility := omit);
3395
3396 var template GSUP_PDU gsup_rel := tr_GSUP_PROC_SS_ERR(
3397 imsi := g_pars.imsi,
3398 sid := gsup_ms_req_complete.ies[1].val.session_id,
3399 state := OSMO_GSUP_SESSION_STATE_END,
3400 cause := ?); /* TODO: expect some specific value */
3401
3402 /* Expect release on both interfaces */
3403 interleave {
3404 [] BSSAP.receive(tr_PDU_DTAP_MT(dtap_rel)) { };
3405 [] GSUP.receive(gsup_rel) { };
3406 }
3407
3408 f_expect_clear();
3409 setverdict(pass);
3410}
3411testcase TC_lu_and_ss_session_timeout() runs on MTC_CT {
3412 var BSC_ConnHdlr vc_conn;
3413 f_init();
Vadim Yanitskiy36d28dd2018-12-03 02:45:45 +07003414 f_vty_config(MSCVTY, "msc", "ncss guard-timeout 3");
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003415 vc_conn := f_start_handler(refers(f_tc_lu_and_ss_session_timeout), 51);
3416 vc_conn.done;
Vadim Yanitskiy36d28dd2018-12-03 02:45:45 +07003417 f_vty_config(MSCVTY, "msc", "ncss guard-timeout 0");
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003418}
3419
Harald Weltee13cfb22019-04-23 16:52:02 +02003420
Stefan Sperling89eb1f32018-12-17 15:06:20 +01003421/* A5/1 only permitted on network side; attempt an invalid CIPHER MODE COMPLETE with A5/3 which MSC should reject. */
3422private function f_tc_cipher_complete_with_invalid_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
3423 pars.net.expect_auth := true;
3424 pars.net.expect_ciph := true;
3425 pars.net.kc_support := '02'O; /* A5/1 only */
3426 f_init_handler(pars);
3427
3428 g_pars.vec := f_gen_auth_vec_2g();
3429
3430 /* Can't use f_perform_lu() directly. Code below is based on it. */
3431
3432 /* tell GSUP dispatcher to send this IMSI to us */
3433 f_create_gsup_expect(hex2str(g_pars.imsi));
3434
3435 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
3436 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
Harald Weltedceacc72019-04-21 20:58:35 +02003437 f_cl3_or_initial_ue(l3_lu);
Stefan Sperling89eb1f32018-12-17 15:06:20 +01003438
3439 f_mm_auth();
3440
3441 var OCT1 a5_net := f_alg_mask_from_cm(g_pars.cm2);
3442 var OCT1 a5_intersect := g_pars.net.kc_support and4b a5_net;
3443 alt {
3444 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(a5_intersect, g_pars.vec.kc)) {
3445 BSSAP.send(ts_BSSMAP_CipherModeCompl(int2oct(4 /* "accept" A5/3 */, 1)));
3446 }
3447 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc)) {
3448 setverdict(fail, "Wrong ciphering algorithm mask in CiphModCmd");
3449 mtc.stop;
3450 }
3451 [] BSSAP.receive {
3452 setverdict(fail, "Unknown/unexpected BSSAP received");
3453 mtc.stop;
3454 }
3455 }
3456
3457 /* Expect LU reject from MSC. */
3458 alt {
3459 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
3460 setverdict(pass);
3461 }
3462 [] BSSAP.receive {
3463 setverdict(fail, "Unknown/unexpected BSSAP received");
3464 mtc.stop;
3465 }
3466 }
Stefan Sperlingc620b352018-12-18 17:23:36 +01003467 f_expect_clear();
Stefan Sperling89eb1f32018-12-17 15:06:20 +01003468}
3469
3470testcase TC_cipher_complete_with_invalid_cipher() runs on MTC_CT {
3471 var BSC_ConnHdlr vc_conn;
3472 f_init();
3473 f_vty_config(MSCVTY, "network", "encryption a5 1");
3474
3475 vc_conn := f_start_handler(refers(f_tc_cipher_complete_with_invalid_cipher), 52);
3476 vc_conn.done;
3477}
3478
Harald Welteb2284bd2019-05-10 11:30:43 +02003479/* Location Update with invalid (non-matching) MCC/MNC reported on BSSMAP level from BSC */
3480friend function f_tc_lu_with_invalid_mcc_mnc(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
3481 f_init_handler(pars);
3482
3483 /* tell GSUP dispatcher to send this IMSI to us */
3484 f_create_gsup_expect(hex2str(g_pars.imsi));
3485
3486 /* modify the cell ID which will be used to construct the COMPLELTE L3 or InitialUE */
3487 g_pars.cell_id := valueof(ts_CellId_CGI('333'H, '22'H, 23, 42));
3488
3489 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
3490 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
3491 f_cl3_or_initial_ue(l3_lu);
3492
3493 /* Expect LU reject from MSC. */
3494 alt {
3495 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
3496 setverdict(pass);
3497 }
3498 [] BSSAP.receive {
3499 setverdict(fail, "Unknown/unexpected BSSAP received");
3500 mtc.stop;
3501 }
3502 }
3503 f_expect_clear();
3504}
3505testcase TC_lu_with_invalid_mcc_mnc() runs on MTC_CT {
3506 var BSC_ConnHdlr vc_conn;
3507 f_init();
3508 vc_conn := f_start_handler(refers(f_tc_lu_with_invalid_mcc_mnc), 54);
3509 vc_conn.done;
3510}
3511
Stefan Sperlinga2d59c62018-12-18 16:32:44 +01003512private function f_tc_cipher_complete_without_alg(charstring id, BSC_ConnHdlrPars pars, octetstring kc_support) runs on BSC_ConnHdlr {
3513 pars.net.expect_auth := true;
3514 pars.net.expect_ciph := true;
3515 pars.net.kc_support := kc_support;
3516 f_init_handler(pars);
3517
3518 g_pars.vec := f_gen_auth_vec_2g();
3519
3520 /* Can't use f_perform_lu() directly. Code below is based on it. */
3521
3522 /* tell GSUP dispatcher to send this IMSI to us */
3523 f_create_gsup_expect(hex2str(g_pars.imsi));
3524
3525 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
3526 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
3527 f_cl3_or_initial_ue(l3_lu);
3528
3529 f_mm_auth();
3530
3531 var OCT1 a5_net := f_alg_mask_from_cm(g_pars.cm2);
3532 var OCT1 a5_intersect := g_pars.net.kc_support and4b a5_net;
3533 alt {
3534 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(a5_intersect, g_pars.vec.kc)) {
3535 BSSAP.send(ts_BSSMAP_CipherModeComplAlg(omit));
3536 }
3537 [] BSSAP.receive(tr_BSSMAP_ClassmarkReq) {
3538 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
3539 repeat;
3540 }
3541 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc)) {
3542 setverdict(fail, "Wrong ciphering algorithm mask in CiphModCmd");
3543 mtc.stop;
3544 }
3545 [] BSSAP.receive {
3546 setverdict(fail, "Unknown/unexpected BSSAP received");
3547 mtc.stop;
3548 }
3549 }
3550
3551 /* TODO: Verify MSC is using the best cipher available! How? */
3552
3553 f_msc_lu_hlr();
3554 f_accept_reject_lu();
3555 f_expect_clear();
3556 setverdict(pass);
3557}
3558
3559/* A5/1 only permitted on network side; attempt CIPHER MODE COMPLETE without specifying the accepted algorithm. */
3560private function f_tc_cipher_complete_1_without_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
3561 f_tc_cipher_complete_without_alg(id, pars, '02'O /* A5/1 only */);
3562}
3563
3564/* A5/3 only permitted on network side; attempt CIPHER MODE COMPLETE without specifying the accepted algorithm. */
3565private function f_tc_cipher_complete_3_without_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
3566 f_tc_cipher_complete_without_alg(id, pars, '08'O /* A5/3 only */);
3567}
3568
3569/* A5/1 + A5/3 permitted on network side; attempt CIPHER MODE COMPLETE without specifying the accepted algorithm. */
3570private function f_tc_cipher_complete_13_without_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
3571 f_tc_cipher_complete_without_alg(id, pars, '0A'O /* A5/1 and A5/3 enabled */);
3572}
3573
3574testcase TC_cipher_complete_1_without_cipher() runs on MTC_CT {
3575 var BSC_ConnHdlr vc_conn;
3576 f_init();
3577 f_vty_config(MSCVTY, "network", "encryption a5 1");
3578
3579 vc_conn := f_start_handler(refers(f_tc_cipher_complete_1_without_cipher), 53);
3580 vc_conn.done;
3581}
3582
3583testcase TC_cipher_complete_3_without_cipher() runs on MTC_CT {
3584 var BSC_ConnHdlr vc_conn;
3585 f_init();
3586 f_vty_config(MSCVTY, "network", "encryption a5 3");
3587
3588 vc_conn := f_start_handler(refers(f_tc_cipher_complete_3_without_cipher), 54);
3589 vc_conn.done;
3590}
3591
3592testcase TC_cipher_complete_13_without_cipher() runs on MTC_CT {
3593 var BSC_ConnHdlr vc_conn;
3594 f_init();
3595 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
3596
3597 vc_conn := f_start_handler(refers(f_tc_cipher_complete_13_without_cipher), 55);
3598 vc_conn.done;
3599}
Harald Welteb2284bd2019-05-10 11:30:43 +02003600
Harald Weltef640a012018-04-14 17:49:21 +02003601/* TODO (SMS):
3602 * different user data lengths
3603 * SMPP transaction mode with unsuccessful delivery
3604 * queued MT-SMS with no paging response + later delivery
3605 * different data coding schemes
3606 * multi-part SMS
3607 * user-data headers
3608 * TP-PID for SMS to SIM
3609 * behavior if SMS memory is full + RP-SMMA
3610 * delivery reports
3611 * SMPP osmocom extensions
3612 * more-messages-to-send
3613 * SMS during ongoing call (SACCH/SAPI3)
3614 */
3615
3616/* TODO (General):
Harald Welteba7b6d92018-01-23 21:32:34 +01003617 * continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
3618 * malformed messages (missing IE, invalid message type): properly rejected?
3619 * MT call while LU or is ongoing: Do we use existing lchan or page while lchan active?
3620 * 3G/2G auth permutations
3621 * encryption algorithms vs. classmark vs. vty config
Harald Welteba7b6d92018-01-23 21:32:34 +01003622 * send new transaction after/during clear (like SMS, ...)
Harald Welte45164da2018-01-24 12:51:27 +01003623 * too long L3 INFO in DTAP
3624 * too long / padded BSSAP
3625 * too long / short TLV values
Harald Welteba7b6d92018-01-23 21:32:34 +01003626 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01003627
Harald Weltee13cfb22019-04-23 16:52:02 +02003628/***********************************************************************
3629 * SGsAP Testing
3630 ***********************************************************************/
3631
Philipp Maier948747b2019-04-02 15:22:33 +02003632/* Check if a subscriber exists in the VLR */
3633private function f_ctrl_subscr_in_vlr(charstring imsi_or_msisdn) runs on BSC_ConnHdlr return boolean {
3634
3635 var CtrlValue active_subsribers;
3636 var integer rc;
3637 active_subsribers := f_ctrl_get(IPA_CTRL, "subscriber-list-active-v1");
3638
3639 rc := f_strstr(active_subsribers, imsi_or_msisdn);
3640 if (rc < 0) {
3641 return false;
3642 }
3643
3644 return true;
3645}
3646
Harald Welte4263c522018-12-06 11:56:27 +01003647/* Perform a location updatye at the A-Interface and run some checks to confirm
3648 * that everything is back to normal. */
3649private function f_sgsap_bssmap_screening() runs on BSC_ConnHdlr {
3650 var SmsParameters spars := valueof(t_SmsPars);
3651
3652 /* Perform a location update, the SGs association is expected to fall
3653 * back to NULL */
3654 f_perform_lu();
3655 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
3656
3657 /* Trigger a paging request and expect the paging on BSSMAP, this is
3658 * to make sure that pagings are sent throught the A-Interface again
3659 * and not throught the SGs interface.*/
Harald Welte6811d102019-04-14 22:23:14 +02003660 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Harald Welte4263c522018-12-06 11:56:27 +01003661 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
3662
3663 alt {
Harald Weltee13cfb22019-04-23 16:52:02 +02003664 [g_pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)); {
3665 setverdict(pass);
3666 }
Harald Welte62113fc2019-05-09 13:04:02 +02003667 [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 +01003668 setverdict(pass);
3669 }
3670 [] SGsAP.receive {
3671 setverdict(fail, "Received unexpected message on SGs");
3672 }
3673 }
3674
3675 /* Send an SMS to make sure that also payload messages are routed
3676 * throught the A-Interface again */
3677 f_establish_fully(EST_TYPE_MO_SMS);
3678 f_mo_sms(spars);
3679 f_expect_clear();
3680}
3681
3682private function f_tc_sgsap_reset(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
3683 var charstring vlr_name;
3684 f_init_handler(pars);
3685
3686 vlr_name := f_sgsap_reset_mme(mp_mme_name);
3687 log("VLR name: ", vlr_name);
3688 setverdict(pass);
Neels Hofmeyrc0b520d2019-03-06 15:35:50 +01003689 f_sleep(1.0);
Harald Welte4263c522018-12-06 11:56:27 +01003690}
3691
3692testcase TC_sgsap_reset() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003693 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01003694 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003695 f_init(1, true);
3696 pars := f_init_pars(11810, true);
3697 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_reset), pars);
Harald Welte4263c522018-12-06 11:56:27 +01003698 vc_conn.done;
3699}
3700
3701/* like f_mm_auth() but for SGs */
3702function f_mm_auth_sgs() runs on BSC_ConnHdlr {
3703 if (g_pars.net.expect_auth) {
3704 g_pars.vec := f_gen_auth_vec_3g();
3705 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
3706 g_pars.vec.sres,
3707 g_pars.vec.kc,
3708 g_pars.vec.ik,
3709 g_pars.vec.ck,
3710 g_pars.vec.autn,
3711 g_pars.vec.res));
3712 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
3713 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
3714 SGsAP.receive(tr_ML3_MT_MM_AUTH_REQ_3G(g_pars.vec.rand, g_pars.vec.autn));
3715 SGsAP.send(ts_ML3_MT_MM_AUTH_RESP_3G(g_pars.vec.sres, g_pars.vec.res));
3716 }
3717}
3718
3719/* like f_perform_lu(), but on SGs rather than BSSAP */
3720function f_sgs_perform_lu() runs on BSC_ConnHdlr {
3721 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
3722 var PDU_SGsAP lur;
3723 var PDU_SGsAP lua;
3724 var PDU_SGsAP mm_info;
3725 var octetstring mm_info_dtap;
3726
3727 /* tell GSUP dispatcher to send this IMSI to us */
3728 f_create_gsup_expect(hex2str(g_pars.imsi));
3729
3730 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
3731 ts_SGsAP_LAI('901'H, '70'H, 2342)));
3732 /* Old LAI, if MS sends it */
3733 /* TMSI status, if MS has no valid TMSI */
3734 /* IMEISV, if it supports "automatic device detection" */
3735 /* TAI, if available in MME */
3736 /* E-CGI, if available in MME */
3737 SGsAP.send(lur);
3738
3739 /* FIXME: is this really done over SGs? The Ue is already authenticated
3740 * via the MME ... */
3741 f_mm_auth_sgs();
3742
3743 /* Expect MSC to perform LU with HLR */
3744 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
3745 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
3746 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
3747 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
3748
3749 alt {
3750 [] SGsAP.receive(tr_SGsAP_LU_ACCEPT(g_pars.imsi, ?)) -> value lua {
3751 if (isvalue(lua.sGsAP_LOCATION_UPDATE_ACCEPT.newTMSIorIMSI.iD.iD.tmsi_ptmsi.octets)) {
3752 g_pars.tmsi :=lua.sGsAP_LOCATION_UPDATE_ACCEPT.newTMSIorIMSI.iD.iD.tmsi_ptmsi.octets
3753 SGsAP.send(ts_SGsAP_TMSI_REALL_CMPL(g_pars.imsi));
3754 }
3755 setverdict(pass);
3756 }
3757 [] SGsAP.receive(tr_SGsAP_LU_REJECT(g_pars.imsi, ?, ?)) {
3758 setverdict(fail, "Received LU-REJECT instead of ACCEPT");
3759 }
3760 [] SGsAP.receive {
3761 setverdict(fail, "Received unexpected message on SGs");
3762 }
3763 }
3764
3765 /* Check MM information */
3766 if (mp_mm_info == true) {
3767 SGsAP.receive(tr_SGsAP_MM_INFO_REQ(g_pars.imsi, ?)) -> value mm_info;
3768 mm_info_dtap := '0532'O & mm_info.sGsAP_MM_INFORMATION_REQUEST.mM_Information.information;
3769 if (not match(dec_PDU_ML3_NW_MS(mm_info_dtap), tr_ML3_MT_MM_Info)) {
3770 setverdict(fail, "Unexpected MM Information");
3771 }
3772 }
3773
3774 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
3775}
3776
3777private function f_tc_sgsap_lu(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
3778 f_init_handler(pars);
3779 f_sgs_perform_lu();
3780 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
3781
3782 f_sgsap_bssmap_screening();
3783
3784 setverdict(pass);
3785}
3786testcase TC_sgsap_lu() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003787 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01003788 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003789 f_init(1, true);
3790 pars := f_init_pars(11811, true);
3791 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu), pars);
Harald Welte4263c522018-12-06 11:56:27 +01003792 vc_conn.done;
3793}
3794
3795/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
3796private function f_tc_sgsap_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
3797 f_init_handler(pars);
3798 var PDU_SGsAP lur;
3799
3800 f_create_gsup_expect(hex2str(g_pars.imsi));
3801 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
3802 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
3803 ts_SGsAP_LAI('901'H, '70'H, 2342)));
3804 SGsAP.send(lur);
3805
3806 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
3807 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
3808 alt {
3809 [] SGsAP.receive(tr_SGsAP_LU_REJECT(g_pars.imsi, ?, ?)) {
3810 setverdict(pass);
3811 }
3812 [] SGsAP.receive(tr_SGsAP_LU_ACCEPT(g_pars.imsi, ?)) {
3813 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
3814 mtc.stop;
3815 }
3816 [] SGsAP.receive {
3817 setverdict(fail, "Received unexpected message on SGs");
3818 }
3819 }
3820
3821 f_sgsap_bssmap_screening();
3822
3823 setverdict(pass);
3824}
3825testcase TC_sgsap_lu_imsi_reject() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003826 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01003827 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003828 f_init(1, true);
3829 pars := f_init_pars(11812, true);
Harald Welte4263c522018-12-06 11:56:27 +01003830
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003831 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu_imsi_reject), pars);
Harald Welte4263c522018-12-06 11:56:27 +01003832 vc_conn.done;
3833}
3834
3835/* Do LU by IMSI, but then remain silent so that Ts6-1 times out */
3836private function f_tc_sgsap_lu_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
3837 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
3838 var PDU_SGsAP lur;
3839
3840 f_init_handler(pars);
3841
3842 /* tell GSUP dispatcher to send this IMSI to us */
3843 f_create_gsup_expect(hex2str(g_pars.imsi));
3844
3845 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
3846 ts_SGsAP_LAI('901'H, '70'H, 2342)));
3847 /* Old LAI, if MS sends it */
3848 /* TMSI status, if MS has no valid TMSI */
3849 /* IMEISV, if it supports "automatic device detection" */
3850 /* TAI, if available in MME */
3851 /* E-CGI, if available in MME */
3852 SGsAP.send(lur);
3853
3854 /* FIXME: is this really done over SGs? The Ue is already authenticated
3855 * via the MME ... */
3856 f_mm_auth_sgs();
3857
3858 /* Expect MSC to perform LU with HLR */
3859 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
3860 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
3861 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
3862 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
3863
3864 alt {
3865 [] SGsAP.receive(tr_SGsAP_LU_ACCEPT(g_pars.imsi, ?)) {
3866 setverdict(pass);
3867 }
3868 [] SGsAP.receive(tr_SGsAP_LU_REJECT(g_pars.imsi, ?, ?)) {
3869 setverdict(fail, "Received LU-REJECT instead of ACCEPT");
3870 }
3871 [] SGsAP.receive {
3872 setverdict(fail, "Received unexpected message on SGs");
3873 }
3874 }
3875
3876 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
3877
3878 /* Wait until the VLR has abort the TMSI reallocation procedure */
3879 f_sleep(45.0);
3880
3881 /* The outcome does not change the SGs state, see also 5.2.3.4 */
3882 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
3883
3884 f_sgsap_bssmap_screening();
3885
3886 setverdict(pass);
3887}
3888testcase TC_sgsap_lu_and_nothing() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003889 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01003890 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003891 f_init(1, true);
3892 pars := f_init_pars(11813, true);
Harald Welte4263c522018-12-06 11:56:27 +01003893
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003894 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu_and_nothing), pars);
Harald Welte4263c522018-12-06 11:56:27 +01003895 vc_conn.done;
3896}
3897
3898private function f_tc_sgsap_expl_imsi_det_eps(charstring id, BSC_ConnHdlrPars pars)
3899runs on BSC_ConnHdlr {
3900 f_init_handler(pars);
3901 f_sgs_perform_lu();
3902 f_sleep(3.0);
3903
3904 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
3905 SGsAP.send(ts_SGsAP_EPS_DETACH_IND(g_pars.imsi, mme_name, UE_initiated));
3906 SGsAP.receive(tr_SGsAP_EPS_DETACH_ACK(g_pars.imsi));
3907 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
3908
3909 f_sgsap_bssmap_screening();
3910
3911 setverdict(pass);
3912}
3913testcase TC_sgsap_expl_imsi_det_eps() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003914 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01003915 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003916 f_init(1, true);
3917 pars := f_init_pars(11814, true);
3918 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_expl_imsi_det_eps), pars);
Harald Welte4263c522018-12-06 11:56:27 +01003919 vc_conn.done;
3920}
3921
Philipp Maierfc19f172019-03-21 11:17:54 +01003922private function f_tc_sgsap_impl_imsi_det_eps(charstring id, BSC_ConnHdlrPars pars)
3923runs on BSC_ConnHdlr {
3924 f_init_handler(pars);
3925 f_sgs_perform_lu();
3926 f_sleep(3.0);
3927
3928 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
3929 SGsAP.send(ts_SGsAP_EPS_DETACH_IND(g_pars.imsi, mme_name, network_initiated));
3930 SGsAP.receive(tr_SGsAP_EPS_DETACH_ACK(g_pars.imsi));
3931 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
3932
3933 f_sgsap_bssmap_screening();
3934
3935 setverdict(pass);
3936}
3937testcase TC_sgsap_impl_imsi_det_eps() runs on MTC_CT {
3938 var BSC_ConnHdlrPars pars;
3939 var BSC_ConnHdlr vc_conn;
3940 f_init(1, true);
3941 pars := f_init_pars(11814, true);
3942 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_impl_imsi_det_eps), pars);
3943 vc_conn.done;
3944}
3945
Harald Welte4263c522018-12-06 11:56:27 +01003946private function f_tc_sgsap_expl_imsi_det_noneps(charstring id, BSC_ConnHdlrPars pars)
3947runs on BSC_ConnHdlr {
3948 f_init_handler(pars);
3949 f_sgs_perform_lu();
3950 f_sleep(3.0);
3951
3952 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
3953 SGsAP.send(ts_SGsAP_IMSI_DETACH_IND(g_pars.imsi, mme_name, combined_UE_initiated));
3954 SGsAP.receive(tr_SGsAP_IMSI_DETACH_ACK(g_pars.imsi));
Philipp Maierd08e7e72019-04-02 15:27:10 +02003955
3956 if (f_ctrl_subscr_in_vlr(hex2str(g_pars.imsi))) {
3957 setverdict(fail, "subscriber not removed from VLR");
3958 }
Harald Welte4263c522018-12-06 11:56:27 +01003959
3960 f_sgsap_bssmap_screening();
3961
3962 setverdict(pass);
3963}
3964testcase TC_sgsap_expl_imsi_det_noneps() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003965 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01003966 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003967 f_init(1, true);
3968 pars := f_init_pars(11815, true);
3969 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_expl_imsi_det_noneps), pars);
Harald Welte4263c522018-12-06 11:56:27 +01003970 vc_conn.done;
3971}
3972
Philipp Maier5d812702019-03-21 10:51:26 +01003973private function f_tc_sgsap_impl_imsi_det_noneps(charstring id, BSC_ConnHdlrPars pars)
3974runs on BSC_ConnHdlr {
3975 f_init_handler(pars);
3976 f_sgs_perform_lu();
3977 f_sleep(3.0);
3978
3979 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
3980 SGsAP.send(ts_SGsAP_IMSI_DETACH_IND(g_pars.imsi, mme_name, implicit_network_initiated));
3981 SGsAP.receive(tr_SGsAP_IMSI_DETACH_ACK(g_pars.imsi));
3982
3983 if (f_ctrl_subscr_in_vlr(hex2str(g_pars.imsi))) {
3984 setverdict(fail, "subscriber not removed from VLR");
3985 }
3986
3987 f_sgsap_bssmap_screening();
3988
3989 setverdict(pass);
3990}
3991testcase TC_sgsap_impl_imsi_det_noneps() runs on MTC_CT {
3992 var BSC_ConnHdlrPars pars;
3993 var BSC_ConnHdlr vc_conn;
3994 f_init(1, true);
3995 pars := f_init_pars(11815, true);
3996 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_impl_imsi_det_noneps), pars);
3997 vc_conn.done;
3998}
3999
Harald Welte4263c522018-12-06 11:56:27 +01004000/* Trigger a paging request via VTY and send a paging reject in response */
4001private function f_tc_sgsap_paging_rej(charstring id, BSC_ConnHdlrPars pars)
4002runs on BSC_ConnHdlr {
4003 f_init_handler(pars);
4004 f_sgs_perform_lu();
4005 f_sleep(1.0);
4006
4007 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4008 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
4009 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4010 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4011
4012 /* Initiate paging via VTY */
4013 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4014 alt {
4015 [] SGsAP.receive(exp_resp) {
4016 setverdict(pass);
4017 }
4018 [] SGsAP.receive {
4019 setverdict(fail, "Received unexpected message on SGs");
4020 }
4021 }
4022
4023 /* Now reject the paging */
4024 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, IMSI_unknown));
4025
4026 /* Wait for the states inside the MSC to settle and check the state
4027 * of the SGs Association */
4028 f_sleep(1.0);
4029 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4030
4031 /* FIXME: At the moment we send an IMSI_unknown as cause code, which is fine,
4032 * but we also need to cover tha case where the cause code indicates an
4033 * "IMSI detached for EPS services". In those cases the VLR is expected to
4034 * try paging on tha A/Iu interface. This will be another testcase similar to
4035 * this one, but extended with checks for the presence of the A/Iu paging
4036 * messages. */
4037
4038 f_sgsap_bssmap_screening();
4039
4040 setverdict(pass);
4041}
4042testcase TC_sgsap_paging_rej() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004043 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004044 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004045 f_init(1, true);
4046 pars := f_init_pars(11816, true);
4047 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_rej), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004048 vc_conn.done;
4049}
4050
4051/* Trigger a paging request via VTY and send a paging reject that indicates
4052 * that the subscriber intentionally rejected the call. */
4053private function f_tc_sgsap_paging_subscr_rej(charstring id, BSC_ConnHdlrPars pars)
4054runs on BSC_ConnHdlr {
4055 f_init_handler(pars);
4056 f_sgs_perform_lu();
4057 f_sleep(1.0);
4058
4059 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4060 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
4061 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4062 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4063
4064 /* Initiate paging via VTY */
4065 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4066 alt {
4067 [] SGsAP.receive(exp_resp) {
4068 setverdict(pass);
4069 }
4070 [] SGsAP.receive {
4071 setverdict(fail, "Received unexpected message on SGs");
4072 }
4073 }
4074
4075 /* Now reject the paging */
4076 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, user_rejected_mobile_terminating_CS_fallback_call));
4077
4078 /* Wait for the states inside the MSC to settle and check the state
4079 * of the SGs Association */
4080 f_sleep(1.0);
4081 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4082
4083 /* FIXME: The VLR is supposed to trigger an User Determined User Busy (UDUB) as specified
4084 * in 3GPP TS 24.082, this is not yet implemented in the MSC or in this tests, we need
4085 * to check back how this works and how it can be tested */
4086
4087 f_sgsap_bssmap_screening();
4088
4089 setverdict(pass);
4090}
4091testcase TC_sgsap_paging_subscr_rej() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004092 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004093 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004094 f_init(1, true);
4095 pars := f_init_pars(11817, true);
4096 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_subscr_rej), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004097 vc_conn.done;
4098}
4099
4100/* Trigger a paging request via VTY and send an UE unreacable messge in response */
4101private function f_tc_sgsap_paging_ue_unr(charstring id, BSC_ConnHdlrPars pars)
4102runs on BSC_ConnHdlr {
4103 f_init_handler(pars);
4104 f_sgs_perform_lu();
4105 f_sleep(1.0);
4106
4107 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4108 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
4109 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4110 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4111
4112 /* Initiate paging via VTY */
4113 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4114 alt {
4115 [] SGsAP.receive(exp_resp) {
4116 setverdict(pass);
4117 }
4118 [] SGsAP.receive {
4119 setverdict(fail, "Received unexpected message on SGs");
4120 }
4121 }
4122
4123 /* Now pretend that the UE is unreachable */
4124 SGsAP.send(ts_SGsAP_UE_UNREACHABLE(g_pars.imsi, UE_unreachable));
4125
4126 /* Wait for the states inside the MSC to settle and check the state
4127 * of the SGs Association. */
4128 f_sleep(1.0);
4129 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4130
4131 f_sgsap_bssmap_screening();
4132
4133 setverdict(pass);
4134}
4135testcase TC_sgsap_paging_ue_unr() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004136 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004137 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004138 f_init(1, true);
4139 pars := f_init_pars(11818, true);
4140 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_ue_unr), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004141 vc_conn.done;
4142}
4143
4144/* Trigger a paging request via VTY but don't respond to it */
4145private function f_tc_sgsap_paging_and_nothing(charstring id, BSC_ConnHdlrPars pars)
4146runs on BSC_ConnHdlr {
4147 f_init_handler(pars);
4148 f_sgs_perform_lu();
4149 f_sleep(1.0);
4150
4151 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4152 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
4153 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4154 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4155
4156 /* Initiate paging via VTY */
4157 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4158 alt {
4159 [] SGsAP.receive(exp_resp) {
4160 setverdict(pass);
4161 }
4162 [] SGsAP.receive {
4163 setverdict(fail, "Received unexpected message on SGs");
4164 }
4165 }
4166
4167 /* Now do nothing, the MSC/VLR should fail silently to page after a
4168 * few seconds, The SGs association must remain unchanged. */
4169 f_sleep(15.0);
4170 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4171
4172 f_sgsap_bssmap_screening();
4173
4174 setverdict(pass);
4175}
4176testcase TC_sgsap_paging_and_nothing() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004177 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004178 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004179 f_init(1, true);
4180 pars := f_init_pars(11819, true);
4181 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_and_nothing), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004182 vc_conn.done;
4183}
4184
4185/* Trigger a paging request via VTY and slip in an LU */
4186private function f_tc_sgsap_paging_and_lu(charstring id, BSC_ConnHdlrPars pars)
4187runs on BSC_ConnHdlr {
4188 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4189 f_init_handler(pars);
4190
4191 /* First we prepar the situation, where the SGs association is in state
4192 * NULL and the confirmed by radio contact indicator is set to false
4193 * as well. This can be archived by performing an SGs LU and then
4194 * resetting the VLR */
4195 f_sgs_perform_lu();
4196 f_sgsap_reset_mme(mp_mme_name);
4197 f_sleep(1.0);
4198 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4199
4200 /* Perform a paging, expect the paging messages on the SGs interface */
4201 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4202 alt {
4203 [] SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit)) {
4204 setverdict(pass);
4205 }
4206 [] SGsAP.receive {
4207 setverdict(fail, "Received unexpected message on SGs");
4208 }
4209 }
4210
4211 /* Perform the LU as normal */
4212 f_sgs_perform_lu();
4213 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4214
4215 /* Expect a new paging request right after the LU */
4216 alt {
4217 [] SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit)) {
4218 setverdict(pass);
4219 }
4220 [] SGsAP.receive {
4221 setverdict(fail, "Received unexpected message on SGs");
4222 }
4223 }
4224
4225 /* Test is done now, lets round everything up by rejecting the paging
4226 * cleanly. */
4227 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, user_rejected_mobile_terminating_CS_fallback_call));
4228 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4229
4230 f_sgsap_bssmap_screening();
4231
4232 setverdict(pass);
4233}
4234testcase TC_sgsap_paging_and_lu() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004235 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004236 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004237 f_init(1, true);
4238 pars := f_init_pars(11820, true);
4239 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_and_lu), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004240 vc_conn.done;
4241}
4242
4243/* Send unexpected unit-data through the SGs interface */
4244private function f_tc_sgsap_unexp_ud(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4245 f_init_handler(pars);
4246 f_sleep(1.0);
4247
4248 /* This simulates what happens when a subscriber without SGs
4249 * association gets unitdata via the SGs interface. */
4250
4251 /* Make sure the subscriber exists and the SGs association
4252 * is in NULL state */
4253 f_perform_lu();
4254 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4255
4256 /* Send some random unit data, the MSC/VLR should send a release
4257 * immediately. */
4258 SGsAP.send(ts_SGsAP_UL_UD(pars.imsi,'1234'O));
4259 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, IMSI_detached_for_EPS_nonEPS_services));
4260
4261 f_sgsap_bssmap_screening();
4262
4263 setverdict(pass);
4264}
4265testcase TC_sgsap_unexp_ud() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004266 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004267 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004268 f_init(1, true);
4269 pars := f_init_pars(11821, true);
4270 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_unexp_ud), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004271 vc_conn.done;
4272}
4273
4274/* Send unsolicited unit-data through the SGs interface */
4275private function f_tc_sgsap_unsol_ud(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4276 f_init_handler(pars);
4277 f_sleep(1.0);
4278
4279 /* This simulates what happens when the MME attempts to send unitdata
4280 * to a subscriber that is completely unknown to the VLR */
4281
4282 /* Send some random unit data, the MSC/VLR should send a release
4283 * immediately. */
4284 SGsAP.send(ts_SGsAP_UL_UD(pars.imsi,'1234'O));
4285 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, IMSI_unknown));
4286
4287 f_sgsap_bssmap_screening();
4288
4289 setverdict(pass);
4290}
4291testcase TC_sgsap_unsol_ud() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004292 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004293 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004294 f_init(1, true);
4295 pars := f_init_pars(11822, true);
4296 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_unsol_ud), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004297 vc_conn.done;
4298}
4299
4300private altstep as_other_sms_sgs() runs on BSC_ConnHdlr {
4301 /* FIXME: Match an actual payload (second questionmark), the type is
4302 * octetstring, how do we use a tr_PDU_DTAP_MT here? */
4303 [] SGsAP.receive(tr_SGsAP_DL_UD(?,?)) {
4304 setverdict(fail, "Unexpected SMS related PDU from MSC");
4305 mtc.stop;
4306 }
4307}
4308
4309/* receive a MT-SMS delivered from the MSC/SMSC over an already existing SGsAP connection */
4310function f_mt_sms_sgs(inout SmsParameters spars)
4311runs on BSC_ConnHdlr {
4312 var template (value) TPDU_RP_DATA_MS_SGSN tp_mo;
4313 var template (value) RPDU_MS_SGSN rp_mo;
4314 var template (value) PDU_ML3_MS_NW l3_mo;
4315
4316 var template TPDU_RP_DATA_SGSN_MS tp_mt;
4317 var template RPDU_SGSN_MS rp_mt;
4318 var template PDU_ML3_NW_MS l3_mt;
4319
4320 var PDU_ML3_NW_MS sgsap_l3_mt;
4321
4322 var default d := activate(as_other_sms_sgs());
4323
4324 /* Expect CP-DATA(RP-DATA(SMS-DELIVER)) */
4325 tp_mt := tr_SMS_DELIVER(?, spars.tp.ud, spars.tp.pid, spars.tp.dcs, ?);
4326 rp_mt := tr_RP_DATA_MT(?, ?, omit, tp_mt);
4327 l3_mt := tr_ML3_MT_SMS(?, c_TIF_ORIG, tr_CP_DATA_MT(rp_mt));
4328
4329 SGsAP.receive(l3_mt) -> value sgsap_l3_mt;
4330
4331 /* Extract relevant identifiers */
4332 spars.tid := bit2int(sgsap_l3_mt.tiOrSkip.transactionId.tio);
4333 spars.rp.msg_ref := sgsap_l3_mt.msgs.sms.cP_DATA.cP_User_Data.cP_RPDU.rP_DATA_SGSN_MS.rP_MessageReference;
4334
4335 /* send CP-ACK for CP-DATA just received */
4336 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_REPL, ts_CP_ACK_MO);
4337
4338 SGsAP.send(l3_mo);
4339
4340 /* send RP-ACK for RP-DATA */
4341 rp_mo := ts_RP_ACK_MO(spars.rp.msg_ref);
4342 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_REPL, ts_CP_DATA_MO(rp_mo));
4343
4344 SGsAP.send(l3_mo);
4345
4346 /* expect CP-ACK for CP-DATA(RP-ACK) just sent */
4347 l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_ORIG, tr_CP_ACK_MT);
4348
4349 SGsAP.receive(l3_mt);
4350
4351 deactivate(d);
4352
4353 setverdict(pass);
4354}
4355
4356/* submit a MO-SMS to MSC/SMSC over an already existing SGsAP connection */
4357function f_mo_sms_sgs(inout SmsParameters spars)
4358runs on BSC_ConnHdlr {
4359 var template (value) TPDU_RP_DATA_MS_SGSN tp_mo;
4360 var template (value) RPDU_MS_SGSN rp_mo;
4361 var template (value) PDU_ML3_MS_NW l3_mo;
4362
4363 var template TPDU_RP_DATA_SGSN_MS tp_mt;
4364 var template RPDU_SGSN_MS rp_mt;
4365 var template PDU_ML3_NW_MS l3_mt;
4366
4367 var default d := activate(as_other_sms_sgs());
4368
4369 /* just in case this is routed to SMPP.. */
4370 f_create_smpp_expect(hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue));
4371
4372 tp_mo := ts_SMS_SUBMIT(spars.tp.msg_ref, spars.tp.da, spars.tp.pid, spars.tp.dcs,
4373 spars.tp.udl, spars.tp.ud);
4374 rp_mo := ts_RP_DATA_MO(spars.rp.msg_ref, spars.rp.orig, spars.rp.dest, tp_mo);
4375 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_DATA_MO(rp_mo));
4376
4377 SGsAP.send(l3_mo);
4378
4379 /* receive CP-ACK for CP-DATA above */
4380 SGsAP.receive(tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_ACK_MT));
4381
4382 if (ispresent(spars.exp_rp_err)) {
4383 /* expect an RP-ERROR message from MSC with given cause */
4384 rp_mt := tr_RP_ERROR_MT(spars.rp.msg_ref, spars.exp_rp_err);
4385 l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_DATA_MT(rp_mt));
4386 SGsAP.receive(l3_mt);
4387 /* send CP-ACK for CP-DATA just received */
4388 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_ACK_MO);
4389 SGsAP.send(l3_mo);
4390 } else {
4391 /* expect RP-ACK for RP-DATA */
4392 rp_mt := tr_RP_ACK_MT(spars.rp.msg_ref);
4393 l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_DATA_MT(rp_mt));
4394 SGsAP.receive(l3_mt);
4395 /* send CP-ACO for CP-DATA just received */
4396 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_ACK_MO);
4397 SGsAP.send(l3_mo);
4398 }
4399
4400 deactivate(d);
4401
4402 setverdict(pass);
4403}
4404
4405private function f_vty_sms_send_conn_hdlr(charstring imsi, charstring msisdn, charstring text)
4406runs on BSC_ConnHdlr {
4407 f_vty_transceive(MSCVTY, "subscriber imsi "&imsi&" sms sender msisdn "&msisdn&" send "&text);
4408}
4409
4410/* Send a MT SMS via SGs interface */
4411private function f_tc_sgsap_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4412 f_init_handler(pars);
4413 f_sgs_perform_lu();
4414 f_sleep(1.0);
4415 var SmsParameters spars := valueof(t_SmsPars);
4416 spars.tp.ud := 'C8329BFD064D9B53'O;
4417
4418 /* Trigger SMS via VTY */
4419 f_vty_sms_send_conn_hdlr(hex2str(pars.imsi), "2342", "Hello SMS");
4420 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4421
4422 /* Expect a paging request and respond accordingly with a service request */
4423 SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, SMS_indicator, omit));
4424 SGsAP.send(ts_SGsAP_SERVICE_REQ(pars.imsi, SMS_indicator, EMM_CONNECTED));
4425
4426 /* Connection is now live, receive the MT-SMS */
4427 f_mt_sms_sgs(spars);
4428
4429 /* Expect a concluding release from the MSC */
4430 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, omit));
4431
4432 /* Make sure that subscriber is still present and the SGs association is in tact (ref-counting) */
4433 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4434
4435 f_sgsap_bssmap_screening();
4436
4437 setverdict(pass);
4438}
4439testcase TC_sgsap_mt_sms() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004440 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004441 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004442 f_init(1, true);
4443 pars := f_init_pars(11823, true);
4444 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mt_sms), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004445 vc_conn.done;
4446}
4447
4448/* Send a MO SMS via SGs interface */
4449private function f_tc_sgsap_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4450 f_init_handler(pars);
4451 f_sgs_perform_lu();
4452 f_sleep(1.0);
4453 var SmsParameters spars := valueof(t_SmsPars);
4454 spars.tp.ud := 'C8329BFD064D9B53'O;
4455
4456 /* Send the MO-SMS */
4457 f_mo_sms_sgs(spars);
4458
4459 /* Expect a concluding release from the MSC/VLR */
4460 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, omit));
4461
4462 /* Make sure that subscriber is still present and the SGs association is in tact (ref-counting) */
4463 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4464
4465 setverdict(pass);
4466
4467 f_sgsap_bssmap_screening()
4468}
4469testcase TC_sgsap_mo_sms() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004470 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004471 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004472 f_init(1, true);
4473 pars := f_init_pars(11824, true);
4474 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mo_sms), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004475 vc_conn.done;
4476}
4477
4478/* Trigger sending of an MT sms via VTY but never respond to anything */
4479private function f_tc_sgsap_mt_sms_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4480 f_init_handler(pars, 170.0);
4481 f_sgs_perform_lu();
4482 f_sleep(1.0);
4483
4484 var SmsParameters spars := valueof(t_SmsPars);
4485 spars.tp.ud := 'C8329BFD064D9B53'O;
4486 var integer page_count := 0;
4487 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4488 var template PDU_SGsAP exp_pag_req := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, SMS_indicator, omit);
4489 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4490 exp_pag_req.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4491
4492 /* Trigger SMS via VTY */
4493 f_vty_sms_send_conn_hdlr(hex2str(pars.imsi), "2342", "Hello SMS");
4494
Neels Hofmeyr16237742019-03-06 15:34:01 +01004495 /* Expect the MSC/VLR to page exactly once */
4496 SGsAP.receive(exp_pag_req);
Harald Welte4263c522018-12-06 11:56:27 +01004497
4498 /* Wait some time to make sure the MSC is not delivering any further
4499 * paging messages or anything else that could be unexpected. */
4500 timer T := 20.0;
4501 T.start
4502 alt {
4503 [] SGsAP.receive(exp_pag_req)
4504 {
4505 setverdict(fail, "paging seems not to stop!");
4506 mtc.stop;
4507 }
4508 [] SGsAP.receive {
4509 setverdict(fail, "unexpected SGsAP message received");
4510 self.stop;
4511 }
4512 [] T.timeout {
4513 setverdict(pass);
4514 }
4515 }
4516
4517 /* Even on a failed paging the SGs Association should stay intact */
4518 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4519
4520 /* Note: We do not execute f_sgsap_bssmap_screening() here since the
4521 * MSC/VLR would re-try to deliver the test SMS trigered above and
4522 * so the screening would fail. */
4523
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01004524 f_vty_sms_clear(hex2str(g_pars.imsi));
4525
Harald Welte4263c522018-12-06 11:56:27 +01004526 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " expire");
4527
4528 setverdict(pass);
Neels Hofmeyrb0f82342019-03-06 15:36:51 +01004529
4530 f_sgsap_bssmap_screening();
Harald Welte4263c522018-12-06 11:56:27 +01004531}
4532testcase TC_sgsap_mt_sms_and_nothing() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004533 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004534 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004535 f_init(1, true);
4536 pars := f_init_pars(11825, true);
4537 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mt_sms_and_nothing), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004538 vc_conn.done;
4539}
4540
4541/* Trigger sending of an MT sms via VTY but reject the paging immediately */
4542private function f_tc_sgsap_mt_sms_and_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4543 f_init_handler(pars, 150.0);
4544 f_sgs_perform_lu();
4545 f_sleep(1.0);
4546
4547 var SmsParameters spars := valueof(t_SmsPars);
4548 spars.tp.ud := 'C8329BFD064D9B53'O;
4549 var integer page_count := 0;
4550 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4551 var template PDU_SGsAP exp_pag_req := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, SMS_indicator, omit);
4552 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4553 exp_pag_req.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4554
4555 /* Trigger SMS via VTY */
4556 f_vty_sms_send_conn_hdlr(hex2str(pars.imsi), "2342", "Hello SMS");
4557
4558 /* Expect a paging request and reject it immediately */
4559 SGsAP.receive(exp_pag_req);
4560 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, IMSI_unknown));
4561
4562 /* The MSC/VLR should no longer try to page once the paging has been
4563 * rejected. Wait some time and check if there are no unexpected
4564 * messages on the SGs interface. */
4565 timer T := 20.0;
4566 T.start
4567 alt {
4568 [] SGsAP.receive(exp_pag_req)
4569 {
4570 setverdict(fail, "paging seems not to stop!");
4571 mtc.stop;
4572 }
4573 [] SGsAP.receive {
4574 setverdict(fail, "unexpected SGsAP message received");
4575 self.stop;
4576 }
4577 [] T.timeout {
4578 setverdict(pass);
4579 }
4580 }
4581
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01004582 f_vty_sms_clear(hex2str(g_pars.imsi));
4583
Harald Welte4263c522018-12-06 11:56:27 +01004584 /* A rejected paging with IMSI_unknown (see above) should always send
4585 * the SGs association to NULL. */
4586 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4587
4588 f_sgsap_bssmap_screening();
4589
Harald Welte4263c522018-12-06 11:56:27 +01004590 setverdict(pass);
4591}
4592testcase TC_sgsap_mt_sms_and_reject() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004593 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004594 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004595 f_init(1, true);
4596 pars := f_init_pars(11826, true);
4597 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mt_sms_and_reject), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004598 vc_conn.done;
4599}
4600
4601/* Perform an MT CSDB call including LU */
4602private function f_mt_lu_and_csfb_call(charstring id, BSC_ConnHdlrPars pars, boolean bssmap_lu) runs on BSC_ConnHdlr {
4603 f_init_handler(pars);
4604
4605 /* Be sure that the BSSMAP reset is done before we begin. */
4606 f_sleep(2.0);
4607
4608 /* Testcase variation: See what happens when we do a regular BSSMAP
4609 * LU first (this should not hurt in any way!) */
4610 if (bssmap_lu) {
4611 f_perform_lu();
4612 }
4613
4614 f_sgs_perform_lu();
4615 f_sleep(1.0);
4616
4617 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4618 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
4619 cpars.bss_rtp_port := 1110;
4620 cpars.mgcp_connection_id_bss := '10004'H;
4621 cpars.mgcp_connection_id_mss := '10005'H;
4622
4623 /* Note: This is an optional parameter. When the call-agent (MSC) does
4624 * supply a full endpoint name this setting will be overwritten. */
4625 cpars.mgcp_ep := "rtpbridge/1@mgw";
4626
4627 /* Initiate a call via MNCC interface */
4628 f_mt_call_initate(cpars);
4629
4630 /* Expect a paging request and respond accordingly with a service request */
4631 SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit));
4632 SGsAP.send(ts_SGsAP_SERVICE_REQ(pars.imsi, CS_call_indicator, EMM_CONNECTED));
4633
4634 /* Complete the call, hold it for some time and then tear it down */
4635 f_mt_call_complete(cpars);
4636 f_sleep(3.0);
Harald Welte4c422b72019-02-17 16:27:10 +01004637 f_call_hangup(cpars, true, is_csfb := true);
Harald Welte4263c522018-12-06 11:56:27 +01004638
4639 /* Make sure that subscriber is still present and the SGs association is in tact (ref-counting) */
4640 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4641
4642 /* Finally simulate the return of the UE to the 4G network */
4643 SGsAP.send(ts_SGsAP_MO_CSFB_IND(pars.imsi));
4644
4645 /* Test for successful return by triggering a paging, when the paging
4646 * request is received via SGs, we can be sure that the MSC/VLR has
4647 * recognized that the UE is now back on 4G */
4648 f_sleep(1.0);
4649 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4650 alt {
4651 [] SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit)) {
4652 setverdict(pass);
4653 }
4654 [] SGsAP.receive {
4655 setverdict(fail, "Received unexpected message on SGs");
4656 }
4657 }
4658
4659 f_sgsap_bssmap_screening();
4660
4661 setverdict(pass);
4662}
4663
4664/* Perform a regular BSSAP LU first, do a SGSAP LU and then make a CSFB call */
4665private function f_tc_bssap_lu_sgsap_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4666 f_mt_lu_and_csfb_call(id, pars, true);
4667}
4668testcase TC_bssap_lu_sgsap_lu_and_mt_call() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004669 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004670 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004671 f_init(1, true);
4672 pars := f_init_pars(118139, true);
Harald Welte4263c522018-12-06 11:56:27 +01004673
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004674 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 +01004675 vc_conn.done;
4676}
4677
4678
4679/* Perform a SGSAP LU and then make a CSFB call */
4680private function f_tc_sgsap_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4681 f_mt_lu_and_csfb_call(id, pars, false);
4682}
4683testcase TC_sgsap_lu_and_mt_call() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004684 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004685 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004686 f_init(1, true);
4687 pars := f_init_pars(11827, true);
Harald Welte4263c522018-12-06 11:56:27 +01004688
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004689 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu_and_mt_call), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004690 vc_conn.done;
4691}
4692
Philipp Maier628c0052019-04-09 17:36:57 +02004693/* Simulate an HLR/VLR failure */
4694private function f_tc_sgsap_vlr_failure(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4695 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4696 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4697
4698 var PDU_SGsAP lur;
4699
4700 f_init_handler(pars);
4701
4702 /* Attempt location update (which is expected to fail) */
4703 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
4704 ts_SGsAP_LAI('901'H, '70'H, 2342)));
4705 SGsAP.send(lur);
4706
4707 /* Respond to SGsAP-RESET-INDICATION from VLR */
4708 alt {
4709 [] SGsAP.receive(tr_SGsAP_RESET_IND_VLR(vlr_name)); {
4710 SGsAP.send(valueof(ts_SGsAP_RESET_ACK_MME(mme_name)));
4711 setverdict(pass);
4712 }
4713 [] SGsAP.receive {
4714 setverdict(fail, "Received unexpected message on SGs");
4715 }
4716 }
4717
4718 f_sleep(1.0);
4719 setverdict(pass);
4720}
4721testcase TC_sgsap_vlr_failure() runs on MTC_CT {
4722 var BSC_ConnHdlrPars pars;
4723 var BSC_ConnHdlr vc_conn;
4724 f_init(1, true, false);
4725 pars := f_init_pars(11811, true, false);
4726 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_vlr_failure), pars);
4727 vc_conn.done;
4728}
4729
Harald Welte4263c522018-12-06 11:56:27 +01004730/* SGs TODO:
4731 * LU attempt for IMSI without NAM_PS in HLR
4732 * LU attempt with AUTH FAIL due to invalid RES/SRES
4733 * LU attempt with no response from HLR (VLR should timeout + LU REJ)
4734 * LU attempt with new TMSI but without TMSI REALL CMPL baco to VLR
4735 * implicit IMSI detach from EPS
4736 * implicit IMSI detach from non-EPS
4737 * MM INFO
4738 *
4739 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01004740
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02004741private function f_tc_ho_inter_bsc_unknown_cell(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4742 f_init_handler(pars);
4743 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
4744 cpars.bss_rtp_port := 1110;
4745 cpars.mgcp_connection_id_bss := '22222'H;
4746 cpars.mgcp_connection_id_mss := '33333'H;
4747 cpars.mgcp_ep := "rtpbridge/1@mgw";
4748 cpars.mo_call := true;
4749
4750 f_perform_lu();
4751 f_mo_call_establish(cpars);
4752
4753 f_sleep(1.0);
4754
4755 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
4756 var BssmapCause cause := enum2int(cause_val);
4757
4758 var template BSSMAP_FIELD_CellIdentificationList cil;
4759 cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('023'H, '42'H, 999) } };
4760
4761 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
4762 BSSAP.receive(tr_BSSMAP_HandoverRequiredReject);
4763
4764 f_call_hangup(cpars, true);
4765}
4766testcase TC_ho_inter_bsc_unknown_cell() runs on MTC_CT {
4767 var BSC_ConnHdlr vc_conn;
4768 f_init();
4769
4770 vc_conn := f_start_handler(refers(f_tc_ho_inter_bsc_unknown_cell), 53);
4771 vc_conn.done;
4772}
4773
4774private altstep as_mgcp_ack_all_mdcx(CallParameters cpars) runs on BSC_ConnHdlr {
4775 var MgcpCommand mgcp_cmd;
4776 [] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
4777 var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_mss, cpars.mgw_rtp_ip_mss,
4778 hex2str(cpars.mgcp_call_id), "42",
4779 cpars.mgw_rtp_port_mss,
4780 { int2str(cpars.rtp_payload_type) },
4781 { valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
4782 cpars.rtp_sdp_format)),
4783 valueof(ts_SDP_ptime(20)) }));
4784 MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
4785 repeat;
4786 }
4787}
4788
4789private function f_tc_ho_inter_bsc0(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4790 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
4791 cpars.bss_rtp_port := 1110;
4792 cpars.mgcp_connection_id_bss := '22222'H;
4793 cpars.mgcp_connection_id_mss := '33333'H;
4794 cpars.mgcp_ep := "rtpbridge/1@mgw";
4795 cpars.mo_call := true;
4796
4797 f_init_handler(pars);
4798
4799 f_vty_transceive(MSCVTY, "configure terminal");
4800 f_vty_transceive(MSCVTY, "msc");
4801 f_vty_transceive(MSCVTY, "neighbor a cgi 262 42 23 42 ran-pc 0.24.1");
4802 f_vty_transceive(MSCVTY, "neighbor a lac 5 ran-pc 0.24.2");
4803 f_vty_transceive(MSCVTY, "exit");
4804 f_vty_transceive(MSCVTY, "exit");
4805
4806 f_perform_lu();
4807 f_mo_call_establish(cpars);
4808
4809 f_sleep(1.0);
4810
4811 var default ack_mdcx := activate(as_mgcp_ack_all_mdcx(cpars));
4812
4813 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
4814 var BssmapCause cause := enum2int(cause_val);
4815
4816 var template BSSMAP_FIELD_CellIdentificationList cil;
4817 cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('023'H, '42'H, 5) } };
4818
4819 /* old BSS sends Handover Required */
4820 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
4821
4822 /* Now the action goes on in f_tc_ho_inter_bsc1() */
4823
4824 /* MSC forwards the RR Handover Command to old BSS */
4825 var PDU_BSSAP ho_command;
4826 BSSAP.receive(tr_BSSMAP_HandoverCommand) -> value ho_command;
4827
4828 log("GOT HandoverCommand", ho_command);
4829
4830 BSSAP.receive(tr_BSSMAP_HandoverSucceeded);
4831
4832 /* f_tc_ho_inter_bsc1() completes Handover, then expecting a Clear here. */
4833 f_expect_clear();
4834
4835 log("FIRST inter-BSC Handover done");
4836
4837
4838 /* ------------------------ */
4839
4840 /* Ok, that went well, now the other BSC is handovering back here --
4841 * from now on this here is the new BSS. */
4842 f_create_bssmap_exp_handoverRequest(193);
4843
4844 var PDU_BSSAP ho_request;
4845 BSSAP.receive(tr_BSSMAP_HandoverRequest) -> value ho_request;
4846
4847 /* new BSS composes a RR Handover Command */
4848 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
4849 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
4850 var BSSMAP_IE_AoIP_TransportLayerAddress tla := valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
4851 BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
4852 tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
4853
4854 /* Now f_tc_ho_inter_bsc1() expects HandoverCommand */
4855
4856 f_sleep(0.5);
4857
4858 /* Notify that the MS is now over here */
4859
4860 BSSAP.send(ts_BSSMAP_HandoverDetect);
4861 f_sleep(0.1);
4862 BSSAP.send(ts_BSSMAP_HandoverComplete);
4863
4864 f_sleep(3.0);
4865
4866 deactivate(ack_mdcx);
4867
4868 var default ccrel := activate(as_optional_cc_rel(cpars, true));
4869
4870 /* blatant cheating */
4871 var N_Sd_Array last_n_sd := f_bssmap_last_n_sd();
4872 last_n_sd[0] := 3;
4873 f_bssmap_continue_after_n_sd(last_n_sd);
4874
4875 f_call_hangup(cpars, true);
4876 f_sleep(1.0);
4877 deactivate(ccrel);
4878
4879 setverdict(pass);
4880}
4881private function f_tc_ho_inter_bsc1(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4882 f_init_handler(pars);
4883 f_create_bssmap_exp_handoverRequest(194);
4884
4885 var PDU_BSSAP ho_request;
4886 BSSAP.receive(tr_BSSMAP_HandoverRequest) -> value ho_request;
4887
4888 /* new BSS composes a RR Handover Command */
4889 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
4890 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
4891 var BSSMAP_IE_AoIP_TransportLayerAddress tla := valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
4892 BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
4893 tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
4894
4895 /* Now f_tc_ho_inter_bsc0() expects HandoverCommand */
4896
4897 f_sleep(0.5);
4898
4899 /* Notify that the MS is now over here */
4900
4901 BSSAP.send(ts_BSSMAP_HandoverDetect);
4902 f_sleep(0.1);
4903 BSSAP.send(ts_BSSMAP_HandoverComplete);
4904
4905 f_sleep(3.0);
4906
4907 /* Now I'd like to f_call_hangup() but we don't know any cpars here. So
4908 * ... handover back to the first BSC :P */
4909
4910 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
4911 var BssmapCause cause := enum2int(cause_val);
4912
4913 var template BSSMAP_FIELD_CellIdentificationList cil;
4914 cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('262'H, '42'H, 23) } };
4915
4916 /* old BSS sends Handover Required */
4917 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
4918
4919 /* Now the action goes on in f_tc_ho_inter_bsc0() */
4920
4921 /* MSC forwards the RR Handover Command to old BSS */
4922 var PDU_BSSAP ho_command;
4923 BSSAP.receive(tr_BSSMAP_HandoverCommand) -> value ho_command;
4924
4925 log("GOT HandoverCommand", ho_command);
4926
4927 BSSAP.receive(tr_BSSMAP_HandoverSucceeded);
4928
4929 /* f_tc_ho_inter_bsc1() completes Handover, then expecting a Clear here. */
4930 f_expect_clear();
4931 setverdict(pass);
4932}
4933testcase TC_ho_inter_bsc() runs on MTC_CT {
4934 var BSC_ConnHdlr vc_conn0;
4935 var BSC_ConnHdlr vc_conn1;
4936 f_init(2);
4937
4938 var BSC_ConnHdlrPars pars0 := f_init_pars(53);
4939 var BSC_ConnHdlrPars pars1 := f_init_pars(53);
4940
4941 vc_conn0 := f_start_handler_with_pars(refers(f_tc_ho_inter_bsc0), pars0, 0);
4942 vc_conn1 := f_start_handler_with_pars(refers(f_tc_ho_inter_bsc1), pars1, 1);
4943 vc_conn0.done;
4944 vc_conn1.done;
4945}
4946
4947function f_ML3_patch_seq_nr_MS_NW(in uint2_t seq_nr, inout octetstring enc_l3) {
4948 log("MS_NW patching N(SD)=", seq_nr, " into dtap ", enc_l3);
4949 enc_l3[2] := (enc_l3[2] and4b '3f'O) or4b bit2oct(int2bit(seq_nr, 8) << 6);
4950 log("MS_NW patched enc_l3: ", enc_l3);
4951}
4952
4953private function f_tc_ho_inter_msc_out(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4954 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
4955 cpars.bss_rtp_port := 1110;
4956 cpars.mgcp_connection_id_bss := '22222'H;
4957 cpars.mgcp_connection_id_mss := '33333'H;
4958 cpars.mgcp_ep := "rtpbridge/1@mgw";
4959 cpars.mo_call := true;
4960 var hexstring ho_number := f_gen_msisdn(99999);
4961
4962 f_init_handler(pars);
4963
4964 f_create_mncc_expect(hex2str(ho_number));
4965
4966 f_vty_transceive(MSCVTY, "configure terminal");
4967 f_vty_transceive(MSCVTY, "msc");
4968 f_vty_transceive(MSCVTY, "neighbor a cgi 017 017 1 1 msc-ipa-name msc-017-017-1");
4969 f_vty_transceive(MSCVTY, "exit");
4970 f_vty_transceive(MSCVTY, "exit");
4971
4972 f_perform_lu();
4973 f_mo_call_establish(cpars);
4974
4975 f_sleep(1.0);
4976
4977 var default ack_mdcx := activate(as_mgcp_ack_all_mdcx(cpars));
4978
4979 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_BETTER_CELL;
4980 var BssmapCause cause := enum2int(cause_val);
4981
4982 var template BSSMAP_FIELD_CellIdentificationList cil;
4983 cil := { cIl_LAI := { ts_BSSMAP_CI_LAI('017'H, '017'H, 1) } };
4984
4985 /* old BSS sends Handover Required */
4986 BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
4987
4988 /* The target cell 017-017 LAC 1 is configured to be a remote MSC of name "msc-017-017-1".
4989 * This MSC tries to reach the other MSC via GSUP. */
4990
4991 var octetstring remote_msc_name := '6D73632D3031372D3031372D3100'O; /* "msc-017-017-1\0" as octetstring */
4992 var GSUP_PDU prep_ho_req;
4993 GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_REQUEST,
4994 pars.imsi, destination_name := remote_msc_name)) -> value prep_ho_req;
4995
4996 var GSUP_IeValue source_name_ie;
4997 f_gsup_find_ie(prep_ho_req, OSMO_GSUP_SOURCE_NAME_IE, source_name_ie);
4998 var octetstring local_msc_name := source_name_ie.source_name;
4999
5000 /* Remote MSC has figured out its BSC and signals success */
5001 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5002 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5003 var PDU_BSSAP ho_req_ack := valueof(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
5004 aoIPTransportLayer := omit,
5005 speechCodec := ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
5006 GSUP.send(ts_GSUP_E_PrepareHandoverResult(
5007 pars.imsi,
5008 ho_number,
5009 remote_msc_name, local_msc_name,
5010 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006, enc_PDU_BSSAP(ho_req_ack)))));
5011
5012 /* MSC forwards the RR Handover Command to old BSS */
5013 BSSAP.receive(tr_BSSMAP_HandoverCommand);
5014
5015 /* The MS shows up at remote new BSS */
5016
5017 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST,
5018 pars.imsi, remote_msc_name, local_msc_name,
5019 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
5020 enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverDetect))))));
5021 BSSAP.receive(tr_BSSMAP_HandoverSucceeded);
5022 f_sleep(0.1);
5023
5024 /* Save the MS sequence counters for use on the other connection */
5025 var N_Sd_Array last_n_sd := f_bssmap_last_n_sd();
5026
5027 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_SEND_END_SIGNAL_REQUEST,
5028 pars.imsi, remote_msc_name, local_msc_name,
5029 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
5030 enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverComplete))))));
5031
5032 /* The local BSS conn clears, all communication goes via remote MSC now */
5033 f_expect_clear();
5034
5035 /**********************************/
5036 /* Play through some signalling across the inter-MSC link.
5037 * This is a copy of f_tc_lu_and_mo_ussd_single_request() translated into GSUP AN-APDUs. */
5038
5039 if (false) {
5040 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
5041 invoke_id := 5, /* Phone may not start from 0 or 1 */
5042 op_code := SS_OP_CODE_PROCESS_USS_REQ,
5043 ussd_string := "*#100#"
5044 );
5045
5046 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
5047 invoke_id := 5, /* InvokeID shall be the same for both REQ and RSP */
5048 op_code := SS_OP_CODE_PROCESS_USS_REQ,
5049 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
5050 )
5051
5052 /* Compose a new SS/REGISTER message with request */
5053 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
5054 tid := 1, /* We just need a single transaction */
5055 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
5056 facility := valueof(facility_req)
5057 );
5058 var PDU_ML3_MS_NW ussd_req_v := valueof(ussd_req);
5059
5060 /* Compose SS/RELEASE_COMPLETE template with expected response */
5061 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
5062 tid := 1, /* Response should arrive within the same transaction */
5063 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
5064 facility := valueof(facility_rsp)
5065 );
5066
5067 /* Compose expected MSC -> HLR message */
5068 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
5069 imsi := g_pars.imsi,
5070 state := OSMO_GSUP_SESSION_STATE_BEGIN,
5071 ss := valueof(facility_req)
5072 );
5073
5074 /* To be used for sending response with correct session ID */
5075 var GSUP_PDU gsup_req_complete;
5076
5077 /* Request own number */
5078 /* From remote MSC instead of BSSAP directly */
5079 /* Patch the correct N_SD value into the message. */
5080 var octetstring l3_enc := enc_PDU_ML3_MS_NW(ussd_req_v);
5081 var RAN_Emulation.ConnectionData cd;
5082 f_ML3_patch_seq_nr_MS_NW(f_next_n_sd(last_n_sd, f_ML3_n_sd_idx(ussd_req_v)), l3_enc);
5083 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PROCESS_ACCESS_SIGNALLING_REQUEST,
5084 pars.imsi, remote_msc_name, local_msc_name,
5085 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
5086 enc_PDU_BSSAP(valueof(ts_BSSAP_DTAP(l3_enc)))
5087 ))
5088 ));
5089
5090 /* Expect GSUP message containing the SS payload */
5091 gsup_req_complete := f_expect_gsup_msg(gsup_req);
5092
5093 /* Compose the response from HLR using received session ID */
5094 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
5095 imsi := g_pars.imsi,
5096 sid := gsup_req_complete.ies[1].val.session_id,
5097 state := OSMO_GSUP_SESSION_STATE_END,
5098 ss := valueof(facility_rsp)
5099 );
5100
5101 /* Finally, HLR terminates the session */
5102 GSUP.send(gsup_rsp);
5103
5104 /* The USSD response goes out to remote MSC, on GSUP E instead of BSSAP */
5105 var GSUP_PDU gsup_ussd_rsp;
5106 GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST,
5107 pars.imsi, destination_name := remote_msc_name)) -> value gsup_ussd_rsp;
5108
5109 var GSUP_IeValue an_apdu;
5110 if (not f_gsup_find_ie(gsup_ussd_rsp, OSMO_GSUP_AN_APDU_IE, an_apdu)) {
5111 setverdict(fail, "No AN-APDU in received GSUP message. Expected USSD response in DTAP, got", gsup_ussd_rsp);
5112 mtc.stop;
5113 }
5114 var PDU_BSSAP bssap_dtap_mt := dec_PDU_BSSAP(an_apdu.an_apdu.pdu);
5115 var PDU_ML3_NW_MS dtap_mt := dec_PDU_ML3_NW_MS(bssap_dtap_mt.pdu.dtap);
5116 log("Expecting", ussd_rsp);
5117 log("Got", dtap_mt);
5118 if (not match(dtap_mt, ussd_rsp)) {
5119 setverdict(fail, "Unexpected GSUP message. Expected USSD response in DTAP, got", gsup_ussd_rsp);
5120 mtc.stop;
5121 }
5122 }
5123 /**********************************/
5124
5125
5126 /* inter-MSC handover back to the first MSC */
5127 f_create_bssmap_exp_handoverRequest(193);
5128 cil := { cIl_CGI := { ts_BSSMAP_CI_CGI('262'H, '42'H, 23, 42) } };
5129
5130 /* old BSS sends Handover Required, via inter-MSC E link: like
5131 * BSSAP.send(ts_BSSMAP_HandoverRequired(cause, cil));
5132 * but via GSUP */
5133 GSUP.send(ts_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_REQUEST,
5134 pars.imsi, remote_msc_name, local_msc_name,
5135 valueof(t_GSUP_AN_APDU(OSMO_GSUP_AN_PROTO_48006,
5136 enc_PDU_BSSAP(valueof(ts_BSSMAP_HandoverRequired(cause, cil)))
5137 ))
5138 ));
5139
5140 /* MSC asks local BSS to prepare Handover to it */
5141 BSSAP.receive(tr_BSSMAP_HandoverRequest);
5142
5143 /* Make sure the new BSSAP conn continues with the correct N_SD sequence numbers */
5144 f_bssmap_continue_after_n_sd(last_n_sd);
5145
5146 /* new BSS composes a RR Handover Command */
5147 rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5148 rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5149 var BSSMAP_IE_AoIP_TransportLayerAddress tla := valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
5150 BSSAP.send(ts_BSSMAP_HandoverRequestAcknowledge(rr_ho_cmd_enc, lengthof(rr_ho_cmd_enc),
5151 tla, ts_BSSMAP_IE_SpeechCodec({ts_CodecFR})));
5152
5153 /* HandoverCommand goes out via remote MSC-I */
5154 var GSUP_PDU prep_subsq_ho_res;
5155 GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_PREPARE_SUBSEQUENT_HANDOVER_RESULT,
5156 pars.imsi, destination_name := remote_msc_name)) -> value prep_subsq_ho_res;
5157
5158 /* MS shows up at the local BSS */
5159 BSSAP.send(ts_BSSMAP_HandoverDetect);
5160 f_sleep(0.1);
5161 BSSAP.send(ts_BSSMAP_HandoverComplete);
5162
5163 /* Handover Succeeded message */
5164 GSUP.receive(tr_GSUP_E_AN_APDU(OSMO_GSUP_MSGT_E_FORWARD_ACCESS_SIGNALLING_REQUEST,
5165 pars.imsi, destination_name := remote_msc_name));
5166
5167 /* MS has handovered to here, Clear Command goes out via remote MSC-I -- in form of a GSUP Close. */
5168 GSUP.receive(tr_GSUP_E_NO_PDU(OSMO_GSUP_MSGT_E_CLOSE,
5169 pars.imsi, destination_name := remote_msc_name));
5170
5171 /* Handover ends successfully. Call goes on for a little longer and then we hang up. */
5172
5173 f_sleep(1.0);
5174 deactivate(ack_mdcx);
5175
5176 /* FIXME: the inter-MSC call has put a number of MNCC messages in the queue, which above code should expect and
5177 * clear out. The f_call_hangup() expects an MNCC_REL_IND, so, for the time being, just clear the MNCC messages
5178 * before starting the call hangup. Instead of this, the individual messages should be tested for above. */
5179 MNCC.clear;
5180
5181 var default ccrel := activate(as_optional_cc_rel(cpars, true));
5182 f_call_hangup(cpars, true);
5183 f_sleep(1.0);
5184 deactivate(ccrel);
5185
5186 setverdict(pass);
5187}
5188testcase TC_ho_inter_msc_out() runs on MTC_CT {
5189 var BSC_ConnHdlr vc_conn;
5190 f_init(1);
5191
5192 var BSC_ConnHdlrPars pars := f_init_pars(54);
5193
5194 vc_conn := f_start_handler_with_pars(refers(f_tc_ho_inter_msc_out), pars, 0);
5195 vc_conn.done;
5196}
5197
5198
Harald Weltef6dd64d2017-11-19 12:09:51 +01005199control {
Philipp Maier328d1662018-03-07 10:40:27 +01005200 execute( TC_cr_before_reset() );
Harald Weltea49e36e2018-01-21 19:29:33 +01005201 execute( TC_lu_imsi_noauth_tmsi() );
Harald Welted2328a22018-01-27 14:27:16 +01005202 execute( TC_lu_imsi_noauth_notmsi() );
Harald Weltea49e36e2018-01-21 19:29:33 +01005203 execute( TC_lu_imsi_reject() );
5204 execute( TC_lu_imsi_timeout_gsup() );
Harald Welted2328a22018-01-27 14:27:16 +01005205 execute( TC_lu_imsi_auth_tmsi() );
Harald Welte8a397ae2019-04-21 22:03:37 +02005206 execute( TC_lu_imsi_auth3g_tmsi() );
Harald Welted2328a22018-01-27 14:27:16 +01005207 execute( TC_cmserv_imsi_unknown() );
Harald Welte2bb825f2018-01-22 11:31:18 +01005208 execute( TC_lu_and_mo_call() );
Harald Welte071ed732018-01-23 19:53:52 +01005209 execute( TC_lu_auth_sai_timeout() );
5210 execute( TC_lu_auth_sai_err() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01005211 execute( TC_lu_clear_request() );
5212 execute( TC_lu_disconnect() );
5213 execute( TC_lu_by_imei() );
5214 execute( TC_lu_by_tmsi_noauth_unknown() );
5215 execute( TC_imsi_detach_by_imsi() );
5216 execute( TC_imsi_detach_by_tmsi() );
5217 execute( TC_imsi_detach_by_imei() );
5218 execute( TC_emerg_call_imei_reject() );
5219 execute( TC_emerg_call_imsi() );
5220 execute( TC_cm_serv_req_vgcs_reject() );
5221 execute( TC_cm_serv_req_vbs_reject() );
5222 execute( TC_cm_serv_req_lcs_reject() );
Harald Welte0195ab12018-01-24 21:50:20 +01005223 execute( TC_cm_reest_req_reject() );
Harald Welte1af6ea82018-01-25 18:33:15 +01005224 execute( TC_lu_auth_2G_fail() );
5225 execute( TC_lu_imsi_auth_tmsi_encr_13_13() );
5226 execute( TC_cl3_no_payload() );
5227 execute( TC_cl3_rnd_payload() );
Harald Welte1852a842018-01-26 22:53:36 +01005228 execute( TC_establish_and_nothing() );
5229 execute( TC_mo_setup_and_nothing() );
5230 execute( TC_mo_crcx_ran_timeout() );
5231 execute( TC_mo_crcx_ran_reject() );
Harald Welted2328a22018-01-27 14:27:16 +01005232 execute( TC_mt_crcx_ran_reject() );
Daniel Willmann8b084372018-02-04 13:35:26 +01005233 execute( TC_mo_setup_and_dtmf_dup() );
Harald Welteaa54cf82018-01-30 08:15:32 +01005234 //execute( TC_mt_t310() );
Harald Welte167458a2018-01-27 15:58:16 +01005235 execute( TC_gsup_cancel() );
Harald Welte9de84792018-01-28 01:06:35 +01005236 execute( TC_lu_imsi_auth_tmsi_encr_1_13() );
5237 execute( TC_lu_imsi_auth_tmsi_encr_3_13() );
5238 execute( TC_lu_imsi_auth_tmsi_encr_3_1() );
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01005239 execute( TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() );
Harald Welte9de84792018-01-28 01:06:35 +01005240 execute( TC_lu_imsi_auth_tmsi_encr_13_2() );
5241 execute( TC_lu_imsi_auth_tmsi_encr_013_2() );
Philipp Maier94f3f1b2018-03-15 18:54:13 +01005242 execute( TC_mo_release_timeout() );
Philipp Maier2a98a732018-03-19 16:06:12 +01005243 execute( TC_lu_and_mt_call_no_dlcx_resp() );
Philipp Maier75932982018-03-27 14:52:35 +02005244 execute( TC_reset_two() );
Harald Welte33ec09b2018-02-10 15:34:46 +01005245
5246 execute( TC_lu_and_mt_call() );
5247
Harald Weltef45efeb2018-04-09 18:19:24 +02005248 execute( TC_lu_and_mo_sms() );
5249 execute( TC_lu_and_mt_sms() );
Philipp Maier3983e702018-11-22 19:01:33 +01005250 execute( TC_lu_and_mt_sms_paging_and_nothing() );
Harald Weltef640a012018-04-14 17:49:21 +02005251 execute( TC_smpp_mo_sms() );
5252 execute( TC_smpp_mt_sms() );
Harald Weltef45efeb2018-04-09 18:19:24 +02005253
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07005254 execute( TC_gsup_mo_sms() );
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07005255 execute( TC_gsup_mo_smma() );
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07005256 execute( TC_gsup_mt_sms_ack() );
5257 execute( TC_gsup_mt_sms_err() );
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07005258 execute( TC_gsup_mt_sms_rp_mr() );
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07005259 execute( TC_gsup_mo_mt_sms_rp_mr() );
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07005260
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07005261 execute( TC_lu_and_mo_ussd_single_request() );
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07005262 execute( TC_lu_and_mt_ussd_notification() );
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07005263 execute( TC_lu_and_mo_ussd_during_mt_call() );
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07005264 execute( TC_lu_and_mt_ussd_during_mt_call() );
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07005265 execute( TC_lu_and_mo_ussd_mo_release() );
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07005266 execute( TC_lu_and_ss_session_timeout() );
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07005267
Stefan Sperling89eb1f32018-12-17 15:06:20 +01005268 execute( TC_cipher_complete_with_invalid_cipher() );
Stefan Sperlinga2d59c62018-12-18 16:32:44 +01005269 execute( TC_cipher_complete_1_without_cipher() );
5270 execute( TC_cipher_complete_3_without_cipher() );
5271 execute( TC_cipher_complete_13_without_cipher() );
Harald Welteb2284bd2019-05-10 11:30:43 +02005272 execute( TC_lu_with_invalid_mcc_mnc() );
Stefan Sperling89eb1f32018-12-17 15:06:20 +01005273
Harald Welte4263c522018-12-06 11:56:27 +01005274 execute( TC_sgsap_reset() );
5275 execute( TC_sgsap_lu() );
5276 execute( TC_sgsap_lu_imsi_reject() );
5277 execute( TC_sgsap_lu_and_nothing() );
5278 execute( TC_sgsap_expl_imsi_det_eps() );
Philipp Maierfc19f172019-03-21 11:17:54 +01005279 execute( TC_sgsap_impl_imsi_det_eps() );
Harald Welte4263c522018-12-06 11:56:27 +01005280 execute( TC_sgsap_expl_imsi_det_noneps() );
Philipp Maier5d812702019-03-21 10:51:26 +01005281 execute( TC_sgsap_impl_imsi_det_noneps() );
Harald Welte4263c522018-12-06 11:56:27 +01005282 execute( TC_sgsap_paging_rej() );
5283 execute( TC_sgsap_paging_subscr_rej() );
5284 execute( TC_sgsap_paging_ue_unr() );
5285 execute( TC_sgsap_paging_and_nothing() );
5286 execute( TC_sgsap_paging_and_lu() );
5287 execute( TC_sgsap_mt_sms() );
5288 execute( TC_sgsap_mo_sms() );
5289 execute( TC_sgsap_mt_sms_and_nothing() );
5290 execute( TC_sgsap_mt_sms_and_reject() );
5291 execute( TC_sgsap_unexp_ud() );
5292 execute( TC_sgsap_unsol_ud() );
5293 execute( TC_bssap_lu_sgsap_lu_and_mt_call() );
5294 execute( TC_sgsap_lu_and_mt_call() );
Philipp Maier628c0052019-04-09 17:36:57 +02005295 execute( TC_sgsap_vlr_failure() );
Harald Welte4263c522018-12-06 11:56:27 +01005296
Neels Hofmeyr0ac63152019-05-07 01:20:17 +02005297 execute( TC_ho_inter_bsc_unknown_cell() );
5298 execute( TC_ho_inter_bsc() );
5299
5300 execute( TC_ho_inter_msc_out() );
5301
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01005302 /* Run this last: at the time of writing this test crashes the MSC */
5303 execute( TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() );
Philipp Maierdb7fb8d2019-02-11 10:50:13 +01005304 execute( TC_gsup_mt_multi_part_sms() );
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02005305 execute( TC_mo_cc_bssmap_clear() );
Harald Weltef6dd64d2017-11-19 12:09:51 +01005306}
5307
5308
5309}