blob: 74d1b938747ebc85b3e4d2ebfb5e5d75708aac4a [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 Weltef6dd64d2017-11-19 12:09:51 +0100129}
130
131template PDU_BSSAP ts_BSSAP_BSSMAP := {
132 discriminator := '0'B,
133 spare := '0000000'B,
134 dlci := omit,
135 lengthIndicator := 0, /* overwritten by codec */
136 pdu := ?
137}
138
139template PDU_BSSAP tr_BSSAP_BSSMAP := {
140 discriminator := '0'B,
141 spare := '0000000'B,
142 dlci := omit,
143 lengthIndicator := ?,
144 pdu := {
145 bssmap := ?
146 }
147}
148
149
150type integer BssmapCause;
151
152template (value) BSSMAP_IE_Cause ts_BSSMAP_IE_Cause(BssmapCause val) := {
153 elementIdentifier := '04'O,
154 lengthIndicator := 0,
155 causeValue := int2bit(val, 7),
156 extensionCauseValue := '0'B,
157 spare1 := omit
158}
159
160template (value) PDU_BSSAP ts_BSSMAP_Reset(BssmapCause cause) modifies ts_BSSAP_BSSMAP := {
161 pdu := {
162 bssmap := {
163 reset := {
164 messageType := '30'O,
165 cause := ts_BSSMAP_IE_Cause(cause),
166 a_InterfaceSelectorForReset := omit
167 }
168 }
169 }
170}
171
172template (value) PDU_BSSAP ts_BSSMAP_ResetAck modifies ts_BSSAP_BSSMAP := {
173 pdu := {
174 bssmap := {
175 resetAck := {
176 messageType := '31'O,
177 a_InterfaceSelectorForReset := omit
178 }
179 }
180 }
181}
182
183template PDU_BSSAP tr_BSSMAP_ResetAck modifies tr_BSSAP_BSSMAP := {
184 pdu := {
185 bssmap := {
186 resetAck := {
187 messageType := '31'O,
188 a_InterfaceSelectorForReset := *
189 }
190 }
191 }
192}
193
194template BSSMAP_IE_CellIdentifier ts_BSSMAP_IE_CellID := {
195 elementIdentifier := '05'O,
196 lengthIndicator := 0,
197 cellIdentifierDiscriminator := '0000'B,
198 spare1_4 := '0000'B,
199 cellIdentification := ?
200}
201
202type uint16_t BssmapLAC;
203type uint16_t BssmapCI;
204
205/*
206template BSSMAP_IE_CellIdentifier ts_CellId_CGI(mcc, mnc, lac, ci)
207modifies ts_BSSMAP_IE_CellID := {
208 cellIdentification := {
209 cI_LAC_CGI := {
210 mnc_mcc := FIXME,
211 lac := int2oct(lac, 2),
212 ci := int2oct(ci, 2)
213 }
214 }
215}
216*/
217
218template BSSMAP_IE_CellIdentifier ts_CellID_LAC_CI(BssmapLAC lac, BssmapCI ci)
219modifies ts_BSSMAP_IE_CellID := {
220 cellIdentification := {
221 cI_LAC_CI := {
222 lac := int2oct(lac, 2),
223 ci := int2oct(ci, 2)
224 }
225 }
226}
227
228template BSSMAP_IE_CellIdentifier ts_CellId_CI(BssmapCI ci)
229modifies ts_BSSMAP_IE_CellID := {
230 cellIdentification := {
231 cI_CI := int2oct(ci, 2)
232 }
233}
234
235template BSSMAP_IE_CellIdentifier ts_CellId_none
236modifies ts_BSSMAP_IE_CellID := {
237 cellIdentification := {
238 cI_noCell := ''O
239 }
240}
241
242
243template BSSMAP_IE_Layer3Information ts_BSSMAP_IE_L3Info(octetstring l3info) := {
244 elementIdentifier := '17'O,
245 lengthIndicator := 0,
246 layer3info := l3info
247}
248
249template PDU_BSSAP ts_BSSMAP_ComplL3(BSSMAP_IE_CellIdentifier cell_id, octetstring l3_info)
250modifies ts_BSSAP_BSSMAP := {
251 pdu := {
252 bssmap := {
253 completeLayer3Information := {
254 messageType := '57'O,
255 cellIdentifier := cell_id,
256 layer3Information := ts_BSSMAP_IE_L3Info(l3_info),
257 chosenChannel := omit,
258 lSAIdentifier := omit,
259 aPDU := omit,
260 codecList := omit,
261 redirectAttemptFlag := omit,
262 sendSequenceNumber := omit,
263 iMSI := omit
264 }
265 }
266 }
267}
268
269template PDU_BSSAP ts_BSSMAP_HandoReq(BssmapCause cause, BSSMAP_IE_CellIdentifierList cid_list)
270modifies ts_BSSAP_BSSMAP := {
271 pdu := {
272 bssmap := {
273 handoverRequired := {
274 messageType := '11'O,
275 cause := ts_BSSMAP_IE_Cause(cause),
276 responseRequest := omit,
277 cellIdentifierList := cid_list,
278 circuitPoolList := omit,
279 currentChannelType1 := omit,
280 speechVersion := omit,
281 queueingIndicator := omit,
282 oldToNewBSSInfo := omit,
283 sourceToTargetRNCTransparentInfo := omit,
284 sourceToTargetRNCTransparentInfoCDMA := omit,
285 gERANClassmark := omit,
286 talkerPriority := omit,
287 speechCodec := omit,
288 cSG_Identifier := omit
289 }
290 }
291 }
292}
293
294// enc_PDU_BSSAP
295
296function f_send_BSSAP_UNITDATA(template PDU_BSSAP bssap) runs on MTC_CT {
Harald Weltea49e36e2018-01-21 19:29:33 +0100297 BSSAP.send(ts_BSSAP_UNITDATA_req(g_sccp_addr_peer, g_sccp_addr_own, bssap))
Harald Weltef6dd64d2017-11-19 12:09:51 +0100298}
299
Harald Weltea49e36e2018-01-21 19:29:33 +0100300type function void_fn(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100301
Harald Welte81b7f9d2018-01-24 19:06:24 +0100302private function f_concat_pad(integer tot_len, hexstring prefix, integer suffix) return hexstring {
303 var integer suffix_len := tot_len - lengthof(prefix);
304 var charstring suffix_ch := int2str(suffix);
305 var integer pad_len := suffix_len - lengthof(suffix_ch);
306
307 return prefix & int2hex(0, pad_len) & str2hex(suffix_ch);
Harald Welte256571e2018-01-24 18:47:19 +0100308}
309
Harald Welte81b7f9d2018-01-24 19:06:24 +0100310function f_gen_imei(integer suffix) return hexstring {
311 return f_concat_pad(15, '49999'H, suffix);
Harald Weltea49e36e2018-01-21 19:29:33 +0100312}
313
Harald Welte81b7f9d2018-01-24 19:06:24 +0100314function f_gen_imsi(integer suffix) return hexstring {
315 return f_concat_pad(15, '26242'H, suffix);
316}
317
318function f_gen_msisdn(integer suffix) return hexstring {
319 return f_concat_pad(12, '49123'H, suffix);
Harald Weltea49e36e2018-01-21 19:29:33 +0100320}
321
322/* FIXME: move into BSC_ConnectionHandler? */
323function f_start_handler(void_fn fn, charstring id, integer imsi_suffix) runs on MTC_CT return BSC_ConnHdlr {
324 var BSC_ConnHdlr vc_conn;
325 var BSC_ConnHdlrPars pars := {
326 sccp_addr_own := g_sccp_addr_own,
327 sccp_addr_peer := g_sccp_addr_peer,
328 cell_id := valueof(ts_CellId_CGI('262'H, '042'H, 23, 42)),
Harald Welte81b7f9d2018-01-24 19:06:24 +0100329 imei := f_gen_imei(imsi_suffix),
330 imsi := f_gen_imsi(imsi_suffix),
331 msisdn := f_gen_msisdn(imsi_suffix),
Harald Welte256571e2018-01-24 18:47:19 +0100332 tmsi := omit,
Harald Welte82600572018-01-21 20:54:08 +0100333 cm2 := valueof(ts_CM2_default),
Harald Welte16114282018-01-24 22:41:21 +0100334 cm3 := omit,
335 kc := omit
Harald Weltea49e36e2018-01-21 19:29:33 +0100336 };
337
338 vc_conn := BSC_ConnHdlr.create(id);
339 /* BSSMAP part / A interface */
340 connect(vc_conn:BSSAP, vc_BSSMAP:CLIENT);
341 connect(vc_conn:BSSAP_PROC, vc_BSSMAP:PROC);
342 /* MNCC part */
343 connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
344 connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);
345 /* GSUP part */
346 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
347 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
348
349 vc_conn.start(derefers(fn)(id, pars));
350 return vc_conn;
351}
352
353function f_sleep(float seconds) {
354 timer T := seconds;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100355 T.start;
356 T.timeout;
Harald Weltea49e36e2018-01-21 19:29:33 +0100357}
Harald Weltef6dd64d2017-11-19 12:09:51 +0100358
Harald Welte3ca1c902018-01-24 18:51:27 +0100359function f_vty_config(TELNETasp_PT pt, charstring config_node, charstring cmd)
360{
361 /* enter config mode; enter node */
362 f_vty_enter_config(pt);
363 f_vty_transceive(pt, config_node);
364 /* execute command */
365 f_vty_transceive(pt, cmd);
366 /* leave config mode */
367 f_vty_transceive(pt, "end");
368}
369
Harald Weltea49e36e2018-01-21 19:29:33 +0100370private function f_tc_lu_imsi_noauth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
371 g_pars := pars;
Harald Welte8a121b32018-01-22 03:00:41 +0100372 f_perform_lu(false, true, true);
Harald Weltea49e36e2018-01-21 19:29:33 +0100373}
Harald Weltea49e36e2018-01-21 19:29:33 +0100374testcase TC_lu_imsi_noauth_tmsi() runs on MTC_CT {
375 var BSC_ConnHdlr vc_conn;
376 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100377 f_vty_config(MSCVTY, "network", "authentication optional");
378 f_vty_config(MSCVTY, "msc", "assign-tmsi");
Harald Weltea49e36e2018-01-21 19:29:33 +0100379
380 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi), testcasename(), 1);
381 vc_conn.done;
382}
383
384private function f_tc_lu_imsi_noauth_notmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
385 g_pars := pars;
Harald Welte8a121b32018-01-22 03:00:41 +0100386 f_perform_lu(false, false, true);
Harald Weltea49e36e2018-01-21 19:29:33 +0100387}
Harald Weltea49e36e2018-01-21 19:29:33 +0100388testcase TC_lu_imsi_noauth_notmsi() runs on MTC_CT {
389 var BSC_ConnHdlr vc_conn;
390 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100391 f_vty_config(MSCVTY, "network", "authentication optional");
392 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
Harald Weltea49e36e2018-01-21 19:29:33 +0100393
394 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi), testcasename(), 2);
395 vc_conn.done;
396}
397
398/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
399private function f_tc_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
400 g_pars := pars;
401 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
402
403 f_create_gsup_expect(hex2str(g_pars.imsi));
404 f_bssap_compl_l3(l3_lu);
405 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
406 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
407 alt {
408 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej(int2oct(23,1)))) { }
409 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
410 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
411 self.stop;
412 }
413 }
414 BSSAP.receive(tr_BSSMAP_ClearCommand);
415 BSSAP.send(ts_BSSMAP_ClearComplete);
416 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
417 setverdict(pass);
418}
419testcase TC_lu_imsi_reject() runs on MTC_CT {
420 var BSC_ConnHdlr vc_conn;
421 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100422 f_vty_config(MSCVTY, "network", "authentication optional");
Harald Weltea49e36e2018-01-21 19:29:33 +0100423
424 vc_conn := f_start_handler(refers(f_tc_lu_imsi_reject), testcasename(), 3);
425 vc_conn.done;
426}
427
428/* Do LU by IMSI, timeout on GSUP */
429private function f_tc_lu_imsi_timeout_gsup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
430 g_pars := pars;
431 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
432
433 f_create_gsup_expect(hex2str(g_pars.imsi));
434 f_bssap_compl_l3(l3_lu);
435 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
436 /* Normally the HLR would need to respond here, but we decide to force a timeout here */
437 alt {
438 /* FIXME: Expect specific reject cause */
439 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
440 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
441 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
442 self.stop;
443 }
444 }
445 BSSAP.receive(tr_BSSMAP_ClearCommand);
446 BSSAP.send(ts_BSSMAP_ClearComplete);
447 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
448 setverdict(pass);
449}
450testcase TC_lu_imsi_timeout_gsup() runs on MTC_CT {
451 var BSC_ConnHdlr vc_conn;
452 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100453 f_vty_config(MSCVTY, "network", "authentication optional");
Harald Weltea49e36e2018-01-21 19:29:33 +0100454
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 Welte3ca1c902018-01-24 18:51:27 +0100509 f_vty_config(MSCVTY, "network", "authentication optional");
Harald Welte81b7f9d2018-01-24 19:06:24 +0100510 vc_conn := f_start_handler(refers(f_tc_cmserv_imsi_unknown), testcasename(), 6);
Harald Weltea49e36e2018-01-21 19:29:33 +0100511 vc_conn.done;
512}
513
Harald Welte2bb825f2018-01-22 11:31:18 +0100514private function f_tc_lu_and_mo_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
515 g_pars := pars;
516 f_perform_lu(false, true, true);
517
518 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)), false);
519
520 var hexstring called := '12345'H;
521 var integer tid := 0;
522 var MNCC_PDU mncc;
523 f_create_mncc_expect(hex2str(called));
524
525 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(tid, called)));
526 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(called)))) -> value mncc;
527 /* FIXME: extract call_id */
528
529 /* Call Proceeding */
530 MNCC.send(ts_MNCC_CALL_PROC_req(mncc.u.signal.callref, ts_MNCC_bcap_voice));
531 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(tid)));
532
533 /* Alerting */
534 MNCC.send(ts_MNCC_ALERT_req(mncc.u.signal.callref));
535 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(tid)));
536
537 /* Answer. This causes TCH assignment in case of "late assignment" */
538 MNCC.send(ts_MNCC_SETUP_COMPL_req(mncc.u.signal.callref));
539
540 f_sleep(3.0);
541
542 /* Hangup by "B" side */
543 MNCC.send(ts_MNCC_DISC_req(mncc.u.signal.callref, valueof(ts_MNCC_cause(23))));
544 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(tid)));
545
546 /* Release of call */
547 MNCC.send(ts_MNCC_REL_req(mncc.u.signal.callref, valueof(ts_MNCC_cause(42))));
548 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(tid)));
549
550 /* clearing of radio channel */
551 BSSAP.receive(tr_BSSMAP_ClearCommand);
552 BSSAP.send(ts_BSSMAP_ClearComplete);
553 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
554
555 f_sleep(5.0);
556}
557testcase TC_lu_and_mo_call() runs on MTC_CT {
558 var BSC_ConnHdlr vc_conn;
559 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100560 f_vty_config(MSCVTY, "network", "authentication optional");
Harald Welte2bb825f2018-01-22 11:31:18 +0100561
Harald Welte81b7f9d2018-01-24 19:06:24 +0100562 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_call), testcasename(), 7);
Harald Welte071ed732018-01-23 19:53:52 +0100563 vc_conn.done;
564}
565
566/* Test LU (with authentication enabled), where HLR times out sending SAI response */
567private function f_tc_lu_auth_sai_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
568 g_pars := pars;
569
570 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
571 var PDU_DTAP_MT dtap_mt;
572
573 /* tell GSUP dispatcher to send this IMSI to us */
574 f_create_gsup_expect(hex2str(g_pars.imsi));
575
576 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
577 f_bssap_compl_l3(l3_lu);
578
579 /* Send Early Classmark, just for the fun of it */
580 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
581
582 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
583 /* The HLR would normally return an auth vector here, but we fail to do so. */
584
585 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
586 BSSAP.receive(tr_BSSMAP_ClearCommand);
587 BSSAP.send(ts_BSSMAP_ClearComplete);
588 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
589 setverdict(pass);
590}
591testcase TC_lu_auth_sai_timeout() runs on MTC_CT {
592 var BSC_ConnHdlr vc_conn;
593 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100594 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100595
Harald Welte81b7f9d2018-01-24 19:06:24 +0100596 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_timeout), testcasename(), 8);
Harald Welte071ed732018-01-23 19:53:52 +0100597 vc_conn.done;
598}
599
600/* Test LU (with authentication enabled), where HLR rejects sending SAI error */
601private function f_tc_lu_auth_sai_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
602 g_pars := pars;
603
604 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
605 var PDU_DTAP_MT dtap_mt;
606
607 /* tell GSUP dispatcher to send this IMSI to us */
608 f_create_gsup_expect(hex2str(g_pars.imsi));
609
610 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
611 f_bssap_compl_l3(l3_lu);
612
613 /* Send Early Classmark, just for the fun of it */
614 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
615
616 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
617 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 13));
618
619 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
620 BSSAP.receive(tr_BSSMAP_ClearCommand);
621 BSSAP.send(ts_BSSMAP_ClearComplete);
622 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
623 setverdict(pass);
624}
625testcase TC_lu_auth_sai_err() runs on MTC_CT {
626 var BSC_ConnHdlr vc_conn;
627 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100628 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100629
Harald Welte81b7f9d2018-01-24 19:06:24 +0100630 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_err), testcasename(), 9);
Harald Welte2bb825f2018-01-22 11:31:18 +0100631 vc_conn.done;
632}
Harald Weltea49e36e2018-01-21 19:29:33 +0100633
Harald Weltebc881782018-01-23 20:09:15 +0100634/* Test LU but BSC will send a clear request in the middle */
635private function f_tc_lu_clear_request(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
636 g_pars := pars;
637
638 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
639 var PDU_DTAP_MT dtap_mt;
640
641 /* tell GSUP dispatcher to send this IMSI to us */
642 f_create_gsup_expect(hex2str(g_pars.imsi));
643
644 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
645 f_bssap_compl_l3(l3_lu);
646
647 /* Send Early Classmark, just for the fun of it */
648 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
649
650 f_sleep(1.0);
651 /* send clear request in the middle of the LU */
652 BSSAP.send(ts_BSSMAP_ClearRequest(0));
653 BSSAP.receive(tr_BSSMAP_ClearCommand);
654 BSSAP.send(ts_BSSMAP_ClearComplete);
655 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
656 setverdict(pass);
657}
658testcase TC_lu_clear_request() runs on MTC_CT {
659 var BSC_ConnHdlr vc_conn;
660 f_init();
661
Harald Welte81b7f9d2018-01-24 19:06:24 +0100662 vc_conn := f_start_handler(refers(f_tc_lu_clear_request), testcasename(), 10);
Harald Weltebc881782018-01-23 20:09:15 +0100663 vc_conn.done;
664}
665
Harald Welte66af9e62018-01-24 17:28:21 +0100666/* Test LU but BSC will send a clear request in the middle */
667private function f_tc_lu_disconnect(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
668 g_pars := pars;
669
670 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
671 var PDU_DTAP_MT dtap_mt;
672
673 /* tell GSUP dispatcher to send this IMSI to us */
674 f_create_gsup_expect(hex2str(g_pars.imsi));
675
676 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
677 f_bssap_compl_l3(l3_lu);
678
679 /* Send Early Classmark, just for the fun of it */
680 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
681
682 f_sleep(1.0);
683 /* send clear request in the middle of the LU */
684 BSSAP.send(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
685 setverdict(pass);
686}
687testcase TC_lu_disconnect() runs on MTC_CT {
688 var BSC_ConnHdlr vc_conn;
689 f_init();
690
Harald Welte81b7f9d2018-01-24 19:06:24 +0100691 vc_conn := f_start_handler(refers(f_tc_lu_disconnect), testcasename(), 11);
Harald Welte66af9e62018-01-24 17:28:21 +0100692 vc_conn.done;
693}
694
695
Harald Welteba7b6d92018-01-23 21:32:34 +0100696/* Test LU but with illegal mobile identity type = IMEI */
697private function f_tc_lu_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
698 g_pars := pars;
699
Harald Welte256571e2018-01-24 18:47:19 +0100700 var PDU_ML3_MS_NW l3_lu := f_build_lu_imei(g_pars.imei)
Harald Welteba7b6d92018-01-23 21:32:34 +0100701 var PDU_DTAP_MT dtap_mt;
702
703 /* tell GSUP dispatcher to send this IMSI to us */
704 f_create_gsup_expect(hex2str(g_pars.imsi));
705
706 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
707 f_bssap_compl_l3(l3_lu);
708
709 /* Send Early Classmark, just for the fun of it */
710 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
711 /* wait for LU reject, ignore any ID REQ */
712 alt {
713 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
714 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req)) { repeat; }
715 }
716 /* wait for normal teardown */
717 BSSAP.receive(tr_BSSMAP_ClearCommand);
718 BSSAP.send(ts_BSSMAP_ClearComplete);
719 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
720 setverdict(pass);
721}
722testcase TC_lu_by_imei() runs on MTC_CT {
723 var BSC_ConnHdlr vc_conn;
724 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100725 f_vty_config(MSCVTY, "network", "authentication optional");
Harald Welteba7b6d92018-01-23 21:32:34 +0100726
Harald Welte81b7f9d2018-01-24 19:06:24 +0100727 vc_conn := f_start_handler(refers(f_tc_lu_by_imei), testcasename(), 12);
Harald Welteba7b6d92018-01-23 21:32:34 +0100728 vc_conn.done;
729}
730
731/* Test LU by TMSI with unknown TMSI, expect (and answer) ID REQ. */
732private function f_tc_lu_tmsi_noauth_unknown(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
733 g_pars := pars;
734
735 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('01020304'O); /* FIXME: Random */
736 var PDU_DTAP_MT dtap_mt;
737
738 /* tell GSUP dispatcher to send this IMSI to us */
739 f_create_gsup_expect(hex2str(g_pars.imsi));
740
741 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
742 f_bssap_compl_l3(l3_lu);
743
744 /* Send Early Classmark, just for the fun of it */
745 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
746
747 /* Wait for + respond to ID REQ (IMSI) */
748 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req('001'B)));
749 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
750
751 /* Expect MSC to do UpdateLocation to HLR; respond to it */
752 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
753 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
754 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
755 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
756
757 alt {
758 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) { }
759 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
760 setverdict(fail, "Expected LU ACK, but received REJ");
761 }
762 }
763
764 /* wait for normal teardown */
765 BSSAP.receive(tr_BSSMAP_ClearCommand);
766 BSSAP.send(ts_BSSMAP_ClearComplete);
767 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
768 setverdict(pass);
769}
770testcase TC_lu_by_tmsi_noauth_unknown() runs on MTC_CT {
771 var BSC_ConnHdlr vc_conn;
772 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100773 f_vty_config(MSCVTY, "network", "authentication optional");
Harald Welteba7b6d92018-01-23 21:32:34 +0100774
Harald Welte81b7f9d2018-01-24 19:06:24 +0100775 vc_conn := f_start_handler(refers(f_tc_lu_tmsi_noauth_unknown), testcasename(), 13);
Harald Welteba7b6d92018-01-23 21:32:34 +0100776 vc_conn.done;
777}
778
779
Harald Welte45164da2018-01-24 12:51:27 +0100780/* Test IMSI DETACH (MI=IMSI) */
781private function f_tc_imsi_detach_by_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
782 g_pars := pars;
783
784 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
785
786 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
787 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
788
789 /* Send Early Classmark, just for the fun of it? */
790 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
791
792 /* wait for normal teardown */
793 BSSAP.receive(tr_BSSMAP_ClearCommand);
794 BSSAP.send(ts_BSSMAP_ClearComplete);
795 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
796 setverdict(pass);
797}
798testcase TC_imsi_detach_by_imsi() runs on MTC_CT {
799 var BSC_ConnHdlr vc_conn;
800 f_init();
801
Harald Welte81b7f9d2018-01-24 19:06:24 +0100802 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imsi), testcasename(), 14);
Harald Welte45164da2018-01-24 12:51:27 +0100803 vc_conn.done;
804}
805
806/* Test IMSI DETACH (MI=TMSI) */
807private function f_tc_imsi_detach_by_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
808 g_pars := pars;
809
810 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('01020304'O));
811
812 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
813 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
814
815 /* Send Early Classmark, just for the fun of it? */
816 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
817
818 /* wait for normal teardown */
819 BSSAP.receive(tr_BSSMAP_ClearCommand);
820 BSSAP.send(ts_BSSMAP_ClearComplete);
821 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
822 setverdict(pass);
823}
824testcase TC_imsi_detach_by_tmsi() runs on MTC_CT {
825 var BSC_ConnHdlr vc_conn;
826 f_init();
827
Harald Welte81b7f9d2018-01-24 19:06:24 +0100828 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_tmsi), testcasename(), 15);
Harald Welte45164da2018-01-24 12:51:27 +0100829 vc_conn.done;
830}
831
832/* Test IMSI DETACH (MI=IMEI), which is illegal */
833private function f_tc_imsi_detach_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
834 g_pars := pars;
835
Harald Welte256571e2018-01-24 18:47:19 +0100836 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte45164da2018-01-24 12:51:27 +0100837
838 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
839 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
840
841 /* Send Early Classmark, just for the fun of it? */
842 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
843
844 /* wait for normal teardown */
845 BSSAP.receive(tr_BSSMAP_ClearCommand);
846 BSSAP.send(ts_BSSMAP_ClearComplete);
847 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
848 setverdict(pass);
849}
850testcase TC_imsi_detach_by_imei() runs on MTC_CT {
851 var BSC_ConnHdlr vc_conn;
852 f_init();
853
Harald Welte81b7f9d2018-01-24 19:06:24 +0100854 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imei), testcasename(), 16);
Harald Welte45164da2018-01-24 12:51:27 +0100855 vc_conn.done;
856}
857
858
859/* helper function for an emergency call. caller passes in mobile identity to use */
860private function f_emerg_call(MobileIdentityLV mi) runs on BSC_ConnHdlr {
861
Harald Welte6ed6bf92018-01-24 21:09:15 +0100862 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100863 f_bssap_compl_l3(l3_info);
864 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC));
865
866 var hexstring called := '112'H;
867 var integer tid := 0;
868 var MNCC_PDU mncc;
869 f_create_mncc_expect(hex2str(called));
870
871 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_EMERG_SETUP(tid)));
872 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(called)))) -> value mncc;
873 /* FIXME: extract call_id */
874
875 /* Call Proceeding */
876 MNCC.send(ts_MNCC_CALL_PROC_req(mncc.u.signal.callref, ts_MNCC_bcap_voice));
877 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(tid)));
878
879 /* Alerting */
880 MNCC.send(ts_MNCC_ALERT_req(mncc.u.signal.callref));
881 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(tid)));
882
883 /* Answer. This causes TCH assignment in case of "late assignment" */
884 MNCC.send(ts_MNCC_SETUP_COMPL_req(mncc.u.signal.callref));
885
886 f_sleep(3.0);
887
888 /* Hangup by "B" side */
889 MNCC.send(ts_MNCC_DISC_req(mncc.u.signal.callref, valueof(ts_MNCC_cause(23))));
890 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(tid)));
891
892 /* Release of call */
893 MNCC.send(ts_MNCC_REL_req(mncc.u.signal.callref, valueof(ts_MNCC_cause(42))));
894 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(tid)));
895
896 /* clearing of radio channel */
897 BSSAP.receive(tr_BSSMAP_ClearCommand);
898 BSSAP.send(ts_BSSMAP_ClearComplete);
899 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
900
901 f_sleep(5.0);
902}
903
904/* establish an emergency call by IMEI, no SIM inserted (and hence no IMSI) */
905private function f_tc_emerg_call_imei_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
906 g_pars := pars;
907
Harald Welte256571e2018-01-24 18:47:19 +0100908 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100909 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100910 f_bssap_compl_l3(l3_info);
911 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ('05'O)));
Harald Weltef6b62ee2018-01-24 21:49:32 +0100912 BSSAP.receive(tr_BSSMAP_ClearCommand);
913 BSSAP.send(ts_BSSMAP_ClearComplete);
914 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
Harald Welte45164da2018-01-24 12:51:27 +0100915 setverdict(pass);
916}
917testcase TC_emerg_call_imei_reject() runs on MTC_CT {
918 var BSC_ConnHdlr vc_conn;
919 f_init();
920
Harald Welte81b7f9d2018-01-24 19:06:24 +0100921 vc_conn := f_start_handler(refers(f_tc_emerg_call_imei_reject), testcasename(), 17);
Harald Welte45164da2018-01-24 12:51:27 +0100922 vc_conn.done;
923}
924
Harald Welted5b91402018-01-24 18:48:16 +0100925/* establish an emergency call by IMSI, SIM inserted (and hence IMSI) */
Harald Welte45164da2018-01-24 12:51:27 +0100926private function f_tc_emerg_call_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
927 g_pars := pars;
928 /* First perform location update to ensure subscriber is known */
929 f_perform_lu(false, true, true);
930 /* Then issue emergency call identified by IMSI */
931 f_emerg_call(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
932}
933testcase TC_emerg_call_imsi() runs on MTC_CT {
934 var BSC_ConnHdlr vc_conn;
935 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100936 f_vty_config(MSCVTY, "network", "authentication optional");
Harald Weltef6b62ee2018-01-24 21:49:32 +0100937 f_vty_config(MSCVTY, "msc", "assign-tmsi");
Harald Welte45164da2018-01-24 12:51:27 +0100938
Harald Welte81b7f9d2018-01-24 19:06:24 +0100939 vc_conn := f_start_handler(refers(f_tc_emerg_call_imsi), testcasename(), 18);
Harald Welte45164da2018-01-24 12:51:27 +0100940 vc_conn.done;
941}
942
943/* CM Service Request for VGCS -> reject */
944private function f_tc_cm_serv_req_vgcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
945 g_pars := pars;
946
947 /* First perform location update to ensure subscriber is known */
948 f_perform_lu(false, true, true);
949
950 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100951 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VGCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100952 f_bssap_compl_l3(l3_info);
953 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Weltef6b62ee2018-01-24 21:49:32 +0100954 BSSAP.receive(tr_BSSMAP_ClearCommand);
955 BSSAP.send(ts_BSSMAP_ClearComplete);
956 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
Harald Welte45164da2018-01-24 12:51:27 +0100957 setverdict(pass);
958}
959testcase TC_cm_serv_req_vgcs_reject() runs on MTC_CT {
960 var BSC_ConnHdlr vc_conn;
961 f_init();
Harald Weltef6b62ee2018-01-24 21:49:32 +0100962 f_vty_config(MSCVTY, "network", "authentication optional");
963 f_vty_config(MSCVTY, "msc", "assign-tmsi");
Harald Welte45164da2018-01-24 12:51:27 +0100964
Harald Welte81b7f9d2018-01-24 19:06:24 +0100965 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vgcs_reject), testcasename(), 19);
Harald Welte45164da2018-01-24 12:51:27 +0100966 vc_conn.done;
967}
968
969/* CM Service Request for VBS -> reject */
970private function f_tc_cm_serv_req_vbs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
971 g_pars := pars;
972
973 /* First perform location update to ensure subscriber is known */
974 f_perform_lu(false, true, true);
975
976 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100977 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VBS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100978 f_bssap_compl_l3(l3_info);
979 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Weltef6b62ee2018-01-24 21:49:32 +0100980 BSSAP.receive(tr_BSSMAP_ClearCommand);
981 BSSAP.send(ts_BSSMAP_ClearComplete);
982 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
Harald Welte45164da2018-01-24 12:51:27 +0100983 setverdict(pass);
984}
985testcase TC_cm_serv_req_vbs_reject() runs on MTC_CT {
986 var BSC_ConnHdlr vc_conn;
987 f_init();
Harald Weltef6b62ee2018-01-24 21:49:32 +0100988 f_vty_config(MSCVTY, "network", "authentication optional");
989 f_vty_config(MSCVTY, "msc", "assign-tmsi");
Harald Welte45164da2018-01-24 12:51:27 +0100990
Harald Welte81b7f9d2018-01-24 19:06:24 +0100991 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vbs_reject), testcasename(), 20);
Harald Welte45164da2018-01-24 12:51:27 +0100992 vc_conn.done;
993}
994
995/* CM Service Request for LCS -> reject */
996private function f_tc_cm_serv_req_lcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
997 g_pars := pars;
998
999 /* First perform location update to ensure subscriber is known */
1000 f_perform_lu(false, true, true);
1001
1002 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001003 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_LCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +01001004 f_bssap_compl_l3(l3_info);
1005 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte0195ab12018-01-24 21:50:20 +01001006 BSSAP.receive(tr_BSSMAP_ClearCommand);
1007 BSSAP.send(ts_BSSMAP_ClearComplete);
1008 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
Harald Welte45164da2018-01-24 12:51:27 +01001009 setverdict(pass);
1010}
1011testcase TC_cm_serv_req_lcs_reject() runs on MTC_CT {
1012 var BSC_ConnHdlr vc_conn;
1013 f_init();
Harald Welte0195ab12018-01-24 21:50:20 +01001014 f_vty_config(MSCVTY, "network", "authentication optional");
1015 f_vty_config(MSCVTY, "msc", "assign-tmsi");
Harald Welte45164da2018-01-24 12:51:27 +01001016
Harald Welte81b7f9d2018-01-24 19:06:24 +01001017 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_lcs_reject), testcasename(), 21);
Harald Welte45164da2018-01-24 12:51:27 +01001018 vc_conn.done;
1019}
1020
Harald Welte0195ab12018-01-24 21:50:20 +01001021/* CM Re-Establishment Request */
1022private function f_tc_cm_reest_req_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1023 g_pars := pars;
1024
1025 /* First perform location update to ensure subscriber is known */
1026 f_perform_lu(false, true, true);
1027
1028 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1029 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REEST_REQ(0, mi));
1030 f_bssap_compl_l3(l3_info);
1031 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
1032 BSSAP.receive(tr_BSSMAP_ClearCommand);
1033 BSSAP.send(ts_BSSMAP_ClearComplete);
1034 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1035 setverdict(pass);
1036}
1037testcase TC_cm_reest_req_reject() runs on MTC_CT {
1038 var BSC_ConnHdlr vc_conn;
1039 f_init();
1040 f_vty_config(MSCVTY, "network", "authentication optional");
1041 f_vty_config(MSCVTY, "msc", "assign-tmsi");
1042
1043 vc_conn := f_start_handler(refers(f_tc_cm_reest_req_reject), testcasename(), 22);
1044 vc_conn.done;
1045}
1046
Harald Weltec638f4d2018-01-24 22:00:36 +01001047/* Test LU (with authentication enabled), with wrong response from MS */
1048private function f_tc_lu_auth_2G_fail(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1049 g_pars := pars;
1050
1051 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
1052
1053 /* tell GSUP dispatcher to send this IMSI to us */
1054 f_create_gsup_expect(hex2str(g_pars.imsi));
1055
1056 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
1057 f_bssap_compl_l3(l3_lu);
1058
1059 /* Send Early Classmark, just for the fun of it */
1060 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1061
1062 var AuthVector vec := f_gen_auth_vec_2g();
1063 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(vec.rand, vec.sres, vec.kc));
1064 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
1065 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
1066
1067 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(vec.rand)));
1068 /* Send back wrong auth response */
1069 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G('00000000'O)));
1070
1071 /* Expect GSUP AUTH FAIL REP to HLR */
1072 GSUP.receive(tr_GSUP_AUTH_FAIL_IND(g_pars.imsi));
1073
1074 /* Expect LU REJECT with Cause == Illegal MS */
1075 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej('03'O)));
1076 BSSAP.receive(tr_BSSMAP_ClearCommand);
1077 BSSAP.send(ts_BSSMAP_ClearComplete);
1078 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1079 setverdict(pass);
1080}
1081testcase TC_lu_auth_2G_fail() 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
1087 vc_conn := f_start_handler(refers(f_tc_lu_auth_2G_fail), testcasename(), 23);
1088 vc_conn.done;
1089}
1090
Harald Welte16114282018-01-24 22:41:21 +01001091private function f_tc_lu_imsi_auth_tmsi_encr_13_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1092 g_pars := pars;
1093 f_perform_lu(true, true, true, true);
1094}
1095testcase TC_lu_imsi_auth_tmsi_encr_13_13() runs on MTC_CT {
1096 var BSC_ConnHdlr vc_conn;
1097 f_init();
1098 f_vty_config(MSCVTY, "network", "authentication required");
1099 f_vty_config(MSCVTY, "msc", "assign-tmsi");
1100 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1101
1102 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_13), testcasename(), 24);
1103 vc_conn.done;
1104}
1105
Harald Welte45164da2018-01-24 12:51:27 +01001106
Harald Welteba7b6d92018-01-23 21:32:34 +01001107/* TODO:
1108 * continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
1109 * malformed messages (missing IE, invalid message type): properly rejected?
1110 * MT call while LU or is ongoing: Do we use existing lchan or page while lchan active?
1111 * 3G/2G auth permutations
1112 * encryption algorithms vs. classmark vs. vty config
1113 * emergency call
1114 * IMSI DETACH
1115 * send new transaction after/during clear (like SMS, ...)
Harald Welte45164da2018-01-24 12:51:27 +01001116 * too long L3 INFO in DTAP
1117 * too long / padded BSSAP
1118 * too long / short TLV values
Harald Welteba7b6d92018-01-23 21:32:34 +01001119 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01001120
1121
1122control {
Harald Weltea49e36e2018-01-21 19:29:33 +01001123 execute( TC_cmserv_imsi_unknown() );
1124 execute( TC_lu_imsi_noauth_tmsi() );
1125 //execute( TC_lu_imsi_noauth_notmsi() );
1126 execute( TC_lu_imsi_reject() );
1127 execute( TC_lu_imsi_timeout_gsup() );
Harald Welte2bb825f2018-01-22 11:31:18 +01001128 execute( TC_lu_and_mo_call() );
Harald Welte071ed732018-01-23 19:53:52 +01001129 execute( TC_lu_auth_sai_timeout() );
1130 execute( TC_lu_auth_sai_err() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01001131 execute( TC_lu_clear_request() );
1132 execute( TC_lu_disconnect() );
1133 execute( TC_lu_by_imei() );
1134 execute( TC_lu_by_tmsi_noauth_unknown() );
1135 execute( TC_imsi_detach_by_imsi() );
1136 execute( TC_imsi_detach_by_tmsi() );
1137 execute( TC_imsi_detach_by_imei() );
1138 execute( TC_emerg_call_imei_reject() );
1139 execute( TC_emerg_call_imsi() );
1140 execute( TC_cm_serv_req_vgcs_reject() );
1141 execute( TC_cm_serv_req_vbs_reject() );
1142 execute( TC_cm_serv_req_lcs_reject() );
Harald Welte0195ab12018-01-24 21:50:20 +01001143 execute( TC_cm_reest_req_reject() );
Harald Weltef6dd64d2017-11-19 12:09:51 +01001144}
1145
1146
1147}