blob: 84f33b78b0bd1b2febb012ba4799ab7fd0b43d6e [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 Weltef6dd64d2017-11-19 12:09:51 +010050
Harald Weltea4ca4462018-02-09 00:17:14 +010051type component MTC_CT extends CTRL_Adapter_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +010052 var boolean g_initialized := false;
Harald Weltea49e36e2018-01-21 19:29:33 +010053
Harald Weltea4ca4462018-02-09 00:17:14 +010054 var BSSAP_Adapter g_bssap;
55
Harald Weltea49e36e2018-01-21 19:29:33 +010056 /* no 'adapter_CT' for MNCC or GSUP */
57 var MNCC_Emulation_CT vc_MNCC;
Harald Welte4aa970c2018-01-26 10:38:09 +010058 var MGCP_Emulation_CT vc_MGCP;
Harald Weltea49e36e2018-01-21 19:29:33 +010059 var GSUP_Emulation_CT vc_GSUP;
60 var IPA_Emulation_CT vc_GSUP_IPA;
61
62 /* only to get events from IPA underneath GSUP */
63 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte3ca1c902018-01-24 18:51:27 +010064 /* VTY to MSC */
65 port TELNETasp_PT MSCVTY;
Philipp Maier328d1662018-03-07 10:40:27 +010066
67 /* A port to directly send BSSAP messages. This port is used for
68 * tests that require low level access to sen arbitrary BSSAP
69 * messages. Run f_init_bssap_direct() to connect and initialize */
70 port BSSAP_CODEC_PT BSSAP_DIRECT;
71
72 /* When BSSAP messages are directly sent, then the connection
73 * handler is not active, which means that also no guard timer is
74 * set up. The following timer will serve as a replacement */
75 timer Tguard_direct := 60.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +010076}
77
78modulepar {
Harald Weltea49e36e2018-01-21 19:29:33 +010079 /* remote parameters of IUT */
80 charstring mp_msc_ip := "127.0.0.1";
81 integer mp_msc_ctrl_port := 4255;
82 integer mp_msc_vty_port := 4254;
Harald Weltef6dd64d2017-11-19 12:09:51 +010083
Harald Weltea49e36e2018-01-21 19:29:33 +010084 /* local parameters of emulated HLR */
85 charstring mp_hlr_ip := "127.0.0.1";
86 integer mp_hlr_port := 4222;
Harald Welte6126fb02018-01-27 20:08:24 +010087 charstring mp_mgw_ip := "127.0.0.1";
88 integer mp_mgw_port := 2427;
Harald Weltef6dd64d2017-11-19 12:09:51 +010089
Harald Weltea49e36e2018-01-21 19:29:33 +010090 charstring mp_msc_mncc := "/tmp/mncc";
Harald Weltea4ca4462018-02-09 00:17:14 +010091
92 BSSAP_Configuration mp_bssap_cfg := {
93 sccp_service_type := "mtp3_itu",
94 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
95 own_pc := 185,
96 own_ssn := 254,
97 peer_pc := 187,
98 peer_ssn := 254
99 };
Harald Weltef6dd64d2017-11-19 12:09:51 +0100100}
101
Philipp Maier328d1662018-03-07 10:40:27 +0100102/* altstep for the global guard timer (only used when BSSAP_DIRECT
103 * is used for communication */
104private altstep as_Tguard_direct() runs on MTC_CT {
105 [] Tguard_direct.timeout {
106 setverdict(fail, "Tguard timeout");
107 self.stop;
108 }
109}
Harald Weltef6dd64d2017-11-19 12:09:51 +0100110
Harald Weltea49e36e2018-01-21 19:29:33 +0100111function f_init_mncc(charstring id) runs on MTC_CT {
112 id := id & "-MNCC";
113 var MnccOps ops := {
114 create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
115 unitdata_cb := refers(MNCC_Emulation.DummyUnitdataCallback)
116 }
117
118 vc_MNCC := MNCC_Emulation_CT.create(id);
119 map(vc_MNCC:MNCC, system:MNCC_CODEC_PT);
120 vc_MNCC.start(MNCC_Emulation.main(ops, id, mp_msc_mncc));
Harald Weltef6dd64d2017-11-19 12:09:51 +0100121}
122
Harald Welte4aa970c2018-01-26 10:38:09 +0100123function f_init_mgcp(charstring id) runs on MTC_CT {
124 id := id & "-MGCP";
125 var MGCPOps ops := {
126 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
127 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
128 }
129 var MGCP_conn_parameters pars := {
Harald Welte6126fb02018-01-27 20:08:24 +0100130 callagent_ip := mp_msc_ip,
Harald Welte4aa970c2018-01-26 10:38:09 +0100131 callagent_udp_port := -1,
Harald Welte6126fb02018-01-27 20:08:24 +0100132 mgw_ip := mp_mgw_ip,
133 mgw_udp_port := mp_mgw_port
Harald Welte4aa970c2018-01-26 10:38:09 +0100134 }
135
136 vc_MGCP := MGCP_Emulation_CT.create(id);
137 map(vc_MGCP:MGCP, system:MGCP_CODEC_PT);
138 vc_MGCP.start(MGCP_Emulation.main(ops, pars, id));
139}
140
Harald Weltea49e36e2018-01-21 19:29:33 +0100141function f_init_gsup(charstring id) runs on MTC_CT {
142 id := id & "-GSUP";
143 var GsupOps ops := {
144 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
145 }
146
147 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
148 vc_GSUP := GSUP_Emulation_CT.create(id);
149
150 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
151 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
152 /* we use this hack to get events like ASP_IPA_EVENT_UP */
153 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
154
155 vc_GSUP.start(GSUP_Emulation.main(ops, id));
156 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
157
158 /* wait for incoming connection to GSUP port before proceeding */
159 timer T := 10.0;
160 T.start;
161 alt {
162 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
163 [] T.timeout {
Harald Welte458fd372018-03-21 11:26:23 +0100164 setverdict(fail, "No connection to GSUP Port");
Harald Weltea49e36e2018-01-21 19:29:33 +0100165 self.stop
166 }
167 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100168}
169
Harald Weltea49e36e2018-01-21 19:29:33 +0100170function f_init() runs on MTC_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +0100171
172 if (g_initialized == true) {
173 return;
174 }
175 g_initialized := true;
176
Harald Weltea4ca4462018-02-09 00:17:14 +0100177 f_bssap_init(g_bssap, mp_bssap_cfg, "MSC_Test", BSC_BssmapOps);
Harald Weltea49e36e2018-01-21 19:29:33 +0100178 f_ipa_ctrl_start(mp_msc_ip, mp_msc_ctrl_port);
179 f_init_mncc("MSC_Test");
Harald Welte4aa970c2018-01-26 10:38:09 +0100180 f_init_mgcp("MSC_Test");
Harald Weltea49e36e2018-01-21 19:29:33 +0100181 f_init_gsup("MSC_Test");
Harald Welte3ca1c902018-01-24 18:51:27 +0100182
183 map(self:MSCVTY, system:MSCVTY);
184 f_vty_set_prompts(MSCVTY);
185 f_vty_transceive(MSCVTY, "enable");
Harald Welteb14c77a2018-01-25 17:25:44 +0100186
187 /* set some defaults */
188 f_vty_config(MSCVTY, "network", "authentication optional");
189 f_vty_config(MSCVTY, "msc", "assign-tmsi");
190 f_vty_config(MSCVTY, "network", "encryption a5 0");
Harald Weltef6dd64d2017-11-19 12:09:51 +0100191}
192
Philipp Maier328d1662018-03-07 10:40:27 +0100193/* Initialize for a direct connection to BSSAP. This function is an alternative
194 * to f_init() when the high level functions of the BSC_ConnectionHandler are
195 * not needed. */
196function f_init_bssap_direct() runs on MTC_CT {
197 f_bssap_init(g_bssap, mp_bssap_cfg, "MSC_Test", omit);
198 connect(g_bssap.vc_SCCP:SCCP_SP_PORT, self:BSSAP_DIRECT);
199
200 /* Start guard timer and activate it as default */
201 Tguard_direct.start
202 activate(as_Tguard_direct());
203}
204
Harald Weltef6dd64d2017-11-19 12:09:51 +0100205template PDU_BSSAP ts_BSSAP_BSSMAP := {
206 discriminator := '0'B,
207 spare := '0000000'B,
208 dlci := omit,
209 lengthIndicator := 0, /* overwritten by codec */
210 pdu := ?
211}
212
213template PDU_BSSAP tr_BSSAP_BSSMAP := {
214 discriminator := '0'B,
215 spare := '0000000'B,
216 dlci := omit,
217 lengthIndicator := ?,
218 pdu := {
219 bssmap := ?
220 }
221}
222
223
224type integer BssmapCause;
225
226template (value) BSSMAP_IE_Cause ts_BSSMAP_IE_Cause(BssmapCause val) := {
227 elementIdentifier := '04'O,
228 lengthIndicator := 0,
229 causeValue := int2bit(val, 7),
230 extensionCauseValue := '0'B,
231 spare1 := omit
232}
233
234template (value) PDU_BSSAP ts_BSSMAP_Reset(BssmapCause cause) modifies ts_BSSAP_BSSMAP := {
235 pdu := {
236 bssmap := {
237 reset := {
238 messageType := '30'O,
239 cause := ts_BSSMAP_IE_Cause(cause),
240 a_InterfaceSelectorForReset := omit
241 }
242 }
243 }
244}
245
246template (value) PDU_BSSAP ts_BSSMAP_ResetAck modifies ts_BSSAP_BSSMAP := {
247 pdu := {
248 bssmap := {
249 resetAck := {
250 messageType := '31'O,
251 a_InterfaceSelectorForReset := omit
252 }
253 }
254 }
255}
256
257template PDU_BSSAP tr_BSSMAP_ResetAck modifies tr_BSSAP_BSSMAP := {
258 pdu := {
259 bssmap := {
260 resetAck := {
261 messageType := '31'O,
262 a_InterfaceSelectorForReset := *
263 }
264 }
265 }
266}
267
268template BSSMAP_IE_CellIdentifier ts_BSSMAP_IE_CellID := {
269 elementIdentifier := '05'O,
270 lengthIndicator := 0,
271 cellIdentifierDiscriminator := '0000'B,
272 spare1_4 := '0000'B,
273 cellIdentification := ?
274}
275
276type uint16_t BssmapLAC;
277type uint16_t BssmapCI;
278
279/*
280template BSSMAP_IE_CellIdentifier ts_CellId_CGI(mcc, mnc, lac, ci)
281modifies ts_BSSMAP_IE_CellID := {
282 cellIdentification := {
283 cI_LAC_CGI := {
284 mnc_mcc := FIXME,
285 lac := int2oct(lac, 2),
286 ci := int2oct(ci, 2)
287 }
288 }
289}
290*/
291
292template BSSMAP_IE_CellIdentifier ts_CellID_LAC_CI(BssmapLAC lac, BssmapCI ci)
293modifies ts_BSSMAP_IE_CellID := {
294 cellIdentification := {
295 cI_LAC_CI := {
296 lac := int2oct(lac, 2),
297 ci := int2oct(ci, 2)
298 }
299 }
300}
301
302template BSSMAP_IE_CellIdentifier ts_CellId_CI(BssmapCI ci)
303modifies ts_BSSMAP_IE_CellID := {
304 cellIdentification := {
305 cI_CI := int2oct(ci, 2)
306 }
307}
308
309template BSSMAP_IE_CellIdentifier ts_CellId_none
310modifies ts_BSSMAP_IE_CellID := {
311 cellIdentification := {
312 cI_noCell := ''O
313 }
314}
315
316
317template BSSMAP_IE_Layer3Information ts_BSSMAP_IE_L3Info(octetstring l3info) := {
318 elementIdentifier := '17'O,
319 lengthIndicator := 0,
320 layer3info := l3info
321}
322
323template PDU_BSSAP ts_BSSMAP_ComplL3(BSSMAP_IE_CellIdentifier cell_id, octetstring l3_info)
324modifies ts_BSSAP_BSSMAP := {
325 pdu := {
326 bssmap := {
327 completeLayer3Information := {
328 messageType := '57'O,
329 cellIdentifier := cell_id,
330 layer3Information := ts_BSSMAP_IE_L3Info(l3_info),
331 chosenChannel := omit,
332 lSAIdentifier := omit,
333 aPDU := omit,
334 codecList := omit,
335 redirectAttemptFlag := omit,
336 sendSequenceNumber := omit,
337 iMSI := omit
338 }
339 }
340 }
341}
342
343template PDU_BSSAP ts_BSSMAP_HandoReq(BssmapCause cause, BSSMAP_IE_CellIdentifierList cid_list)
344modifies ts_BSSAP_BSSMAP := {
345 pdu := {
346 bssmap := {
347 handoverRequired := {
348 messageType := '11'O,
349 cause := ts_BSSMAP_IE_Cause(cause),
350 responseRequest := omit,
351 cellIdentifierList := cid_list,
352 circuitPoolList := omit,
353 currentChannelType1 := omit,
354 speechVersion := omit,
355 queueingIndicator := omit,
356 oldToNewBSSInfo := omit,
357 sourceToTargetRNCTransparentInfo := omit,
358 sourceToTargetRNCTransparentInfoCDMA := omit,
359 gERANClassmark := omit,
360 talkerPriority := omit,
361 speechCodec := omit,
362 cSG_Identifier := omit
363 }
364 }
365 }
366}
367
Harald Weltea49e36e2018-01-21 19:29:33 +0100368type function void_fn(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100369
Harald Weltea49e36e2018-01-21 19:29:33 +0100370/* FIXME: move into BSC_ConnectionHandler? */
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100371function f_init_pars(integer imsi_suffix) runs on MTC_CT return BSC_ConnHdlrPars {
Harald Weltede371492018-01-27 23:44:41 +0100372 var BSC_ConnHdlrNetworkPars net_pars := {
373 kc_support := '0A'O, /* A5/1 and A5/3 enabled */
374 expect_tmsi := true,
375 expect_auth := false,
376 expect_ciph := false
377 };
Harald Weltea49e36e2018-01-21 19:29:33 +0100378 var BSC_ConnHdlrPars pars := {
Harald Weltea4ca4462018-02-09 00:17:14 +0100379 sccp_addr_own := g_bssap.sccp_addr_own,
380 sccp_addr_peer := g_bssap.sccp_addr_peer,
Harald Welteedbab812018-03-18 16:02:25 +0100381 cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42)),
Harald Welte81b7f9d2018-01-24 19:06:24 +0100382 imei := f_gen_imei(imsi_suffix),
383 imsi := f_gen_imsi(imsi_suffix),
384 msisdn := f_gen_msisdn(imsi_suffix),
Harald Welte256571e2018-01-24 18:47:19 +0100385 tmsi := omit,
Harald Welte9de84792018-01-28 01:06:35 +0100386 cm1 := valueof(ts_CM1),
Harald Welte82600572018-01-21 20:54:08 +0100387 cm2 := valueof(ts_CM2_default),
Harald Welte16114282018-01-24 22:41:21 +0100388 cm3 := omit,
Harald Weltede371492018-01-27 23:44:41 +0100389 vec := omit,
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100390 net := net_pars,
391 send_early_cm := true
Harald Weltea49e36e2018-01-21 19:29:33 +0100392 };
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100393 return pars;
394}
395
396function f_start_handler_with_pars(void_fn fn, BSC_ConnHdlrPars pars) runs on MTC_CT return BSC_ConnHdlr {
397 var BSC_ConnHdlr vc_conn;
398 var charstring id := testcasename();
Harald Weltea49e36e2018-01-21 19:29:33 +0100399
400 vc_conn := BSC_ConnHdlr.create(id);
401 /* BSSMAP part / A interface */
Harald Weltea4ca4462018-02-09 00:17:14 +0100402 connect(vc_conn:BSSAP, g_bssap.vc_BSSMAP:CLIENT);
403 connect(vc_conn:BSSAP_PROC, g_bssap.vc_BSSMAP:PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100404 /* MNCC part */
405 connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
406 connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);
Harald Welte4aa970c2018-01-26 10:38:09 +0100407 /* MGCP part */
408 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
409 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100410 /* GSUP part */
411 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
412 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
413
Harald Weltea10db902018-01-27 12:44:49 +0100414 /* We cannot use vc_conn.start(f_init_handler(fn, id, pars)); as we cannot have
415 * a stand-alone 'derefers()' call, see https://www.eclipse.org/forums/index.php/t/1091364/ */
Harald Weltea49e36e2018-01-21 19:29:33 +0100416 vc_conn.start(derefers(fn)(id, pars));
417 return vc_conn;
418}
419
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100420function f_start_handler(void_fn fn, integer imsi_suffix) runs on MTC_CT return BSC_ConnHdlr {
421 return f_start_handler_with_pars(fn, f_init_pars(imsi_suffix));
422}
423
Harald Weltea49e36e2018-01-21 19:29:33 +0100424private function f_tc_lu_imsi_noauth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100425 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100426 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100427}
Harald Weltea49e36e2018-01-21 19:29:33 +0100428testcase TC_lu_imsi_noauth_tmsi() runs on MTC_CT {
429 var BSC_ConnHdlr vc_conn;
430 f_init();
431
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100432 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi), 1);
Harald Weltea49e36e2018-01-21 19:29:33 +0100433 vc_conn.done;
434}
435
436private function f_tc_lu_imsi_noauth_notmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100437 pars.net.expect_tmsi := false;
Harald Weltea10db902018-01-27 12:44:49 +0100438 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100439 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100440}
Harald Weltea49e36e2018-01-21 19:29:33 +0100441testcase TC_lu_imsi_noauth_notmsi() runs on MTC_CT {
442 var BSC_ConnHdlr vc_conn;
443 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100444 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
Harald Weltea49e36e2018-01-21 19:29:33 +0100445
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100446 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi), 2);
Harald Weltea49e36e2018-01-21 19:29:33 +0100447 vc_conn.done;
448}
449
450/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
451private function f_tc_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100452 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100453 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
454
455 f_create_gsup_expect(hex2str(g_pars.imsi));
456 f_bssap_compl_l3(l3_lu);
457 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
458 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
459 alt {
Harald Welte5946b332018-03-18 23:32:21 +0100460 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej(int2oct(23,1)))) {
461 f_expect_clear();
462 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100463 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
464 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
465 self.stop;
466 }
467 }
Harald Welte1ddc7162018-01-27 14:25:46 +0100468 f_expect_clear();
Harald Weltea49e36e2018-01-21 19:29:33 +0100469}
470testcase TC_lu_imsi_reject() runs on MTC_CT {
471 var BSC_ConnHdlr vc_conn;
472 f_init();
473
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100474 vc_conn := f_start_handler(refers(f_tc_lu_imsi_reject), 3);
Harald Weltea49e36e2018-01-21 19:29:33 +0100475 vc_conn.done;
476}
477
478/* Do LU by IMSI, timeout on GSUP */
479private function f_tc_lu_imsi_timeout_gsup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100480 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100481 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
482
483 f_create_gsup_expect(hex2str(g_pars.imsi));
484 f_bssap_compl_l3(l3_lu);
485 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
486 /* Normally the HLR would need to respond here, but we decide to force a timeout here */
487 alt {
488 /* FIXME: Expect specific reject cause */
Harald Welte5946b332018-03-18 23:32:21 +0100489 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
490 f_expect_clear();
491 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100492 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
493 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
494 self.stop;
495 }
496 }
Harald Welte1ddc7162018-01-27 14:25:46 +0100497 f_expect_clear();
Harald Weltea49e36e2018-01-21 19:29:33 +0100498}
499testcase TC_lu_imsi_timeout_gsup() runs on MTC_CT {
500 var BSC_ConnHdlr vc_conn;
501 f_init();
502
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100503 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_gsup), 4);
Harald Weltea49e36e2018-01-21 19:29:33 +0100504 vc_conn.done;
505}
506
Harald Welte7b1b2812018-01-22 21:23:06 +0100507private function f_tc_lu_imsi_auth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100508 pars.net.expect_auth := true;
Harald Weltea10db902018-01-27 12:44:49 +0100509 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100510 f_perform_lu();
Harald Welte7b1b2812018-01-22 21:23:06 +0100511}
512testcase TC_lu_imsi_auth_tmsi() runs on MTC_CT {
513 var BSC_ConnHdlr vc_conn;
514 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100515 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte7b1b2812018-01-22 21:23:06 +0100516
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100517 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi), 5);
Harald Welte7b1b2812018-01-22 21:23:06 +0100518 vc_conn.done;
519}
520
Harald Weltea49e36e2018-01-21 19:29:33 +0100521
522/* Send CM SERVICE REQ for IMSI that has never performed LU before */
523private function f_tc_cmserv_imsi_unknown(charstring id, BSC_ConnHdlrPars pars)
524runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100525 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100526
527 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welteedbab812018-03-18 16:02:25 +0100528 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100529 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltea49e36e2018-01-21 19:29:33 +0100530
531 f_create_gsup_expect(hex2str(g_pars.imsi));
532
533 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
534 f_bssap_compl_l3(l3_info);
535
536 timer T := 10.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100537 T.start;
538 alt {
Harald Weltea49e36e2018-01-21 19:29:33 +0100539 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
540 //[] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC)) { }
541 [] BSSAP.receive { setverdict(fail, "Received unexpected BSSAP"); }
542 [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
543 setverdict(fail, "Unexpected GSUP UL REQ");
544 }
Daniel Willmann90829d62018-02-15 17:45:14 +0100545 [] T.timeout { setverdict(fail, "Timeout waiting for CM SERV REQ"); }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100546 }
547
Harald Welte1ddc7162018-01-27 14:25:46 +0100548 f_expect_clear();
Harald Weltef6dd64d2017-11-19 12:09:51 +0100549}
Harald Weltea49e36e2018-01-21 19:29:33 +0100550testcase TC_cmserv_imsi_unknown() runs on MTC_CT {
551 var BSC_ConnHdlr vc_conn;
552 f_init();
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100553 vc_conn := f_start_handler(refers(f_tc_cmserv_imsi_unknown), 6);
Harald Weltea49e36e2018-01-21 19:29:33 +0100554 vc_conn.done;
555}
556
Harald Welte2bb825f2018-01-22 11:31:18 +0100557private function f_tc_lu_and_mo_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100558 f_init_handler(pars);
Harald Welteb71901a2018-01-26 19:16:05 +0100559 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
560 cpars.bss_rtp_port := 1110;
561 cpars.mgcp_connection_id_bss := '22222'H;
562 cpars.mgcp_connection_id_mss := '33333'H;
Philipp Maierf1e02bb2018-03-15 16:30:00 +0100563 cpars.mgcp_ep := "rtpbridge/1@mgw";
Harald Welte2bb825f2018-01-22 11:31:18 +0100564
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100565 f_perform_lu();
Harald Welteb71901a2018-01-26 19:16:05 +0100566 f_mo_call(cpars);
Harald Welte2bb825f2018-01-22 11:31:18 +0100567}
568testcase TC_lu_and_mo_call() runs on MTC_CT {
569 var BSC_ConnHdlr vc_conn;
570 f_init();
571
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100572 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_call), 7);
Harald Welte071ed732018-01-23 19:53:52 +0100573 vc_conn.done;
574}
575
576/* Test LU (with authentication enabled), where HLR times out sending SAI response */
577private function f_tc_lu_auth_sai_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100578 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100579
580 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
581 var PDU_DTAP_MT dtap_mt;
582
583 /* tell GSUP dispatcher to send this IMSI to us */
584 f_create_gsup_expect(hex2str(g_pars.imsi));
585
586 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
587 f_bssap_compl_l3(l3_lu);
588
589 /* Send Early Classmark, just for the fun of it */
590 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
591
592 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
593 /* The HLR would normally return an auth vector here, but we fail to do so. */
594
595 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100596 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100597}
598testcase TC_lu_auth_sai_timeout() runs on MTC_CT {
599 var BSC_ConnHdlr vc_conn;
600 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100601 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100602
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100603 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_timeout), 8);
Harald Welte071ed732018-01-23 19:53:52 +0100604 vc_conn.done;
605}
606
607/* Test LU (with authentication enabled), where HLR rejects sending SAI error */
608private function f_tc_lu_auth_sai_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100609 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100610
611 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
612 var PDU_DTAP_MT dtap_mt;
613
614 /* tell GSUP dispatcher to send this IMSI to us */
615 f_create_gsup_expect(hex2str(g_pars.imsi));
616
617 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
618 f_bssap_compl_l3(l3_lu);
619
620 /* Send Early Classmark, just for the fun of it */
621 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
622
623 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
624 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 13));
625
626 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100627 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100628}
629testcase TC_lu_auth_sai_err() runs on MTC_CT {
630 var BSC_ConnHdlr vc_conn;
631 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100632 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100633
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100634 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_err), 9);
Harald Welte2bb825f2018-01-22 11:31:18 +0100635 vc_conn.done;
636}
Harald Weltea49e36e2018-01-21 19:29:33 +0100637
Harald Weltebc881782018-01-23 20:09:15 +0100638/* Test LU but BSC will send a clear request in the middle */
639private function f_tc_lu_clear_request(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100640 f_init_handler(pars);
Harald Weltebc881782018-01-23 20:09:15 +0100641
642 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
643 var PDU_DTAP_MT dtap_mt;
644
645 /* tell GSUP dispatcher to send this IMSI to us */
646 f_create_gsup_expect(hex2str(g_pars.imsi));
647
648 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
649 f_bssap_compl_l3(l3_lu);
650
651 /* Send Early Classmark, just for the fun of it */
652 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
653
654 f_sleep(1.0);
655 /* send clear request in the middle of the LU */
656 BSSAP.send(ts_BSSMAP_ClearRequest(0));
657 BSSAP.receive(tr_BSSMAP_ClearCommand);
658 BSSAP.send(ts_BSSMAP_ClearComplete);
Harald Welte89a32492018-01-27 19:07:28 +0100659 alt {
660 /* See https://osmocom.org/issues/2862 */
661 [] BSSAP.receive(tr_BSSMAP_ClearCommand) { repeat; }
662 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
663 }
Harald Weltebc881782018-01-23 20:09:15 +0100664 setverdict(pass);
665}
666testcase TC_lu_clear_request() runs on MTC_CT {
667 var BSC_ConnHdlr vc_conn;
668 f_init();
669
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100670 vc_conn := f_start_handler(refers(f_tc_lu_clear_request), 10);
Harald Weltebc881782018-01-23 20:09:15 +0100671 vc_conn.done;
672}
673
Harald Welte66af9e62018-01-24 17:28:21 +0100674/* Test LU but BSC will send a clear request in the middle */
675private function f_tc_lu_disconnect(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100676 f_init_handler(pars);
Harald Welte66af9e62018-01-24 17:28:21 +0100677
678 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
679 var PDU_DTAP_MT dtap_mt;
680
681 /* tell GSUP dispatcher to send this IMSI to us */
682 f_create_gsup_expect(hex2str(g_pars.imsi));
683
684 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
685 f_bssap_compl_l3(l3_lu);
686
687 /* Send Early Classmark, just for the fun of it */
688 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
689
690 f_sleep(1.0);
691 /* send clear request in the middle of the LU */
692 BSSAP.send(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
693 setverdict(pass);
694}
695testcase TC_lu_disconnect() runs on MTC_CT {
696 var BSC_ConnHdlr vc_conn;
697 f_init();
698
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100699 vc_conn := f_start_handler(refers(f_tc_lu_disconnect), 11);
Harald Welte66af9e62018-01-24 17:28:21 +0100700 vc_conn.done;
701}
702
703
Harald Welteba7b6d92018-01-23 21:32:34 +0100704/* Test LU but with illegal mobile identity type = IMEI */
705private function f_tc_lu_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100706 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100707
Harald Welte256571e2018-01-24 18:47:19 +0100708 var PDU_ML3_MS_NW l3_lu := f_build_lu_imei(g_pars.imei)
Harald Welteba7b6d92018-01-23 21:32:34 +0100709 var PDU_DTAP_MT dtap_mt;
710
711 /* tell GSUP dispatcher to send this IMSI to us */
712 f_create_gsup_expect(hex2str(g_pars.imsi));
713
714 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
715 f_bssap_compl_l3(l3_lu);
716
717 /* Send Early Classmark, just for the fun of it */
718 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
719 /* wait for LU reject, ignore any ID REQ */
720 alt {
721 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
722 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req)) { repeat; }
723 }
724 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100725 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100726}
727testcase TC_lu_by_imei() runs on MTC_CT {
728 var BSC_ConnHdlr vc_conn;
729 f_init();
730
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100731 vc_conn := f_start_handler(refers(f_tc_lu_by_imei), 12);
Harald Welteba7b6d92018-01-23 21:32:34 +0100732 vc_conn.done;
733}
734
735/* Test LU by TMSI with unknown TMSI, expect (and answer) ID REQ. */
736private function f_tc_lu_tmsi_noauth_unknown(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100737 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100738
739 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('01020304'O); /* FIXME: Random */
740 var PDU_DTAP_MT dtap_mt;
741
742 /* tell GSUP dispatcher to send this IMSI to us */
743 f_create_gsup_expect(hex2str(g_pars.imsi));
744
745 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
746 f_bssap_compl_l3(l3_lu);
747
748 /* Send Early Classmark, just for the fun of it */
749 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
750
751 /* Wait for + respond to ID REQ (IMSI) */
752 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req('001'B)));
753 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
754
755 /* Expect MSC to do UpdateLocation to HLR; respond to it */
756 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
757 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
758 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
759 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
760
761 alt {
Harald Welte7ec4fa82018-01-27 10:57:40 +0100762 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
763 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
764 }
Harald Welteba7b6d92018-01-23 21:32:34 +0100765 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
766 setverdict(fail, "Expected LU ACK, but received REJ");
767 }
768 }
769
770 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100771 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100772}
773testcase TC_lu_by_tmsi_noauth_unknown() runs on MTC_CT {
774 var BSC_ConnHdlr vc_conn;
775 f_init();
776
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100777 vc_conn := f_start_handler(refers(f_tc_lu_tmsi_noauth_unknown), 13);
Harald Welteba7b6d92018-01-23 21:32:34 +0100778 vc_conn.done;
779}
780
781
Harald Welte45164da2018-01-24 12:51:27 +0100782/* Test IMSI DETACH (MI=IMSI) */
783private function f_tc_imsi_detach_by_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100784 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100785
786 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
787
788 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
789 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
790
791 /* Send Early Classmark, just for the fun of it? */
792 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
793
794 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100795 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100796}
797testcase TC_imsi_detach_by_imsi() runs on MTC_CT {
798 var BSC_ConnHdlr vc_conn;
799 f_init();
800
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100801 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imsi), 14);
Harald Welte45164da2018-01-24 12:51:27 +0100802 vc_conn.done;
803}
804
805/* Test IMSI DETACH (MI=TMSI) */
806private function f_tc_imsi_detach_by_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100807 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100808
809 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('01020304'O));
810
811 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
812 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
813
814 /* Send Early Classmark, just for the fun of it? */
815 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
816
817 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100818 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100819}
820testcase TC_imsi_detach_by_tmsi() runs on MTC_CT {
821 var BSC_ConnHdlr vc_conn;
822 f_init();
823
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100824 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_tmsi), 15);
Harald Welte45164da2018-01-24 12:51:27 +0100825 vc_conn.done;
826}
827
828/* Test IMSI DETACH (MI=IMEI), which is illegal */
829private function f_tc_imsi_detach_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100830 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100831
Harald Welte256571e2018-01-24 18:47:19 +0100832 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte45164da2018-01-24 12:51:27 +0100833
834 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
835 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
836
837 /* Send Early Classmark, just for the fun of it? */
838 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
839
840 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100841 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100842}
843testcase TC_imsi_detach_by_imei() runs on MTC_CT {
844 var BSC_ConnHdlr vc_conn;
845 f_init();
846
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100847 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imei), 16);
Harald Welte45164da2018-01-24 12:51:27 +0100848 vc_conn.done;
849}
850
851
852/* helper function for an emergency call. caller passes in mobile identity to use */
853private function f_emerg_call(MobileIdentityLV mi) runs on BSC_ConnHdlr {
Harald Welte0bef21e2018-02-10 09:48:23 +0100854 var CallParameters cpars := valueof(t_CallParams('112'H, 0));
855 cpars.emergency := true;
Philipp Maierf1e02bb2018-03-15 16:30:00 +0100856 cpars.mgcp_ep := "rtpbridge/1@mgw";
Harald Welte45164da2018-01-24 12:51:27 +0100857
Harald Welte0bef21e2018-02-10 09:48:23 +0100858 f_mo_call(cpars);
Harald Welte45164da2018-01-24 12:51:27 +0100859}
860
861/* establish an emergency call by IMEI, no SIM inserted (and hence no IMSI) */
862private function f_tc_emerg_call_imei_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100863 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100864
Harald Welte256571e2018-01-24 18:47:19 +0100865 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100866 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100867 f_bssap_compl_l3(l3_info);
868 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ('05'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +0100869 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100870}
871testcase TC_emerg_call_imei_reject() runs on MTC_CT {
872 var BSC_ConnHdlr vc_conn;
873 f_init();
874
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100875 vc_conn := f_start_handler(refers(f_tc_emerg_call_imei_reject), 17);
Harald Welte45164da2018-01-24 12:51:27 +0100876 vc_conn.done;
877}
878
Harald Welted5b91402018-01-24 18:48:16 +0100879/* establish an emergency call by IMSI, SIM inserted (and hence IMSI) */
Harald Welte45164da2018-01-24 12:51:27 +0100880private function f_tc_emerg_call_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100881 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100882 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100883 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +0100884 /* Then issue emergency call identified by IMSI */
885 f_emerg_call(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
886}
887testcase TC_emerg_call_imsi() runs on MTC_CT {
888 var BSC_ConnHdlr vc_conn;
889 f_init();
890
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100891 vc_conn := f_start_handler(refers(f_tc_emerg_call_imsi), 18);
Harald Welte45164da2018-01-24 12:51:27 +0100892 vc_conn.done;
893}
894
895/* CM Service Request for VGCS -> reject */
896private function f_tc_cm_serv_req_vgcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100897 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100898
899 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100900 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +0100901
902 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100903 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VGCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100904 f_bssap_compl_l3(l3_info);
905 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100906 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100907}
908testcase TC_cm_serv_req_vgcs_reject() runs on MTC_CT {
909 var BSC_ConnHdlr vc_conn;
910 f_init();
911
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100912 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vgcs_reject), 19);
Harald Welte45164da2018-01-24 12:51:27 +0100913 vc_conn.done;
914}
915
916/* CM Service Request for VBS -> reject */
917private function f_tc_cm_serv_req_vbs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100918 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100919
920 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100921 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +0100922
923 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100924 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VBS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100925 f_bssap_compl_l3(l3_info);
926 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100927 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100928}
929testcase TC_cm_serv_req_vbs_reject() runs on MTC_CT {
930 var BSC_ConnHdlr vc_conn;
931 f_init();
932
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100933 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vbs_reject), 20);
Harald Welte45164da2018-01-24 12:51:27 +0100934 vc_conn.done;
935}
936
937/* CM Service Request for LCS -> reject */
938private function f_tc_cm_serv_req_lcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100939 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100940
941 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100942 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +0100943
944 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100945 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_LCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100946 f_bssap_compl_l3(l3_info);
947 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100948 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100949}
950testcase TC_cm_serv_req_lcs_reject() runs on MTC_CT {
951 var BSC_ConnHdlr vc_conn;
952 f_init();
953
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100954 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_lcs_reject), 21);
Harald Welte45164da2018-01-24 12:51:27 +0100955 vc_conn.done;
956}
957
Harald Welte0195ab12018-01-24 21:50:20 +0100958/* CM Re-Establishment Request */
959private function f_tc_cm_reest_req_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100960 f_init_handler(pars);
Harald Welte0195ab12018-01-24 21:50:20 +0100961
962 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100963 f_perform_lu();
Harald Welte0195ab12018-01-24 21:50:20 +0100964
965 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
966 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REEST_REQ(0, mi));
967 f_bssap_compl_l3(l3_info);
968 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100969 f_expect_clear();
Harald Welte0195ab12018-01-24 21:50:20 +0100970}
971testcase TC_cm_reest_req_reject() runs on MTC_CT {
972 var BSC_ConnHdlr vc_conn;
973 f_init();
Harald Welte0195ab12018-01-24 21:50:20 +0100974
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100975 vc_conn := f_start_handler(refers(f_tc_cm_reest_req_reject), 22);
Harald Welte0195ab12018-01-24 21:50:20 +0100976 vc_conn.done;
977}
978
Harald Weltec638f4d2018-01-24 22:00:36 +0100979/* Test LU (with authentication enabled), with wrong response from MS */
980private function f_tc_lu_auth_2G_fail(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100981 f_init_handler(pars);
Harald Weltec638f4d2018-01-24 22:00:36 +0100982
983 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
984
985 /* tell GSUP dispatcher to send this IMSI to us */
986 f_create_gsup_expect(hex2str(g_pars.imsi));
987
988 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
989 f_bssap_compl_l3(l3_lu);
990
991 /* Send Early Classmark, just for the fun of it */
992 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
993
994 var AuthVector vec := f_gen_auth_vec_2g();
995 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(vec.rand, vec.sres, vec.kc));
996 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
997 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
998
999 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(vec.rand)));
1000 /* Send back wrong auth response */
1001 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G('00000000'O)));
1002
1003 /* Expect GSUP AUTH FAIL REP to HLR */
1004 GSUP.receive(tr_GSUP_AUTH_FAIL_IND(g_pars.imsi));
1005
1006 /* Expect LU REJECT with Cause == Illegal MS */
1007 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej('03'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +01001008 f_expect_clear();
Harald Weltec638f4d2018-01-24 22:00:36 +01001009}
1010testcase TC_lu_auth_2G_fail() runs on MTC_CT {
1011 var BSC_ConnHdlr vc_conn;
1012 f_init();
1013 f_vty_config(MSCVTY, "network", "authentication required");
Harald Weltec638f4d2018-01-24 22:00:36 +01001014
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001015 vc_conn := f_start_handler(refers(f_tc_lu_auth_2G_fail), 23);
Harald Weltec638f4d2018-01-24 22:00:36 +01001016 vc_conn.done;
1017}
1018
Harald Weltede371492018-01-27 23:44:41 +01001019/* A5/1 + A5/3 permitted on network side, and MS capable to do it */
Harald Welte16114282018-01-24 22:41:21 +01001020private 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 +01001021 pars.net.expect_auth := true;
1022 pars.net.expect_ciph := true;
Harald Weltea10db902018-01-27 12:44:49 +01001023 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001024 f_perform_lu();
Harald Welte16114282018-01-24 22:41:21 +01001025}
1026testcase TC_lu_imsi_auth_tmsi_encr_13_13() runs on MTC_CT {
1027 var BSC_ConnHdlr vc_conn;
1028 f_init();
1029 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte16114282018-01-24 22:41:21 +01001030 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1031
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001032 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_13), 24);
Harald Welte16114282018-01-24 22:41:21 +01001033 vc_conn.done;
1034}
1035
Harald Welte1af6ea82018-01-25 18:33:15 +01001036/* Test Complete L3 without payload */
1037private function f_tc_cl3_no_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001038 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001039
1040 /* Send Complete L3 Info with empty L3 frame */
1041 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1042 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, ''O))));
1043
Harald Weltef466eb42018-01-27 14:26:54 +01001044 timer T := 5.0;
1045 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001046 alt {
1047 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
1048 /* Expect LU REJECT with Cause == Illegal MS */
Harald Weltebdb3c452018-03-18 22:43:06 +01001049 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
1050 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001051 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001052 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001053 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Harald Weltef466eb42018-01-27 14:26:54 +01001054 self.stop;
1055 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001056 }
1057 setverdict(pass);
1058}
1059testcase TC_cl3_no_payload() runs on MTC_CT {
1060 var BSC_ConnHdlr vc_conn;
1061 f_init();
1062
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001063 vc_conn := f_start_handler(refers(f_tc_cl3_no_payload), 25);
Harald Welte1af6ea82018-01-25 18:33:15 +01001064 vc_conn.done;
1065}
1066
1067/* Test Complete L3 with random payload */
1068private function f_tc_cl3_rnd_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001069 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001070
1071 var integer len := float2int(rnd() * 256.0);
1072 var octetstring payl := f_rnd_octstring(len);
1073
1074 /* Send Complete L3 Info with empty L3 frame */
1075 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1076 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, payl))));
1077
Harald Weltef466eb42018-01-27 14:26:54 +01001078 timer T := 5.0;
1079 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001080 alt {
1081 /* Immediate disconnect */
1082 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte1af6ea82018-01-25 18:33:15 +01001083 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
Harald Weltebdb3c452018-03-18 22:43:06 +01001084 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001085 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001086 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001087 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Harald Weltef466eb42018-01-27 14:26:54 +01001088 self.stop;
1089 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001090 }
1091 setverdict(pass);
1092}
1093testcase TC_cl3_rnd_payload() runs on MTC_CT {
1094 var BSC_ConnHdlr vc_conn;
1095 f_init();
1096
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001097 vc_conn := f_start_handler(refers(f_tc_cl3_rnd_payload), 26);
Harald Welte1af6ea82018-01-25 18:33:15 +01001098 vc_conn.done;
1099}
1100
Harald Welte116e4332018-01-26 22:17:48 +01001101/* Test Complete L3 with random payload */
1102private function f_tc_establish_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001103 f_init_handler(pars);
Harald Welte116e4332018-01-26 22:17:48 +01001104
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001105 f_perform_lu();
Harald Welte116e4332018-01-26 22:17:48 +01001106
Harald Weltede371492018-01-27 23:44:41 +01001107 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
Harald Welte1ddc7162018-01-27 14:25:46 +01001108 f_expect_clear();
Harald Welte116e4332018-01-26 22:17:48 +01001109}
1110testcase TC_establish_and_nothing() runs on MTC_CT {
1111 var BSC_ConnHdlr vc_conn;
1112 f_init();
1113
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001114 vc_conn := f_start_handler(refers(f_tc_establish_and_nothing), 27);
Harald Welte116e4332018-01-26 22:17:48 +01001115 vc_conn.done;
1116}
1117
Harald Welte12510c52018-01-26 22:26:24 +01001118/* Test MO Call SETUP with no response from MNCC */
1119private function f_tc_mo_setup_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001120 f_init_handler(pars);
1121
Harald Welte12510c52018-01-26 22:26:24 +01001122 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1123
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001124 f_perform_lu();
Harald Welte12510c52018-01-26 22:26:24 +01001125
Harald Weltede371492018-01-27 23:44:41 +01001126 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
Harald Welte12510c52018-01-26 22:26:24 +01001127 f_create_mncc_expect(hex2str(cpars.called_party));
1128 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1129
1130 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1131
Harald Welte1ddc7162018-01-27 14:25:46 +01001132 f_expect_clear(30.0);
Harald Welte12510c52018-01-26 22:26:24 +01001133}
1134testcase TC_mo_setup_and_nothing() runs on MTC_CT {
1135 var BSC_ConnHdlr vc_conn;
1136 f_init();
1137
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001138 vc_conn := f_start_handler(refers(f_tc_mo_setup_and_nothing), 28);
Harald Welte12510c52018-01-26 22:26:24 +01001139 vc_conn.done;
1140}
1141
Harald Welte3ab88002018-01-26 22:37:25 +01001142/* Test MO Call with no response to RAN-side CRCX */
1143private function f_tc_mo_crcx_ran_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001144 f_init_handler(pars);
Harald Welte3ab88002018-01-26 22:37:25 +01001145 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1146 var MNCC_PDU mncc;
1147 var MgcpCommand mgcp_cmd;
1148
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001149 f_perform_lu();
Harald Welte3ab88002018-01-26 22:37:25 +01001150
Harald Weltede371492018-01-27 23:44:41 +01001151 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
Harald Welte3ab88002018-01-26 22:37:25 +01001152 f_create_mncc_expect(hex2str(cpars.called_party));
1153 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1154
1155 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1156 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1157 cpars.mncc_callref := mncc.u.signal.callref;
1158 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1159 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1160
1161 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
Harald Welte1852a842018-01-26 22:53:36 +01001162 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1163 cpars.mgcp_ep := mgcp_cmd.line.ep;
Harald Welte3ab88002018-01-26 22:37:25 +01001164 /* never respond to this */
1165
Philipp Maier8e58f592018-03-14 11:10:56 +01001166 /* When the connection with the MGW fails, the MSC will first request
1167 * a release via call control. We will answer this request normally. */
1168 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1169 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1170
Harald Welte1ddc7162018-01-27 14:25:46 +01001171 f_expect_clear(30.0);
Harald Welte3ab88002018-01-26 22:37:25 +01001172}
1173testcase TC_mo_crcx_ran_timeout() runs on MTC_CT {
1174 var BSC_ConnHdlr vc_conn;
1175 f_init();
1176
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001177 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_timeout), 29);
Harald Welte3ab88002018-01-26 22:37:25 +01001178 vc_conn.done;
1179}
1180
Harald Welte0cc82d92018-01-26 22:52:34 +01001181/* Test MO Call with reject to RAN-side CRCX */
1182private function f_tc_mo_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001183 f_init_handler(pars);
Harald Welte0cc82d92018-01-26 22:52:34 +01001184 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1185 var MNCC_PDU mncc;
1186 var MgcpCommand mgcp_cmd;
1187
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001188 f_perform_lu();
Harald Welte0cc82d92018-01-26 22:52:34 +01001189
Harald Weltede371492018-01-27 23:44:41 +01001190 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
Harald Welte0cc82d92018-01-26 22:52:34 +01001191 f_create_mncc_expect(hex2str(cpars.called_party));
1192 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1193
1194 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1195 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1196 cpars.mncc_callref := mncc.u.signal.callref;
1197 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1198 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1199
1200 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001201
1202 /* Detect if the received CRCX is a wildcarded CRCX request. If yes,
1203 * set an endpoint name that fits the pattern. If not, just use the
1204 * endpoint name from the request */
1205 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
1206 cpars.mgcp_ep := "rtpbridge/1@mgw";
1207 } else {
1208 cpars.mgcp_ep := mgcp_cmd.line.ep;
1209 }
1210
Harald Welte0cc82d92018-01-26 22:52:34 +01001211 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001212
Harald Welte0cc82d92018-01-26 22:52:34 +01001213 /* Respond to CRCX with error */
1214 var MgcpResponse mgcp_rsp := {
1215 line := {
1216 code := "542",
1217 trans_id := mgcp_cmd.line.trans_id,
1218 string := "FORCED_FAIL"
1219 },
Harald Welte0cc82d92018-01-26 22:52:34 +01001220 sdp := omit
1221 }
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001222 var MgcpParameter mgcp_rsp_param := {
1223 code := "Z",
1224 val := cpars.mgcp_ep
1225 };
1226 mgcp_rsp.params[0] := mgcp_rsp_param;
Harald Welte0cc82d92018-01-26 22:52:34 +01001227 MGCP.send(mgcp_rsp);
1228
1229 timer T := 30.0;
1230 T.start;
1231 alt {
1232 [] T.timeout { setverdict(fail, "Timeout waiting for channel release"); self.stop; }
Daniel Willmann5868e622018-02-15 17:42:59 +01001233 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id))) {
1234 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1235 repeat;
1236 }
1237 [] BSSAP.receive {
1238 repeat;
1239 }
Harald Welte0cc82d92018-01-26 22:52:34 +01001240 [] MNCC.receive { repeat; }
1241 [] GSUP.receive { repeat; }
1242 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1243 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1244 f_create_mgcp_delete_ep(cpars.mgcp_ep);
Harald Welteec6e5b42018-01-27 12:45:15 +01001245 repeat;
Harald Welte0cc82d92018-01-26 22:52:34 +01001246 }
1247 [] MGCP.receive { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001248 [] as_clear_cmd_compl_disc();
Harald Welte0cc82d92018-01-26 22:52:34 +01001249 }
1250}
1251testcase TC_mo_crcx_ran_reject() runs on MTC_CT {
1252 var BSC_ConnHdlr vc_conn;
1253 f_init();
1254
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001255 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_reject), 30);
Harald Welte0cc82d92018-01-26 22:52:34 +01001256 vc_conn.done;
1257}
1258
Harald Welte3ab88002018-01-26 22:37:25 +01001259
Harald Welte812f7a42018-01-27 00:49:18 +01001260/* helper function to start a MT call: MNCC SETUP; Paging; DChan est.; DTAP SETUP */
1261private function f_mt_call_start(inout CallParameters cpars) runs on BSC_ConnHdlr {
1262 var MNCC_PDU mncc;
1263 var MgcpCommand mgcp_cmd;
1264 var OCT4 tmsi;
1265
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001266 f_perform_lu();
Harald Welte812f7a42018-01-27 00:49:18 +01001267 if (isvalue(g_pars.tmsi)) {
1268 tmsi := g_pars.tmsi;
1269 } else {
1270 tmsi := 'FFFFFFFF'O;
1271 }
1272 f_bssmap_register_imsi(g_pars.imsi, tmsi);
1273
1274 /* Allocate call reference and send SETUP via MNCC to MSC */
1275 cpars.mncc_callref := f_rnd_int(2147483648);
1276 MNCC.send(ts_MNCC_SETUP_req(cpars.mncc_callref, hex2str(g_pars.msisdn),
1277 hex2str(cpars.called_party), hex2str(g_pars.imsi)));
1278
1279 /* MSC->BSC: expect PAGING from MSC */
1280 BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));
1281 /* MS -> MSC: PAGING RESPONSE */
Harald Welte081b19a2018-02-10 09:11:13 +01001282 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)), EST_TYPE_PAG_RESP);
Harald Welte812f7a42018-01-27 00:49:18 +01001283
1284 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1285
1286 /* MSC->MS: SETUP */
1287 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party)));
1288}
1289
1290/* Test MT Call */
1291private function f_tc_mt_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001292 f_init_handler(pars);
Harald Welte812f7a42018-01-27 00:49:18 +01001293 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1294 var MNCC_PDU mncc;
1295 var MgcpCommand mgcp_cmd;
1296
1297 f_mt_call_start(cpars);
1298
1299 /* MS->MSC: CALL CONFIRMED */
1300 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1301
1302 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1303
1304 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1305 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001306
1307 /* Detect if the received CRCX is a wildcarded CRCX request. If yes,
1308 * set an endpoint name that fits the pattern. If not, just use the
1309 * endpoint name from the request */
1310 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
1311 cpars.mgcp_ep := "rtpbridge/1@mgw";
1312 } else {
1313 cpars.mgcp_ep := mgcp_cmd.line.ep;
1314 }
1315
Harald Welte812f7a42018-01-27 00:49:18 +01001316 /* Respond to CRCX with error */
1317 var MgcpResponse mgcp_rsp := {
1318 line := {
1319 code := "542",
1320 trans_id := mgcp_cmd.line.trans_id,
1321 string := "FORCED_FAIL"
1322 },
Harald Welte812f7a42018-01-27 00:49:18 +01001323 sdp := omit
1324 }
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001325 var MgcpParameter mgcp_rsp_param := {
1326 code := "Z",
1327 val := cpars.mgcp_ep
1328 };
1329 mgcp_rsp.params[0] := mgcp_rsp_param;
Harald Welte812f7a42018-01-27 00:49:18 +01001330 MGCP.send(mgcp_rsp);
1331
1332 timer T := 30.0;
1333 T.start;
1334 alt {
1335 [] T.timeout { setverdict(fail, "Timeout waiting for channel release"); self.stop; }
Harald Welte812f7a42018-01-27 00:49:18 +01001336 [] BSSAP.receive { repeat; }
1337 [] MNCC.receive { repeat; }
1338 [] GSUP.receive { repeat; }
1339 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1340 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1341 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1342 repeat;
1343 }
1344 [] MGCP.receive { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001345 [] as_clear_cmd_compl_disc();
Harald Welte812f7a42018-01-27 00:49:18 +01001346 }
1347}
1348testcase TC_mt_crcx_ran_reject() runs on MTC_CT {
1349 var BSC_ConnHdlr vc_conn;
1350 f_init();
1351
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001352 vc_conn := f_start_handler(refers(f_tc_mt_crcx_ran_reject), 31);
Harald Welte812f7a42018-01-27 00:49:18 +01001353 vc_conn.done;
1354}
1355
1356
1357/* Test MT Call T310 timer */
1358private function f_tc_mt_t310(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltead2952e2018-01-27 14:12:46 +01001359 f_init_handler(pars, 200.0);
Harald Welte812f7a42018-01-27 00:49:18 +01001360 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1361 var MNCC_PDU mncc;
1362 var MgcpCommand mgcp_cmd;
1363
1364 f_mt_call_start(cpars);
1365
1366 /* MS->MSC: CALL CONFIRMED */
1367 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
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);
1372 cpars.mgcp_ep := mgcp_cmd.line.ep;
1373 /* FIXME: Respond to CRCX */
1374
1375 /* old libosmocore T310 default timeout is 180s. so let's wait 190 */
1376 timer T := 190.0;
1377 T.start;
1378 alt {
1379 [] T.timeout { setverdict(fail, "Timeout waiting for T310"); self.stop; }
1380 [] MNCC.receive(tr_MNCC_DISC_ind(cpars.mncc_callref)) {
1381 MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(23))));
1382 }
1383 }
1384 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));
1385 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1386 /* FIXME: We're sending this with TIflag 0: allocated by sender, which is wrong */
1387 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1388
1389 alt {
Harald Welte812f7a42018-01-27 00:49:18 +01001390 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1391 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1392 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1393 repeat;
1394 }
Harald Welte5946b332018-03-18 23:32:21 +01001395 [] as_clear_cmd_compl_disc();
Harald Welte812f7a42018-01-27 00:49:18 +01001396 }
1397}
1398testcase TC_mt_t310() runs on MTC_CT {
1399 var BSC_ConnHdlr vc_conn;
1400 f_init();
1401
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001402 vc_conn := f_start_handler(refers(f_tc_mt_t310), 32);
Harald Welte812f7a42018-01-27 00:49:18 +01001403 vc_conn.done;
1404}
1405
Harald Welte167458a2018-01-27 15:58:16 +01001406/* Perform successful LU + MO call, then GSUP LocationCancel. Subscriber must be denied CM SERV */
1407private function f_tc_gsup_cancel(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1408 f_init_handler(pars);
1409 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1410 cpars.bss_rtp_port := 1110;
1411 cpars.mgcp_connection_id_bss := '22222'H;
1412 cpars.mgcp_connection_id_mss := '33333'H;
1413
1414 /* Location Update to make subscriber known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001415 f_perform_lu();
Harald Welte167458a2018-01-27 15:58:16 +01001416
1417 /* First MO call should succeed */
1418 f_mo_call(cpars);
1419
1420 /* Cancel the subscriber in the VLR */
1421 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1422 alt {
1423 [] GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi)) { }
1424 [] GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi)) {
1425 setverdict(fail, "Received GSUP Location Cancel Error");
1426 self.stop;
1427 }
1428 }
1429
1430 /* Follow-up transactions should fail */
1431 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1432 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
1433 f_bssap_compl_l3(l3_info);
1434 alt {
1435 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
1436 [] BSSAP.receive {
1437 setverdict(fail, "Received unexpected BSSAP instead of CM SERV REJ");
1438 self.stop;
1439 }
1440 }
1441 setverdict(pass);
1442}
1443testcase TC_gsup_cancel() runs on MTC_CT {
1444 var BSC_ConnHdlr vc_conn;
1445 f_init();
1446
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001447 vc_conn := f_start_handler(refers(f_tc_gsup_cancel), 33);
Harald Welte167458a2018-01-27 15:58:16 +01001448 vc_conn.done;
1449}
1450
Harald Welte9de84792018-01-28 01:06:35 +01001451/* A5/1 only permitted on network side, and MS capable to do it */
1452private function f_tc_lu_imsi_auth_tmsi_encr_1_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1453 pars.net.expect_auth := true;
1454 pars.net.expect_ciph := true;
1455 pars.net.kc_support := '02'O; /* A5/1 only */
1456 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001457 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001458}
1459testcase TC_lu_imsi_auth_tmsi_encr_1_13() runs on MTC_CT {
1460 var BSC_ConnHdlr vc_conn;
1461 f_init();
1462 f_vty_config(MSCVTY, "network", "authentication required");
1463 f_vty_config(MSCVTY, "network", "encryption a5 1");
1464
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001465 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_1_13), 34);
Harald Welte9de84792018-01-28 01:06:35 +01001466 vc_conn.done;
1467}
1468
1469/* A5/3 only permitted on network side, and MS capable to do it */
1470private function f_tc_lu_imsi_auth_tmsi_encr_3_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1471 pars.net.expect_auth := true;
1472 pars.net.expect_ciph := true;
1473 pars.net.kc_support := '08'O; /* A5/3 only */
1474 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001475 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001476}
1477testcase TC_lu_imsi_auth_tmsi_encr_3_13() runs on MTC_CT {
1478 var BSC_ConnHdlr vc_conn;
1479 f_init();
1480 f_vty_config(MSCVTY, "network", "authentication required");
1481 f_vty_config(MSCVTY, "network", "encryption a5 3");
1482
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001483 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_13), 35);
Harald Welte9de84792018-01-28 01:06:35 +01001484 vc_conn.done;
1485}
1486
1487/* A5/3 only permitted on network side, and MS with only A5/1 support */
1488private function f_tc_lu_imsi_auth_tmsi_encr_3_1(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1489 pars.net.expect_auth := true;
1490 pars.net.expect_ciph := true;
1491 pars.net.kc_support := '08'O; /* A5/3 only */
1492 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1493 f_init_handler(pars, 15.0);
1494
1495 /* cannot use f_perform_lu() as we expect a reject */
1496 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1497 f_create_gsup_expect(hex2str(g_pars.imsi));
1498 f_bssap_compl_l3(l3_lu);
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001499 if (pars.send_early_cm) {
1500 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1501 } else {
1502 pars.cm1.esind := '0'B;
1503 }
Harald Welte9de84792018-01-28 01:06:35 +01001504 f_mm_auth();
1505 alt {
Harald Welte5946b332018-03-18 23:32:21 +01001506 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1507 f_expect_clear();
1508 }
Harald Welte9de84792018-01-28 01:06:35 +01001509 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1510 setverdict(fail, "CipherModeCommand despite no A5 intersection");
1511 self.stop;
1512 }
1513 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001514 setverdict(fail, "Unknown/unexpected BSSAP received");
Harald Welte9de84792018-01-28 01:06:35 +01001515 self.stop;
1516 }
1517 }
1518 setverdict(pass);
1519}
1520testcase TC_lu_imsi_auth_tmsi_encr_3_1() runs on MTC_CT {
1521 var BSC_ConnHdlr vc_conn;
1522 f_init();
1523 f_vty_config(MSCVTY, "network", "authentication required");
1524 f_vty_config(MSCVTY, "network", "encryption a5 3");
1525
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001526 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 360);
1527 vc_conn.done;
1528}
1529testcase TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() runs on MTC_CT {
1530 var BSC_ConnHdlrPars pars;
1531 var BSC_ConnHdlr vc_conn;
1532 f_init();
1533 f_vty_config(MSCVTY, "network", "authentication required");
1534 f_vty_config(MSCVTY, "network", "encryption a5 3");
1535
1536 pars := f_init_pars(361);
1537 pars.send_early_cm := false;
1538 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 +01001539 vc_conn.done;
1540}
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01001541testcase TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() runs on MTC_CT {
1542 var BSC_ConnHdlr vc_conn;
1543 f_init();
1544 f_vty_config(MSCVTY, "network", "authentication required");
1545 f_vty_config(MSCVTY, "network", "encryption a5 3");
1546
1547 /* Make sure the MSC category is on DEBUG level to trigger the log
1548 * message that is reported in OS#2947 to trigger the segfault */
1549 f_vty_config(MSCVTY, "log stderr", "logging level msc debug");
1550
1551 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 362);
1552 vc_conn.done;
1553}
Harald Welte9de84792018-01-28 01:06:35 +01001554
1555/* A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
1556private function f_tc_lu_imsi_auth_tmsi_encr_13_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1557 pars.net.expect_auth := true;
1558 pars.net.expect_ciph := true;
1559 pars.net.kc_support := '0A'O; /* A5/1 + A5/3 */
1560 pars.cm1.a5_1 := '1'B;
1561 pars.cm2.a5_1 := '1'B;
1562 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1563 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
1564 f_init_handler(pars, 15.0);
1565
1566 /* cannot use f_perform_lu() as we expect a reject */
1567 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1568 f_create_gsup_expect(hex2str(g_pars.imsi));
1569 f_bssap_compl_l3(l3_lu);
1570 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1571 f_mm_auth();
1572 alt {
Harald Welte5946b332018-03-18 23:32:21 +01001573 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1574 f_expect_clear();
1575 }
Harald Welte9de84792018-01-28 01:06:35 +01001576 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1577 setverdict(fail, "CipherModeCommand despite no A5 intersection");
1578 self.stop;
1579 }
1580 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001581 setverdict(fail, "Unknown/unexpected BSSAP received");
Harald Welte9de84792018-01-28 01:06:35 +01001582 self.stop;
1583 }
1584 }
1585 setverdict(pass);
1586}
1587testcase TC_lu_imsi_auth_tmsi_encr_13_2() runs on MTC_CT {
1588 var BSC_ConnHdlr vc_conn;
1589 f_init();
1590 f_vty_config(MSCVTY, "network", "authentication required");
1591 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1592
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001593 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_2), 37);
Harald Welte9de84792018-01-28 01:06:35 +01001594 vc_conn.done;
1595}
1596
1597/* A5/0 + A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
1598private function f_tc_lu_imsi_auth_tmsi_encr_013_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1599 pars.net.expect_auth := true;
1600 pars.net.expect_ciph := true;
1601 pars.net.kc_support := '0B'O; /* A5/1 + A5/3 */
1602 pars.cm1.a5_1 := '1'B;
1603 pars.cm2.a5_1 := '1'B;
1604 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1605 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
1606 f_init_handler(pars, 15.0);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001607 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001608}
1609testcase TC_lu_imsi_auth_tmsi_encr_013_2() runs on MTC_CT {
1610 var BSC_ConnHdlr vc_conn;
1611 f_init();
1612 f_vty_config(MSCVTY, "network", "authentication required");
1613 f_vty_config(MSCVTY, "network", "encryption a5 0 1 3");
1614
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001615 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_013_2), 38);
Harald Welte9de84792018-01-28 01:06:35 +01001616 vc_conn.done;
1617}
1618
Harald Welte33ec09b2018-02-10 15:34:46 +01001619/* LU followed by MT call (including paging) */
1620private function f_tc_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1621 f_init_handler(pars);
1622 //FIXME: odd digits var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1623 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1624 cpars.bss_rtp_port := 1110;
1625 cpars.mgcp_connection_id_bss := '10004'H;
1626 cpars.mgcp_connection_id_mss := '10005'H;
1627
Philipp Maier4b2692d2018-03-14 16:37:48 +01001628 /* Note: This is an optional parameter. When the call-agent (MSC) does
1629 * supply a full endpoint name this setting will be overwritten. */
1630 cpars.mgcp_ep := "rtpbridge/1@mgw";
1631
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001632 f_perform_lu();
Harald Welte33ec09b2018-02-10 15:34:46 +01001633 f_mt_call(cpars);
1634}
1635testcase TC_lu_and_mt_call() runs on MTC_CT {
1636 var BSC_ConnHdlr vc_conn;
1637 f_init();
1638
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001639 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call), 39);
Harald Welte33ec09b2018-02-10 15:34:46 +01001640 vc_conn.done;
1641}
1642
Daniel Willmann8b084372018-02-04 13:35:26 +01001643/* Test MO Call SETUP with DTMF */
1644private function f_tc_mo_setup_dtmf_dup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1645 f_init_handler(pars);
1646 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1647 cpars.bss_rtp_port := 1110;
1648 cpars.mgcp_connection_id_bss := '22222'H;
1649 cpars.mgcp_connection_id_mss := '33333'H;
1650
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001651 f_perform_lu();
Daniel Willmann8b084372018-02-04 13:35:26 +01001652 f_mo_seq_dtmf_dup(cpars);
1653}
1654testcase TC_mo_setup_and_dtmf_dup() runs on MTC_CT {
1655 var BSC_ConnHdlr vc_conn;
1656 f_init();
1657
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001658 vc_conn := f_start_handler(refers(f_tc_mo_setup_dtmf_dup), 39);
Daniel Willmann8b084372018-02-04 13:35:26 +01001659 vc_conn.done;
1660}
Harald Welte9de84792018-01-28 01:06:35 +01001661
Philipp Maier328d1662018-03-07 10:40:27 +01001662testcase TC_cr_before_reset() runs on MTC_CT {
1663 timer T := 4.0;
1664 var boolean reset_ack_seen := false;
1665 f_init_bssap_direct();
1666
1667 /* Make a blind connection attemt, to trigger the deadlock condition */
1668 BSSAP_DIRECT.send(ts_BSSAP_CONNECT_req(g_bssap.sccp_addr_peer, g_bssap.sccp_addr_own, 1, omit));
1669
1670 /* Send a BSSMAP reset */
1671 BSSAP_DIRECT.send(ts_BSSAP_UNITDATA_req(g_bssap.sccp_addr_peer, g_bssap.sccp_addr_own, ts_BSSMAP_Reset(0)));
1672 T.start
1673 alt {
1674 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_ResetAck)) {
1675 reset_ack_seen := true;
1676 repeat;
1677 }
1678
1679 /* Acknowledge MSC sided reset requests */
1680 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) {
1681 BSSAP_DIRECT.send(ts_BSSAP_UNITDATA_req(g_bssap.sccp_addr_peer, g_bssap.sccp_addr_own, ts_BSSMAP_ResetAck));
1682 repeat;
1683 }
1684
1685 /* Ignore all other messages (e.g CR from the connection request) */
1686 [] BSSAP_DIRECT.receive { repeat }
1687
1688 /* If we got no BSSMAP RESET ACK back, then the MSC entered the
1689 * deadlock situation. The MSC is then unable to respond to any
1690 * further BSSMAP RESET or any other sort of traffic. */
1691 [reset_ack_seen == true] T.timeout { setverdict(pass) }
1692 [reset_ack_seen == false] T.timeout {
1693 setverdict(fail, "no BSSMAP RESET ACK seen!");
1694 }
1695 }
1696}
Harald Welte9de84792018-01-28 01:06:35 +01001697
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001698/* Test MO Call with no response to RAN-side CRCX or DTAP Release */
1699private function f_tc_mo_release_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1700 f_init_handler(pars);
1701 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1702 var MNCC_PDU mncc;
1703 var MgcpCommand mgcp_cmd;
1704
1705 f_perform_lu();
1706
1707 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
1708 f_create_mncc_expect(hex2str(cpars.called_party));
1709 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1710
1711 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1712 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1713 cpars.mncc_callref := mncc.u.signal.callref;
1714 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1715 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1716
1717 /* Drop CRCX */
1718 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1719
1720 /* Drop DTAP Release */
1721 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1722
1723 /* Drop resent DTAP Release */
1724 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1725
1726 f_expect_clear(60.0);
1727}
1728testcase TC_mo_release_timeout() runs on MTC_CT {
1729 var BSC_ConnHdlr vc_conn;
1730 f_init();
1731
1732 vc_conn := f_start_handler(refers(f_tc_mo_release_timeout), 40);
1733 vc_conn.done;
1734}
1735
Harald Welte12510c52018-01-26 22:26:24 +01001736
Philipp Maier2a98a732018-03-19 16:06:12 +01001737/* LU followed by MT call (including paging) */
1738private function f_tc_lu_and_mt_call_no_dlcx_resp(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1739 f_init_handler(pars);
1740 //FIXME: odd digits var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1741 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1742 cpars.bss_rtp_port := 1110;
1743 cpars.mgcp_connection_id_bss := '10004'H;
1744 cpars.mgcp_connection_id_mss := '10005'H;
1745
1746 /* Note: This is an optional parameter. When the call-agent (MSC) does
1747 * supply a full endpoint name this setting will be overwritten. */
1748 cpars.mgcp_ep := "rtpbridge/1@mgw";
1749
1750 /* Intentionally disable the CRCX response */
1751 cpars.mgw_drop_dlcx := true;
1752
1753 /* Perform location update and call */
1754 f_perform_lu();
1755 f_mt_call(cpars);
1756}
1757testcase TC_lu_and_mt_call_no_dlcx_resp() runs on MTC_CT {
1758 var BSC_ConnHdlr vc_conn;
1759 f_init();
1760
1761 /* Perform an almost normal looking locationupdate + mt-call, but do
1762 * not respond to the DLCX at the end of the call */
1763 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call_no_dlcx_resp), 41);
1764 vc_conn.done;
1765
1766 /* Wait a guard period until the MGCP layer in the MSC times out,
1767 * if the MSC is vulnerable to the use-after-free situation that is
1768 * fixed by I78f1b6a9149488a4ad3f120c1e190a83c07d4b89 then it should
1769 * segfault now */
1770 f_sleep(6.0);
1771
1772 /* Run the init procedures once more. If the MSC has crashed, this
1773 * this will fail */
1774 f_init();
1775}
Harald Welte45164da2018-01-24 12:51:27 +01001776
Harald Welteba7b6d92018-01-23 21:32:34 +01001777/* TODO:
1778 * continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
1779 * malformed messages (missing IE, invalid message type): properly rejected?
1780 * MT call while LU or is ongoing: Do we use existing lchan or page while lchan active?
1781 * 3G/2G auth permutations
1782 * encryption algorithms vs. classmark vs. vty config
Harald Welteba7b6d92018-01-23 21:32:34 +01001783 * send new transaction after/during clear (like SMS, ...)
Harald Welte45164da2018-01-24 12:51:27 +01001784 * too long L3 INFO in DTAP
1785 * too long / padded BSSAP
1786 * too long / short TLV values
Harald Welteba7b6d92018-01-23 21:32:34 +01001787 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01001788
1789
1790control {
Philipp Maier328d1662018-03-07 10:40:27 +01001791 execute( TC_cr_before_reset() );
Harald Weltea49e36e2018-01-21 19:29:33 +01001792 execute( TC_lu_imsi_noauth_tmsi() );
Harald Welted2328a22018-01-27 14:27:16 +01001793 execute( TC_lu_imsi_noauth_notmsi() );
Harald Weltea49e36e2018-01-21 19:29:33 +01001794 execute( TC_lu_imsi_reject() );
1795 execute( TC_lu_imsi_timeout_gsup() );
Harald Welted2328a22018-01-27 14:27:16 +01001796 execute( TC_lu_imsi_auth_tmsi() );
1797 execute( TC_cmserv_imsi_unknown() );
Harald Welte2bb825f2018-01-22 11:31:18 +01001798 execute( TC_lu_and_mo_call() );
Harald Welte071ed732018-01-23 19:53:52 +01001799 execute( TC_lu_auth_sai_timeout() );
1800 execute( TC_lu_auth_sai_err() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01001801 execute( TC_lu_clear_request() );
1802 execute( TC_lu_disconnect() );
1803 execute( TC_lu_by_imei() );
1804 execute( TC_lu_by_tmsi_noauth_unknown() );
1805 execute( TC_imsi_detach_by_imsi() );
1806 execute( TC_imsi_detach_by_tmsi() );
1807 execute( TC_imsi_detach_by_imei() );
1808 execute( TC_emerg_call_imei_reject() );
1809 execute( TC_emerg_call_imsi() );
1810 execute( TC_cm_serv_req_vgcs_reject() );
1811 execute( TC_cm_serv_req_vbs_reject() );
1812 execute( TC_cm_serv_req_lcs_reject() );
Harald Welte0195ab12018-01-24 21:50:20 +01001813 execute( TC_cm_reest_req_reject() );
Harald Welte1af6ea82018-01-25 18:33:15 +01001814 execute( TC_lu_auth_2G_fail() );
1815 execute( TC_lu_imsi_auth_tmsi_encr_13_13() );
1816 execute( TC_cl3_no_payload() );
1817 execute( TC_cl3_rnd_payload() );
Harald Welte1852a842018-01-26 22:53:36 +01001818 execute( TC_establish_and_nothing() );
1819 execute( TC_mo_setup_and_nothing() );
1820 execute( TC_mo_crcx_ran_timeout() );
1821 execute( TC_mo_crcx_ran_reject() );
Harald Welted2328a22018-01-27 14:27:16 +01001822 execute( TC_mt_crcx_ran_reject() );
Daniel Willmann8b084372018-02-04 13:35:26 +01001823 execute( TC_mo_setup_and_dtmf_dup() );
Harald Welteaa54cf82018-01-30 08:15:32 +01001824 //execute( TC_mt_t310() );
Harald Welte167458a2018-01-27 15:58:16 +01001825 execute( TC_gsup_cancel() );
Harald Welte9de84792018-01-28 01:06:35 +01001826 execute( TC_lu_imsi_auth_tmsi_encr_1_13() );
1827 execute( TC_lu_imsi_auth_tmsi_encr_3_13() );
1828 execute( TC_lu_imsi_auth_tmsi_encr_3_1() );
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001829 execute( TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() );
Harald Welte9de84792018-01-28 01:06:35 +01001830 execute( TC_lu_imsi_auth_tmsi_encr_13_2() );
1831 execute( TC_lu_imsi_auth_tmsi_encr_013_2() );
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001832 execute( TC_mo_release_timeout() );
Philipp Maier2a98a732018-03-19 16:06:12 +01001833 execute( TC_lu_and_mt_call_no_dlcx_resp() );
Harald Welte33ec09b2018-02-10 15:34:46 +01001834
1835 execute( TC_lu_and_mt_call() );
1836
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01001837 /* Run this last: at the time of writing this test crashes the MSC */
1838 execute( TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() );
Harald Weltef6dd64d2017-11-19 12:09:51 +01001839}
1840
1841
1842}