blob: 8b216266d89384e780def4723d886317a24016da [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;
4import from IPA_Emulation all;
5
Harald Weltec2c52552018-03-01 21:20:39 +01006import from General_Types all;
7import from Osmocom_Types all;
Harald Welte39b82d32018-03-01 10:21:29 +01008import from Osmocom_CTRL_Adapter all;
9
10import from Osmocom_VTY_Functions all;
11import from TELNETasp_PortType all;
12
13type component test_CT extends CTRL_Adapter_CT {
Harald Weltedf327232017-12-28 22:51:51 +010014 var IPA_Emulation_CT vc_IPA;
15 var IPA_CCM_Parameters ccm_pars;
16 port IPA_GSUP_PT GSUP;
Harald Welte39b82d32018-03-01 10:21:29 +010017
18 port TELNETasp_PT VTY;
Harald Weltec2c52552018-03-01 21:20:39 +010019
20 timer g_Tguard := 10.0;
Harald Weltedf327232017-12-28 22:51:51 +010021};
22
23modulepar {
24 charstring mp_hlr_ip := "127.0.0.1";
25 integer mp_hlr_gsup_port := 4222;
26 integer mp_hlr_ctrl_port := 4259;
27};
28
Harald Weltec2c52552018-03-01 21:20:39 +010029type record HlrSubscrAud2G {
30 charstring algo,
31 OCT16 ki
32}
33
34type record HlrSubscrAud3G {
35 charstring algo,
36 OCT16 k,
37 OCT16 op,
38 boolean op_is_opc
39}
40
41type record HlrSubscriber {
42 hexstring imsi,
43 hexstring msisdn,
44 HlrSubscrAud2G aud2g optional,
45 HlrSubscrAud3G aud3g optional
46}
47
48type record of HlrSubscriber HlrSubscriberList;
49
50template (value) HlrSubscriber t_SubNoAuth(hexstring imsi, hexstring msisdn) := {
51 imsi := imsi,
52 msisdn := msisdn,
53 aud2g := omit,
54 aud3g := omit
55}
56
57const OCT16 c_KI_DEFAULT := '000102030405060708090a0b0c0d0e0f'O;
58const OCT16 c_K_DEFAULT := '101112131415161718191a1b1c1d1e1f'O;
59const OCT16 c_OP_DEFAULT := '202122232425262728292a2b2c2d2e2f'O;
60//const OCT16 c_OPC_DEFAULT := '303132333435363738393a3b3c3d3f'O;
61
62template (value) HlrSubscriber t_Sub2G(hexstring imsi, hexstring msisdn, charstring algo) := {
63 imsi := imsi,
64 msisdn := msisdn,
65 aud2g := {
66 algo := algo,
67 ki := c_KI_DEFAULT
68 },
69 aud3g := omit
70}
71
72template (value) HlrSubscriber t_Sub3G(hexstring imsi, hexstring msisdn, charstring algo, boolean is_opc) := {
73 imsi := imsi,
74 msisdn := msisdn,
75 aud2g := omit,
76 aud3g := {
77 algo := algo,
78 k := c_K_DEFAULT,
79 op := c_OP_DEFAULT,
80 op_is_opc := is_opc
81 }
82}
83
84template (value) HlrSubscriber t_Sub2G3G(hexstring imsi, hexstring msisdn, charstring algo2g, charstring algo3g, boolean is_opc) := {
85 imsi := imsi,
86 msisdn := msisdn,
87 aud2g := {
88 algo := algo2g,
89 ki := c_KI_DEFAULT
90 },
91 aud3g := {
92 algo := algo3g,
93 k := c_K_DEFAULT,
94 op := c_OP_DEFAULT,
95 op_is_opc := is_opc
96 }
97}
98
99/* generate a variety of subscribers with different parameters */
100function f_gen_subs() runs on test_CT return HlrSubscriberList {
101 var HlrSubscriber sub;
102 var HlrSubscriberList sl := {};
103
104 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v1"));
105 sl := sl & { sub };
106
107 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v2"));
108 sl := sl & { sub };
109
110 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v3"));
111 sl := sl & { sub };
112
113 sub := valueof(t_Sub3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "milenage", false));
114 sl := sl & { sub };
115
116 sub := valueof(t_Sub3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "milenage", true));
117 sl := sl & { sub };
118
119 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
120 "comp128v1", "milenage", false));
121 sl := sl & { sub };
122
123 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
124 "comp128v2", "milenage", false));
125 sl := sl & { sub };
126
127 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
128 "comp128v3", "milenage", false));
129 sl := sl & { sub };
130
131 return sl;
132}
133
Harald Welte39b82d32018-03-01 10:21:29 +0100134function f_init_vty() runs on test_CT {
135 map(self:VTY, system:VTY);
136 f_vty_set_prompts(VTY);
137 f_vty_transceive(VTY, "enable");
138}
139
Harald Weltec2c52552018-03-01 21:20:39 +0100140private altstep as_Tguard() runs on test_CT {
141 [] g_Tguard.timeout {
142 setverdict(fail, "g_Tguard timeout");
143 self.stop;
144 }
145}
146
Harald Weltedf327232017-12-28 22:51:51 +0100147function f_init() runs on test_CT {
Harald Weltec2c52552018-03-01 21:20:39 +0100148
149 /* activate default guard timer to ensure all tests eventually terminate */
150 g_Tguard.start;
151 activate(as_Tguard());
152
Harald Weltedf327232017-12-28 22:51:51 +0100153 ccm_pars := c_IPA_default_ccm_pars;
154 ccm_pars.name := "Osmocom TTCN-3 GSUP Simulator";
155
156 vc_IPA := IPA_Emulation_CT.create("IPA");
157 map(vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
158 connect(vc_IPA:IPA_GSUP_PORT, self:GSUP);
159 vc_IPA.start(IPA_Emulation.main_client(mp_hlr_ip, mp_hlr_gsup_port, "", -1, ccm_pars));
Harald Welte39b82d32018-03-01 10:21:29 +0100160
Harald Welte79420cc2018-03-01 16:49:29 +0100161 timer T:= 10.0;
162 alt {
163 [] GSUP.receive(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_UP}) { }
164 [] T.timeout {
165 setverdict(fail, "Timeout waiting for GSUP IPA Link to come up");
166 self.stop;
167 }
168 }
169
Harald Welte39b82d32018-03-01 10:21:29 +0100170 f_init_vty();
171
172 f_ipa_ctrl_start(mp_hlr_ip, mp_hlr_ctrl_port);
Harald Weltedf327232017-12-28 22:51:51 +0100173}
174
Harald Weltec2c52552018-03-01 21:20:39 +0100175function f_vty_transceive_match(TELNETasp_PT pt, charstring cmd, template charstring exp_ret) {
176 var charstring ret := f_vty_transceive_ret(pt, cmd);
177 if (not match(ret, exp_ret)) {
178 setverdict(fail, "Non-matching VTY response: ", ret);
179 self.stop;
Harald Weltedf327232017-12-28 22:51:51 +0100180 }
181}
182
Harald Welte70296062018-03-01 22:42:03 +0100183private template (value) charstring t_subscr_prefix(hexstring imsi) :=
184 "subscriber imsi " & hex2str(imsi) & " ";
185
Harald Weltec2c52552018-03-01 21:20:39 +0100186/* create a given subscriber using the VTY */
187function f_vty_subscr_create(HlrSubscriber sub) runs on test_CT {
Harald Welte70296062018-03-01 22:42:03 +0100188 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
Harald Weltec2c52552018-03-01 21:20:39 +0100189 f_vty_transceive_match(VTY, prefix & "create", pattern "% Created subscriber *");
190 f_vty_transceive_match(VTY, prefix & "update msisdn " & hex2str(sub.msisdn),
191 pattern "% Updated subscriber *");
192 if (ispresent(sub.aud2g)) {
193 f_vty_transceive_match(VTY, prefix & "update aud2g " & sub.aud2g.algo &
194 " ki " & oct2str(sub.aud2g.ki),
195 pattern "");
196 } else {
197 f_vty_transceive_match(VTY, prefix & "update aud2g none", pattern "");
198 }
199
200 if (ispresent(sub.aud3g)) {
201 var charstring op_mode := "op";
202 if (sub.aud3g.op_is_opc) {
203 op_mode := "opc";
204 }
205 f_vty_transceive_match(VTY, prefix & "update aud3g " & sub.aud3g.algo &
206 " k " & oct2str(sub.aud3g.k) & " " & op_mode & " " &
207 oct2str(sub.aud3g.op), pattern "");
208 } else {
209 f_vty_transceive_match(VTY, prefix & "update aud3g none", pattern "");
210 }
211}
212
Harald Welte09b3c502018-03-01 22:42:22 +0100213function f_vty_subscr_update_msisdn(HlrSubscriber sub, hexstring new_msisdn) runs on test_CT {
214 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
215 f_vty_transceive_match(VTY, prefix & "update msisdn " & hex2str(new_msisdn),
216 pattern "% Updated subscriber *");
217}
218
Harald Weltec2c52552018-03-01 21:20:39 +0100219/* perform 'delete' on subscriber */
220function f_vty_subscr_delete(HlrSubscriber sub) runs on test_CT {
Harald Welte70296062018-03-01 22:42:03 +0100221 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
Harald Weltec2c52552018-03-01 21:20:39 +0100222 f_vty_transceive_match(VTY, prefix & "delete",
223 pattern "% Deleted subscriber for IMSI *");
224}
225
226/* perform 'show' on subscriber; match result with pattern 'exp' */
227function f_vty_subscr_show(HlrSubscriber sub, template charstring exp) runs on test_CT {
Harald Welte70296062018-03-01 22:42:03 +0100228 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
Harald Weltec2c52552018-03-01 21:20:39 +0100229 f_vty_transceive_match(VTY, prefix & "show", exp);
230}
231
232
233/* perform SendAuthInfo for given imsi, return the GSUP response/error */
234function f_perform_SAI(hexstring imsi, template (omit) integer exp_err_cause := omit)
235runs on test_CT return GSUP_PDU {
236 var GSUP_PDU ret;
237 timer T := 3.0;
238 var boolean exp_fail := false;
239 if (not istemplatekind(exp_err_cause, "omit")) {
240 exp_fail := true;
241 }
242
243 GSUP.send(valueof(ts_GSUP_SAI_REQ(imsi)));
244 T.start;
245 alt {
246 [exp_fail] GSUP.receive(tr_GSUP_SAI_ERR(imsi, exp_err_cause)) -> value ret {
247 setverdict(pass);
248 }
249 [exp_fail] GSUP.receive(tr_GSUP_SAI_ERR(imsi, ?)) -> value ret {
250 setverdict(fail, "Unexpected SAI ERROR Cause");
251 }
252 [exp_fail] GSUP.receive(tr_GSUP_SAI_RES(imsi)) -> value ret {
253 setverdict(fail, "Unexpected SAI.res for unknown IMSI");
254 }
255 [not exp_fail] GSUP.receive(tr_GSUP_SAI_ERR(imsi, ?)) -> value ret {
256 setverdict(fail, "Unexpected SAI ERROR");
257 }
258 [not exp_fail] GSUP.receive(tr_GSUP_SAI_RES(imsi)) -> value ret {
259 setverdict(pass);
260 }
261 [] GSUP.receive { repeat; }
262 [] T.timeout {
263 setverdict(fail, "Timeout waiting for SAI response");
264 self.stop;
265 }
266 }
267 return ret;
268}
269
270function f_perform_UL(hexstring imsi, template hexstring msisdn,
271 template (omit) integer exp_err_cause := omit)
272runs on test_CT return GSUP_PDU {
273 var GSUP_PDU ret;
274 timer T := 3.0;
275 var boolean exp_fail := false;
276 var boolean isd_done := false;
277 if (not istemplatekind(exp_err_cause, "omit")) {
278 exp_fail := true;
279 }
280
281 GSUP.send(valueof(ts_GSUP_UL_REQ(imsi)));
282 T.start;
283 alt {
284 [exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, exp_err_cause)) -> value ret {
285 setverdict(pass);
286 }
287 [exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, ?)) -> value ret {
288 setverdict(fail, "Unexpected UL ERROR Cause");
289 }
290 [exp_fail] GSUP.receive(tr_GSUP_UL_RES(imsi)) -> value ret {
291 setverdict(fail, "Unexpected UL.res for unknown IMSI");
292 }
293 [exp_fail] GSUP.receive(tr_GSUP_ISD_REQ(imsi)) -> value ret {
294 setverdict(fail, "Unexpected ISD.req in error case");
295 }
296 [not exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, ?)) -> value ret {
297 setverdict(fail, "Unexpected UL ERROR");
298 }
299 [not exp_fail and not isd_done] GSUP.receive(tr_GSUP_ISD_REQ(imsi, msisdn)) -> value ret {
300 GSUP.send(ts_GSUP_ISD_RES(imsi));
301 isd_done := true;
Harald Welte8f0c9332018-03-01 23:38:40 +0100302 repeat;
Harald Weltec2c52552018-03-01 21:20:39 +0100303 }
304 [not exp_fail and isd_done] GSUP.receive(tr_GSUP_UL_RES(imsi)) -> value ret {
305 setverdict(pass);
306 }
307 [] GSUP.receive { repeat; }
308 [] T.timeout {
309 setverdict(fail, "Timeout waiting for UL response");
310 self.stop;
311 }
312 }
313 return ret;
314}
315
Harald Welte958f8b42018-03-01 23:40:17 +0100316/* perform PurgeMS for given imsi, return the GSUP response/error */
317function f_perform_PURGE(hexstring imsi, GSUP_CnDomain cn_dom,
318 template (omit) integer exp_err_cause := omit)
319runs on test_CT return GSUP_PDU {
320 var GSUP_PDU ret;
321 timer T := 3.0;
322 var boolean exp_fail := false;
323 if (not istemplatekind(exp_err_cause, "omit")) {
324 exp_fail := true;
325 }
326
327 GSUP.send(valueof(ts_GSUP_PURGE_MS_REQ(imsi, cn_dom)));
328 T.start;
329 alt {
330 [exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_ERR(imsi, exp_err_cause)) -> value ret {
331 setverdict(pass);
332 }
333 [exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_ERR(imsi, ?)) -> value ret {
334 setverdict(fail, "Unexpected PURGE ERROR Cause");
335 }
336 [exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_RES(imsi)) -> value ret {
337 setverdict(fail, "Unexpected PURGE.res for unknown IMSI");
338 }
339 [not exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_ERR(imsi, ?)) -> value ret {
340 setverdict(fail, "Unexpected PURGE ERROR");
341 }
342 [not exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_RES(imsi)) -> value ret {
343 setverdict(pass);
344 }
345 [] GSUP.receive { repeat; }
346 [] T.timeout {
347 setverdict(fail, "Timeout waiting for PURGE response");
348 self.stop;
349 }
350 }
351 return ret;
352}
353
354
Harald Weltec2c52552018-03-01 21:20:39 +0100355testcase TC_gsup_sai_err_invalid_imsi() runs on test_CT {
Harald Welte3f662762018-03-02 10:48:20 +0100356 /* 23.003 Section 2.2 clearly states that an IMSI with less
357 * than 5 digits is impossible. Even 5 digits is still questionable */
358 var hexstring imsi := '0123'H;
Harald Weltec2c52552018-03-01 21:20:39 +0100359 var GSUP_PDU res;
360
361 f_init();
362
Harald Welte3f662762018-03-02 10:48:20 +0100363 res := f_perform_SAI(imsi, 96); /* Invalid Mandatory information */
Harald Weltec2c52552018-03-01 21:20:39 +0100364 setverdict(pass);
365}
366
Harald Welte3f662762018-03-02 10:48:20 +0100367testcase TC_gsup_sai_err_unknown_imsi() runs on test_CT {
368 var hexstring imsi := f_rnd_imsi('26242'H);
369 var GSUP_PDU res;
370
371 f_init();
372
373 res := f_perform_SAI(imsi, 2);
374 setverdict(pass);
375}
376
377
Harald Weltec2c52552018-03-01 21:20:39 +0100378/* test SAI for a number of different subscriber cases (algo, 2g/3g, ...) */
379testcase TC_gsup_sai() runs on test_CT {
380 var HlrSubscriberList sl;
381 var GSUP_PDU res;
382
383 f_init();
384
385 sl := f_gen_subs();
386 for (var integer i := 0; i < sizeof(sl); i := i+1) {
387 var HlrSubscriber sub := sl[i];
388 log("Testing SAI for ", sub);
389 f_vty_subscr_create(sub);
390 res := f_perform_SAI(sub.imsi);
391 /* TODO: match if tuple[s] matches expectation */
392 f_vty_subscr_delete(sub);
393 }
394
395 setverdict(pass);
396}
397
398/* test UL for unknown IMSI */
399testcase TC_gsup_ul_unknown_imsi() runs on test_CT {
400 var hexstring imsi := f_rnd_imsi('26242'H);
401 var GSUP_PDU res;
402
403 f_init();
404
405 res := f_perform_UL(imsi, ?, 2);
406 setverdict(pass);
407}
408
409/* test SAI for a number of different subscriber cases (algo, 2g/3g, ...) */
410testcase TC_gsup_ul() runs on test_CT {
411 var HlrSubscriberList sl;
412 var GSUP_PDU res;
413
414 f_init();
415
416 sl := f_gen_subs();
417 for (var integer i := 0; i < sizeof(sl); i := i+1) {
418 var HlrSubscriber sub := sl[i];
419 log("Testing UL for ", sub);
420 f_vty_subscr_create(sub);
421 res := f_perform_UL(sub.imsi, sub.msisdn);
422 f_vty_subscr_delete(sub);
423 }
424
425 setverdict(pass);
426}
427
428/* Test only the VTY commands */
429testcase TC_vty() runs on test_CT {
430 var HlrSubscriber sub;
431
432 f_init();
433
434 /* we're not using f_gen_subs() here as the expect pattern for the 'show' are different
435 * from case to case */
436 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v1"));
437 f_vty_subscr_create(sub);
438 f_vty_subscr_show(sub, pattern "*IMSI: *2G auth: COMP128v1*");
439 f_vty_subscr_delete(sub);
440
441 sub := valueof(t_Sub3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
442 "milenage", false));
443 f_vty_subscr_create(sub);
444 f_vty_subscr_show(sub, pattern "*IMSI: *3G auth: MILENAGE*");
445 f_vty_subscr_delete(sub);
446
447 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
448 "comp128v1", "milenage", false));
449 f_vty_subscr_create(sub);
450 f_vty_subscr_show(sub, pattern "*IMSI: *2G auth: COMP128v1*3G auth: MILENAGE*");
451 f_vty_subscr_delete(sub);
452
453 setverdict(pass);
454}
455
Harald Welte09b3c502018-03-01 22:42:22 +0100456/* VTY changes to MSISDN should result in ISD to current VLR */
457testcase TC_vty_msisdn_isd() runs on test_CT {
458 var HlrSubscriber sub;
459 var hexstring new_msisdn;
460 var GSUP_PDU res;
461 timer T := 5.0;
462
463 f_init();
464
465 /* Create Subscriber */
466 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v1"));
467 f_vty_subscr_create(sub);
468
469 /* Perform UpdateLocation (VLR now known to HLR) */
470 res := f_perform_UL(sub.imsi, sub.msisdn);
471
472 /* Then change IMSI via VTY */
473 new_msisdn := '49161'H & f_rnd_hexstring(7, 9);
474 f_vty_subscr_update_msisdn(sub, new_msisdn);
475 /* And expect InsertSubscriberData as result */
476 T.start;
477 alt {
478 [] GSUP.receive(tr_GSUP_ISD_REQ(sub.imsi, new_msisdn)) {
479 GSUP.send(ts_GSUP_ISD_RES(sub.imsi));
480 sub.msisdn := new_msisdn;
481 setverdict(pass);
482 }
483 [] GSUP.receive { repeat; }
484 [] T.timeout {
485 setverdict(fail, "Timeout waiting for ISD.req");
486 }
487 }
488}
489
Harald Welte958f8b42018-03-01 23:40:17 +0100490/* Test PURGE MS for CS services */
491testcase TC_gsup_purge_cs() runs on test_CT {
492 var HlrSubscriberList sl;
493 var GSUP_PDU res;
494
495 f_init();
496
497 sl := f_gen_subs();
498 for (var integer i := 0; i < sizeof(sl); i := i+1) {
499 var HlrSubscriber sub := sl[i];
500 log("Testing CS Purge for ", sub);
501 f_vty_subscr_create(sub);
502 res := f_perform_UL(sub.imsi, sub.msisdn);
503 res := f_perform_PURGE(sub.imsi, OSMO_GSUP_CN_DOMAIN_CS);
504 f_vty_subscr_delete(sub);
505 }
506
507 setverdict(pass);
508}
509
510/* Test PURGE MS for PS services */
511testcase TC_gsup_purge_ps() runs on test_CT {
512 var HlrSubscriberList sl;
513 var GSUP_PDU res;
514
515 f_init();
516
517 sl := f_gen_subs();
518 for (var integer i := 0; i < sizeof(sl); i := i+1) {
519 var HlrSubscriber sub := sl[i];
520 log("Testing PS Purge for ", sub);
521 f_vty_subscr_create(sub);
522 res := f_perform_UL(sub.imsi, sub.msisdn);
523 res := f_perform_PURGE(sub.imsi, OSMO_GSUP_CN_DOMAIN_PS);
524 f_vty_subscr_delete(sub);
525 }
526
527 setverdict(pass);
528}
529
530/* Test PURGEG MS procedure for unknown IMSI */
531testcase TC_gsup_purge_unknown() runs on test_CT {
532 var hexstring imsi := '2345743413463'H;
533 var GSUP_PDU res;
534
535 f_init();
536
537 res := f_perform_PURGE(imsi, OSMO_GSUP_CN_DOMAIN_CS, 2);
538
539 setverdict(pass);
540}
541
542
Harald Weltec2c52552018-03-01 21:20:39 +0100543/* TODO:
544 * UL with ISD error
545 * UL with ISD timeout
Harald Weltec2c52552018-03-01 21:20:39 +0100546 * LOCATION CANCEL
547 * AUTH FAIL REP
548 * DELETE DATA after hlr_subscr_nam() change
549 * correctness
550 ** wrong message type
551 ** wrong length of PDU
552 ** too short message
553 ** missing IMSI IE
554
555 */
556
Harald Weltedf327232017-12-28 22:51:51 +0100557control {
558 execute( TC_gsup_sai_err_invalid_imsi() );
Harald Weltec2c52552018-03-01 21:20:39 +0100559 execute( TC_gsup_sai() );
560 execute( TC_gsup_ul_unknown_imsi() );
Harald Welte3f662762018-03-02 10:48:20 +0100561 execute( TC_gsup_sai_err_unknown_imsi() );
Harald Weltec2c52552018-03-01 21:20:39 +0100562 execute( TC_gsup_ul() );
563 execute( TC_vty() );
Harald Welte09b3c502018-03-01 22:42:22 +0100564 execute( TC_vty_msisdn_isd() );
Harald Welte958f8b42018-03-01 23:40:17 +0100565 execute( TC_gsup_purge_cs() );
566 execute( TC_gsup_purge_ps() );
567 execute( TC_gsup_purge_unknown() );
Harald Weltedf327232017-12-28 22:51:51 +0100568};
569
570};