blob: 367cd79a420f1e925ae3bfcca26b8ab3f3980d14 [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),
334 cm3 := omit
Harald Weltea49e36e2018-01-21 19:29:33 +0100335 };
336
337 vc_conn := BSC_ConnHdlr.create(id);
338 /* BSSMAP part / A interface */
339 connect(vc_conn:BSSAP, vc_BSSMAP:CLIENT);
340 connect(vc_conn:BSSAP_PROC, vc_BSSMAP:PROC);
341 /* MNCC part */
342 connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
343 connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);
344 /* GSUP part */
345 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
346 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
347
348 vc_conn.start(derefers(fn)(id, pars));
349 return vc_conn;
350}
351
352function f_sleep(float seconds) {
353 timer T := seconds;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100354 T.start;
355 T.timeout;
Harald Weltea49e36e2018-01-21 19:29:33 +0100356}
Harald Weltef6dd64d2017-11-19 12:09:51 +0100357
Harald Welte3ca1c902018-01-24 18:51:27 +0100358function f_vty_config(TELNETasp_PT pt, charstring config_node, charstring cmd)
359{
360 /* enter config mode; enter node */
361 f_vty_enter_config(pt);
362 f_vty_transceive(pt, config_node);
363 /* execute command */
364 f_vty_transceive(pt, cmd);
365 /* leave config mode */
366 f_vty_transceive(pt, "end");
367}
368
Harald Weltea49e36e2018-01-21 19:29:33 +0100369private function f_tc_lu_imsi_noauth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
370 g_pars := pars;
Harald Welte8a121b32018-01-22 03:00:41 +0100371 f_perform_lu(false, true, true);
Harald Weltea49e36e2018-01-21 19:29:33 +0100372}
Harald Weltea49e36e2018-01-21 19:29:33 +0100373testcase TC_lu_imsi_noauth_tmsi() runs on MTC_CT {
374 var BSC_ConnHdlr vc_conn;
375 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100376 f_vty_config(MSCVTY, "network", "authentication optional");
377 f_vty_config(MSCVTY, "msc", "assign-tmsi");
Harald Weltea49e36e2018-01-21 19:29:33 +0100378
379 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi), testcasename(), 1);
380 vc_conn.done;
381}
382
383private function f_tc_lu_imsi_noauth_notmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
384 g_pars := pars;
Harald Welte8a121b32018-01-22 03:00:41 +0100385 f_perform_lu(false, false, true);
Harald Weltea49e36e2018-01-21 19:29:33 +0100386}
Harald Weltea49e36e2018-01-21 19:29:33 +0100387testcase TC_lu_imsi_noauth_notmsi() runs on MTC_CT {
388 var BSC_ConnHdlr vc_conn;
389 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100390 f_vty_config(MSCVTY, "network", "authentication optional");
391 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
Harald Weltea49e36e2018-01-21 19:29:33 +0100392
393 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi), testcasename(), 2);
394 vc_conn.done;
395}
396
397/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
398private function f_tc_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
399 g_pars := pars;
400 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
401
402 f_create_gsup_expect(hex2str(g_pars.imsi));
403 f_bssap_compl_l3(l3_lu);
404 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
405 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
406 alt {
407 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej(int2oct(23,1)))) { }
408 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
409 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
410 self.stop;
411 }
412 }
413 BSSAP.receive(tr_BSSMAP_ClearCommand);
414 BSSAP.send(ts_BSSMAP_ClearComplete);
415 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
416 setverdict(pass);
417}
418testcase TC_lu_imsi_reject() runs on MTC_CT {
419 var BSC_ConnHdlr vc_conn;
420 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100421 f_vty_config(MSCVTY, "network", "authentication optional");
Harald Weltea49e36e2018-01-21 19:29:33 +0100422
423 vc_conn := f_start_handler(refers(f_tc_lu_imsi_reject), testcasename(), 3);
424 vc_conn.done;
425}
426
427/* Do LU by IMSI, timeout on GSUP */
428private function f_tc_lu_imsi_timeout_gsup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
429 g_pars := pars;
430 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
431
432 f_create_gsup_expect(hex2str(g_pars.imsi));
433 f_bssap_compl_l3(l3_lu);
434 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
435 /* Normally the HLR would need to respond here, but we decide to force a timeout here */
436 alt {
437 /* FIXME: Expect specific reject cause */
438 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
439 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
440 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
441 self.stop;
442 }
443 }
444 BSSAP.receive(tr_BSSMAP_ClearCommand);
445 BSSAP.send(ts_BSSMAP_ClearComplete);
446 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
447 setverdict(pass);
448}
449testcase TC_lu_imsi_timeout_gsup() runs on MTC_CT {
450 var BSC_ConnHdlr vc_conn;
451 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100452 f_vty_config(MSCVTY, "network", "authentication optional");
Harald Weltea49e36e2018-01-21 19:29:33 +0100453
454 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_gsup), testcasename(), 4);
455 vc_conn.done;
456}
457
Harald Welte7b1b2812018-01-22 21:23:06 +0100458private function f_tc_lu_imsi_auth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
459 g_pars := pars;
460 f_perform_lu(true, true, true);
461}
462testcase TC_lu_imsi_auth_tmsi() runs on MTC_CT {
463 var BSC_ConnHdlr vc_conn;
464 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100465 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte7b1b2812018-01-22 21:23:06 +0100466
467 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi), testcasename(), 5);
468 vc_conn.done;
469}
470
Harald Weltea49e36e2018-01-21 19:29:33 +0100471
472/* Send CM SERVICE REQ for IMSI that has never performed LU before */
473private function f_tc_cmserv_imsi_unknown(charstring id, BSC_ConnHdlrPars pars)
474runs on BSC_ConnHdlr {
475
476 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
477 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '042'H, 23, 42));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100478 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltea49e36e2018-01-21 19:29:33 +0100479
480 f_create_gsup_expect(hex2str(g_pars.imsi));
481
482 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
483 f_bssap_compl_l3(l3_info);
484
485 timer T := 10.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100486 T.start;
487 alt {
Harald Weltea49e36e2018-01-21 19:29:33 +0100488 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
489 //[] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC)) { }
490 [] BSSAP.receive { setverdict(fail, "Received unexpected BSSAP"); }
491 [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
492 setverdict(fail, "Unexpected GSUP UL REQ");
493 }
494 [] T.timeout { setverdict(inconc, "Timeout waiting for CM SERV REQ"); }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100495 }
496
Harald Weltea49e36e2018-01-21 19:29:33 +0100497 alt {
498 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
499 setverdict(pass);
500 }
501 [] BSSAP.receive { setverdict(fail, "Received unexpected BSSAP"); }
502 [] T.timeout { setverdict(inconc, "Timeout waiting for CM SERV REQ"); }
503 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100504}
Harald Weltea49e36e2018-01-21 19:29:33 +0100505testcase TC_cmserv_imsi_unknown() runs on MTC_CT {
506 var BSC_ConnHdlr vc_conn;
507 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100508 f_vty_config(MSCVTY, "network", "authentication optional");
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();
Harald Welte3ca1c902018-01-24 18:51:27 +0100559 f_vty_config(MSCVTY, "network", "authentication optional");
Harald Welte2bb825f2018-01-22 11:31:18 +0100560
Harald Welte81b7f9d2018-01-24 19:06:24 +0100561 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_call), testcasename(), 7);
Harald Welte071ed732018-01-23 19:53:52 +0100562 vc_conn.done;
563}
564
565/* Test LU (with authentication enabled), where HLR times out sending SAI response */
566private function f_tc_lu_auth_sai_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
567 g_pars := pars;
568
569 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
570 var PDU_DTAP_MT dtap_mt;
571
572 /* tell GSUP dispatcher to send this IMSI to us */
573 f_create_gsup_expect(hex2str(g_pars.imsi));
574
575 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
576 f_bssap_compl_l3(l3_lu);
577
578 /* Send Early Classmark, just for the fun of it */
579 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
580
581 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
582 /* The HLR would normally return an auth vector here, but we fail to do so. */
583
584 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
585 BSSAP.receive(tr_BSSMAP_ClearCommand);
586 BSSAP.send(ts_BSSMAP_ClearComplete);
587 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
588 setverdict(pass);
589}
590testcase TC_lu_auth_sai_timeout() runs on MTC_CT {
591 var BSC_ConnHdlr vc_conn;
592 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100593 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100594
Harald Welte81b7f9d2018-01-24 19:06:24 +0100595 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_timeout), testcasename(), 8);
Harald Welte071ed732018-01-23 19:53:52 +0100596 vc_conn.done;
597}
598
599/* Test LU (with authentication enabled), where HLR rejects sending SAI error */
600private function f_tc_lu_auth_sai_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
601 g_pars := pars;
602
603 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
604 var PDU_DTAP_MT dtap_mt;
605
606 /* tell GSUP dispatcher to send this IMSI to us */
607 f_create_gsup_expect(hex2str(g_pars.imsi));
608
609 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
610 f_bssap_compl_l3(l3_lu);
611
612 /* Send Early Classmark, just for the fun of it */
613 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
614
615 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
616 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 13));
617
618 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
619 BSSAP.receive(tr_BSSMAP_ClearCommand);
620 BSSAP.send(ts_BSSMAP_ClearComplete);
621 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
622 setverdict(pass);
623}
624testcase TC_lu_auth_sai_err() runs on MTC_CT {
625 var BSC_ConnHdlr vc_conn;
626 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100627 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100628
Harald Welte81b7f9d2018-01-24 19:06:24 +0100629 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_err), testcasename(), 9);
Harald Welte2bb825f2018-01-22 11:31:18 +0100630 vc_conn.done;
631}
Harald Weltea49e36e2018-01-21 19:29:33 +0100632
Harald Weltebc881782018-01-23 20:09:15 +0100633/* Test LU but BSC will send a clear request in the middle */
634private function f_tc_lu_clear_request(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
635 g_pars := pars;
636
637 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
638 var PDU_DTAP_MT dtap_mt;
639
640 /* tell GSUP dispatcher to send this IMSI to us */
641 f_create_gsup_expect(hex2str(g_pars.imsi));
642
643 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
644 f_bssap_compl_l3(l3_lu);
645
646 /* Send Early Classmark, just for the fun of it */
647 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
648
649 f_sleep(1.0);
650 /* send clear request in the middle of the LU */
651 BSSAP.send(ts_BSSMAP_ClearRequest(0));
652 BSSAP.receive(tr_BSSMAP_ClearCommand);
653 BSSAP.send(ts_BSSMAP_ClearComplete);
654 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
655 setverdict(pass);
656}
657testcase TC_lu_clear_request() runs on MTC_CT {
658 var BSC_ConnHdlr vc_conn;
659 f_init();
660
Harald Welte81b7f9d2018-01-24 19:06:24 +0100661 vc_conn := f_start_handler(refers(f_tc_lu_clear_request), testcasename(), 10);
Harald Weltebc881782018-01-23 20:09:15 +0100662 vc_conn.done;
663}
664
Harald Welte66af9e62018-01-24 17:28:21 +0100665/* Test LU but BSC will send a clear request in the middle */
666private function f_tc_lu_disconnect(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
667 g_pars := pars;
668
669 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
670 var PDU_DTAP_MT dtap_mt;
671
672 /* tell GSUP dispatcher to send this IMSI to us */
673 f_create_gsup_expect(hex2str(g_pars.imsi));
674
675 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
676 f_bssap_compl_l3(l3_lu);
677
678 /* Send Early Classmark, just for the fun of it */
679 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
680
681 f_sleep(1.0);
682 /* send clear request in the middle of the LU */
683 BSSAP.send(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
684 setverdict(pass);
685}
686testcase TC_lu_disconnect() runs on MTC_CT {
687 var BSC_ConnHdlr vc_conn;
688 f_init();
689
Harald Welte81b7f9d2018-01-24 19:06:24 +0100690 vc_conn := f_start_handler(refers(f_tc_lu_disconnect), testcasename(), 11);
Harald Welte66af9e62018-01-24 17:28:21 +0100691 vc_conn.done;
692}
693
694
Harald Welteba7b6d92018-01-23 21:32:34 +0100695/* Test LU but with illegal mobile identity type = IMEI */
696private function f_tc_lu_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
697 g_pars := pars;
698
Harald Welte256571e2018-01-24 18:47:19 +0100699 var PDU_ML3_MS_NW l3_lu := f_build_lu_imei(g_pars.imei)
Harald Welteba7b6d92018-01-23 21:32:34 +0100700 var PDU_DTAP_MT dtap_mt;
701
702 /* tell GSUP dispatcher to send this IMSI to us */
703 f_create_gsup_expect(hex2str(g_pars.imsi));
704
705 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
706 f_bssap_compl_l3(l3_lu);
707
708 /* Send Early Classmark, just for the fun of it */
709 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
710 /* wait for LU reject, ignore any ID REQ */
711 alt {
712 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
713 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req)) { repeat; }
714 }
715 /* wait for normal teardown */
716 BSSAP.receive(tr_BSSMAP_ClearCommand);
717 BSSAP.send(ts_BSSMAP_ClearComplete);
718 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
719 setverdict(pass);
720}
721testcase TC_lu_by_imei() runs on MTC_CT {
722 var BSC_ConnHdlr vc_conn;
723 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100724 f_vty_config(MSCVTY, "network", "authentication optional");
Harald Welteba7b6d92018-01-23 21:32:34 +0100725
Harald Welte81b7f9d2018-01-24 19:06:24 +0100726 vc_conn := f_start_handler(refers(f_tc_lu_by_imei), testcasename(), 12);
Harald Welteba7b6d92018-01-23 21:32:34 +0100727 vc_conn.done;
728}
729
730/* Test LU by TMSI with unknown TMSI, expect (and answer) ID REQ. */
731private function f_tc_lu_tmsi_noauth_unknown(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
732 g_pars := pars;
733
734 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('01020304'O); /* FIXME: Random */
735 var PDU_DTAP_MT dtap_mt;
736
737 /* tell GSUP dispatcher to send this IMSI to us */
738 f_create_gsup_expect(hex2str(g_pars.imsi));
739
740 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
741 f_bssap_compl_l3(l3_lu);
742
743 /* Send Early Classmark, just for the fun of it */
744 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
745
746 /* Wait for + respond to ID REQ (IMSI) */
747 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req('001'B)));
748 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
749
750 /* Expect MSC to do UpdateLocation to HLR; respond to it */
751 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
752 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
753 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
754 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
755
756 alt {
757 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) { }
758 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
759 setverdict(fail, "Expected LU ACK, but received REJ");
760 }
761 }
762
763 /* wait for normal teardown */
764 BSSAP.receive(tr_BSSMAP_ClearCommand);
765 BSSAP.send(ts_BSSMAP_ClearComplete);
766 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
767 setverdict(pass);
768}
769testcase TC_lu_by_tmsi_noauth_unknown() runs on MTC_CT {
770 var BSC_ConnHdlr vc_conn;
771 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100772 f_vty_config(MSCVTY, "network", "authentication optional");
Harald Welteba7b6d92018-01-23 21:32:34 +0100773
Harald Welte81b7f9d2018-01-24 19:06:24 +0100774 vc_conn := f_start_handler(refers(f_tc_lu_tmsi_noauth_unknown), testcasename(), 13);
Harald Welteba7b6d92018-01-23 21:32:34 +0100775 vc_conn.done;
776}
777
778
Harald Welte45164da2018-01-24 12:51:27 +0100779/* Test IMSI DETACH (MI=IMSI) */
780private function f_tc_imsi_detach_by_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
781 g_pars := pars;
782
783 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
784
785 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
786 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
787
788 /* Send Early Classmark, just for the fun of it? */
789 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
790
791 /* wait for normal teardown */
792 BSSAP.receive(tr_BSSMAP_ClearCommand);
793 BSSAP.send(ts_BSSMAP_ClearComplete);
794 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
795 setverdict(pass);
796}
797testcase TC_imsi_detach_by_imsi() runs on MTC_CT {
798 var BSC_ConnHdlr vc_conn;
799 f_init();
800
Harald Welte81b7f9d2018-01-24 19:06:24 +0100801 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imsi), testcasename(), 14);
Harald Welte45164da2018-01-24 12:51:27 +0100802 vc_conn.done;
803}
804
805/* Test IMSI DETACH (MI=TMSI) */
806private function f_tc_imsi_detach_by_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
807 g_pars := pars;
808
809 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('01020304'O));
810
811 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
812 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
813
814 /* Send Early Classmark, just for the fun of it? */
815 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
816
817 /* wait for normal teardown */
818 BSSAP.receive(tr_BSSMAP_ClearCommand);
819 BSSAP.send(ts_BSSMAP_ClearComplete);
820 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
821 setverdict(pass);
822}
823testcase TC_imsi_detach_by_tmsi() runs on MTC_CT {
824 var BSC_ConnHdlr vc_conn;
825 f_init();
826
Harald Welte81b7f9d2018-01-24 19:06:24 +0100827 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_tmsi), testcasename(), 15);
Harald Welte45164da2018-01-24 12:51:27 +0100828 vc_conn.done;
829}
830
831/* Test IMSI DETACH (MI=IMEI), which is illegal */
832private function f_tc_imsi_detach_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
833 g_pars := pars;
834
Harald Welte256571e2018-01-24 18:47:19 +0100835 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte45164da2018-01-24 12:51:27 +0100836
837 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
838 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
839
840 /* Send Early Classmark, just for the fun of it? */
841 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
842
843 /* wait for normal teardown */
844 BSSAP.receive(tr_BSSMAP_ClearCommand);
845 BSSAP.send(ts_BSSMAP_ClearComplete);
846 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
847 setverdict(pass);
848}
849testcase TC_imsi_detach_by_imei() runs on MTC_CT {
850 var BSC_ConnHdlr vc_conn;
851 f_init();
852
Harald Welte81b7f9d2018-01-24 19:06:24 +0100853 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imei), testcasename(), 16);
Harald Welte45164da2018-01-24 12:51:27 +0100854 vc_conn.done;
855}
856
857
858/* helper function for an emergency call. caller passes in mobile identity to use */
859private function f_emerg_call(MobileIdentityLV mi) runs on BSC_ConnHdlr {
860
Harald Welte6ed6bf92018-01-24 21:09:15 +0100861 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100862 f_bssap_compl_l3(l3_info);
863 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC));
864
865 var hexstring called := '112'H;
866 var integer tid := 0;
867 var MNCC_PDU mncc;
868 f_create_mncc_expect(hex2str(called));
869
870 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_EMERG_SETUP(tid)));
871 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(called)))) -> value mncc;
872 /* FIXME: extract call_id */
873
874 /* Call Proceeding */
875 MNCC.send(ts_MNCC_CALL_PROC_req(mncc.u.signal.callref, ts_MNCC_bcap_voice));
876 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(tid)));
877
878 /* Alerting */
879 MNCC.send(ts_MNCC_ALERT_req(mncc.u.signal.callref));
880 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(tid)));
881
882 /* Answer. This causes TCH assignment in case of "late assignment" */
883 MNCC.send(ts_MNCC_SETUP_COMPL_req(mncc.u.signal.callref));
884
885 f_sleep(3.0);
886
887 /* Hangup by "B" side */
888 MNCC.send(ts_MNCC_DISC_req(mncc.u.signal.callref, valueof(ts_MNCC_cause(23))));
889 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(tid)));
890
891 /* Release of call */
892 MNCC.send(ts_MNCC_REL_req(mncc.u.signal.callref, valueof(ts_MNCC_cause(42))));
893 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(tid)));
894
895 /* clearing of radio channel */
896 BSSAP.receive(tr_BSSMAP_ClearCommand);
897 BSSAP.send(ts_BSSMAP_ClearComplete);
898 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
899
900 f_sleep(5.0);
901}
902
903/* establish an emergency call by IMEI, no SIM inserted (and hence no IMSI) */
904private function f_tc_emerg_call_imei_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
905 g_pars := pars;
906
Harald Welte256571e2018-01-24 18:47:19 +0100907 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100908 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100909 f_bssap_compl_l3(l3_info);
910 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ('05'O)));
Harald Weltef6b62ee2018-01-24 21:49:32 +0100911 BSSAP.receive(tr_BSSMAP_ClearCommand);
912 BSSAP.send(ts_BSSMAP_ClearComplete);
913 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
Harald Welte45164da2018-01-24 12:51:27 +0100914 setverdict(pass);
915}
916testcase TC_emerg_call_imei_reject() runs on MTC_CT {
917 var BSC_ConnHdlr vc_conn;
918 f_init();
919
Harald Welte81b7f9d2018-01-24 19:06:24 +0100920 vc_conn := f_start_handler(refers(f_tc_emerg_call_imei_reject), testcasename(), 17);
Harald Welte45164da2018-01-24 12:51:27 +0100921 vc_conn.done;
922}
923
Harald Welted5b91402018-01-24 18:48:16 +0100924/* establish an emergency call by IMSI, SIM inserted (and hence IMSI) */
Harald Welte45164da2018-01-24 12:51:27 +0100925private function f_tc_emerg_call_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
926 g_pars := pars;
927 /* First perform location update to ensure subscriber is known */
928 f_perform_lu(false, true, true);
929 /* Then issue emergency call identified by IMSI */
930 f_emerg_call(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
931}
932testcase TC_emerg_call_imsi() runs on MTC_CT {
933 var BSC_ConnHdlr vc_conn;
934 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100935 f_vty_config(MSCVTY, "network", "authentication optional");
Harald Weltef6b62ee2018-01-24 21:49:32 +0100936 f_vty_config(MSCVTY, "msc", "assign-tmsi");
Harald Welte45164da2018-01-24 12:51:27 +0100937
Harald Welte81b7f9d2018-01-24 19:06:24 +0100938 vc_conn := f_start_handler(refers(f_tc_emerg_call_imsi), testcasename(), 18);
Harald Welte45164da2018-01-24 12:51:27 +0100939 vc_conn.done;
940}
941
942/* CM Service Request for VGCS -> reject */
943private function f_tc_cm_serv_req_vgcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
944 g_pars := pars;
945
946 /* First perform location update to ensure subscriber is known */
947 f_perform_lu(false, true, true);
948
949 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100950 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VGCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100951 f_bssap_compl_l3(l3_info);
952 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Weltef6b62ee2018-01-24 21:49:32 +0100953 BSSAP.receive(tr_BSSMAP_ClearCommand);
954 BSSAP.send(ts_BSSMAP_ClearComplete);
955 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
Harald Welte45164da2018-01-24 12:51:27 +0100956 setverdict(pass);
957}
958testcase TC_cm_serv_req_vgcs_reject() runs on MTC_CT {
959 var BSC_ConnHdlr vc_conn;
960 f_init();
Harald Weltef6b62ee2018-01-24 21:49:32 +0100961 f_vty_config(MSCVTY, "network", "authentication optional");
962 f_vty_config(MSCVTY, "msc", "assign-tmsi");
Harald Welte45164da2018-01-24 12:51:27 +0100963
Harald Welte81b7f9d2018-01-24 19:06:24 +0100964 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vgcs_reject), testcasename(), 19);
Harald Welte45164da2018-01-24 12:51:27 +0100965 vc_conn.done;
966}
967
968/* CM Service Request for VBS -> reject */
969private function f_tc_cm_serv_req_vbs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
970 g_pars := pars;
971
972 /* First perform location update to ensure subscriber is known */
973 f_perform_lu(false, true, true);
974
975 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100976 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VBS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100977 f_bssap_compl_l3(l3_info);
978 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Weltef6b62ee2018-01-24 21:49:32 +0100979 BSSAP.receive(tr_BSSMAP_ClearCommand);
980 BSSAP.send(ts_BSSMAP_ClearComplete);
981 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
Harald Welte45164da2018-01-24 12:51:27 +0100982 setverdict(pass);
983}
984testcase TC_cm_serv_req_vbs_reject() runs on MTC_CT {
985 var BSC_ConnHdlr vc_conn;
986 f_init();
Harald Weltef6b62ee2018-01-24 21:49:32 +0100987 f_vty_config(MSCVTY, "network", "authentication optional");
988 f_vty_config(MSCVTY, "msc", "assign-tmsi");
Harald Welte45164da2018-01-24 12:51:27 +0100989
Harald Welte81b7f9d2018-01-24 19:06:24 +0100990 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vbs_reject), testcasename(), 20);
Harald Welte45164da2018-01-24 12:51:27 +0100991 vc_conn.done;
992}
993
994/* CM Service Request for LCS -> reject */
995private function f_tc_cm_serv_req_lcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
996 g_pars := pars;
997
998 /* First perform location update to ensure subscriber is known */
999 f_perform_lu(false, true, true);
1000
1001 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +01001002 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_LCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +01001003 f_bssap_compl_l3(l3_info);
1004 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte0195ab12018-01-24 21:50:20 +01001005 BSSAP.receive(tr_BSSMAP_ClearCommand);
1006 BSSAP.send(ts_BSSMAP_ClearComplete);
1007 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
Harald Welte45164da2018-01-24 12:51:27 +01001008 setverdict(pass);
1009}
1010testcase TC_cm_serv_req_lcs_reject() runs on MTC_CT {
1011 var BSC_ConnHdlr vc_conn;
1012 f_init();
Harald Welte0195ab12018-01-24 21:50:20 +01001013 f_vty_config(MSCVTY, "network", "authentication optional");
1014 f_vty_config(MSCVTY, "msc", "assign-tmsi");
Harald Welte45164da2018-01-24 12:51:27 +01001015
Harald Welte81b7f9d2018-01-24 19:06:24 +01001016 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_lcs_reject), testcasename(), 21);
Harald Welte45164da2018-01-24 12:51:27 +01001017 vc_conn.done;
1018}
1019
Harald Welte0195ab12018-01-24 21:50:20 +01001020/* CM Re-Establishment Request */
1021private function f_tc_cm_reest_req_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1022 g_pars := pars;
1023
1024 /* First perform location update to ensure subscriber is known */
1025 f_perform_lu(false, true, true);
1026
1027 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1028 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REEST_REQ(0, mi));
1029 f_bssap_compl_l3(l3_info);
1030 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
1031 BSSAP.receive(tr_BSSMAP_ClearCommand);
1032 BSSAP.send(ts_BSSMAP_ClearComplete);
1033 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1034 setverdict(pass);
1035}
1036testcase TC_cm_reest_req_reject() runs on MTC_CT {
1037 var BSC_ConnHdlr vc_conn;
1038 f_init();
1039 f_vty_config(MSCVTY, "network", "authentication optional");
1040 f_vty_config(MSCVTY, "msc", "assign-tmsi");
1041
1042 vc_conn := f_start_handler(refers(f_tc_cm_reest_req_reject), testcasename(), 22);
1043 vc_conn.done;
1044}
1045
Harald Weltec638f4d2018-01-24 22:00:36 +01001046/* Test LU (with authentication enabled), with wrong response from MS */
1047private function f_tc_lu_auth_2G_fail(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1048 g_pars := pars;
1049
1050 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
1051
1052 /* tell GSUP dispatcher to send this IMSI to us */
1053 f_create_gsup_expect(hex2str(g_pars.imsi));
1054
1055 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
1056 f_bssap_compl_l3(l3_lu);
1057
1058 /* Send Early Classmark, just for the fun of it */
1059 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
1060
1061 var AuthVector vec := f_gen_auth_vec_2g();
1062 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(vec.rand, vec.sres, vec.kc));
1063 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
1064 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
1065
1066 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(vec.rand)));
1067 /* Send back wrong auth response */
1068 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G('00000000'O)));
1069
1070 /* Expect GSUP AUTH FAIL REP to HLR */
1071 GSUP.receive(tr_GSUP_AUTH_FAIL_IND(g_pars.imsi));
1072
1073 /* Expect LU REJECT with Cause == Illegal MS */
1074 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej('03'O)));
1075 BSSAP.receive(tr_BSSMAP_ClearCommand);
1076 BSSAP.send(ts_BSSMAP_ClearComplete);
1077 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1078 setverdict(pass);
1079}
1080testcase TC_lu_auth_2G_fail() runs on MTC_CT {
1081 var BSC_ConnHdlr vc_conn;
1082 f_init();
1083 f_vty_config(MSCVTY, "network", "authentication required");
1084 f_vty_config(MSCVTY, "msc", "assign-tmsi");
1085
1086 vc_conn := f_start_handler(refers(f_tc_lu_auth_2G_fail), testcasename(), 23);
1087 vc_conn.done;
1088}
1089
Harald Welte45164da2018-01-24 12:51:27 +01001090
Harald Welteba7b6d92018-01-23 21:32:34 +01001091/* TODO:
1092 * continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
1093 * malformed messages (missing IE, invalid message type): properly rejected?
1094 * MT call while LU or is ongoing: Do we use existing lchan or page while lchan active?
1095 * 3G/2G auth permutations
1096 * encryption algorithms vs. classmark vs. vty config
1097 * emergency call
1098 * IMSI DETACH
1099 * send new transaction after/during clear (like SMS, ...)
Harald Welte45164da2018-01-24 12:51:27 +01001100 * too long L3 INFO in DTAP
1101 * too long / padded BSSAP
1102 * too long / short TLV values
Harald Welteba7b6d92018-01-23 21:32:34 +01001103 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01001104
1105
1106control {
Harald Weltea49e36e2018-01-21 19:29:33 +01001107 execute( TC_cmserv_imsi_unknown() );
1108 execute( TC_lu_imsi_noauth_tmsi() );
1109 //execute( TC_lu_imsi_noauth_notmsi() );
1110 execute( TC_lu_imsi_reject() );
1111 execute( TC_lu_imsi_timeout_gsup() );
Harald Welte2bb825f2018-01-22 11:31:18 +01001112 execute( TC_lu_and_mo_call() );
Harald Welte071ed732018-01-23 19:53:52 +01001113 execute( TC_lu_auth_sai_timeout() );
1114 execute( TC_lu_auth_sai_err() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01001115 execute( TC_lu_clear_request() );
1116 execute( TC_lu_disconnect() );
1117 execute( TC_lu_by_imei() );
1118 execute( TC_lu_by_tmsi_noauth_unknown() );
1119 execute( TC_imsi_detach_by_imsi() );
1120 execute( TC_imsi_detach_by_tmsi() );
1121 execute( TC_imsi_detach_by_imei() );
1122 execute( TC_emerg_call_imei_reject() );
1123 execute( TC_emerg_call_imsi() );
1124 execute( TC_cm_serv_req_vgcs_reject() );
1125 execute( TC_cm_serv_req_vbs_reject() );
1126 execute( TC_cm_serv_req_lcs_reject() );
Harald Welte0195ab12018-01-24 21:50:20 +01001127 execute( TC_cm_reest_req_reject() );
Harald Weltef6dd64d2017-11-19 12:09:51 +01001128}
1129
1130
1131}