blob: e1019a2875f1e52d12d27cc0e17cfc52787ee9a9 [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);
1152 msc_send_ussd_release_complete(conn);
1153
1154 vlr_subscr_put(vsub);
1155 talloc_free(text);
1156 return CMD_SUCCESS;
1157}
1158
1159DEFUN(subscriber_paging,
1160 subscriber_paging_cmd,
1161 "subscriber " SUBSCR_TYPES " ID paging",
1162 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1163{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001164 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1165 struct subscr_request *req;
1166
1167 if (!vsub) {
1168 vty_out(vty, "%% No subscriber found for %s %s%s",
1169 argv[0], argv[1], VTY_NEWLINE);
1170 return CMD_WARNING;
1171 }
1172
Harald Welte0df904d2018-12-03 11:00:04 +01001173 req = subscr_request_conn(vsub, NULL, NULL, "manual Paging from VTY", SGSAP_SERV_IND_CS_CALL);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001174 if (req)
1175 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1176 else
1177 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1178
1179 vlr_subscr_put(vsub);
1180 return req ? CMD_SUCCESS : CMD_WARNING;
1181}
1182
1183static int loop_by_char(uint8_t ch)
1184{
1185 switch (ch) {
1186 case 'a':
1187 return GSM414_LOOP_A;
1188 case 'b':
1189 return GSM414_LOOP_B;
1190 case 'c':
1191 return GSM414_LOOP_C;
1192 case 'd':
1193 return GSM414_LOOP_D;
1194 case 'e':
1195 return GSM414_LOOP_E;
1196 case 'f':
1197 return GSM414_LOOP_F;
1198 case 'i':
1199 return GSM414_LOOP_I;
1200 }
1201 return -1;
1202}
1203
1204DEFUN(subscriber_mstest_close,
1205 subscriber_mstest_close_cmd,
1206 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1207 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1208 "Close a TCH Loop inside the MS\n"
1209 "Loop Type A\n"
1210 "Loop Type B\n"
1211 "Loop Type C\n"
1212 "Loop Type D\n"
1213 "Loop Type E\n"
1214 "Loop Type F\n"
1215 "Loop Type I\n")
1216{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001217 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001218 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1219 const char *loop_str;
1220 int loop_mode;
1221
1222 if (!vsub) {
1223 vty_out(vty, "%% No subscriber found for %s %s%s",
1224 argv[0], argv[1], VTY_NEWLINE);
1225 return CMD_WARNING;
1226 }
1227
1228 loop_str = argv[2];
1229 loop_mode = loop_by_char(loop_str[0]);
1230
1231 conn = connection_for_subscr(vsub);
1232 if (!conn) {
1233 vty_out(vty, "%% An active connection is required for %s %s%s",
1234 argv[0], argv[1], VTY_NEWLINE);
1235 vlr_subscr_put(vsub);
1236 return CMD_WARNING;
1237 }
1238
1239 gsm0414_tx_close_tch_loop_cmd(conn, loop_mode);
1240
1241 return CMD_SUCCESS;
1242}
1243
1244DEFUN(subscriber_mstest_open,
1245 subscriber_mstest_open_cmd,
1246 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1247 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1248 "Open a TCH Loop inside the MS\n")
1249{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001250 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001251 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1252
1253 if (!vsub) {
1254 vty_out(vty, "%% No subscriber found for %s %s%s",
1255 argv[0], argv[1], VTY_NEWLINE);
1256 return CMD_WARNING;
1257 }
1258
1259 conn = connection_for_subscr(vsub);
1260 if (!conn) {
1261 vty_out(vty, "%% An active connection is required for %s %s%s",
1262 argv[0], argv[1], VTY_NEWLINE);
1263 vlr_subscr_put(vsub);
1264 return CMD_WARNING;
1265 }
1266
1267 gsm0414_tx_open_loop_cmd(conn);
1268
1269 return CMD_SUCCESS;
1270}
1271
1272DEFUN(ena_subscr_expire,
1273 ena_subscr_expire_cmd,
1274 "subscriber " SUBSCR_TYPES " ID expire",
1275 SUBSCR_HELP "Expire the subscriber Now\n")
1276{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001277 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1278 argv[1]);
1279
1280 if (!vsub) {
1281 vty_out(vty, "%% No subscriber found for %s %s%s",
1282 argv[0], argv[1], VTY_NEWLINE);
1283 return CMD_WARNING;
1284 }
1285
1286 if (vlr_subscr_expire(vsub))
1287 vty_out(vty, "%% VLR released subscriber %s%s",
1288 vlr_subscr_name(vsub), VTY_NEWLINE);
1289
1290 if (vsub->use_count > 1)
1291 vty_out(vty, "%% Subscriber %s is still in use,"
1292 " should be released soon%s",
1293 vlr_subscr_name(vsub), VTY_NEWLINE);
1294
1295 vlr_subscr_put(vsub);
1296 return CMD_SUCCESS;
1297}
1298
1299static int scall_cbfn(unsigned int subsys, unsigned int signal,
1300 void *handler_data, void *signal_data)
1301{
1302 struct scall_signal_data *sigdata = signal_data;
1303 struct vty *vty = sigdata->data;
1304
1305 switch (signal) {
1306 case S_SCALL_SUCCESS:
1307 vty_out(vty, "%% silent call success%s", VTY_NEWLINE);
1308 break;
1309 case S_SCALL_EXPIRED:
1310 vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE);
1311 break;
1312 }
1313 return 0;
1314}
1315
1316DEFUN(show_stats,
1317 show_stats_cmd,
1318 "show statistics",
1319 SHOW_STR "Display network statistics\n")
1320{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001321 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001322 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1323 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1324 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001325 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001326 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001327 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001328 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001329 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001330 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1331 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001332 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001333 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001334 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1335 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001336 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001337 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001338 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1339 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1340 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001341 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001342 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001343 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1344 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001345 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001346 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001347 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1348 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001349 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001350 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001351 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1352 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1353 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1354 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1355 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001356 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001357 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1358 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1359 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1360 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1361 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001362 return CMD_SUCCESS;
1363}
1364
1365DEFUN(show_smsqueue,
1366 show_smsqueue_cmd,
1367 "show sms-queue",
1368 SHOW_STR "Display SMSqueue statistics\n")
1369{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001370 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001371 return CMD_SUCCESS;
1372}
1373
1374DEFUN(smsqueue_trigger,
1375 smsqueue_trigger_cmd,
1376 "sms-queue trigger",
1377 "SMS Queue\n" "Trigger sending messages\n")
1378{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001379 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001380 return CMD_SUCCESS;
1381}
1382
1383DEFUN(smsqueue_max,
1384 smsqueue_max_cmd,
1385 "sms-queue max-pending <1-500>",
1386 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1387{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001388 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001389 return CMD_SUCCESS;
1390}
1391
1392DEFUN(smsqueue_clear,
1393 smsqueue_clear_cmd,
1394 "sms-queue clear",
1395 "SMS Queue\n" "Clear the queue of pending SMS\n")
1396{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001397 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001398 return CMD_SUCCESS;
1399}
1400
1401DEFUN(smsqueue_fail,
1402 smsqueue_fail_cmd,
1403 "sms-queue max-failure <1-500>",
1404 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1405{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001406 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001407 return CMD_SUCCESS;
1408}
1409
1410
1411DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1412 "mncc-int", "Configure internal MNCC handler")
1413{
1414 vty->node = MNCC_INT_NODE;
1415
1416 return CMD_SUCCESS;
1417}
1418
1419static struct cmd_node mncc_int_node = {
1420 MNCC_INT_NODE,
1421 "%s(config-mncc-int)# ",
1422 1,
1423};
1424
1425static const struct value_string tchf_codec_names[] = {
1426 { GSM48_CMODE_SPEECH_V1, "fr" },
1427 { GSM48_CMODE_SPEECH_EFR, "efr" },
1428 { GSM48_CMODE_SPEECH_AMR, "amr" },
1429 { 0, NULL }
1430};
1431
1432static const struct value_string tchh_codec_names[] = {
1433 { GSM48_CMODE_SPEECH_V1, "hr" },
1434 { GSM48_CMODE_SPEECH_AMR, "amr" },
1435 { 0, NULL }
1436};
1437
1438static int config_write_mncc_int(struct vty *vty)
1439{
1440 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1441 vty_out(vty, " default-codec tch-f %s%s",
1442 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1443 VTY_NEWLINE);
1444 vty_out(vty, " default-codec tch-h %s%s",
1445 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1446 VTY_NEWLINE);
1447
1448 return CMD_SUCCESS;
1449}
1450
1451DEFUN(mnccint_def_codec_f,
1452 mnccint_def_codec_f_cmd,
1453 "default-codec tch-f (fr|efr|amr)",
1454 "Set default codec\n" "Codec for TCH/F\n"
1455 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1456{
1457 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1458
1459 return CMD_SUCCESS;
1460}
1461
1462DEFUN(mnccint_def_codec_h,
1463 mnccint_def_codec_h_cmd,
1464 "default-codec tch-h (hr|amr)",
1465 "Set default codec\n" "Codec for TCH/H\n"
1466 "Half-Rate\n" "Adaptive Multi-Rate\n")
1467{
1468 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1469
1470 return CMD_SUCCESS;
1471}
1472
1473
1474DEFUN(logging_fltr_imsi,
1475 logging_fltr_imsi_cmd,
1476 "logging filter imsi IMSI",
1477 LOGGING_STR FILTER_STR
1478 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1479{
1480 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001481 struct log_target *tgt = osmo_log_vty2tgt(vty);
1482 const char *imsi = argv[0];
1483
1484 if (!tgt)
1485 return CMD_WARNING;
1486
1487 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi);
1488
1489 if (!vlr_subscr) {
1490 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1491 argv[0], VTY_NEWLINE);
1492 return CMD_WARNING;
1493 }
1494
1495 log_set_filter_vlr_subscr(tgt, vlr_subscr);
1496 return CMD_SUCCESS;
1497}
1498
1499static struct cmd_node hlr_node = {
1500 HLR_NODE,
1501 "%s(config-hlr)# ",
1502 1,
1503};
1504
1505DEFUN(cfg_hlr, cfg_hlr_cmd,
1506 "hlr", "Configure connection to the HLR")
1507{
1508 vty->node = HLR_NODE;
1509 return CMD_SUCCESS;
1510}
1511
1512DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1513 "Remote GSUP address of the HLR\n"
1514 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1515{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001516 talloc_free((void*)gsmnet->gsup_server_addr_str);
1517 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1518 return CMD_SUCCESS;
1519}
1520
1521DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1522 "Remote GSUP port of the HLR\n"
1523 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1524{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001525 gsmnet->gsup_server_port = atoi(argv[0]);
1526 return CMD_SUCCESS;
1527}
1528
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001529DEFUN(cfg_hlr_ipa_name,
1530 cfg_hlr_ipa_name_cmd,
1531 "ipa-name NAME",
1532 "Set the IPA name of this MSC\n"
1533 "A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. "
1534 "This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. "
1535 "The default is 'MSC-00-00-00-00-00-00'.\n")
1536{
1537 if (vty->type != VTY_FILE) {
1538 vty_out(vty, "The IPA name cannot be changed at run-time; "
1539 "It can only be set in the configuraton file.%s", VTY_NEWLINE);
1540 return CMD_WARNING;
1541 }
1542
1543 gsmnet->msc_ipa_name = talloc_strdup(gsmnet, argv[0]);
1544 return CMD_SUCCESS;
1545}
1546
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001547static int config_write_hlr(struct vty *vty)
1548{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001549 vty_out(vty, "hlr%s", VTY_NEWLINE);
1550 vty_out(vty, " remote-ip %s%s",
1551 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1552 vty_out(vty, " remote-port %u%s",
1553 gsmnet->gsup_server_port, VTY_NEWLINE);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001554 if (gsmnet->msc_ipa_name)
1555 vty_out(vty, " ipa-name %s%s", gsmnet->msc_ipa_name, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001556 return CMD_SUCCESS;
1557}
1558
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001559void msc_vty_init(struct gsm_network *msc_network)
1560{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001561 OSMO_ASSERT(gsmnet == NULL);
1562 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001563
1564 osmo_stats_vty_add_cmds();
1565
1566 install_element(CONFIG_NODE, &cfg_net_cmd);
1567 install_node(&net_node, config_write_net);
1568 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
1569 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1570 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1571 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
1572 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
1573 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
1574 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
1575 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
1576 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
1577 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
1578 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
1579 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
1580 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001581
1582 install_element(CONFIG_NODE, &cfg_msc_cmd);
1583 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001584 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01001585 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
1586 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02001587 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01001588 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001589 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01001590 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
1591 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Oliver Smith0fec28a2018-12-14 10:52:52 +01001592 install_element(MSC_NODE, &cfg_msc_check_imei_rqd_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001593 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
1594 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01001595 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01001596 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +07001597 install_element(MSC_NODE, &cfg_msc_sms_over_gsup_cmd);
1598 install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001599
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02001600 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001601#ifdef BUILD_IU
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +01001602 ranap_iu_vty_init(MSC_NODE, &msc_network->iu.rab_assign_addr_enc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001603#endif
Harald Welte0df904d2018-12-03 11:00:04 +01001604 sgs_vty_init();
Stefan Sperling617ac802018-02-22 17:58:20 +01001605 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001606
1607 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
1608
1609 install_element_ve(&show_subscr_cmd);
1610 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01001611 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001612 install_element_ve(&show_msc_conn_cmd);
1613 install_element_ve(&show_msc_transaction_cmd);
1614
1615 install_element_ve(&sms_send_pend_cmd);
1616 install_element_ve(&sms_delete_expired_cmd);
1617
1618 install_element_ve(&subscriber_create_cmd);
1619 install_element_ve(&subscriber_send_sms_cmd);
1620 install_element_ve(&subscriber_silent_sms_cmd);
1621 install_element_ve(&subscriber_silent_call_start_cmd);
1622 install_element_ve(&subscriber_silent_call_stop_cmd);
1623 install_element_ve(&subscriber_ussd_notify_cmd);
1624 install_element_ve(&subscriber_mstest_close_cmd);
1625 install_element_ve(&subscriber_mstest_open_cmd);
1626 install_element_ve(&subscriber_paging_cmd);
1627 install_element_ve(&show_stats_cmd);
1628 install_element_ve(&show_smsqueue_cmd);
1629 install_element_ve(&logging_fltr_imsi_cmd);
1630
1631 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
1632 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
1633 install_element(ENABLE_NODE, &smsqueue_max_cmd);
1634 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
1635 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
1636 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
1637
1638 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1639 install_node(&mncc_int_node, config_write_mncc_int);
1640 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1641 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1642
1643 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
1644
1645 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1646 install_node(&hlr_node, config_write_hlr);
1647 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1648 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001649 install_element(HLR_NODE, &cfg_hlr_ipa_name_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001650}