blob: e1d1b40208a356c3e162ba983258dc60312e755f [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>
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020033
Maxc51609a2018-11-09 17:13:00 +010034#include <osmocom/sigtran/sccp_helpers.h>
35
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020036#include <osmocom/vty/command.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010037#include <osmocom/vty/logging.h>
Stefan Sperling617ac802018-02-22 17:58:20 +010038#include <osmocom/vty/misc.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010039#include <osmocom/vty/stats.h>
40
Neels Hofmeyr00e82d62017-07-05 15:19:52 +020041#ifdef BUILD_IU
42#include <osmocom/ranap/iu_client.h>
43#endif
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020044
Neels Hofmeyr90843962017-09-04 15:04:35 +020045#include <osmocom/msc/vty.h>
46#include <osmocom/msc/gsm_data.h>
47#include <osmocom/msc/gsm_subscriber.h>
48#include <osmocom/msc/vlr.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010049#include <osmocom/msc/transaction.h>
50#include <osmocom/msc/db.h>
Maxc51609a2018-11-09 17:13:00 +010051#include <osmocom/msc/a_iface.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010052#include <osmocom/msc/sms_queue.h>
53#include <osmocom/msc/silent_call.h>
54#include <osmocom/msc/gsm_04_80.h>
55#include <osmocom/msc/gsm_04_14.h>
56#include <osmocom/msc/signal.h>
57#include <osmocom/msc/mncc_int.h>
Vadim Yanitskiy1b891302018-08-04 01:33:08 +070058#include <osmocom/msc/rrlp.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010059
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010060static struct gsm_network *gsmnet = NULL;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010061
62struct cmd_node net_node = {
63 GSMNET_NODE,
64 "%s(config-net)# ",
65 1,
66};
67
68#define NETWORK_STR "Configure the GSM network\n"
69#define CODE_CMD_STR "Code commands\n"
70#define NAME_CMD_STR "Name Commands\n"
71#define NAME_STR "Name to use\n"
72
73DEFUN(cfg_net,
74 cfg_net_cmd,
75 "network", NETWORK_STR)
76{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010077 vty->index = gsmnet;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010078 vty->node = GSMNET_NODE;
79
80 return CMD_SUCCESS;
81}
82
83DEFUN(cfg_net_ncc,
84 cfg_net_ncc_cmd,
85 "network country code <1-999>",
86 "Set the GSM network country code\n"
87 "Country commands\n"
88 CODE_CMD_STR
89 "Network Country Code to use\n")
90{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010091 gsmnet->plmn.mcc = atoi(argv[0]);
92
93 return CMD_SUCCESS;
94}
95
96DEFUN(cfg_net_mnc,
97 cfg_net_mnc_cmd,
98 "mobile network code <0-999>",
99 "Set the GSM mobile network code\n"
100 "Network Commands\n"
101 CODE_CMD_STR
102 "Mobile Network Code to use\n")
103{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100104 uint16_t mnc;
105 bool mnc_3_digits;
106
107 if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
108 vty_out(vty, "%% Error decoding MNC: %s%s", argv[0], VTY_NEWLINE);
109 return CMD_WARNING;
110 }
111
112 gsmnet->plmn.mnc = mnc;
113 gsmnet->plmn.mnc_3_digits = mnc_3_digits;
114
115 return CMD_SUCCESS;
116}
117
118DEFUN(cfg_net_name_short,
119 cfg_net_name_short_cmd,
120 "short name NAME",
121 "Set the short GSM network name\n" NAME_CMD_STR NAME_STR)
122{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100123 osmo_talloc_replace_string(gsmnet, &gsmnet->name_short, argv[0]);
124 return CMD_SUCCESS;
125}
126
127DEFUN(cfg_net_name_long,
128 cfg_net_name_long_cmd,
129 "long name NAME",
130 "Set the long GSM network name\n" NAME_CMD_STR NAME_STR)
131{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100132 osmo_talloc_replace_string(gsmnet, &gsmnet->name_long, argv[0]);
133 return CMD_SUCCESS;
134}
135
136DEFUN(cfg_net_encryption,
137 cfg_net_encryption_cmd,
138 "encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]",
139 "Encryption options\n"
140 "GSM A5 Air Interface Encryption\n"
141 "A5/n Algorithm Number\n"
142 "A5/n Algorithm Number\n"
143 "A5/n Algorithm Number\n"
144 "A5/n Algorithm Number\n")
145{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100146 unsigned int i;
147
148 gsmnet->a5_encryption_mask = 0;
149 for (i = 0; i < argc; i++)
150 gsmnet->a5_encryption_mask |= (1 << atoi(argv[i]));
151
152 return CMD_SUCCESS;
153}
154
155DEFUN(cfg_net_authentication,
156 cfg_net_authentication_cmd,
157 "authentication (optional|required)",
158 "Whether to enforce MS authentication in 2G\n"
159 "Allow MS to attach via 2G BSC without authentication\n"
160 "Always do authentication\n")
161{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100162 gsmnet->authentication_required = (argv[0][0] == 'r') ? true : false;
163
164 return CMD_SUCCESS;
165}
166
167DEFUN(cfg_net_rrlp_mode, cfg_net_rrlp_mode_cmd,
168 "rrlp mode (none|ms-based|ms-preferred|ass-preferred)",
169 "Radio Resource Location Protocol\n"
170 "Set the Radio Resource Location Protocol Mode\n"
171 "Don't send RRLP request\n"
172 "Request MS-based location\n"
173 "Request any location, prefer MS-based\n"
174 "Request any location, prefer MS-assisted\n")
175{
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700176 gsmnet->rrlp.mode = msc_rrlp_mode_parse(argv[0]);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100177
178 return CMD_SUCCESS;
179}
180
181DEFUN(cfg_net_mm_info, cfg_net_mm_info_cmd,
182 "mm info (0|1)",
183 "Mobility Management\n"
184 "Send MM INFO after LOC UPD ACCEPT\n"
185 "Disable\n" "Enable\n")
186{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100187 gsmnet->send_mm_info = atoi(argv[0]);
188
189 return CMD_SUCCESS;
190}
191
192DEFUN(cfg_net_timezone,
193 cfg_net_timezone_cmd,
194 "timezone <-19-19> (0|15|30|45)",
195 "Set the Timezone Offset of the network\n"
196 "Timezone offset (hours)\n"
197 "Timezone offset (00 minutes)\n"
198 "Timezone offset (15 minutes)\n"
199 "Timezone offset (30 minutes)\n"
200 "Timezone offset (45 minutes)\n"
201 )
202{
203 struct gsm_network *net = vty->index;
204 int tzhr = atoi(argv[0]);
205 int tzmn = atoi(argv[1]);
206
207 net->tz.hr = tzhr;
208 net->tz.mn = tzmn;
209 net->tz.dst = 0;
210 net->tz.override = 1;
211
212 return CMD_SUCCESS;
213}
214
215DEFUN(cfg_net_timezone_dst,
216 cfg_net_timezone_dst_cmd,
217 "timezone <-19-19> (0|15|30|45) <0-2>",
218 "Set the Timezone Offset of the network\n"
219 "Timezone offset (hours)\n"
220 "Timezone offset (00 minutes)\n"
221 "Timezone offset (15 minutes)\n"
222 "Timezone offset (30 minutes)\n"
223 "Timezone offset (45 minutes)\n"
224 "DST offset (hours)\n"
225 )
226{
227 struct gsm_network *net = vty->index;
228 int tzhr = atoi(argv[0]);
229 int tzmn = atoi(argv[1]);
230 int tzdst = atoi(argv[2]);
231
232 net->tz.hr = tzhr;
233 net->tz.mn = tzmn;
234 net->tz.dst = tzdst;
235 net->tz.override = 1;
236
237 return CMD_SUCCESS;
238}
239
240DEFUN(cfg_net_no_timezone,
241 cfg_net_no_timezone_cmd,
242 "no timezone",
243 NO_STR
244 "Disable network timezone override, use system tz\n")
245{
246 struct gsm_network *net = vty->index;
247
248 net->tz.override = 0;
249
250 return CMD_SUCCESS;
251}
252
253DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
254 "periodic location update <6-1530>",
255 "Periodic Location Updating Interval\n"
256 "Periodic Location Updating Interval\n"
257 "Periodic Location Updating Interval\n"
258 "Periodic Location Updating Interval in Minutes\n")
259{
260 struct gsm_network *net = vty->index;
261
262 net->t3212 = atoi(argv[0]) / 6;
263
264 return CMD_SUCCESS;
265}
266
267DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
268 "no periodic location update",
269 NO_STR
270 "Periodic Location Updating Interval\n"
271 "Periodic Location Updating Interval\n"
272 "Periodic Location Updating Interval\n")
273{
274 struct gsm_network *net = vty->index;
275
276 net->t3212 = 0;
277
278 return CMD_SUCCESS;
279}
280
281static int config_write_net(struct vty *vty)
282{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100283 int i;
284
285 vty_out(vty, "network%s", VTY_NEWLINE);
286 vty_out(vty, " network country code %s%s", osmo_mcc_name(gsmnet->plmn.mcc), VTY_NEWLINE);
287 vty_out(vty, " mobile network code %s%s",
288 osmo_mnc_name(gsmnet->plmn.mnc, gsmnet->plmn.mnc_3_digits), VTY_NEWLINE);
289 vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
290 vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
291 vty_out(vty, " encryption a5");
292 for (i = 0; i < 8; i++) {
293 if (gsmnet->a5_encryption_mask & (1 << i))
294 vty_out(vty, " %u", i);
295 }
296 vty_out(vty, "%s", VTY_NEWLINE);
297 vty_out(vty, " authentication %s%s",
298 gsmnet->authentication_required ? "required" : "optional", VTY_NEWLINE);
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700299 vty_out(vty, " rrlp mode %s%s", msc_rrlp_mode_name(gsmnet->rrlp.mode),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100300 VTY_NEWLINE);
301 vty_out(vty, " mm info %u%s", gsmnet->send_mm_info, VTY_NEWLINE);
302 if (gsmnet->tz.override != 0) {
303 if (gsmnet->tz.dst)
304 vty_out(vty, " timezone %d %d %d%s",
305 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
306 VTY_NEWLINE);
307 else
308 vty_out(vty, " timezone %d %d%s",
309 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
310 }
311 if (gsmnet->t3212 == 0)
312 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
313 else
314 vty_out(vty, " periodic location update %u%s",
315 gsmnet->t3212 * 6, VTY_NEWLINE);
316
317 if (gsmnet->emergency.route_to_msisdn) {
318 vty_out(vty, " emergency-call route-to-msisdn %s%s",
319 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
320 }
321
322 return CMD_SUCCESS;
323}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200324
325static struct cmd_node msc_node = {
326 MSC_NODE,
327 "%s(config-msc)# ",
328 1,
329};
330
331DEFUN(cfg_msc, cfg_msc_cmd,
332 "msc", "Configure MSC options")
333{
334 vty->node = MSC_NODE;
335 return CMD_SUCCESS;
336}
337
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100338#define MNCC_STR "Configure Mobile Network Call Control\n"
339#define MNCC_GUARD_TIMEOUT_STR "Set global guard timer for mncc interface activity\n"
340#define MNCC_GUARD_TIMEOUT_VALUE_STR "guard timer value (sec.)\n"
341
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100342DEFUN(cfg_msc_mncc_internal,
343 cfg_msc_mncc_internal_cmd,
344 "mncc internal",
345 MNCC_STR "Use internal MNCC handler (default; changes need a program restart)\n")
346{
347 gsm_network_set_mncc_sock_path(gsmnet, NULL);
348 return CMD_SUCCESS;
349}
350
351DEFUN(cfg_msc_mncc_external,
352 cfg_msc_mncc_external_cmd,
353 "mncc external MNCC_SOCKET_PATH",
354 MNCC_STR "Use external MNCC handler (changes need a program restart)\n"
355 "File system path to create the MNCC unix domain socket at\n")
356{
357 gsm_network_set_mncc_sock_path(gsmnet, argv[0]);
358 return CMD_SUCCESS;
359}
360
Philipp Maier9ca7b312018-10-10 17:00:49 +0200361DEFUN(cfg_msc_mncc_guard_timeout,
362 cfg_msc_mncc_guard_timeout_cmd,
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100363 "mncc guard-timeout <0-255>",
364 MNCC_STR
365 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR)
Philipp Maier9ca7b312018-10-10 17:00:49 +0200366{
367 gsmnet->mncc_guard_timeout = atoi(argv[0]);
368 return CMD_SUCCESS;
369}
370
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100371ALIAS_DEPRECATED(cfg_msc_mncc_guard_timeout,
372 cfg_msc_deprecated_mncc_guard_timeout_cmd,
373 "mncc-guard-timeout <0-255>",
374 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR);
375
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200376DEFUN(cfg_msc_assign_tmsi, cfg_msc_assign_tmsi_cmd,
377 "assign-tmsi",
378 "Assign TMSI during Location Updating.\n")
379{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200380 gsmnet->vlr->cfg.assign_tmsi = true;
381 return CMD_SUCCESS;
382}
383
384DEFUN(cfg_msc_no_assign_tmsi, cfg_msc_no_assign_tmsi_cmd,
385 "no assign-tmsi",
386 NO_STR "Assign TMSI during Location Updating.\n")
387{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200388 gsmnet->vlr->cfg.assign_tmsi = false;
389 return CMD_SUCCESS;
390}
391
Philipp Maierfbf66102017-04-09 12:32:51 +0200392DEFUN(cfg_msc_cs7_instance_a,
393 cfg_msc_cs7_instance_a_cmd,
394 "cs7-instance-a <0-15>",
395 "Set SS7 to be used by the A-Interface.\n" "SS7 instance reference number\n")
396{
Philipp Maierfbf66102017-04-09 12:32:51 +0200397 gsmnet->a.cs7_instance = atoi(argv[0]);
398 return CMD_SUCCESS;
399}
400
401DEFUN(cfg_msc_cs7_instance_iu,
402 cfg_msc_cs7_instance_iu_cmd,
403 "cs7-instance-iu <0-15>",
404 "Set SS7 to be used by the Iu-Interface.\n" "SS7 instance reference number\n")
405{
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100406#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200407 gsmnet->iu.cs7_instance = atoi(argv[0]);
408 return CMD_SUCCESS;
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100409#else
410 vty_out(vty, "WARNING: 'cs7-instance-iu' without effect: built without Iu support%s",
411 VTY_NEWLINE);
412 return CMD_WARNING;
413#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200414}
415
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100416DEFUN(cfg_msc_auth_tuple_max_reuse_count, cfg_msc_auth_tuple_max_reuse_count_cmd,
417 "auth-tuple-max-reuse-count <-1-2147483647>",
418 "Configure authentication tuple re-use\n"
419 "0 to use each auth tuple at most once (default), >0 to limit re-use, -1 to re-use infinitely (vulnerable!).\n")
420{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100421 gsmnet->vlr->cfg.auth_tuple_max_reuse_count = atoi(argv[0]);
422 return CMD_SUCCESS;
423}
424
425DEFUN(cfg_msc_auth_tuple_reuse_on_error, cfg_msc_auth_tuple_reuse_on_error_cmd,
426 "auth-tuple-reuse-on-error (0|1)",
427 "Configure authentication tuple re-use when HLR is not responsive\n"
428 "0 = never re-use auth tuples beyond auth-tuple-max-reuse-count (default)\n"
429 "1 = if the HLR does not deliver new tuples, do re-use already available old ones.\n")
430{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100431 gsmnet->vlr->cfg.auth_reuse_old_sets_on_error = atoi(argv[0]) ? true : false;
432 return CMD_SUCCESS;
433}
434
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100435DEFUN(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd,
436 "paging response-timer (default|<1-65535>)",
437 "Configure Paging\n"
438 "Set Paging timeout, the minimum time to pass between (unsuccessful) Pagings sent towards"
439 " BSS or RNC\n"
440 "Set to default timeout (" OSMO_STRINGIFY_VAL(MSC_PAGING_RESPONSE_TIMER_DEFAULT) " seconds)\n"
441 "Set paging timeout in seconds\n")
442{
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100443 if (!strcmp(argv[1], "default"))
444 gsmnet->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
445 else
446 gsmnet->paging_response_timer = atoi(argv[0]);
447 return CMD_SUCCESS;
448}
449
Harald Welte69c54a82018-02-09 20:41:14 +0100450DEFUN(cfg_msc_emergency_msisdn, cfg_msc_emergency_msisdn_cmd,
451 "emergency-call route-to-msisdn MSISDN",
452 "Configure Emergency Call Behaviour\n"
453 "MSISDN to which Emergency Calls are Dispatched\n"
454 "MSISDN (E.164 Phone Number)\n")
455{
Harald Welte69c54a82018-02-09 20:41:14 +0100456 osmo_talloc_replace_string(gsmnet, &gsmnet->emergency.route_to_msisdn, argv[0]);
457
458 return CMD_SUCCESS;
459}
460
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200461static int config_write_msc(struct vty *vty)
462{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200463 vty_out(vty, "msc%s", VTY_NEWLINE);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100464 if (gsmnet->mncc_sock_path)
465 vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE);
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100466 vty_out(vty, " mncc guard-timeout %i%s",
Philipp Maier9ca7b312018-10-10 17:00:49 +0200467 gsmnet->mncc_guard_timeout, VTY_NEWLINE);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200468 vty_out(vty, " %sassign-tmsi%s",
469 gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
470
Philipp Maierfbf66102017-04-09 12:32:51 +0200471 vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
472 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100473#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200474 vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance,
475 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100476#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200477
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100478 if (gsmnet->vlr->cfg.auth_tuple_max_reuse_count)
479 vty_out(vty, " auth-tuple-max-reuse-count %d%s",
480 OSMO_MAX(-1, gsmnet->vlr->cfg.auth_tuple_max_reuse_count),
481 VTY_NEWLINE);
482 if (gsmnet->vlr->cfg.auth_reuse_old_sets_on_error)
483 vty_out(vty, " auth-tuple-reuse-on-error 1%s",
484 VTY_NEWLINE);
485
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100486 if (gsmnet->paging_response_timer != MSC_PAGING_RESPONSE_TIMER_DEFAULT)
487 vty_out(vty, " paging response-timer %u%s", gsmnet->paging_response_timer, VTY_NEWLINE);
488
Harald Welte69c54a82018-02-09 20:41:14 +0100489 if (gsmnet->emergency.route_to_msisdn) {
490 vty_out(vty, " emergency-call route-to-msisdn %s%s",
491 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
492 }
493
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +0200494 mgcp_client_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200495#ifdef BUILD_IU
Neels Hofmeyr00e82d62017-07-05 15:19:52 +0200496 ranap_iu_vty_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200497#endif
498
499 return CMD_SUCCESS;
500}
501
Maxc51609a2018-11-09 17:13:00 +0100502DEFUN(show_bsc, show_bsc_cmd,
503 "show bsc", SHOW_STR "BSC\n")
504{
505 struct bsc_context *bsc_ctx;
506 struct osmo_ss7_instance *ss7 = osmo_ss7_instance_find(gsmnet->a.cs7_instance);
507
508 llist_for_each_entry(bsc_ctx, &gsmnet->a.bscs, list) {
509 vty_out(vty, "BSC %s%s", osmo_sccp_addr_name(ss7, &bsc_ctx->bsc_addr), VTY_NEWLINE);
510 }
511
512 return CMD_SUCCESS;
513}
514
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100515static void vty_conn_hdr(struct vty *vty)
516{
517 vty_out(vty, "--ConnId ------------Subscriber RAN --LAC Use --Tokens C A5 State%s",
518 VTY_NEWLINE);
519}
520
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100521static void vty_dump_one_conn(struct vty *vty, const struct ran_conn *conn)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100522{
523 vty_out(vty, "%08x %22s %3s %5u %3u %08x %c /%1u %27s %s",
524 conn->a.conn_id,
525 conn->vsub ? vlr_subscr_name(conn->vsub) : "-",
526 conn->via_ran == RAN_UTRAN_IU ? "Iu" : "A",
527 conn->lac,
528 conn->use_count,
529 conn->use_tokens,
530 conn->received_cm_service_request ? 'C' : '-',
Neels Hofmeyrf41658d2018-11-30 04:35:50 +0100531 conn->geran_encr.alg_id,
Neels Hofmeyr4d3a66b2018-03-31 18:45:59 +0200532 conn->fi ? osmo_fsm_inst_state_name(conn->fi) : "-",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100533 VTY_NEWLINE);
534}
535
536DEFUN(show_msc_conn, show_msc_conn_cmd,
537 "show connection", SHOW_STR "Subscriber Connections\n")
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200538{
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100539 struct ran_conn *conn;
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200540
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100541 vty_conn_hdr(vty);
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100542 llist_for_each_entry(conn, &gsmnet->ran_conns, entry)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100543 vty_dump_one_conn(vty, conn);
544
545 return CMD_SUCCESS;
546}
547
548static void vty_trans_hdr(struct vty *vty)
549{
550 vty_out(vty, "------------Subscriber --ConnId -P TI -CallRef Proto%s",
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200551 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100552}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200553
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100554static const char *get_trans_proto_str(const struct gsm_trans *trans)
555{
556 static char buf[256];
557
558 switch (trans->protocol) {
559 case GSM48_PDISC_CC:
560 snprintf(buf, sizeof(buf), "%s %4u %4u",
561 gsm48_cc_state_name(trans->cc.state),
562 trans->cc.Tcurrent,
563 trans->cc.T308_second);
564 break;
565 case GSM48_PDISC_SMS:
566 snprintf(buf, sizeof(buf), "%s %s",
567 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
568 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
569 break;
570 default:
571 buf[0] = '\0';
572 break;
573 }
574
575 return buf;
576}
577
578static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
579{
580 vty_out(vty, "%22s %08x %s %02u %08x %s%s",
581 trans->vsub ? vlr_subscr_name(trans->vsub) : "-",
582 trans->conn ? trans->conn->a.conn_id : 0,
583 gsm48_pdisc_name(trans->protocol),
584 trans->transaction_id,
585 trans->callref,
586 get_trans_proto_str(trans), VTY_NEWLINE);
587}
588
589DEFUN(show_msc_transaction, show_msc_transaction_cmd,
590 "show transaction", SHOW_STR "Transactions\n")
591{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100592 struct gsm_trans *trans;
593
594 vty_trans_hdr(vty);
595 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
596 vty_dump_one_trans(vty, trans);
597
598 return CMD_SUCCESS;
599}
600
601static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
602{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100603 struct gsm_trans *trans;
604 int reqs;
605 struct llist_head *entry;
606
607 if (strlen(vsub->name))
608 vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
609 if (strlen(vsub->msisdn))
610 vty_out(vty, " Extension: %s%s", vsub->msisdn,
611 VTY_NEWLINE);
612 vty_out(vty, " LAC: %d/0x%x%s",
613 vsub->lac, vsub->lac, VTY_NEWLINE);
614 vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
615 if (vsub->tmsi != GSM_RESERVED_TMSI)
616 vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
617 VTY_NEWLINE);
618 if (vsub->tmsi_new != GSM_RESERVED_TMSI)
619 vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
620 VTY_NEWLINE);
621
622#if 0
623 /* TODO: add this to vlr_subscr? */
624 if (vsub->auth_info.auth_algo != AUTH_ALGO_NONE) {
625 struct gsm_auth_info *i = &vsub->auth_info;
626 vty_out(vty, " A3A8 algorithm id: %d%s",
627 i->auth_algo, VTY_NEWLINE);
628 vty_out(vty, " A3A8 Ki: %s%s",
629 osmo_hexdump(i->a3a8_ki, i->a3a8_ki_len),
630 VTY_NEWLINE);
631 }
632#endif
633
634 if (vsub->last_tuple) {
Neels Hofmeyr8b6e5362018-11-30 02:57:33 +0100635 struct vlr_auth_tuple *t = vsub->last_tuple;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100636 vty_out(vty, " A3A8 last tuple (used %d times):%s",
637 t->use_count, VTY_NEWLINE);
638 vty_out(vty, " seq # : %d%s",
639 t->key_seq, VTY_NEWLINE);
640 vty_out(vty, " RAND : %s%s",
641 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
642 VTY_NEWLINE);
643 vty_out(vty, " SRES : %s%s",
644 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
645 VTY_NEWLINE);
646 vty_out(vty, " Kc : %s%s",
647 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
648 VTY_NEWLINE);
649 }
650
651 reqs = 0;
652 llist_for_each(entry, &vsub->cs.requests)
653 reqs += 1;
654 vty_out(vty, " Paging: %s paging for %d requests%s",
655 vsub->cs.is_paging ? "is" : "not", reqs, VTY_NEWLINE);
656 vty_out(vty, " Use count: %u%s", vsub->use_count, VTY_NEWLINE);
657
658 /* Connection */
659 if (vsub->msc_conn_ref) {
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100660 struct ran_conn *conn = vsub->msc_conn_ref;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100661 vty_conn_hdr(vty);
662 vty_dump_one_conn(vty, conn);
663 }
664
665 /* Transactions */
666 vty_trans_hdr(vty);
667 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
668 if (trans->vsub != vsub)
669 continue;
670 vty_dump_one_trans(vty, trans);
671 }
672}
673
674/* Subscriber */
675DEFUN(show_subscr_cache,
676 show_subscr_cache_cmd,
677 "show subscriber cache",
678 SHOW_STR "Show information about subscribers\n"
679 "Display contents of subscriber cache\n")
680{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100681 struct vlr_subscr *vsub;
682 int count = 0;
683
684 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
685 if (++count > 100) {
686 vty_out(vty, "%% More than %d subscribers in cache,"
687 " stopping here.%s", count-1, VTY_NEWLINE);
688 break;
689 }
690 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
691 subscr_dump_full_vty(vty, vsub);
Harald Welte69c54a82018-02-09 20:41:14 +0100692 }
693
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200694 return CMD_SUCCESS;
695}
696
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100697DEFUN(sms_send_pend,
698 sms_send_pend_cmd,
699 "sms send pending",
700 "SMS related commands\n" "SMS Sending related commands\n"
701 "Send all pending SMS")
702{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100703 struct gsm_sms *sms;
704 unsigned long long sms_id = 0;
705
706 while (1) {
707 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
708 if (!sms)
709 break;
710
711 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700712 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100713
714 sms_id = sms->id + 1;
715 }
716
717 return CMD_SUCCESS;
718}
719
720DEFUN(sms_delete_expired,
721 sms_delete_expired_cmd,
722 "sms delete expired",
723 "SMS related commands\n" "SMS Database related commands\n"
724 "Delete all expired SMS")
725{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100726 struct gsm_sms *sms;
727 unsigned long long sms_id = 0;
728 long long num_deleted = 0;
729
730 while (1) {
731 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
732 if (!sms)
733 break;
734
735 /* Skip SMS which are currently queued for sending. */
736 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
737 continue;
738
739 /* Expiration check is performed by the DB layer. */
740 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
741 num_deleted++;
742
743 sms_id = sms->id + 1;
744 }
745
746 if (num_deleted == 0) {
747 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
748 return CMD_WARNING;
749 }
750
751 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
752 return CMD_SUCCESS;
753}
754
755static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +0200756 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100757 char *str, uint8_t tp_pid)
758{
759 struct gsm_network *net = receiver->vlr->user_ctx;
760 struct gsm_sms *sms;
761
Harald Welte39b55482018-04-09 19:19:33 +0200762 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100763 sms->protocol_id = tp_pid;
764
765 /* store in database for the queue */
766 if (db_sms_store(sms) != 0) {
767 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
768 sms_free(sms);
769 return CMD_WARNING;
770 }
771 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
772
773 sms_free(sms);
774 sms_queue_trigger(net->sms_queue);
775 return CMD_SUCCESS;
776}
777
778static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
779 const char *type,
780 const char *id)
781{
782 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
783 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id);
784 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
785 return vlr_subscr_find_by_imsi(gsmnet->vlr, id);
786 else if (!strcmp(type, "tmsi"))
787 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id));
788
789 return NULL;
790}
791#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
792#define SUBSCR_HELP "Operations on a Subscriber\n" \
793 "Identify subscriber by MSISDN (phone number)\n" \
794 "Legacy alias for 'msisdn'\n" \
795 "Identify subscriber by IMSI\n" \
796 "Identify subscriber by TMSI\n" \
797 "Identify subscriber by database ID\n" \
798 "Identifier for the subscriber\n"
799
800DEFUN(show_subscr,
801 show_subscr_cmd,
802 "show subscriber " SUBSCR_TYPES " ID",
803 SHOW_STR SUBSCR_HELP)
804{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100805 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
806 argv[1]);
807
808 if (!vsub) {
809 vty_out(vty, "%% No subscriber found for %s %s%s",
810 argv[0], argv[1], VTY_NEWLINE);
811 return CMD_WARNING;
812 }
813
814 subscr_dump_full_vty(vty, vsub);
815
816 vlr_subscr_put(vsub);
817
818 return CMD_SUCCESS;
819}
820
821DEFUN(subscriber_create,
822 subscriber_create_cmd,
823 "subscriber create imsi ID",
824 "Operations on a Subscriber\n" \
825 "Create new subscriber\n" \
826 "Identify the subscriber by his IMSI\n" \
827 "Identifier for the subscriber\n")
828{
829 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
830 VTY_NEWLINE);
831 return CMD_WARNING;
832}
833
834DEFUN(subscriber_send_pending_sms,
835 subscriber_send_pending_sms_cmd,
836 "subscriber " SUBSCR_TYPES " ID sms pending-send",
837 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
838{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100839 struct vlr_subscr *vsub;
840 struct gsm_sms *sms;
841
842 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
843 if (!vsub) {
844 vty_out(vty, "%% No subscriber found for %s %s%s",
845 argv[0], argv[1], VTY_NEWLINE);
846 return CMD_WARNING;
847 }
848
849 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
850 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700851 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100852
853 vlr_subscr_put(vsub);
854
855 return CMD_SUCCESS;
856}
857
858DEFUN(subscriber_send_sms,
859 subscriber_send_sms_cmd,
860 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
861 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
862{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100863 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200864 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100865 char *str;
866 int rc;
867
868 if (!vsub) {
869 vty_out(vty, "%% No subscriber found for %s %s%s",
870 argv[0], argv[1], VTY_NEWLINE);
871 rc = CMD_WARNING;
872 goto err;
873 }
874
Harald Welte39b55482018-04-09 19:19:33 +0200875 if (!strcmp(argv[2], "msisdn"))
876 sender_msisdn = argv[3];
877 else {
878 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
879 if (!sender) {
880 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
881 rc = CMD_WARNING;
882 goto err;
883 }
884 sender_msisdn = sender->msisdn;
885 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100886 }
887
888 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +0200889 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100890 talloc_free(str);
891
892err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100893 if (vsub)
894 vlr_subscr_put(vsub);
895
896 return rc;
897}
898
899DEFUN(subscriber_silent_sms,
900 subscriber_silent_sms_cmd,
901
902 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
903 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
904{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100905 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200906 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100907 char *str;
908 int rc;
909
910 if (!vsub) {
911 vty_out(vty, "%% No subscriber found for %s %s%s",
912 argv[0], argv[1], VTY_NEWLINE);
913 rc = CMD_WARNING;
914 goto err;
915 }
916
Harald Welte39b55482018-04-09 19:19:33 +0200917 if (!strcmp(argv[2], "msisdn")) {
918 sender_msisdn = argv[3];
919 } else {
920 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
921 if (!sender) {
922 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
923 rc = CMD_WARNING;
924 goto err;
925 }
926 sender_msisdn = sender->msisdn;
927 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100928 }
929
930 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +0200931 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100932 talloc_free(str);
933
934err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100935 if (vsub)
936 vlr_subscr_put(vsub);
937
938 return rc;
939}
940
941#define CHAN_TYPES "(any|tch/f|tch/any|sdcch)"
942#define CHAN_TYPE_HELP \
943 "Any channel\n" \
944 "TCH/F channel\n" \
945 "Any TCH channel\n" \
946 "SDCCH channel\n"
947
948DEFUN(subscriber_silent_call_start,
949 subscriber_silent_call_start_cmd,
950 "subscriber " SUBSCR_TYPES " ID silent-call start (any|tch/f|tch/any|sdcch)",
951 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
952 CHAN_TYPE_HELP)
953{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100954 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
955 int rc, type;
956
957 if (!vsub) {
958 vty_out(vty, "%% No subscriber found for %s %s%s",
959 argv[0], argv[1], VTY_NEWLINE);
960 return CMD_WARNING;
961 }
962
963 if (!strcmp(argv[2], "tch/f"))
964 type = RSL_CHANNEED_TCH_F;
965 else if (!strcmp(argv[2], "tch/any"))
966 type = RSL_CHANNEED_TCH_ForH;
967 else if (!strcmp(argv[2], "sdcch"))
968 type = RSL_CHANNEED_SDCCH;
969 else
970 type = RSL_CHANNEED_ANY; /* Defaults to ANY */
971
972 rc = gsm_silent_call_start(vsub, vty, type);
973 switch (rc) {
974 case -ENODEV:
975 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
976 break;
977 default:
978 if (rc)
979 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
980 else
981 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
982 break;
983 }
984
985 vlr_subscr_put(vsub);
986 return rc ? CMD_WARNING : CMD_SUCCESS;
987}
988
989DEFUN(subscriber_silent_call_stop,
990 subscriber_silent_call_stop_cmd,
991 "subscriber " SUBSCR_TYPES " ID silent-call stop",
992 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
993 CHAN_TYPE_HELP)
994{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100995 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
996 int rc;
997
998 if (!vsub) {
999 vty_out(vty, "%% No subscriber found for %s %s%s",
1000 argv[0], argv[1], VTY_NEWLINE);
1001 return CMD_WARNING;
1002 }
1003
1004 rc = gsm_silent_call_stop(vsub);
1005 switch (rc) {
1006 case -ENODEV:
1007 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
1008 break;
1009 case -ENOENT:
1010 vty_out(vty, "%% Subscriber has no silent call active%s",
1011 VTY_NEWLINE);
1012 break;
1013 default:
1014 if (rc)
1015 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
1016 else
1017 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
1018 break;
1019 }
1020
1021 vlr_subscr_put(vsub);
1022 return rc ? CMD_WARNING : CMD_SUCCESS;
1023}
1024
1025DEFUN(subscriber_ussd_notify,
1026 subscriber_ussd_notify_cmd,
1027 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1028 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1029 "Alerting Level 0\n"
1030 "Alerting Level 1\n"
1031 "Alerting Level 2\n"
1032 "Text of USSD message to send\n")
1033{
1034 char *text;
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001035 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001036 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1037 int level;
1038
1039 if (!vsub) {
1040 vty_out(vty, "%% No subscriber found for %s %s%s",
1041 argv[0], argv[1], VTY_NEWLINE);
1042 return CMD_WARNING;
1043 }
1044
1045 level = atoi(argv[2]);
1046 text = argv_concat(argv, argc, 3);
1047 if (!text) {
1048 vlr_subscr_put(vsub);
1049 return CMD_WARNING;
1050 }
1051
1052 conn = connection_for_subscr(vsub);
1053 if (!conn) {
1054 vty_out(vty, "%% An active connection is required for %s %s%s",
1055 argv[0], argv[1], VTY_NEWLINE);
1056 vlr_subscr_put(vsub);
1057 talloc_free(text);
1058 return CMD_WARNING;
1059 }
1060
1061 msc_send_ussd_notify(conn, level, text);
1062 msc_send_ussd_release_complete(conn);
1063
1064 vlr_subscr_put(vsub);
1065 talloc_free(text);
1066 return CMD_SUCCESS;
1067}
1068
1069DEFUN(subscriber_paging,
1070 subscriber_paging_cmd,
1071 "subscriber " SUBSCR_TYPES " ID paging",
1072 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1073{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001074 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1075 struct subscr_request *req;
1076
1077 if (!vsub) {
1078 vty_out(vty, "%% No subscriber found for %s %s%s",
1079 argv[0], argv[1], VTY_NEWLINE);
1080 return CMD_WARNING;
1081 }
1082
1083 req = subscr_request_conn(vsub, NULL, NULL, "manual Paging from VTY");
1084 if (req)
1085 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1086 else
1087 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1088
1089 vlr_subscr_put(vsub);
1090 return req ? CMD_SUCCESS : CMD_WARNING;
1091}
1092
1093static int loop_by_char(uint8_t ch)
1094{
1095 switch (ch) {
1096 case 'a':
1097 return GSM414_LOOP_A;
1098 case 'b':
1099 return GSM414_LOOP_B;
1100 case 'c':
1101 return GSM414_LOOP_C;
1102 case 'd':
1103 return GSM414_LOOP_D;
1104 case 'e':
1105 return GSM414_LOOP_E;
1106 case 'f':
1107 return GSM414_LOOP_F;
1108 case 'i':
1109 return GSM414_LOOP_I;
1110 }
1111 return -1;
1112}
1113
1114DEFUN(subscriber_mstest_close,
1115 subscriber_mstest_close_cmd,
1116 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1117 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1118 "Close a TCH Loop inside the MS\n"
1119 "Loop Type A\n"
1120 "Loop Type B\n"
1121 "Loop Type C\n"
1122 "Loop Type D\n"
1123 "Loop Type E\n"
1124 "Loop Type F\n"
1125 "Loop Type I\n")
1126{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001127 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001128 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1129 const char *loop_str;
1130 int loop_mode;
1131
1132 if (!vsub) {
1133 vty_out(vty, "%% No subscriber found for %s %s%s",
1134 argv[0], argv[1], VTY_NEWLINE);
1135 return CMD_WARNING;
1136 }
1137
1138 loop_str = argv[2];
1139 loop_mode = loop_by_char(loop_str[0]);
1140
1141 conn = connection_for_subscr(vsub);
1142 if (!conn) {
1143 vty_out(vty, "%% An active connection is required for %s %s%s",
1144 argv[0], argv[1], VTY_NEWLINE);
1145 vlr_subscr_put(vsub);
1146 return CMD_WARNING;
1147 }
1148
1149 gsm0414_tx_close_tch_loop_cmd(conn, loop_mode);
1150
1151 return CMD_SUCCESS;
1152}
1153
1154DEFUN(subscriber_mstest_open,
1155 subscriber_mstest_open_cmd,
1156 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1157 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1158 "Open a TCH Loop inside the MS\n")
1159{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001160 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001161 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1162
1163 if (!vsub) {
1164 vty_out(vty, "%% No subscriber found for %s %s%s",
1165 argv[0], argv[1], VTY_NEWLINE);
1166 return CMD_WARNING;
1167 }
1168
1169 conn = connection_for_subscr(vsub);
1170 if (!conn) {
1171 vty_out(vty, "%% An active connection is required for %s %s%s",
1172 argv[0], argv[1], VTY_NEWLINE);
1173 vlr_subscr_put(vsub);
1174 return CMD_WARNING;
1175 }
1176
1177 gsm0414_tx_open_loop_cmd(conn);
1178
1179 return CMD_SUCCESS;
1180}
1181
1182DEFUN(ena_subscr_expire,
1183 ena_subscr_expire_cmd,
1184 "subscriber " SUBSCR_TYPES " ID expire",
1185 SUBSCR_HELP "Expire the subscriber Now\n")
1186{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001187 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1188 argv[1]);
1189
1190 if (!vsub) {
1191 vty_out(vty, "%% No subscriber found for %s %s%s",
1192 argv[0], argv[1], VTY_NEWLINE);
1193 return CMD_WARNING;
1194 }
1195
1196 if (vlr_subscr_expire(vsub))
1197 vty_out(vty, "%% VLR released subscriber %s%s",
1198 vlr_subscr_name(vsub), VTY_NEWLINE);
1199
1200 if (vsub->use_count > 1)
1201 vty_out(vty, "%% Subscriber %s is still in use,"
1202 " should be released soon%s",
1203 vlr_subscr_name(vsub), VTY_NEWLINE);
1204
1205 vlr_subscr_put(vsub);
1206 return CMD_SUCCESS;
1207}
1208
1209static int scall_cbfn(unsigned int subsys, unsigned int signal,
1210 void *handler_data, void *signal_data)
1211{
1212 struct scall_signal_data *sigdata = signal_data;
1213 struct vty *vty = sigdata->data;
1214
1215 switch (signal) {
1216 case S_SCALL_SUCCESS:
1217 vty_out(vty, "%% silent call success%s", VTY_NEWLINE);
1218 break;
1219 case S_SCALL_EXPIRED:
1220 vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE);
1221 break;
1222 }
1223 return 0;
1224}
1225
1226DEFUN(show_stats,
1227 show_stats_cmd,
1228 "show statistics",
1229 SHOW_STR "Display network statistics\n")
1230{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001231 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001232 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1233 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1234 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001235 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001236 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001237 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001238 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001239 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001240 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1241 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001242 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001243 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001244 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1245 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001246 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001247 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001248 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1249 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1250 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001251 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001252 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001253 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1254 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001255 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001256 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001257 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1258 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001259 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001260 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001261 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1262 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1263 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1264 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1265 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001266 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001267 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1268 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1269 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1270 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1271 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001272 return CMD_SUCCESS;
1273}
1274
1275DEFUN(show_smsqueue,
1276 show_smsqueue_cmd,
1277 "show sms-queue",
1278 SHOW_STR "Display SMSqueue statistics\n")
1279{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001280 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001281 return CMD_SUCCESS;
1282}
1283
1284DEFUN(smsqueue_trigger,
1285 smsqueue_trigger_cmd,
1286 "sms-queue trigger",
1287 "SMS Queue\n" "Trigger sending messages\n")
1288{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001289 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001290 return CMD_SUCCESS;
1291}
1292
1293DEFUN(smsqueue_max,
1294 smsqueue_max_cmd,
1295 "sms-queue max-pending <1-500>",
1296 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1297{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001298 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001299 return CMD_SUCCESS;
1300}
1301
1302DEFUN(smsqueue_clear,
1303 smsqueue_clear_cmd,
1304 "sms-queue clear",
1305 "SMS Queue\n" "Clear the queue of pending SMS\n")
1306{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001307 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001308 return CMD_SUCCESS;
1309}
1310
1311DEFUN(smsqueue_fail,
1312 smsqueue_fail_cmd,
1313 "sms-queue max-failure <1-500>",
1314 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1315{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001316 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001317 return CMD_SUCCESS;
1318}
1319
1320
1321DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1322 "mncc-int", "Configure internal MNCC handler")
1323{
1324 vty->node = MNCC_INT_NODE;
1325
1326 return CMD_SUCCESS;
1327}
1328
1329static struct cmd_node mncc_int_node = {
1330 MNCC_INT_NODE,
1331 "%s(config-mncc-int)# ",
1332 1,
1333};
1334
1335static const struct value_string tchf_codec_names[] = {
1336 { GSM48_CMODE_SPEECH_V1, "fr" },
1337 { GSM48_CMODE_SPEECH_EFR, "efr" },
1338 { GSM48_CMODE_SPEECH_AMR, "amr" },
1339 { 0, NULL }
1340};
1341
1342static const struct value_string tchh_codec_names[] = {
1343 { GSM48_CMODE_SPEECH_V1, "hr" },
1344 { GSM48_CMODE_SPEECH_AMR, "amr" },
1345 { 0, NULL }
1346};
1347
1348static int config_write_mncc_int(struct vty *vty)
1349{
1350 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1351 vty_out(vty, " default-codec tch-f %s%s",
1352 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1353 VTY_NEWLINE);
1354 vty_out(vty, " default-codec tch-h %s%s",
1355 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1356 VTY_NEWLINE);
1357
1358 return CMD_SUCCESS;
1359}
1360
1361DEFUN(mnccint_def_codec_f,
1362 mnccint_def_codec_f_cmd,
1363 "default-codec tch-f (fr|efr|amr)",
1364 "Set default codec\n" "Codec for TCH/F\n"
1365 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1366{
1367 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1368
1369 return CMD_SUCCESS;
1370}
1371
1372DEFUN(mnccint_def_codec_h,
1373 mnccint_def_codec_h_cmd,
1374 "default-codec tch-h (hr|amr)",
1375 "Set default codec\n" "Codec for TCH/H\n"
1376 "Half-Rate\n" "Adaptive Multi-Rate\n")
1377{
1378 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1379
1380 return CMD_SUCCESS;
1381}
1382
1383
1384DEFUN(logging_fltr_imsi,
1385 logging_fltr_imsi_cmd,
1386 "logging filter imsi IMSI",
1387 LOGGING_STR FILTER_STR
1388 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1389{
1390 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001391 struct log_target *tgt = osmo_log_vty2tgt(vty);
1392 const char *imsi = argv[0];
1393
1394 if (!tgt)
1395 return CMD_WARNING;
1396
1397 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi);
1398
1399 if (!vlr_subscr) {
1400 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1401 argv[0], VTY_NEWLINE);
1402 return CMD_WARNING;
1403 }
1404
1405 log_set_filter_vlr_subscr(tgt, vlr_subscr);
1406 return CMD_SUCCESS;
1407}
1408
1409static struct cmd_node hlr_node = {
1410 HLR_NODE,
1411 "%s(config-hlr)# ",
1412 1,
1413};
1414
1415DEFUN(cfg_hlr, cfg_hlr_cmd,
1416 "hlr", "Configure connection to the HLR")
1417{
1418 vty->node = HLR_NODE;
1419 return CMD_SUCCESS;
1420}
1421
1422DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1423 "Remote GSUP address of the HLR\n"
1424 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1425{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001426 talloc_free((void*)gsmnet->gsup_server_addr_str);
1427 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1428 return CMD_SUCCESS;
1429}
1430
1431DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1432 "Remote GSUP port of the HLR\n"
1433 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1434{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001435 gsmnet->gsup_server_port = atoi(argv[0]);
1436 return CMD_SUCCESS;
1437}
1438
1439static int config_write_hlr(struct vty *vty)
1440{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001441 vty_out(vty, "hlr%s", VTY_NEWLINE);
1442 vty_out(vty, " remote-ip %s%s",
1443 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1444 vty_out(vty, " remote-port %u%s",
1445 gsmnet->gsup_server_port, VTY_NEWLINE);
1446 return CMD_SUCCESS;
1447}
1448
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001449void msc_vty_init(struct gsm_network *msc_network)
1450{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001451 OSMO_ASSERT(gsmnet == NULL);
1452 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001453
1454 osmo_stats_vty_add_cmds();
1455
1456 install_element(CONFIG_NODE, &cfg_net_cmd);
1457 install_node(&net_node, config_write_net);
1458 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
1459 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1460 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1461 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
1462 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
1463 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
1464 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
1465 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
1466 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
1467 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
1468 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
1469 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
1470 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001471
1472 install_element(CONFIG_NODE, &cfg_msc_cmd);
1473 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001474 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01001475 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
1476 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02001477 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01001478 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001479 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01001480 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
1481 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001482 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
1483 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01001484 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01001485 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001486
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02001487 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001488#ifdef BUILD_IU
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +01001489 ranap_iu_vty_init(MSC_NODE, &msc_network->iu.rab_assign_addr_enc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001490#endif
Stefan Sperling617ac802018-02-22 17:58:20 +01001491 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001492
1493 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
1494
1495 install_element_ve(&show_subscr_cmd);
1496 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01001497 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001498 install_element_ve(&show_msc_conn_cmd);
1499 install_element_ve(&show_msc_transaction_cmd);
1500
1501 install_element_ve(&sms_send_pend_cmd);
1502 install_element_ve(&sms_delete_expired_cmd);
1503
1504 install_element_ve(&subscriber_create_cmd);
1505 install_element_ve(&subscriber_send_sms_cmd);
1506 install_element_ve(&subscriber_silent_sms_cmd);
1507 install_element_ve(&subscriber_silent_call_start_cmd);
1508 install_element_ve(&subscriber_silent_call_stop_cmd);
1509 install_element_ve(&subscriber_ussd_notify_cmd);
1510 install_element_ve(&subscriber_mstest_close_cmd);
1511 install_element_ve(&subscriber_mstest_open_cmd);
1512 install_element_ve(&subscriber_paging_cmd);
1513 install_element_ve(&show_stats_cmd);
1514 install_element_ve(&show_smsqueue_cmd);
1515 install_element_ve(&logging_fltr_imsi_cmd);
1516
1517 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
1518 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
1519 install_element(ENABLE_NODE, &smsqueue_max_cmd);
1520 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
1521 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
1522 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
1523
1524 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1525 install_node(&mncc_int_node, config_write_mncc_int);
1526 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1527 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1528
1529 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
1530
1531 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1532 install_node(&hlr_node, config_write_hlr);
1533 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1534 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001535}