blob: 0ac61bc0e48d322d25438a693f53975db3cb83e8 [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 Weltea49e36e2018-01-21 19:29:33 +010039import from BSSAP_Adapter all;
40import from BSSAP_CodecPort all;
41import from BSSMAP_Templates all;
42import from BSSMAP_Emulation all;
43import from BSC_ConnectionHandler all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010044
Harald Weltea49e36e2018-01-21 19:29:33 +010045import from MobileL3_Types all;
46import from MobileL3_CommonIE_Types all;
47import from L3_Templates all;
Harald Welte158a7ca2018-02-16 18:11:31 +010048import from L3_Common all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010049
Harald Weltef640a012018-04-14 17:49:21 +020050import from SMPP_Types all;
51import from SMPP_Templates all;
52import from SMPP_Emulation all;
53
Stefan Sperlingc307e682018-06-14 15:15:46 +020054import from SCCP_Templates all;
55
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +070056import from SS_Types all;
57import from SS_Templates all;
58import from USSD_Helpers all;
59
Philipp Maier75932982018-03-27 14:52:35 +020060const integer NUM_BSC := 2;
61type record of BSSAP_Configuration BSSAP_Configurations;
Harald Weltef6dd64d2017-11-19 12:09:51 +010062
Harald Weltea4ca4462018-02-09 00:17:14 +010063type component MTC_CT extends CTRL_Adapter_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +010064 var boolean g_initialized := false;
Harald Weltea49e36e2018-01-21 19:29:33 +010065
Philipp Maier75932982018-03-27 14:52:35 +020066 var BSSAP_Adapter g_bssap[NUM_BSC];
Harald Weltea4ca4462018-02-09 00:17:14 +010067
Harald Weltea49e36e2018-01-21 19:29:33 +010068 /* no 'adapter_CT' for MNCC or GSUP */
69 var MNCC_Emulation_CT vc_MNCC;
Harald Welte4aa970c2018-01-26 10:38:09 +010070 var MGCP_Emulation_CT vc_MGCP;
Harald Weltea49e36e2018-01-21 19:29:33 +010071 var GSUP_Emulation_CT vc_GSUP;
72 var IPA_Emulation_CT vc_GSUP_IPA;
Harald Weltef640a012018-04-14 17:49:21 +020073 var SMPP_Emulation_CT vc_SMPP;
Harald Weltea49e36e2018-01-21 19:29:33 +010074
75 /* only to get events from IPA underneath GSUP */
76 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte3ca1c902018-01-24 18:51:27 +010077 /* VTY to MSC */
78 port TELNETasp_PT MSCVTY;
Philipp Maier328d1662018-03-07 10:40:27 +010079
80 /* A port to directly send BSSAP messages. This port is used for
81 * tests that require low level access to sen arbitrary BSSAP
82 * messages. Run f_init_bssap_direct() to connect and initialize */
83 port BSSAP_CODEC_PT BSSAP_DIRECT;
84
85 /* When BSSAP messages are directly sent, then the connection
86 * handler is not active, which means that also no guard timer is
87 * set up. The following timer will serve as a replacement */
88 timer Tguard_direct := 60.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +010089}
90
91modulepar {
Harald Weltea49e36e2018-01-21 19:29:33 +010092 /* remote parameters of IUT */
93 charstring mp_msc_ip := "127.0.0.1";
94 integer mp_msc_ctrl_port := 4255;
95 integer mp_msc_vty_port := 4254;
Harald Weltef6dd64d2017-11-19 12:09:51 +010096
Harald Weltea49e36e2018-01-21 19:29:33 +010097 /* local parameters of emulated HLR */
Philipp Maier9b690e42018-12-21 11:50:03 +010098 boolean mp_mm_info := false;
Harald Weltea49e36e2018-01-21 19:29:33 +010099 charstring mp_hlr_ip := "127.0.0.1";
100 integer mp_hlr_port := 4222;
Harald Welte6126fb02018-01-27 20:08:24 +0100101 charstring mp_mgw_ip := "127.0.0.1";
102 integer mp_mgw_port := 2427;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100103
Harald Weltea49e36e2018-01-21 19:29:33 +0100104 charstring mp_msc_mncc := "/tmp/mncc";
Harald Weltea4ca4462018-02-09 00:17:14 +0100105
Harald Weltef640a012018-04-14 17:49:21 +0200106 integer mp_msc_smpp_port := 2775;
107 charstring mp_smpp_system_id := "msc_tester";
108 charstring mp_smpp_password := "osmocom1";
109
Philipp Maier75932982018-03-27 14:52:35 +0200110 BSSAP_Configurations mp_bssap_cfg := {
111 {
112 sccp_service_type := "mtp3_itu",
113 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
114 own_pc := 185,
115 own_ssn := 254,
116 peer_pc := 187,
117 peer_ssn := 254,
118 sio := '83'O,
119 rctx := 0
120 },
121 {
122 sccp_service_type := "mtp3_itu",
123 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
124 own_pc := 186,
125 own_ssn := 254,
126 peer_pc := 187,
127 peer_ssn := 254,
128 sio := '83'O,
129 rctx := 1
130 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100131 };
Harald Weltef6dd64d2017-11-19 12:09:51 +0100132}
133
Philipp Maier328d1662018-03-07 10:40:27 +0100134/* altstep for the global guard timer (only used when BSSAP_DIRECT
135 * is used for communication */
136private altstep as_Tguard_direct() runs on MTC_CT {
137 [] Tguard_direct.timeout {
138 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200139 mtc.stop;
Philipp Maier328d1662018-03-07 10:40:27 +0100140 }
141}
Harald Weltef6dd64d2017-11-19 12:09:51 +0100142
Harald Weltef640a012018-04-14 17:49:21 +0200143function f_init_smpp(charstring id) runs on MTC_CT {
144 id := id & "-SMPP";
145 var EsmePars pars := {
146 mode := MODE_TRANSCEIVER,
147 bind := {
148 system_id := mp_smpp_system_id,
149 password := mp_smpp_password,
150 system_type := "MSC_Tests",
151 interface_version := hex2int('34'H),
152 addr_ton := unknown,
153 addr_npi := unknown,
154 address_range := ""
155 },
156 esme_role := true
157 }
158
159 vc_SMPP := SMPP_Emulation_CT.create(id);
160 map(vc_SMPP:SMPP_PORT, system:SMPP_PORT);
161 vc_SMPP.start(SMPP_Emulation.main_client(pars, mp_msc_ip, mp_msc_smpp_port, "", -1));
162}
163
164
Harald Weltea49e36e2018-01-21 19:29:33 +0100165function f_init_mncc(charstring id) runs on MTC_CT {
166 id := id & "-MNCC";
167 var MnccOps ops := {
168 create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
169 unitdata_cb := refers(MNCC_Emulation.DummyUnitdataCallback)
170 }
171
172 vc_MNCC := MNCC_Emulation_CT.create(id);
173 map(vc_MNCC:MNCC, system:MNCC_CODEC_PT);
174 vc_MNCC.start(MNCC_Emulation.main(ops, id, mp_msc_mncc));
Harald Weltef6dd64d2017-11-19 12:09:51 +0100175}
176
Harald Welte4aa970c2018-01-26 10:38:09 +0100177function f_init_mgcp(charstring id) runs on MTC_CT {
178 id := id & "-MGCP";
179 var MGCPOps ops := {
180 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
181 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
182 }
183 var MGCP_conn_parameters pars := {
Harald Welte6126fb02018-01-27 20:08:24 +0100184 callagent_ip := mp_msc_ip,
Harald Welte4aa970c2018-01-26 10:38:09 +0100185 callagent_udp_port := -1,
Harald Welte6126fb02018-01-27 20:08:24 +0100186 mgw_ip := mp_mgw_ip,
187 mgw_udp_port := mp_mgw_port
Harald Welte4aa970c2018-01-26 10:38:09 +0100188 }
189
190 vc_MGCP := MGCP_Emulation_CT.create(id);
191 map(vc_MGCP:MGCP, system:MGCP_CODEC_PT);
192 vc_MGCP.start(MGCP_Emulation.main(ops, pars, id));
193}
194
Harald Weltea49e36e2018-01-21 19:29:33 +0100195function f_init_gsup(charstring id) runs on MTC_CT {
196 id := id & "-GSUP";
197 var GsupOps ops := {
198 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
199 }
200
201 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
202 vc_GSUP := GSUP_Emulation_CT.create(id);
203
204 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
205 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
206 /* we use this hack to get events like ASP_IPA_EVENT_UP */
207 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
208
209 vc_GSUP.start(GSUP_Emulation.main(ops, id));
210 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
211
212 /* wait for incoming connection to GSUP port before proceeding */
213 timer T := 10.0;
214 T.start;
215 alt {
216 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
217 [] T.timeout {
Harald Welte458fd372018-03-21 11:26:23 +0100218 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200219 mtc.stop
Harald Weltea49e36e2018-01-21 19:29:33 +0100220 }
221 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100222}
223
Philipp Maier75932982018-03-27 14:52:35 +0200224function f_init(integer num_bsc := 1) runs on MTC_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +0100225
226 if (g_initialized == true) {
227 return;
228 }
229 g_initialized := true;
230
Philipp Maier75932982018-03-27 14:52:35 +0200231 if (num_bsc > NUM_BSC) {
Daniel Willmannafce8662018-07-06 23:11:32 +0200232 testcase.stop("excess number of BSC instances requested");
Philipp Maier75932982018-03-27 14:52:35 +0200233 }
234
235 for (var integer i := 0; i < num_bsc; i := i + 1) {
236 if (isbound(mp_bssap_cfg[i])) {
Philipp Maierdefd9482018-05-16 16:44:37 +0200237 f_bssap_init(g_bssap[i], mp_bssap_cfg[i], "MSC_Test_" & int2str(i), BSC_BssmapOps);
Harald Welted5833a82018-05-27 16:52:56 +0200238 f_bssap_start(g_bssap[i]);
Philipp Maier75932982018-03-27 14:52:35 +0200239 } else {
Daniel Willmannafce8662018-07-06 23:11:32 +0200240 testcase.stop("missing BSSAP configuration");
Philipp Maier75932982018-03-27 14:52:35 +0200241 }
242 }
243
Harald Weltea49e36e2018-01-21 19:29:33 +0100244 f_ipa_ctrl_start(mp_msc_ip, mp_msc_ctrl_port);
245 f_init_mncc("MSC_Test");
Harald Welte4aa970c2018-01-26 10:38:09 +0100246 f_init_mgcp("MSC_Test");
Harald Weltea49e36e2018-01-21 19:29:33 +0100247 f_init_gsup("MSC_Test");
Harald Weltef640a012018-04-14 17:49:21 +0200248 f_init_smpp("MSC_Test");
Harald Welte3ca1c902018-01-24 18:51:27 +0100249
250 map(self:MSCVTY, system:MSCVTY);
251 f_vty_set_prompts(MSCVTY);
252 f_vty_transceive(MSCVTY, "enable");
Harald Welteb14c77a2018-01-25 17:25:44 +0100253
254 /* set some defaults */
255 f_vty_config(MSCVTY, "network", "authentication optional");
256 f_vty_config(MSCVTY, "msc", "assign-tmsi");
257 f_vty_config(MSCVTY, "network", "encryption a5 0");
Harald Weltef6dd64d2017-11-19 12:09:51 +0100258}
259
Philipp Maier328d1662018-03-07 10:40:27 +0100260/* Initialize for a direct connection to BSSAP. This function is an alternative
261 * to f_init() when the high level functions of the BSC_ConnectionHandler are
262 * not needed. */
263function f_init_bssap_direct() runs on MTC_CT {
Philipp Maier75932982018-03-27 14:52:35 +0200264 f_bssap_init(g_bssap[0], mp_bssap_cfg[0], "MSC_Test", omit);
265 connect(g_bssap[0].vc_SCCP:SCCP_SP_PORT, self:BSSAP_DIRECT);
Philipp Maier328d1662018-03-07 10:40:27 +0100266
267 /* Start guard timer and activate it as default */
268 Tguard_direct.start
269 activate(as_Tguard_direct());
270}
271
Harald Weltef6dd64d2017-11-19 12:09:51 +0100272template PDU_BSSAP ts_BSSAP_BSSMAP := {
273 discriminator := '0'B,
274 spare := '0000000'B,
275 dlci := omit,
276 lengthIndicator := 0, /* overwritten by codec */
277 pdu := ?
278}
279
280template PDU_BSSAP tr_BSSAP_BSSMAP := {
281 discriminator := '0'B,
282 spare := '0000000'B,
283 dlci := omit,
284 lengthIndicator := ?,
285 pdu := {
286 bssmap := ?
287 }
288}
289
290
291type integer BssmapCause;
292
293template (value) BSSMAP_IE_Cause ts_BSSMAP_IE_Cause(BssmapCause val) := {
294 elementIdentifier := '04'O,
295 lengthIndicator := 0,
296 causeValue := int2bit(val, 7),
297 extensionCauseValue := '0'B,
298 spare1 := omit
299}
300
301template (value) PDU_BSSAP ts_BSSMAP_Reset(BssmapCause cause) modifies ts_BSSAP_BSSMAP := {
302 pdu := {
303 bssmap := {
304 reset := {
305 messageType := '30'O,
306 cause := ts_BSSMAP_IE_Cause(cause),
307 a_InterfaceSelectorForReset := omit
308 }
309 }
310 }
311}
312
313template (value) PDU_BSSAP ts_BSSMAP_ResetAck modifies ts_BSSAP_BSSMAP := {
314 pdu := {
315 bssmap := {
316 resetAck := {
317 messageType := '31'O,
318 a_InterfaceSelectorForReset := omit
319 }
320 }
321 }
322}
323
324template PDU_BSSAP tr_BSSMAP_ResetAck modifies tr_BSSAP_BSSMAP := {
325 pdu := {
326 bssmap := {
327 resetAck := {
328 messageType := '31'O,
329 a_InterfaceSelectorForReset := *
330 }
331 }
332 }
333}
334
335template BSSMAP_IE_CellIdentifier ts_BSSMAP_IE_CellID := {
336 elementIdentifier := '05'O,
337 lengthIndicator := 0,
338 cellIdentifierDiscriminator := '0000'B,
339 spare1_4 := '0000'B,
340 cellIdentification := ?
341}
342
343type uint16_t BssmapLAC;
344type uint16_t BssmapCI;
345
346/*
347template BSSMAP_IE_CellIdentifier ts_CellId_CGI(mcc, mnc, lac, ci)
348modifies ts_BSSMAP_IE_CellID := {
349 cellIdentification := {
350 cI_LAC_CGI := {
351 mnc_mcc := FIXME,
352 lac := int2oct(lac, 2),
353 ci := int2oct(ci, 2)
354 }
355 }
356}
357*/
358
359template BSSMAP_IE_CellIdentifier ts_CellID_LAC_CI(BssmapLAC lac, BssmapCI ci)
360modifies ts_BSSMAP_IE_CellID := {
361 cellIdentification := {
362 cI_LAC_CI := {
363 lac := int2oct(lac, 2),
364 ci := int2oct(ci, 2)
365 }
366 }
367}
368
369template BSSMAP_IE_CellIdentifier ts_CellId_CI(BssmapCI ci)
370modifies ts_BSSMAP_IE_CellID := {
371 cellIdentification := {
372 cI_CI := int2oct(ci, 2)
373 }
374}
375
376template BSSMAP_IE_CellIdentifier ts_CellId_none
377modifies ts_BSSMAP_IE_CellID := {
378 cellIdentification := {
379 cI_noCell := ''O
380 }
381}
382
383
384template BSSMAP_IE_Layer3Information ts_BSSMAP_IE_L3Info(octetstring l3info) := {
385 elementIdentifier := '17'O,
386 lengthIndicator := 0,
387 layer3info := l3info
388}
389
390template PDU_BSSAP ts_BSSMAP_ComplL3(BSSMAP_IE_CellIdentifier cell_id, octetstring l3_info)
391modifies ts_BSSAP_BSSMAP := {
392 pdu := {
393 bssmap := {
394 completeLayer3Information := {
395 messageType := '57'O,
396 cellIdentifier := cell_id,
397 layer3Information := ts_BSSMAP_IE_L3Info(l3_info),
398 chosenChannel := omit,
399 lSAIdentifier := omit,
400 aPDU := omit,
401 codecList := omit,
402 redirectAttemptFlag := omit,
403 sendSequenceNumber := omit,
404 iMSI := omit
405 }
406 }
407 }
408}
409
410template PDU_BSSAP ts_BSSMAP_HandoReq(BssmapCause cause, BSSMAP_IE_CellIdentifierList cid_list)
411modifies ts_BSSAP_BSSMAP := {
412 pdu := {
413 bssmap := {
414 handoverRequired := {
415 messageType := '11'O,
416 cause := ts_BSSMAP_IE_Cause(cause),
417 responseRequest := omit,
418 cellIdentifierList := cid_list,
419 circuitPoolList := omit,
420 currentChannelType1 := omit,
421 speechVersion := omit,
422 queueingIndicator := omit,
423 oldToNewBSSInfo := omit,
424 sourceToTargetRNCTransparentInfo := omit,
425 sourceToTargetRNCTransparentInfoCDMA := omit,
426 gERANClassmark := omit,
427 talkerPriority := omit,
428 speechCodec := omit,
429 cSG_Identifier := omit
430 }
431 }
432 }
433}
434
Harald Weltea49e36e2018-01-21 19:29:33 +0100435type function void_fn(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100436
Harald Weltea49e36e2018-01-21 19:29:33 +0100437/* FIXME: move into BSC_ConnectionHandler? */
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100438function f_init_pars(integer imsi_suffix) runs on MTC_CT return BSC_ConnHdlrPars {
Harald Weltede371492018-01-27 23:44:41 +0100439 var BSC_ConnHdlrNetworkPars net_pars := {
440 kc_support := '0A'O, /* A5/1 and A5/3 enabled */
441 expect_tmsi := true,
442 expect_auth := false,
443 expect_ciph := false
444 };
Harald Weltea49e36e2018-01-21 19:29:33 +0100445 var BSC_ConnHdlrPars pars := {
Philipp Maier75932982018-03-27 14:52:35 +0200446 sccp_addr_own := g_bssap[0].sccp_addr_own,
447 sccp_addr_peer := g_bssap[0].sccp_addr_peer,
Harald Welteedbab812018-03-18 16:02:25 +0100448 cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42)),
Harald Welte81b7f9d2018-01-24 19:06:24 +0100449 imei := f_gen_imei(imsi_suffix),
450 imsi := f_gen_imsi(imsi_suffix),
451 msisdn := f_gen_msisdn(imsi_suffix),
Harald Welte256571e2018-01-24 18:47:19 +0100452 tmsi := omit,
Harald Welte9de84792018-01-28 01:06:35 +0100453 cm1 := valueof(ts_CM1),
Harald Welte82600572018-01-21 20:54:08 +0100454 cm2 := valueof(ts_CM2_default),
Harald Welte16114282018-01-24 22:41:21 +0100455 cm3 := omit,
Harald Weltede371492018-01-27 23:44:41 +0100456 vec := omit,
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100457 net := net_pars,
Philipp Maieraeb29a82018-11-08 17:40:53 +0100458 send_early_cm := true,
459 ipa_ctrl_ip := mp_msc_ip,
460 ipa_ctrl_port := mp_msc_ctrl_port,
Philipp Maier9b690e42018-12-21 11:50:03 +0100461 ipa_ctrl_enable := true,
462 mm_info := mp_mm_info
Harald Weltea49e36e2018-01-21 19:29:33 +0100463 };
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100464 return pars;
465}
466
467function f_start_handler_with_pars(void_fn fn, BSC_ConnHdlrPars pars) runs on MTC_CT return BSC_ConnHdlr {
468 var BSC_ConnHdlr vc_conn;
469 var charstring id := testcasename();
Harald Weltea49e36e2018-01-21 19:29:33 +0100470
471 vc_conn := BSC_ConnHdlr.create(id);
472 /* BSSMAP part / A interface */
Philipp Maier75932982018-03-27 14:52:35 +0200473 connect(vc_conn:BSSAP, g_bssap[0].vc_BSSMAP:CLIENT);
474 connect(vc_conn:BSSAP_PROC, g_bssap[0].vc_BSSMAP:PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100475 /* MNCC part */
476 connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
477 connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);
Harald Welte4aa970c2018-01-26 10:38:09 +0100478 /* MGCP part */
479 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
480 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100481 /* GSUP part */
482 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
483 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
Harald Weltef640a012018-04-14 17:49:21 +0200484 /* SMPP part */
485 connect(vc_conn:SMPP, vc_SMPP:SMPP_CLIENT);
486 connect(vc_conn:SMPP_PROC, vc_SMPP:SMPP_PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100487
Harald Weltea10db902018-01-27 12:44:49 +0100488 /* We cannot use vc_conn.start(f_init_handler(fn, id, pars)); as we cannot have
489 * a stand-alone 'derefers()' call, see https://www.eclipse.org/forums/index.php/t/1091364/ */
Harald Weltea49e36e2018-01-21 19:29:33 +0100490 vc_conn.start(derefers(fn)(id, pars));
491 return vc_conn;
492}
493
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100494function f_start_handler(void_fn fn, integer imsi_suffix) runs on MTC_CT return BSC_ConnHdlr {
495 return f_start_handler_with_pars(fn, f_init_pars(imsi_suffix));
496}
497
Harald Weltea49e36e2018-01-21 19:29:33 +0100498private function f_tc_lu_imsi_noauth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100499 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100500 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100501}
Harald Weltea49e36e2018-01-21 19:29:33 +0100502testcase TC_lu_imsi_noauth_tmsi() runs on MTC_CT {
503 var BSC_ConnHdlr vc_conn;
504 f_init();
505
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100506 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi), 1);
Harald Weltea49e36e2018-01-21 19:29:33 +0100507 vc_conn.done;
508}
509
510private function f_tc_lu_imsi_noauth_notmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100511 pars.net.expect_tmsi := false;
Harald Weltea10db902018-01-27 12:44:49 +0100512 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100513 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100514}
Harald Weltea49e36e2018-01-21 19:29:33 +0100515testcase TC_lu_imsi_noauth_notmsi() runs on MTC_CT {
516 var BSC_ConnHdlr vc_conn;
517 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100518 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
Harald Weltea49e36e2018-01-21 19:29:33 +0100519
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100520 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi), 2);
Harald Weltea49e36e2018-01-21 19:29:33 +0100521 vc_conn.done;
522}
523
524/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
525private function f_tc_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100526 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100527 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
528
529 f_create_gsup_expect(hex2str(g_pars.imsi));
530 f_bssap_compl_l3(l3_lu);
531 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
532 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
533 alt {
Harald Welte5946b332018-03-18 23:32:21 +0100534 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej(int2oct(23,1)))) {
535 f_expect_clear();
536 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100537 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
538 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
Daniel Willmannafce8662018-07-06 23:11:32 +0200539 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100540 }
541 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100542}
543testcase TC_lu_imsi_reject() runs on MTC_CT {
544 var BSC_ConnHdlr vc_conn;
545 f_init();
546
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100547 vc_conn := f_start_handler(refers(f_tc_lu_imsi_reject), 3);
Harald Weltea49e36e2018-01-21 19:29:33 +0100548 vc_conn.done;
549}
550
551/* Do LU by IMSI, timeout on GSUP */
552private function f_tc_lu_imsi_timeout_gsup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100553 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100554 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
555
556 f_create_gsup_expect(hex2str(g_pars.imsi));
557 f_bssap_compl_l3(l3_lu);
558 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
559 /* Normally the HLR would need to respond here, but we decide to force a timeout here */
560 alt {
561 /* FIXME: Expect specific reject cause */
Harald Welte5946b332018-03-18 23:32:21 +0100562 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
563 f_expect_clear();
564 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100565 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
566 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
Daniel Willmannafce8662018-07-06 23:11:32 +0200567 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100568 }
569 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100570}
571testcase TC_lu_imsi_timeout_gsup() runs on MTC_CT {
572 var BSC_ConnHdlr vc_conn;
573 f_init();
574
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100575 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_gsup), 4);
Harald Weltea49e36e2018-01-21 19:29:33 +0100576 vc_conn.done;
577}
578
Harald Welte7b1b2812018-01-22 21:23:06 +0100579private function f_tc_lu_imsi_auth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100580 pars.net.expect_auth := true;
Harald Weltea10db902018-01-27 12:44:49 +0100581 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100582 f_perform_lu();
Harald Welte7b1b2812018-01-22 21:23:06 +0100583}
584testcase TC_lu_imsi_auth_tmsi() runs on MTC_CT {
585 var BSC_ConnHdlr vc_conn;
586 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100587 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte7b1b2812018-01-22 21:23:06 +0100588
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100589 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi), 5);
Harald Welte7b1b2812018-01-22 21:23:06 +0100590 vc_conn.done;
591}
592
Harald Weltea49e36e2018-01-21 19:29:33 +0100593
594/* Send CM SERVICE REQ for IMSI that has never performed LU before */
595private function f_tc_cmserv_imsi_unknown(charstring id, BSC_ConnHdlrPars pars)
596runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100597 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100598
599 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welteedbab812018-03-18 16:02:25 +0100600 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100601 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltea49e36e2018-01-21 19:29:33 +0100602
603 f_create_gsup_expect(hex2str(g_pars.imsi));
604
605 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
606 f_bssap_compl_l3(l3_info);
607
608 timer T := 10.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100609 T.start;
610 alt {
Harald Weltea49e36e2018-01-21 19:29:33 +0100611 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
612 //[] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC)) { }
Daniel Willmannafce8662018-07-06 23:11:32 +0200613 [] BSSAP.receive {
614 setverdict(fail, "Received unexpected BSSAP");
615 mtc.stop;
616 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100617 [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
618 setverdict(fail, "Unexpected GSUP UL REQ");
Daniel Willmannafce8662018-07-06 23:11:32 +0200619 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100620 }
Daniel Willmannafce8662018-07-06 23:11:32 +0200621 [] T.timeout {
622 setverdict(fail, "Timeout waiting for CM SERV REQ");
623 mtc.stop;
624 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100625 }
626
Harald Welte1ddc7162018-01-27 14:25:46 +0100627 f_expect_clear();
Harald Weltef6dd64d2017-11-19 12:09:51 +0100628}
Harald Weltea49e36e2018-01-21 19:29:33 +0100629testcase TC_cmserv_imsi_unknown() runs on MTC_CT {
630 var BSC_ConnHdlr vc_conn;
631 f_init();
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100632 vc_conn := f_start_handler(refers(f_tc_cmserv_imsi_unknown), 6);
Harald Weltea49e36e2018-01-21 19:29:33 +0100633 vc_conn.done;
634}
635
Harald Welte2bb825f2018-01-22 11:31:18 +0100636private function f_tc_lu_and_mo_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100637 f_init_handler(pars);
Harald Welteb71901a2018-01-26 19:16:05 +0100638 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
639 cpars.bss_rtp_port := 1110;
640 cpars.mgcp_connection_id_bss := '22222'H;
641 cpars.mgcp_connection_id_mss := '33333'H;
Philipp Maierf1e02bb2018-03-15 16:30:00 +0100642 cpars.mgcp_ep := "rtpbridge/1@mgw";
Harald Welte2bb825f2018-01-22 11:31:18 +0100643
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100644 f_perform_lu();
Harald Welteb71901a2018-01-26 19:16:05 +0100645 f_mo_call(cpars);
Harald Welte2bb825f2018-01-22 11:31:18 +0100646}
647testcase TC_lu_and_mo_call() runs on MTC_CT {
648 var BSC_ConnHdlr vc_conn;
649 f_init();
650
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100651 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_call), 7);
Harald Welte071ed732018-01-23 19:53:52 +0100652 vc_conn.done;
653}
654
655/* Test LU (with authentication enabled), where HLR times out sending SAI response */
656private function f_tc_lu_auth_sai_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100657 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100658
659 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
660 var PDU_DTAP_MT dtap_mt;
661
662 /* tell GSUP dispatcher to send this IMSI to us */
663 f_create_gsup_expect(hex2str(g_pars.imsi));
664
665 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
666 f_bssap_compl_l3(l3_lu);
667
668 /* Send Early Classmark, just for the fun of it */
669 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
670
671 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
672 /* The HLR would normally return an auth vector here, but we fail to do so. */
673
674 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100675 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100676}
677testcase TC_lu_auth_sai_timeout() runs on MTC_CT {
678 var BSC_ConnHdlr vc_conn;
679 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100680 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100681
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100682 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_timeout), 8);
Harald Welte071ed732018-01-23 19:53:52 +0100683 vc_conn.done;
684}
685
686/* Test LU (with authentication enabled), where HLR rejects sending SAI error */
687private function f_tc_lu_auth_sai_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100688 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100689
690 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
691 var PDU_DTAP_MT dtap_mt;
692
693 /* tell GSUP dispatcher to send this IMSI to us */
694 f_create_gsup_expect(hex2str(g_pars.imsi));
695
696 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
697 f_bssap_compl_l3(l3_lu);
698
699 /* Send Early Classmark, just for the fun of it */
700 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
701
702 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
703 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 13));
704
705 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100706 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100707}
708testcase TC_lu_auth_sai_err() runs on MTC_CT {
709 var BSC_ConnHdlr vc_conn;
710 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100711 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100712
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100713 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_err), 9);
Harald Welte2bb825f2018-01-22 11:31:18 +0100714 vc_conn.done;
715}
Harald Weltea49e36e2018-01-21 19:29:33 +0100716
Harald Weltebc881782018-01-23 20:09:15 +0100717/* Test LU but BSC will send a clear request in the middle */
718private function f_tc_lu_clear_request(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100719 f_init_handler(pars);
Harald Weltebc881782018-01-23 20:09:15 +0100720
721 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
722 var PDU_DTAP_MT dtap_mt;
723
724 /* tell GSUP dispatcher to send this IMSI to us */
725 f_create_gsup_expect(hex2str(g_pars.imsi));
726
727 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
728 f_bssap_compl_l3(l3_lu);
729
730 /* Send Early Classmark, just for the fun of it */
731 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
732
733 f_sleep(1.0);
734 /* send clear request in the middle of the LU */
735 BSSAP.send(ts_BSSMAP_ClearRequest(0));
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200736 alt {
737 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { repeat; }
738 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {}
739 }
Harald Weltebc881782018-01-23 20:09:15 +0100740 BSSAP.send(ts_BSSMAP_ClearComplete);
Harald Welte89a32492018-01-27 19:07:28 +0100741 alt {
742 /* See https://osmocom.org/issues/2862 */
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200743 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
744 setverdict(fail, "Got a second Clear Command, only one expected");
Daniel Willmannafce8662018-07-06 23:11:32 +0200745 mtc.stop;
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200746 repeat;
747 }
Harald Welte89a32492018-01-27 19:07:28 +0100748 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
749 }
Harald Weltebc881782018-01-23 20:09:15 +0100750 setverdict(pass);
751}
752testcase TC_lu_clear_request() runs on MTC_CT {
753 var BSC_ConnHdlr vc_conn;
754 f_init();
755
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100756 vc_conn := f_start_handler(refers(f_tc_lu_clear_request), 10);
Harald Weltebc881782018-01-23 20:09:15 +0100757 vc_conn.done;
758}
759
Harald Welte66af9e62018-01-24 17:28:21 +0100760/* Test LU but BSC will send a clear request in the middle */
761private function f_tc_lu_disconnect(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100762 f_init_handler(pars);
Harald Welte66af9e62018-01-24 17:28:21 +0100763
764 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
765 var PDU_DTAP_MT dtap_mt;
766
767 /* tell GSUP dispatcher to send this IMSI to us */
768 f_create_gsup_expect(hex2str(g_pars.imsi));
769
770 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
771 f_bssap_compl_l3(l3_lu);
772
773 /* Send Early Classmark, just for the fun of it */
774 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
775
776 f_sleep(1.0);
777 /* send clear request in the middle of the LU */
778 BSSAP.send(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
779 setverdict(pass);
780}
781testcase TC_lu_disconnect() runs on MTC_CT {
782 var BSC_ConnHdlr vc_conn;
783 f_init();
784
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100785 vc_conn := f_start_handler(refers(f_tc_lu_disconnect), 11);
Harald Welte66af9e62018-01-24 17:28:21 +0100786 vc_conn.done;
787}
788
789
Harald Welteba7b6d92018-01-23 21:32:34 +0100790/* Test LU but with illegal mobile identity type = IMEI */
791private function f_tc_lu_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100792 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100793
Harald Welte256571e2018-01-24 18:47:19 +0100794 var PDU_ML3_MS_NW l3_lu := f_build_lu_imei(g_pars.imei)
Harald Welteba7b6d92018-01-23 21:32:34 +0100795 var PDU_DTAP_MT dtap_mt;
796
797 /* tell GSUP dispatcher to send this IMSI to us */
798 f_create_gsup_expect(hex2str(g_pars.imsi));
799
800 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
801 f_bssap_compl_l3(l3_lu);
802
803 /* Send Early Classmark, just for the fun of it */
804 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
805 /* wait for LU reject, ignore any ID REQ */
806 alt {
807 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
808 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req)) { repeat; }
809 }
810 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100811 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100812}
813testcase TC_lu_by_imei() 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_by_imei), 12);
Harald Welteba7b6d92018-01-23 21:32:34 +0100818 vc_conn.done;
819}
820
821/* Test LU by TMSI with unknown TMSI, expect (and answer) ID REQ. */
822private function f_tc_lu_tmsi_noauth_unknown(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Stefan Sperling04fc4bc2018-06-25 17:44:57 +0200823 /* We piggyback a test for an MSC crash on overlong IMSI (OS#2864) onto this test. */
824 var hexstring overlong_imsi := '012345789ABCDEF0123456789ABCDEF'H;
Harald Weltea10db902018-01-27 12:44:49 +0100825 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100826
827 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('01020304'O); /* FIXME: Random */
828 var PDU_DTAP_MT dtap_mt;
829
830 /* tell GSUP dispatcher to send this IMSI to us */
831 f_create_gsup_expect(hex2str(g_pars.imsi));
832
833 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
834 f_bssap_compl_l3(l3_lu);
835
836 /* Send Early Classmark, just for the fun of it */
837 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
838
839 /* Wait for + respond to ID REQ (IMSI) */
840 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req('001'B)));
Stefan Sperling04fc4bc2018-06-25 17:44:57 +0200841 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 +0100842 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
843
844 /* Expect MSC to do UpdateLocation to HLR; respond to it */
845 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
846 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
847 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
848 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
849
850 alt {
Harald Welte7ec4fa82018-01-27 10:57:40 +0100851 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
852 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
853 }
Harald Welteba7b6d92018-01-23 21:32:34 +0100854 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
855 setverdict(fail, "Expected LU ACK, but received REJ");
Daniel Willmannafce8662018-07-06 23:11:32 +0200856 mtc.stop;
Harald Welteba7b6d92018-01-23 21:32:34 +0100857 }
858 }
859
Philipp Maier9b690e42018-12-21 11:50:03 +0100860 /* Wait for MM-Information (if enabled) */
861 f_expect_mm_info();
862
Harald Welteba7b6d92018-01-23 21:32:34 +0100863 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100864 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100865}
866testcase TC_lu_by_tmsi_noauth_unknown() runs on MTC_CT {
867 var BSC_ConnHdlr vc_conn;
868 f_init();
869
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100870 vc_conn := f_start_handler(refers(f_tc_lu_tmsi_noauth_unknown), 13);
Harald Welteba7b6d92018-01-23 21:32:34 +0100871 vc_conn.done;
872}
873
874
Harald Welte45164da2018-01-24 12:51:27 +0100875/* Test IMSI DETACH (MI=IMSI) */
876private function f_tc_imsi_detach_by_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100877 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100878
879 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
880
881 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
882 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
883
884 /* Send Early Classmark, just for the fun of it? */
885 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
886
887 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100888 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100889}
890testcase TC_imsi_detach_by_imsi() runs on MTC_CT {
891 var BSC_ConnHdlr vc_conn;
892 f_init();
893
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100894 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imsi), 14);
Harald Welte45164da2018-01-24 12:51:27 +0100895 vc_conn.done;
896}
897
898/* Test IMSI DETACH (MI=TMSI) */
899private function f_tc_imsi_detach_by_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100900 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100901
902 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('01020304'O));
903
904 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
905 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
906
907 /* Send Early Classmark, just for the fun of it? */
908 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
909
910 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100911 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100912}
913testcase TC_imsi_detach_by_tmsi() runs on MTC_CT {
914 var BSC_ConnHdlr vc_conn;
915 f_init();
916
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100917 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_tmsi), 15);
Harald Welte45164da2018-01-24 12:51:27 +0100918 vc_conn.done;
919}
920
921/* Test IMSI DETACH (MI=IMEI), which is illegal */
922private function f_tc_imsi_detach_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100923 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100924
Harald Welte256571e2018-01-24 18:47:19 +0100925 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte45164da2018-01-24 12:51:27 +0100926
927 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
928 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
929
930 /* Send Early Classmark, just for the fun of it? */
931 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
932
933 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100934 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100935}
936testcase TC_imsi_detach_by_imei() runs on MTC_CT {
937 var BSC_ConnHdlr vc_conn;
938 f_init();
939
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100940 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imei), 16);
Harald Welte45164da2018-01-24 12:51:27 +0100941 vc_conn.done;
942}
943
944
945/* helper function for an emergency call. caller passes in mobile identity to use */
946private function f_emerg_call(MobileIdentityLV mi) runs on BSC_ConnHdlr {
Harald Welte0bef21e2018-02-10 09:48:23 +0100947 var CallParameters cpars := valueof(t_CallParams('112'H, 0));
948 cpars.emergency := true;
Philipp Maierf1e02bb2018-03-15 16:30:00 +0100949 cpars.mgcp_ep := "rtpbridge/1@mgw";
Harald Welte45164da2018-01-24 12:51:27 +0100950
Harald Welte0bef21e2018-02-10 09:48:23 +0100951 f_mo_call(cpars);
Harald Welte45164da2018-01-24 12:51:27 +0100952}
953
954/* establish an emergency call by IMEI, no SIM inserted (and hence no IMSI) */
955private function f_tc_emerg_call_imei_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100956 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100957
Harald Welte256571e2018-01-24 18:47:19 +0100958 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100959 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100960 f_bssap_compl_l3(l3_info);
961 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ('05'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +0100962 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100963}
964testcase TC_emerg_call_imei_reject() runs on MTC_CT {
965 var BSC_ConnHdlr vc_conn;
966 f_init();
967
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100968 vc_conn := f_start_handler(refers(f_tc_emerg_call_imei_reject), 17);
Harald Welte45164da2018-01-24 12:51:27 +0100969 vc_conn.done;
970}
971
Harald Welted5b91402018-01-24 18:48:16 +0100972/* establish an emergency call by IMSI, SIM inserted (and hence IMSI) */
Harald Welte45164da2018-01-24 12:51:27 +0100973private function f_tc_emerg_call_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100974 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100975 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100976 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +0100977 /* Then issue emergency call identified by IMSI */
978 f_emerg_call(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
979}
980testcase TC_emerg_call_imsi() runs on MTC_CT {
981 var BSC_ConnHdlr vc_conn;
982 f_init();
983
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100984 vc_conn := f_start_handler(refers(f_tc_emerg_call_imsi), 18);
Harald Welte45164da2018-01-24 12:51:27 +0100985 vc_conn.done;
986}
987
988/* CM Service Request for VGCS -> reject */
989private function f_tc_cm_serv_req_vgcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100990 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100991
992 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100993 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +0100994
995 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100996 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VGCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100997 f_bssap_compl_l3(l3_info);
998 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100999 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001000}
1001testcase TC_cm_serv_req_vgcs_reject() runs on MTC_CT {
1002 var BSC_ConnHdlr vc_conn;
1003 f_init();
1004
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001005 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vgcs_reject), 19);
Harald Welte45164da2018-01-24 12:51:27 +01001006 vc_conn.done;
1007}
1008
1009/* CM Service Request for VBS -> reject */
1010private function f_tc_cm_serv_req_vbs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001011 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001012
1013 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001014 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001015
1016 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001017 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VBS, mi));
Harald Welte45164da2018-01-24 12:51:27 +01001018 f_bssap_compl_l3(l3_info);
1019 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001020 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001021}
1022testcase TC_cm_serv_req_vbs_reject() runs on MTC_CT {
1023 var BSC_ConnHdlr vc_conn;
1024 f_init();
1025
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001026 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vbs_reject), 20);
Harald Welte45164da2018-01-24 12:51:27 +01001027 vc_conn.done;
1028}
1029
1030/* CM Service Request for LCS -> reject */
1031private function f_tc_cm_serv_req_lcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001032 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001033
1034 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001035 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001036
1037 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001038 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_LCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +01001039 f_bssap_compl_l3(l3_info);
1040 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001041 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001042}
1043testcase TC_cm_serv_req_lcs_reject() runs on MTC_CT {
1044 var BSC_ConnHdlr vc_conn;
1045 f_init();
1046
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001047 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_lcs_reject), 21);
Harald Welte45164da2018-01-24 12:51:27 +01001048 vc_conn.done;
1049}
1050
Harald Welte0195ab12018-01-24 21:50:20 +01001051/* CM Re-Establishment Request */
1052private function f_tc_cm_reest_req_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001053 f_init_handler(pars);
Harald Welte0195ab12018-01-24 21:50:20 +01001054
1055 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001056 f_perform_lu();
Harald Welte0195ab12018-01-24 21:50:20 +01001057
1058 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1059 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REEST_REQ(0, mi));
1060 f_bssap_compl_l3(l3_info);
1061 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001062 f_expect_clear();
Harald Welte0195ab12018-01-24 21:50:20 +01001063}
1064testcase TC_cm_reest_req_reject() runs on MTC_CT {
1065 var BSC_ConnHdlr vc_conn;
1066 f_init();
Harald Welte0195ab12018-01-24 21:50:20 +01001067
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001068 vc_conn := f_start_handler(refers(f_tc_cm_reest_req_reject), 22);
Harald Welte0195ab12018-01-24 21:50:20 +01001069 vc_conn.done;
1070}
1071
Harald Weltec638f4d2018-01-24 22:00:36 +01001072/* Test LU (with authentication enabled), with wrong response from MS */
1073private function f_tc_lu_auth_2G_fail(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001074 f_init_handler(pars);
Harald Weltec638f4d2018-01-24 22:00:36 +01001075
1076 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
1077
1078 /* tell GSUP dispatcher to send this IMSI to us */
1079 f_create_gsup_expect(hex2str(g_pars.imsi));
1080
1081 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
1082 f_bssap_compl_l3(l3_lu);
1083
1084 /* Send Early Classmark, just for the fun of it */
1085 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1086
1087 var AuthVector vec := f_gen_auth_vec_2g();
1088 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(vec.rand, vec.sres, vec.kc));
1089 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
1090 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
1091
1092 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(vec.rand)));
1093 /* Send back wrong auth response */
1094 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G('00000000'O)));
1095
1096 /* Expect GSUP AUTH FAIL REP to HLR */
1097 GSUP.receive(tr_GSUP_AUTH_FAIL_IND(g_pars.imsi));
1098
1099 /* Expect LU REJECT with Cause == Illegal MS */
1100 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej('03'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +01001101 f_expect_clear();
Harald Weltec638f4d2018-01-24 22:00:36 +01001102}
1103testcase TC_lu_auth_2G_fail() runs on MTC_CT {
1104 var BSC_ConnHdlr vc_conn;
1105 f_init();
1106 f_vty_config(MSCVTY, "network", "authentication required");
Harald Weltec638f4d2018-01-24 22:00:36 +01001107
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001108 vc_conn := f_start_handler(refers(f_tc_lu_auth_2G_fail), 23);
Harald Weltec638f4d2018-01-24 22:00:36 +01001109 vc_conn.done;
1110}
1111
Harald Weltede371492018-01-27 23:44:41 +01001112/* A5/1 + A5/3 permitted on network side, and MS capable to do it */
Harald Welte16114282018-01-24 22:41:21 +01001113private 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 +01001114 pars.net.expect_auth := true;
1115 pars.net.expect_ciph := true;
Harald Weltea10db902018-01-27 12:44:49 +01001116 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001117 f_perform_lu();
Harald Welte16114282018-01-24 22:41:21 +01001118}
1119testcase TC_lu_imsi_auth_tmsi_encr_13_13() runs on MTC_CT {
1120 var BSC_ConnHdlr vc_conn;
1121 f_init();
1122 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte16114282018-01-24 22:41:21 +01001123 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1124
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001125 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_13), 24);
Harald Welte16114282018-01-24 22:41:21 +01001126 vc_conn.done;
1127}
1128
Harald Welte1af6ea82018-01-25 18:33:15 +01001129/* Test Complete L3 without payload */
1130private function f_tc_cl3_no_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001131 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001132
1133 /* Send Complete L3 Info with empty L3 frame */
1134 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1135 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, ''O))));
1136
Harald Weltef466eb42018-01-27 14:26:54 +01001137 timer T := 5.0;
1138 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001139 alt {
1140 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
1141 /* Expect LU REJECT with Cause == Illegal MS */
Harald Weltebdb3c452018-03-18 22:43:06 +01001142 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
1143 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001144 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001145 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001146 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Daniel Willmannafce8662018-07-06 23:11:32 +02001147 mtc.stop;
Harald Weltef466eb42018-01-27 14:26:54 +01001148 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001149 }
1150 setverdict(pass);
1151}
1152testcase TC_cl3_no_payload() runs on MTC_CT {
1153 var BSC_ConnHdlr vc_conn;
1154 f_init();
1155
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001156 vc_conn := f_start_handler(refers(f_tc_cl3_no_payload), 25);
Harald Welte1af6ea82018-01-25 18:33:15 +01001157 vc_conn.done;
1158}
1159
1160/* Test Complete L3 with random payload */
1161private function f_tc_cl3_rnd_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001162 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001163
Daniel Willmannaa14a382018-07-26 08:29:45 +02001164 /* length is limited by PDU_BSSAP length field which includes some
1165 * other fields beside l3info payload. So payl can only be 240 bytes
1166 * Since rnd() returns values < 1 multiply with 241
1167 */
1168 var integer len := float2int(rnd() * 241.0);
Harald Welte1af6ea82018-01-25 18:33:15 +01001169 var octetstring payl := f_rnd_octstring(len);
1170
1171 /* Send Complete L3 Info with empty L3 frame */
1172 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1173 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, payl))));
1174
Harald Weltef466eb42018-01-27 14:26:54 +01001175 timer T := 5.0;
1176 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001177 alt {
1178 /* Immediate disconnect */
1179 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte1af6ea82018-01-25 18:33:15 +01001180 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
Harald Weltebdb3c452018-03-18 22:43:06 +01001181 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001182 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001183 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001184 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Daniel Willmannafce8662018-07-06 23:11:32 +02001185 mtc.stop;
Harald Weltef466eb42018-01-27 14:26:54 +01001186 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001187 }
1188 setverdict(pass);
1189}
1190testcase TC_cl3_rnd_payload() runs on MTC_CT {
1191 var BSC_ConnHdlr vc_conn;
1192 f_init();
1193
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001194 vc_conn := f_start_handler(refers(f_tc_cl3_rnd_payload), 26);
Harald Welte1af6ea82018-01-25 18:33:15 +01001195 vc_conn.done;
1196}
1197
Harald Welte116e4332018-01-26 22:17:48 +01001198/* Test Complete L3 with random payload */
1199private function f_tc_establish_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001200 f_init_handler(pars);
Harald Welte116e4332018-01-26 22:17:48 +01001201
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001202 f_perform_lu();
Harald Welte116e4332018-01-26 22:17:48 +01001203
Harald Welteb9e86fa2018-04-09 18:18:31 +02001204 f_establish_fully();
Daniel Willmann898a7e02018-05-17 12:16:16 +02001205 f_expect_clear(10.0);
Harald Welte116e4332018-01-26 22:17:48 +01001206}
1207testcase TC_establish_and_nothing() runs on MTC_CT {
1208 var BSC_ConnHdlr vc_conn;
1209 f_init();
1210
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001211 vc_conn := f_start_handler(refers(f_tc_establish_and_nothing), 27);
Harald Welte116e4332018-01-26 22:17:48 +01001212 vc_conn.done;
1213}
1214
Harald Welte12510c52018-01-26 22:26:24 +01001215/* Test MO Call SETUP with no response from MNCC */
1216private function f_tc_mo_setup_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Philipp Maier109e6aa2018-10-17 10:53:32 +02001217 f_init_handler(pars, 190.0);
Harald Weltea10db902018-01-27 12:44:49 +01001218
Harald Welte12510c52018-01-26 22:26:24 +01001219 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1220
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001221 f_perform_lu();
Harald Welte12510c52018-01-26 22:26:24 +01001222
Harald Welteb9e86fa2018-04-09 18:18:31 +02001223 f_establish_fully();
Harald Welte12510c52018-01-26 22:26:24 +01001224 f_create_mncc_expect(hex2str(cpars.called_party));
1225 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1226
1227 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1228
Philipp Maier109e6aa2018-10-17 10:53:32 +02001229 f_expect_clear(185.0);
Harald Welte12510c52018-01-26 22:26:24 +01001230}
1231testcase TC_mo_setup_and_nothing() runs on MTC_CT {
1232 var BSC_ConnHdlr vc_conn;
1233 f_init();
1234
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001235 vc_conn := f_start_handler(refers(f_tc_mo_setup_and_nothing), 28);
Harald Welte12510c52018-01-26 22:26:24 +01001236 vc_conn.done;
1237}
1238
Harald Welte3ab88002018-01-26 22:37:25 +01001239/* Test MO Call with no response to RAN-side CRCX */
1240private function f_tc_mo_crcx_ran_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001241 f_init_handler(pars);
Harald Welte3ab88002018-01-26 22:37:25 +01001242 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1243 var MNCC_PDU mncc;
1244 var MgcpCommand mgcp_cmd;
1245
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001246 f_perform_lu();
Harald Welte3ab88002018-01-26 22:37:25 +01001247
Harald Welteb9e86fa2018-04-09 18:18:31 +02001248 f_establish_fully();
Harald Welte3ab88002018-01-26 22:37:25 +01001249 f_create_mncc_expect(hex2str(cpars.called_party));
1250 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1251
1252 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1253 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1254 cpars.mncc_callref := mncc.u.signal.callref;
1255 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1256 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1257
1258 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
Harald Welte1852a842018-01-26 22:53:36 +01001259 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1260 cpars.mgcp_ep := mgcp_cmd.line.ep;
Harald Welte3ab88002018-01-26 22:37:25 +01001261 /* never respond to this */
1262
Philipp Maier8e58f592018-03-14 11:10:56 +01001263 /* When the connection with the MGW fails, the MSC will first request
1264 * a release via call control. We will answer this request normally. */
1265 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1266 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1267
Harald Welte1ddc7162018-01-27 14:25:46 +01001268 f_expect_clear(30.0);
Harald Welte3ab88002018-01-26 22:37:25 +01001269}
1270testcase TC_mo_crcx_ran_timeout() runs on MTC_CT {
1271 var BSC_ConnHdlr vc_conn;
1272 f_init();
1273
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001274 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_timeout), 29);
Harald Welte3ab88002018-01-26 22:37:25 +01001275 vc_conn.done;
1276}
1277
Harald Welte0cc82d92018-01-26 22:52:34 +01001278/* Test MO Call with reject to RAN-side CRCX */
1279private function f_tc_mo_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001280 f_init_handler(pars);
Harald Welte0cc82d92018-01-26 22:52:34 +01001281 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1282 var MNCC_PDU mncc;
1283 var MgcpCommand mgcp_cmd;
1284
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001285 f_perform_lu();
Harald Welte0cc82d92018-01-26 22:52:34 +01001286
Harald Welteb9e86fa2018-04-09 18:18:31 +02001287 f_establish_fully();
Harald Welte0cc82d92018-01-26 22:52:34 +01001288 f_create_mncc_expect(hex2str(cpars.called_party));
1289 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1290
1291 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1292 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1293 cpars.mncc_callref := mncc.u.signal.callref;
1294 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1295 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1296
1297 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001298
1299 /* Detect if the received CRCX is a wildcarded CRCX request. If yes,
1300 * set an endpoint name that fits the pattern. If not, just use the
1301 * endpoint name from the request */
1302 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
1303 cpars.mgcp_ep := "rtpbridge/1@mgw";
1304 } else {
1305 cpars.mgcp_ep := mgcp_cmd.line.ep;
1306 }
1307
Harald Welte0cc82d92018-01-26 22:52:34 +01001308 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001309
Harald Welte0cc82d92018-01-26 22:52:34 +01001310 /* Respond to CRCX with error */
1311 var MgcpResponse mgcp_rsp := {
1312 line := {
1313 code := "542",
1314 trans_id := mgcp_cmd.line.trans_id,
1315 string := "FORCED_FAIL"
1316 },
Harald Welte0cc82d92018-01-26 22:52:34 +01001317 sdp := omit
1318 }
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001319 var MgcpParameter mgcp_rsp_param := {
1320 code := "Z",
1321 val := cpars.mgcp_ep
1322 };
1323 mgcp_rsp.params[0] := mgcp_rsp_param;
Harald Welte0cc82d92018-01-26 22:52:34 +01001324 MGCP.send(mgcp_rsp);
1325
1326 timer T := 30.0;
1327 T.start;
1328 alt {
Daniel Willmannafce8662018-07-06 23:11:32 +02001329 [] T.timeout {
1330 setverdict(fail, "Timeout waiting for channel release");
1331 mtc.stop;
1332 }
Daniel Willmann5868e622018-02-15 17:42:59 +01001333 [] 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 repeat;
1336 }
Harald Welte0cc82d92018-01-26 22:52:34 +01001337 [] MNCC.receive { repeat; }
1338 [] GSUP.receive { repeat; }
Philipp Maierc6e06f72018-04-11 18:12:23 +02001339 /* Note: As we did not respond properly to the CRCX from the MSC we
1340 * expect the MSC to omit any further MGCP operation (At least in the
1341 * the current implementation, there is no recovery mechanism implemented
1342 * and a DLCX can not be performed as the MSC does not know a specific
1343 * endpoint yet. */
Daniel Willmannafce8662018-07-06 23:11:32 +02001344 [] MGCP.receive {
1345 setverdict(fail, "Unexpected MGCP message");
1346 mtc.stop;
1347 }
Harald Welte5946b332018-03-18 23:32:21 +01001348 [] as_clear_cmd_compl_disc();
Harald Welte0cc82d92018-01-26 22:52:34 +01001349 }
1350}
1351testcase TC_mo_crcx_ran_reject() runs on MTC_CT {
1352 var BSC_ConnHdlr vc_conn;
1353 f_init();
1354
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001355 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_reject), 30);
Harald Welte0cc82d92018-01-26 22:52:34 +01001356 vc_conn.done;
1357}
1358
Harald Welte3ab88002018-01-26 22:37:25 +01001359
Harald Welte812f7a42018-01-27 00:49:18 +01001360/* helper function to start a MT call: MNCC SETUP; Paging; DChan est.; DTAP SETUP */
1361private function f_mt_call_start(inout CallParameters cpars) runs on BSC_ConnHdlr {
1362 var MNCC_PDU mncc;
1363 var MgcpCommand mgcp_cmd;
1364 var OCT4 tmsi;
1365
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001366 f_perform_lu();
Harald Welte812f7a42018-01-27 00:49:18 +01001367 if (isvalue(g_pars.tmsi)) {
1368 tmsi := g_pars.tmsi;
1369 } else {
1370 tmsi := 'FFFFFFFF'O;
1371 }
1372 f_bssmap_register_imsi(g_pars.imsi, tmsi);
1373
1374 /* Allocate call reference and send SETUP via MNCC to MSC */
1375 cpars.mncc_callref := f_rnd_int(2147483648);
1376 MNCC.send(ts_MNCC_SETUP_req(cpars.mncc_callref, hex2str(g_pars.msisdn),
1377 hex2str(cpars.called_party), hex2str(g_pars.imsi)));
1378
1379 /* MSC->BSC: expect PAGING from MSC */
1380 BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));
1381 /* MS -> MSC: PAGING RESPONSE */
Harald Welteb9e86fa2018-04-09 18:18:31 +02001382 f_establish_fully(EST_TYPE_PAG_RESP);
Harald Welte812f7a42018-01-27 00:49:18 +01001383
1384 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1385
1386 /* MSC->MS: SETUP */
1387 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party)));
1388}
1389
1390/* Test MT Call */
1391private function f_tc_mt_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001392 f_init_handler(pars);
Harald Welte812f7a42018-01-27 00:49:18 +01001393 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1394 var MNCC_PDU mncc;
1395 var MgcpCommand mgcp_cmd;
1396
1397 f_mt_call_start(cpars);
1398
1399 /* MS->MSC: CALL CONFIRMED */
1400 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1401
1402 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1403
1404 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1405 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001406
1407 /* Detect if the received CRCX is a wildcarded CRCX request. If yes,
1408 * set an endpoint name that fits the pattern. If not, just use the
1409 * endpoint name from the request */
1410 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
1411 cpars.mgcp_ep := "rtpbridge/1@mgw";
1412 } else {
1413 cpars.mgcp_ep := mgcp_cmd.line.ep;
1414 }
1415
Harald Welte812f7a42018-01-27 00:49:18 +01001416 /* Respond to CRCX with error */
1417 var MgcpResponse mgcp_rsp := {
1418 line := {
1419 code := "542",
1420 trans_id := mgcp_cmd.line.trans_id,
1421 string := "FORCED_FAIL"
1422 },
Harald Welte812f7a42018-01-27 00:49:18 +01001423 sdp := omit
1424 }
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001425 var MgcpParameter mgcp_rsp_param := {
1426 code := "Z",
1427 val := cpars.mgcp_ep
1428 };
1429 mgcp_rsp.params[0] := mgcp_rsp_param;
Harald Welte812f7a42018-01-27 00:49:18 +01001430 MGCP.send(mgcp_rsp);
1431
1432 timer T := 30.0;
1433 T.start;
1434 alt {
Daniel Willmannafce8662018-07-06 23:11:32 +02001435 [] T.timeout {
1436 setverdict(fail, "Timeout waiting for channel release");
1437 mtc.stop;
1438 }
Harald Welte812f7a42018-01-27 00:49:18 +01001439 [] BSSAP.receive { repeat; }
1440 [] MNCC.receive { repeat; }
1441 [] GSUP.receive { repeat; }
1442 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1443 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1444 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1445 repeat;
1446 }
1447 [] MGCP.receive { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001448 [] as_clear_cmd_compl_disc();
Harald Welte812f7a42018-01-27 00:49:18 +01001449 }
1450}
1451testcase TC_mt_crcx_ran_reject() runs on MTC_CT {
1452 var BSC_ConnHdlr vc_conn;
1453 f_init();
1454
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001455 vc_conn := f_start_handler(refers(f_tc_mt_crcx_ran_reject), 31);
Harald Welte812f7a42018-01-27 00:49:18 +01001456 vc_conn.done;
1457}
1458
1459
1460/* Test MT Call T310 timer */
1461private function f_tc_mt_t310(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltead2952e2018-01-27 14:12:46 +01001462 f_init_handler(pars, 200.0);
Harald Welte812f7a42018-01-27 00:49:18 +01001463 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1464 var MNCC_PDU mncc;
1465 var MgcpCommand mgcp_cmd;
1466
1467 f_mt_call_start(cpars);
1468
1469 /* MS->MSC: CALL CONFIRMED */
1470 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
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);
1475 cpars.mgcp_ep := mgcp_cmd.line.ep;
1476 /* FIXME: Respond to CRCX */
1477
1478 /* old libosmocore T310 default timeout is 180s. so let's wait 190 */
1479 timer T := 190.0;
1480 T.start;
1481 alt {
Daniel Willmannafce8662018-07-06 23:11:32 +02001482 [] T.timeout {
1483 setverdict(fail, "Timeout waiting for T310");
1484 mtc.stop;
1485 }
Harald Welte812f7a42018-01-27 00:49:18 +01001486 [] MNCC.receive(tr_MNCC_DISC_ind(cpars.mncc_callref)) {
1487 MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(23))));
1488 }
1489 }
1490 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));
1491 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1492 /* FIXME: We're sending this with TIflag 0: allocated by sender, which is wrong */
1493 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1494
1495 alt {
Harald Welte812f7a42018-01-27 00:49:18 +01001496 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1497 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1498 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1499 repeat;
1500 }
Harald Welte5946b332018-03-18 23:32:21 +01001501 [] as_clear_cmd_compl_disc();
Harald Welte812f7a42018-01-27 00:49:18 +01001502 }
1503}
1504testcase TC_mt_t310() runs on MTC_CT {
1505 var BSC_ConnHdlr vc_conn;
1506 f_init();
1507
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001508 vc_conn := f_start_handler(refers(f_tc_mt_t310), 32);
Harald Welte812f7a42018-01-27 00:49:18 +01001509 vc_conn.done;
1510}
1511
Harald Welte167458a2018-01-27 15:58:16 +01001512/* Perform successful LU + MO call, then GSUP LocationCancel. Subscriber must be denied CM SERV */
1513private function f_tc_gsup_cancel(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1514 f_init_handler(pars);
1515 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1516 cpars.bss_rtp_port := 1110;
1517 cpars.mgcp_connection_id_bss := '22222'H;
1518 cpars.mgcp_connection_id_mss := '33333'H;
Daniel Willmann9b0235b2018-07-24 12:13:34 +02001519 cpars.mgcp_ep := "rtpbridge/1@mgw";
Harald Welte167458a2018-01-27 15:58:16 +01001520
1521 /* Location Update to make subscriber known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001522 f_perform_lu();
Harald Welte167458a2018-01-27 15:58:16 +01001523
1524 /* First MO call should succeed */
1525 f_mo_call(cpars);
1526
1527 /* Cancel the subscriber in the VLR */
1528 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1529 alt {
1530 [] GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi)) { }
1531 [] GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi)) {
1532 setverdict(fail, "Received GSUP Location Cancel Error");
Daniel Willmannafce8662018-07-06 23:11:32 +02001533 mtc.stop;
Harald Welte167458a2018-01-27 15:58:16 +01001534 }
1535 }
1536
1537 /* Follow-up transactions should fail */
1538 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1539 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
1540 f_bssap_compl_l3(l3_info);
1541 alt {
1542 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
1543 [] BSSAP.receive {
1544 setverdict(fail, "Received unexpected BSSAP instead of CM SERV REJ");
Daniel Willmannafce8662018-07-06 23:11:32 +02001545 mtc.stop;
Harald Welte167458a2018-01-27 15:58:16 +01001546 }
1547 }
1548 setverdict(pass);
1549}
1550testcase TC_gsup_cancel() runs on MTC_CT {
1551 var BSC_ConnHdlr vc_conn;
1552 f_init();
1553
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001554 vc_conn := f_start_handler(refers(f_tc_gsup_cancel), 33);
Harald Welte167458a2018-01-27 15:58:16 +01001555 vc_conn.done;
1556}
1557
Harald Welte9de84792018-01-28 01:06:35 +01001558/* A5/1 only permitted on network side, and MS capable to do it */
1559private function f_tc_lu_imsi_auth_tmsi_encr_1_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1560 pars.net.expect_auth := true;
1561 pars.net.expect_ciph := true;
1562 pars.net.kc_support := '02'O; /* A5/1 only */
1563 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001564 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001565}
1566testcase TC_lu_imsi_auth_tmsi_encr_1_13() runs on MTC_CT {
1567 var BSC_ConnHdlr vc_conn;
1568 f_init();
1569 f_vty_config(MSCVTY, "network", "authentication required");
1570 f_vty_config(MSCVTY, "network", "encryption a5 1");
1571
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001572 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_1_13), 34);
Harald Welte9de84792018-01-28 01:06:35 +01001573 vc_conn.done;
1574}
1575
1576/* A5/3 only permitted on network side, and MS capable to do it */
1577private function f_tc_lu_imsi_auth_tmsi_encr_3_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1578 pars.net.expect_auth := true;
1579 pars.net.expect_ciph := true;
1580 pars.net.kc_support := '08'O; /* A5/3 only */
1581 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001582 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001583}
1584testcase TC_lu_imsi_auth_tmsi_encr_3_13() runs on MTC_CT {
1585 var BSC_ConnHdlr vc_conn;
1586 f_init();
1587 f_vty_config(MSCVTY, "network", "authentication required");
1588 f_vty_config(MSCVTY, "network", "encryption a5 3");
1589
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001590 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_13), 35);
Harald Welte9de84792018-01-28 01:06:35 +01001591 vc_conn.done;
1592}
1593
1594/* A5/3 only permitted on network side, and MS with only A5/1 support */
1595private function f_tc_lu_imsi_auth_tmsi_encr_3_1(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1596 pars.net.expect_auth := true;
1597 pars.net.expect_ciph := true;
1598 pars.net.kc_support := '08'O; /* A5/3 only */
1599 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1600 f_init_handler(pars, 15.0);
1601
1602 /* cannot use f_perform_lu() as we expect a reject */
1603 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1604 f_create_gsup_expect(hex2str(g_pars.imsi));
1605 f_bssap_compl_l3(l3_lu);
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001606 if (pars.send_early_cm) {
1607 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1608 } else {
1609 pars.cm1.esind := '0'B;
1610 }
Harald Welte9de84792018-01-28 01:06:35 +01001611 f_mm_auth();
1612 alt {
Daniel Willmann52918e52018-09-20 14:39:09 +02001613 [] BSSAP.receive(tr_BSSMAP_ClassmarkReq) {
1614 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1615 repeat;
1616 }
Harald Welte5946b332018-03-18 23:32:21 +01001617 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1618 f_expect_clear();
1619 }
Harald Welte9de84792018-01-28 01:06:35 +01001620 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1621 setverdict(fail, "CipherModeCommand despite no A5 intersection");
Daniel Willmannafce8662018-07-06 23:11:32 +02001622 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001623 }
1624 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001625 setverdict(fail, "Unknown/unexpected BSSAP received");
Daniel Willmannafce8662018-07-06 23:11:32 +02001626 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001627 }
1628 }
1629 setverdict(pass);
1630}
1631testcase TC_lu_imsi_auth_tmsi_encr_3_1() runs on MTC_CT {
1632 var BSC_ConnHdlr vc_conn;
1633 f_init();
1634 f_vty_config(MSCVTY, "network", "authentication required");
1635 f_vty_config(MSCVTY, "network", "encryption a5 3");
1636
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001637 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 360);
1638 vc_conn.done;
1639}
1640testcase TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() runs on MTC_CT {
1641 var BSC_ConnHdlrPars pars;
1642 var BSC_ConnHdlr vc_conn;
1643 f_init();
1644 f_vty_config(MSCVTY, "network", "authentication required");
1645 f_vty_config(MSCVTY, "network", "encryption a5 3");
1646
1647 pars := f_init_pars(361);
1648 pars.send_early_cm := false;
1649 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 +01001650 vc_conn.done;
1651}
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01001652testcase TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() runs on MTC_CT {
1653 var BSC_ConnHdlr vc_conn;
1654 f_init();
1655 f_vty_config(MSCVTY, "network", "authentication required");
1656 f_vty_config(MSCVTY, "network", "encryption a5 3");
1657
1658 /* Make sure the MSC category is on DEBUG level to trigger the log
1659 * message that is reported in OS#2947 to trigger the segfault */
1660 f_vty_config(MSCVTY, "log stderr", "logging level msc debug");
1661
1662 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 362);
1663 vc_conn.done;
1664}
Harald Welte9de84792018-01-28 01:06:35 +01001665
1666/* A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
1667private function f_tc_lu_imsi_auth_tmsi_encr_13_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1668 pars.net.expect_auth := true;
1669 pars.net.expect_ciph := true;
1670 pars.net.kc_support := '0A'O; /* A5/1 + A5/3 */
1671 pars.cm1.a5_1 := '1'B;
1672 pars.cm2.a5_1 := '1'B;
1673 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1674 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
1675 f_init_handler(pars, 15.0);
1676
1677 /* cannot use f_perform_lu() as we expect a reject */
1678 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1679 f_create_gsup_expect(hex2str(g_pars.imsi));
1680 f_bssap_compl_l3(l3_lu);
1681 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1682 f_mm_auth();
1683 alt {
Harald Welte5946b332018-03-18 23:32:21 +01001684 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1685 f_expect_clear();
1686 }
Harald Welte9de84792018-01-28 01:06:35 +01001687 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1688 setverdict(fail, "CipherModeCommand despite no A5 intersection");
Daniel Willmannafce8662018-07-06 23:11:32 +02001689 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001690 }
1691 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001692 setverdict(fail, "Unknown/unexpected BSSAP received");
Daniel Willmannafce8662018-07-06 23:11:32 +02001693 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001694 }
1695 }
1696 setverdict(pass);
1697}
1698testcase TC_lu_imsi_auth_tmsi_encr_13_2() runs on MTC_CT {
1699 var BSC_ConnHdlr vc_conn;
1700 f_init();
1701 f_vty_config(MSCVTY, "network", "authentication required");
1702 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1703
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001704 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_2), 37);
Harald Welte9de84792018-01-28 01:06:35 +01001705 vc_conn.done;
1706}
1707
1708/* A5/0 + A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
1709private function f_tc_lu_imsi_auth_tmsi_encr_013_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1710 pars.net.expect_auth := true;
1711 pars.net.expect_ciph := true;
1712 pars.net.kc_support := '0B'O; /* A5/1 + A5/3 */
1713 pars.cm1.a5_1 := '1'B;
1714 pars.cm2.a5_1 := '1'B;
1715 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1716 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
1717 f_init_handler(pars, 15.0);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001718 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001719}
1720testcase TC_lu_imsi_auth_tmsi_encr_013_2() runs on MTC_CT {
1721 var BSC_ConnHdlr vc_conn;
1722 f_init();
1723 f_vty_config(MSCVTY, "network", "authentication required");
1724 f_vty_config(MSCVTY, "network", "encryption a5 0 1 3");
1725
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001726 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_013_2), 38);
Harald Welte9de84792018-01-28 01:06:35 +01001727 vc_conn.done;
1728}
1729
Harald Welte33ec09b2018-02-10 15:34:46 +01001730/* LU followed by MT call (including paging) */
1731private function f_tc_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1732 f_init_handler(pars);
Stefan Sperling26d57be2018-11-12 17:03:26 +01001733 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Harald Welte33ec09b2018-02-10 15:34:46 +01001734 cpars.bss_rtp_port := 1110;
1735 cpars.mgcp_connection_id_bss := '10004'H;
1736 cpars.mgcp_connection_id_mss := '10005'H;
1737
Philipp Maier4b2692d2018-03-14 16:37:48 +01001738 /* Note: This is an optional parameter. When the call-agent (MSC) does
1739 * supply a full endpoint name this setting will be overwritten. */
1740 cpars.mgcp_ep := "rtpbridge/1@mgw";
1741
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001742 f_perform_lu();
Harald Welte33ec09b2018-02-10 15:34:46 +01001743 f_mt_call(cpars);
1744}
1745testcase TC_lu_and_mt_call() runs on MTC_CT {
1746 var BSC_ConnHdlr vc_conn;
1747 f_init();
1748
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001749 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call), 39);
Harald Welte33ec09b2018-02-10 15:34:46 +01001750 vc_conn.done;
1751}
1752
Daniel Willmann8b084372018-02-04 13:35:26 +01001753/* Test MO Call SETUP with DTMF */
1754private function f_tc_mo_setup_dtmf_dup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1755 f_init_handler(pars);
1756 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1757 cpars.bss_rtp_port := 1110;
1758 cpars.mgcp_connection_id_bss := '22222'H;
1759 cpars.mgcp_connection_id_mss := '33333'H;
1760
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001761 f_perform_lu();
Daniel Willmann8b084372018-02-04 13:35:26 +01001762 f_mo_seq_dtmf_dup(cpars);
1763}
1764testcase TC_mo_setup_and_dtmf_dup() runs on MTC_CT {
1765 var BSC_ConnHdlr vc_conn;
1766 f_init();
1767
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001768 vc_conn := f_start_handler(refers(f_tc_mo_setup_dtmf_dup), 39);
Daniel Willmann8b084372018-02-04 13:35:26 +01001769 vc_conn.done;
1770}
Harald Welte9de84792018-01-28 01:06:35 +01001771
Philipp Maier328d1662018-03-07 10:40:27 +01001772testcase TC_cr_before_reset() runs on MTC_CT {
1773 timer T := 4.0;
1774 var boolean reset_ack_seen := false;
1775 f_init_bssap_direct();
1776
Daniel Willmann42d1d5b2018-08-07 15:18:41 +02001777 f_bssap_start(g_bssap[0]);
1778
Daniel Willmanne8018962018-08-21 14:18:00 +02001779 f_sleep(3.0);
1780
Philipp Maier328d1662018-03-07 10:40:27 +01001781 /* Make a blind connection attemt, to trigger the deadlock condition */
Philipp Maier75932982018-03-27 14:52:35 +02001782 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 +01001783
1784 /* Send a BSSMAP reset */
Philipp Maier75932982018-03-27 14:52:35 +02001785 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 +01001786 T.start
1787 alt {
1788 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_ResetAck)) {
1789 reset_ack_seen := true;
1790 repeat;
1791 }
1792
1793 /* Acknowledge MSC sided reset requests */
1794 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) {
Philipp Maier75932982018-03-27 14:52:35 +02001795 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 +01001796 repeat;
1797 }
1798
1799 /* Ignore all other messages (e.g CR from the connection request) */
1800 [] BSSAP_DIRECT.receive { repeat }
1801
1802 /* If we got no BSSMAP RESET ACK back, then the MSC entered the
1803 * deadlock situation. The MSC is then unable to respond to any
1804 * further BSSMAP RESET or any other sort of traffic. */
1805 [reset_ack_seen == true] T.timeout { setverdict(pass) }
1806 [reset_ack_seen == false] T.timeout {
1807 setverdict(fail, "no BSSMAP RESET ACK seen!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001808 mtc.stop;
Philipp Maier328d1662018-03-07 10:40:27 +01001809 }
1810 }
1811}
Harald Welte9de84792018-01-28 01:06:35 +01001812
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001813/* Test MO Call with no response to RAN-side CRCX or DTAP Release */
1814private function f_tc_mo_release_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1815 f_init_handler(pars);
1816 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1817 var MNCC_PDU mncc;
1818 var MgcpCommand mgcp_cmd;
1819
1820 f_perform_lu();
1821
Harald Welteb9e86fa2018-04-09 18:18:31 +02001822 f_establish_fully();
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001823 f_create_mncc_expect(hex2str(cpars.called_party));
1824 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1825
1826 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1827 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1828 cpars.mncc_callref := mncc.u.signal.callref;
1829 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1830 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1831
1832 /* Drop CRCX */
1833 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1834
1835 /* Drop DTAP Release */
1836 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1837
1838 /* Drop resent DTAP Release */
1839 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1840
1841 f_expect_clear(60.0);
1842}
1843testcase TC_mo_release_timeout() runs on MTC_CT {
1844 var BSC_ConnHdlr vc_conn;
1845 f_init();
1846
1847 vc_conn := f_start_handler(refers(f_tc_mo_release_timeout), 40);
1848 vc_conn.done;
1849}
1850
Harald Welte12510c52018-01-26 22:26:24 +01001851
Philipp Maier2a98a732018-03-19 16:06:12 +01001852/* LU followed by MT call (including paging) */
1853private function f_tc_lu_and_mt_call_no_dlcx_resp(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1854 f_init_handler(pars);
Stefan Sperling26d57be2018-11-12 17:03:26 +01001855 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Philipp Maier2a98a732018-03-19 16:06:12 +01001856 cpars.bss_rtp_port := 1110;
1857 cpars.mgcp_connection_id_bss := '10004'H;
1858 cpars.mgcp_connection_id_mss := '10005'H;
1859
1860 /* Note: This is an optional parameter. When the call-agent (MSC) does
1861 * supply a full endpoint name this setting will be overwritten. */
1862 cpars.mgcp_ep := "rtpbridge/1@mgw";
1863
1864 /* Intentionally disable the CRCX response */
1865 cpars.mgw_drop_dlcx := true;
1866
1867 /* Perform location update and call */
1868 f_perform_lu();
1869 f_mt_call(cpars);
1870}
1871testcase TC_lu_and_mt_call_no_dlcx_resp() runs on MTC_CT {
1872 var BSC_ConnHdlr vc_conn;
1873 f_init();
1874
1875 /* Perform an almost normal looking locationupdate + mt-call, but do
1876 * not respond to the DLCX at the end of the call */
1877 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call_no_dlcx_resp), 41);
1878 vc_conn.done;
1879
1880 /* Wait a guard period until the MGCP layer in the MSC times out,
1881 * if the MSC is vulnerable to the use-after-free situation that is
1882 * fixed by I78f1b6a9149488a4ad3f120c1e190a83c07d4b89 then it should
1883 * segfault now */
1884 f_sleep(6.0);
1885
1886 /* Run the init procedures once more. If the MSC has crashed, this
1887 * this will fail */
1888 f_init();
1889}
Harald Welte45164da2018-01-24 12:51:27 +01001890
Philipp Maier75932982018-03-27 14:52:35 +02001891/* Two BSSMAP resets from two different BSCs */
1892testcase TC_reset_two() runs on MTC_CT {
1893 var BSC_ConnHdlr vc_conn;
1894 f_init(2);
1895 f_sleep(2.0);
1896 setverdict(pass);
1897}
1898
Harald Weltef640a012018-04-14 17:49:21 +02001899/***********************************************************************
1900 * SMS Testing
1901 ***********************************************************************/
1902
Harald Weltef45efeb2018-04-09 18:19:24 +02001903/* LU followed by MO SMS */
1904private function f_tc_lu_and_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1905 var SmsParameters spars := valueof(t_SmsPars);
1906
1907 f_init_handler(pars);
1908
1909 /* Perform location update and call */
1910 f_perform_lu();
1911
1912 f_establish_fully(EST_TYPE_MO_SMS);
1913
1914 //spars.exp_rp_err := 96; /* invalid mandatory information */
1915 f_mo_sms(spars);
1916
1917 f_expect_clear();
1918}
1919testcase TC_lu_and_mo_sms() runs on MTC_CT {
1920 var BSC_ConnHdlr vc_conn;
1921 f_init();
1922 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_sms), 42);
1923 vc_conn.done;
1924}
1925
1926private function f_vty_sms_send(charstring imsi, charstring msisdn, charstring text)
1927runs on MTC_CT {
1928 f_vty_transceive(MSCVTY, "subscriber imsi "&imsi&" sms sender msisdn "&msisdn&" send "&text);
1929}
1930
1931/* LU followed by MT SMS */
1932private function f_tc_lu_and_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1933 var SmsParameters spars := valueof(t_SmsPars);
1934 var OCT4 tmsi;
1935
1936 f_init_handler(pars);
1937
1938 /* Perform location update and call */
1939 f_perform_lu();
1940
1941 /* register an 'expect' for given IMSI (+TMSI) */
1942 if (isvalue(g_pars.tmsi)) {
1943 tmsi := g_pars.tmsi;
1944 } else {
1945 tmsi := 'FFFFFFFF'O;
1946 }
1947 f_bssmap_register_imsi(g_pars.imsi, tmsi);
1948
1949 /* FIXME: actually cause MSC to send a SMS via VTY or SMPP */
1950
1951 /* MSC->BSC: expect PAGING from MSC */
1952 BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));
1953 /* Establish DTAP / BSSAP / SCCP connection */
1954 f_establish_fully(EST_TYPE_PAG_RESP);
1955
1956 spars.tp.ud := 'C8329BFD064D9B53'O;
1957 f_mt_sms(spars);
1958
1959 f_expect_clear();
1960}
1961testcase TC_lu_and_mt_sms() runs on MTC_CT {
1962 var BSC_ConnHdlrPars pars;
1963 var BSC_ConnHdlr vc_conn;
1964 f_init();
1965 pars := f_init_pars(43);
1966 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_sms), pars);
1967 f_sleep(2.0);
1968 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
1969 vc_conn.done;
1970}
1971
Harald Weltef640a012018-04-14 17:49:21 +02001972/* mobile originated SMS from MS/BTS/BSC side to SMPP */
1973private function f_tc_smpp_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1974 var SmsParameters spars := valueof(t_SmsPars);
Harald Weltef45efeb2018-04-09 18:19:24 +02001975
Harald Weltef640a012018-04-14 17:49:21 +02001976 f_init_handler(pars);
Harald Weltef45efeb2018-04-09 18:19:24 +02001977
Harald Weltef640a012018-04-14 17:49:21 +02001978 /* Perform location update so IMSI is known + registered in MSC/VLR */
1979 f_perform_lu();
1980 f_establish_fully(EST_TYPE_MO_SMS);
1981
1982 f_mo_sms(spars);
1983
1984 var SMPP_PDU smpp;
1985 var template SMPP_PDU tr_smpp := tr_SMPP(c_SMPP_command_id_deliver_sm, ESME_ROK);
1986 tr_smpp.body.deliver_sm := {
1987 service_type := "CMT",
1988 source_addr_ton := network_specific,
1989 source_addr_npi := isdn,
1990 source_addr := hex2str(pars.msisdn),
1991 dest_addr_ton := f_sm_ton_from_gsm(spars.tp.da.tP_DA_NoPad.tP_TypeOfNumber),
1992 dest_addr_npi := f_sm_npi_from_gsm(spars.tp.da.tP_DA_NoPad.tP_NumberingPlanID),
1993 destination_addr := hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue),
1994 esm_class := '00000001'B,
1995 protocol_id := 0,
1996 priority_flag := 0,
1997 schedule_delivery_time := "",
1998 replace_if_present := 0,
1999 data_coding := '00000001'B,
2000 sm_default_msg_id := 0,
2001 sm_length := ?,
2002 short_message := spars.tp.ud,
2003 opt_pars := {
2004 {
2005 tag := user_message_reference,
2006 len := 2,
2007 opt_value := {
2008 int2_val := oct2int(spars.tp.msg_ref)
2009 }
2010 }
2011 }
2012 };
2013 alt {
2014 [] SMPP.receive(tr_smpp) -> value smpp {
2015 SMPP.send(ts_SMPP_DELIVER_SM_resp(ESME_ROK, smpp.header.seq_num));
2016 }
2017 [] SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK)) { repeat; }
2018 }
2019
2020 f_expect_clear();
2021}
2022testcase TC_smpp_mo_sms() runs on MTC_CT {
2023 var BSC_ConnHdlr vc_conn;
2024 f_init();
2025 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "default-route");
2026 vc_conn := f_start_handler(refers(f_tc_smpp_mo_sms), 44);
2027 vc_conn.done;
2028 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "no default-route");
2029}
2030
2031/* convert GSM L3 TON to SMPP_TON enum */
2032function f_sm_ton_from_gsm(BIT3 ton) return SMPP_TON {
2033 select (ton) {
2034 case ('000'B) { return unknown; }
2035 case ('001'B) { return international; }
2036 case ('010'B) { return national; }
2037 case ('011'B) { return network_specific; }
2038 case ('100'B) { return subscriber_number; }
2039 case ('101'B) { return alphanumeric; }
2040 case ('110'B) { return abbreviated; }
2041 }
2042 setverdict(fail, "Unknown TON ", ton);
Daniel Willmannafce8662018-07-06 23:11:32 +02002043 mtc.stop;
Harald Weltef640a012018-04-14 17:49:21 +02002044}
2045/* convert GSM L3 NPI to SMPP_NPI enum */
2046function f_sm_npi_from_gsm(BIT4 npi) return SMPP_NPI {
2047 select (npi) {
2048 case ('0000'B) { return unknown; }
2049 case ('0001'B) { return isdn; }
2050 case ('0011'B) { return data; }
2051 case ('0100'B) { return telex; }
2052 case ('0110'B) { return land_mobile; }
2053 case ('1000'B) { return national; }
2054 case ('1001'B) { return private_; }
2055 case ('1010'B) { return ermes; }
2056 }
2057 setverdict(fail, "Unknown NPI ", npi);
Daniel Willmannafce8662018-07-06 23:11:32 +02002058 mtc.stop;
Harald Weltef640a012018-04-14 17:49:21 +02002059}
2060
2061/* build a SMPP_SM from SmsParameters */
2062function f_mt_sm_from_spars(SmsParameters spars)
2063runs on BSC_ConnHdlr return SMPP_SM {
2064 var SMPP_SM sm := {
2065 service_type := "CMT",
2066 source_addr_ton := f_sm_ton_from_gsm(spars.tp.da.tP_DA_NoPad.tP_TypeOfNumber),
2067 source_addr_npi := f_sm_npi_from_gsm(spars.tp.da.tP_DA_NoPad.tP_NumberingPlanID),
2068 source_addr := hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue),
2069 dest_addr_ton := international,
2070 dest_addr_npi := isdn,
2071 destination_addr := hex2str(g_pars.msisdn),
2072 esm_class := '00000001'B,
2073 protocol_id := 0,
2074 priority_flag := 0,
2075 schedule_delivery_time := "",
2076 validity_period := "",
2077 registered_delivery := '00000000'B,
2078 replace_if_present := 0,
2079 data_coding := '00000001'B,
2080 sm_default_msg_id := 0,
2081 sm_length := spars.tp.udl,
2082 short_message := spars.tp.ud,
2083 opt_pars := {}
2084 };
2085 return sm;
2086}
2087
2088/* helper function to encode SMS from 'spars', send it via SMPP to MSC; receive it on MS side */
2089private function f_smpp_mt_sms(SmsParameters spars, boolean trans_mode) runs on BSC_ConnHdlr {
2090 var SMPP_SM sm := f_mt_sm_from_spars(spars);
2091 if (trans_mode) {
2092 sm.esm_class := '00000010'B;
2093 }
2094
2095 /* actually cause MSC to send a SMS via SUBMIT-SM from SMPP side */
2096 SMPP.send(ts_SMPP_SUBMIT_SM(sm));
2097 if (not match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
2098 /* if we're not in SMPP transaction mode, we expect the SMPP-level ACK
2099 * before we expect the SMS delivery on the BSC/radio side */
2100 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
2101 }
2102
2103 /* MSC->BSC: expect PAGING from MSC */
2104 BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));
2105 /* Establish DTAP / BSSAP / SCCP connection */
2106 f_establish_fully(EST_TYPE_PAG_RESP);
2107 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
2108
2109 f_mt_sms(spars);
2110
2111 if (match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
2112 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
2113 }
2114 f_expect_clear();
2115}
2116
2117/* mobile terminated SMS, from SMPP to BSC/BTS/MS */
2118private function f_tc_smpp_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2119 f_init_handler(pars);
2120
2121 /* Perform location update so IMSI is known + registered in MSC/VLR */
2122 f_perform_lu();
2123 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
2124
2125 /* register an 'expect' for given IMSI (+TMSI) */
2126 var OCT4 tmsi;
2127 if (isvalue(g_pars.tmsi)) {
2128 tmsi := g_pars.tmsi;
2129 } else {
2130 tmsi := 'FFFFFFFF'O;
2131 }
2132 f_bssmap_register_imsi(g_pars.imsi, tmsi);
2133
2134 var SmsParameters spars := valueof(t_SmsPars);
2135 /* TODO: test with more intelligent user data; test different coding schemes */
2136 spars.tp.ud := '00'O;
2137 spars.tp.udl := 1;
2138
2139 /* first test the non-transaction store+forward mode */
2140 f_smpp_mt_sms(spars, false);
2141
2142 /* then test the transaction mode */
2143 f_smpp_mt_sms(spars, true);
2144}
2145testcase TC_smpp_mt_sms() runs on MTC_CT {
2146 var BSC_ConnHdlr vc_conn;
2147 f_init();
2148 vc_conn := f_start_handler(refers(f_tc_smpp_mt_sms), 45);
2149 vc_conn.done;
2150}
2151
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002152/***********************************************************************
2153 * USSD Testing
2154 ***********************************************************************/
2155
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07002156private altstep as_unexp_gsup_or_bssap_msg()
2157runs on BSC_ConnHdlr {
2158 [] GSUP.receive {
2159 setverdict(fail, "Unknown/unexpected GSUP received");
2160 self.stop;
2161 }
2162 [] BSSAP.receive {
2163 setverdict(fail, "Unknown/unexpected BSSAP message received");
2164 self.stop;
2165 }
2166}
2167
2168private function f_expect_gsup_msg(template GSUP_PDU msg)
2169runs on BSC_ConnHdlr return GSUP_PDU {
2170 var GSUP_PDU gsup_msg_complete;
2171
2172 alt {
2173 [] GSUP.receive(msg) -> value gsup_msg_complete {
2174 setverdict(pass);
2175 }
2176 /* We don't expect anything else */
2177 [] as_unexp_gsup_or_bssap_msg();
2178 }
2179
2180 return gsup_msg_complete;
2181}
2182
2183private function f_expect_mt_dtap_msg(template PDU_ML3_NW_MS msg)
2184runs on BSC_ConnHdlr return PDU_ML3_NW_MS {
2185 var PDU_DTAP_MT bssap_msg_complete;
2186
2187 alt {
2188 [] BSSAP.receive(tr_PDU_DTAP_MT(msg)) -> value bssap_msg_complete {
2189 setverdict(pass);
2190 }
2191 /* We don't expect anything else */
2192 [] as_unexp_gsup_or_bssap_msg();
2193 }
2194
2195 return bssap_msg_complete.dtap;
2196}
2197
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002198/* LU followed by MO USSD request */
2199private function f_tc_lu_and_mo_ussd_single_request(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002200runs on BSC_ConnHdlr {
2201 f_init_handler(pars);
2202
2203 /* Perform location update */
2204 f_perform_lu();
2205
2206 /* Send CM Service Request for SS/USSD */
2207 f_establish_fully(EST_TYPE_SS_ACT);
2208
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002209 /* We need to inspect GSUP activity */
2210 f_create_gsup_expect(hex2str(g_pars.imsi));
2211
2212 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
2213 invoke_id := 5, /* Phone may not start from 0 or 1 */
2214 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2215 ussd_string := "*#100#"
2216 );
2217
2218 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
2219 invoke_id := 5, /* InvokeID shall be the same for both REQ and RSP */
2220 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2221 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
2222 )
2223
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002224 /* Compose a new SS/REGISTER message with request */
2225 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
2226 tid := 1, /* We just need a single transaction */
2227 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002228 facility := valueof(facility_req)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002229 );
2230
2231 /* Compose SS/RELEASE_COMPLETE template with expected response */
2232 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
2233 tid := 1, /* Response should arrive within the same transaction */
2234 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002235 facility := valueof(facility_rsp)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002236 );
2237
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002238 /* Compose expected MSC -> HLR message */
2239 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
2240 imsi := g_pars.imsi,
2241 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2242 ss := valueof(facility_req)
2243 );
2244
2245 /* To be used for sending response with correct session ID */
2246 var GSUP_PDU gsup_req_complete;
2247
2248 /* Request own number */
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002249 BSSAP.send(ts_PDU_DTAP_MO(ussd_req));
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002250 /* Expect GSUP message containing the SS payload */
2251 gsup_req_complete := f_expect_gsup_msg(gsup_req);
2252
2253 /* Compose the response from HLR using received session ID */
2254 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
2255 imsi := g_pars.imsi,
2256 sid := gsup_req_complete.ies[1].val.session_id,
2257 state := OSMO_GSUP_SESSION_STATE_END,
2258 ss := valueof(facility_rsp)
2259 );
2260
2261 /* Finally, HLR terminates the session */
2262 GSUP.send(gsup_rsp);
2263 /* Expect RELEASE_COMPLETE message with the response */
2264 f_expect_mt_dtap_msg(ussd_rsp);
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002265
2266 f_expect_clear();
2267}
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002268testcase TC_lu_and_mo_ussd_single_request() runs on MTC_CT {
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002269 var BSC_ConnHdlr vc_conn;
2270 f_init();
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002271 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_single_request), 46);
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002272 vc_conn.done;
2273}
2274
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07002275/* LU followed by MT USSD notification */
2276private function f_tc_lu_and_mt_ussd_notification(charstring id, BSC_ConnHdlrPars pars)
2277runs on BSC_ConnHdlr {
2278 f_init_handler(pars);
2279
2280 /* Perform location update */
2281 f_perform_lu();
2282
2283 f_bssmap_register_imsi(g_pars.imsi, g_pars.tmsi);
2284
2285 /* We need to inspect GSUP activity */
2286 f_create_gsup_expect(hex2str(g_pars.imsi));
2287
2288 /* Facility IE with network-originated USSD notification */
2289 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
2290 op_code := SS_OP_CODE_USS_NOTIFY,
2291 ussd_string := "Mahlzeit!"
2292 );
2293
2294 /* Facility IE with acknowledgment to the USSD notification */
2295 var template OCTN facility_rsp := enc_SS_FacilityInformation(
2296 /* In case of USSD notification, Return Result is empty */
2297 valueof(ts_SS_USSD_FACILITY_RETURN_RESULT_EMPTY())
2298 );
2299
2300 /* Compose a new MT SS/REGISTER message with USSD notification */
2301 var template PDU_ML3_NW_MS ussd_ntf := tr_ML3_MT_SS_REGISTER(
2302 tid := 0, /* FIXME: most likely, it should be 0 */
2303 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2304 facility := valueof(facility_req)
2305 );
2306
2307 /* Compose HLR -> MSC GSUP message */
2308 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
2309 imsi := g_pars.imsi,
2310 sid := '20000101'O,
2311 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2312 ss := valueof(facility_req)
2313 );
2314
2315 /* Send it to MSC and expect Paging Request */
2316 GSUP.send(gsup_req);
2317 alt {
2318 [] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
2319 setverdict(pass);
2320 }
2321 /* We don't expect anything else */
2322 [] as_unexp_gsup_or_bssap_msg();
2323 }
2324
2325 /* Send Paging Response and expect USSD notification */
2326 f_establish_fully(EST_TYPE_PAG_RESP);
2327 /* Expect MT REGISTER message with USSD notification */
2328 f_expect_mt_dtap_msg(ussd_ntf);
2329
2330 /* Compose a new MO SS/FACILITY message with empty response */
2331 var template (value) PDU_ML3_MS_NW ussd_rsp := ts_ML3_MO_SS_FACILITY(
2332 tid := 0, /* FIXME: it shall match the request tid */
2333 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
2334 facility := valueof(facility_rsp)
2335 );
2336
2337 /* Compose expected MSC -> HLR GSUP message */
2338 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_REQ(
2339 imsi := g_pars.imsi,
2340 sid := '20000101'O,
2341 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
2342 ss := valueof(facility_rsp)
2343 );
2344
2345 /* MS sends response to the notification */
2346 BSSAP.send(ts_PDU_DTAP_MO(ussd_rsp));
2347 /* Expect GSUP message containing the SS payload */
2348 f_expect_gsup_msg(gsup_rsp);
2349
2350 /* Compose expected MT SS/RELEASE COMPLETE message */
2351 var template PDU_ML3_NW_MS ussd_term := tr_ML3_MT_SS_RELEASE_COMPLETE(
2352 tid := 0, /* FIXME: it shall match the request tid */
2353 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2354 facility := omit
2355 );
2356
2357 /* Compose MSC -> HLR GSUP message */
2358 var template GSUP_PDU gsup_term := ts_GSUP_PROC_SS_REQ(
2359 imsi := g_pars.imsi,
2360 sid := '20000101'O,
2361 state := OSMO_GSUP_SESSION_STATE_END
2362 );
2363
2364 /* Finally, HLR terminates the session */
2365 GSUP.send(gsup_term)
2366 /* Expect MT RELEASE COMPLETE without Facility IE */
2367 f_expect_mt_dtap_msg(ussd_term);
2368
2369 f_expect_clear();
2370}
2371testcase TC_lu_and_mt_ussd_notification() runs on MTC_CT {
2372 var BSC_ConnHdlr vc_conn;
2373 f_init();
2374 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_ussd_notification), 47);
2375 vc_conn.done;
2376}
2377
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002378/* LU followed by MT call and MO USSD request during this call */
2379private function f_tc_lu_and_mo_ussd_during_mt_call(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002380runs on BSC_ConnHdlr {
2381 f_init_handler(pars);
2382
2383 /* Call parameters taken from f_tc_lu_and_mt_call */
2384 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
2385 cpars.mgcp_connection_id_bss := '10004'H;
2386 cpars.mgcp_connection_id_mss := '10005'H;
2387 cpars.mgcp_ep := "rtpbridge/1@mgw";
2388 cpars.bss_rtp_port := 1110;
2389
2390 /* Perform location update */
2391 f_perform_lu();
2392
2393 /* Establish a MT call */
2394 f_mt_call_establish(cpars);
2395
2396 /* Hold the call for some time */
2397 f_sleep(1.0);
2398
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002399 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
2400 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2401 ussd_string := "*#100#"
2402 );
2403
2404 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
2405 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2406 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
2407 )
2408
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002409 /* Compose a new SS/REGISTER message with request */
2410 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
2411 tid := 1, /* We just need a single transaction */
2412 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002413 facility := valueof(facility_req)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002414 );
2415
2416 /* Compose SS/RELEASE_COMPLETE template with expected response */
2417 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
2418 tid := 1, /* Response should arrive within the same transaction */
2419 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002420 facility := valueof(facility_rsp)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002421 );
2422
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002423 /* Compose expected MSC -> HLR message */
2424 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
2425 imsi := g_pars.imsi,
2426 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2427 ss := valueof(facility_req)
2428 );
2429
2430 /* To be used for sending response with correct session ID */
2431 var GSUP_PDU gsup_req_complete;
2432
2433 /* Request own number */
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002434 BSSAP.send(ts_PDU_DTAP_MO(ussd_req));
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002435 /* Expect GSUP message containing the SS payload */
2436 gsup_req_complete := f_expect_gsup_msg(gsup_req);
2437
2438 /* Compose the response from HLR using received session ID */
2439 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
2440 imsi := g_pars.imsi,
2441 sid := gsup_req_complete.ies[1].val.session_id,
2442 state := OSMO_GSUP_SESSION_STATE_END,
2443 ss := valueof(facility_rsp)
2444 );
2445
2446 /* Finally, HLR terminates the session */
2447 GSUP.send(gsup_rsp);
2448 /* Expect RELEASE_COMPLETE message with the response */
2449 f_expect_mt_dtap_msg(ussd_rsp);
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002450
2451 /* Hold the call for some time */
2452 f_sleep(1.0);
2453
2454 /* Release the call (does Clear Complete itself) */
2455 f_call_hangup(cpars, true);
2456}
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002457testcase TC_lu_and_mo_ussd_during_mt_call() runs on MTC_CT {
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002458 var BSC_ConnHdlr vc_conn;
2459 f_init();
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002460 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_during_mt_call), 48);
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002461 vc_conn.done;
2462}
2463
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02002464/* BSSMAP Clear Request in the middle of a call, see OS#3062 */
2465private function f_tc_mo_cc_bssmap_clear(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2466 f_init_handler(pars);
2467 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
2468 var MNCC_PDU mncc;
2469 var MgcpCommand mgcp_cmd;
2470
2471 f_perform_lu();
2472
2473 f_establish_fully();
2474 f_create_mncc_expect(hex2str(cpars.called_party));
2475 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
2476
2477 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
2478 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
2479 cpars.mncc_callref := mncc.u.signal.callref;
2480 log("mncc_callref=", cpars.mncc_callref);
2481 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
2482 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
2483
2484 MNCC.send(ts_MNCC_ALERT_req(cpars.mncc_callref));
2485 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(cpars.transaction_id)));
2486 MGCP.receive(tr_CRCX);
2487
2488 f_sleep(1.0);
2489 BSSAP.send(ts_BSSMAP_ClearRequest(0));
2490
2491 MNCC.receive(tr_MNCC_REL_ind(?, ?)) -> value mncc;
2492
2493 BSSAP.receive(tr_BSSMAP_ClearCommand);
2494 BSSAP.send(ts_BSSMAP_ClearComplete);
2495
2496 f_sleep(1.0);
2497}
2498testcase TC_mo_cc_bssmap_clear() runs on MTC_CT {
2499 var BSC_ConnHdlr vc_conn;
2500 f_init();
2501
2502 vc_conn := f_start_handler(refers(f_tc_mo_cc_bssmap_clear), 43);
2503 vc_conn.done;
2504}
2505
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07002506/* LU followed by MT call and MT USSD request during this call */
2507private function f_tc_lu_and_mt_ussd_during_mt_call(charstring id, BSC_ConnHdlrPars pars)
2508runs on BSC_ConnHdlr {
2509 f_init_handler(pars);
2510
2511 /* Call parameters taken from f_tc_lu_and_mt_call */
2512 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
2513 cpars.mgcp_connection_id_bss := '10004'H;
2514 cpars.mgcp_connection_id_mss := '10005'H;
2515 cpars.mgcp_ep := "rtpbridge/1@mgw";
2516 cpars.bss_rtp_port := 1110;
2517
2518 /* Perform location update */
2519 f_perform_lu();
2520
2521 /* Establish a MT call */
2522 f_mt_call_establish(cpars);
2523
2524 /* Hold the call for some time */
2525 f_sleep(1.0);
2526
2527 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
2528 op_code := SS_OP_CODE_USS_REQUEST,
2529 ussd_string := "Please type anything..."
2530 );
2531
2532 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
2533 op_code := SS_OP_CODE_USS_REQUEST,
2534 ussd_string := "Nope."
2535 )
2536
2537 /* Compose MT SS/REGISTER message with network-originated request */
2538 var template (value) PDU_ML3_NW_MS ussd_req := ts_ML3_MT_SS_REGISTER(
2539 tid := 0, /* FIXME: most likely, it should be 0 */
2540 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2541 facility := valueof(facility_req)
2542 );
2543
2544 /* Compose HLR -> MSC GSUP message */
2545 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
2546 imsi := g_pars.imsi,
2547 sid := '20000101'O,
2548 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2549 ss := valueof(facility_req)
2550 );
2551
2552 /* Send it to MSC */
2553 GSUP.send(gsup_req);
2554 /* Expect MT REGISTER message with USSD request */
2555 f_expect_mt_dtap_msg(ussd_req);
2556
2557 /* Compose a new MO SS/FACILITY message with response */
2558 var template (value) PDU_ML3_MS_NW ussd_rsp := ts_ML3_MO_SS_FACILITY(
2559 tid := 0, /* FIXME: it shall match the request tid */
2560 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
2561 facility := valueof(facility_rsp)
2562 );
2563
2564 /* Compose expected MSC -> HLR GSUP message */
2565 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_REQ(
2566 imsi := g_pars.imsi,
2567 sid := '20000101'O,
2568 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
2569 ss := valueof(facility_rsp)
2570 );
2571
2572 /* MS sends response */
2573 BSSAP.send(ts_PDU_DTAP_MO(ussd_rsp));
2574 f_expect_gsup_msg(gsup_rsp);
2575
2576 /* Compose expected MT SS/RELEASE COMPLETE message */
2577 var template PDU_ML3_NW_MS ussd_term := tr_ML3_MT_SS_RELEASE_COMPLETE(
2578 tid := 0, /* FIXME: it shall match the request tid */
2579 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2580 facility := omit
2581 );
2582
2583 /* Compose MSC -> HLR GSUP message */
2584 var template GSUP_PDU gsup_term := ts_GSUP_PROC_SS_REQ(
2585 imsi := g_pars.imsi,
2586 sid := '20000101'O,
2587 state := OSMO_GSUP_SESSION_STATE_END
2588 );
2589
2590 /* Finally, HLR terminates the session */
2591 GSUP.send(gsup_term);
2592 /* Expect MT RELEASE COMPLETE without Facility IE */
2593 f_expect_mt_dtap_msg(ussd_term);
2594
2595 /* Hold the call for some time */
2596 f_sleep(1.0);
2597
2598 /* Release the call (does Clear Complete itself) */
2599 f_call_hangup(cpars, true);
2600}
2601testcase TC_lu_and_mt_ussd_during_mt_call() runs on MTC_CT {
2602 var BSC_ConnHdlr vc_conn;
2603 f_init();
2604 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_ussd_during_mt_call), 49);
2605 vc_conn.done;
2606}
2607
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07002608/* LU followed by MO USSD request and MO Release during transaction */
2609private function f_tc_lu_and_mo_ussd_mo_release(charstring id, BSC_ConnHdlrPars pars)
2610runs on BSC_ConnHdlr {
2611 f_init_handler(pars);
2612
2613 /* Perform location update */
2614 f_perform_lu();
2615
2616 /* Send CM Service Request for SS/USSD */
2617 f_establish_fully(EST_TYPE_SS_ACT);
2618
2619 /* We need to inspect GSUP activity */
2620 f_create_gsup_expect(hex2str(g_pars.imsi));
2621
2622 var template OCTN facility_ms_req := f_USSD_FACILITY_IE_INVOKE(
2623 invoke_id := 1, /* Initial request */
2624 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2625 ussd_string := "*6766*266#"
2626 );
2627
2628 var template OCTN facility_net_req := f_USSD_FACILITY_IE_INVOKE(
2629 invoke_id := 2, /* Counter request */
2630 op_code := SS_OP_CODE_USS_REQUEST,
2631 ussd_string := "Password?!?"
2632 )
2633
2634 /* Compose MO SS/REGISTER message with request */
2635 var template (value) PDU_ML3_MS_NW ussd_ms_req := ts_ML3_MO_SS_REGISTER(
2636 tid := 1, /* We just need a single transaction */
2637 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2638 facility := valueof(facility_ms_req)
2639 );
2640
2641 /* Compose expected MSC -> HLR message */
2642 var template GSUP_PDU gsup_ms_req := tr_GSUP_PROC_SS_REQ(
2643 imsi := g_pars.imsi,
2644 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2645 ss := valueof(facility_ms_req)
2646 );
2647
2648 /* To be used for sending response with correct session ID */
2649 var GSUP_PDU gsup_ms_req_complete;
2650
2651 /* Initiate a new transaction */
2652 BSSAP.send(ts_PDU_DTAP_MO(ussd_ms_req));
2653 /* Expect GSUP request with original Facility IE */
2654 gsup_ms_req_complete := f_expect_gsup_msg(gsup_ms_req);
2655
2656 /* Compose the response from HLR using received session ID */
2657 var template (value) GSUP_PDU gsup_net_req := ts_GSUP_PROC_SS_REQ(
2658 imsi := g_pars.imsi,
2659 sid := gsup_ms_req_complete.ies[1].val.session_id,
2660 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
2661 ss := valueof(facility_net_req)
2662 );
2663
2664 /* Compose expected MT SS/FACILITY template with counter request */
2665 var template PDU_ML3_NW_MS ussd_net_req := tr_ML3_MT_SS_FACILITY(
2666 tid := 1, /* Response should arrive within the same transaction */
2667 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
2668 facility := valueof(facility_net_req)
2669 );
2670
2671 /* Send response over GSUP */
2672 GSUP.send(gsup_net_req);
2673 /* Expect MT SS/FACILITY message with counter request */
2674 f_expect_mt_dtap_msg(ussd_net_req);
2675
2676 /* Compose MO SS/RELEASE COMPLETE */
2677 var template (value) PDU_ML3_MS_NW ussd_abort := ts_ML3_MO_SS_RELEASE_COMPLETE(
2678 tid := 1, /* Response should arrive within the same transaction */
2679 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2680 facility := omit
2681 /* TODO: cause? */
2682 );
2683
2684 /* Compose expected HLR -> MSC abort message */
2685 var template GSUP_PDU gsup_abort := tr_GSUP_PROC_SS_REQ(
2686 imsi := g_pars.imsi,
2687 sid := gsup_ms_req_complete.ies[1].val.session_id,
2688 state := OSMO_GSUP_SESSION_STATE_END
2689 );
2690
2691 /* Abort transaction */
2692 BSSAP.send(ts_PDU_DTAP_MO(ussd_abort));
2693 /* Expect GSUP message indicating abort */
2694 f_expect_gsup_msg(gsup_abort);
2695
2696 f_expect_clear();
2697}
2698testcase TC_lu_and_mo_ussd_mo_release() runs on MTC_CT {
2699 var BSC_ConnHdlr vc_conn;
2700 f_init();
2701 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_mo_release), 50);
2702 vc_conn.done;
2703}
2704
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07002705/* LU followed by MO USSD request and MT Release due to timeout */
2706private function f_tc_lu_and_ss_session_timeout(charstring id, BSC_ConnHdlrPars pars)
2707runs on BSC_ConnHdlr {
2708 f_init_handler(pars);
2709
2710 /* Perform location update */
2711 f_perform_lu();
2712
2713 /* Send CM Service Request for SS/USSD */
2714 f_establish_fully(EST_TYPE_SS_ACT);
2715
2716 /* We need to inspect GSUP activity */
2717 f_create_gsup_expect(hex2str(g_pars.imsi));
2718
2719 var template OCTN facility_ms_req := f_USSD_FACILITY_IE_INVOKE(
2720 invoke_id := 1,
2721 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2722 ussd_string := "#release_me");
2723
2724 /* Compose MO SS/REGISTER message with request */
2725 var template (value) PDU_ML3_MS_NW ussd_ms_req := ts_ML3_MO_SS_REGISTER(
2726 tid := 1, /* An arbitrary transaction identifier */
2727 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2728 facility := valueof(facility_ms_req));
2729
2730 /* Compose expected MSC -> HLR message */
2731 var template GSUP_PDU gsup_ms_req := tr_GSUP_PROC_SS_REQ(
2732 imsi := g_pars.imsi,
2733 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2734 ss := valueof(facility_ms_req));
2735
2736 /* To be used for sending response with correct session ID */
2737 var GSUP_PDU gsup_ms_req_complete;
2738
2739 /* Initiate a new SS transaction */
2740 BSSAP.send(ts_PDU_DTAP_MO(ussd_ms_req));
2741 /* Expect GSUP request with original Facility IE */
2742 gsup_ms_req_complete := f_expect_gsup_msg(gsup_ms_req);
2743
2744 /* Don't respond, wait for timeout */
2745 f_sleep(3.0);
2746
2747 var template PDU_ML3_NW_MS dtap_rel := tr_ML3_MT_SS_RELEASE_COMPLETE(
2748 tid := 1, /* Should match the request's tid */
2749 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
2750 cause := *, /* TODO: expect some specific value */
2751 facility := omit);
2752
2753 var template GSUP_PDU gsup_rel := tr_GSUP_PROC_SS_ERR(
2754 imsi := g_pars.imsi,
2755 sid := gsup_ms_req_complete.ies[1].val.session_id,
2756 state := OSMO_GSUP_SESSION_STATE_END,
2757 cause := ?); /* TODO: expect some specific value */
2758
2759 /* Expect release on both interfaces */
2760 interleave {
2761 [] BSSAP.receive(tr_PDU_DTAP_MT(dtap_rel)) { };
2762 [] GSUP.receive(gsup_rel) { };
2763 }
2764
2765 f_expect_clear();
2766 setverdict(pass);
2767}
2768testcase TC_lu_and_ss_session_timeout() runs on MTC_CT {
2769 var BSC_ConnHdlr vc_conn;
2770 f_init();
Vadim Yanitskiy36d28dd2018-12-03 02:45:45 +07002771 f_vty_config(MSCVTY, "msc", "ncss guard-timeout 3");
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07002772 vc_conn := f_start_handler(refers(f_tc_lu_and_ss_session_timeout), 51);
2773 vc_conn.done;
Vadim Yanitskiy36d28dd2018-12-03 02:45:45 +07002774 f_vty_config(MSCVTY, "msc", "ncss guard-timeout 0");
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07002775}
2776
Stefan Sperling89eb1f32018-12-17 15:06:20 +01002777/* A5/1 only permitted on network side; attempt an invalid CIPHER MODE COMPLETE with A5/3 which MSC should reject. */
2778private function f_tc_cipher_complete_with_invalid_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2779 pars.net.expect_auth := true;
2780 pars.net.expect_ciph := true;
2781 pars.net.kc_support := '02'O; /* A5/1 only */
2782 f_init_handler(pars);
2783
2784 g_pars.vec := f_gen_auth_vec_2g();
2785
2786 /* Can't use f_perform_lu() directly. Code below is based on it. */
2787
2788 /* tell GSUP dispatcher to send this IMSI to us */
2789 f_create_gsup_expect(hex2str(g_pars.imsi));
2790
2791 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
2792 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
2793 f_bssap_compl_l3(l3_lu);
2794
2795 f_mm_auth();
2796
2797 var OCT1 a5_net := f_alg_mask_from_cm(g_pars.cm2);
2798 var OCT1 a5_intersect := g_pars.net.kc_support and4b a5_net;
2799 alt {
2800 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(a5_intersect, g_pars.vec.kc)) {
2801 BSSAP.send(ts_BSSMAP_CipherModeCompl(int2oct(4 /* "accept" A5/3 */, 1)));
2802 }
2803 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc)) {
2804 setverdict(fail, "Wrong ciphering algorithm mask in CiphModCmd");
2805 mtc.stop;
2806 }
2807 [] BSSAP.receive {
2808 setverdict(fail, "Unknown/unexpected BSSAP received");
2809 mtc.stop;
2810 }
2811 }
2812
2813 /* Expect LU reject from MSC. */
2814 alt {
2815 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
2816 setverdict(pass);
2817 }
2818 [] BSSAP.receive {
2819 setverdict(fail, "Unknown/unexpected BSSAP received");
2820 mtc.stop;
2821 }
2822 }
Stefan Sperlingc620b352018-12-18 17:23:36 +01002823 f_expect_clear();
Stefan Sperling89eb1f32018-12-17 15:06:20 +01002824}
2825
2826testcase TC_cipher_complete_with_invalid_cipher() runs on MTC_CT {
2827 var BSC_ConnHdlr vc_conn;
2828 f_init();
2829 f_vty_config(MSCVTY, "network", "encryption a5 1");
2830
2831 vc_conn := f_start_handler(refers(f_tc_cipher_complete_with_invalid_cipher), 52);
2832 vc_conn.done;
2833}
2834
Harald Weltef640a012018-04-14 17:49:21 +02002835/* TODO (SMS):
2836 * different user data lengths
2837 * SMPP transaction mode with unsuccessful delivery
2838 * queued MT-SMS with no paging response + later delivery
2839 * different data coding schemes
2840 * multi-part SMS
2841 * user-data headers
2842 * TP-PID for SMS to SIM
2843 * behavior if SMS memory is full + RP-SMMA
2844 * delivery reports
2845 * SMPP osmocom extensions
2846 * more-messages-to-send
2847 * SMS during ongoing call (SACCH/SAPI3)
2848 */
2849
2850/* TODO (General):
Harald Welteba7b6d92018-01-23 21:32:34 +01002851 * continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
2852 * malformed messages (missing IE, invalid message type): properly rejected?
2853 * MT call while LU or is ongoing: Do we use existing lchan or page while lchan active?
2854 * 3G/2G auth permutations
2855 * encryption algorithms vs. classmark vs. vty config
Harald Welteba7b6d92018-01-23 21:32:34 +01002856 * send new transaction after/during clear (like SMS, ...)
Harald Welte45164da2018-01-24 12:51:27 +01002857 * too long L3 INFO in DTAP
2858 * too long / padded BSSAP
2859 * too long / short TLV values
Harald Welteba7b6d92018-01-23 21:32:34 +01002860 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01002861
2862
2863control {
Philipp Maier328d1662018-03-07 10:40:27 +01002864 execute( TC_cr_before_reset() );
Harald Weltea49e36e2018-01-21 19:29:33 +01002865 execute( TC_lu_imsi_noauth_tmsi() );
Harald Welted2328a22018-01-27 14:27:16 +01002866 execute( TC_lu_imsi_noauth_notmsi() );
Harald Weltea49e36e2018-01-21 19:29:33 +01002867 execute( TC_lu_imsi_reject() );
2868 execute( TC_lu_imsi_timeout_gsup() );
Harald Welted2328a22018-01-27 14:27:16 +01002869 execute( TC_lu_imsi_auth_tmsi() );
2870 execute( TC_cmserv_imsi_unknown() );
Harald Welte2bb825f2018-01-22 11:31:18 +01002871 execute( TC_lu_and_mo_call() );
Harald Welte071ed732018-01-23 19:53:52 +01002872 execute( TC_lu_auth_sai_timeout() );
2873 execute( TC_lu_auth_sai_err() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01002874 execute( TC_lu_clear_request() );
2875 execute( TC_lu_disconnect() );
2876 execute( TC_lu_by_imei() );
2877 execute( TC_lu_by_tmsi_noauth_unknown() );
2878 execute( TC_imsi_detach_by_imsi() );
2879 execute( TC_imsi_detach_by_tmsi() );
2880 execute( TC_imsi_detach_by_imei() );
2881 execute( TC_emerg_call_imei_reject() );
2882 execute( TC_emerg_call_imsi() );
2883 execute( TC_cm_serv_req_vgcs_reject() );
2884 execute( TC_cm_serv_req_vbs_reject() );
2885 execute( TC_cm_serv_req_lcs_reject() );
Harald Welte0195ab12018-01-24 21:50:20 +01002886 execute( TC_cm_reest_req_reject() );
Harald Welte1af6ea82018-01-25 18:33:15 +01002887 execute( TC_lu_auth_2G_fail() );
2888 execute( TC_lu_imsi_auth_tmsi_encr_13_13() );
2889 execute( TC_cl3_no_payload() );
2890 execute( TC_cl3_rnd_payload() );
Harald Welte1852a842018-01-26 22:53:36 +01002891 execute( TC_establish_and_nothing() );
2892 execute( TC_mo_setup_and_nothing() );
2893 execute( TC_mo_crcx_ran_timeout() );
2894 execute( TC_mo_crcx_ran_reject() );
Harald Welted2328a22018-01-27 14:27:16 +01002895 execute( TC_mt_crcx_ran_reject() );
Daniel Willmann8b084372018-02-04 13:35:26 +01002896 execute( TC_mo_setup_and_dtmf_dup() );
Harald Welteaa54cf82018-01-30 08:15:32 +01002897 //execute( TC_mt_t310() );
Harald Welte167458a2018-01-27 15:58:16 +01002898 execute( TC_gsup_cancel() );
Harald Welte9de84792018-01-28 01:06:35 +01002899 execute( TC_lu_imsi_auth_tmsi_encr_1_13() );
2900 execute( TC_lu_imsi_auth_tmsi_encr_3_13() );
2901 execute( TC_lu_imsi_auth_tmsi_encr_3_1() );
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01002902 execute( TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() );
Harald Welte9de84792018-01-28 01:06:35 +01002903 execute( TC_lu_imsi_auth_tmsi_encr_13_2() );
2904 execute( TC_lu_imsi_auth_tmsi_encr_013_2() );
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002905 execute( TC_mo_release_timeout() );
Philipp Maier2a98a732018-03-19 16:06:12 +01002906 execute( TC_lu_and_mt_call_no_dlcx_resp() );
Philipp Maier75932982018-03-27 14:52:35 +02002907 execute( TC_reset_two() );
Harald Welte33ec09b2018-02-10 15:34:46 +01002908
2909 execute( TC_lu_and_mt_call() );
2910
Harald Weltef45efeb2018-04-09 18:19:24 +02002911 execute( TC_lu_and_mo_sms() );
2912 execute( TC_lu_and_mt_sms() );
Harald Weltef640a012018-04-14 17:49:21 +02002913 execute( TC_smpp_mo_sms() );
2914 execute( TC_smpp_mt_sms() );
Harald Weltef45efeb2018-04-09 18:19:24 +02002915
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002916 execute( TC_lu_and_mo_ussd_single_request() );
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07002917 execute( TC_lu_and_mt_ussd_notification() );
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002918 execute( TC_lu_and_mo_ussd_during_mt_call() );
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07002919 execute( TC_lu_and_mt_ussd_during_mt_call() );
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07002920 execute( TC_lu_and_mo_ussd_mo_release() );
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07002921 execute( TC_lu_and_ss_session_timeout() );
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002922
Stefan Sperling89eb1f32018-12-17 15:06:20 +01002923 execute( TC_cipher_complete_with_invalid_cipher() );
2924
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01002925 /* Run this last: at the time of writing this test crashes the MSC */
2926 execute( TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() );
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02002927 execute( TC_mo_cc_bssmap_clear() );
Harald Weltef6dd64d2017-11-19 12:09:51 +01002928}
2929
2930
2931}