blob: 9bc8f3aae14f5637e0e89d06e8e85932423d5e3f [file] [log] [blame]
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001/* MSC interface to quagga VTY */
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002/* (C) 2016-2018 by sysmocom s.m.f.c. GmbH <info@sysmocom.de>
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02003 * Based on OpenBSC interface to quagga VTY (libmsc/vty_interface_layer3.c)
Harald Welte7b222aa2017-12-23 19:30:32 +01004 * (C) 2009-2017 by Harald Welte <laforge@gnumonks.org>
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02005 * (C) 2009-2011 by Holger Hans Peter Freyther
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23/* NOTE: I would have liked to call this the MSC_NODE instead of the MSC_NODE,
24 * but MSC_NODE already exists to configure a remote MSC for osmo-bsc. */
25
Neels Hofmeyr00e82d62017-07-05 15:19:52 +020026#include "../../bscconfig.h"
27
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020028#include <inttypes.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010029#include <limits.h>
30
31#include <osmocom/gsm/protocol/gsm_08_58.h>
32#include <osmocom/gsm/protocol/gsm_04_14.h>
Philipp Maier8fa2dbe2019-03-19 18:51:37 +010033#include <osmocom/gsm/protocol/gsm_08_08.h>
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020034
Maxc51609a2018-11-09 17:13:00 +010035#include <osmocom/sigtran/sccp_helpers.h>
36
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020037#include <osmocom/vty/command.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010038#include <osmocom/vty/logging.h>
Stefan Sperling617ac802018-02-22 17:58:20 +010039#include <osmocom/vty/misc.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010040#include <osmocom/vty/stats.h>
41
Neels Hofmeyr00e82d62017-07-05 15:19:52 +020042#ifdef BUILD_IU
43#include <osmocom/ranap/iu_client.h>
44#endif
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020045
Neels Hofmeyr90843962017-09-04 15:04:35 +020046#include <osmocom/msc/vty.h>
47#include <osmocom/msc/gsm_data.h>
48#include <osmocom/msc/gsm_subscriber.h>
49#include <osmocom/msc/vlr.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010050#include <osmocom/msc/transaction.h>
51#include <osmocom/msc/db.h>
Maxc51609a2018-11-09 17:13:00 +010052#include <osmocom/msc/a_iface.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010053#include <osmocom/msc/sms_queue.h>
54#include <osmocom/msc/silent_call.h>
55#include <osmocom/msc/gsm_04_80.h>
56#include <osmocom/msc/gsm_04_14.h>
57#include <osmocom/msc/signal.h>
58#include <osmocom/msc/mncc_int.h>
Vadim Yanitskiy1b891302018-08-04 01:33:08 +070059#include <osmocom/msc/rrlp.h>
Harald Welte0df904d2018-12-03 11:00:04 +010060#include <osmocom/msc/vlr_sgs.h>
61#include <osmocom/msc/sgs_vty.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010062
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010063static struct gsm_network *gsmnet = NULL;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010064
65struct cmd_node net_node = {
66 GSMNET_NODE,
67 "%s(config-net)# ",
68 1,
69};
70
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +010071#define VSUB_USE_VTY "VTY"
72
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010073#define NETWORK_STR "Configure the GSM network\n"
74#define CODE_CMD_STR "Code commands\n"
75#define NAME_CMD_STR "Name Commands\n"
76#define NAME_STR "Name to use\n"
77
78DEFUN(cfg_net,
79 cfg_net_cmd,
80 "network", NETWORK_STR)
81{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010082 vty->index = gsmnet;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010083 vty->node = GSMNET_NODE;
84
85 return CMD_SUCCESS;
86}
87
88DEFUN(cfg_net_ncc,
89 cfg_net_ncc_cmd,
90 "network country code <1-999>",
91 "Set the GSM network country code\n"
92 "Country commands\n"
93 CODE_CMD_STR
94 "Network Country Code to use\n")
95{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010096 gsmnet->plmn.mcc = atoi(argv[0]);
97
98 return CMD_SUCCESS;
99}
100
101DEFUN(cfg_net_mnc,
102 cfg_net_mnc_cmd,
103 "mobile network code <0-999>",
104 "Set the GSM mobile network code\n"
105 "Network Commands\n"
106 CODE_CMD_STR
107 "Mobile Network Code to use\n")
108{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100109 uint16_t mnc;
110 bool mnc_3_digits;
111
112 if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
113 vty_out(vty, "%% Error decoding MNC: %s%s", argv[0], VTY_NEWLINE);
114 return CMD_WARNING;
115 }
116
117 gsmnet->plmn.mnc = mnc;
118 gsmnet->plmn.mnc_3_digits = mnc_3_digits;
119
120 return CMD_SUCCESS;
121}
122
123DEFUN(cfg_net_name_short,
124 cfg_net_name_short_cmd,
125 "short name NAME",
126 "Set the short GSM network name\n" NAME_CMD_STR NAME_STR)
127{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100128 osmo_talloc_replace_string(gsmnet, &gsmnet->name_short, argv[0]);
129 return CMD_SUCCESS;
130}
131
132DEFUN(cfg_net_name_long,
133 cfg_net_name_long_cmd,
134 "long name NAME",
135 "Set the long GSM network name\n" NAME_CMD_STR NAME_STR)
136{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100137 osmo_talloc_replace_string(gsmnet, &gsmnet->name_long, argv[0]);
138 return CMD_SUCCESS;
139}
140
141DEFUN(cfg_net_encryption,
142 cfg_net_encryption_cmd,
143 "encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]",
144 "Encryption options\n"
145 "GSM A5 Air Interface Encryption\n"
146 "A5/n Algorithm Number\n"
147 "A5/n Algorithm Number\n"
148 "A5/n Algorithm Number\n"
149 "A5/n Algorithm Number\n")
150{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100151 unsigned int i;
152
153 gsmnet->a5_encryption_mask = 0;
154 for (i = 0; i < argc; i++)
155 gsmnet->a5_encryption_mask |= (1 << atoi(argv[i]));
156
157 return CMD_SUCCESS;
158}
159
160DEFUN(cfg_net_authentication,
161 cfg_net_authentication_cmd,
162 "authentication (optional|required)",
163 "Whether to enforce MS authentication in 2G\n"
164 "Allow MS to attach via 2G BSC without authentication\n"
165 "Always do authentication\n")
166{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100167 gsmnet->authentication_required = (argv[0][0] == 'r') ? true : false;
168
169 return CMD_SUCCESS;
170}
171
172DEFUN(cfg_net_rrlp_mode, cfg_net_rrlp_mode_cmd,
173 "rrlp mode (none|ms-based|ms-preferred|ass-preferred)",
174 "Radio Resource Location Protocol\n"
175 "Set the Radio Resource Location Protocol Mode\n"
176 "Don't send RRLP request\n"
177 "Request MS-based location\n"
178 "Request any location, prefer MS-based\n"
179 "Request any location, prefer MS-assisted\n")
180{
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700181 gsmnet->rrlp.mode = msc_rrlp_mode_parse(argv[0]);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100182
183 return CMD_SUCCESS;
184}
185
186DEFUN(cfg_net_mm_info, cfg_net_mm_info_cmd,
187 "mm info (0|1)",
188 "Mobility Management\n"
189 "Send MM INFO after LOC UPD ACCEPT\n"
190 "Disable\n" "Enable\n")
191{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100192 gsmnet->send_mm_info = atoi(argv[0]);
193
194 return CMD_SUCCESS;
195}
196
197DEFUN(cfg_net_timezone,
198 cfg_net_timezone_cmd,
199 "timezone <-19-19> (0|15|30|45)",
200 "Set the Timezone Offset of the network\n"
201 "Timezone offset (hours)\n"
202 "Timezone offset (00 minutes)\n"
203 "Timezone offset (15 minutes)\n"
204 "Timezone offset (30 minutes)\n"
205 "Timezone offset (45 minutes)\n"
206 )
207{
208 struct gsm_network *net = vty->index;
209 int tzhr = atoi(argv[0]);
210 int tzmn = atoi(argv[1]);
211
212 net->tz.hr = tzhr;
213 net->tz.mn = tzmn;
214 net->tz.dst = 0;
215 net->tz.override = 1;
216
217 return CMD_SUCCESS;
218}
219
220DEFUN(cfg_net_timezone_dst,
221 cfg_net_timezone_dst_cmd,
222 "timezone <-19-19> (0|15|30|45) <0-2>",
223 "Set the Timezone Offset of the network\n"
224 "Timezone offset (hours)\n"
225 "Timezone offset (00 minutes)\n"
226 "Timezone offset (15 minutes)\n"
227 "Timezone offset (30 minutes)\n"
228 "Timezone offset (45 minutes)\n"
229 "DST offset (hours)\n"
230 )
231{
232 struct gsm_network *net = vty->index;
233 int tzhr = atoi(argv[0]);
234 int tzmn = atoi(argv[1]);
235 int tzdst = atoi(argv[2]);
236
237 net->tz.hr = tzhr;
238 net->tz.mn = tzmn;
239 net->tz.dst = tzdst;
240 net->tz.override = 1;
241
242 return CMD_SUCCESS;
243}
244
245DEFUN(cfg_net_no_timezone,
246 cfg_net_no_timezone_cmd,
247 "no timezone",
248 NO_STR
249 "Disable network timezone override, use system tz\n")
250{
251 struct gsm_network *net = vty->index;
252
253 net->tz.override = 0;
254
255 return CMD_SUCCESS;
256}
257
258DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
259 "periodic location update <6-1530>",
260 "Periodic Location Updating Interval\n"
261 "Periodic Location Updating Interval\n"
262 "Periodic Location Updating Interval\n"
263 "Periodic Location Updating Interval in Minutes\n")
264{
265 struct gsm_network *net = vty->index;
266
267 net->t3212 = atoi(argv[0]) / 6;
268
269 return CMD_SUCCESS;
270}
271
272DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
273 "no periodic location update",
274 NO_STR
275 "Periodic Location Updating Interval\n"
276 "Periodic Location Updating Interval\n"
277 "Periodic Location Updating Interval\n")
278{
279 struct gsm_network *net = vty->index;
280
281 net->t3212 = 0;
282
283 return CMD_SUCCESS;
284}
285
286static int config_write_net(struct vty *vty)
287{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100288 int i;
289
290 vty_out(vty, "network%s", VTY_NEWLINE);
291 vty_out(vty, " network country code %s%s", osmo_mcc_name(gsmnet->plmn.mcc), VTY_NEWLINE);
292 vty_out(vty, " mobile network code %s%s",
293 osmo_mnc_name(gsmnet->plmn.mnc, gsmnet->plmn.mnc_3_digits), VTY_NEWLINE);
294 vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
295 vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
296 vty_out(vty, " encryption a5");
297 for (i = 0; i < 8; i++) {
298 if (gsmnet->a5_encryption_mask & (1 << i))
299 vty_out(vty, " %u", i);
300 }
301 vty_out(vty, "%s", VTY_NEWLINE);
302 vty_out(vty, " authentication %s%s",
303 gsmnet->authentication_required ? "required" : "optional", VTY_NEWLINE);
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700304 vty_out(vty, " rrlp mode %s%s", msc_rrlp_mode_name(gsmnet->rrlp.mode),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100305 VTY_NEWLINE);
306 vty_out(vty, " mm info %u%s", gsmnet->send_mm_info, VTY_NEWLINE);
307 if (gsmnet->tz.override != 0) {
308 if (gsmnet->tz.dst)
309 vty_out(vty, " timezone %d %d %d%s",
310 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
311 VTY_NEWLINE);
312 else
313 vty_out(vty, " timezone %d %d%s",
314 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
315 }
316 if (gsmnet->t3212 == 0)
317 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
318 else
319 vty_out(vty, " periodic location update %u%s",
320 gsmnet->t3212 * 6, VTY_NEWLINE);
321
322 if (gsmnet->emergency.route_to_msisdn) {
323 vty_out(vty, " emergency-call route-to-msisdn %s%s",
324 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
325 }
326
327 return CMD_SUCCESS;
328}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200329
330static struct cmd_node msc_node = {
331 MSC_NODE,
332 "%s(config-msc)# ",
333 1,
334};
335
336DEFUN(cfg_msc, cfg_msc_cmd,
337 "msc", "Configure MSC options")
338{
339 vty->node = MSC_NODE;
340 return CMD_SUCCESS;
341}
342
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100343#define MNCC_STR "Configure Mobile Network Call Control\n"
344#define MNCC_GUARD_TIMEOUT_STR "Set global guard timer for mncc interface activity\n"
345#define MNCC_GUARD_TIMEOUT_VALUE_STR "guard timer value (sec.)\n"
346
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100347DEFUN(cfg_msc_mncc_internal,
348 cfg_msc_mncc_internal_cmd,
349 "mncc internal",
350 MNCC_STR "Use internal MNCC handler (default; changes need a program restart)\n")
351{
352 gsm_network_set_mncc_sock_path(gsmnet, NULL);
353 return CMD_SUCCESS;
354}
355
356DEFUN(cfg_msc_mncc_external,
357 cfg_msc_mncc_external_cmd,
358 "mncc external MNCC_SOCKET_PATH",
359 MNCC_STR "Use external MNCC handler (changes need a program restart)\n"
360 "File system path to create the MNCC unix domain socket at\n")
361{
362 gsm_network_set_mncc_sock_path(gsmnet, argv[0]);
363 return CMD_SUCCESS;
364}
365
Philipp Maier9ca7b312018-10-10 17:00:49 +0200366DEFUN(cfg_msc_mncc_guard_timeout,
367 cfg_msc_mncc_guard_timeout_cmd,
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100368 "mncc guard-timeout <0-255>",
369 MNCC_STR
370 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR)
Philipp Maier9ca7b312018-10-10 17:00:49 +0200371{
372 gsmnet->mncc_guard_timeout = atoi(argv[0]);
373 return CMD_SUCCESS;
374}
375
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100376ALIAS_DEPRECATED(cfg_msc_mncc_guard_timeout,
377 cfg_msc_deprecated_mncc_guard_timeout_cmd,
378 "mncc-guard-timeout <0-255>",
379 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR);
380
Vadim Yanitskiy64623e12018-11-28 23:05:51 +0700381#define NCSS_STR "Configure call independent Supplementary Services\n"
382
383DEFUN(cfg_msc_ncss_guard_timeout,
384 cfg_msc_ncss_guard_timeout_cmd,
385 "ncss guard-timeout <0-255>",
386 NCSS_STR "Set guard timer for session activity\n"
387 "guard timer value (sec.), or 0 to disable\n")
388{
389 gsmnet->ncss_guard_timeout = atoi(argv[0]);
390 return CMD_SUCCESS;
391}
392
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200393DEFUN(cfg_msc_assign_tmsi, cfg_msc_assign_tmsi_cmd,
394 "assign-tmsi",
395 "Assign TMSI during Location Updating.\n")
396{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200397 gsmnet->vlr->cfg.assign_tmsi = true;
398 return CMD_SUCCESS;
399}
400
401DEFUN(cfg_msc_no_assign_tmsi, cfg_msc_no_assign_tmsi_cmd,
402 "no assign-tmsi",
403 NO_STR "Assign TMSI during Location Updating.\n")
404{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200405 gsmnet->vlr->cfg.assign_tmsi = false;
406 return CMD_SUCCESS;
407}
408
Philipp Maierfbf66102017-04-09 12:32:51 +0200409DEFUN(cfg_msc_cs7_instance_a,
410 cfg_msc_cs7_instance_a_cmd,
411 "cs7-instance-a <0-15>",
412 "Set SS7 to be used by the A-Interface.\n" "SS7 instance reference number\n")
413{
Philipp Maierfbf66102017-04-09 12:32:51 +0200414 gsmnet->a.cs7_instance = atoi(argv[0]);
415 return CMD_SUCCESS;
416}
417
418DEFUN(cfg_msc_cs7_instance_iu,
419 cfg_msc_cs7_instance_iu_cmd,
420 "cs7-instance-iu <0-15>",
421 "Set SS7 to be used by the Iu-Interface.\n" "SS7 instance reference number\n")
422{
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100423#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200424 gsmnet->iu.cs7_instance = atoi(argv[0]);
425 return CMD_SUCCESS;
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100426#else
427 vty_out(vty, "WARNING: 'cs7-instance-iu' without effect: built without Iu support%s",
428 VTY_NEWLINE);
429 return CMD_WARNING;
430#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200431}
432
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100433DEFUN(cfg_msc_auth_tuple_max_reuse_count, cfg_msc_auth_tuple_max_reuse_count_cmd,
434 "auth-tuple-max-reuse-count <-1-2147483647>",
435 "Configure authentication tuple re-use\n"
436 "0 to use each auth tuple at most once (default), >0 to limit re-use, -1 to re-use infinitely (vulnerable!).\n")
437{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100438 gsmnet->vlr->cfg.auth_tuple_max_reuse_count = atoi(argv[0]);
439 return CMD_SUCCESS;
440}
441
442DEFUN(cfg_msc_auth_tuple_reuse_on_error, cfg_msc_auth_tuple_reuse_on_error_cmd,
443 "auth-tuple-reuse-on-error (0|1)",
444 "Configure authentication tuple re-use when HLR is not responsive\n"
Oliver Smithd6e24fd2019-01-09 10:46:43 +0100445 "Never re-use auth tuples beyond auth-tuple-max-reuse-count (default)\n"
446 "If the HLR does not deliver new tuples, do re-use already available old ones.\n")
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100447{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100448 gsmnet->vlr->cfg.auth_reuse_old_sets_on_error = atoi(argv[0]) ? true : false;
449 return CMD_SUCCESS;
450}
451
Oliver Smith0fec28a2018-12-14 10:52:52 +0100452DEFUN(cfg_msc_check_imei_rqd, cfg_msc_check_imei_rqd_cmd,
453 "check-imei-rqd (0|1)",
454 "Send each IMEI to the EIR to ask if it is permitted or not. The EIR is implemented as part of OsmoHLR, "
455 "and can optionally save the IMEI in the HLR.\n"
456 "Do not send IMEIs to the EIR\n"
457 "Send each IMEI to the EIR\n")
458{
459 gsmnet->vlr->cfg.check_imei_rqd = atoi(argv[0]) ? true : false;
460 return CMD_SUCCESS;
461}
462
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100463DEFUN(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd,
464 "paging response-timer (default|<1-65535>)",
465 "Configure Paging\n"
466 "Set Paging timeout, the minimum time to pass between (unsuccessful) Pagings sent towards"
467 " BSS or RNC\n"
468 "Set to default timeout (" OSMO_STRINGIFY_VAL(MSC_PAGING_RESPONSE_TIMER_DEFAULT) " seconds)\n"
469 "Set paging timeout in seconds\n")
470{
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100471 if (!strcmp(argv[1], "default"))
472 gsmnet->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
473 else
474 gsmnet->paging_response_timer = atoi(argv[0]);
475 return CMD_SUCCESS;
476}
477
Harald Welte69c54a82018-02-09 20:41:14 +0100478DEFUN(cfg_msc_emergency_msisdn, cfg_msc_emergency_msisdn_cmd,
479 "emergency-call route-to-msisdn MSISDN",
480 "Configure Emergency Call Behaviour\n"
481 "MSISDN to which Emergency Calls are Dispatched\n"
482 "MSISDN (E.164 Phone Number)\n")
483{
Harald Welte69c54a82018-02-09 20:41:14 +0100484 osmo_talloc_replace_string(gsmnet, &gsmnet->emergency.route_to_msisdn, argv[0]);
485
486 return CMD_SUCCESS;
487}
488
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700489/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
490DEFUN(cfg_msc_sms_over_gsup, cfg_msc_sms_over_gsup_cmd,
491 "sms-over-gsup",
492 "Enable routing of SMS messages over GSUP\n")
493{
494 gsmnet->sms_over_gsup = true;
495 return CMD_SUCCESS;
496}
497
498/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
499DEFUN(cfg_msc_no_sms_over_gsup, cfg_msc_no_sms_over_gsup_cmd,
500 "no sms-over-gsup",
501 NO_STR "Disable routing of SMS messages over GSUP\n")
502{
503 gsmnet->sms_over_gsup = false;
504 return CMD_SUCCESS;
505}
506
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200507static int config_write_msc(struct vty *vty)
508{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200509 vty_out(vty, "msc%s", VTY_NEWLINE);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100510 if (gsmnet->mncc_sock_path)
511 vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE);
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100512 vty_out(vty, " mncc guard-timeout %i%s",
Philipp Maier9ca7b312018-10-10 17:00:49 +0200513 gsmnet->mncc_guard_timeout, VTY_NEWLINE);
Vadim Yanitskiy64623e12018-11-28 23:05:51 +0700514 vty_out(vty, " ncss guard-timeout %i%s",
515 gsmnet->ncss_guard_timeout, VTY_NEWLINE);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200516 vty_out(vty, " %sassign-tmsi%s",
517 gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
518
Philipp Maierfbf66102017-04-09 12:32:51 +0200519 vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
520 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100521#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200522 vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance,
523 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100524#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200525
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100526 if (gsmnet->vlr->cfg.auth_tuple_max_reuse_count)
527 vty_out(vty, " auth-tuple-max-reuse-count %d%s",
528 OSMO_MAX(-1, gsmnet->vlr->cfg.auth_tuple_max_reuse_count),
529 VTY_NEWLINE);
530 if (gsmnet->vlr->cfg.auth_reuse_old_sets_on_error)
531 vty_out(vty, " auth-tuple-reuse-on-error 1%s",
532 VTY_NEWLINE);
533
Oliver Smith0fec28a2018-12-14 10:52:52 +0100534 if (gsmnet->vlr->cfg.check_imei_rqd)
535 vty_out(vty, " check-imei-rqd 1 %s",
536 VTY_NEWLINE);
537
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100538 if (gsmnet->paging_response_timer != MSC_PAGING_RESPONSE_TIMER_DEFAULT)
539 vty_out(vty, " paging response-timer %u%s", gsmnet->paging_response_timer, VTY_NEWLINE);
540
Harald Welte69c54a82018-02-09 20:41:14 +0100541 if (gsmnet->emergency.route_to_msisdn) {
542 vty_out(vty, " emergency-call route-to-msisdn %s%s",
543 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
544 }
545
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700546 if (gsmnet->sms_over_gsup)
547 vty_out(vty, " sms-over-gsup%s", VTY_NEWLINE);
548
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +0200549 mgcp_client_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200550#ifdef BUILD_IU
Neels Hofmeyr00e82d62017-07-05 15:19:52 +0200551 ranap_iu_vty_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200552#endif
553
554 return CMD_SUCCESS;
555}
556
Maxc51609a2018-11-09 17:13:00 +0100557DEFUN(show_bsc, show_bsc_cmd,
558 "show bsc", SHOW_STR "BSC\n")
559{
560 struct bsc_context *bsc_ctx;
561 struct osmo_ss7_instance *ss7 = osmo_ss7_instance_find(gsmnet->a.cs7_instance);
562
563 llist_for_each_entry(bsc_ctx, &gsmnet->a.bscs, list) {
564 vty_out(vty, "BSC %s%s", osmo_sccp_addr_name(ss7, &bsc_ctx->bsc_addr), VTY_NEWLINE);
565 }
566
567 return CMD_SUCCESS;
568}
569
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100570static void vty_conn_hdr(struct vty *vty)
571{
Max45df98b2019-01-17 18:44:33 +0100572 unsigned lnum = 0;
573 struct ran_conn *conn;
574
575 llist_for_each_entry(conn, &gsmnet->ran_conns, entry)
576 lnum++;
577
578 if (lnum)
579 vty_out(vty, "--ConnId RAN --LAC Use --Tokens C A5 State ------------ Subscriber%s",
580 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100581}
582
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100583static void vty_dump_one_conn(struct vty *vty, const struct ran_conn *conn)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100584{
Max45df98b2019-01-17 18:44:33 +0100585 vty_out(vty, "%08x %3s %5u %3u %08x %c /%1u %27s %22s%s",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100586 conn->a.conn_id,
Harald Welte0df904d2018-12-03 11:00:04 +0100587 osmo_rat_type_name(conn->via_ran),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100588 conn->lac,
589 conn->use_count,
590 conn->use_tokens,
591 conn->received_cm_service_request ? 'C' : '-',
Neels Hofmeyrf41658d2018-11-30 04:35:50 +0100592 conn->geran_encr.alg_id,
Neels Hofmeyr4d3a66b2018-03-31 18:45:59 +0200593 conn->fi ? osmo_fsm_inst_state_name(conn->fi) : "-",
Max45df98b2019-01-17 18:44:33 +0100594 conn->vsub ? vlr_subscr_name(conn->vsub) : "-",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100595 VTY_NEWLINE);
596}
597
598DEFUN(show_msc_conn, show_msc_conn_cmd,
599 "show connection", SHOW_STR "Subscriber Connections\n")
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200600{
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100601 struct ran_conn *conn;
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200602
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100603 vty_conn_hdr(vty);
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100604 llist_for_each_entry(conn, &gsmnet->ran_conns, entry)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100605 vty_dump_one_conn(vty, conn);
606
607 return CMD_SUCCESS;
608}
609
610static void vty_trans_hdr(struct vty *vty)
611{
Max45df98b2019-01-17 18:44:33 +0100612 unsigned lnum = 0;
613 struct gsm_trans *trans;
614
615 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
616 lnum++;
617
618 if (lnum)
619 vty_out(vty, "--ConnId -P TI -CallRef [--- Proto ---] ------------ Subscriber%s",
620 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100621}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200622
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100623static const char *get_trans_proto_str(const struct gsm_trans *trans)
624{
625 static char buf[256];
626
627 switch (trans->protocol) {
628 case GSM48_PDISC_CC:
629 snprintf(buf, sizeof(buf), "%s %4u %4u",
630 gsm48_cc_state_name(trans->cc.state),
631 trans->cc.Tcurrent,
632 trans->cc.T308_second);
633 break;
634 case GSM48_PDISC_SMS:
635 snprintf(buf, sizeof(buf), "%s %s",
636 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
637 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
638 break;
639 default:
640 buf[0] = '\0';
641 break;
642 }
643
644 return buf;
645}
646
647static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
648{
Max45df98b2019-01-17 18:44:33 +0100649 vty_out(vty, "%08x %s %02u %08x [%s] %22s%s",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100650 trans->conn ? trans->conn->a.conn_id : 0,
651 gsm48_pdisc_name(trans->protocol),
652 trans->transaction_id,
653 trans->callref,
Max45df98b2019-01-17 18:44:33 +0100654 get_trans_proto_str(trans),
655 trans->vsub ? vlr_subscr_name(trans->vsub) : "-",
656 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100657}
658
659DEFUN(show_msc_transaction, show_msc_transaction_cmd,
660 "show transaction", SHOW_STR "Transactions\n")
661{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100662 struct gsm_trans *trans;
663
664 vty_trans_hdr(vty);
665 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
666 vty_dump_one_trans(vty, trans);
667
668 return CMD_SUCCESS;
669}
670
671static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
672{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100673 struct gsm_trans *trans;
674 int reqs;
675 struct llist_head *entry;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100676 char buf[128];
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100677
678 if (strlen(vsub->name))
679 vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
680 if (strlen(vsub->msisdn))
681 vty_out(vty, " Extension: %s%s", vsub->msisdn,
682 VTY_NEWLINE);
683 vty_out(vty, " LAC: %d/0x%x%s",
Max7d41d872018-12-19 11:48:33 +0100684 vsub->cgi.lai.lac, vsub->cgi.lai.lac, VTY_NEWLINE);
Philipp Maier2a0ac3b2018-12-17 10:03:50 +0100685 vty_out(vty, " RAN: %s%s",
Neels Hofmeyr7814a832018-12-26 00:40:18 +0100686 osmo_rat_type_name(vsub->cs.attached_via_ran), VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100687 vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
688 if (vsub->tmsi != GSM_RESERVED_TMSI)
689 vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
690 VTY_NEWLINE);
691 if (vsub->tmsi_new != GSM_RESERVED_TMSI)
692 vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
693 VTY_NEWLINE);
Philipp Maier6d71ccf2018-12-14 13:30:14 +0100694 if (vsub->imei[0] != '\0')
695 vty_out(vty, " IMEI: %s%s", vsub->imei, VTY_NEWLINE);
696 if (vsub->imeisv[0] != '\0')
697 vty_out(vty, " IMEISV: %s%s", vsub->imeisv, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100698
Philipp Maier89561bc2018-12-14 13:34:25 +0100699 vty_out(vty, " Flags: %s", VTY_NEWLINE);
700 vty_out(vty, " IMSI detached: %s%s",
701 vsub->imsi_detached_flag ? "true" : "false", VTY_NEWLINE);
702 vty_out(vty, " Conf. by radio contact: %s%s",
703 vsub->conf_by_radio_contact_ind ? "true" : "false",
704 VTY_NEWLINE);
705 vty_out(vty, " Subscr. data conf. by HLR: %s%s",
706 vsub->sub_dataconf_by_hlr_ind ? "true" : "false", VTY_NEWLINE);
707 vty_out(vty, " Location conf. in HLR: %s%s",
708 vsub->loc_conf_in_hlr_ind ? "true" : "false", VTY_NEWLINE);
709 vty_out(vty, " Subscriber dormant: %s%s",
710 vsub->dormant_ind ? "true" : "false", VTY_NEWLINE);
711 vty_out(vty, " Received cancel locataion: %s%s",
712 vsub->cancel_loc_rx ? "true" : "false", VTY_NEWLINE);
713 vty_out(vty, " MS not reachable: %s%s",
714 vsub->ms_not_reachable_flag ? "true" : "false", VTY_NEWLINE);
715 vty_out(vty, " LA allowed: %s%s",
716 vsub->la_allowed ? "true" : "false", VTY_NEWLINE);
717
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100718#if 0
719 /* TODO: add this to vlr_subscr? */
720 if (vsub->auth_info.auth_algo != AUTH_ALGO_NONE) {
721 struct gsm_auth_info *i = &vsub->auth_info;
722 vty_out(vty, " A3A8 algorithm id: %d%s",
723 i->auth_algo, VTY_NEWLINE);
724 vty_out(vty, " A3A8 Ki: %s%s",
725 osmo_hexdump(i->a3a8_ki, i->a3a8_ki_len),
726 VTY_NEWLINE);
727 }
728#endif
729
730 if (vsub->last_tuple) {
Neels Hofmeyr8b6e5362018-11-30 02:57:33 +0100731 struct vlr_auth_tuple *t = vsub->last_tuple;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100732 vty_out(vty, " A3A8 last tuple (used %d times):%s",
733 t->use_count, VTY_NEWLINE);
734 vty_out(vty, " seq # : %d%s",
735 t->key_seq, VTY_NEWLINE);
736 vty_out(vty, " RAND : %s%s",
737 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
738 VTY_NEWLINE);
739 vty_out(vty, " SRES : %s%s",
740 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
741 VTY_NEWLINE);
742 vty_out(vty, " Kc : %s%s",
743 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
744 VTY_NEWLINE);
745 }
746
747 reqs = 0;
748 llist_for_each(entry, &vsub->cs.requests)
749 reqs += 1;
750 vty_out(vty, " Paging: %s paging for %d requests%s",
751 vsub->cs.is_paging ? "is" : "not", reqs, VTY_NEWLINE);
Harald Welte0df904d2018-12-03 11:00:04 +0100752
753 /* SGs related */
754 vty_out(vty, " SGs-state: %s%s",
755 osmo_fsm_inst_state_name(vsub->sgs_fsm), VTY_NEWLINE);
Vadim Yanitskiy477cbc62019-02-23 16:59:16 +0700756 if (strlen(vsub->sgs.mme_name))
Harald Welte0df904d2018-12-03 11:00:04 +0100757 vty_out(vty, " SGs-MME: %s%s", vsub->sgs.mme_name, VTY_NEWLINE);
758 else
759 vty_out(vty, " SGs-MME: (none)%s", VTY_NEWLINE);
760
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100761 vty_out(vty, " Use: %s%s", osmo_use_count_name_buf(buf, sizeof(buf), &vsub->use_count), VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100762
763 /* Connection */
764 if (vsub->msc_conn_ref) {
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100765 struct ran_conn *conn = vsub->msc_conn_ref;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100766 vty_conn_hdr(vty);
767 vty_dump_one_conn(vty, conn);
768 }
769
770 /* Transactions */
771 vty_trans_hdr(vty);
772 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
773 if (trans->vsub != vsub)
774 continue;
775 vty_dump_one_trans(vty, trans);
776 }
777}
778
779/* Subscriber */
780DEFUN(show_subscr_cache,
781 show_subscr_cache_cmd,
782 "show subscriber cache",
783 SHOW_STR "Show information about subscribers\n"
784 "Display contents of subscriber cache\n")
785{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100786 struct vlr_subscr *vsub;
787 int count = 0;
788
789 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
790 if (++count > 100) {
791 vty_out(vty, "%% More than %d subscribers in cache,"
792 " stopping here.%s", count-1, VTY_NEWLINE);
793 break;
794 }
795 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
796 subscr_dump_full_vty(vty, vsub);
Harald Welte69c54a82018-02-09 20:41:14 +0100797 }
798
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200799 return CMD_SUCCESS;
800}
801
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100802DEFUN(sms_send_pend,
803 sms_send_pend_cmd,
804 "sms send pending",
805 "SMS related commands\n" "SMS Sending related commands\n"
806 "Send all pending SMS")
807{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100808 struct gsm_sms *sms;
809 unsigned long long sms_id = 0;
810
811 while (1) {
812 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
813 if (!sms)
814 break;
815
816 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700817 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100818
819 sms_id = sms->id + 1;
820 }
821
822 return CMD_SUCCESS;
823}
824
825DEFUN(sms_delete_expired,
826 sms_delete_expired_cmd,
827 "sms delete expired",
828 "SMS related commands\n" "SMS Database related commands\n"
829 "Delete all expired SMS")
830{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100831 struct gsm_sms *sms;
832 unsigned long long sms_id = 0;
833 long long num_deleted = 0;
834
835 while (1) {
836 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
837 if (!sms)
838 break;
839
840 /* Skip SMS which are currently queued for sending. */
841 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
842 continue;
843
844 /* Expiration check is performed by the DB layer. */
845 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
846 num_deleted++;
847
848 sms_id = sms->id + 1;
849 }
850
851 if (num_deleted == 0) {
852 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
853 return CMD_WARNING;
854 }
855
856 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
857 return CMD_SUCCESS;
858}
859
860static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +0200861 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100862 char *str, uint8_t tp_pid)
863{
864 struct gsm_network *net = receiver->vlr->user_ctx;
865 struct gsm_sms *sms;
866
Harald Welte39b55482018-04-09 19:19:33 +0200867 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100868 sms->protocol_id = tp_pid;
869
870 /* store in database for the queue */
871 if (db_sms_store(sms) != 0) {
872 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
873 sms_free(sms);
874 return CMD_WARNING;
875 }
876 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
877
878 sms_free(sms);
879 sms_queue_trigger(net->sms_queue);
880 return CMD_SUCCESS;
881}
882
883static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
884 const char *type,
885 const char *id)
886{
887 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100888 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100889 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100890 return vlr_subscr_find_by_imsi(gsmnet->vlr, id, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100891 else if (!strcmp(type, "tmsi"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100892 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id), VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100893
894 return NULL;
895}
896#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
897#define SUBSCR_HELP "Operations on a Subscriber\n" \
898 "Identify subscriber by MSISDN (phone number)\n" \
899 "Legacy alias for 'msisdn'\n" \
900 "Identify subscriber by IMSI\n" \
901 "Identify subscriber by TMSI\n" \
902 "Identify subscriber by database ID\n" \
903 "Identifier for the subscriber\n"
904
905DEFUN(show_subscr,
906 show_subscr_cmd,
907 "show subscriber " SUBSCR_TYPES " ID",
908 SHOW_STR SUBSCR_HELP)
909{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100910 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
911 argv[1]);
912
913 if (!vsub) {
914 vty_out(vty, "%% No subscriber found for %s %s%s",
915 argv[0], argv[1], VTY_NEWLINE);
916 return CMD_WARNING;
917 }
918
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100919 /* In the vty output to the user, exclude this local use count added by vlr_subscr_get() in get_vsub_by_argv().
920 * This works, because: for get_vsub_by_argv() to succeed, there *must* have been at least one use count before
921 * this, and since this is not multi-threaded, this vlr_subscr_put() cannot possibly reach a count of 0. */
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100922 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100923
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100924 subscr_dump_full_vty(vty, vsub);
925
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100926 return CMD_SUCCESS;
927}
928
929DEFUN(subscriber_create,
930 subscriber_create_cmd,
931 "subscriber create imsi ID",
932 "Operations on a Subscriber\n" \
933 "Create new subscriber\n" \
934 "Identify the subscriber by his IMSI\n" \
935 "Identifier for the subscriber\n")
936{
937 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
938 VTY_NEWLINE);
939 return CMD_WARNING;
940}
941
942DEFUN(subscriber_send_pending_sms,
943 subscriber_send_pending_sms_cmd,
944 "subscriber " SUBSCR_TYPES " ID sms pending-send",
945 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
946{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100947 struct vlr_subscr *vsub;
948 struct gsm_sms *sms;
949
950 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
951 if (!vsub) {
952 vty_out(vty, "%% No subscriber found for %s %s%s",
953 argv[0], argv[1], VTY_NEWLINE);
954 return CMD_WARNING;
955 }
956
957 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
958 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700959 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100960
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100961 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100962
963 return CMD_SUCCESS;
964}
965
Neels Hofmeyrf90496f2019-03-06 16:19:50 +0100966DEFUN(subscriber_sms_delete_all,
967 subscriber_sms_delete_all_cmd,
968 "subscriber " SUBSCR_TYPES " ID sms delete-all",
969 SUBSCR_HELP "SMS Operations\n"
970 "Delete all SMS to be delivered to this subscriber"
971 " -- WARNING: the SMS data for all unsent SMS for this subscriber"
972 " WILL BE LOST.\n")
973{
974 struct vlr_subscr *vsub;
975
976 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
977 if (!vsub) {
978 vty_out(vty, "%% No subscriber found for %s %s%s",
979 argv[0], argv[1], VTY_NEWLINE);
980 return CMD_WARNING;
981 }
982
983 db_sms_delete_by_msisdn(vsub->msisdn);
984
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100985 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyrf90496f2019-03-06 16:19:50 +0100986
987 return CMD_SUCCESS;
988}
989
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100990DEFUN(subscriber_send_sms,
991 subscriber_send_sms_cmd,
992 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
993 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
994{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100995 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200996 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100997 char *str;
998 int rc;
999
1000 if (!vsub) {
1001 vty_out(vty, "%% No subscriber found for %s %s%s",
1002 argv[0], argv[1], VTY_NEWLINE);
1003 rc = CMD_WARNING;
1004 goto err;
1005 }
1006
Harald Welte39b55482018-04-09 19:19:33 +02001007 if (!strcmp(argv[2], "msisdn"))
1008 sender_msisdn = argv[3];
1009 else {
1010 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1011 if (!sender) {
1012 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1013 rc = CMD_WARNING;
1014 goto err;
1015 }
1016 sender_msisdn = sender->msisdn;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001017 vlr_subscr_put(sender, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001018 }
1019
1020 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001021 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001022 talloc_free(str);
1023
1024err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001025 if (vsub)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001026 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001027
1028 return rc;
1029}
1030
1031DEFUN(subscriber_silent_sms,
1032 subscriber_silent_sms_cmd,
1033
1034 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
1035 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
1036{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001037 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +02001038 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001039 char *str;
1040 int rc;
1041
1042 if (!vsub) {
1043 vty_out(vty, "%% No subscriber found for %s %s%s",
1044 argv[0], argv[1], VTY_NEWLINE);
1045 rc = CMD_WARNING;
1046 goto err;
1047 }
1048
Harald Welte39b55482018-04-09 19:19:33 +02001049 if (!strcmp(argv[2], "msisdn")) {
1050 sender_msisdn = argv[3];
1051 } else {
1052 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1053 if (!sender) {
1054 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1055 rc = CMD_WARNING;
1056 goto err;
1057 }
1058 sender_msisdn = sender->msisdn;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001059 vlr_subscr_put(sender, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001060 }
1061
1062 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001063 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001064 talloc_free(str);
1065
1066err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001067 if (vsub)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001068 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001069
1070 return rc;
1071}
1072
Sylvain Munaut93558302019-02-14 20:13:08 +01001073#define CHAN_TYPES "(any|tch/f|tch/h|tch/any|sdcch)"
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001074#define CHAN_TYPE_HELP \
1075 "Any channel\n" \
1076 "TCH/F channel\n" \
Sylvain Munaut93558302019-02-14 20:13:08 +01001077 "TCH/H channel\n" \
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001078 "Any TCH channel\n" \
1079 "SDCCH channel\n"
1080
Sylvain Munaut93558302019-02-14 20:13:08 +01001081#define CHAN_MODES "(signalling|speech-hr|speech-fr|speech-efr|speech-amr)"
1082#define CHAN_MODE_HELP \
1083 "Signalling only\n" \
1084 "Speech with HR codec\n" \
1085 "Speech with FR codec\n" \
1086 "Speech with EFR codec\n" \
1087 "Speech with AMR codec\n"
1088
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001089DEFUN(subscriber_silent_call_start,
1090 subscriber_silent_call_start_cmd,
Sylvain Munaut93558302019-02-14 20:13:08 +01001091 "subscriber " SUBSCR_TYPES " ID silent-call start " CHAN_TYPES " " CHAN_MODES " [IP] [<0-65535>]",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001092 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
Sylvain Munaut93558302019-02-14 20:13:08 +01001093 CHAN_TYPE_HELP CHAN_MODE_HELP
1094 "Target IP for RTP traffic (default 127.0.0.1)\n"
1095 "Target port for RTP traffic (default: 4000)\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001096{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001097 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Sylvain Munaut93558302019-02-14 20:13:08 +01001098 struct gsm0808_channel_type ct;
1099 const char *ip;
1100 uint16_t port;
1101 int rc, speech;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001102
1103 if (!vsub) {
1104 vty_out(vty, "%% No subscriber found for %s %s%s",
1105 argv[0], argv[1], VTY_NEWLINE);
1106 return CMD_WARNING;
1107 }
1108
Sylvain Munaut93558302019-02-14 20:13:08 +01001109 memset(&ct, 0x00, sizeof(ct));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001110
Sylvain Munaut93558302019-02-14 20:13:08 +01001111 if (!strcmp(argv[3], "signalling")) {
1112 ct.ch_indctr = GSM0808_CHAN_SIGN;
1113 ct.perm_spch[0] = 0; /* Spare but required */
1114 ct.perm_spch_len = 1;
1115 } else if (!strcmp(argv[3], "speech-hr")) {
1116 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1117 ct.perm_spch[0] = GSM0808_PERM_HR1;
1118 ct.perm_spch_len = 1;
1119 } else if (!strcmp(argv[3], "speech-fr")) {
1120 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1121 ct.perm_spch[0] = GSM0808_PERM_FR1;
1122 ct.perm_spch_len = 1;
1123 } else if (!strcmp(argv[3], "speech-efr")) {
1124 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1125 ct.perm_spch[0] = GSM0808_PERM_FR2;
1126 ct.perm_spch_len = 1;
1127 } else if (!strcmp(argv[3], "speech-amr")) {
1128 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1129 ct.perm_spch[0] = GSM0808_PERM_FR3;
1130 ct.perm_spch[1] = GSM0808_PERM_HR3;
1131 ct.perm_spch_len = 2;
1132 }
1133
1134 speech = ct.ch_indctr == GSM0808_CHAN_SPEECH;
1135
1136 if (!strcmp(argv[2], "tch/f"))
1137 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_BM : GSM0808_SIGN_FULL_BM;
1138 else if (!strcmp(argv[2], "tch/h"))
1139 ct.ch_rate_type = speech ? GSM0808_SPEECH_HALF_LM : GSM0808_SIGN_HALF_LM;
1140 else if (!strcmp(argv[2], "tch/any"))
1141 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_FULL_PREF;
1142 else if (!strcmp(argv[2], "sdcch")) {
1143 if (speech) {
1144 vty_out(vty, "Can't request speech on SDCCH%s", VTY_NEWLINE);
1145 return CMD_WARNING;
1146 }
1147 ct.ch_rate_type = GSM0808_SIGN_SDCCH;
1148 } else
1149 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_ANY;
1150
1151 ip = argc >= 5 ? argv[4] : "127.0.0.1";
1152 port = argc >= 6 ? atoi(argv[5]) : 4000;
1153
1154 rc = gsm_silent_call_start(vsub, &ct, ip, port, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001155 switch (rc) {
1156 case -ENODEV:
1157 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
1158 break;
1159 default:
1160 if (rc)
1161 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
1162 else
1163 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
1164 break;
1165 }
1166
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001167 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001168 return rc ? CMD_WARNING : CMD_SUCCESS;
1169}
1170
1171DEFUN(subscriber_silent_call_stop,
1172 subscriber_silent_call_stop_cmd,
1173 "subscriber " SUBSCR_TYPES " ID silent-call stop",
1174 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
1175 CHAN_TYPE_HELP)
1176{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001177 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1178 int rc;
1179
1180 if (!vsub) {
1181 vty_out(vty, "%% No subscriber found for %s %s%s",
1182 argv[0], argv[1], VTY_NEWLINE);
1183 return CMD_WARNING;
1184 }
1185
1186 rc = gsm_silent_call_stop(vsub);
1187 switch (rc) {
1188 case -ENODEV:
1189 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
1190 break;
1191 case -ENOENT:
1192 vty_out(vty, "%% Subscriber has no silent call active%s",
1193 VTY_NEWLINE);
1194 break;
1195 default:
1196 if (rc)
1197 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
1198 else
1199 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
1200 break;
1201 }
1202
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001203 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001204 return rc ? CMD_WARNING : CMD_SUCCESS;
1205}
1206
1207DEFUN(subscriber_ussd_notify,
1208 subscriber_ussd_notify_cmd,
1209 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1210 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1211 "Alerting Level 0\n"
1212 "Alerting Level 1\n"
1213 "Alerting Level 2\n"
1214 "Text of USSD message to send\n")
1215{
1216 char *text;
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001217 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001218 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1219 int level;
1220
1221 if (!vsub) {
1222 vty_out(vty, "%% No subscriber found for %s %s%s",
1223 argv[0], argv[1], VTY_NEWLINE);
1224 return CMD_WARNING;
1225 }
1226
1227 level = atoi(argv[2]);
1228 text = argv_concat(argv, argc, 3);
1229 if (!text) {
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001230 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001231 return CMD_WARNING;
1232 }
1233
1234 conn = connection_for_subscr(vsub);
1235 if (!conn) {
1236 vty_out(vty, "%% An active connection is required for %s %s%s",
1237 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001238 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001239 talloc_free(text);
1240 return CMD_WARNING;
1241 }
1242
1243 msc_send_ussd_notify(conn, level, text);
Vadim Yanitskiyf20c6b72018-11-29 01:20:58 +07001244 /* FIXME: since we don't allocate a transaction here,
1245 * we use dummy GSM 04.07 transaction ID. */
1246 msc_send_ussd_release_complete(conn, 0x00);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001247
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001248 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001249 talloc_free(text);
1250 return CMD_SUCCESS;
1251}
1252
1253DEFUN(subscriber_paging,
1254 subscriber_paging_cmd,
1255 "subscriber " SUBSCR_TYPES " ID paging",
1256 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1257{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001258 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1259 struct subscr_request *req;
1260
1261 if (!vsub) {
1262 vty_out(vty, "%% No subscriber found for %s %s%s",
1263 argv[0], argv[1], VTY_NEWLINE);
1264 return CMD_WARNING;
1265 }
1266
Harald Welte0df904d2018-12-03 11:00:04 +01001267 req = subscr_request_conn(vsub, NULL, NULL, "manual Paging from VTY", SGSAP_SERV_IND_CS_CALL);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001268 if (req)
1269 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1270 else
1271 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1272
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001273 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001274 return req ? CMD_SUCCESS : CMD_WARNING;
1275}
1276
1277static int loop_by_char(uint8_t ch)
1278{
1279 switch (ch) {
1280 case 'a':
1281 return GSM414_LOOP_A;
1282 case 'b':
1283 return GSM414_LOOP_B;
1284 case 'c':
1285 return GSM414_LOOP_C;
1286 case 'd':
1287 return GSM414_LOOP_D;
1288 case 'e':
1289 return GSM414_LOOP_E;
1290 case 'f':
1291 return GSM414_LOOP_F;
1292 case 'i':
1293 return GSM414_LOOP_I;
1294 }
1295 return -1;
1296}
1297
1298DEFUN(subscriber_mstest_close,
1299 subscriber_mstest_close_cmd,
1300 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1301 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1302 "Close a TCH Loop inside the MS\n"
1303 "Loop Type A\n"
1304 "Loop Type B\n"
1305 "Loop Type C\n"
1306 "Loop Type D\n"
1307 "Loop Type E\n"
1308 "Loop Type F\n"
1309 "Loop Type I\n")
1310{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001311 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001312 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1313 const char *loop_str;
1314 int loop_mode;
1315
1316 if (!vsub) {
1317 vty_out(vty, "%% No subscriber found for %s %s%s",
1318 argv[0], argv[1], VTY_NEWLINE);
1319 return CMD_WARNING;
1320 }
1321
1322 loop_str = argv[2];
1323 loop_mode = loop_by_char(loop_str[0]);
1324
1325 conn = connection_for_subscr(vsub);
1326 if (!conn) {
1327 vty_out(vty, "%% An active connection is required for %s %s%s",
1328 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001329 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001330 return CMD_WARNING;
1331 }
1332
1333 gsm0414_tx_close_tch_loop_cmd(conn, loop_mode);
1334
1335 return CMD_SUCCESS;
1336}
1337
1338DEFUN(subscriber_mstest_open,
1339 subscriber_mstest_open_cmd,
1340 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1341 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1342 "Open a TCH Loop inside the MS\n")
1343{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001344 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001345 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1346
1347 if (!vsub) {
1348 vty_out(vty, "%% No subscriber found for %s %s%s",
1349 argv[0], argv[1], VTY_NEWLINE);
1350 return CMD_WARNING;
1351 }
1352
1353 conn = connection_for_subscr(vsub);
1354 if (!conn) {
1355 vty_out(vty, "%% An active connection is required for %s %s%s",
1356 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001357 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001358 return CMD_WARNING;
1359 }
1360
1361 gsm0414_tx_open_loop_cmd(conn);
1362
1363 return CMD_SUCCESS;
1364}
1365
1366DEFUN(ena_subscr_expire,
1367 ena_subscr_expire_cmd,
1368 "subscriber " SUBSCR_TYPES " ID expire",
1369 SUBSCR_HELP "Expire the subscriber Now\n")
1370{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001371 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1372 argv[1]);
1373
1374 if (!vsub) {
1375 vty_out(vty, "%% No subscriber found for %s %s%s",
1376 argv[0], argv[1], VTY_NEWLINE);
1377 return CMD_WARNING;
1378 }
1379
1380 if (vlr_subscr_expire(vsub))
1381 vty_out(vty, "%% VLR released subscriber %s%s",
1382 vlr_subscr_name(vsub), VTY_NEWLINE);
1383
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001384 if (osmo_use_count_total(&vsub->use_count) > 1)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001385 vty_out(vty, "%% Subscriber %s is still in use,"
1386 " should be released soon%s",
1387 vlr_subscr_name(vsub), VTY_NEWLINE);
1388
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001389 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001390 return CMD_SUCCESS;
1391}
1392
1393static int scall_cbfn(unsigned int subsys, unsigned int signal,
1394 void *handler_data, void *signal_data)
1395{
1396 struct scall_signal_data *sigdata = signal_data;
1397 struct vty *vty = sigdata->data;
1398
1399 switch (signal) {
1400 case S_SCALL_SUCCESS:
1401 vty_out(vty, "%% silent call success%s", VTY_NEWLINE);
1402 break;
1403 case S_SCALL_EXPIRED:
1404 vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE);
1405 break;
1406 }
1407 return 0;
1408}
1409
1410DEFUN(show_stats,
1411 show_stats_cmd,
1412 "show statistics",
1413 SHOW_STR "Display network statistics\n")
1414{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001415 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001416 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1417 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1418 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001419 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001420 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001421 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001422 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001423 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001424 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1425 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001426 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001427 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001428 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1429 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001430 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001431 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001432 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1433 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1434 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001435 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001436 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001437 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1438 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001439 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001440 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001441 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1442 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001443 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001444 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001445 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1446 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1447 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1448 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1449 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001450 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001451 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1452 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1453 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1454 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1455 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001456 return CMD_SUCCESS;
1457}
1458
1459DEFUN(show_smsqueue,
1460 show_smsqueue_cmd,
1461 "show sms-queue",
1462 SHOW_STR "Display SMSqueue statistics\n")
1463{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001464 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001465 return CMD_SUCCESS;
1466}
1467
1468DEFUN(smsqueue_trigger,
1469 smsqueue_trigger_cmd,
1470 "sms-queue trigger",
1471 "SMS Queue\n" "Trigger sending messages\n")
1472{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001473 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001474 return CMD_SUCCESS;
1475}
1476
1477DEFUN(smsqueue_max,
1478 smsqueue_max_cmd,
1479 "sms-queue max-pending <1-500>",
1480 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1481{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001482 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001483 return CMD_SUCCESS;
1484}
1485
1486DEFUN(smsqueue_clear,
1487 smsqueue_clear_cmd,
1488 "sms-queue clear",
1489 "SMS Queue\n" "Clear the queue of pending SMS\n")
1490{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001491 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001492 return CMD_SUCCESS;
1493}
1494
1495DEFUN(smsqueue_fail,
1496 smsqueue_fail_cmd,
1497 "sms-queue max-failure <1-500>",
1498 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1499{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001500 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001501 return CMD_SUCCESS;
1502}
1503
1504
1505DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1506 "mncc-int", "Configure internal MNCC handler")
1507{
1508 vty->node = MNCC_INT_NODE;
1509
1510 return CMD_SUCCESS;
1511}
1512
1513static struct cmd_node mncc_int_node = {
1514 MNCC_INT_NODE,
1515 "%s(config-mncc-int)# ",
1516 1,
1517};
1518
1519static const struct value_string tchf_codec_names[] = {
1520 { GSM48_CMODE_SPEECH_V1, "fr" },
1521 { GSM48_CMODE_SPEECH_EFR, "efr" },
1522 { GSM48_CMODE_SPEECH_AMR, "amr" },
1523 { 0, NULL }
1524};
1525
1526static const struct value_string tchh_codec_names[] = {
1527 { GSM48_CMODE_SPEECH_V1, "hr" },
1528 { GSM48_CMODE_SPEECH_AMR, "amr" },
1529 { 0, NULL }
1530};
1531
1532static int config_write_mncc_int(struct vty *vty)
1533{
1534 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1535 vty_out(vty, " default-codec tch-f %s%s",
1536 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1537 VTY_NEWLINE);
1538 vty_out(vty, " default-codec tch-h %s%s",
1539 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1540 VTY_NEWLINE);
1541
1542 return CMD_SUCCESS;
1543}
1544
1545DEFUN(mnccint_def_codec_f,
1546 mnccint_def_codec_f_cmd,
1547 "default-codec tch-f (fr|efr|amr)",
1548 "Set default codec\n" "Codec for TCH/F\n"
1549 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1550{
1551 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1552
1553 return CMD_SUCCESS;
1554}
1555
1556DEFUN(mnccint_def_codec_h,
1557 mnccint_def_codec_h_cmd,
1558 "default-codec tch-h (hr|amr)",
1559 "Set default codec\n" "Codec for TCH/H\n"
1560 "Half-Rate\n" "Adaptive Multi-Rate\n")
1561{
1562 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1563
1564 return CMD_SUCCESS;
1565}
1566
1567
1568DEFUN(logging_fltr_imsi,
1569 logging_fltr_imsi_cmd,
1570 "logging filter imsi IMSI",
1571 LOGGING_STR FILTER_STR
1572 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1573{
1574 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001575 struct log_target *tgt = osmo_log_vty2tgt(vty);
1576 const char *imsi = argv[0];
1577
1578 if (!tgt)
1579 return CMD_WARNING;
1580
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001581 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001582
1583 if (!vlr_subscr) {
1584 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1585 argv[0], VTY_NEWLINE);
1586 return CMD_WARNING;
1587 }
1588
1589 log_set_filter_vlr_subscr(tgt, vlr_subscr);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001590 vlr_subscr_put(vlr_subscr, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001591 return CMD_SUCCESS;
1592}
1593
1594static struct cmd_node hlr_node = {
1595 HLR_NODE,
1596 "%s(config-hlr)# ",
1597 1,
1598};
1599
1600DEFUN(cfg_hlr, cfg_hlr_cmd,
1601 "hlr", "Configure connection to the HLR")
1602{
1603 vty->node = HLR_NODE;
1604 return CMD_SUCCESS;
1605}
1606
1607DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1608 "Remote GSUP address of the HLR\n"
1609 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1610{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001611 talloc_free((void*)gsmnet->gsup_server_addr_str);
1612 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1613 return CMD_SUCCESS;
1614}
1615
1616DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1617 "Remote GSUP port of the HLR\n"
1618 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1619{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001620 gsmnet->gsup_server_port = atoi(argv[0]);
1621 return CMD_SUCCESS;
1622}
1623
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001624DEFUN(cfg_hlr_ipa_name,
1625 cfg_hlr_ipa_name_cmd,
1626 "ipa-name NAME",
1627 "Set the IPA name of this MSC\n"
1628 "A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. "
1629 "This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. "
1630 "The default is 'MSC-00-00-00-00-00-00'.\n")
1631{
1632 if (vty->type != VTY_FILE) {
1633 vty_out(vty, "The IPA name cannot be changed at run-time; "
1634 "It can only be set in the configuraton file.%s", VTY_NEWLINE);
1635 return CMD_WARNING;
1636 }
1637
1638 gsmnet->msc_ipa_name = talloc_strdup(gsmnet, argv[0]);
1639 return CMD_SUCCESS;
1640}
1641
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001642static int config_write_hlr(struct vty *vty)
1643{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001644 vty_out(vty, "hlr%s", VTY_NEWLINE);
1645 vty_out(vty, " remote-ip %s%s",
1646 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1647 vty_out(vty, " remote-port %u%s",
1648 gsmnet->gsup_server_port, VTY_NEWLINE);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001649 if (gsmnet->msc_ipa_name)
1650 vty_out(vty, " ipa-name %s%s", gsmnet->msc_ipa_name, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001651 return CMD_SUCCESS;
1652}
1653
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001654void msc_vty_init(struct gsm_network *msc_network)
1655{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001656 OSMO_ASSERT(gsmnet == NULL);
1657 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001658
1659 osmo_stats_vty_add_cmds();
1660
1661 install_element(CONFIG_NODE, &cfg_net_cmd);
1662 install_node(&net_node, config_write_net);
1663 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
1664 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1665 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1666 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
1667 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
1668 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
1669 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
1670 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
1671 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
1672 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
1673 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
1674 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
1675 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001676
1677 install_element(CONFIG_NODE, &cfg_msc_cmd);
1678 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001679 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01001680 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
1681 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02001682 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01001683 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Vadim Yanitskiy64623e12018-11-28 23:05:51 +07001684 install_element(MSC_NODE, &cfg_msc_ncss_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001685 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01001686 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
1687 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Oliver Smith0fec28a2018-12-14 10:52:52 +01001688 install_element(MSC_NODE, &cfg_msc_check_imei_rqd_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001689 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
1690 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01001691 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01001692 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +07001693 install_element(MSC_NODE, &cfg_msc_sms_over_gsup_cmd);
1694 install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001695
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02001696 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001697#ifdef BUILD_IU
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +01001698 ranap_iu_vty_init(MSC_NODE, &msc_network->iu.rab_assign_addr_enc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001699#endif
Harald Welte0df904d2018-12-03 11:00:04 +01001700 sgs_vty_init();
Stefan Sperling617ac802018-02-22 17:58:20 +01001701 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001702
1703 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
1704
1705 install_element_ve(&show_subscr_cmd);
1706 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01001707 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001708 install_element_ve(&show_msc_conn_cmd);
1709 install_element_ve(&show_msc_transaction_cmd);
1710
1711 install_element_ve(&sms_send_pend_cmd);
1712 install_element_ve(&sms_delete_expired_cmd);
1713
1714 install_element_ve(&subscriber_create_cmd);
1715 install_element_ve(&subscriber_send_sms_cmd);
1716 install_element_ve(&subscriber_silent_sms_cmd);
1717 install_element_ve(&subscriber_silent_call_start_cmd);
1718 install_element_ve(&subscriber_silent_call_stop_cmd);
1719 install_element_ve(&subscriber_ussd_notify_cmd);
1720 install_element_ve(&subscriber_mstest_close_cmd);
1721 install_element_ve(&subscriber_mstest_open_cmd);
1722 install_element_ve(&subscriber_paging_cmd);
1723 install_element_ve(&show_stats_cmd);
1724 install_element_ve(&show_smsqueue_cmd);
1725 install_element_ve(&logging_fltr_imsi_cmd);
1726
1727 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
1728 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
1729 install_element(ENABLE_NODE, &smsqueue_max_cmd);
1730 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
1731 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
1732 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001733 install_element(ENABLE_NODE, &subscriber_sms_delete_all_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001734
1735 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1736 install_node(&mncc_int_node, config_write_mncc_int);
1737 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1738 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1739
1740 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
1741
1742 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1743 install_node(&hlr_node, config_write_hlr);
1744 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1745 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001746 install_element(HLR_NODE, &cfg_hlr_ipa_name_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001747}