blob: b4cf19546a42336a384dab96ff4ce9a52e195e9c [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 Welte70296062018-03-01 22:42:03 +0100175private template (value) charstring t_subscr_prefix(hexstring imsi) :=
176 "subscriber imsi " & hex2str(imsi) & " ";
177
Harald Weltec2c52552018-03-01 21:20:39 +0100178/* create a given subscriber using the VTY */
179function f_vty_subscr_create(HlrSubscriber sub) runs on test_CT {
Harald Welte70296062018-03-01 22:42:03 +0100180 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
Harald Weltec2c52552018-03-01 21:20:39 +0100181 f_vty_transceive_match(VTY, prefix & "create", pattern "% Created subscriber *");
182 f_vty_transceive_match(VTY, prefix & "update msisdn " & hex2str(sub.msisdn),
183 pattern "% Updated subscriber *");
184 if (ispresent(sub.aud2g)) {
185 f_vty_transceive_match(VTY, prefix & "update aud2g " & sub.aud2g.algo &
186 " ki " & oct2str(sub.aud2g.ki),
187 pattern "");
188 } else {
189 f_vty_transceive_match(VTY, prefix & "update aud2g none", pattern "");
190 }
191
192 if (ispresent(sub.aud3g)) {
193 var charstring op_mode := "op";
194 if (sub.aud3g.op_is_opc) {
195 op_mode := "opc";
196 }
197 f_vty_transceive_match(VTY, prefix & "update aud3g " & sub.aud3g.algo &
198 " k " & oct2str(sub.aud3g.k) & " " & op_mode & " " &
199 oct2str(sub.aud3g.op), pattern "");
200 } else {
201 f_vty_transceive_match(VTY, prefix & "update aud3g none", pattern "");
202 }
203}
204
Harald Welte09b3c502018-03-01 22:42:22 +0100205function f_vty_subscr_update_msisdn(HlrSubscriber sub, hexstring new_msisdn) runs on test_CT {
206 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
207 f_vty_transceive_match(VTY, prefix & "update msisdn " & hex2str(new_msisdn),
208 pattern "% Updated subscriber *");
209}
210
Harald Weltec2c52552018-03-01 21:20:39 +0100211/* perform 'delete' on subscriber */
212function f_vty_subscr_delete(HlrSubscriber sub) runs on test_CT {
Harald Welte70296062018-03-01 22:42:03 +0100213 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
Harald Weltec2c52552018-03-01 21:20:39 +0100214 f_vty_transceive_match(VTY, prefix & "delete",
215 pattern "% Deleted subscriber for IMSI *");
216}
217
218/* perform 'show' on subscriber; match result with pattern 'exp' */
219function f_vty_subscr_show(HlrSubscriber sub, template charstring exp) runs on test_CT {
Harald Welte70296062018-03-01 22:42:03 +0100220 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
Harald Weltec2c52552018-03-01 21:20:39 +0100221 f_vty_transceive_match(VTY, prefix & "show", exp);
222}
223
224
225/* perform SendAuthInfo for given imsi, return the GSUP response/error */
226function f_perform_SAI(hexstring imsi, template (omit) integer exp_err_cause := omit)
227runs on test_CT return GSUP_PDU {
228 var GSUP_PDU ret;
229 timer T := 3.0;
230 var boolean exp_fail := false;
231 if (not istemplatekind(exp_err_cause, "omit")) {
232 exp_fail := true;
233 }
234
235 GSUP.send(valueof(ts_GSUP_SAI_REQ(imsi)));
236 T.start;
237 alt {
238 [exp_fail] GSUP.receive(tr_GSUP_SAI_ERR(imsi, exp_err_cause)) -> value ret {
239 setverdict(pass);
240 }
241 [exp_fail] GSUP.receive(tr_GSUP_SAI_ERR(imsi, ?)) -> value ret {
242 setverdict(fail, "Unexpected SAI ERROR Cause");
243 }
244 [exp_fail] GSUP.receive(tr_GSUP_SAI_RES(imsi)) -> value ret {
245 setverdict(fail, "Unexpected SAI.res for unknown IMSI");
246 }
247 [not exp_fail] GSUP.receive(tr_GSUP_SAI_ERR(imsi, ?)) -> value ret {
248 setverdict(fail, "Unexpected SAI ERROR");
249 }
250 [not exp_fail] GSUP.receive(tr_GSUP_SAI_RES(imsi)) -> value ret {
251 setverdict(pass);
252 }
253 [] GSUP.receive { repeat; }
254 [] T.timeout {
255 setverdict(fail, "Timeout waiting for SAI response");
256 self.stop;
257 }
258 }
259 return ret;
260}
261
262function f_perform_UL(hexstring imsi, template hexstring msisdn,
263 template (omit) integer exp_err_cause := omit)
264runs on test_CT return GSUP_PDU {
265 var GSUP_PDU ret;
266 timer T := 3.0;
267 var boolean exp_fail := false;
268 var boolean isd_done := false;
269 if (not istemplatekind(exp_err_cause, "omit")) {
270 exp_fail := true;
271 }
272
273 GSUP.send(valueof(ts_GSUP_UL_REQ(imsi)));
274 T.start;
275 alt {
276 [exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, exp_err_cause)) -> value ret {
277 setverdict(pass);
278 }
279 [exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, ?)) -> value ret {
280 setverdict(fail, "Unexpected UL ERROR Cause");
281 }
282 [exp_fail] GSUP.receive(tr_GSUP_UL_RES(imsi)) -> value ret {
283 setverdict(fail, "Unexpected UL.res for unknown IMSI");
284 }
285 [exp_fail] GSUP.receive(tr_GSUP_ISD_REQ(imsi)) -> value ret {
286 setverdict(fail, "Unexpected ISD.req in error case");
287 }
288 [not exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, ?)) -> value ret {
289 setverdict(fail, "Unexpected UL ERROR");
290 }
291 [not exp_fail and not isd_done] GSUP.receive(tr_GSUP_ISD_REQ(imsi, msisdn)) -> value ret {
292 GSUP.send(ts_GSUP_ISD_RES(imsi));
293 isd_done := true;
Harald Welte8f0c9332018-03-01 23:38:40 +0100294 repeat;
Harald Weltec2c52552018-03-01 21:20:39 +0100295 }
296 [not exp_fail and isd_done] GSUP.receive(tr_GSUP_UL_RES(imsi)) -> value ret {
297 setverdict(pass);
298 }
299 [] GSUP.receive { repeat; }
300 [] T.timeout {
301 setverdict(fail, "Timeout waiting for UL response");
302 self.stop;
303 }
304 }
305 return ret;
306}
307
Harald Welte958f8b42018-03-01 23:40:17 +0100308/* perform PurgeMS for given imsi, return the GSUP response/error */
309function f_perform_PURGE(hexstring imsi, GSUP_CnDomain cn_dom,
310 template (omit) integer exp_err_cause := omit)
311runs on test_CT return GSUP_PDU {
312 var GSUP_PDU ret;
313 timer T := 3.0;
314 var boolean exp_fail := false;
315 if (not istemplatekind(exp_err_cause, "omit")) {
316 exp_fail := true;
317 }
318
319 GSUP.send(valueof(ts_GSUP_PURGE_MS_REQ(imsi, cn_dom)));
320 T.start;
321 alt {
322 [exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_ERR(imsi, exp_err_cause)) -> value ret {
323 setverdict(pass);
324 }
325 [exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_ERR(imsi, ?)) -> value ret {
326 setverdict(fail, "Unexpected PURGE ERROR Cause");
327 }
328 [exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_RES(imsi)) -> value ret {
329 setverdict(fail, "Unexpected PURGE.res for unknown IMSI");
330 }
331 [not exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_ERR(imsi, ?)) -> value ret {
332 setverdict(fail, "Unexpected PURGE ERROR");
333 }
334 [not exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_RES(imsi)) -> value ret {
335 setverdict(pass);
336 }
337 [] GSUP.receive { repeat; }
338 [] T.timeout {
339 setverdict(fail, "Timeout waiting for PURGE response");
340 self.stop;
341 }
342 }
343 return ret;
344}
345
346
Harald Weltec2c52552018-03-01 21:20:39 +0100347testcase TC_gsup_sai_err_invalid_imsi() runs on test_CT {
Harald Welte3f662762018-03-02 10:48:20 +0100348 /* 23.003 Section 2.2 clearly states that an IMSI with less
349 * than 5 digits is impossible. Even 5 digits is still questionable */
350 var hexstring imsi := '0123'H;
Harald Weltec2c52552018-03-01 21:20:39 +0100351 var GSUP_PDU res;
352
353 f_init();
354
Harald Welte3f662762018-03-02 10:48:20 +0100355 res := f_perform_SAI(imsi, 96); /* Invalid Mandatory information */
Harald Weltec2c52552018-03-01 21:20:39 +0100356 setverdict(pass);
357}
358
Harald Welte3f662762018-03-02 10:48:20 +0100359testcase TC_gsup_sai_err_unknown_imsi() runs on test_CT {
360 var hexstring imsi := f_rnd_imsi('26242'H);
361 var GSUP_PDU res;
362
363 f_init();
364
365 res := f_perform_SAI(imsi, 2);
366 setverdict(pass);
367}
368
369
Harald Weltec2c52552018-03-01 21:20:39 +0100370/* test SAI for a number of different subscriber cases (algo, 2g/3g, ...) */
371testcase TC_gsup_sai() runs on test_CT {
372 var HlrSubscriberList sl;
373 var GSUP_PDU res;
374
375 f_init();
376
377 sl := f_gen_subs();
378 for (var integer i := 0; i < sizeof(sl); i := i+1) {
379 var HlrSubscriber sub := sl[i];
380 log("Testing SAI for ", sub);
381 f_vty_subscr_create(sub);
382 res := f_perform_SAI(sub.imsi);
383 /* TODO: match if tuple[s] matches expectation */
384 f_vty_subscr_delete(sub);
385 }
386
387 setverdict(pass);
388}
389
390/* test UL for unknown IMSI */
391testcase TC_gsup_ul_unknown_imsi() runs on test_CT {
392 var hexstring imsi := f_rnd_imsi('26242'H);
393 var GSUP_PDU res;
394
395 f_init();
396
397 res := f_perform_UL(imsi, ?, 2);
398 setverdict(pass);
399}
400
401/* test SAI for a number of different subscriber cases (algo, 2g/3g, ...) */
402testcase TC_gsup_ul() runs on test_CT {
403 var HlrSubscriberList sl;
404 var GSUP_PDU res;
405
406 f_init();
407
408 sl := f_gen_subs();
409 for (var integer i := 0; i < sizeof(sl); i := i+1) {
410 var HlrSubscriber sub := sl[i];
411 log("Testing UL for ", sub);
412 f_vty_subscr_create(sub);
413 res := f_perform_UL(sub.imsi, sub.msisdn);
414 f_vty_subscr_delete(sub);
415 }
416
417 setverdict(pass);
418}
419
420/* Test only the VTY commands */
421testcase TC_vty() runs on test_CT {
422 var HlrSubscriber sub;
423
424 f_init();
425
426 /* we're not using f_gen_subs() here as the expect pattern for the 'show' are different
427 * from case to case */
428 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v1"));
429 f_vty_subscr_create(sub);
430 f_vty_subscr_show(sub, pattern "*IMSI: *2G auth: COMP128v1*");
431 f_vty_subscr_delete(sub);
432
433 sub := valueof(t_Sub3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
434 "milenage", false));
435 f_vty_subscr_create(sub);
436 f_vty_subscr_show(sub, pattern "*IMSI: *3G auth: MILENAGE*");
437 f_vty_subscr_delete(sub);
438
439 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
440 "comp128v1", "milenage", false));
441 f_vty_subscr_create(sub);
442 f_vty_subscr_show(sub, pattern "*IMSI: *2G auth: COMP128v1*3G auth: MILENAGE*");
443 f_vty_subscr_delete(sub);
444
445 setverdict(pass);
446}
447
Harald Welte09b3c502018-03-01 22:42:22 +0100448/* VTY changes to MSISDN should result in ISD to current VLR */
449testcase TC_vty_msisdn_isd() runs on test_CT {
450 var HlrSubscriber sub;
451 var hexstring new_msisdn;
452 var GSUP_PDU res;
453 timer T := 5.0;
454
455 f_init();
456
457 /* Create Subscriber */
458 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v1"));
459 f_vty_subscr_create(sub);
460
461 /* Perform UpdateLocation (VLR now known to HLR) */
462 res := f_perform_UL(sub.imsi, sub.msisdn);
463
464 /* Then change IMSI via VTY */
465 new_msisdn := '49161'H & f_rnd_hexstring(7, 9);
466 f_vty_subscr_update_msisdn(sub, new_msisdn);
467 /* And expect InsertSubscriberData as result */
468 T.start;
469 alt {
470 [] GSUP.receive(tr_GSUP_ISD_REQ(sub.imsi, new_msisdn)) {
471 GSUP.send(ts_GSUP_ISD_RES(sub.imsi));
472 sub.msisdn := new_msisdn;
473 setverdict(pass);
474 }
Stefan Sperling7c096872018-04-09 11:24:22 +0200475 [] GSUP.receive(tr_GSUP_ISD_REQ(sub.imsi, sub.msisdn)) {
476 log("received ISD req with old MSISDN");
477 setverdict(fail);
478 }
Harald Welte09b3c502018-03-01 22:42:22 +0100479 [] GSUP.receive { repeat; }
480 [] T.timeout {
481 setverdict(fail, "Timeout waiting for ISD.req");
482 }
483 }
484}
485
Harald Welte958f8b42018-03-01 23:40:17 +0100486/* Test PURGE MS for CS services */
487testcase TC_gsup_purge_cs() runs on test_CT {
488 var HlrSubscriberList sl;
489 var GSUP_PDU res;
490
491 f_init();
492
493 sl := f_gen_subs();
494 for (var integer i := 0; i < sizeof(sl); i := i+1) {
495 var HlrSubscriber sub := sl[i];
496 log("Testing CS Purge for ", sub);
497 f_vty_subscr_create(sub);
498 res := f_perform_UL(sub.imsi, sub.msisdn);
499 res := f_perform_PURGE(sub.imsi, OSMO_GSUP_CN_DOMAIN_CS);
500 f_vty_subscr_delete(sub);
501 }
502
503 setverdict(pass);
504}
505
506/* Test PURGE MS for PS services */
507testcase TC_gsup_purge_ps() runs on test_CT {
508 var HlrSubscriberList sl;
509 var GSUP_PDU res;
510
511 f_init();
512
513 sl := f_gen_subs();
514 for (var integer i := 0; i < sizeof(sl); i := i+1) {
515 var HlrSubscriber sub := sl[i];
516 log("Testing PS Purge for ", sub);
517 f_vty_subscr_create(sub);
518 res := f_perform_UL(sub.imsi, sub.msisdn);
519 res := f_perform_PURGE(sub.imsi, OSMO_GSUP_CN_DOMAIN_PS);
520 f_vty_subscr_delete(sub);
521 }
522
523 setverdict(pass);
524}
525
526/* Test PURGEG MS procedure for unknown IMSI */
527testcase TC_gsup_purge_unknown() runs on test_CT {
528 var hexstring imsi := '2345743413463'H;
529 var GSUP_PDU res;
530
531 f_init();
532
533 res := f_perform_PURGE(imsi, OSMO_GSUP_CN_DOMAIN_CS, 2);
534
535 setverdict(pass);
536}
537
538
Harald Weltec2c52552018-03-01 21:20:39 +0100539/* TODO:
540 * UL with ISD error
541 * UL with ISD timeout
Harald Weltec2c52552018-03-01 21:20:39 +0100542 * LOCATION CANCEL
543 * AUTH FAIL REP
544 * DELETE DATA after hlr_subscr_nam() change
545 * correctness
546 ** wrong message type
547 ** wrong length of PDU
548 ** too short message
549 ** missing IMSI IE
550
551 */
552
Harald Weltedf327232017-12-28 22:51:51 +0100553control {
554 execute( TC_gsup_sai_err_invalid_imsi() );
Harald Weltec2c52552018-03-01 21:20:39 +0100555 execute( TC_gsup_sai() );
556 execute( TC_gsup_ul_unknown_imsi() );
Harald Welte3f662762018-03-02 10:48:20 +0100557 execute( TC_gsup_sai_err_unknown_imsi() );
Harald Weltec2c52552018-03-01 21:20:39 +0100558 execute( TC_gsup_ul() );
559 execute( TC_vty() );
Harald Welte09b3c502018-03-01 22:42:22 +0100560 execute( TC_vty_msisdn_isd() );
Harald Welte958f8b42018-03-01 23:40:17 +0100561 execute( TC_gsup_purge_cs() );
562 execute( TC_gsup_purge_ps() );
563 execute( TC_gsup_purge_unknown() );
Harald Weltedf327232017-12-28 22:51:51 +0100564};
565
566};