blob: 87adc82def928150261b369fb0dec125cf16bd2c [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
Stefan Sperlingafa030d2018-12-06 12:06:59 +0100461DEFUN(cfg_msc_ipa_name,
462 cfg_msc_ipa_name_cmd,
463 "ipa-name NAME",
464 "Set the IPA name of this MSC\n"
465 "A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. "
466 "This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. "
467 "The default is 'MSC-00-00-00-00-00-00'.\n")
468{
Stefan Sperling1051c422018-12-13 10:16:49 +0100469 if (!msc_parsing_config_file) {
470 vty_out(vty, "The IPA name cannot be changed at run-time; "
471 "It can only be set in the configuraton file.%s", VTY_NEWLINE);
472 return CMD_WARNING;
473 }
474
Stefan Sperlingafa030d2018-12-06 12:06:59 +0100475 gsmnet->msc_ipa_name = talloc_strdup(gsmnet, argv[0]);
476 return CMD_SUCCESS;
477}
478
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200479static int config_write_msc(struct vty *vty)
480{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200481 vty_out(vty, "msc%s", VTY_NEWLINE);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100482 if (gsmnet->mncc_sock_path)
483 vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE);
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100484 vty_out(vty, " mncc guard-timeout %i%s",
Philipp Maier9ca7b312018-10-10 17:00:49 +0200485 gsmnet->mncc_guard_timeout, VTY_NEWLINE);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200486 vty_out(vty, " %sassign-tmsi%s",
487 gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
488
Philipp Maierfbf66102017-04-09 12:32:51 +0200489 vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
490 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100491#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200492 vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance,
493 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100494#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200495
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100496 if (gsmnet->vlr->cfg.auth_tuple_max_reuse_count)
497 vty_out(vty, " auth-tuple-max-reuse-count %d%s",
498 OSMO_MAX(-1, gsmnet->vlr->cfg.auth_tuple_max_reuse_count),
499 VTY_NEWLINE);
500 if (gsmnet->vlr->cfg.auth_reuse_old_sets_on_error)
501 vty_out(vty, " auth-tuple-reuse-on-error 1%s",
502 VTY_NEWLINE);
503
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100504 if (gsmnet->paging_response_timer != MSC_PAGING_RESPONSE_TIMER_DEFAULT)
505 vty_out(vty, " paging response-timer %u%s", gsmnet->paging_response_timer, VTY_NEWLINE);
506
Harald Welte69c54a82018-02-09 20:41:14 +0100507 if (gsmnet->emergency.route_to_msisdn) {
508 vty_out(vty, " emergency-call route-to-msisdn %s%s",
509 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
510 }
511
Stefan Sperlingafa030d2018-12-06 12:06:59 +0100512 if (gsmnet->msc_ipa_name)
513 vty_out(vty, " ipa-name %s%s", gsmnet->msc_ipa_name, VTY_NEWLINE);
514
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +0200515 mgcp_client_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200516#ifdef BUILD_IU
Neels Hofmeyr00e82d62017-07-05 15:19:52 +0200517 ranap_iu_vty_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200518#endif
519
520 return CMD_SUCCESS;
521}
522
Maxc51609a2018-11-09 17:13:00 +0100523DEFUN(show_bsc, show_bsc_cmd,
524 "show bsc", SHOW_STR "BSC\n")
525{
526 struct bsc_context *bsc_ctx;
527 struct osmo_ss7_instance *ss7 = osmo_ss7_instance_find(gsmnet->a.cs7_instance);
528
529 llist_for_each_entry(bsc_ctx, &gsmnet->a.bscs, list) {
530 vty_out(vty, "BSC %s%s", osmo_sccp_addr_name(ss7, &bsc_ctx->bsc_addr), VTY_NEWLINE);
531 }
532
533 return CMD_SUCCESS;
534}
535
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100536static void vty_conn_hdr(struct vty *vty)
537{
538 vty_out(vty, "--ConnId ------------Subscriber RAN --LAC Use --Tokens C A5 State%s",
539 VTY_NEWLINE);
540}
541
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100542static void vty_dump_one_conn(struct vty *vty, const struct ran_conn *conn)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100543{
544 vty_out(vty, "%08x %22s %3s %5u %3u %08x %c /%1u %27s %s",
545 conn->a.conn_id,
546 conn->vsub ? vlr_subscr_name(conn->vsub) : "-",
547 conn->via_ran == RAN_UTRAN_IU ? "Iu" : "A",
548 conn->lac,
549 conn->use_count,
550 conn->use_tokens,
551 conn->received_cm_service_request ? 'C' : '-',
Neels Hofmeyrf41658d2018-11-30 04:35:50 +0100552 conn->geran_encr.alg_id,
Neels Hofmeyr4d3a66b2018-03-31 18:45:59 +0200553 conn->fi ? osmo_fsm_inst_state_name(conn->fi) : "-",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100554 VTY_NEWLINE);
555}
556
557DEFUN(show_msc_conn, show_msc_conn_cmd,
558 "show connection", SHOW_STR "Subscriber Connections\n")
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200559{
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100560 struct ran_conn *conn;
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200561
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100562 vty_conn_hdr(vty);
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100563 llist_for_each_entry(conn, &gsmnet->ran_conns, entry)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100564 vty_dump_one_conn(vty, conn);
565
566 return CMD_SUCCESS;
567}
568
569static void vty_trans_hdr(struct vty *vty)
570{
571 vty_out(vty, "------------Subscriber --ConnId -P TI -CallRef Proto%s",
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200572 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100573}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200574
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100575static const char *get_trans_proto_str(const struct gsm_trans *trans)
576{
577 static char buf[256];
578
579 switch (trans->protocol) {
580 case GSM48_PDISC_CC:
581 snprintf(buf, sizeof(buf), "%s %4u %4u",
582 gsm48_cc_state_name(trans->cc.state),
583 trans->cc.Tcurrent,
584 trans->cc.T308_second);
585 break;
586 case GSM48_PDISC_SMS:
587 snprintf(buf, sizeof(buf), "%s %s",
588 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
589 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
590 break;
591 default:
592 buf[0] = '\0';
593 break;
594 }
595
596 return buf;
597}
598
599static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
600{
601 vty_out(vty, "%22s %08x %s %02u %08x %s%s",
602 trans->vsub ? vlr_subscr_name(trans->vsub) : "-",
603 trans->conn ? trans->conn->a.conn_id : 0,
604 gsm48_pdisc_name(trans->protocol),
605 trans->transaction_id,
606 trans->callref,
607 get_trans_proto_str(trans), VTY_NEWLINE);
608}
609
610DEFUN(show_msc_transaction, show_msc_transaction_cmd,
611 "show transaction", SHOW_STR "Transactions\n")
612{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100613 struct gsm_trans *trans;
614
615 vty_trans_hdr(vty);
616 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
617 vty_dump_one_trans(vty, trans);
618
619 return CMD_SUCCESS;
620}
621
622static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
623{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100624 struct gsm_trans *trans;
625 int reqs;
626 struct llist_head *entry;
627
628 if (strlen(vsub->name))
629 vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
630 if (strlen(vsub->msisdn))
631 vty_out(vty, " Extension: %s%s", vsub->msisdn,
632 VTY_NEWLINE);
633 vty_out(vty, " LAC: %d/0x%x%s",
634 vsub->lac, vsub->lac, VTY_NEWLINE);
635 vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
636 if (vsub->tmsi != GSM_RESERVED_TMSI)
637 vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
638 VTY_NEWLINE);
639 if (vsub->tmsi_new != GSM_RESERVED_TMSI)
640 vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
641 VTY_NEWLINE);
642
643#if 0
644 /* TODO: add this to vlr_subscr? */
645 if (vsub->auth_info.auth_algo != AUTH_ALGO_NONE) {
646 struct gsm_auth_info *i = &vsub->auth_info;
647 vty_out(vty, " A3A8 algorithm id: %d%s",
648 i->auth_algo, VTY_NEWLINE);
649 vty_out(vty, " A3A8 Ki: %s%s",
650 osmo_hexdump(i->a3a8_ki, i->a3a8_ki_len),
651 VTY_NEWLINE);
652 }
653#endif
654
655 if (vsub->last_tuple) {
Neels Hofmeyr8b6e5362018-11-30 02:57:33 +0100656 struct vlr_auth_tuple *t = vsub->last_tuple;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100657 vty_out(vty, " A3A8 last tuple (used %d times):%s",
658 t->use_count, VTY_NEWLINE);
659 vty_out(vty, " seq # : %d%s",
660 t->key_seq, VTY_NEWLINE);
661 vty_out(vty, " RAND : %s%s",
662 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
663 VTY_NEWLINE);
664 vty_out(vty, " SRES : %s%s",
665 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
666 VTY_NEWLINE);
667 vty_out(vty, " Kc : %s%s",
668 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
669 VTY_NEWLINE);
670 }
671
672 reqs = 0;
673 llist_for_each(entry, &vsub->cs.requests)
674 reqs += 1;
675 vty_out(vty, " Paging: %s paging for %d requests%s",
676 vsub->cs.is_paging ? "is" : "not", reqs, VTY_NEWLINE);
677 vty_out(vty, " Use count: %u%s", vsub->use_count, VTY_NEWLINE);
678
679 /* Connection */
680 if (vsub->msc_conn_ref) {
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100681 struct ran_conn *conn = vsub->msc_conn_ref;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100682 vty_conn_hdr(vty);
683 vty_dump_one_conn(vty, conn);
684 }
685
686 /* Transactions */
687 vty_trans_hdr(vty);
688 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
689 if (trans->vsub != vsub)
690 continue;
691 vty_dump_one_trans(vty, trans);
692 }
693}
694
695/* Subscriber */
696DEFUN(show_subscr_cache,
697 show_subscr_cache_cmd,
698 "show subscriber cache",
699 SHOW_STR "Show information about subscribers\n"
700 "Display contents of subscriber cache\n")
701{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100702 struct vlr_subscr *vsub;
703 int count = 0;
704
705 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
706 if (++count > 100) {
707 vty_out(vty, "%% More than %d subscribers in cache,"
708 " stopping here.%s", count-1, VTY_NEWLINE);
709 break;
710 }
711 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
712 subscr_dump_full_vty(vty, vsub);
Harald Welte69c54a82018-02-09 20:41:14 +0100713 }
714
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200715 return CMD_SUCCESS;
716}
717
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100718DEFUN(sms_send_pend,
719 sms_send_pend_cmd,
720 "sms send pending",
721 "SMS related commands\n" "SMS Sending related commands\n"
722 "Send all pending SMS")
723{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100724 struct gsm_sms *sms;
725 unsigned long long sms_id = 0;
726
727 while (1) {
728 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
729 if (!sms)
730 break;
731
732 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700733 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100734
735 sms_id = sms->id + 1;
736 }
737
738 return CMD_SUCCESS;
739}
740
741DEFUN(sms_delete_expired,
742 sms_delete_expired_cmd,
743 "sms delete expired",
744 "SMS related commands\n" "SMS Database related commands\n"
745 "Delete all expired SMS")
746{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100747 struct gsm_sms *sms;
748 unsigned long long sms_id = 0;
749 long long num_deleted = 0;
750
751 while (1) {
752 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
753 if (!sms)
754 break;
755
756 /* Skip SMS which are currently queued for sending. */
757 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
758 continue;
759
760 /* Expiration check is performed by the DB layer. */
761 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
762 num_deleted++;
763
764 sms_id = sms->id + 1;
765 }
766
767 if (num_deleted == 0) {
768 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
769 return CMD_WARNING;
770 }
771
772 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
773 return CMD_SUCCESS;
774}
775
776static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +0200777 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100778 char *str, uint8_t tp_pid)
779{
780 struct gsm_network *net = receiver->vlr->user_ctx;
781 struct gsm_sms *sms;
782
Harald Welte39b55482018-04-09 19:19:33 +0200783 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100784 sms->protocol_id = tp_pid;
785
786 /* store in database for the queue */
787 if (db_sms_store(sms) != 0) {
788 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
789 sms_free(sms);
790 return CMD_WARNING;
791 }
792 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
793
794 sms_free(sms);
795 sms_queue_trigger(net->sms_queue);
796 return CMD_SUCCESS;
797}
798
799static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
800 const char *type,
801 const char *id)
802{
803 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
804 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id);
805 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
806 return vlr_subscr_find_by_imsi(gsmnet->vlr, id);
807 else if (!strcmp(type, "tmsi"))
808 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id));
809
810 return NULL;
811}
812#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
813#define SUBSCR_HELP "Operations on a Subscriber\n" \
814 "Identify subscriber by MSISDN (phone number)\n" \
815 "Legacy alias for 'msisdn'\n" \
816 "Identify subscriber by IMSI\n" \
817 "Identify subscriber by TMSI\n" \
818 "Identify subscriber by database ID\n" \
819 "Identifier for the subscriber\n"
820
821DEFUN(show_subscr,
822 show_subscr_cmd,
823 "show subscriber " SUBSCR_TYPES " ID",
824 SHOW_STR SUBSCR_HELP)
825{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100826 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
827 argv[1]);
828
829 if (!vsub) {
830 vty_out(vty, "%% No subscriber found for %s %s%s",
831 argv[0], argv[1], VTY_NEWLINE);
832 return CMD_WARNING;
833 }
834
835 subscr_dump_full_vty(vty, vsub);
836
837 vlr_subscr_put(vsub);
838
839 return CMD_SUCCESS;
840}
841
842DEFUN(subscriber_create,
843 subscriber_create_cmd,
844 "subscriber create imsi ID",
845 "Operations on a Subscriber\n" \
846 "Create new subscriber\n" \
847 "Identify the subscriber by his IMSI\n" \
848 "Identifier for the subscriber\n")
849{
850 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
851 VTY_NEWLINE);
852 return CMD_WARNING;
853}
854
855DEFUN(subscriber_send_pending_sms,
856 subscriber_send_pending_sms_cmd,
857 "subscriber " SUBSCR_TYPES " ID sms pending-send",
858 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
859{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100860 struct vlr_subscr *vsub;
861 struct gsm_sms *sms;
862
863 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
864 if (!vsub) {
865 vty_out(vty, "%% No subscriber found for %s %s%s",
866 argv[0], argv[1], VTY_NEWLINE);
867 return CMD_WARNING;
868 }
869
870 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
871 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700872 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100873
874 vlr_subscr_put(vsub);
875
876 return CMD_SUCCESS;
877}
878
879DEFUN(subscriber_send_sms,
880 subscriber_send_sms_cmd,
881 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
882 SUBSCR_HELP "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, 0);
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
920DEFUN(subscriber_silent_sms,
921 subscriber_silent_sms_cmd,
922
923 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
924 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
925{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100926 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200927 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100928 char *str;
929 int rc;
930
931 if (!vsub) {
932 vty_out(vty, "%% No subscriber found for %s %s%s",
933 argv[0], argv[1], VTY_NEWLINE);
934 rc = CMD_WARNING;
935 goto err;
936 }
937
Harald Welte39b55482018-04-09 19:19:33 +0200938 if (!strcmp(argv[2], "msisdn")) {
939 sender_msisdn = argv[3];
940 } else {
941 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
942 if (!sender) {
943 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
944 rc = CMD_WARNING;
945 goto err;
946 }
947 sender_msisdn = sender->msisdn;
948 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100949 }
950
951 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +0200952 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100953 talloc_free(str);
954
955err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100956 if (vsub)
957 vlr_subscr_put(vsub);
958
959 return rc;
960}
961
962#define CHAN_TYPES "(any|tch/f|tch/any|sdcch)"
963#define CHAN_TYPE_HELP \
964 "Any channel\n" \
965 "TCH/F channel\n" \
966 "Any TCH channel\n" \
967 "SDCCH channel\n"
968
969DEFUN(subscriber_silent_call_start,
970 subscriber_silent_call_start_cmd,
971 "subscriber " SUBSCR_TYPES " ID silent-call start (any|tch/f|tch/any|sdcch)",
972 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
973 CHAN_TYPE_HELP)
974{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100975 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
976 int rc, type;
977
978 if (!vsub) {
979 vty_out(vty, "%% No subscriber found for %s %s%s",
980 argv[0], argv[1], VTY_NEWLINE);
981 return CMD_WARNING;
982 }
983
984 if (!strcmp(argv[2], "tch/f"))
985 type = RSL_CHANNEED_TCH_F;
986 else if (!strcmp(argv[2], "tch/any"))
987 type = RSL_CHANNEED_TCH_ForH;
988 else if (!strcmp(argv[2], "sdcch"))
989 type = RSL_CHANNEED_SDCCH;
990 else
991 type = RSL_CHANNEED_ANY; /* Defaults to ANY */
992
993 rc = gsm_silent_call_start(vsub, vty, type);
994 switch (rc) {
995 case -ENODEV:
996 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
997 break;
998 default:
999 if (rc)
1000 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
1001 else
1002 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
1003 break;
1004 }
1005
1006 vlr_subscr_put(vsub);
1007 return rc ? CMD_WARNING : CMD_SUCCESS;
1008}
1009
1010DEFUN(subscriber_silent_call_stop,
1011 subscriber_silent_call_stop_cmd,
1012 "subscriber " SUBSCR_TYPES " ID silent-call stop",
1013 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
1014 CHAN_TYPE_HELP)
1015{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001016 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1017 int rc;
1018
1019 if (!vsub) {
1020 vty_out(vty, "%% No subscriber found for %s %s%s",
1021 argv[0], argv[1], VTY_NEWLINE);
1022 return CMD_WARNING;
1023 }
1024
1025 rc = gsm_silent_call_stop(vsub);
1026 switch (rc) {
1027 case -ENODEV:
1028 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
1029 break;
1030 case -ENOENT:
1031 vty_out(vty, "%% Subscriber has no silent call active%s",
1032 VTY_NEWLINE);
1033 break;
1034 default:
1035 if (rc)
1036 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
1037 else
1038 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
1039 break;
1040 }
1041
1042 vlr_subscr_put(vsub);
1043 return rc ? CMD_WARNING : CMD_SUCCESS;
1044}
1045
1046DEFUN(subscriber_ussd_notify,
1047 subscriber_ussd_notify_cmd,
1048 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1049 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1050 "Alerting Level 0\n"
1051 "Alerting Level 1\n"
1052 "Alerting Level 2\n"
1053 "Text of USSD message to send\n")
1054{
1055 char *text;
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001056 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001057 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1058 int level;
1059
1060 if (!vsub) {
1061 vty_out(vty, "%% No subscriber found for %s %s%s",
1062 argv[0], argv[1], VTY_NEWLINE);
1063 return CMD_WARNING;
1064 }
1065
1066 level = atoi(argv[2]);
1067 text = argv_concat(argv, argc, 3);
1068 if (!text) {
1069 vlr_subscr_put(vsub);
1070 return CMD_WARNING;
1071 }
1072
1073 conn = connection_for_subscr(vsub);
1074 if (!conn) {
1075 vty_out(vty, "%% An active connection is required for %s %s%s",
1076 argv[0], argv[1], VTY_NEWLINE);
1077 vlr_subscr_put(vsub);
1078 talloc_free(text);
1079 return CMD_WARNING;
1080 }
1081
1082 msc_send_ussd_notify(conn, level, text);
1083 msc_send_ussd_release_complete(conn);
1084
1085 vlr_subscr_put(vsub);
1086 talloc_free(text);
1087 return CMD_SUCCESS;
1088}
1089
1090DEFUN(subscriber_paging,
1091 subscriber_paging_cmd,
1092 "subscriber " SUBSCR_TYPES " ID paging",
1093 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1094{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001095 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1096 struct subscr_request *req;
1097
1098 if (!vsub) {
1099 vty_out(vty, "%% No subscriber found for %s %s%s",
1100 argv[0], argv[1], VTY_NEWLINE);
1101 return CMD_WARNING;
1102 }
1103
1104 req = subscr_request_conn(vsub, NULL, NULL, "manual Paging from VTY");
1105 if (req)
1106 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1107 else
1108 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1109
1110 vlr_subscr_put(vsub);
1111 return req ? CMD_SUCCESS : CMD_WARNING;
1112}
1113
1114static int loop_by_char(uint8_t ch)
1115{
1116 switch (ch) {
1117 case 'a':
1118 return GSM414_LOOP_A;
1119 case 'b':
1120 return GSM414_LOOP_B;
1121 case 'c':
1122 return GSM414_LOOP_C;
1123 case 'd':
1124 return GSM414_LOOP_D;
1125 case 'e':
1126 return GSM414_LOOP_E;
1127 case 'f':
1128 return GSM414_LOOP_F;
1129 case 'i':
1130 return GSM414_LOOP_I;
1131 }
1132 return -1;
1133}
1134
1135DEFUN(subscriber_mstest_close,
1136 subscriber_mstest_close_cmd,
1137 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1138 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1139 "Close a TCH Loop inside the MS\n"
1140 "Loop Type A\n"
1141 "Loop Type B\n"
1142 "Loop Type C\n"
1143 "Loop Type D\n"
1144 "Loop Type E\n"
1145 "Loop Type F\n"
1146 "Loop Type I\n")
1147{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001148 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001149 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1150 const char *loop_str;
1151 int loop_mode;
1152
1153 if (!vsub) {
1154 vty_out(vty, "%% No subscriber found for %s %s%s",
1155 argv[0], argv[1], VTY_NEWLINE);
1156 return CMD_WARNING;
1157 }
1158
1159 loop_str = argv[2];
1160 loop_mode = loop_by_char(loop_str[0]);
1161
1162 conn = connection_for_subscr(vsub);
1163 if (!conn) {
1164 vty_out(vty, "%% An active connection is required for %s %s%s",
1165 argv[0], argv[1], VTY_NEWLINE);
1166 vlr_subscr_put(vsub);
1167 return CMD_WARNING;
1168 }
1169
1170 gsm0414_tx_close_tch_loop_cmd(conn, loop_mode);
1171
1172 return CMD_SUCCESS;
1173}
1174
1175DEFUN(subscriber_mstest_open,
1176 subscriber_mstest_open_cmd,
1177 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1178 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1179 "Open a TCH Loop inside the MS\n")
1180{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001181 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001182 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1183
1184 if (!vsub) {
1185 vty_out(vty, "%% No subscriber found for %s %s%s",
1186 argv[0], argv[1], VTY_NEWLINE);
1187 return CMD_WARNING;
1188 }
1189
1190 conn = connection_for_subscr(vsub);
1191 if (!conn) {
1192 vty_out(vty, "%% An active connection is required for %s %s%s",
1193 argv[0], argv[1], VTY_NEWLINE);
1194 vlr_subscr_put(vsub);
1195 return CMD_WARNING;
1196 }
1197
1198 gsm0414_tx_open_loop_cmd(conn);
1199
1200 return CMD_SUCCESS;
1201}
1202
1203DEFUN(ena_subscr_expire,
1204 ena_subscr_expire_cmd,
1205 "subscriber " SUBSCR_TYPES " ID expire",
1206 SUBSCR_HELP "Expire the subscriber Now\n")
1207{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001208 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1209 argv[1]);
1210
1211 if (!vsub) {
1212 vty_out(vty, "%% No subscriber found for %s %s%s",
1213 argv[0], argv[1], VTY_NEWLINE);
1214 return CMD_WARNING;
1215 }
1216
1217 if (vlr_subscr_expire(vsub))
1218 vty_out(vty, "%% VLR released subscriber %s%s",
1219 vlr_subscr_name(vsub), VTY_NEWLINE);
1220
1221 if (vsub->use_count > 1)
1222 vty_out(vty, "%% Subscriber %s is still in use,"
1223 " should be released soon%s",
1224 vlr_subscr_name(vsub), VTY_NEWLINE);
1225
1226 vlr_subscr_put(vsub);
1227 return CMD_SUCCESS;
1228}
1229
1230static int scall_cbfn(unsigned int subsys, unsigned int signal,
1231 void *handler_data, void *signal_data)
1232{
1233 struct scall_signal_data *sigdata = signal_data;
1234 struct vty *vty = sigdata->data;
1235
1236 switch (signal) {
1237 case S_SCALL_SUCCESS:
1238 vty_out(vty, "%% silent call success%s", VTY_NEWLINE);
1239 break;
1240 case S_SCALL_EXPIRED:
1241 vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE);
1242 break;
1243 }
1244 return 0;
1245}
1246
1247DEFUN(show_stats,
1248 show_stats_cmd,
1249 "show statistics",
1250 SHOW_STR "Display network statistics\n")
1251{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001252 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001253 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1254 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1255 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001256 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001257 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001258 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001259 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001260 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001261 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1262 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001263 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001264 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001265 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1266 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001267 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001268 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001269 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1270 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1271 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001272 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001273 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001274 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1275 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001276 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001277 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001278 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1279 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001280 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001281 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001282 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1283 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1284 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1285 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1286 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001287 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001288 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1289 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1290 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1291 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1292 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001293 return CMD_SUCCESS;
1294}
1295
1296DEFUN(show_smsqueue,
1297 show_smsqueue_cmd,
1298 "show sms-queue",
1299 SHOW_STR "Display SMSqueue statistics\n")
1300{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001301 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001302 return CMD_SUCCESS;
1303}
1304
1305DEFUN(smsqueue_trigger,
1306 smsqueue_trigger_cmd,
1307 "sms-queue trigger",
1308 "SMS Queue\n" "Trigger sending messages\n")
1309{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001310 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001311 return CMD_SUCCESS;
1312}
1313
1314DEFUN(smsqueue_max,
1315 smsqueue_max_cmd,
1316 "sms-queue max-pending <1-500>",
1317 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1318{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001319 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001320 return CMD_SUCCESS;
1321}
1322
1323DEFUN(smsqueue_clear,
1324 smsqueue_clear_cmd,
1325 "sms-queue clear",
1326 "SMS Queue\n" "Clear the queue of pending SMS\n")
1327{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001328 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001329 return CMD_SUCCESS;
1330}
1331
1332DEFUN(smsqueue_fail,
1333 smsqueue_fail_cmd,
1334 "sms-queue max-failure <1-500>",
1335 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1336{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001337 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001338 return CMD_SUCCESS;
1339}
1340
1341
1342DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1343 "mncc-int", "Configure internal MNCC handler")
1344{
1345 vty->node = MNCC_INT_NODE;
1346
1347 return CMD_SUCCESS;
1348}
1349
1350static struct cmd_node mncc_int_node = {
1351 MNCC_INT_NODE,
1352 "%s(config-mncc-int)# ",
1353 1,
1354};
1355
1356static const struct value_string tchf_codec_names[] = {
1357 { GSM48_CMODE_SPEECH_V1, "fr" },
1358 { GSM48_CMODE_SPEECH_EFR, "efr" },
1359 { GSM48_CMODE_SPEECH_AMR, "amr" },
1360 { 0, NULL }
1361};
1362
1363static const struct value_string tchh_codec_names[] = {
1364 { GSM48_CMODE_SPEECH_V1, "hr" },
1365 { GSM48_CMODE_SPEECH_AMR, "amr" },
1366 { 0, NULL }
1367};
1368
1369static int config_write_mncc_int(struct vty *vty)
1370{
1371 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1372 vty_out(vty, " default-codec tch-f %s%s",
1373 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1374 VTY_NEWLINE);
1375 vty_out(vty, " default-codec tch-h %s%s",
1376 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1377 VTY_NEWLINE);
1378
1379 return CMD_SUCCESS;
1380}
1381
1382DEFUN(mnccint_def_codec_f,
1383 mnccint_def_codec_f_cmd,
1384 "default-codec tch-f (fr|efr|amr)",
1385 "Set default codec\n" "Codec for TCH/F\n"
1386 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1387{
1388 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1389
1390 return CMD_SUCCESS;
1391}
1392
1393DEFUN(mnccint_def_codec_h,
1394 mnccint_def_codec_h_cmd,
1395 "default-codec tch-h (hr|amr)",
1396 "Set default codec\n" "Codec for TCH/H\n"
1397 "Half-Rate\n" "Adaptive Multi-Rate\n")
1398{
1399 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1400
1401 return CMD_SUCCESS;
1402}
1403
1404
1405DEFUN(logging_fltr_imsi,
1406 logging_fltr_imsi_cmd,
1407 "logging filter imsi IMSI",
1408 LOGGING_STR FILTER_STR
1409 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1410{
1411 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001412 struct log_target *tgt = osmo_log_vty2tgt(vty);
1413 const char *imsi = argv[0];
1414
1415 if (!tgt)
1416 return CMD_WARNING;
1417
1418 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi);
1419
1420 if (!vlr_subscr) {
1421 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1422 argv[0], VTY_NEWLINE);
1423 return CMD_WARNING;
1424 }
1425
1426 log_set_filter_vlr_subscr(tgt, vlr_subscr);
1427 return CMD_SUCCESS;
1428}
1429
1430static struct cmd_node hlr_node = {
1431 HLR_NODE,
1432 "%s(config-hlr)# ",
1433 1,
1434};
1435
1436DEFUN(cfg_hlr, cfg_hlr_cmd,
1437 "hlr", "Configure connection to the HLR")
1438{
1439 vty->node = HLR_NODE;
1440 return CMD_SUCCESS;
1441}
1442
1443DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1444 "Remote GSUP address of the HLR\n"
1445 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1446{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001447 talloc_free((void*)gsmnet->gsup_server_addr_str);
1448 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1449 return CMD_SUCCESS;
1450}
1451
1452DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1453 "Remote GSUP port of the HLR\n"
1454 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1455{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001456 gsmnet->gsup_server_port = atoi(argv[0]);
1457 return CMD_SUCCESS;
1458}
1459
1460static int config_write_hlr(struct vty *vty)
1461{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001462 vty_out(vty, "hlr%s", VTY_NEWLINE);
1463 vty_out(vty, " remote-ip %s%s",
1464 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1465 vty_out(vty, " remote-port %u%s",
1466 gsmnet->gsup_server_port, VTY_NEWLINE);
1467 return CMD_SUCCESS;
1468}
1469
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001470void msc_vty_init(struct gsm_network *msc_network)
1471{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001472 OSMO_ASSERT(gsmnet == NULL);
1473 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001474
1475 osmo_stats_vty_add_cmds();
1476
1477 install_element(CONFIG_NODE, &cfg_net_cmd);
1478 install_node(&net_node, config_write_net);
1479 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
1480 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1481 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1482 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
1483 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
1484 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
1485 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
1486 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
1487 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
1488 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
1489 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
1490 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
1491 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001492
1493 install_element(CONFIG_NODE, &cfg_msc_cmd);
1494 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001495 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01001496 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
1497 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02001498 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01001499 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001500 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01001501 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
1502 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001503 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
1504 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01001505 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01001506 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Stefan Sperlingafa030d2018-12-06 12:06:59 +01001507 install_element(MSC_NODE, &cfg_msc_ipa_name_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001508
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02001509 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001510#ifdef BUILD_IU
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +01001511 ranap_iu_vty_init(MSC_NODE, &msc_network->iu.rab_assign_addr_enc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001512#endif
Stefan Sperling617ac802018-02-22 17:58:20 +01001513 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001514
1515 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
1516
1517 install_element_ve(&show_subscr_cmd);
1518 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01001519 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001520 install_element_ve(&show_msc_conn_cmd);
1521 install_element_ve(&show_msc_transaction_cmd);
1522
1523 install_element_ve(&sms_send_pend_cmd);
1524 install_element_ve(&sms_delete_expired_cmd);
1525
1526 install_element_ve(&subscriber_create_cmd);
1527 install_element_ve(&subscriber_send_sms_cmd);
1528 install_element_ve(&subscriber_silent_sms_cmd);
1529 install_element_ve(&subscriber_silent_call_start_cmd);
1530 install_element_ve(&subscriber_silent_call_stop_cmd);
1531 install_element_ve(&subscriber_ussd_notify_cmd);
1532 install_element_ve(&subscriber_mstest_close_cmd);
1533 install_element_ve(&subscriber_mstest_open_cmd);
1534 install_element_ve(&subscriber_paging_cmd);
1535 install_element_ve(&show_stats_cmd);
1536 install_element_ve(&show_smsqueue_cmd);
1537 install_element_ve(&logging_fltr_imsi_cmd);
1538
1539 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
1540 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
1541 install_element(ENABLE_NODE, &smsqueue_max_cmd);
1542 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
1543 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
1544 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
1545
1546 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1547 install_node(&mncc_int_node, config_write_mncc_int);
1548 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1549 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1550
1551 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
1552
1553 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1554 install_node(&hlr_node, config_write_hlr);
1555 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1556 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001557}