blob: 2bf5e5784c44c5e7bf3dc8824e3d41a20f6ff630 [file] [log] [blame]
Harald Welte78cae922018-03-01 10:12:56 +01001module HLR_Tests {
Harald Weltedf327232017-12-28 22:51:51 +01002
3import from GSUP_Types all;
Harald Welteed380d12018-06-14 13:42:11 +02004import from GSUP_Emulation all;
Harald Weltedf327232017-12-28 22:51:51 +01005import from IPA_Emulation all;
6
Harald Weltec2c52552018-03-01 21:20:39 +01007import from General_Types all;
8import from Osmocom_Types all;
Harald Welte39b82d32018-03-01 10:21:29 +01009import from Osmocom_CTRL_Adapter all;
10
11import from Osmocom_VTY_Functions all;
12import from TELNETasp_PortType all;
13
14type component test_CT extends CTRL_Adapter_CT {
Harald Weltedf327232017-12-28 22:51:51 +010015 var IPA_Emulation_CT vc_IPA;
16 var IPA_CCM_Parameters ccm_pars;
Harald Welteed380d12018-06-14 13:42:11 +020017 /* legacy tests without ConnHdlr */
Harald Weltedf327232017-12-28 22:51:51 +010018 port IPA_GSUP_PT GSUP;
Harald Welteed380d12018-06-14 13:42:11 +020019 /* new tests using ConnHdlr + GSUP_Emulation */
20 var GSUP_Emulation_CT vc_GSUP;
21 /* only to get events from IPA underneath GSUP */
22 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte39b82d32018-03-01 10:21:29 +010023
24 port TELNETasp_PT VTY;
Harald Weltec2c52552018-03-01 21:20:39 +010025
26 timer g_Tguard := 10.0;
Harald Weltedf327232017-12-28 22:51:51 +010027};
28
29modulepar {
30 charstring mp_hlr_ip := "127.0.0.1";
31 integer mp_hlr_gsup_port := 4222;
32 integer mp_hlr_ctrl_port := 4259;
33};
34
Harald Weltec2c52552018-03-01 21:20:39 +010035type record HlrSubscrAud2G {
36 charstring algo,
37 OCT16 ki
38}
39
40type record HlrSubscrAud3G {
41 charstring algo,
42 OCT16 k,
43 OCT16 op,
44 boolean op_is_opc
45}
46
47type record HlrSubscriber {
48 hexstring imsi,
49 hexstring msisdn,
50 HlrSubscrAud2G aud2g optional,
51 HlrSubscrAud3G aud3g optional
52}
53
54type record of HlrSubscriber HlrSubscriberList;
55
Harald Welteed380d12018-06-14 13:42:11 +020056type component HLR_ConnHdlr extends GSUP_ConnHdlr {
57 timer g_Tguard := 10.0;
58 var HLR_ConnHdlrPars g_pars;
59 port TELNETasp_PT VTY;
60}
61
62type record HLR_ConnHdlrPars {
63 HlrSubscriber sub
64}
65
66template (value) HLR_ConnHdlrPars t_Pars(hexstring imsi, hexstring msisdn := ''H) := {
67 sub := {
68 imsi := imsi,
69 msisdn := msisdn,
70 aud2g := omit,
71 aud3g := omit
72 }
73}
74
75template (value) HLR_ConnHdlrPars t_Pars_sub(HlrSubscriber sub) := {
76 sub := sub
77}
78
79type function void_fn() runs on HLR_ConnHdlr;
80
81/***********************************************************************
82 * Main Component
83 ***********************************************************************/
84
85function f_init_vty() runs on test_CT {
86 map(self:VTY, system:VTY);
87 f_vty_set_prompts(VTY);
88 f_vty_transceive(VTY, "enable");
89}
90
91private altstep as_Tguard() runs on test_CT {
92 [] g_Tguard.timeout {
93 setverdict(fail, "g_Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +020094 mtc.stop;
Harald Welteed380d12018-06-14 13:42:11 +020095 }
96}
97
98function f_init_gsup(charstring id, boolean legacy) runs on test_CT {
99 id := id & "-GSUP";
100 var GsupOps ops := {
101 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
102 }
103
104 ccm_pars := c_IPA_default_ccm_pars;
105 ccm_pars.name := "Osmocom TTCN-3 GSUP Simulator";
Harald Welte4a3242e2018-06-24 22:28:53 +0200106 ccm_pars.ser_nr := "MSC-00-00-00-00-00-00";
Harald Welteed380d12018-06-14 13:42:11 +0200107
108 vc_IPA := IPA_Emulation_CT.create(id & "-IPA");
109 log("legacy= ", legacy);
110 if (not legacy) {
111 log("in not legacy case 1");
112 vc_GSUP := GSUP_Emulation_CT.create(id);
113 }
114
115 map(vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
116 if (not legacy) {
117 log("in not legacy case 2");
118 connect(vc_GSUP:GSUP, vc_IPA:IPA_GSUP_PORT);
119 connect(vc_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
120 vc_GSUP.start(GSUP_Emulation.main(ops, id));
121 } else {
122 connect(vc_IPA:IPA_GSUP_PORT, self:GSUP);
123 }
124
125 vc_IPA.start(IPA_Emulation.main_client(mp_hlr_ip, mp_hlr_gsup_port, "", -1, ccm_pars));
126
127 /* wait for incoming connection to GSUP port before proceeding */
128 timer T := 10.0;
129 T.start;
130 alt {
131 [not legacy] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
132 [legacy] GSUP.receive(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_UP}) { }
133 [] T.timeout {
134 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200135 mtc.stop;
Harald Welteed380d12018-06-14 13:42:11 +0200136 }
137 }
138}
139
140function f_init(boolean legacy := true) runs on test_CT {
141
142 /* activate default guard timer to ensure all tests eventually terminate */
143 g_Tguard.start;
144 activate(as_Tguard());
145
146 f_init_gsup("HLR_Test", legacy);
147 f_init_vty();
148
149 f_ipa_ctrl_start(mp_hlr_ip, mp_hlr_ctrl_port);
150}
151
152function f_start_handler(void_fn fn, HLR_ConnHdlrPars pars) runs on test_CT return HLR_ConnHdlr {
153 var HLR_ConnHdlr vc_conn;
154 var charstring id := testcasename();
155
156 vc_conn := HLR_ConnHdlr.create(id);
157 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
158 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
159
160 vc_conn.start(f_handler_init(fn, id, pars));
161 return vc_conn;
162}
163
164private function f_handler_init_vty() runs on HLR_ConnHdlr {
165 map(self:VTY, system:VTY);
166 f_vty_set_prompts(VTY);
167 f_vty_transceive(VTY, "enable");
168}
169
170/* first function inside ConnHdlr component; sets g_pars + starts function */
171function f_handler_init(void_fn fn, charstring id, template (omit) HLR_ConnHdlrPars pars := omit)
172runs on HLR_ConnHdlr
173{
174 if (isvalue(pars)) {
175 g_pars := valueof(pars);
176 f_create_gsup_expect(hex2str(g_pars.sub.imsi));
177 }
178 f_handler_init_vty();
179 fn.apply();
180}
181
182/***********************************************************************
183 * Subscriber creation via VTY
184 ***********************************************************************/
185
Harald Weltec2c52552018-03-01 21:20:39 +0100186template (value) HlrSubscriber t_SubNoAuth(hexstring imsi, hexstring msisdn) := {
187 imsi := imsi,
188 msisdn := msisdn,
189 aud2g := omit,
190 aud3g := omit
191}
192
193const OCT16 c_KI_DEFAULT := '000102030405060708090a0b0c0d0e0f'O;
194const OCT16 c_K_DEFAULT := '101112131415161718191a1b1c1d1e1f'O;
195const OCT16 c_OP_DEFAULT := '202122232425262728292a2b2c2d2e2f'O;
196//const OCT16 c_OPC_DEFAULT := '303132333435363738393a3b3c3d3f'O;
197
198template (value) HlrSubscriber t_Sub2G(hexstring imsi, hexstring msisdn, charstring algo) := {
199 imsi := imsi,
200 msisdn := msisdn,
201 aud2g := {
202 algo := algo,
203 ki := c_KI_DEFAULT
204 },
205 aud3g := omit
206}
207
208template (value) HlrSubscriber t_Sub3G(hexstring imsi, hexstring msisdn, charstring algo, boolean is_opc) := {
209 imsi := imsi,
210 msisdn := msisdn,
211 aud2g := omit,
212 aud3g := {
213 algo := algo,
214 k := c_K_DEFAULT,
215 op := c_OP_DEFAULT,
216 op_is_opc := is_opc
217 }
218}
219
220template (value) HlrSubscriber t_Sub2G3G(hexstring imsi, hexstring msisdn, charstring algo2g, charstring algo3g, boolean is_opc) := {
221 imsi := imsi,
222 msisdn := msisdn,
223 aud2g := {
224 algo := algo2g,
225 ki := c_KI_DEFAULT
226 },
227 aud3g := {
228 algo := algo3g,
229 k := c_K_DEFAULT,
230 op := c_OP_DEFAULT,
231 op_is_opc := is_opc
232 }
233}
234
235/* generate a variety of subscribers with different parameters */
236function f_gen_subs() runs on test_CT return HlrSubscriberList {
237 var HlrSubscriber sub;
238 var HlrSubscriberList sl := {};
239
240 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v1"));
241 sl := sl & { sub };
242
243 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v2"));
244 sl := sl & { sub };
245
246 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v3"));
247 sl := sl & { sub };
248
249 sub := valueof(t_Sub3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "milenage", false));
250 sl := sl & { sub };
251
252 sub := valueof(t_Sub3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "milenage", true));
253 sl := sl & { sub };
254
255 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
256 "comp128v1", "milenage", false));
257 sl := sl & { sub };
258
259 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
260 "comp128v2", "milenage", false));
261 sl := sl & { sub };
262
263 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
264 "comp128v3", "milenage", false));
265 sl := sl & { sub };
266
267 return sl;
268}
269
Harald Welteed380d12018-06-14 13:42:11 +0200270function f_vty_transceive_match(TELNETasp_PT pt, charstring cmd, template charstring exp_ret) {
271 var charstring ret := f_vty_transceive_ret(pt, cmd);
272 if (not match(ret, exp_ret)) {
273 setverdict(fail, "Non-matching VTY response: ", ret);
Daniel Willmannafce8662018-07-06 23:11:32 +0200274 mtc.stop;
Harald Weltec2c52552018-03-01 21:20:39 +0100275 }
276}
277
Harald Welte70296062018-03-01 22:42:03 +0100278private template (value) charstring t_subscr_prefix(hexstring imsi) :=
279 "subscriber imsi " & hex2str(imsi) & " ";
280
Harald Weltec2c52552018-03-01 21:20:39 +0100281/* create a given subscriber using the VTY */
Harald Welteed380d12018-06-14 13:42:11 +0200282function f_vty_subscr_create(TELNETasp_PT VTY, HlrSubscriber sub) {
Harald Welte70296062018-03-01 22:42:03 +0100283 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
Harald Weltec2c52552018-03-01 21:20:39 +0100284 f_vty_transceive_match(VTY, prefix & "create", pattern "% Created subscriber *");
285 f_vty_transceive_match(VTY, prefix & "update msisdn " & hex2str(sub.msisdn),
286 pattern "% Updated subscriber *");
287 if (ispresent(sub.aud2g)) {
288 f_vty_transceive_match(VTY, prefix & "update aud2g " & sub.aud2g.algo &
289 " ki " & oct2str(sub.aud2g.ki),
290 pattern "");
291 } else {
292 f_vty_transceive_match(VTY, prefix & "update aud2g none", pattern "");
293 }
294
295 if (ispresent(sub.aud3g)) {
296 var charstring op_mode := "op";
297 if (sub.aud3g.op_is_opc) {
298 op_mode := "opc";
299 }
300 f_vty_transceive_match(VTY, prefix & "update aud3g " & sub.aud3g.algo &
301 " k " & oct2str(sub.aud3g.k) & " " & op_mode & " " &
302 oct2str(sub.aud3g.op), pattern "");
303 } else {
304 f_vty_transceive_match(VTY, prefix & "update aud3g none", pattern "");
305 }
306}
307
Harald Welteed380d12018-06-14 13:42:11 +0200308function f_vty_subscr_update_msisdn(TELNETasp_PT VTY, HlrSubscriber sub, hexstring new_msisdn) {
Harald Welte09b3c502018-03-01 22:42:22 +0100309 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
310 f_vty_transceive_match(VTY, prefix & "update msisdn " & hex2str(new_msisdn),
311 pattern "% Updated subscriber *");
312}
313
Harald Weltec2c52552018-03-01 21:20:39 +0100314/* perform 'delete' on subscriber */
Harald Welteed380d12018-06-14 13:42:11 +0200315function f_vty_subscr_delete(TELNETasp_PT VTY, HlrSubscriber sub) {
Harald Welte70296062018-03-01 22:42:03 +0100316 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
Harald Weltec2c52552018-03-01 21:20:39 +0100317 f_vty_transceive_match(VTY, prefix & "delete",
318 pattern "% Deleted subscriber for IMSI *");
319}
320
321/* perform 'show' on subscriber; match result with pattern 'exp' */
Harald Welteed380d12018-06-14 13:42:11 +0200322function f_vty_subscr_show(TELNETasp_PT VTY, HlrSubscriber sub, template charstring exp) {
Harald Welte70296062018-03-01 22:42:03 +0100323 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
Harald Weltec2c52552018-03-01 21:20:39 +0100324 f_vty_transceive_match(VTY, prefix & "show", exp);
325}
326
327
Harald Welteed380d12018-06-14 13:42:11 +0200328/***********************************************************************
329 * Helper functions for ConnHdlr
330 ***********************************************************************/
331
Harald Weltec2c52552018-03-01 21:20:39 +0100332/* perform SendAuthInfo for given imsi, return the GSUP response/error */
333function f_perform_SAI(hexstring imsi, template (omit) integer exp_err_cause := omit)
Harald Welteed380d12018-06-14 13:42:11 +0200334runs on HLR_ConnHdlr return GSUP_PDU {
Harald Weltec2c52552018-03-01 21:20:39 +0100335 var GSUP_PDU ret;
336 timer T := 3.0;
337 var boolean exp_fail := false;
338 if (not istemplatekind(exp_err_cause, "omit")) {
339 exp_fail := true;
340 }
341
342 GSUP.send(valueof(ts_GSUP_SAI_REQ(imsi)));
343 T.start;
344 alt {
345 [exp_fail] GSUP.receive(tr_GSUP_SAI_ERR(imsi, exp_err_cause)) -> value ret {
346 setverdict(pass);
347 }
348 [exp_fail] GSUP.receive(tr_GSUP_SAI_ERR(imsi, ?)) -> value ret {
349 setverdict(fail, "Unexpected SAI ERROR Cause");
350 }
351 [exp_fail] GSUP.receive(tr_GSUP_SAI_RES(imsi)) -> value ret {
352 setverdict(fail, "Unexpected SAI.res for unknown IMSI");
353 }
354 [not exp_fail] GSUP.receive(tr_GSUP_SAI_ERR(imsi, ?)) -> value ret {
355 setverdict(fail, "Unexpected SAI ERROR");
356 }
357 [not exp_fail] GSUP.receive(tr_GSUP_SAI_RES(imsi)) -> value ret {
358 setverdict(pass);
359 }
360 [] GSUP.receive { repeat; }
361 [] T.timeout {
362 setverdict(fail, "Timeout waiting for SAI response");
Daniel Willmannafce8662018-07-06 23:11:32 +0200363 mtc.stop;
Harald Weltec2c52552018-03-01 21:20:39 +0100364 }
365 }
366 return ret;
367}
368
369function f_perform_UL(hexstring imsi, template hexstring msisdn,
370 template (omit) integer exp_err_cause := omit)
Harald Welteed380d12018-06-14 13:42:11 +0200371runs on HLR_ConnHdlr return GSUP_PDU {
Harald Weltec2c52552018-03-01 21:20:39 +0100372 var GSUP_PDU ret;
373 timer T := 3.0;
374 var boolean exp_fail := false;
375 var boolean isd_done := false;
376 if (not istemplatekind(exp_err_cause, "omit")) {
377 exp_fail := true;
378 }
379
380 GSUP.send(valueof(ts_GSUP_UL_REQ(imsi)));
381 T.start;
382 alt {
383 [exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, exp_err_cause)) -> value ret {
384 setverdict(pass);
385 }
386 [exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, ?)) -> value ret {
387 setverdict(fail, "Unexpected UL ERROR Cause");
388 }
389 [exp_fail] GSUP.receive(tr_GSUP_UL_RES(imsi)) -> value ret {
390 setverdict(fail, "Unexpected UL.res for unknown IMSI");
391 }
392 [exp_fail] GSUP.receive(tr_GSUP_ISD_REQ(imsi)) -> value ret {
393 setverdict(fail, "Unexpected ISD.req in error case");
394 }
395 [not exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, ?)) -> value ret {
396 setverdict(fail, "Unexpected UL ERROR");
397 }
398 [not exp_fail and not isd_done] GSUP.receive(tr_GSUP_ISD_REQ(imsi, msisdn)) -> value ret {
399 GSUP.send(ts_GSUP_ISD_RES(imsi));
400 isd_done := true;
Harald Welte8f0c9332018-03-01 23:38:40 +0100401 repeat;
Harald Weltec2c52552018-03-01 21:20:39 +0100402 }
403 [not exp_fail and isd_done] GSUP.receive(tr_GSUP_UL_RES(imsi)) -> value ret {
404 setverdict(pass);
405 }
406 [] GSUP.receive { repeat; }
407 [] T.timeout {
408 setverdict(fail, "Timeout waiting for UL response");
Daniel Willmannafce8662018-07-06 23:11:32 +0200409 mtc.stop;
Harald Weltec2c52552018-03-01 21:20:39 +0100410 }
411 }
412 return ret;
413}
414
Harald Welte958f8b42018-03-01 23:40:17 +0100415/* perform PurgeMS for given imsi, return the GSUP response/error */
416function f_perform_PURGE(hexstring imsi, GSUP_CnDomain cn_dom,
417 template (omit) integer exp_err_cause := omit)
Harald Welteed380d12018-06-14 13:42:11 +0200418runs on HLR_ConnHdlr return GSUP_PDU {
Harald Welte958f8b42018-03-01 23:40:17 +0100419 var GSUP_PDU ret;
420 timer T := 3.0;
421 var boolean exp_fail := false;
422 if (not istemplatekind(exp_err_cause, "omit")) {
423 exp_fail := true;
424 }
425
426 GSUP.send(valueof(ts_GSUP_PURGE_MS_REQ(imsi, cn_dom)));
427 T.start;
428 alt {
429 [exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_ERR(imsi, exp_err_cause)) -> value ret {
430 setverdict(pass);
431 }
432 [exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_ERR(imsi, ?)) -> value ret {
433 setverdict(fail, "Unexpected PURGE ERROR Cause");
434 }
435 [exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_RES(imsi)) -> value ret {
436 setverdict(fail, "Unexpected PURGE.res for unknown IMSI");
437 }
438 [not exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_ERR(imsi, ?)) -> value ret {
439 setverdict(fail, "Unexpected PURGE ERROR");
440 }
441 [not exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_RES(imsi)) -> value ret {
442 setverdict(pass);
443 }
444 [] GSUP.receive { repeat; }
445 [] T.timeout {
446 setverdict(fail, "Timeout waiting for PURGE response");
Daniel Willmannafce8662018-07-06 23:11:32 +0200447 mtc.stop;
Harald Welte958f8b42018-03-01 23:40:17 +0100448 }
449 }
450 return ret;
451}
452
453
Harald Welteed380d12018-06-14 13:42:11 +0200454/***********************************************************************
455 * Testcases
456 ***********************************************************************/
457
458/* 23.003 Section 2.2 clearly states that an IMSI with less
459 * than 5 digits is impossible. Even 5 digits is still questionable */
460private function f_TC_gsup_sai_err_invalid_imsi() runs on HLR_ConnHdlr {
Harald Weltec2c52552018-03-01 21:20:39 +0100461 var GSUP_PDU res;
Harald Welteed380d12018-06-14 13:42:11 +0200462 res := f_perform_SAI(g_pars.sub.imsi, 96); /* Invalid Mandatory information */
463 setverdict(pass);
464}
465testcase TC_gsup_sai_err_invalid_imsi() runs on test_CT {
466 var HLR_ConnHdlr vc_conn;
467 var HLR_ConnHdlrPars pars := valueof(t_Pars('0123'H));
468 f_init(false);
469 vc_conn := f_start_handler(refers(f_TC_gsup_sai_err_invalid_imsi), pars);
470 vc_conn.done;
471}
Harald Weltec2c52552018-03-01 21:20:39 +0100472
Harald Weltec2c52552018-03-01 21:20:39 +0100473
Harald Welteed380d12018-06-14 13:42:11 +0200474private function f_TC_gsup_sai_err_unknown_imsi() runs on HLR_ConnHdlr {
475 var GSUP_PDU res;
476 res := f_perform_SAI(g_pars.sub.imsi, 2);
Harald Weltec2c52552018-03-01 21:20:39 +0100477 setverdict(pass);
478}
479
Harald Welte3f662762018-03-02 10:48:20 +0100480testcase TC_gsup_sai_err_unknown_imsi() runs on test_CT {
Harald Welteed380d12018-06-14 13:42:11 +0200481 var HLR_ConnHdlr vc_conn;
482 var HLR_ConnHdlrPars pars := valueof(t_Pars(f_rnd_imsi('26242'H)));
483 f_init(false);
484 vc_conn := f_start_handler(refers(f_TC_gsup_sai_err_unknown_imsi), pars);
485 vc_conn.done;
Harald Welte3f662762018-03-02 10:48:20 +0100486}
487
Harald Welteed380d12018-06-14 13:42:11 +0200488function f_start_handler_per_sub(void_fn fn, HlrSubscriberList sl) runs on test_CT {
489 for (var integer i := 0; i < sizeof(sl); i := i+1) {
490 var HlrSubscriber sub := sl[i];
491 var HLR_ConnHdlrPars pars := valueof(t_Pars_sub(sub));
492 var HLR_ConnHdlr vc_conn;
493
494 f_vty_subscr_create(VTY, sub);
495 vc_conn := f_start_handler(fn, pars);
496 vc_conn.done;
497 f_vty_subscr_delete(VTY, sub);
498 }
499}
Harald Welte3f662762018-03-02 10:48:20 +0100500
Harald Weltec2c52552018-03-01 21:20:39 +0100501/* test SAI for a number of different subscriber cases (algo, 2g/3g, ...) */
Harald Welteed380d12018-06-14 13:42:11 +0200502private function f_TC_gsup_sai() runs on HLR_ConnHdlr {
503 var GSUP_PDU res;
504 res := f_perform_SAI(g_pars.sub.imsi);
505 /* TODO: match if tuple[s] matches expectation */
506 setverdict(pass);
507}
Harald Weltec2c52552018-03-01 21:20:39 +0100508testcase TC_gsup_sai() runs on test_CT {
509 var HlrSubscriberList sl;
510 var GSUP_PDU res;
511
Harald Welteed380d12018-06-14 13:42:11 +0200512 f_init(false);
Harald Weltec2c52552018-03-01 21:20:39 +0100513
514 sl := f_gen_subs();
Harald Welteed380d12018-06-14 13:42:11 +0200515 f_start_handler_per_sub(refers(f_TC_gsup_sai), sl);
Harald Weltec2c52552018-03-01 21:20:39 +0100516
517 setverdict(pass);
518}
519
520/* test UL for unknown IMSI */
Harald Welteed380d12018-06-14 13:42:11 +0200521private function f_TC_ul_unknown_imsi() runs on HLR_ConnHdlr {
Harald Weltec2c52552018-03-01 21:20:39 +0100522 var GSUP_PDU res;
Harald Welteed380d12018-06-14 13:42:11 +0200523 res := f_perform_UL(g_pars.sub.imsi, ?, 2);
Harald Weltec2c52552018-03-01 21:20:39 +0100524 setverdict(pass);
525}
Harald Welteed380d12018-06-14 13:42:11 +0200526testcase TC_gsup_ul_unknown_imsi() runs on test_CT {
527 var hexstring imsi := f_rnd_imsi('26242'H);
528 var HLR_ConnHdlrPars pars := valueof(t_Pars(imsi));
529 var HLR_ConnHdlr vc_conn;
Harald Weltec2c52552018-03-01 21:20:39 +0100530
Harald Welteed380d12018-06-14 13:42:11 +0200531 f_init(false);
532 vc_conn := f_start_handler(refers(f_TC_ul_unknown_imsi), pars);
533 vc_conn.done;
534}
535
536/* test UL for a number of different subscriber cases (algo, 2g/3g, ...) */
537private function f_TC_gsup_ul() runs on HLR_ConnHdlr {
538 var GSUP_PDU res;
539 res := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn);
540 setverdict(pass);
541}
Harald Weltec2c52552018-03-01 21:20:39 +0100542testcase TC_gsup_ul() runs on test_CT {
543 var HlrSubscriberList sl;
544 var GSUP_PDU res;
545
Harald Welteed380d12018-06-14 13:42:11 +0200546 f_init(false);
Harald Weltec2c52552018-03-01 21:20:39 +0100547 sl := f_gen_subs();
Harald Welteed380d12018-06-14 13:42:11 +0200548 f_start_handler_per_sub(refers(f_TC_gsup_ul), sl);
Harald Weltec2c52552018-03-01 21:20:39 +0100549
550 setverdict(pass);
551}
552
553/* Test only the VTY commands */
554testcase TC_vty() runs on test_CT {
555 var HlrSubscriber sub;
556
557 f_init();
558
559 /* we're not using f_gen_subs() here as the expect pattern for the 'show' are different
560 * from case to case */
561 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v1"));
Harald Welteed380d12018-06-14 13:42:11 +0200562 f_vty_subscr_create(VTY, sub);
563 f_vty_subscr_show(VTY, sub, pattern "*IMSI: *2G auth: COMP128v1*");
564 f_vty_subscr_delete(VTY, sub);
Harald Weltec2c52552018-03-01 21:20:39 +0100565
566 sub := valueof(t_Sub3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
567 "milenage", false));
Harald Welteed380d12018-06-14 13:42:11 +0200568 f_vty_subscr_create(VTY, sub);
569 f_vty_subscr_show(VTY, sub, pattern "*IMSI: *3G auth: MILENAGE*");
570 f_vty_subscr_delete(VTY, sub);
Harald Weltec2c52552018-03-01 21:20:39 +0100571
572 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
573 "comp128v1", "milenage", false));
Harald Welteed380d12018-06-14 13:42:11 +0200574 f_vty_subscr_create(VTY, sub);
575 f_vty_subscr_show(VTY, sub, pattern "*IMSI: *2G auth: COMP128v1*3G auth: MILENAGE*");
576 f_vty_subscr_delete(VTY, sub);
Harald Weltec2c52552018-03-01 21:20:39 +0100577
578 setverdict(pass);
579}
580
Harald Welte09b3c502018-03-01 22:42:22 +0100581/* VTY changes to MSISDN should result in ISD to current VLR */
Harald Welteed380d12018-06-14 13:42:11 +0200582private function f_TC_vty_msisdn_isd() runs on HLR_ConnHdlr {
Harald Welte09b3c502018-03-01 22:42:22 +0100583 var hexstring new_msisdn;
584 var GSUP_PDU res;
585 timer T := 5.0;
586
Harald Welte09b3c502018-03-01 22:42:22 +0100587 /* Create Subscriber */
Harald Welteed380d12018-06-14 13:42:11 +0200588 f_vty_subscr_create(VTY, g_pars.sub);
Harald Welte09b3c502018-03-01 22:42:22 +0100589
590 /* Perform UpdateLocation (VLR now known to HLR) */
Harald Welteed380d12018-06-14 13:42:11 +0200591 res := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn);
Harald Welte09b3c502018-03-01 22:42:22 +0100592
593 /* Then change IMSI via VTY */
594 new_msisdn := '49161'H & f_rnd_hexstring(7, 9);
Harald Welteed380d12018-06-14 13:42:11 +0200595 f_vty_subscr_update_msisdn(VTY, g_pars.sub, new_msisdn);
Harald Welte09b3c502018-03-01 22:42:22 +0100596 /* And expect InsertSubscriberData as result */
597 T.start;
598 alt {
Harald Welteed380d12018-06-14 13:42:11 +0200599 [] GSUP.receive(tr_GSUP_ISD_REQ(g_pars.sub.imsi, new_msisdn)) {
600 GSUP.send(ts_GSUP_ISD_RES(g_pars.sub.imsi));
601 g_pars.sub.msisdn := new_msisdn;
Harald Welte09b3c502018-03-01 22:42:22 +0100602 setverdict(pass);
603 }
Harald Welteed380d12018-06-14 13:42:11 +0200604 [] GSUP.receive(tr_GSUP_ISD_REQ(g_pars.sub.imsi, g_pars.sub.msisdn)) {
Stefan Sperling7c096872018-04-09 11:24:22 +0200605 log("received ISD req with old MSISDN");
606 setverdict(fail);
607 }
Harald Welte09b3c502018-03-01 22:42:22 +0100608 [] GSUP.receive { repeat; }
609 [] T.timeout {
610 setverdict(fail, "Timeout waiting for ISD.req");
611 }
612 }
613}
Harald Welteed380d12018-06-14 13:42:11 +0200614testcase TC_vty_msisdn_isd() runs on test_CT {
615 var HlrSubscriber sub;
616 var HLR_ConnHdlr vc_conn;
617
618 f_init(false);
619
620 /* Create Subscriber */
621 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v1"));
622
623 vc_conn := f_start_handler(refers(f_TC_vty_msisdn_isd), valueof(t_Pars_sub(sub)));
624 vc_conn.done;
625}
Harald Welte09b3c502018-03-01 22:42:22 +0100626
Harald Welte958f8b42018-03-01 23:40:17 +0100627/* Test PURGE MS for CS services */
Harald Welteed380d12018-06-14 13:42:11 +0200628private function f_TC_gsup_purge_cs() runs on HLR_ConnHdlr {
629 var GSUP_PDU res;
630 res := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn);
631 res := f_perform_PURGE(g_pars.sub.imsi, OSMO_GSUP_CN_DOMAIN_CS);
632}
Harald Welte958f8b42018-03-01 23:40:17 +0100633testcase TC_gsup_purge_cs() runs on test_CT {
634 var HlrSubscriberList sl;
635 var GSUP_PDU res;
636
Harald Welteed380d12018-06-14 13:42:11 +0200637 f_init(false);
Harald Welte958f8b42018-03-01 23:40:17 +0100638 sl := f_gen_subs();
Harald Welteed380d12018-06-14 13:42:11 +0200639 f_start_handler_per_sub(refers(f_TC_gsup_purge_cs), sl);
Harald Welte958f8b42018-03-01 23:40:17 +0100640
641 setverdict(pass);
642}
643
644/* Test PURGE MS for PS services */
Harald Welteed380d12018-06-14 13:42:11 +0200645private function f_TC_gsup_purge_ps() runs on HLR_ConnHdlr {
646 var GSUP_PDU res;
647 res := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn);
648 res := f_perform_PURGE(g_pars.sub.imsi, OSMO_GSUP_CN_DOMAIN_PS);
649}
Harald Welte958f8b42018-03-01 23:40:17 +0100650testcase TC_gsup_purge_ps() runs on test_CT {
651 var HlrSubscriberList sl;
Harald Welte958f8b42018-03-01 23:40:17 +0100652
Harald Welteed380d12018-06-14 13:42:11 +0200653 f_init(false);
Harald Welte958f8b42018-03-01 23:40:17 +0100654 sl := f_gen_subs();
Harald Welteed380d12018-06-14 13:42:11 +0200655 f_start_handler_per_sub(refers(f_TC_gsup_purge_ps), sl);
Harald Welte958f8b42018-03-01 23:40:17 +0100656
657 setverdict(pass);
658}
659
660/* Test PURGEG MS procedure for unknown IMSI */
Harald Welteed380d12018-06-14 13:42:11 +0200661
662private function f_TC_gsup_purge_unknown() runs on HLR_ConnHdlr {
663 var GSUP_PDU res;
664 res := f_perform_PURGE(g_pars.sub.imsi, OSMO_GSUP_CN_DOMAIN_CS, 2);
665}
Harald Welte958f8b42018-03-01 23:40:17 +0100666testcase TC_gsup_purge_unknown() runs on test_CT {
667 var hexstring imsi := '2345743413463'H;
Harald Welteed380d12018-06-14 13:42:11 +0200668 var HLR_ConnHdlrPars pars := valueof(t_Pars(imsi));
669 var HLR_ConnHdlr vc_conn;
Harald Welte958f8b42018-03-01 23:40:17 +0100670
Harald Welteed380d12018-06-14 13:42:11 +0200671 f_init(false);
672 vc_conn := f_start_handler(refers(f_TC_ul_unknown_imsi), pars);
673 vc_conn.done;
Harald Welte958f8b42018-03-01 23:40:17 +0100674
675 setverdict(pass);
676}
677
Harald Weltec2c52552018-03-01 21:20:39 +0100678/* TODO:
679 * UL with ISD error
680 * UL with ISD timeout
Harald Weltec2c52552018-03-01 21:20:39 +0100681 * LOCATION CANCEL
682 * AUTH FAIL REP
683 * DELETE DATA after hlr_subscr_nam() change
684 * correctness
685 ** wrong message type
686 ** wrong length of PDU
687 ** too short message
688 ** missing IMSI IE
689
690 */
691
Harald Weltedf327232017-12-28 22:51:51 +0100692control {
693 execute( TC_gsup_sai_err_invalid_imsi() );
Harald Weltec2c52552018-03-01 21:20:39 +0100694 execute( TC_gsup_sai() );
695 execute( TC_gsup_ul_unknown_imsi() );
Harald Welte3f662762018-03-02 10:48:20 +0100696 execute( TC_gsup_sai_err_unknown_imsi() );
Harald Weltec2c52552018-03-01 21:20:39 +0100697 execute( TC_gsup_ul() );
698 execute( TC_vty() );
Harald Welte09b3c502018-03-01 22:42:22 +0100699 execute( TC_vty_msisdn_isd() );
Harald Welte958f8b42018-03-01 23:40:17 +0100700 execute( TC_gsup_purge_cs() );
701 execute( TC_gsup_purge_ps() );
702 execute( TC_gsup_purge_unknown() );
Harald Weltedf327232017-12-28 22:51:51 +0100703};
704
705};