blob: 529b7a5f4febf60707f7ac79f9e7e912063da22d [file] [log] [blame]
Neels Hofmeyr7685a782017-01-30 23:30:26 +01001/* OsmoHLR VTY implementation */
2
3/* (C) 2016 sysmocom s.f.m.c. GmbH <info@sysmocom.de>
Neels Hofmeyr7685a782017-01-30 23:30:26 +01004 * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
Harald Weltefa7ee332018-06-24 13:20:32 +02005 * (C) 2018 Harald Welte <laforge@gnumonks.org>
6 *
7 * All Rights Reserved
Neels Hofmeyr7685a782017-01-30 23:30:26 +01008 *
Harald Welte4956ae12018-06-15 22:04:28 +02009 * (C) 2018 Harald Welte <laforge@gnumonks.org>
10 *
11 * All Rights Reserved
12 *
Neels Hofmeyr7685a782017-01-30 23:30:26 +010013 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU Affero General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Affero General Public License for more details.
22 *
23 * You should have received a copy of the GNU Affero General Public License
24 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 *
26 */
27
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +020028#include <osmocom/core/talloc.h>
Neels Hofmeyr7685a782017-01-30 23:30:26 +010029#include <osmocom/vty/vty.h>
Max20ddfdb2019-02-18 13:12:27 +010030#include <osmocom/vty/stats.h>
Neels Hofmeyr7685a782017-01-30 23:30:26 +010031#include <osmocom/vty/command.h>
32#include <osmocom/vty/logging.h>
Harald Welte7ee6e552018-02-14 00:52:05 +010033#include <osmocom/vty/misc.h>
Harald Weltefa7ee332018-06-24 13:20:32 +020034#include <osmocom/abis/ipa.h>
Neels Hofmeyr7685a782017-01-30 23:30:26 +010035
Oliver Smithc7f17872019-03-04 15:10:44 +010036#include "db.h"
Harald Weltedab544e2018-07-29 16:14:48 +020037#include "hlr.h"
Neels Hofmeyr7685a782017-01-30 23:30:26 +010038#include "hlr_vty.h"
Neels Hofmeyr183e7002017-10-06 02:59:54 +020039#include "hlr_vty_subscr.h"
Vadim Yanitskiyd157a562018-12-01 00:03:39 +070040#include "hlr_ussd.h"
Harald Weltefa7ee332018-06-24 13:20:32 +020041#include "gsup_server.h"
Neels Hofmeyr7685a782017-01-30 23:30:26 +010042
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +020043struct cmd_node hlr_node = {
44 HLR_NODE,
45 "%s(config-hlr)# ",
46 1,
47};
48
49DEFUN(cfg_hlr,
50 cfg_hlr_cmd,
51 "hlr",
52 "Configure the HLR")
53{
54 vty->node = HLR_NODE;
55 return CMD_SUCCESS;
56}
57
58struct cmd_node gsup_node = {
59 GSUP_NODE,
60 "%s(config-hlr-gsup)# ",
61 1,
62};
63
64DEFUN(cfg_gsup,
65 cfg_gsup_cmd,
66 "gsup",
67 "Configure GSUP options")
68{
69 vty->node = GSUP_NODE;
70 return CMD_SUCCESS;
71}
72
73static int config_write_hlr(struct vty *vty)
74{
75 vty_out(vty, "hlr%s", VTY_NEWLINE);
Oliver Smith851814a2019-01-11 15:30:21 +010076 if (g_hlr->store_imei)
77 vty_out(vty, " store-imei%s", VTY_NEWLINE);
Neels Hofmeyr5857c592019-04-02 04:24:49 +020078 if (g_hlr->db_file_path && strcmp(g_hlr->db_file_path, HLR_DEFAULT_DB_FILE_PATH))
79 vty_out(vty, " database %s%s", g_hlr->db_file_path, VTY_NEWLINE);
Oliver Smithc7f17872019-03-04 15:10:44 +010080 if (g_hlr->subscr_create_on_demand) {
81 const char *flags_str = "none";
82 uint8_t flags = g_hlr->subscr_create_on_demand_flags;
83 unsigned int rand_msisdn_len = g_hlr->subscr_create_on_demand_rand_msisdn_len;
84
85 if ((flags & DB_SUBSCR_FLAG_NAM_CS) && (flags & DB_SUBSCR_FLAG_NAM_PS))
86 flags_str = "cs+ps";
87 else if (flags & DB_SUBSCR_FLAG_NAM_CS)
88 flags_str = "cs";
89 else if (flags & DB_SUBSCR_FLAG_NAM_PS)
90 flags_str = "ps";
91
92 if (rand_msisdn_len)
93 vty_out(vty, " subscriber-create-on-demand %i %s%s", rand_msisdn_len, flags_str, VTY_NEWLINE);
94 else
95 vty_out(vty, " subscriber-create-on-demand no-msisdn %s%s", flags_str, VTY_NEWLINE);
96 }
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +020097 return CMD_SUCCESS;
98}
99
100static int config_write_hlr_gsup(struct vty *vty)
101{
102 vty_out(vty, " gsup%s", VTY_NEWLINE);
103 if (g_hlr->gsup_bind_addr)
104 vty_out(vty, " bind ip %s%s", g_hlr->gsup_bind_addr, VTY_NEWLINE);
105 return CMD_SUCCESS;
106}
107
Harald Weltefa7ee332018-06-24 13:20:32 +0200108static void show_one_conn(struct vty *vty, const struct osmo_gsup_conn *conn)
109{
110 const struct ipa_server_conn *isc = conn->conn;
111 char *name;
112 int rc;
113
114 rc = osmo_gsup_conn_ccm_get(conn, (uint8_t **) &name, IPAC_IDTAG_SERNR);
115 OSMO_ASSERT(rc);
116
117 vty_out(vty, " '%s' from %s:%5u, CS=%u, PS=%u, 3G_IND=%u%s",
118 name, isc->addr, isc->port, conn->supports_cs, conn->supports_ps, conn->auc_3g_ind,
119 VTY_NEWLINE);
120}
121
122DEFUN(show_gsup_conn, show_gsup_conn_cmd,
123 "show gsup-connections",
124 SHOW_STR "GSUP Connections from VLRs, SGSNs, EUSEs\n")
125{
126 struct osmo_gsup_server *gs = g_hlr->gs;
127 struct osmo_gsup_conn *conn;
128
129 llist_for_each_entry(conn, &gs->clients, list)
130 show_one_conn(vty, conn);
131
132 return CMD_SUCCESS;
133}
134
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200135DEFUN(cfg_hlr_gsup_bind_ip,
136 cfg_hlr_gsup_bind_ip_cmd,
137 "bind ip A.B.C.D",
138 "Listen/Bind related socket option\n"
139 IP_STR
140 "IPv4 Address to bind the GSUP interface to\n")
141{
142 if(g_hlr->gsup_bind_addr)
143 talloc_free(g_hlr->gsup_bind_addr);
144 g_hlr->gsup_bind_addr = talloc_strdup(g_hlr, argv[0]);
145
146 return CMD_SUCCESS;
147}
148
Harald Welte4956ae12018-06-15 22:04:28 +0200149/***********************************************************************
Harald Weltedab544e2018-07-29 16:14:48 +0200150 * USSD Entity
Harald Welte4956ae12018-06-15 22:04:28 +0200151 ***********************************************************************/
152
153#include "hlr_ussd.h"
154
Harald Weltedab544e2018-07-29 16:14:48 +0200155#define USSD_STR "USSD Configuration\n"
156#define UROUTE_STR "Routing Configuration\n"
157#define PREFIX_STR "Prefix-Matching Route\n" "USSD Prefix\n"
Harald Welte4956ae12018-06-15 22:04:28 +0200158
Piotr Krysik0b497962019-08-22 11:18:15 +0200159#define INT_CHOICE "(own-msisdn|own-imsi|get-ran|gsm-on|gsm-off|umts-on|umts-off|lte-on|lte-off)"
Harald Weltedab544e2018-07-29 16:14:48 +0200160#define INT_STR "Internal USSD Handler\n" \
161 "Respond with subscribers' own MSISDN\n" \
Vadim Yanitskiy277b2d62018-12-27 05:39:54 +0700162 "Respond with subscribers' own IMSI\n" \
Vadim Yanitskiye9dd9c62018-12-27 08:15:00 +0700163 "Respond with available RAN types\n" \
Piotr Krysik0b497962019-08-22 11:18:15 +0200164 "Enable GSM service\n" \
165 "Disable GSM service\n" \
Vadim Yanitskiye9dd9c62018-12-27 08:15:00 +0700166 "Enable UMTS service\n" \
Piotr Krysik0b497962019-08-22 11:18:15 +0200167 "Disable UMTS service\n" \
168 "Enable LTE service\n" \
169 "Disable LTE service\n"
Harald Weltedab544e2018-07-29 16:14:48 +0200170
171#define EXT_STR "External USSD Handler\n" \
172 "Name of External USSD Handler (IPA CCM ID)\n"
173
174DEFUN(cfg_ussd_route_pfx_int, cfg_ussd_route_pfx_int_cmd,
175 "ussd route prefix PREFIX internal " INT_CHOICE,
176 USSD_STR UROUTE_STR PREFIX_STR INT_STR)
177{
178 const struct hlr_iuse *iuse = iuse_find(argv[1]);
179 struct hlr_ussd_route *rt = ussd_route_find_prefix(g_hlr, argv[0]);
Harald Welte4956ae12018-06-15 22:04:28 +0200180 if (rt) {
181 vty_out(vty, "%% Cannot add [another?] route for prefix %s%s", argv[0], VTY_NEWLINE);
182 return CMD_WARNING;
183 }
Harald Weltedab544e2018-07-29 16:14:48 +0200184 ussd_route_prefix_alloc_int(g_hlr, argv[0], iuse);
Harald Welte4956ae12018-06-15 22:04:28 +0200185
186 return CMD_SUCCESS;
187}
188
Harald Weltedab544e2018-07-29 16:14:48 +0200189DEFUN(cfg_ussd_route_pfx_ext, cfg_ussd_route_pfx_ext_cmd,
190 "ussd route prefix PREFIX external EUSE",
191 USSD_STR UROUTE_STR PREFIX_STR EXT_STR)
Harald Welte4956ae12018-06-15 22:04:28 +0200192{
Harald Weltedab544e2018-07-29 16:14:48 +0200193 struct hlr_euse *euse = euse_find(g_hlr, argv[1]);
194 struct hlr_ussd_route *rt = ussd_route_find_prefix(g_hlr, argv[0]);
195 if (rt) {
196 vty_out(vty, "%% Cannot add [another?] route for prefix %s%s", argv[0], VTY_NEWLINE);
197 return CMD_WARNING;
198 }
199 if (!euse) {
200 vty_out(vty, "%% Cannot find euse '%s'%s", argv[1], VTY_NEWLINE);
201 return CMD_WARNING;
202 }
203 ussd_route_prefix_alloc_ext(g_hlr, argv[0], euse);
204
205 return CMD_SUCCESS;
206}
207
208DEFUN(cfg_ussd_no_route_pfx, cfg_ussd_no_route_pfx_cmd,
209 "no ussd route prefix PREFIX",
210 NO_STR USSD_STR UROUTE_STR PREFIX_STR)
211{
212 struct hlr_ussd_route *rt = ussd_route_find_prefix(g_hlr, argv[0]);
Harald Welte4956ae12018-06-15 22:04:28 +0200213 if (!rt) {
214 vty_out(vty, "%% Cannot find route for prefix %s%s", argv[0], VTY_NEWLINE);
215 return CMD_WARNING;
216 }
Harald Weltedab544e2018-07-29 16:14:48 +0200217 ussd_route_del(rt);
Harald Welte4956ae12018-06-15 22:04:28 +0200218
219 return CMD_SUCCESS;
220}
221
Harald Weltedab544e2018-07-29 16:14:48 +0200222DEFUN(cfg_ussd_defaultroute, cfg_ussd_defaultroute_cmd,
223 "ussd default-route external EUSE",
224 USSD_STR "Configure default-route for all USSD to unknown destinations\n"
225 EXT_STR)
Harald Welte4956ae12018-06-15 22:04:28 +0200226{
Vadim Yanitskiyb93c44f2018-08-02 23:37:51 +0700227 struct hlr_euse *euse;
228
229 euse = euse_find(g_hlr, argv[0]);
230 if (!euse) {
231 vty_out(vty, "%% Cannot find EUSE %s%s", argv[0], VTY_NEWLINE);
232 return CMD_WARNING;
233 }
Harald Welte4956ae12018-06-15 22:04:28 +0200234
235 if (g_hlr->euse_default != euse) {
236 vty_out(vty, "Switching default route from %s to %s%s",
Harald Welte55d32a12018-07-30 17:26:35 +0200237 g_hlr->euse_default ? g_hlr->euse_default->name : "<none>",
238 euse->name, VTY_NEWLINE);
Harald Welte4956ae12018-06-15 22:04:28 +0200239 g_hlr->euse_default = euse;
240 }
241
242 return CMD_SUCCESS;
243}
244
Harald Weltedab544e2018-07-29 16:14:48 +0200245DEFUN(cfg_ussd_no_defaultroute, cfg_ussd_no_defaultroute_cmd,
246 "no ussd default-route",
247 NO_STR USSD_STR "Remove the default-route for all USSD to unknown destinations\n")
Harald Welte4956ae12018-06-15 22:04:28 +0200248{
Harald Welte4956ae12018-06-15 22:04:28 +0200249 g_hlr->euse_default = NULL;
250
251 return CMD_SUCCESS;
252}
253
Neels Hofmeyr5857c592019-04-02 04:24:49 +0200254DEFUN(cfg_database, cfg_database_cmd,
255 "database PATH",
256 "Set the path to the HLR database file\n"
257 "Relative or absolute file system path to the database file (default is '" HLR_DEFAULT_DB_FILE_PATH "')\n")
258{
259 osmo_talloc_replace_string(g_hlr, &g_hlr->db_file_path, argv[0]);
260 return CMD_SUCCESS;
261}
262
Harald Welte4956ae12018-06-15 22:04:28 +0200263struct cmd_node euse_node = {
264 EUSE_NODE,
265 "%s(config-hlr-euse)# ",
266 1,
267};
268
269DEFUN(cfg_euse, cfg_euse_cmd,
270 "euse NAME",
271 "Configure a particular External USSD Entity\n"
272 "Alphanumeric name of the External USSD Entity\n")
273{
274 struct hlr_euse *euse;
275 const char *id = argv[0];
276
277 euse = euse_find(g_hlr, id);
278 if (!euse) {
279 euse = euse_alloc(g_hlr, id);
280 if (!euse)
281 return CMD_WARNING;
282 }
283 vty->index = euse;
284 vty->index_sub = &euse->description;
285 vty->node = EUSE_NODE;
286
287 return CMD_SUCCESS;
288}
289
290DEFUN(cfg_no_euse, cfg_no_euse_cmd,
291 "no euse NAME",
292 NO_STR "Remove a particular External USSD Entity\n"
293 "Alphanumeric name of the External USSD Entity\n")
294{
295 struct hlr_euse *euse = euse_find(g_hlr, argv[0]);
296 if (!euse) {
297 vty_out(vty, "%% Cannot remove non-existant EUSE %s%s", argv[0], VTY_NEWLINE);
298 return CMD_WARNING;
299 }
300 if (g_hlr->euse_default == euse) {
301 vty_out(vty, "%% Cannot remove EUSE %s, it is the default route%s", argv[0], VTY_NEWLINE);
302 return CMD_WARNING;
303 }
304 euse_del(euse);
305 return CMD_SUCCESS;
306}
307
308static void dump_one_euse(struct vty *vty, struct hlr_euse *euse)
309{
Harald Welte4956ae12018-06-15 22:04:28 +0200310 vty_out(vty, " euse %s%s", euse->name, VTY_NEWLINE);
Harald Welte4956ae12018-06-15 22:04:28 +0200311}
312
313static int config_write_euse(struct vty *vty)
314{
315 struct hlr_euse *euse;
Harald Weltedab544e2018-07-29 16:14:48 +0200316 struct hlr_ussd_route *rt;
Harald Welte4956ae12018-06-15 22:04:28 +0200317
318 llist_for_each_entry(euse, &g_hlr->euse_list, list)
319 dump_one_euse(vty, euse);
320
Harald Weltedab544e2018-07-29 16:14:48 +0200321 llist_for_each_entry(rt, &g_hlr->ussd_routes, list) {
322 vty_out(vty, " ussd route prefix %s %s %s%s", rt->prefix,
323 rt->is_external ? "external" : "internal",
324 rt->is_external ? rt->u.euse->name : rt->u.iuse->name,
325 VTY_NEWLINE);
326 }
327
328 if (g_hlr->euse_default)
329 vty_out(vty, " ussd default-route external %s%s", g_hlr->euse_default->name, VTY_NEWLINE);
330
Vadim Yanitskiyd157a562018-12-01 00:03:39 +0700331 if (g_hlr->ncss_guard_timeout != NCSS_GUARD_TIMEOUT_DEFAULT)
332 vty_out(vty, " ncss-guard-timeout %i%s",
333 g_hlr->ncss_guard_timeout, VTY_NEWLINE);
334
Harald Welte4956ae12018-06-15 22:04:28 +0200335 return 0;
336}
337
Vadim Yanitskiyd157a562018-12-01 00:03:39 +0700338DEFUN(cfg_ncss_guard_timeout, cfg_ncss_guard_timeout_cmd,
339 "ncss-guard-timeout <0-255>",
340 "Set guard timer for NCSS (call independent SS) session activity\n"
341 "Guard timer value (sec.), or 0 to disable")
342{
343 g_hlr->ncss_guard_timeout = atoi(argv[0]);
344 return CMD_SUCCESS;
345}
346
Oliver Smith851814a2019-01-11 15:30:21 +0100347DEFUN(cfg_store_imei, cfg_store_imei_cmd,
348 "store-imei",
349 "Save the IMEI in the database when receiving Check IMEI requests. Note that an MSC does not necessarily send"
350 " Check IMEI requests (for OsmoMSC, you may want to set 'check-imei-rqd 1').")
351{
352 g_hlr->store_imei = true;
353 return CMD_SUCCESS;
354}
355
356DEFUN(cfg_no_store_imei, cfg_no_store_imei_cmd,
357 "no store-imei",
358 "Do not save the IMEI in the database, when receiving Check IMEI requests.")
359{
360 g_hlr->store_imei = false;
361 return CMD_SUCCESS;
362}
363
Oliver Smithc7f17872019-03-04 15:10:44 +0100364DEFUN(cfg_subscr_create_on_demand, cfg_subscr_create_on_demand_cmd,
365 "subscriber-create-on-demand (no-msisdn|<3-15>) (none|cs|ps|cs+ps)",
366 "Make a new record when a subscriber is first seen.\n"
367 "Do not automatically assign MSISDN.\n"
368 "Length of an automatically assigned MSISDN.\n"
369 "Do not allow any NAM (Network Access Mode) by default.\n"
370 "Allow access to circuit switched NAM by default.\n"
371 "Allow access to packet switched NAM by default.\n"
372 "Allow access to circuit and packet switched NAM by default.\n")
373{
374 unsigned int rand_msisdn_len = 0;
375 uint8_t flags = 0x00;
376
377 if (strcmp(argv[0], "no-msisdn") != 0)
378 rand_msisdn_len = atoi(argv[0]);
379
380 if (strstr(argv[1], "cs"))
381 flags |= DB_SUBSCR_FLAG_NAM_CS;
382 if (strstr(argv[1], "ps"))
383 flags |= DB_SUBSCR_FLAG_NAM_PS;
384
385 g_hlr->subscr_create_on_demand = true;
386 g_hlr->subscr_create_on_demand_rand_msisdn_len = rand_msisdn_len;
387 g_hlr->subscr_create_on_demand_flags = flags;
388
389 return CMD_SUCCESS;
390}
391
392DEFUN(cfg_no_subscr_create_on_demand, cfg_no_subscr_create_on_demand_cmd,
393 "no subscriber-create-on-demand",
394 "Do not make a new record when a subscriber is first seen.\n")
395{
396 g_hlr->subscr_create_on_demand = false;
397 return CMD_SUCCESS;
398}
399
Harald Welte4956ae12018-06-15 22:04:28 +0200400/***********************************************************************
401 * Common Code
402 ***********************************************************************/
403
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200404int hlr_vty_go_parent(struct vty *vty)
405{
406 switch (vty->node) {
407 case GSUP_NODE:
Harald Welte4956ae12018-06-15 22:04:28 +0200408 case EUSE_NODE:
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200409 vty->node = HLR_NODE;
410 vty->index = NULL;
Harald Welte4956ae12018-06-15 22:04:28 +0200411 vty->index_sub = NULL;
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200412 break;
413 default:
414 case HLR_NODE:
415 vty->node = CONFIG_NODE;
416 vty->index = NULL;
417 break;
418 case CONFIG_NODE:
419 vty->node = ENABLE_NODE;
420 vty->index = NULL;
421 break;
422 }
423
424 return vty->node;
425}
426
Neels Hofmeyr7685a782017-01-30 23:30:26 +0100427int hlr_vty_is_config_node(struct vty *vty, int node)
428{
429 switch (node) {
430 /* add items that are not config */
431 case CONFIG_NODE:
432 return 0;
433
434 default:
435 return 1;
436 }
437}
438
Pau Espin Pedrole49391b2019-08-05 15:57:10 +0200439void hlr_vty_init(void)
Neels Hofmeyr7685a782017-01-30 23:30:26 +0100440{
Pau Espin Pedrole49391b2019-08-05 15:57:10 +0200441 logging_vty_add_cmds();
Harald Welte7ee6e552018-02-14 00:52:05 +0100442 osmo_talloc_vty_add_cmds();
Max20ddfdb2019-02-18 13:12:27 +0100443 osmo_stats_vty_add_cmds();
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200444
Harald Weltefa7ee332018-06-24 13:20:32 +0200445 install_element_ve(&show_gsup_conn_cmd);
446
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200447 install_element(CONFIG_NODE, &cfg_hlr_cmd);
448 install_node(&hlr_node, config_write_hlr);
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200449
450 install_element(HLR_NODE, &cfg_gsup_cmd);
451 install_node(&gsup_node, config_write_hlr_gsup);
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200452
453 install_element(GSUP_NODE, &cfg_hlr_gsup_bind_ip_cmd);
Neels Hofmeyr183e7002017-10-06 02:59:54 +0200454
Neels Hofmeyr5857c592019-04-02 04:24:49 +0200455 install_element(HLR_NODE, &cfg_database_cmd);
456
Harald Welte4956ae12018-06-15 22:04:28 +0200457 install_element(HLR_NODE, &cfg_euse_cmd);
458 install_element(HLR_NODE, &cfg_no_euse_cmd);
459 install_node(&euse_node, config_write_euse);
Harald Weltedab544e2018-07-29 16:14:48 +0200460 install_element(HLR_NODE, &cfg_ussd_route_pfx_int_cmd);
461 install_element(HLR_NODE, &cfg_ussd_route_pfx_ext_cmd);
462 install_element(HLR_NODE, &cfg_ussd_no_route_pfx_cmd);
463 install_element(HLR_NODE, &cfg_ussd_defaultroute_cmd);
464 install_element(HLR_NODE, &cfg_ussd_no_defaultroute_cmd);
Vadim Yanitskiyd157a562018-12-01 00:03:39 +0700465 install_element(HLR_NODE, &cfg_ncss_guard_timeout_cmd);
Oliver Smith851814a2019-01-11 15:30:21 +0100466 install_element(HLR_NODE, &cfg_store_imei_cmd);
467 install_element(HLR_NODE, &cfg_no_store_imei_cmd);
Oliver Smithc7f17872019-03-04 15:10:44 +0100468 install_element(HLR_NODE, &cfg_subscr_create_on_demand_cmd);
469 install_element(HLR_NODE, &cfg_no_subscr_create_on_demand_cmd);
Harald Welte4956ae12018-06-15 22:04:28 +0200470
Harald Welted5807b82018-07-29 12:27:41 +0200471 hlr_vty_subscriber_init();
Neels Hofmeyr7685a782017-01-30 23:30:26 +0100472}