blob: ea450b39dd26b6e7b794ab71817250d1e4e70ec1 [file] [log] [blame]
Harald Welte78cae922018-03-01 10:12:56 +01001module HLR_Tests {
Harald Weltedf327232017-12-28 22:51:51 +01002
Harald Welte34b5a952019-05-27 11:54:11 +02003/* HLR test suite in TTCN-3
4 * (C) 2017-2018 Harald Welte <laforge@gnumonks.org>
5 * (C) 2018 sysmocom - s.f.m.c. GmbH
6 * (C) 2018 Vadim Yanitskiy <axilirator@gmail.com>
7 * All rights reserved.
8 *
9 * Released under the terms of GNU General Public License, Version 2 or
10 * (at your option) any later version.
11 *
12 * SPDX-License-Identifier: GPL-2.0-or-later
13 */
14
15
16
Harald Weltedf327232017-12-28 22:51:51 +010017import from GSUP_Types all;
Harald Welteed380d12018-06-14 13:42:11 +020018import from GSUP_Emulation all;
Harald Weltedf327232017-12-28 22:51:51 +010019import from IPA_Emulation all;
20
Harald Weltec2c52552018-03-01 21:20:39 +010021import from General_Types all;
22import from Osmocom_Types all;
Harald Welte39b82d32018-03-01 10:21:29 +010023import from Osmocom_CTRL_Adapter all;
24
Harald Welte4ea1f8a2018-06-12 09:26:10 +020025import from TCCEncoding_Functions all;
26import from SS_Types all;
27import from SS_Templates all;
28import from MAP_Errors all;
29import from USSD_Helpers all;
30
Harald Welte39b82d32018-03-01 10:21:29 +010031import from Osmocom_VTY_Functions all;
32import from TELNETasp_PortType all;
33
Oliver Smithdeb80a62019-11-29 16:01:54 +010034import from MSLookup_mDNS_Types all;
35import from MSLookup_mDNS_Emulation all;
36import from MSLookup_mDNS_Templates all;
Oliver Smithb51a53f2020-01-29 15:06:54 +010037import from DNS_Helpers all;
Oliver Smithdeb80a62019-11-29 16:01:54 +010038
Harald Welte39b82d32018-03-01 10:21:29 +010039type component test_CT extends CTRL_Adapter_CT {
Oliver Smith6e81f7e2020-01-29 14:25:41 +010040 /* emulated GSUP client (MSC/SGSN) */
Harald Weltedf327232017-12-28 22:51:51 +010041 var IPA_Emulation_CT vc_IPA;
42 var IPA_CCM_Parameters ccm_pars;
Harald Welteed380d12018-06-14 13:42:11 +020043 /* legacy tests without ConnHdlr */
Harald Weltedf327232017-12-28 22:51:51 +010044 port IPA_GSUP_PT GSUP;
Harald Welteed380d12018-06-14 13:42:11 +020045 /* new tests using ConnHdlr + GSUP_Emulation */
46 var GSUP_Emulation_CT vc_GSUP;
47 /* only to get events from IPA underneath GSUP */
48 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte39b82d32018-03-01 10:21:29 +010049
50 port TELNETasp_PT VTY;
Harald Weltec2c52552018-03-01 21:20:39 +010051
Oliver Smithdeb80a62019-11-29 16:01:54 +010052 var MSLookup_mDNS_Emulation_CT vc_MSLookup_mDNS;
53
Oliver Smith6e81f7e2020-01-29 14:25:41 +010054 /* emulated GSUP server (second HLR) */
55 var IPA_Emulation_CT vc_IPA_server;
56 var GSUP_Emulation_CT vc_GSUP_server;
57
Harald Weltec2c52552018-03-01 21:20:39 +010058 timer g_Tguard := 10.0;
Harald Weltedf327232017-12-28 22:51:51 +010059};
60
61modulepar {
Oliver Smith6e81f7e2020-01-29 14:25:41 +010062 /* OsmoHLR */
Harald Weltedf327232017-12-28 22:51:51 +010063 charstring mp_hlr_ip := "127.0.0.1";
64 integer mp_hlr_gsup_port := 4222;
65 integer mp_hlr_ctrl_port := 4259;
Alexander Couzens92696442020-01-10 07:57:16 +010066 /* how many auth tuples are expected
67 when IE ts_GSUP_IE_NUM_VECTORS_REQ is absent */
68 integer mp_default_num_auth_tuples := 5;
Oliver Smithdeb80a62019-11-29 16:01:54 +010069
Oliver Smith6e81f7e2020-01-29 14:25:41 +010070 /* emulated GSUP server (second HLR) */
71 charstring mp_hlr_ts_ip := "127.0.0.99";
72 integer mp_hlr_ts_port := 4222;
73
Oliver Smithdeb80a62019-11-29 16:01:54 +010074 /* drop after osmo-hlr release > 1.2.0 */
75 boolean mp_hlr_supports_dgsm := true;
Harald Weltedf327232017-12-28 22:51:51 +010076};
77
Harald Weltec2c52552018-03-01 21:20:39 +010078type record HlrSubscrAud2G {
79 charstring algo,
80 OCT16 ki
81}
82
83type record HlrSubscrAud3G {
84 charstring algo,
85 OCT16 k,
86 OCT16 op,
87 boolean op_is_opc
88}
89
90type record HlrSubscriber {
91 hexstring imsi,
92 hexstring msisdn,
93 HlrSubscrAud2G aud2g optional,
94 HlrSubscrAud3G aud3g optional
95}
96
97type record of HlrSubscriber HlrSubscriberList;
98
Harald Welteed380d12018-06-14 13:42:11 +020099type component HLR_ConnHdlr extends GSUP_ConnHdlr {
100 timer g_Tguard := 10.0;
101 var HLR_ConnHdlrPars g_pars;
102 port TELNETasp_PT VTY;
Oliver Smithdeb80a62019-11-29 16:01:54 +0100103 port MSLookup_mDNS_PT mDNS;
Oliver Smith6e81f7e2020-01-29 14:25:41 +0100104
105 /* Pass from test_CT for explicit addressing */
106 var GSUP_Emulation_CT vc_GSUP_server;
107 var GSUP_Emulation_CT vc_GSUP_client;
108 var IPA_CCM_Parameters ccm_pars_client;
Harald Welteed380d12018-06-14 13:42:11 +0200109}
110
111type record HLR_ConnHdlrPars {
Harald Welte4ea1f8a2018-06-12 09:26:10 +0200112 HlrSubscriber sub,
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100113 HLR_ConnHdlrParsUssd ussd optional,
114 octetstring source_name optional
Harald Welte4ea1f8a2018-06-12 09:26:10 +0200115}
116
117type record HLR_ConnHdlrParsUssd {
118 OCT4 sid
Harald Welteed380d12018-06-14 13:42:11 +0200119}
120
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100121template (value) HLR_ConnHdlrPars t_Pars(hexstring imsi, hexstring msisdn := ''H,
122 template (omit) octetstring source_name := omit) := {
Harald Welteed380d12018-06-14 13:42:11 +0200123 sub := {
124 imsi := imsi,
125 msisdn := msisdn,
126 aud2g := omit,
127 aud3g := omit
Harald Welte4ea1f8a2018-06-12 09:26:10 +0200128 },
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100129 ussd := omit,
130 source_name := source_name
Harald Welteed380d12018-06-14 13:42:11 +0200131}
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100132template (value) HLR_ConnHdlrPars t_Pars_via_proxy(hexstring imsi, hexstring msisdn := ''H) :=
133 t_Pars(imsi, msisdn, source_name := char2oct("the-source\n"));
Harald Welteed380d12018-06-14 13:42:11 +0200134
135template (value) HLR_ConnHdlrPars t_Pars_sub(HlrSubscriber sub) := {
Harald Welte4ea1f8a2018-06-12 09:26:10 +0200136 sub := sub,
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100137 ussd := omit,
138 source_name := omit
139}
140
141template (value) HLR_ConnHdlrPars t_Pars_sub_via_proxy(HlrSubscriber sub) := {
142 sub := sub,
143 ussd := omit,
144 source_name := char2oct("the-source\n")
Harald Welteed380d12018-06-14 13:42:11 +0200145}
146
147type function void_fn() runs on HLR_ConnHdlr;
148
149/***********************************************************************
150 * Main Component
151 ***********************************************************************/
152
153function f_init_vty() runs on test_CT {
154 map(self:VTY, system:VTY);
155 f_vty_set_prompts(VTY);
156 f_vty_transceive(VTY, "enable");
Oliver Smithdeb80a62019-11-29 16:01:54 +0100157 if (mp_hlr_supports_dgsm) {
158 f_vty_config(VTY, "mslookup", "no mdns bind");
159 }
Harald Welteed380d12018-06-14 13:42:11 +0200160}
161
162private altstep as_Tguard() runs on test_CT {
163 [] g_Tguard.timeout {
164 setverdict(fail, "g_Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200165 mtc.stop;
Harald Welteed380d12018-06-14 13:42:11 +0200166 }
167}
168
Oliver Smith6e81f7e2020-01-29 14:25:41 +0100169/* emulated GSUP client (MSC/SGSN) */
Harald Welteed380d12018-06-14 13:42:11 +0200170function f_init_gsup(charstring id, boolean legacy) runs on test_CT {
171 id := id & "-GSUP";
172 var GsupOps ops := {
173 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
174 }
175
176 ccm_pars := c_IPA_default_ccm_pars;
177 ccm_pars.name := "Osmocom TTCN-3 GSUP Simulator";
Harald Welte4a3242e2018-06-24 22:28:53 +0200178 ccm_pars.ser_nr := "MSC-00-00-00-00-00-00";
Harald Welteed380d12018-06-14 13:42:11 +0200179
180 vc_IPA := IPA_Emulation_CT.create(id & "-IPA");
181 log("legacy= ", legacy);
182 if (not legacy) {
183 log("in not legacy case 1");
184 vc_GSUP := GSUP_Emulation_CT.create(id);
185 }
186
187 map(vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
188 if (not legacy) {
189 log("in not legacy case 2");
190 connect(vc_GSUP:GSUP, vc_IPA:IPA_GSUP_PORT);
191 connect(vc_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
192 vc_GSUP.start(GSUP_Emulation.main(ops, id));
193 } else {
194 connect(vc_IPA:IPA_GSUP_PORT, self:GSUP);
195 }
196
197 vc_IPA.start(IPA_Emulation.main_client(mp_hlr_ip, mp_hlr_gsup_port, "", -1, ccm_pars));
198
199 /* wait for incoming connection to GSUP port before proceeding */
200 timer T := 10.0;
201 T.start;
202 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700203 [not legacy] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +0700204 [legacy] GSUP.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Welteed380d12018-06-14 13:42:11 +0200205 [] T.timeout {
206 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200207 mtc.stop;
Harald Welteed380d12018-06-14 13:42:11 +0200208 }
209 }
210}
211
Oliver Smith6e81f7e2020-01-29 14:25:41 +0100212/* emulated GSUP server (second HLR) */
213function f_init_gsup_server(charstring id) runs on test_CT {
214 id := id & "-GSUP-server";
215 var GsupOps ops := {
216 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
217 }
218
219 vc_GSUP_server := GSUP_Emulation_CT.create(id);
220 vc_IPA_server := IPA_Emulation_CT.create(id & "-IPA");
221
222 connect(vc_GSUP_server:GSUP, vc_IPA_server:IPA_GSUP_PORT);
223 map(vc_IPA_server:IPA_PORT, system:IPA_CODEC_PT);
224
225 vc_GSUP_server.start(GSUP_Emulation.main(ops, id));
226 vc_IPA_server.start(IPA_Emulation.main_server(mp_hlr_ts_ip, mp_hlr_ts_port));
227}
228
Oliver Smithdeb80a62019-11-29 16:01:54 +0100229function f_init_mslookup() runs on test_CT {
230 vc_MSLookup_mDNS := MSLookup_mDNS_Emulation_CT.create;
231 vc_MSLookup_mDNS.start(MSLookup_mDNS_Emulation.f_main());
232}
233
Oliver Smith6e81f7e2020-01-29 14:25:41 +0100234function f_init(boolean legacy := true, boolean gsup_server := false) runs on test_CT {
Harald Welteed380d12018-06-14 13:42:11 +0200235
236 /* activate default guard timer to ensure all tests eventually terminate */
237 g_Tguard.start;
238 activate(as_Tguard());
239
240 f_init_gsup("HLR_Test", legacy);
241 f_init_vty();
Oliver Smithdeb80a62019-11-29 16:01:54 +0100242 f_init_mslookup();
Harald Welteed380d12018-06-14 13:42:11 +0200243
Oliver Smith6e81f7e2020-01-29 14:25:41 +0100244 if (gsup_server) {
245 f_init_gsup_server("HLR_Test");
246 }
247
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +0100248 f_ipa_ctrl_start_client(mp_hlr_ip, mp_hlr_ctrl_port);
Harald Welteed380d12018-06-14 13:42:11 +0200249}
250
Oliver Smith6e81f7e2020-01-29 14:25:41 +0100251/*! Start HLR_ConnHdlr from testCT in a separate thread.
252 * \param void_fn function to run inside the thread.
253 * \param gsup_server if true, connect the emulated GSUP server ports to the new HLR_ConnHdlr. Then both the emulated
254 * GSUP client (MSC/SGSN) and server (second HLR) are connected. Explicit addressing with "to" and
255 * "from" must be used, i.e. 'GSUP.receive(tr_GSUP_UL_REQ(...)) from vc_GSUP_server'. */
256function f_start_handler(void_fn fn, HLR_ConnHdlrPars pars, boolean gsup_server := false) runs on test_CT
257return HLR_ConnHdlr {
Harald Welteed380d12018-06-14 13:42:11 +0200258 var HLR_ConnHdlr vc_conn;
259 var charstring id := testcasename();
260
261 vc_conn := HLR_ConnHdlr.create(id);
262 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
263 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
Oliver Smithdeb80a62019-11-29 16:01:54 +0100264 connect(vc_conn:mDNS, vc_MSLookup_mDNS:mDNS);
Harald Welteed380d12018-06-14 13:42:11 +0200265
Oliver Smith6e81f7e2020-01-29 14:25:41 +0100266 if (gsup_server) {
267 connect(vc_conn:GSUP, vc_GSUP_server:GSUP_CLIENT);
268 connect(vc_conn:GSUP_PROC, vc_GSUP_server:GSUP_PROC);
269 vc_conn.start(f_handler_init(fn, id, vc_GSUP_server, vc_GSUP, ccm_pars, pars));
270 } else {
271 vc_conn.start(f_handler_init(fn, id, omit, vc_GSUP, ccm_pars, pars));
272 }
273
Harald Welteed380d12018-06-14 13:42:11 +0200274 return vc_conn;
275}
276
277private function f_handler_init_vty() runs on HLR_ConnHdlr {
278 map(self:VTY, system:VTY);
279 f_vty_set_prompts(VTY);
280 f_vty_transceive(VTY, "enable");
281}
282
283/* first function inside ConnHdlr component; sets g_pars + starts function */
Oliver Smith6e81f7e2020-01-29 14:25:41 +0100284function f_handler_init(void_fn fn, charstring id,
285 template (omit) GSUP_Emulation_CT vc_GSUP_server_test_ct,
286 GSUP_Emulation_CT vc_GSUP_client_test_ct,
287 IPA_CCM_Parameters ccm_pars_client_test_ct,
288 template (omit) HLR_ConnHdlrPars pars := omit)
Harald Welteed380d12018-06-14 13:42:11 +0200289runs on HLR_ConnHdlr
290{
Oliver Smith6e81f7e2020-01-29 14:25:41 +0100291 /* Pass from test_CT for explicit addressing */
292 if (isvalue(vc_GSUP_server_test_ct)) {
293 vc_GSUP_server := valueof(vc_GSUP_server_test_ct);
294 }
295 vc_GSUP_client := vc_GSUP_client_test_ct;
296 ccm_pars_client := ccm_pars_client_test_ct;
297
Harald Welteed380d12018-06-14 13:42:11 +0200298 if (isvalue(pars)) {
299 g_pars := valueof(pars);
Oliver Smith6e81f7e2020-01-29 14:25:41 +0100300 f_create_gsup_expect_explicit(hex2str(g_pars.sub.imsi), vc_GSUP_client);
Harald Welteed380d12018-06-14 13:42:11 +0200301 }
302 f_handler_init_vty();
303 fn.apply();
304}
305
306/***********************************************************************
307 * Subscriber creation via VTY
308 ***********************************************************************/
309
Harald Weltec2c52552018-03-01 21:20:39 +0100310template (value) HlrSubscriber t_SubNoAuth(hexstring imsi, hexstring msisdn) := {
311 imsi := imsi,
312 msisdn := msisdn,
313 aud2g := omit,
314 aud3g := omit
315}
316
317const OCT16 c_KI_DEFAULT := '000102030405060708090a0b0c0d0e0f'O;
318const OCT16 c_K_DEFAULT := '101112131415161718191a1b1c1d1e1f'O;
319const OCT16 c_OP_DEFAULT := '202122232425262728292a2b2c2d2e2f'O;
320//const OCT16 c_OPC_DEFAULT := '303132333435363738393a3b3c3d3f'O;
321
322template (value) HlrSubscriber t_Sub2G(hexstring imsi, hexstring msisdn, charstring algo) := {
323 imsi := imsi,
324 msisdn := msisdn,
325 aud2g := {
326 algo := algo,
327 ki := c_KI_DEFAULT
328 },
329 aud3g := omit
330}
331
332template (value) HlrSubscriber t_Sub3G(hexstring imsi, hexstring msisdn, charstring algo, boolean is_opc) := {
333 imsi := imsi,
334 msisdn := msisdn,
335 aud2g := omit,
336 aud3g := {
337 algo := algo,
338 k := c_K_DEFAULT,
339 op := c_OP_DEFAULT,
340 op_is_opc := is_opc
341 }
342}
343
344template (value) HlrSubscriber t_Sub2G3G(hexstring imsi, hexstring msisdn, charstring algo2g, charstring algo3g, boolean is_opc) := {
345 imsi := imsi,
346 msisdn := msisdn,
347 aud2g := {
348 algo := algo2g,
349 ki := c_KI_DEFAULT
350 },
351 aud3g := {
352 algo := algo3g,
353 k := c_K_DEFAULT,
354 op := c_OP_DEFAULT,
355 op_is_opc := is_opc
356 }
357}
358
359/* generate a variety of subscribers with different parameters */
360function f_gen_subs() runs on test_CT return HlrSubscriberList {
361 var HlrSubscriber sub;
362 var HlrSubscriberList sl := {};
363
364 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v1"));
365 sl := sl & { sub };
366
367 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v2"));
368 sl := sl & { sub };
369
370 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v3"));
371 sl := sl & { sub };
372
373 sub := valueof(t_Sub3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "milenage", false));
374 sl := sl & { sub };
375
376 sub := valueof(t_Sub3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "milenage", true));
377 sl := sl & { sub };
378
379 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
380 "comp128v1", "milenage", false));
381 sl := sl & { sub };
382
383 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
384 "comp128v2", "milenage", false));
385 sl := sl & { sub };
386
387 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
388 "comp128v3", "milenage", false));
389 sl := sl & { sub };
390
391 return sl;
392}
Harald Welteaf7c3182019-08-22 12:40:22 +0200393function f_gen_3G_subs() runs on test_CT return HlrSubscriberList {
394 var HlrSubscriber sub;
395 var HlrSubscriberList sl := {};
396
397 sub := valueof(t_Sub3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "milenage", false));
398 sl := sl & { sub };
399
400 sub := valueof(t_Sub3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "milenage", true));
401 sl := sl & { sub };
402
403 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
404 "comp128v1", "milenage", false));
405 sl := sl & { sub };
406
407 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
408 "comp128v2", "milenage", false));
409 sl := sl & { sub };
410
411 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
412 "comp128v3", "milenage", false));
413 sl := sl & { sub };
414
415 return sl;
416}
Harald Weltec2c52552018-03-01 21:20:39 +0100417
Harald Welteed380d12018-06-14 13:42:11 +0200418function f_vty_transceive_match(TELNETasp_PT pt, charstring cmd, template charstring exp_ret) {
419 var charstring ret := f_vty_transceive_ret(pt, cmd);
420 if (not match(ret, exp_ret)) {
421 setverdict(fail, "Non-matching VTY response: ", ret);
Daniel Willmannafce8662018-07-06 23:11:32 +0200422 mtc.stop;
Harald Weltec2c52552018-03-01 21:20:39 +0100423 }
424}
425
Oliver Smith141620d2019-06-07 12:27:33 +0200426function f_vty_transceive_nomatch(TELNETasp_PT pt, charstring cmd, template charstring exp_ret) {
427 var charstring ret := f_vty_transceive_ret(pt, cmd);
428 if (match(ret, exp_ret)) {
429 setverdict(fail, "Matching VTY response: ", ret, ", should *not* have matched: ", exp_ret);
430 mtc.stop;
431 }
432}
433
Harald Welte70296062018-03-01 22:42:03 +0100434private template (value) charstring t_subscr_prefix(hexstring imsi) :=
435 "subscriber imsi " & hex2str(imsi) & " ";
436
Harald Weltec2c52552018-03-01 21:20:39 +0100437/* create a given subscriber using the VTY */
Harald Welteed380d12018-06-14 13:42:11 +0200438function f_vty_subscr_create(TELNETasp_PT VTY, HlrSubscriber sub) {
Harald Welte70296062018-03-01 22:42:03 +0100439 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
Harald Weltec2c52552018-03-01 21:20:39 +0100440 f_vty_transceive_match(VTY, prefix & "create", pattern "% Created subscriber *");
441 f_vty_transceive_match(VTY, prefix & "update msisdn " & hex2str(sub.msisdn),
442 pattern "% Updated subscriber *");
443 if (ispresent(sub.aud2g)) {
444 f_vty_transceive_match(VTY, prefix & "update aud2g " & sub.aud2g.algo &
445 " ki " & oct2str(sub.aud2g.ki),
446 pattern "");
447 } else {
448 f_vty_transceive_match(VTY, prefix & "update aud2g none", pattern "");
449 }
450
451 if (ispresent(sub.aud3g)) {
452 var charstring op_mode := "op";
453 if (sub.aud3g.op_is_opc) {
454 op_mode := "opc";
455 }
456 f_vty_transceive_match(VTY, prefix & "update aud3g " & sub.aud3g.algo &
457 " k " & oct2str(sub.aud3g.k) & " " & op_mode & " " &
458 oct2str(sub.aud3g.op), pattern "");
459 } else {
460 f_vty_transceive_match(VTY, prefix & "update aud3g none", pattern "");
461 }
462}
463
Harald Welteed380d12018-06-14 13:42:11 +0200464function f_vty_subscr_update_msisdn(TELNETasp_PT VTY, HlrSubscriber sub, hexstring new_msisdn) {
Harald Welte09b3c502018-03-01 22:42:22 +0100465 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
466 f_vty_transceive_match(VTY, prefix & "update msisdn " & hex2str(new_msisdn),
467 pattern "% Updated subscriber *");
468}
469
Harald Weltec2c52552018-03-01 21:20:39 +0100470/* perform 'delete' on subscriber */
Harald Welteed380d12018-06-14 13:42:11 +0200471function f_vty_subscr_delete(TELNETasp_PT VTY, HlrSubscriber sub) {
Harald Welte70296062018-03-01 22:42:03 +0100472 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
Harald Weltec2c52552018-03-01 21:20:39 +0100473 f_vty_transceive_match(VTY, prefix & "delete",
474 pattern "% Deleted subscriber for IMSI *");
475}
476
477/* perform 'show' on subscriber; match result with pattern 'exp' */
Harald Welteed380d12018-06-14 13:42:11 +0200478function f_vty_subscr_show(TELNETasp_PT VTY, HlrSubscriber sub, template charstring exp) {
Harald Welte70296062018-03-01 22:42:03 +0100479 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
Harald Weltec2c52552018-03-01 21:20:39 +0100480 f_vty_transceive_match(VTY, prefix & "show", exp);
481}
482
Oliver Smith141620d2019-06-07 12:27:33 +0200483/* perform 'show' on subscriber; result must not match with pattern 'exp' */
484function f_vty_subscr_show_nomatch(TELNETasp_PT VTY, HlrSubscriber sub, template charstring exp) {
485 var charstring prefix := valueof(t_subscr_prefix(sub.imsi));
486 f_vty_transceive_nomatch(VTY, prefix & "show", exp);
487}
Harald Weltec2c52552018-03-01 21:20:39 +0100488
Harald Welteed380d12018-06-14 13:42:11 +0200489/***********************************************************************
490 * Helper functions for ConnHdlr
491 ***********************************************************************/
492
Harald Weltec2c52552018-03-01 21:20:39 +0100493/* perform SendAuthInfo for given imsi, return the GSUP response/error */
Harald Welteaf7c3182019-08-22 12:40:22 +0200494function f_perform_SAI(hexstring imsi, template (omit) integer exp_err_cause := omit,
Alexander Couzens92696442020-01-10 07:57:16 +0100495 boolean is_eps := false, template (omit) integer num_auth_tuple := omit)
Harald Welteed380d12018-06-14 13:42:11 +0200496runs on HLR_ConnHdlr return GSUP_PDU {
Alexander Couzens92696442020-01-10 07:57:16 +0100497 var template GSUP_PDU sai_msg;
Harald Weltec2c52552018-03-01 21:20:39 +0100498 var GSUP_PDU ret;
499 timer T := 3.0;
500 var boolean exp_fail := false;
501 if (not istemplatekind(exp_err_cause, "omit")) {
502 exp_fail := true;
503 }
504
Harald Welteaf7c3182019-08-22 12:40:22 +0200505 if (is_eps) {
Alexander Couzens92696442020-01-10 07:57:16 +0100506 sai_msg := ts_GSUP_SAI_REQ_EPS(imsi);
Harald Welteaf7c3182019-08-22 12:40:22 +0200507 } else {
Alexander Couzens92696442020-01-10 07:57:16 +0100508 sai_msg := ts_GSUP_SAI_REQ(imsi);
Harald Welteaf7c3182019-08-22 12:40:22 +0200509 }
Alexander Couzens92696442020-01-10 07:57:16 +0100510 if (not istemplatekind(num_auth_tuple, "omit")) {
511 sai_msg.ies := valueof(sai_msg.ies) & {
512 valueof(ts_GSUP_IE_NUM_VECTORS_REQ(int2oct(valueof(num_auth_tuple), 1)))
513 };
514 }
515 GSUP.send(sai_msg);
516
Harald Weltec2c52552018-03-01 21:20:39 +0100517 T.start;
518 alt {
519 [exp_fail] GSUP.receive(tr_GSUP_SAI_ERR(imsi, exp_err_cause)) -> value ret {
520 setverdict(pass);
521 }
522 [exp_fail] GSUP.receive(tr_GSUP_SAI_ERR(imsi, ?)) -> value ret {
523 setverdict(fail, "Unexpected SAI ERROR Cause");
524 }
525 [exp_fail] GSUP.receive(tr_GSUP_SAI_RES(imsi)) -> value ret {
526 setverdict(fail, "Unexpected SAI.res for unknown IMSI");
527 }
528 [not exp_fail] GSUP.receive(tr_GSUP_SAI_ERR(imsi, ?)) -> value ret {
529 setverdict(fail, "Unexpected SAI ERROR");
530 }
531 [not exp_fail] GSUP.receive(tr_GSUP_SAI_RES(imsi)) -> value ret {
532 setverdict(pass);
533 }
534 [] GSUP.receive { repeat; }
535 [] T.timeout {
536 setverdict(fail, "Timeout waiting for SAI response");
Daniel Willmannafce8662018-07-06 23:11:32 +0200537 mtc.stop;
Harald Weltec2c52552018-03-01 21:20:39 +0100538 }
539 }
540 return ret;
541}
542
543function f_perform_UL(hexstring imsi, template hexstring msisdn,
Oliver Smith62a1c632020-01-15 15:58:54 +0100544 template (omit) integer exp_err_cause := omit,
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100545 GSUP_CnDomain dom := OSMO_GSUP_CN_DOMAIN_PS,
546 template (omit) octetstring source_name := omit)
Harald Welteed380d12018-06-14 13:42:11 +0200547runs on HLR_ConnHdlr return GSUP_PDU {
Harald Weltec2c52552018-03-01 21:20:39 +0100548 var GSUP_PDU ret;
549 timer T := 3.0;
550 var boolean exp_fail := false;
551 var boolean isd_done := false;
552 if (not istemplatekind(exp_err_cause, "omit")) {
553 exp_fail := true;
554 }
555
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100556 GSUP.send(valueof(ts_GSUP_UL_REQ(imsi, dom, source_name := source_name)));
Harald Weltec2c52552018-03-01 21:20:39 +0100557 T.start;
558 alt {
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100559 [exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, exp_err_cause, destination_name := source_name)) -> value ret {
Harald Weltec2c52552018-03-01 21:20:39 +0100560 setverdict(pass);
561 }
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100562 [exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, ?, destination_name := source_name)) -> value ret {
Harald Weltec2c52552018-03-01 21:20:39 +0100563 setverdict(fail, "Unexpected UL ERROR Cause");
Neels Hofmeyrc0c1aca2019-11-11 03:40:46 +0100564 mtc.stop;
Harald Weltec2c52552018-03-01 21:20:39 +0100565 }
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100566 [exp_fail] GSUP.receive(tr_GSUP_UL_RES(imsi, destination_name := source_name)) -> value ret {
Harald Weltec2c52552018-03-01 21:20:39 +0100567 setverdict(fail, "Unexpected UL.res for unknown IMSI");
Neels Hofmeyrc0c1aca2019-11-11 03:40:46 +0100568 mtc.stop;
Harald Weltec2c52552018-03-01 21:20:39 +0100569 }
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100570 [exp_fail] GSUP.receive(tr_GSUP_ISD_REQ(imsi, destination_name := source_name)) -> value ret {
Harald Weltec2c52552018-03-01 21:20:39 +0100571 setverdict(fail, "Unexpected ISD.req in error case");
Neels Hofmeyrc0c1aca2019-11-11 03:40:46 +0100572 mtc.stop;
Harald Weltec2c52552018-03-01 21:20:39 +0100573 }
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100574 [not exp_fail] GSUP.receive(tr_GSUP_UL_ERR(imsi, ?, destination_name := source_name)) -> value ret {
Harald Weltec2c52552018-03-01 21:20:39 +0100575 setverdict(fail, "Unexpected UL ERROR");
Neels Hofmeyrc0c1aca2019-11-11 03:40:46 +0100576 mtc.stop;
Harald Weltec2c52552018-03-01 21:20:39 +0100577 }
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100578 [not exp_fail and not isd_done] GSUP.receive(tr_GSUP_ISD_REQ(imsi, msisdn, destination_name := source_name)) -> value ret {
579 GSUP.send(ts_GSUP_ISD_RES(imsi, source_name := source_name));
Harald Weltec2c52552018-03-01 21:20:39 +0100580 isd_done := true;
Harald Welte8f0c9332018-03-01 23:38:40 +0100581 repeat;
Harald Weltec2c52552018-03-01 21:20:39 +0100582 }
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100583 [not exp_fail and isd_done] GSUP.receive(tr_GSUP_UL_RES(imsi, destination_name := source_name)) -> value ret {
Harald Weltec2c52552018-03-01 21:20:39 +0100584 setverdict(pass);
585 }
586 [] GSUP.receive { repeat; }
587 [] T.timeout {
588 setverdict(fail, "Timeout waiting for UL response");
Daniel Willmannafce8662018-07-06 23:11:32 +0200589 mtc.stop;
Harald Weltec2c52552018-03-01 21:20:39 +0100590 }
591 }
592 return ret;
593}
594
Oliver Smithb51a53f2020-01-29 15:06:54 +0100595/* Perform Location Update with IMSI that is unknown to OsmoHLR. Let it ask for the HLR that knows the IMSI via
596 * mslookup. The TTCN-3 testsuite pretends to be the home HLR, that knows the IMSI. The proxy HLR connects to the
597 * home HLR and forwards GSUP messages, until LU is complete.
598 * Make sure to let a timer run while calling this function (see TC_MSLookup_GSUP_proxy). */
599function f_perform_UL_proxy(hexstring imsi, hexstring msisdn, GSUP_CnDomain dom := OSMO_GSUP_CN_DOMAIN_PS)
600runs on HLR_ConnHdlr {
601 var MSLookup_mDNS mdns_msg;
602 var integer id;
603 var charstring domain := "gsup.hlr." & hex2str(imsi) & ".imsi.mdns.osmocom.org";
604 var octetstring destination_name := char2oct(ccm_pars_client.ser_nr) & '00'O; /* TS-MSC IPA name */
605
606 /* Testing the HLR as proxy. The MSC asking the proxy and the home HLR are both enacted by TTCN3 (TS).
607 * MSC=vc_GSUP_client <---> osmo-hlr as proxy <---> vc_GSUP_server=home HLR
608 * GSUP.send(..) to vc_GSUP_client ---> osmo-hlr ---> GSUP.receive(..) from vc_GSUP_server
609 * GSUP.receive(..) from vc_GSUP_client <--- osmo-hlr <--- GSUP.send(..) to vc_GSUP_server */
610
611 /* [GSUP] TS-MSC => HLR proxy: Update Location Request with unknown IMSI */
612 GSUP.send(ts_GSUP_UL_REQ(imsi, dom)) to vc_GSUP_client;
613
614 /* [GSUP] TS-HLR: expect GSUP messages with that IMSI */
615 f_create_gsup_expect_explicit(hex2str(imsi), vc_GSUP_server);
616
617 /* [mDNS] TS-HLR <= HLR proxy: query for GSUP server who knows the IMSI */
618 mDNS.receive(tr_MSLookup_mDNS_query(domain)) -> value mdns_msg;
619
620 /* [mDNS] TS-HLR => HLR proxy: result with IP/port of TS GSUP server */
621 id := mdns_msg.dnsMessage.header.id;
622 mDNS.send(ts_MSLookup_mDNS_result_IPv4(id, domain, f_enc_IPv4(mp_hlr_ts_ip), mp_hlr_ts_port));
623
624 /* [GSUP] TS-HLR <=> HLR proxy <=> TS-MSC: finish up UL */
625 GSUP.receive(tr_GSUP_UL_REQ(imsi)) from vc_GSUP_server;
626 GSUP.send(ts_GSUP_ISD_REQ(imsi, msisdn, destination_name)) to vc_GSUP_server;
627 GSUP.receive(tr_GSUP_ISD_REQ(imsi, g_pars.sub.msisdn)) from vc_GSUP_client;
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100628 GSUP.send(ts_GSUP_ISD_RES(imsi, destination_name := destination_name)) to vc_GSUP_server;
Oliver Smithb51a53f2020-01-29 15:06:54 +0100629 GSUP.receive(tr_GSUP_ISD_RES(imsi)) from vc_GSUP_client;
630 GSUP.send(ts_GSUP_UL_RES(imsi, destination_name)) to vc_GSUP_server;
631 GSUP.receive(tr_GSUP_UL_RES(imsi)) from vc_GSUP_client;
632}
633
Harald Welte958f8b42018-03-01 23:40:17 +0100634/* perform PurgeMS for given imsi, return the GSUP response/error */
635function f_perform_PURGE(hexstring imsi, GSUP_CnDomain cn_dom,
636 template (omit) integer exp_err_cause := omit)
Harald Welteed380d12018-06-14 13:42:11 +0200637runs on HLR_ConnHdlr return GSUP_PDU {
Harald Welte958f8b42018-03-01 23:40:17 +0100638 var GSUP_PDU ret;
639 timer T := 3.0;
640 var boolean exp_fail := false;
641 if (not istemplatekind(exp_err_cause, "omit")) {
642 exp_fail := true;
643 }
644
645 GSUP.send(valueof(ts_GSUP_PURGE_MS_REQ(imsi, cn_dom)));
646 T.start;
647 alt {
648 [exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_ERR(imsi, exp_err_cause)) -> value ret {
649 setverdict(pass);
650 }
651 [exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_ERR(imsi, ?)) -> value ret {
652 setverdict(fail, "Unexpected PURGE ERROR Cause");
653 }
654 [exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_RES(imsi)) -> value ret {
655 setverdict(fail, "Unexpected PURGE.res for unknown IMSI");
656 }
657 [not exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_ERR(imsi, ?)) -> value ret {
658 setverdict(fail, "Unexpected PURGE ERROR");
659 }
660 [not exp_fail] GSUP.receive(tr_GSUP_PURGE_MS_RES(imsi)) -> value ret {
661 setverdict(pass);
662 }
663 [] GSUP.receive { repeat; }
664 [] T.timeout {
665 setverdict(fail, "Timeout waiting for PURGE response");
Daniel Willmannafce8662018-07-06 23:11:32 +0200666 mtc.stop;
Harald Welte958f8b42018-03-01 23:40:17 +0100667 }
668 }
669 return ret;
670}
671
Harald Welte4ea1f8a2018-06-12 09:26:10 +0200672function f_SS_xceive(hexstring imsi, OCT4 sid, GSUP_SessionState state, octetstring ss,
673 template (omit) integer exp_err_cause := omit)
674runs on HLR_ConnHdlr return GSUP_PDU {
675 var GSUP_PDU ret;
676 timer T := 3.0;
677 var boolean exp_fail := false;
678 if (not istemplatekind(exp_err_cause, "omit")) {
679 exp_fail := true;
680 }
681
682 GSUP.send(valueof(ts_GSUP_PROC_SS_REQ(imsi, sid, state, ss)));
683 T.start;
684 alt {
Vadim Yanitskiy21c42332018-11-29 00:18:05 +0700685 [exp_fail] GSUP.receive(tr_GSUP_PROC_SS_ERR(imsi, sid, ?, exp_err_cause)) -> value ret {
Harald Welte4ea1f8a2018-06-12 09:26:10 +0200686 setverdict(pass);
687 }
Vadim Yanitskiy21c42332018-11-29 00:18:05 +0700688 [exp_fail] GSUP.receive(tr_GSUP_PROC_SS_ERR(imsi, sid, ?, ?)) -> value ret {
Harald Welte4ea1f8a2018-06-12 09:26:10 +0200689 setverdict(fail, "Unexpected PROC_SS ERROR Cause");
690 }
691 [exp_fail] GSUP.receive(tr_GSUP_PROC_SS_RES(imsi, sid, ?, ?)) -> value ret {
692 setverdict(fail, "Unexpected PROC_SS.res for unknown IMSI");
693 }
Vadim Yanitskiy21c42332018-11-29 00:18:05 +0700694 [not exp_fail] GSUP.receive(tr_GSUP_PROC_SS_ERR(imsi, sid, ?, ?)) -> value ret {
Harald Welte4ea1f8a2018-06-12 09:26:10 +0200695 setverdict(fail, "Unexpected PROC_SS ERROR");
696 }
697 [not exp_fail] GSUP.receive(tr_GSUP_PROC_SS_RES(imsi, sid, ?, ?)) -> value ret {
698 setverdict(pass);
699 }
700 [] GSUP.receive { repeat; }
701 [] T.timeout {
702 setverdict(fail, "Timeout waiting for PROC_SS response");
703 self.stop;
704 }
705 }
706 return ret;
707}
708
709private function f_SS_expect(hexstring imsi, OCT4 sid, GSUP_SessionState state,
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100710 template SS_FacilityInformation facility := *,
711 template octetstring destination_name := omit)
Harald Welte4ea1f8a2018-06-12 09:26:10 +0200712runs on HLR_ConnHdlr return GSUP_PDU {
713 var GSUP_PDU ret;
714 timer T := 3.0;
715 var boolean exp_ss := true;
716 if (istemplatekind(facility, "omit")) {
717 exp_ss := false;
718 }
719 T.start;
720 alt {
Vadim Yanitskiy21c42332018-11-29 00:18:05 +0700721 [] GSUP.receive(tr_GSUP_PROC_SS_ERR(imsi, sid, ?, ?)) -> value ret {
Harald Welte4ea1f8a2018-06-12 09:26:10 +0200722 setverdict(fail, "Unexpected PROC_SS ERROR Cause");
Neels Hofmeyrc0c1aca2019-11-11 03:40:46 +0100723 mtc.stop;
Harald Welte4ea1f8a2018-06-12 09:26:10 +0200724 }
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100725 [not exp_ss] GSUP.receive(tr_GSUP_PROC_SS_RES(imsi, sid, state, omit, destination_name := destination_name)) -> value ret {
Harald Welte4ea1f8a2018-06-12 09:26:10 +0200726 setverdict(pass);
727 }
728 [exp_ss] GSUP.receive(tr_GSUP_PROC_SS_RES(imsi, sid, state, omit)) -> value ret {
729 setverdict(fail, "Unexpected PROC_SS.res without SS IE");
Neels Hofmeyrc0c1aca2019-11-11 03:40:46 +0100730 mtc.stop;
Harald Welte4ea1f8a2018-06-12 09:26:10 +0200731 }
732/*
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100733 [exp_ss] GSUP.receive(tr_GSUP_PROC_SS_RES(imsi, sid, state, decmatch facility, destination_name := destination_name)) -> value ret {
Harald Welte4ea1f8a2018-06-12 09:26:10 +0200734 setverdict(pass);
735 }
736*/
737
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100738 [exp_ss] GSUP.receive(tr_GSUP_PROC_SS_RES(imsi, sid, state, ?, destination_name := destination_name)) -> value ret {
Harald Welte4ea1f8a2018-06-12 09:26:10 +0200739 var GSUP_IeValue ss_ie;
740 f_gsup_find_ie(ret, OSMO_GSUP_SS_INFO_IE, ss_ie);
741 var SS_FacilityInformation dec_fac := dec_SS_FacilityInformation(ss_ie.ss_info);
742 log("pattern: ", facility);
743 if (match(dec_fac, facility)) {
744 setverdict(pass);
745 } else {
746 setverdict(fail, "Unexpected PROC_SS.res with non-matching facility IE");
Neels Hofmeyrc0c1aca2019-11-11 03:40:46 +0100747 mtc.stop;
Harald Welte4ea1f8a2018-06-12 09:26:10 +0200748 }
749 }
Neels Hofmeyrc0c1aca2019-11-11 03:40:46 +0100750 [] GSUP.receive {
751 setverdict(fail, "Unexpected GSUP");
752 mtc.stop;
753 }
Harald Welte4ea1f8a2018-06-12 09:26:10 +0200754 [] T.timeout {
755 setverdict(fail, "Timeout waiting for PROC_SS response");
756 self.stop;
757 }
758 }
759
760 return ret;
761}
762
Oliver Smith936dbe62019-06-04 15:54:17 +0200763function f_perform_CHECK_IMEI(hexstring imsi, hexstring imei,
764 template (omit) integer exp_err_cause := omit,
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100765 template (omit) GSUP_IMEIResult result := omit,
766 template (omit) octetstring source_name := omit)
Oliver Smith936dbe62019-06-04 15:54:17 +0200767runs on HLR_ConnHdlr {
768 var GSUP_PDU pdu;
769 timer T := 3.0;
770 var boolean exp_fail := false;
771 if (not istemplatekind(exp_err_cause, "omit")) {
772 exp_fail := true;
773 }
774
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100775 GSUP.send(valueof(ts_GSUP_CHECK_IMEI_REQ(imsi, imei, source_name := source_name)));
Oliver Smith936dbe62019-06-04 15:54:17 +0200776 T.start;
777 alt {
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100778 [exp_fail] GSUP.receive(tr_GSUP_CHECK_IMEI_ERR(imsi, exp_err_cause, destination_name := source_name)) -> value pdu {
Oliver Smith936dbe62019-06-04 15:54:17 +0200779 setverdict(pass);
780 }
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100781 [exp_fail] GSUP.receive(tr_GSUP_CHECK_IMEI_ERR(imsi, ?, destination_name := source_name)) -> value pdu {
Oliver Smith936dbe62019-06-04 15:54:17 +0200782 setverdict(fail, "Unexpected CHECK IMEI ERROR Cause: ", pdu);
Neels Hofmeyrc0c1aca2019-11-11 03:40:46 +0100783 mtc.stop;
Oliver Smith936dbe62019-06-04 15:54:17 +0200784 }
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100785 [exp_fail] GSUP.receive(tr_GSUP_CHECK_IMEI_RES(imsi, ?, destination_name := source_name)) -> value pdu {
Oliver Smith936dbe62019-06-04 15:54:17 +0200786 setverdict(fail, "Unexpected CHECK IMEI RES instead of ERR");
Neels Hofmeyrc0c1aca2019-11-11 03:40:46 +0100787 mtc.stop;
Oliver Smith936dbe62019-06-04 15:54:17 +0200788 }
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100789 [not exp_fail] GSUP.receive(tr_GSUP_CHECK_IMEI_ERR(imsi, ?, destination_name := source_name)) -> value pdu {
Oliver Smith936dbe62019-06-04 15:54:17 +0200790 setverdict(fail, "Unexpected CHECK IMEI ERROR");
Neels Hofmeyrc0c1aca2019-11-11 03:40:46 +0100791 mtc.stop;
Oliver Smith936dbe62019-06-04 15:54:17 +0200792 }
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100793 [not exp_fail] GSUP.receive(tr_GSUP_CHECK_IMEI_RES(imsi, result, destination_name := source_name)) -> value pdu {
Oliver Smith936dbe62019-06-04 15:54:17 +0200794 setverdict(pass);
795 }
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100796 [not exp_fail] GSUP.receive(tr_GSUP_CHECK_IMEI_RES(imsi, ?, destination_name := source_name)) -> value pdu {
Oliver Smith936dbe62019-06-04 15:54:17 +0200797 setverdict(fail, "Unexpected CHECK IMEI RES");
Neels Hofmeyrc0c1aca2019-11-11 03:40:46 +0100798 mtc.stop;
Oliver Smith936dbe62019-06-04 15:54:17 +0200799 }
800 [] GSUP.receive { repeat; }
801 [] T.timeout {
802 setverdict(fail, "Timeout waiting for CHECK IMEI response");
803 mtc.stop;
804 }
805 }
806}
807
808
Harald Welte4ea1f8a2018-06-12 09:26:10 +0200809
Harald Welte958f8b42018-03-01 23:40:17 +0100810
Harald Welteed380d12018-06-14 13:42:11 +0200811/***********************************************************************
812 * Testcases
813 ***********************************************************************/
814
815/* 23.003 Section 2.2 clearly states that an IMSI with less
816 * than 5 digits is impossible. Even 5 digits is still questionable */
817private function f_TC_gsup_sai_err_invalid_imsi() runs on HLR_ConnHdlr {
Harald Weltec2c52552018-03-01 21:20:39 +0100818 var GSUP_PDU res;
Harald Welteed380d12018-06-14 13:42:11 +0200819 res := f_perform_SAI(g_pars.sub.imsi, 96); /* Invalid Mandatory information */
820 setverdict(pass);
821}
822testcase TC_gsup_sai_err_invalid_imsi() runs on test_CT {
823 var HLR_ConnHdlr vc_conn;
824 var HLR_ConnHdlrPars pars := valueof(t_Pars('0123'H));
825 f_init(false);
826 vc_conn := f_start_handler(refers(f_TC_gsup_sai_err_invalid_imsi), pars);
827 vc_conn.done;
828}
Harald Weltec2c52552018-03-01 21:20:39 +0100829
Harald Weltec2c52552018-03-01 21:20:39 +0100830
Harald Welteed380d12018-06-14 13:42:11 +0200831private function f_TC_gsup_sai_err_unknown_imsi() runs on HLR_ConnHdlr {
832 var GSUP_PDU res;
833 res := f_perform_SAI(g_pars.sub.imsi, 2);
Harald Weltec2c52552018-03-01 21:20:39 +0100834 setverdict(pass);
835}
836
Harald Welte3f662762018-03-02 10:48:20 +0100837testcase TC_gsup_sai_err_unknown_imsi() runs on test_CT {
Harald Welteed380d12018-06-14 13:42:11 +0200838 var HLR_ConnHdlr vc_conn;
839 var HLR_ConnHdlrPars pars := valueof(t_Pars(f_rnd_imsi('26242'H)));
840 f_init(false);
841 vc_conn := f_start_handler(refers(f_TC_gsup_sai_err_unknown_imsi), pars);
842 vc_conn.done;
Harald Welte3f662762018-03-02 10:48:20 +0100843}
844
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100845function f_start_handler_per_sub(void_fn fn, HlrSubscriberList sl, boolean via_proxy := false) runs on test_CT {
Harald Welteed380d12018-06-14 13:42:11 +0200846 for (var integer i := 0; i < sizeof(sl); i := i+1) {
847 var HlrSubscriber sub := sl[i];
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100848 var HLR_ConnHdlrPars pars;
849 if (via_proxy) {
850 pars := valueof(t_Pars_sub_via_proxy(sub));
851 } else {
852 pars := valueof(t_Pars_sub(sub));
853 }
Harald Welteed380d12018-06-14 13:42:11 +0200854 var HLR_ConnHdlr vc_conn;
855
856 f_vty_subscr_create(VTY, sub);
857 vc_conn := f_start_handler(fn, pars);
858 vc_conn.done;
859 f_vty_subscr_delete(VTY, sub);
860 }
861}
Harald Welte3f662762018-03-02 10:48:20 +0100862
Harald Weltec2c52552018-03-01 21:20:39 +0100863/* test SAI for a number of different subscriber cases (algo, 2g/3g, ...) */
Harald Welteed380d12018-06-14 13:42:11 +0200864private function f_TC_gsup_sai() runs on HLR_ConnHdlr {
865 var GSUP_PDU res;
866 res := f_perform_SAI(g_pars.sub.imsi);
Harald Welte4b612042019-12-03 20:08:57 +0100867 if (ispresent(g_pars.sub.aud3g)) {
868 f_ensure_amf_separation_bit(res, '0'B);
869 }
Alexander Couzens92696442020-01-10 07:57:16 +0100870
871 f_count_auth_tuples(res, mp_default_num_auth_tuples);
Harald Welteed380d12018-06-14 13:42:11 +0200872 setverdict(pass);
873}
Harald Weltec2c52552018-03-01 21:20:39 +0100874testcase TC_gsup_sai() runs on test_CT {
875 var HlrSubscriberList sl;
876 var GSUP_PDU res;
877
Harald Welteed380d12018-06-14 13:42:11 +0200878 f_init(false);
Harald Weltec2c52552018-03-01 21:20:39 +0100879
880 sl := f_gen_subs();
Harald Welteed380d12018-06-14 13:42:11 +0200881 f_start_handler_per_sub(refers(f_TC_gsup_sai), sl);
Harald Weltec2c52552018-03-01 21:20:39 +0100882
883 setverdict(pass);
884}
885
Alexander Couzens92696442020-01-10 07:57:16 +0100886/* test SAI for a number of different subscriber cases (algo, 2g/3g, ...) */
887private function f_TC_gsup_sai_num_auth_vectors() runs on HLR_ConnHdlr {
888 var GSUP_PDU res;
889 res := f_perform_SAI(g_pars.sub.imsi, num_auth_tuple := 1);
890 f_count_auth_tuples(res, 1);
891 res := f_perform_SAI(g_pars.sub.imsi, num_auth_tuple := 4);
892 f_count_auth_tuples(res, 4);
893 res := f_perform_SAI(g_pars.sub.imsi, num_auth_tuple := 5);
894 f_count_auth_tuples(res, 5);
895 res := f_perform_SAI(g_pars.sub.imsi, num_auth_tuple := 254);
896 f_count_auth_tuples(res, 5);
897 setverdict(pass);
898}
899testcase TC_gsup_sai_num_auth_vectors() runs on test_CT {
900 var HlrSubscriberList sl;
901 var GSUP_PDU res;
902
903 f_init(false);
904
905 sl := f_gen_subs();
906 f_start_handler_per_sub(refers(f_TC_gsup_sai_num_auth_vectors), sl);
907
908 setverdict(pass);
909}
910
Harald Welteaf7c3182019-08-22 12:40:22 +0200911private function f_ensure_amf_separation_bit(GSUP_PDU res, BIT1 sep_bit)
912{
913 for (var integer i := 0; i < lengthof(res.ies); i := i+1) {
914 var GSUP_IE tuple := res.ies[i];
915 if (tuple.tag != OSMO_GSUP_AUTH_TUPLE_IE) {
916 continue;
917 }
918 var GSUP_IeValue autn;
919 if (f_gsup_find_nested_ie(tuple.val.auth_tuple, OSMO_GSUP_AUTN_IE, autn) == false) {
920 setverdict(fail, "Couldn't find AUTN IE in tuple ", i);
921 mtc.stop;
922 }
923 var bitstring amf := oct2bit(substr(autn.autn, 6, 2));
924 if (amf[0] != sep_bit) {
925 setverdict(fail, "AMF bit 0 (separation bit) must be ", sep_bit," but was not");
926 mtc.stop;
927 }
928 }
929}
930
Alexander Couzens92696442020-01-10 07:57:16 +0100931private function f_count_auth_tuples(GSUP_PDU res, template (omit) integer expected_auth_tuples := omit)
932{
933 var integer auth_tuples := 0;
934 for (var integer i := 0; i < lengthof(res.ies); i := i+1) {
935 var GSUP_IE tuple := res.ies[i];
936 if (tuple.tag == OSMO_GSUP_AUTH_TUPLE_IE) {
937 auth_tuples := auth_tuples + 1;
938 }
939 }
940
941 if ((not istemplatekind(expected_auth_tuples, "omit")) and
942 not match(auth_tuples, valueof(expected_auth_tuples))) {
943 setverdict(fail,
944 "Did not received expected number of auth tuples. Expected ",
945 mp_default_num_auth_tuples,
946 " but received ", auth_tuples);
947 }
948}
949
Harald Welteaf7c3182019-08-22 12:40:22 +0200950/* test SAI for a number of different subscriber cases (algo, 2g/3g, ...) */
951private function f_TC_gsup_sai_eps() runs on HLR_ConnHdlr {
952 var GSUP_PDU res;
953 res := f_perform_SAI(g_pars.sub.imsi, is_eps := true);
954 f_ensure_amf_separation_bit(res, '1'B);
955
956 /* TODO: match if tuple[s] matches expectation */
957 setverdict(pass);
958}
959testcase TC_gsup_sai_eps() runs on test_CT {
960 var HlrSubscriberList sl;
961 var GSUP_PDU res;
962
963 f_init(false);
964
965 sl := f_gen_3G_subs();
966 f_start_handler_per_sub(refers(f_TC_gsup_sai_eps), sl);
967
968 setverdict(pass);
969}
970
971
Harald Weltec2c52552018-03-01 21:20:39 +0100972/* test UL for unknown IMSI */
Harald Welteed380d12018-06-14 13:42:11 +0200973private function f_TC_ul_unknown_imsi() runs on HLR_ConnHdlr {
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100974 f_perform_UL(g_pars.sub.imsi, ?, 2, source_name := g_pars.source_name);
Harald Weltec2c52552018-03-01 21:20:39 +0100975 setverdict(pass);
976}
Harald Welteed380d12018-06-14 13:42:11 +0200977testcase TC_gsup_ul_unknown_imsi() runs on test_CT {
978 var hexstring imsi := f_rnd_imsi('26242'H);
979 var HLR_ConnHdlrPars pars := valueof(t_Pars(imsi));
980 var HLR_ConnHdlr vc_conn;
Harald Weltec2c52552018-03-01 21:20:39 +0100981
Harald Welteed380d12018-06-14 13:42:11 +0200982 f_init(false);
983 vc_conn := f_start_handler(refers(f_TC_ul_unknown_imsi), pars);
984 vc_conn.done;
985}
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100986testcase TC_gsup_ul_unknown_imsi_via_proxy() runs on test_CT {
987 var hexstring imsi := f_rnd_imsi('26242'H);
988 var HLR_ConnHdlrPars pars := valueof(t_Pars_via_proxy(imsi));
989 var HLR_ConnHdlr vc_conn;
990
991 f_init(false);
992 vc_conn := f_start_handler(refers(f_TC_ul_unknown_imsi), pars);
993 vc_conn.done;
994}
Harald Welteed380d12018-06-14 13:42:11 +0200995
996/* test UL for a number of different subscriber cases (algo, 2g/3g, ...) */
997private function f_TC_gsup_ul() runs on HLR_ConnHdlr {
998 var GSUP_PDU res;
Neels Hofmeyrb2168512019-11-11 03:40:26 +0100999 res := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn, source_name := g_pars.source_name);
Harald Welteed380d12018-06-14 13:42:11 +02001000 setverdict(pass);
1001}
Harald Weltec2c52552018-03-01 21:20:39 +01001002testcase TC_gsup_ul() runs on test_CT {
1003 var HlrSubscriberList sl;
1004 var GSUP_PDU res;
1005
Harald Welteed380d12018-06-14 13:42:11 +02001006 f_init(false);
Harald Weltec2c52552018-03-01 21:20:39 +01001007 sl := f_gen_subs();
Harald Welteed380d12018-06-14 13:42:11 +02001008 f_start_handler_per_sub(refers(f_TC_gsup_ul), sl);
Harald Weltec2c52552018-03-01 21:20:39 +01001009
1010 setverdict(pass);
1011}
Neels Hofmeyrb2168512019-11-11 03:40:26 +01001012testcase TC_gsup_ul_via_proxy() runs on test_CT {
1013 var HlrSubscriberList sl;
1014 var GSUP_PDU res;
1015
1016 f_init(false);
1017 sl := f_gen_subs();
1018 f_start_handler_per_sub(refers(f_TC_gsup_ul), sl, via_proxy := true);
1019
1020 setverdict(pass);
1021}
Harald Weltec2c52552018-03-01 21:20:39 +01001022
1023/* Test only the VTY commands */
1024testcase TC_vty() runs on test_CT {
1025 var HlrSubscriber sub;
1026
1027 f_init();
1028
1029 /* we're not using f_gen_subs() here as the expect pattern for the 'show' are different
1030 * from case to case */
1031 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v1"));
Harald Welteed380d12018-06-14 13:42:11 +02001032 f_vty_subscr_create(VTY, sub);
1033 f_vty_subscr_show(VTY, sub, pattern "*IMSI: *2G auth: COMP128v1*");
1034 f_vty_subscr_delete(VTY, sub);
Harald Weltec2c52552018-03-01 21:20:39 +01001035
1036 sub := valueof(t_Sub3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
1037 "milenage", false));
Harald Welteed380d12018-06-14 13:42:11 +02001038 f_vty_subscr_create(VTY, sub);
1039 f_vty_subscr_show(VTY, sub, pattern "*IMSI: *3G auth: MILENAGE*");
1040 f_vty_subscr_delete(VTY, sub);
Harald Weltec2c52552018-03-01 21:20:39 +01001041
1042 sub := valueof(t_Sub2G3G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9),
1043 "comp128v1", "milenage", false));
Harald Welteed380d12018-06-14 13:42:11 +02001044 f_vty_subscr_create(VTY, sub);
1045 f_vty_subscr_show(VTY, sub, pattern "*IMSI: *2G auth: COMP128v1*3G auth: MILENAGE*");
1046 f_vty_subscr_delete(VTY, sub);
Harald Weltec2c52552018-03-01 21:20:39 +01001047
1048 setverdict(pass);
1049}
1050
Harald Welte09b3c502018-03-01 22:42:22 +01001051/* VTY changes to MSISDN should result in ISD to current VLR */
Harald Welteed380d12018-06-14 13:42:11 +02001052private function f_TC_vty_msisdn_isd() runs on HLR_ConnHdlr {
Harald Welte09b3c502018-03-01 22:42:22 +01001053 var hexstring new_msisdn;
1054 var GSUP_PDU res;
1055 timer T := 5.0;
1056
Harald Welte09b3c502018-03-01 22:42:22 +01001057 /* Create Subscriber */
Harald Welteed380d12018-06-14 13:42:11 +02001058 f_vty_subscr_create(VTY, g_pars.sub);
Harald Welte09b3c502018-03-01 22:42:22 +01001059
1060 /* Perform UpdateLocation (VLR now known to HLR) */
Harald Welteed380d12018-06-14 13:42:11 +02001061 res := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn);
Harald Welte09b3c502018-03-01 22:42:22 +01001062
1063 /* Then change IMSI via VTY */
1064 new_msisdn := '49161'H & f_rnd_hexstring(7, 9);
Harald Welteed380d12018-06-14 13:42:11 +02001065 f_vty_subscr_update_msisdn(VTY, g_pars.sub, new_msisdn);
Harald Welte09b3c502018-03-01 22:42:22 +01001066 /* And expect InsertSubscriberData as result */
1067 T.start;
1068 alt {
Harald Welteed380d12018-06-14 13:42:11 +02001069 [] GSUP.receive(tr_GSUP_ISD_REQ(g_pars.sub.imsi, new_msisdn)) {
1070 GSUP.send(ts_GSUP_ISD_RES(g_pars.sub.imsi));
1071 g_pars.sub.msisdn := new_msisdn;
Harald Welte09b3c502018-03-01 22:42:22 +01001072 setverdict(pass);
1073 }
Harald Welteed380d12018-06-14 13:42:11 +02001074 [] GSUP.receive(tr_GSUP_ISD_REQ(g_pars.sub.imsi, g_pars.sub.msisdn)) {
Stefan Sperling7c096872018-04-09 11:24:22 +02001075 log("received ISD req with old MSISDN");
1076 setverdict(fail);
1077 }
Harald Welte09b3c502018-03-01 22:42:22 +01001078 [] GSUP.receive { repeat; }
1079 [] T.timeout {
1080 setverdict(fail, "Timeout waiting for ISD.req");
1081 }
1082 }
1083}
Harald Welteed380d12018-06-14 13:42:11 +02001084testcase TC_vty_msisdn_isd() runs on test_CT {
1085 var HlrSubscriber sub;
1086 var HLR_ConnHdlr vc_conn;
1087
1088 f_init(false);
1089
1090 /* Create Subscriber */
1091 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H), '49161'H & f_rnd_hexstring(7, 9), "comp128v1"));
1092
1093 vc_conn := f_start_handler(refers(f_TC_vty_msisdn_isd), valueof(t_Pars_sub(sub)));
1094 vc_conn.done;
1095}
Harald Welte09b3c502018-03-01 22:42:22 +01001096
Harald Welte958f8b42018-03-01 23:40:17 +01001097/* Test PURGE MS for CS services */
Harald Welteed380d12018-06-14 13:42:11 +02001098private function f_TC_gsup_purge_cs() runs on HLR_ConnHdlr {
1099 var GSUP_PDU res;
1100 res := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn);
1101 res := f_perform_PURGE(g_pars.sub.imsi, OSMO_GSUP_CN_DOMAIN_CS);
1102}
Harald Welte958f8b42018-03-01 23:40:17 +01001103testcase TC_gsup_purge_cs() runs on test_CT {
1104 var HlrSubscriberList sl;
1105 var GSUP_PDU res;
1106
Harald Welteed380d12018-06-14 13:42:11 +02001107 f_init(false);
Harald Welte958f8b42018-03-01 23:40:17 +01001108 sl := f_gen_subs();
Harald Welteed380d12018-06-14 13:42:11 +02001109 f_start_handler_per_sub(refers(f_TC_gsup_purge_cs), sl);
Harald Welte958f8b42018-03-01 23:40:17 +01001110
1111 setverdict(pass);
1112}
1113
1114/* Test PURGE MS for PS services */
Harald Welteed380d12018-06-14 13:42:11 +02001115private function f_TC_gsup_purge_ps() runs on HLR_ConnHdlr {
1116 var GSUP_PDU res;
1117 res := f_perform_UL(g_pars.sub.imsi, g_pars.sub.msisdn);
1118 res := f_perform_PURGE(g_pars.sub.imsi, OSMO_GSUP_CN_DOMAIN_PS);
1119}
Harald Welte958f8b42018-03-01 23:40:17 +01001120testcase TC_gsup_purge_ps() runs on test_CT {
1121 var HlrSubscriberList sl;
Harald Welte958f8b42018-03-01 23:40:17 +01001122
Harald Welteed380d12018-06-14 13:42:11 +02001123 f_init(false);
Harald Welte958f8b42018-03-01 23:40:17 +01001124 sl := f_gen_subs();
Harald Welteed380d12018-06-14 13:42:11 +02001125 f_start_handler_per_sub(refers(f_TC_gsup_purge_ps), sl);
Harald Welte958f8b42018-03-01 23:40:17 +01001126
1127 setverdict(pass);
1128}
1129
1130/* Test PURGEG MS procedure for unknown IMSI */
Harald Welteed380d12018-06-14 13:42:11 +02001131
1132private function f_TC_gsup_purge_unknown() runs on HLR_ConnHdlr {
1133 var GSUP_PDU res;
1134 res := f_perform_PURGE(g_pars.sub.imsi, OSMO_GSUP_CN_DOMAIN_CS, 2);
1135}
Harald Welte958f8b42018-03-01 23:40:17 +01001136testcase TC_gsup_purge_unknown() runs on test_CT {
1137 var hexstring imsi := '2345743413463'H;
Harald Welteed380d12018-06-14 13:42:11 +02001138 var HLR_ConnHdlrPars pars := valueof(t_Pars(imsi));
1139 var HLR_ConnHdlr vc_conn;
Harald Welte958f8b42018-03-01 23:40:17 +01001140
Harald Welteed380d12018-06-14 13:42:11 +02001141 f_init(false);
1142 vc_conn := f_start_handler(refers(f_TC_ul_unknown_imsi), pars);
1143 vc_conn.done;
Harald Welte958f8b42018-03-01 23:40:17 +01001144
1145 setverdict(pass);
1146}
1147
Harald Welte4ea1f8a2018-06-12 09:26:10 +02001148import from HLR_EUSE all;
1149
1150/* Test for USSD request to undefined/unrouted short-code. Expect ss-NotAvailable(18) */
1151private function f_TC_mo_ussd_unknown() runs on HLR_ConnHdlr {
1152 var GSUP_PDU res;
1153 var octetstring ss := f_USSD_FACILITY_IE_INVOKE(
1154 op_code := SS_OP_CODE_PROCESS_USS_REQ,
1155 ussd_string := "*#200#");
1156 GSUP.send(valueof(ts_GSUP_PROC_SS_REQ(g_pars.sub.imsi, g_pars.ussd.sid,
1157 OSMO_GSUP_SESSION_STATE_BEGIN, ss)));
Vadim Yanitskiy06e53c52019-03-28 15:08:24 +07001158 res := f_SS_expect(g_pars.sub.imsi, g_pars.ussd.sid,
1159 OSMO_GSUP_SESSION_STATE_END,
1160 tr_SS_FACILITY_RETURN_ERROR(1, 18));
Harald Welte4ea1f8a2018-06-12 09:26:10 +02001161}
1162testcase TC_mo_ussd_unknown() runs on test_CT {
1163 var HlrSubscriberList sl;
1164 var HLR_ConnHdlr vc_conn;
1165
1166 f_init(false);
1167 sl := f_gen_subs();
1168 for (var integer i := 0; i < sizeof(sl); i := i+1) {
1169 var HLR_ConnHdlrPars pars := valueof(t_Pars_sub(sl[i]));
1170 pars.ussd.sid := f_rnd_octstring(4);
1171 f_vty_subscr_create(VTY, pars.sub);
1172 vc_conn := f_start_handler(refers(f_TC_mo_ussd_unknown), pars);
1173 vc_conn.done;
1174 }
1175}
1176
1177/* Test for USSD request to currently disconnected EUSE. Expect ss-SystemFailure(34) */
1178private function f_TC_mo_ussd_euse_disc() runs on HLR_ConnHdlr {
1179 var GSUP_PDU res;
1180 var octetstring ss := f_USSD_FACILITY_IE_INVOKE(
1181 op_code := SS_OP_CODE_PROCESS_USS_REQ,
1182 ussd_string := "*100#");
1183 GSUP.send(valueof(ts_GSUP_PROC_SS_REQ(g_pars.sub.imsi, g_pars.ussd.sid,
1184 OSMO_GSUP_SESSION_STATE_BEGIN, ss)));
Vadim Yanitskiy06e53c52019-03-28 15:08:24 +07001185 res := f_SS_expect(g_pars.sub.imsi, g_pars.ussd.sid,
1186 OSMO_GSUP_SESSION_STATE_END,
1187 tr_SS_FACILITY_RETURN_ERROR(1, 34));
Harald Welte4ea1f8a2018-06-12 09:26:10 +02001188}
1189testcase TC_mo_ussd_euse_disc() runs on test_CT {
1190 var HlrSubscriberList sl;
1191 var HLR_ConnHdlr vc_conn;
1192
1193 f_init(false);
1194 sl := f_gen_subs();
1195 for (var integer i := 0; i < sizeof(sl); i := i+1) {
1196 var HLR_ConnHdlrPars pars := valueof(t_Pars_sub(sl[i]));
1197 pars.ussd.sid := f_rnd_octstring(4);
1198 f_vty_subscr_create(VTY, pars.sub);
1199 vc_conn := f_start_handler(refers(f_TC_mo_ussd_euse_disc), pars);
1200 vc_conn.done;
1201 }
1202}
1203
1204/* Test for USSD request to internal own-imsi IUSE. */
1205private function f_TC_mo_ussd_iuse_imsi() runs on HLR_ConnHdlr {
1206 var GSUP_PDU res;
1207 var charstring resp_str;
1208 var octetstring ss := f_USSD_FACILITY_IE_INVOKE(
1209 op_code := SS_OP_CODE_PROCESS_USS_REQ,
1210 ussd_string := "*#101#");
1211 GSUP.send(valueof(ts_GSUP_PROC_SS_REQ(g_pars.sub.imsi, g_pars.ussd.sid,
Neels Hofmeyrb2168512019-11-11 03:40:26 +01001212 OSMO_GSUP_SESSION_STATE_BEGIN, ss,
1213 source_name := g_pars.source_name)));
Harald Welte4ea1f8a2018-06-12 09:26:10 +02001214 resp_str := "Your IMSI is " & hex2str(g_pars.sub.imsi);
Vadim Yanitskiy06e53c52019-03-28 15:08:24 +07001215 res := f_SS_expect(g_pars.sub.imsi, g_pars.ussd.sid,
1216 OSMO_GSUP_SESSION_STATE_END,
1217 tr_SS_USSD_FACILITY_RETURN_RESULT(1, 59, SS_USSD_DEFAULT_DCS,
Neels Hofmeyrb2168512019-11-11 03:40:26 +01001218 f_encGSM7bit(resp_str)),
1219 destination_name := g_pars.source_name);
Harald Welte4ea1f8a2018-06-12 09:26:10 +02001220}
1221testcase TC_mo_ussd_iuse_imsi() runs on test_CT {
1222 var HlrSubscriberList sl;
1223 var HLR_ConnHdlr vc_conn;
1224
1225 f_init(false);
1226 sl := f_gen_subs();
1227 for (var integer i := 0; i < sizeof(sl); i := i+1) {
1228 var HLR_ConnHdlrPars pars := valueof(t_Pars_sub(sl[i]));
1229 pars.ussd.sid := f_rnd_octstring(4);
1230 f_vty_subscr_create(VTY, pars.sub);
1231 vc_conn := f_start_handler(refers(f_TC_mo_ussd_iuse_imsi), pars);
1232 vc_conn.done;
1233 }
1234}
Neels Hofmeyrb2168512019-11-11 03:40:26 +01001235testcase TC_mo_ussd_iuse_imsi_via_proxy() runs on test_CT {
1236 var HlrSubscriberList sl;
1237 var HLR_ConnHdlr vc_conn;
1238
1239 f_init(false);
1240 sl := f_gen_subs();
1241 for (var integer i := 0; i < sizeof(sl); i := i+1) {
1242 var HLR_ConnHdlrPars pars := valueof(t_Pars_sub_via_proxy(sl[i]));
1243 pars.ussd.sid := f_rnd_octstring(4);
1244 f_vty_subscr_create(VTY, pars.sub);
1245 vc_conn := f_start_handler(refers(f_TC_mo_ussd_iuse_imsi), pars);
1246 vc_conn.done;
1247 }
1248}
Harald Welte4ea1f8a2018-06-12 09:26:10 +02001249
1250/* Test for USSD request to internal own-msisdn IUSE. */
1251private function f_TC_mo_ussd_iuse_msisdn() runs on HLR_ConnHdlr {
1252 var GSUP_PDU res;
1253 var charstring resp_str;
1254 var octetstring ss := f_USSD_FACILITY_IE_INVOKE(
1255 op_code := SS_OP_CODE_PROCESS_USS_REQ,
1256 ussd_string := "*#100#");
1257 GSUP.send(valueof(ts_GSUP_PROC_SS_REQ(g_pars.sub.imsi, g_pars.ussd.sid,
Neels Hofmeyrb2168512019-11-11 03:40:26 +01001258 OSMO_GSUP_SESSION_STATE_BEGIN, ss,
1259 source_name := g_pars.source_name)));
Harald Welte4ea1f8a2018-06-12 09:26:10 +02001260 resp_str := "Your extension is " & hex2str(g_pars.sub.msisdn);
Vadim Yanitskiy06e53c52019-03-28 15:08:24 +07001261 res := f_SS_expect(g_pars.sub.imsi, g_pars.ussd.sid,
1262 OSMO_GSUP_SESSION_STATE_END,
1263 tr_SS_USSD_FACILITY_RETURN_RESULT(1, 59, SS_USSD_DEFAULT_DCS,
Neels Hofmeyrb2168512019-11-11 03:40:26 +01001264 f_encGSM7bit(resp_str)),
1265 destination_name := g_pars.source_name);
Harald Welte4ea1f8a2018-06-12 09:26:10 +02001266}
1267testcase TC_mo_ussd_iuse_msisdn() runs on test_CT {
1268 var HlrSubscriberList sl;
1269 var HLR_ConnHdlr vc_conn;
1270
1271 f_init(false);
1272 sl := f_gen_subs();
1273 for (var integer i := 0; i < sizeof(sl); i := i+1) {
1274 var HLR_ConnHdlrPars pars := valueof(t_Pars_sub(sl[i]));
1275 pars.ussd.sid := f_rnd_octstring(4);
1276 f_vty_subscr_create(VTY, pars.sub);
1277 vc_conn := f_start_handler(refers(f_TC_mo_ussd_iuse_msisdn), pars);
1278 vc_conn.done;
1279 }
1280}
Neels Hofmeyrb2168512019-11-11 03:40:26 +01001281testcase TC_mo_ussd_iuse_msisdn_via_proxy() runs on test_CT {
1282 var HlrSubscriberList sl;
1283 var HLR_ConnHdlr vc_conn;
1284
1285 f_init(false);
1286 sl := f_gen_subs();
1287 for (var integer i := 0; i < sizeof(sl); i := i+1) {
1288 var HLR_ConnHdlrPars pars := valueof(t_Pars_sub_via_proxy(sl[i]));
1289 pars.ussd.sid := f_rnd_octstring(4);
1290 f_vty_subscr_create(VTY, pars.sub);
1291 vc_conn := f_start_handler(refers(f_TC_mo_ussd_iuse_msisdn), pars);
1292 vc_conn.done;
1293 }
1294}
Harald Welte4ea1f8a2018-06-12 09:26:10 +02001295
1296/* Test routing of USSD to EUSE by a specific route */
1297private function f_TC_mo_ussd_100() runs on HLR_ConnHdlr {
1298 var GSUP_PDU res;
1299 /* invoke / invoke id 1 / processUSS-req */
1300 //var octetstring ss := 'a11202010102013b300a04010f0405aa180c3602'O;
1301 var octetstring ss := f_USSD_FACILITY_IE_INVOKE(
1302 op_code := SS_OP_CODE_PROCESS_USS_REQ,
1303 ussd_string := "*100#");
1304 GSUP.send(valueof(ts_GSUP_PROC_SS_REQ(g_pars.sub.imsi, g_pars.ussd.sid,
1305 OSMO_GSUP_SESSION_STATE_BEGIN, ss)));
Vadim Yanitskiy06e53c52019-03-28 15:08:24 +07001306 res := f_SS_expect(g_pars.sub.imsi, g_pars.ussd.sid,
1307 OSMO_GSUP_SESSION_STATE_END,
1308 tr_SS_USSD_FACILITY_RETURN_RESULT(1, 59, SS_USSD_DEFAULT_DCS,
1309 f_encGSM7bit("*100#")));
Harald Welte4ea1f8a2018-06-12 09:26:10 +02001310}
1311testcase TC_mo_ussd_euse() runs on test_CT {
1312 var HlrSubscriberList sl;
1313 var HLR_ConnHdlr vc_conn;
1314
1315 var HLR_EUSE_CT vc_EUSE := HLR_EUSE_CT.create("EUSE-" & testcasename());
1316 vc_EUSE.start(HLR_EUSE.f_main_mo(mp_hlr_ip, mp_hlr_gsup_port, "foobar", refers(f_ss_echo)));
1317
1318 f_init(false);
1319 sl := f_gen_subs();
1320 for (var integer i := 0; i < sizeof(sl); i := i+1) {
1321 var HLR_ConnHdlrPars pars := valueof(t_Pars_sub(sl[i]));
1322 pars.ussd.sid := f_rnd_octstring(4);
1323 f_vty_subscr_create(VTY, pars.sub);
1324 vc_conn := f_start_handler(refers(f_TC_mo_ussd_100), pars);
1325 vc_conn.done;
1326 }
1327
1328 vc_EUSE.stop;
1329}
1330
1331/* Test routing of USSD to EUSE by a specific route, with CONTINUE */
1332private function f_TC_mo_ussd_100_continue() runs on HLR_ConnHdlr {
1333 var GSUP_PDU res;
1334 /* Simulate BEGIN from MS/MSC */
1335 var octetstring ss := f_USSD_FACILITY_IE_INVOKE(op_code := SS_OP_CODE_PROCESS_USS_REQ,
1336 ussd_string := "*100#");
1337 GSUP.send(valueof(ts_GSUP_PROC_SS_REQ(g_pars.sub.imsi, g_pars.ussd.sid,
1338 OSMO_GSUP_SESSION_STATE_BEGIN, ss)));
1339 /* expect echo response from EUSE */
Vadim Yanitskiy06e53c52019-03-28 15:08:24 +07001340 res := f_SS_expect(g_pars.sub.imsi, g_pars.ussd.sid,
1341 OSMO_GSUP_SESSION_STATE_CONTINUE,
1342 tr_SS_USSD_FACILITY_RETURN_RESULT(1, 59, SS_USSD_DEFAULT_DCS,
1343 f_encGSM7bit("*100#")));
Harald Welte4ea1f8a2018-06-12 09:26:10 +02001344
1345 /* Simulate CONTINUE from MS/MSC */
1346 ss := f_USSD_FACILITY_IE_INVOKE(op_code := SS_OP_CODE_PROCESS_USS_REQ,
1347 ussd_string := "mahlzeit");
1348 GSUP.send(valueof(ts_GSUP_PROC_SS_REQ(g_pars.sub.imsi, g_pars.ussd.sid,
1349 OSMO_GSUP_SESSION_STATE_CONTINUE, ss)));
1350
1351 /* expect echo response from EUSE */
Vadim Yanitskiy06e53c52019-03-28 15:08:24 +07001352 res := f_SS_expect(g_pars.sub.imsi, g_pars.ussd.sid,
1353 OSMO_GSUP_SESSION_STATE_END,
1354 tr_SS_USSD_FACILITY_RETURN_RESULT(1, 59, SS_USSD_DEFAULT_DCS,
1355 f_encGSM7bit("mahlzeit")));
Harald Welte4ea1f8a2018-06-12 09:26:10 +02001356}
1357testcase TC_mo_ussd_euse_continue() runs on test_CT {
1358 var HlrSubscriberList sl;
1359 var HLR_ConnHdlr vc_conn;
1360
1361 var HLR_EUSE_CT vc_EUSE := HLR_EUSE_CT.create("EUSE-" & testcasename());
1362 vc_EUSE.start(HLR_EUSE.f_main_mo(mp_hlr_ip, mp_hlr_gsup_port, "foobar",
1363 refers(f_ss_echo_continue)));
1364
1365 f_init(false);
1366 sl := f_gen_subs();
1367 for (var integer i := 0; i < sizeof(sl); i := i+1) {
1368 var HLR_ConnHdlrPars pars := valueof(t_Pars_sub(sl[i]));
1369 pars.ussd.sid := f_rnd_octstring(4);
1370 f_vty_subscr_create(VTY, pars.sub);
1371 vc_conn := f_start_handler(refers(f_TC_mo_ussd_100_continue), pars);
1372 vc_conn.done;
1373 }
1374
1375 vc_EUSE.stop;
1376}
1377
1378
1379/* Test routing of USSD to EUSE by default-route */
1380private function f_TC_mo_ussd_999() runs on HLR_ConnHdlr {
1381 var GSUP_PDU res;
1382 var octetstring ss := f_USSD_FACILITY_IE_INVOKE(
1383 op_code := SS_OP_CODE_PROCESS_USS_REQ,
1384 ussd_string := "*999#");
1385 GSUP.send(valueof(ts_GSUP_PROC_SS_REQ(g_pars.sub.imsi, g_pars.ussd.sid,
1386 OSMO_GSUP_SESSION_STATE_BEGIN, ss)));
Vadim Yanitskiy06e53c52019-03-28 15:08:24 +07001387 res := f_SS_expect(g_pars.sub.imsi, g_pars.ussd.sid,
1388 OSMO_GSUP_SESSION_STATE_END,
1389 tr_SS_USSD_FACILITY_RETURN_RESULT(1, 59, SS_USSD_DEFAULT_DCS,
1390 f_encGSM7bit("*999#")));
Harald Welte4ea1f8a2018-06-12 09:26:10 +02001391}
1392testcase TC_mo_ussd_euse_defaultroute() runs on test_CT {
1393 var HlrSubscriberList sl;
1394 var HLR_ConnHdlr vc_conn;
1395
1396 var HLR_EUSE_CT vc_EUSE := HLR_EUSE_CT.create("EUSE-" & testcasename());
1397 vc_EUSE.start(HLR_EUSE.f_main_mo(mp_hlr_ip, mp_hlr_gsup_port, "foobar", refers(f_ss_echo)));
1398
1399 f_init(false);
1400 f_vty_config(VTY, "hlr", "ussd default-route external foobar");
1401
1402 sl := f_gen_subs();
1403 for (var integer i := 0; i < sizeof(sl); i := i+1) {
1404 var HLR_ConnHdlrPars pars := valueof(t_Pars_sub(sl[i]));
1405 pars.ussd.sid := f_rnd_octstring(4);
1406 f_vty_subscr_create(VTY, pars.sub);
1407 vc_conn := f_start_handler(refers(f_TC_mo_ussd_999), pars);
1408 vc_conn.done;
1409 }
1410
1411 f_vty_config(VTY, "hlr", "no ussd default-route");
1412 vc_EUSE.stop;
1413}
1414
Vadim Yanitskiyeffab7c2018-11-28 06:02:22 +07001415/**
1416 * Test "Structured" Supplementary Services
1417 *
1418 * NOTE: at the moment, OsmoHLR doesn't support "structured" SS,
1419 * so such requests are being rejected (actually ReturnError
1420 * with GSM0480_ERR_CODE_FACILITY_NOT_SUPPORTED).
1421 */
1422private function f_TC_mo_sss_reject() runs on HLR_ConnHdlr {
1423 var SS_FacilityInformation ss_req;
Vadim Yanitskiy06e53c52019-03-28 15:08:24 +07001424 var GSUP_PDU res;
Vadim Yanitskiyeffab7c2018-11-28 06:02:22 +07001425
1426 /* Prepare '*#21#' SS request */
1427 ss_req := valueof(ts_SS_FACILITY_INVOKE(
1428 invoke_id := 0,
1429 op_code := SS_OP_CODE_INTERROGATE_SS,
1430 ss_code := '21'O));
1431
1432 /* Send it towards HLR */
1433 GSUP.send(valueof(ts_GSUP_PROC_SS_REQ(
1434 g_pars.sub.imsi,
1435 g_pars.ussd.sid,
1436 OSMO_GSUP_SESSION_STATE_BEGIN,
1437 enc_SS_FacilityInformation(ss_req))));
1438
1439 /* Expect ReturnError with FACILITY_NOT_SUPPORTED */
Vadim Yanitskiy06e53c52019-03-28 15:08:24 +07001440 res := f_SS_expect(g_pars.sub.imsi, g_pars.ussd.sid,
1441 OSMO_GSUP_SESSION_STATE_END,
1442 tr_SS_FACILITY_RETURN_ERROR(0, 21));
Vadim Yanitskiyeffab7c2018-11-28 06:02:22 +07001443}
1444testcase TC_mo_sss_reject() runs on test_CT {
1445 var HLR_ConnHdlrPars pars;
1446 var HLR_ConnHdlr vc_conn;
1447 var HlrSubscriber sub;
1448
1449 f_init(false);
1450
1451 /* Create a random subscriber */
1452 sub := valueof(t_Sub2G(f_rnd_imsi('26242'H),
1453 '49161'H & f_rnd_hexstring(7, 9), "comp128v1"));
1454 pars := valueof(t_Pars_sub(sub));
1455 pars.ussd.sid := f_rnd_octstring(4);
1456
1457 f_vty_subscr_create(VTY, sub);
1458 vc_conn := f_start_handler(refers(f_TC_mo_sss_reject), pars);
1459 vc_conn.done;
1460 f_vty_subscr_delete(VTY, sub);
1461}
1462
Harald Welte4ea1f8a2018-06-12 09:26:10 +02001463
1464/* TODO USSD:
1465 * MO USSD for IMSI of non-existant subscriber
1466 * MT USSD from EUSE
1467 * timeout cases
1468 */
1469
Oliver Smith936dbe62019-06-04 15:54:17 +02001470
1471/* Test Check IMEI */
1472private function f_TC_gsup_check_imei() runs on HLR_ConnHdlr {
1473 /* store-imei disabled */
1474 f_vty_config(VTY, "hlr", "no store-imei");
Neels Hofmeyrb2168512019-11-11 03:40:26 +01001475 f_perform_CHECK_IMEI(g_pars.sub.imsi, '12345678901234'H, result := OSMO_GSUP_IMEI_RESULT_ACK,
1476 source_name := g_pars.source_name);
Oliver Smith936dbe62019-06-04 15:54:17 +02001477 f_vty_subscr_show_nomatch(VTY, g_pars.sub, pattern "*IMEI: *12345678901234*");
1478
1479 /* store-imei enabled */
1480 f_vty_config(VTY, "hlr", "store-imei");
Neels Hofmeyrb2168512019-11-11 03:40:26 +01001481 f_perform_CHECK_IMEI(g_pars.sub.imsi, '12345678901234'H, result := OSMO_GSUP_IMEI_RESULT_ACK,
1482 source_name := g_pars.source_name);
Oliver Smith936dbe62019-06-04 15:54:17 +02001483 f_vty_subscr_show(VTY, g_pars.sub, pattern "*IMEI: *12345678901234*");
1484}
1485testcase TC_gsup_check_imei() runs on test_CT {
1486 var HlrSubscriberList sl;
1487
1488 f_init(false);
1489 sl := f_gen_subs();
1490 f_start_handler_per_sub(refers(f_TC_gsup_check_imei), sl);
1491
1492 setverdict(pass);
1493}
Neels Hofmeyrb2168512019-11-11 03:40:26 +01001494testcase TC_gsup_check_imei_via_proxy() runs on test_CT {
1495 var HlrSubscriberList sl;
1496
1497 f_init(false);
1498 sl := f_gen_subs();
1499 f_start_handler_per_sub(refers(f_TC_gsup_check_imei), sl, via_proxy := true);
1500
1501 setverdict(pass);
1502}
Oliver Smith936dbe62019-06-04 15:54:17 +02001503
1504/* Test Check IMEI with invalid IMEI length */
1505private function f_TC_gsup_check_imei_invalid_len() runs on HLR_ConnHdlr {
1506 /* IMEI too long */
1507 f_perform_CHECK_IMEI(g_pars.sub.imsi, '111456789012345F'H, 96 /* Invalid Mandatory Information */);
1508 f_perform_CHECK_IMEI(g_pars.sub.imsi, '2224567890123456'H, 96 /* Invalid Mandatory Information */);
1509
1510 /* IMEI too short */
1511 f_perform_CHECK_IMEI(g_pars.sub.imsi, '3334567890123F'H, 96 /* Invalid Mandatory Information */);
1512 f_perform_CHECK_IMEI(g_pars.sub.imsi, '444456789012'H, 96 /* Invalid Mandatory Information */);
1513 f_perform_CHECK_IMEI(g_pars.sub.imsi, ''H, 96 /* Invalid Mandatory Information */);
1514}
1515testcase TC_gsup_check_imei_invalid_len() runs on test_CT {
1516 var HlrSubscriberList sl;
1517
1518 f_init(false);
1519 sl := f_gen_subs();
1520 f_start_handler_per_sub(refers(f_TC_gsup_check_imei_invalid_len), sl);
1521
1522 setverdict(pass);
1523}
1524
1525/* Test Check IMEI with unknown IMSI */
1526private function f_TC_gsup_check_imei_unknown_imsi() runs on HLR_ConnHdlr {
1527 f_vty_config(VTY, "hlr", "no store-imei");
1528 f_perform_CHECK_IMEI(g_pars.sub.imsi, '22245678901234'H, 96 /* Invalid Mandatory Information */);
1529
1530 /* Check again with store-imei set (different code path) */
1531 f_vty_config(VTY, "hlr", "store-imei");
1532 f_perform_CHECK_IMEI(g_pars.sub.imsi, '22245678901234'H, 96 /* Invalid Mandatory Information */);
1533
1534 setverdict(pass);
1535}
1536testcase TC_gsup_check_imei_unknown_imsi() runs on test_CT {
1537 var hexstring imsi := f_rnd_imsi('26242'H);
1538 var HLR_ConnHdlrPars pars := valueof(t_Pars(imsi));
1539 var HLR_ConnHdlr vc_conn;
1540
1541 f_init(false);
1542 vc_conn := f_start_handler(refers(f_TC_gsup_check_imei_unknown_imsi), pars);
1543 vc_conn.done;
1544}
1545
Oliver Smith1b257802019-06-11 09:43:42 +02001546/* Test create-subscriber-on-demand during Check IMEI (OsmoMSC would be set to "check-imei-rqd early") */
1547private function f_TC_subscr_create_on_demand_check_imei_early() runs on HLR_ConnHdlr {
1548 var GSUP_PDU res; /* save various return values to prevent ttcn3 compiler warnings */
1549 var charstring imsi_pattern := "*IMSI: " & hex2str(g_pars.sub.imsi) & "*";
1550
1551 /* Random MSISDN and CS+PS NAM (LU must pass) */
1552 f_vty_config(VTY, "hlr", "subscriber-create-on-demand 3 cs+ps");
1553 f_perform_CHECK_IMEI(g_pars.sub.imsi, '12345678901234'H, result := OSMO_GSUP_IMEI_RESULT_ACK);
1554 f_vty_subscr_show(VTY, g_pars.sub, pattern imsi_pattern);
1555 f_vty_subscr_show(VTY, g_pars.sub, pattern "*MSISDN: \d\d\d*"); /* last line, hence not matching "\d\d\d\n" */
1556 f_vty_subscr_show_nomatch(VTY, g_pars.sub, pattern "*[CP]S disabled*");
1557 res := f_perform_UL(g_pars.sub.imsi, ?);
1558 f_vty_subscr_delete(VTY, g_pars.sub);
1559
1560 /* Random MSISDN and PS NAM (LU must pass) */
1561 f_vty_config(VTY, "hlr", "subscriber-create-on-demand 3 ps");
1562 f_perform_CHECK_IMEI(g_pars.sub.imsi, '12345678901234'H, result := OSMO_GSUP_IMEI_RESULT_ACK);
1563 f_vty_subscr_show(VTY, g_pars.sub, pattern imsi_pattern);
1564 f_vty_subscr_show(VTY, g_pars.sub, pattern "*MSISDN: \d\d\d*");
1565 f_vty_subscr_show(VTY, g_pars.sub, pattern "*CS disabled*");
1566 f_vty_subscr_show_nomatch(VTY, g_pars.sub, pattern "*PS disabled*");
1567 res := f_perform_UL(g_pars.sub.imsi, ?);
1568 f_vty_subscr_delete(VTY, g_pars.sub);
1569
1570 /* Random MSISDN and CS NAM (LU must fail) */
1571 f_vty_config(VTY, "hlr", "subscriber-create-on-demand 3 cs");
1572 f_perform_CHECK_IMEI(g_pars.sub.imsi, '12345678901234'H, result := OSMO_GSUP_IMEI_RESULT_ACK);
1573 f_vty_subscr_show(VTY, g_pars.sub, pattern imsi_pattern);
1574 f_vty_subscr_show(VTY, g_pars.sub, pattern "*MSISDN: \d\d\d*");
1575 f_vty_subscr_show(VTY, g_pars.sub, pattern "*PS disabled*");
1576 f_vty_subscr_show_nomatch(VTY, g_pars.sub, pattern "*CS disabled*");
1577 res := f_perform_UL(g_pars.sub.imsi, ?, 7 /* GPRS services not allowed */);
1578 f_vty_subscr_delete(VTY, g_pars.sub);
1579
1580 /* Random MSISDN and no NAM (LU must fail) */
1581 f_vty_config(VTY, "hlr", "subscriber-create-on-demand 3 none");
1582 f_perform_CHECK_IMEI(g_pars.sub.imsi, '12345678901234'H, result := OSMO_GSUP_IMEI_RESULT_ACK);
1583 f_vty_subscr_show(VTY, g_pars.sub, pattern imsi_pattern);
1584 f_vty_subscr_show(VTY, g_pars.sub, pattern "*MSISDN: \d\d\d*");
1585 f_vty_subscr_show(VTY, g_pars.sub, pattern "*CS disabled*PS disabled*");
1586 res := f_perform_UL(g_pars.sub.imsi, ?, 7 /* GPRS services not allowed */);
1587 f_vty_subscr_delete(VTY, g_pars.sub);
1588
1589 /* No MSISDN and no NAM (LU must fail) */
1590 f_vty_config(VTY, "hlr", "subscriber-create-on-demand no-msisdn none");
1591 f_perform_CHECK_IMEI(g_pars.sub.imsi, '12345678901234'H, result := OSMO_GSUP_IMEI_RESULT_ACK);
1592 f_vty_subscr_show(VTY, g_pars.sub, pattern imsi_pattern);
1593 f_vty_subscr_show(VTY, g_pars.sub, pattern "*MSISDN: none*");
1594 f_vty_subscr_show(VTY, g_pars.sub, pattern "*CS disabled*PS disabled*");
1595 res := f_perform_UL(g_pars.sub.imsi, ?, 7 /* GPRS services not allowed */);
1596 f_vty_subscr_delete(VTY, g_pars.sub);
1597
1598 /* No MSISDN and CS+PS NAM (LU must pass) */
1599 f_vty_config(VTY, "hlr", "subscriber-create-on-demand no-msisdn cs+ps");
1600 f_perform_CHECK_IMEI(g_pars.sub.imsi, '12345678901234'H, result := OSMO_GSUP_IMEI_RESULT_ACK);
1601 f_vty_subscr_show(VTY, g_pars.sub, pattern imsi_pattern);
1602 f_vty_subscr_show(VTY, g_pars.sub, pattern "*MSISDN: none*");
1603 f_vty_subscr_show_nomatch(VTY, g_pars.sub, pattern "*[CP]S disabled*");
1604 res := f_perform_UL(g_pars.sub.imsi, omit);
1605 f_vty_subscr_delete(VTY, g_pars.sub);
1606
1607 setverdict(pass);
1608}
1609testcase TC_subscr_create_on_demand_check_imei_early() runs on test_CT {
1610 var hexstring imsi := f_rnd_imsi('26242'H);
1611 var HLR_ConnHdlrPars pars := valueof(t_Pars(imsi));
1612 var HLR_ConnHdlr vc_conn;
1613
1614 f_init(false);
1615 vc_conn := f_start_handler(refers(f_TC_subscr_create_on_demand_check_imei_early), pars);
1616 vc_conn.done;
1617}
1618
1619/* Test create-subscriber-on-demand during LU (Location Update) */
1620private function f_TC_subscr_create_on_demand_ul() runs on HLR_ConnHdlr {
1621 var GSUP_PDU res;
1622 var charstring imsi_pattern := "*IMSI: " & hex2str(g_pars.sub.imsi) & "*";
1623
1624 /* Random MSISDN and CS+PS NAM (LU must pass) */
1625 f_vty_config(VTY, "hlr", "subscriber-create-on-demand 3 cs+ps");
1626 res := f_perform_UL(g_pars.sub.imsi, ?);
1627 f_vty_subscr_show(VTY, g_pars.sub, pattern imsi_pattern);
1628 f_vty_subscr_show(VTY, g_pars.sub, pattern "*MSISDN: \d\d\d\n*");
1629 f_vty_subscr_show_nomatch(VTY, g_pars.sub, pattern "*[CP]S disabled*");
1630 f_vty_subscr_delete(VTY, g_pars.sub);
1631
1632 /* Random MSISDN and PS NAM (LU must pass) */
1633 f_vty_config(VTY, "hlr", "subscriber-create-on-demand 3 ps");
1634 res := f_perform_UL(g_pars.sub.imsi, ?);
1635 f_vty_subscr_show(VTY, g_pars.sub, pattern imsi_pattern);
1636 f_vty_subscr_show(VTY, g_pars.sub, pattern "*MSISDN: \d\d\d\n*");
1637 f_vty_subscr_show(VTY, g_pars.sub, pattern "*CS disabled*");
1638 f_vty_subscr_show_nomatch(VTY, g_pars.sub, pattern "*PS disabled*");
1639 f_vty_subscr_delete(VTY, g_pars.sub);
1640
1641 /* Random MSISDN and CS NAM (LU must fail) */
1642 f_vty_config(VTY, "hlr", "subscriber-create-on-demand 3 cs");
1643 res := f_perform_UL(g_pars.sub.imsi, ?, 7 /* GPRS services not allowed */);
1644 f_vty_subscr_show(VTY, g_pars.sub, pattern imsi_pattern);
1645 f_vty_subscr_show(VTY, g_pars.sub, pattern "*MSISDN: \d\d\d\n*");
1646 f_vty_subscr_show(VTY, g_pars.sub, pattern "*PS disabled*");
1647 f_vty_subscr_show_nomatch(VTY, g_pars.sub, pattern "*CS disabled*");
1648 f_vty_subscr_delete(VTY, g_pars.sub);
1649
1650 /* Random MSISDN and no NAM (LU must fail) */
1651 f_vty_config(VTY, "hlr", "subscriber-create-on-demand 3 none");
1652 res := f_perform_UL(g_pars.sub.imsi, ?, 7 /* GPRS services not allowed */);
1653 f_vty_subscr_show(VTY, g_pars.sub, pattern imsi_pattern);
1654 f_vty_subscr_show(VTY, g_pars.sub, pattern "*MSISDN: \d\d\d\n*");
1655 f_vty_subscr_show(VTY, g_pars.sub, pattern "*CS disabled*PS disabled*");
1656 f_vty_subscr_delete(VTY, g_pars.sub);
1657
1658 /* No MSISDN and no NAM (LU must fail) */
1659 f_vty_config(VTY, "hlr", "subscriber-create-on-demand no-msisdn none");
1660 res := f_perform_UL(g_pars.sub.imsi, ?, 7 /* GPRS services not allowed */);
1661 f_vty_subscr_show(VTY, g_pars.sub, pattern imsi_pattern);
1662 f_vty_subscr_show(VTY, g_pars.sub, pattern "*MSISDN: none*");
1663 f_vty_subscr_show(VTY, g_pars.sub, pattern "*CS disabled*PS disabled*");
1664 f_vty_subscr_delete(VTY, g_pars.sub);
1665
1666 /* No MSISDN and CS+PS NAM (LU must pass) */
1667 f_vty_config(VTY, "hlr", "subscriber-create-on-demand no-msisdn cs+ps");
1668 res := f_perform_UL(g_pars.sub.imsi, omit);
1669 f_vty_subscr_show(VTY, g_pars.sub, pattern imsi_pattern);
1670 f_vty_subscr_show(VTY, g_pars.sub, pattern "*MSISDN: none*");
1671 f_vty_subscr_show_nomatch(VTY, g_pars.sub, pattern "*[CP]S disabled*");
1672 f_vty_subscr_delete(VTY, g_pars.sub);
1673
1674 setverdict(pass);
1675}
1676testcase TC_subscr_create_on_demand_ul() runs on test_CT {
1677 var hexstring imsi := f_rnd_imsi('26242'H);
1678 var HLR_ConnHdlrPars pars := valueof(t_Pars(imsi));
1679 var HLR_ConnHdlr vc_conn;
1680
1681 f_init(false);
1682 vc_conn := f_start_handler(refers(f_TC_subscr_create_on_demand_ul), pars);
1683 vc_conn.done;
1684}
1685
1686/* Test create-subscriber-on-demand during SAI (SendAuthInfo) */
1687private function f_TC_subscr_create_on_demand_sai() runs on HLR_ConnHdlr {
1688 var GSUP_PDU res;
1689 var charstring imsi_pattern := "*IMSI: " & hex2str(g_pars.sub.imsi) & "*";
1690
1691 /* HLR creates the subscriber on demand. Then the IMSI is known, but there is no auth data, so the HLR returns
1692 * the "slightly inaccurate cause 'IMSI Unknown' via GSUP". The MS is able to do a LU afterwards. */
1693 f_vty_config(VTY, "hlr", "subscriber-create-on-demand 3 cs+ps");
1694 res := f_perform_SAI(g_pars.sub.imsi, 2 /* IMSI Unknown */ );
1695
1696 /* Verify that it was created before the LU */
1697 f_vty_subscr_show(VTY, g_pars.sub, pattern imsi_pattern);
1698 f_vty_subscr_show(VTY, g_pars.sub, pattern "*MSISDN: \d\d\d*"); /* last line, hence not matching "\d\d\d\n" */
1699 f_vty_subscr_show_nomatch(VTY, g_pars.sub, pattern "*[CP]S disabled*");
1700
1701 /* Location update */
1702 res := f_perform_UL(g_pars.sub.imsi, ?);
1703 f_vty_subscr_delete(VTY, g_pars.sub);
1704 setverdict(pass);
1705}
1706testcase TC_subscr_create_on_demand_sai() runs on test_CT {
1707 var hexstring imsi := f_rnd_imsi('26242'H);
1708 var HLR_ConnHdlrPars pars := valueof(t_Pars(imsi));
1709 var HLR_ConnHdlr vc_conn;
1710
1711 f_init(false);
1712 vc_conn := f_start_handler(refers(f_TC_subscr_create_on_demand_sai), pars);
1713 vc_conn.done;
1714}
1715
Oliver Smithdeb80a62019-11-29 16:01:54 +01001716/* Send an mslookup mDNS request to the home HLR, asking about a service that is not "gsup.hlr". (Hence the "_other" in
1717 * the test name, service "gsup.hlr" has different code paths, see related tests). */
1718private function f_TC_MSLookup_mDNS_service_other_home() runs on HLR_ConnHdlr {
1719 timer T;
1720 var MSLookup_mDNS vl_rmsg;
1721 var integer id := f_rnd_int(65535); /* mDNS packet ID */
1722 var hexstring msisdn := '49161'H & f_rnd_hexstring(7, 9);
1723 var charstring domain := "sip.voice." & hex2str(msisdn) & ".msisdn.mdns.osmocom.org";
1724
1725 /* Create subscriber */
1726 g_pars.sub.msisdn := msisdn;
1727 f_vty_subscr_create(VTY, g_pars.sub);
1728
1729 /* Send mDNS query, expect timeout */
1730 mDNS.send(ts_MSLookup_mDNS_query(id, domain));
1731 T.start(1.0);
1732 alt {
1733 [] mDNS.receive(tr_MSLookup_mDNS_result_IPv4(id, domain, '42424242'O, 5060)) {
1734 setverdict(fail, "OsmoHLR answered to mDNS query before subscriber did LU");
1735 }
1736 [] mDNS.receive(MSLookup_mDNS:?) -> value vl_rmsg {
1737 repeat;
1738 }
1739 [] T.timeout {
1740 }
1741 }
1742
1743 /* Location update */
1744 f_perform_UL(g_pars.sub.imsi, msisdn, dom := OSMO_GSUP_CN_DOMAIN_CS);
1745
1746 /* Send mDNS query again, expect result */
1747 mDNS.send(ts_MSLookup_mDNS_query(id, domain));
1748 T.start(1.0);
1749 alt {
1750 [] mDNS.receive(tr_MSLookup_mDNS_result_IPv4(id, domain, '42424242'O, 5060)) {
1751 setverdict(pass);
1752 }
1753 [] mDNS.receive(MSLookup_mDNS:?) -> value vl_rmsg {
1754 repeat;
1755 }
1756 [] T.timeout {
1757 setverdict(fail, "OsmoHLR did not answer to mDNS query");
1758 }
1759 }
1760
1761 f_vty_subscr_delete(VTY, g_pars.sub);
1762}
1763testcase TC_MSLookup_mDNS_service_other_home() runs on test_CT {
1764 var hexstring imsi := f_rnd_imsi('26242'H);
1765 var HLR_ConnHdlr vc_conn;
1766 var HLR_ConnHdlrPars pars := valueof(t_Pars(imsi));
1767
1768 f_init(false);
1769 f_vty_config(VTY, "mslookup", "mdns bind");
1770 f_vty_config2(VTY, {"mslookup", "server"}, "service sip.voice at 66.66.66.66 5060");
1771
1772 vc_conn := f_start_handler(refers(f_TC_MSLookup_mDNS_service_other_home), pars);
1773 vc_conn.done;
1774}
1775
Oliver Smithb51a53f2020-01-29 15:06:54 +01001776/* Let OsmoHLR act as proxy between MSC and another HLR during UL */
1777private function f_TC_MSLookup_GSUP_proxy() runs on HLR_ConnHdlr {
1778 f_perform_UL_proxy(g_pars.sub.imsi, g_pars.sub.msisdn, OSMO_GSUP_CN_DOMAIN_CS);
1779 setverdict(pass);
1780}
1781testcase TC_MSLookup_GSUP_proxy() runs on test_CT {
1782 var hexstring imsi := f_rnd_imsi('26242'H);
1783 var hexstring msisdn := '49161'H & f_rnd_hexstring(7, 9);
1784 var HLR_ConnHdlr vc_conn;
1785 var HLR_ConnHdlrPars pars := valueof(t_Pars(imsi, msisdn));
1786
1787 f_init(false, true);
1788 f_vty_config(VTY, "mslookup", "mdns bind");
1789 vc_conn := f_start_handler(refers(f_TC_MSLookup_GSUP_proxy), pars, true);
1790
1791 timer T := 3.0;
1792 T.start;
1793 alt {
1794 [] vc_conn.done {}
1795 [] T.timeout { setverdict(fail, "Timeout"); mtc.stop; };
1796 }
1797}
1798
Oliver Smith18b48082020-01-30 10:34:47 +01001799/* Request "gsup.hlr" service right after creating subscriber from the home HLR. "TC_MSLookup_mDNS_service_other_home"
1800 * is similar, but does not query the "gsup.hlr" service. The "gsup.hlr" service has a different code path in OsmoHLR:
1801 * - it exists without being explicitly configured and returns the IP and port of the HLR's own GSUP server
1802 * - the request is answered, even if the subscriber is not attached to the HLR (for Location Update via proxy) */
1803private function f_TC_MSLookup_mDNS_service_GSUP_HLR_home() runs on HLR_ConnHdlr {
1804 timer T;
1805 var MSLookup_mDNS vl_rmsg;
1806 var integer id := f_rnd_int(65535); /* mDNS packet ID */
1807 var charstring domain := "gsup.hlr." & hex2str(g_pars.sub.imsi) & ".imsi.mdns.osmocom.org";
1808
1809 /* Create subscriber */
1810 g_pars.sub.msisdn := '133713381339'H;
1811 f_vty_subscr_create(VTY, g_pars.sub);
1812
1813 /* Send mDNS query, expect result */
1814 mDNS.send(ts_MSLookup_mDNS_query(id, domain));
1815 T.start(1.0);
1816 alt {
1817 [] mDNS.receive(tr_MSLookup_mDNS_result_IPv4(id, domain, f_enc_IPv4(mp_hlr_ip), mp_hlr_gsup_port)) {
1818 setverdict(pass);
1819 }
1820 [] mDNS.receive(MSLookup_mDNS:?) -> value vl_rmsg {
1821 repeat;
1822 }
1823 [] T.timeout {
1824 setverdict(fail, "OsmoHLR did not answer to mDNS query");
1825 }
1826 }
1827
1828 f_vty_subscr_delete(VTY, g_pars.sub);
1829}
1830testcase TC_MSLookup_mDNS_service_GSUP_HLR_home() runs on test_CT {
1831 var hexstring imsi := f_rnd_imsi('26242'H);
1832 var HLR_ConnHdlr vc_conn;
1833 var HLR_ConnHdlrPars pars := valueof(t_Pars(imsi));
1834
1835 f_init(false);
1836 f_vty_config(VTY, "mslookup", "mdns bind");
1837
1838 vc_conn := f_start_handler(refers(f_TC_MSLookup_mDNS_service_GSUP_HLR_home), pars);
1839 vc_conn.done;
1840}
1841
Oliver Smithda83c832020-01-30 15:10:20 +01001842/* Ask proxy HLR about gsup.hlr service, and expect no answer. */
1843private function f_TC_MSLookup_mDNS_service_GSUP_HLR_proxy() runs on HLR_ConnHdlr {
1844 timer T;
1845 var integer id := f_rnd_int(65535); /* mDNS packet ID */
1846 var charstring domain := "gsup.hlr." & hex2str(g_pars.sub.imsi) & ".imsi.mdns.osmocom.org";
1847
1848 f_perform_UL_proxy(g_pars.sub.imsi, g_pars.sub.msisdn, OSMO_GSUP_CN_DOMAIN_CS);
1849
1850 /* Send mDNS query, expect timeout */
1851 mDNS.send(ts_MSLookup_mDNS_query(id, domain));
1852 T.start(1.0);
1853 alt {
1854 [] mDNS.receive(tr_MSLookup_mDNS_result_IPv4(id, domain, f_enc_IPv4(mp_hlr_ip), mp_hlr_gsup_port)) {
1855 setverdict(fail, "mslookup result received from proxy HLR for gsup.hlr service");
1856 }
1857 [] mDNS.receive(MSLookup_mDNS:?) {
1858 repeat;
1859 }
1860 [] T.timeout {
1861 setverdict(pass);
1862 }
1863 }
1864}
1865testcase TC_MSLookup_mDNS_service_GSUP_HLR_proxy() runs on test_CT {
1866 var hexstring imsi := f_rnd_imsi('26242'H);
1867 var hexstring msisdn := '49161'H & f_rnd_hexstring(7, 9);
1868 var HLR_ConnHdlr vc_conn;
1869 var HLR_ConnHdlrPars pars := valueof(t_Pars(imsi, msisdn));
1870
1871 f_init(false, true);
1872 f_vty_config(VTY, "mslookup", "mdns bind");
1873 vc_conn := f_start_handler(refers(f_TC_MSLookup_mDNS_service_GSUP_HLR_proxy), pars, true);
1874
1875 timer T := 3.0;
1876 T.start;
1877 alt {
1878 [] vc_conn.done {}
1879 [] T.timeout { setverdict(fail, "Timeout"); mtc.stop; };
1880 }
1881}
1882
Oliver Smith421ea892020-01-30 15:53:50 +01001883/* Ask proxy HLR about configured sip.voice service, and expect result. */
1884private function f_TC_MSLookup_mDNS_service_other_proxy() runs on HLR_ConnHdlr {
1885 timer T;
1886 var integer id := f_rnd_int(65535); /* mDNS packet ID */
1887 var charstring domain := "sip.voice." & hex2str(g_pars.sub.msisdn) & ".msisdn.mdns.osmocom.org";
1888
1889 f_perform_UL_proxy(g_pars.sub.imsi, g_pars.sub.msisdn, OSMO_GSUP_CN_DOMAIN_CS);
1890
1891 /* Send mDNS query, expect result */
1892 mDNS.send(ts_MSLookup_mDNS_query(id, domain));
1893 T.start(1.0);
1894 alt {
1895 [] mDNS.receive(tr_MSLookup_mDNS_result_IPv4(id, domain, f_enc_IPv4("66.66.66.66"), 5060)) {
1896 setverdict(pass);
1897 }
1898 [] mDNS.receive(MSLookup_mDNS:?) {
1899 repeat;
1900 }
1901 [] T.timeout {
1902 setverdict(fail, "Timeout");
1903 }
1904 }
1905}
1906testcase TC_MSLookup_mDNS_service_other_proxy() runs on test_CT {
1907 var hexstring imsi := f_rnd_imsi('26242'H);
1908 var hexstring msisdn := '49161'H & f_rnd_hexstring(7, 9);
1909 var HLR_ConnHdlr vc_conn;
1910 var HLR_ConnHdlrPars pars := valueof(t_Pars(imsi, msisdn));
1911
1912 f_init(false, true);
1913 f_vty_config(VTY, "mslookup", "mdns bind");
1914 f_vty_config2(VTY, {"mslookup", "server"}, "service sip.voice at 66.66.66.66 5060");
1915 vc_conn := f_start_handler(refers(f_TC_MSLookup_mDNS_service_other_proxy), pars, true);
1916
1917 timer T := 3.0;
1918 T.start;
1919 alt {
1920 [] vc_conn.done {}
1921 [] T.timeout { setverdict(fail, "Timeout"); mtc.stop; };
1922 }
1923}
1924
Harald Weltec2c52552018-03-01 21:20:39 +01001925/* TODO:
1926 * UL with ISD error
1927 * UL with ISD timeout
Harald Weltec2c52552018-03-01 21:20:39 +01001928 * LOCATION CANCEL
1929 * AUTH FAIL REP
1930 * DELETE DATA after hlr_subscr_nam() change
1931 * correctness
1932 ** wrong message type
1933 ** wrong length of PDU
1934 ** too short message
1935 ** missing IMSI IE
1936
1937 */
1938
Harald Weltedf327232017-12-28 22:51:51 +01001939control {
1940 execute( TC_gsup_sai_err_invalid_imsi() );
Harald Weltec2c52552018-03-01 21:20:39 +01001941 execute( TC_gsup_sai() );
Alexander Couzens92696442020-01-10 07:57:16 +01001942 execute( TC_gsup_sai_num_auth_vectors() );
Harald Welteaf7c3182019-08-22 12:40:22 +02001943 execute( TC_gsup_sai_eps() );
Harald Weltec2c52552018-03-01 21:20:39 +01001944 execute( TC_gsup_ul_unknown_imsi() );
Neels Hofmeyrb2168512019-11-11 03:40:26 +01001945 execute( TC_gsup_ul_unknown_imsi_via_proxy() );
Harald Welte3f662762018-03-02 10:48:20 +01001946 execute( TC_gsup_sai_err_unknown_imsi() );
Harald Weltec2c52552018-03-01 21:20:39 +01001947 execute( TC_gsup_ul() );
Neels Hofmeyrb2168512019-11-11 03:40:26 +01001948 execute( TC_gsup_ul_via_proxy() );
Harald Weltec2c52552018-03-01 21:20:39 +01001949 execute( TC_vty() );
Harald Welte09b3c502018-03-01 22:42:22 +01001950 execute( TC_vty_msisdn_isd() );
Harald Welte958f8b42018-03-01 23:40:17 +01001951 execute( TC_gsup_purge_cs() );
1952 execute( TC_gsup_purge_ps() );
1953 execute( TC_gsup_purge_unknown() );
Harald Welte4ea1f8a2018-06-12 09:26:10 +02001954
1955 execute( TC_mo_ussd_unknown() );
1956 execute( TC_mo_ussd_euse_disc() );
1957 execute( TC_mo_ussd_iuse_imsi() );
Neels Hofmeyrb2168512019-11-11 03:40:26 +01001958 execute( TC_mo_ussd_iuse_imsi_via_proxy() );
Harald Welte4ea1f8a2018-06-12 09:26:10 +02001959 execute( TC_mo_ussd_iuse_msisdn() );
Neels Hofmeyrb2168512019-11-11 03:40:26 +01001960 execute( TC_mo_ussd_iuse_msisdn_via_proxy() );
Harald Welte4ea1f8a2018-06-12 09:26:10 +02001961 execute( TC_mo_ussd_euse() );
1962 execute( TC_mo_ussd_euse_continue() );
1963 execute( TC_mo_ussd_euse_defaultroute() );
Vadim Yanitskiyeffab7c2018-11-28 06:02:22 +07001964
1965 /* "Structured" Supplementary Services */
1966 execute( TC_mo_sss_reject() );
Oliver Smith936dbe62019-06-04 15:54:17 +02001967
1968 execute( TC_gsup_check_imei() );
Neels Hofmeyrb2168512019-11-11 03:40:26 +01001969 execute( TC_gsup_check_imei_via_proxy() );
Oliver Smith936dbe62019-06-04 15:54:17 +02001970 execute( TC_gsup_check_imei_invalid_len() );
1971 execute( TC_gsup_check_imei_unknown_imsi() );
Oliver Smith1b257802019-06-11 09:43:42 +02001972 execute( TC_subscr_create_on_demand_check_imei_early() );
1973 execute( TC_subscr_create_on_demand_ul() );
1974 execute( TC_subscr_create_on_demand_sai() );
Oliver Smithdeb80a62019-11-29 16:01:54 +01001975
1976 if (mp_hlr_supports_dgsm) {
1977 execute( TC_MSLookup_mDNS_service_other_home() );
Oliver Smithb51a53f2020-01-29 15:06:54 +01001978 execute( TC_MSLookup_GSUP_proxy() );
Oliver Smith18b48082020-01-30 10:34:47 +01001979 execute( TC_MSLookup_mDNS_service_GSUP_HLR_home() );
Oliver Smithda83c832020-01-30 15:10:20 +01001980 execute( TC_MSLookup_mDNS_service_GSUP_HLR_proxy() );
Oliver Smith421ea892020-01-30 15:53:50 +01001981 execute( TC_MSLookup_mDNS_service_other_proxy() );
Oliver Smithdeb80a62019-11-29 16:01:54 +01001982 }
Harald Weltedf327232017-12-28 22:51:51 +01001983};
1984
1985};