blob: b6b38dddd23a22e10d30ba0fc1643590b60fc970 [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 Welte6126fb02018-01-27 20:08:24 +010074 charstring mp_mgw_ip := "127.0.0.1";
75 integer mp_mgw_port := 2427;
Harald Weltef6dd64d2017-11-19 12:09:51 +010076
Harald Weltea49e36e2018-01-21 19:29:33 +010077 charstring mp_msc_mncc := "/tmp/mncc";
Harald Weltef6dd64d2017-11-19 12:09:51 +010078}
79
80
Harald Weltea49e36e2018-01-21 19:29:33 +010081function f_init_mncc(charstring id) runs on MTC_CT {
82 id := id & "-MNCC";
83 var MnccOps ops := {
84 create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
85 unitdata_cb := refers(MNCC_Emulation.DummyUnitdataCallback)
86 }
87
88 vc_MNCC := MNCC_Emulation_CT.create(id);
89 map(vc_MNCC:MNCC, system:MNCC_CODEC_PT);
90 vc_MNCC.start(MNCC_Emulation.main(ops, id, mp_msc_mncc));
Harald Weltef6dd64d2017-11-19 12:09:51 +010091}
92
Harald Welte4aa970c2018-01-26 10:38:09 +010093function f_init_mgcp(charstring id) runs on MTC_CT {
94 id := id & "-MGCP";
95 var MGCPOps ops := {
96 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
97 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
98 }
99 var MGCP_conn_parameters pars := {
Harald Welte6126fb02018-01-27 20:08:24 +0100100 callagent_ip := mp_msc_ip,
Harald Welte4aa970c2018-01-26 10:38:09 +0100101 callagent_udp_port := -1,
Harald Welte6126fb02018-01-27 20:08:24 +0100102 mgw_ip := mp_mgw_ip,
103 mgw_udp_port := mp_mgw_port
Harald Welte4aa970c2018-01-26 10:38:09 +0100104 }
105
106 vc_MGCP := MGCP_Emulation_CT.create(id);
107 map(vc_MGCP:MGCP, system:MGCP_CODEC_PT);
108 vc_MGCP.start(MGCP_Emulation.main(ops, pars, id));
109}
110
Harald Weltea49e36e2018-01-21 19:29:33 +0100111function f_init_gsup(charstring id) runs on MTC_CT {
112 id := id & "-GSUP";
113 var GsupOps ops := {
114 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
115 }
116
117 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
118 vc_GSUP := GSUP_Emulation_CT.create(id);
119
120 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
121 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
122 /* we use this hack to get events like ASP_IPA_EVENT_UP */
123 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
124
125 vc_GSUP.start(GSUP_Emulation.main(ops, id));
126 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
127
128 /* wait for incoming connection to GSUP port before proceeding */
129 timer T := 10.0;
130 T.start;
131 alt {
132 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
133 [] T.timeout {
134 setverdict(inconc, "No connection to GSUP Port");
135 self.stop
136 }
137 }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100138}
139
Harald Weltea49e36e2018-01-21 19:29:33 +0100140function f_init() runs on MTC_CT {
Harald Weltef6dd64d2017-11-19 12:09:51 +0100141
142 if (g_initialized == true) {
143 return;
144 }
145 g_initialized := true;
146
Harald Weltea49e36e2018-01-21 19:29:33 +0100147 f_bssap_init("MSC_Test", BSC_BssmapOps);
148 f_ipa_ctrl_start(mp_msc_ip, mp_msc_ctrl_port);
149 f_init_mncc("MSC_Test");
Harald Welte4aa970c2018-01-26 10:38:09 +0100150 f_init_mgcp("MSC_Test");
Harald Weltea49e36e2018-01-21 19:29:33 +0100151 f_init_gsup("MSC_Test");
Harald Welte3ca1c902018-01-24 18:51:27 +0100152
153 map(self:MSCVTY, system:MSCVTY);
154 f_vty_set_prompts(MSCVTY);
155 f_vty_transceive(MSCVTY, "enable");
Harald Welteb14c77a2018-01-25 17:25:44 +0100156
157 /* set some defaults */
158 f_vty_config(MSCVTY, "network", "authentication optional");
159 f_vty_config(MSCVTY, "msc", "assign-tmsi");
160 f_vty_config(MSCVTY, "network", "encryption a5 0");
Harald Weltef6dd64d2017-11-19 12:09:51 +0100161}
162
163template PDU_BSSAP ts_BSSAP_BSSMAP := {
164 discriminator := '0'B,
165 spare := '0000000'B,
166 dlci := omit,
167 lengthIndicator := 0, /* overwritten by codec */
168 pdu := ?
169}
170
171template PDU_BSSAP tr_BSSAP_BSSMAP := {
172 discriminator := '0'B,
173 spare := '0000000'B,
174 dlci := omit,
175 lengthIndicator := ?,
176 pdu := {
177 bssmap := ?
178 }
179}
180
181
182type integer BssmapCause;
183
184template (value) BSSMAP_IE_Cause ts_BSSMAP_IE_Cause(BssmapCause val) := {
185 elementIdentifier := '04'O,
186 lengthIndicator := 0,
187 causeValue := int2bit(val, 7),
188 extensionCauseValue := '0'B,
189 spare1 := omit
190}
191
192template (value) PDU_BSSAP ts_BSSMAP_Reset(BssmapCause cause) modifies ts_BSSAP_BSSMAP := {
193 pdu := {
194 bssmap := {
195 reset := {
196 messageType := '30'O,
197 cause := ts_BSSMAP_IE_Cause(cause),
198 a_InterfaceSelectorForReset := omit
199 }
200 }
201 }
202}
203
204template (value) PDU_BSSAP ts_BSSMAP_ResetAck modifies ts_BSSAP_BSSMAP := {
205 pdu := {
206 bssmap := {
207 resetAck := {
208 messageType := '31'O,
209 a_InterfaceSelectorForReset := omit
210 }
211 }
212 }
213}
214
215template PDU_BSSAP tr_BSSMAP_ResetAck modifies tr_BSSAP_BSSMAP := {
216 pdu := {
217 bssmap := {
218 resetAck := {
219 messageType := '31'O,
220 a_InterfaceSelectorForReset := *
221 }
222 }
223 }
224}
225
226template BSSMAP_IE_CellIdentifier ts_BSSMAP_IE_CellID := {
227 elementIdentifier := '05'O,
228 lengthIndicator := 0,
229 cellIdentifierDiscriminator := '0000'B,
230 spare1_4 := '0000'B,
231 cellIdentification := ?
232}
233
234type uint16_t BssmapLAC;
235type uint16_t BssmapCI;
236
237/*
238template BSSMAP_IE_CellIdentifier ts_CellId_CGI(mcc, mnc, lac, ci)
239modifies ts_BSSMAP_IE_CellID := {
240 cellIdentification := {
241 cI_LAC_CGI := {
242 mnc_mcc := FIXME,
243 lac := int2oct(lac, 2),
244 ci := int2oct(ci, 2)
245 }
246 }
247}
248*/
249
250template BSSMAP_IE_CellIdentifier ts_CellID_LAC_CI(BssmapLAC lac, BssmapCI ci)
251modifies ts_BSSMAP_IE_CellID := {
252 cellIdentification := {
253 cI_LAC_CI := {
254 lac := int2oct(lac, 2),
255 ci := int2oct(ci, 2)
256 }
257 }
258}
259
260template BSSMAP_IE_CellIdentifier ts_CellId_CI(BssmapCI ci)
261modifies ts_BSSMAP_IE_CellID := {
262 cellIdentification := {
263 cI_CI := int2oct(ci, 2)
264 }
265}
266
267template BSSMAP_IE_CellIdentifier ts_CellId_none
268modifies ts_BSSMAP_IE_CellID := {
269 cellIdentification := {
270 cI_noCell := ''O
271 }
272}
273
274
275template BSSMAP_IE_Layer3Information ts_BSSMAP_IE_L3Info(octetstring l3info) := {
276 elementIdentifier := '17'O,
277 lengthIndicator := 0,
278 layer3info := l3info
279}
280
281template PDU_BSSAP ts_BSSMAP_ComplL3(BSSMAP_IE_CellIdentifier cell_id, octetstring l3_info)
282modifies ts_BSSAP_BSSMAP := {
283 pdu := {
284 bssmap := {
285 completeLayer3Information := {
286 messageType := '57'O,
287 cellIdentifier := cell_id,
288 layer3Information := ts_BSSMAP_IE_L3Info(l3_info),
289 chosenChannel := omit,
290 lSAIdentifier := omit,
291 aPDU := omit,
292 codecList := omit,
293 redirectAttemptFlag := omit,
294 sendSequenceNumber := omit,
295 iMSI := omit
296 }
297 }
298 }
299}
300
301template PDU_BSSAP ts_BSSMAP_HandoReq(BssmapCause cause, BSSMAP_IE_CellIdentifierList cid_list)
302modifies ts_BSSAP_BSSMAP := {
303 pdu := {
304 bssmap := {
305 handoverRequired := {
306 messageType := '11'O,
307 cause := ts_BSSMAP_IE_Cause(cause),
308 responseRequest := omit,
309 cellIdentifierList := cid_list,
310 circuitPoolList := omit,
311 currentChannelType1 := omit,
312 speechVersion := omit,
313 queueingIndicator := omit,
314 oldToNewBSSInfo := omit,
315 sourceToTargetRNCTransparentInfo := omit,
316 sourceToTargetRNCTransparentInfoCDMA := omit,
317 gERANClassmark := omit,
318 talkerPriority := omit,
319 speechCodec := omit,
320 cSG_Identifier := omit
321 }
322 }
323 }
324}
325
326// enc_PDU_BSSAP
327
328function f_send_BSSAP_UNITDATA(template PDU_BSSAP bssap) runs on MTC_CT {
Harald Weltea49e36e2018-01-21 19:29:33 +0100329 BSSAP.send(ts_BSSAP_UNITDATA_req(g_sccp_addr_peer, g_sccp_addr_own, bssap))
Harald Weltef6dd64d2017-11-19 12:09:51 +0100330}
331
Harald Weltea49e36e2018-01-21 19:29:33 +0100332type function void_fn(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100333
Harald Welte81b7f9d2018-01-24 19:06:24 +0100334private function f_concat_pad(integer tot_len, hexstring prefix, integer suffix) return hexstring {
335 var integer suffix_len := tot_len - lengthof(prefix);
336 var charstring suffix_ch := int2str(suffix);
337 var integer pad_len := suffix_len - lengthof(suffix_ch);
338
339 return prefix & int2hex(0, pad_len) & str2hex(suffix_ch);
Harald Welte256571e2018-01-24 18:47:19 +0100340}
341
Harald Welte81b7f9d2018-01-24 19:06:24 +0100342function f_gen_imei(integer suffix) return hexstring {
343 return f_concat_pad(15, '49999'H, suffix);
Harald Weltea49e36e2018-01-21 19:29:33 +0100344}
345
Harald Welte81b7f9d2018-01-24 19:06:24 +0100346function f_gen_imsi(integer suffix) return hexstring {
347 return f_concat_pad(15, '26242'H, suffix);
348}
349
350function f_gen_msisdn(integer suffix) return hexstring {
351 return f_concat_pad(12, '49123'H, suffix);
Harald Weltea49e36e2018-01-21 19:29:33 +0100352}
353
354/* FIXME: move into BSC_ConnectionHandler? */
355function f_start_handler(void_fn fn, charstring id, integer imsi_suffix) runs on MTC_CT return BSC_ConnHdlr {
356 var BSC_ConnHdlr vc_conn;
357 var BSC_ConnHdlrPars pars := {
358 sccp_addr_own := g_sccp_addr_own,
359 sccp_addr_peer := g_sccp_addr_peer,
360 cell_id := valueof(ts_CellId_CGI('262'H, '042'H, 23, 42)),
Harald Welte81b7f9d2018-01-24 19:06:24 +0100361 imei := f_gen_imei(imsi_suffix),
362 imsi := f_gen_imsi(imsi_suffix),
363 msisdn := f_gen_msisdn(imsi_suffix),
Harald Welte256571e2018-01-24 18:47:19 +0100364 tmsi := omit,
Harald Welte82600572018-01-21 20:54:08 +0100365 cm2 := valueof(ts_CM2_default),
Harald Welte16114282018-01-24 22:41:21 +0100366 cm3 := omit,
Harald Welte148a7082018-01-26 18:56:43 +0100367 vec := omit
Harald Weltea49e36e2018-01-21 19:29:33 +0100368 };
369
370 vc_conn := BSC_ConnHdlr.create(id);
371 /* BSSMAP part / A interface */
372 connect(vc_conn:BSSAP, vc_BSSMAP:CLIENT);
373 connect(vc_conn:BSSAP_PROC, vc_BSSMAP:PROC);
374 /* MNCC part */
375 connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
376 connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);
Harald Welte4aa970c2018-01-26 10:38:09 +0100377 /* MGCP part */
378 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
379 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltea49e36e2018-01-21 19:29:33 +0100380 /* GSUP part */
381 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
382 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
383
Harald Weltea10db902018-01-27 12:44:49 +0100384 /* We cannot use vc_conn.start(f_init_handler(fn, id, pars)); as we cannot have
385 * a stand-alone 'derefers()' call, see https://www.eclipse.org/forums/index.php/t/1091364/ */
Harald Weltea49e36e2018-01-21 19:29:33 +0100386 vc_conn.start(derefers(fn)(id, pars));
387 return vc_conn;
388}
389
Harald Welte3ca1c902018-01-24 18:51:27 +0100390function f_vty_config(TELNETasp_PT pt, charstring config_node, charstring cmd)
391{
392 /* enter config mode; enter node */
393 f_vty_enter_config(pt);
394 f_vty_transceive(pt, config_node);
395 /* execute command */
396 f_vty_transceive(pt, cmd);
397 /* leave config mode */
398 f_vty_transceive(pt, "end");
399}
400
Harald Weltea49e36e2018-01-21 19:29:33 +0100401private function f_tc_lu_imsi_noauth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100402 f_init_handler(pars);
Harald Welte8a121b32018-01-22 03:00:41 +0100403 f_perform_lu(false, true, true);
Harald Weltea49e36e2018-01-21 19:29:33 +0100404}
Harald Weltea49e36e2018-01-21 19:29:33 +0100405testcase TC_lu_imsi_noauth_tmsi() runs on MTC_CT {
406 var BSC_ConnHdlr vc_conn;
407 f_init();
408
409 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_tmsi), testcasename(), 1);
410 vc_conn.done;
411}
412
413private function f_tc_lu_imsi_noauth_notmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100414 f_init_handler(pars);
Harald Welte8a121b32018-01-22 03:00:41 +0100415 f_perform_lu(false, false, true);
Harald Weltea49e36e2018-01-21 19:29:33 +0100416}
Harald Weltea49e36e2018-01-21 19:29:33 +0100417testcase TC_lu_imsi_noauth_notmsi() runs on MTC_CT {
418 var BSC_ConnHdlr vc_conn;
419 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100420 f_vty_config(MSCVTY, "msc", "no assign-tmsi");
Harald Weltea49e36e2018-01-21 19:29:33 +0100421
422 vc_conn := f_start_handler(refers(f_tc_lu_imsi_noauth_notmsi), testcasename(), 2);
423 vc_conn.done;
424}
425
426/* Do LU by IMSI, refuse it on GSUP and expect LU REJ back to MS */
427private function f_tc_lu_imsi_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100428 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100429 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
430
431 f_create_gsup_expect(hex2str(g_pars.imsi));
432 f_bssap_compl_l3(l3_lu);
433 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
434 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 23));
435 alt {
436 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej(int2oct(23,1)))) { }
437 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
438 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
439 self.stop;
440 }
441 }
Harald Welte1ddc7162018-01-27 14:25:46 +0100442 f_expect_clear();
Harald Weltea49e36e2018-01-21 19:29:33 +0100443}
444testcase TC_lu_imsi_reject() runs on MTC_CT {
445 var BSC_ConnHdlr vc_conn;
446 f_init();
447
448 vc_conn := f_start_handler(refers(f_tc_lu_imsi_reject), testcasename(), 3);
449 vc_conn.done;
450}
451
452/* Do LU by IMSI, timeout on GSUP */
453private function f_tc_lu_imsi_timeout_gsup(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100454 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100455 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi);
456
457 f_create_gsup_expect(hex2str(g_pars.imsi));
458 f_bssap_compl_l3(l3_lu);
459 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
460 /* Normally the HLR would need to respond here, but we decide to force a timeout here */
461 alt {
462 /* FIXME: Expect specific reject cause */
463 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
464 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
465 setverdict(fail, "Expecting LU REJ, but got ACCEPT");
466 self.stop;
467 }
468 }
Harald Welte1ddc7162018-01-27 14:25:46 +0100469 f_expect_clear();
Harald Weltea49e36e2018-01-21 19:29:33 +0100470}
471testcase TC_lu_imsi_timeout_gsup() runs on MTC_CT {
472 var BSC_ConnHdlr vc_conn;
473 f_init();
474
475 vc_conn := f_start_handler(refers(f_tc_lu_imsi_timeout_gsup), testcasename(), 4);
476 vc_conn.done;
477}
478
Harald Welte7b1b2812018-01-22 21:23:06 +0100479private function f_tc_lu_imsi_auth_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100480 f_init_handler(pars);
Harald Welte7b1b2812018-01-22 21:23:06 +0100481 f_perform_lu(true, true, true);
482}
483testcase TC_lu_imsi_auth_tmsi() runs on MTC_CT {
484 var BSC_ConnHdlr vc_conn;
485 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100486 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte7b1b2812018-01-22 21:23:06 +0100487
488 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi), testcasename(), 5);
489 vc_conn.done;
490}
491
Harald Weltea49e36e2018-01-21 19:29:33 +0100492
493/* Send CM SERVICE REQ for IMSI that has never performed LU before */
494private function f_tc_cmserv_imsi_unknown(charstring id, BSC_ConnHdlrPars pars)
495runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100496 f_init_handler(pars);
Harald Weltea49e36e2018-01-21 19:29:33 +0100497
498 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
499 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellId_CGI('262'H, '042'H, 23, 42));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100500 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Weltea49e36e2018-01-21 19:29:33 +0100501
502 f_create_gsup_expect(hex2str(g_pars.imsi));
503
504 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
505 f_bssap_compl_l3(l3_info);
506
507 timer T := 10.0;
Harald Weltef6dd64d2017-11-19 12:09:51 +0100508 T.start;
509 alt {
Harald Weltea49e36e2018-01-21 19:29:33 +0100510 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
511 //[] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC)) { }
512 [] BSSAP.receive { setverdict(fail, "Received unexpected BSSAP"); }
513 [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
514 setverdict(fail, "Unexpected GSUP UL REQ");
515 }
516 [] T.timeout { setverdict(inconc, "Timeout waiting for CM SERV REQ"); }
Harald Weltef6dd64d2017-11-19 12:09:51 +0100517 }
518
Harald Welte1ddc7162018-01-27 14:25:46 +0100519 f_expect_clear();
Harald Weltef6dd64d2017-11-19 12:09:51 +0100520}
Harald Weltea49e36e2018-01-21 19:29:33 +0100521testcase TC_cmserv_imsi_unknown() runs on MTC_CT {
522 var BSC_ConnHdlr vc_conn;
523 f_init();
Harald Welte81b7f9d2018-01-24 19:06:24 +0100524 vc_conn := f_start_handler(refers(f_tc_cmserv_imsi_unknown), testcasename(), 6);
Harald Weltea49e36e2018-01-21 19:29:33 +0100525 vc_conn.done;
526}
527
Harald Welte2bb825f2018-01-22 11:31:18 +0100528private function f_tc_lu_and_mo_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100529 f_init_handler(pars);
Harald Welteb71901a2018-01-26 19:16:05 +0100530 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
531 cpars.bss_rtp_port := 1110;
532 cpars.mgcp_connection_id_bss := '22222'H;
533 cpars.mgcp_connection_id_mss := '33333'H;
Harald Welte2bb825f2018-01-22 11:31:18 +0100534
Harald Welteb71901a2018-01-26 19:16:05 +0100535 f_perform_lu(cpars.expect_auth, true, true);
536 f_mo_call(cpars);
Harald Welte2bb825f2018-01-22 11:31:18 +0100537}
538testcase TC_lu_and_mo_call() runs on MTC_CT {
539 var BSC_ConnHdlr vc_conn;
540 f_init();
541
Harald Welte81b7f9d2018-01-24 19:06:24 +0100542 vc_conn := f_start_handler(refers(f_tc_lu_and_mo_call), testcasename(), 7);
Harald Welte071ed732018-01-23 19:53:52 +0100543 vc_conn.done;
544}
545
546/* Test LU (with authentication enabled), where HLR times out sending SAI response */
547private function f_tc_lu_auth_sai_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100548 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100549
550 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
551 var PDU_DTAP_MT dtap_mt;
552
553 /* tell GSUP dispatcher to send this IMSI to us */
554 f_create_gsup_expect(hex2str(g_pars.imsi));
555
556 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
557 f_bssap_compl_l3(l3_lu);
558
559 /* Send Early Classmark, just for the fun of it */
560 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
561
562 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
563 /* The HLR would normally return an auth vector here, but we fail to do so. */
564
565 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100566 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100567}
568testcase TC_lu_auth_sai_timeout() runs on MTC_CT {
569 var BSC_ConnHdlr vc_conn;
570 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100571 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100572
Harald Welte81b7f9d2018-01-24 19:06:24 +0100573 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_timeout), testcasename(), 8);
Harald Welte071ed732018-01-23 19:53:52 +0100574 vc_conn.done;
575}
576
577/* Test LU (with authentication enabled), where HLR rejects sending SAI error */
578private function f_tc_lu_auth_sai_err(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100579 f_init_handler(pars);
Harald Welte071ed732018-01-23 19:53:52 +0100580
581 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
582 var PDU_DTAP_MT dtap_mt;
583
584 /* tell GSUP dispatcher to send this IMSI to us */
585 f_create_gsup_expect(hex2str(g_pars.imsi));
586
587 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
588 f_bssap_compl_l3(l3_lu);
589
590 /* Send Early Classmark, just for the fun of it */
591 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
592
593 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
594 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 13));
595
596 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej));
Harald Welte1ddc7162018-01-27 14:25:46 +0100597 f_expect_clear();
Harald Welte071ed732018-01-23 19:53:52 +0100598}
599testcase TC_lu_auth_sai_err() runs on MTC_CT {
600 var BSC_ConnHdlr vc_conn;
601 f_init();
Harald Welte3ca1c902018-01-24 18:51:27 +0100602 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte071ed732018-01-23 19:53:52 +0100603
Harald Welte81b7f9d2018-01-24 19:06:24 +0100604 vc_conn := f_start_handler(refers(f_tc_lu_auth_sai_err), testcasename(), 9);
Harald Welte2bb825f2018-01-22 11:31:18 +0100605 vc_conn.done;
606}
Harald Weltea49e36e2018-01-21 19:29:33 +0100607
Harald Weltebc881782018-01-23 20:09:15 +0100608/* Test LU but BSC will send a clear request in the middle */
609private function f_tc_lu_clear_request(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100610 f_init_handler(pars);
Harald Weltebc881782018-01-23 20:09:15 +0100611
612 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
613 var PDU_DTAP_MT dtap_mt;
614
615 /* tell GSUP dispatcher to send this IMSI to us */
616 f_create_gsup_expect(hex2str(g_pars.imsi));
617
618 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
619 f_bssap_compl_l3(l3_lu);
620
621 /* Send Early Classmark, just for the fun of it */
622 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
623
624 f_sleep(1.0);
625 /* send clear request in the middle of the LU */
626 BSSAP.send(ts_BSSMAP_ClearRequest(0));
627 BSSAP.receive(tr_BSSMAP_ClearCommand);
628 BSSAP.send(ts_BSSMAP_ClearComplete);
Harald Welte89a32492018-01-27 19:07:28 +0100629 alt {
630 /* See https://osmocom.org/issues/2862 */
631 [] BSSAP.receive(tr_BSSMAP_ClearCommand) { repeat; }
632 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
633 }
Harald Weltebc881782018-01-23 20:09:15 +0100634 setverdict(pass);
635}
636testcase TC_lu_clear_request() runs on MTC_CT {
637 var BSC_ConnHdlr vc_conn;
638 f_init();
639
Harald Welte81b7f9d2018-01-24 19:06:24 +0100640 vc_conn := f_start_handler(refers(f_tc_lu_clear_request), testcasename(), 10);
Harald Weltebc881782018-01-23 20:09:15 +0100641 vc_conn.done;
642}
643
Harald Welte66af9e62018-01-24 17:28:21 +0100644/* Test LU but BSC will send a clear request in the middle */
645private function f_tc_lu_disconnect(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100646 f_init_handler(pars);
Harald Welte66af9e62018-01-24 17:28:21 +0100647
648 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
649 var PDU_DTAP_MT dtap_mt;
650
651 /* tell GSUP dispatcher to send this IMSI to us */
652 f_create_gsup_expect(hex2str(g_pars.imsi));
653
654 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
655 f_bssap_compl_l3(l3_lu);
656
657 /* Send Early Classmark, just for the fun of it */
658 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
659
660 f_sleep(1.0);
661 /* send clear request in the middle of the LU */
662 BSSAP.send(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
663 setverdict(pass);
664}
665testcase TC_lu_disconnect() runs on MTC_CT {
666 var BSC_ConnHdlr vc_conn;
667 f_init();
668
Harald Welte81b7f9d2018-01-24 19:06:24 +0100669 vc_conn := f_start_handler(refers(f_tc_lu_disconnect), testcasename(), 11);
Harald Welte66af9e62018-01-24 17:28:21 +0100670 vc_conn.done;
671}
672
673
Harald Welteba7b6d92018-01-23 21:32:34 +0100674/* Test LU but with illegal mobile identity type = IMEI */
675private function f_tc_lu_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100676 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100677
Harald Welte256571e2018-01-24 18:47:19 +0100678 var PDU_ML3_MS_NW l3_lu := f_build_lu_imei(g_pars.imei)
Harald Welteba7b6d92018-01-23 21:32:34 +0100679 var PDU_DTAP_MT dtap_mt;
680
681 /* tell GSUP dispatcher to send this IMSI to us */
682 f_create_gsup_expect(hex2str(g_pars.imsi));
683
684 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
685 f_bssap_compl_l3(l3_lu);
686
687 /* Send Early Classmark, just for the fun of it */
688 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
689 /* wait for LU reject, ignore any ID REQ */
690 alt {
691 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) { }
692 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req)) { repeat; }
693 }
694 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100695 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100696}
697testcase TC_lu_by_imei() runs on MTC_CT {
698 var BSC_ConnHdlr vc_conn;
699 f_init();
700
Harald Welte81b7f9d2018-01-24 19:06:24 +0100701 vc_conn := f_start_handler(refers(f_tc_lu_by_imei), testcasename(), 12);
Harald Welteba7b6d92018-01-23 21:32:34 +0100702 vc_conn.done;
703}
704
705/* Test LU by TMSI with unknown TMSI, expect (and answer) ID REQ. */
706private function f_tc_lu_tmsi_noauth_unknown(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100707 f_init_handler(pars);
Harald Welteba7b6d92018-01-23 21:32:34 +0100708
709 var PDU_ML3_MS_NW l3_lu := f_build_lu_tmsi('01020304'O); /* FIXME: Random */
710 var PDU_DTAP_MT dtap_mt;
711
712 /* tell GSUP dispatcher to send this IMSI to us */
713 f_create_gsup_expect(hex2str(g_pars.imsi));
714
715 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
716 f_bssap_compl_l3(l3_lu);
717
718 /* Send Early Classmark, just for the fun of it */
719 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
720
721 /* Wait for + respond to ID REQ (IMSI) */
722 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req('001'B)));
723 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp_IMSI(g_pars.imsi)));
724
725 /* Expect MSC to do UpdateLocation to HLR; respond to it */
726 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
727 GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
728 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
729 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
730
731 alt {
Harald Welte7ec4fa82018-01-27 10:57:40 +0100732 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) {
733 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
734 }
Harald Welteba7b6d92018-01-23 21:32:34 +0100735 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
736 setverdict(fail, "Expected LU ACK, but received REJ");
737 }
738 }
739
740 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100741 f_expect_clear();
Harald Welteba7b6d92018-01-23 21:32:34 +0100742}
743testcase TC_lu_by_tmsi_noauth_unknown() runs on MTC_CT {
744 var BSC_ConnHdlr vc_conn;
745 f_init();
746
Harald Welte81b7f9d2018-01-24 19:06:24 +0100747 vc_conn := f_start_handler(refers(f_tc_lu_tmsi_noauth_unknown), testcasename(), 13);
Harald Welteba7b6d92018-01-23 21:32:34 +0100748 vc_conn.done;
749}
750
751
Harald Welte45164da2018-01-24 12:51:27 +0100752/* Test IMSI DETACH (MI=IMSI) */
753private function f_tc_imsi_detach_by_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100754 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100755
756 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
757
758 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
759 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
760
761 /* Send Early Classmark, just for the fun of it? */
762 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
763
764 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100765 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100766}
767testcase TC_imsi_detach_by_imsi() runs on MTC_CT {
768 var BSC_ConnHdlr vc_conn;
769 f_init();
770
Harald Welte81b7f9d2018-01-24 19:06:24 +0100771 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imsi), testcasename(), 14);
Harald Welte45164da2018-01-24 12:51:27 +0100772 vc_conn.done;
773}
774
775/* Test IMSI DETACH (MI=TMSI) */
776private function f_tc_imsi_detach_by_tmsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100777 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100778
779 var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV('01020304'O));
780
781 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
782 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
783
784 /* Send Early Classmark, just for the fun of it? */
785 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
786
787 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100788 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100789}
790testcase TC_imsi_detach_by_tmsi() runs on MTC_CT {
791 var BSC_ConnHdlr vc_conn;
792 f_init();
793
Harald Welte81b7f9d2018-01-24 19:06:24 +0100794 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_tmsi), testcasename(), 15);
Harald Welte45164da2018-01-24 12:51:27 +0100795 vc_conn.done;
796}
797
798/* Test IMSI DETACH (MI=IMEI), which is illegal */
799private function f_tc_imsi_detach_by_imei(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100800 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100801
Harald Welte256571e2018-01-24 18:47:19 +0100802 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte45164da2018-01-24 12:51:27 +0100803
804 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
805 f_bssap_compl_l3(valueof(ts_ML3_MO_MM_IMSI_DET_Ind(mi)));
806
807 /* Send Early Classmark, just for the fun of it? */
808 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
809
810 /* wait for normal teardown */
Harald Welte1ddc7162018-01-27 14:25:46 +0100811 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100812}
813testcase TC_imsi_detach_by_imei() runs on MTC_CT {
814 var BSC_ConnHdlr vc_conn;
815 f_init();
816
Harald Welte81b7f9d2018-01-24 19:06:24 +0100817 vc_conn := f_start_handler(refers(f_tc_imsi_detach_by_imei), testcasename(), 16);
Harald Welte45164da2018-01-24 12:51:27 +0100818 vc_conn.done;
819}
820
821
822/* helper function for an emergency call. caller passes in mobile identity to use */
823private function f_emerg_call(MobileIdentityLV mi) runs on BSC_ConnHdlr {
824
Harald Welte6ed6bf92018-01-24 21:09:15 +0100825 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100826 f_bssap_compl_l3(l3_info);
827 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC));
828
829 var hexstring called := '112'H;
830 var integer tid := 0;
831 var MNCC_PDU mncc;
832 f_create_mncc_expect(hex2str(called));
833
834 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_EMERG_SETUP(tid)));
835 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(called)))) -> value mncc;
836 /* FIXME: extract call_id */
837
838 /* Call Proceeding */
839 MNCC.send(ts_MNCC_CALL_PROC_req(mncc.u.signal.callref, ts_MNCC_bcap_voice));
840 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(tid)));
841
842 /* Alerting */
843 MNCC.send(ts_MNCC_ALERT_req(mncc.u.signal.callref));
844 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(tid)));
845
846 /* Answer. This causes TCH assignment in case of "late assignment" */
Harald Welte4017d552018-01-26 21:40:05 +0100847 //MNCC.send(ts_MNCC_SETUP_COMPL_req(mncc.u.signal.callref));
848 MNCC.send(ts_MNCC_SETUP_rsp(mncc.u.signal.callref));
Harald Welte45164da2018-01-24 12:51:27 +0100849
850 f_sleep(3.0);
851
852 /* Hangup by "B" side */
853 MNCC.send(ts_MNCC_DISC_req(mncc.u.signal.callref, valueof(ts_MNCC_cause(23))));
854 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(tid)));
855
856 /* Release of call */
857 MNCC.send(ts_MNCC_REL_req(mncc.u.signal.callref, valueof(ts_MNCC_cause(42))));
858 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(tid)));
859
860 /* clearing of radio channel */
Harald Welte1ddc7162018-01-27 14:25:46 +0100861 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100862}
863
864/* establish an emergency call by IMEI, no SIM inserted (and hence no IMSI) */
865private function f_tc_emerg_call_imei_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100866 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100867
Harald Welte256571e2018-01-24 18:47:19 +0100868 var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100869 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100870 f_bssap_compl_l3(l3_info);
871 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ('05'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +0100872 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100873}
874testcase TC_emerg_call_imei_reject() runs on MTC_CT {
875 var BSC_ConnHdlr vc_conn;
876 f_init();
877
Harald Welte81b7f9d2018-01-24 19:06:24 +0100878 vc_conn := f_start_handler(refers(f_tc_emerg_call_imei_reject), testcasename(), 17);
Harald Welte45164da2018-01-24 12:51:27 +0100879 vc_conn.done;
880}
881
Harald Welted5b91402018-01-24 18:48:16 +0100882/* establish an emergency call by IMSI, SIM inserted (and hence IMSI) */
Harald Welte45164da2018-01-24 12:51:27 +0100883private function f_tc_emerg_call_imsi(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100884 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100885 /* First perform location update to ensure subscriber is known */
886 f_perform_lu(false, true, true);
887 /* Then issue emergency call identified by IMSI */
888 f_emerg_call(valueof(ts_MI_IMSI_LV(g_pars.imsi)));
889}
890testcase TC_emerg_call_imsi() runs on MTC_CT {
891 var BSC_ConnHdlr vc_conn;
892 f_init();
893
Harald Welte81b7f9d2018-01-24 19:06:24 +0100894 vc_conn := f_start_handler(refers(f_tc_emerg_call_imsi), testcasename(), 18);
Harald Welte45164da2018-01-24 12:51:27 +0100895 vc_conn.done;
896}
897
898/* CM Service Request for VGCS -> reject */
899private function f_tc_cm_serv_req_vgcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100900 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100901
902 /* First perform location update to ensure subscriber is known */
903 f_perform_lu(false, true, true);
904
905 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100906 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VGCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100907 f_bssap_compl_l3(l3_info);
908 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100909 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100910}
911testcase TC_cm_serv_req_vgcs_reject() runs on MTC_CT {
912 var BSC_ConnHdlr vc_conn;
913 f_init();
914
Harald Welte81b7f9d2018-01-24 19:06:24 +0100915 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vgcs_reject), testcasename(), 19);
Harald Welte45164da2018-01-24 12:51:27 +0100916 vc_conn.done;
917}
918
919/* CM Service Request for VBS -> reject */
920private function f_tc_cm_serv_req_vbs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100921 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100922
923 /* First perform location update to ensure subscriber is known */
924 f_perform_lu(false, true, true);
925
926 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100927 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_VBS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100928 f_bssap_compl_l3(l3_info);
929 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100930 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100931}
932testcase TC_cm_serv_req_vbs_reject() runs on MTC_CT {
933 var BSC_ConnHdlr vc_conn;
934 f_init();
935
Harald Welte81b7f9d2018-01-24 19:06:24 +0100936 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_vbs_reject), testcasename(), 20);
Harald Welte45164da2018-01-24 12:51:27 +0100937 vc_conn.done;
938}
939
940/* CM Service Request for LCS -> reject */
941private function f_tc_cm_serv_req_lcs_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100942 f_init_handler(pars);
Harald Welte45164da2018-01-24 12:51:27 +0100943
944 /* First perform location update to ensure subscriber is known */
945 f_perform_lu(false, true, true);
946
947 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +0100948 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_LCS, mi));
Harald Welte45164da2018-01-24 12:51:27 +0100949 f_bssap_compl_l3(l3_info);
950 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100951 f_expect_clear();
Harald Welte45164da2018-01-24 12:51:27 +0100952}
953testcase TC_cm_serv_req_lcs_reject() runs on MTC_CT {
954 var BSC_ConnHdlr vc_conn;
955 f_init();
956
Harald Welte81b7f9d2018-01-24 19:06:24 +0100957 vc_conn := f_start_handler(refers(f_tc_cm_serv_req_lcs_reject), testcasename(), 21);
Harald Welte45164da2018-01-24 12:51:27 +0100958 vc_conn.done;
959}
960
Harald Welte0195ab12018-01-24 21:50:20 +0100961/* CM Re-Establishment Request */
962private function f_tc_cm_reest_req_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100963 f_init_handler(pars);
Harald Welte0195ab12018-01-24 21:50:20 +0100964
965 /* First perform location update to ensure subscriber is known */
966 f_perform_lu(false, true, true);
967
968 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
969 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REEST_REQ(0, mi));
970 f_bssap_compl_l3(l3_info);
971 BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ(int2oct(32,1))));
Harald Welte1ddc7162018-01-27 14:25:46 +0100972 f_expect_clear();
Harald Welte0195ab12018-01-24 21:50:20 +0100973}
974testcase TC_cm_reest_req_reject() runs on MTC_CT {
975 var BSC_ConnHdlr vc_conn;
976 f_init();
Harald Welte0195ab12018-01-24 21:50:20 +0100977
978 vc_conn := f_start_handler(refers(f_tc_cm_reest_req_reject), testcasename(), 22);
979 vc_conn.done;
980}
981
Harald Weltec638f4d2018-01-24 22:00:36 +0100982/* Test LU (with authentication enabled), with wrong response from MS */
983private function f_tc_lu_auth_2G_fail(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +0100984 f_init_handler(pars);
Harald Weltec638f4d2018-01-24 22:00:36 +0100985
986 var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
987
988 /* tell GSUP dispatcher to send this IMSI to us */
989 f_create_gsup_expect(hex2str(g_pars.imsi));
990
991 /* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
992 f_bssap_compl_l3(l3_lu);
993
994 /* Send Early Classmark, just for the fun of it */
995 BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
996
997 var AuthVector vec := f_gen_auth_vec_2g();
998 var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(vec.rand, vec.sres, vec.kc));
999 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
1000 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
1001
1002 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(vec.rand)));
1003 /* Send back wrong auth response */
1004 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G('00000000'O)));
1005
1006 /* Expect GSUP AUTH FAIL REP to HLR */
1007 GSUP.receive(tr_GSUP_AUTH_FAIL_IND(g_pars.imsi));
1008
1009 /* Expect LU REJECT with Cause == Illegal MS */
1010 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej('03'O)));
Harald Welte1ddc7162018-01-27 14:25:46 +01001011 f_expect_clear();
Harald Weltec638f4d2018-01-24 22:00:36 +01001012}
1013testcase TC_lu_auth_2G_fail() runs on MTC_CT {
1014 var BSC_ConnHdlr vc_conn;
1015 f_init();
1016 f_vty_config(MSCVTY, "network", "authentication required");
Harald Weltec638f4d2018-01-24 22:00:36 +01001017
1018 vc_conn := f_start_handler(refers(f_tc_lu_auth_2G_fail), testcasename(), 23);
1019 vc_conn.done;
1020}
1021
Harald Welte16114282018-01-24 22:41:21 +01001022private 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 +01001023 f_init_handler(pars);
Harald Welte16114282018-01-24 22:41:21 +01001024 f_perform_lu(true, true, true, true);
1025}
1026testcase TC_lu_imsi_auth_tmsi_encr_13_13() runs on MTC_CT {
1027 var BSC_ConnHdlr vc_conn;
1028 f_init();
1029 f_vty_config(MSCVTY, "network", "authentication required");
Harald Welte16114282018-01-24 22:41:21 +01001030 f_vty_config(MSCVTY, "network", "encryption a5 1 3");
1031
1032 vc_conn := f_start_handler(refers(f_tc_lu_imsi_auth_tmsi_encr_13_13), testcasename(), 24);
1033 vc_conn.done;
1034}
1035
Harald Welte1af6ea82018-01-25 18:33:15 +01001036/* Test Complete L3 without payload */
1037private function f_tc_cl3_no_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001038 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001039
1040 /* Send Complete L3 Info with empty L3 frame */
1041 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1042 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, ''O))));
1043
Harald Weltef466eb42018-01-27 14:26:54 +01001044 timer T := 5.0;
1045 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001046 alt {
1047 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
1048 /* Expect LU REJECT with Cause == Illegal MS */
1049 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1050 BSSAP.send(ts_BSSMAP_ClearComplete);
1051 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1052 }
Harald Weltef466eb42018-01-27 14:26:54 +01001053 [] T.timeout {
1054 setverdict(inconc, "Timeout waiting for ClearCommand or SCCP Release");
1055 self.stop;
1056 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001057 }
1058 setverdict(pass);
1059}
1060testcase TC_cl3_no_payload() runs on MTC_CT {
1061 var BSC_ConnHdlr vc_conn;
1062 f_init();
1063
1064 vc_conn := f_start_handler(refers(f_tc_cl3_no_payload), testcasename(), 24);
1065 vc_conn.done;
1066}
1067
1068/* Test Complete L3 with random payload */
1069private function f_tc_cl3_rnd_payload(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001070 f_init_handler(pars);
Harald Welte1af6ea82018-01-25 18:33:15 +01001071
1072 var integer len := float2int(rnd() * 256.0);
1073 var octetstring payl := f_rnd_octstring(len);
1074
1075 /* Send Complete L3 Info with empty L3 frame */
1076 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
1077 valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, payl))));
1078
Harald Weltef466eb42018-01-27 14:26:54 +01001079 timer T := 5.0;
1080 T.start;
Harald Welte1af6ea82018-01-25 18:33:15 +01001081 alt {
1082 /* Immediate disconnect */
1083 [] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {}
1084 /* Expect LU REJECT with Cause == Illegal MS */
1085 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1086 BSSAP.send(ts_BSSMAP_ClearComplete);
1087 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1088 }
1089 [] BSSAP.receive(tr_PDU_DTAP_MT(?)) { repeat; }
Harald Weltef466eb42018-01-27 14:26:54 +01001090 [] T.timeout {
1091 setverdict(inconc, "Timeout waiting for ClearCommand or SCCP Release");
1092 self.stop;
1093 }
Harald Welte1af6ea82018-01-25 18:33:15 +01001094 }
1095 setverdict(pass);
1096}
1097testcase TC_cl3_rnd_payload() runs on MTC_CT {
1098 var BSC_ConnHdlr vc_conn;
1099 f_init();
1100
1101 vc_conn := f_start_handler(refers(f_tc_cl3_rnd_payload), testcasename(), 24);
1102 vc_conn.done;
1103}
1104
Harald Welte116e4332018-01-26 22:17:48 +01001105/* Test Complete L3 with random payload */
1106private function f_tc_establish_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001107 f_init_handler(pars);
Harald Welte116e4332018-01-26 22:17:48 +01001108
1109 f_perform_lu(false, true, true, false);
1110
1111 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)), false, false);
Harald Welte1ddc7162018-01-27 14:25:46 +01001112 f_expect_clear();
Harald Welte116e4332018-01-26 22:17:48 +01001113}
1114testcase TC_establish_and_nothing() runs on MTC_CT {
1115 var BSC_ConnHdlr vc_conn;
1116 f_init();
1117
1118 vc_conn := f_start_handler(refers(f_tc_establish_and_nothing), testcasename(), 25);
1119 vc_conn.done;
1120}
1121
Harald Welte12510c52018-01-26 22:26:24 +01001122/* Test MO Call SETUP with no response from MNCC */
1123private function f_tc_mo_setup_and_nothing(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001124 f_init_handler(pars);
1125
Harald Welte12510c52018-01-26 22:26:24 +01001126 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1127
1128 f_perform_lu(false, true, true, false);
1129
1130 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)), false, false);
1131 f_create_mncc_expect(hex2str(cpars.called_party));
1132 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1133
1134 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1135
Harald Welte1ddc7162018-01-27 14:25:46 +01001136 f_expect_clear(30.0);
Harald Welte12510c52018-01-26 22:26:24 +01001137}
1138testcase TC_mo_setup_and_nothing() runs on MTC_CT {
1139 var BSC_ConnHdlr vc_conn;
1140 f_init();
1141
1142 vc_conn := f_start_handler(refers(f_tc_mo_setup_and_nothing), testcasename(), 26);
1143 vc_conn.done;
1144}
1145
Harald Welte3ab88002018-01-26 22:37:25 +01001146/* Test MO Call with no response to RAN-side CRCX */
1147private function f_tc_mo_crcx_ran_timeout(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001148 f_init_handler(pars);
Harald Welte3ab88002018-01-26 22:37:25 +01001149 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1150 var MNCC_PDU mncc;
1151 var MgcpCommand mgcp_cmd;
1152
1153 f_perform_lu(false, true, true, false);
1154
1155 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)), false, false);
1156 f_create_mncc_expect(hex2str(cpars.called_party));
1157 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1158
1159 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1160 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1161 cpars.mncc_callref := mncc.u.signal.callref;
1162 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1163 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1164
1165 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
Harald Welte1852a842018-01-26 22:53:36 +01001166 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1167 cpars.mgcp_ep := mgcp_cmd.line.ep;
Harald Welte3ab88002018-01-26 22:37:25 +01001168 /* never respond to this */
1169
Harald Welte1ddc7162018-01-27 14:25:46 +01001170 f_expect_clear(30.0);
Harald Welte3ab88002018-01-26 22:37:25 +01001171}
1172testcase TC_mo_crcx_ran_timeout() runs on MTC_CT {
1173 var BSC_ConnHdlr vc_conn;
1174 f_init();
1175
1176 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_timeout), testcasename(), 27);
1177 vc_conn.done;
1178}
1179
Harald Welte0cc82d92018-01-26 22:52:34 +01001180/* Test MO Call with reject to RAN-side CRCX */
1181private function f_tc_mo_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001182 f_init_handler(pars);
Harald Welte0cc82d92018-01-26 22:52:34 +01001183 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1184 var MNCC_PDU mncc;
1185 var MgcpCommand mgcp_cmd;
1186
1187 f_perform_lu(false, true, true, false);
1188
1189 f_establish_fully(valueof(ts_MI_IMSI_LV(g_pars.imsi)), false, false);
1190 f_create_mncc_expect(hex2str(cpars.called_party));
1191 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1192
1193 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
1194 MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
1195 cpars.mncc_callref := mncc.u.signal.callref;
1196 MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
1197 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
1198
1199 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1200 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1201 cpars.mgcp_ep := mgcp_cmd.line.ep;
1202 /* Respond to CRCX with error */
1203 var MgcpResponse mgcp_rsp := {
1204 line := {
1205 code := "542",
1206 trans_id := mgcp_cmd.line.trans_id,
1207 string := "FORCED_FAIL"
1208 },
1209 params := omit,
1210 sdp := omit
1211 }
1212 MGCP.send(mgcp_rsp);
1213
1214 timer T := 30.0;
1215 T.start;
1216 alt {
1217 [] T.timeout { setverdict(fail, "Timeout waiting for channel release"); self.stop; }
1218 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1219 BSSAP.send(ts_BSSMAP_ClearComplete);
1220 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1221 setverdict(pass);
1222 }
1223 [] BSSAP.receive { repeat; }
1224 [] MNCC.receive { repeat; }
1225 [] GSUP.receive { repeat; }
1226 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1227 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1228 f_create_mgcp_delete_ep(cpars.mgcp_ep);
Harald Welteec6e5b42018-01-27 12:45:15 +01001229 repeat;
Harald Welte0cc82d92018-01-26 22:52:34 +01001230 }
1231 [] MGCP.receive { repeat; }
1232 }
1233}
1234testcase TC_mo_crcx_ran_reject() runs on MTC_CT {
1235 var BSC_ConnHdlr vc_conn;
1236 f_init();
1237
1238 vc_conn := f_start_handler(refers(f_tc_mo_crcx_ran_reject), testcasename(), 28);
1239 vc_conn.done;
1240}
1241
Harald Welte3ab88002018-01-26 22:37:25 +01001242
Harald Welte812f7a42018-01-27 00:49:18 +01001243/* helper function to start a MT call: MNCC SETUP; Paging; DChan est.; DTAP SETUP */
1244private function f_mt_call_start(inout CallParameters cpars) runs on BSC_ConnHdlr {
1245 var MNCC_PDU mncc;
1246 var MgcpCommand mgcp_cmd;
1247 var OCT4 tmsi;
1248
1249 f_perform_lu(false, true, true, false);
1250 if (isvalue(g_pars.tmsi)) {
1251 tmsi := g_pars.tmsi;
1252 } else {
1253 tmsi := 'FFFFFFFF'O;
1254 }
1255 f_bssmap_register_imsi(g_pars.imsi, tmsi);
1256
1257 /* Allocate call reference and send SETUP via MNCC to MSC */
1258 cpars.mncc_callref := f_rnd_int(2147483648);
1259 MNCC.send(ts_MNCC_SETUP_req(cpars.mncc_callref, hex2str(g_pars.msisdn),
1260 hex2str(cpars.called_party), hex2str(g_pars.imsi)));
1261
1262 /* MSC->BSC: expect PAGING from MSC */
1263 BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));
1264 /* MS -> MSC: PAGING RESPONSE */
1265 f_establish_fully_pag(valueof(ts_MI_IMSI_LV(g_pars.imsi)), false, false);
1266
1267 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
1268
1269 /* MSC->MS: SETUP */
1270 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party)));
1271}
1272
1273/* Test MT Call */
1274private function f_tc_mt_crcx_ran_reject(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltea10db902018-01-27 12:44:49 +01001275 f_init_handler(pars);
Harald Welte812f7a42018-01-27 00:49:18 +01001276 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1277 var MNCC_PDU mncc;
1278 var MgcpCommand mgcp_cmd;
1279
1280 f_mt_call_start(cpars);
1281
1282 /* MS->MSC: CALL CONFIRMED */
1283 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1284
1285 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1286
1287 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1288 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1289 cpars.mgcp_ep := mgcp_cmd.line.ep;
1290 /* Respond to CRCX with error */
1291 var MgcpResponse mgcp_rsp := {
1292 line := {
1293 code := "542",
1294 trans_id := mgcp_cmd.line.trans_id,
1295 string := "FORCED_FAIL"
1296 },
1297 params := omit,
1298 sdp := omit
1299 }
1300 MGCP.send(mgcp_rsp);
1301
1302 timer T := 30.0;
1303 T.start;
1304 alt {
1305 [] T.timeout { setverdict(fail, "Timeout waiting for channel release"); self.stop; }
1306 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1307 BSSAP.send(ts_BSSMAP_ClearComplete);
1308 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1309 setverdict(pass);
1310 }
1311 [] BSSAP.receive { repeat; }
1312 [] MNCC.receive { repeat; }
1313 [] GSUP.receive { repeat; }
1314 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1315 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1316 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1317 repeat;
1318 }
1319 [] MGCP.receive { repeat; }
1320 }
1321}
1322testcase TC_mt_crcx_ran_reject() runs on MTC_CT {
1323 var BSC_ConnHdlr vc_conn;
1324 f_init();
1325
1326 vc_conn := f_start_handler(refers(f_tc_mt_crcx_ran_reject), testcasename(), 29);
1327 vc_conn.done;
1328}
1329
1330
1331/* Test MT Call T310 timer */
1332private function f_tc_mt_t310(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
Harald Weltead2952e2018-01-27 14:12:46 +01001333 f_init_handler(pars, 200.0);
Harald Welte812f7a42018-01-27 00:49:18 +01001334 var CallParameters cpars := valueof(t_CallParams('123456'H, 0));
1335 var MNCC_PDU mncc;
1336 var MgcpCommand mgcp_cmd;
1337
1338 f_mt_call_start(cpars);
1339
1340 /* MS->MSC: CALL CONFIRMED */
1341 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CALL_CONF(cpars.transaction_id)));
1342 MNCC.receive(tr_MNCC_CALL_CONF_ind(cpars.mncc_callref));
1343
1344 MGCP.receive(tr_CRCX) -> value mgcp_cmd;
1345 cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
1346 cpars.mgcp_ep := mgcp_cmd.line.ep;
1347 /* FIXME: Respond to CRCX */
1348
1349 /* old libosmocore T310 default timeout is 180s. so let's wait 190 */
1350 timer T := 190.0;
1351 T.start;
1352 alt {
1353 [] T.timeout { setverdict(fail, "Timeout waiting for T310"); self.stop; }
1354 [] MNCC.receive(tr_MNCC_DISC_ind(cpars.mncc_callref)) {
1355 MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(23))));
1356 }
1357 }
1358 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));
1359 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
1360 /* FIXME: We're sending this with TIflag 0: allocated by sender, which is wrong */
1361 BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));
1362
1363 alt {
1364 [] BSSAP.receive(tr_BSSMAP_ClearCommand) {
1365 BSSAP.send(ts_BSSMAP_ClearComplete);
1366 BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
1367 setverdict(pass);
1368 }
1369 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
1370 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
1371 f_create_mgcp_delete_ep(cpars.mgcp_ep);
1372 repeat;
1373 }
1374 }
1375}
1376testcase TC_mt_t310() runs on MTC_CT {
1377 var BSC_ConnHdlr vc_conn;
1378 f_init();
1379
1380 vc_conn := f_start_handler(refers(f_tc_mt_t310), testcasename(), 30);
1381 vc_conn.done;
1382}
1383
Harald Welte167458a2018-01-27 15:58:16 +01001384/* Perform successful LU + MO call, then GSUP LocationCancel. Subscriber must be denied CM SERV */
1385private function f_tc_gsup_cancel(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr {
1386 f_init_handler(pars);
1387 var CallParameters cpars := valueof(t_CallParams('12345'H, 0));
1388 cpars.bss_rtp_port := 1110;
1389 cpars.mgcp_connection_id_bss := '22222'H;
1390 cpars.mgcp_connection_id_mss := '33333'H;
1391
1392 /* Location Update to make subscriber known */
1393 f_perform_lu(cpars.expect_auth, true, true);
1394
1395 /* First MO call should succeed */
1396 f_mo_call(cpars);
1397
1398 /* Cancel the subscriber in the VLR */
1399 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1400 alt {
1401 [] GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi)) { }
1402 [] GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi)) {
1403 setverdict(fail, "Received GSUP Location Cancel Error");
1404 self.stop;
1405 }
1406 }
1407
1408 /* Follow-up transactions should fail */
1409 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
1410 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
1411 f_bssap_compl_l3(l3_info);
1412 alt {
1413 [] BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ)) { }
1414 [] BSSAP.receive {
1415 setverdict(fail, "Received unexpected BSSAP instead of CM SERV REJ");
1416 self.stop;
1417 }
1418 }
1419 setverdict(pass);
1420}
1421testcase TC_gsup_cancel() runs on MTC_CT {
1422 var BSC_ConnHdlr vc_conn;
1423 f_init();
1424
1425 vc_conn := f_start_handler(refers(f_tc_gsup_cancel), testcasename(), 31);
1426 vc_conn.done;
1427}
1428
Harald Welte12510c52018-01-26 22:26:24 +01001429
Harald Welte45164da2018-01-24 12:51:27 +01001430
Harald Welteba7b6d92018-01-23 21:32:34 +01001431/* TODO:
1432 * continue to send repeated MO signalling messages to keep channel open: does MSC tmeout?
1433 * malformed messages (missing IE, invalid message type): properly rejected?
1434 * MT call while LU or is ongoing: Do we use existing lchan or page while lchan active?
1435 * 3G/2G auth permutations
1436 * encryption algorithms vs. classmark vs. vty config
Harald Welteba7b6d92018-01-23 21:32:34 +01001437 * send new transaction after/during clear (like SMS, ...)
Harald Welte45164da2018-01-24 12:51:27 +01001438 * too long L3 INFO in DTAP
1439 * too long / padded BSSAP
1440 * too long / short TLV values
Harald Welteba7b6d92018-01-23 21:32:34 +01001441 */
Harald Weltef6dd64d2017-11-19 12:09:51 +01001442
1443
1444control {
Harald Weltea49e36e2018-01-21 19:29:33 +01001445 execute( TC_lu_imsi_noauth_tmsi() );
Harald Welted2328a22018-01-27 14:27:16 +01001446 execute( TC_lu_imsi_noauth_notmsi() );
Harald Weltea49e36e2018-01-21 19:29:33 +01001447 execute( TC_lu_imsi_reject() );
1448 execute( TC_lu_imsi_timeout_gsup() );
Harald Welted2328a22018-01-27 14:27:16 +01001449 execute( TC_lu_imsi_auth_tmsi() );
1450 execute( TC_cmserv_imsi_unknown() );
Harald Welte2bb825f2018-01-22 11:31:18 +01001451 execute( TC_lu_and_mo_call() );
Harald Welte071ed732018-01-23 19:53:52 +01001452 execute( TC_lu_auth_sai_timeout() );
1453 execute( TC_lu_auth_sai_err() );
Harald Weltee1a2f3c2018-01-24 17:28:48 +01001454 execute( TC_lu_clear_request() );
1455 execute( TC_lu_disconnect() );
1456 execute( TC_lu_by_imei() );
1457 execute( TC_lu_by_tmsi_noauth_unknown() );
1458 execute( TC_imsi_detach_by_imsi() );
1459 execute( TC_imsi_detach_by_tmsi() );
1460 execute( TC_imsi_detach_by_imei() );
1461 execute( TC_emerg_call_imei_reject() );
1462 execute( TC_emerg_call_imsi() );
1463 execute( TC_cm_serv_req_vgcs_reject() );
1464 execute( TC_cm_serv_req_vbs_reject() );
1465 execute( TC_cm_serv_req_lcs_reject() );
Harald Welte0195ab12018-01-24 21:50:20 +01001466 execute( TC_cm_reest_req_reject() );
Harald Welte1af6ea82018-01-25 18:33:15 +01001467 execute( TC_lu_auth_2G_fail() );
1468 execute( TC_lu_imsi_auth_tmsi_encr_13_13() );
1469 execute( TC_cl3_no_payload() );
1470 execute( TC_cl3_rnd_payload() );
Harald Welte1852a842018-01-26 22:53:36 +01001471 execute( TC_establish_and_nothing() );
1472 execute( TC_mo_setup_and_nothing() );
1473 execute( TC_mo_crcx_ran_timeout() );
1474 execute( TC_mo_crcx_ran_reject() );
Harald Welted2328a22018-01-27 14:27:16 +01001475 execute( TC_mt_crcx_ran_reject() );
1476 execute( TC_mt_t310() );
Harald Welte167458a2018-01-27 15:58:16 +01001477 execute( TC_gsup_cancel() );
Harald Weltef6dd64d2017-11-19 12:09:51 +01001478}
1479
1480
1481}