blob: 078b83aea857c0efc1083e6193c9ab30bb15c5f0 [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>
Harald Welte0df904d2018-12-03 11:00:04 +010059#include <osmocom/msc/vlr_sgs.h>
60#include <osmocom/msc/sgs_vty.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010061
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010062static struct gsm_network *gsmnet = NULL;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010063
64struct cmd_node net_node = {
65 GSMNET_NODE,
66 "%s(config-net)# ",
67 1,
68};
69
70#define NETWORK_STR "Configure the GSM network\n"
71#define CODE_CMD_STR "Code commands\n"
72#define NAME_CMD_STR "Name Commands\n"
73#define NAME_STR "Name to use\n"
74
75DEFUN(cfg_net,
76 cfg_net_cmd,
77 "network", NETWORK_STR)
78{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010079 vty->index = gsmnet;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010080 vty->node = GSMNET_NODE;
81
82 return CMD_SUCCESS;
83}
84
85DEFUN(cfg_net_ncc,
86 cfg_net_ncc_cmd,
87 "network country code <1-999>",
88 "Set the GSM network country code\n"
89 "Country commands\n"
90 CODE_CMD_STR
91 "Network Country Code to use\n")
92{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010093 gsmnet->plmn.mcc = atoi(argv[0]);
94
95 return CMD_SUCCESS;
96}
97
98DEFUN(cfg_net_mnc,
99 cfg_net_mnc_cmd,
100 "mobile network code <0-999>",
101 "Set the GSM mobile network code\n"
102 "Network Commands\n"
103 CODE_CMD_STR
104 "Mobile Network Code to use\n")
105{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100106 uint16_t mnc;
107 bool mnc_3_digits;
108
109 if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
110 vty_out(vty, "%% Error decoding MNC: %s%s", argv[0], VTY_NEWLINE);
111 return CMD_WARNING;
112 }
113
114 gsmnet->plmn.mnc = mnc;
115 gsmnet->plmn.mnc_3_digits = mnc_3_digits;
116
117 return CMD_SUCCESS;
118}
119
120DEFUN(cfg_net_name_short,
121 cfg_net_name_short_cmd,
122 "short name NAME",
123 "Set the short GSM network name\n" NAME_CMD_STR NAME_STR)
124{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100125 osmo_talloc_replace_string(gsmnet, &gsmnet->name_short, argv[0]);
126 return CMD_SUCCESS;
127}
128
129DEFUN(cfg_net_name_long,
130 cfg_net_name_long_cmd,
131 "long name NAME",
132 "Set the long GSM network name\n" NAME_CMD_STR NAME_STR)
133{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100134 osmo_talloc_replace_string(gsmnet, &gsmnet->name_long, argv[0]);
135 return CMD_SUCCESS;
136}
137
138DEFUN(cfg_net_encryption,
139 cfg_net_encryption_cmd,
140 "encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]",
141 "Encryption options\n"
142 "GSM A5 Air Interface Encryption\n"
143 "A5/n Algorithm Number\n"
144 "A5/n Algorithm Number\n"
145 "A5/n Algorithm Number\n"
146 "A5/n Algorithm Number\n")
147{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100148 unsigned int i;
149
150 gsmnet->a5_encryption_mask = 0;
151 for (i = 0; i < argc; i++)
152 gsmnet->a5_encryption_mask |= (1 << atoi(argv[i]));
153
154 return CMD_SUCCESS;
155}
156
157DEFUN(cfg_net_authentication,
158 cfg_net_authentication_cmd,
159 "authentication (optional|required)",
160 "Whether to enforce MS authentication in 2G\n"
161 "Allow MS to attach via 2G BSC without authentication\n"
162 "Always do authentication\n")
163{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100164 gsmnet->authentication_required = (argv[0][0] == 'r') ? true : false;
165
166 return CMD_SUCCESS;
167}
168
169DEFUN(cfg_net_rrlp_mode, cfg_net_rrlp_mode_cmd,
170 "rrlp mode (none|ms-based|ms-preferred|ass-preferred)",
171 "Radio Resource Location Protocol\n"
172 "Set the Radio Resource Location Protocol Mode\n"
173 "Don't send RRLP request\n"
174 "Request MS-based location\n"
175 "Request any location, prefer MS-based\n"
176 "Request any location, prefer MS-assisted\n")
177{
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700178 gsmnet->rrlp.mode = msc_rrlp_mode_parse(argv[0]);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100179
180 return CMD_SUCCESS;
181}
182
183DEFUN(cfg_net_mm_info, cfg_net_mm_info_cmd,
184 "mm info (0|1)",
185 "Mobility Management\n"
186 "Send MM INFO after LOC UPD ACCEPT\n"
187 "Disable\n" "Enable\n")
188{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100189 gsmnet->send_mm_info = atoi(argv[0]);
190
191 return CMD_SUCCESS;
192}
193
194DEFUN(cfg_net_timezone,
195 cfg_net_timezone_cmd,
196 "timezone <-19-19> (0|15|30|45)",
197 "Set the Timezone Offset of the network\n"
198 "Timezone offset (hours)\n"
199 "Timezone offset (00 minutes)\n"
200 "Timezone offset (15 minutes)\n"
201 "Timezone offset (30 minutes)\n"
202 "Timezone offset (45 minutes)\n"
203 )
204{
205 struct gsm_network *net = vty->index;
206 int tzhr = atoi(argv[0]);
207 int tzmn = atoi(argv[1]);
208
209 net->tz.hr = tzhr;
210 net->tz.mn = tzmn;
211 net->tz.dst = 0;
212 net->tz.override = 1;
213
214 return CMD_SUCCESS;
215}
216
217DEFUN(cfg_net_timezone_dst,
218 cfg_net_timezone_dst_cmd,
219 "timezone <-19-19> (0|15|30|45) <0-2>",
220 "Set the Timezone Offset of the network\n"
221 "Timezone offset (hours)\n"
222 "Timezone offset (00 minutes)\n"
223 "Timezone offset (15 minutes)\n"
224 "Timezone offset (30 minutes)\n"
225 "Timezone offset (45 minutes)\n"
226 "DST offset (hours)\n"
227 )
228{
229 struct gsm_network *net = vty->index;
230 int tzhr = atoi(argv[0]);
231 int tzmn = atoi(argv[1]);
232 int tzdst = atoi(argv[2]);
233
234 net->tz.hr = tzhr;
235 net->tz.mn = tzmn;
236 net->tz.dst = tzdst;
237 net->tz.override = 1;
238
239 return CMD_SUCCESS;
240}
241
242DEFUN(cfg_net_no_timezone,
243 cfg_net_no_timezone_cmd,
244 "no timezone",
245 NO_STR
246 "Disable network timezone override, use system tz\n")
247{
248 struct gsm_network *net = vty->index;
249
250 net->tz.override = 0;
251
252 return CMD_SUCCESS;
253}
254
255DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
256 "periodic location update <6-1530>",
257 "Periodic Location Updating Interval\n"
258 "Periodic Location Updating Interval\n"
259 "Periodic Location Updating Interval\n"
260 "Periodic Location Updating Interval in Minutes\n")
261{
262 struct gsm_network *net = vty->index;
263
264 net->t3212 = atoi(argv[0]) / 6;
265
266 return CMD_SUCCESS;
267}
268
269DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
270 "no periodic location update",
271 NO_STR
272 "Periodic Location Updating Interval\n"
273 "Periodic Location Updating Interval\n"
274 "Periodic Location Updating Interval\n")
275{
276 struct gsm_network *net = vty->index;
277
278 net->t3212 = 0;
279
280 return CMD_SUCCESS;
281}
282
283static int config_write_net(struct vty *vty)
284{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100285 int i;
286
287 vty_out(vty, "network%s", VTY_NEWLINE);
288 vty_out(vty, " network country code %s%s", osmo_mcc_name(gsmnet->plmn.mcc), VTY_NEWLINE);
289 vty_out(vty, " mobile network code %s%s",
290 osmo_mnc_name(gsmnet->plmn.mnc, gsmnet->plmn.mnc_3_digits), VTY_NEWLINE);
291 vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
292 vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
293 vty_out(vty, " encryption a5");
294 for (i = 0; i < 8; i++) {
295 if (gsmnet->a5_encryption_mask & (1 << i))
296 vty_out(vty, " %u", i);
297 }
298 vty_out(vty, "%s", VTY_NEWLINE);
299 vty_out(vty, " authentication %s%s",
300 gsmnet->authentication_required ? "required" : "optional", VTY_NEWLINE);
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700301 vty_out(vty, " rrlp mode %s%s", msc_rrlp_mode_name(gsmnet->rrlp.mode),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100302 VTY_NEWLINE);
303 vty_out(vty, " mm info %u%s", gsmnet->send_mm_info, VTY_NEWLINE);
304 if (gsmnet->tz.override != 0) {
305 if (gsmnet->tz.dst)
306 vty_out(vty, " timezone %d %d %d%s",
307 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
308 VTY_NEWLINE);
309 else
310 vty_out(vty, " timezone %d %d%s",
311 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
312 }
313 if (gsmnet->t3212 == 0)
314 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
315 else
316 vty_out(vty, " periodic location update %u%s",
317 gsmnet->t3212 * 6, VTY_NEWLINE);
318
319 if (gsmnet->emergency.route_to_msisdn) {
320 vty_out(vty, " emergency-call route-to-msisdn %s%s",
321 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
322 }
323
324 return CMD_SUCCESS;
325}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200326
327static struct cmd_node msc_node = {
328 MSC_NODE,
329 "%s(config-msc)# ",
330 1,
331};
332
333DEFUN(cfg_msc, cfg_msc_cmd,
334 "msc", "Configure MSC options")
335{
336 vty->node = MSC_NODE;
337 return CMD_SUCCESS;
338}
339
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100340#define MNCC_STR "Configure Mobile Network Call Control\n"
341#define MNCC_GUARD_TIMEOUT_STR "Set global guard timer for mncc interface activity\n"
342#define MNCC_GUARD_TIMEOUT_VALUE_STR "guard timer value (sec.)\n"
343
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100344DEFUN(cfg_msc_mncc_internal,
345 cfg_msc_mncc_internal_cmd,
346 "mncc internal",
347 MNCC_STR "Use internal MNCC handler (default; changes need a program restart)\n")
348{
349 gsm_network_set_mncc_sock_path(gsmnet, NULL);
350 return CMD_SUCCESS;
351}
352
353DEFUN(cfg_msc_mncc_external,
354 cfg_msc_mncc_external_cmd,
355 "mncc external MNCC_SOCKET_PATH",
356 MNCC_STR "Use external MNCC handler (changes need a program restart)\n"
357 "File system path to create the MNCC unix domain socket at\n")
358{
359 gsm_network_set_mncc_sock_path(gsmnet, argv[0]);
360 return CMD_SUCCESS;
361}
362
Philipp Maier9ca7b312018-10-10 17:00:49 +0200363DEFUN(cfg_msc_mncc_guard_timeout,
364 cfg_msc_mncc_guard_timeout_cmd,
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100365 "mncc guard-timeout <0-255>",
366 MNCC_STR
367 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR)
Philipp Maier9ca7b312018-10-10 17:00:49 +0200368{
369 gsmnet->mncc_guard_timeout = atoi(argv[0]);
370 return CMD_SUCCESS;
371}
372
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100373ALIAS_DEPRECATED(cfg_msc_mncc_guard_timeout,
374 cfg_msc_deprecated_mncc_guard_timeout_cmd,
375 "mncc-guard-timeout <0-255>",
376 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR);
377
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200378DEFUN(cfg_msc_assign_tmsi, cfg_msc_assign_tmsi_cmd,
379 "assign-tmsi",
380 "Assign TMSI during Location Updating.\n")
381{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200382 gsmnet->vlr->cfg.assign_tmsi = true;
383 return CMD_SUCCESS;
384}
385
386DEFUN(cfg_msc_no_assign_tmsi, cfg_msc_no_assign_tmsi_cmd,
387 "no assign-tmsi",
388 NO_STR "Assign TMSI during Location Updating.\n")
389{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200390 gsmnet->vlr->cfg.assign_tmsi = false;
391 return CMD_SUCCESS;
392}
393
Philipp Maierfbf66102017-04-09 12:32:51 +0200394DEFUN(cfg_msc_cs7_instance_a,
395 cfg_msc_cs7_instance_a_cmd,
396 "cs7-instance-a <0-15>",
397 "Set SS7 to be used by the A-Interface.\n" "SS7 instance reference number\n")
398{
Philipp Maierfbf66102017-04-09 12:32:51 +0200399 gsmnet->a.cs7_instance = atoi(argv[0]);
400 return CMD_SUCCESS;
401}
402
403DEFUN(cfg_msc_cs7_instance_iu,
404 cfg_msc_cs7_instance_iu_cmd,
405 "cs7-instance-iu <0-15>",
406 "Set SS7 to be used by the Iu-Interface.\n" "SS7 instance reference number\n")
407{
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100408#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200409 gsmnet->iu.cs7_instance = atoi(argv[0]);
410 return CMD_SUCCESS;
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100411#else
412 vty_out(vty, "WARNING: 'cs7-instance-iu' without effect: built without Iu support%s",
413 VTY_NEWLINE);
414 return CMD_WARNING;
415#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200416}
417
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100418DEFUN(cfg_msc_auth_tuple_max_reuse_count, cfg_msc_auth_tuple_max_reuse_count_cmd,
419 "auth-tuple-max-reuse-count <-1-2147483647>",
420 "Configure authentication tuple re-use\n"
421 "0 to use each auth tuple at most once (default), >0 to limit re-use, -1 to re-use infinitely (vulnerable!).\n")
422{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100423 gsmnet->vlr->cfg.auth_tuple_max_reuse_count = atoi(argv[0]);
424 return CMD_SUCCESS;
425}
426
427DEFUN(cfg_msc_auth_tuple_reuse_on_error, cfg_msc_auth_tuple_reuse_on_error_cmd,
428 "auth-tuple-reuse-on-error (0|1)",
429 "Configure authentication tuple re-use when HLR is not responsive\n"
Oliver Smithd6e24fd2019-01-09 10:46:43 +0100430 "Never re-use auth tuples beyond auth-tuple-max-reuse-count (default)\n"
431 "If the HLR does not deliver new tuples, do re-use already available old ones.\n")
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100432{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100433 gsmnet->vlr->cfg.auth_reuse_old_sets_on_error = atoi(argv[0]) ? true : false;
434 return CMD_SUCCESS;
435}
436
Oliver Smith0fec28a2018-12-14 10:52:52 +0100437DEFUN(cfg_msc_check_imei_rqd, cfg_msc_check_imei_rqd_cmd,
438 "check-imei-rqd (0|1)",
439 "Send each IMEI to the EIR to ask if it is permitted or not. The EIR is implemented as part of OsmoHLR, "
440 "and can optionally save the IMEI in the HLR.\n"
441 "Do not send IMEIs to the EIR\n"
442 "Send each IMEI to the EIR\n")
443{
444 gsmnet->vlr->cfg.check_imei_rqd = atoi(argv[0]) ? true : false;
445 return CMD_SUCCESS;
446}
447
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100448DEFUN(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd,
449 "paging response-timer (default|<1-65535>)",
450 "Configure Paging\n"
451 "Set Paging timeout, the minimum time to pass between (unsuccessful) Pagings sent towards"
452 " BSS or RNC\n"
453 "Set to default timeout (" OSMO_STRINGIFY_VAL(MSC_PAGING_RESPONSE_TIMER_DEFAULT) " seconds)\n"
454 "Set paging timeout in seconds\n")
455{
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100456 if (!strcmp(argv[1], "default"))
457 gsmnet->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
458 else
459 gsmnet->paging_response_timer = atoi(argv[0]);
460 return CMD_SUCCESS;
461}
462
Harald Welte69c54a82018-02-09 20:41:14 +0100463DEFUN(cfg_msc_emergency_msisdn, cfg_msc_emergency_msisdn_cmd,
464 "emergency-call route-to-msisdn MSISDN",
465 "Configure Emergency Call Behaviour\n"
466 "MSISDN to which Emergency Calls are Dispatched\n"
467 "MSISDN (E.164 Phone Number)\n")
468{
Harald Welte69c54a82018-02-09 20:41:14 +0100469 osmo_talloc_replace_string(gsmnet, &gsmnet->emergency.route_to_msisdn, argv[0]);
470
471 return CMD_SUCCESS;
472}
473
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700474/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
475DEFUN(cfg_msc_sms_over_gsup, cfg_msc_sms_over_gsup_cmd,
476 "sms-over-gsup",
477 "Enable routing of SMS messages over GSUP\n")
478{
479 gsmnet->sms_over_gsup = true;
480 return CMD_SUCCESS;
481}
482
483/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
484DEFUN(cfg_msc_no_sms_over_gsup, cfg_msc_no_sms_over_gsup_cmd,
485 "no sms-over-gsup",
486 NO_STR "Disable routing of SMS messages over GSUP\n")
487{
488 gsmnet->sms_over_gsup = false;
489 return CMD_SUCCESS;
490}
491
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200492static int config_write_msc(struct vty *vty)
493{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200494 vty_out(vty, "msc%s", VTY_NEWLINE);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100495 if (gsmnet->mncc_sock_path)
496 vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE);
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100497 vty_out(vty, " mncc guard-timeout %i%s",
Philipp Maier9ca7b312018-10-10 17:00:49 +0200498 gsmnet->mncc_guard_timeout, VTY_NEWLINE);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200499 vty_out(vty, " %sassign-tmsi%s",
500 gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
501
Philipp Maierfbf66102017-04-09 12:32:51 +0200502 vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
503 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100504#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200505 vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance,
506 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100507#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200508
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100509 if (gsmnet->vlr->cfg.auth_tuple_max_reuse_count)
510 vty_out(vty, " auth-tuple-max-reuse-count %d%s",
511 OSMO_MAX(-1, gsmnet->vlr->cfg.auth_tuple_max_reuse_count),
512 VTY_NEWLINE);
513 if (gsmnet->vlr->cfg.auth_reuse_old_sets_on_error)
514 vty_out(vty, " auth-tuple-reuse-on-error 1%s",
515 VTY_NEWLINE);
516
Oliver Smith0fec28a2018-12-14 10:52:52 +0100517 if (gsmnet->vlr->cfg.check_imei_rqd)
518 vty_out(vty, " check-imei-rqd 1 %s",
519 VTY_NEWLINE);
520
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100521 if (gsmnet->paging_response_timer != MSC_PAGING_RESPONSE_TIMER_DEFAULT)
522 vty_out(vty, " paging response-timer %u%s", gsmnet->paging_response_timer, VTY_NEWLINE);
523
Harald Welte69c54a82018-02-09 20:41:14 +0100524 if (gsmnet->emergency.route_to_msisdn) {
525 vty_out(vty, " emergency-call route-to-msisdn %s%s",
526 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
527 }
528
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700529 if (gsmnet->sms_over_gsup)
530 vty_out(vty, " sms-over-gsup%s", VTY_NEWLINE);
531
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +0200532 mgcp_client_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200533#ifdef BUILD_IU
Neels Hofmeyr00e82d62017-07-05 15:19:52 +0200534 ranap_iu_vty_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200535#endif
536
537 return CMD_SUCCESS;
538}
539
Maxc51609a2018-11-09 17:13:00 +0100540DEFUN(show_bsc, show_bsc_cmd,
541 "show bsc", SHOW_STR "BSC\n")
542{
543 struct bsc_context *bsc_ctx;
544 struct osmo_ss7_instance *ss7 = osmo_ss7_instance_find(gsmnet->a.cs7_instance);
545
546 llist_for_each_entry(bsc_ctx, &gsmnet->a.bscs, list) {
547 vty_out(vty, "BSC %s%s", osmo_sccp_addr_name(ss7, &bsc_ctx->bsc_addr), VTY_NEWLINE);
548 }
549
550 return CMD_SUCCESS;
551}
552
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100553static void vty_conn_hdr(struct vty *vty)
554{
Max45df98b2019-01-17 18:44:33 +0100555 unsigned lnum = 0;
556 struct ran_conn *conn;
557
558 llist_for_each_entry(conn, &gsmnet->ran_conns, entry)
559 lnum++;
560
561 if (lnum)
562 vty_out(vty, "--ConnId RAN --LAC Use --Tokens C A5 State ------------ Subscriber%s",
563 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100564}
565
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100566static void vty_dump_one_conn(struct vty *vty, const struct ran_conn *conn)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100567{
Max45df98b2019-01-17 18:44:33 +0100568 vty_out(vty, "%08x %3s %5u %3u %08x %c /%1u %27s %22s%s",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100569 conn->a.conn_id,
Harald Welte0df904d2018-12-03 11:00:04 +0100570 osmo_rat_type_name(conn->via_ran),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100571 conn->lac,
572 conn->use_count,
573 conn->use_tokens,
574 conn->received_cm_service_request ? 'C' : '-',
Neels Hofmeyrf41658d2018-11-30 04:35:50 +0100575 conn->geran_encr.alg_id,
Neels Hofmeyr4d3a66b2018-03-31 18:45:59 +0200576 conn->fi ? osmo_fsm_inst_state_name(conn->fi) : "-",
Max45df98b2019-01-17 18:44:33 +0100577 conn->vsub ? vlr_subscr_name(conn->vsub) : "-",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100578 VTY_NEWLINE);
579}
580
581DEFUN(show_msc_conn, show_msc_conn_cmd,
582 "show connection", SHOW_STR "Subscriber Connections\n")
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200583{
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100584 struct ran_conn *conn;
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200585
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100586 vty_conn_hdr(vty);
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100587 llist_for_each_entry(conn, &gsmnet->ran_conns, entry)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100588 vty_dump_one_conn(vty, conn);
589
590 return CMD_SUCCESS;
591}
592
593static void vty_trans_hdr(struct vty *vty)
594{
Max45df98b2019-01-17 18:44:33 +0100595 unsigned lnum = 0;
596 struct gsm_trans *trans;
597
598 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
599 lnum++;
600
601 if (lnum)
602 vty_out(vty, "--ConnId -P TI -CallRef [--- Proto ---] ------------ Subscriber%s",
603 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100604}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200605
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100606static const char *get_trans_proto_str(const struct gsm_trans *trans)
607{
608 static char buf[256];
609
610 switch (trans->protocol) {
611 case GSM48_PDISC_CC:
612 snprintf(buf, sizeof(buf), "%s %4u %4u",
613 gsm48_cc_state_name(trans->cc.state),
614 trans->cc.Tcurrent,
615 trans->cc.T308_second);
616 break;
617 case GSM48_PDISC_SMS:
618 snprintf(buf, sizeof(buf), "%s %s",
619 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
620 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
621 break;
622 default:
623 buf[0] = '\0';
624 break;
625 }
626
627 return buf;
628}
629
630static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
631{
Max45df98b2019-01-17 18:44:33 +0100632 vty_out(vty, "%08x %s %02u %08x [%s] %22s%s",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100633 trans->conn ? trans->conn->a.conn_id : 0,
634 gsm48_pdisc_name(trans->protocol),
635 trans->transaction_id,
636 trans->callref,
Max45df98b2019-01-17 18:44:33 +0100637 get_trans_proto_str(trans),
638 trans->vsub ? vlr_subscr_name(trans->vsub) : "-",
639 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100640}
641
642DEFUN(show_msc_transaction, show_msc_transaction_cmd,
643 "show transaction", SHOW_STR "Transactions\n")
644{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100645 struct gsm_trans *trans;
646
647 vty_trans_hdr(vty);
648 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
649 vty_dump_one_trans(vty, trans);
650
651 return CMD_SUCCESS;
652}
653
654static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
655{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100656 struct gsm_trans *trans;
657 int reqs;
658 struct llist_head *entry;
659
660 if (strlen(vsub->name))
661 vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
662 if (strlen(vsub->msisdn))
663 vty_out(vty, " Extension: %s%s", vsub->msisdn,
664 VTY_NEWLINE);
665 vty_out(vty, " LAC: %d/0x%x%s",
Max7d41d872018-12-19 11:48:33 +0100666 vsub->cgi.lai.lac, vsub->cgi.lai.lac, VTY_NEWLINE);
Philipp Maier2a0ac3b2018-12-17 10:03:50 +0100667 vty_out(vty, " RAN: %s%s",
Neels Hofmeyr7814a832018-12-26 00:40:18 +0100668 osmo_rat_type_name(vsub->cs.attached_via_ran), VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100669 vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
670 if (vsub->tmsi != GSM_RESERVED_TMSI)
671 vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
672 VTY_NEWLINE);
673 if (vsub->tmsi_new != GSM_RESERVED_TMSI)
674 vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
675 VTY_NEWLINE);
Philipp Maier6d71ccf2018-12-14 13:30:14 +0100676 if (vsub->imei[0] != '\0')
677 vty_out(vty, " IMEI: %s%s", vsub->imei, VTY_NEWLINE);
678 if (vsub->imeisv[0] != '\0')
679 vty_out(vty, " IMEISV: %s%s", vsub->imeisv, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100680
Philipp Maier89561bc2018-12-14 13:34:25 +0100681 vty_out(vty, " Flags: %s", VTY_NEWLINE);
682 vty_out(vty, " IMSI detached: %s%s",
683 vsub->imsi_detached_flag ? "true" : "false", VTY_NEWLINE);
684 vty_out(vty, " Conf. by radio contact: %s%s",
685 vsub->conf_by_radio_contact_ind ? "true" : "false",
686 VTY_NEWLINE);
687 vty_out(vty, " Subscr. data conf. by HLR: %s%s",
688 vsub->sub_dataconf_by_hlr_ind ? "true" : "false", VTY_NEWLINE);
689 vty_out(vty, " Location conf. in HLR: %s%s",
690 vsub->loc_conf_in_hlr_ind ? "true" : "false", VTY_NEWLINE);
691 vty_out(vty, " Subscriber dormant: %s%s",
692 vsub->dormant_ind ? "true" : "false", VTY_NEWLINE);
693 vty_out(vty, " Received cancel locataion: %s%s",
694 vsub->cancel_loc_rx ? "true" : "false", VTY_NEWLINE);
695 vty_out(vty, " MS not reachable: %s%s",
696 vsub->ms_not_reachable_flag ? "true" : "false", VTY_NEWLINE);
697 vty_out(vty, " LA allowed: %s%s",
698 vsub->la_allowed ? "true" : "false", VTY_NEWLINE);
699
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100700#if 0
701 /* TODO: add this to vlr_subscr? */
702 if (vsub->auth_info.auth_algo != AUTH_ALGO_NONE) {
703 struct gsm_auth_info *i = &vsub->auth_info;
704 vty_out(vty, " A3A8 algorithm id: %d%s",
705 i->auth_algo, VTY_NEWLINE);
706 vty_out(vty, " A3A8 Ki: %s%s",
707 osmo_hexdump(i->a3a8_ki, i->a3a8_ki_len),
708 VTY_NEWLINE);
709 }
710#endif
711
712 if (vsub->last_tuple) {
Neels Hofmeyr8b6e5362018-11-30 02:57:33 +0100713 struct vlr_auth_tuple *t = vsub->last_tuple;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100714 vty_out(vty, " A3A8 last tuple (used %d times):%s",
715 t->use_count, VTY_NEWLINE);
716 vty_out(vty, " seq # : %d%s",
717 t->key_seq, VTY_NEWLINE);
718 vty_out(vty, " RAND : %s%s",
719 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
720 VTY_NEWLINE);
721 vty_out(vty, " SRES : %s%s",
722 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
723 VTY_NEWLINE);
724 vty_out(vty, " Kc : %s%s",
725 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
726 VTY_NEWLINE);
727 }
728
729 reqs = 0;
730 llist_for_each(entry, &vsub->cs.requests)
731 reqs += 1;
732 vty_out(vty, " Paging: %s paging for %d requests%s",
733 vsub->cs.is_paging ? "is" : "not", reqs, VTY_NEWLINE);
Harald Welte0df904d2018-12-03 11:00:04 +0100734
735 /* SGs related */
736 vty_out(vty, " SGs-state: %s%s",
737 osmo_fsm_inst_state_name(vsub->sgs_fsm), VTY_NEWLINE);
738 if (vsub->sgs.mme_name && strlen(vsub->sgs.mme_name))
739 vty_out(vty, " SGs-MME: %s%s", vsub->sgs.mme_name, VTY_NEWLINE);
740 else
741 vty_out(vty, " SGs-MME: (none)%s", VTY_NEWLINE);
742
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100743 vty_out(vty, " Use count: %u%s", vsub->use_count, VTY_NEWLINE);
744
745 /* Connection */
746 if (vsub->msc_conn_ref) {
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100747 struct ran_conn *conn = vsub->msc_conn_ref;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100748 vty_conn_hdr(vty);
749 vty_dump_one_conn(vty, conn);
750 }
751
752 /* Transactions */
753 vty_trans_hdr(vty);
754 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
755 if (trans->vsub != vsub)
756 continue;
757 vty_dump_one_trans(vty, trans);
758 }
759}
760
761/* Subscriber */
762DEFUN(show_subscr_cache,
763 show_subscr_cache_cmd,
764 "show subscriber cache",
765 SHOW_STR "Show information about subscribers\n"
766 "Display contents of subscriber cache\n")
767{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100768 struct vlr_subscr *vsub;
769 int count = 0;
770
771 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
772 if (++count > 100) {
773 vty_out(vty, "%% More than %d subscribers in cache,"
774 " stopping here.%s", count-1, VTY_NEWLINE);
775 break;
776 }
777 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
778 subscr_dump_full_vty(vty, vsub);
Harald Welte69c54a82018-02-09 20:41:14 +0100779 }
780
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200781 return CMD_SUCCESS;
782}
783
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100784DEFUN(sms_send_pend,
785 sms_send_pend_cmd,
786 "sms send pending",
787 "SMS related commands\n" "SMS Sending related commands\n"
788 "Send all pending SMS")
789{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100790 struct gsm_sms *sms;
791 unsigned long long sms_id = 0;
792
793 while (1) {
794 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
795 if (!sms)
796 break;
797
798 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700799 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100800
801 sms_id = sms->id + 1;
802 }
803
804 return CMD_SUCCESS;
805}
806
807DEFUN(sms_delete_expired,
808 sms_delete_expired_cmd,
809 "sms delete expired",
810 "SMS related commands\n" "SMS Database related commands\n"
811 "Delete all expired SMS")
812{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100813 struct gsm_sms *sms;
814 unsigned long long sms_id = 0;
815 long long num_deleted = 0;
816
817 while (1) {
818 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
819 if (!sms)
820 break;
821
822 /* Skip SMS which are currently queued for sending. */
823 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
824 continue;
825
826 /* Expiration check is performed by the DB layer. */
827 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
828 num_deleted++;
829
830 sms_id = sms->id + 1;
831 }
832
833 if (num_deleted == 0) {
834 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
835 return CMD_WARNING;
836 }
837
838 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
839 return CMD_SUCCESS;
840}
841
842static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +0200843 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100844 char *str, uint8_t tp_pid)
845{
846 struct gsm_network *net = receiver->vlr->user_ctx;
847 struct gsm_sms *sms;
848
Harald Welte39b55482018-04-09 19:19:33 +0200849 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100850 sms->protocol_id = tp_pid;
851
852 /* store in database for the queue */
853 if (db_sms_store(sms) != 0) {
854 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
855 sms_free(sms);
856 return CMD_WARNING;
857 }
858 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
859
860 sms_free(sms);
861 sms_queue_trigger(net->sms_queue);
862 return CMD_SUCCESS;
863}
864
865static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
866 const char *type,
867 const char *id)
868{
869 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
870 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id);
871 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
872 return vlr_subscr_find_by_imsi(gsmnet->vlr, id);
873 else if (!strcmp(type, "tmsi"))
874 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id));
875
876 return NULL;
877}
878#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
879#define SUBSCR_HELP "Operations on a Subscriber\n" \
880 "Identify subscriber by MSISDN (phone number)\n" \
881 "Legacy alias for 'msisdn'\n" \
882 "Identify subscriber by IMSI\n" \
883 "Identify subscriber by TMSI\n" \
884 "Identify subscriber by database ID\n" \
885 "Identifier for the subscriber\n"
886
887DEFUN(show_subscr,
888 show_subscr_cmd,
889 "show subscriber " SUBSCR_TYPES " ID",
890 SHOW_STR SUBSCR_HELP)
891{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100892 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
893 argv[1]);
894
895 if (!vsub) {
896 vty_out(vty, "%% No subscriber found for %s %s%s",
897 argv[0], argv[1], VTY_NEWLINE);
898 return CMD_WARNING;
899 }
900
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100901 /* In the vty output to the user, exclude this local use count added by vlr_subscr_get() in get_vsub_by_argv().
902 * This works, because: for get_vsub_by_argv() to succeed, there *must* have been at least one use count before
903 * this, and since this is not multi-threaded, this vlr_subscr_put() cannot possibly reach a count of 0. */
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100904 vlr_subscr_put(vsub);
905
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100906 subscr_dump_full_vty(vty, vsub);
907
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100908 return CMD_SUCCESS;
909}
910
911DEFUN(subscriber_create,
912 subscriber_create_cmd,
913 "subscriber create imsi ID",
914 "Operations on a Subscriber\n" \
915 "Create new subscriber\n" \
916 "Identify the subscriber by his IMSI\n" \
917 "Identifier for the subscriber\n")
918{
919 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
920 VTY_NEWLINE);
921 return CMD_WARNING;
922}
923
924DEFUN(subscriber_send_pending_sms,
925 subscriber_send_pending_sms_cmd,
926 "subscriber " SUBSCR_TYPES " ID sms pending-send",
927 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
928{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100929 struct vlr_subscr *vsub;
930 struct gsm_sms *sms;
931
932 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
933 if (!vsub) {
934 vty_out(vty, "%% No subscriber found for %s %s%s",
935 argv[0], argv[1], VTY_NEWLINE);
936 return CMD_WARNING;
937 }
938
939 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
940 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700941 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100942
943 vlr_subscr_put(vsub);
944
945 return CMD_SUCCESS;
946}
947
948DEFUN(subscriber_send_sms,
949 subscriber_send_sms_cmd,
950 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
951 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
952{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100953 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200954 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100955 char *str;
956 int rc;
957
958 if (!vsub) {
959 vty_out(vty, "%% No subscriber found for %s %s%s",
960 argv[0], argv[1], VTY_NEWLINE);
961 rc = CMD_WARNING;
962 goto err;
963 }
964
Harald Welte39b55482018-04-09 19:19:33 +0200965 if (!strcmp(argv[2], "msisdn"))
966 sender_msisdn = argv[3];
967 else {
968 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
969 if (!sender) {
970 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
971 rc = CMD_WARNING;
972 goto err;
973 }
974 sender_msisdn = sender->msisdn;
975 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100976 }
977
978 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +0200979 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100980 talloc_free(str);
981
982err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100983 if (vsub)
984 vlr_subscr_put(vsub);
985
986 return rc;
987}
988
989DEFUN(subscriber_silent_sms,
990 subscriber_silent_sms_cmd,
991
992 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
993 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
994{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100995 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200996 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100997 char *str;
998 int rc;
999
1000 if (!vsub) {
1001 vty_out(vty, "%% No subscriber found for %s %s%s",
1002 argv[0], argv[1], VTY_NEWLINE);
1003 rc = CMD_WARNING;
1004 goto err;
1005 }
1006
Harald Welte39b55482018-04-09 19:19:33 +02001007 if (!strcmp(argv[2], "msisdn")) {
1008 sender_msisdn = argv[3];
1009 } else {
1010 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1011 if (!sender) {
1012 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1013 rc = CMD_WARNING;
1014 goto err;
1015 }
1016 sender_msisdn = sender->msisdn;
1017 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001018 }
1019
1020 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001021 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001022 talloc_free(str);
1023
1024err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001025 if (vsub)
1026 vlr_subscr_put(vsub);
1027
1028 return rc;
1029}
1030
1031#define CHAN_TYPES "(any|tch/f|tch/any|sdcch)"
1032#define CHAN_TYPE_HELP \
1033 "Any channel\n" \
1034 "TCH/F channel\n" \
1035 "Any TCH channel\n" \
1036 "SDCCH channel\n"
1037
1038DEFUN(subscriber_silent_call_start,
1039 subscriber_silent_call_start_cmd,
1040 "subscriber " SUBSCR_TYPES " ID silent-call start (any|tch/f|tch/any|sdcch)",
1041 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
1042 CHAN_TYPE_HELP)
1043{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001044 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1045 int rc, type;
1046
1047 if (!vsub) {
1048 vty_out(vty, "%% No subscriber found for %s %s%s",
1049 argv[0], argv[1], VTY_NEWLINE);
1050 return CMD_WARNING;
1051 }
1052
1053 if (!strcmp(argv[2], "tch/f"))
1054 type = RSL_CHANNEED_TCH_F;
1055 else if (!strcmp(argv[2], "tch/any"))
1056 type = RSL_CHANNEED_TCH_ForH;
1057 else if (!strcmp(argv[2], "sdcch"))
1058 type = RSL_CHANNEED_SDCCH;
1059 else
1060 type = RSL_CHANNEED_ANY; /* Defaults to ANY */
1061
1062 rc = gsm_silent_call_start(vsub, vty, type);
1063 switch (rc) {
1064 case -ENODEV:
1065 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
1066 break;
1067 default:
1068 if (rc)
1069 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
1070 else
1071 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
1072 break;
1073 }
1074
1075 vlr_subscr_put(vsub);
1076 return rc ? CMD_WARNING : CMD_SUCCESS;
1077}
1078
1079DEFUN(subscriber_silent_call_stop,
1080 subscriber_silent_call_stop_cmd,
1081 "subscriber " SUBSCR_TYPES " ID silent-call stop",
1082 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
1083 CHAN_TYPE_HELP)
1084{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001085 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1086 int rc;
1087
1088 if (!vsub) {
1089 vty_out(vty, "%% No subscriber found for %s %s%s",
1090 argv[0], argv[1], VTY_NEWLINE);
1091 return CMD_WARNING;
1092 }
1093
1094 rc = gsm_silent_call_stop(vsub);
1095 switch (rc) {
1096 case -ENODEV:
1097 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
1098 break;
1099 case -ENOENT:
1100 vty_out(vty, "%% Subscriber has no silent call active%s",
1101 VTY_NEWLINE);
1102 break;
1103 default:
1104 if (rc)
1105 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
1106 else
1107 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
1108 break;
1109 }
1110
1111 vlr_subscr_put(vsub);
1112 return rc ? CMD_WARNING : CMD_SUCCESS;
1113}
1114
1115DEFUN(subscriber_ussd_notify,
1116 subscriber_ussd_notify_cmd,
1117 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1118 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1119 "Alerting Level 0\n"
1120 "Alerting Level 1\n"
1121 "Alerting Level 2\n"
1122 "Text of USSD message to send\n")
1123{
1124 char *text;
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001125 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001126 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1127 int level;
1128
1129 if (!vsub) {
1130 vty_out(vty, "%% No subscriber found for %s %s%s",
1131 argv[0], argv[1], VTY_NEWLINE);
1132 return CMD_WARNING;
1133 }
1134
1135 level = atoi(argv[2]);
1136 text = argv_concat(argv, argc, 3);
1137 if (!text) {
1138 vlr_subscr_put(vsub);
1139 return CMD_WARNING;
1140 }
1141
1142 conn = connection_for_subscr(vsub);
1143 if (!conn) {
1144 vty_out(vty, "%% An active connection is required for %s %s%s",
1145 argv[0], argv[1], VTY_NEWLINE);
1146 vlr_subscr_put(vsub);
1147 talloc_free(text);
1148 return CMD_WARNING;
1149 }
1150
1151 msc_send_ussd_notify(conn, level, text);
Vadim Yanitskiyf20c6b72018-11-29 01:20:58 +07001152 /* FIXME: since we don't allocate a transaction here,
1153 * we use dummy GSM 04.07 transaction ID. */
1154 msc_send_ussd_release_complete(conn, 0x00);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001155
1156 vlr_subscr_put(vsub);
1157 talloc_free(text);
1158 return CMD_SUCCESS;
1159}
1160
1161DEFUN(subscriber_paging,
1162 subscriber_paging_cmd,
1163 "subscriber " SUBSCR_TYPES " ID paging",
1164 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1165{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001166 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1167 struct subscr_request *req;
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
Harald Welte0df904d2018-12-03 11:00:04 +01001175 req = subscr_request_conn(vsub, NULL, NULL, "manual Paging from VTY", SGSAP_SERV_IND_CS_CALL);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001176 if (req)
1177 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1178 else
1179 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1180
1181 vlr_subscr_put(vsub);
1182 return req ? CMD_SUCCESS : CMD_WARNING;
1183}
1184
1185static int loop_by_char(uint8_t ch)
1186{
1187 switch (ch) {
1188 case 'a':
1189 return GSM414_LOOP_A;
1190 case 'b':
1191 return GSM414_LOOP_B;
1192 case 'c':
1193 return GSM414_LOOP_C;
1194 case 'd':
1195 return GSM414_LOOP_D;
1196 case 'e':
1197 return GSM414_LOOP_E;
1198 case 'f':
1199 return GSM414_LOOP_F;
1200 case 'i':
1201 return GSM414_LOOP_I;
1202 }
1203 return -1;
1204}
1205
1206DEFUN(subscriber_mstest_close,
1207 subscriber_mstest_close_cmd,
1208 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1209 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1210 "Close a TCH Loop inside the MS\n"
1211 "Loop Type A\n"
1212 "Loop Type B\n"
1213 "Loop Type C\n"
1214 "Loop Type D\n"
1215 "Loop Type E\n"
1216 "Loop Type F\n"
1217 "Loop Type I\n")
1218{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001219 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001220 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1221 const char *loop_str;
1222 int loop_mode;
1223
1224 if (!vsub) {
1225 vty_out(vty, "%% No subscriber found for %s %s%s",
1226 argv[0], argv[1], VTY_NEWLINE);
1227 return CMD_WARNING;
1228 }
1229
1230 loop_str = argv[2];
1231 loop_mode = loop_by_char(loop_str[0]);
1232
1233 conn = connection_for_subscr(vsub);
1234 if (!conn) {
1235 vty_out(vty, "%% An active connection is required for %s %s%s",
1236 argv[0], argv[1], VTY_NEWLINE);
1237 vlr_subscr_put(vsub);
1238 return CMD_WARNING;
1239 }
1240
1241 gsm0414_tx_close_tch_loop_cmd(conn, loop_mode);
1242
1243 return CMD_SUCCESS;
1244}
1245
1246DEFUN(subscriber_mstest_open,
1247 subscriber_mstest_open_cmd,
1248 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1249 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1250 "Open a TCH Loop inside the MS\n")
1251{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001252 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001253 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1254
1255 if (!vsub) {
1256 vty_out(vty, "%% No subscriber found for %s %s%s",
1257 argv[0], argv[1], VTY_NEWLINE);
1258 return CMD_WARNING;
1259 }
1260
1261 conn = connection_for_subscr(vsub);
1262 if (!conn) {
1263 vty_out(vty, "%% An active connection is required for %s %s%s",
1264 argv[0], argv[1], VTY_NEWLINE);
1265 vlr_subscr_put(vsub);
1266 return CMD_WARNING;
1267 }
1268
1269 gsm0414_tx_open_loop_cmd(conn);
1270
1271 return CMD_SUCCESS;
1272}
1273
1274DEFUN(ena_subscr_expire,
1275 ena_subscr_expire_cmd,
1276 "subscriber " SUBSCR_TYPES " ID expire",
1277 SUBSCR_HELP "Expire the subscriber Now\n")
1278{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001279 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1280 argv[1]);
1281
1282 if (!vsub) {
1283 vty_out(vty, "%% No subscriber found for %s %s%s",
1284 argv[0], argv[1], VTY_NEWLINE);
1285 return CMD_WARNING;
1286 }
1287
1288 if (vlr_subscr_expire(vsub))
1289 vty_out(vty, "%% VLR released subscriber %s%s",
1290 vlr_subscr_name(vsub), VTY_NEWLINE);
1291
1292 if (vsub->use_count > 1)
1293 vty_out(vty, "%% Subscriber %s is still in use,"
1294 " should be released soon%s",
1295 vlr_subscr_name(vsub), VTY_NEWLINE);
1296
1297 vlr_subscr_put(vsub);
1298 return CMD_SUCCESS;
1299}
1300
1301static int scall_cbfn(unsigned int subsys, unsigned int signal,
1302 void *handler_data, void *signal_data)
1303{
1304 struct scall_signal_data *sigdata = signal_data;
1305 struct vty *vty = sigdata->data;
1306
1307 switch (signal) {
1308 case S_SCALL_SUCCESS:
1309 vty_out(vty, "%% silent call success%s", VTY_NEWLINE);
1310 break;
1311 case S_SCALL_EXPIRED:
1312 vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE);
1313 break;
1314 }
1315 return 0;
1316}
1317
1318DEFUN(show_stats,
1319 show_stats_cmd,
1320 "show statistics",
1321 SHOW_STR "Display network statistics\n")
1322{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001323 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001324 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1325 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1326 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001327 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001328 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001329 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001330 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001331 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001332 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1333 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001334 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001335 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001336 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1337 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001338 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001339 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001340 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1341 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1342 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001343 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001344 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001345 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1346 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001347 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001348 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001349 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1350 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001351 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001352 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001353 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1354 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1355 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1356 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1357 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001358 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001359 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1360 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1361 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1362 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1363 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001364 return CMD_SUCCESS;
1365}
1366
1367DEFUN(show_smsqueue,
1368 show_smsqueue_cmd,
1369 "show sms-queue",
1370 SHOW_STR "Display SMSqueue statistics\n")
1371{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001372 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001373 return CMD_SUCCESS;
1374}
1375
1376DEFUN(smsqueue_trigger,
1377 smsqueue_trigger_cmd,
1378 "sms-queue trigger",
1379 "SMS Queue\n" "Trigger sending messages\n")
1380{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001381 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001382 return CMD_SUCCESS;
1383}
1384
1385DEFUN(smsqueue_max,
1386 smsqueue_max_cmd,
1387 "sms-queue max-pending <1-500>",
1388 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1389{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001390 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001391 return CMD_SUCCESS;
1392}
1393
1394DEFUN(smsqueue_clear,
1395 smsqueue_clear_cmd,
1396 "sms-queue clear",
1397 "SMS Queue\n" "Clear the queue of pending SMS\n")
1398{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001399 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001400 return CMD_SUCCESS;
1401}
1402
1403DEFUN(smsqueue_fail,
1404 smsqueue_fail_cmd,
1405 "sms-queue max-failure <1-500>",
1406 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1407{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001408 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001409 return CMD_SUCCESS;
1410}
1411
1412
1413DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1414 "mncc-int", "Configure internal MNCC handler")
1415{
1416 vty->node = MNCC_INT_NODE;
1417
1418 return CMD_SUCCESS;
1419}
1420
1421static struct cmd_node mncc_int_node = {
1422 MNCC_INT_NODE,
1423 "%s(config-mncc-int)# ",
1424 1,
1425};
1426
1427static const struct value_string tchf_codec_names[] = {
1428 { GSM48_CMODE_SPEECH_V1, "fr" },
1429 { GSM48_CMODE_SPEECH_EFR, "efr" },
1430 { GSM48_CMODE_SPEECH_AMR, "amr" },
1431 { 0, NULL }
1432};
1433
1434static const struct value_string tchh_codec_names[] = {
1435 { GSM48_CMODE_SPEECH_V1, "hr" },
1436 { GSM48_CMODE_SPEECH_AMR, "amr" },
1437 { 0, NULL }
1438};
1439
1440static int config_write_mncc_int(struct vty *vty)
1441{
1442 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1443 vty_out(vty, " default-codec tch-f %s%s",
1444 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1445 VTY_NEWLINE);
1446 vty_out(vty, " default-codec tch-h %s%s",
1447 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1448 VTY_NEWLINE);
1449
1450 return CMD_SUCCESS;
1451}
1452
1453DEFUN(mnccint_def_codec_f,
1454 mnccint_def_codec_f_cmd,
1455 "default-codec tch-f (fr|efr|amr)",
1456 "Set default codec\n" "Codec for TCH/F\n"
1457 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1458{
1459 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1460
1461 return CMD_SUCCESS;
1462}
1463
1464DEFUN(mnccint_def_codec_h,
1465 mnccint_def_codec_h_cmd,
1466 "default-codec tch-h (hr|amr)",
1467 "Set default codec\n" "Codec for TCH/H\n"
1468 "Half-Rate\n" "Adaptive Multi-Rate\n")
1469{
1470 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1471
1472 return CMD_SUCCESS;
1473}
1474
1475
1476DEFUN(logging_fltr_imsi,
1477 logging_fltr_imsi_cmd,
1478 "logging filter imsi IMSI",
1479 LOGGING_STR FILTER_STR
1480 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1481{
1482 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001483 struct log_target *tgt = osmo_log_vty2tgt(vty);
1484 const char *imsi = argv[0];
1485
1486 if (!tgt)
1487 return CMD_WARNING;
1488
1489 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi);
1490
1491 if (!vlr_subscr) {
1492 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1493 argv[0], VTY_NEWLINE);
1494 return CMD_WARNING;
1495 }
1496
1497 log_set_filter_vlr_subscr(tgt, vlr_subscr);
1498 return CMD_SUCCESS;
1499}
1500
1501static struct cmd_node hlr_node = {
1502 HLR_NODE,
1503 "%s(config-hlr)# ",
1504 1,
1505};
1506
1507DEFUN(cfg_hlr, cfg_hlr_cmd,
1508 "hlr", "Configure connection to the HLR")
1509{
1510 vty->node = HLR_NODE;
1511 return CMD_SUCCESS;
1512}
1513
1514DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1515 "Remote GSUP address of the HLR\n"
1516 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1517{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001518 talloc_free((void*)gsmnet->gsup_server_addr_str);
1519 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1520 return CMD_SUCCESS;
1521}
1522
1523DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1524 "Remote GSUP port of the HLR\n"
1525 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1526{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001527 gsmnet->gsup_server_port = atoi(argv[0]);
1528 return CMD_SUCCESS;
1529}
1530
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001531DEFUN(cfg_hlr_ipa_name,
1532 cfg_hlr_ipa_name_cmd,
1533 "ipa-name NAME",
1534 "Set the IPA name of this MSC\n"
1535 "A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. "
1536 "This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. "
1537 "The default is 'MSC-00-00-00-00-00-00'.\n")
1538{
1539 if (vty->type != VTY_FILE) {
1540 vty_out(vty, "The IPA name cannot be changed at run-time; "
1541 "It can only be set in the configuraton file.%s", VTY_NEWLINE);
1542 return CMD_WARNING;
1543 }
1544
1545 gsmnet->msc_ipa_name = talloc_strdup(gsmnet, argv[0]);
1546 return CMD_SUCCESS;
1547}
1548
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001549static int config_write_hlr(struct vty *vty)
1550{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001551 vty_out(vty, "hlr%s", VTY_NEWLINE);
1552 vty_out(vty, " remote-ip %s%s",
1553 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1554 vty_out(vty, " remote-port %u%s",
1555 gsmnet->gsup_server_port, VTY_NEWLINE);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001556 if (gsmnet->msc_ipa_name)
1557 vty_out(vty, " ipa-name %s%s", gsmnet->msc_ipa_name, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001558 return CMD_SUCCESS;
1559}
1560
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001561void msc_vty_init(struct gsm_network *msc_network)
1562{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001563 OSMO_ASSERT(gsmnet == NULL);
1564 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001565
1566 osmo_stats_vty_add_cmds();
1567
1568 install_element(CONFIG_NODE, &cfg_net_cmd);
1569 install_node(&net_node, config_write_net);
1570 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
1571 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1572 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1573 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
1574 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
1575 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
1576 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
1577 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
1578 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
1579 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
1580 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
1581 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
1582 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001583
1584 install_element(CONFIG_NODE, &cfg_msc_cmd);
1585 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001586 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01001587 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
1588 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02001589 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01001590 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001591 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01001592 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
1593 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Oliver Smith0fec28a2018-12-14 10:52:52 +01001594 install_element(MSC_NODE, &cfg_msc_check_imei_rqd_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001595 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
1596 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01001597 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01001598 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +07001599 install_element(MSC_NODE, &cfg_msc_sms_over_gsup_cmd);
1600 install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001601
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02001602 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001603#ifdef BUILD_IU
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +01001604 ranap_iu_vty_init(MSC_NODE, &msc_network->iu.rab_assign_addr_enc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001605#endif
Harald Welte0df904d2018-12-03 11:00:04 +01001606 sgs_vty_init();
Stefan Sperling617ac802018-02-22 17:58:20 +01001607 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001608
1609 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
1610
1611 install_element_ve(&show_subscr_cmd);
1612 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01001613 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001614 install_element_ve(&show_msc_conn_cmd);
1615 install_element_ve(&show_msc_transaction_cmd);
1616
1617 install_element_ve(&sms_send_pend_cmd);
1618 install_element_ve(&sms_delete_expired_cmd);
1619
1620 install_element_ve(&subscriber_create_cmd);
1621 install_element_ve(&subscriber_send_sms_cmd);
1622 install_element_ve(&subscriber_silent_sms_cmd);
1623 install_element_ve(&subscriber_silent_call_start_cmd);
1624 install_element_ve(&subscriber_silent_call_stop_cmd);
1625 install_element_ve(&subscriber_ussd_notify_cmd);
1626 install_element_ve(&subscriber_mstest_close_cmd);
1627 install_element_ve(&subscriber_mstest_open_cmd);
1628 install_element_ve(&subscriber_paging_cmd);
1629 install_element_ve(&show_stats_cmd);
1630 install_element_ve(&show_smsqueue_cmd);
1631 install_element_ve(&logging_fltr_imsi_cmd);
1632
1633 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
1634 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
1635 install_element(ENABLE_NODE, &smsqueue_max_cmd);
1636 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
1637 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
1638 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
1639
1640 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1641 install_node(&mncc_int_node, config_write_mncc_int);
1642 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1643 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1644
1645 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
1646
1647 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1648 install_node(&hlr_node, config_write_hlr);
1649 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1650 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001651 install_element(HLR_NODE, &cfg_hlr_ipa_name_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001652}