blob: 94e5822d2131bef2347c4a805e1be280f404192e [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 Weltef6dd64d2017-11-19 12:09:51 +010048
Harald Weltef6dd64d2017-11-19 12:09:51 +010049
Harald Weltea49e36e2018-01-21 19:29:33 +010050type component MTC_CT extends BSSAP_Adapter_CT, CTRL_Adapter_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +010051 var boolean g_initialized := false;
Harald Weltea49e36e2018-01-21 19:29:33 +010052
53 /* no 'adapter_CT' for MNCC or GSUP */
54 var MNCC_Emulation_CT vc_MNCC;
Harald Welte4aa970c2018-01-26 10:38:09 +010055 var MGCP_Emulation_CT vc_MGCP;
Harald Weltea49e36e2018-01-21 19:29:33 +010056 var GSUP_Emulation_CT vc_GSUP;
57 var IPA_Emulation_CT vc_GSUP_IPA;
58
59 /* only to get events from IPA underneath GSUP */
60 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte3ca1c902018-01-24 18:51:27 +010061 /* VTY to MSC */
62 port TELNETasp_PT MSCVTY;
Harald Weltef6dd64d2017-11-19 12:09:51 +010063}
64
65modulepar {
Harald Weltea49e36e2018-01-21 19:29:33 +010066 /* remote parameters of IUT */
67 charstring mp_msc_ip := "127.0.0.1";
68 integer mp_msc_ctrl_port := 4255;
69 integer mp_msc_vty_port := 4254;
Harald Weltef6dd64d2017-11-19 12:09:51 +010070
Harald Weltea49e36e2018-01-21 19:29:33 +010071 /* local parameters of emulated HLR */
72 charstring mp_hlr_ip := "127.0.0.1";
73 integer mp_hlr_port := 4222;
Harald Weltef6dd64d2017-11-19 12:09:51 +010074
Harald Weltea49e36e2018-01-21 19:29:33 +010075 charstring mp_msc_mncc := "/tmp/mncc";
Harald Weltef6dd64d2017-11-19 12:09:51 +010076}
77
78
Harald Weltea49e36e2018-01-21 19:29:33 +010079function f_init_mncc(charstring id) runs on MTC_CT {
80 id := id & "-MNCC";
81 var MnccOps ops := {
82 create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
83 unitdata_cb := refers(MNCC_Emulation.DummyUnitdataCallback)
84 }
85
86 vc_MNCC := MNCC_Emulation_CT.create(id);
87 map(vc_MNCC:MNCC, system:MNCC_CODEC_PT);
88 vc_MNCC.start(MNCC_Emulation.main(ops, id, mp_msc_mncc));
Harald Weltef6dd64d2017-11-19 12:09:51 +010089}
90
Harald Welte4aa970c2018-01-26 10:38:09 +010091function f_init_mgcp(charstring id) runs on MTC_CT {
92 id := id & "-MGCP";
93 var MGCPOps ops := {
94 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
95 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
96 }
97 var MGCP_conn_parameters pars := {
98 callagent_ip := "127.0.0.1",
99 callagent_udp_port := -1,
100 mgw_ip := "127.0.0.1",
101 mgw_udp_port := 2427
102 }
103
104 vc_MGCP := MGCP_Emulation_CT.create(id);
105 map(vc_MGCP:MGCP, system:MGCP_CODEC_PT);
106 vc_MGCP.start(MGCP_Emulation.main(ops, pars, id));
107}
108
Harald Weltea49e36e2018-01-21 19:29:33 +0100109function f_init_gsup(charstring id) runs on MTC_CT {
110 id := id & "-GSUP";
111 var GsupOps ops := {
112 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
113 }
114
115 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
116 vc_GSUP := GSUP_Emulation_CT.create(id);
117
118 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
119 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
120 /* we use this hack to get events like ASP_IPA_EVENT_UP */
121 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
122
123 vc_GSUP.start(GSUP_Emulation.main(ops, id));
124 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
125
126 /* wait for incoming connection to GSUP port before proceeding */
127 timer T := 10.0;
128 T.start;
129 alt {
130 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
131 [] T.timeout {
132 setverdict(inconc, "No connection to GSUP Port");
133 self.stop
134 }
135 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100136}
137
Harald Weltea49e36e2018-01-21 19:29:33 +0100138function f_init() runs on MTC_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +0100139
140 if (g_initialized == true) {
141 return;
142 }
143 g_initialized := true;
144
Harald Weltea49e36e2018-01-21 19:29:33 +0100145 f_bssap_init("MSC_Test", BSC_BssmapOps);
146 f_ipa_ctrl_start(mp_msc_ip, mp_msc_ctrl_port);
147 f_init_mncc("MSC_Test");
Harald Welte4aa970c2018-01-26 10:38:09 +0100148 f_init_mgcp("MSC_Test");
Harald Weltea49e36e2018-01-21 19:29:33 +0100149 f_init_gsup("MSC_Test");
Harald Welte3ca1c902018-01-24 18:51:27 +0100150
151 map(self:MSCVTY, system:MSCVTY);
152 f_vty_set_prompts(MSCVTY);
153 f_vty_transceive(MSCVTY, "enable");
Harald Welteb14c77a2018-01-25 17:25:44 +0100154
155 /* set some defaults */
156 f_vty_config(MSCVTY, "network", "authentication optional");
157 f_vty_config(MSCVTY, "msc", "assign-tmsi");
158 f_vty_config(MSCVTY, "network", "encryption a5 0");
Harald Weltef6dd64d2017-11-19 12:09:51 +0100159}
160
161template PDU_BSSAP ts_BSSAP_BSSMAP := {
162 discriminator := '0'B,
163 spare := '0000000'B,
164 dlci := omit,
165 lengthIndicator := 0, /* overwritten by codec */
166 pdu := ?
167}
168
169template PDU_BSSAP tr_BSSAP_BSSMAP := {
170 discriminator := '0'B,
171 spare := '0000000'B,
172 dlci := omit,
173 lengthIndicator := ?,
174 pdu := {
175 bssmap := ?
176 }
177}
178
179
180type integer BssmapCause;
181
182template (value) BSSMAP_IE_Cause ts_BSSMAP_IE_Cause(BssmapCause val) := {
183 elementIdentifier := '04'O,
184 lengthIndicator := 0,
185 causeValue := int2bit(val, 7),
186 extensionCauseValue := '0'B,
187 spare1 := omit
188}
189
190template (value) PDU_BSSAP ts_BSSMAP_Reset(BssmapCause cause) modifies ts_BSSAP_BSSMAP := {
191 pdu := {
192 bssmap := {
193 reset := {
194 messageType := '30'O,
195 cause := ts_BSSMAP_IE_Cause(cause),
196 a_InterfaceSelectorForReset := omit
197 }
198 }
199 }
200}
201
202template (value) PDU_BSSAP ts_BSSMAP_ResetAck modifies ts_BSSAP_BSSMAP := {
203 pdu := {
204 bssmap := {
205 resetAck := {
206 messageType := '31'O,
207 a_InterfaceSelectorForReset := omit
208 }
209 }
210 }
211}
212
213template PDU_BSSAP tr_BSSMAP_ResetAck modifies tr_BSSAP_BSSMAP := {
214 pdu := {
215 bssmap := {
216 resetAck := {
217 messageType := '31'O,
218 a_InterfaceSelectorForReset := *
219 }
220 }
221 }
222}
223
224template BSSMAP_IE_CellIdentifier ts_BSSMAP_IE_CellID := {
225 elementIdentifier := '05'O,
226 lengthIndicator := 0,
227 cellIdentifierDiscriminator := '0000'B,
228 spare1_4 := '0000'B,
229 cellIdentification := ?
230}
231
232type uint16_t BssmapLAC;
233type uint16_t BssmapCI;
234
235/*
236template BSSMAP_IE_CellIdentifier ts_CellId_CGI(mcc, mnc, lac, ci)
237modifies ts_BSSMAP_IE_CellID := {
238 cellIdentification := {
239 cI_LAC_CGI := {
240 mnc_mcc := FIXME,
241 lac := int2oct(lac, 2),
242 ci := int2oct(ci, 2)
243 }
244 }
245}
246*/
247
248template BSSMAP_IE_CellIdentifier ts_CellID_LAC_CI(BssmapLAC lac, BssmapCI ci)
249modifies ts_BSSMAP_IE_CellID := {
250 cellIdentification := {
251 cI_LAC_CI := {
252 lac := int2oct(lac, 2),
253 ci := int2oct(ci, 2)
254 }
255 }
256}
257
258template BSSMAP_IE_CellIdentifier ts_CellId_CI(BssmapCI ci)
259modifies ts_BSSMAP_IE_CellID := {
260 cellIdentification := {
261 cI_CI := int2oct(ci, 2)
262 }
263}
264
265template BSSMAP_IE_CellIdentifier ts_CellId_none
266modifies ts_BSSMAP_IE_CellID := {
267 cellIdentification := {
268 cI_noCell := ''O
269 }
270}
271
272
273template BSSMAP_IE_Layer3Information ts_BSSMAP_IE_L3Info(octetstring l3info) := {
274 elementIdentifier := '17'O,
275 lengthIndicator := 0,
276 layer3info := l3info
277}
278
279template PDU_BSSAP ts_BSSMAP_ComplL3(BSSMAP_IE_CellIdentifier cell_id, octetstring l3_info)
280modifies ts_BSSAP_BSSMAP := {
281 pdu := {
282 bssmap := {
283 completeLayer3Information := {
284 messageType := '57'O,
285 cellIdentifier := cell_id,
286 layer3Information := ts_BSSMAP_IE_L3Info(l3_info),
287 chosenChannel := omit,
288 lSAIdentifier := omit,
289 aPDU := omit,
290 codecList := omit,
291 redirectAttemptFlag := omit,
292 sendSequenceNumber := omit,
293 iMSI := omit
294 }
295 }
296 }
297}
298
299template PDU_BSSAP ts_BSSMAP_HandoReq(BssmapCause cause, BSSMAP_IE_CellIdentifierList cid_list)
300modifies ts_BSSAP_BSSMAP := {
301 pdu := {
302 bssmap := {
303 handoverRequired := {
304 messageType := '11'O,
305 cause := ts_BSSMAP_IE_Cause(cause),
306 responseRequest := omit,
307 cellIdentifierList := cid_list,
308 circuitPoolList := omit,
309 currentChannelType1 := omit,
310 speechVersion := omit,
311 queueingIndicator := omit,
312 oldToNewBSSInfo := omit,
313 sourceToTargetRNCTransparentInfo := omit,
314 sourceToTargetRNCTransparentInfoCDMA := omit,
315 gERANClassmark := omit,
316 talkerPriority := omit,
317 speechCodec := omit,
318 cSG_Identifier := omit
319 }
320 }
321 }
322}
323
324// enc_PDU_BSSAP
325
326function f_send_BSSAP_UNITDATA(template PDU_BSSAP bssap) runs on MTC_CT {
Harald Weltea49e36e2018-01-21 19:29:33 +0100327 BSSAP.send(ts_BSSAP_UNITDATA_req(g_sccp_addr_peer, g_sccp_addr_own, bssap))
Harald Weltef6dd64d2017-11-19 12:09:51 +0100328}
329
Harald Weltea49e36e2018-01-21 19:29:33 +0100330type function void_fn(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100331
Harald Welte81b7f9d2018-01-24 19:06:24 +0100332private function f_concat_pad(integer tot_len, hexstring prefix, integer suffix) return hexstring {
333 var integer suffix_len := tot_len - lengthof(prefix);
334 var charstring suffix_ch := int2str(suffix);
335 var integer pad_len := suffix_len - lengthof(suffix_ch);
336
337 return prefix & int2hex(0, pad_len) & str2hex(suffix_ch);
Harald Welte256571e2018-01-24 18:47:19 +0100338}
339
Harald Welte81b7f9d2018-01-24 19:06:24 +0100340function f_gen_imei(integer suffix) return hexstring {
341 return f_concat_pad(15, '49999'H, suffix);
Harald Weltea49e36e2018-01-21 19:29:33 +0100342}
343
Harald Welte81b7f9d2018-01-24 19:06:24 +0100344function f_gen_imsi(integer suffix) return hexstring {
345 return f_concat_pad(15, '26242'H, suffix);
346}
347
348function f_gen_msisdn(integer suffix) return hexstring {
349 return f_concat_pad(12, '49123'H, suffix);
Harald Weltea49e36e2018-01-21 19:29:33 +0100350}
351
352/* FIXME: move into BSC_ConnectionHandler? */
353function f_start_handler(void_fn fn, charstring id, integer imsi_suffix) runs on MTC_CT return BSC_ConnHdlr {
354 var BSC_ConnHdlr vc_conn;
355 var BSC_ConnHdlrPars pars := {
356 sccp_addr_own := g_sccp_addr_own,
357 sccp_addr_peer := g_sccp_addr_peer,
358 cell_id := valueof(ts_CellId_CGI('262'H, '042'H, 23, 42)),
Harald Welte81b7f9d2018-01-24 19:06:24 +0100359 imei := f_gen_imei(imsi_suffix),
360 imsi := f_gen_imsi(imsi_suffix),
361 msisdn := f_gen_msisdn(imsi_suffix),
Harald Welte256571e2018-01-24 18:47:19 +0100362 tmsi := omit,
Harald Welte82600572018-01-21 20:54:08 +0100363 cm2 := valueof(ts_CM2_default),
Harald Welte16114282018-01-24 22:41:21 +0100364 cm3 := omit,
Harald Welte148a7082018-01-26 18:56:43 +0100365 vec := omit
Harald Weltea49e36e2018-01-21 19:29:33 +0100366 };
367
368 vc_conn := BSC_ConnHdlr.create(id);
369 /* BSSMAP part / A interface */
370 connect(vc_conn:BSSAP, vc_BSSMAP:CLIENT);
371 connect(vc_conn:BSSAP_PROC, vc_BSSMAP:PROC);
372 /* MNCC part */
373 connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
374 connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);
Harald Welte4aa970c2018-01-26 10:38:09 +0100375 /* MGCP part */
376 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
377 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100378 /* GSUP part */
379 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
380 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
381
382 vc_conn.start(derefers(fn)(id, pars));
383 return vc_conn;
384}
385
Harald Welte3ca1c902018-01-24 18:51:27 +0100386function f_vty_config(TELNETasp_PT pt, charstring config_node, charstring cmd)
387{
388 /* enter config mode; enter node */
389 f_vty_enter_config(pt);
390 f_vty_transceive(pt, config_node);
391 /* execute command */
392 f_vty_transceive(pt, cmd);
393 /* leave config mode */
394 f_vty_transceive(pt, "end");
395}
396
Harald Weltea49e36e2018-01-21 19:29:33 +0100397private function f_tc_lu_imsi_noauth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
398 g_pars := pars;
Harald Welte8a121b32018-01-22 03:00:41 +0100399 f_perform_lu(false, true, true);
Harald Weltea49e36e2018-01-21 19:29:33 +0100400}
Harald Weltea49e36e2018-01-21 19:29:33 +0100401testcase TC_lu_imsi_noauth_tmsi() runs on MTC_CT {
402 var BSC_ConnHdlr vc_conn;
403 f_init();
404
405 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi), testcasename(), 1);
406 vc_conn.done;
407}
408
409private function f_tc_lu_imsi_noauth_notmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
410 g_pars := pars;
Harald Welte8a121b32018-01-22 03:00:41 +0100411 f_perform_lu(false, false, true);
Harald Weltea49e36e2018-01-21 19:29:33 +0100412}
Harald Weltea49e36e2018-01-21 19:29:33 +0100413testcase TC_lu_imsi_noauth_notmsi() runs on MTC_CT {
414 var BSC_ConnHdlr vc_conn;
415 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100416 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
Harald Weltea49e36e2018-01-21 19:29:33 +0100417
418 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi), testcasename(), 2);
419 vc_conn.done;
420}
421
422/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
423private function f_tc_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
424 g_pars := pars;
425 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
426
427 f_create_gsup_expect(hex2str(g_pars.imsi));
428 f_bssap_compl_l3(l3_lu);
429 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
430 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
431 alt {
432 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej(int2oct(23,1)))) { }
433 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
434 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
435 self.stop;
436 }
437 }
438 BSSAP.receive(tr_BSSMAP_ClearCommand);
439 BSSAP.send(ts_BSSMAP_ClearComplete);
440 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
441 setverdict(pass);
442}
443testcase TC_lu_imsi_reject() runs on MTC_CT {
444 var BSC_ConnHdlr vc_conn;
445 f_init();
446
447 vc_conn := f_start_handler(refers(f_tc_lu_imsi_reject), testcasename(), 3);
448 vc_conn.done;
449}
450
451/* Do LU by IMSI, timeout on GSUP */
452private function f_tc_lu_imsi_timeout_gsup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
453 g_pars := pars;
454 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
455
456 f_create_gsup_expect(hex2str(g_pars.imsi));
457 f_bssap_compl_l3(l3_lu);
458 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
459 /* Normally the HLR would need to respond here, but we decide to force a timeout here */
460 alt {
461 /* FIXME: Expect specific reject cause */
462 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
463 [] 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 }
468 BSSAP.receive(tr_BSSMAP_ClearCommand);
469 BSSAP.send(ts_BSSMAP_ClearComplete);
470 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
471 setverdict(pass);
472}
473testcase TC_lu_imsi_timeout_gsup() runs on MTC_CT {
474 var BSC_ConnHdlr vc_conn;
475 f_init();
476
477 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_gsup), testcasename(), 4);
478 vc_conn.done;
479}
480
Harald Welte7b1b2812018-01-22 21:23:06 +0100481private function f_tc_lu_imsi_auth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
482 g_pars := pars;
483 f_perform_lu(true, true, true);
484}
485testcase TC_lu_imsi_auth_tmsi() runs on MTC_CT {
486 var BSC_ConnHdlr vc_conn;
487 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100488 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte7b1b2812018-01-22 21:23:06 +0100489
490 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi), testcasename(), 5);
491 vc_conn.done;
492}
493
Harald Weltea49e36e2018-01-21 19:29:33 +0100494
495/* Send CM SERVICE REQ for IMSI that has never performed LU before */
496private function f_tc_cmserv_imsi_unknown(charstring id, BSC_ConnHdlrPars pars)
497runs on BSC_ConnHdlr {
Harald Welte4f9cdb82018-01-27 10:57:11 +0100498 g_pars := pars;
Harald Weltea49e36e2018-01-21 19:29:33 +0100499
500 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
501 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '042'H, 23, 42));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100502 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltea49e36e2018-01-21 19:29:33 +0100503
504 f_create_gsup_expect(hex2str(g_pars.imsi));
505
506 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
507 f_bssap_compl_l3(l3_info);
508
509 timer T := 10.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100510 T.start;
511 alt {
Harald Weltea49e36e2018-01-21 19:29:33 +0100512 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
513 //[] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC)) { }
514 [] BSSAP.receive { setverdict(fail, "Received unexpected BSSAP"); }
515 [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
516 setverdict(fail, "Unexpected GSUP UL REQ");
517 }
518 [] T.timeout { setverdict(inconc, "Timeout waiting for CM SERV REQ"); }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100519 }
520
Harald Weltea49e36e2018-01-21 19:29:33 +0100521 alt {
522 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
523 setverdict(pass);
524 }
525 [] BSSAP.receive { setverdict(fail, "Received unexpected BSSAP"); }
526 [] T.timeout { setverdict(inconc, "Timeout waiting for CM SERV REQ"); }
527 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100528}
Harald Weltea49e36e2018-01-21 19:29:33 +0100529testcase TC_cmserv_imsi_unknown() runs on MTC_CT {
530 var BSC_ConnHdlr vc_conn;
531 f_init();
Harald Welte81b7f9d2018-01-24 19:06:24 +0100532 vc_conn := f_start_handler(refers(f_tc_cmserv_imsi_unknown), testcasename(), 6);
Harald Weltea49e36e2018-01-21 19:29:33 +0100533 vc_conn.done;
534}
535
Harald Welte2bb825f2018-01-22 11:31:18 +0100536private function f_tc_lu_and_mo_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
537 g_pars := pars;
Harald Welteb71901a2018-01-26 19:16:05 +0100538 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
539 cpars.bss_rtp_port := 1110;
540 cpars.mgcp_connection_id_bss := '22222'H;
541 cpars.mgcp_connection_id_mss := '33333'H;
Harald Welte2bb825f2018-01-22 11:31:18 +0100542
Harald Welteb71901a2018-01-26 19:16:05 +0100543 f_perform_lu(cpars.expect_auth, true, true);
544 f_mo_call(cpars);
Harald Welte2bb825f2018-01-22 11:31:18 +0100545}
546testcase TC_lu_and_mo_call() runs on MTC_CT {
547 var BSC_ConnHdlr vc_conn;
548 f_init();
549
Harald Welte81b7f9d2018-01-24 19:06:24 +0100550 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_call), testcasename(), 7);
Harald Welte071ed732018-01-23 19:53:52 +0100551 vc_conn.done;
552}
553
554/* Test LU (with authentication enabled), where HLR times out sending SAI response */
555private function f_tc_lu_auth_sai_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
556 g_pars := pars;
557
558 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
559 var PDU_DTAP_MT dtap_mt;
560
561 /* tell GSUP dispatcher to send this IMSI to us */
562 f_create_gsup_expect(hex2str(g_pars.imsi));
563
564 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
565 f_bssap_compl_l3(l3_lu);
566
567 /* Send Early Classmark, just for the fun of it */
568 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
569
570 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
571 /* The HLR would normally return an auth vector here, but we fail to do so. */
572
573 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
574 BSSAP.receive(tr_BSSMAP_ClearCommand);
575 BSSAP.send(ts_BSSMAP_ClearComplete);
576 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
577 setverdict(pass);
578}
579testcase TC_lu_auth_sai_timeout() runs on MTC_CT {
580 var BSC_ConnHdlr vc_conn;
581 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100582 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100583
Harald Welte81b7f9d2018-01-24 19:06:24 +0100584 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_timeout), testcasename(), 8);
Harald Welte071ed732018-01-23 19:53:52 +0100585 vc_conn.done;
586}
587
588/* Test LU (with authentication enabled), where HLR rejects sending SAI error */
589private function f_tc_lu_auth_sai_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
590 g_pars := pars;
591
592 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
593 var PDU_DTAP_MT dtap_mt;
594
595 /* tell GSUP dispatcher to send this IMSI to us */
596 f_create_gsup_expect(hex2str(g_pars.imsi));
597
598 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
599 f_bssap_compl_l3(l3_lu);
600
601 /* Send Early Classmark, just for the fun of it */
602 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
603
604 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
605 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 13));
606
607 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
608 BSSAP.receive(tr_BSSMAP_ClearCommand);
609 BSSAP.send(ts_BSSMAP_ClearComplete);
610 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
611 setverdict(pass);
612}
613testcase TC_lu_auth_sai_err() runs on MTC_CT {
614 var BSC_ConnHdlr vc_conn;
615 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100616 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100617
Harald Welte81b7f9d2018-01-24 19:06:24 +0100618 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_err), testcasename(), 9);
Harald Welte2bb825f2018-01-22 11:31:18 +0100619 vc_conn.done;
620}
Harald Weltea49e36e2018-01-21 19:29:33 +0100621
Harald Weltebc881782018-01-23 20:09:15 +0100622/* Test LU but BSC will send a clear request in the middle */
623private function f_tc_lu_clear_request(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
624 g_pars := pars;
625
626 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
627 var PDU_DTAP_MT dtap_mt;
628
629 /* tell GSUP dispatcher to send this IMSI to us */
630 f_create_gsup_expect(hex2str(g_pars.imsi));
631
632 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
633 f_bssap_compl_l3(l3_lu);
634
635 /* Send Early Classmark, just for the fun of it */
636 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
637
638 f_sleep(1.0);
639 /* send clear request in the middle of the LU */
640 BSSAP.send(ts_BSSMAP_ClearRequest(0));
641 BSSAP.receive(tr_BSSMAP_ClearCommand);
642 BSSAP.send(ts_BSSMAP_ClearComplete);
643 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
644 setverdict(pass);
645}
646testcase TC_lu_clear_request() runs on MTC_CT {
647 var BSC_ConnHdlr vc_conn;
648 f_init();
649
Harald Welte81b7f9d2018-01-24 19:06:24 +0100650 vc_conn := f_start_handler(refers(f_tc_lu_clear_request), testcasename(), 10);
Harald Weltebc881782018-01-23 20:09:15 +0100651 vc_conn.done;
652}
653
Harald Welte66af9e62018-01-24 17:28:21 +0100654/* Test LU but BSC will send a clear request in the middle */
655private function f_tc_lu_disconnect(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
656 g_pars := pars;
657
658 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
659 var PDU_DTAP_MT dtap_mt;
660
661 /* tell GSUP dispatcher to send this IMSI to us */
662 f_create_gsup_expect(hex2str(g_pars.imsi));
663
664 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
665 f_bssap_compl_l3(l3_lu);
666
667 /* Send Early Classmark, just for the fun of it */
668 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
669
670 f_sleep(1.0);
671 /* send clear request in the middle of the LU */
672 BSSAP.send(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
673 setverdict(pass);
674}
675testcase TC_lu_disconnect() runs on MTC_CT {
676 var BSC_ConnHdlr vc_conn;
677 f_init();
678
Harald Welte81b7f9d2018-01-24 19:06:24 +0100679 vc_conn := f_start_handler(refers(f_tc_lu_disconnect), testcasename(), 11);
Harald Welte66af9e62018-01-24 17:28:21 +0100680 vc_conn.done;
681}
682
683
Harald Welteba7b6d92018-01-23 21:32:34 +0100684/* Test LU but with illegal mobile identity type = IMEI */
685private function f_tc_lu_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
686 g_pars := pars;
687
Harald Welte256571e2018-01-24 18:47:19 +0100688 var PDU_ML3_MS_NW l3_lu := f_build_lu_imei(g_pars.imei)
Harald Welteba7b6d92018-01-23 21:32:34 +0100689 var PDU_DTAP_MT dtap_mt;
690
691 /* tell GSUP dispatcher to send this IMSI to us */
692 f_create_gsup_expect(hex2str(g_pars.imsi));
693
694 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
695 f_bssap_compl_l3(l3_lu);
696
697 /* Send Early Classmark, just for the fun of it */
698 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
699 /* wait for LU reject, ignore any ID REQ */
700 alt {
701 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
702 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req)) { repeat; }
703 }
704 /* wait for normal teardown */
705 BSSAP.receive(tr_BSSMAP_ClearCommand);
706 BSSAP.send(ts_BSSMAP_ClearComplete);
707 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
708 setverdict(pass);
709}
710testcase TC_lu_by_imei() runs on MTC_CT {
711 var BSC_ConnHdlr vc_conn;
712 f_init();
713
Harald Welte81b7f9d2018-01-24 19:06:24 +0100714 vc_conn := f_start_handler(refers(f_tc_lu_by_imei), testcasename(), 12);
Harald Welteba7b6d92018-01-23 21:32:34 +0100715 vc_conn.done;
716}
717
718/* Test LU by TMSI with unknown TMSI, expect (and answer) ID REQ. */
719private function f_tc_lu_tmsi_noauth_unknown(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
720 g_pars := pars;
721
722 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('01020304'O); /* FIXME: Random */
723 var PDU_DTAP_MT dtap_mt;
724
725 /* tell GSUP dispatcher to send this IMSI to us */
726 f_create_gsup_expect(hex2str(g_pars.imsi));
727
728 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
729 f_bssap_compl_l3(l3_lu);
730
731 /* Send Early Classmark, just for the fun of it */
732 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
733
734 /* Wait for + respond to ID REQ (IMSI) */
735 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req('001'B)));
736 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
737
738 /* Expect MSC to do UpdateLocation to HLR; respond to it */
739 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
740 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
741 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
742 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
743
744 alt {
Harald Welte7ec4fa82018-01-27 10:57:40 +0100745 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
746 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
747 }
Harald Welteba7b6d92018-01-23 21:32:34 +0100748 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
749 setverdict(fail, "Expected LU ACK, but received REJ");
750 }
751 }
752
753 /* wait for normal teardown */
754 BSSAP.receive(tr_BSSMAP_ClearCommand);
755 BSSAP.send(ts_BSSMAP_ClearComplete);
756 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
757 setverdict(pass);
758}
759testcase TC_lu_by_tmsi_noauth_unknown() runs on MTC_CT {
760 var BSC_ConnHdlr vc_conn;
761 f_init();
762
Harald Welte81b7f9d2018-01-24 19:06:24 +0100763 vc_conn := f_start_handler(refers(f_tc_lu_tmsi_noauth_unknown), testcasename(), 13);
Harald Welteba7b6d92018-01-23 21:32:34 +0100764 vc_conn.done;
765}
766
767
Harald Welte45164da2018-01-24 12:51:27 +0100768/* Test IMSI DETACH (MI=IMSI) */
769private function f_tc_imsi_detach_by_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
770 g_pars := pars;
771
772 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
773
774 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
775 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
776
777 /* Send Early Classmark, just for the fun of it? */
778 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
779
780 /* wait for normal teardown */
781 BSSAP.receive(tr_BSSMAP_ClearCommand);
782 BSSAP.send(ts_BSSMAP_ClearComplete);
783 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
784 setverdict(pass);
785}
786testcase TC_imsi_detach_by_imsi() runs on MTC_CT {
787 var BSC_ConnHdlr vc_conn;
788 f_init();
789
Harald Welte81b7f9d2018-01-24 19:06:24 +0100790 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imsi), testcasename(), 14);
Harald Welte45164da2018-01-24 12:51:27 +0100791 vc_conn.done;
792}
793
794/* Test IMSI DETACH (MI=TMSI) */
795private function f_tc_imsi_detach_by_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
796 g_pars := pars;
797
798 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('01020304'O));
799
800 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
801 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
802
803 /* Send Early Classmark, just for the fun of it? */
804 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
805
806 /* wait for normal teardown */
807 BSSAP.receive(tr_BSSMAP_ClearCommand);
808 BSSAP.send(ts_BSSMAP_ClearComplete);
809 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
810 setverdict(pass);
811}
812testcase TC_imsi_detach_by_tmsi() runs on MTC_CT {
813 var BSC_ConnHdlr vc_conn;
814 f_init();
815
Harald Welte81b7f9d2018-01-24 19:06:24 +0100816 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_tmsi), testcasename(), 15);
Harald Welte45164da2018-01-24 12:51:27 +0100817 vc_conn.done;
818}
819
820/* Test IMSI DETACH (MI=IMEI), which is illegal */
821private function f_tc_imsi_detach_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
822 g_pars := pars;
823
Harald Welte256571e2018-01-24 18:47:19 +0100824 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte45164da2018-01-24 12:51:27 +0100825
826 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
827 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
828
829 /* Send Early Classmark, just for the fun of it? */
830 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
831
832 /* wait for normal teardown */
833 BSSAP.receive(tr_BSSMAP_ClearCommand);
834 BSSAP.send(ts_BSSMAP_ClearComplete);
835 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
836 setverdict(pass);
837}
838testcase TC_imsi_detach_by_imei() runs on MTC_CT {
839 var BSC_ConnHdlr vc_conn;
840 f_init();
841
Harald Welte81b7f9d2018-01-24 19:06:24 +0100842 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imei), testcasename(), 16);
Harald Welte45164da2018-01-24 12:51:27 +0100843 vc_conn.done;
844}
845
846
847/* helper function for an emergency call. caller passes in mobile identity to use */
848private function f_emerg_call(MobileIdentityLV mi) runs on BSC_ConnHdlr {
849
Harald Welte6ed6bf92018-01-24 21:09:15 +0100850 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100851 f_bssap_compl_l3(l3_info);
852 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC));
853
854 var hexstring called := '112'H;
855 var integer tid := 0;
856 var MNCC_PDU mncc;
857 f_create_mncc_expect(hex2str(called));
858
859 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_EMERG_SETUP(tid)));
860 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(called)))) -> value mncc;
861 /* FIXME: extract call_id */
862
863 /* Call Proceeding */
864 MNCC.send(ts_MNCC_CALL_PROC_req(mncc.u.signal.callref, ts_MNCC_bcap_voice));
865 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(tid)));
866
867 /* Alerting */
868 MNCC.send(ts_MNCC_ALERT_req(mncc.u.signal.callref));
869 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(tid)));
870
871 /* Answer. This causes TCH assignment in case of "late assignment" */
Harald Welte4017d552018-01-26 21:40:05 +0100872 //MNCC.send(ts_MNCC_SETUP_COMPL_req(mncc.u.signal.callref));
873 MNCC.send(ts_MNCC_SETUP_rsp(mncc.u.signal.callref));
Harald Welte45164da2018-01-24 12:51:27 +0100874
875 f_sleep(3.0);
876
877 /* Hangup by "B" side */
878 MNCC.send(ts_MNCC_DISC_req(mncc.u.signal.callref, valueof(ts_MNCC_cause(23))));
879 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(tid)));
880
881 /* Release of call */
882 MNCC.send(ts_MNCC_REL_req(mncc.u.signal.callref, valueof(ts_MNCC_cause(42))));
883 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(tid)));
884
885 /* clearing of radio channel */
886 BSSAP.receive(tr_BSSMAP_ClearCommand);
887 BSSAP.send(ts_BSSMAP_ClearComplete);
888 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
889
890 f_sleep(5.0);
891}
892
893/* establish an emergency call by IMEI, no SIM inserted (and hence no IMSI) */
894private function f_tc_emerg_call_imei_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
895 g_pars := pars;
896
Harald Welte256571e2018-01-24 18:47:19 +0100897 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100898 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100899 f_bssap_compl_l3(l3_info);
900 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ('05'O)));
Harald Weltef6b62ee2018-01-24 21:49:32 +0100901 BSSAP.receive(tr_BSSMAP_ClearCommand);
902 BSSAP.send(ts_BSSMAP_ClearComplete);
903 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
Harald Welte45164da2018-01-24 12:51:27 +0100904 setverdict(pass);
905}
906testcase TC_emerg_call_imei_reject() runs on MTC_CT {
907 var BSC_ConnHdlr vc_conn;
908 f_init();
909
Harald Welte81b7f9d2018-01-24 19:06:24 +0100910 vc_conn := f_start_handler(refers(f_tc_emerg_call_imei_reject), testcasename(), 17);
Harald Welte45164da2018-01-24 12:51:27 +0100911 vc_conn.done;
912}
913
Harald Welted5b91402018-01-24 18:48:16 +0100914/* establish an emergency call by IMSI, SIM inserted (and hence IMSI) */
Harald Welte45164da2018-01-24 12:51:27 +0100915private function f_tc_emerg_call_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
916 g_pars := pars;
917 /* First perform location update to ensure subscriber is known */
918 f_perform_lu(false, true, true);
919 /* Then issue emergency call identified by IMSI */
920 f_emerg_call(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
921}
922testcase TC_emerg_call_imsi() runs on MTC_CT {
923 var BSC_ConnHdlr vc_conn;
924 f_init();
925
Harald Welte81b7f9d2018-01-24 19:06:24 +0100926 vc_conn := f_start_handler(refers(f_tc_emerg_call_imsi), testcasename(), 18);
Harald Welte45164da2018-01-24 12:51:27 +0100927 vc_conn.done;
928}
929
930/* CM Service Request for VGCS -> reject */
931private function f_tc_cm_serv_req_vgcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
932 g_pars := pars;
933
934 /* First perform location update to ensure subscriber is known */
935 f_perform_lu(false, true, true);
936
937 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100938 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VGCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100939 f_bssap_compl_l3(l3_info);
940 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Weltef6b62ee2018-01-24 21:49:32 +0100941 BSSAP.receive(tr_BSSMAP_ClearCommand);
942 BSSAP.send(ts_BSSMAP_ClearComplete);
943 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
Harald Welte45164da2018-01-24 12:51:27 +0100944 setverdict(pass);
945}
946testcase TC_cm_serv_req_vgcs_reject() runs on MTC_CT {
947 var BSC_ConnHdlr vc_conn;
948 f_init();
949
Harald Welte81b7f9d2018-01-24 19:06:24 +0100950 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vgcs_reject), testcasename(), 19);
Harald Welte45164da2018-01-24 12:51:27 +0100951 vc_conn.done;
952}
953
954/* CM Service Request for VBS -> reject */
955private function f_tc_cm_serv_req_vbs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
956 g_pars := pars;
957
958 /* First perform location update to ensure subscriber is known */
959 f_perform_lu(false, true, true);
960
961 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100962 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VBS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100963 f_bssap_compl_l3(l3_info);
964 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Weltef6b62ee2018-01-24 21:49:32 +0100965 BSSAP.receive(tr_BSSMAP_ClearCommand);
966 BSSAP.send(ts_BSSMAP_ClearComplete);
967 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
Harald Welte45164da2018-01-24 12:51:27 +0100968 setverdict(pass);
969}
970testcase TC_cm_serv_req_vbs_reject() runs on MTC_CT {
971 var BSC_ConnHdlr vc_conn;
972 f_init();
973
Harald Welte81b7f9d2018-01-24 19:06:24 +0100974 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vbs_reject), testcasename(), 20);
Harald Welte45164da2018-01-24 12:51:27 +0100975 vc_conn.done;
976}
977
978/* CM Service Request for LCS -> reject */
979private function f_tc_cm_serv_req_lcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
980 g_pars := pars;
981
982 /* First perform location update to ensure subscriber is known */
983 f_perform_lu(false, true, true);
984
985 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100986 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_LCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100987 f_bssap_compl_l3(l3_info);
988 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte0195ab12018-01-24 21:50:20 +0100989 BSSAP.receive(tr_BSSMAP_ClearCommand);
990 BSSAP.send(ts_BSSMAP_ClearComplete);
991 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
Harald Welte45164da2018-01-24 12:51:27 +0100992 setverdict(pass);
993}
994testcase TC_cm_serv_req_lcs_reject() runs on MTC_CT {
995 var BSC_ConnHdlr vc_conn;
996 f_init();
997
Harald Welte81b7f9d2018-01-24 19:06:24 +0100998 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_lcs_reject), testcasename(), 21);
Harald Welte45164da2018-01-24 12:51:27 +0100999 vc_conn.done;
1000}
1001
Harald Welte0195ab12018-01-24 21:50:20 +01001002/* CM Re-Establishment Request */
1003private function f_tc_cm_reest_req_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1004 g_pars := pars;
1005
1006 /* First perform location update to ensure subscriber is known */
1007 f_perform_lu(false, true, true);
1008
1009 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1010 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REEST_REQ(0, mi));
1011 f_bssap_compl_l3(l3_info);
1012 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
1013 BSSAP.receive(tr_BSSMAP_ClearCommand);
1014 BSSAP.send(ts_BSSMAP_ClearComplete);
1015 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1016 setverdict(pass);
1017}
1018testcase TC_cm_reest_req_reject() runs on MTC_CT {
1019 var BSC_ConnHdlr vc_conn;
1020 f_init();
Harald Welte0195ab12018-01-24 21:50:20 +01001021
1022 vc_conn := f_start_handler(refers(f_tc_cm_reest_req_reject), testcasename(), 22);
1023 vc_conn.done;
1024}
1025
Harald Weltec638f4d2018-01-24 22:00:36 +01001026/* Test LU (with authentication enabled), with wrong response from MS */
1027private function f_tc_lu_auth_2G_fail(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1028 g_pars := pars;
1029
1030 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
1031
1032 /* tell GSUP dispatcher to send this IMSI to us */
1033 f_create_gsup_expect(hex2str(g_pars.imsi));
1034
1035 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
1036 f_bssap_compl_l3(l3_lu);
1037
1038 /* Send Early Classmark, just for the fun of it */
1039 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1040
1041 var AuthVector vec := f_gen_auth_vec_2g();
1042 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(vec.rand, vec.sres, vec.kc));
1043 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
1044 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
1045
1046 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(vec.rand)));
1047 /* Send back wrong auth response */
1048 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G('00000000'O)));
1049
1050 /* Expect GSUP AUTH FAIL REP to HLR */
1051 GSUP.receive(tr_GSUP_AUTH_FAIL_IND(g_pars.imsi));
1052
1053 /* Expect LU REJECT with Cause == Illegal MS */
1054 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej('03'O)));
1055 BSSAP.receive(tr_BSSMAP_ClearCommand);
1056 BSSAP.send(ts_BSSMAP_ClearComplete);
1057 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1058 setverdict(pass);
1059}
1060testcase TC_lu_auth_2G_fail() runs on MTC_CT {
1061 var BSC_ConnHdlr vc_conn;
1062 f_init();
1063 f_vty_config(MSCVTY, "network", "authentication required");
1064 f_vty_config(MSCVTY, "msc", "assign-tmsi");
1065
1066 vc_conn := f_start_handler(refers(f_tc_lu_auth_2G_fail), testcasename(), 23);
1067 vc_conn.done;
1068}
1069
Harald Welte16114282018-01-24 22:41:21 +01001070private function f_tc_lu_imsi_auth_tmsi_encr_13_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1071 g_pars := pars;
1072 f_perform_lu(true, true, true, true);
1073}
1074testcase TC_lu_imsi_auth_tmsi_encr_13_13() runs on MTC_CT {
1075 var BSC_ConnHdlr vc_conn;
1076 f_init();
1077 f_vty_config(MSCVTY, "network", "authentication required");
1078 f_vty_config(MSCVTY, "msc", "assign-tmsi");
1079 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1080
1081 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_13), testcasename(), 24);
1082 vc_conn.done;
1083}
1084
Harald Welte1af6ea82018-01-25 18:33:15 +01001085/* Test Complete L3 without payload */
1086private function f_tc_cl3_no_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1087 g_pars := pars;
1088
1089 /* Send Complete L3 Info with empty L3 frame */
1090 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1091 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, ''O))));
1092
1093 alt {
1094 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
1095 /* Expect LU REJECT with Cause == Illegal MS */
1096 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1097 BSSAP.send(ts_BSSMAP_ClearComplete);
1098 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1099 }
1100 }
1101 setverdict(pass);
1102}
1103testcase TC_cl3_no_payload() runs on MTC_CT {
1104 var BSC_ConnHdlr vc_conn;
1105 f_init();
1106
1107 vc_conn := f_start_handler(refers(f_tc_cl3_no_payload), testcasename(), 24);
1108 vc_conn.done;
1109}
1110
1111/* Test Complete L3 with random payload */
1112private function f_tc_cl3_rnd_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1113 g_pars := pars;
1114
1115 var integer len := float2int(rnd() * 256.0);
1116 var octetstring payl := f_rnd_octstring(len);
1117
1118 /* Send Complete L3 Info with empty L3 frame */
1119 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1120 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, payl))));
1121
1122 alt {
1123 /* Immediate disconnect */
1124 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
1125 /* Expect LU REJECT with Cause == Illegal MS */
1126 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1127 BSSAP.send(ts_BSSMAP_ClearComplete);
1128 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1129 }
1130 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
1131 }
1132 setverdict(pass);
1133}
1134testcase TC_cl3_rnd_payload() runs on MTC_CT {
1135 var BSC_ConnHdlr vc_conn;
1136 f_init();
1137
1138 vc_conn := f_start_handler(refers(f_tc_cl3_rnd_payload), testcasename(), 24);
1139 vc_conn.done;
1140}
1141
Harald Welte116e4332018-01-26 22:17:48 +01001142/* Test Complete L3 with random payload */
1143private function f_tc_establish_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1144 g_pars := pars;
1145
1146 f_perform_lu(false, true, true, false);
1147
1148 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)), false, false);
1149 timer T := 30.0;
Harald Welte946a5382018-01-26 22:53:14 +01001150 T.start;
Harald Welte116e4332018-01-26 22:17:48 +01001151 alt {
Harald Welte12510c52018-01-26 22:26:24 +01001152 [] T.timeout { setverdict(fail, "Timeout waiting for channel release"); self.stop; }
Harald Welte116e4332018-01-26 22:17:48 +01001153 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1154 BSSAP.send(ts_BSSMAP_ClearComplete);
1155 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1156 setverdict(pass);
1157 }
1158 [] BSSAP.receive { repeat; }
1159 [] MNCC.receive { repeat; }
1160 [] GSUP.receive { repeat; }
1161 [] MGCP.receive { repeat; }
1162 }
1163}
1164testcase TC_establish_and_nothing() runs on MTC_CT {
1165 var BSC_ConnHdlr vc_conn;
1166 f_init();
1167
1168 vc_conn := f_start_handler(refers(f_tc_establish_and_nothing), testcasename(), 25);
1169 vc_conn.done;
1170}
1171
Harald Welte12510c52018-01-26 22:26:24 +01001172/* Test MO Call SETUP with no response from MNCC */
1173private function f_tc_mo_setup_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1174 g_pars := pars;
1175 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1176
1177 f_perform_lu(false, true, true, false);
1178
1179 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)), false, false);
1180 f_create_mncc_expect(hex2str(cpars.called_party));
1181 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1182
1183 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1184
1185 timer T := 30.0;
Harald Welte946a5382018-01-26 22:53:14 +01001186 T.start;
Harald Welte12510c52018-01-26 22:26:24 +01001187 alt {
1188 [] T.timeout { setverdict(fail, "Timeout waiting for channel release"); self.stop; }
1189 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1190 BSSAP.send(ts_BSSMAP_ClearComplete);
1191 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1192 setverdict(pass);
1193 }
1194 [] BSSAP.receive { repeat; }
1195 [] MNCC.receive { repeat; }
1196 [] GSUP.receive { repeat; }
1197 [] MGCP.receive { repeat; }
1198 }
1199}
1200testcase TC_mo_setup_and_nothing() runs on MTC_CT {
1201 var BSC_ConnHdlr vc_conn;
1202 f_init();
1203
1204 vc_conn := f_start_handler(refers(f_tc_mo_setup_and_nothing), testcasename(), 26);
1205 vc_conn.done;
1206}
1207
Harald Welte3ab88002018-01-26 22:37:25 +01001208/* Test MO Call with no response to RAN-side CRCX */
1209private function f_tc_mo_crcx_ran_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1210 g_pars := pars;
1211 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1212 var MNCC_PDU mncc;
1213 var MgcpCommand mgcp_cmd;
1214
1215 f_perform_lu(false, true, true, false);
1216
1217 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)), false, false);
1218 f_create_mncc_expect(hex2str(cpars.called_party));
1219 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1220
1221 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1222 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1223 cpars.mncc_callref := mncc.u.signal.callref;
1224 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1225 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1226
1227 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
Harald Welte1852a842018-01-26 22:53:36 +01001228 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1229 cpars.mgcp_ep := mgcp_cmd.line.ep;
Harald Welte3ab88002018-01-26 22:37:25 +01001230 /* never respond to this */
1231
1232 timer T := 30.0;
Harald Welte946a5382018-01-26 22:53:14 +01001233 T.start;
Harald Welte3ab88002018-01-26 22:37:25 +01001234 alt {
1235 [] T.timeout { setverdict(fail, "Timeout waiting for channel release"); self.stop; }
1236 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1237 BSSAP.send(ts_BSSMAP_ClearComplete);
1238 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1239 setverdict(pass);
1240 }
1241 [] BSSAP.receive { repeat; }
1242 [] MNCC.receive { repeat; }
1243 [] GSUP.receive { repeat; }
1244 [] MGCP.receive { repeat; }
1245 }
1246}
1247testcase TC_mo_crcx_ran_timeout() runs on MTC_CT {
1248 var BSC_ConnHdlr vc_conn;
1249 f_init();
1250
1251 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_timeout), testcasename(), 27);
1252 vc_conn.done;
1253}
1254
Harald Welte0cc82d92018-01-26 22:52:34 +01001255/* Test MO Call with reject to RAN-side CRCX */
1256private function f_tc_mo_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1257 g_pars := pars;
1258 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1259 var MNCC_PDU mncc;
1260 var MgcpCommand mgcp_cmd;
1261
1262 f_perform_lu(false, true, true, false);
1263
1264 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)), false, false);
1265 f_create_mncc_expect(hex2str(cpars.called_party));
1266 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1267
1268 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1269 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1270 cpars.mncc_callref := mncc.u.signal.callref;
1271 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1272 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1273
1274 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1275 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1276 cpars.mgcp_ep := mgcp_cmd.line.ep;
1277 /* Respond to CRCX with error */
1278 var MgcpResponse mgcp_rsp := {
1279 line := {
1280 code := "542",
1281 trans_id := mgcp_cmd.line.trans_id,
1282 string := "FORCED_FAIL"
1283 },
1284 params := omit,
1285 sdp := omit
1286 }
1287 MGCP.send(mgcp_rsp);
1288
1289 timer T := 30.0;
1290 T.start;
1291 alt {
1292 [] T.timeout { setverdict(fail, "Timeout waiting for channel release"); self.stop; }
1293 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1294 BSSAP.send(ts_BSSMAP_ClearComplete);
1295 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1296 setverdict(pass);
1297 }
1298 [] BSSAP.receive { repeat; }
1299 [] MNCC.receive { repeat; }
1300 [] GSUP.receive { repeat; }
1301 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1302 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1303 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1304 }
1305 [] MGCP.receive { repeat; }
1306 }
1307}
1308testcase TC_mo_crcx_ran_reject() runs on MTC_CT {
1309 var BSC_ConnHdlr vc_conn;
1310 f_init();
1311
1312 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_reject), testcasename(), 28);
1313 vc_conn.done;
1314}
1315
Harald Welte3ab88002018-01-26 22:37:25 +01001316
Harald Welte812f7a42018-01-27 00:49:18 +01001317/* helper function to start a MT call: MNCC SETUP; Paging; DChan est.; DTAP SETUP */
1318private function f_mt_call_start(inout CallParameters cpars) runs on BSC_ConnHdlr {
1319 var MNCC_PDU mncc;
1320 var MgcpCommand mgcp_cmd;
1321 var OCT4 tmsi;
1322
1323 f_perform_lu(false, true, true, false);
1324 if (isvalue(g_pars.tmsi)) {
1325 tmsi := g_pars.tmsi;
1326 } else {
1327 tmsi := 'FFFFFFFF'O;
1328 }
1329 f_bssmap_register_imsi(g_pars.imsi, tmsi);
1330
1331 /* Allocate call reference and send SETUP via MNCC to MSC */
1332 cpars.mncc_callref := f_rnd_int(2147483648);
1333 MNCC.send(ts_MNCC_SETUP_req(cpars.mncc_callref, hex2str(g_pars.msisdn),
1334 hex2str(cpars.called_party), hex2str(g_pars.imsi)));
1335
1336 /* MSC->BSC: expect PAGING from MSC */
1337 BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));
1338 /* MS -> MSC: PAGING RESPONSE */
1339 f_establish_fully_pag(valueof(ts_MI_IMSI_LV(g_pars.imsi)), false, false);
1340
1341 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1342
1343 /* MSC->MS: SETUP */
1344 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party)));
1345}
1346
1347/* Test MT Call */
1348private function f_tc_mt_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1349 g_pars := pars;
1350 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1351 var MNCC_PDU mncc;
1352 var MgcpCommand mgcp_cmd;
1353
1354 f_mt_call_start(cpars);
1355
1356 /* MS->MSC: CALL CONFIRMED */
1357 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1358
1359 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1360
1361 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1362 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1363 cpars.mgcp_ep := mgcp_cmd.line.ep;
1364 /* Respond to CRCX with error */
1365 var MgcpResponse mgcp_rsp := {
1366 line := {
1367 code := "542",
1368 trans_id := mgcp_cmd.line.trans_id,
1369 string := "FORCED_FAIL"
1370 },
1371 params := omit,
1372 sdp := omit
1373 }
1374 MGCP.send(mgcp_rsp);
1375
1376 timer T := 30.0;
1377 T.start;
1378 alt {
1379 [] T.timeout { setverdict(fail, "Timeout waiting for channel release"); self.stop; }
1380 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1381 BSSAP.send(ts_BSSMAP_ClearComplete);
1382 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1383 setverdict(pass);
1384 }
1385 [] BSSAP.receive { repeat; }
1386 [] MNCC.receive { repeat; }
1387 [] GSUP.receive { repeat; }
1388 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1389 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1390 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1391 repeat;
1392 }
1393 [] MGCP.receive { repeat; }
1394 }
1395}
1396testcase TC_mt_crcx_ran_reject() runs on MTC_CT {
1397 var BSC_ConnHdlr vc_conn;
1398 f_init();
1399
1400 vc_conn := f_start_handler(refers(f_tc_mt_crcx_ran_reject), testcasename(), 29);
1401 vc_conn.done;
1402}
1403
1404
1405/* Test MT Call T310 timer */
1406private function f_tc_mt_t310(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1407 g_pars := pars;
1408 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1409 var MNCC_PDU mncc;
1410 var MgcpCommand mgcp_cmd;
1411
1412 f_mt_call_start(cpars);
1413
1414 /* MS->MSC: CALL CONFIRMED */
1415 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1416 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1417
1418 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1419 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1420 cpars.mgcp_ep := mgcp_cmd.line.ep;
1421 /* FIXME: Respond to CRCX */
1422
1423 /* old libosmocore T310 default timeout is 180s. so let's wait 190 */
1424 timer T := 190.0;
1425 T.start;
1426 alt {
1427 [] T.timeout { setverdict(fail, "Timeout waiting for T310"); self.stop; }
1428 [] MNCC.receive(tr_MNCC_DISC_ind(cpars.mncc_callref)) {
1429 MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(23))));
1430 }
1431 }
1432 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));
1433 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1434 /* FIXME: We're sending this with TIflag 0: allocated by sender, which is wrong */
1435 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1436
1437 alt {
1438 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1439 BSSAP.send(ts_BSSMAP_ClearComplete);
1440 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1441 setverdict(pass);
1442 }
1443 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1444 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1445 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1446 repeat;
1447 }
1448 }
1449}
1450testcase TC_mt_t310() runs on MTC_CT {
1451 var BSC_ConnHdlr vc_conn;
1452 f_init();
1453
1454 vc_conn := f_start_handler(refers(f_tc_mt_t310), testcasename(), 30);
1455 vc_conn.done;
1456}
1457
Harald Welte12510c52018-01-26 22:26:24 +01001458
Harald Welte45164da2018-01-24 12:51:27 +01001459
Harald Welteba7b6d92018-01-23 21:32:34 +01001460/* TODO:
1461 * continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
1462 * malformed messages (missing IE, invalid message type): properly rejected?
1463 * MT call while LU or is ongoing: Do we use existing lchan or page while lchan active?
1464 * 3G/2G auth permutations
1465 * encryption algorithms vs. classmark vs. vty config
Harald Welteba7b6d92018-01-23 21:32:34 +01001466 * send new transaction after/during clear (like SMS, ...)
Harald Welte45164da2018-01-24 12:51:27 +01001467 * too long L3 INFO in DTAP
1468 * too long / padded BSSAP
1469 * too long / short TLV values
Harald Welteba7b6d92018-01-23 21:32:34 +01001470 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01001471
1472
1473control {
Harald Weltea49e36e2018-01-21 19:29:33 +01001474 execute( TC_cmserv_imsi_unknown() );
1475 execute( TC_lu_imsi_noauth_tmsi() );
1476 //execute( TC_lu_imsi_noauth_notmsi() );
1477 execute( TC_lu_imsi_reject() );
1478 execute( TC_lu_imsi_timeout_gsup() );
Harald Welte2bb825f2018-01-22 11:31:18 +01001479 execute( TC_lu_and_mo_call() );
Harald Welte071ed732018-01-23 19:53:52 +01001480 execute( TC_lu_auth_sai_timeout() );
1481 execute( TC_lu_auth_sai_err() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01001482 execute( TC_lu_clear_request() );
1483 execute( TC_lu_disconnect() );
1484 execute( TC_lu_by_imei() );
1485 execute( TC_lu_by_tmsi_noauth_unknown() );
1486 execute( TC_imsi_detach_by_imsi() );
1487 execute( TC_imsi_detach_by_tmsi() );
1488 execute( TC_imsi_detach_by_imei() );
1489 execute( TC_emerg_call_imei_reject() );
1490 execute( TC_emerg_call_imsi() );
1491 execute( TC_cm_serv_req_vgcs_reject() );
1492 execute( TC_cm_serv_req_vbs_reject() );
1493 execute( TC_cm_serv_req_lcs_reject() );
Harald Welte0195ab12018-01-24 21:50:20 +01001494 execute( TC_cm_reest_req_reject() );
Harald Welte1af6ea82018-01-25 18:33:15 +01001495 execute( TC_lu_auth_2G_fail() );
1496 execute( TC_lu_imsi_auth_tmsi_encr_13_13() );
1497 execute( TC_cl3_no_payload() );
1498 execute( TC_cl3_rnd_payload() );
Harald Welte1852a842018-01-26 22:53:36 +01001499 execute( TC_establish_and_nothing() );
1500 execute( TC_mo_setup_and_nothing() );
1501 execute( TC_mo_crcx_ran_timeout() );
1502 execute( TC_mo_crcx_ran_reject() );
Harald Weltef6dd64d2017-11-19 12:09:51 +01001503}
1504
1505
1506}