blob: d9e57a73be6ec41e57c0b587d40900176307ea9f [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
Philipp Maier9ca7b312018-10-10 17:00:49 +0200342DEFUN(cfg_msc_mncc_guard_timeout,
343 cfg_msc_mncc_guard_timeout_cmd,
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100344 "mncc guard-timeout <0-255>",
345 MNCC_STR
346 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR)
Philipp Maier9ca7b312018-10-10 17:00:49 +0200347{
348 gsmnet->mncc_guard_timeout = atoi(argv[0]);
349 return CMD_SUCCESS;
350}
351
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100352ALIAS_DEPRECATED(cfg_msc_mncc_guard_timeout,
353 cfg_msc_deprecated_mncc_guard_timeout_cmd,
354 "mncc-guard-timeout <0-255>",
355 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR);
356
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200357DEFUN(cfg_msc_assign_tmsi, cfg_msc_assign_tmsi_cmd,
358 "assign-tmsi",
359 "Assign TMSI during Location Updating.\n")
360{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200361 gsmnet->vlr->cfg.assign_tmsi = true;
362 return CMD_SUCCESS;
363}
364
365DEFUN(cfg_msc_no_assign_tmsi, cfg_msc_no_assign_tmsi_cmd,
366 "no assign-tmsi",
367 NO_STR "Assign TMSI during Location Updating.\n")
368{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200369 gsmnet->vlr->cfg.assign_tmsi = false;
370 return CMD_SUCCESS;
371}
372
Philipp Maierfbf66102017-04-09 12:32:51 +0200373DEFUN(cfg_msc_cs7_instance_a,
374 cfg_msc_cs7_instance_a_cmd,
375 "cs7-instance-a <0-15>",
376 "Set SS7 to be used by the A-Interface.\n" "SS7 instance reference number\n")
377{
Philipp Maierfbf66102017-04-09 12:32:51 +0200378 gsmnet->a.cs7_instance = atoi(argv[0]);
379 return CMD_SUCCESS;
380}
381
382DEFUN(cfg_msc_cs7_instance_iu,
383 cfg_msc_cs7_instance_iu_cmd,
384 "cs7-instance-iu <0-15>",
385 "Set SS7 to be used by the Iu-Interface.\n" "SS7 instance reference number\n")
386{
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100387#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200388 gsmnet->iu.cs7_instance = atoi(argv[0]);
389 return CMD_SUCCESS;
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100390#else
391 vty_out(vty, "WARNING: 'cs7-instance-iu' without effect: built without Iu support%s",
392 VTY_NEWLINE);
393 return CMD_WARNING;
394#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200395}
396
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100397DEFUN(cfg_msc_auth_tuple_max_reuse_count, cfg_msc_auth_tuple_max_reuse_count_cmd,
398 "auth-tuple-max-reuse-count <-1-2147483647>",
399 "Configure authentication tuple re-use\n"
400 "0 to use each auth tuple at most once (default), >0 to limit re-use, -1 to re-use infinitely (vulnerable!).\n")
401{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100402 gsmnet->vlr->cfg.auth_tuple_max_reuse_count = atoi(argv[0]);
403 return CMD_SUCCESS;
404}
405
406DEFUN(cfg_msc_auth_tuple_reuse_on_error, cfg_msc_auth_tuple_reuse_on_error_cmd,
407 "auth-tuple-reuse-on-error (0|1)",
408 "Configure authentication tuple re-use when HLR is not responsive\n"
409 "0 = never re-use auth tuples beyond auth-tuple-max-reuse-count (default)\n"
410 "1 = if the HLR does not deliver new tuples, do re-use already available old ones.\n")
411{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100412 gsmnet->vlr->cfg.auth_reuse_old_sets_on_error = atoi(argv[0]) ? true : false;
413 return CMD_SUCCESS;
414}
415
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100416DEFUN(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd,
417 "paging response-timer (default|<1-65535>)",
418 "Configure Paging\n"
419 "Set Paging timeout, the minimum time to pass between (unsuccessful) Pagings sent towards"
420 " BSS or RNC\n"
421 "Set to default timeout (" OSMO_STRINGIFY_VAL(MSC_PAGING_RESPONSE_TIMER_DEFAULT) " seconds)\n"
422 "Set paging timeout in seconds\n")
423{
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100424 if (!strcmp(argv[1], "default"))
425 gsmnet->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
426 else
427 gsmnet->paging_response_timer = atoi(argv[0]);
428 return CMD_SUCCESS;
429}
430
Harald Welte69c54a82018-02-09 20:41:14 +0100431DEFUN(cfg_msc_emergency_msisdn, cfg_msc_emergency_msisdn_cmd,
432 "emergency-call route-to-msisdn MSISDN",
433 "Configure Emergency Call Behaviour\n"
434 "MSISDN to which Emergency Calls are Dispatched\n"
435 "MSISDN (E.164 Phone Number)\n")
436{
Harald Welte69c54a82018-02-09 20:41:14 +0100437 osmo_talloc_replace_string(gsmnet, &gsmnet->emergency.route_to_msisdn, argv[0]);
438
439 return CMD_SUCCESS;
440}
441
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200442static int config_write_msc(struct vty *vty)
443{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200444 vty_out(vty, "msc%s", VTY_NEWLINE);
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100445 vty_out(vty, " mncc guard-timeout %i%s",
Philipp Maier9ca7b312018-10-10 17:00:49 +0200446 gsmnet->mncc_guard_timeout, VTY_NEWLINE);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200447 vty_out(vty, " %sassign-tmsi%s",
448 gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
449
Philipp Maierfbf66102017-04-09 12:32:51 +0200450 vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
451 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100452#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200453 vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance,
454 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100455#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200456
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100457 if (gsmnet->vlr->cfg.auth_tuple_max_reuse_count)
458 vty_out(vty, " auth-tuple-max-reuse-count %d%s",
459 OSMO_MAX(-1, gsmnet->vlr->cfg.auth_tuple_max_reuse_count),
460 VTY_NEWLINE);
461 if (gsmnet->vlr->cfg.auth_reuse_old_sets_on_error)
462 vty_out(vty, " auth-tuple-reuse-on-error 1%s",
463 VTY_NEWLINE);
464
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100465 if (gsmnet->paging_response_timer != MSC_PAGING_RESPONSE_TIMER_DEFAULT)
466 vty_out(vty, " paging response-timer %u%s", gsmnet->paging_response_timer, VTY_NEWLINE);
467
Harald Welte69c54a82018-02-09 20:41:14 +0100468 if (gsmnet->emergency.route_to_msisdn) {
469 vty_out(vty, " emergency-call route-to-msisdn %s%s",
470 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
471 }
472
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +0200473 mgcp_client_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200474#ifdef BUILD_IU
Neels Hofmeyr00e82d62017-07-05 15:19:52 +0200475 ranap_iu_vty_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200476#endif
477
478 return CMD_SUCCESS;
479}
480
Maxc51609a2018-11-09 17:13:00 +0100481DEFUN(show_bsc, show_bsc_cmd,
482 "show bsc", SHOW_STR "BSC\n")
483{
484 struct bsc_context *bsc_ctx;
485 struct osmo_ss7_instance *ss7 = osmo_ss7_instance_find(gsmnet->a.cs7_instance);
486
487 llist_for_each_entry(bsc_ctx, &gsmnet->a.bscs, list) {
488 vty_out(vty, "BSC %s%s", osmo_sccp_addr_name(ss7, &bsc_ctx->bsc_addr), VTY_NEWLINE);
489 }
490
491 return CMD_SUCCESS;
492}
493
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100494static void vty_conn_hdr(struct vty *vty)
495{
496 vty_out(vty, "--ConnId ------------Subscriber RAN --LAC Use --Tokens C A5 State%s",
497 VTY_NEWLINE);
498}
499
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100500static void vty_dump_one_conn(struct vty *vty, const struct ran_conn *conn)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100501{
502 vty_out(vty, "%08x %22s %3s %5u %3u %08x %c /%1u %27s %s",
503 conn->a.conn_id,
504 conn->vsub ? vlr_subscr_name(conn->vsub) : "-",
505 conn->via_ran == RAN_UTRAN_IU ? "Iu" : "A",
506 conn->lac,
507 conn->use_count,
508 conn->use_tokens,
509 conn->received_cm_service_request ? 'C' : '-',
Neels Hofmeyrf41658d2018-11-30 04:35:50 +0100510 conn->geran_encr.alg_id,
Neels Hofmeyr4d3a66b2018-03-31 18:45:59 +0200511 conn->fi ? osmo_fsm_inst_state_name(conn->fi) : "-",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100512 VTY_NEWLINE);
513}
514
515DEFUN(show_msc_conn, show_msc_conn_cmd,
516 "show connection", SHOW_STR "Subscriber Connections\n")
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200517{
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100518 struct ran_conn *conn;
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200519
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100520 vty_conn_hdr(vty);
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100521 llist_for_each_entry(conn, &gsmnet->ran_conns, entry)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100522 vty_dump_one_conn(vty, conn);
523
524 return CMD_SUCCESS;
525}
526
527static void vty_trans_hdr(struct vty *vty)
528{
529 vty_out(vty, "------------Subscriber --ConnId -P TI -CallRef Proto%s",
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200530 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100531}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200532
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100533static const char *get_trans_proto_str(const struct gsm_trans *trans)
534{
535 static char buf[256];
536
537 switch (trans->protocol) {
538 case GSM48_PDISC_CC:
539 snprintf(buf, sizeof(buf), "%s %4u %4u",
540 gsm48_cc_state_name(trans->cc.state),
541 trans->cc.Tcurrent,
542 trans->cc.T308_second);
543 break;
544 case GSM48_PDISC_SMS:
545 snprintf(buf, sizeof(buf), "%s %s",
546 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
547 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
548 break;
549 default:
550 buf[0] = '\0';
551 break;
552 }
553
554 return buf;
555}
556
557static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
558{
559 vty_out(vty, "%22s %08x %s %02u %08x %s%s",
560 trans->vsub ? vlr_subscr_name(trans->vsub) : "-",
561 trans->conn ? trans->conn->a.conn_id : 0,
562 gsm48_pdisc_name(trans->protocol),
563 trans->transaction_id,
564 trans->callref,
565 get_trans_proto_str(trans), VTY_NEWLINE);
566}
567
568DEFUN(show_msc_transaction, show_msc_transaction_cmd,
569 "show transaction", SHOW_STR "Transactions\n")
570{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100571 struct gsm_trans *trans;
572
573 vty_trans_hdr(vty);
574 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
575 vty_dump_one_trans(vty, trans);
576
577 return CMD_SUCCESS;
578}
579
580static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
581{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100582 struct gsm_trans *trans;
583 int reqs;
584 struct llist_head *entry;
585
586 if (strlen(vsub->name))
587 vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
588 if (strlen(vsub->msisdn))
589 vty_out(vty, " Extension: %s%s", vsub->msisdn,
590 VTY_NEWLINE);
591 vty_out(vty, " LAC: %d/0x%x%s",
592 vsub->lac, vsub->lac, VTY_NEWLINE);
593 vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
594 if (vsub->tmsi != GSM_RESERVED_TMSI)
595 vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
596 VTY_NEWLINE);
597 if (vsub->tmsi_new != GSM_RESERVED_TMSI)
598 vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
599 VTY_NEWLINE);
600
601#if 0
602 /* TODO: add this to vlr_subscr? */
603 if (vsub->auth_info.auth_algo != AUTH_ALGO_NONE) {
604 struct gsm_auth_info *i = &vsub->auth_info;
605 vty_out(vty, " A3A8 algorithm id: %d%s",
606 i->auth_algo, VTY_NEWLINE);
607 vty_out(vty, " A3A8 Ki: %s%s",
608 osmo_hexdump(i->a3a8_ki, i->a3a8_ki_len),
609 VTY_NEWLINE);
610 }
611#endif
612
613 if (vsub->last_tuple) {
Neels Hofmeyr8b6e5362018-11-30 02:57:33 +0100614 struct vlr_auth_tuple *t = vsub->last_tuple;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100615 vty_out(vty, " A3A8 last tuple (used %d times):%s",
616 t->use_count, VTY_NEWLINE);
617 vty_out(vty, " seq # : %d%s",
618 t->key_seq, VTY_NEWLINE);
619 vty_out(vty, " RAND : %s%s",
620 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
621 VTY_NEWLINE);
622 vty_out(vty, " SRES : %s%s",
623 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
624 VTY_NEWLINE);
625 vty_out(vty, " Kc : %s%s",
626 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
627 VTY_NEWLINE);
628 }
629
630 reqs = 0;
631 llist_for_each(entry, &vsub->cs.requests)
632 reqs += 1;
633 vty_out(vty, " Paging: %s paging for %d requests%s",
634 vsub->cs.is_paging ? "is" : "not", reqs, VTY_NEWLINE);
635 vty_out(vty, " Use count: %u%s", vsub->use_count, VTY_NEWLINE);
636
637 /* Connection */
638 if (vsub->msc_conn_ref) {
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100639 struct ran_conn *conn = vsub->msc_conn_ref;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100640 vty_conn_hdr(vty);
641 vty_dump_one_conn(vty, conn);
642 }
643
644 /* Transactions */
645 vty_trans_hdr(vty);
646 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
647 if (trans->vsub != vsub)
648 continue;
649 vty_dump_one_trans(vty, trans);
650 }
651}
652
653/* Subscriber */
654DEFUN(show_subscr_cache,
655 show_subscr_cache_cmd,
656 "show subscriber cache",
657 SHOW_STR "Show information about subscribers\n"
658 "Display contents of subscriber cache\n")
659{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100660 struct vlr_subscr *vsub;
661 int count = 0;
662
663 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
664 if (++count > 100) {
665 vty_out(vty, "%% More than %d subscribers in cache,"
666 " stopping here.%s", count-1, VTY_NEWLINE);
667 break;
668 }
669 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
670 subscr_dump_full_vty(vty, vsub);
Harald Welte69c54a82018-02-09 20:41:14 +0100671 }
672
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200673 return CMD_SUCCESS;
674}
675
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100676DEFUN(sms_send_pend,
677 sms_send_pend_cmd,
678 "sms send pending",
679 "SMS related commands\n" "SMS Sending related commands\n"
680 "Send all pending SMS")
681{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100682 struct gsm_sms *sms;
683 unsigned long long sms_id = 0;
684
685 while (1) {
686 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
687 if (!sms)
688 break;
689
690 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700691 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100692
693 sms_id = sms->id + 1;
694 }
695
696 return CMD_SUCCESS;
697}
698
699DEFUN(sms_delete_expired,
700 sms_delete_expired_cmd,
701 "sms delete expired",
702 "SMS related commands\n" "SMS Database related commands\n"
703 "Delete all expired SMS")
704{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100705 struct gsm_sms *sms;
706 unsigned long long sms_id = 0;
707 long long num_deleted = 0;
708
709 while (1) {
710 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
711 if (!sms)
712 break;
713
714 /* Skip SMS which are currently queued for sending. */
715 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
716 continue;
717
718 /* Expiration check is performed by the DB layer. */
719 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
720 num_deleted++;
721
722 sms_id = sms->id + 1;
723 }
724
725 if (num_deleted == 0) {
726 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
727 return CMD_WARNING;
728 }
729
730 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
731 return CMD_SUCCESS;
732}
733
734static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +0200735 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100736 char *str, uint8_t tp_pid)
737{
738 struct gsm_network *net = receiver->vlr->user_ctx;
739 struct gsm_sms *sms;
740
Harald Welte39b55482018-04-09 19:19:33 +0200741 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100742 sms->protocol_id = tp_pid;
743
744 /* store in database for the queue */
745 if (db_sms_store(sms) != 0) {
746 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
747 sms_free(sms);
748 return CMD_WARNING;
749 }
750 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
751
752 sms_free(sms);
753 sms_queue_trigger(net->sms_queue);
754 return CMD_SUCCESS;
755}
756
757static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
758 const char *type,
759 const char *id)
760{
761 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
762 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id);
763 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
764 return vlr_subscr_find_by_imsi(gsmnet->vlr, id);
765 else if (!strcmp(type, "tmsi"))
766 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id));
767
768 return NULL;
769}
770#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
771#define SUBSCR_HELP "Operations on a Subscriber\n" \
772 "Identify subscriber by MSISDN (phone number)\n" \
773 "Legacy alias for 'msisdn'\n" \
774 "Identify subscriber by IMSI\n" \
775 "Identify subscriber by TMSI\n" \
776 "Identify subscriber by database ID\n" \
777 "Identifier for the subscriber\n"
778
779DEFUN(show_subscr,
780 show_subscr_cmd,
781 "show subscriber " SUBSCR_TYPES " ID",
782 SHOW_STR SUBSCR_HELP)
783{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100784 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
785 argv[1]);
786
787 if (!vsub) {
788 vty_out(vty, "%% No subscriber found for %s %s%s",
789 argv[0], argv[1], VTY_NEWLINE);
790 return CMD_WARNING;
791 }
792
793 subscr_dump_full_vty(vty, vsub);
794
795 vlr_subscr_put(vsub);
796
797 return CMD_SUCCESS;
798}
799
800DEFUN(subscriber_create,
801 subscriber_create_cmd,
802 "subscriber create imsi ID",
803 "Operations on a Subscriber\n" \
804 "Create new subscriber\n" \
805 "Identify the subscriber by his IMSI\n" \
806 "Identifier for the subscriber\n")
807{
808 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
809 VTY_NEWLINE);
810 return CMD_WARNING;
811}
812
813DEFUN(subscriber_send_pending_sms,
814 subscriber_send_pending_sms_cmd,
815 "subscriber " SUBSCR_TYPES " ID sms pending-send",
816 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
817{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100818 struct vlr_subscr *vsub;
819 struct gsm_sms *sms;
820
821 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
822 if (!vsub) {
823 vty_out(vty, "%% No subscriber found for %s %s%s",
824 argv[0], argv[1], VTY_NEWLINE);
825 return CMD_WARNING;
826 }
827
828 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
829 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700830 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100831
832 vlr_subscr_put(vsub);
833
834 return CMD_SUCCESS;
835}
836
837DEFUN(subscriber_send_sms,
838 subscriber_send_sms_cmd,
839 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
840 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
841{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100842 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200843 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100844 char *str;
845 int rc;
846
847 if (!vsub) {
848 vty_out(vty, "%% No subscriber found for %s %s%s",
849 argv[0], argv[1], VTY_NEWLINE);
850 rc = CMD_WARNING;
851 goto err;
852 }
853
Harald Welte39b55482018-04-09 19:19:33 +0200854 if (!strcmp(argv[2], "msisdn"))
855 sender_msisdn = argv[3];
856 else {
857 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
858 if (!sender) {
859 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
860 rc = CMD_WARNING;
861 goto err;
862 }
863 sender_msisdn = sender->msisdn;
864 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100865 }
866
867 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +0200868 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100869 talloc_free(str);
870
871err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100872 if (vsub)
873 vlr_subscr_put(vsub);
874
875 return rc;
876}
877
878DEFUN(subscriber_silent_sms,
879 subscriber_silent_sms_cmd,
880
881 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
882 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
883{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100884 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200885 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100886 char *str;
887 int rc;
888
889 if (!vsub) {
890 vty_out(vty, "%% No subscriber found for %s %s%s",
891 argv[0], argv[1], VTY_NEWLINE);
892 rc = CMD_WARNING;
893 goto err;
894 }
895
Harald Welte39b55482018-04-09 19:19:33 +0200896 if (!strcmp(argv[2], "msisdn")) {
897 sender_msisdn = argv[3];
898 } else {
899 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
900 if (!sender) {
901 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
902 rc = CMD_WARNING;
903 goto err;
904 }
905 sender_msisdn = sender->msisdn;
906 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100907 }
908
909 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +0200910 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100911 talloc_free(str);
912
913err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100914 if (vsub)
915 vlr_subscr_put(vsub);
916
917 return rc;
918}
919
920#define CHAN_TYPES "(any|tch/f|tch/any|sdcch)"
921#define CHAN_TYPE_HELP \
922 "Any channel\n" \
923 "TCH/F channel\n" \
924 "Any TCH channel\n" \
925 "SDCCH channel\n"
926
927DEFUN(subscriber_silent_call_start,
928 subscriber_silent_call_start_cmd,
929 "subscriber " SUBSCR_TYPES " ID silent-call start (any|tch/f|tch/any|sdcch)",
930 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
931 CHAN_TYPE_HELP)
932{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100933 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
934 int rc, type;
935
936 if (!vsub) {
937 vty_out(vty, "%% No subscriber found for %s %s%s",
938 argv[0], argv[1], VTY_NEWLINE);
939 return CMD_WARNING;
940 }
941
942 if (!strcmp(argv[2], "tch/f"))
943 type = RSL_CHANNEED_TCH_F;
944 else if (!strcmp(argv[2], "tch/any"))
945 type = RSL_CHANNEED_TCH_ForH;
946 else if (!strcmp(argv[2], "sdcch"))
947 type = RSL_CHANNEED_SDCCH;
948 else
949 type = RSL_CHANNEED_ANY; /* Defaults to ANY */
950
951 rc = gsm_silent_call_start(vsub, vty, type);
952 switch (rc) {
953 case -ENODEV:
954 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
955 break;
956 default:
957 if (rc)
958 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
959 else
960 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
961 break;
962 }
963
964 vlr_subscr_put(vsub);
965 return rc ? CMD_WARNING : CMD_SUCCESS;
966}
967
968DEFUN(subscriber_silent_call_stop,
969 subscriber_silent_call_stop_cmd,
970 "subscriber " SUBSCR_TYPES " ID silent-call stop",
971 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
972 CHAN_TYPE_HELP)
973{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100974 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
975 int rc;
976
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 rc = gsm_silent_call_stop(vsub);
984 switch (rc) {
985 case -ENODEV:
986 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
987 break;
988 case -ENOENT:
989 vty_out(vty, "%% Subscriber has no silent call active%s",
990 VTY_NEWLINE);
991 break;
992 default:
993 if (rc)
994 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
995 else
996 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
997 break;
998 }
999
1000 vlr_subscr_put(vsub);
1001 return rc ? CMD_WARNING : CMD_SUCCESS;
1002}
1003
1004DEFUN(subscriber_ussd_notify,
1005 subscriber_ussd_notify_cmd,
1006 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1007 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1008 "Alerting Level 0\n"
1009 "Alerting Level 1\n"
1010 "Alerting Level 2\n"
1011 "Text of USSD message to send\n")
1012{
1013 char *text;
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001014 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001015 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1016 int level;
1017
1018 if (!vsub) {
1019 vty_out(vty, "%% No subscriber found for %s %s%s",
1020 argv[0], argv[1], VTY_NEWLINE);
1021 return CMD_WARNING;
1022 }
1023
1024 level = atoi(argv[2]);
1025 text = argv_concat(argv, argc, 3);
1026 if (!text) {
1027 vlr_subscr_put(vsub);
1028 return CMD_WARNING;
1029 }
1030
1031 conn = connection_for_subscr(vsub);
1032 if (!conn) {
1033 vty_out(vty, "%% An active connection is required for %s %s%s",
1034 argv[0], argv[1], VTY_NEWLINE);
1035 vlr_subscr_put(vsub);
1036 talloc_free(text);
1037 return CMD_WARNING;
1038 }
1039
1040 msc_send_ussd_notify(conn, level, text);
1041 msc_send_ussd_release_complete(conn);
1042
1043 vlr_subscr_put(vsub);
1044 talloc_free(text);
1045 return CMD_SUCCESS;
1046}
1047
1048DEFUN(subscriber_paging,
1049 subscriber_paging_cmd,
1050 "subscriber " SUBSCR_TYPES " ID paging",
1051 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1052{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001053 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1054 struct subscr_request *req;
1055
1056 if (!vsub) {
1057 vty_out(vty, "%% No subscriber found for %s %s%s",
1058 argv[0], argv[1], VTY_NEWLINE);
1059 return CMD_WARNING;
1060 }
1061
1062 req = subscr_request_conn(vsub, NULL, NULL, "manual Paging from VTY");
1063 if (req)
1064 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1065 else
1066 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1067
1068 vlr_subscr_put(vsub);
1069 return req ? CMD_SUCCESS : CMD_WARNING;
1070}
1071
1072static int loop_by_char(uint8_t ch)
1073{
1074 switch (ch) {
1075 case 'a':
1076 return GSM414_LOOP_A;
1077 case 'b':
1078 return GSM414_LOOP_B;
1079 case 'c':
1080 return GSM414_LOOP_C;
1081 case 'd':
1082 return GSM414_LOOP_D;
1083 case 'e':
1084 return GSM414_LOOP_E;
1085 case 'f':
1086 return GSM414_LOOP_F;
1087 case 'i':
1088 return GSM414_LOOP_I;
1089 }
1090 return -1;
1091}
1092
1093DEFUN(subscriber_mstest_close,
1094 subscriber_mstest_close_cmd,
1095 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1096 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1097 "Close a TCH Loop inside the MS\n"
1098 "Loop Type A\n"
1099 "Loop Type B\n"
1100 "Loop Type C\n"
1101 "Loop Type D\n"
1102 "Loop Type E\n"
1103 "Loop Type F\n"
1104 "Loop Type I\n")
1105{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001106 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001107 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1108 const char *loop_str;
1109 int loop_mode;
1110
1111 if (!vsub) {
1112 vty_out(vty, "%% No subscriber found for %s %s%s",
1113 argv[0], argv[1], VTY_NEWLINE);
1114 return CMD_WARNING;
1115 }
1116
1117 loop_str = argv[2];
1118 loop_mode = loop_by_char(loop_str[0]);
1119
1120 conn = connection_for_subscr(vsub);
1121 if (!conn) {
1122 vty_out(vty, "%% An active connection is required for %s %s%s",
1123 argv[0], argv[1], VTY_NEWLINE);
1124 vlr_subscr_put(vsub);
1125 return CMD_WARNING;
1126 }
1127
1128 gsm0414_tx_close_tch_loop_cmd(conn, loop_mode);
1129
1130 return CMD_SUCCESS;
1131}
1132
1133DEFUN(subscriber_mstest_open,
1134 subscriber_mstest_open_cmd,
1135 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1136 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1137 "Open a TCH Loop inside the MS\n")
1138{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001139 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001140 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1141
1142 if (!vsub) {
1143 vty_out(vty, "%% No subscriber found for %s %s%s",
1144 argv[0], argv[1], VTY_NEWLINE);
1145 return CMD_WARNING;
1146 }
1147
1148 conn = connection_for_subscr(vsub);
1149 if (!conn) {
1150 vty_out(vty, "%% An active connection is required for %s %s%s",
1151 argv[0], argv[1], VTY_NEWLINE);
1152 vlr_subscr_put(vsub);
1153 return CMD_WARNING;
1154 }
1155
1156 gsm0414_tx_open_loop_cmd(conn);
1157
1158 return CMD_SUCCESS;
1159}
1160
1161DEFUN(ena_subscr_expire,
1162 ena_subscr_expire_cmd,
1163 "subscriber " SUBSCR_TYPES " ID expire",
1164 SUBSCR_HELP "Expire the subscriber Now\n")
1165{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001166 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1167 argv[1]);
1168
1169 if (!vsub) {
1170 vty_out(vty, "%% No subscriber found for %s %s%s",
1171 argv[0], argv[1], VTY_NEWLINE);
1172 return CMD_WARNING;
1173 }
1174
1175 if (vlr_subscr_expire(vsub))
1176 vty_out(vty, "%% VLR released subscriber %s%s",
1177 vlr_subscr_name(vsub), VTY_NEWLINE);
1178
1179 if (vsub->use_count > 1)
1180 vty_out(vty, "%% Subscriber %s is still in use,"
1181 " should be released soon%s",
1182 vlr_subscr_name(vsub), VTY_NEWLINE);
1183
1184 vlr_subscr_put(vsub);
1185 return CMD_SUCCESS;
1186}
1187
1188static int scall_cbfn(unsigned int subsys, unsigned int signal,
1189 void *handler_data, void *signal_data)
1190{
1191 struct scall_signal_data *sigdata = signal_data;
1192 struct vty *vty = sigdata->data;
1193
1194 switch (signal) {
1195 case S_SCALL_SUCCESS:
1196 vty_out(vty, "%% silent call success%s", VTY_NEWLINE);
1197 break;
1198 case S_SCALL_EXPIRED:
1199 vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE);
1200 break;
1201 }
1202 return 0;
1203}
1204
1205DEFUN(show_stats,
1206 show_stats_cmd,
1207 "show statistics",
1208 SHOW_STR "Display network statistics\n")
1209{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001210 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001211 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1212 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1213 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001214 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001215 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001216 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001217 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001218 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001219 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1220 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001221 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001222 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001223 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1224 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001225 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001226 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001227 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1228 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1229 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001230 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001231 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001232 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1233 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001234 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001235 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001236 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1237 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001238 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001239 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001240 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1241 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1242 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1243 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1244 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001245 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001246 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1247 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1248 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1249 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1250 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001251 return CMD_SUCCESS;
1252}
1253
1254DEFUN(show_smsqueue,
1255 show_smsqueue_cmd,
1256 "show sms-queue",
1257 SHOW_STR "Display SMSqueue statistics\n")
1258{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001259 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001260 return CMD_SUCCESS;
1261}
1262
1263DEFUN(smsqueue_trigger,
1264 smsqueue_trigger_cmd,
1265 "sms-queue trigger",
1266 "SMS Queue\n" "Trigger sending messages\n")
1267{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001268 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001269 return CMD_SUCCESS;
1270}
1271
1272DEFUN(smsqueue_max,
1273 smsqueue_max_cmd,
1274 "sms-queue max-pending <1-500>",
1275 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1276{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001277 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001278 return CMD_SUCCESS;
1279}
1280
1281DEFUN(smsqueue_clear,
1282 smsqueue_clear_cmd,
1283 "sms-queue clear",
1284 "SMS Queue\n" "Clear the queue of pending SMS\n")
1285{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001286 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001287 return CMD_SUCCESS;
1288}
1289
1290DEFUN(smsqueue_fail,
1291 smsqueue_fail_cmd,
1292 "sms-queue max-failure <1-500>",
1293 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1294{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001295 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001296 return CMD_SUCCESS;
1297}
1298
1299
1300DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1301 "mncc-int", "Configure internal MNCC handler")
1302{
1303 vty->node = MNCC_INT_NODE;
1304
1305 return CMD_SUCCESS;
1306}
1307
1308static struct cmd_node mncc_int_node = {
1309 MNCC_INT_NODE,
1310 "%s(config-mncc-int)# ",
1311 1,
1312};
1313
1314static const struct value_string tchf_codec_names[] = {
1315 { GSM48_CMODE_SPEECH_V1, "fr" },
1316 { GSM48_CMODE_SPEECH_EFR, "efr" },
1317 { GSM48_CMODE_SPEECH_AMR, "amr" },
1318 { 0, NULL }
1319};
1320
1321static const struct value_string tchh_codec_names[] = {
1322 { GSM48_CMODE_SPEECH_V1, "hr" },
1323 { GSM48_CMODE_SPEECH_AMR, "amr" },
1324 { 0, NULL }
1325};
1326
1327static int config_write_mncc_int(struct vty *vty)
1328{
1329 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1330 vty_out(vty, " default-codec tch-f %s%s",
1331 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1332 VTY_NEWLINE);
1333 vty_out(vty, " default-codec tch-h %s%s",
1334 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1335 VTY_NEWLINE);
1336
1337 return CMD_SUCCESS;
1338}
1339
1340DEFUN(mnccint_def_codec_f,
1341 mnccint_def_codec_f_cmd,
1342 "default-codec tch-f (fr|efr|amr)",
1343 "Set default codec\n" "Codec for TCH/F\n"
1344 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1345{
1346 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1347
1348 return CMD_SUCCESS;
1349}
1350
1351DEFUN(mnccint_def_codec_h,
1352 mnccint_def_codec_h_cmd,
1353 "default-codec tch-h (hr|amr)",
1354 "Set default codec\n" "Codec for TCH/H\n"
1355 "Half-Rate\n" "Adaptive Multi-Rate\n")
1356{
1357 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1358
1359 return CMD_SUCCESS;
1360}
1361
1362
1363DEFUN(logging_fltr_imsi,
1364 logging_fltr_imsi_cmd,
1365 "logging filter imsi IMSI",
1366 LOGGING_STR FILTER_STR
1367 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1368{
1369 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001370 struct log_target *tgt = osmo_log_vty2tgt(vty);
1371 const char *imsi = argv[0];
1372
1373 if (!tgt)
1374 return CMD_WARNING;
1375
1376 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi);
1377
1378 if (!vlr_subscr) {
1379 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1380 argv[0], VTY_NEWLINE);
1381 return CMD_WARNING;
1382 }
1383
1384 log_set_filter_vlr_subscr(tgt, vlr_subscr);
1385 return CMD_SUCCESS;
1386}
1387
1388static struct cmd_node hlr_node = {
1389 HLR_NODE,
1390 "%s(config-hlr)# ",
1391 1,
1392};
1393
1394DEFUN(cfg_hlr, cfg_hlr_cmd,
1395 "hlr", "Configure connection to the HLR")
1396{
1397 vty->node = HLR_NODE;
1398 return CMD_SUCCESS;
1399}
1400
1401DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1402 "Remote GSUP address of the HLR\n"
1403 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1404{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001405 talloc_free((void*)gsmnet->gsup_server_addr_str);
1406 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1407 return CMD_SUCCESS;
1408}
1409
1410DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1411 "Remote GSUP port of the HLR\n"
1412 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1413{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001414 gsmnet->gsup_server_port = atoi(argv[0]);
1415 return CMD_SUCCESS;
1416}
1417
1418static int config_write_hlr(struct vty *vty)
1419{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001420 vty_out(vty, "hlr%s", VTY_NEWLINE);
1421 vty_out(vty, " remote-ip %s%s",
1422 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1423 vty_out(vty, " remote-port %u%s",
1424 gsmnet->gsup_server_port, VTY_NEWLINE);
1425 return CMD_SUCCESS;
1426}
1427
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001428void msc_vty_init(struct gsm_network *msc_network)
1429{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001430 OSMO_ASSERT(gsmnet == NULL);
1431 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001432
1433 osmo_stats_vty_add_cmds();
1434
1435 install_element(CONFIG_NODE, &cfg_net_cmd);
1436 install_node(&net_node, config_write_net);
1437 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
1438 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1439 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1440 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
1441 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
1442 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
1443 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
1444 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
1445 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
1446 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
1447 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
1448 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
1449 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001450
1451 install_element(CONFIG_NODE, &cfg_msc_cmd);
1452 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001453 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02001454 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01001455 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001456 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01001457 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
1458 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001459 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
1460 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01001461 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01001462 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001463
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02001464 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001465#ifdef BUILD_IU
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +01001466 ranap_iu_vty_init(MSC_NODE, &msc_network->iu.rab_assign_addr_enc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001467#endif
Stefan Sperling617ac802018-02-22 17:58:20 +01001468 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001469
1470 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
1471
1472 install_element_ve(&show_subscr_cmd);
1473 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01001474 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001475 install_element_ve(&show_msc_conn_cmd);
1476 install_element_ve(&show_msc_transaction_cmd);
1477
1478 install_element_ve(&sms_send_pend_cmd);
1479 install_element_ve(&sms_delete_expired_cmd);
1480
1481 install_element_ve(&subscriber_create_cmd);
1482 install_element_ve(&subscriber_send_sms_cmd);
1483 install_element_ve(&subscriber_silent_sms_cmd);
1484 install_element_ve(&subscriber_silent_call_start_cmd);
1485 install_element_ve(&subscriber_silent_call_stop_cmd);
1486 install_element_ve(&subscriber_ussd_notify_cmd);
1487 install_element_ve(&subscriber_mstest_close_cmd);
1488 install_element_ve(&subscriber_mstest_open_cmd);
1489 install_element_ve(&subscriber_paging_cmd);
1490 install_element_ve(&show_stats_cmd);
1491 install_element_ve(&show_smsqueue_cmd);
1492 install_element_ve(&logging_fltr_imsi_cmd);
1493
1494 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
1495 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
1496 install_element(ENABLE_NODE, &smsqueue_max_cmd);
1497 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
1498 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
1499 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
1500
1501 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1502 install_node(&mncc_int_node, config_write_mncc_int);
1503 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1504 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1505
1506 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
1507
1508 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1509 install_node(&hlr_node, config_write_hlr);
1510 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1511 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001512}