blob: 8c221dc8734653c320cfdc17a435c0c3cba1ac0f [file] [log] [blame]
Harald Weltef6dd64d2017-11-19 12:09:51 +01001module MSC_Tests {
2
3import from General_Types all;
4import from Osmocom_Types all;
5
6import from M3UA_Types all;
7import from M3UA_Emulation all;
8
9import from MTP3asp_Types all;
10import from MTP3asp_PortType all;
11
12import from SCCPasp_Types all;
13import from SCCP_Types all;
14import from SCCP_Emulation all;
15
16import from SCTPasp_Types all;
17import from SCTPasp_PortType all;
18
Harald Weltea49e36e2018-01-21 19:29:33 +010019import from Osmocom_CTRL_Functions all;
20import from Osmocom_CTRL_Types all;
21import from Osmocom_CTRL_Adapter all;
22
Harald Welte3ca1c902018-01-24 18:51:27 +010023import from TELNETasp_PortType all;
24import from Osmocom_VTY_Functions all;
25
Harald Weltea49e36e2018-01-21 19:29:33 +010026import from MNCC_Emulation all;
Harald Welte2bb825f2018-01-22 11:31:18 +010027import from MNCC_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +010028
Harald Welte4aa970c2018-01-26 10:38:09 +010029import from MGCP_Emulation all;
30import from MGCP_Types all;
31import from MGCP_Templates all;
32import from SDP_Types all;
33
Harald Weltea49e36e2018-01-21 19:29:33 +010034import from GSUP_Emulation all;
35import from GSUP_Types all;
36import from IPA_Emulation all;
37
Harald Weltef6dd64d2017-11-19 12:09:51 +010038import from BSSAP_Types all;
Harald Welte6811d102019-04-14 22:23:14 +020039import from RAN_Adapter all;
Harald Weltea49e36e2018-01-21 19:29:33 +010040import from BSSAP_CodecPort all;
41import from BSSMAP_Templates all;
Harald Welte6811d102019-04-14 22:23:14 +020042import from RAN_Emulation all;
Harald Weltea49e36e2018-01-21 19:29:33 +010043import from BSC_ConnectionHandler all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010044
Harald Welte4263c522018-12-06 11:56:27 +010045import from SGsAP_Templates all;
46import from SGsAP_Types all;
47import from SGsAP_Emulation all;
48
Harald Weltea49e36e2018-01-21 19:29:33 +010049import from MobileL3_Types all;
50import from MobileL3_CommonIE_Types all;
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +070051import from MobileL3_SMS_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +010052import from L3_Templates all;
Harald Welte158a7ca2018-02-16 18:11:31 +010053import from L3_Common all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010054
Harald Weltef640a012018-04-14 17:49:21 +020055import from SMPP_Types all;
56import from SMPP_Templates all;
57import from SMPP_Emulation all;
58
Stefan Sperlingc307e682018-06-14 15:15:46 +020059import from SCCP_Templates all;
60
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +070061import from SS_Types all;
62import from SS_Templates all;
63import from USSD_Helpers all;
Harald Welte4263c522018-12-06 11:56:27 +010064import from DNS_Helpers all;
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +070065
Philipp Maier948747b2019-04-02 15:22:33 +020066import from TCCConversion_Functions all;
67
Philipp Maier75932982018-03-27 14:52:35 +020068const integer NUM_BSC := 2;
Harald Welte6811d102019-04-14 22:23:14 +020069type record of RAN_Configuration RAN_Configurations;
Harald Weltef6dd64d2017-11-19 12:09:51 +010070
Harald Welte4263c522018-12-06 11:56:27 +010071/* Needed for SGsAP SMS */
72import from MobileL3_SMS_Types all;
73
Harald Weltea4ca4462018-02-09 00:17:14 +010074type component MTC_CT extends CTRL_Adapter_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +010075 var boolean g_initialized := false;
Harald Weltea49e36e2018-01-21 19:29:33 +010076
Harald Welte6811d102019-04-14 22:23:14 +020077 var RAN_Adapter g_bssap[NUM_BSC];
Harald Weltea4ca4462018-02-09 00:17:14 +010078
Harald Weltea49e36e2018-01-21 19:29:33 +010079 /* no 'adapter_CT' for MNCC or GSUP */
80 var MNCC_Emulation_CT vc_MNCC;
Harald Welte4aa970c2018-01-26 10:38:09 +010081 var MGCP_Emulation_CT vc_MGCP;
Harald Weltea49e36e2018-01-21 19:29:33 +010082 var GSUP_Emulation_CT vc_GSUP;
83 var IPA_Emulation_CT vc_GSUP_IPA;
Harald Weltef640a012018-04-14 17:49:21 +020084 var SMPP_Emulation_CT vc_SMPP;
Harald Welte4263c522018-12-06 11:56:27 +010085 var SGsAP_Emulation_CT vc_SGsAP;
Harald Weltea49e36e2018-01-21 19:29:33 +010086
87 /* only to get events from IPA underneath GSUP */
88 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte3ca1c902018-01-24 18:51:27 +010089 /* VTY to MSC */
90 port TELNETasp_PT MSCVTY;
Philipp Maier328d1662018-03-07 10:40:27 +010091
92 /* A port to directly send BSSAP messages. This port is used for
93 * tests that require low level access to sen arbitrary BSSAP
94 * messages. Run f_init_bssap_direct() to connect and initialize */
95 port BSSAP_CODEC_PT BSSAP_DIRECT;
96
97 /* When BSSAP messages are directly sent, then the connection
98 * handler is not active, which means that also no guard timer is
99 * set up. The following timer will serve as a replacement */
100 timer Tguard_direct := 60.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100101}
102
103modulepar {
Harald Weltea49e36e2018-01-21 19:29:33 +0100104 /* remote parameters of IUT */
105 charstring mp_msc_ip := "127.0.0.1";
106 integer mp_msc_ctrl_port := 4255;
107 integer mp_msc_vty_port := 4254;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100108
Harald Weltea49e36e2018-01-21 19:29:33 +0100109 /* local parameters of emulated HLR */
Philipp Maier9b690e42018-12-21 11:50:03 +0100110 boolean mp_mm_info := false;
Harald Weltea49e36e2018-01-21 19:29:33 +0100111 charstring mp_hlr_ip := "127.0.0.1";
112 integer mp_hlr_port := 4222;
Harald Welte6126fb02018-01-27 20:08:24 +0100113 charstring mp_mgw_ip := "127.0.0.1";
114 integer mp_mgw_port := 2427;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100115
Harald Weltea49e36e2018-01-21 19:29:33 +0100116 charstring mp_msc_mncc := "/tmp/mncc";
Harald Weltea4ca4462018-02-09 00:17:14 +0100117
Harald Weltef640a012018-04-14 17:49:21 +0200118 integer mp_msc_smpp_port := 2775;
119 charstring mp_smpp_system_id := "msc_tester";
120 charstring mp_smpp_password := "osmocom1";
Harald Welte4263c522018-12-06 11:56:27 +0100121 charstring mp_mme_name := "mmec01.mmegi0001.mme.epc.mnc070.mcc901.3gppnetwork.org";
122 charstring mp_vlr_name := "vlr.example.net";
Harald Weltef640a012018-04-14 17:49:21 +0200123
Harald Welte6811d102019-04-14 22:23:14 +0200124 RAN_Configurations mp_bssap_cfg := {
Philipp Maier75932982018-03-27 14:52:35 +0200125 {
126 sccp_service_type := "mtp3_itu",
127 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
128 own_pc := 185,
129 own_ssn := 254,
130 peer_pc := 187,
131 peer_ssn := 254,
132 sio := '83'O,
133 rctx := 0
134 },
135 {
136 sccp_service_type := "mtp3_itu",
137 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
138 own_pc := 186,
139 own_ssn := 254,
140 peer_pc := 187,
141 peer_ssn := 254,
142 sio := '83'O,
143 rctx := 1
144 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100145 };
Harald Weltef6dd64d2017-11-19 12:09:51 +0100146}
147
Philipp Maier328d1662018-03-07 10:40:27 +0100148/* altstep for the global guard timer (only used when BSSAP_DIRECT
149 * is used for communication */
150private altstep as_Tguard_direct() runs on MTC_CT {
151 [] Tguard_direct.timeout {
152 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200153 mtc.stop;
Philipp Maier328d1662018-03-07 10:40:27 +0100154 }
155}
Harald Weltef6dd64d2017-11-19 12:09:51 +0100156
Neels Hofmeyrde76f052019-02-26 05:02:46 +0100157private altstep as_optional_cc_rel(CallParameters cpars) runs on BSC_ConnHdlr {
158 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id))) { repeat; };
159}
160
Harald Weltef640a012018-04-14 17:49:21 +0200161function f_init_smpp(charstring id) runs on MTC_CT {
162 id := id & "-SMPP";
163 var EsmePars pars := {
164 mode := MODE_TRANSCEIVER,
165 bind := {
166 system_id := mp_smpp_system_id,
167 password := mp_smpp_password,
168 system_type := "MSC_Tests",
169 interface_version := hex2int('34'H),
170 addr_ton := unknown,
171 addr_npi := unknown,
172 address_range := ""
173 },
174 esme_role := true
175 }
176
177 vc_SMPP := SMPP_Emulation_CT.create(id);
178 map(vc_SMPP:SMPP_PORT, system:SMPP_PORT);
179 vc_SMPP.start(SMPP_Emulation.main_client(pars, mp_msc_ip, mp_msc_smpp_port, "", -1));
180}
181
182
Harald Weltea49e36e2018-01-21 19:29:33 +0100183function f_init_mncc(charstring id) runs on MTC_CT {
184 id := id & "-MNCC";
185 var MnccOps ops := {
186 create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
187 unitdata_cb := refers(MNCC_Emulation.DummyUnitdataCallback)
188 }
189
190 vc_MNCC := MNCC_Emulation_CT.create(id);
191 map(vc_MNCC:MNCC, system:MNCC_CODEC_PT);
192 vc_MNCC.start(MNCC_Emulation.main(ops, id, mp_msc_mncc));
Harald Weltef6dd64d2017-11-19 12:09:51 +0100193}
194
Harald Welte4aa970c2018-01-26 10:38:09 +0100195function f_init_mgcp(charstring id) runs on MTC_CT {
196 id := id & "-MGCP";
197 var MGCPOps ops := {
198 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
199 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
200 }
201 var MGCP_conn_parameters pars := {
Harald Welte6126fb02018-01-27 20:08:24 +0100202 callagent_ip := mp_msc_ip,
Harald Welte4aa970c2018-01-26 10:38:09 +0100203 callagent_udp_port := -1,
Harald Welte6126fb02018-01-27 20:08:24 +0100204 mgw_ip := mp_mgw_ip,
205 mgw_udp_port := mp_mgw_port
Harald Welte4aa970c2018-01-26 10:38:09 +0100206 }
207
208 vc_MGCP := MGCP_Emulation_CT.create(id);
209 map(vc_MGCP:MGCP, system:MGCP_CODEC_PT);
210 vc_MGCP.start(MGCP_Emulation.main(ops, pars, id));
211}
212
Philipp Maierc09a1312019-04-09 16:05:26 +0200213function ForwardUnitdataCallback(PDU_SGsAP msg)
214runs on SGsAP_Emulation_CT return template PDU_SGsAP {
215 SGsAP_CLIENT.send(msg);
216 return omit;
217}
218
Harald Welte4263c522018-12-06 11:56:27 +0100219function f_init_sgsap(charstring id) runs on MTC_CT {
220 id := id & "-SGsAP";
221 var SGsAPOps ops := {
222 create_cb := refers(SGsAP_Emulation.ExpectedCreateCallback),
Philipp Maierc09a1312019-04-09 16:05:26 +0200223 unitdata_cb := refers(ForwardUnitdataCallback)
Harald Welte4263c522018-12-06 11:56:27 +0100224 }
225 var SGsAP_conn_parameters pars := {
226 remote_ip := mp_msc_ip,
227 remote_sctp_port := 29118,
228 local_ip := "",
229 local_sctp_port := -1
230 }
231
232 vc_SGsAP := SGsAP_Emulation_CT.create(id);
233 map(vc_SGsAP:SGsAP, system:SGsAP_CODEC_PT);
234 vc_SGsAP.start(SGsAP_Emulation.main(ops, pars, id));
235}
236
237
Harald Weltea49e36e2018-01-21 19:29:33 +0100238function f_init_gsup(charstring id) runs on MTC_CT {
239 id := id & "-GSUP";
240 var GsupOps ops := {
241 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
242 }
243
244 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
245 vc_GSUP := GSUP_Emulation_CT.create(id);
246
247 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
248 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
249 /* we use this hack to get events like ASP_IPA_EVENT_UP */
250 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
251
252 vc_GSUP.start(GSUP_Emulation.main(ops, id));
253 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
254
255 /* wait for incoming connection to GSUP port before proceeding */
256 timer T := 10.0;
257 T.start;
258 alt {
259 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
260 [] T.timeout {
Harald Welte458fd372018-03-21 11:26:23 +0100261 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200262 mtc.stop
Harald Weltea49e36e2018-01-21 19:29:33 +0100263 }
264 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100265}
266
Philipp Maierc09a1312019-04-09 16:05:26 +0200267function f_init(integer num_bsc := 1, boolean sgsap := false, boolean gsup := true) runs on MTC_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +0100268
269 if (g_initialized == true) {
270 return;
271 }
272 g_initialized := true;
273
Philipp Maier75932982018-03-27 14:52:35 +0200274 if (num_bsc > NUM_BSC) {
Daniel Willmannafce8662018-07-06 23:11:32 +0200275 testcase.stop("excess number of BSC instances requested");
Philipp Maier75932982018-03-27 14:52:35 +0200276 }
277
278 for (var integer i := 0; i < num_bsc; i := i + 1) {
279 if (isbound(mp_bssap_cfg[i])) {
Harald Welte6811d102019-04-14 22:23:14 +0200280 f_bssap_init(g_bssap[i], mp_bssap_cfg[i], "MSC_Test_" & int2str(i), BSC_RanOps);
Harald Welted5833a82018-05-27 16:52:56 +0200281 f_bssap_start(g_bssap[i]);
Philipp Maier75932982018-03-27 14:52:35 +0200282 } else {
Daniel Willmannafce8662018-07-06 23:11:32 +0200283 testcase.stop("missing BSSAP configuration");
Philipp Maier75932982018-03-27 14:52:35 +0200284 }
285 }
286
Harald Weltea49e36e2018-01-21 19:29:33 +0100287 f_ipa_ctrl_start(mp_msc_ip, mp_msc_ctrl_port);
288 f_init_mncc("MSC_Test");
Harald Welte4aa970c2018-01-26 10:38:09 +0100289 f_init_mgcp("MSC_Test");
Philipp Maierc09a1312019-04-09 16:05:26 +0200290
291 if (gsup == true) {
292 f_init_gsup("MSC_Test");
293 }
Harald Weltef640a012018-04-14 17:49:21 +0200294 f_init_smpp("MSC_Test");
Philipp Maier57865482019-01-07 18:33:13 +0100295
Philipp Maier8e07a4a2019-02-14 18:23:28 +0100296 if (sgsap == true) {
Philipp Maier57865482019-01-07 18:33:13 +0100297 f_init_sgsap("MSC_Test");
298 }
Harald Welte3ca1c902018-01-24 18:51:27 +0100299
300 map(self:MSCVTY, system:MSCVTY);
301 f_vty_set_prompts(MSCVTY);
302 f_vty_transceive(MSCVTY, "enable");
Harald Welteb14c77a2018-01-25 17:25:44 +0100303
304 /* set some defaults */
305 f_vty_config(MSCVTY, "network", "authentication optional");
306 f_vty_config(MSCVTY, "msc", "assign-tmsi");
307 f_vty_config(MSCVTY, "network", "encryption a5 0");
Harald Weltef6dd64d2017-11-19 12:09:51 +0100308}
309
Philipp Maier328d1662018-03-07 10:40:27 +0100310/* Initialize for a direct connection to BSSAP. This function is an alternative
311 * to f_init() when the high level functions of the BSC_ConnectionHandler are
312 * not needed. */
313function f_init_bssap_direct() runs on MTC_CT {
Philipp Maier75932982018-03-27 14:52:35 +0200314 f_bssap_init(g_bssap[0], mp_bssap_cfg[0], "MSC_Test", omit);
315 connect(g_bssap[0].vc_SCCP:SCCP_SP_PORT, self:BSSAP_DIRECT);
Philipp Maier328d1662018-03-07 10:40:27 +0100316
317 /* Start guard timer and activate it as default */
318 Tguard_direct.start
319 activate(as_Tguard_direct());
320}
321
Harald Weltef6dd64d2017-11-19 12:09:51 +0100322template PDU_BSSAP ts_BSSAP_BSSMAP := {
323 discriminator := '0'B,
324 spare := '0000000'B,
325 dlci := omit,
326 lengthIndicator := 0, /* overwritten by codec */
327 pdu := ?
328}
329
330template PDU_BSSAP tr_BSSAP_BSSMAP := {
331 discriminator := '0'B,
332 spare := '0000000'B,
333 dlci := omit,
334 lengthIndicator := ?,
335 pdu := {
336 bssmap := ?
337 }
338}
339
340
341type integer BssmapCause;
342
343template (value) BSSMAP_IE_Cause ts_BSSMAP_IE_Cause(BssmapCause val) := {
344 elementIdentifier := '04'O,
345 lengthIndicator := 0,
346 causeValue := int2bit(val, 7),
347 extensionCauseValue := '0'B,
348 spare1 := omit
349}
350
351template (value) PDU_BSSAP ts_BSSMAP_Reset(BssmapCause cause) modifies ts_BSSAP_BSSMAP := {
352 pdu := {
353 bssmap := {
354 reset := {
355 messageType := '30'O,
356 cause := ts_BSSMAP_IE_Cause(cause),
357 a_InterfaceSelectorForReset := omit
358 }
359 }
360 }
361}
362
363template (value) PDU_BSSAP ts_BSSMAP_ResetAck modifies ts_BSSAP_BSSMAP := {
364 pdu := {
365 bssmap := {
366 resetAck := {
367 messageType := '31'O,
368 a_InterfaceSelectorForReset := omit
369 }
370 }
371 }
372}
373
374template PDU_BSSAP tr_BSSMAP_ResetAck modifies tr_BSSAP_BSSMAP := {
375 pdu := {
376 bssmap := {
377 resetAck := {
378 messageType := '31'O,
379 a_InterfaceSelectorForReset := *
380 }
381 }
382 }
383}
384
385template BSSMAP_IE_CellIdentifier ts_BSSMAP_IE_CellID := {
386 elementIdentifier := '05'O,
387 lengthIndicator := 0,
388 cellIdentifierDiscriminator := '0000'B,
389 spare1_4 := '0000'B,
390 cellIdentification := ?
391}
392
393type uint16_t BssmapLAC;
394type uint16_t BssmapCI;
395
396/*
397template BSSMAP_IE_CellIdentifier ts_CellId_CGI(mcc, mnc, lac, ci)
398modifies ts_BSSMAP_IE_CellID := {
399 cellIdentification := {
400 cI_LAC_CGI := {
401 mnc_mcc := FIXME,
402 lac := int2oct(lac, 2),
403 ci := int2oct(ci, 2)
404 }
405 }
406}
407*/
408
409template BSSMAP_IE_CellIdentifier ts_CellID_LAC_CI(BssmapLAC lac, BssmapCI ci)
410modifies ts_BSSMAP_IE_CellID := {
411 cellIdentification := {
412 cI_LAC_CI := {
413 lac := int2oct(lac, 2),
414 ci := int2oct(ci, 2)
415 }
416 }
417}
418
419template BSSMAP_IE_CellIdentifier ts_CellId_CI(BssmapCI ci)
420modifies ts_BSSMAP_IE_CellID := {
421 cellIdentification := {
422 cI_CI := int2oct(ci, 2)
423 }
424}
425
426template BSSMAP_IE_CellIdentifier ts_CellId_none
427modifies ts_BSSMAP_IE_CellID := {
428 cellIdentification := {
429 cI_noCell := ''O
430 }
431}
432
433
434template BSSMAP_IE_Layer3Information ts_BSSMAP_IE_L3Info(octetstring l3info) := {
435 elementIdentifier := '17'O,
436 lengthIndicator := 0,
437 layer3info := l3info
438}
439
440template PDU_BSSAP ts_BSSMAP_ComplL3(BSSMAP_IE_CellIdentifier cell_id, octetstring l3_info)
441modifies ts_BSSAP_BSSMAP := {
442 pdu := {
443 bssmap := {
444 completeLayer3Information := {
445 messageType := '57'O,
446 cellIdentifier := cell_id,
447 layer3Information := ts_BSSMAP_IE_L3Info(l3_info),
448 chosenChannel := omit,
449 lSAIdentifier := omit,
450 aPDU := omit,
451 codecList := omit,
452 redirectAttemptFlag := omit,
453 sendSequenceNumber := omit,
454 iMSI := omit
455 }
456 }
457 }
458}
459
460template PDU_BSSAP ts_BSSMAP_HandoReq(BssmapCause cause, BSSMAP_IE_CellIdentifierList cid_list)
461modifies ts_BSSAP_BSSMAP := {
462 pdu := {
463 bssmap := {
464 handoverRequired := {
465 messageType := '11'O,
466 cause := ts_BSSMAP_IE_Cause(cause),
467 responseRequest := omit,
468 cellIdentifierList := cid_list,
469 circuitPoolList := omit,
470 currentChannelType1 := omit,
471 speechVersion := omit,
472 queueingIndicator := omit,
473 oldToNewBSSInfo := omit,
474 sourceToTargetRNCTransparentInfo := omit,
475 sourceToTargetRNCTransparentInfoCDMA := omit,
476 gERANClassmark := omit,
477 talkerPriority := omit,
478 speechCodec := omit,
479 cSG_Identifier := omit
480 }
481 }
482 }
483}
484
Harald Weltea49e36e2018-01-21 19:29:33 +0100485type function void_fn(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100486
Harald Weltea49e36e2018-01-21 19:29:33 +0100487/* FIXME: move into BSC_ConnectionHandler? */
Harald Weltef9abf8d2019-04-21 13:07:17 +0200488function f_init_pars(integer imsi_suffix, boolean sgsap := false, boolean gsup := true, integer ran_idx := 0)
489runs on MTC_CT return BSC_ConnHdlrPars {
Harald Weltede371492018-01-27 23:44:41 +0100490 var BSC_ConnHdlrNetworkPars net_pars := {
491 kc_support := '0A'O, /* A5/1 and A5/3 enabled */
492 expect_tmsi := true,
493 expect_auth := false,
494 expect_ciph := false
495 };
Harald Weltea49e36e2018-01-21 19:29:33 +0100496 var BSC_ConnHdlrPars pars := {
Harald Weltef9abf8d2019-04-21 13:07:17 +0200497 sccp_addr_own := g_bssap[ran_idx].sccp_addr_own,
498 sccp_addr_peer := g_bssap[ran_idx].sccp_addr_peer,
Harald Welteedbab812018-03-18 16:02:25 +0100499 cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42)),
Harald Welte81b7f9d2018-01-24 19:06:24 +0100500 imei := f_gen_imei(imsi_suffix),
501 imsi := f_gen_imsi(imsi_suffix),
502 msisdn := f_gen_msisdn(imsi_suffix),
Harald Welte256571e2018-01-24 18:47:19 +0100503 tmsi := omit,
Harald Welte9de84792018-01-28 01:06:35 +0100504 cm1 := valueof(ts_CM1),
Harald Welte82600572018-01-21 20:54:08 +0100505 cm2 := valueof(ts_CM2_default),
Harald Welte16114282018-01-24 22:41:21 +0100506 cm3 := omit,
Harald Weltede371492018-01-27 23:44:41 +0100507 vec := omit,
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100508 net := net_pars,
Philipp Maieraeb29a82018-11-08 17:40:53 +0100509 send_early_cm := true,
510 ipa_ctrl_ip := mp_msc_ip,
511 ipa_ctrl_port := mp_msc_ctrl_port,
Philipp Maier9b690e42018-12-21 11:50:03 +0100512 ipa_ctrl_enable := true,
Philipp Maier57865482019-01-07 18:33:13 +0100513 mm_info := mp_mm_info,
Philipp Maierc09a1312019-04-09 16:05:26 +0200514 sgsap_enable := sgsap,
Harald Weltef9abf8d2019-04-21 13:07:17 +0200515 gsup_enable := gsup,
516 ran_idx := ran_idx
Harald Weltea49e36e2018-01-21 19:29:33 +0100517 };
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100518 return pars;
519}
520
521function f_start_handler_with_pars(void_fn fn, BSC_ConnHdlrPars pars) runs on MTC_CT return BSC_ConnHdlr {
522 var BSC_ConnHdlr vc_conn;
523 var charstring id := testcasename();
Harald Weltea49e36e2018-01-21 19:29:33 +0100524
525 vc_conn := BSC_ConnHdlr.create(id);
526 /* BSSMAP part / A interface */
Harald Weltef9abf8d2019-04-21 13:07:17 +0200527 connect(vc_conn:BSSAP, g_bssap[pars.ran_idx].vc_RAN:CLIENT);
528 connect(vc_conn:BSSAP_PROC, g_bssap[pars.ran_idx].vc_RAN:PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100529 /* MNCC part */
530 connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
531 connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);
Harald Welte4aa970c2018-01-26 10:38:09 +0100532 /* MGCP part */
533 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
534 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100535 /* GSUP part */
Philipp Maierc09a1312019-04-09 16:05:26 +0200536 if (pars.gsup_enable == true) {
537 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
538 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
539 }
Harald Weltef640a012018-04-14 17:49:21 +0200540 /* SMPP part */
541 connect(vc_conn:SMPP, vc_SMPP:SMPP_CLIENT);
542 connect(vc_conn:SMPP_PROC, vc_SMPP:SMPP_PROC);
Harald Welte4263c522018-12-06 11:56:27 +0100543 /* SGs part */
Philipp Maier8e07a4a2019-02-14 18:23:28 +0100544 if (pars.sgsap_enable == true) {
Philipp Maier57865482019-01-07 18:33:13 +0100545 connect(vc_conn:SGsAP, vc_SGsAP:SGsAP_CLIENT);
546 connect(vc_conn:SGsAP_PROC, vc_SGsAP:SGsAP_PROC);
547 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100548
Harald Weltea10db902018-01-27 12:44:49 +0100549 /* We cannot use vc_conn.start(f_init_handler(fn, id, pars)); as we cannot have
550 * a stand-alone 'derefers()' call, see https://www.eclipse.org/forums/index.php/t/1091364/ */
Harald Weltea49e36e2018-01-21 19:29:33 +0100551 vc_conn.start(derefers(fn)(id, pars));
552 return vc_conn;
553}
554
Harald Weltef9abf8d2019-04-21 13:07:17 +0200555function f_start_handler(void_fn fn, integer imsi_suffix, integer ran_idx := 0) runs on MTC_CT return BSC_ConnHdlr {
556 return f_start_handler_with_pars(fn, f_init_pars(imsi_suffix, ran_idx := ran_idx));
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100557}
558
Harald Weltea49e36e2018-01-21 19:29:33 +0100559private function f_tc_lu_imsi_noauth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100560 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100561 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100562}
Harald Weltea49e36e2018-01-21 19:29:33 +0100563testcase TC_lu_imsi_noauth_tmsi() runs on MTC_CT {
564 var BSC_ConnHdlr vc_conn;
565 f_init();
566
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100567 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi), 1);
Harald Weltea49e36e2018-01-21 19:29:33 +0100568 vc_conn.done;
569}
570
571private function f_tc_lu_imsi_noauth_notmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100572 pars.net.expect_tmsi := false;
Harald Weltea10db902018-01-27 12:44:49 +0100573 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100574 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100575}
Harald Weltea49e36e2018-01-21 19:29:33 +0100576testcase TC_lu_imsi_noauth_notmsi() runs on MTC_CT {
577 var BSC_ConnHdlr vc_conn;
578 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100579 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
Harald Weltea49e36e2018-01-21 19:29:33 +0100580
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100581 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi), 2);
Harald Weltea49e36e2018-01-21 19:29:33 +0100582 vc_conn.done;
583}
584
585/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
586private function f_tc_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100587 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100588 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
589
590 f_create_gsup_expect(hex2str(g_pars.imsi));
591 f_bssap_compl_l3(l3_lu);
592 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
593 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
594 alt {
Harald Welte5946b332018-03-18 23:32:21 +0100595 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej(int2oct(23,1)))) {
596 f_expect_clear();
597 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100598 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
599 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
Daniel Willmannafce8662018-07-06 23:11:32 +0200600 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100601 }
602 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100603}
604testcase TC_lu_imsi_reject() runs on MTC_CT {
605 var BSC_ConnHdlr vc_conn;
606 f_init();
607
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100608 vc_conn := f_start_handler(refers(f_tc_lu_imsi_reject), 3);
Harald Weltea49e36e2018-01-21 19:29:33 +0100609 vc_conn.done;
610}
611
612/* Do LU by IMSI, timeout on GSUP */
613private function f_tc_lu_imsi_timeout_gsup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100614 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100615 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
616
617 f_create_gsup_expect(hex2str(g_pars.imsi));
618 f_bssap_compl_l3(l3_lu);
619 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
620 /* Normally the HLR would need to respond here, but we decide to force a timeout here */
621 alt {
622 /* FIXME: Expect specific reject cause */
Harald Welte5946b332018-03-18 23:32:21 +0100623 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
624 f_expect_clear();
625 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100626 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
627 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
Daniel Willmannafce8662018-07-06 23:11:32 +0200628 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100629 }
630 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100631}
632testcase TC_lu_imsi_timeout_gsup() runs on MTC_CT {
633 var BSC_ConnHdlr vc_conn;
634 f_init();
635
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100636 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_gsup), 4);
Harald Weltea49e36e2018-01-21 19:29:33 +0100637 vc_conn.done;
638}
639
Harald Welte7b1b2812018-01-22 21:23:06 +0100640private function f_tc_lu_imsi_auth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100641 pars.net.expect_auth := true;
Harald Weltea10db902018-01-27 12:44:49 +0100642 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100643 f_perform_lu();
Harald Welte7b1b2812018-01-22 21:23:06 +0100644}
645testcase TC_lu_imsi_auth_tmsi() runs on MTC_CT {
646 var BSC_ConnHdlr vc_conn;
647 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100648 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte7b1b2812018-01-22 21:23:06 +0100649
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100650 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi), 5);
Harald Welte7b1b2812018-01-22 21:23:06 +0100651 vc_conn.done;
652}
653
Harald Weltea49e36e2018-01-21 19:29:33 +0100654
655/* Send CM SERVICE REQ for IMSI that has never performed LU before */
656private function f_tc_cmserv_imsi_unknown(charstring id, BSC_ConnHdlrPars pars)
657runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100658 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100659
660 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welteedbab812018-03-18 16:02:25 +0100661 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100662 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltea49e36e2018-01-21 19:29:33 +0100663
664 f_create_gsup_expect(hex2str(g_pars.imsi));
665
666 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
667 f_bssap_compl_l3(l3_info);
668
669 timer T := 10.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100670 T.start;
671 alt {
Harald Weltea49e36e2018-01-21 19:29:33 +0100672 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
673 //[] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC)) { }
Daniel Willmannafce8662018-07-06 23:11:32 +0200674 [] BSSAP.receive {
675 setverdict(fail, "Received unexpected BSSAP");
676 mtc.stop;
677 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100678 [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
679 setverdict(fail, "Unexpected GSUP UL REQ");
Daniel Willmannafce8662018-07-06 23:11:32 +0200680 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100681 }
Daniel Willmannafce8662018-07-06 23:11:32 +0200682 [] T.timeout {
683 setverdict(fail, "Timeout waiting for CM SERV REQ");
684 mtc.stop;
685 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100686 }
687
Harald Welte1ddc7162018-01-27 14:25:46 +0100688 f_expect_clear();
Harald Weltef6dd64d2017-11-19 12:09:51 +0100689}
Harald Weltea49e36e2018-01-21 19:29:33 +0100690testcase TC_cmserv_imsi_unknown() runs on MTC_CT {
691 var BSC_ConnHdlr vc_conn;
692 f_init();
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100693 vc_conn := f_start_handler(refers(f_tc_cmserv_imsi_unknown), 6);
Harald Weltea49e36e2018-01-21 19:29:33 +0100694 vc_conn.done;
695}
696
Harald Welte2bb825f2018-01-22 11:31:18 +0100697private function f_tc_lu_and_mo_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100698 f_init_handler(pars);
Harald Welteb71901a2018-01-26 19:16:05 +0100699 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
700 cpars.bss_rtp_port := 1110;
701 cpars.mgcp_connection_id_bss := '22222'H;
702 cpars.mgcp_connection_id_mss := '33333'H;
Philipp Maierf1e02bb2018-03-15 16:30:00 +0100703 cpars.mgcp_ep := "rtpbridge/1@mgw";
Harald Welte2bb825f2018-01-22 11:31:18 +0100704
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100705 f_perform_lu();
Harald Welteb71901a2018-01-26 19:16:05 +0100706 f_mo_call(cpars);
Harald Welte2bb825f2018-01-22 11:31:18 +0100707}
708testcase TC_lu_and_mo_call() runs on MTC_CT {
709 var BSC_ConnHdlr vc_conn;
710 f_init();
711
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100712 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_call), 7);
Harald Welte071ed732018-01-23 19:53:52 +0100713 vc_conn.done;
714}
715
716/* Test LU (with authentication enabled), where HLR times out sending SAI response */
717private function f_tc_lu_auth_sai_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100718 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100719
720 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
721 var PDU_DTAP_MT dtap_mt;
722
723 /* tell GSUP dispatcher to send this IMSI to us */
724 f_create_gsup_expect(hex2str(g_pars.imsi));
725
726 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
727 f_bssap_compl_l3(l3_lu);
728
729 /* Send Early Classmark, just for the fun of it */
730 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
731
732 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
733 /* The HLR would normally return an auth vector here, but we fail to do so. */
734
735 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100736 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100737}
738testcase TC_lu_auth_sai_timeout() runs on MTC_CT {
739 var BSC_ConnHdlr vc_conn;
740 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100741 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100742
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100743 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_timeout), 8);
Harald Welte071ed732018-01-23 19:53:52 +0100744 vc_conn.done;
745}
746
747/* Test LU (with authentication enabled), where HLR rejects sending SAI error */
748private function f_tc_lu_auth_sai_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100749 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100750
751 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
752 var PDU_DTAP_MT dtap_mt;
753
754 /* tell GSUP dispatcher to send this IMSI to us */
755 f_create_gsup_expect(hex2str(g_pars.imsi));
756
757 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
758 f_bssap_compl_l3(l3_lu);
759
760 /* Send Early Classmark, just for the fun of it */
761 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
762
763 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
764 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 13));
765
766 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100767 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100768}
769testcase TC_lu_auth_sai_err() runs on MTC_CT {
770 var BSC_ConnHdlr vc_conn;
771 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100772 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100773
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100774 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_err), 9);
Harald Welte2bb825f2018-01-22 11:31:18 +0100775 vc_conn.done;
776}
Harald Weltea49e36e2018-01-21 19:29:33 +0100777
Harald Weltebc881782018-01-23 20:09:15 +0100778/* Test LU but BSC will send a clear request in the middle */
779private function f_tc_lu_clear_request(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100780 f_init_handler(pars);
Harald Weltebc881782018-01-23 20:09:15 +0100781
782 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
783 var PDU_DTAP_MT dtap_mt;
784
785 /* tell GSUP dispatcher to send this IMSI to us */
786 f_create_gsup_expect(hex2str(g_pars.imsi));
787
788 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
789 f_bssap_compl_l3(l3_lu);
790
791 /* Send Early Classmark, just for the fun of it */
792 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
793
794 f_sleep(1.0);
795 /* send clear request in the middle of the LU */
796 BSSAP.send(ts_BSSMAP_ClearRequest(0));
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200797 alt {
798 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { repeat; }
799 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {}
800 }
Harald Weltebc881782018-01-23 20:09:15 +0100801 BSSAP.send(ts_BSSMAP_ClearComplete);
Harald Welte89a32492018-01-27 19:07:28 +0100802 alt {
803 /* See https://osmocom.org/issues/2862 */
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200804 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
805 setverdict(fail, "Got a second Clear Command, only one expected");
Daniel Willmannafce8662018-07-06 23:11:32 +0200806 mtc.stop;
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200807 repeat;
808 }
Harald Welte6811d102019-04-14 22:23:14 +0200809 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte89a32492018-01-27 19:07:28 +0100810 }
Harald Weltebc881782018-01-23 20:09:15 +0100811 setverdict(pass);
812}
813testcase TC_lu_clear_request() runs on MTC_CT {
814 var BSC_ConnHdlr vc_conn;
815 f_init();
816
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100817 vc_conn := f_start_handler(refers(f_tc_lu_clear_request), 10);
Harald Weltebc881782018-01-23 20:09:15 +0100818 vc_conn.done;
819}
820
Harald Welte66af9e62018-01-24 17:28:21 +0100821/* Test LU but BSC will send a clear request in the middle */
822private function f_tc_lu_disconnect(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100823 f_init_handler(pars);
Harald Welte66af9e62018-01-24 17:28:21 +0100824
825 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
826 var PDU_DTAP_MT dtap_mt;
827
828 /* tell GSUP dispatcher to send this IMSI to us */
829 f_create_gsup_expect(hex2str(g_pars.imsi));
830
831 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
832 f_bssap_compl_l3(l3_lu);
833
834 /* Send Early Classmark, just for the fun of it */
835 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
836
837 f_sleep(1.0);
838 /* send clear request in the middle of the LU */
Harald Welte6811d102019-04-14 22:23:14 +0200839 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Harald Welte66af9e62018-01-24 17:28:21 +0100840 setverdict(pass);
Neels Hofmeyrbb825c92019-03-06 15:35:50 +0100841 f_sleep(1.0);
Harald Welte66af9e62018-01-24 17:28:21 +0100842}
843testcase TC_lu_disconnect() runs on MTC_CT {
844 var BSC_ConnHdlr vc_conn;
845 f_init();
846
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100847 vc_conn := f_start_handler(refers(f_tc_lu_disconnect), 11);
Harald Welte66af9e62018-01-24 17:28:21 +0100848 vc_conn.done;
849}
850
851
Harald Welteba7b6d92018-01-23 21:32:34 +0100852/* Test LU but with illegal mobile identity type = IMEI */
853private function f_tc_lu_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100854 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100855
Harald Welte256571e2018-01-24 18:47:19 +0100856 var PDU_ML3_MS_NW l3_lu := f_build_lu_imei(g_pars.imei)
Harald Welteba7b6d92018-01-23 21:32:34 +0100857 var PDU_DTAP_MT dtap_mt;
858
859 /* tell GSUP dispatcher to send this IMSI to us */
860 f_create_gsup_expect(hex2str(g_pars.imsi));
861
862 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
863 f_bssap_compl_l3(l3_lu);
864
865 /* Send Early Classmark, just for the fun of it */
866 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
867 /* wait for LU reject, ignore any ID REQ */
868 alt {
869 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
870 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req)) { repeat; }
871 }
872 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100873 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100874}
875testcase TC_lu_by_imei() runs on MTC_CT {
876 var BSC_ConnHdlr vc_conn;
877 f_init();
878
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100879 vc_conn := f_start_handler(refers(f_tc_lu_by_imei), 12);
Harald Welteba7b6d92018-01-23 21:32:34 +0100880 vc_conn.done;
881}
882
883/* Test LU by TMSI with unknown TMSI, expect (and answer) ID REQ. */
884private function f_tc_lu_tmsi_noauth_unknown(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Stefan Sperling04fc4bc2018-06-25 17:44:57 +0200885 /* We piggyback a test for an MSC crash on overlong IMSI (OS#2864) onto this test. */
886 var hexstring overlong_imsi := '012345789ABCDEF0123456789ABCDEF'H;
Harald Weltea10db902018-01-27 12:44:49 +0100887 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100888
889 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('01020304'O); /* FIXME: Random */
890 var PDU_DTAP_MT dtap_mt;
891
892 /* tell GSUP dispatcher to send this IMSI to us */
893 f_create_gsup_expect(hex2str(g_pars.imsi));
894
895 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
896 f_bssap_compl_l3(l3_lu);
897
898 /* Send Early Classmark, just for the fun of it */
899 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
900
901 /* Wait for + respond to ID REQ (IMSI) */
902 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req('001'B)));
Stefan Sperling04fc4bc2018-06-25 17:44:57 +0200903 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 +0100904 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
905
906 /* Expect MSC to do UpdateLocation to HLR; respond to it */
907 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
908 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
909 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
910 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
911
912 alt {
Harald Welte7ec4fa82018-01-27 10:57:40 +0100913 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
914 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
915 }
Harald Welteba7b6d92018-01-23 21:32:34 +0100916 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
917 setverdict(fail, "Expected LU ACK, but received REJ");
Daniel Willmannafce8662018-07-06 23:11:32 +0200918 mtc.stop;
Harald Welteba7b6d92018-01-23 21:32:34 +0100919 }
920 }
921
Philipp Maier9b690e42018-12-21 11:50:03 +0100922 /* Wait for MM-Information (if enabled) */
923 f_expect_mm_info();
924
Harald Welteba7b6d92018-01-23 21:32:34 +0100925 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100926 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100927}
928testcase TC_lu_by_tmsi_noauth_unknown() runs on MTC_CT {
929 var BSC_ConnHdlr vc_conn;
930 f_init();
931
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100932 vc_conn := f_start_handler(refers(f_tc_lu_tmsi_noauth_unknown), 13);
Harald Welteba7b6d92018-01-23 21:32:34 +0100933 vc_conn.done;
934}
935
936
Harald Welte45164da2018-01-24 12:51:27 +0100937/* Test IMSI DETACH (MI=IMSI) */
938private function f_tc_imsi_detach_by_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100939 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100940
941 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
942
943 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
944 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
945
946 /* Send Early Classmark, just for the fun of it? */
947 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
948
949 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100950 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100951}
952testcase TC_imsi_detach_by_imsi() runs on MTC_CT {
953 var BSC_ConnHdlr vc_conn;
954 f_init();
955
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100956 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imsi), 14);
Harald Welte45164da2018-01-24 12:51:27 +0100957 vc_conn.done;
958}
959
960/* Test IMSI DETACH (MI=TMSI) */
961private function f_tc_imsi_detach_by_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100962 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100963
964 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('01020304'O));
965
966 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
967 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
968
969 /* Send Early Classmark, just for the fun of it? */
970 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
971
972 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100973 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100974}
975testcase TC_imsi_detach_by_tmsi() runs on MTC_CT {
976 var BSC_ConnHdlr vc_conn;
977 f_init();
978
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100979 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_tmsi), 15);
Harald Welte45164da2018-01-24 12:51:27 +0100980 vc_conn.done;
981}
982
983/* Test IMSI DETACH (MI=IMEI), which is illegal */
984private function f_tc_imsi_detach_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100985 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100986
Harald Welte256571e2018-01-24 18:47:19 +0100987 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte45164da2018-01-24 12:51:27 +0100988
989 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
990 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
991
992 /* Send Early Classmark, just for the fun of it? */
993 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
994
995 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100996 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100997}
998testcase TC_imsi_detach_by_imei() runs on MTC_CT {
999 var BSC_ConnHdlr vc_conn;
1000 f_init();
1001
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001002 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imei), 16);
Harald Welte45164da2018-01-24 12:51:27 +01001003 vc_conn.done;
1004}
1005
1006
1007/* helper function for an emergency call. caller passes in mobile identity to use */
1008private function f_emerg_call(MobileIdentityLV mi) runs on BSC_ConnHdlr {
Harald Welte0bef21e2018-02-10 09:48:23 +01001009 var CallParameters cpars := valueof(t_CallParams('112'H, 0));
1010 cpars.emergency := true;
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001011 cpars.mgcp_ep := "rtpbridge/1@mgw";
Harald Welte45164da2018-01-24 12:51:27 +01001012
Harald Welte0bef21e2018-02-10 09:48:23 +01001013 f_mo_call(cpars);
Harald Welte45164da2018-01-24 12:51:27 +01001014}
1015
1016/* establish an emergency call by IMEI, no SIM inserted (and hence no IMSI) */
1017private function f_tc_emerg_call_imei_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001018 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001019
Harald Welte256571e2018-01-24 18:47:19 +01001020 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001021 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Welte45164da2018-01-24 12:51:27 +01001022 f_bssap_compl_l3(l3_info);
1023 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ('05'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +01001024 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001025}
1026testcase TC_emerg_call_imei_reject() runs on MTC_CT {
1027 var BSC_ConnHdlr vc_conn;
1028 f_init();
1029
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001030 vc_conn := f_start_handler(refers(f_tc_emerg_call_imei_reject), 17);
Harald Welte45164da2018-01-24 12:51:27 +01001031 vc_conn.done;
1032}
1033
Harald Welted5b91402018-01-24 18:48:16 +01001034/* establish an emergency call by IMSI, SIM inserted (and hence IMSI) */
Harald Welte45164da2018-01-24 12:51:27 +01001035private function f_tc_emerg_call_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001036 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001037 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001038 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001039 /* Then issue emergency call identified by IMSI */
1040 f_emerg_call(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
1041}
1042testcase TC_emerg_call_imsi() runs on MTC_CT {
1043 var BSC_ConnHdlr vc_conn;
1044 f_init();
1045
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001046 vc_conn := f_start_handler(refers(f_tc_emerg_call_imsi), 18);
Harald Welte45164da2018-01-24 12:51:27 +01001047 vc_conn.done;
1048}
1049
1050/* CM Service Request for VGCS -> reject */
1051private function f_tc_cm_serv_req_vgcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001052 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001053
1054 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001055 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001056
1057 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001058 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VGCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +01001059 f_bssap_compl_l3(l3_info);
1060 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001061 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001062}
1063testcase TC_cm_serv_req_vgcs_reject() runs on MTC_CT {
1064 var BSC_ConnHdlr vc_conn;
1065 f_init();
1066
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001067 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vgcs_reject), 19);
Harald Welte45164da2018-01-24 12:51:27 +01001068 vc_conn.done;
1069}
1070
1071/* CM Service Request for VBS -> reject */
1072private function f_tc_cm_serv_req_vbs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001073 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001074
1075 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001076 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001077
1078 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001079 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VBS, mi));
Harald Welte45164da2018-01-24 12:51:27 +01001080 f_bssap_compl_l3(l3_info);
1081 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001082 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001083}
1084testcase TC_cm_serv_req_vbs_reject() runs on MTC_CT {
1085 var BSC_ConnHdlr vc_conn;
1086 f_init();
1087
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001088 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vbs_reject), 20);
Harald Welte45164da2018-01-24 12:51:27 +01001089 vc_conn.done;
1090}
1091
1092/* CM Service Request for LCS -> reject */
1093private function f_tc_cm_serv_req_lcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001094 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001095
1096 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001097 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001098
1099 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001100 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_LCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +01001101 f_bssap_compl_l3(l3_info);
1102 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001103 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001104}
1105testcase TC_cm_serv_req_lcs_reject() runs on MTC_CT {
1106 var BSC_ConnHdlr vc_conn;
1107 f_init();
1108
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001109 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_lcs_reject), 21);
Harald Welte45164da2018-01-24 12:51:27 +01001110 vc_conn.done;
1111}
1112
Harald Welte0195ab12018-01-24 21:50:20 +01001113/* CM Re-Establishment Request */
1114private function f_tc_cm_reest_req_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001115 f_init_handler(pars);
Harald Welte0195ab12018-01-24 21:50:20 +01001116
1117 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001118 f_perform_lu();
Harald Welte0195ab12018-01-24 21:50:20 +01001119
1120 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1121 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REEST_REQ(0, mi));
1122 f_bssap_compl_l3(l3_info);
1123 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001124 f_expect_clear();
Harald Welte0195ab12018-01-24 21:50:20 +01001125}
1126testcase TC_cm_reest_req_reject() runs on MTC_CT {
1127 var BSC_ConnHdlr vc_conn;
1128 f_init();
Harald Welte0195ab12018-01-24 21:50:20 +01001129
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001130 vc_conn := f_start_handler(refers(f_tc_cm_reest_req_reject), 22);
Harald Welte0195ab12018-01-24 21:50:20 +01001131 vc_conn.done;
1132}
1133
Harald Weltec638f4d2018-01-24 22:00:36 +01001134/* Test LU (with authentication enabled), with wrong response from MS */
1135private function f_tc_lu_auth_2G_fail(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001136 f_init_handler(pars);
Harald Weltec638f4d2018-01-24 22:00:36 +01001137
1138 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
1139
1140 /* tell GSUP dispatcher to send this IMSI to us */
1141 f_create_gsup_expect(hex2str(g_pars.imsi));
1142
1143 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
1144 f_bssap_compl_l3(l3_lu);
1145
1146 /* Send Early Classmark, just for the fun of it */
1147 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1148
1149 var AuthVector vec := f_gen_auth_vec_2g();
1150 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(vec.rand, vec.sres, vec.kc));
1151 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
1152 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
1153
1154 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(vec.rand)));
1155 /* Send back wrong auth response */
1156 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G('00000000'O)));
1157
1158 /* Expect GSUP AUTH FAIL REP to HLR */
1159 GSUP.receive(tr_GSUP_AUTH_FAIL_IND(g_pars.imsi));
1160
1161 /* Expect LU REJECT with Cause == Illegal MS */
1162 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej('03'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +01001163 f_expect_clear();
Harald Weltec638f4d2018-01-24 22:00:36 +01001164}
1165testcase TC_lu_auth_2G_fail() runs on MTC_CT {
1166 var BSC_ConnHdlr vc_conn;
1167 f_init();
1168 f_vty_config(MSCVTY, "network", "authentication required");
Harald Weltec638f4d2018-01-24 22:00:36 +01001169
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001170 vc_conn := f_start_handler(refers(f_tc_lu_auth_2G_fail), 23);
Harald Weltec638f4d2018-01-24 22:00:36 +01001171 vc_conn.done;
1172}
1173
Harald Weltede371492018-01-27 23:44:41 +01001174/* A5/1 + A5/3 permitted on network side, and MS capable to do it */
Harald Welte16114282018-01-24 22:41:21 +01001175private 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 +01001176 pars.net.expect_auth := true;
1177 pars.net.expect_ciph := true;
Harald Weltea10db902018-01-27 12:44:49 +01001178 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001179 f_perform_lu();
Harald Welte16114282018-01-24 22:41:21 +01001180}
1181testcase TC_lu_imsi_auth_tmsi_encr_13_13() runs on MTC_CT {
1182 var BSC_ConnHdlr vc_conn;
1183 f_init();
1184 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte16114282018-01-24 22:41:21 +01001185 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1186
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001187 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_13), 24);
Harald Welte16114282018-01-24 22:41:21 +01001188 vc_conn.done;
1189}
1190
Harald Welte1af6ea82018-01-25 18:33:15 +01001191/* Test Complete L3 without payload */
1192private function f_tc_cl3_no_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001193 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001194
1195 /* Send Complete L3 Info with empty L3 frame */
1196 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1197 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, ''O))));
1198
Harald Weltef466eb42018-01-27 14:26:54 +01001199 timer T := 5.0;
1200 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001201 alt {
Harald Welte6811d102019-04-14 22:23:14 +02001202 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte1af6ea82018-01-25 18:33:15 +01001203 /* Expect LU REJECT with Cause == Illegal MS */
Harald Weltebdb3c452018-03-18 22:43:06 +01001204 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
Harald Welte6811d102019-04-14 22:23:14 +02001205 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001206 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001207 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001208 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Daniel Willmannafce8662018-07-06 23:11:32 +02001209 mtc.stop;
Harald Weltef466eb42018-01-27 14:26:54 +01001210 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001211 }
1212 setverdict(pass);
1213}
1214testcase TC_cl3_no_payload() runs on MTC_CT {
1215 var BSC_ConnHdlr vc_conn;
1216 f_init();
1217
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001218 vc_conn := f_start_handler(refers(f_tc_cl3_no_payload), 25);
Harald Welte1af6ea82018-01-25 18:33:15 +01001219 vc_conn.done;
1220}
1221
1222/* Test Complete L3 with random payload */
1223private function f_tc_cl3_rnd_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001224 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001225
Daniel Willmannaa14a382018-07-26 08:29:45 +02001226 /* length is limited by PDU_BSSAP length field which includes some
1227 * other fields beside l3info payload. So payl can only be 240 bytes
1228 * Since rnd() returns values < 1 multiply with 241
1229 */
1230 var integer len := float2int(rnd() * 241.0);
Harald Welte1af6ea82018-01-25 18:33:15 +01001231 var octetstring payl := f_rnd_octstring(len);
1232
1233 /* Send Complete L3 Info with empty L3 frame */
1234 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1235 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, payl))));
1236
Harald Weltef466eb42018-01-27 14:26:54 +01001237 timer T := 5.0;
1238 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001239 alt {
1240 /* Immediate disconnect */
Harald Welte6811d102019-04-14 22:23:14 +02001241 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte1af6ea82018-01-25 18:33:15 +01001242 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
Harald Welte6811d102019-04-14 22:23:14 +02001243 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001244 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001245 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001246 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Daniel Willmannafce8662018-07-06 23:11:32 +02001247 mtc.stop;
Harald Weltef466eb42018-01-27 14:26:54 +01001248 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001249 }
1250 setverdict(pass);
1251}
1252testcase TC_cl3_rnd_payload() runs on MTC_CT {
1253 var BSC_ConnHdlr vc_conn;
1254 f_init();
1255
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001256 vc_conn := f_start_handler(refers(f_tc_cl3_rnd_payload), 26);
Harald Welte1af6ea82018-01-25 18:33:15 +01001257 vc_conn.done;
1258}
1259
Harald Welte116e4332018-01-26 22:17:48 +01001260/* Test Complete L3 with random payload */
1261private function f_tc_establish_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001262 f_init_handler(pars);
Harald Welte116e4332018-01-26 22:17:48 +01001263
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001264 f_perform_lu();
Harald Welte116e4332018-01-26 22:17:48 +01001265
Harald Welteb9e86fa2018-04-09 18:18:31 +02001266 f_establish_fully();
Daniel Willmann898a7e02018-05-17 12:16:16 +02001267 f_expect_clear(10.0);
Harald Welte116e4332018-01-26 22:17:48 +01001268}
1269testcase TC_establish_and_nothing() runs on MTC_CT {
1270 var BSC_ConnHdlr vc_conn;
1271 f_init();
1272
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001273 vc_conn := f_start_handler(refers(f_tc_establish_and_nothing), 27);
Harald Welte116e4332018-01-26 22:17:48 +01001274 vc_conn.done;
1275}
1276
Harald Welte12510c52018-01-26 22:26:24 +01001277/* Test MO Call SETUP with no response from MNCC */
1278private function f_tc_mo_setup_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Philipp Maier109e6aa2018-10-17 10:53:32 +02001279 f_init_handler(pars, 190.0);
Harald Weltea10db902018-01-27 12:44:49 +01001280
Harald Welte12510c52018-01-26 22:26:24 +01001281 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1282
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001283 f_perform_lu();
Harald Welte12510c52018-01-26 22:26:24 +01001284
Harald Welteb9e86fa2018-04-09 18:18:31 +02001285 f_establish_fully();
Harald Welte12510c52018-01-26 22:26:24 +01001286 f_create_mncc_expect(hex2str(cpars.called_party));
1287 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1288
1289 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1290
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001291 var default ccrel := activate(as_optional_cc_rel(cpars));
1292
Philipp Maier109e6aa2018-10-17 10:53:32 +02001293 f_expect_clear(185.0);
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001294
1295 deactivate(ccrel);
1296
1297 f_sleep(1.0);
Harald Welte12510c52018-01-26 22:26:24 +01001298}
1299testcase TC_mo_setup_and_nothing() runs on MTC_CT {
1300 var BSC_ConnHdlr vc_conn;
1301 f_init();
1302
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001303 vc_conn := f_start_handler(refers(f_tc_mo_setup_and_nothing), 28);
Harald Welte12510c52018-01-26 22:26:24 +01001304 vc_conn.done;
1305}
1306
Harald Welte3ab88002018-01-26 22:37:25 +01001307/* Test MO Call with no response to RAN-side CRCX */
1308private function f_tc_mo_crcx_ran_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001309 f_init_handler(pars);
Harald Welte3ab88002018-01-26 22:37:25 +01001310 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1311 var MNCC_PDU mncc;
1312 var MgcpCommand mgcp_cmd;
1313
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001314 f_perform_lu();
Harald Welte3ab88002018-01-26 22:37:25 +01001315
Harald Welteb9e86fa2018-04-09 18:18:31 +02001316 f_establish_fully();
Harald Welte3ab88002018-01-26 22:37:25 +01001317 f_create_mncc_expect(hex2str(cpars.called_party));
1318 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1319
1320 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1321 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1322 cpars.mncc_callref := mncc.u.signal.callref;
1323 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1324 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1325
1326 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
Harald Welte1852a842018-01-26 22:53:36 +01001327 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1328 cpars.mgcp_ep := mgcp_cmd.line.ep;
Harald Welte3ab88002018-01-26 22:37:25 +01001329 /* never respond to this */
1330
Philipp Maier8e58f592018-03-14 11:10:56 +01001331 /* When the connection with the MGW fails, the MSC will first request
1332 * a release via call control. We will answer this request normally. */
1333 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1334 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1335
Harald Welte1ddc7162018-01-27 14:25:46 +01001336 f_expect_clear(30.0);
Harald Welte3ab88002018-01-26 22:37:25 +01001337}
1338testcase TC_mo_crcx_ran_timeout() runs on MTC_CT {
1339 var BSC_ConnHdlr vc_conn;
1340 f_init();
1341
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001342 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_timeout), 29);
Harald Welte3ab88002018-01-26 22:37:25 +01001343 vc_conn.done;
1344}
1345
Harald Welte0cc82d92018-01-26 22:52:34 +01001346/* Test MO Call with reject to RAN-side CRCX */
1347private function f_tc_mo_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001348 f_init_handler(pars);
Harald Welte0cc82d92018-01-26 22:52:34 +01001349 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1350 var MNCC_PDU mncc;
1351 var MgcpCommand mgcp_cmd;
1352
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001353 f_perform_lu();
Harald Welte0cc82d92018-01-26 22:52:34 +01001354
Harald Welteb9e86fa2018-04-09 18:18:31 +02001355 f_establish_fully();
Harald Welte0cc82d92018-01-26 22:52:34 +01001356 f_create_mncc_expect(hex2str(cpars.called_party));
1357 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1358
1359 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1360 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1361 cpars.mncc_callref := mncc.u.signal.callref;
1362 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1363 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1364
1365 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001366
1367 /* Detect if the received CRCX is a wildcarded CRCX request. If yes,
1368 * set an endpoint name that fits the pattern. If not, just use the
1369 * endpoint name from the request */
1370 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
1371 cpars.mgcp_ep := "rtpbridge/1@mgw";
1372 } else {
1373 cpars.mgcp_ep := mgcp_cmd.line.ep;
1374 }
1375
Harald Welte0cc82d92018-01-26 22:52:34 +01001376 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001377
Harald Welte0cc82d92018-01-26 22:52:34 +01001378 /* Respond to CRCX with error */
1379 var MgcpResponse mgcp_rsp := {
1380 line := {
1381 code := "542",
1382 trans_id := mgcp_cmd.line.trans_id,
1383 string := "FORCED_FAIL"
1384 },
Harald Welte0cc82d92018-01-26 22:52:34 +01001385 sdp := omit
1386 }
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001387 var MgcpParameter mgcp_rsp_param := {
1388 code := "Z",
1389 val := cpars.mgcp_ep
1390 };
1391 mgcp_rsp.params[0] := mgcp_rsp_param;
Harald Welte0cc82d92018-01-26 22:52:34 +01001392 MGCP.send(mgcp_rsp);
1393
1394 timer T := 30.0;
1395 T.start;
1396 alt {
Daniel Willmannafce8662018-07-06 23:11:32 +02001397 [] T.timeout {
1398 setverdict(fail, "Timeout waiting for channel release");
1399 mtc.stop;
1400 }
Daniel Willmann5868e622018-02-15 17:42:59 +01001401 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id))) {
1402 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1403 repeat;
1404 }
Harald Welte0cc82d92018-01-26 22:52:34 +01001405 [] MNCC.receive { repeat; }
1406 [] GSUP.receive { repeat; }
Philipp Maierc6e06f72018-04-11 18:12:23 +02001407 /* Note: As we did not respond properly to the CRCX from the MSC we
1408 * expect the MSC to omit any further MGCP operation (At least in the
1409 * the current implementation, there is no recovery mechanism implemented
1410 * and a DLCX can not be performed as the MSC does not know a specific
1411 * endpoint yet. */
Daniel Willmannafce8662018-07-06 23:11:32 +02001412 [] MGCP.receive {
1413 setverdict(fail, "Unexpected MGCP message");
1414 mtc.stop;
1415 }
Harald Welte5946b332018-03-18 23:32:21 +01001416 [] as_clear_cmd_compl_disc();
Harald Welte0cc82d92018-01-26 22:52:34 +01001417 }
1418}
1419testcase TC_mo_crcx_ran_reject() runs on MTC_CT {
1420 var BSC_ConnHdlr vc_conn;
1421 f_init();
1422
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001423 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_reject), 30);
Harald Welte0cc82d92018-01-26 22:52:34 +01001424 vc_conn.done;
1425}
1426
Harald Welte3ab88002018-01-26 22:37:25 +01001427
Harald Welte812f7a42018-01-27 00:49:18 +01001428/* helper function to start a MT call: MNCC SETUP; Paging; DChan est.; DTAP SETUP */
1429private function f_mt_call_start(inout CallParameters cpars) runs on BSC_ConnHdlr {
1430 var MNCC_PDU mncc;
1431 var MgcpCommand mgcp_cmd;
1432 var OCT4 tmsi;
1433
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001434 f_perform_lu();
Harald Welte812f7a42018-01-27 00:49:18 +01001435 if (isvalue(g_pars.tmsi)) {
1436 tmsi := g_pars.tmsi;
1437 } else {
1438 tmsi := 'FFFFFFFF'O;
1439 }
Harald Welte6811d102019-04-14 22:23:14 +02001440 f_ran_register_imsi(g_pars.imsi, tmsi);
Harald Welte812f7a42018-01-27 00:49:18 +01001441
1442 /* Allocate call reference and send SETUP via MNCC to MSC */
1443 cpars.mncc_callref := f_rnd_int(2147483648);
1444 MNCC.send(ts_MNCC_SETUP_req(cpars.mncc_callref, hex2str(g_pars.msisdn),
1445 hex2str(cpars.called_party), hex2str(g_pars.imsi)));
1446
1447 /* MSC->BSC: expect PAGING from MSC */
Harald Weltee035e3e2019-04-21 17:32:05 +02001448 f_expect_paging();
1449
Harald Welte812f7a42018-01-27 00:49:18 +01001450 /* MS -> MSC: PAGING RESPONSE */
Harald Welteb9e86fa2018-04-09 18:18:31 +02001451 f_establish_fully(EST_TYPE_PAG_RESP);
Harald Welte812f7a42018-01-27 00:49:18 +01001452
1453 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1454
1455 /* MSC->MS: SETUP */
1456 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party)));
1457}
1458
1459/* Test MT Call */
1460private function f_tc_mt_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001461 f_init_handler(pars);
Harald Welte812f7a42018-01-27 00:49:18 +01001462 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1463 var MNCC_PDU mncc;
1464 var MgcpCommand mgcp_cmd;
1465
1466 f_mt_call_start(cpars);
1467
1468 /* MS->MSC: CALL CONFIRMED */
1469 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1470
1471 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1472
1473 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1474 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001475
1476 /* Detect if the received CRCX is a wildcarded CRCX request. If yes,
1477 * set an endpoint name that fits the pattern. If not, just use the
1478 * endpoint name from the request */
1479 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
1480 cpars.mgcp_ep := "rtpbridge/1@mgw";
1481 } else {
1482 cpars.mgcp_ep := mgcp_cmd.line.ep;
1483 }
1484
Harald Welte812f7a42018-01-27 00:49:18 +01001485 /* Respond to CRCX with error */
1486 var MgcpResponse mgcp_rsp := {
1487 line := {
1488 code := "542",
1489 trans_id := mgcp_cmd.line.trans_id,
1490 string := "FORCED_FAIL"
1491 },
Harald Welte812f7a42018-01-27 00:49:18 +01001492 sdp := omit
1493 }
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001494 var MgcpParameter mgcp_rsp_param := {
1495 code := "Z",
1496 val := cpars.mgcp_ep
1497 };
1498 mgcp_rsp.params[0] := mgcp_rsp_param;
Harald Welte812f7a42018-01-27 00:49:18 +01001499 MGCP.send(mgcp_rsp);
1500
1501 timer T := 30.0;
1502 T.start;
1503 alt {
Daniel Willmannafce8662018-07-06 23:11:32 +02001504 [] T.timeout {
1505 setverdict(fail, "Timeout waiting for channel release");
1506 mtc.stop;
1507 }
Harald Welte812f7a42018-01-27 00:49:18 +01001508 [] MNCC.receive { repeat; }
1509 [] GSUP.receive { repeat; }
1510 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1511 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1512 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1513 repeat;
1514 }
1515 [] MGCP.receive { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001516 [] as_clear_cmd_compl_disc();
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001517 [] as_optional_cc_rel(cpars);
Harald Welte812f7a42018-01-27 00:49:18 +01001518 }
1519}
1520testcase TC_mt_crcx_ran_reject() runs on MTC_CT {
1521 var BSC_ConnHdlr vc_conn;
1522 f_init();
1523
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001524 vc_conn := f_start_handler(refers(f_tc_mt_crcx_ran_reject), 31);
Harald Welte812f7a42018-01-27 00:49:18 +01001525 vc_conn.done;
1526}
1527
1528
1529/* Test MT Call T310 timer */
1530private function f_tc_mt_t310(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltead2952e2018-01-27 14:12:46 +01001531 f_init_handler(pars, 200.0);
Harald Welte812f7a42018-01-27 00:49:18 +01001532 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1533 var MNCC_PDU mncc;
1534 var MgcpCommand mgcp_cmd;
1535
1536 f_mt_call_start(cpars);
1537
1538 /* MS->MSC: CALL CONFIRMED */
1539 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1540 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1541
1542 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1543 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1544 cpars.mgcp_ep := mgcp_cmd.line.ep;
1545 /* FIXME: Respond to CRCX */
1546
1547 /* old libosmocore T310 default timeout is 180s. so let's wait 190 */
1548 timer T := 190.0;
1549 T.start;
1550 alt {
Daniel Willmannafce8662018-07-06 23:11:32 +02001551 [] T.timeout {
1552 setverdict(fail, "Timeout waiting for T310");
1553 mtc.stop;
1554 }
Harald Welte812f7a42018-01-27 00:49:18 +01001555 [] MNCC.receive(tr_MNCC_DISC_ind(cpars.mncc_callref)) {
1556 MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(23))));
1557 }
1558 }
1559 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));
1560 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1561 /* FIXME: We're sending this with TIflag 0: allocated by sender, which is wrong */
1562 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1563
1564 alt {
Harald Welte812f7a42018-01-27 00:49:18 +01001565 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1566 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1567 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1568 repeat;
1569 }
Harald Welte5946b332018-03-18 23:32:21 +01001570 [] as_clear_cmd_compl_disc();
Harald Welte812f7a42018-01-27 00:49:18 +01001571 }
1572}
1573testcase TC_mt_t310() runs on MTC_CT {
1574 var BSC_ConnHdlr vc_conn;
1575 f_init();
1576
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001577 vc_conn := f_start_handler(refers(f_tc_mt_t310), 32);
Harald Welte812f7a42018-01-27 00:49:18 +01001578 vc_conn.done;
1579}
1580
Harald Welte167458a2018-01-27 15:58:16 +01001581/* Perform successful LU + MO call, then GSUP LocationCancel. Subscriber must be denied CM SERV */
1582private function f_tc_gsup_cancel(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1583 f_init_handler(pars);
1584 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1585 cpars.bss_rtp_port := 1110;
1586 cpars.mgcp_connection_id_bss := '22222'H;
1587 cpars.mgcp_connection_id_mss := '33333'H;
Daniel Willmann9b0235b2018-07-24 12:13:34 +02001588 cpars.mgcp_ep := "rtpbridge/1@mgw";
Harald Welte167458a2018-01-27 15:58:16 +01001589
1590 /* Location Update to make subscriber known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001591 f_perform_lu();
Harald Welte167458a2018-01-27 15:58:16 +01001592
1593 /* First MO call should succeed */
1594 f_mo_call(cpars);
1595
1596 /* Cancel the subscriber in the VLR */
1597 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1598 alt {
1599 [] GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi)) { }
1600 [] GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi)) {
1601 setverdict(fail, "Received GSUP Location Cancel Error");
Daniel Willmannafce8662018-07-06 23:11:32 +02001602 mtc.stop;
Harald Welte167458a2018-01-27 15:58:16 +01001603 }
1604 }
1605
1606 /* Follow-up transactions should fail */
1607 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1608 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
1609 f_bssap_compl_l3(l3_info);
1610 alt {
1611 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
1612 [] BSSAP.receive {
1613 setverdict(fail, "Received unexpected BSSAP instead of CM SERV REJ");
Daniel Willmannafce8662018-07-06 23:11:32 +02001614 mtc.stop;
Harald Welte167458a2018-01-27 15:58:16 +01001615 }
1616 }
Neels Hofmeyr0f7429a2019-03-07 22:28:41 +01001617
1618 f_expect_clear();
Harald Welte167458a2018-01-27 15:58:16 +01001619 setverdict(pass);
1620}
1621testcase TC_gsup_cancel() runs on MTC_CT {
1622 var BSC_ConnHdlr vc_conn;
1623 f_init();
1624
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001625 vc_conn := f_start_handler(refers(f_tc_gsup_cancel), 33);
Harald Welte167458a2018-01-27 15:58:16 +01001626 vc_conn.done;
1627}
1628
Harald Welte9de84792018-01-28 01:06:35 +01001629/* A5/1 only permitted on network side, and MS capable to do it */
1630private function f_tc_lu_imsi_auth_tmsi_encr_1_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1631 pars.net.expect_auth := true;
1632 pars.net.expect_ciph := true;
1633 pars.net.kc_support := '02'O; /* A5/1 only */
1634 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001635 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001636}
1637testcase TC_lu_imsi_auth_tmsi_encr_1_13() runs on MTC_CT {
1638 var BSC_ConnHdlr vc_conn;
1639 f_init();
1640 f_vty_config(MSCVTY, "network", "authentication required");
1641 f_vty_config(MSCVTY, "network", "encryption a5 1");
1642
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001643 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_1_13), 34);
Harald Welte9de84792018-01-28 01:06:35 +01001644 vc_conn.done;
1645}
1646
1647/* A5/3 only permitted on network side, and MS capable to do it */
1648private function f_tc_lu_imsi_auth_tmsi_encr_3_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1649 pars.net.expect_auth := true;
1650 pars.net.expect_ciph := true;
1651 pars.net.kc_support := '08'O; /* A5/3 only */
1652 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001653 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001654}
1655testcase TC_lu_imsi_auth_tmsi_encr_3_13() runs on MTC_CT {
1656 var BSC_ConnHdlr vc_conn;
1657 f_init();
1658 f_vty_config(MSCVTY, "network", "authentication required");
1659 f_vty_config(MSCVTY, "network", "encryption a5 3");
1660
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001661 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_13), 35);
Harald Welte9de84792018-01-28 01:06:35 +01001662 vc_conn.done;
1663}
1664
1665/* A5/3 only permitted on network side, and MS with only A5/1 support */
1666private function f_tc_lu_imsi_auth_tmsi_encr_3_1(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1667 pars.net.expect_auth := true;
1668 pars.net.expect_ciph := true;
1669 pars.net.kc_support := '08'O; /* A5/3 only */
1670 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1671 f_init_handler(pars, 15.0);
1672
1673 /* cannot use f_perform_lu() as we expect a reject */
1674 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1675 f_create_gsup_expect(hex2str(g_pars.imsi));
1676 f_bssap_compl_l3(l3_lu);
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001677 if (pars.send_early_cm) {
1678 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1679 } else {
1680 pars.cm1.esind := '0'B;
1681 }
Harald Welte9de84792018-01-28 01:06:35 +01001682 f_mm_auth();
1683 alt {
Daniel Willmann52918e52018-09-20 14:39:09 +02001684 [] BSSAP.receive(tr_BSSMAP_ClassmarkReq) {
1685 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1686 repeat;
1687 }
Harald Welte5946b332018-03-18 23:32:21 +01001688 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1689 f_expect_clear();
1690 }
Harald Welte9de84792018-01-28 01:06:35 +01001691 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1692 setverdict(fail, "CipherModeCommand despite no A5 intersection");
Daniel Willmannafce8662018-07-06 23:11:32 +02001693 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001694 }
1695 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001696 setverdict(fail, "Unknown/unexpected BSSAP received");
Daniel Willmannafce8662018-07-06 23:11:32 +02001697 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001698 }
1699 }
1700 setverdict(pass);
1701}
1702testcase TC_lu_imsi_auth_tmsi_encr_3_1() runs on MTC_CT {
1703 var BSC_ConnHdlr vc_conn;
1704 f_init();
1705 f_vty_config(MSCVTY, "network", "authentication required");
1706 f_vty_config(MSCVTY, "network", "encryption a5 3");
1707
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001708 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 360);
1709 vc_conn.done;
1710}
1711testcase TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() runs on MTC_CT {
1712 var BSC_ConnHdlrPars pars;
1713 var BSC_ConnHdlr vc_conn;
1714 f_init();
1715 f_vty_config(MSCVTY, "network", "authentication required");
1716 f_vty_config(MSCVTY, "network", "encryption a5 3");
1717
1718 pars := f_init_pars(361);
1719 pars.send_early_cm := false;
1720 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 +01001721 vc_conn.done;
1722}
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01001723testcase TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() runs on MTC_CT {
1724 var BSC_ConnHdlr vc_conn;
1725 f_init();
1726 f_vty_config(MSCVTY, "network", "authentication required");
1727 f_vty_config(MSCVTY, "network", "encryption a5 3");
1728
1729 /* Make sure the MSC category is on DEBUG level to trigger the log
1730 * message that is reported in OS#2947 to trigger the segfault */
1731 f_vty_config(MSCVTY, "log stderr", "logging level msc debug");
1732
1733 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 362);
1734 vc_conn.done;
1735}
Harald Welte9de84792018-01-28 01:06:35 +01001736
1737/* A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
1738private function f_tc_lu_imsi_auth_tmsi_encr_13_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1739 pars.net.expect_auth := true;
1740 pars.net.expect_ciph := true;
1741 pars.net.kc_support := '0A'O; /* A5/1 + A5/3 */
1742 pars.cm1.a5_1 := '1'B;
1743 pars.cm2.a5_1 := '1'B;
1744 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1745 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
1746 f_init_handler(pars, 15.0);
1747
1748 /* cannot use f_perform_lu() as we expect a reject */
1749 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1750 f_create_gsup_expect(hex2str(g_pars.imsi));
1751 f_bssap_compl_l3(l3_lu);
1752 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1753 f_mm_auth();
1754 alt {
Harald Welte5946b332018-03-18 23:32:21 +01001755 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1756 f_expect_clear();
1757 }
Harald Welte9de84792018-01-28 01:06:35 +01001758 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1759 setverdict(fail, "CipherModeCommand despite no A5 intersection");
Daniel Willmannafce8662018-07-06 23:11:32 +02001760 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001761 }
1762 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001763 setverdict(fail, "Unknown/unexpected BSSAP received");
Daniel Willmannafce8662018-07-06 23:11:32 +02001764 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001765 }
1766 }
1767 setverdict(pass);
1768}
1769testcase TC_lu_imsi_auth_tmsi_encr_13_2() runs on MTC_CT {
1770 var BSC_ConnHdlr vc_conn;
1771 f_init();
1772 f_vty_config(MSCVTY, "network", "authentication required");
1773 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1774
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001775 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_2), 37);
Harald Welte9de84792018-01-28 01:06:35 +01001776 vc_conn.done;
1777}
1778
1779/* A5/0 + A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
1780private function f_tc_lu_imsi_auth_tmsi_encr_013_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1781 pars.net.expect_auth := true;
1782 pars.net.expect_ciph := true;
1783 pars.net.kc_support := '0B'O; /* A5/1 + A5/3 */
1784 pars.cm1.a5_1 := '1'B;
1785 pars.cm2.a5_1 := '1'B;
1786 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1787 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
1788 f_init_handler(pars, 15.0);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001789 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001790}
1791testcase TC_lu_imsi_auth_tmsi_encr_013_2() runs on MTC_CT {
1792 var BSC_ConnHdlr vc_conn;
1793 f_init();
1794 f_vty_config(MSCVTY, "network", "authentication required");
1795 f_vty_config(MSCVTY, "network", "encryption a5 0 1 3");
1796
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001797 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_013_2), 38);
Harald Welte9de84792018-01-28 01:06:35 +01001798 vc_conn.done;
1799}
1800
Harald Welte33ec09b2018-02-10 15:34:46 +01001801/* LU followed by MT call (including paging) */
1802private function f_tc_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1803 f_init_handler(pars);
Stefan Sperling26d57be2018-11-12 17:03:26 +01001804 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Harald Welte33ec09b2018-02-10 15:34:46 +01001805 cpars.bss_rtp_port := 1110;
1806 cpars.mgcp_connection_id_bss := '10004'H;
1807 cpars.mgcp_connection_id_mss := '10005'H;
1808
Philipp Maier4b2692d2018-03-14 16:37:48 +01001809 /* Note: This is an optional parameter. When the call-agent (MSC) does
1810 * supply a full endpoint name this setting will be overwritten. */
1811 cpars.mgcp_ep := "rtpbridge/1@mgw";
1812
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001813 f_perform_lu();
Harald Welte33ec09b2018-02-10 15:34:46 +01001814 f_mt_call(cpars);
1815}
1816testcase TC_lu_and_mt_call() runs on MTC_CT {
1817 var BSC_ConnHdlr vc_conn;
1818 f_init();
1819
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001820 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call), 39);
Harald Welte33ec09b2018-02-10 15:34:46 +01001821 vc_conn.done;
1822}
1823
Daniel Willmann8b084372018-02-04 13:35:26 +01001824/* Test MO Call SETUP with DTMF */
1825private function f_tc_mo_setup_dtmf_dup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1826 f_init_handler(pars);
1827 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1828 cpars.bss_rtp_port := 1110;
1829 cpars.mgcp_connection_id_bss := '22222'H;
1830 cpars.mgcp_connection_id_mss := '33333'H;
1831
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001832 f_perform_lu();
Daniel Willmann8b084372018-02-04 13:35:26 +01001833 f_mo_seq_dtmf_dup(cpars);
1834}
1835testcase TC_mo_setup_and_dtmf_dup() runs on MTC_CT {
1836 var BSC_ConnHdlr vc_conn;
1837 f_init();
1838
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001839 vc_conn := f_start_handler(refers(f_tc_mo_setup_dtmf_dup), 39);
Daniel Willmann8b084372018-02-04 13:35:26 +01001840 vc_conn.done;
1841}
Harald Welte9de84792018-01-28 01:06:35 +01001842
Philipp Maier328d1662018-03-07 10:40:27 +01001843testcase TC_cr_before_reset() runs on MTC_CT {
1844 timer T := 4.0;
1845 var boolean reset_ack_seen := false;
1846 f_init_bssap_direct();
1847
Daniel Willmann42d1d5b2018-08-07 15:18:41 +02001848 f_bssap_start(g_bssap[0]);
1849
Daniel Willmanne8018962018-08-21 14:18:00 +02001850 f_sleep(3.0);
1851
Philipp Maier328d1662018-03-07 10:40:27 +01001852 /* Make a blind connection attemt, to trigger the deadlock condition */
Philipp Maier75932982018-03-27 14:52:35 +02001853 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 +01001854
1855 /* Send a BSSMAP reset */
Philipp Maier75932982018-03-27 14:52:35 +02001856 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 +01001857 T.start
1858 alt {
1859 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_ResetAck)) {
1860 reset_ack_seen := true;
1861 repeat;
1862 }
1863
1864 /* Acknowledge MSC sided reset requests */
1865 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) {
Philipp Maier75932982018-03-27 14:52:35 +02001866 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 +01001867 repeat;
1868 }
1869
1870 /* Ignore all other messages (e.g CR from the connection request) */
1871 [] BSSAP_DIRECT.receive { repeat }
1872
1873 /* If we got no BSSMAP RESET ACK back, then the MSC entered the
1874 * deadlock situation. The MSC is then unable to respond to any
1875 * further BSSMAP RESET or any other sort of traffic. */
1876 [reset_ack_seen == true] T.timeout { setverdict(pass) }
1877 [reset_ack_seen == false] T.timeout {
1878 setverdict(fail, "no BSSMAP RESET ACK seen!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001879 mtc.stop;
Philipp Maier328d1662018-03-07 10:40:27 +01001880 }
1881 }
1882}
Harald Welte9de84792018-01-28 01:06:35 +01001883
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001884/* Test MO Call with no response to RAN-side CRCX or DTAP Release */
1885private function f_tc_mo_release_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1886 f_init_handler(pars);
1887 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1888 var MNCC_PDU mncc;
1889 var MgcpCommand mgcp_cmd;
1890
1891 f_perform_lu();
1892
Harald Welteb9e86fa2018-04-09 18:18:31 +02001893 f_establish_fully();
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001894 f_create_mncc_expect(hex2str(cpars.called_party));
1895 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1896
1897 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1898 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1899 cpars.mncc_callref := mncc.u.signal.callref;
1900 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1901 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1902
1903 /* Drop CRCX */
1904 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1905
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001906 var default ccrel := activate(as_optional_cc_rel(cpars));
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001907
1908 f_expect_clear(60.0);
Neels Hofmeyrde76f052019-02-26 05:02:46 +01001909
1910 deactivate(ccrel);
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001911}
1912testcase TC_mo_release_timeout() runs on MTC_CT {
1913 var BSC_ConnHdlr vc_conn;
1914 f_init();
1915
1916 vc_conn := f_start_handler(refers(f_tc_mo_release_timeout), 40);
1917 vc_conn.done;
1918}
1919
Harald Welte12510c52018-01-26 22:26:24 +01001920
Philipp Maier2a98a732018-03-19 16:06:12 +01001921/* LU followed by MT call (including paging) */
1922private function f_tc_lu_and_mt_call_no_dlcx_resp(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1923 f_init_handler(pars);
Stefan Sperling26d57be2018-11-12 17:03:26 +01001924 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Philipp Maier2a98a732018-03-19 16:06:12 +01001925 cpars.bss_rtp_port := 1110;
1926 cpars.mgcp_connection_id_bss := '10004'H;
1927 cpars.mgcp_connection_id_mss := '10005'H;
1928
1929 /* Note: This is an optional parameter. When the call-agent (MSC) does
1930 * supply a full endpoint name this setting will be overwritten. */
1931 cpars.mgcp_ep := "rtpbridge/1@mgw";
1932
1933 /* Intentionally disable the CRCX response */
1934 cpars.mgw_drop_dlcx := true;
1935
1936 /* Perform location update and call */
1937 f_perform_lu();
1938 f_mt_call(cpars);
1939}
1940testcase TC_lu_and_mt_call_no_dlcx_resp() runs on MTC_CT {
1941 var BSC_ConnHdlr vc_conn;
1942 f_init();
1943
1944 /* Perform an almost normal looking locationupdate + mt-call, but do
1945 * not respond to the DLCX at the end of the call */
1946 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call_no_dlcx_resp), 41);
1947 vc_conn.done;
1948
1949 /* Wait a guard period until the MGCP layer in the MSC times out,
1950 * if the MSC is vulnerable to the use-after-free situation that is
1951 * fixed by I78f1b6a9149488a4ad3f120c1e190a83c07d4b89 then it should
1952 * segfault now */
1953 f_sleep(6.0);
1954
1955 /* Run the init procedures once more. If the MSC has crashed, this
1956 * this will fail */
1957 f_init();
1958}
Harald Welte45164da2018-01-24 12:51:27 +01001959
Philipp Maier75932982018-03-27 14:52:35 +02001960/* Two BSSMAP resets from two different BSCs */
1961testcase TC_reset_two() runs on MTC_CT {
1962 var BSC_ConnHdlr vc_conn;
1963 f_init(2);
1964 f_sleep(2.0);
1965 setverdict(pass);
1966}
1967
Harald Weltef640a012018-04-14 17:49:21 +02001968/***********************************************************************
1969 * SMS Testing
1970 ***********************************************************************/
1971
Harald Weltef45efeb2018-04-09 18:19:24 +02001972/* LU followed by MO SMS */
1973private function f_tc_lu_and_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1974 var SmsParameters spars := valueof(t_SmsPars);
1975
1976 f_init_handler(pars);
1977
1978 /* Perform location update and call */
1979 f_perform_lu();
1980
1981 f_establish_fully(EST_TYPE_MO_SMS);
1982
1983 //spars.exp_rp_err := 96; /* invalid mandatory information */
1984 f_mo_sms(spars);
1985
1986 f_expect_clear();
1987}
1988testcase TC_lu_and_mo_sms() runs on MTC_CT {
1989 var BSC_ConnHdlr vc_conn;
1990 f_init();
1991 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_sms), 42);
1992 vc_conn.done;
1993}
1994
1995private function f_vty_sms_send(charstring imsi, charstring msisdn, charstring text)
Neels Hofmeyr6aaeccf2019-03-06 15:32:26 +01001996runs on BSC_ConnHdlr {
Harald Weltef45efeb2018-04-09 18:19:24 +02001997 f_vty_transceive(MSCVTY, "subscriber imsi "&imsi&" sms sender msisdn "&msisdn&" send "&text);
1998}
1999
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01002000/* Remove still pending SMS */
2001private function f_vty_sms_clear(charstring imsi)
2002runs on BSC_ConnHdlr {
2003 f_vty_transceive(MSCVTY, "subscriber imsi " & imsi & " sms delete-all");
2004 f_vty_transceive(MSCVTY, "sms-queue clear");
2005}
2006
Harald Weltef45efeb2018-04-09 18:19:24 +02002007/* LU followed by MT SMS */
2008private function f_tc_lu_and_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2009 var SmsParameters spars := valueof(t_SmsPars);
2010 var OCT4 tmsi;
2011
2012 f_init_handler(pars);
2013
2014 /* Perform location update and call */
2015 f_perform_lu();
2016
2017 /* register an 'expect' for given IMSI (+TMSI) */
2018 if (isvalue(g_pars.tmsi)) {
2019 tmsi := g_pars.tmsi;
2020 } else {
2021 tmsi := 'FFFFFFFF'O;
2022 }
Harald Welte6811d102019-04-14 22:23:14 +02002023 f_ran_register_imsi(g_pars.imsi, tmsi);
Harald Weltef45efeb2018-04-09 18:19:24 +02002024
Neels Hofmeyr6aaeccf2019-03-06 15:32:26 +01002025 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
Harald Weltef45efeb2018-04-09 18:19:24 +02002026
2027 /* MSC->BSC: expect PAGING from MSC */
Harald Weltee035e3e2019-04-21 17:32:05 +02002028 f_expect_paging();
2029
Harald Weltef45efeb2018-04-09 18:19:24 +02002030 /* Establish DTAP / BSSAP / SCCP connection */
2031 f_establish_fully(EST_TYPE_PAG_RESP);
2032
2033 spars.tp.ud := 'C8329BFD064D9B53'O;
2034 f_mt_sms(spars);
2035
2036 f_expect_clear();
2037}
2038testcase TC_lu_and_mt_sms() runs on MTC_CT {
2039 var BSC_ConnHdlrPars pars;
2040 var BSC_ConnHdlr vc_conn;
2041 f_init();
2042 pars := f_init_pars(43);
2043 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_sms), pars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002044 vc_conn.done;
2045}
2046
Philipp Maier3983e702018-11-22 19:01:33 +01002047/* Paging for MT SMS but no response */
2048private function f_tc_lu_and_mt_sms_paging_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2049 var SmsParameters spars := valueof(t_SmsPars);
2050 var OCT4 tmsi;
Philipp Maier3983e702018-11-22 19:01:33 +01002051 f_init_handler(pars, 150.0);
2052
2053 /* Perform location update */
2054 f_perform_lu();
2055
2056 /* register an 'expect' for given IMSI (+TMSI) */
2057 if (isvalue(g_pars.tmsi)) {
2058 tmsi := g_pars.tmsi;
2059 } else {
2060 tmsi := 'FFFFFFFF'O;
2061 }
Harald Welte6811d102019-04-14 22:23:14 +02002062 f_ran_register_imsi(g_pars.imsi, tmsi);
Philipp Maier3983e702018-11-22 19:01:33 +01002063
Neels Hofmeyr6aaeccf2019-03-06 15:32:26 +01002064 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
2065
Neels Hofmeyr16237742019-03-06 15:34:01 +01002066 /* Expect the MSC to page exactly once */
2067 BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) { };
Philipp Maier3983e702018-11-22 19:01:33 +01002068
2069 /* Wait some time to make sure the MSC is not delivering any further
2070 * paging messages or anything else that could be unexpected. */
2071 timer T := 20.0;
2072 T.start
2073 alt {
2074 [] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi))
2075 {
2076 setverdict(fail, "paging seems not to stop!");
2077 mtc.stop;
2078 }
2079 [] BSSAP.receive {
2080 setverdict(fail, "unexpected BSSAP message received");
2081 self.stop;
2082 }
2083 [] T.timeout {
2084 setverdict(pass);
2085 }
2086 }
2087
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01002088 f_vty_sms_clear(hex2str(g_pars.imsi));
2089
Philipp Maier3983e702018-11-22 19:01:33 +01002090 setverdict(pass);
2091}
2092testcase TC_lu_and_mt_sms_paging_and_nothing() runs on MTC_CT {
2093 var BSC_ConnHdlrPars pars;
2094 var BSC_ConnHdlr vc_conn;
2095 f_init();
Philipp Maiera99ad262019-01-22 15:35:42 +01002096 pars := f_init_pars(1843);
Philipp Maier3983e702018-11-22 19:01:33 +01002097 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 +01002098 vc_conn.done;
2099}
2100
Harald Weltef640a012018-04-14 17:49:21 +02002101/* mobile originated SMS from MS/BTS/BSC side to SMPP */
2102private function f_tc_smpp_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2103 var SmsParameters spars := valueof(t_SmsPars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002104
Harald Weltef640a012018-04-14 17:49:21 +02002105 f_init_handler(pars);
Harald Weltef45efeb2018-04-09 18:19:24 +02002106
Harald Weltef640a012018-04-14 17:49:21 +02002107 /* Perform location update so IMSI is known + registered in MSC/VLR */
2108 f_perform_lu();
2109 f_establish_fully(EST_TYPE_MO_SMS);
2110
2111 f_mo_sms(spars);
2112
2113 var SMPP_PDU smpp;
2114 var template SMPP_PDU tr_smpp := tr_SMPP(c_SMPP_command_id_deliver_sm, ESME_ROK);
2115 tr_smpp.body.deliver_sm := {
2116 service_type := "CMT",
2117 source_addr_ton := network_specific,
2118 source_addr_npi := isdn,
2119 source_addr := hex2str(pars.msisdn),
2120 dest_addr_ton := f_sm_ton_from_gsm(spars.tp.da.tP_DA_NoPad.tP_TypeOfNumber),
2121 dest_addr_npi := f_sm_npi_from_gsm(spars.tp.da.tP_DA_NoPad.tP_NumberingPlanID),
2122 destination_addr := hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue),
2123 esm_class := '00000001'B,
2124 protocol_id := 0,
2125 priority_flag := 0,
2126 schedule_delivery_time := "",
2127 replace_if_present := 0,
2128 data_coding := '00000001'B,
2129 sm_default_msg_id := 0,
2130 sm_length := ?,
2131 short_message := spars.tp.ud,
2132 opt_pars := {
2133 {
2134 tag := user_message_reference,
2135 len := 2,
2136 opt_value := {
2137 int2_val := oct2int(spars.tp.msg_ref)
2138 }
2139 }
2140 }
2141 };
2142 alt {
2143 [] SMPP.receive(tr_smpp) -> value smpp {
2144 SMPP.send(ts_SMPP_DELIVER_SM_resp(ESME_ROK, smpp.header.seq_num));
2145 }
2146 [] SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK)) { repeat; }
2147 }
2148
2149 f_expect_clear();
2150}
2151testcase TC_smpp_mo_sms() runs on MTC_CT {
2152 var BSC_ConnHdlr vc_conn;
2153 f_init();
2154 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "default-route");
2155 vc_conn := f_start_handler(refers(f_tc_smpp_mo_sms), 44);
2156 vc_conn.done;
2157 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "no default-route");
2158}
2159
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002160/* Test MO-SMS from MS/BTS/BSC towards HLR (via GSUP) */
2161private function f_tc_gsup_mo_sms(charstring id, BSC_ConnHdlrPars pars)
2162runs on BSC_ConnHdlr {
2163 var SmsParameters spars := valueof(t_SmsPars);
2164 var GSUP_PDU gsup_msg_rx;
2165 var octetstring sm_tpdu;
2166
2167 f_init_handler(pars);
2168
2169 /* We need to inspect GSUP activity */
2170 f_create_gsup_expect(hex2str(g_pars.imsi));
2171
2172 /* Perform location update */
2173 f_perform_lu();
2174
2175 /* Send CM Service Request for SMS */
2176 f_establish_fully(EST_TYPE_MO_SMS);
2177
2178 /* Prepare expected SM-RP-UI (SM TPDU) */
2179 enc_TPDU_RP_DATA_MS_SGSN_fast(
2180 valueof(ts_SMS_SUBMIT(spars.tp.msg_ref,
2181 spars.tp.da, spars.tp.pid, spars.tp.dcs,
2182 spars.tp.udl, spars.tp.ud)),
2183 sm_tpdu);
2184
2185 var template GSUP_PDU mo_forwardSM := tr_GSUP_MO_FORWARD_SM_REQ(
2186 imsi := g_pars.imsi,
2187 sm_rp_mr := spars.rp.msg_ref,
2188 /* FIXME: extract SM-RP-DA from spars.rp.dest */
2189 sm_rp_da := tr_GSUP_SM_RP_DA_SMSC_ADDR(?),
2190 /* FIXME: MSISDN coding troubles */
2191 sm_rp_oa := tr_GSUP_SM_RP_OA_MSISDN(?),
2192 /* TODO: can we use decmatch here? */
2193 sm_rp_ui := sm_tpdu
2194 );
2195
2196 /* Submit an SMS on DTAP and expect MO-forwardSM-Req on GSUP */
2197 f_mo_sms_submit(spars);
2198 alt {
2199 [] GSUP.receive(mo_forwardSM) -> value gsup_msg_rx {
2200 log("RX MO-forwardSM-Req");
2201 log(gsup_msg_rx);
2202 setverdict(pass);
2203 }
2204 [] GSUP.receive {
2205 log("RX unexpected GSUP message");
2206 setverdict(fail);
2207 mtc.stop;
2208 }
2209 }
2210
2211 /* Trigger RP-ACK by sending MO-forwardSM-Res */
2212 GSUP.send(valueof(ts_GSUP_MO_FORWARD_SM_RES(
2213 imsi := g_pars.imsi,
2214 sm_rp_mr := spars.rp.msg_ref)));
2215 /* Expect RP-ACK on DTAP */
2216 f_mo_sms_wait_rp_ack(spars);
2217
2218 f_expect_clear();
2219}
2220testcase TC_gsup_mo_sms() runs on MTC_CT {
2221 var BSC_ConnHdlr vc_conn;
2222 f_init();
2223 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2224 vc_conn := f_start_handler(refers(f_tc_gsup_mo_sms), 88);
2225 vc_conn.done;
2226 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2227}
2228
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07002229/* Test MO-SMMA from MS/BTS/BSC towards HLR (via GSUP) */
2230private function f_tc_gsup_mo_smma(charstring id, BSC_ConnHdlrPars pars)
2231runs on BSC_ConnHdlr {
2232 var SmsParameters spars := valueof(t_SmsPars);
2233 var GSUP_PDU gsup_msg_rx;
2234
2235 f_init_handler(pars);
2236
2237 /* We need to inspect GSUP activity */
2238 f_create_gsup_expect(hex2str(g_pars.imsi));
2239
2240 /* Perform location update */
2241 f_perform_lu();
2242
2243 /* Send CM Service Request for SMS */
2244 f_establish_fully(EST_TYPE_MO_SMS);
2245
2246 var template GSUP_PDU mo_ReadyForSM := tr_GSUP_MO_READY_FOR_SM_REQ(
2247 imsi := g_pars.imsi,
2248 sm_rp_mr := spars.rp.msg_ref,
2249 sm_alert_rsn := GSUP_SM_ALERT_RSN_TYPE_MEM_AVAIL
2250 );
2251
2252 /* Submit an SMS on DTAP and expect MO-forwardSM-Req on GSUP */
2253 f_mo_smma(spars);
2254 alt {
2255 [] GSUP.receive(mo_ReadyForSM) -> value gsup_msg_rx {
2256 log("RX MO-ReadyForSM-Req");
2257 log(gsup_msg_rx);
2258 setverdict(pass);
2259 }
2260 [] GSUP.receive {
2261 log("RX unexpected GSUP message");
2262 setverdict(fail);
2263 mtc.stop;
2264 }
2265 }
2266
2267 /* Trigger RP-ACK by sending MO-forwardSM-Res */
2268 GSUP.send(valueof(ts_GSUP_MO_READY_FOR_SM_RES(
2269 imsi := g_pars.imsi,
2270 sm_rp_mr := spars.rp.msg_ref)));
2271 /* Expect RP-ACK on DTAP */
2272 f_mo_sms_wait_rp_ack(spars);
2273
2274 f_expect_clear();
2275}
2276testcase TC_gsup_mo_smma() runs on MTC_CT {
2277 var BSC_ConnHdlr vc_conn;
2278 f_init();
2279 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2280 vc_conn := f_start_handler(refers(f_tc_gsup_mo_smma), 89);
2281 vc_conn.done;
2282 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2283}
2284
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002285/* Helper for sending MT SMS over GSUP */
2286private function f_gsup_forwardSM_req(SmsParameters spars, OCT1 mms := '00'O)
2287runs on BSC_ConnHdlr {
2288 GSUP.send(ts_GSUP_MT_FORWARD_SM_REQ(
2289 imsi := g_pars.imsi,
2290 /* NOTE: MSC should assign RP-MR itself */
2291 sm_rp_mr := 'FF'O,
2292 /* FIXME: extract SM-RP-DA from spars.rp.dest */
2293 /* TODO: fix encoding of ts_GSUP_SM_RP_DA_IMSI */
2294 sm_rp_da := valueof(ts_GSUP_SM_RP_DA_MSISDN(g_pars.msisdn)),
2295 sm_rp_oa := valueof(ts_GSUP_SM_RP_OA_SMSC_ADDR(g_pars.msisdn)),
2296 /* Encoded SMS TPDU (taken from Wireshark)
2297 * FIXME: we should encode spars somehow */
2298 sm_rp_ui := '00068021436500008111328130858200'O,
2299 sm_rp_mms := mms
2300 ));
2301}
2302
2303/* Test successful MT-SMS (RP-ACK) over GSUP */
2304private function f_tc_gsup_mt_sms_ack(charstring id, BSC_ConnHdlrPars pars)
2305runs on BSC_ConnHdlr {
2306 var SmsParameters spars := valueof(t_SmsPars);
2307
2308 f_init_handler(pars);
2309
2310 /* We need to inspect GSUP activity */
2311 f_create_gsup_expect(hex2str(g_pars.imsi));
2312
2313 /* Perform location update */
2314 f_perform_lu();
2315
2316 /* Register an 'expect' for given IMSI (+TMSI) */
2317 if (isvalue(g_pars.tmsi)) {
Harald Welte6811d102019-04-14 22:23:14 +02002318 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002319 } else {
Harald Welte6811d102019-04-14 22:23:14 +02002320 f_ran_register_imsi(g_pars.imsi, 'FFFFFFFF'O);
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002321 }
2322
2323 var template GSUP_PDU mt_forwardSM_res := tr_GSUP_MT_FORWARD_SM_RES(
2324 imsi := g_pars.imsi,
2325 /* NOTE: MSC should assign RP-MR itself */
2326 sm_rp_mr := ?
2327 );
2328
2329 /* Submit a MT SMS on GSUP */
2330 f_gsup_forwardSM_req(spars);
2331
2332 /* Expect Paging Request and Establish DTAP / BSSAP / SCCP connection */
Harald Weltee035e3e2019-04-21 17:32:05 +02002333 f_expect_paging();
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002334 f_establish_fully(EST_TYPE_PAG_RESP);
2335
2336 /* Wait for MT SMS on DTAP */
2337 f_mt_sms_expect(spars);
2338
2339 /* Send RP-ACK and expect MT-forwardSM-Res on GSUP */
2340 f_mt_sms_send_rp_ack(spars);
2341 alt {
2342 [] GSUP.receive(mt_forwardSM_res) {
2343 log("RX MT-forwardSM-Res (RP-ACK)");
2344 setverdict(pass);
2345 }
2346 [] GSUP.receive {
2347 log("RX unexpected GSUP message");
2348 setverdict(fail);
2349 mtc.stop;
2350 }
2351 }
2352
2353 f_expect_clear();
2354}
2355testcase TC_gsup_mt_sms_ack() runs on MTC_CT {
2356 var BSC_ConnHdlrPars pars;
2357 var BSC_ConnHdlr vc_conn;
2358 f_init();
2359 pars := f_init_pars(90);
2360 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2361 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_sms_ack), pars);
2362 vc_conn.done;
2363 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2364}
2365
2366/* Test rejected MT-SMS (RP-ERROR) over GSUP */
2367private function f_tc_gsup_mt_sms_err(charstring id, BSC_ConnHdlrPars pars)
2368runs on BSC_ConnHdlr {
2369 var SmsParameters spars := valueof(t_SmsPars);
2370 var OCT1 sm_rp_cause := '78'O; /* dummy RP-Cause value */
2371
2372 f_init_handler(pars);
2373
2374 /* We need to inspect GSUP activity */
2375 f_create_gsup_expect(hex2str(g_pars.imsi));
2376
2377 /* Perform location update */
2378 f_perform_lu();
2379
2380 /* Register an 'expect' for given IMSI (+TMSI) */
2381 if (isvalue(g_pars.tmsi)) {
Harald Welte6811d102019-04-14 22:23:14 +02002382 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002383 } else {
Harald Welte6811d102019-04-14 22:23:14 +02002384 f_ran_register_imsi(g_pars.imsi, 'FFFFFFFF'O);
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002385 }
2386
2387 var template GSUP_PDU mt_forwardSM_err := tr_GSUP_MT_FORWARD_SM_ERR(
2388 imsi := g_pars.imsi,
2389 /* NOTE: MSC should assign RP-MR itself */
2390 sm_rp_mr := ?,
2391 sm_rp_cause := sm_rp_cause
2392 );
2393
2394 /* Submit a MT SMS on GSUP */
2395 f_gsup_forwardSM_req(spars);
2396
2397 /* Expect Paging Request and Establish DTAP / BSSAP / SCCP connection */
Harald Weltee035e3e2019-04-21 17:32:05 +02002398 f_expect_paging();
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07002399 f_establish_fully(EST_TYPE_PAG_RESP);
2400
2401 /* Wait for MT SMS on DTAP */
2402 f_mt_sms_expect(spars);
2403
2404 /* Send RP-ERROR and expect MT-forwardSM-Err on GSUP */
2405 f_mt_sms_send_rp_error(spars, oct2int(sm_rp_cause));
2406 alt {
2407 [] GSUP.receive(mt_forwardSM_err) {
2408 log("RX MT-forwardSM-Err (RP-ERROR)");
2409 setverdict(pass);
2410 mtc.stop;
2411 }
2412 [] GSUP.receive {
2413 log("RX unexpected GSUP message");
2414 setverdict(fail);
2415 mtc.stop;
2416 }
2417 }
2418
2419 f_expect_clear();
2420}
2421testcase TC_gsup_mt_sms_err() runs on MTC_CT {
2422 var BSC_ConnHdlrPars pars;
2423 var BSC_ConnHdlr vc_conn;
2424 f_init();
2425 pars := f_init_pars(91);
2426 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2427 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_sms_err), pars);
2428 vc_conn.done;
2429 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2430}
2431
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002432/* Test SM-RP-MR assignment for MT-SMS over GSUP */
2433private function f_tc_gsup_mt_sms_rp_mr(charstring id, BSC_ConnHdlrPars pars)
2434runs on BSC_ConnHdlr {
2435 var SmsParameters spars1 := valueof(t_SmsPars); /* 1st SMS */
2436 var SmsParameters spars2 := valueof(t_SmsPars); /* 2nd SMS */
2437
2438 f_init_handler(pars);
2439
2440 /* We need to inspect GSUP activity */
2441 f_create_gsup_expect(hex2str(g_pars.imsi));
2442
2443 /* Perform location update */
2444 f_perform_lu();
2445
2446 /* Register an 'expect' for given IMSI (+TMSI) */
2447 if (isvalue(g_pars.tmsi)) {
Harald Welte6811d102019-04-14 22:23:14 +02002448 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002449 } else {
Harald Welte6811d102019-04-14 22:23:14 +02002450 f_ran_register_imsi(g_pars.imsi, 'FFFFFFFF'O);
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002451 }
2452
2453 /* Submit the 1st MT SMS on GSUP */
2454 log("TX MT-forwardSM-Req for the 1st SMS");
2455 f_gsup_forwardSM_req(spars1);
2456
2457 /* Expect Paging Request and Establish DTAP / BSSAP / SCCP connection */
Harald Weltee035e3e2019-04-21 17:32:05 +02002458 f_expect_paging();
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07002459 f_establish_fully(EST_TYPE_PAG_RESP);
2460
2461 /* Wait for 1st MT SMS on DTAP */
2462 f_mt_sms_expect(spars1);
2463 log("RX the 1st SMS on DTAP, DTAP TID is ", spars1.tid,
2464 ", SM-RP-MR is ", spars1.rp.msg_ref);
2465
2466 /* Submit the 2nd MT SMS on GSUP */
2467 log("TX MT-forwardSM-Req for the 2nd SMS");
2468 f_gsup_forwardSM_req(spars2);
2469
2470 /* Wait for 2nd MT SMS on DTAP */
2471 f_mt_sms_expect(spars2);
2472 log("RX the 2nd SMS on DTAP, DTAP TID is ", spars2.tid,
2473 ", SM-RP-MR is ", spars2.rp.msg_ref);
2474
2475 /* Both transaction IDs shall be different */
2476 if (spars1.tid == spars2.tid) {
2477 log("Both DTAP transaction IDs shall be different");
2478 setverdict(fail);
2479 }
2480
2481 /* Both SM-RP-MR values shall be different */
2482 if (spars1.rp.msg_ref == spars2.rp.msg_ref) {
2483 log("Both SM-RP-MR values shall be different");
2484 setverdict(fail);
2485 }
2486
2487 /* Both SM-RP-MR values shall be assigned */
2488 if (spars1.rp.msg_ref == 'FF'O) {
2489 log("Unassigned SM-RP-MR value for the 1st SMS");
2490 setverdict(fail);
2491 }
2492 if (spars2.rp.msg_ref == 'FF'O) {
2493 log("Unassigned SM-RP-MR value for the 2nd SMS");
2494 setverdict(fail);
2495 }
2496
2497 /* Send the 1st RP-ACK and expect MT-forwardSM-Res on GSUP */
2498 f_mt_sms_send_rp_ack(spars1);
2499 alt {
2500 [] GSUP.receive(tr_GSUP_MT_FORWARD_SM_RES(
2501 imsi := g_pars.imsi,
2502 sm_rp_mr := spars1.rp.msg_ref
2503 )) {
2504 log("RX MT-forwardSM-Res (RP-ACK)");
2505 setverdict(pass);
2506 }
2507 [] GSUP.receive {
2508 log("RX unexpected GSUP message");
2509 setverdict(fail);
2510 mtc.stop;
2511 }
2512 }
2513
2514 /* Send the 2nd RP-ACK and expect MT-forwardSM-Res on GSUP */
2515 f_mt_sms_send_rp_ack(spars2);
2516 alt {
2517 [] GSUP.receive(tr_GSUP_MT_FORWARD_SM_RES(
2518 imsi := g_pars.imsi,
2519 sm_rp_mr := spars2.rp.msg_ref
2520 )) {
2521 log("RX MT-forwardSM-Res (RP-ACK)");
2522 setverdict(pass);
2523 }
2524 [] GSUP.receive {
2525 log("RX unexpected GSUP message");
2526 setverdict(fail);
2527 mtc.stop;
2528 }
2529 }
2530
2531 f_expect_clear();
2532}
2533testcase TC_gsup_mt_sms_rp_mr() runs on MTC_CT {
2534 var BSC_ConnHdlrPars pars;
2535 var BSC_ConnHdlr vc_conn;
2536 f_init();
2537 pars := f_init_pars(92);
2538 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2539 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_sms_rp_mr), pars);
2540 vc_conn.done;
2541 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2542}
2543
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07002544/* Test SM-RP-MR assignment for MT-SMS over GSUP */
2545private function f_tc_gsup_mo_mt_sms_rp_mr(charstring id, BSC_ConnHdlrPars pars)
2546runs on BSC_ConnHdlr {
2547 var SmsParameters spars_mo := valueof(t_SmsPars); /* MO SMMA */
2548 var SmsParameters spars_mt := valueof(t_SmsPars); /* MT SMS */
2549
2550 f_init_handler(pars);
2551
2552 /* We need to inspect GSUP activity */
2553 f_create_gsup_expect(hex2str(g_pars.imsi));
2554
2555 /* Perform location update */
2556 f_perform_lu();
2557
2558 /* Register an 'expect' for given IMSI (+TMSI) */
2559 if (isvalue(g_pars.tmsi)) {
Harald Welte6811d102019-04-14 22:23:14 +02002560 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07002561 } else {
Harald Welte6811d102019-04-14 22:23:14 +02002562 f_ran_register_imsi(g_pars.imsi, 'FFFFFFFF'O);
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07002563 }
2564
2565 /* Send CM Service Request for MO SMMA */
2566 f_establish_fully(EST_TYPE_MO_SMS);
2567
2568 /* Submit MO SMMA on DTAP */
2569 log("Submit MO SMMA on DTAP, SM-RP-MR is '00'O");
2570 spars_mo.rp.msg_ref := '00'O;
2571 f_mo_smma(spars_mo);
2572
2573 /* Expect MO-forwardSM-Req for MO SMMA on GSUP */
2574 alt {
2575 [] GSUP.receive(tr_GSUP_MO_READY_FOR_SM_REQ(
2576 imsi := g_pars.imsi,
2577 sm_rp_mr := spars_mo.rp.msg_ref,
2578 sm_alert_rsn := GSUP_SM_ALERT_RSN_TYPE_MEM_AVAIL
2579 )) {
2580 log("RX MO-ReadyForSM-Req, SM-RP-MR is '00'O");
2581 setverdict(pass);
2582 }
2583 [] GSUP.receive {
2584 log("RX unexpected GSUP message");
2585 setverdict(fail);
2586 mtc.stop;
2587 }
2588 }
2589
2590 /* Submit MT SMS on GSUP */
2591 log("TX MT-forwardSM-Req for the MT SMS");
2592 f_gsup_forwardSM_req(spars_mt);
2593
2594 /* Wait for MT SMS on DTAP */
2595 f_mt_sms_expect(spars_mt);
2596 log("RX MT SMS on DTAP, DTAP TID is ", spars_mt.tid,
2597 ", SM-RP-MR is ", spars_mt.rp.msg_ref);
2598
2599 /* Both SM-RP-MR values shall be different */
2600 if (spars_mo.rp.msg_ref == spars_mt.rp.msg_ref) {
2601 log("Both SM-RP-MR values shall be different");
2602 setverdict(fail);
2603 }
2604
2605 /* SM-RP-MR value for MT SMS shall be assigned */
2606 if (spars_mt.rp.msg_ref == 'FF'O) {
2607 log("Unassigned SM-RP-MR value for the MT SMS");
2608 setverdict(fail);
2609 }
2610
2611 /* Trigger RP-ACK for MO SMMA by sending MO-forwardSM-Res */
2612 GSUP.send(valueof(ts_GSUP_MO_READY_FOR_SM_RES(
2613 imsi := g_pars.imsi,
2614 sm_rp_mr := spars_mo.rp.msg_ref)));
2615 /* Expect RP-ACK for MO SMMA on DTAP */
2616 f_mo_sms_wait_rp_ack(spars_mo);
2617
2618 /* Send RP-ACK for MT SMS and expect MT-forwardSM-Res on GSUP */
2619 f_mt_sms_send_rp_ack(spars_mt);
2620 alt {
2621 [] GSUP.receive(tr_GSUP_MT_FORWARD_SM_RES(
2622 imsi := g_pars.imsi,
2623 sm_rp_mr := spars_mt.rp.msg_ref
2624 )) {
2625 log("RX MT-forwardSM-Res (RP-ACK)");
2626 setverdict(pass);
2627 }
2628 [] GSUP.receive {
2629 log("RX unexpected GSUP message");
2630 setverdict(fail);
2631 mtc.stop;
2632 }
2633 }
2634
2635 f_expect_clear();
2636}
2637testcase TC_gsup_mo_mt_sms_rp_mr() runs on MTC_CT {
2638 var BSC_ConnHdlrPars pars;
2639 var BSC_ConnHdlr vc_conn;
2640 f_init();
2641 pars := f_init_pars(93);
2642 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2643 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mo_mt_sms_rp_mr), pars);
2644 vc_conn.done;
2645 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2646}
2647
Vadim Yanitskiy1cd11a02018-12-03 02:43:35 +07002648/* Test multi-part MT-SMS over GSUP */
2649private function f_tc_gsup_mt_multi_part_sms(charstring id, BSC_ConnHdlrPars pars)
2650runs on BSC_ConnHdlr {
2651 var SmsParameters spars := valueof(t_SmsPars);
2652
2653 f_init_handler(pars);
2654
2655 /* We need to inspect GSUP activity */
2656 f_create_gsup_expect(hex2str(g_pars.imsi));
2657
2658 /* Perform location update */
2659 f_perform_lu();
2660
2661 /* Register an 'expect' for given IMSI (+TMSI) */
2662 if (isvalue(g_pars.tmsi)) {
Harald Welte6811d102019-04-14 22:23:14 +02002663 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy1cd11a02018-12-03 02:43:35 +07002664 } else {
Harald Welte6811d102019-04-14 22:23:14 +02002665 f_ran_register_imsi(g_pars.imsi, 'FFFFFFFF'O);
Vadim Yanitskiy1cd11a02018-12-03 02:43:35 +07002666 }
2667
2668 var template GSUP_PDU mt_forwardSM_res := tr_GSUP_MT_FORWARD_SM_RES(
2669 imsi := g_pars.imsi,
2670 /* NOTE: MSC should assign RP-MR itself */
2671 sm_rp_mr := ?
2672 );
2673
2674 /* Send 4 messages (NOTE: SM-RP-UI remains unchanged) */
2675 for (var integer i := 3; i >= 0; i := i-1) {
2676 /* Submit a MT SMS on GSUP (MMS is decremented) */
2677 f_gsup_forwardSM_req(spars, int2oct(i, 1));
2678
2679 /* Expect Paging Request and Establish connection */
2680 if (i == 3) { /* ... only once! */
2681 BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));
2682 f_establish_fully(EST_TYPE_PAG_RESP);
2683 }
2684
2685 /* Wait for MT SMS on DTAP */
2686 f_mt_sms_expect(spars);
2687
2688 /* Send RP-ACK and expect MT-forwardSM-Res on GSUP */
2689 f_mt_sms_send_rp_ack(spars);
2690 alt {
2691 [] GSUP.receive(mt_forwardSM_res) {
2692 log("RX MT-forwardSM-Res (RP-ACK)");
2693 setverdict(pass);
2694 }
2695 [] GSUP.receive {
2696 log("RX unexpected GSUP message");
2697 setverdict(fail);
2698 mtc.stop;
2699 }
2700 }
2701
2702 /* Keep some 'distance' between transmissions */
2703 f_sleep(1.5);
2704 }
2705
2706 f_expect_clear();
2707}
2708testcase TC_gsup_mt_multi_part_sms() runs on MTC_CT {
2709 var BSC_ConnHdlrPars pars;
2710 var BSC_ConnHdlr vc_conn;
2711 f_init();
2712 pars := f_init_pars(91);
2713 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2714 vc_conn := f_start_handler_with_pars(refers(f_tc_gsup_mt_multi_part_sms), pars);
2715 vc_conn.done;
2716 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2717}
2718
Harald Weltef640a012018-04-14 17:49:21 +02002719/* convert GSM L3 TON to SMPP_TON enum */
2720function f_sm_ton_from_gsm(BIT3 ton) return SMPP_TON {
2721 select (ton) {
2722 case ('000'B) { return unknown; }
2723 case ('001'B) { return international; }
2724 case ('010'B) { return national; }
2725 case ('011'B) { return network_specific; }
2726 case ('100'B) { return subscriber_number; }
2727 case ('101'B) { return alphanumeric; }
2728 case ('110'B) { return abbreviated; }
2729 }
2730 setverdict(fail, "Unknown TON ", ton);
Daniel Willmannafce8662018-07-06 23:11:32 +02002731 mtc.stop;
Harald Weltef640a012018-04-14 17:49:21 +02002732}
2733/* convert GSM L3 NPI to SMPP_NPI enum */
2734function f_sm_npi_from_gsm(BIT4 npi) return SMPP_NPI {
2735 select (npi) {
2736 case ('0000'B) { return unknown; }
2737 case ('0001'B) { return isdn; }
2738 case ('0011'B) { return data; }
2739 case ('0100'B) { return telex; }
2740 case ('0110'B) { return land_mobile; }
2741 case ('1000'B) { return national; }
2742 case ('1001'B) { return private_; }
2743 case ('1010'B) { return ermes; }
2744 }
2745 setverdict(fail, "Unknown NPI ", npi);
Daniel Willmannafce8662018-07-06 23:11:32 +02002746 mtc.stop;
Harald Weltef640a012018-04-14 17:49:21 +02002747}
2748
2749/* build a SMPP_SM from SmsParameters */
2750function f_mt_sm_from_spars(SmsParameters spars)
2751runs on BSC_ConnHdlr return SMPP_SM {
2752 var SMPP_SM sm := {
2753 service_type := "CMT",
2754 source_addr_ton := f_sm_ton_from_gsm(spars.tp.da.tP_DA_NoPad.tP_TypeOfNumber),
2755 source_addr_npi := f_sm_npi_from_gsm(spars.tp.da.tP_DA_NoPad.tP_NumberingPlanID),
2756 source_addr := hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue),
2757 dest_addr_ton := international,
2758 dest_addr_npi := isdn,
2759 destination_addr := hex2str(g_pars.msisdn),
2760 esm_class := '00000001'B,
2761 protocol_id := 0,
2762 priority_flag := 0,
2763 schedule_delivery_time := "",
2764 validity_period := "",
2765 registered_delivery := '00000000'B,
2766 replace_if_present := 0,
2767 data_coding := '00000001'B,
2768 sm_default_msg_id := 0,
2769 sm_length := spars.tp.udl,
2770 short_message := spars.tp.ud,
2771 opt_pars := {}
2772 };
2773 return sm;
2774}
2775
2776/* helper function to encode SMS from 'spars', send it via SMPP to MSC; receive it on MS side */
2777private function f_smpp_mt_sms(SmsParameters spars, boolean trans_mode) runs on BSC_ConnHdlr {
2778 var SMPP_SM sm := f_mt_sm_from_spars(spars);
2779 if (trans_mode) {
2780 sm.esm_class := '00000010'B;
2781 }
2782
2783 /* actually cause MSC to send a SMS via SUBMIT-SM from SMPP side */
2784 SMPP.send(ts_SMPP_SUBMIT_SM(sm));
2785 if (not match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
2786 /* if we're not in SMPP transaction mode, we expect the SMPP-level ACK
2787 * before we expect the SMS delivery on the BSC/radio side */
2788 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
2789 }
2790
2791 /* MSC->BSC: expect PAGING from MSC */
Harald Weltee035e3e2019-04-21 17:32:05 +02002792 f_expect_paging();
Harald Weltef640a012018-04-14 17:49:21 +02002793 /* Establish DTAP / BSSAP / SCCP connection */
2794 f_establish_fully(EST_TYPE_PAG_RESP);
2795 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
2796
2797 f_mt_sms(spars);
2798
2799 if (match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
2800 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
2801 }
2802 f_expect_clear();
2803}
2804
2805/* mobile terminated SMS, from SMPP to BSC/BTS/MS */
2806private function f_tc_smpp_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2807 f_init_handler(pars);
2808
2809 /* Perform location update so IMSI is known + registered in MSC/VLR */
2810 f_perform_lu();
2811 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
2812
2813 /* register an 'expect' for given IMSI (+TMSI) */
2814 var OCT4 tmsi;
2815 if (isvalue(g_pars.tmsi)) {
2816 tmsi := g_pars.tmsi;
2817 } else {
2818 tmsi := 'FFFFFFFF'O;
2819 }
Harald Welte6811d102019-04-14 22:23:14 +02002820 f_ran_register_imsi(g_pars.imsi, tmsi);
Harald Weltef640a012018-04-14 17:49:21 +02002821
2822 var SmsParameters spars := valueof(t_SmsPars);
2823 /* TODO: test with more intelligent user data; test different coding schemes */
2824 spars.tp.ud := '00'O;
2825 spars.tp.udl := 1;
2826
2827 /* first test the non-transaction store+forward mode */
2828 f_smpp_mt_sms(spars, false);
2829
2830 /* then test the transaction mode */
2831 f_smpp_mt_sms(spars, true);
2832}
2833testcase TC_smpp_mt_sms() runs on MTC_CT {
2834 var BSC_ConnHdlr vc_conn;
2835 f_init();
2836 vc_conn := f_start_handler(refers(f_tc_smpp_mt_sms), 45);
2837 vc_conn.done;
2838}
2839
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002840/***********************************************************************
2841 * USSD Testing
2842 ***********************************************************************/
2843
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07002844private altstep as_unexp_gsup_or_bssap_msg()
2845runs on BSC_ConnHdlr {
2846 [] GSUP.receive {
2847 setverdict(fail, "Unknown/unexpected GSUP received");
2848 self.stop;
2849 }
2850 [] BSSAP.receive {
2851 setverdict(fail, "Unknown/unexpected BSSAP message received");
2852 self.stop;
2853 }
2854}
2855
2856private function f_expect_gsup_msg(template GSUP_PDU msg)
2857runs on BSC_ConnHdlr return GSUP_PDU {
2858 var GSUP_PDU gsup_msg_complete;
2859
2860 alt {
2861 [] GSUP.receive(msg) -> value gsup_msg_complete {
2862 setverdict(pass);
2863 }
2864 /* We don't expect anything else */
2865 [] as_unexp_gsup_or_bssap_msg();
2866 }
2867
2868 return gsup_msg_complete;
2869}
2870
2871private function f_expect_mt_dtap_msg(template PDU_ML3_NW_MS msg)
2872runs on BSC_ConnHdlr return PDU_ML3_NW_MS {
2873 var PDU_DTAP_MT bssap_msg_complete;
2874
2875 alt {
2876 [] BSSAP.receive(tr_PDU_DTAP_MT(msg)) -> value bssap_msg_complete {
2877 setverdict(pass);
2878 }
2879 /* We don't expect anything else */
2880 [] as_unexp_gsup_or_bssap_msg();
2881 }
2882
2883 return bssap_msg_complete.dtap;
2884}
2885
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002886/* LU followed by MO USSD request */
2887private function f_tc_lu_and_mo_ussd_single_request(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002888runs on BSC_ConnHdlr {
2889 f_init_handler(pars);
2890
2891 /* Perform location update */
2892 f_perform_lu();
2893
2894 /* Send CM Service Request for SS/USSD */
2895 f_establish_fully(EST_TYPE_SS_ACT);
2896
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002897 /* We need to inspect GSUP activity */
2898 f_create_gsup_expect(hex2str(g_pars.imsi));
2899
2900 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
2901 invoke_id := 5, /* Phone may not start from 0 or 1 */
2902 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2903 ussd_string := "*#100#"
2904 );
2905
2906 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
2907 invoke_id := 5, /* InvokeID shall be the same for both REQ and RSP */
2908 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2909 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
2910 )
2911
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002912 /* Compose a new SS/REGISTER message with request */
2913 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
2914 tid := 1, /* We just need a single transaction */
2915 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002916 facility := valueof(facility_req)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002917 );
2918
2919 /* Compose SS/RELEASE_COMPLETE template with expected response */
2920 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
2921 tid := 1, /* Response should arrive within the same transaction */
2922 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002923 facility := valueof(facility_rsp)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002924 );
2925
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002926 /* Compose expected MSC -> HLR message */
2927 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
2928 imsi := g_pars.imsi,
2929 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2930 ss := valueof(facility_req)
2931 );
2932
2933 /* To be used for sending response with correct session ID */
2934 var GSUP_PDU gsup_req_complete;
2935
2936 /* Request own number */
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002937 BSSAP.send(ts_PDU_DTAP_MO(ussd_req));
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002938 /* Expect GSUP message containing the SS payload */
2939 gsup_req_complete := f_expect_gsup_msg(gsup_req);
2940
2941 /* Compose the response from HLR using received session ID */
2942 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
2943 imsi := g_pars.imsi,
2944 sid := gsup_req_complete.ies[1].val.session_id,
2945 state := OSMO_GSUP_SESSION_STATE_END,
2946 ss := valueof(facility_rsp)
2947 );
2948
2949 /* Finally, HLR terminates the session */
2950 GSUP.send(gsup_rsp);
2951 /* Expect RELEASE_COMPLETE message with the response */
2952 f_expect_mt_dtap_msg(ussd_rsp);
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002953
2954 f_expect_clear();
2955}
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002956testcase TC_lu_and_mo_ussd_single_request() runs on MTC_CT {
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002957 var BSC_ConnHdlr vc_conn;
2958 f_init();
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002959 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_single_request), 46);
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002960 vc_conn.done;
2961}
2962
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07002963/* LU followed by MT USSD notification */
2964private function f_tc_lu_and_mt_ussd_notification(charstring id, BSC_ConnHdlrPars pars)
2965runs on BSC_ConnHdlr {
2966 f_init_handler(pars);
2967
2968 /* Perform location update */
2969 f_perform_lu();
2970
Harald Welte6811d102019-04-14 22:23:14 +02002971 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07002972
2973 /* We need to inspect GSUP activity */
2974 f_create_gsup_expect(hex2str(g_pars.imsi));
2975
2976 /* Facility IE with network-originated USSD notification */
2977 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
2978 op_code := SS_OP_CODE_USS_NOTIFY,
2979 ussd_string := "Mahlzeit!"
2980 );
2981
2982 /* Facility IE with acknowledgment to the USSD notification */
2983 var template OCTN facility_rsp := enc_SS_FacilityInformation(
2984 /* In case of USSD notification, Return Result is empty */
2985 valueof(ts_SS_USSD_FACILITY_RETURN_RESULT_EMPTY())
2986 );
2987
2988 /* Compose a new MT SS/REGISTER message with USSD notification */
2989 var template PDU_ML3_NW_MS ussd_ntf := tr_ML3_MT_SS_REGISTER(
2990 tid := 0, /* FIXME: most likely, it should be 0 */
2991 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2992 facility := valueof(facility_req)
2993 );
2994
2995 /* Compose HLR -> MSC GSUP message */
2996 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
2997 imsi := g_pars.imsi,
2998 sid := '20000101'O,
2999 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3000 ss := valueof(facility_req)
3001 );
3002
3003 /* Send it to MSC and expect Paging Request */
3004 GSUP.send(gsup_req);
3005 alt {
3006 [] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
3007 setverdict(pass);
3008 }
3009 /* We don't expect anything else */
3010 [] as_unexp_gsup_or_bssap_msg();
3011 }
3012
3013 /* Send Paging Response and expect USSD notification */
3014 f_establish_fully(EST_TYPE_PAG_RESP);
3015 /* Expect MT REGISTER message with USSD notification */
3016 f_expect_mt_dtap_msg(ussd_ntf);
3017
3018 /* Compose a new MO SS/FACILITY message with empty response */
3019 var template (value) PDU_ML3_MS_NW ussd_rsp := ts_ML3_MO_SS_FACILITY(
3020 tid := 0, /* FIXME: it shall match the request tid */
3021 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3022 facility := valueof(facility_rsp)
3023 );
3024
3025 /* Compose expected MSC -> HLR GSUP message */
3026 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_REQ(
3027 imsi := g_pars.imsi,
3028 sid := '20000101'O,
3029 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
3030 ss := valueof(facility_rsp)
3031 );
3032
3033 /* MS sends response to the notification */
3034 BSSAP.send(ts_PDU_DTAP_MO(ussd_rsp));
3035 /* Expect GSUP message containing the SS payload */
3036 f_expect_gsup_msg(gsup_rsp);
3037
3038 /* Compose expected MT SS/RELEASE COMPLETE message */
3039 var template PDU_ML3_NW_MS ussd_term := tr_ML3_MT_SS_RELEASE_COMPLETE(
3040 tid := 0, /* FIXME: it shall match the request tid */
3041 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3042 facility := omit
3043 );
3044
3045 /* Compose MSC -> HLR GSUP message */
3046 var template GSUP_PDU gsup_term := ts_GSUP_PROC_SS_REQ(
3047 imsi := g_pars.imsi,
3048 sid := '20000101'O,
3049 state := OSMO_GSUP_SESSION_STATE_END
3050 );
3051
3052 /* Finally, HLR terminates the session */
3053 GSUP.send(gsup_term)
3054 /* Expect MT RELEASE COMPLETE without Facility IE */
3055 f_expect_mt_dtap_msg(ussd_term);
3056
3057 f_expect_clear();
3058}
3059testcase TC_lu_and_mt_ussd_notification() runs on MTC_CT {
3060 var BSC_ConnHdlr vc_conn;
3061 f_init();
3062 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_ussd_notification), 47);
3063 vc_conn.done;
3064}
3065
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003066/* LU followed by MT call and MO USSD request during this call */
3067private function f_tc_lu_and_mo_ussd_during_mt_call(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003068runs on BSC_ConnHdlr {
3069 f_init_handler(pars);
3070
3071 /* Call parameters taken from f_tc_lu_and_mt_call */
3072 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
3073 cpars.mgcp_connection_id_bss := '10004'H;
3074 cpars.mgcp_connection_id_mss := '10005'H;
3075 cpars.mgcp_ep := "rtpbridge/1@mgw";
3076 cpars.bss_rtp_port := 1110;
3077
3078 /* Perform location update */
3079 f_perform_lu();
3080
3081 /* Establish a MT call */
3082 f_mt_call_establish(cpars);
3083
3084 /* Hold the call for some time */
3085 f_sleep(1.0);
3086
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003087 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3088 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3089 ussd_string := "*#100#"
3090 );
3091
3092 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
3093 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3094 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
3095 )
3096
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003097 /* Compose a new SS/REGISTER message with request */
3098 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
3099 tid := 1, /* We just need a single transaction */
3100 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003101 facility := valueof(facility_req)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003102 );
3103
3104 /* Compose SS/RELEASE_COMPLETE template with expected response */
3105 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
3106 tid := 1, /* Response should arrive within the same transaction */
3107 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003108 facility := valueof(facility_rsp)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003109 );
3110
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003111 /* Compose expected MSC -> HLR message */
3112 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
3113 imsi := g_pars.imsi,
3114 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3115 ss := valueof(facility_req)
3116 );
3117
3118 /* To be used for sending response with correct session ID */
3119 var GSUP_PDU gsup_req_complete;
3120
3121 /* Request own number */
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003122 BSSAP.send(ts_PDU_DTAP_MO(ussd_req));
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07003123 /* Expect GSUP message containing the SS payload */
3124 gsup_req_complete := f_expect_gsup_msg(gsup_req);
3125
3126 /* Compose the response from HLR using received session ID */
3127 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
3128 imsi := g_pars.imsi,
3129 sid := gsup_req_complete.ies[1].val.session_id,
3130 state := OSMO_GSUP_SESSION_STATE_END,
3131 ss := valueof(facility_rsp)
3132 );
3133
3134 /* Finally, HLR terminates the session */
3135 GSUP.send(gsup_rsp);
3136 /* Expect RELEASE_COMPLETE message with the response */
3137 f_expect_mt_dtap_msg(ussd_rsp);
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003138
3139 /* Hold the call for some time */
3140 f_sleep(1.0);
3141
3142 /* Release the call (does Clear Complete itself) */
3143 f_call_hangup(cpars, true);
3144}
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003145testcase TC_lu_and_mo_ussd_during_mt_call() runs on MTC_CT {
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003146 var BSC_ConnHdlr vc_conn;
3147 f_init();
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003148 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_during_mt_call), 48);
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07003149 vc_conn.done;
3150}
3151
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003152/* BSSMAP Clear Request in the middle of a call, see OS#3062 */
3153private function f_tc_mo_cc_bssmap_clear(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
3154 f_init_handler(pars);
3155 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
3156 var MNCC_PDU mncc;
3157 var MgcpCommand mgcp_cmd;
3158
3159 f_perform_lu();
3160
3161 f_establish_fully();
3162 f_create_mncc_expect(hex2str(cpars.called_party));
3163 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
3164
3165 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
3166 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
3167 cpars.mncc_callref := mncc.u.signal.callref;
3168 log("mncc_callref=", cpars.mncc_callref);
3169 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
3170 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
3171
3172 MNCC.send(ts_MNCC_ALERT_req(cpars.mncc_callref));
3173 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(cpars.transaction_id)));
3174 MGCP.receive(tr_CRCX);
3175
3176 f_sleep(1.0);
3177 BSSAP.send(ts_BSSMAP_ClearRequest(0));
3178
Neels Hofmeyrde76f052019-02-26 05:02:46 +01003179 var default ccrel := activate(as_optional_cc_rel(cpars));
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003180
Neels Hofmeyrde76f052019-02-26 05:02:46 +01003181 interleave {
3182 [] MNCC.receive(tr_MNCC_REL_ind(?, ?)) { };
3183 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
3184 BSSAP.send(ts_BSSMAP_ClearComplete);
3185 };
3186 }
3187
3188 deactivate(ccrel);
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003189
3190 f_sleep(1.0);
3191}
3192testcase TC_mo_cc_bssmap_clear() runs on MTC_CT {
3193 var BSC_ConnHdlr vc_conn;
3194 f_init();
3195
3196 vc_conn := f_start_handler(refers(f_tc_mo_cc_bssmap_clear), 43);
3197 vc_conn.done;
3198}
3199
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003200/* LU followed by MT call and MT USSD request during this call */
3201private function f_tc_lu_and_mt_ussd_during_mt_call(charstring id, BSC_ConnHdlrPars pars)
3202runs on BSC_ConnHdlr {
3203 f_init_handler(pars);
3204
3205 /* Call parameters taken from f_tc_lu_and_mt_call */
3206 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
3207 cpars.mgcp_connection_id_bss := '10004'H;
3208 cpars.mgcp_connection_id_mss := '10005'H;
3209 cpars.mgcp_ep := "rtpbridge/1@mgw";
3210 cpars.bss_rtp_port := 1110;
3211
3212 /* Perform location update */
3213 f_perform_lu();
3214
3215 /* Establish a MT call */
3216 f_mt_call_establish(cpars);
3217
3218 /* Hold the call for some time */
3219 f_sleep(1.0);
3220
3221 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
3222 op_code := SS_OP_CODE_USS_REQUEST,
3223 ussd_string := "Please type anything..."
3224 );
3225
3226 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
3227 op_code := SS_OP_CODE_USS_REQUEST,
3228 ussd_string := "Nope."
3229 )
3230
3231 /* Compose MT SS/REGISTER message with network-originated request */
3232 var template (value) PDU_ML3_NW_MS ussd_req := ts_ML3_MT_SS_REGISTER(
3233 tid := 0, /* FIXME: most likely, it should be 0 */
3234 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3235 facility := valueof(facility_req)
3236 );
3237
3238 /* Compose HLR -> MSC GSUP message */
3239 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
3240 imsi := g_pars.imsi,
3241 sid := '20000101'O,
3242 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3243 ss := valueof(facility_req)
3244 );
3245
3246 /* Send it to MSC */
3247 GSUP.send(gsup_req);
3248 /* Expect MT REGISTER message with USSD request */
3249 f_expect_mt_dtap_msg(ussd_req);
3250
3251 /* Compose a new MO SS/FACILITY message with response */
3252 var template (value) PDU_ML3_MS_NW ussd_rsp := ts_ML3_MO_SS_FACILITY(
3253 tid := 0, /* FIXME: it shall match the request tid */
3254 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3255 facility := valueof(facility_rsp)
3256 );
3257
3258 /* Compose expected MSC -> HLR GSUP message */
3259 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_REQ(
3260 imsi := g_pars.imsi,
3261 sid := '20000101'O,
3262 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
3263 ss := valueof(facility_rsp)
3264 );
3265
3266 /* MS sends response */
3267 BSSAP.send(ts_PDU_DTAP_MO(ussd_rsp));
3268 f_expect_gsup_msg(gsup_rsp);
3269
3270 /* Compose expected MT SS/RELEASE COMPLETE message */
3271 var template PDU_ML3_NW_MS ussd_term := tr_ML3_MT_SS_RELEASE_COMPLETE(
3272 tid := 0, /* FIXME: it shall match the request tid */
3273 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3274 facility := omit
3275 );
3276
3277 /* Compose MSC -> HLR GSUP message */
3278 var template GSUP_PDU gsup_term := ts_GSUP_PROC_SS_REQ(
3279 imsi := g_pars.imsi,
3280 sid := '20000101'O,
3281 state := OSMO_GSUP_SESSION_STATE_END
3282 );
3283
3284 /* Finally, HLR terminates the session */
3285 GSUP.send(gsup_term);
3286 /* Expect MT RELEASE COMPLETE without Facility IE */
3287 f_expect_mt_dtap_msg(ussd_term);
3288
3289 /* Hold the call for some time */
3290 f_sleep(1.0);
3291
3292 /* Release the call (does Clear Complete itself) */
3293 f_call_hangup(cpars, true);
3294}
3295testcase TC_lu_and_mt_ussd_during_mt_call() runs on MTC_CT {
3296 var BSC_ConnHdlr vc_conn;
3297 f_init();
3298 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_ussd_during_mt_call), 49);
3299 vc_conn.done;
3300}
3301
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07003302/* LU followed by MO USSD request and MO Release during transaction */
3303private function f_tc_lu_and_mo_ussd_mo_release(charstring id, BSC_ConnHdlrPars pars)
3304runs on BSC_ConnHdlr {
3305 f_init_handler(pars);
3306
3307 /* Perform location update */
3308 f_perform_lu();
3309
3310 /* Send CM Service Request for SS/USSD */
3311 f_establish_fully(EST_TYPE_SS_ACT);
3312
3313 /* We need to inspect GSUP activity */
3314 f_create_gsup_expect(hex2str(g_pars.imsi));
3315
3316 var template OCTN facility_ms_req := f_USSD_FACILITY_IE_INVOKE(
3317 invoke_id := 1, /* Initial request */
3318 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3319 ussd_string := "*6766*266#"
3320 );
3321
3322 var template OCTN facility_net_req := f_USSD_FACILITY_IE_INVOKE(
3323 invoke_id := 2, /* Counter request */
3324 op_code := SS_OP_CODE_USS_REQUEST,
3325 ussd_string := "Password?!?"
3326 )
3327
3328 /* Compose MO SS/REGISTER message with request */
3329 var template (value) PDU_ML3_MS_NW ussd_ms_req := ts_ML3_MO_SS_REGISTER(
3330 tid := 1, /* We just need a single transaction */
3331 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3332 facility := valueof(facility_ms_req)
3333 );
3334
3335 /* Compose expected MSC -> HLR message */
3336 var template GSUP_PDU gsup_ms_req := tr_GSUP_PROC_SS_REQ(
3337 imsi := g_pars.imsi,
3338 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3339 ss := valueof(facility_ms_req)
3340 );
3341
3342 /* To be used for sending response with correct session ID */
3343 var GSUP_PDU gsup_ms_req_complete;
3344
3345 /* Initiate a new transaction */
3346 BSSAP.send(ts_PDU_DTAP_MO(ussd_ms_req));
3347 /* Expect GSUP request with original Facility IE */
3348 gsup_ms_req_complete := f_expect_gsup_msg(gsup_ms_req);
3349
3350 /* Compose the response from HLR using received session ID */
3351 var template (value) GSUP_PDU gsup_net_req := ts_GSUP_PROC_SS_REQ(
3352 imsi := g_pars.imsi,
3353 sid := gsup_ms_req_complete.ies[1].val.session_id,
3354 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
3355 ss := valueof(facility_net_req)
3356 );
3357
3358 /* Compose expected MT SS/FACILITY template with counter request */
3359 var template PDU_ML3_NW_MS ussd_net_req := tr_ML3_MT_SS_FACILITY(
3360 tid := 1, /* Response should arrive within the same transaction */
3361 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3362 facility := valueof(facility_net_req)
3363 );
3364
3365 /* Send response over GSUP */
3366 GSUP.send(gsup_net_req);
3367 /* Expect MT SS/FACILITY message with counter request */
3368 f_expect_mt_dtap_msg(ussd_net_req);
3369
3370 /* Compose MO SS/RELEASE COMPLETE */
3371 var template (value) PDU_ML3_MS_NW ussd_abort := ts_ML3_MO_SS_RELEASE_COMPLETE(
3372 tid := 1, /* Response should arrive within the same transaction */
3373 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3374 facility := omit
3375 /* TODO: cause? */
3376 );
3377
3378 /* Compose expected HLR -> MSC abort message */
3379 var template GSUP_PDU gsup_abort := tr_GSUP_PROC_SS_REQ(
3380 imsi := g_pars.imsi,
3381 sid := gsup_ms_req_complete.ies[1].val.session_id,
3382 state := OSMO_GSUP_SESSION_STATE_END
3383 );
3384
3385 /* Abort transaction */
3386 BSSAP.send(ts_PDU_DTAP_MO(ussd_abort));
3387 /* Expect GSUP message indicating abort */
3388 f_expect_gsup_msg(gsup_abort);
3389
3390 f_expect_clear();
3391}
3392testcase TC_lu_and_mo_ussd_mo_release() runs on MTC_CT {
3393 var BSC_ConnHdlr vc_conn;
3394 f_init();
3395 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_mo_release), 50);
3396 vc_conn.done;
3397}
3398
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003399/* LU followed by MO USSD request and MT Release due to timeout */
3400private function f_tc_lu_and_ss_session_timeout(charstring id, BSC_ConnHdlrPars pars)
3401runs on BSC_ConnHdlr {
3402 f_init_handler(pars);
3403
3404 /* Perform location update */
3405 f_perform_lu();
3406
3407 /* Send CM Service Request for SS/USSD */
3408 f_establish_fully(EST_TYPE_SS_ACT);
3409
3410 /* We need to inspect GSUP activity */
3411 f_create_gsup_expect(hex2str(g_pars.imsi));
3412
3413 var template OCTN facility_ms_req := f_USSD_FACILITY_IE_INVOKE(
3414 invoke_id := 1,
3415 op_code := SS_OP_CODE_PROCESS_USS_REQ,
3416 ussd_string := "#release_me");
3417
3418 /* Compose MO SS/REGISTER message with request */
3419 var template (value) PDU_ML3_MS_NW ussd_ms_req := ts_ML3_MO_SS_REGISTER(
3420 tid := 1, /* An arbitrary transaction identifier */
3421 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
3422 facility := valueof(facility_ms_req));
3423
3424 /* Compose expected MSC -> HLR message */
3425 var template GSUP_PDU gsup_ms_req := tr_GSUP_PROC_SS_REQ(
3426 imsi := g_pars.imsi,
3427 state := OSMO_GSUP_SESSION_STATE_BEGIN,
3428 ss := valueof(facility_ms_req));
3429
3430 /* To be used for sending response with correct session ID */
3431 var GSUP_PDU gsup_ms_req_complete;
3432
3433 /* Initiate a new SS transaction */
3434 BSSAP.send(ts_PDU_DTAP_MO(ussd_ms_req));
3435 /* Expect GSUP request with original Facility IE */
3436 gsup_ms_req_complete := f_expect_gsup_msg(gsup_ms_req);
3437
3438 /* Don't respond, wait for timeout */
3439 f_sleep(3.0);
3440
3441 var template PDU_ML3_NW_MS dtap_rel := tr_ML3_MT_SS_RELEASE_COMPLETE(
3442 tid := 1, /* Should match the request's tid */
3443 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
3444 cause := *, /* TODO: expect some specific value */
3445 facility := omit);
3446
3447 var template GSUP_PDU gsup_rel := tr_GSUP_PROC_SS_ERR(
3448 imsi := g_pars.imsi,
3449 sid := gsup_ms_req_complete.ies[1].val.session_id,
3450 state := OSMO_GSUP_SESSION_STATE_END,
3451 cause := ?); /* TODO: expect some specific value */
3452
3453 /* Expect release on both interfaces */
3454 interleave {
3455 [] BSSAP.receive(tr_PDU_DTAP_MT(dtap_rel)) { };
3456 [] GSUP.receive(gsup_rel) { };
3457 }
3458
3459 f_expect_clear();
3460 setverdict(pass);
3461}
3462testcase TC_lu_and_ss_session_timeout() runs on MTC_CT {
3463 var BSC_ConnHdlr vc_conn;
3464 f_init();
Vadim Yanitskiy36d28dd2018-12-03 02:45:45 +07003465 f_vty_config(MSCVTY, "msc", "ncss guard-timeout 3");
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003466 vc_conn := f_start_handler(refers(f_tc_lu_and_ss_session_timeout), 51);
3467 vc_conn.done;
Vadim Yanitskiy36d28dd2018-12-03 02:45:45 +07003468 f_vty_config(MSCVTY, "msc", "ncss guard-timeout 0");
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003469}
3470
Stefan Sperling89eb1f32018-12-17 15:06:20 +01003471/* A5/1 only permitted on network side; attempt an invalid CIPHER MODE COMPLETE with A5/3 which MSC should reject. */
3472private function f_tc_cipher_complete_with_invalid_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
3473 pars.net.expect_auth := true;
3474 pars.net.expect_ciph := true;
3475 pars.net.kc_support := '02'O; /* A5/1 only */
3476 f_init_handler(pars);
3477
3478 g_pars.vec := f_gen_auth_vec_2g();
3479
3480 /* Can't use f_perform_lu() directly. Code below is based on it. */
3481
3482 /* tell GSUP dispatcher to send this IMSI to us */
3483 f_create_gsup_expect(hex2str(g_pars.imsi));
3484
3485 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
3486 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
3487 f_bssap_compl_l3(l3_lu);
3488
3489 f_mm_auth();
3490
3491 var OCT1 a5_net := f_alg_mask_from_cm(g_pars.cm2);
3492 var OCT1 a5_intersect := g_pars.net.kc_support and4b a5_net;
3493 alt {
3494 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(a5_intersect, g_pars.vec.kc)) {
3495 BSSAP.send(ts_BSSMAP_CipherModeCompl(int2oct(4 /* "accept" A5/3 */, 1)));
3496 }
3497 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc)) {
3498 setverdict(fail, "Wrong ciphering algorithm mask in CiphModCmd");
3499 mtc.stop;
3500 }
3501 [] BSSAP.receive {
3502 setverdict(fail, "Unknown/unexpected BSSAP received");
3503 mtc.stop;
3504 }
3505 }
3506
3507 /* Expect LU reject from MSC. */
3508 alt {
3509 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
3510 setverdict(pass);
3511 }
3512 [] BSSAP.receive {
3513 setverdict(fail, "Unknown/unexpected BSSAP received");
3514 mtc.stop;
3515 }
3516 }
Stefan Sperlingc620b352018-12-18 17:23:36 +01003517 f_expect_clear();
Stefan Sperling89eb1f32018-12-17 15:06:20 +01003518}
3519
3520testcase TC_cipher_complete_with_invalid_cipher() runs on MTC_CT {
3521 var BSC_ConnHdlr vc_conn;
3522 f_init();
3523 f_vty_config(MSCVTY, "network", "encryption a5 1");
3524
3525 vc_conn := f_start_handler(refers(f_tc_cipher_complete_with_invalid_cipher), 52);
3526 vc_conn.done;
3527}
3528
Harald Weltef640a012018-04-14 17:49:21 +02003529/* TODO (SMS):
3530 * different user data lengths
3531 * SMPP transaction mode with unsuccessful delivery
3532 * queued MT-SMS with no paging response + later delivery
3533 * different data coding schemes
3534 * multi-part SMS
3535 * user-data headers
3536 * TP-PID for SMS to SIM
3537 * behavior if SMS memory is full + RP-SMMA
3538 * delivery reports
3539 * SMPP osmocom extensions
3540 * more-messages-to-send
3541 * SMS during ongoing call (SACCH/SAPI3)
3542 */
3543
3544/* TODO (General):
Harald Welteba7b6d92018-01-23 21:32:34 +01003545 * continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
3546 * malformed messages (missing IE, invalid message type): properly rejected?
3547 * MT call while LU or is ongoing: Do we use existing lchan or page while lchan active?
3548 * 3G/2G auth permutations
3549 * encryption algorithms vs. classmark vs. vty config
Harald Welteba7b6d92018-01-23 21:32:34 +01003550 * send new transaction after/during clear (like SMS, ...)
Harald Welte45164da2018-01-24 12:51:27 +01003551 * too long L3 INFO in DTAP
3552 * too long / padded BSSAP
3553 * too long / short TLV values
Harald Welteba7b6d92018-01-23 21:32:34 +01003554 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01003555
Philipp Maier948747b2019-04-02 15:22:33 +02003556/* Check if a subscriber exists in the VLR */
3557private function f_ctrl_subscr_in_vlr(charstring imsi_or_msisdn) runs on BSC_ConnHdlr return boolean {
3558
3559 var CtrlValue active_subsribers;
3560 var integer rc;
3561 active_subsribers := f_ctrl_get(IPA_CTRL, "subscriber-list-active-v1");
3562
3563 rc := f_strstr(active_subsribers, imsi_or_msisdn);
3564 if (rc < 0) {
3565 return false;
3566 }
3567
3568 return true;
3569}
3570
Harald Welte4263c522018-12-06 11:56:27 +01003571/* Perform a location updatye at the A-Interface and run some checks to confirm
3572 * that everything is back to normal. */
3573private function f_sgsap_bssmap_screening() runs on BSC_ConnHdlr {
3574 var SmsParameters spars := valueof(t_SmsPars);
3575
3576 /* Perform a location update, the SGs association is expected to fall
3577 * back to NULL */
3578 f_perform_lu();
3579 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
3580
3581 /* Trigger a paging request and expect the paging on BSSMAP, this is
3582 * to make sure that pagings are sent throught the A-Interface again
3583 * and not throught the SGs interface.*/
Harald Welte6811d102019-04-14 22:23:14 +02003584 f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
Harald Welte4263c522018-12-06 11:56:27 +01003585 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
3586
3587 alt {
3588 [] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)); {
3589 setverdict(pass);
3590 }
3591 [] SGsAP.receive {
3592 setverdict(fail, "Received unexpected message on SGs");
3593 }
3594 }
3595
3596 /* Send an SMS to make sure that also payload messages are routed
3597 * throught the A-Interface again */
3598 f_establish_fully(EST_TYPE_MO_SMS);
3599 f_mo_sms(spars);
3600 f_expect_clear();
3601}
3602
3603private function f_tc_sgsap_reset(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
3604 var charstring vlr_name;
3605 f_init_handler(pars);
3606
3607 vlr_name := f_sgsap_reset_mme(mp_mme_name);
3608 log("VLR name: ", vlr_name);
3609 setverdict(pass);
Neels Hofmeyrc0b520d2019-03-06 15:35:50 +01003610 f_sleep(1.0);
Harald Welte4263c522018-12-06 11:56:27 +01003611}
3612
3613testcase TC_sgsap_reset() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003614 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01003615 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003616 f_init(1, true);
3617 pars := f_init_pars(11810, true);
3618 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_reset), pars);
Harald Welte4263c522018-12-06 11:56:27 +01003619 vc_conn.done;
3620}
3621
3622/* like f_mm_auth() but for SGs */
3623function f_mm_auth_sgs() runs on BSC_ConnHdlr {
3624 if (g_pars.net.expect_auth) {
3625 g_pars.vec := f_gen_auth_vec_3g();
3626 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
3627 g_pars.vec.sres,
3628 g_pars.vec.kc,
3629 g_pars.vec.ik,
3630 g_pars.vec.ck,
3631 g_pars.vec.autn,
3632 g_pars.vec.res));
3633 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
3634 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
3635 SGsAP.receive(tr_ML3_MT_MM_AUTH_REQ_3G(g_pars.vec.rand, g_pars.vec.autn));
3636 SGsAP.send(ts_ML3_MT_MM_AUTH_RESP_3G(g_pars.vec.sres, g_pars.vec.res));
3637 }
3638}
3639
3640/* like f_perform_lu(), but on SGs rather than BSSAP */
3641function f_sgs_perform_lu() runs on BSC_ConnHdlr {
3642 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
3643 var PDU_SGsAP lur;
3644 var PDU_SGsAP lua;
3645 var PDU_SGsAP mm_info;
3646 var octetstring mm_info_dtap;
3647
3648 /* tell GSUP dispatcher to send this IMSI to us */
3649 f_create_gsup_expect(hex2str(g_pars.imsi));
3650
3651 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
3652 ts_SGsAP_LAI('901'H, '70'H, 2342)));
3653 /* Old LAI, if MS sends it */
3654 /* TMSI status, if MS has no valid TMSI */
3655 /* IMEISV, if it supports "automatic device detection" */
3656 /* TAI, if available in MME */
3657 /* E-CGI, if available in MME */
3658 SGsAP.send(lur);
3659
3660 /* FIXME: is this really done over SGs? The Ue is already authenticated
3661 * via the MME ... */
3662 f_mm_auth_sgs();
3663
3664 /* Expect MSC to perform LU with HLR */
3665 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
3666 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
3667 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
3668 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
3669
3670 alt {
3671 [] SGsAP.receive(tr_SGsAP_LU_ACCEPT(g_pars.imsi, ?)) -> value lua {
3672 if (isvalue(lua.sGsAP_LOCATION_UPDATE_ACCEPT.newTMSIorIMSI.iD.iD.tmsi_ptmsi.octets)) {
3673 g_pars.tmsi :=lua.sGsAP_LOCATION_UPDATE_ACCEPT.newTMSIorIMSI.iD.iD.tmsi_ptmsi.octets
3674 SGsAP.send(ts_SGsAP_TMSI_REALL_CMPL(g_pars.imsi));
3675 }
3676 setverdict(pass);
3677 }
3678 [] SGsAP.receive(tr_SGsAP_LU_REJECT(g_pars.imsi, ?, ?)) {
3679 setverdict(fail, "Received LU-REJECT instead of ACCEPT");
3680 }
3681 [] SGsAP.receive {
3682 setverdict(fail, "Received unexpected message on SGs");
3683 }
3684 }
3685
3686 /* Check MM information */
3687 if (mp_mm_info == true) {
3688 SGsAP.receive(tr_SGsAP_MM_INFO_REQ(g_pars.imsi, ?)) -> value mm_info;
3689 mm_info_dtap := '0532'O & mm_info.sGsAP_MM_INFORMATION_REQUEST.mM_Information.information;
3690 if (not match(dec_PDU_ML3_NW_MS(mm_info_dtap), tr_ML3_MT_MM_Info)) {
3691 setverdict(fail, "Unexpected MM Information");
3692 }
3693 }
3694
3695 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
3696}
3697
3698private function f_tc_sgsap_lu(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
3699 f_init_handler(pars);
3700 f_sgs_perform_lu();
3701 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
3702
3703 f_sgsap_bssmap_screening();
3704
3705 setverdict(pass);
3706}
3707testcase TC_sgsap_lu() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003708 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01003709 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003710 f_init(1, true);
3711 pars := f_init_pars(11811, true);
3712 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu), pars);
Harald Welte4263c522018-12-06 11:56:27 +01003713 vc_conn.done;
3714}
3715
3716/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
3717private function f_tc_sgsap_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
3718 f_init_handler(pars);
3719 var PDU_SGsAP lur;
3720
3721 f_create_gsup_expect(hex2str(g_pars.imsi));
3722 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
3723 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
3724 ts_SGsAP_LAI('901'H, '70'H, 2342)));
3725 SGsAP.send(lur);
3726
3727 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
3728 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
3729 alt {
3730 [] SGsAP.receive(tr_SGsAP_LU_REJECT(g_pars.imsi, ?, ?)) {
3731 setverdict(pass);
3732 }
3733 [] SGsAP.receive(tr_SGsAP_LU_ACCEPT(g_pars.imsi, ?)) {
3734 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
3735 mtc.stop;
3736 }
3737 [] SGsAP.receive {
3738 setverdict(fail, "Received unexpected message on SGs");
3739 }
3740 }
3741
3742 f_sgsap_bssmap_screening();
3743
3744 setverdict(pass);
3745}
3746testcase TC_sgsap_lu_imsi_reject() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003747 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01003748 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003749 f_init(1, true);
3750 pars := f_init_pars(11812, true);
Harald Welte4263c522018-12-06 11:56:27 +01003751
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003752 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu_imsi_reject), pars);
Harald Welte4263c522018-12-06 11:56:27 +01003753 vc_conn.done;
3754}
3755
3756/* Do LU by IMSI, but then remain silent so that Ts6-1 times out */
3757private function f_tc_sgsap_lu_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
3758 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
3759 var PDU_SGsAP lur;
3760
3761 f_init_handler(pars);
3762
3763 /* tell GSUP dispatcher to send this IMSI to us */
3764 f_create_gsup_expect(hex2str(g_pars.imsi));
3765
3766 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
3767 ts_SGsAP_LAI('901'H, '70'H, 2342)));
3768 /* Old LAI, if MS sends it */
3769 /* TMSI status, if MS has no valid TMSI */
3770 /* IMEISV, if it supports "automatic device detection" */
3771 /* TAI, if available in MME */
3772 /* E-CGI, if available in MME */
3773 SGsAP.send(lur);
3774
3775 /* FIXME: is this really done over SGs? The Ue is already authenticated
3776 * via the MME ... */
3777 f_mm_auth_sgs();
3778
3779 /* Expect MSC to perform LU with HLR */
3780 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
3781 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
3782 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
3783 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
3784
3785 alt {
3786 [] SGsAP.receive(tr_SGsAP_LU_ACCEPT(g_pars.imsi, ?)) {
3787 setverdict(pass);
3788 }
3789 [] SGsAP.receive(tr_SGsAP_LU_REJECT(g_pars.imsi, ?, ?)) {
3790 setverdict(fail, "Received LU-REJECT instead of ACCEPT");
3791 }
3792 [] SGsAP.receive {
3793 setverdict(fail, "Received unexpected message on SGs");
3794 }
3795 }
3796
3797 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
3798
3799 /* Wait until the VLR has abort the TMSI reallocation procedure */
3800 f_sleep(45.0);
3801
3802 /* The outcome does not change the SGs state, see also 5.2.3.4 */
3803 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
3804
3805 f_sgsap_bssmap_screening();
3806
3807 setverdict(pass);
3808}
3809testcase TC_sgsap_lu_and_nothing() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003810 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01003811 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003812 f_init(1, true);
3813 pars := f_init_pars(11813, true);
Harald Welte4263c522018-12-06 11:56:27 +01003814
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003815 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu_and_nothing), pars);
Harald Welte4263c522018-12-06 11:56:27 +01003816 vc_conn.done;
3817}
3818
3819private function f_tc_sgsap_expl_imsi_det_eps(charstring id, BSC_ConnHdlrPars pars)
3820runs on BSC_ConnHdlr {
3821 f_init_handler(pars);
3822 f_sgs_perform_lu();
3823 f_sleep(3.0);
3824
3825 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
3826 SGsAP.send(ts_SGsAP_EPS_DETACH_IND(g_pars.imsi, mme_name, UE_initiated));
3827 SGsAP.receive(tr_SGsAP_EPS_DETACH_ACK(g_pars.imsi));
3828 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
3829
3830 f_sgsap_bssmap_screening();
3831
3832 setverdict(pass);
3833}
3834testcase TC_sgsap_expl_imsi_det_eps() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003835 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01003836 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003837 f_init(1, true);
3838 pars := f_init_pars(11814, true);
3839 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_expl_imsi_det_eps), pars);
Harald Welte4263c522018-12-06 11:56:27 +01003840 vc_conn.done;
3841}
3842
Philipp Maierfc19f172019-03-21 11:17:54 +01003843private function f_tc_sgsap_impl_imsi_det_eps(charstring id, BSC_ConnHdlrPars pars)
3844runs on BSC_ConnHdlr {
3845 f_init_handler(pars);
3846 f_sgs_perform_lu();
3847 f_sleep(3.0);
3848
3849 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
3850 SGsAP.send(ts_SGsAP_EPS_DETACH_IND(g_pars.imsi, mme_name, network_initiated));
3851 SGsAP.receive(tr_SGsAP_EPS_DETACH_ACK(g_pars.imsi));
3852 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
3853
3854 f_sgsap_bssmap_screening();
3855
3856 setverdict(pass);
3857}
3858testcase TC_sgsap_impl_imsi_det_eps() runs on MTC_CT {
3859 var BSC_ConnHdlrPars pars;
3860 var BSC_ConnHdlr vc_conn;
3861 f_init(1, true);
3862 pars := f_init_pars(11814, true);
3863 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_impl_imsi_det_eps), pars);
3864 vc_conn.done;
3865}
3866
Harald Welte4263c522018-12-06 11:56:27 +01003867private function f_tc_sgsap_expl_imsi_det_noneps(charstring id, BSC_ConnHdlrPars pars)
3868runs on BSC_ConnHdlr {
3869 f_init_handler(pars);
3870 f_sgs_perform_lu();
3871 f_sleep(3.0);
3872
3873 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
3874 SGsAP.send(ts_SGsAP_IMSI_DETACH_IND(g_pars.imsi, mme_name, combined_UE_initiated));
3875 SGsAP.receive(tr_SGsAP_IMSI_DETACH_ACK(g_pars.imsi));
Philipp Maierd08e7e72019-04-02 15:27:10 +02003876
3877 if (f_ctrl_subscr_in_vlr(hex2str(g_pars.imsi))) {
3878 setverdict(fail, "subscriber not removed from VLR");
3879 }
Harald Welte4263c522018-12-06 11:56:27 +01003880
3881 f_sgsap_bssmap_screening();
3882
3883 setverdict(pass);
3884}
3885testcase TC_sgsap_expl_imsi_det_noneps() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003886 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01003887 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003888 f_init(1, true);
3889 pars := f_init_pars(11815, true);
3890 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_expl_imsi_det_noneps), pars);
Harald Welte4263c522018-12-06 11:56:27 +01003891 vc_conn.done;
3892}
3893
Philipp Maier5d812702019-03-21 10:51:26 +01003894private function f_tc_sgsap_impl_imsi_det_noneps(charstring id, BSC_ConnHdlrPars pars)
3895runs on BSC_ConnHdlr {
3896 f_init_handler(pars);
3897 f_sgs_perform_lu();
3898 f_sleep(3.0);
3899
3900 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
3901 SGsAP.send(ts_SGsAP_IMSI_DETACH_IND(g_pars.imsi, mme_name, implicit_network_initiated));
3902 SGsAP.receive(tr_SGsAP_IMSI_DETACH_ACK(g_pars.imsi));
3903
3904 if (f_ctrl_subscr_in_vlr(hex2str(g_pars.imsi))) {
3905 setverdict(fail, "subscriber not removed from VLR");
3906 }
3907
3908 f_sgsap_bssmap_screening();
3909
3910 setverdict(pass);
3911}
3912testcase TC_sgsap_impl_imsi_det_noneps() runs on MTC_CT {
3913 var BSC_ConnHdlrPars pars;
3914 var BSC_ConnHdlr vc_conn;
3915 f_init(1, true);
3916 pars := f_init_pars(11815, true);
3917 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_impl_imsi_det_noneps), pars);
3918 vc_conn.done;
3919}
3920
Harald Welte4263c522018-12-06 11:56:27 +01003921/* Trigger a paging request via VTY and send a paging reject in response */
3922private function f_tc_sgsap_paging_rej(charstring id, BSC_ConnHdlrPars pars)
3923runs on BSC_ConnHdlr {
3924 f_init_handler(pars);
3925 f_sgs_perform_lu();
3926 f_sleep(1.0);
3927
3928 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
3929 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
3930 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
3931 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
3932
3933 /* Initiate paging via VTY */
3934 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
3935 alt {
3936 [] SGsAP.receive(exp_resp) {
3937 setverdict(pass);
3938 }
3939 [] SGsAP.receive {
3940 setverdict(fail, "Received unexpected message on SGs");
3941 }
3942 }
3943
3944 /* Now reject the paging */
3945 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, IMSI_unknown));
3946
3947 /* Wait for the states inside the MSC to settle and check the state
3948 * of the SGs Association */
3949 f_sleep(1.0);
3950 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
3951
3952 /* FIXME: At the moment we send an IMSI_unknown as cause code, which is fine,
3953 * but we also need to cover tha case where the cause code indicates an
3954 * "IMSI detached for EPS services". In those cases the VLR is expected to
3955 * try paging on tha A/Iu interface. This will be another testcase similar to
3956 * this one, but extended with checks for the presence of the A/Iu paging
3957 * messages. */
3958
3959 f_sgsap_bssmap_screening();
3960
3961 setverdict(pass);
3962}
3963testcase TC_sgsap_paging_rej() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003964 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01003965 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01003966 f_init(1, true);
3967 pars := f_init_pars(11816, true);
3968 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_rej), pars);
Harald Welte4263c522018-12-06 11:56:27 +01003969 vc_conn.done;
3970}
3971
3972/* Trigger a paging request via VTY and send a paging reject that indicates
3973 * that the subscriber intentionally rejected the call. */
3974private function f_tc_sgsap_paging_subscr_rej(charstring id, BSC_ConnHdlrPars pars)
3975runs on BSC_ConnHdlr {
3976 f_init_handler(pars);
3977 f_sgs_perform_lu();
3978 f_sleep(1.0);
3979
3980 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
3981 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
3982 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
3983 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
3984
3985 /* Initiate paging via VTY */
3986 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
3987 alt {
3988 [] SGsAP.receive(exp_resp) {
3989 setverdict(pass);
3990 }
3991 [] SGsAP.receive {
3992 setverdict(fail, "Received unexpected message on SGs");
3993 }
3994 }
3995
3996 /* Now reject the paging */
3997 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, user_rejected_mobile_terminating_CS_fallback_call));
3998
3999 /* Wait for the states inside the MSC to settle and check the state
4000 * of the SGs Association */
4001 f_sleep(1.0);
4002 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4003
4004 /* FIXME: The VLR is supposed to trigger an User Determined User Busy (UDUB) as specified
4005 * in 3GPP TS 24.082, this is not yet implemented in the MSC or in this tests, we need
4006 * to check back how this works and how it can be tested */
4007
4008 f_sgsap_bssmap_screening();
4009
4010 setverdict(pass);
4011}
4012testcase TC_sgsap_paging_subscr_rej() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004013 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004014 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004015 f_init(1, true);
4016 pars := f_init_pars(11817, true);
4017 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_subscr_rej), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004018 vc_conn.done;
4019}
4020
4021/* Trigger a paging request via VTY and send an UE unreacable messge in response */
4022private function f_tc_sgsap_paging_ue_unr(charstring id, BSC_ConnHdlrPars pars)
4023runs on BSC_ConnHdlr {
4024 f_init_handler(pars);
4025 f_sgs_perform_lu();
4026 f_sleep(1.0);
4027
4028 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4029 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
4030 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4031 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4032
4033 /* Initiate paging via VTY */
4034 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4035 alt {
4036 [] SGsAP.receive(exp_resp) {
4037 setverdict(pass);
4038 }
4039 [] SGsAP.receive {
4040 setverdict(fail, "Received unexpected message on SGs");
4041 }
4042 }
4043
4044 /* Now pretend that the UE is unreachable */
4045 SGsAP.send(ts_SGsAP_UE_UNREACHABLE(g_pars.imsi, UE_unreachable));
4046
4047 /* Wait for the states inside the MSC to settle and check the state
4048 * of the SGs Association. */
4049 f_sleep(1.0);
4050 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4051
4052 f_sgsap_bssmap_screening();
4053
4054 setverdict(pass);
4055}
4056testcase TC_sgsap_paging_ue_unr() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004057 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004058 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004059 f_init(1, true);
4060 pars := f_init_pars(11818, true);
4061 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_ue_unr), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004062 vc_conn.done;
4063}
4064
4065/* Trigger a paging request via VTY but don't respond to it */
4066private function f_tc_sgsap_paging_and_nothing(charstring id, BSC_ConnHdlrPars pars)
4067runs on BSC_ConnHdlr {
4068 f_init_handler(pars);
4069 f_sgs_perform_lu();
4070 f_sleep(1.0);
4071
4072 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4073 var template PDU_SGsAP exp_resp := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, CS_call_indicator, omit);
4074 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4075 exp_resp.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4076
4077 /* Initiate paging via VTY */
4078 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4079 alt {
4080 [] SGsAP.receive(exp_resp) {
4081 setverdict(pass);
4082 }
4083 [] SGsAP.receive {
4084 setverdict(fail, "Received unexpected message on SGs");
4085 }
4086 }
4087
4088 /* Now do nothing, the MSC/VLR should fail silently to page after a
4089 * few seconds, The SGs association must remain unchanged. */
4090 f_sleep(15.0);
4091 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4092
4093 f_sgsap_bssmap_screening();
4094
4095 setverdict(pass);
4096}
4097testcase TC_sgsap_paging_and_nothing() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004098 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004099 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004100 f_init(1, true);
4101 pars := f_init_pars(11819, true);
4102 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_and_nothing), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004103 vc_conn.done;
4104}
4105
4106/* Trigger a paging request via VTY and slip in an LU */
4107private function f_tc_sgsap_paging_and_lu(charstring id, BSC_ConnHdlrPars pars)
4108runs on BSC_ConnHdlr {
4109 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4110 f_init_handler(pars);
4111
4112 /* First we prepar the situation, where the SGs association is in state
4113 * NULL and the confirmed by radio contact indicator is set to false
4114 * as well. This can be archived by performing an SGs LU and then
4115 * resetting the VLR */
4116 f_sgs_perform_lu();
4117 f_sgsap_reset_mme(mp_mme_name);
4118 f_sleep(1.0);
4119 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4120
4121 /* Perform a paging, expect the paging messages on the SGs interface */
4122 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4123 alt {
4124 [] SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit)) {
4125 setverdict(pass);
4126 }
4127 [] SGsAP.receive {
4128 setverdict(fail, "Received unexpected message on SGs");
4129 }
4130 }
4131
4132 /* Perform the LU as normal */
4133 f_sgs_perform_lu();
4134 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4135
4136 /* Expect a new paging request right after the LU */
4137 alt {
4138 [] SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit)) {
4139 setverdict(pass);
4140 }
4141 [] SGsAP.receive {
4142 setverdict(fail, "Received unexpected message on SGs");
4143 }
4144 }
4145
4146 /* Test is done now, lets round everything up by rejecting the paging
4147 * cleanly. */
4148 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, user_rejected_mobile_terminating_CS_fallback_call));
4149 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4150
4151 f_sgsap_bssmap_screening();
4152
4153 setverdict(pass);
4154}
4155testcase TC_sgsap_paging_and_lu() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004156 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004157 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004158 f_init(1, true);
4159 pars := f_init_pars(11820, true);
4160 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_paging_and_lu), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004161 vc_conn.done;
4162}
4163
4164/* Send unexpected unit-data through the SGs interface */
4165private function f_tc_sgsap_unexp_ud(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4166 f_init_handler(pars);
4167 f_sleep(1.0);
4168
4169 /* This simulates what happens when a subscriber without SGs
4170 * association gets unitdata via the SGs interface. */
4171
4172 /* Make sure the subscriber exists and the SGs association
4173 * is in NULL state */
4174 f_perform_lu();
4175 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4176
4177 /* Send some random unit data, the MSC/VLR should send a release
4178 * immediately. */
4179 SGsAP.send(ts_SGsAP_UL_UD(pars.imsi,'1234'O));
4180 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, IMSI_detached_for_EPS_nonEPS_services));
4181
4182 f_sgsap_bssmap_screening();
4183
4184 setverdict(pass);
4185}
4186testcase TC_sgsap_unexp_ud() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004187 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004188 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004189 f_init(1, true);
4190 pars := f_init_pars(11821, true);
4191 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_unexp_ud), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004192 vc_conn.done;
4193}
4194
4195/* Send unsolicited unit-data through the SGs interface */
4196private function f_tc_sgsap_unsol_ud(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4197 f_init_handler(pars);
4198 f_sleep(1.0);
4199
4200 /* This simulates what happens when the MME attempts to send unitdata
4201 * to a subscriber that is completely unknown to the VLR */
4202
4203 /* Send some random unit data, the MSC/VLR should send a release
4204 * immediately. */
4205 SGsAP.send(ts_SGsAP_UL_UD(pars.imsi,'1234'O));
4206 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, IMSI_unknown));
4207
4208 f_sgsap_bssmap_screening();
4209
4210 setverdict(pass);
4211}
4212testcase TC_sgsap_unsol_ud() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004213 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004214 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004215 f_init(1, true);
4216 pars := f_init_pars(11822, true);
4217 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_unsol_ud), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004218 vc_conn.done;
4219}
4220
4221private altstep as_other_sms_sgs() runs on BSC_ConnHdlr {
4222 /* FIXME: Match an actual payload (second questionmark), the type is
4223 * octetstring, how do we use a tr_PDU_DTAP_MT here? */
4224 [] SGsAP.receive(tr_SGsAP_DL_UD(?,?)) {
4225 setverdict(fail, "Unexpected SMS related PDU from MSC");
4226 mtc.stop;
4227 }
4228}
4229
4230/* receive a MT-SMS delivered from the MSC/SMSC over an already existing SGsAP connection */
4231function f_mt_sms_sgs(inout SmsParameters spars)
4232runs on BSC_ConnHdlr {
4233 var template (value) TPDU_RP_DATA_MS_SGSN tp_mo;
4234 var template (value) RPDU_MS_SGSN rp_mo;
4235 var template (value) PDU_ML3_MS_NW l3_mo;
4236
4237 var template TPDU_RP_DATA_SGSN_MS tp_mt;
4238 var template RPDU_SGSN_MS rp_mt;
4239 var template PDU_ML3_NW_MS l3_mt;
4240
4241 var PDU_ML3_NW_MS sgsap_l3_mt;
4242
4243 var default d := activate(as_other_sms_sgs());
4244
4245 /* Expect CP-DATA(RP-DATA(SMS-DELIVER)) */
4246 tp_mt := tr_SMS_DELIVER(?, spars.tp.ud, spars.tp.pid, spars.tp.dcs, ?);
4247 rp_mt := tr_RP_DATA_MT(?, ?, omit, tp_mt);
4248 l3_mt := tr_ML3_MT_SMS(?, c_TIF_ORIG, tr_CP_DATA_MT(rp_mt));
4249
4250 SGsAP.receive(l3_mt) -> value sgsap_l3_mt;
4251
4252 /* Extract relevant identifiers */
4253 spars.tid := bit2int(sgsap_l3_mt.tiOrSkip.transactionId.tio);
4254 spars.rp.msg_ref := sgsap_l3_mt.msgs.sms.cP_DATA.cP_User_Data.cP_RPDU.rP_DATA_SGSN_MS.rP_MessageReference;
4255
4256 /* send CP-ACK for CP-DATA just received */
4257 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_REPL, ts_CP_ACK_MO);
4258
4259 SGsAP.send(l3_mo);
4260
4261 /* send RP-ACK for RP-DATA */
4262 rp_mo := ts_RP_ACK_MO(spars.rp.msg_ref);
4263 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_REPL, ts_CP_DATA_MO(rp_mo));
4264
4265 SGsAP.send(l3_mo);
4266
4267 /* expect CP-ACK for CP-DATA(RP-ACK) just sent */
4268 l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_ORIG, tr_CP_ACK_MT);
4269
4270 SGsAP.receive(l3_mt);
4271
4272 deactivate(d);
4273
4274 setverdict(pass);
4275}
4276
4277/* submit a MO-SMS to MSC/SMSC over an already existing SGsAP connection */
4278function f_mo_sms_sgs(inout SmsParameters spars)
4279runs on BSC_ConnHdlr {
4280 var template (value) TPDU_RP_DATA_MS_SGSN tp_mo;
4281 var template (value) RPDU_MS_SGSN rp_mo;
4282 var template (value) PDU_ML3_MS_NW l3_mo;
4283
4284 var template TPDU_RP_DATA_SGSN_MS tp_mt;
4285 var template RPDU_SGSN_MS rp_mt;
4286 var template PDU_ML3_NW_MS l3_mt;
4287
4288 var default d := activate(as_other_sms_sgs());
4289
4290 /* just in case this is routed to SMPP.. */
4291 f_create_smpp_expect(hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue));
4292
4293 tp_mo := ts_SMS_SUBMIT(spars.tp.msg_ref, spars.tp.da, spars.tp.pid, spars.tp.dcs,
4294 spars.tp.udl, spars.tp.ud);
4295 rp_mo := ts_RP_DATA_MO(spars.rp.msg_ref, spars.rp.orig, spars.rp.dest, tp_mo);
4296 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_DATA_MO(rp_mo));
4297
4298 SGsAP.send(l3_mo);
4299
4300 /* receive CP-ACK for CP-DATA above */
4301 SGsAP.receive(tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_ACK_MT));
4302
4303 if (ispresent(spars.exp_rp_err)) {
4304 /* expect an RP-ERROR message from MSC with given cause */
4305 rp_mt := tr_RP_ERROR_MT(spars.rp.msg_ref, spars.exp_rp_err);
4306 l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_DATA_MT(rp_mt));
4307 SGsAP.receive(l3_mt);
4308 /* send CP-ACK for CP-DATA just received */
4309 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_ACK_MO);
4310 SGsAP.send(l3_mo);
4311 } else {
4312 /* expect RP-ACK for RP-DATA */
4313 rp_mt := tr_RP_ACK_MT(spars.rp.msg_ref);
4314 l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_DATA_MT(rp_mt));
4315 SGsAP.receive(l3_mt);
4316 /* send CP-ACO for CP-DATA just received */
4317 l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_ACK_MO);
4318 SGsAP.send(l3_mo);
4319 }
4320
4321 deactivate(d);
4322
4323 setverdict(pass);
4324}
4325
4326private function f_vty_sms_send_conn_hdlr(charstring imsi, charstring msisdn, charstring text)
4327runs on BSC_ConnHdlr {
4328 f_vty_transceive(MSCVTY, "subscriber imsi "&imsi&" sms sender msisdn "&msisdn&" send "&text);
4329}
4330
4331/* Send a MT SMS via SGs interface */
4332private function f_tc_sgsap_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4333 f_init_handler(pars);
4334 f_sgs_perform_lu();
4335 f_sleep(1.0);
4336 var SmsParameters spars := valueof(t_SmsPars);
4337 spars.tp.ud := 'C8329BFD064D9B53'O;
4338
4339 /* Trigger SMS via VTY */
4340 f_vty_sms_send_conn_hdlr(hex2str(pars.imsi), "2342", "Hello SMS");
4341 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4342
4343 /* Expect a paging request and respond accordingly with a service request */
4344 SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, SMS_indicator, omit));
4345 SGsAP.send(ts_SGsAP_SERVICE_REQ(pars.imsi, SMS_indicator, EMM_CONNECTED));
4346
4347 /* Connection is now live, receive the MT-SMS */
4348 f_mt_sms_sgs(spars);
4349
4350 /* Expect a concluding release from the MSC */
4351 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, omit));
4352
4353 /* Make sure that subscriber is still present and the SGs association is in tact (ref-counting) */
4354 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4355
4356 f_sgsap_bssmap_screening();
4357
4358 setverdict(pass);
4359}
4360testcase TC_sgsap_mt_sms() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004361 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004362 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004363 f_init(1, true);
4364 pars := f_init_pars(11823, true);
4365 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mt_sms), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004366 vc_conn.done;
4367}
4368
4369/* Send a MO SMS via SGs interface */
4370private function f_tc_sgsap_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4371 f_init_handler(pars);
4372 f_sgs_perform_lu();
4373 f_sleep(1.0);
4374 var SmsParameters spars := valueof(t_SmsPars);
4375 spars.tp.ud := 'C8329BFD064D9B53'O;
4376
4377 /* Send the MO-SMS */
4378 f_mo_sms_sgs(spars);
4379
4380 /* Expect a concluding release from the MSC/VLR */
4381 SGsAP.receive(tr_SGsAP_RELEASE_REQ(pars.imsi, omit));
4382
4383 /* Make sure that subscriber is still present and the SGs association is in tact (ref-counting) */
4384 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4385
4386 setverdict(pass);
4387
4388 f_sgsap_bssmap_screening()
4389}
4390testcase TC_sgsap_mo_sms() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004391 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004392 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004393 f_init(1, true);
4394 pars := f_init_pars(11824, true);
4395 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mo_sms), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004396 vc_conn.done;
4397}
4398
4399/* Trigger sending of an MT sms via VTY but never respond to anything */
4400private function f_tc_sgsap_mt_sms_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4401 f_init_handler(pars, 170.0);
4402 f_sgs_perform_lu();
4403 f_sleep(1.0);
4404
4405 var SmsParameters spars := valueof(t_SmsPars);
4406 spars.tp.ud := 'C8329BFD064D9B53'O;
4407 var integer page_count := 0;
4408 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4409 var template PDU_SGsAP exp_pag_req := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, SMS_indicator, omit);
4410 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4411 exp_pag_req.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4412
4413 /* Trigger SMS via VTY */
4414 f_vty_sms_send_conn_hdlr(hex2str(pars.imsi), "2342", "Hello SMS");
4415
Neels Hofmeyr16237742019-03-06 15:34:01 +01004416 /* Expect the MSC/VLR to page exactly once */
4417 SGsAP.receive(exp_pag_req);
Harald Welte4263c522018-12-06 11:56:27 +01004418
4419 /* Wait some time to make sure the MSC is not delivering any further
4420 * paging messages or anything else that could be unexpected. */
4421 timer T := 20.0;
4422 T.start
4423 alt {
4424 [] SGsAP.receive(exp_pag_req)
4425 {
4426 setverdict(fail, "paging seems not to stop!");
4427 mtc.stop;
4428 }
4429 [] SGsAP.receive {
4430 setverdict(fail, "unexpected SGsAP message received");
4431 self.stop;
4432 }
4433 [] T.timeout {
4434 setverdict(pass);
4435 }
4436 }
4437
4438 /* Even on a failed paging the SGs Association should stay intact */
4439 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4440
4441 /* Note: We do not execute f_sgsap_bssmap_screening() here since the
4442 * MSC/VLR would re-try to deliver the test SMS trigered above and
4443 * so the screening would fail. */
4444
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01004445 f_vty_sms_clear(hex2str(g_pars.imsi));
4446
Harald Welte4263c522018-12-06 11:56:27 +01004447 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " expire");
4448
4449 setverdict(pass);
Neels Hofmeyrb0f82342019-03-06 15:36:51 +01004450
4451 f_sgsap_bssmap_screening();
Harald Welte4263c522018-12-06 11:56:27 +01004452}
4453testcase TC_sgsap_mt_sms_and_nothing() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004454 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004455 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004456 f_init(1, true);
4457 pars := f_init_pars(11825, true);
4458 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mt_sms_and_nothing), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004459 vc_conn.done;
4460}
4461
4462/* Trigger sending of an MT sms via VTY but reject the paging immediately */
4463private function f_tc_sgsap_mt_sms_and_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4464 f_init_handler(pars, 150.0);
4465 f_sgs_perform_lu();
4466 f_sleep(1.0);
4467
4468 var SmsParameters spars := valueof(t_SmsPars);
4469 spars.tp.ud := 'C8329BFD064D9B53'O;
4470 var integer page_count := 0;
4471 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4472 var template PDU_SGsAP exp_pag_req := tr_SGsAP_PAGING_REQ(g_pars.imsi, vlr_name, SMS_indicator, omit);
4473 var template LocationAreaId exp_lai := ts_SGsAP_IE_Lai(valueof(ts_SGsAP_LAI('901'H, '70'H, 2342)));
4474 exp_pag_req.sGsAP_PAGING_REQUEST.locationAreaId := exp_lai;
4475
4476 /* Trigger SMS via VTY */
4477 f_vty_sms_send_conn_hdlr(hex2str(pars.imsi), "2342", "Hello SMS");
4478
4479 /* Expect a paging request and reject it immediately */
4480 SGsAP.receive(exp_pag_req);
4481 SGsAP.send(ts_SGsAP_PAGING_REJ(g_pars.imsi, IMSI_unknown));
4482
4483 /* The MSC/VLR should no longer try to page once the paging has been
4484 * rejected. Wait some time and check if there are no unexpected
4485 * messages on the SGs interface. */
4486 timer T := 20.0;
4487 T.start
4488 alt {
4489 [] SGsAP.receive(exp_pag_req)
4490 {
4491 setverdict(fail, "paging seems not to stop!");
4492 mtc.stop;
4493 }
4494 [] SGsAP.receive {
4495 setverdict(fail, "unexpected SGsAP message received");
4496 self.stop;
4497 }
4498 [] T.timeout {
4499 setverdict(pass);
4500 }
4501 }
4502
Neels Hofmeyr8256ed22019-03-06 15:34:01 +01004503 f_vty_sms_clear(hex2str(g_pars.imsi));
4504
Harald Welte4263c522018-12-06 11:56:27 +01004505 /* A rejected paging with IMSI_unknown (see above) should always send
4506 * the SGs association to NULL. */
4507 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-NULL");
4508
4509 f_sgsap_bssmap_screening();
4510
Harald Welte4263c522018-12-06 11:56:27 +01004511 setverdict(pass);
4512}
4513testcase TC_sgsap_mt_sms_and_reject() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004514 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004515 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004516 f_init(1, true);
4517 pars := f_init_pars(11826, true);
4518 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_mt_sms_and_reject), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004519 vc_conn.done;
4520}
4521
4522/* Perform an MT CSDB call including LU */
4523private function f_mt_lu_and_csfb_call(charstring id, BSC_ConnHdlrPars pars, boolean bssmap_lu) runs on BSC_ConnHdlr {
4524 f_init_handler(pars);
4525
4526 /* Be sure that the BSSMAP reset is done before we begin. */
4527 f_sleep(2.0);
4528
4529 /* Testcase variation: See what happens when we do a regular BSSMAP
4530 * LU first (this should not hurt in any way!) */
4531 if (bssmap_lu) {
4532 f_perform_lu();
4533 }
4534
4535 f_sgs_perform_lu();
4536 f_sleep(1.0);
4537
4538 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4539 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
4540 cpars.bss_rtp_port := 1110;
4541 cpars.mgcp_connection_id_bss := '10004'H;
4542 cpars.mgcp_connection_id_mss := '10005'H;
4543
4544 /* Note: This is an optional parameter. When the call-agent (MSC) does
4545 * supply a full endpoint name this setting will be overwritten. */
4546 cpars.mgcp_ep := "rtpbridge/1@mgw";
4547
4548 /* Initiate a call via MNCC interface */
4549 f_mt_call_initate(cpars);
4550
4551 /* Expect a paging request and respond accordingly with a service request */
4552 SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit));
4553 SGsAP.send(ts_SGsAP_SERVICE_REQ(pars.imsi, CS_call_indicator, EMM_CONNECTED));
4554
4555 /* Complete the call, hold it for some time and then tear it down */
4556 f_mt_call_complete(cpars);
4557 f_sleep(3.0);
Harald Welte4c422b72019-02-17 16:27:10 +01004558 f_call_hangup(cpars, true, is_csfb := true);
Harald Welte4263c522018-12-06 11:56:27 +01004559
4560 /* Make sure that subscriber is still present and the SGs association is in tact (ref-counting) */
4561 f_ctrl_get_exp(IPA_CTRL, "fsm.SGs-UE.id.imsi:" & hex2str(g_pars.imsi) & ".state", "SGs-ASSOCIATED");
4562
4563 /* Finally simulate the return of the UE to the 4G network */
4564 SGsAP.send(ts_SGsAP_MO_CSFB_IND(pars.imsi));
4565
4566 /* Test for successful return by triggering a paging, when the paging
4567 * request is received via SGs, we can be sure that the MSC/VLR has
4568 * recognized that the UE is now back on 4G */
4569 f_sleep(1.0);
4570 f_vty_transceive(MSCVTY, "subscriber imsi " & hex2str(g_pars.imsi) & " paging");
4571 alt {
4572 [] SGsAP.receive(tr_SGsAP_PAGING_REQ(pars.imsi, vlr_name, CS_call_indicator, omit)) {
4573 setverdict(pass);
4574 }
4575 [] SGsAP.receive {
4576 setverdict(fail, "Received unexpected message on SGs");
4577 }
4578 }
4579
4580 f_sgsap_bssmap_screening();
4581
4582 setverdict(pass);
4583}
4584
4585/* Perform a regular BSSAP LU first, do a SGSAP LU and then make a CSFB call */
4586private function f_tc_bssap_lu_sgsap_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4587 f_mt_lu_and_csfb_call(id, pars, true);
4588}
4589testcase TC_bssap_lu_sgsap_lu_and_mt_call() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004590 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004591 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004592 f_init(1, true);
4593 pars := f_init_pars(118139, true);
Harald Welte4263c522018-12-06 11:56:27 +01004594
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004595 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 +01004596 vc_conn.done;
4597}
4598
4599
4600/* Perform a SGSAP LU and then make a CSFB call */
4601private function f_tc_sgsap_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4602 f_mt_lu_and_csfb_call(id, pars, false);
4603}
4604testcase TC_sgsap_lu_and_mt_call() runs on MTC_CT {
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004605 var BSC_ConnHdlrPars pars;
Harald Welte4263c522018-12-06 11:56:27 +01004606 var BSC_ConnHdlr vc_conn;
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004607 f_init(1, true);
4608 pars := f_init_pars(11827, true);
Harald Welte4263c522018-12-06 11:56:27 +01004609
Philipp Maier8e07a4a2019-02-14 18:23:28 +01004610 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_lu_and_mt_call), pars);
Harald Welte4263c522018-12-06 11:56:27 +01004611 vc_conn.done;
4612}
4613
Philipp Maier628c0052019-04-09 17:36:57 +02004614/* Simulate an HLR/VLR failure */
4615private function f_tc_sgsap_vlr_failure(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
4616 var octetstring mme_name := f_enc_dns_hostname(mp_mme_name);
4617 var octetstring vlr_name := f_enc_dns_hostname(mp_vlr_name);
4618
4619 var PDU_SGsAP lur;
4620
4621 f_init_handler(pars);
4622
4623 /* Attempt location update (which is expected to fail) */
4624 lur := valueof(ts_SGsAP_LU_REQ(g_pars.imsi, mme_name, IMSI_attach,
4625 ts_SGsAP_LAI('901'H, '70'H, 2342)));
4626 SGsAP.send(lur);
4627
4628 /* Respond to SGsAP-RESET-INDICATION from VLR */
4629 alt {
4630 [] SGsAP.receive(tr_SGsAP_RESET_IND_VLR(vlr_name)); {
4631 SGsAP.send(valueof(ts_SGsAP_RESET_ACK_MME(mme_name)));
4632 setverdict(pass);
4633 }
4634 [] SGsAP.receive {
4635 setverdict(fail, "Received unexpected message on SGs");
4636 }
4637 }
4638
4639 f_sleep(1.0);
4640 setverdict(pass);
4641}
4642testcase TC_sgsap_vlr_failure() runs on MTC_CT {
4643 var BSC_ConnHdlrPars pars;
4644 var BSC_ConnHdlr vc_conn;
4645 f_init(1, true, false);
4646 pars := f_init_pars(11811, true, false);
4647 vc_conn := f_start_handler_with_pars(refers(f_tc_sgsap_vlr_failure), pars);
4648 vc_conn.done;
4649}
4650
Harald Welte4263c522018-12-06 11:56:27 +01004651/* SGs TODO:
4652 * LU attempt for IMSI without NAM_PS in HLR
4653 * LU attempt with AUTH FAIL due to invalid RES/SRES
4654 * LU attempt with no response from HLR (VLR should timeout + LU REJ)
4655 * LU attempt with new TMSI but without TMSI REALL CMPL baco to VLR
4656 * implicit IMSI detach from EPS
4657 * implicit IMSI detach from non-EPS
4658 * MM INFO
4659 *
4660 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01004661
4662control {
Philipp Maier328d1662018-03-07 10:40:27 +01004663 execute( TC_cr_before_reset() );
Harald Weltea49e36e2018-01-21 19:29:33 +01004664 execute( TC_lu_imsi_noauth_tmsi() );
Harald Welted2328a22018-01-27 14:27:16 +01004665 execute( TC_lu_imsi_noauth_notmsi() );
Harald Weltea49e36e2018-01-21 19:29:33 +01004666 execute( TC_lu_imsi_reject() );
4667 execute( TC_lu_imsi_timeout_gsup() );
Harald Welted2328a22018-01-27 14:27:16 +01004668 execute( TC_lu_imsi_auth_tmsi() );
4669 execute( TC_cmserv_imsi_unknown() );
Harald Welte2bb825f2018-01-22 11:31:18 +01004670 execute( TC_lu_and_mo_call() );
Harald Welte071ed732018-01-23 19:53:52 +01004671 execute( TC_lu_auth_sai_timeout() );
4672 execute( TC_lu_auth_sai_err() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01004673 execute( TC_lu_clear_request() );
4674 execute( TC_lu_disconnect() );
4675 execute( TC_lu_by_imei() );
4676 execute( TC_lu_by_tmsi_noauth_unknown() );
4677 execute( TC_imsi_detach_by_imsi() );
4678 execute( TC_imsi_detach_by_tmsi() );
4679 execute( TC_imsi_detach_by_imei() );
4680 execute( TC_emerg_call_imei_reject() );
4681 execute( TC_emerg_call_imsi() );
4682 execute( TC_cm_serv_req_vgcs_reject() );
4683 execute( TC_cm_serv_req_vbs_reject() );
4684 execute( TC_cm_serv_req_lcs_reject() );
Harald Welte0195ab12018-01-24 21:50:20 +01004685 execute( TC_cm_reest_req_reject() );
Harald Welte1af6ea82018-01-25 18:33:15 +01004686 execute( TC_lu_auth_2G_fail() );
4687 execute( TC_lu_imsi_auth_tmsi_encr_13_13() );
4688 execute( TC_cl3_no_payload() );
4689 execute( TC_cl3_rnd_payload() );
Harald Welte1852a842018-01-26 22:53:36 +01004690 execute( TC_establish_and_nothing() );
4691 execute( TC_mo_setup_and_nothing() );
4692 execute( TC_mo_crcx_ran_timeout() );
4693 execute( TC_mo_crcx_ran_reject() );
Harald Welted2328a22018-01-27 14:27:16 +01004694 execute( TC_mt_crcx_ran_reject() );
Daniel Willmann8b084372018-02-04 13:35:26 +01004695 execute( TC_mo_setup_and_dtmf_dup() );
Harald Welteaa54cf82018-01-30 08:15:32 +01004696 //execute( TC_mt_t310() );
Harald Welte167458a2018-01-27 15:58:16 +01004697 execute( TC_gsup_cancel() );
Harald Welte9de84792018-01-28 01:06:35 +01004698 execute( TC_lu_imsi_auth_tmsi_encr_1_13() );
4699 execute( TC_lu_imsi_auth_tmsi_encr_3_13() );
4700 execute( TC_lu_imsi_auth_tmsi_encr_3_1() );
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01004701 execute( TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() );
Harald Welte9de84792018-01-28 01:06:35 +01004702 execute( TC_lu_imsi_auth_tmsi_encr_13_2() );
4703 execute( TC_lu_imsi_auth_tmsi_encr_013_2() );
Philipp Maier94f3f1b2018-03-15 18:54:13 +01004704 execute( TC_mo_release_timeout() );
Philipp Maier2a98a732018-03-19 16:06:12 +01004705 execute( TC_lu_and_mt_call_no_dlcx_resp() );
Philipp Maier75932982018-03-27 14:52:35 +02004706 execute( TC_reset_two() );
Harald Welte33ec09b2018-02-10 15:34:46 +01004707
4708 execute( TC_lu_and_mt_call() );
4709
Harald Weltef45efeb2018-04-09 18:19:24 +02004710 execute( TC_lu_and_mo_sms() );
4711 execute( TC_lu_and_mt_sms() );
Philipp Maier3983e702018-11-22 19:01:33 +01004712 execute( TC_lu_and_mt_sms_paging_and_nothing() );
Harald Weltef640a012018-04-14 17:49:21 +02004713 execute( TC_smpp_mo_sms() );
4714 execute( TC_smpp_mt_sms() );
Harald Weltef45efeb2018-04-09 18:19:24 +02004715
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07004716 execute( TC_gsup_mo_sms() );
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07004717 execute( TC_gsup_mo_smma() );
Vadim Yanitskiyd7b37ab2018-11-24 03:40:20 +07004718 execute( TC_gsup_mt_sms_ack() );
4719 execute( TC_gsup_mt_sms_err() );
Vadim Yanitskiybe1ff4b2019-01-18 15:04:13 +07004720 execute( TC_gsup_mt_sms_rp_mr() );
Vadim Yanitskiy5ac49cc2019-01-24 16:57:31 +07004721 execute( TC_gsup_mo_mt_sms_rp_mr() );
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07004722
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07004723 execute( TC_lu_and_mo_ussd_single_request() );
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07004724 execute( TC_lu_and_mt_ussd_notification() );
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07004725 execute( TC_lu_and_mo_ussd_during_mt_call() );
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07004726 execute( TC_lu_and_mt_ussd_during_mt_call() );
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07004727 execute( TC_lu_and_mo_ussd_mo_release() );
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07004728 execute( TC_lu_and_ss_session_timeout() );
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07004729
Stefan Sperling89eb1f32018-12-17 15:06:20 +01004730 execute( TC_cipher_complete_with_invalid_cipher() );
4731
Harald Welte4263c522018-12-06 11:56:27 +01004732 execute( TC_sgsap_reset() );
4733 execute( TC_sgsap_lu() );
4734 execute( TC_sgsap_lu_imsi_reject() );
4735 execute( TC_sgsap_lu_and_nothing() );
4736 execute( TC_sgsap_expl_imsi_det_eps() );
Philipp Maierfc19f172019-03-21 11:17:54 +01004737 execute( TC_sgsap_impl_imsi_det_eps() );
Harald Welte4263c522018-12-06 11:56:27 +01004738 execute( TC_sgsap_expl_imsi_det_noneps() );
Philipp Maier5d812702019-03-21 10:51:26 +01004739 execute( TC_sgsap_impl_imsi_det_noneps() );
Harald Welte4263c522018-12-06 11:56:27 +01004740 execute( TC_sgsap_paging_rej() );
4741 execute( TC_sgsap_paging_subscr_rej() );
4742 execute( TC_sgsap_paging_ue_unr() );
4743 execute( TC_sgsap_paging_and_nothing() );
4744 execute( TC_sgsap_paging_and_lu() );
4745 execute( TC_sgsap_mt_sms() );
4746 execute( TC_sgsap_mo_sms() );
4747 execute( TC_sgsap_mt_sms_and_nothing() );
4748 execute( TC_sgsap_mt_sms_and_reject() );
4749 execute( TC_sgsap_unexp_ud() );
4750 execute( TC_sgsap_unsol_ud() );
4751 execute( TC_bssap_lu_sgsap_lu_and_mt_call() );
4752 execute( TC_sgsap_lu_and_mt_call() );
Philipp Maier628c0052019-04-09 17:36:57 +02004753 execute( TC_sgsap_vlr_failure() );
Harald Welte4263c522018-12-06 11:56:27 +01004754
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01004755 /* Run this last: at the time of writing this test crashes the MSC */
4756 execute( TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() );
Philipp Maierdb7fb8d2019-02-11 10:50:13 +01004757 execute( TC_gsup_mt_multi_part_sms() );
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02004758 execute( TC_mo_cc_bssmap_clear() );
Harald Weltef6dd64d2017-11-19 12:09:51 +01004759}
4760
4761
4762}