blob: 5f49d3a7ec0db7225362380c1bcc14c7489019be [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
29import from GSUP_Emulation all;
30import from GSUP_Types all;
31import from IPA_Emulation all;
32
Harald Weltef6dd64d2017-11-19 12:09:51 +010033import from BSSAP_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +010034import from BSSAP_Adapter all;
35import from BSSAP_CodecPort all;
36import from BSSMAP_Templates all;
37import from BSSMAP_Emulation all;
38import from BSC_ConnectionHandler all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010039
Harald Weltea49e36e2018-01-21 19:29:33 +010040import from MobileL3_Types all;
41import from MobileL3_CommonIE_Types all;
42import from L3_Templates all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010043
Harald Weltef6dd64d2017-11-19 12:09:51 +010044
Harald Weltea49e36e2018-01-21 19:29:33 +010045type component MTC_CT extends BSSAP_Adapter_CT, CTRL_Adapter_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +010046 var boolean g_initialized := false;
Harald Weltea49e36e2018-01-21 19:29:33 +010047
48 /* no 'adapter_CT' for MNCC or GSUP */
49 var MNCC_Emulation_CT vc_MNCC;
50 var GSUP_Emulation_CT vc_GSUP;
51 var IPA_Emulation_CT vc_GSUP_IPA;
52
53 /* only to get events from IPA underneath GSUP */
54 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte3ca1c902018-01-24 18:51:27 +010055 /* VTY to MSC */
56 port TELNETasp_PT MSCVTY;
Harald Weltef6dd64d2017-11-19 12:09:51 +010057}
58
59modulepar {
Harald Weltea49e36e2018-01-21 19:29:33 +010060 /* remote parameters of IUT */
61 charstring mp_msc_ip := "127.0.0.1";
62 integer mp_msc_ctrl_port := 4255;
63 integer mp_msc_vty_port := 4254;
Harald Weltef6dd64d2017-11-19 12:09:51 +010064
Harald Weltea49e36e2018-01-21 19:29:33 +010065 /* local parameters of emulated HLR */
66 charstring mp_hlr_ip := "127.0.0.1";
67 integer mp_hlr_port := 4222;
Harald Weltef6dd64d2017-11-19 12:09:51 +010068
Harald Weltea49e36e2018-01-21 19:29:33 +010069 charstring mp_msc_mncc := "/tmp/mncc";
Harald Weltef6dd64d2017-11-19 12:09:51 +010070}
71
72
Harald Weltea49e36e2018-01-21 19:29:33 +010073function f_init_mncc(charstring id) runs on MTC_CT {
74 id := id & "-MNCC";
75 var MnccOps ops := {
76 create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
77 unitdata_cb := refers(MNCC_Emulation.DummyUnitdataCallback)
78 }
79
80 vc_MNCC := MNCC_Emulation_CT.create(id);
81 map(vc_MNCC:MNCC, system:MNCC_CODEC_PT);
82 vc_MNCC.start(MNCC_Emulation.main(ops, id, mp_msc_mncc));
Harald Weltef6dd64d2017-11-19 12:09:51 +010083}
84
Harald Weltea49e36e2018-01-21 19:29:33 +010085function f_init_gsup(charstring id) runs on MTC_CT {
86 id := id & "-GSUP";
87 var GsupOps ops := {
88 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
89 }
90
91 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
92 vc_GSUP := GSUP_Emulation_CT.create(id);
93
94 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
95 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
96 /* we use this hack to get events like ASP_IPA_EVENT_UP */
97 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
98
99 vc_GSUP.start(GSUP_Emulation.main(ops, id));
100 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
101
102 /* wait for incoming connection to GSUP port before proceeding */
103 timer T := 10.0;
104 T.start;
105 alt {
106 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
107 [] T.timeout {
108 setverdict(inconc, "No connection to GSUP Port");
109 self.stop
110 }
111 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100112}
113
Harald Weltea49e36e2018-01-21 19:29:33 +0100114function f_init() runs on MTC_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +0100115
116 if (g_initialized == true) {
117 return;
118 }
119 g_initialized := true;
120
Harald Weltea49e36e2018-01-21 19:29:33 +0100121 f_bssap_init("MSC_Test", BSC_BssmapOps);
122 f_ipa_ctrl_start(mp_msc_ip, mp_msc_ctrl_port);
123 f_init_mncc("MSC_Test");
124 f_init_gsup("MSC_Test");
Harald Welte3ca1c902018-01-24 18:51:27 +0100125
126 map(self:MSCVTY, system:MSCVTY);
127 f_vty_set_prompts(MSCVTY);
128 f_vty_transceive(MSCVTY, "enable");
Harald Welteb14c77a2018-01-25 17:25:44 +0100129
130 /* set some defaults */
131 f_vty_config(MSCVTY, "network", "authentication optional");
132 f_vty_config(MSCVTY, "msc", "assign-tmsi");
133 f_vty_config(MSCVTY, "network", "encryption a5 0");
Harald Weltef6dd64d2017-11-19 12:09:51 +0100134}
135
136template PDU_BSSAP ts_BSSAP_BSSMAP := {
137 discriminator := '0'B,
138 spare := '0000000'B,
139 dlci := omit,
140 lengthIndicator := 0, /* overwritten by codec */
141 pdu := ?
142}
143
144template PDU_BSSAP tr_BSSAP_BSSMAP := {
145 discriminator := '0'B,
146 spare := '0000000'B,
147 dlci := omit,
148 lengthIndicator := ?,
149 pdu := {
150 bssmap := ?
151 }
152}
153
154
155type integer BssmapCause;
156
157template (value) BSSMAP_IE_Cause ts_BSSMAP_IE_Cause(BssmapCause val) := {
158 elementIdentifier := '04'O,
159 lengthIndicator := 0,
160 causeValue := int2bit(val, 7),
161 extensionCauseValue := '0'B,
162 spare1 := omit
163}
164
165template (value) PDU_BSSAP ts_BSSMAP_Reset(BssmapCause cause) modifies ts_BSSAP_BSSMAP := {
166 pdu := {
167 bssmap := {
168 reset := {
169 messageType := '30'O,
170 cause := ts_BSSMAP_IE_Cause(cause),
171 a_InterfaceSelectorForReset := omit
172 }
173 }
174 }
175}
176
177template (value) PDU_BSSAP ts_BSSMAP_ResetAck modifies ts_BSSAP_BSSMAP := {
178 pdu := {
179 bssmap := {
180 resetAck := {
181 messageType := '31'O,
182 a_InterfaceSelectorForReset := omit
183 }
184 }
185 }
186}
187
188template PDU_BSSAP tr_BSSMAP_ResetAck modifies tr_BSSAP_BSSMAP := {
189 pdu := {
190 bssmap := {
191 resetAck := {
192 messageType := '31'O,
193 a_InterfaceSelectorForReset := *
194 }
195 }
196 }
197}
198
199template BSSMAP_IE_CellIdentifier ts_BSSMAP_IE_CellID := {
200 elementIdentifier := '05'O,
201 lengthIndicator := 0,
202 cellIdentifierDiscriminator := '0000'B,
203 spare1_4 := '0000'B,
204 cellIdentification := ?
205}
206
207type uint16_t BssmapLAC;
208type uint16_t BssmapCI;
209
210/*
211template BSSMAP_IE_CellIdentifier ts_CellId_CGI(mcc, mnc, lac, ci)
212modifies ts_BSSMAP_IE_CellID := {
213 cellIdentification := {
214 cI_LAC_CGI := {
215 mnc_mcc := FIXME,
216 lac := int2oct(lac, 2),
217 ci := int2oct(ci, 2)
218 }
219 }
220}
221*/
222
223template BSSMAP_IE_CellIdentifier ts_CellID_LAC_CI(BssmapLAC lac, BssmapCI ci)
224modifies ts_BSSMAP_IE_CellID := {
225 cellIdentification := {
226 cI_LAC_CI := {
227 lac := int2oct(lac, 2),
228 ci := int2oct(ci, 2)
229 }
230 }
231}
232
233template BSSMAP_IE_CellIdentifier ts_CellId_CI(BssmapCI ci)
234modifies ts_BSSMAP_IE_CellID := {
235 cellIdentification := {
236 cI_CI := int2oct(ci, 2)
237 }
238}
239
240template BSSMAP_IE_CellIdentifier ts_CellId_none
241modifies ts_BSSMAP_IE_CellID := {
242 cellIdentification := {
243 cI_noCell := ''O
244 }
245}
246
247
248template BSSMAP_IE_Layer3Information ts_BSSMAP_IE_L3Info(octetstring l3info) := {
249 elementIdentifier := '17'O,
250 lengthIndicator := 0,
251 layer3info := l3info
252}
253
254template PDU_BSSAP ts_BSSMAP_ComplL3(BSSMAP_IE_CellIdentifier cell_id, octetstring l3_info)
255modifies ts_BSSAP_BSSMAP := {
256 pdu := {
257 bssmap := {
258 completeLayer3Information := {
259 messageType := '57'O,
260 cellIdentifier := cell_id,
261 layer3Information := ts_BSSMAP_IE_L3Info(l3_info),
262 chosenChannel := omit,
263 lSAIdentifier := omit,
264 aPDU := omit,
265 codecList := omit,
266 redirectAttemptFlag := omit,
267 sendSequenceNumber := omit,
268 iMSI := omit
269 }
270 }
271 }
272}
273
274template PDU_BSSAP ts_BSSMAP_HandoReq(BssmapCause cause, BSSMAP_IE_CellIdentifierList cid_list)
275modifies ts_BSSAP_BSSMAP := {
276 pdu := {
277 bssmap := {
278 handoverRequired := {
279 messageType := '11'O,
280 cause := ts_BSSMAP_IE_Cause(cause),
281 responseRequest := omit,
282 cellIdentifierList := cid_list,
283 circuitPoolList := omit,
284 currentChannelType1 := omit,
285 speechVersion := omit,
286 queueingIndicator := omit,
287 oldToNewBSSInfo := omit,
288 sourceToTargetRNCTransparentInfo := omit,
289 sourceToTargetRNCTransparentInfoCDMA := omit,
290 gERANClassmark := omit,
291 talkerPriority := omit,
292 speechCodec := omit,
293 cSG_Identifier := omit
294 }
295 }
296 }
297}
298
299// enc_PDU_BSSAP
300
301function f_send_BSSAP_UNITDATA(template PDU_BSSAP bssap) runs on MTC_CT {
Harald Weltea49e36e2018-01-21 19:29:33 +0100302 BSSAP.send(ts_BSSAP_UNITDATA_req(g_sccp_addr_peer, g_sccp_addr_own, bssap))
Harald Weltef6dd64d2017-11-19 12:09:51 +0100303}
304
Harald Weltea49e36e2018-01-21 19:29:33 +0100305type function void_fn(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100306
Harald Welte81b7f9d2018-01-24 19:06:24 +0100307private function f_concat_pad(integer tot_len, hexstring prefix, integer suffix) return hexstring {
308 var integer suffix_len := tot_len - lengthof(prefix);
309 var charstring suffix_ch := int2str(suffix);
310 var integer pad_len := suffix_len - lengthof(suffix_ch);
311
312 return prefix & int2hex(0, pad_len) & str2hex(suffix_ch);
Harald Welte256571e2018-01-24 18:47:19 +0100313}
314
Harald Welte81b7f9d2018-01-24 19:06:24 +0100315function f_gen_imei(integer suffix) return hexstring {
316 return f_concat_pad(15, '49999'H, suffix);
Harald Weltea49e36e2018-01-21 19:29:33 +0100317}
318
Harald Welte81b7f9d2018-01-24 19:06:24 +0100319function f_gen_imsi(integer suffix) return hexstring {
320 return f_concat_pad(15, '26242'H, suffix);
321}
322
323function f_gen_msisdn(integer suffix) return hexstring {
324 return f_concat_pad(12, '49123'H, suffix);
Harald Weltea49e36e2018-01-21 19:29:33 +0100325}
326
327/* FIXME: move into BSC_ConnectionHandler? */
328function f_start_handler(void_fn fn, charstring id, integer imsi_suffix) runs on MTC_CT return BSC_ConnHdlr {
329 var BSC_ConnHdlr vc_conn;
330 var BSC_ConnHdlrPars pars := {
331 sccp_addr_own := g_sccp_addr_own,
332 sccp_addr_peer := g_sccp_addr_peer,
333 cell_id := valueof(ts_CellId_CGI('262'H, '042'H, 23, 42)),
Harald Welte81b7f9d2018-01-24 19:06:24 +0100334 imei := f_gen_imei(imsi_suffix),
335 imsi := f_gen_imsi(imsi_suffix),
336 msisdn := f_gen_msisdn(imsi_suffix),
Harald Welte256571e2018-01-24 18:47:19 +0100337 tmsi := omit,
Harald Welte82600572018-01-21 20:54:08 +0100338 cm2 := valueof(ts_CM2_default),
Harald Welte16114282018-01-24 22:41:21 +0100339 cm3 := omit,
340 kc := omit
Harald Weltea49e36e2018-01-21 19:29:33 +0100341 };
342
343 vc_conn := BSC_ConnHdlr.create(id);
344 /* BSSMAP part / A interface */
345 connect(vc_conn:BSSAP, vc_BSSMAP:CLIENT);
346 connect(vc_conn:BSSAP_PROC, vc_BSSMAP:PROC);
347 /* MNCC part */
348 connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
349 connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);
350 /* GSUP part */
351 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
352 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
353
354 vc_conn.start(derefers(fn)(id, pars));
355 return vc_conn;
356}
357
358function f_sleep(float seconds) {
359 timer T := seconds;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100360 T.start;
361 T.timeout;
Harald Weltea49e36e2018-01-21 19:29:33 +0100362}
Harald Weltef6dd64d2017-11-19 12:09:51 +0100363
Harald Welte3ca1c902018-01-24 18:51:27 +0100364function f_vty_config(TELNETasp_PT pt, charstring config_node, charstring cmd)
365{
366 /* enter config mode; enter node */
367 f_vty_enter_config(pt);
368 f_vty_transceive(pt, config_node);
369 /* execute command */
370 f_vty_transceive(pt, cmd);
371 /* leave config mode */
372 f_vty_transceive(pt, "end");
373}
374
Harald Weltea49e36e2018-01-21 19:29:33 +0100375private function f_tc_lu_imsi_noauth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
376 g_pars := pars;
Harald Welte8a121b32018-01-22 03:00:41 +0100377 f_perform_lu(false, true, true);
Harald Weltea49e36e2018-01-21 19:29:33 +0100378}
Harald Weltea49e36e2018-01-21 19:29:33 +0100379testcase TC_lu_imsi_noauth_tmsi() runs on MTC_CT {
380 var BSC_ConnHdlr vc_conn;
381 f_init();
382
383 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi), testcasename(), 1);
384 vc_conn.done;
385}
386
387private function f_tc_lu_imsi_noauth_notmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
388 g_pars := pars;
Harald Welte8a121b32018-01-22 03:00:41 +0100389 f_perform_lu(false, false, true);
Harald Weltea49e36e2018-01-21 19:29:33 +0100390}
Harald Weltea49e36e2018-01-21 19:29:33 +0100391testcase TC_lu_imsi_noauth_notmsi() runs on MTC_CT {
392 var BSC_ConnHdlr vc_conn;
393 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100394 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
Harald Weltea49e36e2018-01-21 19:29:33 +0100395
396 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi), testcasename(), 2);
397 vc_conn.done;
398}
399
400/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
401private function f_tc_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
402 g_pars := pars;
403 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
404
405 f_create_gsup_expect(hex2str(g_pars.imsi));
406 f_bssap_compl_l3(l3_lu);
407 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
408 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
409 alt {
410 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej(int2oct(23,1)))) { }
411 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
412 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
413 self.stop;
414 }
415 }
416 BSSAP.receive(tr_BSSMAP_ClearCommand);
417 BSSAP.send(ts_BSSMAP_ClearComplete);
418 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
419 setverdict(pass);
420}
421testcase TC_lu_imsi_reject() runs on MTC_CT {
422 var BSC_ConnHdlr vc_conn;
423 f_init();
424
425 vc_conn := f_start_handler(refers(f_tc_lu_imsi_reject), testcasename(), 3);
426 vc_conn.done;
427}
428
429/* Do LU by IMSI, timeout on GSUP */
430private function f_tc_lu_imsi_timeout_gsup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
431 g_pars := pars;
432 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
433
434 f_create_gsup_expect(hex2str(g_pars.imsi));
435 f_bssap_compl_l3(l3_lu);
436 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
437 /* Normally the HLR would need to respond here, but we decide to force a timeout here */
438 alt {
439 /* FIXME: Expect specific reject cause */
440 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
441 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
442 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
443 self.stop;
444 }
445 }
446 BSSAP.receive(tr_BSSMAP_ClearCommand);
447 BSSAP.send(ts_BSSMAP_ClearComplete);
448 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
449 setverdict(pass);
450}
451testcase TC_lu_imsi_timeout_gsup() runs on MTC_CT {
452 var BSC_ConnHdlr vc_conn;
453 f_init();
454
455 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_gsup), testcasename(), 4);
456 vc_conn.done;
457}
458
Harald Welte7b1b2812018-01-22 21:23:06 +0100459private function f_tc_lu_imsi_auth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
460 g_pars := pars;
461 f_perform_lu(true, true, true);
462}
463testcase TC_lu_imsi_auth_tmsi() runs on MTC_CT {
464 var BSC_ConnHdlr vc_conn;
465 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100466 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte7b1b2812018-01-22 21:23:06 +0100467
468 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi), testcasename(), 5);
469 vc_conn.done;
470}
471
Harald Weltea49e36e2018-01-21 19:29:33 +0100472
473/* Send CM SERVICE REQ for IMSI that has never performed LU before */
474private function f_tc_cmserv_imsi_unknown(charstring id, BSC_ConnHdlrPars pars)
475runs on BSC_ConnHdlr {
476
477 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
478 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '042'H, 23, 42));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100479 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltea49e36e2018-01-21 19:29:33 +0100480
481 f_create_gsup_expect(hex2str(g_pars.imsi));
482
483 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
484 f_bssap_compl_l3(l3_info);
485
486 timer T := 10.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100487 T.start;
488 alt {
Harald Weltea49e36e2018-01-21 19:29:33 +0100489 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
490 //[] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC)) { }
491 [] BSSAP.receive { setverdict(fail, "Received unexpected BSSAP"); }
492 [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
493 setverdict(fail, "Unexpected GSUP UL REQ");
494 }
495 [] T.timeout { setverdict(inconc, "Timeout waiting for CM SERV REQ"); }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100496 }
497
Harald Weltea49e36e2018-01-21 19:29:33 +0100498 alt {
499 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
500 setverdict(pass);
501 }
502 [] BSSAP.receive { setverdict(fail, "Received unexpected BSSAP"); }
503 [] T.timeout { setverdict(inconc, "Timeout waiting for CM SERV REQ"); }
504 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100505}
Harald Weltea49e36e2018-01-21 19:29:33 +0100506testcase TC_cmserv_imsi_unknown() runs on MTC_CT {
507 var BSC_ConnHdlr vc_conn;
508 f_init();
Harald Welte81b7f9d2018-01-24 19:06:24 +0100509 vc_conn := f_start_handler(refers(f_tc_cmserv_imsi_unknown), testcasename(), 6);
Harald Weltea49e36e2018-01-21 19:29:33 +0100510 vc_conn.done;
511}
512
Harald Welte2bb825f2018-01-22 11:31:18 +0100513private function f_tc_lu_and_mo_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
514 g_pars := pars;
515 f_perform_lu(false, true, true);
516
517 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)), false);
518
519 var hexstring called := '12345'H;
520 var integer tid := 0;
521 var MNCC_PDU mncc;
522 f_create_mncc_expect(hex2str(called));
523
524 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(tid, called)));
525 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(called)))) -> value mncc;
526 /* FIXME: extract call_id */
527
528 /* Call Proceeding */
529 MNCC.send(ts_MNCC_CALL_PROC_req(mncc.u.signal.callref, ts_MNCC_bcap_voice));
530 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(tid)));
531
532 /* Alerting */
533 MNCC.send(ts_MNCC_ALERT_req(mncc.u.signal.callref));
534 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(tid)));
535
536 /* Answer. This causes TCH assignment in case of "late assignment" */
537 MNCC.send(ts_MNCC_SETUP_COMPL_req(mncc.u.signal.callref));
538
539 f_sleep(3.0);
540
541 /* Hangup by "B" side */
542 MNCC.send(ts_MNCC_DISC_req(mncc.u.signal.callref, valueof(ts_MNCC_cause(23))));
543 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(tid)));
544
545 /* Release of call */
546 MNCC.send(ts_MNCC_REL_req(mncc.u.signal.callref, valueof(ts_MNCC_cause(42))));
547 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(tid)));
548
549 /* clearing of radio channel */
550 BSSAP.receive(tr_BSSMAP_ClearCommand);
551 BSSAP.send(ts_BSSMAP_ClearComplete);
552 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
553
554 f_sleep(5.0);
555}
556testcase TC_lu_and_mo_call() runs on MTC_CT {
557 var BSC_ConnHdlr vc_conn;
558 f_init();
559
Harald Welte81b7f9d2018-01-24 19:06:24 +0100560 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_call), testcasename(), 7);
Harald Welte071ed732018-01-23 19:53:52 +0100561 vc_conn.done;
562}
563
564/* Test LU (with authentication enabled), where HLR times out sending SAI response */
565private function f_tc_lu_auth_sai_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
566 g_pars := pars;
567
568 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
569 var PDU_DTAP_MT dtap_mt;
570
571 /* tell GSUP dispatcher to send this IMSI to us */
572 f_create_gsup_expect(hex2str(g_pars.imsi));
573
574 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
575 f_bssap_compl_l3(l3_lu);
576
577 /* Send Early Classmark, just for the fun of it */
578 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
579
580 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
581 /* The HLR would normally return an auth vector here, but we fail to do so. */
582
583 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
584 BSSAP.receive(tr_BSSMAP_ClearCommand);
585 BSSAP.send(ts_BSSMAP_ClearComplete);
586 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
587 setverdict(pass);
588}
589testcase TC_lu_auth_sai_timeout() runs on MTC_CT {
590 var BSC_ConnHdlr vc_conn;
591 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100592 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100593
Harald Welte81b7f9d2018-01-24 19:06:24 +0100594 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_timeout), testcasename(), 8);
Harald Welte071ed732018-01-23 19:53:52 +0100595 vc_conn.done;
596}
597
598/* Test LU (with authentication enabled), where HLR rejects sending SAI error */
599private function f_tc_lu_auth_sai_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
600 g_pars := pars;
601
602 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
603 var PDU_DTAP_MT dtap_mt;
604
605 /* tell GSUP dispatcher to send this IMSI to us */
606 f_create_gsup_expect(hex2str(g_pars.imsi));
607
608 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
609 f_bssap_compl_l3(l3_lu);
610
611 /* Send Early Classmark, just for the fun of it */
612 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
613
614 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
615 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 13));
616
617 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
618 BSSAP.receive(tr_BSSMAP_ClearCommand);
619 BSSAP.send(ts_BSSMAP_ClearComplete);
620 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
621 setverdict(pass);
622}
623testcase TC_lu_auth_sai_err() runs on MTC_CT {
624 var BSC_ConnHdlr vc_conn;
625 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100626 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100627
Harald Welte81b7f9d2018-01-24 19:06:24 +0100628 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_err), testcasename(), 9);
Harald Welte2bb825f2018-01-22 11:31:18 +0100629 vc_conn.done;
630}
Harald Weltea49e36e2018-01-21 19:29:33 +0100631
Harald Weltebc881782018-01-23 20:09:15 +0100632/* Test LU but BSC will send a clear request in the middle */
633private function f_tc_lu_clear_request(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
634 g_pars := pars;
635
636 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
637 var PDU_DTAP_MT dtap_mt;
638
639 /* tell GSUP dispatcher to send this IMSI to us */
640 f_create_gsup_expect(hex2str(g_pars.imsi));
641
642 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
643 f_bssap_compl_l3(l3_lu);
644
645 /* Send Early Classmark, just for the fun of it */
646 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
647
648 f_sleep(1.0);
649 /* send clear request in the middle of the LU */
650 BSSAP.send(ts_BSSMAP_ClearRequest(0));
651 BSSAP.receive(tr_BSSMAP_ClearCommand);
652 BSSAP.send(ts_BSSMAP_ClearComplete);
653 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
654 setverdict(pass);
655}
656testcase TC_lu_clear_request() runs on MTC_CT {
657 var BSC_ConnHdlr vc_conn;
658 f_init();
659
Harald Welte81b7f9d2018-01-24 19:06:24 +0100660 vc_conn := f_start_handler(refers(f_tc_lu_clear_request), testcasename(), 10);
Harald Weltebc881782018-01-23 20:09:15 +0100661 vc_conn.done;
662}
663
Harald Welte66af9e62018-01-24 17:28:21 +0100664/* Test LU but BSC will send a clear request in the middle */
665private function f_tc_lu_disconnect(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
666 g_pars := pars;
667
668 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
669 var PDU_DTAP_MT dtap_mt;
670
671 /* tell GSUP dispatcher to send this IMSI to us */
672 f_create_gsup_expect(hex2str(g_pars.imsi));
673
674 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
675 f_bssap_compl_l3(l3_lu);
676
677 /* Send Early Classmark, just for the fun of it */
678 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
679
680 f_sleep(1.0);
681 /* send clear request in the middle of the LU */
682 BSSAP.send(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
683 setverdict(pass);
684}
685testcase TC_lu_disconnect() runs on MTC_CT {
686 var BSC_ConnHdlr vc_conn;
687 f_init();
688
Harald Welte81b7f9d2018-01-24 19:06:24 +0100689 vc_conn := f_start_handler(refers(f_tc_lu_disconnect), testcasename(), 11);
Harald Welte66af9e62018-01-24 17:28:21 +0100690 vc_conn.done;
691}
692
693
Harald Welteba7b6d92018-01-23 21:32:34 +0100694/* Test LU but with illegal mobile identity type = IMEI */
695private function f_tc_lu_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
696 g_pars := pars;
697
Harald Welte256571e2018-01-24 18:47:19 +0100698 var PDU_ML3_MS_NW l3_lu := f_build_lu_imei(g_pars.imei)
Harald Welteba7b6d92018-01-23 21:32:34 +0100699 var PDU_DTAP_MT dtap_mt;
700
701 /* tell GSUP dispatcher to send this IMSI to us */
702 f_create_gsup_expect(hex2str(g_pars.imsi));
703
704 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
705 f_bssap_compl_l3(l3_lu);
706
707 /* Send Early Classmark, just for the fun of it */
708 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
709 /* wait for LU reject, ignore any ID REQ */
710 alt {
711 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
712 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req)) { repeat; }
713 }
714 /* wait for normal teardown */
715 BSSAP.receive(tr_BSSMAP_ClearCommand);
716 BSSAP.send(ts_BSSMAP_ClearComplete);
717 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
718 setverdict(pass);
719}
720testcase TC_lu_by_imei() runs on MTC_CT {
721 var BSC_ConnHdlr vc_conn;
722 f_init();
723
Harald Welte81b7f9d2018-01-24 19:06:24 +0100724 vc_conn := f_start_handler(refers(f_tc_lu_by_imei), testcasename(), 12);
Harald Welteba7b6d92018-01-23 21:32:34 +0100725 vc_conn.done;
726}
727
728/* Test LU by TMSI with unknown TMSI, expect (and answer) ID REQ. */
729private function f_tc_lu_tmsi_noauth_unknown(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
730 g_pars := pars;
731
732 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('01020304'O); /* FIXME: Random */
733 var PDU_DTAP_MT dtap_mt;
734
735 /* tell GSUP dispatcher to send this IMSI to us */
736 f_create_gsup_expect(hex2str(g_pars.imsi));
737
738 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
739 f_bssap_compl_l3(l3_lu);
740
741 /* Send Early Classmark, just for the fun of it */
742 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
743
744 /* Wait for + respond to ID REQ (IMSI) */
745 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req('001'B)));
746 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
747
748 /* Expect MSC to do UpdateLocation to HLR; respond to it */
749 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
750 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
751 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
752 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
753
754 alt {
755 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) { }
756 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
757 setverdict(fail, "Expected LU ACK, but received REJ");
758 }
759 }
760
761 /* wait for normal teardown */
762 BSSAP.receive(tr_BSSMAP_ClearCommand);
763 BSSAP.send(ts_BSSMAP_ClearComplete);
764 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
765 setverdict(pass);
766}
767testcase TC_lu_by_tmsi_noauth_unknown() runs on MTC_CT {
768 var BSC_ConnHdlr vc_conn;
769 f_init();
770
Harald Welte81b7f9d2018-01-24 19:06:24 +0100771 vc_conn := f_start_handler(refers(f_tc_lu_tmsi_noauth_unknown), testcasename(), 13);
Harald Welteba7b6d92018-01-23 21:32:34 +0100772 vc_conn.done;
773}
774
775
Harald Welte45164da2018-01-24 12:51:27 +0100776/* Test IMSI DETACH (MI=IMSI) */
777private function f_tc_imsi_detach_by_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
778 g_pars := pars;
779
780 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
781
782 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
783 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
784
785 /* Send Early Classmark, just for the fun of it? */
786 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
787
788 /* wait for normal teardown */
789 BSSAP.receive(tr_BSSMAP_ClearCommand);
790 BSSAP.send(ts_BSSMAP_ClearComplete);
791 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
792 setverdict(pass);
793}
794testcase TC_imsi_detach_by_imsi() runs on MTC_CT {
795 var BSC_ConnHdlr vc_conn;
796 f_init();
797
Harald Welte81b7f9d2018-01-24 19:06:24 +0100798 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imsi), testcasename(), 14);
Harald Welte45164da2018-01-24 12:51:27 +0100799 vc_conn.done;
800}
801
802/* Test IMSI DETACH (MI=TMSI) */
803private function f_tc_imsi_detach_by_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
804 g_pars := pars;
805
806 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('01020304'O));
807
808 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
809 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
810
811 /* Send Early Classmark, just for the fun of it? */
812 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
813
814 /* wait for normal teardown */
815 BSSAP.receive(tr_BSSMAP_ClearCommand);
816 BSSAP.send(ts_BSSMAP_ClearComplete);
817 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
818 setverdict(pass);
819}
820testcase TC_imsi_detach_by_tmsi() runs on MTC_CT {
821 var BSC_ConnHdlr vc_conn;
822 f_init();
823
Harald Welte81b7f9d2018-01-24 19:06:24 +0100824 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_tmsi), testcasename(), 15);
Harald Welte45164da2018-01-24 12:51:27 +0100825 vc_conn.done;
826}
827
828/* Test IMSI DETACH (MI=IMEI), which is illegal */
829private function f_tc_imsi_detach_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
830 g_pars := pars;
831
Harald Welte256571e2018-01-24 18:47:19 +0100832 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte45164da2018-01-24 12:51:27 +0100833
834 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
835 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
836
837 /* Send Early Classmark, just for the fun of it? */
838 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
839
840 /* wait for normal teardown */
841 BSSAP.receive(tr_BSSMAP_ClearCommand);
842 BSSAP.send(ts_BSSMAP_ClearComplete);
843 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
844 setverdict(pass);
845}
846testcase TC_imsi_detach_by_imei() runs on MTC_CT {
847 var BSC_ConnHdlr vc_conn;
848 f_init();
849
Harald Welte81b7f9d2018-01-24 19:06:24 +0100850 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imei), testcasename(), 16);
Harald Welte45164da2018-01-24 12:51:27 +0100851 vc_conn.done;
852}
853
854
855/* helper function for an emergency call. caller passes in mobile identity to use */
856private function f_emerg_call(MobileIdentityLV mi) runs on BSC_ConnHdlr {
857
Harald Welte6ed6bf92018-01-24 21:09:15 +0100858 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100859 f_bssap_compl_l3(l3_info);
860 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC));
861
862 var hexstring called := '112'H;
863 var integer tid := 0;
864 var MNCC_PDU mncc;
865 f_create_mncc_expect(hex2str(called));
866
867 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_EMERG_SETUP(tid)));
868 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(called)))) -> value mncc;
869 /* FIXME: extract call_id */
870
871 /* Call Proceeding */
872 MNCC.send(ts_MNCC_CALL_PROC_req(mncc.u.signal.callref, ts_MNCC_bcap_voice));
873 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(tid)));
874
875 /* Alerting */
876 MNCC.send(ts_MNCC_ALERT_req(mncc.u.signal.callref));
877 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(tid)));
878
879 /* Answer. This causes TCH assignment in case of "late assignment" */
880 MNCC.send(ts_MNCC_SETUP_COMPL_req(mncc.u.signal.callref));
881
882 f_sleep(3.0);
883
884 /* Hangup by "B" side */
885 MNCC.send(ts_MNCC_DISC_req(mncc.u.signal.callref, valueof(ts_MNCC_cause(23))));
886 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(tid)));
887
888 /* Release of call */
889 MNCC.send(ts_MNCC_REL_req(mncc.u.signal.callref, valueof(ts_MNCC_cause(42))));
890 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(tid)));
891
892 /* clearing of radio channel */
893 BSSAP.receive(tr_BSSMAP_ClearCommand);
894 BSSAP.send(ts_BSSMAP_ClearComplete);
895 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
896
897 f_sleep(5.0);
898}
899
900/* establish an emergency call by IMEI, no SIM inserted (and hence no IMSI) */
901private function f_tc_emerg_call_imei_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
902 g_pars := pars;
903
Harald Welte256571e2018-01-24 18:47:19 +0100904 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100905 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100906 f_bssap_compl_l3(l3_info);
907 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ('05'O)));
Harald Weltef6b62ee2018-01-24 21:49:32 +0100908 BSSAP.receive(tr_BSSMAP_ClearCommand);
909 BSSAP.send(ts_BSSMAP_ClearComplete);
910 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
Harald Welte45164da2018-01-24 12:51:27 +0100911 setverdict(pass);
912}
913testcase TC_emerg_call_imei_reject() runs on MTC_CT {
914 var BSC_ConnHdlr vc_conn;
915 f_init();
916
Harald Welte81b7f9d2018-01-24 19:06:24 +0100917 vc_conn := f_start_handler(refers(f_tc_emerg_call_imei_reject), testcasename(), 17);
Harald Welte45164da2018-01-24 12:51:27 +0100918 vc_conn.done;
919}
920
Harald Welted5b91402018-01-24 18:48:16 +0100921/* establish an emergency call by IMSI, SIM inserted (and hence IMSI) */
Harald Welte45164da2018-01-24 12:51:27 +0100922private function f_tc_emerg_call_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
923 g_pars := pars;
924 /* First perform location update to ensure subscriber is known */
925 f_perform_lu(false, true, true);
926 /* Then issue emergency call identified by IMSI */
927 f_emerg_call(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
928}
929testcase TC_emerg_call_imsi() runs on MTC_CT {
930 var BSC_ConnHdlr vc_conn;
931 f_init();
932
Harald Welte81b7f9d2018-01-24 19:06:24 +0100933 vc_conn := f_start_handler(refers(f_tc_emerg_call_imsi), testcasename(), 18);
Harald Welte45164da2018-01-24 12:51:27 +0100934 vc_conn.done;
935}
936
937/* CM Service Request for VGCS -> reject */
938private function f_tc_cm_serv_req_vgcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
939 g_pars := pars;
940
941 /* First perform location update to ensure subscriber is known */
942 f_perform_lu(false, true, true);
943
944 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100945 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VGCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100946 f_bssap_compl_l3(l3_info);
947 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Weltef6b62ee2018-01-24 21:49:32 +0100948 BSSAP.receive(tr_BSSMAP_ClearCommand);
949 BSSAP.send(ts_BSSMAP_ClearComplete);
950 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
Harald Welte45164da2018-01-24 12:51:27 +0100951 setverdict(pass);
952}
953testcase TC_cm_serv_req_vgcs_reject() runs on MTC_CT {
954 var BSC_ConnHdlr vc_conn;
955 f_init();
956
Harald Welte81b7f9d2018-01-24 19:06:24 +0100957 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vgcs_reject), testcasename(), 19);
Harald Welte45164da2018-01-24 12:51:27 +0100958 vc_conn.done;
959}
960
961/* CM Service Request for VBS -> reject */
962private function f_tc_cm_serv_req_vbs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
963 g_pars := pars;
964
965 /* First perform location update to ensure subscriber is known */
966 f_perform_lu(false, true, true);
967
968 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100969 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VBS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100970 f_bssap_compl_l3(l3_info);
971 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Weltef6b62ee2018-01-24 21:49:32 +0100972 BSSAP.receive(tr_BSSMAP_ClearCommand);
973 BSSAP.send(ts_BSSMAP_ClearComplete);
974 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
Harald Welte45164da2018-01-24 12:51:27 +0100975 setverdict(pass);
976}
977testcase TC_cm_serv_req_vbs_reject() runs on MTC_CT {
978 var BSC_ConnHdlr vc_conn;
979 f_init();
980
Harald Welte81b7f9d2018-01-24 19:06:24 +0100981 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vbs_reject), testcasename(), 20);
Harald Welte45164da2018-01-24 12:51:27 +0100982 vc_conn.done;
983}
984
985/* CM Service Request for LCS -> reject */
986private function f_tc_cm_serv_req_lcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
987 g_pars := pars;
988
989 /* First perform location update to ensure subscriber is known */
990 f_perform_lu(false, true, true);
991
992 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100993 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_LCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100994 f_bssap_compl_l3(l3_info);
995 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte0195ab12018-01-24 21:50:20 +0100996 BSSAP.receive(tr_BSSMAP_ClearCommand);
997 BSSAP.send(ts_BSSMAP_ClearComplete);
998 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
Harald Welte45164da2018-01-24 12:51:27 +0100999 setverdict(pass);
1000}
1001testcase TC_cm_serv_req_lcs_reject() runs on MTC_CT {
1002 var BSC_ConnHdlr vc_conn;
1003 f_init();
1004
Harald Welte81b7f9d2018-01-24 19:06:24 +01001005 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_lcs_reject), testcasename(), 21);
Harald Welte45164da2018-01-24 12:51:27 +01001006 vc_conn.done;
1007}
1008
Harald Welte0195ab12018-01-24 21:50:20 +01001009/* CM Re-Establishment Request */
1010private function f_tc_cm_reest_req_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1011 g_pars := pars;
1012
1013 /* First perform location update to ensure subscriber is known */
1014 f_perform_lu(false, true, true);
1015
1016 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1017 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REEST_REQ(0, mi));
1018 f_bssap_compl_l3(l3_info);
1019 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
1020 BSSAP.receive(tr_BSSMAP_ClearCommand);
1021 BSSAP.send(ts_BSSMAP_ClearComplete);
1022 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1023 setverdict(pass);
1024}
1025testcase TC_cm_reest_req_reject() runs on MTC_CT {
1026 var BSC_ConnHdlr vc_conn;
1027 f_init();
Harald Welte0195ab12018-01-24 21:50:20 +01001028
1029 vc_conn := f_start_handler(refers(f_tc_cm_reest_req_reject), testcasename(), 22);
1030 vc_conn.done;
1031}
1032
Harald Weltec638f4d2018-01-24 22:00:36 +01001033/* Test LU (with authentication enabled), with wrong response from MS */
1034private function f_tc_lu_auth_2G_fail(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1035 g_pars := pars;
1036
1037 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
1038
1039 /* tell GSUP dispatcher to send this IMSI to us */
1040 f_create_gsup_expect(hex2str(g_pars.imsi));
1041
1042 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
1043 f_bssap_compl_l3(l3_lu);
1044
1045 /* Send Early Classmark, just for the fun of it */
1046 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1047
1048 var AuthVector vec := f_gen_auth_vec_2g();
1049 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(vec.rand, vec.sres, vec.kc));
1050 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
1051 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
1052
1053 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(vec.rand)));
1054 /* Send back wrong auth response */
1055 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G('00000000'O)));
1056
1057 /* Expect GSUP AUTH FAIL REP to HLR */
1058 GSUP.receive(tr_GSUP_AUTH_FAIL_IND(g_pars.imsi));
1059
1060 /* Expect LU REJECT with Cause == Illegal MS */
1061 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej('03'O)));
1062 BSSAP.receive(tr_BSSMAP_ClearCommand);
1063 BSSAP.send(ts_BSSMAP_ClearComplete);
1064 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1065 setverdict(pass);
1066}
1067testcase TC_lu_auth_2G_fail() runs on MTC_CT {
1068 var BSC_ConnHdlr vc_conn;
1069 f_init();
1070 f_vty_config(MSCVTY, "network", "authentication required");
1071 f_vty_config(MSCVTY, "msc", "assign-tmsi");
1072
1073 vc_conn := f_start_handler(refers(f_tc_lu_auth_2G_fail), testcasename(), 23);
1074 vc_conn.done;
1075}
1076
Harald Welte16114282018-01-24 22:41:21 +01001077private function f_tc_lu_imsi_auth_tmsi_encr_13_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1078 g_pars := pars;
1079 f_perform_lu(true, true, true, true);
1080}
1081testcase TC_lu_imsi_auth_tmsi_encr_13_13() runs on MTC_CT {
1082 var BSC_ConnHdlr vc_conn;
1083 f_init();
1084 f_vty_config(MSCVTY, "network", "authentication required");
1085 f_vty_config(MSCVTY, "msc", "assign-tmsi");
1086 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1087
1088 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_13), testcasename(), 24);
1089 vc_conn.done;
1090}
1091
Harald Welte1af6ea82018-01-25 18:33:15 +01001092/* Test Complete L3 without payload */
1093private function f_tc_cl3_no_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1094 g_pars := pars;
1095
1096 /* Send Complete L3 Info with empty L3 frame */
1097 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1098 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, ''O))));
1099
1100 alt {
1101 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
1102 /* Expect LU REJECT with Cause == Illegal MS */
1103 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1104 BSSAP.send(ts_BSSMAP_ClearComplete);
1105 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1106 }
1107 }
1108 setverdict(pass);
1109}
1110testcase TC_cl3_no_payload() runs on MTC_CT {
1111 var BSC_ConnHdlr vc_conn;
1112 f_init();
1113
1114 vc_conn := f_start_handler(refers(f_tc_cl3_no_payload), testcasename(), 24);
1115 vc_conn.done;
1116}
1117
1118/* Test Complete L3 with random payload */
1119private function f_tc_cl3_rnd_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1120 g_pars := pars;
1121
1122 var integer len := float2int(rnd() * 256.0);
1123 var octetstring payl := f_rnd_octstring(len);
1124
1125 /* Send Complete L3 Info with empty L3 frame */
1126 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1127 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, payl))));
1128
1129 alt {
1130 /* Immediate disconnect */
1131 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
1132 /* Expect LU REJECT with Cause == Illegal MS */
1133 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1134 BSSAP.send(ts_BSSMAP_ClearComplete);
1135 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1136 }
1137 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
1138 }
1139 setverdict(pass);
1140}
1141testcase TC_cl3_rnd_payload() runs on MTC_CT {
1142 var BSC_ConnHdlr vc_conn;
1143 f_init();
1144
1145 vc_conn := f_start_handler(refers(f_tc_cl3_rnd_payload), testcasename(), 24);
1146 vc_conn.done;
1147}
1148
Harald Welte45164da2018-01-24 12:51:27 +01001149
Harald Welteba7b6d92018-01-23 21:32:34 +01001150/* TODO:
1151 * continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
1152 * malformed messages (missing IE, invalid message type): properly rejected?
1153 * MT call while LU or is ongoing: Do we use existing lchan or page while lchan active?
1154 * 3G/2G auth permutations
1155 * encryption algorithms vs. classmark vs. vty config
Harald Welteba7b6d92018-01-23 21:32:34 +01001156 * send new transaction after/during clear (like SMS, ...)
Harald Welte45164da2018-01-24 12:51:27 +01001157 * too long L3 INFO in DTAP
1158 * too long / padded BSSAP
1159 * too long / short TLV values
Harald Welteba7b6d92018-01-23 21:32:34 +01001160 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01001161
1162
1163control {
Harald Weltea49e36e2018-01-21 19:29:33 +01001164 execute( TC_cmserv_imsi_unknown() );
1165 execute( TC_lu_imsi_noauth_tmsi() );
1166 //execute( TC_lu_imsi_noauth_notmsi() );
1167 execute( TC_lu_imsi_reject() );
1168 execute( TC_lu_imsi_timeout_gsup() );
Harald Welte2bb825f2018-01-22 11:31:18 +01001169 execute( TC_lu_and_mo_call() );
Harald Welte071ed732018-01-23 19:53:52 +01001170 execute( TC_lu_auth_sai_timeout() );
1171 execute( TC_lu_auth_sai_err() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01001172 execute( TC_lu_clear_request() );
1173 execute( TC_lu_disconnect() );
1174 execute( TC_lu_by_imei() );
1175 execute( TC_lu_by_tmsi_noauth_unknown() );
1176 execute( TC_imsi_detach_by_imsi() );
1177 execute( TC_imsi_detach_by_tmsi() );
1178 execute( TC_imsi_detach_by_imei() );
1179 execute( TC_emerg_call_imei_reject() );
1180 execute( TC_emerg_call_imsi() );
1181 execute( TC_cm_serv_req_vgcs_reject() );
1182 execute( TC_cm_serv_req_vbs_reject() );
1183 execute( TC_cm_serv_req_lcs_reject() );
Harald Welte0195ab12018-01-24 21:50:20 +01001184 execute( TC_cm_reest_req_reject() );
Harald Welte1af6ea82018-01-25 18:33:15 +01001185 execute( TC_lu_auth_2G_fail() );
1186 execute( TC_lu_imsi_auth_tmsi_encr_13_13() );
1187 execute( TC_cl3_no_payload() );
1188 execute( TC_cl3_rnd_payload() );
Harald Weltef6dd64d2017-11-19 12:09:51 +01001189}
1190
1191
1192}