blob: d0000d84871ad4d4406a3410e4bbc56e9ffdcb84 [file] [log] [blame]
Harald Weltef6dd64d2017-11-19 12:09:51 +01001module MSC_Tests {
2
3import from General_Types all;
4import from Osmocom_Types all;
5
6import from M3UA_Types all;
7import from M3UA_Emulation all;
8
9import from MTP3asp_Types all;
10import from MTP3asp_PortType all;
11
12import from SCCPasp_Types all;
13import from SCCP_Types all;
14import from SCCP_Emulation all;
15
16import from SCTPasp_Types all;
17import from SCTPasp_PortType all;
18
Harald Weltea49e36e2018-01-21 19:29:33 +010019import from Osmocom_CTRL_Functions all;
20import from Osmocom_CTRL_Types all;
21import from Osmocom_CTRL_Adapter all;
22
Harald Welte3ca1c902018-01-24 18:51:27 +010023import from TELNETasp_PortType all;
24import from Osmocom_VTY_Functions all;
25
Harald Weltea49e36e2018-01-21 19:29:33 +010026import from MNCC_Emulation all;
Harald Welte2bb825f2018-01-22 11:31:18 +010027import from MNCC_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +010028
Harald Welte4aa970c2018-01-26 10:38:09 +010029import from MGCP_Emulation all;
30import from MGCP_Types all;
31import from MGCP_Templates all;
32import from SDP_Types all;
33
Harald Weltea49e36e2018-01-21 19:29:33 +010034import from GSUP_Emulation all;
35import from GSUP_Types all;
36import from IPA_Emulation all;
37
Harald Weltef6dd64d2017-11-19 12:09:51 +010038import from BSSAP_Types all;
Harald Weltea49e36e2018-01-21 19:29:33 +010039import from BSSAP_Adapter all;
40import from BSSAP_CodecPort all;
41import from BSSMAP_Templates all;
42import from BSSMAP_Emulation all;
43import from BSC_ConnectionHandler all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010044
Harald Weltea49e36e2018-01-21 19:29:33 +010045import from MobileL3_Types all;
46import from MobileL3_CommonIE_Types all;
47import from L3_Templates all;
Harald Weltef6dd64d2017-11-19 12:09:51 +010048
Harald Weltef6dd64d2017-11-19 12:09:51 +010049
Harald Weltea49e36e2018-01-21 19:29:33 +010050type component MTC_CT extends BSSAP_Adapter_CT, CTRL_Adapter_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +010051 var boolean g_initialized := false;
Harald Weltea49e36e2018-01-21 19:29:33 +010052
53 /* no 'adapter_CT' for MNCC or GSUP */
54 var MNCC_Emulation_CT vc_MNCC;
Harald Welte4aa970c2018-01-26 10:38:09 +010055 var MGCP_Emulation_CT vc_MGCP;
Harald Weltea49e36e2018-01-21 19:29:33 +010056 var GSUP_Emulation_CT vc_GSUP;
57 var IPA_Emulation_CT vc_GSUP_IPA;
58
59 /* only to get events from IPA underneath GSUP */
60 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte3ca1c902018-01-24 18:51:27 +010061 /* VTY to MSC */
62 port TELNETasp_PT MSCVTY;
Harald Weltef6dd64d2017-11-19 12:09:51 +010063}
64
65modulepar {
Harald Weltea49e36e2018-01-21 19:29:33 +010066 /* remote parameters of IUT */
67 charstring mp_msc_ip := "127.0.0.1";
68 integer mp_msc_ctrl_port := 4255;
69 integer mp_msc_vty_port := 4254;
Harald Weltef6dd64d2017-11-19 12:09:51 +010070
Harald Weltea49e36e2018-01-21 19:29:33 +010071 /* local parameters of emulated HLR */
72 charstring mp_hlr_ip := "127.0.0.1";
73 integer mp_hlr_port := 4222;
Harald Weltef6dd64d2017-11-19 12:09:51 +010074
Harald Weltea49e36e2018-01-21 19:29:33 +010075 charstring mp_msc_mncc := "/tmp/mncc";
Harald Weltef6dd64d2017-11-19 12:09:51 +010076}
77
78
Harald Weltea49e36e2018-01-21 19:29:33 +010079function f_init_mncc(charstring id) runs on MTC_CT {
80 id := id & "-MNCC";
81 var MnccOps ops := {
82 create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
83 unitdata_cb := refers(MNCC_Emulation.DummyUnitdataCallback)
84 }
85
86 vc_MNCC := MNCC_Emulation_CT.create(id);
87 map(vc_MNCC:MNCC, system:MNCC_CODEC_PT);
88 vc_MNCC.start(MNCC_Emulation.main(ops, id, mp_msc_mncc));
Harald Weltef6dd64d2017-11-19 12:09:51 +010089}
90
Harald Welte4aa970c2018-01-26 10:38:09 +010091function f_init_mgcp(charstring id) runs on MTC_CT {
92 id := id & "-MGCP";
93 var MGCPOps ops := {
94 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
95 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
96 }
97 var MGCP_conn_parameters pars := {
98 callagent_ip := "127.0.0.1",
99 callagent_udp_port := -1,
100 mgw_ip := "127.0.0.1",
101 mgw_udp_port := 2427
102 }
103
104 vc_MGCP := MGCP_Emulation_CT.create(id);
105 map(vc_MGCP:MGCP, system:MGCP_CODEC_PT);
106 vc_MGCP.start(MGCP_Emulation.main(ops, pars, id));
107}
108
Harald Weltea49e36e2018-01-21 19:29:33 +0100109function f_init_gsup(charstring id) runs on MTC_CT {
110 id := id & "-GSUP";
111 var GsupOps ops := {
112 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
113 }
114
115 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
116 vc_GSUP := GSUP_Emulation_CT.create(id);
117
118 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
119 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
120 /* we use this hack to get events like ASP_IPA_EVENT_UP */
121 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
122
123 vc_GSUP.start(GSUP_Emulation.main(ops, id));
124 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
125
126 /* wait for incoming connection to GSUP port before proceeding */
127 timer T := 10.0;
128 T.start;
129 alt {
130 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
131 [] T.timeout {
132 setverdict(inconc, "No connection to GSUP Port");
133 self.stop
134 }
135 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100136}
137
Harald Weltea49e36e2018-01-21 19:29:33 +0100138function f_init() runs on MTC_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +0100139
140 if (g_initialized == true) {
141 return;
142 }
143 g_initialized := true;
144
Harald Weltea49e36e2018-01-21 19:29:33 +0100145 f_bssap_init("MSC_Test", BSC_BssmapOps);
146 f_ipa_ctrl_start(mp_msc_ip, mp_msc_ctrl_port);
147 f_init_mncc("MSC_Test");
Harald Welte4aa970c2018-01-26 10:38:09 +0100148 f_init_mgcp("MSC_Test");
Harald Weltea49e36e2018-01-21 19:29:33 +0100149 f_init_gsup("MSC_Test");
Harald Welte3ca1c902018-01-24 18:51:27 +0100150
151 map(self:MSCVTY, system:MSCVTY);
152 f_vty_set_prompts(MSCVTY);
153 f_vty_transceive(MSCVTY, "enable");
Harald Welteb14c77a2018-01-25 17:25:44 +0100154
155 /* set some defaults */
156 f_vty_config(MSCVTY, "network", "authentication optional");
157 f_vty_config(MSCVTY, "msc", "assign-tmsi");
158 f_vty_config(MSCVTY, "network", "encryption a5 0");
Harald Weltef6dd64d2017-11-19 12:09:51 +0100159}
160
161template PDU_BSSAP ts_BSSAP_BSSMAP := {
162 discriminator := '0'B,
163 spare := '0000000'B,
164 dlci := omit,
165 lengthIndicator := 0, /* overwritten by codec */
166 pdu := ?
167}
168
169template PDU_BSSAP tr_BSSAP_BSSMAP := {
170 discriminator := '0'B,
171 spare := '0000000'B,
172 dlci := omit,
173 lengthIndicator := ?,
174 pdu := {
175 bssmap := ?
176 }
177}
178
179
180type integer BssmapCause;
181
182template (value) BSSMAP_IE_Cause ts_BSSMAP_IE_Cause(BssmapCause val) := {
183 elementIdentifier := '04'O,
184 lengthIndicator := 0,
185 causeValue := int2bit(val, 7),
186 extensionCauseValue := '0'B,
187 spare1 := omit
188}
189
190template (value) PDU_BSSAP ts_BSSMAP_Reset(BssmapCause cause) modifies ts_BSSAP_BSSMAP := {
191 pdu := {
192 bssmap := {
193 reset := {
194 messageType := '30'O,
195 cause := ts_BSSMAP_IE_Cause(cause),
196 a_InterfaceSelectorForReset := omit
197 }
198 }
199 }
200}
201
202template (value) PDU_BSSAP ts_BSSMAP_ResetAck modifies ts_BSSAP_BSSMAP := {
203 pdu := {
204 bssmap := {
205 resetAck := {
206 messageType := '31'O,
207 a_InterfaceSelectorForReset := omit
208 }
209 }
210 }
211}
212
213template PDU_BSSAP tr_BSSMAP_ResetAck modifies tr_BSSAP_BSSMAP := {
214 pdu := {
215 bssmap := {
216 resetAck := {
217 messageType := '31'O,
218 a_InterfaceSelectorForReset := *
219 }
220 }
221 }
222}
223
224template BSSMAP_IE_CellIdentifier ts_BSSMAP_IE_CellID := {
225 elementIdentifier := '05'O,
226 lengthIndicator := 0,
227 cellIdentifierDiscriminator := '0000'B,
228 spare1_4 := '0000'B,
229 cellIdentification := ?
230}
231
232type uint16_t BssmapLAC;
233type uint16_t BssmapCI;
234
235/*
236template BSSMAP_IE_CellIdentifier ts_CellId_CGI(mcc, mnc, lac, ci)
237modifies ts_BSSMAP_IE_CellID := {
238 cellIdentification := {
239 cI_LAC_CGI := {
240 mnc_mcc := FIXME,
241 lac := int2oct(lac, 2),
242 ci := int2oct(ci, 2)
243 }
244 }
245}
246*/
247
248template BSSMAP_IE_CellIdentifier ts_CellID_LAC_CI(BssmapLAC lac, BssmapCI ci)
249modifies ts_BSSMAP_IE_CellID := {
250 cellIdentification := {
251 cI_LAC_CI := {
252 lac := int2oct(lac, 2),
253 ci := int2oct(ci, 2)
254 }
255 }
256}
257
258template BSSMAP_IE_CellIdentifier ts_CellId_CI(BssmapCI ci)
259modifies ts_BSSMAP_IE_CellID := {
260 cellIdentification := {
261 cI_CI := int2oct(ci, 2)
262 }
263}
264
265template BSSMAP_IE_CellIdentifier ts_CellId_none
266modifies ts_BSSMAP_IE_CellID := {
267 cellIdentification := {
268 cI_noCell := ''O
269 }
270}
271
272
273template BSSMAP_IE_Layer3Information ts_BSSMAP_IE_L3Info(octetstring l3info) := {
274 elementIdentifier := '17'O,
275 lengthIndicator := 0,
276 layer3info := l3info
277}
278
279template PDU_BSSAP ts_BSSMAP_ComplL3(BSSMAP_IE_CellIdentifier cell_id, octetstring l3_info)
280modifies ts_BSSAP_BSSMAP := {
281 pdu := {
282 bssmap := {
283 completeLayer3Information := {
284 messageType := '57'O,
285 cellIdentifier := cell_id,
286 layer3Information := ts_BSSMAP_IE_L3Info(l3_info),
287 chosenChannel := omit,
288 lSAIdentifier := omit,
289 aPDU := omit,
290 codecList := omit,
291 redirectAttemptFlag := omit,
292 sendSequenceNumber := omit,
293 iMSI := omit
294 }
295 }
296 }
297}
298
299template PDU_BSSAP ts_BSSMAP_HandoReq(BssmapCause cause, BSSMAP_IE_CellIdentifierList cid_list)
300modifies ts_BSSAP_BSSMAP := {
301 pdu := {
302 bssmap := {
303 handoverRequired := {
304 messageType := '11'O,
305 cause := ts_BSSMAP_IE_Cause(cause),
306 responseRequest := omit,
307 cellIdentifierList := cid_list,
308 circuitPoolList := omit,
309 currentChannelType1 := omit,
310 speechVersion := omit,
311 queueingIndicator := omit,
312 oldToNewBSSInfo := omit,
313 sourceToTargetRNCTransparentInfo := omit,
314 sourceToTargetRNCTransparentInfoCDMA := omit,
315 gERANClassmark := omit,
316 talkerPriority := omit,
317 speechCodec := omit,
318 cSG_Identifier := omit
319 }
320 }
321 }
322}
323
324// enc_PDU_BSSAP
325
326function f_send_BSSAP_UNITDATA(template PDU_BSSAP bssap) runs on MTC_CT {
Harald Weltea49e36e2018-01-21 19:29:33 +0100327 BSSAP.send(ts_BSSAP_UNITDATA_req(g_sccp_addr_peer, g_sccp_addr_own, bssap))
Harald Weltef6dd64d2017-11-19 12:09:51 +0100328}
329
Harald Weltea49e36e2018-01-21 19:29:33 +0100330type function void_fn(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100331
Harald Welte81b7f9d2018-01-24 19:06:24 +0100332private function f_concat_pad(integer tot_len, hexstring prefix, integer suffix) return hexstring {
333 var integer suffix_len := tot_len - lengthof(prefix);
334 var charstring suffix_ch := int2str(suffix);
335 var integer pad_len := suffix_len - lengthof(suffix_ch);
336
337 return prefix & int2hex(0, pad_len) & str2hex(suffix_ch);
Harald Welte256571e2018-01-24 18:47:19 +0100338}
339
Harald Welte81b7f9d2018-01-24 19:06:24 +0100340function f_gen_imei(integer suffix) return hexstring {
341 return f_concat_pad(15, '49999'H, suffix);
Harald Weltea49e36e2018-01-21 19:29:33 +0100342}
343
Harald Welte81b7f9d2018-01-24 19:06:24 +0100344function f_gen_imsi(integer suffix) return hexstring {
345 return f_concat_pad(15, '26242'H, suffix);
346}
347
348function f_gen_msisdn(integer suffix) return hexstring {
349 return f_concat_pad(12, '49123'H, suffix);
Harald Weltea49e36e2018-01-21 19:29:33 +0100350}
351
352/* FIXME: move into BSC_ConnectionHandler? */
353function f_start_handler(void_fn fn, charstring id, integer imsi_suffix) runs on MTC_CT return BSC_ConnHdlr {
354 var BSC_ConnHdlr vc_conn;
355 var BSC_ConnHdlrPars pars := {
356 sccp_addr_own := g_sccp_addr_own,
357 sccp_addr_peer := g_sccp_addr_peer,
358 cell_id := valueof(ts_CellId_CGI('262'H, '042'H, 23, 42)),
Harald Welte81b7f9d2018-01-24 19:06:24 +0100359 imei := f_gen_imei(imsi_suffix),
360 imsi := f_gen_imsi(imsi_suffix),
361 msisdn := f_gen_msisdn(imsi_suffix),
Harald Welte256571e2018-01-24 18:47:19 +0100362 tmsi := omit,
Harald Welte82600572018-01-21 20:54:08 +0100363 cm2 := valueof(ts_CM2_default),
Harald Welte16114282018-01-24 22:41:21 +0100364 cm3 := omit,
Harald Welte148a7082018-01-26 18:56:43 +0100365 vec := omit
Harald Weltea49e36e2018-01-21 19:29:33 +0100366 };
367
368 vc_conn := BSC_ConnHdlr.create(id);
369 /* BSSMAP part / A interface */
370 connect(vc_conn:BSSAP, vc_BSSMAP:CLIENT);
371 connect(vc_conn:BSSAP_PROC, vc_BSSMAP:PROC);
372 /* MNCC part */
373 connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
374 connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);
Harald Welte4aa970c2018-01-26 10:38:09 +0100375 /* MGCP part */
376 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
377 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100378 /* GSUP part */
379 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
380 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
381
Harald Weltea10db902018-01-27 12:44:49 +0100382 /* We cannot use vc_conn.start(f_init_handler(fn, id, pars)); as we cannot have
383 * a stand-alone 'derefers()' call, see https://www.eclipse.org/forums/index.php/t/1091364/ */
Harald Weltea49e36e2018-01-21 19:29:33 +0100384 vc_conn.start(derefers(fn)(id, pars));
385 return vc_conn;
386}
387
Harald Welte3ca1c902018-01-24 18:51:27 +0100388function f_vty_config(TELNETasp_PT pt, charstring config_node, charstring cmd)
389{
390 /* enter config mode; enter node */
391 f_vty_enter_config(pt);
392 f_vty_transceive(pt, config_node);
393 /* execute command */
394 f_vty_transceive(pt, cmd);
395 /* leave config mode */
396 f_vty_transceive(pt, "end");
397}
398
Harald Weltea49e36e2018-01-21 19:29:33 +0100399private function f_tc_lu_imsi_noauth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100400 f_init_handler(pars);
Harald Welte8a121b32018-01-22 03:00:41 +0100401 f_perform_lu(false, true, true);
Harald Weltea49e36e2018-01-21 19:29:33 +0100402}
Harald Weltea49e36e2018-01-21 19:29:33 +0100403testcase TC_lu_imsi_noauth_tmsi() runs on MTC_CT {
404 var BSC_ConnHdlr vc_conn;
405 f_init();
406
407 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi), testcasename(), 1);
408 vc_conn.done;
409}
410
411private function f_tc_lu_imsi_noauth_notmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100412 f_init_handler(pars);
Harald Welte8a121b32018-01-22 03:00:41 +0100413 f_perform_lu(false, false, true);
Harald Weltea49e36e2018-01-21 19:29:33 +0100414}
Harald Weltea49e36e2018-01-21 19:29:33 +0100415testcase TC_lu_imsi_noauth_notmsi() runs on MTC_CT {
416 var BSC_ConnHdlr vc_conn;
417 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100418 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
Harald Weltea49e36e2018-01-21 19:29:33 +0100419
420 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi), testcasename(), 2);
421 vc_conn.done;
422}
423
424/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
425private function f_tc_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100426 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100427 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
428
429 f_create_gsup_expect(hex2str(g_pars.imsi));
430 f_bssap_compl_l3(l3_lu);
431 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
432 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
433 alt {
434 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej(int2oct(23,1)))) { }
435 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
436 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
437 self.stop;
438 }
439 }
Harald Welte1ddc7162018-01-27 14:25:46 +0100440 f_expect_clear();
Harald Weltea49e36e2018-01-21 19:29:33 +0100441}
442testcase TC_lu_imsi_reject() runs on MTC_CT {
443 var BSC_ConnHdlr vc_conn;
444 f_init();
445
446 vc_conn := f_start_handler(refers(f_tc_lu_imsi_reject), testcasename(), 3);
447 vc_conn.done;
448}
449
450/* Do LU by IMSI, timeout on GSUP */
451private function f_tc_lu_imsi_timeout_gsup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100452 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100453 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
454
455 f_create_gsup_expect(hex2str(g_pars.imsi));
456 f_bssap_compl_l3(l3_lu);
457 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
458 /* Normally the HLR would need to respond here, but we decide to force a timeout here */
459 alt {
460 /* FIXME: Expect specific reject cause */
461 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
462 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
463 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
464 self.stop;
465 }
466 }
Harald Welte1ddc7162018-01-27 14:25:46 +0100467 f_expect_clear();
Harald Weltea49e36e2018-01-21 19:29:33 +0100468}
469testcase TC_lu_imsi_timeout_gsup() runs on MTC_CT {
470 var BSC_ConnHdlr vc_conn;
471 f_init();
472
473 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_gsup), testcasename(), 4);
474 vc_conn.done;
475}
476
Harald Welte7b1b2812018-01-22 21:23:06 +0100477private function f_tc_lu_imsi_auth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100478 f_init_handler(pars);
Harald Welte7b1b2812018-01-22 21:23:06 +0100479 f_perform_lu(true, true, true);
480}
481testcase TC_lu_imsi_auth_tmsi() runs on MTC_CT {
482 var BSC_ConnHdlr vc_conn;
483 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100484 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte7b1b2812018-01-22 21:23:06 +0100485
486 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi), testcasename(), 5);
487 vc_conn.done;
488}
489
Harald Weltea49e36e2018-01-21 19:29:33 +0100490
491/* Send CM SERVICE REQ for IMSI that has never performed LU before */
492private function f_tc_cmserv_imsi_unknown(charstring id, BSC_ConnHdlrPars pars)
493runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100494 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100495
496 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
497 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '042'H, 23, 42));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100498 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltea49e36e2018-01-21 19:29:33 +0100499
500 f_create_gsup_expect(hex2str(g_pars.imsi));
501
502 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
503 f_bssap_compl_l3(l3_info);
504
505 timer T := 10.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100506 T.start;
507 alt {
Harald Weltea49e36e2018-01-21 19:29:33 +0100508 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
509 //[] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC)) { }
510 [] BSSAP.receive { setverdict(fail, "Received unexpected BSSAP"); }
511 [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
512 setverdict(fail, "Unexpected GSUP UL REQ");
513 }
514 [] T.timeout { setverdict(inconc, "Timeout waiting for CM SERV REQ"); }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100515 }
516
Harald Welte1ddc7162018-01-27 14:25:46 +0100517 f_expect_clear();
Harald Weltef6dd64d2017-11-19 12:09:51 +0100518}
Harald Weltea49e36e2018-01-21 19:29:33 +0100519testcase TC_cmserv_imsi_unknown() runs on MTC_CT {
520 var BSC_ConnHdlr vc_conn;
521 f_init();
Harald Welte81b7f9d2018-01-24 19:06:24 +0100522 vc_conn := f_start_handler(refers(f_tc_cmserv_imsi_unknown), testcasename(), 6);
Harald Weltea49e36e2018-01-21 19:29:33 +0100523 vc_conn.done;
524}
525
Harald Welte2bb825f2018-01-22 11:31:18 +0100526private function f_tc_lu_and_mo_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100527 f_init_handler(pars);
Harald Welteb71901a2018-01-26 19:16:05 +0100528 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
529 cpars.bss_rtp_port := 1110;
530 cpars.mgcp_connection_id_bss := '22222'H;
531 cpars.mgcp_connection_id_mss := '33333'H;
Harald Welte2bb825f2018-01-22 11:31:18 +0100532
Harald Welteb71901a2018-01-26 19:16:05 +0100533 f_perform_lu(cpars.expect_auth, true, true);
534 f_mo_call(cpars);
Harald Welte2bb825f2018-01-22 11:31:18 +0100535}
536testcase TC_lu_and_mo_call() runs on MTC_CT {
537 var BSC_ConnHdlr vc_conn;
538 f_init();
539
Harald Welte81b7f9d2018-01-24 19:06:24 +0100540 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_call), testcasename(), 7);
Harald Welte071ed732018-01-23 19:53:52 +0100541 vc_conn.done;
542}
543
544/* Test LU (with authentication enabled), where HLR times out sending SAI response */
545private function f_tc_lu_auth_sai_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100546 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100547
548 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
549 var PDU_DTAP_MT dtap_mt;
550
551 /* tell GSUP dispatcher to send this IMSI to us */
552 f_create_gsup_expect(hex2str(g_pars.imsi));
553
554 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
555 f_bssap_compl_l3(l3_lu);
556
557 /* Send Early Classmark, just for the fun of it */
558 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
559
560 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
561 /* The HLR would normally return an auth vector here, but we fail to do so. */
562
563 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100564 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100565}
566testcase TC_lu_auth_sai_timeout() runs on MTC_CT {
567 var BSC_ConnHdlr vc_conn;
568 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100569 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100570
Harald Welte81b7f9d2018-01-24 19:06:24 +0100571 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_timeout), testcasename(), 8);
Harald Welte071ed732018-01-23 19:53:52 +0100572 vc_conn.done;
573}
574
575/* Test LU (with authentication enabled), where HLR rejects sending SAI error */
576private function f_tc_lu_auth_sai_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100577 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100578
579 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
580 var PDU_DTAP_MT dtap_mt;
581
582 /* tell GSUP dispatcher to send this IMSI to us */
583 f_create_gsup_expect(hex2str(g_pars.imsi));
584
585 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
586 f_bssap_compl_l3(l3_lu);
587
588 /* Send Early Classmark, just for the fun of it */
589 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
590
591 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
592 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 13));
593
594 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100595 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100596}
597testcase TC_lu_auth_sai_err() runs on MTC_CT {
598 var BSC_ConnHdlr vc_conn;
599 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100600 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100601
Harald Welte81b7f9d2018-01-24 19:06:24 +0100602 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_err), testcasename(), 9);
Harald Welte2bb825f2018-01-22 11:31:18 +0100603 vc_conn.done;
604}
Harald Weltea49e36e2018-01-21 19:29:33 +0100605
Harald Weltebc881782018-01-23 20:09:15 +0100606/* Test LU but BSC will send a clear request in the middle */
607private function f_tc_lu_clear_request(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100608 f_init_handler(pars);
Harald Weltebc881782018-01-23 20:09:15 +0100609
610 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
611 var PDU_DTAP_MT dtap_mt;
612
613 /* tell GSUP dispatcher to send this IMSI to us */
614 f_create_gsup_expect(hex2str(g_pars.imsi));
615
616 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
617 f_bssap_compl_l3(l3_lu);
618
619 /* Send Early Classmark, just for the fun of it */
620 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
621
622 f_sleep(1.0);
623 /* send clear request in the middle of the LU */
624 BSSAP.send(ts_BSSMAP_ClearRequest(0));
625 BSSAP.receive(tr_BSSMAP_ClearCommand);
626 BSSAP.send(ts_BSSMAP_ClearComplete);
Harald Welte89a32492018-01-27 19:07:28 +0100627 alt {
628 /* See https://osmocom.org/issues/2862 */
629 [] BSSAP.receive(tr_BSSMAP_ClearCommand) { repeat; }
630 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
631 }
Harald Weltebc881782018-01-23 20:09:15 +0100632 setverdict(pass);
633}
634testcase TC_lu_clear_request() runs on MTC_CT {
635 var BSC_ConnHdlr vc_conn;
636 f_init();
637
Harald Welte81b7f9d2018-01-24 19:06:24 +0100638 vc_conn := f_start_handler(refers(f_tc_lu_clear_request), testcasename(), 10);
Harald Weltebc881782018-01-23 20:09:15 +0100639 vc_conn.done;
640}
641
Harald Welte66af9e62018-01-24 17:28:21 +0100642/* Test LU but BSC will send a clear request in the middle */
643private function f_tc_lu_disconnect(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100644 f_init_handler(pars);
Harald Welte66af9e62018-01-24 17:28:21 +0100645
646 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
647 var PDU_DTAP_MT dtap_mt;
648
649 /* tell GSUP dispatcher to send this IMSI to us */
650 f_create_gsup_expect(hex2str(g_pars.imsi));
651
652 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
653 f_bssap_compl_l3(l3_lu);
654
655 /* Send Early Classmark, just for the fun of it */
656 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
657
658 f_sleep(1.0);
659 /* send clear request in the middle of the LU */
660 BSSAP.send(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
661 setverdict(pass);
662}
663testcase TC_lu_disconnect() runs on MTC_CT {
664 var BSC_ConnHdlr vc_conn;
665 f_init();
666
Harald Welte81b7f9d2018-01-24 19:06:24 +0100667 vc_conn := f_start_handler(refers(f_tc_lu_disconnect), testcasename(), 11);
Harald Welte66af9e62018-01-24 17:28:21 +0100668 vc_conn.done;
669}
670
671
Harald Welteba7b6d92018-01-23 21:32:34 +0100672/* Test LU but with illegal mobile identity type = IMEI */
673private function f_tc_lu_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100674 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100675
Harald Welte256571e2018-01-24 18:47:19 +0100676 var PDU_ML3_MS_NW l3_lu := f_build_lu_imei(g_pars.imei)
Harald Welteba7b6d92018-01-23 21:32:34 +0100677 var PDU_DTAP_MT dtap_mt;
678
679 /* tell GSUP dispatcher to send this IMSI to us */
680 f_create_gsup_expect(hex2str(g_pars.imsi));
681
682 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
683 f_bssap_compl_l3(l3_lu);
684
685 /* Send Early Classmark, just for the fun of it */
686 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
687 /* wait for LU reject, ignore any ID REQ */
688 alt {
689 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
690 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req)) { repeat; }
691 }
692 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100693 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100694}
695testcase TC_lu_by_imei() runs on MTC_CT {
696 var BSC_ConnHdlr vc_conn;
697 f_init();
698
Harald Welte81b7f9d2018-01-24 19:06:24 +0100699 vc_conn := f_start_handler(refers(f_tc_lu_by_imei), testcasename(), 12);
Harald Welteba7b6d92018-01-23 21:32:34 +0100700 vc_conn.done;
701}
702
703/* Test LU by TMSI with unknown TMSI, expect (and answer) ID REQ. */
704private function f_tc_lu_tmsi_noauth_unknown(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100705 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100706
707 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('01020304'O); /* FIXME: Random */
708 var PDU_DTAP_MT dtap_mt;
709
710 /* tell GSUP dispatcher to send this IMSI to us */
711 f_create_gsup_expect(hex2str(g_pars.imsi));
712
713 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
714 f_bssap_compl_l3(l3_lu);
715
716 /* Send Early Classmark, just for the fun of it */
717 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
718
719 /* Wait for + respond to ID REQ (IMSI) */
720 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req('001'B)));
721 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
722
723 /* Expect MSC to do UpdateLocation to HLR; respond to it */
724 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
725 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
726 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
727 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
728
729 alt {
Harald Welte7ec4fa82018-01-27 10:57:40 +0100730 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
731 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
732 }
Harald Welteba7b6d92018-01-23 21:32:34 +0100733 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
734 setverdict(fail, "Expected LU ACK, but received REJ");
735 }
736 }
737
738 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100739 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100740}
741testcase TC_lu_by_tmsi_noauth_unknown() runs on MTC_CT {
742 var BSC_ConnHdlr vc_conn;
743 f_init();
744
Harald Welte81b7f9d2018-01-24 19:06:24 +0100745 vc_conn := f_start_handler(refers(f_tc_lu_tmsi_noauth_unknown), testcasename(), 13);
Harald Welteba7b6d92018-01-23 21:32:34 +0100746 vc_conn.done;
747}
748
749
Harald Welte45164da2018-01-24 12:51:27 +0100750/* Test IMSI DETACH (MI=IMSI) */
751private function f_tc_imsi_detach_by_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100752 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100753
754 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
755
756 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
757 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
758
759 /* Send Early Classmark, just for the fun of it? */
760 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
761
762 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100763 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100764}
765testcase TC_imsi_detach_by_imsi() runs on MTC_CT {
766 var BSC_ConnHdlr vc_conn;
767 f_init();
768
Harald Welte81b7f9d2018-01-24 19:06:24 +0100769 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imsi), testcasename(), 14);
Harald Welte45164da2018-01-24 12:51:27 +0100770 vc_conn.done;
771}
772
773/* Test IMSI DETACH (MI=TMSI) */
774private function f_tc_imsi_detach_by_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100775 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100776
777 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('01020304'O));
778
779 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
780 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
781
782 /* Send Early Classmark, just for the fun of it? */
783 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
784
785 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100786 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100787}
788testcase TC_imsi_detach_by_tmsi() runs on MTC_CT {
789 var BSC_ConnHdlr vc_conn;
790 f_init();
791
Harald Welte81b7f9d2018-01-24 19:06:24 +0100792 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_tmsi), testcasename(), 15);
Harald Welte45164da2018-01-24 12:51:27 +0100793 vc_conn.done;
794}
795
796/* Test IMSI DETACH (MI=IMEI), which is illegal */
797private function f_tc_imsi_detach_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100798 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100799
Harald Welte256571e2018-01-24 18:47:19 +0100800 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte45164da2018-01-24 12:51:27 +0100801
802 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
803 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
804
805 /* Send Early Classmark, just for the fun of it? */
806 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
807
808 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100809 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100810}
811testcase TC_imsi_detach_by_imei() runs on MTC_CT {
812 var BSC_ConnHdlr vc_conn;
813 f_init();
814
Harald Welte81b7f9d2018-01-24 19:06:24 +0100815 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imei), testcasename(), 16);
Harald Welte45164da2018-01-24 12:51:27 +0100816 vc_conn.done;
817}
818
819
820/* helper function for an emergency call. caller passes in mobile identity to use */
821private function f_emerg_call(MobileIdentityLV mi) runs on BSC_ConnHdlr {
822
Harald Welte6ed6bf92018-01-24 21:09:15 +0100823 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100824 f_bssap_compl_l3(l3_info);
825 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC));
826
827 var hexstring called := '112'H;
828 var integer tid := 0;
829 var MNCC_PDU mncc;
830 f_create_mncc_expect(hex2str(called));
831
832 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_EMERG_SETUP(tid)));
833 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(called)))) -> value mncc;
834 /* FIXME: extract call_id */
835
836 /* Call Proceeding */
837 MNCC.send(ts_MNCC_CALL_PROC_req(mncc.u.signal.callref, ts_MNCC_bcap_voice));
838 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(tid)));
839
840 /* Alerting */
841 MNCC.send(ts_MNCC_ALERT_req(mncc.u.signal.callref));
842 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(tid)));
843
844 /* Answer. This causes TCH assignment in case of "late assignment" */
Harald Welte4017d552018-01-26 21:40:05 +0100845 //MNCC.send(ts_MNCC_SETUP_COMPL_req(mncc.u.signal.callref));
846 MNCC.send(ts_MNCC_SETUP_rsp(mncc.u.signal.callref));
Harald Welte45164da2018-01-24 12:51:27 +0100847
848 f_sleep(3.0);
849
850 /* Hangup by "B" side */
851 MNCC.send(ts_MNCC_DISC_req(mncc.u.signal.callref, valueof(ts_MNCC_cause(23))));
852 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(tid)));
853
854 /* Release of call */
855 MNCC.send(ts_MNCC_REL_req(mncc.u.signal.callref, valueof(ts_MNCC_cause(42))));
856 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(tid)));
857
858 /* clearing of radio channel */
Harald Welte1ddc7162018-01-27 14:25:46 +0100859 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100860}
861
862/* establish an emergency call by IMEI, no SIM inserted (and hence no IMSI) */
863private function f_tc_emerg_call_imei_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100864 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100865
Harald Welte256571e2018-01-24 18:47:19 +0100866 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100867 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100868 f_bssap_compl_l3(l3_info);
869 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ('05'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +0100870 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100871}
872testcase TC_emerg_call_imei_reject() runs on MTC_CT {
873 var BSC_ConnHdlr vc_conn;
874 f_init();
875
Harald Welte81b7f9d2018-01-24 19:06:24 +0100876 vc_conn := f_start_handler(refers(f_tc_emerg_call_imei_reject), testcasename(), 17);
Harald Welte45164da2018-01-24 12:51:27 +0100877 vc_conn.done;
878}
879
Harald Welted5b91402018-01-24 18:48:16 +0100880/* establish an emergency call by IMSI, SIM inserted (and hence IMSI) */
Harald Welte45164da2018-01-24 12:51:27 +0100881private function f_tc_emerg_call_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100882 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100883 /* First perform location update to ensure subscriber is known */
884 f_perform_lu(false, true, true);
885 /* Then issue emergency call identified by IMSI */
886 f_emerg_call(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
887}
888testcase TC_emerg_call_imsi() runs on MTC_CT {
889 var BSC_ConnHdlr vc_conn;
890 f_init();
891
Harald Welte81b7f9d2018-01-24 19:06:24 +0100892 vc_conn := f_start_handler(refers(f_tc_emerg_call_imsi), testcasename(), 18);
Harald Welte45164da2018-01-24 12:51:27 +0100893 vc_conn.done;
894}
895
896/* CM Service Request for VGCS -> reject */
897private function f_tc_cm_serv_req_vgcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100898 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100899
900 /* First perform location update to ensure subscriber is known */
901 f_perform_lu(false, true, true);
902
903 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100904 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VGCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100905 f_bssap_compl_l3(l3_info);
906 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100907 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100908}
909testcase TC_cm_serv_req_vgcs_reject() runs on MTC_CT {
910 var BSC_ConnHdlr vc_conn;
911 f_init();
912
Harald Welte81b7f9d2018-01-24 19:06:24 +0100913 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vgcs_reject), testcasename(), 19);
Harald Welte45164da2018-01-24 12:51:27 +0100914 vc_conn.done;
915}
916
917/* CM Service Request for VBS -> reject */
918private function f_tc_cm_serv_req_vbs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100919 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100920
921 /* First perform location update to ensure subscriber is known */
922 f_perform_lu(false, true, true);
923
924 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100925 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VBS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100926 f_bssap_compl_l3(l3_info);
927 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100928 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100929}
930testcase TC_cm_serv_req_vbs_reject() runs on MTC_CT {
931 var BSC_ConnHdlr vc_conn;
932 f_init();
933
Harald Welte81b7f9d2018-01-24 19:06:24 +0100934 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vbs_reject), testcasename(), 20);
Harald Welte45164da2018-01-24 12:51:27 +0100935 vc_conn.done;
936}
937
938/* CM Service Request for LCS -> reject */
939private function f_tc_cm_serv_req_lcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100940 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100941
942 /* First perform location update to ensure subscriber is known */
943 f_perform_lu(false, true, true);
944
945 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100946 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_LCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100947 f_bssap_compl_l3(l3_info);
948 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100949 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100950}
951testcase TC_cm_serv_req_lcs_reject() runs on MTC_CT {
952 var BSC_ConnHdlr vc_conn;
953 f_init();
954
Harald Welte81b7f9d2018-01-24 19:06:24 +0100955 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_lcs_reject), testcasename(), 21);
Harald Welte45164da2018-01-24 12:51:27 +0100956 vc_conn.done;
957}
958
Harald Welte0195ab12018-01-24 21:50:20 +0100959/* CM Re-Establishment Request */
960private function f_tc_cm_reest_req_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100961 f_init_handler(pars);
Harald Welte0195ab12018-01-24 21:50:20 +0100962
963 /* First perform location update to ensure subscriber is known */
964 f_perform_lu(false, true, true);
965
966 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
967 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REEST_REQ(0, mi));
968 f_bssap_compl_l3(l3_info);
969 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100970 f_expect_clear();
Harald Welte0195ab12018-01-24 21:50:20 +0100971}
972testcase TC_cm_reest_req_reject() runs on MTC_CT {
973 var BSC_ConnHdlr vc_conn;
974 f_init();
Harald Welte0195ab12018-01-24 21:50:20 +0100975
976 vc_conn := f_start_handler(refers(f_tc_cm_reest_req_reject), testcasename(), 22);
977 vc_conn.done;
978}
979
Harald Weltec638f4d2018-01-24 22:00:36 +0100980/* Test LU (with authentication enabled), with wrong response from MS */
981private function f_tc_lu_auth_2G_fail(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100982 f_init_handler(pars);
Harald Weltec638f4d2018-01-24 22:00:36 +0100983
984 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
985
986 /* tell GSUP dispatcher to send this IMSI to us */
987 f_create_gsup_expect(hex2str(g_pars.imsi));
988
989 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
990 f_bssap_compl_l3(l3_lu);
991
992 /* Send Early Classmark, just for the fun of it */
993 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
994
995 var AuthVector vec := f_gen_auth_vec_2g();
996 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(vec.rand, vec.sres, vec.kc));
997 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
998 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
999
1000 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(vec.rand)));
1001 /* Send back wrong auth response */
1002 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G('00000000'O)));
1003
1004 /* Expect GSUP AUTH FAIL REP to HLR */
1005 GSUP.receive(tr_GSUP_AUTH_FAIL_IND(g_pars.imsi));
1006
1007 /* Expect LU REJECT with Cause == Illegal MS */
1008 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej('03'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +01001009 f_expect_clear();
Harald Weltec638f4d2018-01-24 22:00:36 +01001010}
1011testcase TC_lu_auth_2G_fail() runs on MTC_CT {
1012 var BSC_ConnHdlr vc_conn;
1013 f_init();
1014 f_vty_config(MSCVTY, "network", "authentication required");
Harald Weltec638f4d2018-01-24 22:00:36 +01001015
1016 vc_conn := f_start_handler(refers(f_tc_lu_auth_2G_fail), testcasename(), 23);
1017 vc_conn.done;
1018}
1019
Harald Welte16114282018-01-24 22:41:21 +01001020private function f_tc_lu_imsi_auth_tmsi_encr_13_13(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001021 f_init_handler(pars);
Harald Welte16114282018-01-24 22:41:21 +01001022 f_perform_lu(true, true, true, true);
1023}
1024testcase TC_lu_imsi_auth_tmsi_encr_13_13() runs on MTC_CT {
1025 var BSC_ConnHdlr vc_conn;
1026 f_init();
1027 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte16114282018-01-24 22:41:21 +01001028 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1029
1030 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_13), testcasename(), 24);
1031 vc_conn.done;
1032}
1033
Harald Welte1af6ea82018-01-25 18:33:15 +01001034/* Test Complete L3 without payload */
1035private function f_tc_cl3_no_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001036 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001037
1038 /* Send Complete L3 Info with empty L3 frame */
1039 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1040 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, ''O))));
1041
Harald Weltef466eb42018-01-27 14:26:54 +01001042 timer T := 5.0;
1043 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001044 alt {
1045 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
1046 /* Expect LU REJECT with Cause == Illegal MS */
1047 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1048 BSSAP.send(ts_BSSMAP_ClearComplete);
1049 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1050 }
Harald Weltef466eb42018-01-27 14:26:54 +01001051 [] T.timeout {
1052 setverdict(inconc, "Timeout waiting for ClearCommand or SCCP Release");
1053 self.stop;
1054 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001055 }
1056 setverdict(pass);
1057}
1058testcase TC_cl3_no_payload() runs on MTC_CT {
1059 var BSC_ConnHdlr vc_conn;
1060 f_init();
1061
1062 vc_conn := f_start_handler(refers(f_tc_cl3_no_payload), testcasename(), 24);
1063 vc_conn.done;
1064}
1065
1066/* Test Complete L3 with random payload */
1067private function f_tc_cl3_rnd_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001068 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001069
1070 var integer len := float2int(rnd() * 256.0);
1071 var octetstring payl := f_rnd_octstring(len);
1072
1073 /* Send Complete L3 Info with empty L3 frame */
1074 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1075 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, payl))));
1076
Harald Weltef466eb42018-01-27 14:26:54 +01001077 timer T := 5.0;
1078 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001079 alt {
1080 /* Immediate disconnect */
1081 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
1082 /* Expect LU REJECT with Cause == Illegal MS */
1083 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1084 BSSAP.send(ts_BSSMAP_ClearComplete);
1085 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1086 }
1087 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
Harald Weltef466eb42018-01-27 14:26:54 +01001088 [] T.timeout {
1089 setverdict(inconc, "Timeout waiting for ClearCommand or SCCP Release");
1090 self.stop;
1091 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001092 }
1093 setverdict(pass);
1094}
1095testcase TC_cl3_rnd_payload() runs on MTC_CT {
1096 var BSC_ConnHdlr vc_conn;
1097 f_init();
1098
1099 vc_conn := f_start_handler(refers(f_tc_cl3_rnd_payload), testcasename(), 24);
1100 vc_conn.done;
1101}
1102
Harald Welte116e4332018-01-26 22:17:48 +01001103/* Test Complete L3 with random payload */
1104private function f_tc_establish_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001105 f_init_handler(pars);
Harald Welte116e4332018-01-26 22:17:48 +01001106
1107 f_perform_lu(false, true, true, false);
1108
1109 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)), false, false);
Harald Welte1ddc7162018-01-27 14:25:46 +01001110 f_expect_clear();
Harald Welte116e4332018-01-26 22:17:48 +01001111}
1112testcase TC_establish_and_nothing() runs on MTC_CT {
1113 var BSC_ConnHdlr vc_conn;
1114 f_init();
1115
1116 vc_conn := f_start_handler(refers(f_tc_establish_and_nothing), testcasename(), 25);
1117 vc_conn.done;
1118}
1119
Harald Welte12510c52018-01-26 22:26:24 +01001120/* Test MO Call SETUP with no response from MNCC */
1121private function f_tc_mo_setup_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001122 f_init_handler(pars);
1123
Harald Welte12510c52018-01-26 22:26:24 +01001124 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1125
1126 f_perform_lu(false, true, true, false);
1127
1128 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)), false, false);
1129 f_create_mncc_expect(hex2str(cpars.called_party));
1130 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1131
1132 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1133
Harald Welte1ddc7162018-01-27 14:25:46 +01001134 f_expect_clear(30.0);
Harald Welte12510c52018-01-26 22:26:24 +01001135}
1136testcase TC_mo_setup_and_nothing() runs on MTC_CT {
1137 var BSC_ConnHdlr vc_conn;
1138 f_init();
1139
1140 vc_conn := f_start_handler(refers(f_tc_mo_setup_and_nothing), testcasename(), 26);
1141 vc_conn.done;
1142}
1143
Harald Welte3ab88002018-01-26 22:37:25 +01001144/* Test MO Call with no response to RAN-side CRCX */
1145private function f_tc_mo_crcx_ran_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001146 f_init_handler(pars);
Harald Welte3ab88002018-01-26 22:37:25 +01001147 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1148 var MNCC_PDU mncc;
1149 var MgcpCommand mgcp_cmd;
1150
1151 f_perform_lu(false, true, true, false);
1152
1153 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)), false, false);
1154 f_create_mncc_expect(hex2str(cpars.called_party));
1155 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1156
1157 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1158 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1159 cpars.mncc_callref := mncc.u.signal.callref;
1160 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1161 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1162
1163 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
Harald Welte1852a842018-01-26 22:53:36 +01001164 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1165 cpars.mgcp_ep := mgcp_cmd.line.ep;
Harald Welte3ab88002018-01-26 22:37:25 +01001166 /* never respond to this */
1167
Harald Welte1ddc7162018-01-27 14:25:46 +01001168 f_expect_clear(30.0);
Harald Welte3ab88002018-01-26 22:37:25 +01001169}
1170testcase TC_mo_crcx_ran_timeout() runs on MTC_CT {
1171 var BSC_ConnHdlr vc_conn;
1172 f_init();
1173
1174 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_timeout), testcasename(), 27);
1175 vc_conn.done;
1176}
1177
Harald Welte0cc82d92018-01-26 22:52:34 +01001178/* Test MO Call with reject to RAN-side CRCX */
1179private function f_tc_mo_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001180 f_init_handler(pars);
Harald Welte0cc82d92018-01-26 22:52:34 +01001181 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1182 var MNCC_PDU mncc;
1183 var MgcpCommand mgcp_cmd;
1184
1185 f_perform_lu(false, true, true, false);
1186
1187 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)), false, false);
1188 f_create_mncc_expect(hex2str(cpars.called_party));
1189 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1190
1191 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1192 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1193 cpars.mncc_callref := mncc.u.signal.callref;
1194 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1195 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1196
1197 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1198 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1199 cpars.mgcp_ep := mgcp_cmd.line.ep;
1200 /* Respond to CRCX with error */
1201 var MgcpResponse mgcp_rsp := {
1202 line := {
1203 code := "542",
1204 trans_id := mgcp_cmd.line.trans_id,
1205 string := "FORCED_FAIL"
1206 },
1207 params := omit,
1208 sdp := omit
1209 }
1210 MGCP.send(mgcp_rsp);
1211
1212 timer T := 30.0;
1213 T.start;
1214 alt {
1215 [] T.timeout { setverdict(fail, "Timeout waiting for channel release"); self.stop; }
1216 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1217 BSSAP.send(ts_BSSMAP_ClearComplete);
1218 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1219 setverdict(pass);
1220 }
1221 [] BSSAP.receive { repeat; }
1222 [] MNCC.receive { repeat; }
1223 [] GSUP.receive { repeat; }
1224 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1225 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1226 f_create_mgcp_delete_ep(cpars.mgcp_ep);
Harald Welteec6e5b42018-01-27 12:45:15 +01001227 repeat;
Harald Welte0cc82d92018-01-26 22:52:34 +01001228 }
1229 [] MGCP.receive { repeat; }
1230 }
1231}
1232testcase TC_mo_crcx_ran_reject() runs on MTC_CT {
1233 var BSC_ConnHdlr vc_conn;
1234 f_init();
1235
1236 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_reject), testcasename(), 28);
1237 vc_conn.done;
1238}
1239
Harald Welte3ab88002018-01-26 22:37:25 +01001240
Harald Welte812f7a42018-01-27 00:49:18 +01001241/* helper function to start a MT call: MNCC SETUP; Paging; DChan est.; DTAP SETUP */
1242private function f_mt_call_start(inout CallParameters cpars) runs on BSC_ConnHdlr {
1243 var MNCC_PDU mncc;
1244 var MgcpCommand mgcp_cmd;
1245 var OCT4 tmsi;
1246
1247 f_perform_lu(false, true, true, false);
1248 if (isvalue(g_pars.tmsi)) {
1249 tmsi := g_pars.tmsi;
1250 } else {
1251 tmsi := 'FFFFFFFF'O;
1252 }
1253 f_bssmap_register_imsi(g_pars.imsi, tmsi);
1254
1255 /* Allocate call reference and send SETUP via MNCC to MSC */
1256 cpars.mncc_callref := f_rnd_int(2147483648);
1257 MNCC.send(ts_MNCC_SETUP_req(cpars.mncc_callref, hex2str(g_pars.msisdn),
1258 hex2str(cpars.called_party), hex2str(g_pars.imsi)));
1259
1260 /* MSC->BSC: expect PAGING from MSC */
1261 BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));
1262 /* MS -> MSC: PAGING RESPONSE */
1263 f_establish_fully_pag(valueof(ts_MI_IMSI_LV(g_pars.imsi)), false, false);
1264
1265 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1266
1267 /* MSC->MS: SETUP */
1268 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party)));
1269}
1270
1271/* Test MT Call */
1272private function f_tc_mt_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001273 f_init_handler(pars);
Harald Welte812f7a42018-01-27 00:49:18 +01001274 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1275 var MNCC_PDU mncc;
1276 var MgcpCommand mgcp_cmd;
1277
1278 f_mt_call_start(cpars);
1279
1280 /* MS->MSC: CALL CONFIRMED */
1281 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1282
1283 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1284
1285 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1286 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1287 cpars.mgcp_ep := mgcp_cmd.line.ep;
1288 /* Respond to CRCX with error */
1289 var MgcpResponse mgcp_rsp := {
1290 line := {
1291 code := "542",
1292 trans_id := mgcp_cmd.line.trans_id,
1293 string := "FORCED_FAIL"
1294 },
1295 params := omit,
1296 sdp := omit
1297 }
1298 MGCP.send(mgcp_rsp);
1299
1300 timer T := 30.0;
1301 T.start;
1302 alt {
1303 [] T.timeout { setverdict(fail, "Timeout waiting for channel release"); self.stop; }
1304 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1305 BSSAP.send(ts_BSSMAP_ClearComplete);
1306 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1307 setverdict(pass);
1308 }
1309 [] BSSAP.receive { repeat; }
1310 [] MNCC.receive { repeat; }
1311 [] GSUP.receive { repeat; }
1312 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1313 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1314 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1315 repeat;
1316 }
1317 [] MGCP.receive { repeat; }
1318 }
1319}
1320testcase TC_mt_crcx_ran_reject() runs on MTC_CT {
1321 var BSC_ConnHdlr vc_conn;
1322 f_init();
1323
1324 vc_conn := f_start_handler(refers(f_tc_mt_crcx_ran_reject), testcasename(), 29);
1325 vc_conn.done;
1326}
1327
1328
1329/* Test MT Call T310 timer */
1330private function f_tc_mt_t310(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltead2952e2018-01-27 14:12:46 +01001331 f_init_handler(pars, 200.0);
Harald Welte812f7a42018-01-27 00:49:18 +01001332 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1333 var MNCC_PDU mncc;
1334 var MgcpCommand mgcp_cmd;
1335
1336 f_mt_call_start(cpars);
1337
1338 /* MS->MSC: CALL CONFIRMED */
1339 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1340 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1341
1342 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1343 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1344 cpars.mgcp_ep := mgcp_cmd.line.ep;
1345 /* FIXME: Respond to CRCX */
1346
1347 /* old libosmocore T310 default timeout is 180s. so let's wait 190 */
1348 timer T := 190.0;
1349 T.start;
1350 alt {
1351 [] T.timeout { setverdict(fail, "Timeout waiting for T310"); self.stop; }
1352 [] MNCC.receive(tr_MNCC_DISC_ind(cpars.mncc_callref)) {
1353 MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(23))));
1354 }
1355 }
1356 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));
1357 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1358 /* FIXME: We're sending this with TIflag 0: allocated by sender, which is wrong */
1359 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1360
1361 alt {
1362 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1363 BSSAP.send(ts_BSSMAP_ClearComplete);
1364 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1365 setverdict(pass);
1366 }
1367 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1368 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1369 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1370 repeat;
1371 }
1372 }
1373}
1374testcase TC_mt_t310() runs on MTC_CT {
1375 var BSC_ConnHdlr vc_conn;
1376 f_init();
1377
1378 vc_conn := f_start_handler(refers(f_tc_mt_t310), testcasename(), 30);
1379 vc_conn.done;
1380}
1381
Harald Welte167458a2018-01-27 15:58:16 +01001382/* Perform successful LU + MO call, then GSUP LocationCancel. Subscriber must be denied CM SERV */
1383private function f_tc_gsup_cancel(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1384 f_init_handler(pars);
1385 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1386 cpars.bss_rtp_port := 1110;
1387 cpars.mgcp_connection_id_bss := '22222'H;
1388 cpars.mgcp_connection_id_mss := '33333'H;
1389
1390 /* Location Update to make subscriber known */
1391 f_perform_lu(cpars.expect_auth, true, true);
1392
1393 /* First MO call should succeed */
1394 f_mo_call(cpars);
1395
1396 /* Cancel the subscriber in the VLR */
1397 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1398 alt {
1399 [] GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi)) { }
1400 [] GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi)) {
1401 setverdict(fail, "Received GSUP Location Cancel Error");
1402 self.stop;
1403 }
1404 }
1405
1406 /* Follow-up transactions should fail */
1407 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1408 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
1409 f_bssap_compl_l3(l3_info);
1410 alt {
1411 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
1412 [] BSSAP.receive {
1413 setverdict(fail, "Received unexpected BSSAP instead of CM SERV REJ");
1414 self.stop;
1415 }
1416 }
1417 setverdict(pass);
1418}
1419testcase TC_gsup_cancel() runs on MTC_CT {
1420 var BSC_ConnHdlr vc_conn;
1421 f_init();
1422
1423 vc_conn := f_start_handler(refers(f_tc_gsup_cancel), testcasename(), 31);
1424 vc_conn.done;
1425}
1426
Harald Welte12510c52018-01-26 22:26:24 +01001427
Harald Welte45164da2018-01-24 12:51:27 +01001428
Harald Welteba7b6d92018-01-23 21:32:34 +01001429/* TODO:
1430 * continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
1431 * malformed messages (missing IE, invalid message type): properly rejected?
1432 * MT call while LU or is ongoing: Do we use existing lchan or page while lchan active?
1433 * 3G/2G auth permutations
1434 * encryption algorithms vs. classmark vs. vty config
Harald Welteba7b6d92018-01-23 21:32:34 +01001435 * send new transaction after/during clear (like SMS, ...)
Harald Welte45164da2018-01-24 12:51:27 +01001436 * too long L3 INFO in DTAP
1437 * too long / padded BSSAP
1438 * too long / short TLV values
Harald Welteba7b6d92018-01-23 21:32:34 +01001439 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01001440
1441
1442control {
Harald Weltea49e36e2018-01-21 19:29:33 +01001443 execute( TC_lu_imsi_noauth_tmsi() );
Harald Welted2328a22018-01-27 14:27:16 +01001444 execute( TC_lu_imsi_noauth_notmsi() );
Harald Weltea49e36e2018-01-21 19:29:33 +01001445 execute( TC_lu_imsi_reject() );
1446 execute( TC_lu_imsi_timeout_gsup() );
Harald Welted2328a22018-01-27 14:27:16 +01001447 execute( TC_lu_imsi_auth_tmsi() );
1448 execute( TC_cmserv_imsi_unknown() );
Harald Welte2bb825f2018-01-22 11:31:18 +01001449 execute( TC_lu_and_mo_call() );
Harald Welte071ed732018-01-23 19:53:52 +01001450 execute( TC_lu_auth_sai_timeout() );
1451 execute( TC_lu_auth_sai_err() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01001452 execute( TC_lu_clear_request() );
1453 execute( TC_lu_disconnect() );
1454 execute( TC_lu_by_imei() );
1455 execute( TC_lu_by_tmsi_noauth_unknown() );
1456 execute( TC_imsi_detach_by_imsi() );
1457 execute( TC_imsi_detach_by_tmsi() );
1458 execute( TC_imsi_detach_by_imei() );
1459 execute( TC_emerg_call_imei_reject() );
1460 execute( TC_emerg_call_imsi() );
1461 execute( TC_cm_serv_req_vgcs_reject() );
1462 execute( TC_cm_serv_req_vbs_reject() );
1463 execute( TC_cm_serv_req_lcs_reject() );
Harald Welte0195ab12018-01-24 21:50:20 +01001464 execute( TC_cm_reest_req_reject() );
Harald Welte1af6ea82018-01-25 18:33:15 +01001465 execute( TC_lu_auth_2G_fail() );
1466 execute( TC_lu_imsi_auth_tmsi_encr_13_13() );
1467 execute( TC_cl3_no_payload() );
1468 execute( TC_cl3_rnd_payload() );
Harald Welte1852a842018-01-26 22:53:36 +01001469 execute( TC_establish_and_nothing() );
1470 execute( TC_mo_setup_and_nothing() );
1471 execute( TC_mo_crcx_ran_timeout() );
1472 execute( TC_mo_crcx_ran_reject() );
Harald Welted2328a22018-01-27 14:27:16 +01001473 execute( TC_mt_crcx_ran_reject() );
1474 execute( TC_mt_t310() );
Harald Welte167458a2018-01-27 15:58:16 +01001475 execute( TC_gsup_cancel() );
Harald Weltef6dd64d2017-11-19 12:09:51 +01001476}
1477
1478
1479}