blob: f843839cc6e4cceb83424f08ce321edef21652fa [file] [log] [blame]
Harald Weltef6dd64d2017-11-19 12:09:51 +01001module MSC_Tests {
2
3import from General_Types all;
4import from Osmocom_Types all;
5
6import from M3UA_Types all;
7import from M3UA_Emulation all;
8
9import from MTP3asp_Types all;
10import from MTP3asp_PortType all;
11
12import from SCCPasp_Types all;
13import from SCCP_Types all;
14import from SCCP_Emulation all;
15
16import from SCTPasp_Types all;
17import from SCTPasp_PortType all;
18
Harald Weltea49e36e2018-01-21 19:29:33 +010019import from Osmocom_CTRL_Functions all;
20import from Osmocom_CTRL_Types all;
21import from Osmocom_CTRL_Adapter all;
22
Harald Welte3ca1c902018-01-24 18:51:27 +010023import from TELNETasp_PortType all;
24import from Osmocom_VTY_Functions all;
25
Harald Weltea49e36e2018-01-21 19:29:33 +010026import from MNCC_Emulation all;
Harald Welte2bb825f2018-01-22 11:31:18 +010027import from MNCC_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +010028
Harald Welte4aa970c2018-01-26 10:38:09 +010029import from MGCP_Emulation all;
30import from MGCP_Types all;
31import from MGCP_Templates all;
32import from SDP_Types all;
33
Harald Weltea49e36e2018-01-21 19:29:33 +010034import from GSUP_Emulation all;
35import from GSUP_Types all;
36import from IPA_Emulation all;
37
Harald Weltef6dd64d2017-11-19 12:09:51 +010038import from BSSAP_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +010039import from BSSAP_Adapter all;
40import from BSSAP_CodecPort all;
41import from BSSMAP_Templates all;
42import from BSSMAP_Emulation all;
43import from BSC_ConnectionHandler all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010044
Harald Weltea49e36e2018-01-21 19:29:33 +010045import from MobileL3_Types all;
46import from MobileL3_CommonIE_Types all;
47import from L3_Templates all;
Harald Welte158a7ca2018-02-16 18:11:31 +010048import from L3_Common all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010049
Harald Weltef640a012018-04-14 17:49:21 +020050import from SMPP_Types all;
51import from SMPP_Templates all;
52import from SMPP_Emulation all;
53
Philipp Maier75932982018-03-27 14:52:35 +020054const integer NUM_BSC := 2;
55type record of BSSAP_Configuration BSSAP_Configurations;
Harald Weltef6dd64d2017-11-19 12:09:51 +010056
Harald Weltea4ca4462018-02-09 00:17:14 +010057type component MTC_CT extends CTRL_Adapter_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +010058 var boolean g_initialized := false;
Harald Weltea49e36e2018-01-21 19:29:33 +010059
Philipp Maier75932982018-03-27 14:52:35 +020060 var BSSAP_Adapter g_bssap[NUM_BSC];
Harald Weltea4ca4462018-02-09 00:17:14 +010061
Harald Weltea49e36e2018-01-21 19:29:33 +010062 /* no 'adapter_CT' for MNCC or GSUP */
63 var MNCC_Emulation_CT vc_MNCC;
Harald Welte4aa970c2018-01-26 10:38:09 +010064 var MGCP_Emulation_CT vc_MGCP;
Harald Weltea49e36e2018-01-21 19:29:33 +010065 var GSUP_Emulation_CT vc_GSUP;
66 var IPA_Emulation_CT vc_GSUP_IPA;
Harald Weltef640a012018-04-14 17:49:21 +020067 var SMPP_Emulation_CT vc_SMPP;
Harald Weltea49e36e2018-01-21 19:29:33 +010068
69 /* only to get events from IPA underneath GSUP */
70 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte3ca1c902018-01-24 18:51:27 +010071 /* VTY to MSC */
72 port TELNETasp_PT MSCVTY;
Philipp Maier328d1662018-03-07 10:40:27 +010073
74 /* A port to directly send BSSAP messages. This port is used for
75 * tests that require low level access to sen arbitrary BSSAP
76 * messages. Run f_init_bssap_direct() to connect and initialize */
77 port BSSAP_CODEC_PT BSSAP_DIRECT;
78
79 /* When BSSAP messages are directly sent, then the connection
80 * handler is not active, which means that also no guard timer is
81 * set up. The following timer will serve as a replacement */
82 timer Tguard_direct := 60.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +010083}
84
85modulepar {
Harald Weltea49e36e2018-01-21 19:29:33 +010086 /* remote parameters of IUT */
87 charstring mp_msc_ip := "127.0.0.1";
88 integer mp_msc_ctrl_port := 4255;
89 integer mp_msc_vty_port := 4254;
Harald Weltef6dd64d2017-11-19 12:09:51 +010090
Harald Weltea49e36e2018-01-21 19:29:33 +010091 /* local parameters of emulated HLR */
92 charstring mp_hlr_ip := "127.0.0.1";
93 integer mp_hlr_port := 4222;
Harald Welte6126fb02018-01-27 20:08:24 +010094 charstring mp_mgw_ip := "127.0.0.1";
95 integer mp_mgw_port := 2427;
Harald Weltef6dd64d2017-11-19 12:09:51 +010096
Harald Weltea49e36e2018-01-21 19:29:33 +010097 charstring mp_msc_mncc := "/tmp/mncc";
Harald Weltea4ca4462018-02-09 00:17:14 +010098
Harald Weltef640a012018-04-14 17:49:21 +020099 integer mp_msc_smpp_port := 2775;
100 charstring mp_smpp_system_id := "msc_tester";
101 charstring mp_smpp_password := "osmocom1";
102
Philipp Maier75932982018-03-27 14:52:35 +0200103 BSSAP_Configurations mp_bssap_cfg := {
104 {
105 sccp_service_type := "mtp3_itu",
106 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
107 own_pc := 185,
108 own_ssn := 254,
109 peer_pc := 187,
110 peer_ssn := 254,
111 sio := '83'O,
112 rctx := 0
113 },
114 {
115 sccp_service_type := "mtp3_itu",
116 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
117 own_pc := 186,
118 own_ssn := 254,
119 peer_pc := 187,
120 peer_ssn := 254,
121 sio := '83'O,
122 rctx := 1
123 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100124 };
Harald Weltef6dd64d2017-11-19 12:09:51 +0100125}
126
Philipp Maier328d1662018-03-07 10:40:27 +0100127/* altstep for the global guard timer (only used when BSSAP_DIRECT
128 * is used for communication */
129private altstep as_Tguard_direct() runs on MTC_CT {
130 [] Tguard_direct.timeout {
131 setverdict(fail, "Tguard timeout");
132 self.stop;
133 }
134}
Harald Weltef6dd64d2017-11-19 12:09:51 +0100135
Harald Weltef640a012018-04-14 17:49:21 +0200136function f_init_smpp(charstring id) runs on MTC_CT {
137 id := id & "-SMPP";
138 var EsmePars pars := {
139 mode := MODE_TRANSCEIVER,
140 bind := {
141 system_id := mp_smpp_system_id,
142 password := mp_smpp_password,
143 system_type := "MSC_Tests",
144 interface_version := hex2int('34'H),
145 addr_ton := unknown,
146 addr_npi := unknown,
147 address_range := ""
148 },
149 esme_role := true
150 }
151
152 vc_SMPP := SMPP_Emulation_CT.create(id);
153 map(vc_SMPP:SMPP_PORT, system:SMPP_PORT);
154 vc_SMPP.start(SMPP_Emulation.main_client(pars, mp_msc_ip, mp_msc_smpp_port, "", -1));
155}
156
157
Harald Weltea49e36e2018-01-21 19:29:33 +0100158function f_init_mncc(charstring id) runs on MTC_CT {
159 id := id & "-MNCC";
160 var MnccOps ops := {
161 create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
162 unitdata_cb := refers(MNCC_Emulation.DummyUnitdataCallback)
163 }
164
165 vc_MNCC := MNCC_Emulation_CT.create(id);
166 map(vc_MNCC:MNCC, system:MNCC_CODEC_PT);
167 vc_MNCC.start(MNCC_Emulation.main(ops, id, mp_msc_mncc));
Harald Weltef6dd64d2017-11-19 12:09:51 +0100168}
169
Harald Welte4aa970c2018-01-26 10:38:09 +0100170function f_init_mgcp(charstring id) runs on MTC_CT {
171 id := id & "-MGCP";
172 var MGCPOps ops := {
173 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
174 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
175 }
176 var MGCP_conn_parameters pars := {
Harald Welte6126fb02018-01-27 20:08:24 +0100177 callagent_ip := mp_msc_ip,
Harald Welte4aa970c2018-01-26 10:38:09 +0100178 callagent_udp_port := -1,
Harald Welte6126fb02018-01-27 20:08:24 +0100179 mgw_ip := mp_mgw_ip,
180 mgw_udp_port := mp_mgw_port
Harald Welte4aa970c2018-01-26 10:38:09 +0100181 }
182
183 vc_MGCP := MGCP_Emulation_CT.create(id);
184 map(vc_MGCP:MGCP, system:MGCP_CODEC_PT);
185 vc_MGCP.start(MGCP_Emulation.main(ops, pars, id));
186}
187
Harald Weltea49e36e2018-01-21 19:29:33 +0100188function f_init_gsup(charstring id) runs on MTC_CT {
189 id := id & "-GSUP";
190 var GsupOps ops := {
191 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
192 }
193
194 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
195 vc_GSUP := GSUP_Emulation_CT.create(id);
196
197 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
198 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
199 /* we use this hack to get events like ASP_IPA_EVENT_UP */
200 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
201
202 vc_GSUP.start(GSUP_Emulation.main(ops, id));
203 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
204
205 /* wait for incoming connection to GSUP port before proceeding */
206 timer T := 10.0;
207 T.start;
208 alt {
209 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
210 [] T.timeout {
Harald Welte458fd372018-03-21 11:26:23 +0100211 setverdict(fail, "No connection to GSUP Port");
Harald Weltea49e36e2018-01-21 19:29:33 +0100212 self.stop
213 }
214 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100215}
216
Philipp Maier75932982018-03-27 14:52:35 +0200217function f_init(integer num_bsc := 1) runs on MTC_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +0100218
219 if (g_initialized == true) {
220 return;
221 }
222 g_initialized := true;
223
Philipp Maier75932982018-03-27 14:52:35 +0200224 if (num_bsc > NUM_BSC) {
225 setverdict(fail, "excess number of BSC instances requested");
226 }
227
228 for (var integer i := 0; i < num_bsc; i := i + 1) {
229 if (isbound(mp_bssap_cfg[i])) {
Philipp Maierdefd9482018-05-16 16:44:37 +0200230 f_bssap_init(g_bssap[i], mp_bssap_cfg[i], "MSC_Test_" & int2str(i), BSC_BssmapOps);
Harald Welted5833a82018-05-27 16:52:56 +0200231 f_bssap_start(g_bssap[i]);
Philipp Maier75932982018-03-27 14:52:35 +0200232 } else {
233 setverdict(fail, "missing BSSAP configuration");
234 }
235 }
236
Harald Weltea49e36e2018-01-21 19:29:33 +0100237 f_ipa_ctrl_start(mp_msc_ip, mp_msc_ctrl_port);
238 f_init_mncc("MSC_Test");
Harald Welte4aa970c2018-01-26 10:38:09 +0100239 f_init_mgcp("MSC_Test");
Harald Weltea49e36e2018-01-21 19:29:33 +0100240 f_init_gsup("MSC_Test");
Harald Weltef640a012018-04-14 17:49:21 +0200241 f_init_smpp("MSC_Test");
Harald Welte3ca1c902018-01-24 18:51:27 +0100242
243 map(self:MSCVTY, system:MSCVTY);
244 f_vty_set_prompts(MSCVTY);
245 f_vty_transceive(MSCVTY, "enable");
Harald Welteb14c77a2018-01-25 17:25:44 +0100246
247 /* set some defaults */
248 f_vty_config(MSCVTY, "network", "authentication optional");
249 f_vty_config(MSCVTY, "msc", "assign-tmsi");
250 f_vty_config(MSCVTY, "network", "encryption a5 0");
Harald Weltef6dd64d2017-11-19 12:09:51 +0100251}
252
Philipp Maier328d1662018-03-07 10:40:27 +0100253/* Initialize for a direct connection to BSSAP. This function is an alternative
254 * to f_init() when the high level functions of the BSC_ConnectionHandler are
255 * not needed. */
256function f_init_bssap_direct() runs on MTC_CT {
Philipp Maier75932982018-03-27 14:52:35 +0200257 f_bssap_init(g_bssap[0], mp_bssap_cfg[0], "MSC_Test", omit);
258 connect(g_bssap[0].vc_SCCP:SCCP_SP_PORT, self:BSSAP_DIRECT);
Philipp Maier328d1662018-03-07 10:40:27 +0100259
260 /* Start guard timer and activate it as default */
261 Tguard_direct.start
262 activate(as_Tguard_direct());
263}
264
Harald Weltef6dd64d2017-11-19 12:09:51 +0100265template PDU_BSSAP ts_BSSAP_BSSMAP := {
266 discriminator := '0'B,
267 spare := '0000000'B,
268 dlci := omit,
269 lengthIndicator := 0, /* overwritten by codec */
270 pdu := ?
271}
272
273template PDU_BSSAP tr_BSSAP_BSSMAP := {
274 discriminator := '0'B,
275 spare := '0000000'B,
276 dlci := omit,
277 lengthIndicator := ?,
278 pdu := {
279 bssmap := ?
280 }
281}
282
283
284type integer BssmapCause;
285
286template (value) BSSMAP_IE_Cause ts_BSSMAP_IE_Cause(BssmapCause val) := {
287 elementIdentifier := '04'O,
288 lengthIndicator := 0,
289 causeValue := int2bit(val, 7),
290 extensionCauseValue := '0'B,
291 spare1 := omit
292}
293
294template (value) PDU_BSSAP ts_BSSMAP_Reset(BssmapCause cause) modifies ts_BSSAP_BSSMAP := {
295 pdu := {
296 bssmap := {
297 reset := {
298 messageType := '30'O,
299 cause := ts_BSSMAP_IE_Cause(cause),
300 a_InterfaceSelectorForReset := omit
301 }
302 }
303 }
304}
305
306template (value) PDU_BSSAP ts_BSSMAP_ResetAck modifies ts_BSSAP_BSSMAP := {
307 pdu := {
308 bssmap := {
309 resetAck := {
310 messageType := '31'O,
311 a_InterfaceSelectorForReset := omit
312 }
313 }
314 }
315}
316
317template PDU_BSSAP tr_BSSMAP_ResetAck modifies tr_BSSAP_BSSMAP := {
318 pdu := {
319 bssmap := {
320 resetAck := {
321 messageType := '31'O,
322 a_InterfaceSelectorForReset := *
323 }
324 }
325 }
326}
327
328template BSSMAP_IE_CellIdentifier ts_BSSMAP_IE_CellID := {
329 elementIdentifier := '05'O,
330 lengthIndicator := 0,
331 cellIdentifierDiscriminator := '0000'B,
332 spare1_4 := '0000'B,
333 cellIdentification := ?
334}
335
336type uint16_t BssmapLAC;
337type uint16_t BssmapCI;
338
339/*
340template BSSMAP_IE_CellIdentifier ts_CellId_CGI(mcc, mnc, lac, ci)
341modifies ts_BSSMAP_IE_CellID := {
342 cellIdentification := {
343 cI_LAC_CGI := {
344 mnc_mcc := FIXME,
345 lac := int2oct(lac, 2),
346 ci := int2oct(ci, 2)
347 }
348 }
349}
350*/
351
352template BSSMAP_IE_CellIdentifier ts_CellID_LAC_CI(BssmapLAC lac, BssmapCI ci)
353modifies ts_BSSMAP_IE_CellID := {
354 cellIdentification := {
355 cI_LAC_CI := {
356 lac := int2oct(lac, 2),
357 ci := int2oct(ci, 2)
358 }
359 }
360}
361
362template BSSMAP_IE_CellIdentifier ts_CellId_CI(BssmapCI ci)
363modifies ts_BSSMAP_IE_CellID := {
364 cellIdentification := {
365 cI_CI := int2oct(ci, 2)
366 }
367}
368
369template BSSMAP_IE_CellIdentifier ts_CellId_none
370modifies ts_BSSMAP_IE_CellID := {
371 cellIdentification := {
372 cI_noCell := ''O
373 }
374}
375
376
377template BSSMAP_IE_Layer3Information ts_BSSMAP_IE_L3Info(octetstring l3info) := {
378 elementIdentifier := '17'O,
379 lengthIndicator := 0,
380 layer3info := l3info
381}
382
383template PDU_BSSAP ts_BSSMAP_ComplL3(BSSMAP_IE_CellIdentifier cell_id, octetstring l3_info)
384modifies ts_BSSAP_BSSMAP := {
385 pdu := {
386 bssmap := {
387 completeLayer3Information := {
388 messageType := '57'O,
389 cellIdentifier := cell_id,
390 layer3Information := ts_BSSMAP_IE_L3Info(l3_info),
391 chosenChannel := omit,
392 lSAIdentifier := omit,
393 aPDU := omit,
394 codecList := omit,
395 redirectAttemptFlag := omit,
396 sendSequenceNumber := omit,
397 iMSI := omit
398 }
399 }
400 }
401}
402
403template PDU_BSSAP ts_BSSMAP_HandoReq(BssmapCause cause, BSSMAP_IE_CellIdentifierList cid_list)
404modifies ts_BSSAP_BSSMAP := {
405 pdu := {
406 bssmap := {
407 handoverRequired := {
408 messageType := '11'O,
409 cause := ts_BSSMAP_IE_Cause(cause),
410 responseRequest := omit,
411 cellIdentifierList := cid_list,
412 circuitPoolList := omit,
413 currentChannelType1 := omit,
414 speechVersion := omit,
415 queueingIndicator := omit,
416 oldToNewBSSInfo := omit,
417 sourceToTargetRNCTransparentInfo := omit,
418 sourceToTargetRNCTransparentInfoCDMA := omit,
419 gERANClassmark := omit,
420 talkerPriority := omit,
421 speechCodec := omit,
422 cSG_Identifier := omit
423 }
424 }
425 }
426}
427
Harald Weltea49e36e2018-01-21 19:29:33 +0100428type function void_fn(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100429
Harald Weltea49e36e2018-01-21 19:29:33 +0100430/* FIXME: move into BSC_ConnectionHandler? */
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100431function f_init_pars(integer imsi_suffix) runs on MTC_CT return BSC_ConnHdlrPars {
Harald Weltede371492018-01-27 23:44:41 +0100432 var BSC_ConnHdlrNetworkPars net_pars := {
433 kc_support := '0A'O, /* A5/1 and A5/3 enabled */
434 expect_tmsi := true,
435 expect_auth := false,
436 expect_ciph := false
437 };
Harald Weltea49e36e2018-01-21 19:29:33 +0100438 var BSC_ConnHdlrPars pars := {
Philipp Maier75932982018-03-27 14:52:35 +0200439 sccp_addr_own := g_bssap[0].sccp_addr_own,
440 sccp_addr_peer := g_bssap[0].sccp_addr_peer,
Harald Welteedbab812018-03-18 16:02:25 +0100441 cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42)),
Harald Welte81b7f9d2018-01-24 19:06:24 +0100442 imei := f_gen_imei(imsi_suffix),
443 imsi := f_gen_imsi(imsi_suffix),
444 msisdn := f_gen_msisdn(imsi_suffix),
Harald Welte256571e2018-01-24 18:47:19 +0100445 tmsi := omit,
Harald Welte9de84792018-01-28 01:06:35 +0100446 cm1 := valueof(ts_CM1),
Harald Welte82600572018-01-21 20:54:08 +0100447 cm2 := valueof(ts_CM2_default),
Harald Welte16114282018-01-24 22:41:21 +0100448 cm3 := omit,
Harald Weltede371492018-01-27 23:44:41 +0100449 vec := omit,
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100450 net := net_pars,
451 send_early_cm := true
Harald Weltea49e36e2018-01-21 19:29:33 +0100452 };
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100453 return pars;
454}
455
456function f_start_handler_with_pars(void_fn fn, BSC_ConnHdlrPars pars) runs on MTC_CT return BSC_ConnHdlr {
457 var BSC_ConnHdlr vc_conn;
458 var charstring id := testcasename();
Harald Weltea49e36e2018-01-21 19:29:33 +0100459
460 vc_conn := BSC_ConnHdlr.create(id);
461 /* BSSMAP part / A interface */
Philipp Maier75932982018-03-27 14:52:35 +0200462 connect(vc_conn:BSSAP, g_bssap[0].vc_BSSMAP:CLIENT);
463 connect(vc_conn:BSSAP_PROC, g_bssap[0].vc_BSSMAP:PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100464 /* MNCC part */
465 connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
466 connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);
Harald Welte4aa970c2018-01-26 10:38:09 +0100467 /* MGCP part */
468 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
469 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100470 /* GSUP part */
471 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
472 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
Harald Weltef640a012018-04-14 17:49:21 +0200473 /* SMPP part */
474 connect(vc_conn:SMPP, vc_SMPP:SMPP_CLIENT);
475 connect(vc_conn:SMPP_PROC, vc_SMPP:SMPP_PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100476
Harald Weltea10db902018-01-27 12:44:49 +0100477 /* We cannot use vc_conn.start(f_init_handler(fn, id, pars)); as we cannot have
478 * a stand-alone 'derefers()' call, see https://www.eclipse.org/forums/index.php/t/1091364/ */
Harald Weltea49e36e2018-01-21 19:29:33 +0100479 vc_conn.start(derefers(fn)(id, pars));
480 return vc_conn;
481}
482
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100483function f_start_handler(void_fn fn, integer imsi_suffix) runs on MTC_CT return BSC_ConnHdlr {
484 return f_start_handler_with_pars(fn, f_init_pars(imsi_suffix));
485}
486
Harald Weltea49e36e2018-01-21 19:29:33 +0100487private function f_tc_lu_imsi_noauth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100488 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100489 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100490}
Harald Weltea49e36e2018-01-21 19:29:33 +0100491testcase TC_lu_imsi_noauth_tmsi() runs on MTC_CT {
492 var BSC_ConnHdlr vc_conn;
493 f_init();
494
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100495 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi), 1);
Harald Weltea49e36e2018-01-21 19:29:33 +0100496 vc_conn.done;
497}
498
499private function f_tc_lu_imsi_noauth_notmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100500 pars.net.expect_tmsi := false;
Harald Weltea10db902018-01-27 12:44:49 +0100501 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100502 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100503}
Harald Weltea49e36e2018-01-21 19:29:33 +0100504testcase TC_lu_imsi_noauth_notmsi() runs on MTC_CT {
505 var BSC_ConnHdlr vc_conn;
506 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100507 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
Harald Weltea49e36e2018-01-21 19:29:33 +0100508
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100509 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi), 2);
Harald Weltea49e36e2018-01-21 19:29:33 +0100510 vc_conn.done;
511}
512
513/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
514private function f_tc_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100515 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100516 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
517
518 f_create_gsup_expect(hex2str(g_pars.imsi));
519 f_bssap_compl_l3(l3_lu);
520 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
521 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
522 alt {
Harald Welte5946b332018-03-18 23:32:21 +0100523 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej(int2oct(23,1)))) {
524 f_expect_clear();
525 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100526 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
527 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
528 self.stop;
529 }
530 }
Harald Welte1ddc7162018-01-27 14:25:46 +0100531 f_expect_clear();
Harald Weltea49e36e2018-01-21 19:29:33 +0100532}
533testcase TC_lu_imsi_reject() runs on MTC_CT {
534 var BSC_ConnHdlr vc_conn;
535 f_init();
536
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100537 vc_conn := f_start_handler(refers(f_tc_lu_imsi_reject), 3);
Harald Weltea49e36e2018-01-21 19:29:33 +0100538 vc_conn.done;
539}
540
541/* Do LU by IMSI, timeout on GSUP */
542private function f_tc_lu_imsi_timeout_gsup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100543 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100544 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
545
546 f_create_gsup_expect(hex2str(g_pars.imsi));
547 f_bssap_compl_l3(l3_lu);
548 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
549 /* Normally the HLR would need to respond here, but we decide to force a timeout here */
550 alt {
551 /* FIXME: Expect specific reject cause */
Harald Welte5946b332018-03-18 23:32:21 +0100552 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
553 f_expect_clear();
554 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100555 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
556 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
557 self.stop;
558 }
559 }
Harald Welte1ddc7162018-01-27 14:25:46 +0100560 f_expect_clear();
Harald Weltea49e36e2018-01-21 19:29:33 +0100561}
562testcase TC_lu_imsi_timeout_gsup() runs on MTC_CT {
563 var BSC_ConnHdlr vc_conn;
564 f_init();
565
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100566 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_gsup), 4);
Harald Weltea49e36e2018-01-21 19:29:33 +0100567 vc_conn.done;
568}
569
Harald Welte7b1b2812018-01-22 21:23:06 +0100570private function f_tc_lu_imsi_auth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100571 pars.net.expect_auth := true;
Harald Weltea10db902018-01-27 12:44:49 +0100572 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100573 f_perform_lu();
Harald Welte7b1b2812018-01-22 21:23:06 +0100574}
575testcase TC_lu_imsi_auth_tmsi() runs on MTC_CT {
576 var BSC_ConnHdlr vc_conn;
577 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100578 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte7b1b2812018-01-22 21:23:06 +0100579
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100580 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi), 5);
Harald Welte7b1b2812018-01-22 21:23:06 +0100581 vc_conn.done;
582}
583
Harald Weltea49e36e2018-01-21 19:29:33 +0100584
585/* Send CM SERVICE REQ for IMSI that has never performed LU before */
586private function f_tc_cmserv_imsi_unknown(charstring id, BSC_ConnHdlrPars pars)
587runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100588 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100589
590 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welteedbab812018-03-18 16:02:25 +0100591 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100592 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltea49e36e2018-01-21 19:29:33 +0100593
594 f_create_gsup_expect(hex2str(g_pars.imsi));
595
596 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
597 f_bssap_compl_l3(l3_info);
598
599 timer T := 10.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100600 T.start;
601 alt {
Harald Weltea49e36e2018-01-21 19:29:33 +0100602 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
603 //[] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC)) { }
604 [] BSSAP.receive { setverdict(fail, "Received unexpected BSSAP"); }
605 [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
606 setverdict(fail, "Unexpected GSUP UL REQ");
607 }
Daniel Willmann90829d62018-02-15 17:45:14 +0100608 [] T.timeout { setverdict(fail, "Timeout waiting for CM SERV REQ"); }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100609 }
610
Harald Welte1ddc7162018-01-27 14:25:46 +0100611 f_expect_clear();
Harald Weltef6dd64d2017-11-19 12:09:51 +0100612}
Harald Weltea49e36e2018-01-21 19:29:33 +0100613testcase TC_cmserv_imsi_unknown() runs on MTC_CT {
614 var BSC_ConnHdlr vc_conn;
615 f_init();
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100616 vc_conn := f_start_handler(refers(f_tc_cmserv_imsi_unknown), 6);
Harald Weltea49e36e2018-01-21 19:29:33 +0100617 vc_conn.done;
618}
619
Harald Welte2bb825f2018-01-22 11:31:18 +0100620private function f_tc_lu_and_mo_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100621 f_init_handler(pars);
Harald Welteb71901a2018-01-26 19:16:05 +0100622 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
623 cpars.bss_rtp_port := 1110;
624 cpars.mgcp_connection_id_bss := '22222'H;
625 cpars.mgcp_connection_id_mss := '33333'H;
Philipp Maierf1e02bb2018-03-15 16:30:00 +0100626 cpars.mgcp_ep := "rtpbridge/1@mgw";
Harald Welte2bb825f2018-01-22 11:31:18 +0100627
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100628 f_perform_lu();
Harald Welteb71901a2018-01-26 19:16:05 +0100629 f_mo_call(cpars);
Harald Welte2bb825f2018-01-22 11:31:18 +0100630}
631testcase TC_lu_and_mo_call() runs on MTC_CT {
632 var BSC_ConnHdlr vc_conn;
633 f_init();
634
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100635 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_call), 7);
Harald Welte071ed732018-01-23 19:53:52 +0100636 vc_conn.done;
637}
638
639/* Test LU (with authentication enabled), where HLR times out sending SAI response */
640private function f_tc_lu_auth_sai_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100641 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100642
643 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
644 var PDU_DTAP_MT dtap_mt;
645
646 /* tell GSUP dispatcher to send this IMSI to us */
647 f_create_gsup_expect(hex2str(g_pars.imsi));
648
649 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
650 f_bssap_compl_l3(l3_lu);
651
652 /* Send Early Classmark, just for the fun of it */
653 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
654
655 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
656 /* The HLR would normally return an auth vector here, but we fail to do so. */
657
658 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100659 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100660}
661testcase TC_lu_auth_sai_timeout() runs on MTC_CT {
662 var BSC_ConnHdlr vc_conn;
663 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100664 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100665
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100666 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_timeout), 8);
Harald Welte071ed732018-01-23 19:53:52 +0100667 vc_conn.done;
668}
669
670/* Test LU (with authentication enabled), where HLR rejects sending SAI error */
671private function f_tc_lu_auth_sai_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100672 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100673
674 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
675 var PDU_DTAP_MT dtap_mt;
676
677 /* tell GSUP dispatcher to send this IMSI to us */
678 f_create_gsup_expect(hex2str(g_pars.imsi));
679
680 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
681 f_bssap_compl_l3(l3_lu);
682
683 /* Send Early Classmark, just for the fun of it */
684 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
685
686 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
687 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 13));
688
689 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100690 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100691}
692testcase TC_lu_auth_sai_err() runs on MTC_CT {
693 var BSC_ConnHdlr vc_conn;
694 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100695 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100696
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100697 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_err), 9);
Harald Welte2bb825f2018-01-22 11:31:18 +0100698 vc_conn.done;
699}
Harald Weltea49e36e2018-01-21 19:29:33 +0100700
Harald Weltebc881782018-01-23 20:09:15 +0100701/* Test LU but BSC will send a clear request in the middle */
702private function f_tc_lu_clear_request(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100703 f_init_handler(pars);
Harald Weltebc881782018-01-23 20:09:15 +0100704
705 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
706 var PDU_DTAP_MT dtap_mt;
707
708 /* tell GSUP dispatcher to send this IMSI to us */
709 f_create_gsup_expect(hex2str(g_pars.imsi));
710
711 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
712 f_bssap_compl_l3(l3_lu);
713
714 /* Send Early Classmark, just for the fun of it */
715 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
716
717 f_sleep(1.0);
718 /* send clear request in the middle of the LU */
719 BSSAP.send(ts_BSSMAP_ClearRequest(0));
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200720 alt {
721 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { repeat; }
722 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {}
723 }
Harald Weltebc881782018-01-23 20:09:15 +0100724 BSSAP.send(ts_BSSMAP_ClearComplete);
Harald Welte89a32492018-01-27 19:07:28 +0100725 alt {
726 /* See https://osmocom.org/issues/2862 */
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200727 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
728 setverdict(fail, "Got a second Clear Command, only one expected");
729 repeat;
730 }
Harald Welte89a32492018-01-27 19:07:28 +0100731 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
732 }
Harald Weltebc881782018-01-23 20:09:15 +0100733 setverdict(pass);
734}
735testcase TC_lu_clear_request() runs on MTC_CT {
736 var BSC_ConnHdlr vc_conn;
737 f_init();
738
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100739 vc_conn := f_start_handler(refers(f_tc_lu_clear_request), 10);
Harald Weltebc881782018-01-23 20:09:15 +0100740 vc_conn.done;
741}
742
Harald Welte66af9e62018-01-24 17:28:21 +0100743/* Test LU but BSC will send a clear request in the middle */
744private function f_tc_lu_disconnect(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100745 f_init_handler(pars);
Harald Welte66af9e62018-01-24 17:28:21 +0100746
747 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
748 var PDU_DTAP_MT dtap_mt;
749
750 /* tell GSUP dispatcher to send this IMSI to us */
751 f_create_gsup_expect(hex2str(g_pars.imsi));
752
753 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
754 f_bssap_compl_l3(l3_lu);
755
756 /* Send Early Classmark, just for the fun of it */
757 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
758
759 f_sleep(1.0);
760 /* send clear request in the middle of the LU */
761 BSSAP.send(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
762 setverdict(pass);
763}
764testcase TC_lu_disconnect() runs on MTC_CT {
765 var BSC_ConnHdlr vc_conn;
766 f_init();
767
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100768 vc_conn := f_start_handler(refers(f_tc_lu_disconnect), 11);
Harald Welte66af9e62018-01-24 17:28:21 +0100769 vc_conn.done;
770}
771
772
Harald Welteba7b6d92018-01-23 21:32:34 +0100773/* Test LU but with illegal mobile identity type = IMEI */
774private function f_tc_lu_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100775 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100776
Harald Welte256571e2018-01-24 18:47:19 +0100777 var PDU_ML3_MS_NW l3_lu := f_build_lu_imei(g_pars.imei)
Harald Welteba7b6d92018-01-23 21:32:34 +0100778 var PDU_DTAP_MT dtap_mt;
779
780 /* tell GSUP dispatcher to send this IMSI to us */
781 f_create_gsup_expect(hex2str(g_pars.imsi));
782
783 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
784 f_bssap_compl_l3(l3_lu);
785
786 /* Send Early Classmark, just for the fun of it */
787 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
788 /* wait for LU reject, ignore any ID REQ */
789 alt {
790 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
791 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req)) { repeat; }
792 }
793 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100794 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100795}
796testcase TC_lu_by_imei() runs on MTC_CT {
797 var BSC_ConnHdlr vc_conn;
798 f_init();
799
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100800 vc_conn := f_start_handler(refers(f_tc_lu_by_imei), 12);
Harald Welteba7b6d92018-01-23 21:32:34 +0100801 vc_conn.done;
802}
803
804/* Test LU by TMSI with unknown TMSI, expect (and answer) ID REQ. */
805private function f_tc_lu_tmsi_noauth_unknown(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100806 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100807
808 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('01020304'O); /* FIXME: Random */
809 var PDU_DTAP_MT dtap_mt;
810
811 /* tell GSUP dispatcher to send this IMSI to us */
812 f_create_gsup_expect(hex2str(g_pars.imsi));
813
814 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
815 f_bssap_compl_l3(l3_lu);
816
817 /* Send Early Classmark, just for the fun of it */
818 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
819
820 /* Wait for + respond to ID REQ (IMSI) */
821 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req('001'B)));
822 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
823
824 /* Expect MSC to do UpdateLocation to HLR; respond to it */
825 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
826 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
827 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
828 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
829
830 alt {
Harald Welte7ec4fa82018-01-27 10:57:40 +0100831 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
832 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
833 }
Harald Welteba7b6d92018-01-23 21:32:34 +0100834 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
835 setverdict(fail, "Expected LU ACK, but received REJ");
836 }
837 }
838
839 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100840 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100841}
842testcase TC_lu_by_tmsi_noauth_unknown() runs on MTC_CT {
843 var BSC_ConnHdlr vc_conn;
844 f_init();
845
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100846 vc_conn := f_start_handler(refers(f_tc_lu_tmsi_noauth_unknown), 13);
Harald Welteba7b6d92018-01-23 21:32:34 +0100847 vc_conn.done;
848}
849
850
Harald Welte45164da2018-01-24 12:51:27 +0100851/* Test IMSI DETACH (MI=IMSI) */
852private function f_tc_imsi_detach_by_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100853 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100854
855 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
856
857 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
858 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
859
860 /* Send Early Classmark, just for the fun of it? */
861 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
862
863 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100864 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100865}
866testcase TC_imsi_detach_by_imsi() runs on MTC_CT {
867 var BSC_ConnHdlr vc_conn;
868 f_init();
869
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100870 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imsi), 14);
Harald Welte45164da2018-01-24 12:51:27 +0100871 vc_conn.done;
872}
873
874/* Test IMSI DETACH (MI=TMSI) */
875private function f_tc_imsi_detach_by_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100876 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100877
878 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('01020304'O));
879
880 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
881 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
882
883 /* Send Early Classmark, just for the fun of it? */
884 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
885
886 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100887 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100888}
889testcase TC_imsi_detach_by_tmsi() runs on MTC_CT {
890 var BSC_ConnHdlr vc_conn;
891 f_init();
892
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100893 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_tmsi), 15);
Harald Welte45164da2018-01-24 12:51:27 +0100894 vc_conn.done;
895}
896
897/* Test IMSI DETACH (MI=IMEI), which is illegal */
898private function f_tc_imsi_detach_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100899 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100900
Harald Welte256571e2018-01-24 18:47:19 +0100901 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte45164da2018-01-24 12:51:27 +0100902
903 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
904 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
905
906 /* Send Early Classmark, just for the fun of it? */
907 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
908
909 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100910 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100911}
912testcase TC_imsi_detach_by_imei() runs on MTC_CT {
913 var BSC_ConnHdlr vc_conn;
914 f_init();
915
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100916 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imei), 16);
Harald Welte45164da2018-01-24 12:51:27 +0100917 vc_conn.done;
918}
919
920
921/* helper function for an emergency call. caller passes in mobile identity to use */
922private function f_emerg_call(MobileIdentityLV mi) runs on BSC_ConnHdlr {
Harald Welte0bef21e2018-02-10 09:48:23 +0100923 var CallParameters cpars := valueof(t_CallParams('112'H, 0));
924 cpars.emergency := true;
Philipp Maierf1e02bb2018-03-15 16:30:00 +0100925 cpars.mgcp_ep := "rtpbridge/1@mgw";
Harald Welte45164da2018-01-24 12:51:27 +0100926
Harald Welte0bef21e2018-02-10 09:48:23 +0100927 f_mo_call(cpars);
Harald Welte45164da2018-01-24 12:51:27 +0100928}
929
930/* establish an emergency call by IMEI, no SIM inserted (and hence no IMSI) */
931private function f_tc_emerg_call_imei_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100932 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100933
Harald Welte256571e2018-01-24 18:47:19 +0100934 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100935 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100936 f_bssap_compl_l3(l3_info);
937 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ('05'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +0100938 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100939}
940testcase TC_emerg_call_imei_reject() runs on MTC_CT {
941 var BSC_ConnHdlr vc_conn;
942 f_init();
943
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100944 vc_conn := f_start_handler(refers(f_tc_emerg_call_imei_reject), 17);
Harald Welte45164da2018-01-24 12:51:27 +0100945 vc_conn.done;
946}
947
Harald Welted5b91402018-01-24 18:48:16 +0100948/* establish an emergency call by IMSI, SIM inserted (and hence IMSI) */
Harald Welte45164da2018-01-24 12:51:27 +0100949private function f_tc_emerg_call_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100950 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100951 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100952 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +0100953 /* Then issue emergency call identified by IMSI */
954 f_emerg_call(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
955}
956testcase TC_emerg_call_imsi() runs on MTC_CT {
957 var BSC_ConnHdlr vc_conn;
958 f_init();
959
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100960 vc_conn := f_start_handler(refers(f_tc_emerg_call_imsi), 18);
Harald Welte45164da2018-01-24 12:51:27 +0100961 vc_conn.done;
962}
963
964/* CM Service Request for VGCS -> reject */
965private function f_tc_cm_serv_req_vgcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100966 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100967
968 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100969 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +0100970
971 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100972 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VGCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100973 f_bssap_compl_l3(l3_info);
974 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100975 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100976}
977testcase TC_cm_serv_req_vgcs_reject() runs on MTC_CT {
978 var BSC_ConnHdlr vc_conn;
979 f_init();
980
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100981 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vgcs_reject), 19);
Harald Welte45164da2018-01-24 12:51:27 +0100982 vc_conn.done;
983}
984
985/* CM Service Request for VBS -> reject */
986private function f_tc_cm_serv_req_vbs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100987 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100988
989 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100990 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +0100991
992 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100993 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VBS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100994 f_bssap_compl_l3(l3_info);
995 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100996 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100997}
998testcase TC_cm_serv_req_vbs_reject() runs on MTC_CT {
999 var BSC_ConnHdlr vc_conn;
1000 f_init();
1001
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001002 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vbs_reject), 20);
Harald Welte45164da2018-01-24 12:51:27 +01001003 vc_conn.done;
1004}
1005
1006/* CM Service Request for LCS -> reject */
1007private function f_tc_cm_serv_req_lcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001008 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +01001009
1010 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001011 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +01001012
1013 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001014 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_LCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +01001015 f_bssap_compl_l3(l3_info);
1016 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001017 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +01001018}
1019testcase TC_cm_serv_req_lcs_reject() runs on MTC_CT {
1020 var BSC_ConnHdlr vc_conn;
1021 f_init();
1022
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001023 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_lcs_reject), 21);
Harald Welte45164da2018-01-24 12:51:27 +01001024 vc_conn.done;
1025}
1026
Harald Welte0195ab12018-01-24 21:50:20 +01001027/* CM Re-Establishment Request */
1028private function f_tc_cm_reest_req_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001029 f_init_handler(pars);
Harald Welte0195ab12018-01-24 21:50:20 +01001030
1031 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001032 f_perform_lu();
Harald Welte0195ab12018-01-24 21:50:20 +01001033
1034 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1035 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REEST_REQ(0, mi));
1036 f_bssap_compl_l3(l3_info);
1037 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001038 f_expect_clear();
Harald Welte0195ab12018-01-24 21:50:20 +01001039}
1040testcase TC_cm_reest_req_reject() runs on MTC_CT {
1041 var BSC_ConnHdlr vc_conn;
1042 f_init();
Harald Welte0195ab12018-01-24 21:50:20 +01001043
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001044 vc_conn := f_start_handler(refers(f_tc_cm_reest_req_reject), 22);
Harald Welte0195ab12018-01-24 21:50:20 +01001045 vc_conn.done;
1046}
1047
Harald Weltec638f4d2018-01-24 22:00:36 +01001048/* Test LU (with authentication enabled), with wrong response from MS */
1049private function f_tc_lu_auth_2G_fail(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001050 f_init_handler(pars);
Harald Weltec638f4d2018-01-24 22:00:36 +01001051
1052 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
1053
1054 /* tell GSUP dispatcher to send this IMSI to us */
1055 f_create_gsup_expect(hex2str(g_pars.imsi));
1056
1057 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
1058 f_bssap_compl_l3(l3_lu);
1059
1060 /* Send Early Classmark, just for the fun of it */
1061 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1062
1063 var AuthVector vec := f_gen_auth_vec_2g();
1064 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(vec.rand, vec.sres, vec.kc));
1065 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
1066 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
1067
1068 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(vec.rand)));
1069 /* Send back wrong auth response */
1070 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G('00000000'O)));
1071
1072 /* Expect GSUP AUTH FAIL REP to HLR */
1073 GSUP.receive(tr_GSUP_AUTH_FAIL_IND(g_pars.imsi));
1074
1075 /* Expect LU REJECT with Cause == Illegal MS */
1076 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej('03'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +01001077 f_expect_clear();
Harald Weltec638f4d2018-01-24 22:00:36 +01001078}
1079testcase TC_lu_auth_2G_fail() runs on MTC_CT {
1080 var BSC_ConnHdlr vc_conn;
1081 f_init();
1082 f_vty_config(MSCVTY, "network", "authentication required");
Harald Weltec638f4d2018-01-24 22:00:36 +01001083
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001084 vc_conn := f_start_handler(refers(f_tc_lu_auth_2G_fail), 23);
Harald Weltec638f4d2018-01-24 22:00:36 +01001085 vc_conn.done;
1086}
1087
Harald Weltede371492018-01-27 23:44:41 +01001088/* A5/1 + A5/3 permitted on network side, and MS capable to do it */
Harald Welte16114282018-01-24 22:41:21 +01001089private 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 +01001090 pars.net.expect_auth := true;
1091 pars.net.expect_ciph := true;
Harald Weltea10db902018-01-27 12:44:49 +01001092 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001093 f_perform_lu();
Harald Welte16114282018-01-24 22:41:21 +01001094}
1095testcase TC_lu_imsi_auth_tmsi_encr_13_13() runs on MTC_CT {
1096 var BSC_ConnHdlr vc_conn;
1097 f_init();
1098 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte16114282018-01-24 22:41:21 +01001099 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1100
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001101 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_13), 24);
Harald Welte16114282018-01-24 22:41:21 +01001102 vc_conn.done;
1103}
1104
Harald Welte1af6ea82018-01-25 18:33:15 +01001105/* Test Complete L3 without payload */
1106private function f_tc_cl3_no_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001107 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001108
1109 /* Send Complete L3 Info with empty L3 frame */
1110 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1111 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, ''O))));
1112
Harald Weltef466eb42018-01-27 14:26:54 +01001113 timer T := 5.0;
1114 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001115 alt {
1116 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
1117 /* Expect LU REJECT with Cause == Illegal MS */
Harald Weltebdb3c452018-03-18 22:43:06 +01001118 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
1119 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001120 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001121 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001122 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Harald Weltef466eb42018-01-27 14:26:54 +01001123 self.stop;
1124 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001125 }
1126 setverdict(pass);
1127}
1128testcase TC_cl3_no_payload() runs on MTC_CT {
1129 var BSC_ConnHdlr vc_conn;
1130 f_init();
1131
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001132 vc_conn := f_start_handler(refers(f_tc_cl3_no_payload), 25);
Harald Welte1af6ea82018-01-25 18:33:15 +01001133 vc_conn.done;
1134}
1135
1136/* Test Complete L3 with random payload */
1137private function f_tc_cl3_rnd_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001138 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001139
1140 var integer len := float2int(rnd() * 256.0);
1141 var octetstring payl := f_rnd_octstring(len);
1142
1143 /* Send Complete L3 Info with empty L3 frame */
1144 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1145 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, payl))));
1146
Harald Weltef466eb42018-01-27 14:26:54 +01001147 timer T := 5.0;
1148 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001149 alt {
1150 /* Immediate disconnect */
1151 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte1af6ea82018-01-25 18:33:15 +01001152 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
Harald Weltebdb3c452018-03-18 22:43:06 +01001153 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001154 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001155 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001156 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Harald Weltef466eb42018-01-27 14:26:54 +01001157 self.stop;
1158 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001159 }
1160 setverdict(pass);
1161}
1162testcase TC_cl3_rnd_payload() runs on MTC_CT {
1163 var BSC_ConnHdlr vc_conn;
1164 f_init();
1165
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001166 vc_conn := f_start_handler(refers(f_tc_cl3_rnd_payload), 26);
Harald Welte1af6ea82018-01-25 18:33:15 +01001167 vc_conn.done;
1168}
1169
Harald Welte116e4332018-01-26 22:17:48 +01001170/* Test Complete L3 with random payload */
1171private function f_tc_establish_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001172 f_init_handler(pars);
Harald Welte116e4332018-01-26 22:17:48 +01001173
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001174 f_perform_lu();
Harald Welte116e4332018-01-26 22:17:48 +01001175
Harald Welteb9e86fa2018-04-09 18:18:31 +02001176 f_establish_fully();
Daniel Willmann898a7e02018-05-17 12:16:16 +02001177 f_expect_clear(10.0);
Harald Welte116e4332018-01-26 22:17:48 +01001178}
1179testcase TC_establish_and_nothing() runs on MTC_CT {
1180 var BSC_ConnHdlr vc_conn;
1181 f_init();
1182
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001183 vc_conn := f_start_handler(refers(f_tc_establish_and_nothing), 27);
Harald Welte116e4332018-01-26 22:17:48 +01001184 vc_conn.done;
1185}
1186
Harald Welte12510c52018-01-26 22:26:24 +01001187/* Test MO Call SETUP with no response from MNCC */
1188private function f_tc_mo_setup_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001189 f_init_handler(pars);
1190
Harald Welte12510c52018-01-26 22:26:24 +01001191 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1192
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001193 f_perform_lu();
Harald Welte12510c52018-01-26 22:26:24 +01001194
Harald Welteb9e86fa2018-04-09 18:18:31 +02001195 f_establish_fully();
Harald Welte12510c52018-01-26 22:26:24 +01001196 f_create_mncc_expect(hex2str(cpars.called_party));
1197 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1198
1199 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1200
Harald Welte1ddc7162018-01-27 14:25:46 +01001201 f_expect_clear(30.0);
Harald Welte12510c52018-01-26 22:26:24 +01001202}
1203testcase TC_mo_setup_and_nothing() runs on MTC_CT {
1204 var BSC_ConnHdlr vc_conn;
1205 f_init();
1206
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001207 vc_conn := f_start_handler(refers(f_tc_mo_setup_and_nothing), 28);
Harald Welte12510c52018-01-26 22:26:24 +01001208 vc_conn.done;
1209}
1210
Harald Welte3ab88002018-01-26 22:37:25 +01001211/* Test MO Call with no response to RAN-side CRCX */
1212private function f_tc_mo_crcx_ran_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001213 f_init_handler(pars);
Harald Welte3ab88002018-01-26 22:37:25 +01001214 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1215 var MNCC_PDU mncc;
1216 var MgcpCommand mgcp_cmd;
1217
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001218 f_perform_lu();
Harald Welte3ab88002018-01-26 22:37:25 +01001219
Harald Welteb9e86fa2018-04-09 18:18:31 +02001220 f_establish_fully();
Harald Welte3ab88002018-01-26 22:37:25 +01001221 f_create_mncc_expect(hex2str(cpars.called_party));
1222 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1223
1224 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1225 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1226 cpars.mncc_callref := mncc.u.signal.callref;
1227 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1228 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1229
1230 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
Harald Welte1852a842018-01-26 22:53:36 +01001231 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1232 cpars.mgcp_ep := mgcp_cmd.line.ep;
Harald Welte3ab88002018-01-26 22:37:25 +01001233 /* never respond to this */
1234
Philipp Maier8e58f592018-03-14 11:10:56 +01001235 /* When the connection with the MGW fails, the MSC will first request
1236 * a release via call control. We will answer this request normally. */
1237 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1238 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1239
Harald Welte1ddc7162018-01-27 14:25:46 +01001240 f_expect_clear(30.0);
Harald Welte3ab88002018-01-26 22:37:25 +01001241}
1242testcase TC_mo_crcx_ran_timeout() runs on MTC_CT {
1243 var BSC_ConnHdlr vc_conn;
1244 f_init();
1245
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001246 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_timeout), 29);
Harald Welte3ab88002018-01-26 22:37:25 +01001247 vc_conn.done;
1248}
1249
Harald Welte0cc82d92018-01-26 22:52:34 +01001250/* Test MO Call with reject to RAN-side CRCX */
1251private function f_tc_mo_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001252 f_init_handler(pars);
Harald Welte0cc82d92018-01-26 22:52:34 +01001253 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1254 var MNCC_PDU mncc;
1255 var MgcpCommand mgcp_cmd;
1256
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001257 f_perform_lu();
Harald Welte0cc82d92018-01-26 22:52:34 +01001258
Harald Welteb9e86fa2018-04-09 18:18:31 +02001259 f_establish_fully();
Harald Welte0cc82d92018-01-26 22:52:34 +01001260 f_create_mncc_expect(hex2str(cpars.called_party));
1261 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1262
1263 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1264 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1265 cpars.mncc_callref := mncc.u.signal.callref;
1266 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1267 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1268
1269 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001270
1271 /* Detect if the received CRCX is a wildcarded CRCX request. If yes,
1272 * set an endpoint name that fits the pattern. If not, just use the
1273 * endpoint name from the request */
1274 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
1275 cpars.mgcp_ep := "rtpbridge/1@mgw";
1276 } else {
1277 cpars.mgcp_ep := mgcp_cmd.line.ep;
1278 }
1279
Harald Welte0cc82d92018-01-26 22:52:34 +01001280 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001281
Harald Welte0cc82d92018-01-26 22:52:34 +01001282 /* Respond to CRCX with error */
1283 var MgcpResponse mgcp_rsp := {
1284 line := {
1285 code := "542",
1286 trans_id := mgcp_cmd.line.trans_id,
1287 string := "FORCED_FAIL"
1288 },
Harald Welte0cc82d92018-01-26 22:52:34 +01001289 sdp := omit
1290 }
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001291 var MgcpParameter mgcp_rsp_param := {
1292 code := "Z",
1293 val := cpars.mgcp_ep
1294 };
1295 mgcp_rsp.params[0] := mgcp_rsp_param;
Harald Welte0cc82d92018-01-26 22:52:34 +01001296 MGCP.send(mgcp_rsp);
1297
1298 timer T := 30.0;
1299 T.start;
1300 alt {
1301 [] T.timeout { setverdict(fail, "Timeout waiting for channel release"); self.stop; }
Daniel Willmann5868e622018-02-15 17:42:59 +01001302 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id))) {
1303 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1304 repeat;
1305 }
Harald Welte0cc82d92018-01-26 22:52:34 +01001306 [] MNCC.receive { repeat; }
1307 [] GSUP.receive { repeat; }
Philipp Maierc6e06f72018-04-11 18:12:23 +02001308 /* Note: As we did not respond properly to the CRCX from the MSC we
1309 * expect the MSC to omit any further MGCP operation (At least in the
1310 * the current implementation, there is no recovery mechanism implemented
1311 * and a DLCX can not be performed as the MSC does not know a specific
1312 * endpoint yet. */
1313 [] MGCP.receive { setverdict(fail, "Unexpected MGCP message"); self.stop; }
Harald Welte5946b332018-03-18 23:32:21 +01001314 [] as_clear_cmd_compl_disc();
Harald Welte0cc82d92018-01-26 22:52:34 +01001315 }
1316}
1317testcase TC_mo_crcx_ran_reject() runs on MTC_CT {
1318 var BSC_ConnHdlr vc_conn;
1319 f_init();
1320
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001321 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_reject), 30);
Harald Welte0cc82d92018-01-26 22:52:34 +01001322 vc_conn.done;
1323}
1324
Harald Welte3ab88002018-01-26 22:37:25 +01001325
Harald Welte812f7a42018-01-27 00:49:18 +01001326/* helper function to start a MT call: MNCC SETUP; Paging; DChan est.; DTAP SETUP */
1327private function f_mt_call_start(inout CallParameters cpars) runs on BSC_ConnHdlr {
1328 var MNCC_PDU mncc;
1329 var MgcpCommand mgcp_cmd;
1330 var OCT4 tmsi;
1331
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001332 f_perform_lu();
Harald Welte812f7a42018-01-27 00:49:18 +01001333 if (isvalue(g_pars.tmsi)) {
1334 tmsi := g_pars.tmsi;
1335 } else {
1336 tmsi := 'FFFFFFFF'O;
1337 }
1338 f_bssmap_register_imsi(g_pars.imsi, tmsi);
1339
1340 /* Allocate call reference and send SETUP via MNCC to MSC */
1341 cpars.mncc_callref := f_rnd_int(2147483648);
1342 MNCC.send(ts_MNCC_SETUP_req(cpars.mncc_callref, hex2str(g_pars.msisdn),
1343 hex2str(cpars.called_party), hex2str(g_pars.imsi)));
1344
1345 /* MSC->BSC: expect PAGING from MSC */
1346 BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));
1347 /* MS -> MSC: PAGING RESPONSE */
Harald Welteb9e86fa2018-04-09 18:18:31 +02001348 f_establish_fully(EST_TYPE_PAG_RESP);
Harald Welte812f7a42018-01-27 00:49:18 +01001349
1350 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1351
1352 /* MSC->MS: SETUP */
1353 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party)));
1354}
1355
1356/* Test MT Call */
1357private function f_tc_mt_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001358 f_init_handler(pars);
Harald Welte812f7a42018-01-27 00:49:18 +01001359 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1360 var MNCC_PDU mncc;
1361 var MgcpCommand mgcp_cmd;
1362
1363 f_mt_call_start(cpars);
1364
1365 /* MS->MSC: CALL CONFIRMED */
1366 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1367
1368 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1369
1370 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1371 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001372
1373 /* Detect if the received CRCX is a wildcarded CRCX request. If yes,
1374 * set an endpoint name that fits the pattern. If not, just use the
1375 * endpoint name from the request */
1376 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
1377 cpars.mgcp_ep := "rtpbridge/1@mgw";
1378 } else {
1379 cpars.mgcp_ep := mgcp_cmd.line.ep;
1380 }
1381
Harald Welte812f7a42018-01-27 00:49:18 +01001382 /* Respond to CRCX with error */
1383 var MgcpResponse mgcp_rsp := {
1384 line := {
1385 code := "542",
1386 trans_id := mgcp_cmd.line.trans_id,
1387 string := "FORCED_FAIL"
1388 },
Harald Welte812f7a42018-01-27 00:49:18 +01001389 sdp := omit
1390 }
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001391 var MgcpParameter mgcp_rsp_param := {
1392 code := "Z",
1393 val := cpars.mgcp_ep
1394 };
1395 mgcp_rsp.params[0] := mgcp_rsp_param;
Harald Welte812f7a42018-01-27 00:49:18 +01001396 MGCP.send(mgcp_rsp);
1397
1398 timer T := 30.0;
1399 T.start;
1400 alt {
1401 [] T.timeout { setverdict(fail, "Timeout waiting for channel release"); self.stop; }
Harald Welte812f7a42018-01-27 00:49:18 +01001402 [] BSSAP.receive { repeat; }
1403 [] MNCC.receive { repeat; }
1404 [] GSUP.receive { repeat; }
1405 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1406 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1407 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1408 repeat;
1409 }
1410 [] MGCP.receive { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001411 [] as_clear_cmd_compl_disc();
Harald Welte812f7a42018-01-27 00:49:18 +01001412 }
1413}
1414testcase TC_mt_crcx_ran_reject() runs on MTC_CT {
1415 var BSC_ConnHdlr vc_conn;
1416 f_init();
1417
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001418 vc_conn := f_start_handler(refers(f_tc_mt_crcx_ran_reject), 31);
Harald Welte812f7a42018-01-27 00:49:18 +01001419 vc_conn.done;
1420}
1421
1422
1423/* Test MT Call T310 timer */
1424private function f_tc_mt_t310(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltead2952e2018-01-27 14:12:46 +01001425 f_init_handler(pars, 200.0);
Harald Welte812f7a42018-01-27 00:49:18 +01001426 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1427 var MNCC_PDU mncc;
1428 var MgcpCommand mgcp_cmd;
1429
1430 f_mt_call_start(cpars);
1431
1432 /* MS->MSC: CALL CONFIRMED */
1433 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1434 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1435
1436 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1437 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1438 cpars.mgcp_ep := mgcp_cmd.line.ep;
1439 /* FIXME: Respond to CRCX */
1440
1441 /* old libosmocore T310 default timeout is 180s. so let's wait 190 */
1442 timer T := 190.0;
1443 T.start;
1444 alt {
1445 [] T.timeout { setverdict(fail, "Timeout waiting for T310"); self.stop; }
1446 [] MNCC.receive(tr_MNCC_DISC_ind(cpars.mncc_callref)) {
1447 MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(23))));
1448 }
1449 }
1450 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));
1451 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1452 /* FIXME: We're sending this with TIflag 0: allocated by sender, which is wrong */
1453 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1454
1455 alt {
Harald Welte812f7a42018-01-27 00:49:18 +01001456 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1457 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1458 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1459 repeat;
1460 }
Harald Welte5946b332018-03-18 23:32:21 +01001461 [] as_clear_cmd_compl_disc();
Harald Welte812f7a42018-01-27 00:49:18 +01001462 }
1463}
1464testcase TC_mt_t310() runs on MTC_CT {
1465 var BSC_ConnHdlr vc_conn;
1466 f_init();
1467
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001468 vc_conn := f_start_handler(refers(f_tc_mt_t310), 32);
Harald Welte812f7a42018-01-27 00:49:18 +01001469 vc_conn.done;
1470}
1471
Harald Welte167458a2018-01-27 15:58:16 +01001472/* Perform successful LU + MO call, then GSUP LocationCancel. Subscriber must be denied CM SERV */
1473private function f_tc_gsup_cancel(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1474 f_init_handler(pars);
1475 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1476 cpars.bss_rtp_port := 1110;
1477 cpars.mgcp_connection_id_bss := '22222'H;
1478 cpars.mgcp_connection_id_mss := '33333'H;
1479
1480 /* Location Update to make subscriber known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001481 f_perform_lu();
Harald Welte167458a2018-01-27 15:58:16 +01001482
1483 /* First MO call should succeed */
1484 f_mo_call(cpars);
1485
1486 /* Cancel the subscriber in the VLR */
1487 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1488 alt {
1489 [] GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi)) { }
1490 [] GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi)) {
1491 setverdict(fail, "Received GSUP Location Cancel Error");
1492 self.stop;
1493 }
1494 }
1495
1496 /* Follow-up transactions should fail */
1497 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1498 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
1499 f_bssap_compl_l3(l3_info);
1500 alt {
1501 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
1502 [] BSSAP.receive {
1503 setverdict(fail, "Received unexpected BSSAP instead of CM SERV REJ");
1504 self.stop;
1505 }
1506 }
1507 setverdict(pass);
1508}
1509testcase TC_gsup_cancel() runs on MTC_CT {
1510 var BSC_ConnHdlr vc_conn;
1511 f_init();
1512
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001513 vc_conn := f_start_handler(refers(f_tc_gsup_cancel), 33);
Harald Welte167458a2018-01-27 15:58:16 +01001514 vc_conn.done;
1515}
1516
Harald Welte9de84792018-01-28 01:06:35 +01001517/* A5/1 only permitted on network side, and MS capable to do it */
1518private function f_tc_lu_imsi_auth_tmsi_encr_1_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1519 pars.net.expect_auth := true;
1520 pars.net.expect_ciph := true;
1521 pars.net.kc_support := '02'O; /* A5/1 only */
1522 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001523 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001524}
1525testcase TC_lu_imsi_auth_tmsi_encr_1_13() runs on MTC_CT {
1526 var BSC_ConnHdlr vc_conn;
1527 f_init();
1528 f_vty_config(MSCVTY, "network", "authentication required");
1529 f_vty_config(MSCVTY, "network", "encryption a5 1");
1530
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001531 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_1_13), 34);
Harald Welte9de84792018-01-28 01:06:35 +01001532 vc_conn.done;
1533}
1534
1535/* A5/3 only permitted on network side, and MS capable to do it */
1536private function f_tc_lu_imsi_auth_tmsi_encr_3_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1537 pars.net.expect_auth := true;
1538 pars.net.expect_ciph := true;
1539 pars.net.kc_support := '08'O; /* A5/3 only */
1540 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001541 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001542}
1543testcase TC_lu_imsi_auth_tmsi_encr_3_13() runs on MTC_CT {
1544 var BSC_ConnHdlr vc_conn;
1545 f_init();
1546 f_vty_config(MSCVTY, "network", "authentication required");
1547 f_vty_config(MSCVTY, "network", "encryption a5 3");
1548
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001549 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_13), 35);
Harald Welte9de84792018-01-28 01:06:35 +01001550 vc_conn.done;
1551}
1552
1553/* A5/3 only permitted on network side, and MS with only A5/1 support */
1554private function f_tc_lu_imsi_auth_tmsi_encr_3_1(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1555 pars.net.expect_auth := true;
1556 pars.net.expect_ciph := true;
1557 pars.net.kc_support := '08'O; /* A5/3 only */
1558 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1559 f_init_handler(pars, 15.0);
1560
1561 /* cannot use f_perform_lu() as we expect a reject */
1562 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1563 f_create_gsup_expect(hex2str(g_pars.imsi));
1564 f_bssap_compl_l3(l3_lu);
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001565 if (pars.send_early_cm) {
1566 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1567 } else {
1568 pars.cm1.esind := '0'B;
1569 }
Harald Welte9de84792018-01-28 01:06:35 +01001570 f_mm_auth();
1571 alt {
Harald Welte5946b332018-03-18 23:32:21 +01001572 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1573 f_expect_clear();
1574 }
Harald Welte9de84792018-01-28 01:06:35 +01001575 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1576 setverdict(fail, "CipherModeCommand despite no A5 intersection");
1577 self.stop;
1578 }
1579 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001580 setverdict(fail, "Unknown/unexpected BSSAP received");
Harald Welte9de84792018-01-28 01:06:35 +01001581 self.stop;
1582 }
1583 }
1584 setverdict(pass);
1585}
1586testcase TC_lu_imsi_auth_tmsi_encr_3_1() runs on MTC_CT {
1587 var BSC_ConnHdlr vc_conn;
1588 f_init();
1589 f_vty_config(MSCVTY, "network", "authentication required");
1590 f_vty_config(MSCVTY, "network", "encryption a5 3");
1591
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001592 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 360);
1593 vc_conn.done;
1594}
1595testcase TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() runs on MTC_CT {
1596 var BSC_ConnHdlrPars pars;
1597 var BSC_ConnHdlr vc_conn;
1598 f_init();
1599 f_vty_config(MSCVTY, "network", "authentication required");
1600 f_vty_config(MSCVTY, "network", "encryption a5 3");
1601
1602 pars := f_init_pars(361);
1603 pars.send_early_cm := false;
1604 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 +01001605 vc_conn.done;
1606}
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01001607testcase TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() runs on MTC_CT {
1608 var BSC_ConnHdlr vc_conn;
1609 f_init();
1610 f_vty_config(MSCVTY, "network", "authentication required");
1611 f_vty_config(MSCVTY, "network", "encryption a5 3");
1612
1613 /* Make sure the MSC category is on DEBUG level to trigger the log
1614 * message that is reported in OS#2947 to trigger the segfault */
1615 f_vty_config(MSCVTY, "log stderr", "logging level msc debug");
1616
1617 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 362);
1618 vc_conn.done;
1619}
Harald Welte9de84792018-01-28 01:06:35 +01001620
1621/* A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
1622private function f_tc_lu_imsi_auth_tmsi_encr_13_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1623 pars.net.expect_auth := true;
1624 pars.net.expect_ciph := true;
1625 pars.net.kc_support := '0A'O; /* A5/1 + A5/3 */
1626 pars.cm1.a5_1 := '1'B;
1627 pars.cm2.a5_1 := '1'B;
1628 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1629 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
1630 f_init_handler(pars, 15.0);
1631
1632 /* cannot use f_perform_lu() as we expect a reject */
1633 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1634 f_create_gsup_expect(hex2str(g_pars.imsi));
1635 f_bssap_compl_l3(l3_lu);
1636 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1637 f_mm_auth();
1638 alt {
Harald Welte5946b332018-03-18 23:32:21 +01001639 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1640 f_expect_clear();
1641 }
Harald Welte9de84792018-01-28 01:06:35 +01001642 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1643 setverdict(fail, "CipherModeCommand despite no A5 intersection");
1644 self.stop;
1645 }
1646 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001647 setverdict(fail, "Unknown/unexpected BSSAP received");
Harald Welte9de84792018-01-28 01:06:35 +01001648 self.stop;
1649 }
1650 }
1651 setverdict(pass);
1652}
1653testcase TC_lu_imsi_auth_tmsi_encr_13_2() 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 1 3");
1658
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001659 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_2), 37);
Harald Welte9de84792018-01-28 01:06:35 +01001660 vc_conn.done;
1661}
1662
1663/* A5/0 + A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
1664private function f_tc_lu_imsi_auth_tmsi_encr_013_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1665 pars.net.expect_auth := true;
1666 pars.net.expect_ciph := true;
1667 pars.net.kc_support := '0B'O; /* A5/1 + A5/3 */
1668 pars.cm1.a5_1 := '1'B;
1669 pars.cm2.a5_1 := '1'B;
1670 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1671 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
1672 f_init_handler(pars, 15.0);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001673 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001674}
1675testcase TC_lu_imsi_auth_tmsi_encr_013_2() runs on MTC_CT {
1676 var BSC_ConnHdlr vc_conn;
1677 f_init();
1678 f_vty_config(MSCVTY, "network", "authentication required");
1679 f_vty_config(MSCVTY, "network", "encryption a5 0 1 3");
1680
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001681 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_013_2), 38);
Harald Welte9de84792018-01-28 01:06:35 +01001682 vc_conn.done;
1683}
1684
Harald Welte33ec09b2018-02-10 15:34:46 +01001685/* LU followed by MT call (including paging) */
1686private function f_tc_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1687 f_init_handler(pars);
1688 //FIXME: odd digits var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1689 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1690 cpars.bss_rtp_port := 1110;
1691 cpars.mgcp_connection_id_bss := '10004'H;
1692 cpars.mgcp_connection_id_mss := '10005'H;
1693
Philipp Maier4b2692d2018-03-14 16:37:48 +01001694 /* Note: This is an optional parameter. When the call-agent (MSC) does
1695 * supply a full endpoint name this setting will be overwritten. */
1696 cpars.mgcp_ep := "rtpbridge/1@mgw";
1697
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001698 f_perform_lu();
Harald Welte33ec09b2018-02-10 15:34:46 +01001699 f_mt_call(cpars);
1700}
1701testcase TC_lu_and_mt_call() runs on MTC_CT {
1702 var BSC_ConnHdlr vc_conn;
1703 f_init();
1704
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001705 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call), 39);
Harald Welte33ec09b2018-02-10 15:34:46 +01001706 vc_conn.done;
1707}
1708
Daniel Willmann8b084372018-02-04 13:35:26 +01001709/* Test MO Call SETUP with DTMF */
1710private function f_tc_mo_setup_dtmf_dup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1711 f_init_handler(pars);
1712 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1713 cpars.bss_rtp_port := 1110;
1714 cpars.mgcp_connection_id_bss := '22222'H;
1715 cpars.mgcp_connection_id_mss := '33333'H;
1716
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001717 f_perform_lu();
Daniel Willmann8b084372018-02-04 13:35:26 +01001718 f_mo_seq_dtmf_dup(cpars);
1719}
1720testcase TC_mo_setup_and_dtmf_dup() runs on MTC_CT {
1721 var BSC_ConnHdlr vc_conn;
1722 f_init();
1723
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001724 vc_conn := f_start_handler(refers(f_tc_mo_setup_dtmf_dup), 39);
Daniel Willmann8b084372018-02-04 13:35:26 +01001725 vc_conn.done;
1726}
Harald Welte9de84792018-01-28 01:06:35 +01001727
Philipp Maier328d1662018-03-07 10:40:27 +01001728testcase TC_cr_before_reset() runs on MTC_CT {
1729 timer T := 4.0;
1730 var boolean reset_ack_seen := false;
1731 f_init_bssap_direct();
1732
1733 /* Make a blind connection attemt, to trigger the deadlock condition */
Philipp Maier75932982018-03-27 14:52:35 +02001734 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 +01001735
1736 /* Send a BSSMAP reset */
Philipp Maier75932982018-03-27 14:52:35 +02001737 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 +01001738 T.start
1739 alt {
1740 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_ResetAck)) {
1741 reset_ack_seen := true;
1742 repeat;
1743 }
1744
1745 /* Acknowledge MSC sided reset requests */
1746 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) {
Philipp Maier75932982018-03-27 14:52:35 +02001747 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 +01001748 repeat;
1749 }
1750
1751 /* Ignore all other messages (e.g CR from the connection request) */
1752 [] BSSAP_DIRECT.receive { repeat }
1753
1754 /* If we got no BSSMAP RESET ACK back, then the MSC entered the
1755 * deadlock situation. The MSC is then unable to respond to any
1756 * further BSSMAP RESET or any other sort of traffic. */
1757 [reset_ack_seen == true] T.timeout { setverdict(pass) }
1758 [reset_ack_seen == false] T.timeout {
1759 setverdict(fail, "no BSSMAP RESET ACK seen!");
1760 }
1761 }
1762}
Harald Welte9de84792018-01-28 01:06:35 +01001763
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001764/* Test MO Call with no response to RAN-side CRCX or DTAP Release */
1765private function f_tc_mo_release_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1766 f_init_handler(pars);
1767 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1768 var MNCC_PDU mncc;
1769 var MgcpCommand mgcp_cmd;
1770
1771 f_perform_lu();
1772
Harald Welteb9e86fa2018-04-09 18:18:31 +02001773 f_establish_fully();
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001774 f_create_mncc_expect(hex2str(cpars.called_party));
1775 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1776
1777 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1778 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1779 cpars.mncc_callref := mncc.u.signal.callref;
1780 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1781 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1782
1783 /* Drop CRCX */
1784 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1785
1786 /* Drop DTAP Release */
1787 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1788
1789 /* Drop resent DTAP Release */
1790 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1791
1792 f_expect_clear(60.0);
1793}
1794testcase TC_mo_release_timeout() runs on MTC_CT {
1795 var BSC_ConnHdlr vc_conn;
1796 f_init();
1797
1798 vc_conn := f_start_handler(refers(f_tc_mo_release_timeout), 40);
1799 vc_conn.done;
1800}
1801
Harald Welte12510c52018-01-26 22:26:24 +01001802
Philipp Maier2a98a732018-03-19 16:06:12 +01001803/* LU followed by MT call (including paging) */
1804private function f_tc_lu_and_mt_call_no_dlcx_resp(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1805 f_init_handler(pars);
1806 //FIXME: odd digits var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1807 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1808 cpars.bss_rtp_port := 1110;
1809 cpars.mgcp_connection_id_bss := '10004'H;
1810 cpars.mgcp_connection_id_mss := '10005'H;
1811
1812 /* Note: This is an optional parameter. When the call-agent (MSC) does
1813 * supply a full endpoint name this setting will be overwritten. */
1814 cpars.mgcp_ep := "rtpbridge/1@mgw";
1815
1816 /* Intentionally disable the CRCX response */
1817 cpars.mgw_drop_dlcx := true;
1818
1819 /* Perform location update and call */
1820 f_perform_lu();
1821 f_mt_call(cpars);
1822}
1823testcase TC_lu_and_mt_call_no_dlcx_resp() runs on MTC_CT {
1824 var BSC_ConnHdlr vc_conn;
1825 f_init();
1826
1827 /* Perform an almost normal looking locationupdate + mt-call, but do
1828 * not respond to the DLCX at the end of the call */
1829 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call_no_dlcx_resp), 41);
1830 vc_conn.done;
1831
1832 /* Wait a guard period until the MGCP layer in the MSC times out,
1833 * if the MSC is vulnerable to the use-after-free situation that is
1834 * fixed by I78f1b6a9149488a4ad3f120c1e190a83c07d4b89 then it should
1835 * segfault now */
1836 f_sleep(6.0);
1837
1838 /* Run the init procedures once more. If the MSC has crashed, this
1839 * this will fail */
1840 f_init();
1841}
Harald Welte45164da2018-01-24 12:51:27 +01001842
Philipp Maier75932982018-03-27 14:52:35 +02001843/* Two BSSMAP resets from two different BSCs */
1844testcase TC_reset_two() runs on MTC_CT {
1845 var BSC_ConnHdlr vc_conn;
1846 f_init(2);
1847 f_sleep(2.0);
1848 setverdict(pass);
1849}
1850
Harald Weltef640a012018-04-14 17:49:21 +02001851/***********************************************************************
1852 * SMS Testing
1853 ***********************************************************************/
1854
Harald Weltef45efeb2018-04-09 18:19:24 +02001855/* LU followed by MO SMS */
1856private function f_tc_lu_and_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1857 var SmsParameters spars := valueof(t_SmsPars);
1858
1859 f_init_handler(pars);
1860
1861 /* Perform location update and call */
1862 f_perform_lu();
1863
1864 f_establish_fully(EST_TYPE_MO_SMS);
1865
1866 //spars.exp_rp_err := 96; /* invalid mandatory information */
1867 f_mo_sms(spars);
1868
1869 f_expect_clear();
1870}
1871testcase TC_lu_and_mo_sms() runs on MTC_CT {
1872 var BSC_ConnHdlr vc_conn;
1873 f_init();
1874 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_sms), 42);
1875 vc_conn.done;
1876}
1877
1878private function f_vty_sms_send(charstring imsi, charstring msisdn, charstring text)
1879runs on MTC_CT {
1880 f_vty_transceive(MSCVTY, "subscriber imsi "&imsi&" sms sender msisdn "&msisdn&" send "&text);
1881}
1882
1883/* LU followed by MT SMS */
1884private function f_tc_lu_and_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1885 var SmsParameters spars := valueof(t_SmsPars);
1886 var OCT4 tmsi;
1887
1888 f_init_handler(pars);
1889
1890 /* Perform location update and call */
1891 f_perform_lu();
1892
1893 /* register an 'expect' for given IMSI (+TMSI) */
1894 if (isvalue(g_pars.tmsi)) {
1895 tmsi := g_pars.tmsi;
1896 } else {
1897 tmsi := 'FFFFFFFF'O;
1898 }
1899 f_bssmap_register_imsi(g_pars.imsi, tmsi);
1900
1901 /* FIXME: actually cause MSC to send a SMS via VTY or SMPP */
1902
1903 /* MSC->BSC: expect PAGING from MSC */
1904 BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));
1905 /* Establish DTAP / BSSAP / SCCP connection */
1906 f_establish_fully(EST_TYPE_PAG_RESP);
1907
1908 spars.tp.ud := 'C8329BFD064D9B53'O;
1909 f_mt_sms(spars);
1910
1911 f_expect_clear();
1912}
1913testcase TC_lu_and_mt_sms() runs on MTC_CT {
1914 var BSC_ConnHdlrPars pars;
1915 var BSC_ConnHdlr vc_conn;
1916 f_init();
1917 pars := f_init_pars(43);
1918 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_sms), pars);
1919 f_sleep(2.0);
1920 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
1921 vc_conn.done;
1922}
1923
Harald Weltef640a012018-04-14 17:49:21 +02001924/* mobile originated SMS from MS/BTS/BSC side to SMPP */
1925private function f_tc_smpp_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1926 var SmsParameters spars := valueof(t_SmsPars);
Harald Weltef45efeb2018-04-09 18:19:24 +02001927
Harald Weltef640a012018-04-14 17:49:21 +02001928 f_init_handler(pars);
Harald Weltef45efeb2018-04-09 18:19:24 +02001929
Harald Weltef640a012018-04-14 17:49:21 +02001930 /* Perform location update so IMSI is known + registered in MSC/VLR */
1931 f_perform_lu();
1932 f_establish_fully(EST_TYPE_MO_SMS);
1933
1934 f_mo_sms(spars);
1935
1936 var SMPP_PDU smpp;
1937 var template SMPP_PDU tr_smpp := tr_SMPP(c_SMPP_command_id_deliver_sm, ESME_ROK);
1938 tr_smpp.body.deliver_sm := {
1939 service_type := "CMT",
1940 source_addr_ton := network_specific,
1941 source_addr_npi := isdn,
1942 source_addr := hex2str(pars.msisdn),
1943 dest_addr_ton := f_sm_ton_from_gsm(spars.tp.da.tP_DA_NoPad.tP_TypeOfNumber),
1944 dest_addr_npi := f_sm_npi_from_gsm(spars.tp.da.tP_DA_NoPad.tP_NumberingPlanID),
1945 destination_addr := hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue),
1946 esm_class := '00000001'B,
1947 protocol_id := 0,
1948 priority_flag := 0,
1949 schedule_delivery_time := "",
1950 replace_if_present := 0,
1951 data_coding := '00000001'B,
1952 sm_default_msg_id := 0,
1953 sm_length := ?,
1954 short_message := spars.tp.ud,
1955 opt_pars := {
1956 {
1957 tag := user_message_reference,
1958 len := 2,
1959 opt_value := {
1960 int2_val := oct2int(spars.tp.msg_ref)
1961 }
1962 }
1963 }
1964 };
1965 alt {
1966 [] SMPP.receive(tr_smpp) -> value smpp {
1967 SMPP.send(ts_SMPP_DELIVER_SM_resp(ESME_ROK, smpp.header.seq_num));
1968 }
1969 [] SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK)) { repeat; }
1970 }
1971
1972 f_expect_clear();
1973}
1974testcase TC_smpp_mo_sms() runs on MTC_CT {
1975 var BSC_ConnHdlr vc_conn;
1976 f_init();
1977 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "default-route");
1978 vc_conn := f_start_handler(refers(f_tc_smpp_mo_sms), 44);
1979 vc_conn.done;
1980 f_vty_config2(MSCVTY, { "smpp", "esme msc_tester"}, "no default-route");
1981}
1982
1983/* convert GSM L3 TON to SMPP_TON enum */
1984function f_sm_ton_from_gsm(BIT3 ton) return SMPP_TON {
1985 select (ton) {
1986 case ('000'B) { return unknown; }
1987 case ('001'B) { return international; }
1988 case ('010'B) { return national; }
1989 case ('011'B) { return network_specific; }
1990 case ('100'B) { return subscriber_number; }
1991 case ('101'B) { return alphanumeric; }
1992 case ('110'B) { return abbreviated; }
1993 }
1994 setverdict(fail, "Unknown TON ", ton);
1995 self.stop;
1996}
1997/* convert GSM L3 NPI to SMPP_NPI enum */
1998function f_sm_npi_from_gsm(BIT4 npi) return SMPP_NPI {
1999 select (npi) {
2000 case ('0000'B) { return unknown; }
2001 case ('0001'B) { return isdn; }
2002 case ('0011'B) { return data; }
2003 case ('0100'B) { return telex; }
2004 case ('0110'B) { return land_mobile; }
2005 case ('1000'B) { return national; }
2006 case ('1001'B) { return private_; }
2007 case ('1010'B) { return ermes; }
2008 }
2009 setverdict(fail, "Unknown NPI ", npi);
2010 self.stop;
2011}
2012
2013/* build a SMPP_SM from SmsParameters */
2014function f_mt_sm_from_spars(SmsParameters spars)
2015runs on BSC_ConnHdlr return SMPP_SM {
2016 var SMPP_SM sm := {
2017 service_type := "CMT",
2018 source_addr_ton := f_sm_ton_from_gsm(spars.tp.da.tP_DA_NoPad.tP_TypeOfNumber),
2019 source_addr_npi := f_sm_npi_from_gsm(spars.tp.da.tP_DA_NoPad.tP_NumberingPlanID),
2020 source_addr := hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue),
2021 dest_addr_ton := international,
2022 dest_addr_npi := isdn,
2023 destination_addr := hex2str(g_pars.msisdn),
2024 esm_class := '00000001'B,
2025 protocol_id := 0,
2026 priority_flag := 0,
2027 schedule_delivery_time := "",
2028 validity_period := "",
2029 registered_delivery := '00000000'B,
2030 replace_if_present := 0,
2031 data_coding := '00000001'B,
2032 sm_default_msg_id := 0,
2033 sm_length := spars.tp.udl,
2034 short_message := spars.tp.ud,
2035 opt_pars := {}
2036 };
2037 return sm;
2038}
2039
2040/* helper function to encode SMS from 'spars', send it via SMPP to MSC; receive it on MS side */
2041private function f_smpp_mt_sms(SmsParameters spars, boolean trans_mode) runs on BSC_ConnHdlr {
2042 var SMPP_SM sm := f_mt_sm_from_spars(spars);
2043 if (trans_mode) {
2044 sm.esm_class := '00000010'B;
2045 }
2046
2047 /* actually cause MSC to send a SMS via SUBMIT-SM from SMPP side */
2048 SMPP.send(ts_SMPP_SUBMIT_SM(sm));
2049 if (not match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
2050 /* if we're not in SMPP transaction mode, we expect the SMPP-level ACK
2051 * before we expect the SMS delivery on the BSC/radio side */
2052 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
2053 }
2054
2055 /* MSC->BSC: expect PAGING from MSC */
2056 BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));
2057 /* Establish DTAP / BSSAP / SCCP connection */
2058 f_establish_fully(EST_TYPE_PAG_RESP);
2059 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
2060
2061 f_mt_sms(spars);
2062
2063 if (match(sm.esm_class, tr_ESM_CLASS_TRANSACTION)) {
2064 SMPP.receive(tr_SMPP(c_SMPP_command_id_submit_sm_resp, ESME_ROK));
2065 }
2066 f_expect_clear();
2067}
2068
2069/* mobile terminated SMS, from SMPP to BSC/BTS/MS */
2070private function f_tc_smpp_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
2071 f_init_handler(pars);
2072
2073 /* Perform location update so IMSI is known + registered in MSC/VLR */
2074 f_perform_lu();
2075 SMPP.receive(tr_SMPP(c_SMPP_command_id_alert_notification, ESME_ROK));
2076
2077 /* register an 'expect' for given IMSI (+TMSI) */
2078 var OCT4 tmsi;
2079 if (isvalue(g_pars.tmsi)) {
2080 tmsi := g_pars.tmsi;
2081 } else {
2082 tmsi := 'FFFFFFFF'O;
2083 }
2084 f_bssmap_register_imsi(g_pars.imsi, tmsi);
2085
2086 var SmsParameters spars := valueof(t_SmsPars);
2087 /* TODO: test with more intelligent user data; test different coding schemes */
2088 spars.tp.ud := '00'O;
2089 spars.tp.udl := 1;
2090
2091 /* first test the non-transaction store+forward mode */
2092 f_smpp_mt_sms(spars, false);
2093
2094 /* then test the transaction mode */
2095 f_smpp_mt_sms(spars, true);
2096}
2097testcase TC_smpp_mt_sms() runs on MTC_CT {
2098 var BSC_ConnHdlr vc_conn;
2099 f_init();
2100 vc_conn := f_start_handler(refers(f_tc_smpp_mt_sms), 45);
2101 vc_conn.done;
2102}
2103
2104/* TODO (SMS):
2105 * different user data lengths
2106 * SMPP transaction mode with unsuccessful delivery
2107 * queued MT-SMS with no paging response + later delivery
2108 * different data coding schemes
2109 * multi-part SMS
2110 * user-data headers
2111 * TP-PID for SMS to SIM
2112 * behavior if SMS memory is full + RP-SMMA
2113 * delivery reports
2114 * SMPP osmocom extensions
2115 * more-messages-to-send
2116 * SMS during ongoing call (SACCH/SAPI3)
2117 */
2118
2119/* TODO (General):
Harald Welteba7b6d92018-01-23 21:32:34 +01002120 * continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
2121 * malformed messages (missing IE, invalid message type): properly rejected?
2122 * MT call while LU or is ongoing: Do we use existing lchan or page while lchan active?
2123 * 3G/2G auth permutations
2124 * encryption algorithms vs. classmark vs. vty config
Harald Welteba7b6d92018-01-23 21:32:34 +01002125 * send new transaction after/during clear (like SMS, ...)
Harald Welte45164da2018-01-24 12:51:27 +01002126 * too long L3 INFO in DTAP
2127 * too long / padded BSSAP
2128 * too long / short TLV values
Harald Welteba7b6d92018-01-23 21:32:34 +01002129 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01002130
2131
2132control {
Philipp Maier328d1662018-03-07 10:40:27 +01002133 execute( TC_cr_before_reset() );
Harald Weltea49e36e2018-01-21 19:29:33 +01002134 execute( TC_lu_imsi_noauth_tmsi() );
Harald Welted2328a22018-01-27 14:27:16 +01002135 execute( TC_lu_imsi_noauth_notmsi() );
Harald Weltea49e36e2018-01-21 19:29:33 +01002136 execute( TC_lu_imsi_reject() );
2137 execute( TC_lu_imsi_timeout_gsup() );
Harald Welted2328a22018-01-27 14:27:16 +01002138 execute( TC_lu_imsi_auth_tmsi() );
2139 execute( TC_cmserv_imsi_unknown() );
Harald Welte2bb825f2018-01-22 11:31:18 +01002140 execute( TC_lu_and_mo_call() );
Harald Welte071ed732018-01-23 19:53:52 +01002141 execute( TC_lu_auth_sai_timeout() );
2142 execute( TC_lu_auth_sai_err() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01002143 execute( TC_lu_clear_request() );
2144 execute( TC_lu_disconnect() );
2145 execute( TC_lu_by_imei() );
2146 execute( TC_lu_by_tmsi_noauth_unknown() );
2147 execute( TC_imsi_detach_by_imsi() );
2148 execute( TC_imsi_detach_by_tmsi() );
2149 execute( TC_imsi_detach_by_imei() );
2150 execute( TC_emerg_call_imei_reject() );
2151 execute( TC_emerg_call_imsi() );
2152 execute( TC_cm_serv_req_vgcs_reject() );
2153 execute( TC_cm_serv_req_vbs_reject() );
2154 execute( TC_cm_serv_req_lcs_reject() );
Harald Welte0195ab12018-01-24 21:50:20 +01002155 execute( TC_cm_reest_req_reject() );
Harald Welte1af6ea82018-01-25 18:33:15 +01002156 execute( TC_lu_auth_2G_fail() );
2157 execute( TC_lu_imsi_auth_tmsi_encr_13_13() );
2158 execute( TC_cl3_no_payload() );
2159 execute( TC_cl3_rnd_payload() );
Harald Welte1852a842018-01-26 22:53:36 +01002160 execute( TC_establish_and_nothing() );
2161 execute( TC_mo_setup_and_nothing() );
2162 execute( TC_mo_crcx_ran_timeout() );
2163 execute( TC_mo_crcx_ran_reject() );
Harald Welted2328a22018-01-27 14:27:16 +01002164 execute( TC_mt_crcx_ran_reject() );
Daniel Willmann8b084372018-02-04 13:35:26 +01002165 execute( TC_mo_setup_and_dtmf_dup() );
Harald Welteaa54cf82018-01-30 08:15:32 +01002166 //execute( TC_mt_t310() );
Harald Welte167458a2018-01-27 15:58:16 +01002167 execute( TC_gsup_cancel() );
Harald Welte9de84792018-01-28 01:06:35 +01002168 execute( TC_lu_imsi_auth_tmsi_encr_1_13() );
2169 execute( TC_lu_imsi_auth_tmsi_encr_3_13() );
2170 execute( TC_lu_imsi_auth_tmsi_encr_3_1() );
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01002171 execute( TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() );
Harald Welte9de84792018-01-28 01:06:35 +01002172 execute( TC_lu_imsi_auth_tmsi_encr_13_2() );
2173 execute( TC_lu_imsi_auth_tmsi_encr_013_2() );
Philipp Maier94f3f1b2018-03-15 18:54:13 +01002174 execute( TC_mo_release_timeout() );
Philipp Maier2a98a732018-03-19 16:06:12 +01002175 execute( TC_lu_and_mt_call_no_dlcx_resp() );
Philipp Maier75932982018-03-27 14:52:35 +02002176 execute( TC_reset_two() );
Harald Welte33ec09b2018-02-10 15:34:46 +01002177
2178 execute( TC_lu_and_mt_call() );
2179
Harald Weltef45efeb2018-04-09 18:19:24 +02002180 execute( TC_lu_and_mo_sms() );
2181 execute( TC_lu_and_mt_sms() );
Harald Weltef640a012018-04-14 17:49:21 +02002182 execute( TC_smpp_mo_sms() );
2183 execute( TC_smpp_mt_sms() );
Harald Weltef45efeb2018-04-09 18:19:24 +02002184
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01002185 /* Run this last: at the time of writing this test crashes the MSC */
2186 execute( TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() );
Harald Weltef6dd64d2017-11-19 12:09:51 +01002187}
2188
2189
2190}