blob: 51d45bac3cc223fadcd79a1fc9dab300129c8d83 [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");
94 self.stop;
95 }
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";
106
107 vc_IPA := IPA_Emulation_CT.create(id & "-IPA");
108 log("legacy= ", legacy);
109 if (not legacy) {
110 log("in not legacy case 1");
111 vc_GSUP := GSUP_Emulation_CT.create(id);
112 }
113
114 map(vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
115 if (not legacy) {
116 log("in not legacy case 2");
117 connect(vc_GSUP:GSUP, vc_IPA:IPA_GSUP_PORT);
118 connect(vc_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
119 vc_GSUP.start(GSUP_Emulation.main(ops, id));
120 } else {
121 connect(vc_IPA:IPA_GSUP_PORT, self:GSUP);
122 }
123
124 vc_IPA.start(IPA_Emulation.main_client(mp_hlr_ip, mp_hlr_gsup_port, "", -1, ccm_pars));
125
126 /* wait for incoming connection to GSUP port before proceeding */
127 timer T := 10.0;
128 T.start;
129 alt {
130 [not legacy] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
131 [legacy] GSUP.receive(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_UP}) { }
132 [] T.timeout {
133 setverdict(fail, "No connection to GSUP Port");
134 self.stop;
135 }
136 }
137}
138
139function f_init(boolean legacy := true) runs on test_CT {
140
141 /* activate default guard timer to ensure all tests eventually terminate */
142 g_Tguard.start;
143 activate(as_Tguard());
144
145 f_init_gsup("HLR_Test", legacy);
146 f_init_vty();
147
148 f_ipa_ctrl_start(mp_hlr_ip, mp_hlr_ctrl_port);
149}
150
151function f_start_handler(void_fn fn, HLR_ConnHdlrPars pars) runs on test_CT return HLR_ConnHdlr {
152 var HLR_ConnHdlr vc_conn;
153 var charstring id := testcasename();
154
155 vc_conn := HLR_ConnHdlr.create(id);
156 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
157 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
158
159 vc_conn.start(f_handler_init(fn, id, pars));
160 return vc_conn;
161}
162
163private function f_handler_init_vty() runs on HLR_ConnHdlr {
164 map(self:VTY, system:VTY);
165 f_vty_set_prompts(VTY);
166 f_vty_transceive(VTY, "enable");
167}
168
169/* first function inside ConnHdlr component; sets g_pars + starts function */
170function f_handler_init(void_fn fn, charstring id, template (omit) HLR_ConnHdlrPars pars := omit)
171runs on HLR_ConnHdlr
172{
173 if (isvalue(pars)) {
174 g_pars := valueof(pars);
175 f_create_gsup_expect(hex2str(g_pars.sub.imsi));
176 }
177 f_handler_init_vty();
178 fn.apply();
179}
180
181/***********************************************************************
182 * Subscriber creation via VTY
183 ***********************************************************************/
184
Harald Weltec2c52552018-03-01 21:20:39 +0100185template (value) HlrSubscriber t_SubNoAuth(hexstring imsi, hexstring msisdn) := {
186 imsi := imsi,
187 msisdn := msisdn,
188 aud2g := omit,
189 aud3g := omit
190}
191
192const OCT16 c_KI_DEFAULT := '000102030405060708090a0b0c0d0e0f'O;
193const OCT16 c_K_DEFAULT := '101112131415161718191a1b1c1d1e1f'O;
194const OCT16 c_OP_DEFAULT := '202122232425262728292a2b2c2d2e2f'O;
195//const OCT16 c_OPC_DEFAULT := '303132333435363738393a3b3c3d3f'O;
196
197template (value) HlrSubscriber t_Sub2G(hexstring imsi, hexstring msisdn, charstring algo) := {
198 imsi := imsi,
199 msisdn := msisdn,
200 aud2g := {
201 algo := algo,
202 ki := c_KI_DEFAULT
203 },
204 aud3g := omit
205}
206
207template (value) HlrSubscriber t_Sub3G(hexstring imsi, hexstring msisdn, charstring algo, boolean is_opc) := {
208 imsi := imsi,
209 msisdn := msisdn,
210 aud2g := omit,
211 aud3g := {
212 algo := algo,
213 k := c_K_DEFAULT,
214 op := c_OP_DEFAULT,
215 op_is_opc := is_opc
216 }
217}
218
219template (value) HlrSubscriber t_Sub2G3G(hexstring imsi, hexstring msisdn, charstring algo2g, charstring algo3g, boolean is_opc) := {
220 imsi := imsi,
221 msisdn := msisdn,
222 aud2g := {
223 algo := algo2g,
224 ki := c_KI_DEFAULT
225 },
226 aud3g := {
227 algo := algo3g,
228 k := c_K_DEFAULT,
229 op := c_OP_DEFAULT,
230 op_is_opc := is_opc
231 }
232}
233
234/* generate a variety of subscribers with different parameters */
235function f_gen_subs() runs on test_CT return HlrSubscriberList {
236 var HlrSubscriber sub;
237 var HlrSubscriberList sl := {};
238
239 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v1"));
240 sl := sl & { sub };
241
242 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v2"));
243 sl := sl & { sub };
244
245 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v3"));
246 sl := sl & { sub };
247
248 sub := valueof(t_Sub3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "milenage", false));
249 sl := sl & { sub };
250
251 sub := valueof(t_Sub3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "milenage", true));
252 sl := sl & { sub };
253
254 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
255 "comp128v1", "milenage", false));
256 sl := sl & { sub };
257
258 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
259 "comp128v2", "milenage", false));
260 sl := sl & { sub };
261
262 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
263 "comp128v3", "milenage", false));
264 sl := sl & { sub };
265
266 return sl;
267}
268
Harald Welteed380d12018-06-14 13:42:11 +0200269function f_vty_transceive_match(TELNETasp_PT pt, charstring cmd, template charstring exp_ret) {
270 var charstring ret := f_vty_transceive_ret(pt, cmd);
271 if (not match(ret, exp_ret)) {
272 setverdict(fail, "Non-matching VTY response: ", ret);
Harald Weltec2c52552018-03-01 21:20:39 +0100273 self.stop;
274 }
275}
276
Harald Welte70296062018-03-01 22:42:03 +0100277private template (value) charstring t_subscr_prefix(hexstring imsi) :=
278 "subscriber imsi " & hex2str(imsi) & " ";
279
Harald Weltec2c52552018-03-01 21:20:39 +0100280/* create a given subscriber using the VTY */
Harald Welteed380d12018-06-14 13:42:11 +0200281function f_vty_subscr_create(TELNETasp_PT VTY, HlrSubscriber sub) {
Harald Welte70296062018-03-01 22:42:03 +0100282 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
Harald Weltec2c52552018-03-01 21:20:39 +0100283 f_vty_transceive_match(VTY, prefix & "create", pattern "% Created subscriber *");
284 f_vty_transceive_match(VTY, prefix & "update msisdn " & hex2str(sub.msisdn),
285 pattern "% Updated subscriber *");
286 if (ispresent(sub.aud2g)) {
287 f_vty_transceive_match(VTY, prefix & "update aud2g " & sub.aud2g.algo &
288 " ki " & oct2str(sub.aud2g.ki),
289 pattern "");
290 } else {
291 f_vty_transceive_match(VTY, prefix & "update aud2g none", pattern "");
292 }
293
294 if (ispresent(sub.aud3g)) {
295 var charstring op_mode := "op";
296 if (sub.aud3g.op_is_opc) {
297 op_mode := "opc";
298 }
299 f_vty_transceive_match(VTY, prefix & "update aud3g " & sub.aud3g.algo &
300 " k " & oct2str(sub.aud3g.k) & " " & op_mode & " " &
301 oct2str(sub.aud3g.op), pattern "");
302 } else {
303 f_vty_transceive_match(VTY, prefix & "update aud3g none", pattern "");
304 }
305}
306
Harald Welteed380d12018-06-14 13:42:11 +0200307function f_vty_subscr_update_msisdn(TELNETasp_PT VTY, HlrSubscriber sub, hexstring new_msisdn) {
Harald Welte09b3c502018-03-01 22:42:22 +0100308 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
309 f_vty_transceive_match(VTY, prefix & "update msisdn " & hex2str(new_msisdn),
310 pattern "% Updated subscriber *");
311}
312
Harald Weltec2c52552018-03-01 21:20:39 +0100313/* perform 'delete' on subscriber */
Harald Welteed380d12018-06-14 13:42:11 +0200314function f_vty_subscr_delete(TELNETasp_PT VTY, HlrSubscriber sub) {
Harald Welte70296062018-03-01 22:42:03 +0100315 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
Harald Weltec2c52552018-03-01 21:20:39 +0100316 f_vty_transceive_match(VTY, prefix & "delete",
317 pattern "% Deleted subscriber for IMSI *");
318}
319
320/* perform 'show' on subscriber; match result with pattern 'exp' */
Harald Welteed380d12018-06-14 13:42:11 +0200321function f_vty_subscr_show(TELNETasp_PT VTY, HlrSubscriber sub, template charstring exp) {
Harald Welte70296062018-03-01 22:42:03 +0100322 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
Harald Weltec2c52552018-03-01 21:20:39 +0100323 f_vty_transceive_match(VTY, prefix & "show", exp);
324}
325
326
Harald Welteed380d12018-06-14 13:42:11 +0200327/***********************************************************************
328 * Helper functions for ConnHdlr
329 ***********************************************************************/
330
Harald Weltec2c52552018-03-01 21:20:39 +0100331/* perform SendAuthInfo for given imsi, return the GSUP response/error */
332function f_perform_SAI(hexstring imsi, template (omit) integer exp_err_cause := omit)
Harald Welteed380d12018-06-14 13:42:11 +0200333runs on HLR_ConnHdlr return GSUP_PDU {
Harald Weltec2c52552018-03-01 21:20:39 +0100334 var GSUP_PDU ret;
335 timer T := 3.0;
336 var boolean exp_fail := false;
337 if (not istemplatekind(exp_err_cause, "omit")) {
338 exp_fail := true;
339 }
340
341 GSUP.send(valueof(ts_GSUP_SAI_REQ(imsi)));
342 T.start;
343 alt {
344 [exp_fail] GSUP.receive(tr_GSUP_SAI_ERR(imsi, exp_err_cause)) -> value ret {
345 setverdict(pass);
346 }
347 [exp_fail] GSUP.receive(tr_GSUP_SAI_ERR(imsi, ?)) -> value ret {
348 setverdict(fail, "Unexpected SAI ERROR Cause");
349 }
350 [exp_fail] GSUP.receive(tr_GSUP_SAI_RES(imsi)) -> value ret {
351 setverdict(fail, "Unexpected SAI.res for unknown IMSI");
352 }
353 [not exp_fail] GSUP.receive(tr_GSUP_SAI_ERR(imsi, ?)) -> value ret {
354 setverdict(fail, "Unexpected SAI ERROR");
355 }
356 [not exp_fail] GSUP.receive(tr_GSUP_SAI_RES(imsi)) -> value ret {
357 setverdict(pass);
358 }
359 [] GSUP.receive { repeat; }
360 [] T.timeout {
361 setverdict(fail, "Timeout waiting for SAI response");
362 self.stop;
363 }
364 }
365 return ret;
366}
367
368function f_perform_UL(hexstring imsi, template hexstring msisdn,
369 template (omit) integer exp_err_cause := omit)
Harald Welteed380d12018-06-14 13:42:11 +0200370runs on HLR_ConnHdlr return GSUP_PDU {
Harald Weltec2c52552018-03-01 21:20:39 +0100371 var GSUP_PDU ret;
372 timer T := 3.0;
373 var boolean exp_fail := false;
374 var boolean isd_done := false;
375 if (not istemplatekind(exp_err_cause, "omit")) {
376 exp_fail := true;
377 }
378
379 GSUP.send(valueof(ts_GSUP_UL_REQ(imsi)));
380 T.start;
381 alt {
382 [exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, exp_err_cause)) -> value ret {
383 setverdict(pass);
384 }
385 [exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, ?)) -> value ret {
386 setverdict(fail, "Unexpected UL ERROR Cause");
387 }
388 [exp_fail] GSUP.receive(tr_GSUP_UL_RES(imsi)) -> value ret {
389 setverdict(fail, "Unexpected UL.res for unknown IMSI");
390 }
391 [exp_fail] GSUP.receive(tr_GSUP_ISD_REQ(imsi)) -> value ret {
392 setverdict(fail, "Unexpected ISD.req in error case");
393 }
394 [not exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, ?)) -> value ret {
395 setverdict(fail, "Unexpected UL ERROR");
396 }
397 [not exp_fail and not isd_done] GSUP.receive(tr_GSUP_ISD_REQ(imsi, msisdn)) -> value ret {
398 GSUP.send(ts_GSUP_ISD_RES(imsi));
399 isd_done := true;
Harald Welte8f0c9332018-03-01 23:38:40 +0100400 repeat;
Harald Weltec2c52552018-03-01 21:20:39 +0100401 }
402 [not exp_fail and isd_done] GSUP.receive(tr_GSUP_UL_RES(imsi)) -> value ret {
403 setverdict(pass);
404 }
405 [] GSUP.receive { repeat; }
406 [] T.timeout {
407 setverdict(fail, "Timeout waiting for UL response");
408 self.stop;
409 }
410 }
411 return ret;
412}
413
Harald Welte958f8b42018-03-01 23:40:17 +0100414/* perform PurgeMS for given imsi, return the GSUP response/error */
415function f_perform_PURGE(hexstring imsi, GSUP_CnDomain cn_dom,
416 template (omit) integer exp_err_cause := omit)
Harald Welteed380d12018-06-14 13:42:11 +0200417runs on HLR_ConnHdlr return GSUP_PDU {
Harald Welte958f8b42018-03-01 23:40:17 +0100418 var GSUP_PDU ret;
419 timer T := 3.0;
420 var boolean exp_fail := false;
421 if (not istemplatekind(exp_err_cause, "omit")) {
422 exp_fail := true;
423 }
424
425 GSUP.send(valueof(ts_GSUP_PURGE_MS_REQ(imsi, cn_dom)));
426 T.start;
427 alt {
428 [exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_ERR(imsi, exp_err_cause)) -> value ret {
429 setverdict(pass);
430 }
431 [exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_ERR(imsi, ?)) -> value ret {
432 setverdict(fail, "Unexpected PURGE ERROR Cause");
433 }
434 [exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_RES(imsi)) -> value ret {
435 setverdict(fail, "Unexpected PURGE.res for unknown IMSI");
436 }
437 [not exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_ERR(imsi, ?)) -> value ret {
438 setverdict(fail, "Unexpected PURGE ERROR");
439 }
440 [not exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_RES(imsi)) -> value ret {
441 setverdict(pass);
442 }
443 [] GSUP.receive { repeat; }
444 [] T.timeout {
445 setverdict(fail, "Timeout waiting for PURGE response");
446 self.stop;
447 }
448 }
449 return ret;
450}
451
452
Harald Welteed380d12018-06-14 13:42:11 +0200453/***********************************************************************
454 * Testcases
455 ***********************************************************************/
456
457/* 23.003 Section 2.2 clearly states that an IMSI with less
458 * than 5 digits is impossible. Even 5 digits is still questionable */
459private function f_TC_gsup_sai_err_invalid_imsi() runs on HLR_ConnHdlr {
Harald Weltec2c52552018-03-01 21:20:39 +0100460 var GSUP_PDU res;
Harald Welteed380d12018-06-14 13:42:11 +0200461 res := f_perform_SAI(g_pars.sub.imsi, 96); /* Invalid Mandatory information */
462 setverdict(pass);
463}
464testcase TC_gsup_sai_err_invalid_imsi() runs on test_CT {
465 var HLR_ConnHdlr vc_conn;
466 var HLR_ConnHdlrPars pars := valueof(t_Pars('0123'H));
467 f_init(false);
468 vc_conn := f_start_handler(refers(f_TC_gsup_sai_err_invalid_imsi), pars);
469 vc_conn.done;
470}
Harald Weltec2c52552018-03-01 21:20:39 +0100471
Harald Weltec2c52552018-03-01 21:20:39 +0100472
Harald Welteed380d12018-06-14 13:42:11 +0200473private function f_TC_gsup_sai_err_unknown_imsi() runs on HLR_ConnHdlr {
474 var GSUP_PDU res;
475 res := f_perform_SAI(g_pars.sub.imsi, 2);
Harald Weltec2c52552018-03-01 21:20:39 +0100476 setverdict(pass);
477}
478
Harald Welte3f662762018-03-02 10:48:20 +0100479testcase TC_gsup_sai_err_unknown_imsi() runs on test_CT {
Harald Welteed380d12018-06-14 13:42:11 +0200480 var HLR_ConnHdlr vc_conn;
481 var HLR_ConnHdlrPars pars := valueof(t_Pars(f_rnd_imsi('26242'H)));
482 f_init(false);
483 vc_conn := f_start_handler(refers(f_TC_gsup_sai_err_unknown_imsi), pars);
484 vc_conn.done;
Harald Welte3f662762018-03-02 10:48:20 +0100485}
486
Harald Welteed380d12018-06-14 13:42:11 +0200487function f_start_handler_per_sub(void_fn fn, HlrSubscriberList sl) runs on test_CT {
488 for (var integer i := 0; i < sizeof(sl); i := i+1) {
489 var HlrSubscriber sub := sl[i];
490 var HLR_ConnHdlrPars pars := valueof(t_Pars_sub(sub));
491 var HLR_ConnHdlr vc_conn;
492
493 f_vty_subscr_create(VTY, sub);
494 vc_conn := f_start_handler(fn, pars);
495 vc_conn.done;
496 f_vty_subscr_delete(VTY, sub);
497 }
498}
Harald Welte3f662762018-03-02 10:48:20 +0100499
Harald Weltec2c52552018-03-01 21:20:39 +0100500/* test SAI for a number of different subscriber cases (algo, 2g/3g, ...) */
Harald Welteed380d12018-06-14 13:42:11 +0200501private function f_TC_gsup_sai() runs on HLR_ConnHdlr {
502 var GSUP_PDU res;
503 res := f_perform_SAI(g_pars.sub.imsi);
504 /* TODO: match if tuple[s] matches expectation */
505 setverdict(pass);
506}
Harald Weltec2c52552018-03-01 21:20:39 +0100507testcase TC_gsup_sai() runs on test_CT {
508 var HlrSubscriberList sl;
509 var GSUP_PDU res;
510
Harald Welteed380d12018-06-14 13:42:11 +0200511 f_init(false);
Harald Weltec2c52552018-03-01 21:20:39 +0100512
513 sl := f_gen_subs();
Harald Welteed380d12018-06-14 13:42:11 +0200514 f_start_handler_per_sub(refers(f_TC_gsup_sai), sl);
Harald Weltec2c52552018-03-01 21:20:39 +0100515
516 setverdict(pass);
517}
518
519/* test UL for unknown IMSI */
Harald Welteed380d12018-06-14 13:42:11 +0200520private function f_TC_ul_unknown_imsi() runs on HLR_ConnHdlr {
Harald Weltec2c52552018-03-01 21:20:39 +0100521 var GSUP_PDU res;
Harald Welteed380d12018-06-14 13:42:11 +0200522 res := f_perform_UL(g_pars.sub.imsi, ?, 2);
Harald Weltec2c52552018-03-01 21:20:39 +0100523 setverdict(pass);
524}
Harald Welteed380d12018-06-14 13:42:11 +0200525testcase TC_gsup_ul_unknown_imsi() runs on test_CT {
526 var hexstring imsi := f_rnd_imsi('26242'H);
527 var HLR_ConnHdlrPars pars := valueof(t_Pars(imsi));
528 var HLR_ConnHdlr vc_conn;
Harald Weltec2c52552018-03-01 21:20:39 +0100529
Harald Welteed380d12018-06-14 13:42:11 +0200530 f_init(false);
531 vc_conn := f_start_handler(refers(f_TC_ul_unknown_imsi), pars);
532 vc_conn.done;
533}
534
535/* test UL for a number of different subscriber cases (algo, 2g/3g, ...) */
536private function f_TC_gsup_ul() runs on HLR_ConnHdlr {
537 var GSUP_PDU res;
538 res := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn);
539 setverdict(pass);
540}
Harald Weltec2c52552018-03-01 21:20:39 +0100541testcase TC_gsup_ul() runs on test_CT {
542 var HlrSubscriberList sl;
543 var GSUP_PDU res;
544
Harald Welteed380d12018-06-14 13:42:11 +0200545 f_init(false);
Harald Weltec2c52552018-03-01 21:20:39 +0100546 sl := f_gen_subs();
Harald Welteed380d12018-06-14 13:42:11 +0200547 f_start_handler_per_sub(refers(f_TC_gsup_ul), sl);
Harald Weltec2c52552018-03-01 21:20:39 +0100548
549 setverdict(pass);
550}
551
552/* Test only the VTY commands */
553testcase TC_vty() runs on test_CT {
554 var HlrSubscriber sub;
555
556 f_init();
557
558 /* we're not using f_gen_subs() here as the expect pattern for the 'show' are different
559 * from case to case */
560 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v1"));
Harald Welteed380d12018-06-14 13:42:11 +0200561 f_vty_subscr_create(VTY, sub);
562 f_vty_subscr_show(VTY, sub, pattern "*IMSI: *2G auth: COMP128v1*");
563 f_vty_subscr_delete(VTY, sub);
Harald Weltec2c52552018-03-01 21:20:39 +0100564
565 sub := valueof(t_Sub3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
566 "milenage", false));
Harald Welteed380d12018-06-14 13:42:11 +0200567 f_vty_subscr_create(VTY, sub);
568 f_vty_subscr_show(VTY, sub, pattern "*IMSI: *3G auth: MILENAGE*");
569 f_vty_subscr_delete(VTY, sub);
Harald Weltec2c52552018-03-01 21:20:39 +0100570
571 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
572 "comp128v1", "milenage", false));
Harald Welteed380d12018-06-14 13:42:11 +0200573 f_vty_subscr_create(VTY, sub);
574 f_vty_subscr_show(VTY, sub, pattern "*IMSI: *2G auth: COMP128v1*3G auth: MILENAGE*");
575 f_vty_subscr_delete(VTY, sub);
Harald Weltec2c52552018-03-01 21:20:39 +0100576
577 setverdict(pass);
578}
579
Harald Welte09b3c502018-03-01 22:42:22 +0100580/* VTY changes to MSISDN should result in ISD to current VLR */
Harald Welteed380d12018-06-14 13:42:11 +0200581private function f_TC_vty_msisdn_isd() runs on HLR_ConnHdlr {
Harald Welte09b3c502018-03-01 22:42:22 +0100582 var hexstring new_msisdn;
583 var GSUP_PDU res;
584 timer T := 5.0;
585
Harald Welte09b3c502018-03-01 22:42:22 +0100586 /* Create Subscriber */
Harald Welteed380d12018-06-14 13:42:11 +0200587 f_vty_subscr_create(VTY, g_pars.sub);
Harald Welte09b3c502018-03-01 22:42:22 +0100588
589 /* Perform UpdateLocation (VLR now known to HLR) */
Harald Welteed380d12018-06-14 13:42:11 +0200590 res := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn);
Harald Welte09b3c502018-03-01 22:42:22 +0100591
592 /* Then change IMSI via VTY */
593 new_msisdn := '49161'H & f_rnd_hexstring(7, 9);
Harald Welteed380d12018-06-14 13:42:11 +0200594 f_vty_subscr_update_msisdn(VTY, g_pars.sub, new_msisdn);
Harald Welte09b3c502018-03-01 22:42:22 +0100595 /* And expect InsertSubscriberData as result */
596 T.start;
597 alt {
Harald Welteed380d12018-06-14 13:42:11 +0200598 [] GSUP.receive(tr_GSUP_ISD_REQ(g_pars.sub.imsi, new_msisdn)) {
599 GSUP.send(ts_GSUP_ISD_RES(g_pars.sub.imsi));
600 g_pars.sub.msisdn := new_msisdn;
Harald Welte09b3c502018-03-01 22:42:22 +0100601 setverdict(pass);
602 }
Harald Welteed380d12018-06-14 13:42:11 +0200603 [] GSUP.receive(tr_GSUP_ISD_REQ(g_pars.sub.imsi, g_pars.sub.msisdn)) {
Stefan Sperling7c096872018-04-09 11:24:22 +0200604 log("received ISD req with old MSISDN");
605 setverdict(fail);
606 }
Harald Welte09b3c502018-03-01 22:42:22 +0100607 [] GSUP.receive { repeat; }
608 [] T.timeout {
609 setverdict(fail, "Timeout waiting for ISD.req");
610 }
611 }
612}
Harald Welteed380d12018-06-14 13:42:11 +0200613testcase TC_vty_msisdn_isd() runs on test_CT {
614 var HlrSubscriber sub;
615 var HLR_ConnHdlr vc_conn;
616
617 f_init(false);
618
619 /* Create Subscriber */
620 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v1"));
621
622 vc_conn := f_start_handler(refers(f_TC_vty_msisdn_isd), valueof(t_Pars_sub(sub)));
623 vc_conn.done;
624}
Harald Welte09b3c502018-03-01 22:42:22 +0100625
Harald Welte958f8b42018-03-01 23:40:17 +0100626/* Test PURGE MS for CS services */
Harald Welteed380d12018-06-14 13:42:11 +0200627private function f_TC_gsup_purge_cs() runs on HLR_ConnHdlr {
628 var GSUP_PDU res;
629 res := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn);
630 res := f_perform_PURGE(g_pars.sub.imsi, OSMO_GSUP_CN_DOMAIN_CS);
631}
Harald Welte958f8b42018-03-01 23:40:17 +0100632testcase TC_gsup_purge_cs() runs on test_CT {
633 var HlrSubscriberList sl;
634 var GSUP_PDU res;
635
Harald Welteed380d12018-06-14 13:42:11 +0200636 f_init(false);
Harald Welte958f8b42018-03-01 23:40:17 +0100637 sl := f_gen_subs();
Harald Welteed380d12018-06-14 13:42:11 +0200638 f_start_handler_per_sub(refers(f_TC_gsup_purge_cs), sl);
Harald Welte958f8b42018-03-01 23:40:17 +0100639
640 setverdict(pass);
641}
642
643/* Test PURGE MS for PS services */
Harald Welteed380d12018-06-14 13:42:11 +0200644private function f_TC_gsup_purge_ps() runs on HLR_ConnHdlr {
645 var GSUP_PDU res;
646 res := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn);
647 res := f_perform_PURGE(g_pars.sub.imsi, OSMO_GSUP_CN_DOMAIN_PS);
648}
Harald Welte958f8b42018-03-01 23:40:17 +0100649testcase TC_gsup_purge_ps() runs on test_CT {
650 var HlrSubscriberList sl;
Harald Welte958f8b42018-03-01 23:40:17 +0100651
Harald Welteed380d12018-06-14 13:42:11 +0200652 f_init(false);
Harald Welte958f8b42018-03-01 23:40:17 +0100653 sl := f_gen_subs();
Harald Welteed380d12018-06-14 13:42:11 +0200654 f_start_handler_per_sub(refers(f_TC_gsup_purge_ps), sl);
Harald Welte958f8b42018-03-01 23:40:17 +0100655
656 setverdict(pass);
657}
658
659/* Test PURGEG MS procedure for unknown IMSI */
Harald Welteed380d12018-06-14 13:42:11 +0200660
661private function f_TC_gsup_purge_unknown() runs on HLR_ConnHdlr {
662 var GSUP_PDU res;
663 res := f_perform_PURGE(g_pars.sub.imsi, OSMO_GSUP_CN_DOMAIN_CS, 2);
664}
Harald Welte958f8b42018-03-01 23:40:17 +0100665testcase TC_gsup_purge_unknown() runs on test_CT {
666 var hexstring imsi := '2345743413463'H;
Harald Welteed380d12018-06-14 13:42:11 +0200667 var HLR_ConnHdlrPars pars := valueof(t_Pars(imsi));
668 var HLR_ConnHdlr vc_conn;
Harald Welte958f8b42018-03-01 23:40:17 +0100669
Harald Welteed380d12018-06-14 13:42:11 +0200670 f_init(false);
671 vc_conn := f_start_handler(refers(f_TC_ul_unknown_imsi), pars);
672 vc_conn.done;
Harald Welte958f8b42018-03-01 23:40:17 +0100673
674 setverdict(pass);
675}
676
Harald Weltec2c52552018-03-01 21:20:39 +0100677/* TODO:
678 * UL with ISD error
679 * UL with ISD timeout
Harald Weltec2c52552018-03-01 21:20:39 +0100680 * LOCATION CANCEL
681 * AUTH FAIL REP
682 * DELETE DATA after hlr_subscr_nam() change
683 * correctness
684 ** wrong message type
685 ** wrong length of PDU
686 ** too short message
687 ** missing IMSI IE
688
689 */
690
Harald Weltedf327232017-12-28 22:51:51 +0100691control {
692 execute( TC_gsup_sai_err_invalid_imsi() );
Harald Weltec2c52552018-03-01 21:20:39 +0100693 execute( TC_gsup_sai() );
694 execute( TC_gsup_ul_unknown_imsi() );
Harald Welte3f662762018-03-02 10:48:20 +0100695 execute( TC_gsup_sai_err_unknown_imsi() );
Harald Weltec2c52552018-03-01 21:20:39 +0100696 execute( TC_gsup_ul() );
697 execute( TC_vty() );
Harald Welte09b3c502018-03-01 22:42:22 +0100698 execute( TC_vty_msisdn_isd() );
Harald Welte958f8b42018-03-01 23:40:17 +0100699 execute( TC_gsup_purge_cs() );
700 execute( TC_gsup_purge_ps() );
701 execute( TC_gsup_purge_unknown() );
Harald Weltedf327232017-12-28 22:51:51 +0100702};
703
704};