blob: 202bce7e9e956829213425c9340fe3e107fbb7c3 [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;
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +070047import from MobileL3_SMS_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +010048import from L3_Templates all;
Harald Welte158a7ca2018-02-16 18:11:31 +010049import from L3_Common all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010050
Harald Weltef640a012018-04-14 17:49:21 +020051import from SMPP_Types all;
52import from SMPP_Templates all;
53import from SMPP_Emulation all;
54
Stefan Sperlingc307e682018-06-14 15:15:46 +020055import from SCCP_Templates all;
56
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +070057import from SS_Types all;
58import from SS_Templates all;
59import from USSD_Helpers all;
60
Philipp Maier75932982018-03-27 14:52:35 +020061const integer NUM_BSC := 2;
62type record of BSSAP_Configuration BSSAP_Configurations;
Harald Weltef6dd64d2017-11-19 12:09:51 +010063
Harald Weltea4ca4462018-02-09 00:17:14 +010064type component MTC_CT extends CTRL_Adapter_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +010065 var boolean g_initialized := false;
Harald Weltea49e36e2018-01-21 19:29:33 +010066
Philipp Maier75932982018-03-27 14:52:35 +020067 var BSSAP_Adapter g_bssap[NUM_BSC];
Harald Weltea4ca4462018-02-09 00:17:14 +010068
Harald Weltea49e36e2018-01-21 19:29:33 +010069 /* no 'adapter_CT' for MNCC or GSUP */
70 var MNCC_Emulation_CT vc_MNCC;
Harald Welte4aa970c2018-01-26 10:38:09 +010071 var MGCP_Emulation_CT vc_MGCP;
Harald Weltea49e36e2018-01-21 19:29:33 +010072 var GSUP_Emulation_CT vc_GSUP;
73 var IPA_Emulation_CT vc_GSUP_IPA;
Harald Weltef640a012018-04-14 17:49:21 +020074 var SMPP_Emulation_CT vc_SMPP;
Harald Weltea49e36e2018-01-21 19:29:33 +010075
76 /* only to get events from IPA underneath GSUP */
77 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte3ca1c902018-01-24 18:51:27 +010078 /* VTY to MSC */
79 port TELNETasp_PT MSCVTY;
Philipp Maier328d1662018-03-07 10:40:27 +010080
81 /* A port to directly send BSSAP messages. This port is used for
82 * tests that require low level access to sen arbitrary BSSAP
83 * messages. Run f_init_bssap_direct() to connect and initialize */
84 port BSSAP_CODEC_PT BSSAP_DIRECT;
85
86 /* When BSSAP messages are directly sent, then the connection
87 * handler is not active, which means that also no guard timer is
88 * set up. The following timer will serve as a replacement */
89 timer Tguard_direct := 60.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +010090}
91
92modulepar {
Harald Weltea49e36e2018-01-21 19:29:33 +010093 /* remote parameters of IUT */
94 charstring mp_msc_ip := "127.0.0.1";
95 integer mp_msc_ctrl_port := 4255;
96 integer mp_msc_vty_port := 4254;
Harald Weltef6dd64d2017-11-19 12:09:51 +010097
Harald Weltea49e36e2018-01-21 19:29:33 +010098 /* local parameters of emulated HLR */
Philipp Maier9b690e42018-12-21 11:50:03 +010099 boolean mp_mm_info := false;
Harald Weltea49e36e2018-01-21 19:29:33 +0100100 charstring mp_hlr_ip := "127.0.0.1";
101 integer mp_hlr_port := 4222;
Harald Welte6126fb02018-01-27 20:08:24 +0100102 charstring mp_mgw_ip := "127.0.0.1";
103 integer mp_mgw_port := 2427;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100104
Harald Weltea49e36e2018-01-21 19:29:33 +0100105 charstring mp_msc_mncc := "/tmp/mncc";
Harald Weltea4ca4462018-02-09 00:17:14 +0100106
Harald Weltef640a012018-04-14 17:49:21 +0200107 integer mp_msc_smpp_port := 2775;
108 charstring mp_smpp_system_id := "msc_tester";
109 charstring mp_smpp_password := "osmocom1";
110
Philipp Maier75932982018-03-27 14:52:35 +0200111 BSSAP_Configurations mp_bssap_cfg := {
112 {
113 sccp_service_type := "mtp3_itu",
114 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
115 own_pc := 185,
116 own_ssn := 254,
117 peer_pc := 187,
118 peer_ssn := 254,
119 sio := '83'O,
120 rctx := 0
121 },
122 {
123 sccp_service_type := "mtp3_itu",
124 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
125 own_pc := 186,
126 own_ssn := 254,
127 peer_pc := 187,
128 peer_ssn := 254,
129 sio := '83'O,
130 rctx := 1
131 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100132 };
Harald Weltef6dd64d2017-11-19 12:09:51 +0100133}
134
Philipp Maier328d1662018-03-07 10:40:27 +0100135/* altstep for the global guard timer (only used when BSSAP_DIRECT
136 * is used for communication */
137private altstep as_Tguard_direct() runs on MTC_CT {
138 [] Tguard_direct.timeout {
139 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200140 mtc.stop;
Philipp Maier328d1662018-03-07 10:40:27 +0100141 }
142}
Harald Weltef6dd64d2017-11-19 12:09:51 +0100143
Harald Weltef640a012018-04-14 17:49:21 +0200144function f_init_smpp(charstring id) runs on MTC_CT {
145 id := id & "-SMPP";
146 var EsmePars pars := {
147 mode := MODE_TRANSCEIVER,
148 bind := {
149 system_id := mp_smpp_system_id,
150 password := mp_smpp_password,
151 system_type := "MSC_Tests",
152 interface_version := hex2int('34'H),
153 addr_ton := unknown,
154 addr_npi := unknown,
155 address_range := ""
156 },
157 esme_role := true
158 }
159
160 vc_SMPP := SMPP_Emulation_CT.create(id);
161 map(vc_SMPP:SMPP_PORT, system:SMPP_PORT);
162 vc_SMPP.start(SMPP_Emulation.main_client(pars, mp_msc_ip, mp_msc_smpp_port, "", -1));
163}
164
165
Harald Weltea49e36e2018-01-21 19:29:33 +0100166function f_init_mncc(charstring id) runs on MTC_CT {
167 id := id & "-MNCC";
168 var MnccOps ops := {
169 create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
170 unitdata_cb := refers(MNCC_Emulation.DummyUnitdataCallback)
171 }
172
173 vc_MNCC := MNCC_Emulation_CT.create(id);
174 map(vc_MNCC:MNCC, system:MNCC_CODEC_PT);
175 vc_MNCC.start(MNCC_Emulation.main(ops, id, mp_msc_mncc));
Harald Weltef6dd64d2017-11-19 12:09:51 +0100176}
177
Harald Welte4aa970c2018-01-26 10:38:09 +0100178function f_init_mgcp(charstring id) runs on MTC_CT {
179 id := id & "-MGCP";
180 var MGCPOps ops := {
181 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
182 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
183 }
184 var MGCP_conn_parameters pars := {
Harald Welte6126fb02018-01-27 20:08:24 +0100185 callagent_ip := mp_msc_ip,
Harald Welte4aa970c2018-01-26 10:38:09 +0100186 callagent_udp_port := -1,
Harald Welte6126fb02018-01-27 20:08:24 +0100187 mgw_ip := mp_mgw_ip,
188 mgw_udp_port := mp_mgw_port
Harald Welte4aa970c2018-01-26 10:38:09 +0100189 }
190
191 vc_MGCP := MGCP_Emulation_CT.create(id);
192 map(vc_MGCP:MGCP, system:MGCP_CODEC_PT);
193 vc_MGCP.start(MGCP_Emulation.main(ops, pars, id));
194}
195
Harald Weltea49e36e2018-01-21 19:29:33 +0100196function f_init_gsup(charstring id) runs on MTC_CT {
197 id := id & "-GSUP";
198 var GsupOps ops := {
199 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
200 }
201
202 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
203 vc_GSUP := GSUP_Emulation_CT.create(id);
204
205 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
206 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
207 /* we use this hack to get events like ASP_IPA_EVENT_UP */
208 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
209
210 vc_GSUP.start(GSUP_Emulation.main(ops, id));
211 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
212
213 /* wait for incoming connection to GSUP port before proceeding */
214 timer T := 10.0;
215 T.start;
216 alt {
217 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
218 [] T.timeout {
Harald Welte458fd372018-03-21 11:26:23 +0100219 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200220 mtc.stop
Harald Weltea49e36e2018-01-21 19:29:33 +0100221 }
222 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100223}
224
Philipp Maier75932982018-03-27 14:52:35 +0200225function f_init(integer num_bsc := 1) runs on MTC_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +0100226
227 if (g_initialized == true) {
228 return;
229 }
230 g_initialized := true;
231
Philipp Maier75932982018-03-27 14:52:35 +0200232 if (num_bsc > NUM_BSC) {
Daniel Willmannafce8662018-07-06 23:11:32 +0200233 testcase.stop("excess number of BSC instances requested");
Philipp Maier75932982018-03-27 14:52:35 +0200234 }
235
236 for (var integer i := 0; i < num_bsc; i := i + 1) {
237 if (isbound(mp_bssap_cfg[i])) {
Philipp Maierdefd9482018-05-16 16:44:37 +0200238 f_bssap_init(g_bssap[i], mp_bssap_cfg[i], "MSC_Test_" & int2str(i), BSC_BssmapOps);
Harald Welted5833a82018-05-27 16:52:56 +0200239 f_bssap_start(g_bssap[i]);
Philipp Maier75932982018-03-27 14:52:35 +0200240 } else {
Daniel Willmannafce8662018-07-06 23:11:32 +0200241 testcase.stop("missing BSSAP configuration");
Philipp Maier75932982018-03-27 14:52:35 +0200242 }
243 }
244
Harald Weltea49e36e2018-01-21 19:29:33 +0100245 f_ipa_ctrl_start(mp_msc_ip, mp_msc_ctrl_port);
246 f_init_mncc("MSC_Test");
Harald Welte4aa970c2018-01-26 10:38:09 +0100247 f_init_mgcp("MSC_Test");
Harald Weltea49e36e2018-01-21 19:29:33 +0100248 f_init_gsup("MSC_Test");
Harald Weltef640a012018-04-14 17:49:21 +0200249 f_init_smpp("MSC_Test");
Harald Welte3ca1c902018-01-24 18:51:27 +0100250
251 map(self:MSCVTY, system:MSCVTY);
252 f_vty_set_prompts(MSCVTY);
253 f_vty_transceive(MSCVTY, "enable");
Harald Welteb14c77a2018-01-25 17:25:44 +0100254
255 /* set some defaults */
256 f_vty_config(MSCVTY, "network", "authentication optional");
257 f_vty_config(MSCVTY, "msc", "assign-tmsi");
258 f_vty_config(MSCVTY, "network", "encryption a5 0");
Harald Weltef6dd64d2017-11-19 12:09:51 +0100259}
260
Philipp Maier328d1662018-03-07 10:40:27 +0100261/* Initialize for a direct connection to BSSAP. This function is an alternative
262 * to f_init() when the high level functions of the BSC_ConnectionHandler are
263 * not needed. */
264function f_init_bssap_direct() runs on MTC_CT {
Philipp Maier75932982018-03-27 14:52:35 +0200265 f_bssap_init(g_bssap[0], mp_bssap_cfg[0], "MSC_Test", omit);
266 connect(g_bssap[0].vc_SCCP:SCCP_SP_PORT, self:BSSAP_DIRECT);
Philipp Maier328d1662018-03-07 10:40:27 +0100267
268 /* Start guard timer and activate it as default */
269 Tguard_direct.start
270 activate(as_Tguard_direct());
271}
272
Harald Weltef6dd64d2017-11-19 12:09:51 +0100273template PDU_BSSAP ts_BSSAP_BSSMAP := {
274 discriminator := '0'B,
275 spare := '0000000'B,
276 dlci := omit,
277 lengthIndicator := 0, /* overwritten by codec */
278 pdu := ?
279}
280
281template PDU_BSSAP tr_BSSAP_BSSMAP := {
282 discriminator := '0'B,
283 spare := '0000000'B,
284 dlci := omit,
285 lengthIndicator := ?,
286 pdu := {
287 bssmap := ?
288 }
289}
290
291
292type integer BssmapCause;
293
294template (value) BSSMAP_IE_Cause ts_BSSMAP_IE_Cause(BssmapCause val) := {
295 elementIdentifier := '04'O,
296 lengthIndicator := 0,
297 causeValue := int2bit(val, 7),
298 extensionCauseValue := '0'B,
299 spare1 := omit
300}
301
302template (value) PDU_BSSAP ts_BSSMAP_Reset(BssmapCause cause) modifies ts_BSSAP_BSSMAP := {
303 pdu := {
304 bssmap := {
305 reset := {
306 messageType := '30'O,
307 cause := ts_BSSMAP_IE_Cause(cause),
308 a_InterfaceSelectorForReset := omit
309 }
310 }
311 }
312}
313
314template (value) PDU_BSSAP ts_BSSMAP_ResetAck modifies ts_BSSAP_BSSMAP := {
315 pdu := {
316 bssmap := {
317 resetAck := {
318 messageType := '31'O,
319 a_InterfaceSelectorForReset := omit
320 }
321 }
322 }
323}
324
325template PDU_BSSAP tr_BSSMAP_ResetAck modifies tr_BSSAP_BSSMAP := {
326 pdu := {
327 bssmap := {
328 resetAck := {
329 messageType := '31'O,
330 a_InterfaceSelectorForReset := *
331 }
332 }
333 }
334}
335
336template BSSMAP_IE_CellIdentifier ts_BSSMAP_IE_CellID := {
337 elementIdentifier := '05'O,
338 lengthIndicator := 0,
339 cellIdentifierDiscriminator := '0000'B,
340 spare1_4 := '0000'B,
341 cellIdentification := ?
342}
343
344type uint16_t BssmapLAC;
345type uint16_t BssmapCI;
346
347/*
348template BSSMAP_IE_CellIdentifier ts_CellId_CGI(mcc, mnc, lac, ci)
349modifies ts_BSSMAP_IE_CellID := {
350 cellIdentification := {
351 cI_LAC_CGI := {
352 mnc_mcc := FIXME,
353 lac := int2oct(lac, 2),
354 ci := int2oct(ci, 2)
355 }
356 }
357}
358*/
359
360template BSSMAP_IE_CellIdentifier ts_CellID_LAC_CI(BssmapLAC lac, BssmapCI ci)
361modifies ts_BSSMAP_IE_CellID := {
362 cellIdentification := {
363 cI_LAC_CI := {
364 lac := int2oct(lac, 2),
365 ci := int2oct(ci, 2)
366 }
367 }
368}
369
370template BSSMAP_IE_CellIdentifier ts_CellId_CI(BssmapCI ci)
371modifies ts_BSSMAP_IE_CellID := {
372 cellIdentification := {
373 cI_CI := int2oct(ci, 2)
374 }
375}
376
377template BSSMAP_IE_CellIdentifier ts_CellId_none
378modifies ts_BSSMAP_IE_CellID := {
379 cellIdentification := {
380 cI_noCell := ''O
381 }
382}
383
384
385template BSSMAP_IE_Layer3Information ts_BSSMAP_IE_L3Info(octetstring l3info) := {
386 elementIdentifier := '17'O,
387 lengthIndicator := 0,
388 layer3info := l3info
389}
390
391template PDU_BSSAP ts_BSSMAP_ComplL3(BSSMAP_IE_CellIdentifier cell_id, octetstring l3_info)
392modifies ts_BSSAP_BSSMAP := {
393 pdu := {
394 bssmap := {
395 completeLayer3Information := {
396 messageType := '57'O,
397 cellIdentifier := cell_id,
398 layer3Information := ts_BSSMAP_IE_L3Info(l3_info),
399 chosenChannel := omit,
400 lSAIdentifier := omit,
401 aPDU := omit,
402 codecList := omit,
403 redirectAttemptFlag := omit,
404 sendSequenceNumber := omit,
405 iMSI := omit
406 }
407 }
408 }
409}
410
411template PDU_BSSAP ts_BSSMAP_HandoReq(BssmapCause cause, BSSMAP_IE_CellIdentifierList cid_list)
412modifies ts_BSSAP_BSSMAP := {
413 pdu := {
414 bssmap := {
415 handoverRequired := {
416 messageType := '11'O,
417 cause := ts_BSSMAP_IE_Cause(cause),
418 responseRequest := omit,
419 cellIdentifierList := cid_list,
420 circuitPoolList := omit,
421 currentChannelType1 := omit,
422 speechVersion := omit,
423 queueingIndicator := omit,
424 oldToNewBSSInfo := omit,
425 sourceToTargetRNCTransparentInfo := omit,
426 sourceToTargetRNCTransparentInfoCDMA := omit,
427 gERANClassmark := omit,
428 talkerPriority := omit,
429 speechCodec := omit,
430 cSG_Identifier := omit
431 }
432 }
433 }
434}
435
Harald Weltea49e36e2018-01-21 19:29:33 +0100436type function void_fn(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100437
Harald Weltea49e36e2018-01-21 19:29:33 +0100438/* FIXME: move into BSC_ConnectionHandler? */
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100439function f_init_pars(integer imsi_suffix) runs on MTC_CT return BSC_ConnHdlrPars {
Harald Weltede371492018-01-27 23:44:41 +0100440 var BSC_ConnHdlrNetworkPars net_pars := {
441 kc_support := '0A'O, /* A5/1 and A5/3 enabled */
442 expect_tmsi := true,
443 expect_auth := false,
444 expect_ciph := false
445 };
Harald Weltea49e36e2018-01-21 19:29:33 +0100446 var BSC_ConnHdlrPars pars := {
Philipp Maier75932982018-03-27 14:52:35 +0200447 sccp_addr_own := g_bssap[0].sccp_addr_own,
448 sccp_addr_peer := g_bssap[0].sccp_addr_peer,
Harald Welteedbab812018-03-18 16:02:25 +0100449 cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42)),
Harald Welte81b7f9d2018-01-24 19:06:24 +0100450 imei := f_gen_imei(imsi_suffix),
451 imsi := f_gen_imsi(imsi_suffix),
452 msisdn := f_gen_msisdn(imsi_suffix),
Harald Welte256571e2018-01-24 18:47:19 +0100453 tmsi := omit,
Harald Welte9de84792018-01-28 01:06:35 +0100454 cm1 := valueof(ts_CM1),
Harald Welte82600572018-01-21 20:54:08 +0100455 cm2 := valueof(ts_CM2_default),
Harald Welte16114282018-01-24 22:41:21 +0100456 cm3 := omit,
Harald Weltede371492018-01-27 23:44:41 +0100457 vec := omit,
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100458 net := net_pars,
Philipp Maieraeb29a82018-11-08 17:40:53 +0100459 send_early_cm := true,
460 ipa_ctrl_ip := mp_msc_ip,
461 ipa_ctrl_port := mp_msc_ctrl_port,
Philipp Maier9b690e42018-12-21 11:50:03 +0100462 ipa_ctrl_enable := true,
463 mm_info := mp_mm_info
Harald Weltea49e36e2018-01-21 19:29:33 +0100464 };
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100465 return pars;
466}
467
468function f_start_handler_with_pars(void_fn fn, BSC_ConnHdlrPars pars) runs on MTC_CT return BSC_ConnHdlr {
469 var BSC_ConnHdlr vc_conn;
470 var charstring id := testcasename();
Harald Weltea49e36e2018-01-21 19:29:33 +0100471
472 vc_conn := BSC_ConnHdlr.create(id);
473 /* BSSMAP part / A interface */
Philipp Maier75932982018-03-27 14:52:35 +0200474 connect(vc_conn:BSSAP, g_bssap[0].vc_BSSMAP:CLIENT);
475 connect(vc_conn:BSSAP_PROC, g_bssap[0].vc_BSSMAP:PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100476 /* MNCC part */
477 connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
478 connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);
Harald Welte4aa970c2018-01-26 10:38:09 +0100479 /* MGCP part */
480 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
481 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100482 /* GSUP part */
483 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
484 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
Harald Weltef640a012018-04-14 17:49:21 +0200485 /* SMPP part */
486 connect(vc_conn:SMPP, vc_SMPP:SMPP_CLIENT);
487 connect(vc_conn:SMPP_PROC, vc_SMPP:SMPP_PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100488
Harald Weltea10db902018-01-27 12:44:49 +0100489 /* We cannot use vc_conn.start(f_init_handler(fn, id, pars)); as we cannot have
490 * a stand-alone 'derefers()' call, see https://www.eclipse.org/forums/index.php/t/1091364/ */
Harald Weltea49e36e2018-01-21 19:29:33 +0100491 vc_conn.start(derefers(fn)(id, pars));
492 return vc_conn;
493}
494
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100495function f_start_handler(void_fn fn, integer imsi_suffix) runs on MTC_CT return BSC_ConnHdlr {
496 return f_start_handler_with_pars(fn, f_init_pars(imsi_suffix));
497}
498
Harald Weltea49e36e2018-01-21 19:29:33 +0100499private function f_tc_lu_imsi_noauth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100500 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100501 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100502}
Harald Weltea49e36e2018-01-21 19:29:33 +0100503testcase TC_lu_imsi_noauth_tmsi() runs on MTC_CT {
504 var BSC_ConnHdlr vc_conn;
505 f_init();
506
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100507 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi), 1);
Harald Weltea49e36e2018-01-21 19:29:33 +0100508 vc_conn.done;
509}
510
511private function f_tc_lu_imsi_noauth_notmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100512 pars.net.expect_tmsi := false;
Harald Weltea10db902018-01-27 12:44:49 +0100513 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100514 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100515}
Harald Weltea49e36e2018-01-21 19:29:33 +0100516testcase TC_lu_imsi_noauth_notmsi() runs on MTC_CT {
517 var BSC_ConnHdlr vc_conn;
518 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100519 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
Harald Weltea49e36e2018-01-21 19:29:33 +0100520
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100521 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi), 2);
Harald Weltea49e36e2018-01-21 19:29:33 +0100522 vc_conn.done;
523}
524
525/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
526private function f_tc_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100527 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100528 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
529
530 f_create_gsup_expect(hex2str(g_pars.imsi));
531 f_bssap_compl_l3(l3_lu);
532 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
533 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
534 alt {
Harald Welte5946b332018-03-18 23:32:21 +0100535 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej(int2oct(23,1)))) {
536 f_expect_clear();
537 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100538 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
539 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
Daniel Willmannafce8662018-07-06 23:11:32 +0200540 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100541 }
542 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100543}
544testcase TC_lu_imsi_reject() runs on MTC_CT {
545 var BSC_ConnHdlr vc_conn;
546 f_init();
547
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100548 vc_conn := f_start_handler(refers(f_tc_lu_imsi_reject), 3);
Harald Weltea49e36e2018-01-21 19:29:33 +0100549 vc_conn.done;
550}
551
552/* Do LU by IMSI, timeout on GSUP */
553private function f_tc_lu_imsi_timeout_gsup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100554 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100555 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
556
557 f_create_gsup_expect(hex2str(g_pars.imsi));
558 f_bssap_compl_l3(l3_lu);
559 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
560 /* Normally the HLR would need to respond here, but we decide to force a timeout here */
561 alt {
562 /* FIXME: Expect specific reject cause */
Harald Welte5946b332018-03-18 23:32:21 +0100563 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
564 f_expect_clear();
565 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100566 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
567 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
Daniel Willmannafce8662018-07-06 23:11:32 +0200568 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100569 }
570 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100571}
572testcase TC_lu_imsi_timeout_gsup() runs on MTC_CT {
573 var BSC_ConnHdlr vc_conn;
574 f_init();
575
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100576 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_gsup), 4);
Harald Weltea49e36e2018-01-21 19:29:33 +0100577 vc_conn.done;
578}
579
Harald Welte7b1b2812018-01-22 21:23:06 +0100580private function f_tc_lu_imsi_auth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100581 pars.net.expect_auth := true;
Harald Weltea10db902018-01-27 12:44:49 +0100582 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100583 f_perform_lu();
Harald Welte7b1b2812018-01-22 21:23:06 +0100584}
585testcase TC_lu_imsi_auth_tmsi() runs on MTC_CT {
586 var BSC_ConnHdlr vc_conn;
587 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100588 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte7b1b2812018-01-22 21:23:06 +0100589
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100590 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi), 5);
Harald Welte7b1b2812018-01-22 21:23:06 +0100591 vc_conn.done;
592}
593
Harald Weltea49e36e2018-01-21 19:29:33 +0100594
595/* Send CM SERVICE REQ for IMSI that has never performed LU before */
596private function f_tc_cmserv_imsi_unknown(charstring id, BSC_ConnHdlrPars pars)
597runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100598 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100599
600 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welteedbab812018-03-18 16:02:25 +0100601 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100602 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltea49e36e2018-01-21 19:29:33 +0100603
604 f_create_gsup_expect(hex2str(g_pars.imsi));
605
606 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
607 f_bssap_compl_l3(l3_info);
608
609 timer T := 10.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100610 T.start;
611 alt {
Harald Weltea49e36e2018-01-21 19:29:33 +0100612 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
613 //[] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC)) { }
Daniel Willmannafce8662018-07-06 23:11:32 +0200614 [] BSSAP.receive {
615 setverdict(fail, "Received unexpected BSSAP");
616 mtc.stop;
617 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100618 [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
619 setverdict(fail, "Unexpected GSUP UL REQ");
Daniel Willmannafce8662018-07-06 23:11:32 +0200620 mtc.stop;
Harald Weltea49e36e2018-01-21 19:29:33 +0100621 }
Daniel Willmannafce8662018-07-06 23:11:32 +0200622 [] T.timeout {
623 setverdict(fail, "Timeout waiting for CM SERV REQ");
624 mtc.stop;
625 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100626 }
627
Harald Welte1ddc7162018-01-27 14:25:46 +0100628 f_expect_clear();
Harald Weltef6dd64d2017-11-19 12:09:51 +0100629}
Harald Weltea49e36e2018-01-21 19:29:33 +0100630testcase TC_cmserv_imsi_unknown() runs on MTC_CT {
631 var BSC_ConnHdlr vc_conn;
632 f_init();
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100633 vc_conn := f_start_handler(refers(f_tc_cmserv_imsi_unknown), 6);
Harald Weltea49e36e2018-01-21 19:29:33 +0100634 vc_conn.done;
635}
636
Harald Welte2bb825f2018-01-22 11:31:18 +0100637private function f_tc_lu_and_mo_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100638 f_init_handler(pars);
Harald Welteb71901a2018-01-26 19:16:05 +0100639 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
640 cpars.bss_rtp_port := 1110;
641 cpars.mgcp_connection_id_bss := '22222'H;
642 cpars.mgcp_connection_id_mss := '33333'H;
Philipp Maierf1e02bb2018-03-15 16:30:00 +0100643 cpars.mgcp_ep := "rtpbridge/1@mgw";
Harald Welte2bb825f2018-01-22 11:31:18 +0100644
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100645 f_perform_lu();
Harald Welteb71901a2018-01-26 19:16:05 +0100646 f_mo_call(cpars);
Harald Welte2bb825f2018-01-22 11:31:18 +0100647}
648testcase TC_lu_and_mo_call() runs on MTC_CT {
649 var BSC_ConnHdlr vc_conn;
650 f_init();
651
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100652 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_call), 7);
Harald Welte071ed732018-01-23 19:53:52 +0100653 vc_conn.done;
654}
655
656/* Test LU (with authentication enabled), where HLR times out sending SAI response */
657private function f_tc_lu_auth_sai_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100658 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100659
660 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
661 var PDU_DTAP_MT dtap_mt;
662
663 /* tell GSUP dispatcher to send this IMSI to us */
664 f_create_gsup_expect(hex2str(g_pars.imsi));
665
666 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
667 f_bssap_compl_l3(l3_lu);
668
669 /* Send Early Classmark, just for the fun of it */
670 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
671
672 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
673 /* The HLR would normally return an auth vector here, but we fail to do so. */
674
675 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100676 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100677}
678testcase TC_lu_auth_sai_timeout() runs on MTC_CT {
679 var BSC_ConnHdlr vc_conn;
680 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100681 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100682
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100683 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_timeout), 8);
Harald Welte071ed732018-01-23 19:53:52 +0100684 vc_conn.done;
685}
686
687/* Test LU (with authentication enabled), where HLR rejects sending SAI error */
688private function f_tc_lu_auth_sai_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100689 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100690
691 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
692 var PDU_DTAP_MT dtap_mt;
693
694 /* tell GSUP dispatcher to send this IMSI to us */
695 f_create_gsup_expect(hex2str(g_pars.imsi));
696
697 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
698 f_bssap_compl_l3(l3_lu);
699
700 /* Send Early Classmark, just for the fun of it */
701 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
702
703 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
704 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 13));
705
706 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100707 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100708}
709testcase TC_lu_auth_sai_err() runs on MTC_CT {
710 var BSC_ConnHdlr vc_conn;
711 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100712 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100713
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100714 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_err), 9);
Harald Welte2bb825f2018-01-22 11:31:18 +0100715 vc_conn.done;
716}
Harald Weltea49e36e2018-01-21 19:29:33 +0100717
Harald Weltebc881782018-01-23 20:09:15 +0100718/* Test LU but BSC will send a clear request in the middle */
719private function f_tc_lu_clear_request(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100720 f_init_handler(pars);
Harald Weltebc881782018-01-23 20:09:15 +0100721
722 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
723 var PDU_DTAP_MT dtap_mt;
724
725 /* tell GSUP dispatcher to send this IMSI to us */
726 f_create_gsup_expect(hex2str(g_pars.imsi));
727
728 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
729 f_bssap_compl_l3(l3_lu);
730
731 /* Send Early Classmark, just for the fun of it */
732 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
733
734 f_sleep(1.0);
735 /* send clear request in the middle of the LU */
736 BSSAP.send(ts_BSSMAP_ClearRequest(0));
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200737 alt {
738 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { repeat; }
739 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {}
740 }
Harald Weltebc881782018-01-23 20:09:15 +0100741 BSSAP.send(ts_BSSMAP_ClearComplete);
Harald Welte89a32492018-01-27 19:07:28 +0100742 alt {
743 /* See https://osmocom.org/issues/2862 */
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200744 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
745 setverdict(fail, "Got a second Clear Command, only one expected");
Daniel Willmannafce8662018-07-06 23:11:32 +0200746 mtc.stop;
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200747 repeat;
748 }
Harald Welte89a32492018-01-27 19:07:28 +0100749 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
750 }
Harald Weltebc881782018-01-23 20:09:15 +0100751 setverdict(pass);
752}
753testcase TC_lu_clear_request() runs on MTC_CT {
754 var BSC_ConnHdlr vc_conn;
755 f_init();
756
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100757 vc_conn := f_start_handler(refers(f_tc_lu_clear_request), 10);
Harald Weltebc881782018-01-23 20:09:15 +0100758 vc_conn.done;
759}
760
Harald Welte66af9e62018-01-24 17:28:21 +0100761/* Test LU but BSC will send a clear request in the middle */
762private function f_tc_lu_disconnect(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100763 f_init_handler(pars);
Harald Welte66af9e62018-01-24 17:28:21 +0100764
765 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
766 var PDU_DTAP_MT dtap_mt;
767
768 /* tell GSUP dispatcher to send this IMSI to us */
769 f_create_gsup_expect(hex2str(g_pars.imsi));
770
771 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
772 f_bssap_compl_l3(l3_lu);
773
774 /* Send Early Classmark, just for the fun of it */
775 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
776
777 f_sleep(1.0);
778 /* send clear request in the middle of the LU */
779 BSSAP.send(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
780 setverdict(pass);
781}
782testcase TC_lu_disconnect() runs on MTC_CT {
783 var BSC_ConnHdlr vc_conn;
784 f_init();
785
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100786 vc_conn := f_start_handler(refers(f_tc_lu_disconnect), 11);
Harald Welte66af9e62018-01-24 17:28:21 +0100787 vc_conn.done;
788}
789
790
Harald Welteba7b6d92018-01-23 21:32:34 +0100791/* Test LU but with illegal mobile identity type = IMEI */
792private function f_tc_lu_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100793 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100794
Harald Welte256571e2018-01-24 18:47:19 +0100795 var PDU_ML3_MS_NW l3_lu := f_build_lu_imei(g_pars.imei)
Harald Welteba7b6d92018-01-23 21:32:34 +0100796 var PDU_DTAP_MT dtap_mt;
797
798 /* tell GSUP dispatcher to send this IMSI to us */
799 f_create_gsup_expect(hex2str(g_pars.imsi));
800
801 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
802 f_bssap_compl_l3(l3_lu);
803
804 /* Send Early Classmark, just for the fun of it */
805 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
806 /* wait for LU reject, ignore any ID REQ */
807 alt {
808 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
809 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req)) { repeat; }
810 }
811 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100812 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100813}
814testcase TC_lu_by_imei() runs on MTC_CT {
815 var BSC_ConnHdlr vc_conn;
816 f_init();
817
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100818 vc_conn := f_start_handler(refers(f_tc_lu_by_imei), 12);
Harald Welteba7b6d92018-01-23 21:32:34 +0100819 vc_conn.done;
820}
821
822/* Test LU by TMSI with unknown TMSI, expect (and answer) ID REQ. */
823private function f_tc_lu_tmsi_noauth_unknown(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Stefan Sperling04fc4bc2018-06-25 17:44:57 +0200824 /* We piggyback a test for an MSC crash on overlong IMSI (OS#2864) onto this test. */
825 var hexstring overlong_imsi := '012345789ABCDEF0123456789ABCDEF'H;
Harald Weltea10db902018-01-27 12:44:49 +0100826 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100827
828 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('01020304'O); /* FIXME: Random */
829 var PDU_DTAP_MT dtap_mt;
830
831 /* tell GSUP dispatcher to send this IMSI to us */
832 f_create_gsup_expect(hex2str(g_pars.imsi));
833
834 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
835 f_bssap_compl_l3(l3_lu);
836
837 /* Send Early Classmark, just for the fun of it */
838 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
839
840 /* Wait for + respond to ID REQ (IMSI) */
841 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req('001'B)));
Stefan Sperling04fc4bc2018-06-25 17:44:57 +0200842 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 +0100843 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
844
845 /* Expect MSC to do UpdateLocation to HLR; respond to it */
846 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
847 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
848 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
849 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
850
851 alt {
Harald Welte7ec4fa82018-01-27 10:57:40 +0100852 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
853 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
854 }
Harald Welteba7b6d92018-01-23 21:32:34 +0100855 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
856 setverdict(fail, "Expected LU ACK, but received REJ");
Daniel Willmannafce8662018-07-06 23:11:32 +0200857 mtc.stop;
Harald Welteba7b6d92018-01-23 21:32:34 +0100858 }
859 }
860
Philipp Maier9b690e42018-12-21 11:50:03 +0100861 /* Wait for MM-Information (if enabled) */
862 f_expect_mm_info();
863
Harald Welteba7b6d92018-01-23 21:32:34 +0100864 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100865 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100866}
867testcase TC_lu_by_tmsi_noauth_unknown() runs on MTC_CT {
868 var BSC_ConnHdlr vc_conn;
869 f_init();
870
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100871 vc_conn := f_start_handler(refers(f_tc_lu_tmsi_noauth_unknown), 13);
Harald Welteba7b6d92018-01-23 21:32:34 +0100872 vc_conn.done;
873}
874
875
Harald Welte45164da2018-01-24 12:51:27 +0100876/* Test IMSI DETACH (MI=IMSI) */
877private function f_tc_imsi_detach_by_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100878 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100879
880 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
881
882 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
883 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
884
885 /* Send Early Classmark, just for the fun of it? */
886 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
887
888 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100889 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100890}
891testcase TC_imsi_detach_by_imsi() runs on MTC_CT {
892 var BSC_ConnHdlr vc_conn;
893 f_init();
894
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100895 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imsi), 14);
Harald Welte45164da2018-01-24 12:51:27 +0100896 vc_conn.done;
897}
898
899/* Test IMSI DETACH (MI=TMSI) */
900private function f_tc_imsi_detach_by_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100901 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100902
903 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('01020304'O));
904
905 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
906 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
907
908 /* Send Early Classmark, just for the fun of it? */
909 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
910
911 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100912 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100913}
914testcase TC_imsi_detach_by_tmsi() runs on MTC_CT {
915 var BSC_ConnHdlr vc_conn;
916 f_init();
917
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100918 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_tmsi), 15);
Harald Welte45164da2018-01-24 12:51:27 +0100919 vc_conn.done;
920}
921
922/* Test IMSI DETACH (MI=IMEI), which is illegal */
923private function f_tc_imsi_detach_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100924 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100925
Harald Welte256571e2018-01-24 18:47:19 +0100926 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte45164da2018-01-24 12:51:27 +0100927
928 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
929 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
930
931 /* Send Early Classmark, just for the fun of it? */
932 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
933
934 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100935 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100936}
937testcase TC_imsi_detach_by_imei() runs on MTC_CT {
938 var BSC_ConnHdlr vc_conn;
939 f_init();
940
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100941 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imei), 16);
Harald Welte45164da2018-01-24 12:51:27 +0100942 vc_conn.done;
943}
944
945
946/* helper function for an emergency call. caller passes in mobile identity to use */
947private function f_emerg_call(MobileIdentityLV mi) runs on BSC_ConnHdlr {
Harald Welte0bef21e2018-02-10 09:48:23 +0100948 var CallParameters cpars := valueof(t_CallParams('112'H, 0));
949 cpars.emergency := true;
Philipp Maierf1e02bb2018-03-15 16:30:00 +0100950 cpars.mgcp_ep := "rtpbridge/1@mgw";
Harald Welte45164da2018-01-24 12:51:27 +0100951
Harald Welte0bef21e2018-02-10 09:48:23 +0100952 f_mo_call(cpars);
Harald Welte45164da2018-01-24 12:51:27 +0100953}
954
955/* establish an emergency call by IMEI, no SIM inserted (and hence no IMSI) */
956private function f_tc_emerg_call_imei_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100957 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100958
Harald Welte256571e2018-01-24 18:47:19 +0100959 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100960 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100961 f_bssap_compl_l3(l3_info);
962 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ('05'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +0100963 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100964}
965testcase TC_emerg_call_imei_reject() runs on MTC_CT {
966 var BSC_ConnHdlr vc_conn;
967 f_init();
968
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100969 vc_conn := f_start_handler(refers(f_tc_emerg_call_imei_reject), 17);
Harald Welte45164da2018-01-24 12:51:27 +0100970 vc_conn.done;
971}
972
Harald Welted5b91402018-01-24 18:48:16 +0100973/* establish an emergency call by IMSI, SIM inserted (and hence IMSI) */
Harald Welte45164da2018-01-24 12:51:27 +0100974private function f_tc_emerg_call_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100975 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100976 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100977 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +0100978 /* Then issue emergency call identified by IMSI */
979 f_emerg_call(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
980}
981testcase TC_emerg_call_imsi() runs on MTC_CT {
982 var BSC_ConnHdlr vc_conn;
983 f_init();
984
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100985 vc_conn := f_start_handler(refers(f_tc_emerg_call_imsi), 18);
Harald Welte45164da2018-01-24 12:51:27 +0100986 vc_conn.done;
987}
988
989/* CM Service Request for VGCS -> reject */
990private function f_tc_cm_serv_req_vgcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100991 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100992
993 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100994 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +0100995
996 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100997 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VGCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100998 f_bssap_compl_l3(l3_info);
999 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001000 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001001}
1002testcase TC_cm_serv_req_vgcs_reject() runs on MTC_CT {
1003 var BSC_ConnHdlr vc_conn;
1004 f_init();
1005
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001006 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vgcs_reject), 19);
Harald Welte45164da2018-01-24 12:51:27 +01001007 vc_conn.done;
1008}
1009
1010/* CM Service Request for VBS -> reject */
1011private function f_tc_cm_serv_req_vbs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001012 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001013
1014 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001015 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001016
1017 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001018 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VBS, mi));
Harald Welte45164da2018-01-24 12:51:27 +01001019 f_bssap_compl_l3(l3_info);
1020 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001021 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001022}
1023testcase TC_cm_serv_req_vbs_reject() runs on MTC_CT {
1024 var BSC_ConnHdlr vc_conn;
1025 f_init();
1026
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001027 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vbs_reject), 20);
Harald Welte45164da2018-01-24 12:51:27 +01001028 vc_conn.done;
1029}
1030
1031/* CM Service Request for LCS -> reject */
1032private function f_tc_cm_serv_req_lcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001033 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001034
1035 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001036 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001037
1038 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001039 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_LCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +01001040 f_bssap_compl_l3(l3_info);
1041 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001042 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001043}
1044testcase TC_cm_serv_req_lcs_reject() runs on MTC_CT {
1045 var BSC_ConnHdlr vc_conn;
1046 f_init();
1047
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001048 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_lcs_reject), 21);
Harald Welte45164da2018-01-24 12:51:27 +01001049 vc_conn.done;
1050}
1051
Harald Welte0195ab12018-01-24 21:50:20 +01001052/* CM Re-Establishment Request */
1053private function f_tc_cm_reest_req_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001054 f_init_handler(pars);
Harald Welte0195ab12018-01-24 21:50:20 +01001055
1056 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001057 f_perform_lu();
Harald Welte0195ab12018-01-24 21:50:20 +01001058
1059 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1060 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REEST_REQ(0, mi));
1061 f_bssap_compl_l3(l3_info);
1062 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001063 f_expect_clear();
Harald Welte0195ab12018-01-24 21:50:20 +01001064}
1065testcase TC_cm_reest_req_reject() runs on MTC_CT {
1066 var BSC_ConnHdlr vc_conn;
1067 f_init();
Harald Welte0195ab12018-01-24 21:50:20 +01001068
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001069 vc_conn := f_start_handler(refers(f_tc_cm_reest_req_reject), 22);
Harald Welte0195ab12018-01-24 21:50:20 +01001070 vc_conn.done;
1071}
1072
Harald Weltec638f4d2018-01-24 22:00:36 +01001073/* Test LU (with authentication enabled), with wrong response from MS */
1074private function f_tc_lu_auth_2G_fail(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001075 f_init_handler(pars);
Harald Weltec638f4d2018-01-24 22:00:36 +01001076
1077 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
1078
1079 /* tell GSUP dispatcher to send this IMSI to us */
1080 f_create_gsup_expect(hex2str(g_pars.imsi));
1081
1082 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
1083 f_bssap_compl_l3(l3_lu);
1084
1085 /* Send Early Classmark, just for the fun of it */
1086 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1087
1088 var AuthVector vec := f_gen_auth_vec_2g();
1089 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(vec.rand, vec.sres, vec.kc));
1090 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
1091 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
1092
1093 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(vec.rand)));
1094 /* Send back wrong auth response */
1095 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G('00000000'O)));
1096
1097 /* Expect GSUP AUTH FAIL REP to HLR */
1098 GSUP.receive(tr_GSUP_AUTH_FAIL_IND(g_pars.imsi));
1099
1100 /* Expect LU REJECT with Cause == Illegal MS */
1101 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej('03'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +01001102 f_expect_clear();
Harald Weltec638f4d2018-01-24 22:00:36 +01001103}
1104testcase TC_lu_auth_2G_fail() runs on MTC_CT {
1105 var BSC_ConnHdlr vc_conn;
1106 f_init();
1107 f_vty_config(MSCVTY, "network", "authentication required");
Harald Weltec638f4d2018-01-24 22:00:36 +01001108
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001109 vc_conn := f_start_handler(refers(f_tc_lu_auth_2G_fail), 23);
Harald Weltec638f4d2018-01-24 22:00:36 +01001110 vc_conn.done;
1111}
1112
Harald Weltede371492018-01-27 23:44:41 +01001113/* A5/1 + A5/3 permitted on network side, and MS capable to do it */
Harald Welte16114282018-01-24 22:41:21 +01001114private 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 +01001115 pars.net.expect_auth := true;
1116 pars.net.expect_ciph := true;
Harald Weltea10db902018-01-27 12:44:49 +01001117 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001118 f_perform_lu();
Harald Welte16114282018-01-24 22:41:21 +01001119}
1120testcase TC_lu_imsi_auth_tmsi_encr_13_13() runs on MTC_CT {
1121 var BSC_ConnHdlr vc_conn;
1122 f_init();
1123 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte16114282018-01-24 22:41:21 +01001124 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1125
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001126 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_13), 24);
Harald Welte16114282018-01-24 22:41:21 +01001127 vc_conn.done;
1128}
1129
Harald Welte1af6ea82018-01-25 18:33:15 +01001130/* Test Complete L3 without payload */
1131private function f_tc_cl3_no_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001132 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001133
1134 /* Send Complete L3 Info with empty L3 frame */
1135 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1136 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, ''O))));
1137
Harald Weltef466eb42018-01-27 14:26:54 +01001138 timer T := 5.0;
1139 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001140 alt {
1141 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
1142 /* Expect LU REJECT with Cause == Illegal MS */
Harald Weltebdb3c452018-03-18 22:43:06 +01001143 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
1144 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001145 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001146 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001147 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Daniel Willmannafce8662018-07-06 23:11:32 +02001148 mtc.stop;
Harald Weltef466eb42018-01-27 14:26:54 +01001149 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001150 }
1151 setverdict(pass);
1152}
1153testcase TC_cl3_no_payload() runs on MTC_CT {
1154 var BSC_ConnHdlr vc_conn;
1155 f_init();
1156
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001157 vc_conn := f_start_handler(refers(f_tc_cl3_no_payload), 25);
Harald Welte1af6ea82018-01-25 18:33:15 +01001158 vc_conn.done;
1159}
1160
1161/* Test Complete L3 with random payload */
1162private function f_tc_cl3_rnd_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001163 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001164
Daniel Willmannaa14a382018-07-26 08:29:45 +02001165 /* length is limited by PDU_BSSAP length field which includes some
1166 * other fields beside l3info payload. So payl can only be 240 bytes
1167 * Since rnd() returns values < 1 multiply with 241
1168 */
1169 var integer len := float2int(rnd() * 241.0);
Harald Welte1af6ea82018-01-25 18:33:15 +01001170 var octetstring payl := f_rnd_octstring(len);
1171
1172 /* Send Complete L3 Info with empty L3 frame */
1173 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1174 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, payl))));
1175
Harald Weltef466eb42018-01-27 14:26:54 +01001176 timer T := 5.0;
1177 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001178 alt {
1179 /* Immediate disconnect */
1180 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte1af6ea82018-01-25 18:33:15 +01001181 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
Harald Weltebdb3c452018-03-18 22:43:06 +01001182 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001183 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001184 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001185 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Daniel Willmannafce8662018-07-06 23:11:32 +02001186 mtc.stop;
Harald Weltef466eb42018-01-27 14:26:54 +01001187 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001188 }
1189 setverdict(pass);
1190}
1191testcase TC_cl3_rnd_payload() runs on MTC_CT {
1192 var BSC_ConnHdlr vc_conn;
1193 f_init();
1194
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001195 vc_conn := f_start_handler(refers(f_tc_cl3_rnd_payload), 26);
Harald Welte1af6ea82018-01-25 18:33:15 +01001196 vc_conn.done;
1197}
1198
Harald Welte116e4332018-01-26 22:17:48 +01001199/* Test Complete L3 with random payload */
1200private function f_tc_establish_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001201 f_init_handler(pars);
Harald Welte116e4332018-01-26 22:17:48 +01001202
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001203 f_perform_lu();
Harald Welte116e4332018-01-26 22:17:48 +01001204
Harald Welteb9e86fa2018-04-09 18:18:31 +02001205 f_establish_fully();
Daniel Willmann898a7e02018-05-17 12:16:16 +02001206 f_expect_clear(10.0);
Harald Welte116e4332018-01-26 22:17:48 +01001207}
1208testcase TC_establish_and_nothing() runs on MTC_CT {
1209 var BSC_ConnHdlr vc_conn;
1210 f_init();
1211
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001212 vc_conn := f_start_handler(refers(f_tc_establish_and_nothing), 27);
Harald Welte116e4332018-01-26 22:17:48 +01001213 vc_conn.done;
1214}
1215
Harald Welte12510c52018-01-26 22:26:24 +01001216/* Test MO Call SETUP with no response from MNCC */
1217private function f_tc_mo_setup_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Philipp Maier109e6aa2018-10-17 10:53:32 +02001218 f_init_handler(pars, 190.0);
Harald Weltea10db902018-01-27 12:44:49 +01001219
Harald Welte12510c52018-01-26 22:26:24 +01001220 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1221
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001222 f_perform_lu();
Harald Welte12510c52018-01-26 22:26:24 +01001223
Harald Welteb9e86fa2018-04-09 18:18:31 +02001224 f_establish_fully();
Harald Welte12510c52018-01-26 22:26:24 +01001225 f_create_mncc_expect(hex2str(cpars.called_party));
1226 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1227
1228 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1229
Philipp Maier109e6aa2018-10-17 10:53:32 +02001230 f_expect_clear(185.0);
Harald Welte12510c52018-01-26 22:26:24 +01001231}
1232testcase TC_mo_setup_and_nothing() runs on MTC_CT {
1233 var BSC_ConnHdlr vc_conn;
1234 f_init();
1235
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001236 vc_conn := f_start_handler(refers(f_tc_mo_setup_and_nothing), 28);
Harald Welte12510c52018-01-26 22:26:24 +01001237 vc_conn.done;
1238}
1239
Harald Welte3ab88002018-01-26 22:37:25 +01001240/* Test MO Call with no response to RAN-side CRCX */
1241private function f_tc_mo_crcx_ran_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001242 f_init_handler(pars);
Harald Welte3ab88002018-01-26 22:37:25 +01001243 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1244 var MNCC_PDU mncc;
1245 var MgcpCommand mgcp_cmd;
1246
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001247 f_perform_lu();
Harald Welte3ab88002018-01-26 22:37:25 +01001248
Harald Welteb9e86fa2018-04-09 18:18:31 +02001249 f_establish_fully();
Harald Welte3ab88002018-01-26 22:37:25 +01001250 f_create_mncc_expect(hex2str(cpars.called_party));
1251 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1252
1253 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1254 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1255 cpars.mncc_callref := mncc.u.signal.callref;
1256 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1257 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1258
1259 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
Harald Welte1852a842018-01-26 22:53:36 +01001260 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1261 cpars.mgcp_ep := mgcp_cmd.line.ep;
Harald Welte3ab88002018-01-26 22:37:25 +01001262 /* never respond to this */
1263
Philipp Maier8e58f592018-03-14 11:10:56 +01001264 /* When the connection with the MGW fails, the MSC will first request
1265 * a release via call control. We will answer this request normally. */
1266 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1267 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1268
Harald Welte1ddc7162018-01-27 14:25:46 +01001269 f_expect_clear(30.0);
Harald Welte3ab88002018-01-26 22:37:25 +01001270}
1271testcase TC_mo_crcx_ran_timeout() runs on MTC_CT {
1272 var BSC_ConnHdlr vc_conn;
1273 f_init();
1274
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001275 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_timeout), 29);
Harald Welte3ab88002018-01-26 22:37:25 +01001276 vc_conn.done;
1277}
1278
Harald Welte0cc82d92018-01-26 22:52:34 +01001279/* Test MO Call with reject to RAN-side CRCX */
1280private function f_tc_mo_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001281 f_init_handler(pars);
Harald Welte0cc82d92018-01-26 22:52:34 +01001282 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1283 var MNCC_PDU mncc;
1284 var MgcpCommand mgcp_cmd;
1285
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001286 f_perform_lu();
Harald Welte0cc82d92018-01-26 22:52:34 +01001287
Harald Welteb9e86fa2018-04-09 18:18:31 +02001288 f_establish_fully();
Harald Welte0cc82d92018-01-26 22:52:34 +01001289 f_create_mncc_expect(hex2str(cpars.called_party));
1290 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1291
1292 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1293 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1294 cpars.mncc_callref := mncc.u.signal.callref;
1295 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1296 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1297
1298 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001299
1300 /* Detect if the received CRCX is a wildcarded CRCX request. If yes,
1301 * set an endpoint name that fits the pattern. If not, just use the
1302 * endpoint name from the request */
1303 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
1304 cpars.mgcp_ep := "rtpbridge/1@mgw";
1305 } else {
1306 cpars.mgcp_ep := mgcp_cmd.line.ep;
1307 }
1308
Harald Welte0cc82d92018-01-26 22:52:34 +01001309 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001310
Harald Welte0cc82d92018-01-26 22:52:34 +01001311 /* Respond to CRCX with error */
1312 var MgcpResponse mgcp_rsp := {
1313 line := {
1314 code := "542",
1315 trans_id := mgcp_cmd.line.trans_id,
1316 string := "FORCED_FAIL"
1317 },
Harald Welte0cc82d92018-01-26 22:52:34 +01001318 sdp := omit
1319 }
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001320 var MgcpParameter mgcp_rsp_param := {
1321 code := "Z",
1322 val := cpars.mgcp_ep
1323 };
1324 mgcp_rsp.params[0] := mgcp_rsp_param;
Harald Welte0cc82d92018-01-26 22:52:34 +01001325 MGCP.send(mgcp_rsp);
1326
1327 timer T := 30.0;
1328 T.start;
1329 alt {
Daniel Willmannafce8662018-07-06 23:11:32 +02001330 [] T.timeout {
1331 setverdict(fail, "Timeout waiting for channel release");
1332 mtc.stop;
1333 }
Daniel Willmann5868e622018-02-15 17:42:59 +01001334 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id))) {
1335 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1336 repeat;
1337 }
Harald Welte0cc82d92018-01-26 22:52:34 +01001338 [] MNCC.receive { repeat; }
1339 [] GSUP.receive { repeat; }
Philipp Maierc6e06f72018-04-11 18:12:23 +02001340 /* Note: As we did not respond properly to the CRCX from the MSC we
1341 * expect the MSC to omit any further MGCP operation (At least in the
1342 * the current implementation, there is no recovery mechanism implemented
1343 * and a DLCX can not be performed as the MSC does not know a specific
1344 * endpoint yet. */
Daniel Willmannafce8662018-07-06 23:11:32 +02001345 [] MGCP.receive {
1346 setverdict(fail, "Unexpected MGCP message");
1347 mtc.stop;
1348 }
Harald Welte5946b332018-03-18 23:32:21 +01001349 [] as_clear_cmd_compl_disc();
Harald Welte0cc82d92018-01-26 22:52:34 +01001350 }
1351}
1352testcase TC_mo_crcx_ran_reject() runs on MTC_CT {
1353 var BSC_ConnHdlr vc_conn;
1354 f_init();
1355
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001356 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_reject), 30);
Harald Welte0cc82d92018-01-26 22:52:34 +01001357 vc_conn.done;
1358}
1359
Harald Welte3ab88002018-01-26 22:37:25 +01001360
Harald Welte812f7a42018-01-27 00:49:18 +01001361/* helper function to start a MT call: MNCC SETUP; Paging; DChan est.; DTAP SETUP */
1362private function f_mt_call_start(inout CallParameters cpars) runs on BSC_ConnHdlr {
1363 var MNCC_PDU mncc;
1364 var MgcpCommand mgcp_cmd;
1365 var OCT4 tmsi;
1366
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001367 f_perform_lu();
Harald Welte812f7a42018-01-27 00:49:18 +01001368 if (isvalue(g_pars.tmsi)) {
1369 tmsi := g_pars.tmsi;
1370 } else {
1371 tmsi := 'FFFFFFFF'O;
1372 }
1373 f_bssmap_register_imsi(g_pars.imsi, tmsi);
1374
1375 /* Allocate call reference and send SETUP via MNCC to MSC */
1376 cpars.mncc_callref := f_rnd_int(2147483648);
1377 MNCC.send(ts_MNCC_SETUP_req(cpars.mncc_callref, hex2str(g_pars.msisdn),
1378 hex2str(cpars.called_party), hex2str(g_pars.imsi)));
1379
1380 /* MSC->BSC: expect PAGING from MSC */
1381 BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));
1382 /* MS -> MSC: PAGING RESPONSE */
Harald Welteb9e86fa2018-04-09 18:18:31 +02001383 f_establish_fully(EST_TYPE_PAG_RESP);
Harald Welte812f7a42018-01-27 00:49:18 +01001384
1385 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1386
1387 /* MSC->MS: SETUP */
1388 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party)));
1389}
1390
1391/* Test MT Call */
1392private function f_tc_mt_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001393 f_init_handler(pars);
Harald Welte812f7a42018-01-27 00:49:18 +01001394 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1395 var MNCC_PDU mncc;
1396 var MgcpCommand mgcp_cmd;
1397
1398 f_mt_call_start(cpars);
1399
1400 /* MS->MSC: CALL CONFIRMED */
1401 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1402
1403 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1404
1405 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1406 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001407
1408 /* Detect if the received CRCX is a wildcarded CRCX request. If yes,
1409 * set an endpoint name that fits the pattern. If not, just use the
1410 * endpoint name from the request */
1411 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
1412 cpars.mgcp_ep := "rtpbridge/1@mgw";
1413 } else {
1414 cpars.mgcp_ep := mgcp_cmd.line.ep;
1415 }
1416
Harald Welte812f7a42018-01-27 00:49:18 +01001417 /* Respond to CRCX with error */
1418 var MgcpResponse mgcp_rsp := {
1419 line := {
1420 code := "542",
1421 trans_id := mgcp_cmd.line.trans_id,
1422 string := "FORCED_FAIL"
1423 },
Harald Welte812f7a42018-01-27 00:49:18 +01001424 sdp := omit
1425 }
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001426 var MgcpParameter mgcp_rsp_param := {
1427 code := "Z",
1428 val := cpars.mgcp_ep
1429 };
1430 mgcp_rsp.params[0] := mgcp_rsp_param;
Harald Welte812f7a42018-01-27 00:49:18 +01001431 MGCP.send(mgcp_rsp);
1432
1433 timer T := 30.0;
1434 T.start;
1435 alt {
Daniel Willmannafce8662018-07-06 23:11:32 +02001436 [] T.timeout {
1437 setverdict(fail, "Timeout waiting for channel release");
1438 mtc.stop;
1439 }
Harald Welte812f7a42018-01-27 00:49:18 +01001440 [] BSSAP.receive { repeat; }
1441 [] MNCC.receive { repeat; }
1442 [] GSUP.receive { repeat; }
1443 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1444 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1445 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1446 repeat;
1447 }
1448 [] MGCP.receive { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001449 [] as_clear_cmd_compl_disc();
Harald Welte812f7a42018-01-27 00:49:18 +01001450 }
1451}
1452testcase TC_mt_crcx_ran_reject() runs on MTC_CT {
1453 var BSC_ConnHdlr vc_conn;
1454 f_init();
1455
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001456 vc_conn := f_start_handler(refers(f_tc_mt_crcx_ran_reject), 31);
Harald Welte812f7a42018-01-27 00:49:18 +01001457 vc_conn.done;
1458}
1459
1460
1461/* Test MT Call T310 timer */
1462private function f_tc_mt_t310(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltead2952e2018-01-27 14:12:46 +01001463 f_init_handler(pars, 200.0);
Harald Welte812f7a42018-01-27 00:49:18 +01001464 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1465 var MNCC_PDU mncc;
1466 var MgcpCommand mgcp_cmd;
1467
1468 f_mt_call_start(cpars);
1469
1470 /* MS->MSC: CALL CONFIRMED */
1471 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1472 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1473
1474 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1475 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1476 cpars.mgcp_ep := mgcp_cmd.line.ep;
1477 /* FIXME: Respond to CRCX */
1478
1479 /* old libosmocore T310 default timeout is 180s. so let's wait 190 */
1480 timer T := 190.0;
1481 T.start;
1482 alt {
Daniel Willmannafce8662018-07-06 23:11:32 +02001483 [] T.timeout {
1484 setverdict(fail, "Timeout waiting for T310");
1485 mtc.stop;
1486 }
Harald Welte812f7a42018-01-27 00:49:18 +01001487 [] MNCC.receive(tr_MNCC_DISC_ind(cpars.mncc_callref)) {
1488 MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(23))));
1489 }
1490 }
1491 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));
1492 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1493 /* FIXME: We're sending this with TIflag 0: allocated by sender, which is wrong */
1494 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1495
1496 alt {
Harald Welte812f7a42018-01-27 00:49:18 +01001497 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1498 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1499 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1500 repeat;
1501 }
Harald Welte5946b332018-03-18 23:32:21 +01001502 [] as_clear_cmd_compl_disc();
Harald Welte812f7a42018-01-27 00:49:18 +01001503 }
1504}
1505testcase TC_mt_t310() runs on MTC_CT {
1506 var BSC_ConnHdlr vc_conn;
1507 f_init();
1508
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001509 vc_conn := f_start_handler(refers(f_tc_mt_t310), 32);
Harald Welte812f7a42018-01-27 00:49:18 +01001510 vc_conn.done;
1511}
1512
Harald Welte167458a2018-01-27 15:58:16 +01001513/* Perform successful LU + MO call, then GSUP LocationCancel. Subscriber must be denied CM SERV */
1514private function f_tc_gsup_cancel(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1515 f_init_handler(pars);
1516 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1517 cpars.bss_rtp_port := 1110;
1518 cpars.mgcp_connection_id_bss := '22222'H;
1519 cpars.mgcp_connection_id_mss := '33333'H;
Daniel Willmann9b0235b2018-07-24 12:13:34 +02001520 cpars.mgcp_ep := "rtpbridge/1@mgw";
Harald Welte167458a2018-01-27 15:58:16 +01001521
1522 /* Location Update to make subscriber known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001523 f_perform_lu();
Harald Welte167458a2018-01-27 15:58:16 +01001524
1525 /* First MO call should succeed */
1526 f_mo_call(cpars);
1527
1528 /* Cancel the subscriber in the VLR */
1529 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1530 alt {
1531 [] GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi)) { }
1532 [] GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi)) {
1533 setverdict(fail, "Received GSUP Location Cancel Error");
Daniel Willmannafce8662018-07-06 23:11:32 +02001534 mtc.stop;
Harald Welte167458a2018-01-27 15:58:16 +01001535 }
1536 }
1537
1538 /* Follow-up transactions should fail */
1539 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1540 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
1541 f_bssap_compl_l3(l3_info);
1542 alt {
1543 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
1544 [] BSSAP.receive {
1545 setverdict(fail, "Received unexpected BSSAP instead of CM SERV REJ");
Daniel Willmannafce8662018-07-06 23:11:32 +02001546 mtc.stop;
Harald Welte167458a2018-01-27 15:58:16 +01001547 }
1548 }
1549 setverdict(pass);
1550}
1551testcase TC_gsup_cancel() runs on MTC_CT {
1552 var BSC_ConnHdlr vc_conn;
1553 f_init();
1554
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001555 vc_conn := f_start_handler(refers(f_tc_gsup_cancel), 33);
Harald Welte167458a2018-01-27 15:58:16 +01001556 vc_conn.done;
1557}
1558
Harald Welte9de84792018-01-28 01:06:35 +01001559/* A5/1 only permitted on network side, and MS capable to do it */
1560private function f_tc_lu_imsi_auth_tmsi_encr_1_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1561 pars.net.expect_auth := true;
1562 pars.net.expect_ciph := true;
1563 pars.net.kc_support := '02'O; /* A5/1 only */
1564 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001565 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001566}
1567testcase TC_lu_imsi_auth_tmsi_encr_1_13() runs on MTC_CT {
1568 var BSC_ConnHdlr vc_conn;
1569 f_init();
1570 f_vty_config(MSCVTY, "network", "authentication required");
1571 f_vty_config(MSCVTY, "network", "encryption a5 1");
1572
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001573 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_1_13), 34);
Harald Welte9de84792018-01-28 01:06:35 +01001574 vc_conn.done;
1575}
1576
1577/* A5/3 only permitted on network side, and MS capable to do it */
1578private function f_tc_lu_imsi_auth_tmsi_encr_3_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1579 pars.net.expect_auth := true;
1580 pars.net.expect_ciph := true;
1581 pars.net.kc_support := '08'O; /* A5/3 only */
1582 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001583 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001584}
1585testcase TC_lu_imsi_auth_tmsi_encr_3_13() runs on MTC_CT {
1586 var BSC_ConnHdlr vc_conn;
1587 f_init();
1588 f_vty_config(MSCVTY, "network", "authentication required");
1589 f_vty_config(MSCVTY, "network", "encryption a5 3");
1590
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001591 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_13), 35);
Harald Welte9de84792018-01-28 01:06:35 +01001592 vc_conn.done;
1593}
1594
1595/* A5/3 only permitted on network side, and MS with only A5/1 support */
1596private function f_tc_lu_imsi_auth_tmsi_encr_3_1(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1597 pars.net.expect_auth := true;
1598 pars.net.expect_ciph := true;
1599 pars.net.kc_support := '08'O; /* A5/3 only */
1600 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1601 f_init_handler(pars, 15.0);
1602
1603 /* cannot use f_perform_lu() as we expect a reject */
1604 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1605 f_create_gsup_expect(hex2str(g_pars.imsi));
1606 f_bssap_compl_l3(l3_lu);
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001607 if (pars.send_early_cm) {
1608 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1609 } else {
1610 pars.cm1.esind := '0'B;
1611 }
Harald Welte9de84792018-01-28 01:06:35 +01001612 f_mm_auth();
1613 alt {
Daniel Willmann52918e52018-09-20 14:39:09 +02001614 [] BSSAP.receive(tr_BSSMAP_ClassmarkReq) {
1615 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1616 repeat;
1617 }
Harald Welte5946b332018-03-18 23:32:21 +01001618 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1619 f_expect_clear();
1620 }
Harald Welte9de84792018-01-28 01:06:35 +01001621 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1622 setverdict(fail, "CipherModeCommand despite no A5 intersection");
Daniel Willmannafce8662018-07-06 23:11:32 +02001623 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001624 }
1625 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001626 setverdict(fail, "Unknown/unexpected BSSAP received");
Daniel Willmannafce8662018-07-06 23:11:32 +02001627 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001628 }
1629 }
1630 setverdict(pass);
1631}
1632testcase TC_lu_imsi_auth_tmsi_encr_3_1() runs on MTC_CT {
1633 var BSC_ConnHdlr vc_conn;
1634 f_init();
1635 f_vty_config(MSCVTY, "network", "authentication required");
1636 f_vty_config(MSCVTY, "network", "encryption a5 3");
1637
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001638 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 360);
1639 vc_conn.done;
1640}
1641testcase TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() runs on MTC_CT {
1642 var BSC_ConnHdlrPars pars;
1643 var BSC_ConnHdlr vc_conn;
1644 f_init();
1645 f_vty_config(MSCVTY, "network", "authentication required");
1646 f_vty_config(MSCVTY, "network", "encryption a5 3");
1647
1648 pars := f_init_pars(361);
1649 pars.send_early_cm := false;
1650 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 +01001651 vc_conn.done;
1652}
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01001653testcase TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() runs on MTC_CT {
1654 var BSC_ConnHdlr vc_conn;
1655 f_init();
1656 f_vty_config(MSCVTY, "network", "authentication required");
1657 f_vty_config(MSCVTY, "network", "encryption a5 3");
1658
1659 /* Make sure the MSC category is on DEBUG level to trigger the log
1660 * message that is reported in OS#2947 to trigger the segfault */
1661 f_vty_config(MSCVTY, "log stderr", "logging level msc debug");
1662
1663 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 362);
1664 vc_conn.done;
1665}
Harald Welte9de84792018-01-28 01:06:35 +01001666
1667/* A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
1668private function f_tc_lu_imsi_auth_tmsi_encr_13_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1669 pars.net.expect_auth := true;
1670 pars.net.expect_ciph := true;
1671 pars.net.kc_support := '0A'O; /* A5/1 + A5/3 */
1672 pars.cm1.a5_1 := '1'B;
1673 pars.cm2.a5_1 := '1'B;
1674 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1675 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
1676 f_init_handler(pars, 15.0);
1677
1678 /* cannot use f_perform_lu() as we expect a reject */
1679 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1680 f_create_gsup_expect(hex2str(g_pars.imsi));
1681 f_bssap_compl_l3(l3_lu);
1682 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1683 f_mm_auth();
1684 alt {
Harald Welte5946b332018-03-18 23:32:21 +01001685 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1686 f_expect_clear();
1687 }
Harald Welte9de84792018-01-28 01:06:35 +01001688 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1689 setverdict(fail, "CipherModeCommand despite no A5 intersection");
Daniel Willmannafce8662018-07-06 23:11:32 +02001690 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001691 }
1692 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001693 setverdict(fail, "Unknown/unexpected BSSAP received");
Daniel Willmannafce8662018-07-06 23:11:32 +02001694 mtc.stop;
Harald Welte9de84792018-01-28 01:06:35 +01001695 }
1696 }
1697 setverdict(pass);
1698}
1699testcase TC_lu_imsi_auth_tmsi_encr_13_2() runs on MTC_CT {
1700 var BSC_ConnHdlr vc_conn;
1701 f_init();
1702 f_vty_config(MSCVTY, "network", "authentication required");
1703 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1704
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001705 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_2), 37);
Harald Welte9de84792018-01-28 01:06:35 +01001706 vc_conn.done;
1707}
1708
1709/* A5/0 + A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
1710private function f_tc_lu_imsi_auth_tmsi_encr_013_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1711 pars.net.expect_auth := true;
1712 pars.net.expect_ciph := true;
1713 pars.net.kc_support := '0B'O; /* A5/1 + A5/3 */
1714 pars.cm1.a5_1 := '1'B;
1715 pars.cm2.a5_1 := '1'B;
1716 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1717 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
1718 f_init_handler(pars, 15.0);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001719 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001720}
1721testcase TC_lu_imsi_auth_tmsi_encr_013_2() runs on MTC_CT {
1722 var BSC_ConnHdlr vc_conn;
1723 f_init();
1724 f_vty_config(MSCVTY, "network", "authentication required");
1725 f_vty_config(MSCVTY, "network", "encryption a5 0 1 3");
1726
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001727 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_013_2), 38);
Harald Welte9de84792018-01-28 01:06:35 +01001728 vc_conn.done;
1729}
1730
Harald Welte33ec09b2018-02-10 15:34:46 +01001731/* LU followed by MT call (including paging) */
1732private function f_tc_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1733 f_init_handler(pars);
Stefan Sperling26d57be2018-11-12 17:03:26 +01001734 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Harald Welte33ec09b2018-02-10 15:34:46 +01001735 cpars.bss_rtp_port := 1110;
1736 cpars.mgcp_connection_id_bss := '10004'H;
1737 cpars.mgcp_connection_id_mss := '10005'H;
1738
Philipp Maier4b2692d2018-03-14 16:37:48 +01001739 /* Note: This is an optional parameter. When the call-agent (MSC) does
1740 * supply a full endpoint name this setting will be overwritten. */
1741 cpars.mgcp_ep := "rtpbridge/1@mgw";
1742
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001743 f_perform_lu();
Harald Welte33ec09b2018-02-10 15:34:46 +01001744 f_mt_call(cpars);
1745}
1746testcase TC_lu_and_mt_call() runs on MTC_CT {
1747 var BSC_ConnHdlr vc_conn;
1748 f_init();
1749
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001750 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call), 39);
Harald Welte33ec09b2018-02-10 15:34:46 +01001751 vc_conn.done;
1752}
1753
Daniel Willmann8b084372018-02-04 13:35:26 +01001754/* Test MO Call SETUP with DTMF */
1755private function f_tc_mo_setup_dtmf_dup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1756 f_init_handler(pars);
1757 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1758 cpars.bss_rtp_port := 1110;
1759 cpars.mgcp_connection_id_bss := '22222'H;
1760 cpars.mgcp_connection_id_mss := '33333'H;
1761
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001762 f_perform_lu();
Daniel Willmann8b084372018-02-04 13:35:26 +01001763 f_mo_seq_dtmf_dup(cpars);
1764}
1765testcase TC_mo_setup_and_dtmf_dup() runs on MTC_CT {
1766 var BSC_ConnHdlr vc_conn;
1767 f_init();
1768
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001769 vc_conn := f_start_handler(refers(f_tc_mo_setup_dtmf_dup), 39);
Daniel Willmann8b084372018-02-04 13:35:26 +01001770 vc_conn.done;
1771}
Harald Welte9de84792018-01-28 01:06:35 +01001772
Philipp Maier328d1662018-03-07 10:40:27 +01001773testcase TC_cr_before_reset() runs on MTC_CT {
1774 timer T := 4.0;
1775 var boolean reset_ack_seen := false;
1776 f_init_bssap_direct();
1777
Daniel Willmann42d1d5b2018-08-07 15:18:41 +02001778 f_bssap_start(g_bssap[0]);
1779
Daniel Willmanne8018962018-08-21 14:18:00 +02001780 f_sleep(3.0);
1781
Philipp Maier328d1662018-03-07 10:40:27 +01001782 /* Make a blind connection attemt, to trigger the deadlock condition */
Philipp Maier75932982018-03-27 14:52:35 +02001783 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 +01001784
1785 /* Send a BSSMAP reset */
Philipp Maier75932982018-03-27 14:52:35 +02001786 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 +01001787 T.start
1788 alt {
1789 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_ResetAck)) {
1790 reset_ack_seen := true;
1791 repeat;
1792 }
1793
1794 /* Acknowledge MSC sided reset requests */
1795 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) {
Philipp Maier75932982018-03-27 14:52:35 +02001796 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 +01001797 repeat;
1798 }
1799
1800 /* Ignore all other messages (e.g CR from the connection request) */
1801 [] BSSAP_DIRECT.receive { repeat }
1802
1803 /* If we got no BSSMAP RESET ACK back, then the MSC entered the
1804 * deadlock situation. The MSC is then unable to respond to any
1805 * further BSSMAP RESET or any other sort of traffic. */
1806 [reset_ack_seen == true] T.timeout { setverdict(pass) }
1807 [reset_ack_seen == false] T.timeout {
1808 setverdict(fail, "no BSSMAP RESET ACK seen!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001809 mtc.stop;
Philipp Maier328d1662018-03-07 10:40:27 +01001810 }
1811 }
1812}
Harald Welte9de84792018-01-28 01:06:35 +01001813
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001814/* Test MO Call with no response to RAN-side CRCX or DTAP Release */
1815private function f_tc_mo_release_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1816 f_init_handler(pars);
1817 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1818 var MNCC_PDU mncc;
1819 var MgcpCommand mgcp_cmd;
1820
1821 f_perform_lu();
1822
Harald Welteb9e86fa2018-04-09 18:18:31 +02001823 f_establish_fully();
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001824 f_create_mncc_expect(hex2str(cpars.called_party));
1825 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1826
1827 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1828 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1829 cpars.mncc_callref := mncc.u.signal.callref;
1830 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1831 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1832
1833 /* Drop CRCX */
1834 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1835
1836 /* Drop DTAP Release */
1837 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1838
1839 /* Drop resent DTAP Release */
1840 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1841
1842 f_expect_clear(60.0);
1843}
1844testcase TC_mo_release_timeout() runs on MTC_CT {
1845 var BSC_ConnHdlr vc_conn;
1846 f_init();
1847
1848 vc_conn := f_start_handler(refers(f_tc_mo_release_timeout), 40);
1849 vc_conn.done;
1850}
1851
Harald Welte12510c52018-01-26 22:26:24 +01001852
Philipp Maier2a98a732018-03-19 16:06:12 +01001853/* LU followed by MT call (including paging) */
1854private function f_tc_lu_and_mt_call_no_dlcx_resp(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1855 f_init_handler(pars);
Stefan Sperling26d57be2018-11-12 17:03:26 +01001856 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
Philipp Maier2a98a732018-03-19 16:06:12 +01001857 cpars.bss_rtp_port := 1110;
1858 cpars.mgcp_connection_id_bss := '10004'H;
1859 cpars.mgcp_connection_id_mss := '10005'H;
1860
1861 /* Note: This is an optional parameter. When the call-agent (MSC) does
1862 * supply a full endpoint name this setting will be overwritten. */
1863 cpars.mgcp_ep := "rtpbridge/1@mgw";
1864
1865 /* Intentionally disable the CRCX response */
1866 cpars.mgw_drop_dlcx := true;
1867
1868 /* Perform location update and call */
1869 f_perform_lu();
1870 f_mt_call(cpars);
1871}
1872testcase TC_lu_and_mt_call_no_dlcx_resp() runs on MTC_CT {
1873 var BSC_ConnHdlr vc_conn;
1874 f_init();
1875
1876 /* Perform an almost normal looking locationupdate + mt-call, but do
1877 * not respond to the DLCX at the end of the call */
1878 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call_no_dlcx_resp), 41);
1879 vc_conn.done;
1880
1881 /* Wait a guard period until the MGCP layer in the MSC times out,
1882 * if the MSC is vulnerable to the use-after-free situation that is
1883 * fixed by I78f1b6a9149488a4ad3f120c1e190a83c07d4b89 then it should
1884 * segfault now */
1885 f_sleep(6.0);
1886
1887 /* Run the init procedures once more. If the MSC has crashed, this
1888 * this will fail */
1889 f_init();
1890}
Harald Welte45164da2018-01-24 12:51:27 +01001891
Philipp Maier75932982018-03-27 14:52:35 +02001892/* Two BSSMAP resets from two different BSCs */
1893testcase TC_reset_two() runs on MTC_CT {
1894 var BSC_ConnHdlr vc_conn;
1895 f_init(2);
1896 f_sleep(2.0);
1897 setverdict(pass);
1898}
1899
Harald Weltef640a012018-04-14 17:49:21 +02001900/***********************************************************************
1901 * SMS Testing
1902 ***********************************************************************/
1903
Harald Weltef45efeb2018-04-09 18:19:24 +02001904/* LU followed by MO SMS */
1905private function f_tc_lu_and_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1906 var SmsParameters spars := valueof(t_SmsPars);
1907
1908 f_init_handler(pars);
1909
1910 /* Perform location update and call */
1911 f_perform_lu();
1912
1913 f_establish_fully(EST_TYPE_MO_SMS);
1914
1915 //spars.exp_rp_err := 96; /* invalid mandatory information */
1916 f_mo_sms(spars);
1917
1918 f_expect_clear();
1919}
1920testcase TC_lu_and_mo_sms() runs on MTC_CT {
1921 var BSC_ConnHdlr vc_conn;
1922 f_init();
1923 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_sms), 42);
1924 vc_conn.done;
1925}
1926
1927private function f_vty_sms_send(charstring imsi, charstring msisdn, charstring text)
1928runs on MTC_CT {
1929 f_vty_transceive(MSCVTY, "subscriber imsi "&imsi&" sms sender msisdn "&msisdn&" send "&text);
1930}
1931
1932/* LU followed by MT SMS */
1933private function f_tc_lu_and_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1934 var SmsParameters spars := valueof(t_SmsPars);
1935 var OCT4 tmsi;
1936
1937 f_init_handler(pars);
1938
1939 /* Perform location update and call */
1940 f_perform_lu();
1941
1942 /* register an 'expect' for given IMSI (+TMSI) */
1943 if (isvalue(g_pars.tmsi)) {
1944 tmsi := g_pars.tmsi;
1945 } else {
1946 tmsi := 'FFFFFFFF'O;
1947 }
1948 f_bssmap_register_imsi(g_pars.imsi, tmsi);
1949
1950 /* FIXME: actually cause MSC to send a SMS via VTY or SMPP */
1951
1952 /* MSC->BSC: expect PAGING from MSC */
1953 BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));
1954 /* Establish DTAP / BSSAP / SCCP connection */
1955 f_establish_fully(EST_TYPE_PAG_RESP);
1956
1957 spars.tp.ud := 'C8329BFD064D9B53'O;
1958 f_mt_sms(spars);
1959
1960 f_expect_clear();
1961}
1962testcase TC_lu_and_mt_sms() runs on MTC_CT {
1963 var BSC_ConnHdlrPars pars;
1964 var BSC_ConnHdlr vc_conn;
1965 f_init();
1966 pars := f_init_pars(43);
1967 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_sms), pars);
1968 f_sleep(2.0);
1969 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
1970 vc_conn.done;
1971}
1972
Harald Weltef640a012018-04-14 17:49:21 +02001973/* mobile originated SMS from MS/BTS/BSC side to SMPP */
1974private function f_tc_smpp_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1975 var SmsParameters spars := valueof(t_SmsPars);
Harald Weltef45efeb2018-04-09 18:19:24 +02001976
Harald Weltef640a012018-04-14 17:49:21 +02001977 f_init_handler(pars);
Harald Weltef45efeb2018-04-09 18:19:24 +02001978
Harald Weltef640a012018-04-14 17:49:21 +02001979 /* Perform location update so IMSI is known + registered in MSC/VLR */
1980 f_perform_lu();
1981 f_establish_fully(EST_TYPE_MO_SMS);
1982
1983 f_mo_sms(spars);
1984
1985 var SMPP_PDU smpp;
1986 var template SMPP_PDU tr_smpp := tr_SMPP(c_SMPP_command_id_deliver_sm, ESME_ROK);
1987 tr_smpp.body.deliver_sm := {
1988 service_type := "CMT",
1989 source_addr_ton := network_specific,
1990 source_addr_npi := isdn,
1991 source_addr := hex2str(pars.msisdn),
1992 dest_addr_ton := f_sm_ton_from_gsm(spars.tp.da.tP_DA_NoPad.tP_TypeOfNumber),
1993 dest_addr_npi := f_sm_npi_from_gsm(spars.tp.da.tP_DA_NoPad.tP_NumberingPlanID),
1994 destination_addr := hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue),
1995 esm_class := '00000001'B,
1996 protocol_id := 0,
1997 priority_flag := 0,
1998 schedule_delivery_time := "",
1999 replace_if_present := 0,
2000 data_coding := '00000001'B,
2001 sm_default_msg_id := 0,
2002 sm_length := ?,
2003 short_message := spars.tp.ud,
2004 opt_pars := {
2005 {
2006 tag := user_message_reference,
2007 len := 2,
2008 opt_value := {
2009 int2_val := oct2int(spars.tp.msg_ref)
2010 }
2011 }
2012 }
2013 };
2014 alt {
2015 [] SMPP.receive(tr_smpp) -> value smpp {
2016 SMPP.send(ts_SMPP_DELIVER_SM_resp(ESME_ROK, smpp.header.seq_num));
2017 }
2018 [] SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK)) { repeat; }
2019 }
2020
2021 f_expect_clear();
2022}
2023testcase TC_smpp_mo_sms() runs on MTC_CT {
2024 var BSC_ConnHdlr vc_conn;
2025 f_init();
2026 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "default-route");
2027 vc_conn := f_start_handler(refers(f_tc_smpp_mo_sms), 44);
2028 vc_conn.done;
2029 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "no default-route");
2030}
2031
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002032/* Test MO-SMS from MS/BTS/BSC towards HLR (via GSUP) */
2033private function f_tc_gsup_mo_sms(charstring id, BSC_ConnHdlrPars pars)
2034runs on BSC_ConnHdlr {
2035 var SmsParameters spars := valueof(t_SmsPars);
2036 var GSUP_PDU gsup_msg_rx;
2037 var octetstring sm_tpdu;
2038
2039 f_init_handler(pars);
2040
2041 /* We need to inspect GSUP activity */
2042 f_create_gsup_expect(hex2str(g_pars.imsi));
2043
2044 /* Perform location update */
2045 f_perform_lu();
2046
2047 /* Send CM Service Request for SMS */
2048 f_establish_fully(EST_TYPE_MO_SMS);
2049
2050 /* Prepare expected SM-RP-UI (SM TPDU) */
2051 enc_TPDU_RP_DATA_MS_SGSN_fast(
2052 valueof(ts_SMS_SUBMIT(spars.tp.msg_ref,
2053 spars.tp.da, spars.tp.pid, spars.tp.dcs,
2054 spars.tp.udl, spars.tp.ud)),
2055 sm_tpdu);
2056
2057 var template GSUP_PDU mo_forwardSM := tr_GSUP_MO_FORWARD_SM_REQ(
2058 imsi := g_pars.imsi,
2059 sm_rp_mr := spars.rp.msg_ref,
2060 /* FIXME: extract SM-RP-DA from spars.rp.dest */
2061 sm_rp_da := tr_GSUP_SM_RP_DA_SMSC_ADDR(?),
2062 /* FIXME: MSISDN coding troubles */
2063 sm_rp_oa := tr_GSUP_SM_RP_OA_MSISDN(?),
2064 /* TODO: can we use decmatch here? */
2065 sm_rp_ui := sm_tpdu
2066 );
2067
2068 /* Submit an SMS on DTAP and expect MO-forwardSM-Req on GSUP */
2069 f_mo_sms_submit(spars);
2070 alt {
2071 [] GSUP.receive(mo_forwardSM) -> value gsup_msg_rx {
2072 log("RX MO-forwardSM-Req");
2073 log(gsup_msg_rx);
2074 setverdict(pass);
2075 }
2076 [] GSUP.receive {
2077 log("RX unexpected GSUP message");
2078 setverdict(fail);
2079 mtc.stop;
2080 }
2081 }
2082
2083 /* Trigger RP-ACK by sending MO-forwardSM-Res */
2084 GSUP.send(valueof(ts_GSUP_MO_FORWARD_SM_RES(
2085 imsi := g_pars.imsi,
2086 sm_rp_mr := spars.rp.msg_ref)));
2087 /* Expect RP-ACK on DTAP */
2088 f_mo_sms_wait_rp_ack(spars);
2089
2090 f_expect_clear();
2091}
2092testcase TC_gsup_mo_sms() runs on MTC_CT {
2093 var BSC_ConnHdlr vc_conn;
2094 f_init();
2095 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2096 vc_conn := f_start_handler(refers(f_tc_gsup_mo_sms), 88);
2097 vc_conn.done;
2098 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2099}
2100
Harald Weltef640a012018-04-14 17:49:21 +02002101/* convert GSM L3 TON to SMPP_TON enum */
2102function f_sm_ton_from_gsm(BIT3 ton) return SMPP_TON {
2103 select (ton) {
2104 case ('000'B) { return unknown; }
2105 case ('001'B) { return international; }
2106 case ('010'B) { return national; }
2107 case ('011'B) { return network_specific; }
2108 case ('100'B) { return subscriber_number; }
2109 case ('101'B) { return alphanumeric; }
2110 case ('110'B) { return abbreviated; }
2111 }
2112 setverdict(fail, "Unknown TON ", ton);
Daniel Willmannafce8662018-07-06 23:11:32 +02002113 mtc.stop;
Harald Weltef640a012018-04-14 17:49:21 +02002114}
2115/* convert GSM L3 NPI to SMPP_NPI enum */
2116function f_sm_npi_from_gsm(BIT4 npi) return SMPP_NPI {
2117 select (npi) {
2118 case ('0000'B) { return unknown; }
2119 case ('0001'B) { return isdn; }
2120 case ('0011'B) { return data; }
2121 case ('0100'B) { return telex; }
2122 case ('0110'B) { return land_mobile; }
2123 case ('1000'B) { return national; }
2124 case ('1001'B) { return private_; }
2125 case ('1010'B) { return ermes; }
2126 }
2127 setverdict(fail, "Unknown NPI ", npi);
Daniel Willmannafce8662018-07-06 23:11:32 +02002128 mtc.stop;
Harald Weltef640a012018-04-14 17:49:21 +02002129}
2130
2131/* build a SMPP_SM from SmsParameters */
2132function f_mt_sm_from_spars(SmsParameters spars)
2133runs on BSC_ConnHdlr return SMPP_SM {
2134 var SMPP_SM sm := {
2135 service_type := "CMT",
2136 source_addr_ton := f_sm_ton_from_gsm(spars.tp.da.tP_DA_NoPad.tP_TypeOfNumber),
2137 source_addr_npi := f_sm_npi_from_gsm(spars.tp.da.tP_DA_NoPad.tP_NumberingPlanID),
2138 source_addr := hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue),
2139 dest_addr_ton := international,
2140 dest_addr_npi := isdn,
2141 destination_addr := hex2str(g_pars.msisdn),
2142 esm_class := '00000001'B,
2143 protocol_id := 0,
2144 priority_flag := 0,
2145 schedule_delivery_time := "",
2146 validity_period := "",
2147 registered_delivery := '00000000'B,
2148 replace_if_present := 0,
2149 data_coding := '00000001'B,
2150 sm_default_msg_id := 0,
2151 sm_length := spars.tp.udl,
2152 short_message := spars.tp.ud,
2153 opt_pars := {}
2154 };
2155 return sm;
2156}
2157
2158/* helper function to encode SMS from 'spars', send it via SMPP to MSC; receive it on MS side */
2159private function f_smpp_mt_sms(SmsParameters spars, boolean trans_mode) runs on BSC_ConnHdlr {
2160 var SMPP_SM sm := f_mt_sm_from_spars(spars);
2161 if (trans_mode) {
2162 sm.esm_class := '00000010'B;
2163 }
2164
2165 /* actually cause MSC to send a SMS via SUBMIT-SM from SMPP side */
2166 SMPP.send(ts_SMPP_SUBMIT_SM(sm));
2167 if (not match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
2168 /* if we're not in SMPP transaction mode, we expect the SMPP-level ACK
2169 * before we expect the SMS delivery on the BSC/radio side */
2170 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
2171 }
2172
2173 /* MSC->BSC: expect PAGING from MSC */
2174 BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));
2175 /* Establish DTAP / BSSAP / SCCP connection */
2176 f_establish_fully(EST_TYPE_PAG_RESP);
2177 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
2178
2179 f_mt_sms(spars);
2180
2181 if (match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
2182 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
2183 }
2184 f_expect_clear();
2185}
2186
2187/* mobile terminated SMS, from SMPP to BSC/BTS/MS */
2188private function f_tc_smpp_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2189 f_init_handler(pars);
2190
2191 /* Perform location update so IMSI is known + registered in MSC/VLR */
2192 f_perform_lu();
2193 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
2194
2195 /* register an 'expect' for given IMSI (+TMSI) */
2196 var OCT4 tmsi;
2197 if (isvalue(g_pars.tmsi)) {
2198 tmsi := g_pars.tmsi;
2199 } else {
2200 tmsi := 'FFFFFFFF'O;
2201 }
2202 f_bssmap_register_imsi(g_pars.imsi, tmsi);
2203
2204 var SmsParameters spars := valueof(t_SmsPars);
2205 /* TODO: test with more intelligent user data; test different coding schemes */
2206 spars.tp.ud := '00'O;
2207 spars.tp.udl := 1;
2208
2209 /* first test the non-transaction store+forward mode */
2210 f_smpp_mt_sms(spars, false);
2211
2212 /* then test the transaction mode */
2213 f_smpp_mt_sms(spars, true);
2214}
2215testcase TC_smpp_mt_sms() runs on MTC_CT {
2216 var BSC_ConnHdlr vc_conn;
2217 f_init();
2218 vc_conn := f_start_handler(refers(f_tc_smpp_mt_sms), 45);
2219 vc_conn.done;
2220}
2221
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002222/***********************************************************************
2223 * USSD Testing
2224 ***********************************************************************/
2225
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07002226private altstep as_unexp_gsup_or_bssap_msg()
2227runs on BSC_ConnHdlr {
2228 [] GSUP.receive {
2229 setverdict(fail, "Unknown/unexpected GSUP received");
2230 self.stop;
2231 }
2232 [] BSSAP.receive {
2233 setverdict(fail, "Unknown/unexpected BSSAP message received");
2234 self.stop;
2235 }
2236}
2237
2238private function f_expect_gsup_msg(template GSUP_PDU msg)
2239runs on BSC_ConnHdlr return GSUP_PDU {
2240 var GSUP_PDU gsup_msg_complete;
2241
2242 alt {
2243 [] GSUP.receive(msg) -> value gsup_msg_complete {
2244 setverdict(pass);
2245 }
2246 /* We don't expect anything else */
2247 [] as_unexp_gsup_or_bssap_msg();
2248 }
2249
2250 return gsup_msg_complete;
2251}
2252
2253private function f_expect_mt_dtap_msg(template PDU_ML3_NW_MS msg)
2254runs on BSC_ConnHdlr return PDU_ML3_NW_MS {
2255 var PDU_DTAP_MT bssap_msg_complete;
2256
2257 alt {
2258 [] BSSAP.receive(tr_PDU_DTAP_MT(msg)) -> value bssap_msg_complete {
2259 setverdict(pass);
2260 }
2261 /* We don't expect anything else */
2262 [] as_unexp_gsup_or_bssap_msg();
2263 }
2264
2265 return bssap_msg_complete.dtap;
2266}
2267
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002268/* LU followed by MO USSD request */
2269private function f_tc_lu_and_mo_ussd_single_request(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002270runs on BSC_ConnHdlr {
2271 f_init_handler(pars);
2272
2273 /* Perform location update */
2274 f_perform_lu();
2275
2276 /* Send CM Service Request for SS/USSD */
2277 f_establish_fully(EST_TYPE_SS_ACT);
2278
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002279 /* We need to inspect GSUP activity */
2280 f_create_gsup_expect(hex2str(g_pars.imsi));
2281
2282 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
2283 invoke_id := 5, /* Phone may not start from 0 or 1 */
2284 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2285 ussd_string := "*#100#"
2286 );
2287
2288 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
2289 invoke_id := 5, /* InvokeID shall be the same for both REQ and RSP */
2290 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2291 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
2292 )
2293
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002294 /* Compose a new SS/REGISTER message with request */
2295 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
2296 tid := 1, /* We just need a single transaction */
2297 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002298 facility := valueof(facility_req)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002299 );
2300
2301 /* Compose SS/RELEASE_COMPLETE template with expected response */
2302 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
2303 tid := 1, /* Response should arrive within the same transaction */
2304 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002305 facility := valueof(facility_rsp)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002306 );
2307
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002308 /* Compose expected MSC -> HLR message */
2309 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
2310 imsi := g_pars.imsi,
2311 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2312 ss := valueof(facility_req)
2313 );
2314
2315 /* To be used for sending response with correct session ID */
2316 var GSUP_PDU gsup_req_complete;
2317
2318 /* Request own number */
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002319 BSSAP.send(ts_PDU_DTAP_MO(ussd_req));
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002320 /* Expect GSUP message containing the SS payload */
2321 gsup_req_complete := f_expect_gsup_msg(gsup_req);
2322
2323 /* Compose the response from HLR using received session ID */
2324 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
2325 imsi := g_pars.imsi,
2326 sid := gsup_req_complete.ies[1].val.session_id,
2327 state := OSMO_GSUP_SESSION_STATE_END,
2328 ss := valueof(facility_rsp)
2329 );
2330
2331 /* Finally, HLR terminates the session */
2332 GSUP.send(gsup_rsp);
2333 /* Expect RELEASE_COMPLETE message with the response */
2334 f_expect_mt_dtap_msg(ussd_rsp);
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002335
2336 f_expect_clear();
2337}
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002338testcase TC_lu_and_mo_ussd_single_request() runs on MTC_CT {
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002339 var BSC_ConnHdlr vc_conn;
2340 f_init();
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002341 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_single_request), 46);
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002342 vc_conn.done;
2343}
2344
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07002345/* LU followed by MT USSD notification */
2346private function f_tc_lu_and_mt_ussd_notification(charstring id, BSC_ConnHdlrPars pars)
2347runs on BSC_ConnHdlr {
2348 f_init_handler(pars);
2349
2350 /* Perform location update */
2351 f_perform_lu();
2352
2353 f_bssmap_register_imsi(g_pars.imsi, g_pars.tmsi);
2354
2355 /* We need to inspect GSUP activity */
2356 f_create_gsup_expect(hex2str(g_pars.imsi));
2357
2358 /* Facility IE with network-originated USSD notification */
2359 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
2360 op_code := SS_OP_CODE_USS_NOTIFY,
2361 ussd_string := "Mahlzeit!"
2362 );
2363
2364 /* Facility IE with acknowledgment to the USSD notification */
2365 var template OCTN facility_rsp := enc_SS_FacilityInformation(
2366 /* In case of USSD notification, Return Result is empty */
2367 valueof(ts_SS_USSD_FACILITY_RETURN_RESULT_EMPTY())
2368 );
2369
2370 /* Compose a new MT SS/REGISTER message with USSD notification */
2371 var template PDU_ML3_NW_MS ussd_ntf := tr_ML3_MT_SS_REGISTER(
2372 tid := 0, /* FIXME: most likely, it should be 0 */
2373 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2374 facility := valueof(facility_req)
2375 );
2376
2377 /* Compose HLR -> MSC GSUP message */
2378 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
2379 imsi := g_pars.imsi,
2380 sid := '20000101'O,
2381 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2382 ss := valueof(facility_req)
2383 );
2384
2385 /* Send it to MSC and expect Paging Request */
2386 GSUP.send(gsup_req);
2387 alt {
2388 [] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
2389 setverdict(pass);
2390 }
2391 /* We don't expect anything else */
2392 [] as_unexp_gsup_or_bssap_msg();
2393 }
2394
2395 /* Send Paging Response and expect USSD notification */
2396 f_establish_fully(EST_TYPE_PAG_RESP);
2397 /* Expect MT REGISTER message with USSD notification */
2398 f_expect_mt_dtap_msg(ussd_ntf);
2399
2400 /* Compose a new MO SS/FACILITY message with empty response */
2401 var template (value) PDU_ML3_MS_NW ussd_rsp := ts_ML3_MO_SS_FACILITY(
2402 tid := 0, /* FIXME: it shall match the request tid */
2403 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
2404 facility := valueof(facility_rsp)
2405 );
2406
2407 /* Compose expected MSC -> HLR GSUP message */
2408 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_REQ(
2409 imsi := g_pars.imsi,
2410 sid := '20000101'O,
2411 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
2412 ss := valueof(facility_rsp)
2413 );
2414
2415 /* MS sends response to the notification */
2416 BSSAP.send(ts_PDU_DTAP_MO(ussd_rsp));
2417 /* Expect GSUP message containing the SS payload */
2418 f_expect_gsup_msg(gsup_rsp);
2419
2420 /* Compose expected MT SS/RELEASE COMPLETE message */
2421 var template PDU_ML3_NW_MS ussd_term := tr_ML3_MT_SS_RELEASE_COMPLETE(
2422 tid := 0, /* FIXME: it shall match the request tid */
2423 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2424 facility := omit
2425 );
2426
2427 /* Compose MSC -> HLR GSUP message */
2428 var template GSUP_PDU gsup_term := ts_GSUP_PROC_SS_REQ(
2429 imsi := g_pars.imsi,
2430 sid := '20000101'O,
2431 state := OSMO_GSUP_SESSION_STATE_END
2432 );
2433
2434 /* Finally, HLR terminates the session */
2435 GSUP.send(gsup_term)
2436 /* Expect MT RELEASE COMPLETE without Facility IE */
2437 f_expect_mt_dtap_msg(ussd_term);
2438
2439 f_expect_clear();
2440}
2441testcase TC_lu_and_mt_ussd_notification() runs on MTC_CT {
2442 var BSC_ConnHdlr vc_conn;
2443 f_init();
2444 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_ussd_notification), 47);
2445 vc_conn.done;
2446}
2447
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002448/* LU followed by MT call and MO USSD request during this call */
2449private function f_tc_lu_and_mo_ussd_during_mt_call(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002450runs on BSC_ConnHdlr {
2451 f_init_handler(pars);
2452
2453 /* Call parameters taken from f_tc_lu_and_mt_call */
2454 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
2455 cpars.mgcp_connection_id_bss := '10004'H;
2456 cpars.mgcp_connection_id_mss := '10005'H;
2457 cpars.mgcp_ep := "rtpbridge/1@mgw";
2458 cpars.bss_rtp_port := 1110;
2459
2460 /* Perform location update */
2461 f_perform_lu();
2462
2463 /* Establish a MT call */
2464 f_mt_call_establish(cpars);
2465
2466 /* Hold the call for some time */
2467 f_sleep(1.0);
2468
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002469 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
2470 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2471 ussd_string := "*#100#"
2472 );
2473
2474 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
2475 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2476 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
2477 )
2478
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002479 /* Compose a new SS/REGISTER message with request */
2480 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
2481 tid := 1, /* We just need a single transaction */
2482 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002483 facility := valueof(facility_req)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002484 );
2485
2486 /* Compose SS/RELEASE_COMPLETE template with expected response */
2487 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
2488 tid := 1, /* Response should arrive within the same transaction */
2489 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002490 facility := valueof(facility_rsp)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002491 );
2492
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002493 /* Compose expected MSC -> HLR message */
2494 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
2495 imsi := g_pars.imsi,
2496 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2497 ss := valueof(facility_req)
2498 );
2499
2500 /* To be used for sending response with correct session ID */
2501 var GSUP_PDU gsup_req_complete;
2502
2503 /* Request own number */
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002504 BSSAP.send(ts_PDU_DTAP_MO(ussd_req));
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002505 /* Expect GSUP message containing the SS payload */
2506 gsup_req_complete := f_expect_gsup_msg(gsup_req);
2507
2508 /* Compose the response from HLR using received session ID */
2509 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
2510 imsi := g_pars.imsi,
2511 sid := gsup_req_complete.ies[1].val.session_id,
2512 state := OSMO_GSUP_SESSION_STATE_END,
2513 ss := valueof(facility_rsp)
2514 );
2515
2516 /* Finally, HLR terminates the session */
2517 GSUP.send(gsup_rsp);
2518 /* Expect RELEASE_COMPLETE message with the response */
2519 f_expect_mt_dtap_msg(ussd_rsp);
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002520
2521 /* Hold the call for some time */
2522 f_sleep(1.0);
2523
2524 /* Release the call (does Clear Complete itself) */
2525 f_call_hangup(cpars, true);
2526}
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002527testcase TC_lu_and_mo_ussd_during_mt_call() runs on MTC_CT {
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002528 var BSC_ConnHdlr vc_conn;
2529 f_init();
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002530 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_during_mt_call), 48);
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002531 vc_conn.done;
2532}
2533
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02002534/* BSSMAP Clear Request in the middle of a call, see OS#3062 */
2535private function f_tc_mo_cc_bssmap_clear(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2536 f_init_handler(pars);
2537 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
2538 var MNCC_PDU mncc;
2539 var MgcpCommand mgcp_cmd;
2540
2541 f_perform_lu();
2542
2543 f_establish_fully();
2544 f_create_mncc_expect(hex2str(cpars.called_party));
2545 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
2546
2547 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
2548 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
2549 cpars.mncc_callref := mncc.u.signal.callref;
2550 log("mncc_callref=", cpars.mncc_callref);
2551 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
2552 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
2553
2554 MNCC.send(ts_MNCC_ALERT_req(cpars.mncc_callref));
2555 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(cpars.transaction_id)));
2556 MGCP.receive(tr_CRCX);
2557
2558 f_sleep(1.0);
2559 BSSAP.send(ts_BSSMAP_ClearRequest(0));
2560
2561 MNCC.receive(tr_MNCC_REL_ind(?, ?)) -> value mncc;
2562
2563 BSSAP.receive(tr_BSSMAP_ClearCommand);
2564 BSSAP.send(ts_BSSMAP_ClearComplete);
2565
2566 f_sleep(1.0);
2567}
2568testcase TC_mo_cc_bssmap_clear() runs on MTC_CT {
2569 var BSC_ConnHdlr vc_conn;
2570 f_init();
2571
2572 vc_conn := f_start_handler(refers(f_tc_mo_cc_bssmap_clear), 43);
2573 vc_conn.done;
2574}
2575
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07002576/* LU followed by MT call and MT USSD request during this call */
2577private function f_tc_lu_and_mt_ussd_during_mt_call(charstring id, BSC_ConnHdlrPars pars)
2578runs on BSC_ConnHdlr {
2579 f_init_handler(pars);
2580
2581 /* Call parameters taken from f_tc_lu_and_mt_call */
2582 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
2583 cpars.mgcp_connection_id_bss := '10004'H;
2584 cpars.mgcp_connection_id_mss := '10005'H;
2585 cpars.mgcp_ep := "rtpbridge/1@mgw";
2586 cpars.bss_rtp_port := 1110;
2587
2588 /* Perform location update */
2589 f_perform_lu();
2590
2591 /* Establish a MT call */
2592 f_mt_call_establish(cpars);
2593
2594 /* Hold the call for some time */
2595 f_sleep(1.0);
2596
2597 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
2598 op_code := SS_OP_CODE_USS_REQUEST,
2599 ussd_string := "Please type anything..."
2600 );
2601
2602 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
2603 op_code := SS_OP_CODE_USS_REQUEST,
2604 ussd_string := "Nope."
2605 )
2606
2607 /* Compose MT SS/REGISTER message with network-originated request */
2608 var template (value) PDU_ML3_NW_MS ussd_req := ts_ML3_MT_SS_REGISTER(
2609 tid := 0, /* FIXME: most likely, it should be 0 */
2610 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2611 facility := valueof(facility_req)
2612 );
2613
2614 /* Compose HLR -> MSC GSUP message */
2615 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
2616 imsi := g_pars.imsi,
2617 sid := '20000101'O,
2618 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2619 ss := valueof(facility_req)
2620 );
2621
2622 /* Send it to MSC */
2623 GSUP.send(gsup_req);
2624 /* Expect MT REGISTER message with USSD request */
2625 f_expect_mt_dtap_msg(ussd_req);
2626
2627 /* Compose a new MO SS/FACILITY message with response */
2628 var template (value) PDU_ML3_MS_NW ussd_rsp := ts_ML3_MO_SS_FACILITY(
2629 tid := 0, /* FIXME: it shall match the request tid */
2630 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
2631 facility := valueof(facility_rsp)
2632 );
2633
2634 /* Compose expected MSC -> HLR GSUP message */
2635 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_REQ(
2636 imsi := g_pars.imsi,
2637 sid := '20000101'O,
2638 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
2639 ss := valueof(facility_rsp)
2640 );
2641
2642 /* MS sends response */
2643 BSSAP.send(ts_PDU_DTAP_MO(ussd_rsp));
2644 f_expect_gsup_msg(gsup_rsp);
2645
2646 /* Compose expected MT SS/RELEASE COMPLETE message */
2647 var template PDU_ML3_NW_MS ussd_term := tr_ML3_MT_SS_RELEASE_COMPLETE(
2648 tid := 0, /* FIXME: it shall match the request tid */
2649 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2650 facility := omit
2651 );
2652
2653 /* Compose MSC -> HLR GSUP message */
2654 var template GSUP_PDU gsup_term := ts_GSUP_PROC_SS_REQ(
2655 imsi := g_pars.imsi,
2656 sid := '20000101'O,
2657 state := OSMO_GSUP_SESSION_STATE_END
2658 );
2659
2660 /* Finally, HLR terminates the session */
2661 GSUP.send(gsup_term);
2662 /* Expect MT RELEASE COMPLETE without Facility IE */
2663 f_expect_mt_dtap_msg(ussd_term);
2664
2665 /* Hold the call for some time */
2666 f_sleep(1.0);
2667
2668 /* Release the call (does Clear Complete itself) */
2669 f_call_hangup(cpars, true);
2670}
2671testcase TC_lu_and_mt_ussd_during_mt_call() runs on MTC_CT {
2672 var BSC_ConnHdlr vc_conn;
2673 f_init();
2674 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_ussd_during_mt_call), 49);
2675 vc_conn.done;
2676}
2677
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07002678/* LU followed by MO USSD request and MO Release during transaction */
2679private function f_tc_lu_and_mo_ussd_mo_release(charstring id, BSC_ConnHdlrPars pars)
2680runs on BSC_ConnHdlr {
2681 f_init_handler(pars);
2682
2683 /* Perform location update */
2684 f_perform_lu();
2685
2686 /* Send CM Service Request for SS/USSD */
2687 f_establish_fully(EST_TYPE_SS_ACT);
2688
2689 /* We need to inspect GSUP activity */
2690 f_create_gsup_expect(hex2str(g_pars.imsi));
2691
2692 var template OCTN facility_ms_req := f_USSD_FACILITY_IE_INVOKE(
2693 invoke_id := 1, /* Initial request */
2694 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2695 ussd_string := "*6766*266#"
2696 );
2697
2698 var template OCTN facility_net_req := f_USSD_FACILITY_IE_INVOKE(
2699 invoke_id := 2, /* Counter request */
2700 op_code := SS_OP_CODE_USS_REQUEST,
2701 ussd_string := "Password?!?"
2702 )
2703
2704 /* Compose MO SS/REGISTER message with request */
2705 var template (value) PDU_ML3_MS_NW ussd_ms_req := ts_ML3_MO_SS_REGISTER(
2706 tid := 1, /* We just need a single transaction */
2707 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2708 facility := valueof(facility_ms_req)
2709 );
2710
2711 /* Compose expected MSC -> HLR message */
2712 var template GSUP_PDU gsup_ms_req := tr_GSUP_PROC_SS_REQ(
2713 imsi := g_pars.imsi,
2714 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2715 ss := valueof(facility_ms_req)
2716 );
2717
2718 /* To be used for sending response with correct session ID */
2719 var GSUP_PDU gsup_ms_req_complete;
2720
2721 /* Initiate a new transaction */
2722 BSSAP.send(ts_PDU_DTAP_MO(ussd_ms_req));
2723 /* Expect GSUP request with original Facility IE */
2724 gsup_ms_req_complete := f_expect_gsup_msg(gsup_ms_req);
2725
2726 /* Compose the response from HLR using received session ID */
2727 var template (value) GSUP_PDU gsup_net_req := ts_GSUP_PROC_SS_REQ(
2728 imsi := g_pars.imsi,
2729 sid := gsup_ms_req_complete.ies[1].val.session_id,
2730 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
2731 ss := valueof(facility_net_req)
2732 );
2733
2734 /* Compose expected MT SS/FACILITY template with counter request */
2735 var template PDU_ML3_NW_MS ussd_net_req := tr_ML3_MT_SS_FACILITY(
2736 tid := 1, /* Response should arrive within the same transaction */
2737 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
2738 facility := valueof(facility_net_req)
2739 );
2740
2741 /* Send response over GSUP */
2742 GSUP.send(gsup_net_req);
2743 /* Expect MT SS/FACILITY message with counter request */
2744 f_expect_mt_dtap_msg(ussd_net_req);
2745
2746 /* Compose MO SS/RELEASE COMPLETE */
2747 var template (value) PDU_ML3_MS_NW ussd_abort := ts_ML3_MO_SS_RELEASE_COMPLETE(
2748 tid := 1, /* Response should arrive within the same transaction */
2749 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2750 facility := omit
2751 /* TODO: cause? */
2752 );
2753
2754 /* Compose expected HLR -> MSC abort message */
2755 var template GSUP_PDU gsup_abort := tr_GSUP_PROC_SS_REQ(
2756 imsi := g_pars.imsi,
2757 sid := gsup_ms_req_complete.ies[1].val.session_id,
2758 state := OSMO_GSUP_SESSION_STATE_END
2759 );
2760
2761 /* Abort transaction */
2762 BSSAP.send(ts_PDU_DTAP_MO(ussd_abort));
2763 /* Expect GSUP message indicating abort */
2764 f_expect_gsup_msg(gsup_abort);
2765
2766 f_expect_clear();
2767}
2768testcase TC_lu_and_mo_ussd_mo_release() runs on MTC_CT {
2769 var BSC_ConnHdlr vc_conn;
2770 f_init();
2771 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_mo_release), 50);
2772 vc_conn.done;
2773}
2774
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07002775/* LU followed by MO USSD request and MT Release due to timeout */
2776private function f_tc_lu_and_ss_session_timeout(charstring id, BSC_ConnHdlrPars pars)
2777runs on BSC_ConnHdlr {
2778 f_init_handler(pars);
2779
2780 /* Perform location update */
2781 f_perform_lu();
2782
2783 /* Send CM Service Request for SS/USSD */
2784 f_establish_fully(EST_TYPE_SS_ACT);
2785
2786 /* We need to inspect GSUP activity */
2787 f_create_gsup_expect(hex2str(g_pars.imsi));
2788
2789 var template OCTN facility_ms_req := f_USSD_FACILITY_IE_INVOKE(
2790 invoke_id := 1,
2791 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2792 ussd_string := "#release_me");
2793
2794 /* Compose MO SS/REGISTER message with request */
2795 var template (value) PDU_ML3_MS_NW ussd_ms_req := ts_ML3_MO_SS_REGISTER(
2796 tid := 1, /* An arbitrary transaction identifier */
2797 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2798 facility := valueof(facility_ms_req));
2799
2800 /* Compose expected MSC -> HLR message */
2801 var template GSUP_PDU gsup_ms_req := tr_GSUP_PROC_SS_REQ(
2802 imsi := g_pars.imsi,
2803 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2804 ss := valueof(facility_ms_req));
2805
2806 /* To be used for sending response with correct session ID */
2807 var GSUP_PDU gsup_ms_req_complete;
2808
2809 /* Initiate a new SS transaction */
2810 BSSAP.send(ts_PDU_DTAP_MO(ussd_ms_req));
2811 /* Expect GSUP request with original Facility IE */
2812 gsup_ms_req_complete := f_expect_gsup_msg(gsup_ms_req);
2813
2814 /* Don't respond, wait for timeout */
2815 f_sleep(3.0);
2816
2817 var template PDU_ML3_NW_MS dtap_rel := tr_ML3_MT_SS_RELEASE_COMPLETE(
2818 tid := 1, /* Should match the request's tid */
2819 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
2820 cause := *, /* TODO: expect some specific value */
2821 facility := omit);
2822
2823 var template GSUP_PDU gsup_rel := tr_GSUP_PROC_SS_ERR(
2824 imsi := g_pars.imsi,
2825 sid := gsup_ms_req_complete.ies[1].val.session_id,
2826 state := OSMO_GSUP_SESSION_STATE_END,
2827 cause := ?); /* TODO: expect some specific value */
2828
2829 /* Expect release on both interfaces */
2830 interleave {
2831 [] BSSAP.receive(tr_PDU_DTAP_MT(dtap_rel)) { };
2832 [] GSUP.receive(gsup_rel) { };
2833 }
2834
2835 f_expect_clear();
2836 setverdict(pass);
2837}
2838testcase TC_lu_and_ss_session_timeout() runs on MTC_CT {
2839 var BSC_ConnHdlr vc_conn;
2840 f_init();
Vadim Yanitskiy36d28dd2018-12-03 02:45:45 +07002841 f_vty_config(MSCVTY, "msc", "ncss guard-timeout 3");
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07002842 vc_conn := f_start_handler(refers(f_tc_lu_and_ss_session_timeout), 51);
2843 vc_conn.done;
Vadim Yanitskiy36d28dd2018-12-03 02:45:45 +07002844 f_vty_config(MSCVTY, "msc", "ncss guard-timeout 0");
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07002845}
2846
Stefan Sperling89eb1f32018-12-17 15:06:20 +01002847/* A5/1 only permitted on network side; attempt an invalid CIPHER MODE COMPLETE with A5/3 which MSC should reject. */
2848private function f_tc_cipher_complete_with_invalid_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2849 pars.net.expect_auth := true;
2850 pars.net.expect_ciph := true;
2851 pars.net.kc_support := '02'O; /* A5/1 only */
2852 f_init_handler(pars);
2853
2854 g_pars.vec := f_gen_auth_vec_2g();
2855
2856 /* Can't use f_perform_lu() directly. Code below is based on it. */
2857
2858 /* tell GSUP dispatcher to send this IMSI to us */
2859 f_create_gsup_expect(hex2str(g_pars.imsi));
2860
2861 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
2862 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
2863 f_bssap_compl_l3(l3_lu);
2864
2865 f_mm_auth();
2866
2867 var OCT1 a5_net := f_alg_mask_from_cm(g_pars.cm2);
2868 var OCT1 a5_intersect := g_pars.net.kc_support and4b a5_net;
2869 alt {
2870 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(a5_intersect, g_pars.vec.kc)) {
2871 BSSAP.send(ts_BSSMAP_CipherModeCompl(int2oct(4 /* "accept" A5/3 */, 1)));
2872 }
2873 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc)) {
2874 setverdict(fail, "Wrong ciphering algorithm mask in CiphModCmd");
2875 mtc.stop;
2876 }
2877 [] BSSAP.receive {
2878 setverdict(fail, "Unknown/unexpected BSSAP received");
2879 mtc.stop;
2880 }
2881 }
2882
2883 /* Expect LU reject from MSC. */
2884 alt {
2885 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
2886 setverdict(pass);
2887 }
2888 [] BSSAP.receive {
2889 setverdict(fail, "Unknown/unexpected BSSAP received");
2890 mtc.stop;
2891 }
2892 }
Stefan Sperlingc620b352018-12-18 17:23:36 +01002893 f_expect_clear();
Stefan Sperling89eb1f32018-12-17 15:06:20 +01002894}
2895
2896testcase TC_cipher_complete_with_invalid_cipher() runs on MTC_CT {
2897 var BSC_ConnHdlr vc_conn;
2898 f_init();
2899 f_vty_config(MSCVTY, "network", "encryption a5 1");
2900
2901 vc_conn := f_start_handler(refers(f_tc_cipher_complete_with_invalid_cipher), 52);
2902 vc_conn.done;
2903}
2904
Harald Weltef640a012018-04-14 17:49:21 +02002905/* TODO (SMS):
2906 * different user data lengths
2907 * SMPP transaction mode with unsuccessful delivery
2908 * queued MT-SMS with no paging response + later delivery
2909 * different data coding schemes
2910 * multi-part SMS
2911 * user-data headers
2912 * TP-PID for SMS to SIM
2913 * behavior if SMS memory is full + RP-SMMA
2914 * delivery reports
2915 * SMPP osmocom extensions
2916 * more-messages-to-send
2917 * SMS during ongoing call (SACCH/SAPI3)
2918 */
2919
2920/* TODO (General):
Harald Welteba7b6d92018-01-23 21:32:34 +01002921 * continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
2922 * malformed messages (missing IE, invalid message type): properly rejected?
2923 * MT call while LU or is ongoing: Do we use existing lchan or page while lchan active?
2924 * 3G/2G auth permutations
2925 * encryption algorithms vs. classmark vs. vty config
Harald Welteba7b6d92018-01-23 21:32:34 +01002926 * send new transaction after/during clear (like SMS, ...)
Harald Welte45164da2018-01-24 12:51:27 +01002927 * too long L3 INFO in DTAP
2928 * too long / padded BSSAP
2929 * too long / short TLV values
Harald Welteba7b6d92018-01-23 21:32:34 +01002930 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01002931
2932
2933control {
Philipp Maier328d1662018-03-07 10:40:27 +01002934 execute( TC_cr_before_reset() );
Harald Weltea49e36e2018-01-21 19:29:33 +01002935 execute( TC_lu_imsi_noauth_tmsi() );
Harald Welted2328a22018-01-27 14:27:16 +01002936 execute( TC_lu_imsi_noauth_notmsi() );
Harald Weltea49e36e2018-01-21 19:29:33 +01002937 execute( TC_lu_imsi_reject() );
2938 execute( TC_lu_imsi_timeout_gsup() );
Harald Welted2328a22018-01-27 14:27:16 +01002939 execute( TC_lu_imsi_auth_tmsi() );
2940 execute( TC_cmserv_imsi_unknown() );
Harald Welte2bb825f2018-01-22 11:31:18 +01002941 execute( TC_lu_and_mo_call() );
Harald Welte071ed732018-01-23 19:53:52 +01002942 execute( TC_lu_auth_sai_timeout() );
2943 execute( TC_lu_auth_sai_err() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01002944 execute( TC_lu_clear_request() );
2945 execute( TC_lu_disconnect() );
2946 execute( TC_lu_by_imei() );
2947 execute( TC_lu_by_tmsi_noauth_unknown() );
2948 execute( TC_imsi_detach_by_imsi() );
2949 execute( TC_imsi_detach_by_tmsi() );
2950 execute( TC_imsi_detach_by_imei() );
2951 execute( TC_emerg_call_imei_reject() );
2952 execute( TC_emerg_call_imsi() );
2953 execute( TC_cm_serv_req_vgcs_reject() );
2954 execute( TC_cm_serv_req_vbs_reject() );
2955 execute( TC_cm_serv_req_lcs_reject() );
Harald Welte0195ab12018-01-24 21:50:20 +01002956 execute( TC_cm_reest_req_reject() );
Harald Welte1af6ea82018-01-25 18:33:15 +01002957 execute( TC_lu_auth_2G_fail() );
2958 execute( TC_lu_imsi_auth_tmsi_encr_13_13() );
2959 execute( TC_cl3_no_payload() );
2960 execute( TC_cl3_rnd_payload() );
Harald Welte1852a842018-01-26 22:53:36 +01002961 execute( TC_establish_and_nothing() );
2962 execute( TC_mo_setup_and_nothing() );
2963 execute( TC_mo_crcx_ran_timeout() );
2964 execute( TC_mo_crcx_ran_reject() );
Harald Welted2328a22018-01-27 14:27:16 +01002965 execute( TC_mt_crcx_ran_reject() );
Daniel Willmann8b084372018-02-04 13:35:26 +01002966 execute( TC_mo_setup_and_dtmf_dup() );
Harald Welteaa54cf82018-01-30 08:15:32 +01002967 //execute( TC_mt_t310() );
Harald Welte167458a2018-01-27 15:58:16 +01002968 execute( TC_gsup_cancel() );
Harald Welte9de84792018-01-28 01:06:35 +01002969 execute( TC_lu_imsi_auth_tmsi_encr_1_13() );
2970 execute( TC_lu_imsi_auth_tmsi_encr_3_13() );
2971 execute( TC_lu_imsi_auth_tmsi_encr_3_1() );
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01002972 execute( TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() );
Harald Welte9de84792018-01-28 01:06:35 +01002973 execute( TC_lu_imsi_auth_tmsi_encr_13_2() );
2974 execute( TC_lu_imsi_auth_tmsi_encr_013_2() );
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002975 execute( TC_mo_release_timeout() );
Philipp Maier2a98a732018-03-19 16:06:12 +01002976 execute( TC_lu_and_mt_call_no_dlcx_resp() );
Philipp Maier75932982018-03-27 14:52:35 +02002977 execute( TC_reset_two() );
Harald Welte33ec09b2018-02-10 15:34:46 +01002978
2979 execute( TC_lu_and_mt_call() );
2980
Harald Weltef45efeb2018-04-09 18:19:24 +02002981 execute( TC_lu_and_mo_sms() );
2982 execute( TC_lu_and_mt_sms() );
Harald Weltef640a012018-04-14 17:49:21 +02002983 execute( TC_smpp_mo_sms() );
2984 execute( TC_smpp_mt_sms() );
Harald Weltef45efeb2018-04-09 18:19:24 +02002985
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07002986 execute( TC_gsup_mo_sms() );
2987
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002988 execute( TC_lu_and_mo_ussd_single_request() );
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07002989 execute( TC_lu_and_mt_ussd_notification() );
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002990 execute( TC_lu_and_mo_ussd_during_mt_call() );
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07002991 execute( TC_lu_and_mt_ussd_during_mt_call() );
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07002992 execute( TC_lu_and_mo_ussd_mo_release() );
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07002993 execute( TC_lu_and_ss_session_timeout() );
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002994
Stefan Sperling89eb1f32018-12-17 15:06:20 +01002995 execute( TC_cipher_complete_with_invalid_cipher() );
2996
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01002997 /* Run this last: at the time of writing this test crashes the MSC */
2998 execute( TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() );
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02002999 execute( TC_mo_cc_bssmap_clear() );
Harald Weltef6dd64d2017-11-19 12:09:51 +01003000}
3001
3002
3003}