blob: 02e0cde70a5c5cfc29f553aee1ab76e02d257888 [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
Alexander Couzens268a33e2020-01-12 00:48:07 +010028#include <errno.h>
29
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +020030#include <osmocom/core/talloc.h>
Alexander Couzens268a33e2020-01-12 00:48:07 +010031#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
Neels Hofmeyr7685a782017-01-30 23:30:26 +010032#include <osmocom/vty/vty.h>
Max20ddfdb2019-02-18 13:12:27 +010033#include <osmocom/vty/stats.h>
Neels Hofmeyr7685a782017-01-30 23:30:26 +010034#include <osmocom/vty/command.h>
35#include <osmocom/vty/logging.h>
Harald Welte7ee6e552018-02-14 00:52:05 +010036#include <osmocom/vty/misc.h>
Harald Weltefa7ee332018-06-24 13:20:32 +020037#include <osmocom/abis/ipa.h>
Neels Hofmeyr7685a782017-01-30 23:30:26 +010038
Neels Hofmeyr2f758032019-11-20 00:37:07 +010039#include <osmocom/hlr/db.h>
40#include <osmocom/hlr/hlr.h>
41#include <osmocom/hlr/hlr_vty.h>
42#include <osmocom/hlr/hlr_vty_subscr.h>
43#include <osmocom/hlr/hlr_ussd.h>
44#include <osmocom/hlr/gsup_server.h>
Neels Hofmeyr7685a782017-01-30 23:30:26 +010045
Alexander Couzens268a33e2020-01-12 00:48:07 +010046static const struct value_string gsm48_gmm_cause_vty_names[] = {
47 { GMM_CAUSE_IMSI_UNKNOWN, "imsi-unknown" },
48 { GMM_CAUSE_ILLEGAL_MS, "illegal-ms" },
49 { GMM_CAUSE_PLMN_NOTALLOWED, "plmn-not-allowed" },
50 { GMM_CAUSE_LA_NOTALLOWED, "la-not-allowed" },
51 { GMM_CAUSE_ROAMING_NOTALLOWED, "roaming-not-allowed" },
52 { GMM_CAUSE_NO_SUIT_CELL_IN_LA, "no-suitable-cell-in-la" },
53 { GMM_CAUSE_NET_FAIL, "net-fail" },
54 { GMM_CAUSE_CONGESTION, "congestion" },
55 { GMM_CAUSE_GSM_AUTH_UNACCEPT, "auth-unacceptable" },
56 { GMM_CAUSE_PROTO_ERR_UNSPEC, "proto-error-unspec" },
57 { 0, NULL },
58};
59
60/* TS 24.008 4.4.4.7 */
61static const struct value_string gsm48_gmm_cause_vty_descs[] = {
62 { GMM_CAUSE_IMSI_UNKNOWN, " #02: (IMSI unknown in HLR)" },
63 { GMM_CAUSE_ILLEGAL_MS, " #03 (Illegal MS)" },
64 { GMM_CAUSE_PLMN_NOTALLOWED, " #11: (PLMN not allowed)" },
65 { GMM_CAUSE_LA_NOTALLOWED, " #12: (Location Area not allowed)" },
66 { GMM_CAUSE_ROAMING_NOTALLOWED, " #13: (Roaming not allowed in this location area)" },
67 { GMM_CAUSE_NO_SUIT_CELL_IN_LA, " #15: (No Suitable Cells In Location Area [continue search in PLMN])." },
68 { GMM_CAUSE_NET_FAIL, " #17: (Network Failure)" },
69 { GMM_CAUSE_CONGESTION, " #22: (Congestion)" },
70 { GMM_CAUSE_GSM_AUTH_UNACCEPT, " #23: (GSM authentication unacceptable [UMTS])" },
71 { GMM_CAUSE_PROTO_ERR_UNSPEC, "#111: (Protocol error, unspecified)" },
72 { 0, NULL },
73};
74
75
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +020076struct cmd_node hlr_node = {
77 HLR_NODE,
78 "%s(config-hlr)# ",
79 1,
80};
81
82DEFUN(cfg_hlr,
83 cfg_hlr_cmd,
84 "hlr",
85 "Configure the HLR")
86{
87 vty->node = HLR_NODE;
88 return CMD_SUCCESS;
89}
90
91struct cmd_node gsup_node = {
92 GSUP_NODE,
93 "%s(config-hlr-gsup)# ",
94 1,
95};
96
97DEFUN(cfg_gsup,
98 cfg_gsup_cmd,
99 "gsup",
100 "Configure GSUP options")
101{
102 vty->node = GSUP_NODE;
103 return CMD_SUCCESS;
104}
105
106static int config_write_hlr(struct vty *vty)
107{
108 vty_out(vty, "hlr%s", VTY_NEWLINE);
Alexander Couzens268a33e2020-01-12 00:48:07 +0100109
110 if (g_hlr->reject_cause != GMM_CAUSE_IMSI_UNKNOWN)
111 vty_out(vty, " reject-cause not-found %s%s",
112 get_value_string_or_null(gsm48_gmm_cause_vty_names,
113 (uint32_t) g_hlr->reject_cause), VTY_NEWLINE);
114 if (g_hlr->no_proxy_reject_cause != GMM_CAUSE_IMSI_UNKNOWN)
115 vty_out(vty, " reject-cause no-proxy %s%s",
116 get_value_string_or_null(gsm48_gmm_cause_vty_names,
117 (uint32_t) g_hlr->no_proxy_reject_cause), VTY_NEWLINE);
Oliver Smith851814a2019-01-11 15:30:21 +0100118 if (g_hlr->store_imei)
119 vty_out(vty, " store-imei%s", VTY_NEWLINE);
Neels Hofmeyr5857c592019-04-02 04:24:49 +0200120 if (g_hlr->db_file_path && strcmp(g_hlr->db_file_path, HLR_DEFAULT_DB_FILE_PATH))
121 vty_out(vty, " database %s%s", g_hlr->db_file_path, VTY_NEWLINE);
Oliver Smithc7f17872019-03-04 15:10:44 +0100122 if (g_hlr->subscr_create_on_demand) {
123 const char *flags_str = "none";
124 uint8_t flags = g_hlr->subscr_create_on_demand_flags;
125 unsigned int rand_msisdn_len = g_hlr->subscr_create_on_demand_rand_msisdn_len;
126
127 if ((flags & DB_SUBSCR_FLAG_NAM_CS) && (flags & DB_SUBSCR_FLAG_NAM_PS))
128 flags_str = "cs+ps";
129 else if (flags & DB_SUBSCR_FLAG_NAM_CS)
130 flags_str = "cs";
131 else if (flags & DB_SUBSCR_FLAG_NAM_PS)
132 flags_str = "ps";
133
134 if (rand_msisdn_len)
135 vty_out(vty, " subscriber-create-on-demand %i %s%s", rand_msisdn_len, flags_str, VTY_NEWLINE);
136 else
137 vty_out(vty, " subscriber-create-on-demand no-msisdn %s%s", flags_str, VTY_NEWLINE);
138 }
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200139 return CMD_SUCCESS;
140}
141
142static int config_write_hlr_gsup(struct vty *vty)
143{
144 vty_out(vty, " gsup%s", VTY_NEWLINE);
145 if (g_hlr->gsup_bind_addr)
146 vty_out(vty, " bind ip %s%s", g_hlr->gsup_bind_addr, VTY_NEWLINE);
Keith649c3352021-02-26 01:05:31 +0100147 if (g_hlr->gsup_unit_name.serno)
148 vty_out(vty, " ipa-name %s%s", g_hlr->gsup_unit_name.serno, VTY_NEWLINE);
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200149 return CMD_SUCCESS;
150}
151
Harald Weltefa7ee332018-06-24 13:20:32 +0200152static void show_one_conn(struct vty *vty, const struct osmo_gsup_conn *conn)
153{
154 const struct ipa_server_conn *isc = conn->conn;
155 char *name;
156 int rc;
157
158 rc = osmo_gsup_conn_ccm_get(conn, (uint8_t **) &name, IPAC_IDTAG_SERNR);
159 OSMO_ASSERT(rc);
160
Neels Hofmeyr3f9d1972019-12-12 04:04:53 +0100161 vty_out(vty, " '%s' from %s:%5u, CS=%u, PS=%u%s",
162 name, isc->addr, isc->port, conn->supports_cs, conn->supports_ps,
Harald Weltefa7ee332018-06-24 13:20:32 +0200163 VTY_NEWLINE);
164}
165
166DEFUN(show_gsup_conn, show_gsup_conn_cmd,
167 "show gsup-connections",
168 SHOW_STR "GSUP Connections from VLRs, SGSNs, EUSEs\n")
169{
170 struct osmo_gsup_server *gs = g_hlr->gs;
171 struct osmo_gsup_conn *conn;
172
173 llist_for_each_entry(conn, &gs->clients, list)
174 show_one_conn(vty, conn);
175
176 return CMD_SUCCESS;
177}
178
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200179DEFUN(cfg_hlr_gsup_bind_ip,
180 cfg_hlr_gsup_bind_ip_cmd,
181 "bind ip A.B.C.D",
182 "Listen/Bind related socket option\n"
183 IP_STR
184 "IPv4 Address to bind the GSUP interface to\n")
185{
186 if(g_hlr->gsup_bind_addr)
187 talloc_free(g_hlr->gsup_bind_addr);
188 g_hlr->gsup_bind_addr = talloc_strdup(g_hlr, argv[0]);
189
190 return CMD_SUCCESS;
191}
192
Neels Hofmeyr76328bd2019-11-20 03:35:37 +0100193DEFUN(cfg_hlr_gsup_ipa_name,
194 cfg_hlr_gsup_ipa_name_cmd,
195 "ipa-name NAME",
196 "Set the IPA name of this HLR, for proxying to remote HLRs\n"
197 "A globally unique name for this HLR. For example: PLMN + redundancy server number: HLR-901-70-0. "
198 "This name is used for GSUP routing and must be set if multiple HLRs interconnect (e.g. mslookup "
199 "for Distributed GSM).\n")
200{
201 if (vty->type != VTY_FILE) {
202 vty_out(vty, "gsup/ipa-name: The GSUP IPA name cannot be changed at run-time; "
Max53f60672022-09-18 20:51:23 +0700203 "It can only be set in the configuration file.%s", VTY_NEWLINE);
Neels Hofmeyr76328bd2019-11-20 03:35:37 +0100204 return CMD_WARNING;
205 }
206
207 g_hlr->gsup_unit_name.serno = talloc_strdup(g_hlr, argv[0]);
208 return CMD_SUCCESS;
209}
210
Harald Welte4956ae12018-06-15 22:04:28 +0200211/***********************************************************************
Harald Weltedab544e2018-07-29 16:14:48 +0200212 * USSD Entity
Harald Welte4956ae12018-06-15 22:04:28 +0200213 ***********************************************************************/
214
Neels Hofmeyr2f758032019-11-20 00:37:07 +0100215#include <osmocom/hlr/hlr_ussd.h>
Harald Welte4956ae12018-06-15 22:04:28 +0200216
Harald Weltedab544e2018-07-29 16:14:48 +0200217#define USSD_STR "USSD Configuration\n"
218#define UROUTE_STR "Routing Configuration\n"
219#define PREFIX_STR "Prefix-Matching Route\n" "USSD Prefix\n"
Harald Welte4956ae12018-06-15 22:04:28 +0200220
Vadim Yanitskiydac855e2020-11-17 04:17:46 +0700221#define INT_CHOICE "(own-msisdn|own-imsi|test-idle)"
Harald Weltedab544e2018-07-29 16:14:48 +0200222#define INT_STR "Internal USSD Handler\n" \
223 "Respond with subscribers' own MSISDN\n" \
Vadim Yanitskiydac855e2020-11-17 04:17:46 +0700224 "Respond with subscribers' own IMSI\n" \
225 "Keep the session idle (useful for testing)\n"
Harald Weltedab544e2018-07-29 16:14:48 +0200226
227#define EXT_STR "External USSD Handler\n" \
228 "Name of External USSD Handler (IPA CCM ID)\n"
229
230DEFUN(cfg_ussd_route_pfx_int, cfg_ussd_route_pfx_int_cmd,
231 "ussd route prefix PREFIX internal " INT_CHOICE,
232 USSD_STR UROUTE_STR PREFIX_STR INT_STR)
233{
234 const struct hlr_iuse *iuse = iuse_find(argv[1]);
235 struct hlr_ussd_route *rt = ussd_route_find_prefix(g_hlr, argv[0]);
Harald Welte4956ae12018-06-15 22:04:28 +0200236 if (rt) {
237 vty_out(vty, "%% Cannot add [another?] route for prefix %s%s", argv[0], VTY_NEWLINE);
238 return CMD_WARNING;
239 }
Harald Weltedab544e2018-07-29 16:14:48 +0200240 ussd_route_prefix_alloc_int(g_hlr, argv[0], iuse);
Harald Welte4956ae12018-06-15 22:04:28 +0200241
242 return CMD_SUCCESS;
243}
244
Harald Weltedab544e2018-07-29 16:14:48 +0200245DEFUN(cfg_ussd_route_pfx_ext, cfg_ussd_route_pfx_ext_cmd,
246 "ussd route prefix PREFIX external EUSE",
247 USSD_STR UROUTE_STR PREFIX_STR EXT_STR)
Harald Welte4956ae12018-06-15 22:04:28 +0200248{
Harald Weltedab544e2018-07-29 16:14:48 +0200249 struct hlr_euse *euse = euse_find(g_hlr, argv[1]);
250 struct hlr_ussd_route *rt = ussd_route_find_prefix(g_hlr, argv[0]);
251 if (rt) {
252 vty_out(vty, "%% Cannot add [another?] route for prefix %s%s", argv[0], VTY_NEWLINE);
253 return CMD_WARNING;
254 }
255 if (!euse) {
256 vty_out(vty, "%% Cannot find euse '%s'%s", argv[1], VTY_NEWLINE);
257 return CMD_WARNING;
258 }
259 ussd_route_prefix_alloc_ext(g_hlr, argv[0], euse);
260
261 return CMD_SUCCESS;
262}
263
264DEFUN(cfg_ussd_no_route_pfx, cfg_ussd_no_route_pfx_cmd,
265 "no ussd route prefix PREFIX",
266 NO_STR USSD_STR UROUTE_STR PREFIX_STR)
267{
268 struct hlr_ussd_route *rt = ussd_route_find_prefix(g_hlr, argv[0]);
Harald Welte4956ae12018-06-15 22:04:28 +0200269 if (!rt) {
270 vty_out(vty, "%% Cannot find route for prefix %s%s", argv[0], VTY_NEWLINE);
271 return CMD_WARNING;
272 }
Harald Weltedab544e2018-07-29 16:14:48 +0200273 ussd_route_del(rt);
Harald Welte4956ae12018-06-15 22:04:28 +0200274
275 return CMD_SUCCESS;
276}
277
Harald Weltedab544e2018-07-29 16:14:48 +0200278DEFUN(cfg_ussd_defaultroute, cfg_ussd_defaultroute_cmd,
279 "ussd default-route external EUSE",
280 USSD_STR "Configure default-route for all USSD to unknown destinations\n"
281 EXT_STR)
Harald Welte4956ae12018-06-15 22:04:28 +0200282{
Vadim Yanitskiyb93c44f2018-08-02 23:37:51 +0700283 struct hlr_euse *euse;
284
285 euse = euse_find(g_hlr, argv[0]);
286 if (!euse) {
287 vty_out(vty, "%% Cannot find EUSE %s%s", argv[0], VTY_NEWLINE);
288 return CMD_WARNING;
289 }
Harald Welte4956ae12018-06-15 22:04:28 +0200290
291 if (g_hlr->euse_default != euse) {
292 vty_out(vty, "Switching default route from %s to %s%s",
Harald Welte55d32a12018-07-30 17:26:35 +0200293 g_hlr->euse_default ? g_hlr->euse_default->name : "<none>",
294 euse->name, VTY_NEWLINE);
Harald Welte4956ae12018-06-15 22:04:28 +0200295 g_hlr->euse_default = euse;
296 }
297
298 return CMD_SUCCESS;
299}
300
Harald Weltedab544e2018-07-29 16:14:48 +0200301DEFUN(cfg_ussd_no_defaultroute, cfg_ussd_no_defaultroute_cmd,
302 "no ussd default-route",
303 NO_STR USSD_STR "Remove the default-route for all USSD to unknown destinations\n")
Harald Welte4956ae12018-06-15 22:04:28 +0200304{
Harald Welte4956ae12018-06-15 22:04:28 +0200305 g_hlr->euse_default = NULL;
306
307 return CMD_SUCCESS;
308}
309
Neels Hofmeyr5857c592019-04-02 04:24:49 +0200310DEFUN(cfg_database, cfg_database_cmd,
311 "database PATH",
312 "Set the path to the HLR database file\n"
313 "Relative or absolute file system path to the database file (default is '" HLR_DEFAULT_DB_FILE_PATH "')\n")
314{
315 osmo_talloc_replace_string(g_hlr, &g_hlr->db_file_path, argv[0]);
316 return CMD_SUCCESS;
317}
318
Harald Welte4956ae12018-06-15 22:04:28 +0200319struct cmd_node euse_node = {
320 EUSE_NODE,
321 "%s(config-hlr-euse)# ",
322 1,
323};
324
325DEFUN(cfg_euse, cfg_euse_cmd,
326 "euse NAME",
327 "Configure a particular External USSD Entity\n"
328 "Alphanumeric name of the External USSD Entity\n")
329{
330 struct hlr_euse *euse;
331 const char *id = argv[0];
332
333 euse = euse_find(g_hlr, id);
334 if (!euse) {
335 euse = euse_alloc(g_hlr, id);
336 if (!euse)
337 return CMD_WARNING;
338 }
339 vty->index = euse;
340 vty->index_sub = &euse->description;
341 vty->node = EUSE_NODE;
342
343 return CMD_SUCCESS;
344}
345
346DEFUN(cfg_no_euse, cfg_no_euse_cmd,
347 "no euse NAME",
348 NO_STR "Remove a particular External USSD Entity\n"
349 "Alphanumeric name of the External USSD Entity\n")
350{
351 struct hlr_euse *euse = euse_find(g_hlr, argv[0]);
352 if (!euse) {
Vadim Yanitskiyc47d5c02020-10-29 18:05:22 +0700353 vty_out(vty, "%% Cannot remove non-existent EUSE %s%s", argv[0], VTY_NEWLINE);
Harald Welte4956ae12018-06-15 22:04:28 +0200354 return CMD_WARNING;
355 }
356 if (g_hlr->euse_default == euse) {
357 vty_out(vty, "%% Cannot remove EUSE %s, it is the default route%s", argv[0], VTY_NEWLINE);
358 return CMD_WARNING;
359 }
360 euse_del(euse);
361 return CMD_SUCCESS;
362}
363
364static void dump_one_euse(struct vty *vty, struct hlr_euse *euse)
365{
Harald Welte4956ae12018-06-15 22:04:28 +0200366 vty_out(vty, " euse %s%s", euse->name, VTY_NEWLINE);
Harald Welte4956ae12018-06-15 22:04:28 +0200367}
368
369static int config_write_euse(struct vty *vty)
370{
371 struct hlr_euse *euse;
Harald Weltedab544e2018-07-29 16:14:48 +0200372 struct hlr_ussd_route *rt;
Harald Welte4956ae12018-06-15 22:04:28 +0200373
374 llist_for_each_entry(euse, &g_hlr->euse_list, list)
375 dump_one_euse(vty, euse);
376
Harald Weltedab544e2018-07-29 16:14:48 +0200377 llist_for_each_entry(rt, &g_hlr->ussd_routes, list) {
378 vty_out(vty, " ussd route prefix %s %s %s%s", rt->prefix,
379 rt->is_external ? "external" : "internal",
380 rt->is_external ? rt->u.euse->name : rt->u.iuse->name,
381 VTY_NEWLINE);
382 }
383
384 if (g_hlr->euse_default)
385 vty_out(vty, " ussd default-route external %s%s", g_hlr->euse_default->name, VTY_NEWLINE);
386
Vadim Yanitskiyd157a562018-12-01 00:03:39 +0700387 if (g_hlr->ncss_guard_timeout != NCSS_GUARD_TIMEOUT_DEFAULT)
388 vty_out(vty, " ncss-guard-timeout %i%s",
389 g_hlr->ncss_guard_timeout, VTY_NEWLINE);
390
Harald Welte4956ae12018-06-15 22:04:28 +0200391 return 0;
392}
393
Vadim Yanitskiyd157a562018-12-01 00:03:39 +0700394DEFUN(cfg_ncss_guard_timeout, cfg_ncss_guard_timeout_cmd,
395 "ncss-guard-timeout <0-255>",
396 "Set guard timer for NCSS (call independent SS) session activity\n"
397 "Guard timer value (sec.), or 0 to disable")
398{
399 g_hlr->ncss_guard_timeout = atoi(argv[0]);
400 return CMD_SUCCESS;
401}
402
Alexander Couzens268a33e2020-01-12 00:48:07 +0100403
404DEFUN(cfg_reject_cause, cfg_reject_cause_cmd,
405 "reject-cause TYPE CAUSE", "") /* Dynamically Generated */
406{
407 int cause_code = get_string_value(gsm48_gmm_cause_vty_names, argv[1]);
408 OSMO_ASSERT(cause_code >= 0);
409
410 if (strcmp(argv[0], "not-found") == 0)
411 g_hlr->reject_cause = (enum gsm48_gmm_cause) cause_code;
412 if (strcmp(argv[0], "no-proxy") == 0)
413 g_hlr->no_proxy_reject_cause = (enum gsm48_gmm_cause) cause_code;
414
415 return CMD_SUCCESS;
416}
417
Oliver Smith851814a2019-01-11 15:30:21 +0100418DEFUN(cfg_store_imei, cfg_store_imei_cmd,
419 "store-imei",
420 "Save the IMEI in the database when receiving Check IMEI requests. Note that an MSC does not necessarily send"
421 " Check IMEI requests (for OsmoMSC, you may want to set 'check-imei-rqd 1').")
422{
423 g_hlr->store_imei = true;
424 return CMD_SUCCESS;
425}
426
427DEFUN(cfg_no_store_imei, cfg_no_store_imei_cmd,
428 "no store-imei",
429 "Do not save the IMEI in the database, when receiving Check IMEI requests.")
430{
431 g_hlr->store_imei = false;
432 return CMD_SUCCESS;
433}
434
Oliver Smithc7f17872019-03-04 15:10:44 +0100435DEFUN(cfg_subscr_create_on_demand, cfg_subscr_create_on_demand_cmd,
436 "subscriber-create-on-demand (no-msisdn|<3-15>) (none|cs|ps|cs+ps)",
437 "Make a new record when a subscriber is first seen.\n"
438 "Do not automatically assign MSISDN.\n"
439 "Length of an automatically assigned MSISDN.\n"
440 "Do not allow any NAM (Network Access Mode) by default.\n"
441 "Allow access to circuit switched NAM by default.\n"
442 "Allow access to packet switched NAM by default.\n"
443 "Allow access to circuit and packet switched NAM by default.\n")
444{
445 unsigned int rand_msisdn_len = 0;
446 uint8_t flags = 0x00;
447
448 if (strcmp(argv[0], "no-msisdn") != 0)
449 rand_msisdn_len = atoi(argv[0]);
450
451 if (strstr(argv[1], "cs"))
452 flags |= DB_SUBSCR_FLAG_NAM_CS;
453 if (strstr(argv[1], "ps"))
454 flags |= DB_SUBSCR_FLAG_NAM_PS;
455
456 g_hlr->subscr_create_on_demand = true;
457 g_hlr->subscr_create_on_demand_rand_msisdn_len = rand_msisdn_len;
458 g_hlr->subscr_create_on_demand_flags = flags;
459
460 return CMD_SUCCESS;
461}
462
463DEFUN(cfg_no_subscr_create_on_demand, cfg_no_subscr_create_on_demand_cmd,
464 "no subscriber-create-on-demand",
465 "Do not make a new record when a subscriber is first seen.\n")
466{
467 g_hlr->subscr_create_on_demand = false;
468 return CMD_SUCCESS;
469}
470
Harald Welte4956ae12018-06-15 22:04:28 +0200471/***********************************************************************
472 * Common Code
473 ***********************************************************************/
474
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200475int hlr_vty_go_parent(struct vty *vty)
476{
477 switch (vty->node) {
478 case GSUP_NODE:
Harald Welte4956ae12018-06-15 22:04:28 +0200479 case EUSE_NODE:
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200480 vty->node = HLR_NODE;
481 vty->index = NULL;
Harald Welte4956ae12018-06-15 22:04:28 +0200482 vty->index_sub = NULL;
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200483 break;
484 default:
485 case HLR_NODE:
486 vty->node = CONFIG_NODE;
487 vty->index = NULL;
488 break;
489 case CONFIG_NODE:
490 vty->node = ENABLE_NODE;
491 vty->index = NULL;
492 break;
493 }
494
495 return vty->node;
496}
497
Neels Hofmeyr7685a782017-01-30 23:30:26 +0100498int hlr_vty_is_config_node(struct vty *vty, int node)
499{
500 switch (node) {
501 /* add items that are not config */
502 case CONFIG_NODE:
503 return 0;
504
505 default:
506 return 1;
507 }
508}
509
Alexander Couzens268a33e2020-01-12 00:48:07 +0100510void hlr_vty_init(void *hlr_ctx)
Neels Hofmeyr7685a782017-01-30 23:30:26 +0100511{
Alexander Couzens268a33e2020-01-12 00:48:07 +0100512 cfg_reject_cause_cmd.string =
513 vty_cmd_string_from_valstr(hlr_ctx,
514 gsm48_gmm_cause_vty_names,
515 "reject-cause (not-found|no-proxy) (", "|", ")",
516 VTY_DO_LOWER);
517
518 cfg_reject_cause_cmd.doc =
519 vty_cmd_string_from_valstr(hlr_ctx,
520 gsm48_gmm_cause_vty_descs,
521 "GSUP/GMM cause to be sent\n"
522 "in the case the IMSI could not be found in the database\n"
523 "in the case no remote HLR reponded to mslookup GSUP request\n",
524 "\n", "", 0);
525
Pau Espin Pedrole49391b2019-08-05 15:57:10 +0200526 logging_vty_add_cmds();
Harald Welte7ee6e552018-02-14 00:52:05 +0100527 osmo_talloc_vty_add_cmds();
Max20ddfdb2019-02-18 13:12:27 +0100528 osmo_stats_vty_add_cmds();
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200529
Harald Weltefa7ee332018-06-24 13:20:32 +0200530 install_element_ve(&show_gsup_conn_cmd);
531
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200532 install_element(CONFIG_NODE, &cfg_hlr_cmd);
533 install_node(&hlr_node, config_write_hlr);
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200534
535 install_element(HLR_NODE, &cfg_gsup_cmd);
536 install_node(&gsup_node, config_write_hlr_gsup);
Pau Espin Pedrolce9bc402017-05-31 13:19:22 +0200537
538 install_element(GSUP_NODE, &cfg_hlr_gsup_bind_ip_cmd);
Neels Hofmeyr76328bd2019-11-20 03:35:37 +0100539 install_element(GSUP_NODE, &cfg_hlr_gsup_ipa_name_cmd);
Neels Hofmeyr183e7002017-10-06 02:59:54 +0200540
Neels Hofmeyr5857c592019-04-02 04:24:49 +0200541 install_element(HLR_NODE, &cfg_database_cmd);
542
Harald Welte4956ae12018-06-15 22:04:28 +0200543 install_element(HLR_NODE, &cfg_euse_cmd);
544 install_element(HLR_NODE, &cfg_no_euse_cmd);
545 install_node(&euse_node, config_write_euse);
Harald Weltedab544e2018-07-29 16:14:48 +0200546 install_element(HLR_NODE, &cfg_ussd_route_pfx_int_cmd);
547 install_element(HLR_NODE, &cfg_ussd_route_pfx_ext_cmd);
548 install_element(HLR_NODE, &cfg_ussd_no_route_pfx_cmd);
549 install_element(HLR_NODE, &cfg_ussd_defaultroute_cmd);
550 install_element(HLR_NODE, &cfg_ussd_no_defaultroute_cmd);
Vadim Yanitskiyd157a562018-12-01 00:03:39 +0700551 install_element(HLR_NODE, &cfg_ncss_guard_timeout_cmd);
Alexander Couzens268a33e2020-01-12 00:48:07 +0100552 install_element(HLR_NODE, &cfg_reject_cause_cmd);
Oliver Smith851814a2019-01-11 15:30:21 +0100553 install_element(HLR_NODE, &cfg_store_imei_cmd);
554 install_element(HLR_NODE, &cfg_no_store_imei_cmd);
Oliver Smithc7f17872019-03-04 15:10:44 +0100555 install_element(HLR_NODE, &cfg_subscr_create_on_demand_cmd);
556 install_element(HLR_NODE, &cfg_no_subscr_create_on_demand_cmd);
Harald Welte4956ae12018-06-15 22:04:28 +0200557
Harald Welted5807b82018-07-29 12:27:41 +0200558 hlr_vty_subscriber_init();
Neels Hofmeyr7685a782017-01-30 23:30:26 +0100559}