blob: ef626bf24d7c1ef9160d37167b19fd36f9eb0fb1 [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
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07002101/* Test MO-SMMA from MS/BTS/BSC towards HLR (via GSUP) */
2102private function f_tc_gsup_mo_smma(charstring id, BSC_ConnHdlrPars pars)
2103runs on BSC_ConnHdlr {
2104 var SmsParameters spars := valueof(t_SmsPars);
2105 var GSUP_PDU gsup_msg_rx;
2106
2107 f_init_handler(pars);
2108
2109 /* We need to inspect GSUP activity */
2110 f_create_gsup_expect(hex2str(g_pars.imsi));
2111
2112 /* Perform location update */
2113 f_perform_lu();
2114
2115 /* Send CM Service Request for SMS */
2116 f_establish_fully(EST_TYPE_MO_SMS);
2117
2118 var template GSUP_PDU mo_ReadyForSM := tr_GSUP_MO_READY_FOR_SM_REQ(
2119 imsi := g_pars.imsi,
2120 sm_rp_mr := spars.rp.msg_ref,
2121 sm_alert_rsn := GSUP_SM_ALERT_RSN_TYPE_MEM_AVAIL
2122 );
2123
2124 /* Submit an SMS on DTAP and expect MO-forwardSM-Req on GSUP */
2125 f_mo_smma(spars);
2126 alt {
2127 [] GSUP.receive(mo_ReadyForSM) -> value gsup_msg_rx {
2128 log("RX MO-ReadyForSM-Req");
2129 log(gsup_msg_rx);
2130 setverdict(pass);
2131 }
2132 [] GSUP.receive {
2133 log("RX unexpected GSUP message");
2134 setverdict(fail);
2135 mtc.stop;
2136 }
2137 }
2138
2139 /* Trigger RP-ACK by sending MO-forwardSM-Res */
2140 GSUP.send(valueof(ts_GSUP_MO_READY_FOR_SM_RES(
2141 imsi := g_pars.imsi,
2142 sm_rp_mr := spars.rp.msg_ref)));
2143 /* Expect RP-ACK on DTAP */
2144 f_mo_sms_wait_rp_ack(spars);
2145
2146 f_expect_clear();
2147}
2148testcase TC_gsup_mo_smma() runs on MTC_CT {
2149 var BSC_ConnHdlr vc_conn;
2150 f_init();
2151 f_vty_config(MSCVTY, "msc", "sms-over-gsup");
2152 vc_conn := f_start_handler(refers(f_tc_gsup_mo_smma), 89);
2153 vc_conn.done;
2154 f_vty_config(MSCVTY, "msc", "no sms-over-gsup");
2155}
2156
Harald Weltef640a012018-04-14 17:49:21 +02002157/* convert GSM L3 TON to SMPP_TON enum */
2158function f_sm_ton_from_gsm(BIT3 ton) return SMPP_TON {
2159 select (ton) {
2160 case ('000'B) { return unknown; }
2161 case ('001'B) { return international; }
2162 case ('010'B) { return national; }
2163 case ('011'B) { return network_specific; }
2164 case ('100'B) { return subscriber_number; }
2165 case ('101'B) { return alphanumeric; }
2166 case ('110'B) { return abbreviated; }
2167 }
2168 setverdict(fail, "Unknown TON ", ton);
Daniel Willmannafce8662018-07-06 23:11:32 +02002169 mtc.stop;
Harald Weltef640a012018-04-14 17:49:21 +02002170}
2171/* convert GSM L3 NPI to SMPP_NPI enum */
2172function f_sm_npi_from_gsm(BIT4 npi) return SMPP_NPI {
2173 select (npi) {
2174 case ('0000'B) { return unknown; }
2175 case ('0001'B) { return isdn; }
2176 case ('0011'B) { return data; }
2177 case ('0100'B) { return telex; }
2178 case ('0110'B) { return land_mobile; }
2179 case ('1000'B) { return national; }
2180 case ('1001'B) { return private_; }
2181 case ('1010'B) { return ermes; }
2182 }
2183 setverdict(fail, "Unknown NPI ", npi);
Daniel Willmannafce8662018-07-06 23:11:32 +02002184 mtc.stop;
Harald Weltef640a012018-04-14 17:49:21 +02002185}
2186
2187/* build a SMPP_SM from SmsParameters */
2188function f_mt_sm_from_spars(SmsParameters spars)
2189runs on BSC_ConnHdlr return SMPP_SM {
2190 var SMPP_SM sm := {
2191 service_type := "CMT",
2192 source_addr_ton := f_sm_ton_from_gsm(spars.tp.da.tP_DA_NoPad.tP_TypeOfNumber),
2193 source_addr_npi := f_sm_npi_from_gsm(spars.tp.da.tP_DA_NoPad.tP_NumberingPlanID),
2194 source_addr := hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue),
2195 dest_addr_ton := international,
2196 dest_addr_npi := isdn,
2197 destination_addr := hex2str(g_pars.msisdn),
2198 esm_class := '00000001'B,
2199 protocol_id := 0,
2200 priority_flag := 0,
2201 schedule_delivery_time := "",
2202 validity_period := "",
2203 registered_delivery := '00000000'B,
2204 replace_if_present := 0,
2205 data_coding := '00000001'B,
2206 sm_default_msg_id := 0,
2207 sm_length := spars.tp.udl,
2208 short_message := spars.tp.ud,
2209 opt_pars := {}
2210 };
2211 return sm;
2212}
2213
2214/* helper function to encode SMS from 'spars', send it via SMPP to MSC; receive it on MS side */
2215private function f_smpp_mt_sms(SmsParameters spars, boolean trans_mode) runs on BSC_ConnHdlr {
2216 var SMPP_SM sm := f_mt_sm_from_spars(spars);
2217 if (trans_mode) {
2218 sm.esm_class := '00000010'B;
2219 }
2220
2221 /* actually cause MSC to send a SMS via SUBMIT-SM from SMPP side */
2222 SMPP.send(ts_SMPP_SUBMIT_SM(sm));
2223 if (not match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
2224 /* if we're not in SMPP transaction mode, we expect the SMPP-level ACK
2225 * before we expect the SMS delivery on the BSC/radio side */
2226 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
2227 }
2228
2229 /* MSC->BSC: expect PAGING from MSC */
2230 BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));
2231 /* Establish DTAP / BSSAP / SCCP connection */
2232 f_establish_fully(EST_TYPE_PAG_RESP);
2233 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
2234
2235 f_mt_sms(spars);
2236
2237 if (match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
2238 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
2239 }
2240 f_expect_clear();
2241}
2242
2243/* mobile terminated SMS, from SMPP to BSC/BTS/MS */
2244private function f_tc_smpp_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2245 f_init_handler(pars);
2246
2247 /* Perform location update so IMSI is known + registered in MSC/VLR */
2248 f_perform_lu();
2249 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
2250
2251 /* register an 'expect' for given IMSI (+TMSI) */
2252 var OCT4 tmsi;
2253 if (isvalue(g_pars.tmsi)) {
2254 tmsi := g_pars.tmsi;
2255 } else {
2256 tmsi := 'FFFFFFFF'O;
2257 }
2258 f_bssmap_register_imsi(g_pars.imsi, tmsi);
2259
2260 var SmsParameters spars := valueof(t_SmsPars);
2261 /* TODO: test with more intelligent user data; test different coding schemes */
2262 spars.tp.ud := '00'O;
2263 spars.tp.udl := 1;
2264
2265 /* first test the non-transaction store+forward mode */
2266 f_smpp_mt_sms(spars, false);
2267
2268 /* then test the transaction mode */
2269 f_smpp_mt_sms(spars, true);
2270}
2271testcase TC_smpp_mt_sms() runs on MTC_CT {
2272 var BSC_ConnHdlr vc_conn;
2273 f_init();
2274 vc_conn := f_start_handler(refers(f_tc_smpp_mt_sms), 45);
2275 vc_conn.done;
2276}
2277
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002278/***********************************************************************
2279 * USSD Testing
2280 ***********************************************************************/
2281
Vadim Yanitskiyce8cc372018-06-21 01:46:33 +07002282private altstep as_unexp_gsup_or_bssap_msg()
2283runs on BSC_ConnHdlr {
2284 [] GSUP.receive {
2285 setverdict(fail, "Unknown/unexpected GSUP received");
2286 self.stop;
2287 }
2288 [] BSSAP.receive {
2289 setverdict(fail, "Unknown/unexpected BSSAP message received");
2290 self.stop;
2291 }
2292}
2293
2294private function f_expect_gsup_msg(template GSUP_PDU msg)
2295runs on BSC_ConnHdlr return GSUP_PDU {
2296 var GSUP_PDU gsup_msg_complete;
2297
2298 alt {
2299 [] GSUP.receive(msg) -> value gsup_msg_complete {
2300 setverdict(pass);
2301 }
2302 /* We don't expect anything else */
2303 [] as_unexp_gsup_or_bssap_msg();
2304 }
2305
2306 return gsup_msg_complete;
2307}
2308
2309private function f_expect_mt_dtap_msg(template PDU_ML3_NW_MS msg)
2310runs on BSC_ConnHdlr return PDU_ML3_NW_MS {
2311 var PDU_DTAP_MT bssap_msg_complete;
2312
2313 alt {
2314 [] BSSAP.receive(tr_PDU_DTAP_MT(msg)) -> value bssap_msg_complete {
2315 setverdict(pass);
2316 }
2317 /* We don't expect anything else */
2318 [] as_unexp_gsup_or_bssap_msg();
2319 }
2320
2321 return bssap_msg_complete.dtap;
2322}
2323
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002324/* LU followed by MO USSD request */
2325private function f_tc_lu_and_mo_ussd_single_request(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002326runs on BSC_ConnHdlr {
2327 f_init_handler(pars);
2328
2329 /* Perform location update */
2330 f_perform_lu();
2331
2332 /* Send CM Service Request for SS/USSD */
2333 f_establish_fully(EST_TYPE_SS_ACT);
2334
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002335 /* We need to inspect GSUP activity */
2336 f_create_gsup_expect(hex2str(g_pars.imsi));
2337
2338 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
2339 invoke_id := 5, /* Phone may not start from 0 or 1 */
2340 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2341 ussd_string := "*#100#"
2342 );
2343
2344 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
2345 invoke_id := 5, /* InvokeID shall be the same for both REQ and RSP */
2346 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2347 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
2348 )
2349
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002350 /* Compose a new SS/REGISTER message with request */
2351 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
2352 tid := 1, /* We just need a single transaction */
2353 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002354 facility := valueof(facility_req)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002355 );
2356
2357 /* Compose SS/RELEASE_COMPLETE template with expected response */
2358 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
2359 tid := 1, /* Response should arrive within the same transaction */
2360 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002361 facility := valueof(facility_rsp)
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002362 );
2363
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002364 /* Compose expected MSC -> HLR message */
2365 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
2366 imsi := g_pars.imsi,
2367 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2368 ss := valueof(facility_req)
2369 );
2370
2371 /* To be used for sending response with correct session ID */
2372 var GSUP_PDU gsup_req_complete;
2373
2374 /* Request own number */
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002375 BSSAP.send(ts_PDU_DTAP_MO(ussd_req));
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002376 /* Expect GSUP message containing the SS payload */
2377 gsup_req_complete := f_expect_gsup_msg(gsup_req);
2378
2379 /* Compose the response from HLR using received session ID */
2380 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
2381 imsi := g_pars.imsi,
2382 sid := gsup_req_complete.ies[1].val.session_id,
2383 state := OSMO_GSUP_SESSION_STATE_END,
2384 ss := valueof(facility_rsp)
2385 );
2386
2387 /* Finally, HLR terminates the session */
2388 GSUP.send(gsup_rsp);
2389 /* Expect RELEASE_COMPLETE message with the response */
2390 f_expect_mt_dtap_msg(ussd_rsp);
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002391
2392 f_expect_clear();
2393}
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002394testcase TC_lu_and_mo_ussd_single_request() runs on MTC_CT {
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002395 var BSC_ConnHdlr vc_conn;
2396 f_init();
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002397 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_single_request), 46);
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07002398 vc_conn.done;
2399}
2400
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07002401/* LU followed by MT USSD notification */
2402private function f_tc_lu_and_mt_ussd_notification(charstring id, BSC_ConnHdlrPars pars)
2403runs on BSC_ConnHdlr {
2404 f_init_handler(pars);
2405
2406 /* Perform location update */
2407 f_perform_lu();
2408
2409 f_bssmap_register_imsi(g_pars.imsi, g_pars.tmsi);
2410
2411 /* We need to inspect GSUP activity */
2412 f_create_gsup_expect(hex2str(g_pars.imsi));
2413
2414 /* Facility IE with network-originated USSD notification */
2415 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
2416 op_code := SS_OP_CODE_USS_NOTIFY,
2417 ussd_string := "Mahlzeit!"
2418 );
2419
2420 /* Facility IE with acknowledgment to the USSD notification */
2421 var template OCTN facility_rsp := enc_SS_FacilityInformation(
2422 /* In case of USSD notification, Return Result is empty */
2423 valueof(ts_SS_USSD_FACILITY_RETURN_RESULT_EMPTY())
2424 );
2425
2426 /* Compose a new MT SS/REGISTER message with USSD notification */
2427 var template PDU_ML3_NW_MS ussd_ntf := tr_ML3_MT_SS_REGISTER(
2428 tid := 0, /* FIXME: most likely, it should be 0 */
2429 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2430 facility := valueof(facility_req)
2431 );
2432
2433 /* Compose HLR -> MSC GSUP message */
2434 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
2435 imsi := g_pars.imsi,
2436 sid := '20000101'O,
2437 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2438 ss := valueof(facility_req)
2439 );
2440
2441 /* Send it to MSC and expect Paging Request */
2442 GSUP.send(gsup_req);
2443 alt {
2444 [] BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi)) {
2445 setverdict(pass);
2446 }
2447 /* We don't expect anything else */
2448 [] as_unexp_gsup_or_bssap_msg();
2449 }
2450
2451 /* Send Paging Response and expect USSD notification */
2452 f_establish_fully(EST_TYPE_PAG_RESP);
2453 /* Expect MT REGISTER message with USSD notification */
2454 f_expect_mt_dtap_msg(ussd_ntf);
2455
2456 /* Compose a new MO SS/FACILITY message with empty response */
2457 var template (value) PDU_ML3_MS_NW ussd_rsp := ts_ML3_MO_SS_FACILITY(
2458 tid := 0, /* FIXME: it shall match the request tid */
2459 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
2460 facility := valueof(facility_rsp)
2461 );
2462
2463 /* Compose expected MSC -> HLR GSUP message */
2464 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_REQ(
2465 imsi := g_pars.imsi,
2466 sid := '20000101'O,
2467 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
2468 ss := valueof(facility_rsp)
2469 );
2470
2471 /* MS sends response to the notification */
2472 BSSAP.send(ts_PDU_DTAP_MO(ussd_rsp));
2473 /* Expect GSUP message containing the SS payload */
2474 f_expect_gsup_msg(gsup_rsp);
2475
2476 /* Compose expected MT SS/RELEASE COMPLETE message */
2477 var template PDU_ML3_NW_MS ussd_term := tr_ML3_MT_SS_RELEASE_COMPLETE(
2478 tid := 0, /* FIXME: it shall match the request tid */
2479 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2480 facility := omit
2481 );
2482
2483 /* Compose MSC -> HLR GSUP message */
2484 var template GSUP_PDU gsup_term := ts_GSUP_PROC_SS_REQ(
2485 imsi := g_pars.imsi,
2486 sid := '20000101'O,
2487 state := OSMO_GSUP_SESSION_STATE_END
2488 );
2489
2490 /* Finally, HLR terminates the session */
2491 GSUP.send(gsup_term)
2492 /* Expect MT RELEASE COMPLETE without Facility IE */
2493 f_expect_mt_dtap_msg(ussd_term);
2494
2495 f_expect_clear();
2496}
2497testcase TC_lu_and_mt_ussd_notification() runs on MTC_CT {
2498 var BSC_ConnHdlr vc_conn;
2499 f_init();
2500 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_ussd_notification), 47);
2501 vc_conn.done;
2502}
2503
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002504/* LU followed by MT call and MO USSD request during this call */
2505private function f_tc_lu_and_mo_ussd_during_mt_call(charstring id, BSC_ConnHdlrPars pars)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002506runs on BSC_ConnHdlr {
2507 f_init_handler(pars);
2508
2509 /* Call parameters taken from f_tc_lu_and_mt_call */
2510 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
2511 cpars.mgcp_connection_id_bss := '10004'H;
2512 cpars.mgcp_connection_id_mss := '10005'H;
2513 cpars.mgcp_ep := "rtpbridge/1@mgw";
2514 cpars.bss_rtp_port := 1110;
2515
2516 /* Perform location update */
2517 f_perform_lu();
2518
2519 /* Establish a MT call */
2520 f_mt_call_establish(cpars);
2521
2522 /* Hold the call for some time */
2523 f_sleep(1.0);
2524
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002525 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
2526 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2527 ussd_string := "*#100#"
2528 );
2529
2530 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
2531 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2532 ussd_string := "Your extension is " & hex2str(g_pars.msisdn) & "\r"
2533 )
2534
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002535 /* Compose a new SS/REGISTER message with request */
2536 var template (value) PDU_ML3_MS_NW ussd_req := ts_ML3_MO_SS_REGISTER(
2537 tid := 1, /* We just need a single transaction */
2538 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002539 facility := valueof(facility_req)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002540 );
2541
2542 /* Compose SS/RELEASE_COMPLETE template with expected response */
2543 var template PDU_ML3_NW_MS ussd_rsp := tr_ML3_MT_SS_RELEASE_COMPLETE(
2544 tid := 1, /* Response should arrive within the same transaction */
2545 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002546 facility := valueof(facility_rsp)
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002547 );
2548
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002549 /* Compose expected MSC -> HLR message */
2550 var template GSUP_PDU gsup_req := tr_GSUP_PROC_SS_REQ(
2551 imsi := g_pars.imsi,
2552 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2553 ss := valueof(facility_req)
2554 );
2555
2556 /* To be used for sending response with correct session ID */
2557 var GSUP_PDU gsup_req_complete;
2558
2559 /* Request own number */
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002560 BSSAP.send(ts_PDU_DTAP_MO(ussd_req));
Vadim Yanitskiy747689e2018-06-19 00:14:28 +07002561 /* Expect GSUP message containing the SS payload */
2562 gsup_req_complete := f_expect_gsup_msg(gsup_req);
2563
2564 /* Compose the response from HLR using received session ID */
2565 var template GSUP_PDU gsup_rsp := ts_GSUP_PROC_SS_REQ(
2566 imsi := g_pars.imsi,
2567 sid := gsup_req_complete.ies[1].val.session_id,
2568 state := OSMO_GSUP_SESSION_STATE_END,
2569 ss := valueof(facility_rsp)
2570 );
2571
2572 /* Finally, HLR terminates the session */
2573 GSUP.send(gsup_rsp);
2574 /* Expect RELEASE_COMPLETE message with the response */
2575 f_expect_mt_dtap_msg(ussd_rsp);
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002576
2577 /* Hold the call for some time */
2578 f_sleep(1.0);
2579
2580 /* Release the call (does Clear Complete itself) */
2581 f_call_hangup(cpars, true);
2582}
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002583testcase TC_lu_and_mo_ussd_during_mt_call() runs on MTC_CT {
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002584 var BSC_ConnHdlr vc_conn;
2585 f_init();
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07002586 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_during_mt_call), 48);
Vadim Yanitskiy0aaf48d2018-06-06 07:02:47 +07002587 vc_conn.done;
2588}
2589
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02002590/* BSSMAP Clear Request in the middle of a call, see OS#3062 */
2591private function f_tc_mo_cc_bssmap_clear(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2592 f_init_handler(pars);
2593 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
2594 var MNCC_PDU mncc;
2595 var MgcpCommand mgcp_cmd;
2596
2597 f_perform_lu();
2598
2599 f_establish_fully();
2600 f_create_mncc_expect(hex2str(cpars.called_party));
2601 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
2602
2603 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
2604 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
2605 cpars.mncc_callref := mncc.u.signal.callref;
2606 log("mncc_callref=", cpars.mncc_callref);
2607 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
2608 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
2609
2610 MNCC.send(ts_MNCC_ALERT_req(cpars.mncc_callref));
2611 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(cpars.transaction_id)));
2612 MGCP.receive(tr_CRCX);
2613
2614 f_sleep(1.0);
2615 BSSAP.send(ts_BSSMAP_ClearRequest(0));
2616
2617 MNCC.receive(tr_MNCC_REL_ind(?, ?)) -> value mncc;
2618
2619 BSSAP.receive(tr_BSSMAP_ClearCommand);
2620 BSSAP.send(ts_BSSMAP_ClearComplete);
2621
2622 f_sleep(1.0);
2623}
2624testcase TC_mo_cc_bssmap_clear() runs on MTC_CT {
2625 var BSC_ConnHdlr vc_conn;
2626 f_init();
2627
2628 vc_conn := f_start_handler(refers(f_tc_mo_cc_bssmap_clear), 43);
2629 vc_conn.done;
2630}
2631
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07002632/* LU followed by MT call and MT USSD request during this call */
2633private function f_tc_lu_and_mt_ussd_during_mt_call(charstring id, BSC_ConnHdlrPars pars)
2634runs on BSC_ConnHdlr {
2635 f_init_handler(pars);
2636
2637 /* Call parameters taken from f_tc_lu_and_mt_call */
2638 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
2639 cpars.mgcp_connection_id_bss := '10004'H;
2640 cpars.mgcp_connection_id_mss := '10005'H;
2641 cpars.mgcp_ep := "rtpbridge/1@mgw";
2642 cpars.bss_rtp_port := 1110;
2643
2644 /* Perform location update */
2645 f_perform_lu();
2646
2647 /* Establish a MT call */
2648 f_mt_call_establish(cpars);
2649
2650 /* Hold the call for some time */
2651 f_sleep(1.0);
2652
2653 var template OCTN facility_req := f_USSD_FACILITY_IE_INVOKE(
2654 op_code := SS_OP_CODE_USS_REQUEST,
2655 ussd_string := "Please type anything..."
2656 );
2657
2658 var template OCTN facility_rsp := f_USSD_FACILITY_IE_RETURN_RESULT(
2659 op_code := SS_OP_CODE_USS_REQUEST,
2660 ussd_string := "Nope."
2661 )
2662
2663 /* Compose MT SS/REGISTER message with network-originated request */
2664 var template (value) PDU_ML3_NW_MS ussd_req := ts_ML3_MT_SS_REGISTER(
2665 tid := 0, /* FIXME: most likely, it should be 0 */
2666 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2667 facility := valueof(facility_req)
2668 );
2669
2670 /* Compose HLR -> MSC GSUP message */
2671 var template (value) GSUP_PDU gsup_req := ts_GSUP_PROC_SS_REQ(
2672 imsi := g_pars.imsi,
2673 sid := '20000101'O,
2674 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2675 ss := valueof(facility_req)
2676 );
2677
2678 /* Send it to MSC */
2679 GSUP.send(gsup_req);
2680 /* Expect MT REGISTER message with USSD request */
2681 f_expect_mt_dtap_msg(ussd_req);
2682
2683 /* Compose a new MO SS/FACILITY message with response */
2684 var template (value) PDU_ML3_MS_NW ussd_rsp := ts_ML3_MO_SS_FACILITY(
2685 tid := 0, /* FIXME: it shall match the request tid */
2686 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
2687 facility := valueof(facility_rsp)
2688 );
2689
2690 /* Compose expected MSC -> HLR GSUP message */
2691 var template GSUP_PDU gsup_rsp := tr_GSUP_PROC_SS_REQ(
2692 imsi := g_pars.imsi,
2693 sid := '20000101'O,
2694 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
2695 ss := valueof(facility_rsp)
2696 );
2697
2698 /* MS sends response */
2699 BSSAP.send(ts_PDU_DTAP_MO(ussd_rsp));
2700 f_expect_gsup_msg(gsup_rsp);
2701
2702 /* Compose expected MT SS/RELEASE COMPLETE message */
2703 var template PDU_ML3_NW_MS ussd_term := tr_ML3_MT_SS_RELEASE_COMPLETE(
2704 tid := 0, /* FIXME: it shall match the request tid */
2705 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2706 facility := omit
2707 );
2708
2709 /* Compose MSC -> HLR GSUP message */
2710 var template GSUP_PDU gsup_term := ts_GSUP_PROC_SS_REQ(
2711 imsi := g_pars.imsi,
2712 sid := '20000101'O,
2713 state := OSMO_GSUP_SESSION_STATE_END
2714 );
2715
2716 /* Finally, HLR terminates the session */
2717 GSUP.send(gsup_term);
2718 /* Expect MT RELEASE COMPLETE without Facility IE */
2719 f_expect_mt_dtap_msg(ussd_term);
2720
2721 /* Hold the call for some time */
2722 f_sleep(1.0);
2723
2724 /* Release the call (does Clear Complete itself) */
2725 f_call_hangup(cpars, true);
2726}
2727testcase TC_lu_and_mt_ussd_during_mt_call() runs on MTC_CT {
2728 var BSC_ConnHdlr vc_conn;
2729 f_init();
2730 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_ussd_during_mt_call), 49);
2731 vc_conn.done;
2732}
2733
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07002734/* LU followed by MO USSD request and MO Release during transaction */
2735private function f_tc_lu_and_mo_ussd_mo_release(charstring id, BSC_ConnHdlrPars pars)
2736runs on BSC_ConnHdlr {
2737 f_init_handler(pars);
2738
2739 /* Perform location update */
2740 f_perform_lu();
2741
2742 /* Send CM Service Request for SS/USSD */
2743 f_establish_fully(EST_TYPE_SS_ACT);
2744
2745 /* We need to inspect GSUP activity */
2746 f_create_gsup_expect(hex2str(g_pars.imsi));
2747
2748 var template OCTN facility_ms_req := f_USSD_FACILITY_IE_INVOKE(
2749 invoke_id := 1, /* Initial request */
2750 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2751 ussd_string := "*6766*266#"
2752 );
2753
2754 var template OCTN facility_net_req := f_USSD_FACILITY_IE_INVOKE(
2755 invoke_id := 2, /* Counter request */
2756 op_code := SS_OP_CODE_USS_REQUEST,
2757 ussd_string := "Password?!?"
2758 )
2759
2760 /* Compose MO SS/REGISTER message with request */
2761 var template (value) PDU_ML3_MS_NW ussd_ms_req := ts_ML3_MO_SS_REGISTER(
2762 tid := 1, /* We just need a single transaction */
2763 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2764 facility := valueof(facility_ms_req)
2765 );
2766
2767 /* Compose expected MSC -> HLR message */
2768 var template GSUP_PDU gsup_ms_req := tr_GSUP_PROC_SS_REQ(
2769 imsi := g_pars.imsi,
2770 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2771 ss := valueof(facility_ms_req)
2772 );
2773
2774 /* To be used for sending response with correct session ID */
2775 var GSUP_PDU gsup_ms_req_complete;
2776
2777 /* Initiate a new transaction */
2778 BSSAP.send(ts_PDU_DTAP_MO(ussd_ms_req));
2779 /* Expect GSUP request with original Facility IE */
2780 gsup_ms_req_complete := f_expect_gsup_msg(gsup_ms_req);
2781
2782 /* Compose the response from HLR using received session ID */
2783 var template (value) GSUP_PDU gsup_net_req := ts_GSUP_PROC_SS_REQ(
2784 imsi := g_pars.imsi,
2785 sid := gsup_ms_req_complete.ies[1].val.session_id,
2786 state := OSMO_GSUP_SESSION_STATE_CONTINUE,
2787 ss := valueof(facility_net_req)
2788 );
2789
2790 /* Compose expected MT SS/FACILITY template with counter request */
2791 var template PDU_ML3_NW_MS ussd_net_req := tr_ML3_MT_SS_FACILITY(
2792 tid := 1, /* Response should arrive within the same transaction */
2793 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
2794 facility := valueof(facility_net_req)
2795 );
2796
2797 /* Send response over GSUP */
2798 GSUP.send(gsup_net_req);
2799 /* Expect MT SS/FACILITY message with counter request */
2800 f_expect_mt_dtap_msg(ussd_net_req);
2801
2802 /* Compose MO SS/RELEASE COMPLETE */
2803 var template (value) PDU_ML3_MS_NW ussd_abort := ts_ML3_MO_SS_RELEASE_COMPLETE(
2804 tid := 1, /* Response should arrive within the same transaction */
2805 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2806 facility := omit
2807 /* TODO: cause? */
2808 );
2809
2810 /* Compose expected HLR -> MSC abort message */
2811 var template GSUP_PDU gsup_abort := tr_GSUP_PROC_SS_REQ(
2812 imsi := g_pars.imsi,
2813 sid := gsup_ms_req_complete.ies[1].val.session_id,
2814 state := OSMO_GSUP_SESSION_STATE_END
2815 );
2816
2817 /* Abort transaction */
2818 BSSAP.send(ts_PDU_DTAP_MO(ussd_abort));
2819 /* Expect GSUP message indicating abort */
2820 f_expect_gsup_msg(gsup_abort);
2821
2822 f_expect_clear();
2823}
2824testcase TC_lu_and_mo_ussd_mo_release() runs on MTC_CT {
2825 var BSC_ConnHdlr vc_conn;
2826 f_init();
2827 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_ussd_mo_release), 50);
2828 vc_conn.done;
2829}
2830
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07002831/* LU followed by MO USSD request and MT Release due to timeout */
2832private function f_tc_lu_and_ss_session_timeout(charstring id, BSC_ConnHdlrPars pars)
2833runs on BSC_ConnHdlr {
2834 f_init_handler(pars);
2835
2836 /* Perform location update */
2837 f_perform_lu();
2838
2839 /* Send CM Service Request for SS/USSD */
2840 f_establish_fully(EST_TYPE_SS_ACT);
2841
2842 /* We need to inspect GSUP activity */
2843 f_create_gsup_expect(hex2str(g_pars.imsi));
2844
2845 var template OCTN facility_ms_req := f_USSD_FACILITY_IE_INVOKE(
2846 invoke_id := 1,
2847 op_code := SS_OP_CODE_PROCESS_USS_REQ,
2848 ussd_string := "#release_me");
2849
2850 /* Compose MO SS/REGISTER message with request */
2851 var template (value) PDU_ML3_MS_NW ussd_ms_req := ts_ML3_MO_SS_REGISTER(
2852 tid := 1, /* An arbitrary transaction identifier */
2853 ti_flag := c_TIF_ORIG, /* Sent from the side that originates the TI */
2854 facility := valueof(facility_ms_req));
2855
2856 /* Compose expected MSC -> HLR message */
2857 var template GSUP_PDU gsup_ms_req := tr_GSUP_PROC_SS_REQ(
2858 imsi := g_pars.imsi,
2859 state := OSMO_GSUP_SESSION_STATE_BEGIN,
2860 ss := valueof(facility_ms_req));
2861
2862 /* To be used for sending response with correct session ID */
2863 var GSUP_PDU gsup_ms_req_complete;
2864
2865 /* Initiate a new SS transaction */
2866 BSSAP.send(ts_PDU_DTAP_MO(ussd_ms_req));
2867 /* Expect GSUP request with original Facility IE */
2868 gsup_ms_req_complete := f_expect_gsup_msg(gsup_ms_req);
2869
2870 /* Don't respond, wait for timeout */
2871 f_sleep(3.0);
2872
2873 var template PDU_ML3_NW_MS dtap_rel := tr_ML3_MT_SS_RELEASE_COMPLETE(
2874 tid := 1, /* Should match the request's tid */
2875 ti_flag := c_TIF_REPL, /* Sent to the side that originates the TI */
2876 cause := *, /* TODO: expect some specific value */
2877 facility := omit);
2878
2879 var template GSUP_PDU gsup_rel := tr_GSUP_PROC_SS_ERR(
2880 imsi := g_pars.imsi,
2881 sid := gsup_ms_req_complete.ies[1].val.session_id,
2882 state := OSMO_GSUP_SESSION_STATE_END,
2883 cause := ?); /* TODO: expect some specific value */
2884
2885 /* Expect release on both interfaces */
2886 interleave {
2887 [] BSSAP.receive(tr_PDU_DTAP_MT(dtap_rel)) { };
2888 [] GSUP.receive(gsup_rel) { };
2889 }
2890
2891 f_expect_clear();
2892 setverdict(pass);
2893}
2894testcase TC_lu_and_ss_session_timeout() runs on MTC_CT {
2895 var BSC_ConnHdlr vc_conn;
2896 f_init();
Vadim Yanitskiy36d28dd2018-12-03 02:45:45 +07002897 f_vty_config(MSCVTY, "msc", "ncss guard-timeout 3");
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07002898 vc_conn := f_start_handler(refers(f_tc_lu_and_ss_session_timeout), 51);
2899 vc_conn.done;
Vadim Yanitskiy36d28dd2018-12-03 02:45:45 +07002900 f_vty_config(MSCVTY, "msc", "ncss guard-timeout 0");
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07002901}
2902
Stefan Sperling89eb1f32018-12-17 15:06:20 +01002903/* A5/1 only permitted on network side; attempt an invalid CIPHER MODE COMPLETE with A5/3 which MSC should reject. */
2904private function f_tc_cipher_complete_with_invalid_cipher(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2905 pars.net.expect_auth := true;
2906 pars.net.expect_ciph := true;
2907 pars.net.kc_support := '02'O; /* A5/1 only */
2908 f_init_handler(pars);
2909
2910 g_pars.vec := f_gen_auth_vec_2g();
2911
2912 /* Can't use f_perform_lu() directly. Code below is based on it. */
2913
2914 /* tell GSUP dispatcher to send this IMSI to us */
2915 f_create_gsup_expect(hex2str(g_pars.imsi));
2916
2917 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
2918 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
2919 f_bssap_compl_l3(l3_lu);
2920
2921 f_mm_auth();
2922
2923 var OCT1 a5_net := f_alg_mask_from_cm(g_pars.cm2);
2924 var OCT1 a5_intersect := g_pars.net.kc_support and4b a5_net;
2925 alt {
2926 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(a5_intersect, g_pars.vec.kc)) {
2927 BSSAP.send(ts_BSSMAP_CipherModeCompl(int2oct(4 /* "accept" A5/3 */, 1)));
2928 }
2929 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc)) {
2930 setverdict(fail, "Wrong ciphering algorithm mask in CiphModCmd");
2931 mtc.stop;
2932 }
2933 [] BSSAP.receive {
2934 setverdict(fail, "Unknown/unexpected BSSAP received");
2935 mtc.stop;
2936 }
2937 }
2938
2939 /* Expect LU reject from MSC. */
2940 alt {
2941 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
2942 setverdict(pass);
2943 }
2944 [] BSSAP.receive {
2945 setverdict(fail, "Unknown/unexpected BSSAP received");
2946 mtc.stop;
2947 }
2948 }
Stefan Sperlingc620b352018-12-18 17:23:36 +01002949 f_expect_clear();
Stefan Sperling89eb1f32018-12-17 15:06:20 +01002950}
2951
2952testcase TC_cipher_complete_with_invalid_cipher() runs on MTC_CT {
2953 var BSC_ConnHdlr vc_conn;
2954 f_init();
2955 f_vty_config(MSCVTY, "network", "encryption a5 1");
2956
2957 vc_conn := f_start_handler(refers(f_tc_cipher_complete_with_invalid_cipher), 52);
2958 vc_conn.done;
2959}
2960
Harald Weltef640a012018-04-14 17:49:21 +02002961/* TODO (SMS):
2962 * different user data lengths
2963 * SMPP transaction mode with unsuccessful delivery
2964 * queued MT-SMS with no paging response + later delivery
2965 * different data coding schemes
2966 * multi-part SMS
2967 * user-data headers
2968 * TP-PID for SMS to SIM
2969 * behavior if SMS memory is full + RP-SMMA
2970 * delivery reports
2971 * SMPP osmocom extensions
2972 * more-messages-to-send
2973 * SMS during ongoing call (SACCH/SAPI3)
2974 */
2975
2976/* TODO (General):
Harald Welteba7b6d92018-01-23 21:32:34 +01002977 * continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
2978 * malformed messages (missing IE, invalid message type): properly rejected?
2979 * MT call while LU or is ongoing: Do we use existing lchan or page while lchan active?
2980 * 3G/2G auth permutations
2981 * encryption algorithms vs. classmark vs. vty config
Harald Welteba7b6d92018-01-23 21:32:34 +01002982 * send new transaction after/during clear (like SMS, ...)
Harald Welte45164da2018-01-24 12:51:27 +01002983 * too long L3 INFO in DTAP
2984 * too long / padded BSSAP
2985 * too long / short TLV values
Harald Welteba7b6d92018-01-23 21:32:34 +01002986 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01002987
2988
2989control {
Philipp Maier328d1662018-03-07 10:40:27 +01002990 execute( TC_cr_before_reset() );
Harald Weltea49e36e2018-01-21 19:29:33 +01002991 execute( TC_lu_imsi_noauth_tmsi() );
Harald Welted2328a22018-01-27 14:27:16 +01002992 execute( TC_lu_imsi_noauth_notmsi() );
Harald Weltea49e36e2018-01-21 19:29:33 +01002993 execute( TC_lu_imsi_reject() );
2994 execute( TC_lu_imsi_timeout_gsup() );
Harald Welted2328a22018-01-27 14:27:16 +01002995 execute( TC_lu_imsi_auth_tmsi() );
2996 execute( TC_cmserv_imsi_unknown() );
Harald Welte2bb825f2018-01-22 11:31:18 +01002997 execute( TC_lu_and_mo_call() );
Harald Welte071ed732018-01-23 19:53:52 +01002998 execute( TC_lu_auth_sai_timeout() );
2999 execute( TC_lu_auth_sai_err() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01003000 execute( TC_lu_clear_request() );
3001 execute( TC_lu_disconnect() );
3002 execute( TC_lu_by_imei() );
3003 execute( TC_lu_by_tmsi_noauth_unknown() );
3004 execute( TC_imsi_detach_by_imsi() );
3005 execute( TC_imsi_detach_by_tmsi() );
3006 execute( TC_imsi_detach_by_imei() );
3007 execute( TC_emerg_call_imei_reject() );
3008 execute( TC_emerg_call_imsi() );
3009 execute( TC_cm_serv_req_vgcs_reject() );
3010 execute( TC_cm_serv_req_vbs_reject() );
3011 execute( TC_cm_serv_req_lcs_reject() );
Harald Welte0195ab12018-01-24 21:50:20 +01003012 execute( TC_cm_reest_req_reject() );
Harald Welte1af6ea82018-01-25 18:33:15 +01003013 execute( TC_lu_auth_2G_fail() );
3014 execute( TC_lu_imsi_auth_tmsi_encr_13_13() );
3015 execute( TC_cl3_no_payload() );
3016 execute( TC_cl3_rnd_payload() );
Harald Welte1852a842018-01-26 22:53:36 +01003017 execute( TC_establish_and_nothing() );
3018 execute( TC_mo_setup_and_nothing() );
3019 execute( TC_mo_crcx_ran_timeout() );
3020 execute( TC_mo_crcx_ran_reject() );
Harald Welted2328a22018-01-27 14:27:16 +01003021 execute( TC_mt_crcx_ran_reject() );
Daniel Willmann8b084372018-02-04 13:35:26 +01003022 execute( TC_mo_setup_and_dtmf_dup() );
Harald Welteaa54cf82018-01-30 08:15:32 +01003023 //execute( TC_mt_t310() );
Harald Welte167458a2018-01-27 15:58:16 +01003024 execute( TC_gsup_cancel() );
Harald Welte9de84792018-01-28 01:06:35 +01003025 execute( TC_lu_imsi_auth_tmsi_encr_1_13() );
3026 execute( TC_lu_imsi_auth_tmsi_encr_3_13() );
3027 execute( TC_lu_imsi_auth_tmsi_encr_3_1() );
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01003028 execute( TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() );
Harald Welte9de84792018-01-28 01:06:35 +01003029 execute( TC_lu_imsi_auth_tmsi_encr_13_2() );
3030 execute( TC_lu_imsi_auth_tmsi_encr_013_2() );
Philipp Maier94f3f1b2018-03-15 18:54:13 +01003031 execute( TC_mo_release_timeout() );
Philipp Maier2a98a732018-03-19 16:06:12 +01003032 execute( TC_lu_and_mt_call_no_dlcx_resp() );
Philipp Maier75932982018-03-27 14:52:35 +02003033 execute( TC_reset_two() );
Harald Welte33ec09b2018-02-10 15:34:46 +01003034
3035 execute( TC_lu_and_mt_call() );
3036
Harald Weltef45efeb2018-04-09 18:19:24 +02003037 execute( TC_lu_and_mo_sms() );
3038 execute( TC_lu_and_mt_sms() );
Harald Weltef640a012018-04-14 17:49:21 +02003039 execute( TC_smpp_mo_sms() );
3040 execute( TC_smpp_mt_sms() );
Harald Weltef45efeb2018-04-09 18:19:24 +02003041
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07003042 execute( TC_gsup_mo_sms() );
Vadim Yanitskiy9cc019a2018-11-15 02:06:07 +07003043 execute( TC_gsup_mo_smma() );
Vadim Yanitskiy103d09f2018-11-12 02:50:23 +07003044
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003045 execute( TC_lu_and_mo_ussd_single_request() );
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003046 execute( TC_lu_and_mt_ussd_notification() );
Vadim Yanitskiy2a978b92018-06-19 17:51:20 +07003047 execute( TC_lu_and_mo_ussd_during_mt_call() );
Vadim Yanitskiy13e4a272018-06-19 18:24:31 +07003048 execute( TC_lu_and_mt_ussd_during_mt_call() );
Vadim Yanitskiy2daf52d2018-06-21 04:19:58 +07003049 execute( TC_lu_and_mo_ussd_mo_release() );
Vadim Yanitskiy0e392dd2018-11-29 00:47:54 +07003050 execute( TC_lu_and_ss_session_timeout() );
Vadim Yanitskiy7d1f9182018-05-28 16:21:42 +07003051
Stefan Sperling89eb1f32018-12-17 15:06:20 +01003052 execute( TC_cipher_complete_with_invalid_cipher() );
3053
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01003054 /* Run this last: at the time of writing this test crashes the MSC */
3055 execute( TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() );
Neels Hofmeyr692c9ee2018-04-10 02:07:13 +02003056 execute( TC_mo_cc_bssmap_clear() );
Harald Weltef6dd64d2017-11-19 12:09:51 +01003057}
3058
3059
3060}