blob: bb28c74962d034f695944c099312c632cffc0082 [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
Philipp Maier75932982018-03-27 14:52:35 +020050const integer NUM_BSC := 2;
51type record of BSSAP_Configuration BSSAP_Configurations;
Harald Weltef6dd64d2017-11-19 12:09:51 +010052
Harald Weltea4ca4462018-02-09 00:17:14 +010053type component MTC_CT extends CTRL_Adapter_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +010054 var boolean g_initialized := false;
Harald Weltea49e36e2018-01-21 19:29:33 +010055
Philipp Maier75932982018-03-27 14:52:35 +020056 var BSSAP_Adapter g_bssap[NUM_BSC];
Harald Weltea4ca4462018-02-09 00:17:14 +010057
Harald Weltea49e36e2018-01-21 19:29:33 +010058 /* no 'adapter_CT' for MNCC or GSUP */
59 var MNCC_Emulation_CT vc_MNCC;
Harald Welte4aa970c2018-01-26 10:38:09 +010060 var MGCP_Emulation_CT vc_MGCP;
Harald Weltea49e36e2018-01-21 19:29:33 +010061 var GSUP_Emulation_CT vc_GSUP;
62 var IPA_Emulation_CT vc_GSUP_IPA;
63
64 /* only to get events from IPA underneath GSUP */
65 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte3ca1c902018-01-24 18:51:27 +010066 /* VTY to MSC */
67 port TELNETasp_PT MSCVTY;
Philipp Maier328d1662018-03-07 10:40:27 +010068
69 /* A port to directly send BSSAP messages. This port is used for
70 * tests that require low level access to sen arbitrary BSSAP
71 * messages. Run f_init_bssap_direct() to connect and initialize */
72 port BSSAP_CODEC_PT BSSAP_DIRECT;
73
74 /* When BSSAP messages are directly sent, then the connection
75 * handler is not active, which means that also no guard timer is
76 * set up. The following timer will serve as a replacement */
77 timer Tguard_direct := 60.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +010078}
79
80modulepar {
Harald Weltea49e36e2018-01-21 19:29:33 +010081 /* remote parameters of IUT */
82 charstring mp_msc_ip := "127.0.0.1";
83 integer mp_msc_ctrl_port := 4255;
84 integer mp_msc_vty_port := 4254;
Harald Weltef6dd64d2017-11-19 12:09:51 +010085
Harald Weltea49e36e2018-01-21 19:29:33 +010086 /* local parameters of emulated HLR */
87 charstring mp_hlr_ip := "127.0.0.1";
88 integer mp_hlr_port := 4222;
Harald Welte6126fb02018-01-27 20:08:24 +010089 charstring mp_mgw_ip := "127.0.0.1";
90 integer mp_mgw_port := 2427;
Harald Weltef6dd64d2017-11-19 12:09:51 +010091
Harald Weltea49e36e2018-01-21 19:29:33 +010092 charstring mp_msc_mncc := "/tmp/mncc";
Harald Weltea4ca4462018-02-09 00:17:14 +010093
Philipp Maier75932982018-03-27 14:52:35 +020094 BSSAP_Configurations mp_bssap_cfg := {
95 {
96 sccp_service_type := "mtp3_itu",
97 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
98 own_pc := 185,
99 own_ssn := 254,
100 peer_pc := 187,
101 peer_ssn := 254,
102 sio := '83'O,
103 rctx := 0
104 },
105 {
106 sccp_service_type := "mtp3_itu",
107 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
108 own_pc := 186,
109 own_ssn := 254,
110 peer_pc := 187,
111 peer_ssn := 254,
112 sio := '83'O,
113 rctx := 1
114 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100115 };
Harald Weltef6dd64d2017-11-19 12:09:51 +0100116}
117
Philipp Maier328d1662018-03-07 10:40:27 +0100118/* altstep for the global guard timer (only used when BSSAP_DIRECT
119 * is used for communication */
120private altstep as_Tguard_direct() runs on MTC_CT {
121 [] Tguard_direct.timeout {
122 setverdict(fail, "Tguard timeout");
123 self.stop;
124 }
125}
Harald Weltef6dd64d2017-11-19 12:09:51 +0100126
Harald Weltea49e36e2018-01-21 19:29:33 +0100127function f_init_mncc(charstring id) runs on MTC_CT {
128 id := id & "-MNCC";
129 var MnccOps ops := {
130 create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
131 unitdata_cb := refers(MNCC_Emulation.DummyUnitdataCallback)
132 }
133
134 vc_MNCC := MNCC_Emulation_CT.create(id);
135 map(vc_MNCC:MNCC, system:MNCC_CODEC_PT);
136 vc_MNCC.start(MNCC_Emulation.main(ops, id, mp_msc_mncc));
Harald Weltef6dd64d2017-11-19 12:09:51 +0100137}
138
Harald Welte4aa970c2018-01-26 10:38:09 +0100139function f_init_mgcp(charstring id) runs on MTC_CT {
140 id := id & "-MGCP";
141 var MGCPOps ops := {
142 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
143 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
144 }
145 var MGCP_conn_parameters pars := {
Harald Welte6126fb02018-01-27 20:08:24 +0100146 callagent_ip := mp_msc_ip,
Harald Welte4aa970c2018-01-26 10:38:09 +0100147 callagent_udp_port := -1,
Harald Welte6126fb02018-01-27 20:08:24 +0100148 mgw_ip := mp_mgw_ip,
149 mgw_udp_port := mp_mgw_port
Harald Welte4aa970c2018-01-26 10:38:09 +0100150 }
151
152 vc_MGCP := MGCP_Emulation_CT.create(id);
153 map(vc_MGCP:MGCP, system:MGCP_CODEC_PT);
154 vc_MGCP.start(MGCP_Emulation.main(ops, pars, id));
155}
156
Harald Weltea49e36e2018-01-21 19:29:33 +0100157function f_init_gsup(charstring id) runs on MTC_CT {
158 id := id & "-GSUP";
159 var GsupOps ops := {
160 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
161 }
162
163 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
164 vc_GSUP := GSUP_Emulation_CT.create(id);
165
166 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
167 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
168 /* we use this hack to get events like ASP_IPA_EVENT_UP */
169 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
170
171 vc_GSUP.start(GSUP_Emulation.main(ops, id));
172 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
173
174 /* wait for incoming connection to GSUP port before proceeding */
175 timer T := 10.0;
176 T.start;
177 alt {
178 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
179 [] T.timeout {
Harald Welte458fd372018-03-21 11:26:23 +0100180 setverdict(fail, "No connection to GSUP Port");
Harald Weltea49e36e2018-01-21 19:29:33 +0100181 self.stop
182 }
183 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100184}
185
Philipp Maier75932982018-03-27 14:52:35 +0200186function f_init(integer num_bsc := 1) runs on MTC_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +0100187
188 if (g_initialized == true) {
189 return;
190 }
191 g_initialized := true;
192
Philipp Maier75932982018-03-27 14:52:35 +0200193 if (num_bsc > NUM_BSC) {
194 setverdict(fail, "excess number of BSC instances requested");
195 }
196
197 for (var integer i := 0; i < num_bsc; i := i + 1) {
198 if (isbound(mp_bssap_cfg[i])) {
199 f_bssap_init(g_bssap[0], mp_bssap_cfg[i], "MSC_Test_" & int2str(i), BSC_BssmapOps);
200 } else {
201 setverdict(fail, "missing BSSAP configuration");
202 }
203 }
204
Harald Weltea49e36e2018-01-21 19:29:33 +0100205 f_ipa_ctrl_start(mp_msc_ip, mp_msc_ctrl_port);
206 f_init_mncc("MSC_Test");
Harald Welte4aa970c2018-01-26 10:38:09 +0100207 f_init_mgcp("MSC_Test");
Harald Weltea49e36e2018-01-21 19:29:33 +0100208 f_init_gsup("MSC_Test");
Harald Welte3ca1c902018-01-24 18:51:27 +0100209
210 map(self:MSCVTY, system:MSCVTY);
211 f_vty_set_prompts(MSCVTY);
212 f_vty_transceive(MSCVTY, "enable");
Harald Welteb14c77a2018-01-25 17:25:44 +0100213
214 /* set some defaults */
215 f_vty_config(MSCVTY, "network", "authentication optional");
216 f_vty_config(MSCVTY, "msc", "assign-tmsi");
217 f_vty_config(MSCVTY, "network", "encryption a5 0");
Harald Weltef6dd64d2017-11-19 12:09:51 +0100218}
219
Philipp Maier328d1662018-03-07 10:40:27 +0100220/* Initialize for a direct connection to BSSAP. This function is an alternative
221 * to f_init() when the high level functions of the BSC_ConnectionHandler are
222 * not needed. */
223function f_init_bssap_direct() runs on MTC_CT {
Philipp Maier75932982018-03-27 14:52:35 +0200224 f_bssap_init(g_bssap[0], mp_bssap_cfg[0], "MSC_Test", omit);
225 connect(g_bssap[0].vc_SCCP:SCCP_SP_PORT, self:BSSAP_DIRECT);
Philipp Maier328d1662018-03-07 10:40:27 +0100226
227 /* Start guard timer and activate it as default */
228 Tguard_direct.start
229 activate(as_Tguard_direct());
230}
231
Harald Weltef6dd64d2017-11-19 12:09:51 +0100232template PDU_BSSAP ts_BSSAP_BSSMAP := {
233 discriminator := '0'B,
234 spare := '0000000'B,
235 dlci := omit,
236 lengthIndicator := 0, /* overwritten by codec */
237 pdu := ?
238}
239
240template PDU_BSSAP tr_BSSAP_BSSMAP := {
241 discriminator := '0'B,
242 spare := '0000000'B,
243 dlci := omit,
244 lengthIndicator := ?,
245 pdu := {
246 bssmap := ?
247 }
248}
249
250
251type integer BssmapCause;
252
253template (value) BSSMAP_IE_Cause ts_BSSMAP_IE_Cause(BssmapCause val) := {
254 elementIdentifier := '04'O,
255 lengthIndicator := 0,
256 causeValue := int2bit(val, 7),
257 extensionCauseValue := '0'B,
258 spare1 := omit
259}
260
261template (value) PDU_BSSAP ts_BSSMAP_Reset(BssmapCause cause) modifies ts_BSSAP_BSSMAP := {
262 pdu := {
263 bssmap := {
264 reset := {
265 messageType := '30'O,
266 cause := ts_BSSMAP_IE_Cause(cause),
267 a_InterfaceSelectorForReset := omit
268 }
269 }
270 }
271}
272
273template (value) PDU_BSSAP ts_BSSMAP_ResetAck modifies ts_BSSAP_BSSMAP := {
274 pdu := {
275 bssmap := {
276 resetAck := {
277 messageType := '31'O,
278 a_InterfaceSelectorForReset := omit
279 }
280 }
281 }
282}
283
284template PDU_BSSAP tr_BSSMAP_ResetAck modifies tr_BSSAP_BSSMAP := {
285 pdu := {
286 bssmap := {
287 resetAck := {
288 messageType := '31'O,
289 a_InterfaceSelectorForReset := *
290 }
291 }
292 }
293}
294
295template BSSMAP_IE_CellIdentifier ts_BSSMAP_IE_CellID := {
296 elementIdentifier := '05'O,
297 lengthIndicator := 0,
298 cellIdentifierDiscriminator := '0000'B,
299 spare1_4 := '0000'B,
300 cellIdentification := ?
301}
302
303type uint16_t BssmapLAC;
304type uint16_t BssmapCI;
305
306/*
307template BSSMAP_IE_CellIdentifier ts_CellId_CGI(mcc, mnc, lac, ci)
308modifies ts_BSSMAP_IE_CellID := {
309 cellIdentification := {
310 cI_LAC_CGI := {
311 mnc_mcc := FIXME,
312 lac := int2oct(lac, 2),
313 ci := int2oct(ci, 2)
314 }
315 }
316}
317*/
318
319template BSSMAP_IE_CellIdentifier ts_CellID_LAC_CI(BssmapLAC lac, BssmapCI ci)
320modifies ts_BSSMAP_IE_CellID := {
321 cellIdentification := {
322 cI_LAC_CI := {
323 lac := int2oct(lac, 2),
324 ci := int2oct(ci, 2)
325 }
326 }
327}
328
329template BSSMAP_IE_CellIdentifier ts_CellId_CI(BssmapCI ci)
330modifies ts_BSSMAP_IE_CellID := {
331 cellIdentification := {
332 cI_CI := int2oct(ci, 2)
333 }
334}
335
336template BSSMAP_IE_CellIdentifier ts_CellId_none
337modifies ts_BSSMAP_IE_CellID := {
338 cellIdentification := {
339 cI_noCell := ''O
340 }
341}
342
343
344template BSSMAP_IE_Layer3Information ts_BSSMAP_IE_L3Info(octetstring l3info) := {
345 elementIdentifier := '17'O,
346 lengthIndicator := 0,
347 layer3info := l3info
348}
349
350template PDU_BSSAP ts_BSSMAP_ComplL3(BSSMAP_IE_CellIdentifier cell_id, octetstring l3_info)
351modifies ts_BSSAP_BSSMAP := {
352 pdu := {
353 bssmap := {
354 completeLayer3Information := {
355 messageType := '57'O,
356 cellIdentifier := cell_id,
357 layer3Information := ts_BSSMAP_IE_L3Info(l3_info),
358 chosenChannel := omit,
359 lSAIdentifier := omit,
360 aPDU := omit,
361 codecList := omit,
362 redirectAttemptFlag := omit,
363 sendSequenceNumber := omit,
364 iMSI := omit
365 }
366 }
367 }
368}
369
370template PDU_BSSAP ts_BSSMAP_HandoReq(BssmapCause cause, BSSMAP_IE_CellIdentifierList cid_list)
371modifies ts_BSSAP_BSSMAP := {
372 pdu := {
373 bssmap := {
374 handoverRequired := {
375 messageType := '11'O,
376 cause := ts_BSSMAP_IE_Cause(cause),
377 responseRequest := omit,
378 cellIdentifierList := cid_list,
379 circuitPoolList := omit,
380 currentChannelType1 := omit,
381 speechVersion := omit,
382 queueingIndicator := omit,
383 oldToNewBSSInfo := omit,
384 sourceToTargetRNCTransparentInfo := omit,
385 sourceToTargetRNCTransparentInfoCDMA := omit,
386 gERANClassmark := omit,
387 talkerPriority := omit,
388 speechCodec := omit,
389 cSG_Identifier := omit
390 }
391 }
392 }
393}
394
Harald Weltea49e36e2018-01-21 19:29:33 +0100395type function void_fn(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100396
Harald Weltea49e36e2018-01-21 19:29:33 +0100397/* FIXME: move into BSC_ConnectionHandler? */
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100398function f_init_pars(integer imsi_suffix) runs on MTC_CT return BSC_ConnHdlrPars {
Harald Weltede371492018-01-27 23:44:41 +0100399 var BSC_ConnHdlrNetworkPars net_pars := {
400 kc_support := '0A'O, /* A5/1 and A5/3 enabled */
401 expect_tmsi := true,
402 expect_auth := false,
403 expect_ciph := false
404 };
Harald Weltea49e36e2018-01-21 19:29:33 +0100405 var BSC_ConnHdlrPars pars := {
Philipp Maier75932982018-03-27 14:52:35 +0200406 sccp_addr_own := g_bssap[0].sccp_addr_own,
407 sccp_addr_peer := g_bssap[0].sccp_addr_peer,
Harald Welteedbab812018-03-18 16:02:25 +0100408 cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42)),
Harald Welte81b7f9d2018-01-24 19:06:24 +0100409 imei := f_gen_imei(imsi_suffix),
410 imsi := f_gen_imsi(imsi_suffix),
411 msisdn := f_gen_msisdn(imsi_suffix),
Harald Welte256571e2018-01-24 18:47:19 +0100412 tmsi := omit,
Harald Welte9de84792018-01-28 01:06:35 +0100413 cm1 := valueof(ts_CM1),
Harald Welte82600572018-01-21 20:54:08 +0100414 cm2 := valueof(ts_CM2_default),
Harald Welte16114282018-01-24 22:41:21 +0100415 cm3 := omit,
Harald Weltede371492018-01-27 23:44:41 +0100416 vec := omit,
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100417 net := net_pars,
418 send_early_cm := true
Harald Weltea49e36e2018-01-21 19:29:33 +0100419 };
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100420 return pars;
421}
422
423function f_start_handler_with_pars(void_fn fn, BSC_ConnHdlrPars pars) runs on MTC_CT return BSC_ConnHdlr {
424 var BSC_ConnHdlr vc_conn;
425 var charstring id := testcasename();
Harald Weltea49e36e2018-01-21 19:29:33 +0100426
427 vc_conn := BSC_ConnHdlr.create(id);
428 /* BSSMAP part / A interface */
Philipp Maier75932982018-03-27 14:52:35 +0200429 connect(vc_conn:BSSAP, g_bssap[0].vc_BSSMAP:CLIENT);
430 connect(vc_conn:BSSAP_PROC, g_bssap[0].vc_BSSMAP:PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100431 /* MNCC part */
432 connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
433 connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);
Harald Welte4aa970c2018-01-26 10:38:09 +0100434 /* MGCP part */
435 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
436 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100437 /* GSUP part */
438 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
439 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
440
Harald Weltea10db902018-01-27 12:44:49 +0100441 /* We cannot use vc_conn.start(f_init_handler(fn, id, pars)); as we cannot have
442 * a stand-alone 'derefers()' call, see https://www.eclipse.org/forums/index.php/t/1091364/ */
Harald Weltea49e36e2018-01-21 19:29:33 +0100443 vc_conn.start(derefers(fn)(id, pars));
444 return vc_conn;
445}
446
Neels Hofmeyr9adaa702018-03-01 20:23:19 +0100447function f_start_handler(void_fn fn, integer imsi_suffix) runs on MTC_CT return BSC_ConnHdlr {
448 return f_start_handler_with_pars(fn, f_init_pars(imsi_suffix));
449}
450
Harald Weltea49e36e2018-01-21 19:29:33 +0100451private function f_tc_lu_imsi_noauth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100452 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100453 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100454}
Harald Weltea49e36e2018-01-21 19:29:33 +0100455testcase TC_lu_imsi_noauth_tmsi() runs on MTC_CT {
456 var BSC_ConnHdlr vc_conn;
457 f_init();
458
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100459 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi), 1);
Harald Weltea49e36e2018-01-21 19:29:33 +0100460 vc_conn.done;
461}
462
463private function f_tc_lu_imsi_noauth_notmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100464 pars.net.expect_tmsi := false;
Harald Weltea10db902018-01-27 12:44:49 +0100465 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100466 f_perform_lu();
Harald Weltea49e36e2018-01-21 19:29:33 +0100467}
Harald Weltea49e36e2018-01-21 19:29:33 +0100468testcase TC_lu_imsi_noauth_notmsi() runs on MTC_CT {
469 var BSC_ConnHdlr vc_conn;
470 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100471 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
Harald Weltea49e36e2018-01-21 19:29:33 +0100472
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100473 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi), 2);
Harald Weltea49e36e2018-01-21 19:29:33 +0100474 vc_conn.done;
475}
476
477/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
478private function f_tc_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100479 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100480 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
481
482 f_create_gsup_expect(hex2str(g_pars.imsi));
483 f_bssap_compl_l3(l3_lu);
484 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
485 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
486 alt {
Harald Welte5946b332018-03-18 23:32:21 +0100487 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej(int2oct(23,1)))) {
488 f_expect_clear();
489 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100490 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
491 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
492 self.stop;
493 }
494 }
Harald Welte1ddc7162018-01-27 14:25:46 +0100495 f_expect_clear();
Harald Weltea49e36e2018-01-21 19:29:33 +0100496}
497testcase TC_lu_imsi_reject() runs on MTC_CT {
498 var BSC_ConnHdlr vc_conn;
499 f_init();
500
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100501 vc_conn := f_start_handler(refers(f_tc_lu_imsi_reject), 3);
Harald Weltea49e36e2018-01-21 19:29:33 +0100502 vc_conn.done;
503}
504
505/* Do LU by IMSI, timeout on GSUP */
506private function f_tc_lu_imsi_timeout_gsup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100507 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100508 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
509
510 f_create_gsup_expect(hex2str(g_pars.imsi));
511 f_bssap_compl_l3(l3_lu);
512 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
513 /* Normally the HLR would need to respond here, but we decide to force a timeout here */
514 alt {
515 /* FIXME: Expect specific reject cause */
Harald Welte5946b332018-03-18 23:32:21 +0100516 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
517 f_expect_clear();
518 }
Harald Weltea49e36e2018-01-21 19:29:33 +0100519 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
520 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
521 self.stop;
522 }
523 }
Harald Welte1ddc7162018-01-27 14:25:46 +0100524 f_expect_clear();
Harald Weltea49e36e2018-01-21 19:29:33 +0100525}
526testcase TC_lu_imsi_timeout_gsup() runs on MTC_CT {
527 var BSC_ConnHdlr vc_conn;
528 f_init();
529
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100530 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_gsup), 4);
Harald Weltea49e36e2018-01-21 19:29:33 +0100531 vc_conn.done;
532}
533
Harald Welte7b1b2812018-01-22 21:23:06 +0100534private function f_tc_lu_imsi_auth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltede371492018-01-27 23:44:41 +0100535 pars.net.expect_auth := true;
Harald Weltea10db902018-01-27 12:44:49 +0100536 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100537 f_perform_lu();
Harald Welte7b1b2812018-01-22 21:23:06 +0100538}
539testcase TC_lu_imsi_auth_tmsi() runs on MTC_CT {
540 var BSC_ConnHdlr vc_conn;
541 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100542 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte7b1b2812018-01-22 21:23:06 +0100543
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100544 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi), 5);
Harald Welte7b1b2812018-01-22 21:23:06 +0100545 vc_conn.done;
546}
547
Harald Weltea49e36e2018-01-21 19:29:33 +0100548
549/* Send CM SERVICE REQ for IMSI that has never performed LU before */
550private function f_tc_cmserv_imsi_unknown(charstring id, BSC_ConnHdlrPars pars)
551runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100552 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100553
554 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welteedbab812018-03-18 16:02:25 +0100555 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '42'H, 23, 42));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100556 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltea49e36e2018-01-21 19:29:33 +0100557
558 f_create_gsup_expect(hex2str(g_pars.imsi));
559
560 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
561 f_bssap_compl_l3(l3_info);
562
563 timer T := 10.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100564 T.start;
565 alt {
Harald Weltea49e36e2018-01-21 19:29:33 +0100566 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
567 //[] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC)) { }
568 [] BSSAP.receive { setverdict(fail, "Received unexpected BSSAP"); }
569 [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
570 setverdict(fail, "Unexpected GSUP UL REQ");
571 }
Daniel Willmann90829d62018-02-15 17:45:14 +0100572 [] T.timeout { setverdict(fail, "Timeout waiting for CM SERV REQ"); }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100573 }
574
Harald Welte1ddc7162018-01-27 14:25:46 +0100575 f_expect_clear();
Harald Weltef6dd64d2017-11-19 12:09:51 +0100576}
Harald Weltea49e36e2018-01-21 19:29:33 +0100577testcase TC_cmserv_imsi_unknown() runs on MTC_CT {
578 var BSC_ConnHdlr vc_conn;
579 f_init();
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100580 vc_conn := f_start_handler(refers(f_tc_cmserv_imsi_unknown), 6);
Harald Weltea49e36e2018-01-21 19:29:33 +0100581 vc_conn.done;
582}
583
Harald Welte2bb825f2018-01-22 11:31:18 +0100584private function f_tc_lu_and_mo_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100585 f_init_handler(pars);
Harald Welteb71901a2018-01-26 19:16:05 +0100586 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
587 cpars.bss_rtp_port := 1110;
588 cpars.mgcp_connection_id_bss := '22222'H;
589 cpars.mgcp_connection_id_mss := '33333'H;
Philipp Maierf1e02bb2018-03-15 16:30:00 +0100590 cpars.mgcp_ep := "rtpbridge/1@mgw";
Harald Welte2bb825f2018-01-22 11:31:18 +0100591
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100592 f_perform_lu();
Harald Welteb71901a2018-01-26 19:16:05 +0100593 f_mo_call(cpars);
Harald Welte2bb825f2018-01-22 11:31:18 +0100594}
595testcase TC_lu_and_mo_call() runs on MTC_CT {
596 var BSC_ConnHdlr vc_conn;
597 f_init();
598
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100599 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_call), 7);
Harald Welte071ed732018-01-23 19:53:52 +0100600 vc_conn.done;
601}
602
603/* Test LU (with authentication enabled), where HLR times out sending SAI response */
604private function f_tc_lu_auth_sai_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100605 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100606
607 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
608 var PDU_DTAP_MT dtap_mt;
609
610 /* tell GSUP dispatcher to send this IMSI to us */
611 f_create_gsup_expect(hex2str(g_pars.imsi));
612
613 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
614 f_bssap_compl_l3(l3_lu);
615
616 /* Send Early Classmark, just for the fun of it */
617 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
618
619 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
620 /* The HLR would normally return an auth vector here, but we fail to do so. */
621
622 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100623 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100624}
625testcase TC_lu_auth_sai_timeout() runs on MTC_CT {
626 var BSC_ConnHdlr vc_conn;
627 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100628 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100629
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100630 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_timeout), 8);
Harald Welte071ed732018-01-23 19:53:52 +0100631 vc_conn.done;
632}
633
634/* Test LU (with authentication enabled), where HLR rejects sending SAI error */
635private function f_tc_lu_auth_sai_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100636 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100637
638 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
639 var PDU_DTAP_MT dtap_mt;
640
641 /* tell GSUP dispatcher to send this IMSI to us */
642 f_create_gsup_expect(hex2str(g_pars.imsi));
643
644 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
645 f_bssap_compl_l3(l3_lu);
646
647 /* Send Early Classmark, just for the fun of it */
648 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
649
650 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
651 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 13));
652
653 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100654 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100655}
656testcase TC_lu_auth_sai_err() runs on MTC_CT {
657 var BSC_ConnHdlr vc_conn;
658 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100659 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100660
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100661 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_err), 9);
Harald Welte2bb825f2018-01-22 11:31:18 +0100662 vc_conn.done;
663}
Harald Weltea49e36e2018-01-21 19:29:33 +0100664
Harald Weltebc881782018-01-23 20:09:15 +0100665/* Test LU but BSC will send a clear request in the middle */
666private function f_tc_lu_clear_request(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100667 f_init_handler(pars);
Harald Weltebc881782018-01-23 20:09:15 +0100668
669 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
670 var PDU_DTAP_MT dtap_mt;
671
672 /* tell GSUP dispatcher to send this IMSI to us */
673 f_create_gsup_expect(hex2str(g_pars.imsi));
674
675 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
676 f_bssap_compl_l3(l3_lu);
677
678 /* Send Early Classmark, just for the fun of it */
679 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
680
681 f_sleep(1.0);
682 /* send clear request in the middle of the LU */
683 BSSAP.send(ts_BSSMAP_ClearRequest(0));
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200684 alt {
685 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { repeat; }
686 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {}
687 }
Harald Weltebc881782018-01-23 20:09:15 +0100688 BSSAP.send(ts_BSSMAP_ClearComplete);
Harald Welte89a32492018-01-27 19:07:28 +0100689 alt {
690 /* See https://osmocom.org/issues/2862 */
Neels Hofmeyr2b326fa2018-04-06 00:59:36 +0200691 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
692 setverdict(fail, "Got a second Clear Command, only one expected");
693 repeat;
694 }
Harald Welte89a32492018-01-27 19:07:28 +0100695 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
696 }
Harald Weltebc881782018-01-23 20:09:15 +0100697 setverdict(pass);
698}
699testcase TC_lu_clear_request() runs on MTC_CT {
700 var BSC_ConnHdlr vc_conn;
701 f_init();
702
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100703 vc_conn := f_start_handler(refers(f_tc_lu_clear_request), 10);
Harald Weltebc881782018-01-23 20:09:15 +0100704 vc_conn.done;
705}
706
Harald Welte66af9e62018-01-24 17:28:21 +0100707/* Test LU but BSC will send a clear request in the middle */
708private function f_tc_lu_disconnect(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100709 f_init_handler(pars);
Harald Welte66af9e62018-01-24 17:28:21 +0100710
711 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
712 var PDU_DTAP_MT dtap_mt;
713
714 /* tell GSUP dispatcher to send this IMSI to us */
715 f_create_gsup_expect(hex2str(g_pars.imsi));
716
717 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
718 f_bssap_compl_l3(l3_lu);
719
720 /* Send Early Classmark, just for the fun of it */
721 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
722
723 f_sleep(1.0);
724 /* send clear request in the middle of the LU */
725 BSSAP.send(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
726 setverdict(pass);
727}
728testcase TC_lu_disconnect() runs on MTC_CT {
729 var BSC_ConnHdlr vc_conn;
730 f_init();
731
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100732 vc_conn := f_start_handler(refers(f_tc_lu_disconnect), 11);
Harald Welte66af9e62018-01-24 17:28:21 +0100733 vc_conn.done;
734}
735
736
Harald Welteba7b6d92018-01-23 21:32:34 +0100737/* Test LU but with illegal mobile identity type = IMEI */
738private function f_tc_lu_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100739 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100740
Harald Welte256571e2018-01-24 18:47:19 +0100741 var PDU_ML3_MS_NW l3_lu := f_build_lu_imei(g_pars.imei)
Harald Welteba7b6d92018-01-23 21:32:34 +0100742 var PDU_DTAP_MT dtap_mt;
743
744 /* tell GSUP dispatcher to send this IMSI to us */
745 f_create_gsup_expect(hex2str(g_pars.imsi));
746
747 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
748 f_bssap_compl_l3(l3_lu);
749
750 /* Send Early Classmark, just for the fun of it */
751 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
752 /* wait for LU reject, ignore any ID REQ */
753 alt {
754 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
755 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req)) { repeat; }
756 }
757 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100758 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100759}
760testcase TC_lu_by_imei() runs on MTC_CT {
761 var BSC_ConnHdlr vc_conn;
762 f_init();
763
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100764 vc_conn := f_start_handler(refers(f_tc_lu_by_imei), 12);
Harald Welteba7b6d92018-01-23 21:32:34 +0100765 vc_conn.done;
766}
767
768/* Test LU by TMSI with unknown TMSI, expect (and answer) ID REQ. */
769private function f_tc_lu_tmsi_noauth_unknown(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100770 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100771
772 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('01020304'O); /* FIXME: Random */
773 var PDU_DTAP_MT dtap_mt;
774
775 /* tell GSUP dispatcher to send this IMSI to us */
776 f_create_gsup_expect(hex2str(g_pars.imsi));
777
778 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
779 f_bssap_compl_l3(l3_lu);
780
781 /* Send Early Classmark, just for the fun of it */
782 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
783
784 /* Wait for + respond to ID REQ (IMSI) */
785 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req('001'B)));
786 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
787
788 /* Expect MSC to do UpdateLocation to HLR; respond to it */
789 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
790 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
791 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
792 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
793
794 alt {
Harald Welte7ec4fa82018-01-27 10:57:40 +0100795 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
796 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
797 }
Harald Welteba7b6d92018-01-23 21:32:34 +0100798 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
799 setverdict(fail, "Expected LU ACK, but received REJ");
800 }
801 }
802
803 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100804 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100805}
806testcase TC_lu_by_tmsi_noauth_unknown() runs on MTC_CT {
807 var BSC_ConnHdlr vc_conn;
808 f_init();
809
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100810 vc_conn := f_start_handler(refers(f_tc_lu_tmsi_noauth_unknown), 13);
Harald Welteba7b6d92018-01-23 21:32:34 +0100811 vc_conn.done;
812}
813
814
Harald Welte45164da2018-01-24 12:51:27 +0100815/* Test IMSI DETACH (MI=IMSI) */
816private function f_tc_imsi_detach_by_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100817 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100818
819 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
820
821 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
822 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
823
824 /* Send Early Classmark, just for the fun of it? */
825 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
826
827 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100828 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100829}
830testcase TC_imsi_detach_by_imsi() runs on MTC_CT {
831 var BSC_ConnHdlr vc_conn;
832 f_init();
833
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100834 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imsi), 14);
Harald Welte45164da2018-01-24 12:51:27 +0100835 vc_conn.done;
836}
837
838/* Test IMSI DETACH (MI=TMSI) */
839private function f_tc_imsi_detach_by_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100840 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100841
842 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('01020304'O));
843
844 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
845 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
846
847 /* Send Early Classmark, just for the fun of it? */
848 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
849
850 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100851 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100852}
853testcase TC_imsi_detach_by_tmsi() runs on MTC_CT {
854 var BSC_ConnHdlr vc_conn;
855 f_init();
856
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100857 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_tmsi), 15);
Harald Welte45164da2018-01-24 12:51:27 +0100858 vc_conn.done;
859}
860
861/* Test IMSI DETACH (MI=IMEI), which is illegal */
862private function f_tc_imsi_detach_by_imei(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 Welte45164da2018-01-24 12:51:27 +0100866
867 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
868 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
869
870 /* Send Early Classmark, just for the fun of it? */
871 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
872
873 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100874 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100875}
876testcase TC_imsi_detach_by_imei() runs on MTC_CT {
877 var BSC_ConnHdlr vc_conn;
878 f_init();
879
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100880 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imei), 16);
Harald Welte45164da2018-01-24 12:51:27 +0100881 vc_conn.done;
882}
883
884
885/* helper function for an emergency call. caller passes in mobile identity to use */
886private function f_emerg_call(MobileIdentityLV mi) runs on BSC_ConnHdlr {
Harald Welte0bef21e2018-02-10 09:48:23 +0100887 var CallParameters cpars := valueof(t_CallParams('112'H, 0));
888 cpars.emergency := true;
Philipp Maierf1e02bb2018-03-15 16:30:00 +0100889 cpars.mgcp_ep := "rtpbridge/1@mgw";
Harald Welte45164da2018-01-24 12:51:27 +0100890
Harald Welte0bef21e2018-02-10 09:48:23 +0100891 f_mo_call(cpars);
Harald Welte45164da2018-01-24 12:51:27 +0100892}
893
894/* establish an emergency call by IMEI, no SIM inserted (and hence no IMSI) */
895private function f_tc_emerg_call_imei_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100896 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100897
Harald Welte256571e2018-01-24 18:47:19 +0100898 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100899 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100900 f_bssap_compl_l3(l3_info);
901 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ('05'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +0100902 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100903}
904testcase TC_emerg_call_imei_reject() runs on MTC_CT {
905 var BSC_ConnHdlr vc_conn;
906 f_init();
907
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100908 vc_conn := f_start_handler(refers(f_tc_emerg_call_imei_reject), 17);
Harald Welte45164da2018-01-24 12:51:27 +0100909 vc_conn.done;
910}
911
Harald Welted5b91402018-01-24 18:48:16 +0100912/* establish an emergency call by IMSI, SIM inserted (and hence IMSI) */
Harald Welte45164da2018-01-24 12:51:27 +0100913private function f_tc_emerg_call_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100914 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100915 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100916 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +0100917 /* Then issue emergency call identified by IMSI */
918 f_emerg_call(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
919}
920testcase TC_emerg_call_imsi() runs on MTC_CT {
921 var BSC_ConnHdlr vc_conn;
922 f_init();
923
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100924 vc_conn := f_start_handler(refers(f_tc_emerg_call_imsi), 18);
Harald Welte45164da2018-01-24 12:51:27 +0100925 vc_conn.done;
926}
927
928/* CM Service Request for VGCS -> reject */
929private function f_tc_cm_serv_req_vgcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100930 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100931
932 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100933 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +0100934
935 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100936 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VGCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100937 f_bssap_compl_l3(l3_info);
938 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100939 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100940}
941testcase TC_cm_serv_req_vgcs_reject() runs on MTC_CT {
942 var BSC_ConnHdlr vc_conn;
943 f_init();
944
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100945 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vgcs_reject), 19);
Harald Welte45164da2018-01-24 12:51:27 +0100946 vc_conn.done;
947}
948
949/* CM Service Request for VBS -> reject */
950private function f_tc_cm_serv_req_vbs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100951 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100952
953 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100954 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +0100955
956 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100957 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VBS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100958 f_bssap_compl_l3(l3_info);
959 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100960 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100961}
962testcase TC_cm_serv_req_vbs_reject() runs on MTC_CT {
963 var BSC_ConnHdlr vc_conn;
964 f_init();
965
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100966 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vbs_reject), 20);
Harald Welte45164da2018-01-24 12:51:27 +0100967 vc_conn.done;
968}
969
970/* CM Service Request for LCS -> reject */
971private function f_tc_cm_serv_req_lcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100972 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100973
974 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100975 f_perform_lu();
Harald Welte45164da2018-01-24 12:51:27 +0100976
977 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100978 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_LCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100979 f_bssap_compl_l3(l3_info);
980 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100981 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100982}
983testcase TC_cm_serv_req_lcs_reject() runs on MTC_CT {
984 var BSC_ConnHdlr vc_conn;
985 f_init();
986
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +0100987 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_lcs_reject), 21);
Harald Welte45164da2018-01-24 12:51:27 +0100988 vc_conn.done;
989}
990
Harald Welte0195ab12018-01-24 21:50:20 +0100991/* CM Re-Establishment Request */
992private function f_tc_cm_reest_req_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100993 f_init_handler(pars);
Harald Welte0195ab12018-01-24 21:50:20 +0100994
995 /* First perform location update to ensure subscriber is known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +0100996 f_perform_lu();
Harald Welte0195ab12018-01-24 21:50:20 +0100997
998 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
999 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REEST_REQ(0, mi));
1000 f_bssap_compl_l3(l3_info);
1001 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +01001002 f_expect_clear();
Harald Welte0195ab12018-01-24 21:50:20 +01001003}
1004testcase TC_cm_reest_req_reject() runs on MTC_CT {
1005 var BSC_ConnHdlr vc_conn;
1006 f_init();
Harald Welte0195ab12018-01-24 21:50:20 +01001007
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001008 vc_conn := f_start_handler(refers(f_tc_cm_reest_req_reject), 22);
Harald Welte0195ab12018-01-24 21:50:20 +01001009 vc_conn.done;
1010}
1011
Harald Weltec638f4d2018-01-24 22:00:36 +01001012/* Test LU (with authentication enabled), with wrong response from MS */
1013private function f_tc_lu_auth_2G_fail(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001014 f_init_handler(pars);
Harald Weltec638f4d2018-01-24 22:00:36 +01001015
1016 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
1017
1018 /* tell GSUP dispatcher to send this IMSI to us */
1019 f_create_gsup_expect(hex2str(g_pars.imsi));
1020
1021 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
1022 f_bssap_compl_l3(l3_lu);
1023
1024 /* Send Early Classmark, just for the fun of it */
1025 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1026
1027 var AuthVector vec := f_gen_auth_vec_2g();
1028 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(vec.rand, vec.sres, vec.kc));
1029 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
1030 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
1031
1032 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(vec.rand)));
1033 /* Send back wrong auth response */
1034 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G('00000000'O)));
1035
1036 /* Expect GSUP AUTH FAIL REP to HLR */
1037 GSUP.receive(tr_GSUP_AUTH_FAIL_IND(g_pars.imsi));
1038
1039 /* Expect LU REJECT with Cause == Illegal MS */
1040 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej('03'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +01001041 f_expect_clear();
Harald Weltec638f4d2018-01-24 22:00:36 +01001042}
1043testcase TC_lu_auth_2G_fail() runs on MTC_CT {
1044 var BSC_ConnHdlr vc_conn;
1045 f_init();
1046 f_vty_config(MSCVTY, "network", "authentication required");
Harald Weltec638f4d2018-01-24 22:00:36 +01001047
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001048 vc_conn := f_start_handler(refers(f_tc_lu_auth_2G_fail), 23);
Harald Weltec638f4d2018-01-24 22:00:36 +01001049 vc_conn.done;
1050}
1051
Harald Weltede371492018-01-27 23:44:41 +01001052/* A5/1 + A5/3 permitted on network side, and MS capable to do it */
Harald Welte16114282018-01-24 22:41:21 +01001053private 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 +01001054 pars.net.expect_auth := true;
1055 pars.net.expect_ciph := true;
Harald Weltea10db902018-01-27 12:44:49 +01001056 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001057 f_perform_lu();
Harald Welte16114282018-01-24 22:41:21 +01001058}
1059testcase TC_lu_imsi_auth_tmsi_encr_13_13() runs on MTC_CT {
1060 var BSC_ConnHdlr vc_conn;
1061 f_init();
1062 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte16114282018-01-24 22:41:21 +01001063 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1064
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001065 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_13), 24);
Harald Welte16114282018-01-24 22:41:21 +01001066 vc_conn.done;
1067}
1068
Harald Welte1af6ea82018-01-25 18:33:15 +01001069/* Test Complete L3 without payload */
1070private function f_tc_cl3_no_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001071 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001072
1073 /* Send Complete L3 Info with empty L3 frame */
1074 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1075 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, ''O))));
1076
Harald Weltef466eb42018-01-27 14:26:54 +01001077 timer T := 5.0;
1078 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001079 alt {
1080 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
1081 /* Expect LU REJECT with Cause == Illegal MS */
Harald Weltebdb3c452018-03-18 22:43:06 +01001082 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
1083 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001084 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001085 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001086 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Harald Weltef466eb42018-01-27 14:26:54 +01001087 self.stop;
1088 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001089 }
1090 setverdict(pass);
1091}
1092testcase TC_cl3_no_payload() runs on MTC_CT {
1093 var BSC_ConnHdlr vc_conn;
1094 f_init();
1095
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001096 vc_conn := f_start_handler(refers(f_tc_cl3_no_payload), 25);
Harald Welte1af6ea82018-01-25 18:33:15 +01001097 vc_conn.done;
1098}
1099
1100/* Test Complete L3 with random payload */
1101private function f_tc_cl3_rnd_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001102 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001103
1104 var integer len := float2int(rnd() * 256.0);
1105 var octetstring payl := f_rnd_octstring(len);
1106
1107 /* Send Complete L3 Info with empty L3 frame */
1108 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1109 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, payl))));
1110
Harald Weltef466eb42018-01-27 14:26:54 +01001111 timer T := 5.0;
1112 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001113 alt {
1114 /* Immediate disconnect */
1115 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
Harald Welte1af6ea82018-01-25 18:33:15 +01001116 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
Harald Weltebdb3c452018-03-18 22:43:06 +01001117 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_CONF_IND) { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001118 [] as_clear_cmd_compl_disc();
Harald Weltef466eb42018-01-27 14:26:54 +01001119 [] T.timeout {
Daniel Willmann90829d62018-02-15 17:45:14 +01001120 setverdict(fail, "Timeout waiting for ClearCommand or SCCP Release");
Harald Weltef466eb42018-01-27 14:26:54 +01001121 self.stop;
1122 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001123 }
1124 setverdict(pass);
1125}
1126testcase TC_cl3_rnd_payload() runs on MTC_CT {
1127 var BSC_ConnHdlr vc_conn;
1128 f_init();
1129
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001130 vc_conn := f_start_handler(refers(f_tc_cl3_rnd_payload), 26);
Harald Welte1af6ea82018-01-25 18:33:15 +01001131 vc_conn.done;
1132}
1133
Harald Welte116e4332018-01-26 22:17:48 +01001134/* Test Complete L3 with random payload */
1135private function f_tc_establish_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001136 f_init_handler(pars);
Harald Welte116e4332018-01-26 22:17:48 +01001137
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001138 f_perform_lu();
Harald Welte116e4332018-01-26 22:17:48 +01001139
Harald Welteb9e86fa2018-04-09 18:18:31 +02001140 f_establish_fully();
Harald Welte1ddc7162018-01-27 14:25:46 +01001141 f_expect_clear();
Harald Welte116e4332018-01-26 22:17:48 +01001142}
1143testcase TC_establish_and_nothing() runs on MTC_CT {
1144 var BSC_ConnHdlr vc_conn;
1145 f_init();
1146
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001147 vc_conn := f_start_handler(refers(f_tc_establish_and_nothing), 27);
Harald Welte116e4332018-01-26 22:17:48 +01001148 vc_conn.done;
1149}
1150
Harald Welte12510c52018-01-26 22:26:24 +01001151/* Test MO Call SETUP with no response from MNCC */
1152private function f_tc_mo_setup_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001153 f_init_handler(pars);
1154
Harald Welte12510c52018-01-26 22:26:24 +01001155 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1156
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001157 f_perform_lu();
Harald Welte12510c52018-01-26 22:26:24 +01001158
Harald Welteb9e86fa2018-04-09 18:18:31 +02001159 f_establish_fully();
Harald Welte12510c52018-01-26 22:26:24 +01001160 f_create_mncc_expect(hex2str(cpars.called_party));
1161 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1162
1163 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1164
Harald Welte1ddc7162018-01-27 14:25:46 +01001165 f_expect_clear(30.0);
Harald Welte12510c52018-01-26 22:26:24 +01001166}
1167testcase TC_mo_setup_and_nothing() runs on MTC_CT {
1168 var BSC_ConnHdlr vc_conn;
1169 f_init();
1170
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001171 vc_conn := f_start_handler(refers(f_tc_mo_setup_and_nothing), 28);
Harald Welte12510c52018-01-26 22:26:24 +01001172 vc_conn.done;
1173}
1174
Harald Welte3ab88002018-01-26 22:37:25 +01001175/* Test MO Call with no response to RAN-side CRCX */
1176private function f_tc_mo_crcx_ran_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001177 f_init_handler(pars);
Harald Welte3ab88002018-01-26 22:37:25 +01001178 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1179 var MNCC_PDU mncc;
1180 var MgcpCommand mgcp_cmd;
1181
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001182 f_perform_lu();
Harald Welte3ab88002018-01-26 22:37:25 +01001183
Harald Welteb9e86fa2018-04-09 18:18:31 +02001184 f_establish_fully();
Harald Welte3ab88002018-01-26 22:37:25 +01001185 f_create_mncc_expect(hex2str(cpars.called_party));
1186 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1187
1188 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1189 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1190 cpars.mncc_callref := mncc.u.signal.callref;
1191 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1192 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1193
1194 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
Harald Welte1852a842018-01-26 22:53:36 +01001195 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1196 cpars.mgcp_ep := mgcp_cmd.line.ep;
Harald Welte3ab88002018-01-26 22:37:25 +01001197 /* never respond to this */
1198
Philipp Maier8e58f592018-03-14 11:10:56 +01001199 /* When the connection with the MGW fails, the MSC will first request
1200 * a release via call control. We will answer this request normally. */
1201 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1202 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1203
Harald Welte1ddc7162018-01-27 14:25:46 +01001204 f_expect_clear(30.0);
Harald Welte3ab88002018-01-26 22:37:25 +01001205}
1206testcase TC_mo_crcx_ran_timeout() runs on MTC_CT {
1207 var BSC_ConnHdlr vc_conn;
1208 f_init();
1209
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001210 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_timeout), 29);
Harald Welte3ab88002018-01-26 22:37:25 +01001211 vc_conn.done;
1212}
1213
Harald Welte0cc82d92018-01-26 22:52:34 +01001214/* Test MO Call with reject to RAN-side CRCX */
1215private function f_tc_mo_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001216 f_init_handler(pars);
Harald Welte0cc82d92018-01-26 22:52:34 +01001217 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1218 var MNCC_PDU mncc;
1219 var MgcpCommand mgcp_cmd;
1220
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001221 f_perform_lu();
Harald Welte0cc82d92018-01-26 22:52:34 +01001222
Harald Welteb9e86fa2018-04-09 18:18:31 +02001223 f_establish_fully();
Harald Welte0cc82d92018-01-26 22:52:34 +01001224 f_create_mncc_expect(hex2str(cpars.called_party));
1225 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1226
1227 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1228 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1229 cpars.mncc_callref := mncc.u.signal.callref;
1230 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1231 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1232
1233 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001234
1235 /* Detect if the received CRCX is a wildcarded CRCX request. If yes,
1236 * set an endpoint name that fits the pattern. If not, just use the
1237 * endpoint name from the request */
1238 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
1239 cpars.mgcp_ep := "rtpbridge/1@mgw";
1240 } else {
1241 cpars.mgcp_ep := mgcp_cmd.line.ep;
1242 }
1243
Harald Welte0cc82d92018-01-26 22:52:34 +01001244 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001245
Harald Welte0cc82d92018-01-26 22:52:34 +01001246 /* Respond to CRCX with error */
1247 var MgcpResponse mgcp_rsp := {
1248 line := {
1249 code := "542",
1250 trans_id := mgcp_cmd.line.trans_id,
1251 string := "FORCED_FAIL"
1252 },
Harald Welte0cc82d92018-01-26 22:52:34 +01001253 sdp := omit
1254 }
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001255 var MgcpParameter mgcp_rsp_param := {
1256 code := "Z",
1257 val := cpars.mgcp_ep
1258 };
1259 mgcp_rsp.params[0] := mgcp_rsp_param;
Harald Welte0cc82d92018-01-26 22:52:34 +01001260 MGCP.send(mgcp_rsp);
1261
1262 timer T := 30.0;
1263 T.start;
1264 alt {
1265 [] T.timeout { setverdict(fail, "Timeout waiting for channel release"); self.stop; }
Daniel Willmann5868e622018-02-15 17:42:59 +01001266 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id))) {
1267 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1268 repeat;
1269 }
Harald Welte0cc82d92018-01-26 22:52:34 +01001270 [] MNCC.receive { repeat; }
1271 [] GSUP.receive { repeat; }
Philipp Maierc6e06f72018-04-11 18:12:23 +02001272 /* Note: As we did not respond properly to the CRCX from the MSC we
1273 * expect the MSC to omit any further MGCP operation (At least in the
1274 * the current implementation, there is no recovery mechanism implemented
1275 * and a DLCX can not be performed as the MSC does not know a specific
1276 * endpoint yet. */
1277 [] MGCP.receive { setverdict(fail, "Unexpected MGCP message"); self.stop; }
Harald Welte5946b332018-03-18 23:32:21 +01001278 [] as_clear_cmd_compl_disc();
Harald Welte0cc82d92018-01-26 22:52:34 +01001279 }
1280}
1281testcase TC_mo_crcx_ran_reject() runs on MTC_CT {
1282 var BSC_ConnHdlr vc_conn;
1283 f_init();
1284
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001285 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_reject), 30);
Harald Welte0cc82d92018-01-26 22:52:34 +01001286 vc_conn.done;
1287}
1288
Harald Welte3ab88002018-01-26 22:37:25 +01001289
Harald Welte812f7a42018-01-27 00:49:18 +01001290/* helper function to start a MT call: MNCC SETUP; Paging; DChan est.; DTAP SETUP */
1291private function f_mt_call_start(inout CallParameters cpars) runs on BSC_ConnHdlr {
1292 var MNCC_PDU mncc;
1293 var MgcpCommand mgcp_cmd;
1294 var OCT4 tmsi;
1295
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001296 f_perform_lu();
Harald Welte812f7a42018-01-27 00:49:18 +01001297 if (isvalue(g_pars.tmsi)) {
1298 tmsi := g_pars.tmsi;
1299 } else {
1300 tmsi := 'FFFFFFFF'O;
1301 }
1302 f_bssmap_register_imsi(g_pars.imsi, tmsi);
1303
1304 /* Allocate call reference and send SETUP via MNCC to MSC */
1305 cpars.mncc_callref := f_rnd_int(2147483648);
1306 MNCC.send(ts_MNCC_SETUP_req(cpars.mncc_callref, hex2str(g_pars.msisdn),
1307 hex2str(cpars.called_party), hex2str(g_pars.imsi)));
1308
1309 /* MSC->BSC: expect PAGING from MSC */
1310 BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));
1311 /* MS -> MSC: PAGING RESPONSE */
Harald Welteb9e86fa2018-04-09 18:18:31 +02001312 f_establish_fully(EST_TYPE_PAG_RESP);
Harald Welte812f7a42018-01-27 00:49:18 +01001313
1314 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1315
1316 /* MSC->MS: SETUP */
1317 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party)));
1318}
1319
1320/* Test MT Call */
1321private function f_tc_mt_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001322 f_init_handler(pars);
Harald Welte812f7a42018-01-27 00:49:18 +01001323 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1324 var MNCC_PDU mncc;
1325 var MgcpCommand mgcp_cmd;
1326
1327 f_mt_call_start(cpars);
1328
1329 /* MS->MSC: CALL CONFIRMED */
1330 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1331
1332 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1333
1334 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1335 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001336
1337 /* Detect if the received CRCX is a wildcarded CRCX request. If yes,
1338 * set an endpoint name that fits the pattern. If not, just use the
1339 * endpoint name from the request */
1340 if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
1341 cpars.mgcp_ep := "rtpbridge/1@mgw";
1342 } else {
1343 cpars.mgcp_ep := mgcp_cmd.line.ep;
1344 }
1345
Harald Welte812f7a42018-01-27 00:49:18 +01001346 /* Respond to CRCX with error */
1347 var MgcpResponse mgcp_rsp := {
1348 line := {
1349 code := "542",
1350 trans_id := mgcp_cmd.line.trans_id,
1351 string := "FORCED_FAIL"
1352 },
Harald Welte812f7a42018-01-27 00:49:18 +01001353 sdp := omit
1354 }
Philipp Maierf1e02bb2018-03-15 16:30:00 +01001355 var MgcpParameter mgcp_rsp_param := {
1356 code := "Z",
1357 val := cpars.mgcp_ep
1358 };
1359 mgcp_rsp.params[0] := mgcp_rsp_param;
Harald Welte812f7a42018-01-27 00:49:18 +01001360 MGCP.send(mgcp_rsp);
1361
1362 timer T := 30.0;
1363 T.start;
1364 alt {
1365 [] T.timeout { setverdict(fail, "Timeout waiting for channel release"); self.stop; }
Harald Welte812f7a42018-01-27 00:49:18 +01001366 [] BSSAP.receive { repeat; }
1367 [] MNCC.receive { repeat; }
1368 [] GSUP.receive { repeat; }
1369 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1370 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1371 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1372 repeat;
1373 }
1374 [] MGCP.receive { repeat; }
Harald Welte5946b332018-03-18 23:32:21 +01001375 [] as_clear_cmd_compl_disc();
Harald Welte812f7a42018-01-27 00:49:18 +01001376 }
1377}
1378testcase TC_mt_crcx_ran_reject() runs on MTC_CT {
1379 var BSC_ConnHdlr vc_conn;
1380 f_init();
1381
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001382 vc_conn := f_start_handler(refers(f_tc_mt_crcx_ran_reject), 31);
Harald Welte812f7a42018-01-27 00:49:18 +01001383 vc_conn.done;
1384}
1385
1386
1387/* Test MT Call T310 timer */
1388private function f_tc_mt_t310(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltead2952e2018-01-27 14:12:46 +01001389 f_init_handler(pars, 200.0);
Harald Welte812f7a42018-01-27 00:49:18 +01001390 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1391 var MNCC_PDU mncc;
1392 var MgcpCommand mgcp_cmd;
1393
1394 f_mt_call_start(cpars);
1395
1396 /* MS->MSC: CALL CONFIRMED */
1397 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1398 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1399
1400 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1401 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1402 cpars.mgcp_ep := mgcp_cmd.line.ep;
1403 /* FIXME: Respond to CRCX */
1404
1405 /* old libosmocore T310 default timeout is 180s. so let's wait 190 */
1406 timer T := 190.0;
1407 T.start;
1408 alt {
1409 [] T.timeout { setverdict(fail, "Timeout waiting for T310"); self.stop; }
1410 [] MNCC.receive(tr_MNCC_DISC_ind(cpars.mncc_callref)) {
1411 MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(23))));
1412 }
1413 }
1414 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));
1415 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1416 /* FIXME: We're sending this with TIflag 0: allocated by sender, which is wrong */
1417 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1418
1419 alt {
Harald Welte812f7a42018-01-27 00:49:18 +01001420 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1421 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1422 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1423 repeat;
1424 }
Harald Welte5946b332018-03-18 23:32:21 +01001425 [] as_clear_cmd_compl_disc();
Harald Welte812f7a42018-01-27 00:49:18 +01001426 }
1427}
1428testcase TC_mt_t310() runs on MTC_CT {
1429 var BSC_ConnHdlr vc_conn;
1430 f_init();
1431
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001432 vc_conn := f_start_handler(refers(f_tc_mt_t310), 32);
Harald Welte812f7a42018-01-27 00:49:18 +01001433 vc_conn.done;
1434}
1435
Harald Welte167458a2018-01-27 15:58:16 +01001436/* Perform successful LU + MO call, then GSUP LocationCancel. Subscriber must be denied CM SERV */
1437private function f_tc_gsup_cancel(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1438 f_init_handler(pars);
1439 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1440 cpars.bss_rtp_port := 1110;
1441 cpars.mgcp_connection_id_bss := '22222'H;
1442 cpars.mgcp_connection_id_mss := '33333'H;
1443
1444 /* Location Update to make subscriber known */
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001445 f_perform_lu();
Harald Welte167458a2018-01-27 15:58:16 +01001446
1447 /* First MO call should succeed */
1448 f_mo_call(cpars);
1449
1450 /* Cancel the subscriber in the VLR */
1451 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1452 alt {
1453 [] GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi)) { }
1454 [] GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi)) {
1455 setverdict(fail, "Received GSUP Location Cancel Error");
1456 self.stop;
1457 }
1458 }
1459
1460 /* Follow-up transactions should fail */
1461 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1462 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
1463 f_bssap_compl_l3(l3_info);
1464 alt {
1465 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
1466 [] BSSAP.receive {
1467 setverdict(fail, "Received unexpected BSSAP instead of CM SERV REJ");
1468 self.stop;
1469 }
1470 }
1471 setverdict(pass);
1472}
1473testcase TC_gsup_cancel() runs on MTC_CT {
1474 var BSC_ConnHdlr vc_conn;
1475 f_init();
1476
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001477 vc_conn := f_start_handler(refers(f_tc_gsup_cancel), 33);
Harald Welte167458a2018-01-27 15:58:16 +01001478 vc_conn.done;
1479}
1480
Harald Welte9de84792018-01-28 01:06:35 +01001481/* A5/1 only permitted on network side, and MS capable to do it */
1482private function f_tc_lu_imsi_auth_tmsi_encr_1_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1483 pars.net.expect_auth := true;
1484 pars.net.expect_ciph := true;
1485 pars.net.kc_support := '02'O; /* A5/1 only */
1486 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001487 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001488}
1489testcase TC_lu_imsi_auth_tmsi_encr_1_13() runs on MTC_CT {
1490 var BSC_ConnHdlr vc_conn;
1491 f_init();
1492 f_vty_config(MSCVTY, "network", "authentication required");
1493 f_vty_config(MSCVTY, "network", "encryption a5 1");
1494
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001495 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_1_13), 34);
Harald Welte9de84792018-01-28 01:06:35 +01001496 vc_conn.done;
1497}
1498
1499/* A5/3 only permitted on network side, and MS capable to do it */
1500private function f_tc_lu_imsi_auth_tmsi_encr_3_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1501 pars.net.expect_auth := true;
1502 pars.net.expect_ciph := true;
1503 pars.net.kc_support := '08'O; /* A5/3 only */
1504 f_init_handler(pars);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001505 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001506}
1507testcase TC_lu_imsi_auth_tmsi_encr_3_13() runs on MTC_CT {
1508 var BSC_ConnHdlr vc_conn;
1509 f_init();
1510 f_vty_config(MSCVTY, "network", "authentication required");
1511 f_vty_config(MSCVTY, "network", "encryption a5 3");
1512
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001513 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_13), 35);
Harald Welte9de84792018-01-28 01:06:35 +01001514 vc_conn.done;
1515}
1516
1517/* A5/3 only permitted on network side, and MS with only A5/1 support */
1518private function f_tc_lu_imsi_auth_tmsi_encr_3_1(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 := '08'O; /* A5/3 only */
1522 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1523 f_init_handler(pars, 15.0);
1524
1525 /* cannot use f_perform_lu() as we expect a reject */
1526 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1527 f_create_gsup_expect(hex2str(g_pars.imsi));
1528 f_bssap_compl_l3(l3_lu);
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001529 if (pars.send_early_cm) {
1530 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1531 } else {
1532 pars.cm1.esind := '0'B;
1533 }
Harald Welte9de84792018-01-28 01:06:35 +01001534 f_mm_auth();
1535 alt {
Harald Welte5946b332018-03-18 23:32:21 +01001536 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1537 f_expect_clear();
1538 }
Harald Welte9de84792018-01-28 01:06:35 +01001539 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1540 setverdict(fail, "CipherModeCommand despite no A5 intersection");
1541 self.stop;
1542 }
1543 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001544 setverdict(fail, "Unknown/unexpected BSSAP received");
Harald Welte9de84792018-01-28 01:06:35 +01001545 self.stop;
1546 }
1547 }
1548 setverdict(pass);
1549}
1550testcase TC_lu_imsi_auth_tmsi_encr_3_1() runs on MTC_CT {
1551 var BSC_ConnHdlr vc_conn;
1552 f_init();
1553 f_vty_config(MSCVTY, "network", "authentication required");
1554 f_vty_config(MSCVTY, "network", "encryption a5 3");
1555
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001556 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 360);
1557 vc_conn.done;
1558}
1559testcase TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() runs on MTC_CT {
1560 var BSC_ConnHdlrPars pars;
1561 var BSC_ConnHdlr vc_conn;
1562 f_init();
1563 f_vty_config(MSCVTY, "network", "authentication required");
1564 f_vty_config(MSCVTY, "network", "encryption a5 3");
1565
1566 pars := f_init_pars(361);
1567 pars.send_early_cm := false;
1568 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 +01001569 vc_conn.done;
1570}
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01001571testcase TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() runs on MTC_CT {
1572 var BSC_ConnHdlr vc_conn;
1573 f_init();
1574 f_vty_config(MSCVTY, "network", "authentication required");
1575 f_vty_config(MSCVTY, "network", "encryption a5 3");
1576
1577 /* Make sure the MSC category is on DEBUG level to trigger the log
1578 * message that is reported in OS#2947 to trigger the segfault */
1579 f_vty_config(MSCVTY, "log stderr", "logging level msc debug");
1580
1581 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_3_1), 362);
1582 vc_conn.done;
1583}
Harald Welte9de84792018-01-28 01:06:35 +01001584
1585/* A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
1586private function f_tc_lu_imsi_auth_tmsi_encr_13_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1587 pars.net.expect_auth := true;
1588 pars.net.expect_ciph := true;
1589 pars.net.kc_support := '0A'O; /* A5/1 + A5/3 */
1590 pars.cm1.a5_1 := '1'B;
1591 pars.cm2.a5_1 := '1'B;
1592 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1593 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
1594 f_init_handler(pars, 15.0);
1595
1596 /* cannot use f_perform_lu() as we expect a reject */
1597 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
1598 f_create_gsup_expect(hex2str(g_pars.imsi));
1599 f_bssap_compl_l3(l3_lu);
1600 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1601 f_mm_auth();
1602 alt {
Harald Welte5946b332018-03-18 23:32:21 +01001603 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
1604 f_expect_clear();
1605 }
Harald Welte9de84792018-01-28 01:06:35 +01001606 [] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?,?)) {
1607 setverdict(fail, "CipherModeCommand despite no A5 intersection");
1608 self.stop;
1609 }
1610 [] BSSAP.receive {
Harald Welte458fd372018-03-21 11:26:23 +01001611 setverdict(fail, "Unknown/unexpected BSSAP received");
Harald Welte9de84792018-01-28 01:06:35 +01001612 self.stop;
1613 }
1614 }
1615 setverdict(pass);
1616}
1617testcase TC_lu_imsi_auth_tmsi_encr_13_2() runs on MTC_CT {
1618 var BSC_ConnHdlr vc_conn;
1619 f_init();
1620 f_vty_config(MSCVTY, "network", "authentication required");
1621 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1622
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001623 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_2), 37);
Harald Welte9de84792018-01-28 01:06:35 +01001624 vc_conn.done;
1625}
1626
1627/* A5/0 + A5/1 + A5/3 only permitted on network side, and MS with only A5/2 support */
1628private function f_tc_lu_imsi_auth_tmsi_encr_013_2(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1629 pars.net.expect_auth := true;
1630 pars.net.expect_ciph := true;
1631 pars.net.kc_support := '0B'O; /* A5/1 + A5/3 */
1632 pars.cm1.a5_1 := '1'B;
1633 pars.cm2.a5_1 := '1'B;
1634 pars.cm2.classmarkInformationType2_oct5.a5_3 := '0'B;
1635 pars.cm2.classmarkInformationType2_oct5.a5_2 := '1'B;
1636 f_init_handler(pars, 15.0);
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001637 f_perform_lu();
Harald Welte9de84792018-01-28 01:06:35 +01001638}
1639testcase TC_lu_imsi_auth_tmsi_encr_013_2() runs on MTC_CT {
1640 var BSC_ConnHdlr vc_conn;
1641 f_init();
1642 f_vty_config(MSCVTY, "network", "authentication required");
1643 f_vty_config(MSCVTY, "network", "encryption a5 0 1 3");
1644
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001645 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_013_2), 38);
Harald Welte9de84792018-01-28 01:06:35 +01001646 vc_conn.done;
1647}
1648
Harald Welte33ec09b2018-02-10 15:34:46 +01001649/* LU followed by MT call (including paging) */
1650private function f_tc_lu_and_mt_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1651 f_init_handler(pars);
1652 //FIXME: odd digits var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1653 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1654 cpars.bss_rtp_port := 1110;
1655 cpars.mgcp_connection_id_bss := '10004'H;
1656 cpars.mgcp_connection_id_mss := '10005'H;
1657
Philipp Maier4b2692d2018-03-14 16:37:48 +01001658 /* Note: This is an optional parameter. When the call-agent (MSC) does
1659 * supply a full endpoint name this setting will be overwritten. */
1660 cpars.mgcp_ep := "rtpbridge/1@mgw";
1661
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001662 f_perform_lu();
Harald Welte33ec09b2018-02-10 15:34:46 +01001663 f_mt_call(cpars);
1664}
1665testcase TC_lu_and_mt_call() runs on MTC_CT {
1666 var BSC_ConnHdlr vc_conn;
1667 f_init();
1668
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001669 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call), 39);
Harald Welte33ec09b2018-02-10 15:34:46 +01001670 vc_conn.done;
1671}
1672
Daniel Willmann8b084372018-02-04 13:35:26 +01001673/* Test MO Call SETUP with DTMF */
1674private function f_tc_mo_setup_dtmf_dup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1675 f_init_handler(pars);
1676 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1677 cpars.bss_rtp_port := 1110;
1678 cpars.mgcp_connection_id_bss := '22222'H;
1679 cpars.mgcp_connection_id_mss := '33333'H;
1680
Neels Hofmeyrc1f105a2018-03-01 20:00:19 +01001681 f_perform_lu();
Daniel Willmann8b084372018-02-04 13:35:26 +01001682 f_mo_seq_dtmf_dup(cpars);
1683}
1684testcase TC_mo_setup_and_dtmf_dup() runs on MTC_CT {
1685 var BSC_ConnHdlr vc_conn;
1686 f_init();
1687
Neels Hofmeyre9b8eeb2018-03-01 20:29:58 +01001688 vc_conn := f_start_handler(refers(f_tc_mo_setup_dtmf_dup), 39);
Daniel Willmann8b084372018-02-04 13:35:26 +01001689 vc_conn.done;
1690}
Harald Welte9de84792018-01-28 01:06:35 +01001691
Philipp Maier328d1662018-03-07 10:40:27 +01001692testcase TC_cr_before_reset() runs on MTC_CT {
1693 timer T := 4.0;
1694 var boolean reset_ack_seen := false;
1695 f_init_bssap_direct();
1696
1697 /* Make a blind connection attemt, to trigger the deadlock condition */
Philipp Maier75932982018-03-27 14:52:35 +02001698 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 +01001699
1700 /* Send a BSSMAP reset */
Philipp Maier75932982018-03-27 14:52:35 +02001701 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 +01001702 T.start
1703 alt {
1704 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_ResetAck)) {
1705 reset_ack_seen := true;
1706 repeat;
1707 }
1708
1709 /* Acknowledge MSC sided reset requests */
1710 [] BSSAP_DIRECT.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) {
Philipp Maier75932982018-03-27 14:52:35 +02001711 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 +01001712 repeat;
1713 }
1714
1715 /* Ignore all other messages (e.g CR from the connection request) */
1716 [] BSSAP_DIRECT.receive { repeat }
1717
1718 /* If we got no BSSMAP RESET ACK back, then the MSC entered the
1719 * deadlock situation. The MSC is then unable to respond to any
1720 * further BSSMAP RESET or any other sort of traffic. */
1721 [reset_ack_seen == true] T.timeout { setverdict(pass) }
1722 [reset_ack_seen == false] T.timeout {
1723 setverdict(fail, "no BSSMAP RESET ACK seen!");
1724 }
1725 }
1726}
Harald Welte9de84792018-01-28 01:06:35 +01001727
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001728/* Test MO Call with no response to RAN-side CRCX or DTAP Release */
1729private function f_tc_mo_release_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1730 f_init_handler(pars);
1731 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1732 var MNCC_PDU mncc;
1733 var MgcpCommand mgcp_cmd;
1734
1735 f_perform_lu();
1736
Harald Welteb9e86fa2018-04-09 18:18:31 +02001737 f_establish_fully();
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001738 f_create_mncc_expect(hex2str(cpars.called_party));
1739 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1740
1741 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1742 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1743 cpars.mncc_callref := mncc.u.signal.callref;
1744 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1745 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1746
1747 /* Drop CRCX */
1748 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1749
1750 /* Drop DTAP Release */
1751 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1752
1753 /* Drop resent DTAP Release */
1754 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1755
1756 f_expect_clear(60.0);
1757}
1758testcase TC_mo_release_timeout() runs on MTC_CT {
1759 var BSC_ConnHdlr vc_conn;
1760 f_init();
1761
1762 vc_conn := f_start_handler(refers(f_tc_mo_release_timeout), 40);
1763 vc_conn.done;
1764}
1765
Harald Welte12510c52018-01-26 22:26:24 +01001766
Philipp Maier2a98a732018-03-19 16:06:12 +01001767/* LU followed by MT call (including paging) */
1768private function f_tc_lu_and_mt_call_no_dlcx_resp(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1769 f_init_handler(pars);
1770 //FIXME: odd digits var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1771 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1772 cpars.bss_rtp_port := 1110;
1773 cpars.mgcp_connection_id_bss := '10004'H;
1774 cpars.mgcp_connection_id_mss := '10005'H;
1775
1776 /* Note: This is an optional parameter. When the call-agent (MSC) does
1777 * supply a full endpoint name this setting will be overwritten. */
1778 cpars.mgcp_ep := "rtpbridge/1@mgw";
1779
1780 /* Intentionally disable the CRCX response */
1781 cpars.mgw_drop_dlcx := true;
1782
1783 /* Perform location update and call */
1784 f_perform_lu();
1785 f_mt_call(cpars);
1786}
1787testcase TC_lu_and_mt_call_no_dlcx_resp() runs on MTC_CT {
1788 var BSC_ConnHdlr vc_conn;
1789 f_init();
1790
1791 /* Perform an almost normal looking locationupdate + mt-call, but do
1792 * not respond to the DLCX at the end of the call */
1793 vc_conn := f_start_handler(refers(f_tc_lu_and_mt_call_no_dlcx_resp), 41);
1794 vc_conn.done;
1795
1796 /* Wait a guard period until the MGCP layer in the MSC times out,
1797 * if the MSC is vulnerable to the use-after-free situation that is
1798 * fixed by I78f1b6a9149488a4ad3f120c1e190a83c07d4b89 then it should
1799 * segfault now */
1800 f_sleep(6.0);
1801
1802 /* Run the init procedures once more. If the MSC has crashed, this
1803 * this will fail */
1804 f_init();
1805}
Harald Welte45164da2018-01-24 12:51:27 +01001806
Philipp Maier75932982018-03-27 14:52:35 +02001807/* Two BSSMAP resets from two different BSCs */
1808testcase TC_reset_two() runs on MTC_CT {
1809 var BSC_ConnHdlr vc_conn;
1810 f_init(2);
1811 f_sleep(2.0);
1812 setverdict(pass);
1813}
1814
Harald Weltef45efeb2018-04-09 18:19:24 +02001815/* LU followed by MO SMS */
1816private function f_tc_lu_and_mo_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1817 var SmsParameters spars := valueof(t_SmsPars);
1818
1819 f_init_handler(pars);
1820
1821 /* Perform location update and call */
1822 f_perform_lu();
1823
1824 f_establish_fully(EST_TYPE_MO_SMS);
1825
1826 //spars.exp_rp_err := 96; /* invalid mandatory information */
1827 f_mo_sms(spars);
1828
1829 f_expect_clear();
1830}
1831testcase TC_lu_and_mo_sms() runs on MTC_CT {
1832 var BSC_ConnHdlr vc_conn;
1833 f_init();
1834 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_sms), 42);
1835 vc_conn.done;
1836}
1837
1838private function f_vty_sms_send(charstring imsi, charstring msisdn, charstring text)
1839runs on MTC_CT {
1840 f_vty_transceive(MSCVTY, "subscriber imsi "&imsi&" sms sender msisdn "&msisdn&" send "&text);
1841}
1842
1843/* LU followed by MT SMS */
1844private function f_tc_lu_and_mt_sms(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1845 var SmsParameters spars := valueof(t_SmsPars);
1846 var OCT4 tmsi;
1847
1848 f_init_handler(pars);
1849
1850 /* Perform location update and call */
1851 f_perform_lu();
1852
1853 /* register an 'expect' for given IMSI (+TMSI) */
1854 if (isvalue(g_pars.tmsi)) {
1855 tmsi := g_pars.tmsi;
1856 } else {
1857 tmsi := 'FFFFFFFF'O;
1858 }
1859 f_bssmap_register_imsi(g_pars.imsi, tmsi);
1860
1861 /* FIXME: actually cause MSC to send a SMS via VTY or SMPP */
1862
1863 /* MSC->BSC: expect PAGING from MSC */
1864 BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));
1865 /* Establish DTAP / BSSAP / SCCP connection */
1866 f_establish_fully(EST_TYPE_PAG_RESP);
1867
1868 spars.tp.ud := 'C8329BFD064D9B53'O;
1869 f_mt_sms(spars);
1870
1871 f_expect_clear();
1872}
1873testcase TC_lu_and_mt_sms() runs on MTC_CT {
1874 var BSC_ConnHdlrPars pars;
1875 var BSC_ConnHdlr vc_conn;
1876 f_init();
1877 pars := f_init_pars(43);
1878 vc_conn := f_start_handler_with_pars(refers(f_tc_lu_and_mt_sms), pars);
1879 f_sleep(2.0);
1880 f_vty_sms_send(hex2str(pars.imsi), "2342", "Hello SMS");
1881 vc_conn.done;
1882}
1883
1884
1885
Harald Welteba7b6d92018-01-23 21:32:34 +01001886/* TODO:
1887 * continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
1888 * malformed messages (missing IE, invalid message type): properly rejected?
1889 * MT call while LU or is ongoing: Do we use existing lchan or page while lchan active?
1890 * 3G/2G auth permutations
1891 * encryption algorithms vs. classmark vs. vty config
Harald Welteba7b6d92018-01-23 21:32:34 +01001892 * send new transaction after/during clear (like SMS, ...)
Harald Welte45164da2018-01-24 12:51:27 +01001893 * too long L3 INFO in DTAP
1894 * too long / padded BSSAP
1895 * too long / short TLV values
Harald Welteba7b6d92018-01-23 21:32:34 +01001896 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01001897
1898
1899control {
Philipp Maier328d1662018-03-07 10:40:27 +01001900 execute( TC_cr_before_reset() );
Harald Weltea49e36e2018-01-21 19:29:33 +01001901 execute( TC_lu_imsi_noauth_tmsi() );
Harald Welted2328a22018-01-27 14:27:16 +01001902 execute( TC_lu_imsi_noauth_notmsi() );
Harald Weltea49e36e2018-01-21 19:29:33 +01001903 execute( TC_lu_imsi_reject() );
1904 execute( TC_lu_imsi_timeout_gsup() );
Harald Welted2328a22018-01-27 14:27:16 +01001905 execute( TC_lu_imsi_auth_tmsi() );
1906 execute( TC_cmserv_imsi_unknown() );
Harald Welte2bb825f2018-01-22 11:31:18 +01001907 execute( TC_lu_and_mo_call() );
Harald Welte071ed732018-01-23 19:53:52 +01001908 execute( TC_lu_auth_sai_timeout() );
1909 execute( TC_lu_auth_sai_err() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01001910 execute( TC_lu_clear_request() );
1911 execute( TC_lu_disconnect() );
1912 execute( TC_lu_by_imei() );
1913 execute( TC_lu_by_tmsi_noauth_unknown() );
1914 execute( TC_imsi_detach_by_imsi() );
1915 execute( TC_imsi_detach_by_tmsi() );
1916 execute( TC_imsi_detach_by_imei() );
1917 execute( TC_emerg_call_imei_reject() );
1918 execute( TC_emerg_call_imsi() );
1919 execute( TC_cm_serv_req_vgcs_reject() );
1920 execute( TC_cm_serv_req_vbs_reject() );
1921 execute( TC_cm_serv_req_lcs_reject() );
Harald Welte0195ab12018-01-24 21:50:20 +01001922 execute( TC_cm_reest_req_reject() );
Harald Welte1af6ea82018-01-25 18:33:15 +01001923 execute( TC_lu_auth_2G_fail() );
1924 execute( TC_lu_imsi_auth_tmsi_encr_13_13() );
1925 execute( TC_cl3_no_payload() );
1926 execute( TC_cl3_rnd_payload() );
Harald Welte1852a842018-01-26 22:53:36 +01001927 execute( TC_establish_and_nothing() );
1928 execute( TC_mo_setup_and_nothing() );
1929 execute( TC_mo_crcx_ran_timeout() );
1930 execute( TC_mo_crcx_ran_reject() );
Harald Welted2328a22018-01-27 14:27:16 +01001931 execute( TC_mt_crcx_ran_reject() );
Daniel Willmann8b084372018-02-04 13:35:26 +01001932 execute( TC_mo_setup_and_dtmf_dup() );
Harald Welteaa54cf82018-01-30 08:15:32 +01001933 //execute( TC_mt_t310() );
Harald Welte167458a2018-01-27 15:58:16 +01001934 execute( TC_gsup_cancel() );
Harald Welte9de84792018-01-28 01:06:35 +01001935 execute( TC_lu_imsi_auth_tmsi_encr_1_13() );
1936 execute( TC_lu_imsi_auth_tmsi_encr_3_13() );
1937 execute( TC_lu_imsi_auth_tmsi_encr_3_1() );
Neels Hofmeyr29b8da02018-03-01 18:09:45 +01001938 execute( TC_lu_imsi_auth_tmsi_encr_3_1_no_cm() );
Harald Welte9de84792018-01-28 01:06:35 +01001939 execute( TC_lu_imsi_auth_tmsi_encr_13_2() );
1940 execute( TC_lu_imsi_auth_tmsi_encr_013_2() );
Philipp Maier94f3f1b2018-03-15 18:54:13 +01001941 execute( TC_mo_release_timeout() );
Philipp Maier2a98a732018-03-19 16:06:12 +01001942 execute( TC_lu_and_mt_call_no_dlcx_resp() );
Philipp Maier75932982018-03-27 14:52:35 +02001943 execute( TC_reset_two() );
Harald Welte33ec09b2018-02-10 15:34:46 +01001944
1945 execute( TC_lu_and_mt_call() );
1946
Harald Weltef45efeb2018-04-09 18:19:24 +02001947 execute( TC_lu_and_mo_sms() );
1948 execute( TC_lu_and_mt_sms() );
1949
Neels Hofmeyr1b3c6e32018-03-01 17:52:21 +01001950 /* Run this last: at the time of writing this test crashes the MSC */
1951 execute( TC_lu_imsi_auth_tmsi_encr_3_1_log_msc_debug() );
Harald Weltef6dd64d2017-11-19 12:09:51 +01001952}
1953
1954
1955}