blob: ac3946afb96a89b11fd2d053f139302004725377 [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
Vadim Yanitskiy64623e12018-11-28 23:05:51 +0700378#define NCSS_STR "Configure call independent Supplementary Services\n"
379
380DEFUN(cfg_msc_ncss_guard_timeout,
381 cfg_msc_ncss_guard_timeout_cmd,
382 "ncss guard-timeout <0-255>",
383 NCSS_STR "Set guard timer for session activity\n"
384 "guard timer value (sec.), or 0 to disable\n")
385{
386 gsmnet->ncss_guard_timeout = atoi(argv[0]);
387 return CMD_SUCCESS;
388}
389
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200390DEFUN(cfg_msc_assign_tmsi, cfg_msc_assign_tmsi_cmd,
391 "assign-tmsi",
392 "Assign TMSI during Location Updating.\n")
393{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200394 gsmnet->vlr->cfg.assign_tmsi = true;
395 return CMD_SUCCESS;
396}
397
398DEFUN(cfg_msc_no_assign_tmsi, cfg_msc_no_assign_tmsi_cmd,
399 "no assign-tmsi",
400 NO_STR "Assign TMSI during Location Updating.\n")
401{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200402 gsmnet->vlr->cfg.assign_tmsi = false;
403 return CMD_SUCCESS;
404}
405
Philipp Maierfbf66102017-04-09 12:32:51 +0200406DEFUN(cfg_msc_cs7_instance_a,
407 cfg_msc_cs7_instance_a_cmd,
408 "cs7-instance-a <0-15>",
409 "Set SS7 to be used by the A-Interface.\n" "SS7 instance reference number\n")
410{
Philipp Maierfbf66102017-04-09 12:32:51 +0200411 gsmnet->a.cs7_instance = atoi(argv[0]);
412 return CMD_SUCCESS;
413}
414
415DEFUN(cfg_msc_cs7_instance_iu,
416 cfg_msc_cs7_instance_iu_cmd,
417 "cs7-instance-iu <0-15>",
418 "Set SS7 to be used by the Iu-Interface.\n" "SS7 instance reference number\n")
419{
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100420#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200421 gsmnet->iu.cs7_instance = atoi(argv[0]);
422 return CMD_SUCCESS;
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100423#else
424 vty_out(vty, "WARNING: 'cs7-instance-iu' without effect: built without Iu support%s",
425 VTY_NEWLINE);
426 return CMD_WARNING;
427#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200428}
429
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100430DEFUN(cfg_msc_auth_tuple_max_reuse_count, cfg_msc_auth_tuple_max_reuse_count_cmd,
431 "auth-tuple-max-reuse-count <-1-2147483647>",
432 "Configure authentication tuple re-use\n"
433 "0 to use each auth tuple at most once (default), >0 to limit re-use, -1 to re-use infinitely (vulnerable!).\n")
434{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100435 gsmnet->vlr->cfg.auth_tuple_max_reuse_count = atoi(argv[0]);
436 return CMD_SUCCESS;
437}
438
439DEFUN(cfg_msc_auth_tuple_reuse_on_error, cfg_msc_auth_tuple_reuse_on_error_cmd,
440 "auth-tuple-reuse-on-error (0|1)",
441 "Configure authentication tuple re-use when HLR is not responsive\n"
Oliver Smithd6e24fd2019-01-09 10:46:43 +0100442 "Never re-use auth tuples beyond auth-tuple-max-reuse-count (default)\n"
443 "If the HLR does not deliver new tuples, do re-use already available old ones.\n")
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100444{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100445 gsmnet->vlr->cfg.auth_reuse_old_sets_on_error = atoi(argv[0]) ? true : false;
446 return CMD_SUCCESS;
447}
448
Oliver Smith0fec28a2018-12-14 10:52:52 +0100449DEFUN(cfg_msc_check_imei_rqd, cfg_msc_check_imei_rqd_cmd,
450 "check-imei-rqd (0|1)",
451 "Send each IMEI to the EIR to ask if it is permitted or not. The EIR is implemented as part of OsmoHLR, "
452 "and can optionally save the IMEI in the HLR.\n"
453 "Do not send IMEIs to the EIR\n"
454 "Send each IMEI to the EIR\n")
455{
456 gsmnet->vlr->cfg.check_imei_rqd = atoi(argv[0]) ? true : false;
457 return CMD_SUCCESS;
458}
459
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100460DEFUN(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd,
461 "paging response-timer (default|<1-65535>)",
462 "Configure Paging\n"
463 "Set Paging timeout, the minimum time to pass between (unsuccessful) Pagings sent towards"
464 " BSS or RNC\n"
465 "Set to default timeout (" OSMO_STRINGIFY_VAL(MSC_PAGING_RESPONSE_TIMER_DEFAULT) " seconds)\n"
466 "Set paging timeout in seconds\n")
467{
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100468 if (!strcmp(argv[1], "default"))
469 gsmnet->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
470 else
471 gsmnet->paging_response_timer = atoi(argv[0]);
472 return CMD_SUCCESS;
473}
474
Harald Welte69c54a82018-02-09 20:41:14 +0100475DEFUN(cfg_msc_emergency_msisdn, cfg_msc_emergency_msisdn_cmd,
476 "emergency-call route-to-msisdn MSISDN",
477 "Configure Emergency Call Behaviour\n"
478 "MSISDN to which Emergency Calls are Dispatched\n"
479 "MSISDN (E.164 Phone Number)\n")
480{
Harald Welte69c54a82018-02-09 20:41:14 +0100481 osmo_talloc_replace_string(gsmnet, &gsmnet->emergency.route_to_msisdn, argv[0]);
482
483 return CMD_SUCCESS;
484}
485
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700486/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
487DEFUN(cfg_msc_sms_over_gsup, cfg_msc_sms_over_gsup_cmd,
488 "sms-over-gsup",
489 "Enable routing of SMS messages over GSUP\n")
490{
491 gsmnet->sms_over_gsup = true;
492 return CMD_SUCCESS;
493}
494
495/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
496DEFUN(cfg_msc_no_sms_over_gsup, cfg_msc_no_sms_over_gsup_cmd,
497 "no sms-over-gsup",
498 NO_STR "Disable routing of SMS messages over GSUP\n")
499{
500 gsmnet->sms_over_gsup = false;
501 return CMD_SUCCESS;
502}
503
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200504static int config_write_msc(struct vty *vty)
505{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200506 vty_out(vty, "msc%s", VTY_NEWLINE);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100507 if (gsmnet->mncc_sock_path)
508 vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE);
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100509 vty_out(vty, " mncc guard-timeout %i%s",
Philipp Maier9ca7b312018-10-10 17:00:49 +0200510 gsmnet->mncc_guard_timeout, VTY_NEWLINE);
Vadim Yanitskiy64623e12018-11-28 23:05:51 +0700511 vty_out(vty, " ncss guard-timeout %i%s",
512 gsmnet->ncss_guard_timeout, VTY_NEWLINE);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200513 vty_out(vty, " %sassign-tmsi%s",
514 gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
515
Philipp Maierfbf66102017-04-09 12:32:51 +0200516 vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
517 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100518#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200519 vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance,
520 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100521#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200522
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100523 if (gsmnet->vlr->cfg.auth_tuple_max_reuse_count)
524 vty_out(vty, " auth-tuple-max-reuse-count %d%s",
525 OSMO_MAX(-1, gsmnet->vlr->cfg.auth_tuple_max_reuse_count),
526 VTY_NEWLINE);
527 if (gsmnet->vlr->cfg.auth_reuse_old_sets_on_error)
528 vty_out(vty, " auth-tuple-reuse-on-error 1%s",
529 VTY_NEWLINE);
530
Oliver Smith0fec28a2018-12-14 10:52:52 +0100531 if (gsmnet->vlr->cfg.check_imei_rqd)
532 vty_out(vty, " check-imei-rqd 1 %s",
533 VTY_NEWLINE);
534
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100535 if (gsmnet->paging_response_timer != MSC_PAGING_RESPONSE_TIMER_DEFAULT)
536 vty_out(vty, " paging response-timer %u%s", gsmnet->paging_response_timer, VTY_NEWLINE);
537
Harald Welte69c54a82018-02-09 20:41:14 +0100538 if (gsmnet->emergency.route_to_msisdn) {
539 vty_out(vty, " emergency-call route-to-msisdn %s%s",
540 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
541 }
542
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700543 if (gsmnet->sms_over_gsup)
544 vty_out(vty, " sms-over-gsup%s", VTY_NEWLINE);
545
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +0200546 mgcp_client_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200547#ifdef BUILD_IU
Neels Hofmeyr00e82d62017-07-05 15:19:52 +0200548 ranap_iu_vty_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200549#endif
550
551 return CMD_SUCCESS;
552}
553
Maxc51609a2018-11-09 17:13:00 +0100554DEFUN(show_bsc, show_bsc_cmd,
555 "show bsc", SHOW_STR "BSC\n")
556{
557 struct bsc_context *bsc_ctx;
558 struct osmo_ss7_instance *ss7 = osmo_ss7_instance_find(gsmnet->a.cs7_instance);
559
560 llist_for_each_entry(bsc_ctx, &gsmnet->a.bscs, list) {
561 vty_out(vty, "BSC %s%s", osmo_sccp_addr_name(ss7, &bsc_ctx->bsc_addr), VTY_NEWLINE);
562 }
563
564 return CMD_SUCCESS;
565}
566
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100567static void vty_conn_hdr(struct vty *vty)
568{
Max45df98b2019-01-17 18:44:33 +0100569 unsigned lnum = 0;
570 struct ran_conn *conn;
571
572 llist_for_each_entry(conn, &gsmnet->ran_conns, entry)
573 lnum++;
574
575 if (lnum)
576 vty_out(vty, "--ConnId RAN --LAC Use --Tokens C A5 State ------------ Subscriber%s",
577 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100578}
579
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100580static void vty_dump_one_conn(struct vty *vty, const struct ran_conn *conn)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100581{
Max45df98b2019-01-17 18:44:33 +0100582 vty_out(vty, "%08x %3s %5u %3u %08x %c /%1u %27s %22s%s",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100583 conn->a.conn_id,
Harald Welte0df904d2018-12-03 11:00:04 +0100584 osmo_rat_type_name(conn->via_ran),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100585 conn->lac,
586 conn->use_count,
587 conn->use_tokens,
588 conn->received_cm_service_request ? 'C' : '-',
Neels Hofmeyrf41658d2018-11-30 04:35:50 +0100589 conn->geran_encr.alg_id,
Neels Hofmeyr4d3a66b2018-03-31 18:45:59 +0200590 conn->fi ? osmo_fsm_inst_state_name(conn->fi) : "-",
Max45df98b2019-01-17 18:44:33 +0100591 conn->vsub ? vlr_subscr_name(conn->vsub) : "-",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100592 VTY_NEWLINE);
593}
594
595DEFUN(show_msc_conn, show_msc_conn_cmd,
596 "show connection", SHOW_STR "Subscriber Connections\n")
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200597{
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100598 struct ran_conn *conn;
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200599
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100600 vty_conn_hdr(vty);
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100601 llist_for_each_entry(conn, &gsmnet->ran_conns, entry)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100602 vty_dump_one_conn(vty, conn);
603
604 return CMD_SUCCESS;
605}
606
607static void vty_trans_hdr(struct vty *vty)
608{
Max45df98b2019-01-17 18:44:33 +0100609 unsigned lnum = 0;
610 struct gsm_trans *trans;
611
612 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
613 lnum++;
614
615 if (lnum)
616 vty_out(vty, "--ConnId -P TI -CallRef [--- Proto ---] ------------ Subscriber%s",
617 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100618}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200619
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100620static const char *get_trans_proto_str(const struct gsm_trans *trans)
621{
622 static char buf[256];
623
624 switch (trans->protocol) {
625 case GSM48_PDISC_CC:
626 snprintf(buf, sizeof(buf), "%s %4u %4u",
627 gsm48_cc_state_name(trans->cc.state),
628 trans->cc.Tcurrent,
629 trans->cc.T308_second);
630 break;
631 case GSM48_PDISC_SMS:
632 snprintf(buf, sizeof(buf), "%s %s",
633 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
634 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
635 break;
636 default:
637 buf[0] = '\0';
638 break;
639 }
640
641 return buf;
642}
643
644static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
645{
Max45df98b2019-01-17 18:44:33 +0100646 vty_out(vty, "%08x %s %02u %08x [%s] %22s%s",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100647 trans->conn ? trans->conn->a.conn_id : 0,
648 gsm48_pdisc_name(trans->protocol),
649 trans->transaction_id,
650 trans->callref,
Max45df98b2019-01-17 18:44:33 +0100651 get_trans_proto_str(trans),
652 trans->vsub ? vlr_subscr_name(trans->vsub) : "-",
653 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100654}
655
656DEFUN(show_msc_transaction, show_msc_transaction_cmd,
657 "show transaction", SHOW_STR "Transactions\n")
658{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100659 struct gsm_trans *trans;
660
661 vty_trans_hdr(vty);
662 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
663 vty_dump_one_trans(vty, trans);
664
665 return CMD_SUCCESS;
666}
667
668static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
669{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100670 struct gsm_trans *trans;
671 int reqs;
672 struct llist_head *entry;
673
674 if (strlen(vsub->name))
675 vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
676 if (strlen(vsub->msisdn))
677 vty_out(vty, " Extension: %s%s", vsub->msisdn,
678 VTY_NEWLINE);
679 vty_out(vty, " LAC: %d/0x%x%s",
Max7d41d872018-12-19 11:48:33 +0100680 vsub->cgi.lai.lac, vsub->cgi.lai.lac, VTY_NEWLINE);
Philipp Maier2a0ac3b2018-12-17 10:03:50 +0100681 vty_out(vty, " RAN: %s%s",
Neels Hofmeyr7814a832018-12-26 00:40:18 +0100682 osmo_rat_type_name(vsub->cs.attached_via_ran), VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100683 vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
684 if (vsub->tmsi != GSM_RESERVED_TMSI)
685 vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
686 VTY_NEWLINE);
687 if (vsub->tmsi_new != GSM_RESERVED_TMSI)
688 vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
689 VTY_NEWLINE);
Philipp Maier6d71ccf2018-12-14 13:30:14 +0100690 if (vsub->imei[0] != '\0')
691 vty_out(vty, " IMEI: %s%s", vsub->imei, VTY_NEWLINE);
692 if (vsub->imeisv[0] != '\0')
693 vty_out(vty, " IMEISV: %s%s", vsub->imeisv, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100694
Philipp Maier89561bc2018-12-14 13:34:25 +0100695 vty_out(vty, " Flags: %s", VTY_NEWLINE);
696 vty_out(vty, " IMSI detached: %s%s",
697 vsub->imsi_detached_flag ? "true" : "false", VTY_NEWLINE);
698 vty_out(vty, " Conf. by radio contact: %s%s",
699 vsub->conf_by_radio_contact_ind ? "true" : "false",
700 VTY_NEWLINE);
701 vty_out(vty, " Subscr. data conf. by HLR: %s%s",
702 vsub->sub_dataconf_by_hlr_ind ? "true" : "false", VTY_NEWLINE);
703 vty_out(vty, " Location conf. in HLR: %s%s",
704 vsub->loc_conf_in_hlr_ind ? "true" : "false", VTY_NEWLINE);
705 vty_out(vty, " Subscriber dormant: %s%s",
706 vsub->dormant_ind ? "true" : "false", VTY_NEWLINE);
707 vty_out(vty, " Received cancel locataion: %s%s",
708 vsub->cancel_loc_rx ? "true" : "false", VTY_NEWLINE);
709 vty_out(vty, " MS not reachable: %s%s",
710 vsub->ms_not_reachable_flag ? "true" : "false", VTY_NEWLINE);
711 vty_out(vty, " LA allowed: %s%s",
712 vsub->la_allowed ? "true" : "false", VTY_NEWLINE);
713
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100714#if 0
715 /* TODO: add this to vlr_subscr? */
716 if (vsub->auth_info.auth_algo != AUTH_ALGO_NONE) {
717 struct gsm_auth_info *i = &vsub->auth_info;
718 vty_out(vty, " A3A8 algorithm id: %d%s",
719 i->auth_algo, VTY_NEWLINE);
720 vty_out(vty, " A3A8 Ki: %s%s",
721 osmo_hexdump(i->a3a8_ki, i->a3a8_ki_len),
722 VTY_NEWLINE);
723 }
724#endif
725
726 if (vsub->last_tuple) {
Neels Hofmeyr8b6e5362018-11-30 02:57:33 +0100727 struct vlr_auth_tuple *t = vsub->last_tuple;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100728 vty_out(vty, " A3A8 last tuple (used %d times):%s",
729 t->use_count, VTY_NEWLINE);
730 vty_out(vty, " seq # : %d%s",
731 t->key_seq, VTY_NEWLINE);
732 vty_out(vty, " RAND : %s%s",
733 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
734 VTY_NEWLINE);
735 vty_out(vty, " SRES : %s%s",
736 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
737 VTY_NEWLINE);
738 vty_out(vty, " Kc : %s%s",
739 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
740 VTY_NEWLINE);
741 }
742
743 reqs = 0;
744 llist_for_each(entry, &vsub->cs.requests)
745 reqs += 1;
746 vty_out(vty, " Paging: %s paging for %d requests%s",
747 vsub->cs.is_paging ? "is" : "not", reqs, VTY_NEWLINE);
Harald Welte0df904d2018-12-03 11:00:04 +0100748
749 /* SGs related */
750 vty_out(vty, " SGs-state: %s%s",
751 osmo_fsm_inst_state_name(vsub->sgs_fsm), VTY_NEWLINE);
Vadim Yanitskiy477cbc62019-02-23 16:59:16 +0700752 if (strlen(vsub->sgs.mme_name))
Harald Welte0df904d2018-12-03 11:00:04 +0100753 vty_out(vty, " SGs-MME: %s%s", vsub->sgs.mme_name, VTY_NEWLINE);
754 else
755 vty_out(vty, " SGs-MME: (none)%s", VTY_NEWLINE);
756
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100757 vty_out(vty, " Use count: %u%s", vsub->use_count, VTY_NEWLINE);
758
759 /* Connection */
760 if (vsub->msc_conn_ref) {
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100761 struct ran_conn *conn = vsub->msc_conn_ref;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100762 vty_conn_hdr(vty);
763 vty_dump_one_conn(vty, conn);
764 }
765
766 /* Transactions */
767 vty_trans_hdr(vty);
768 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
769 if (trans->vsub != vsub)
770 continue;
771 vty_dump_one_trans(vty, trans);
772 }
773}
774
775/* Subscriber */
776DEFUN(show_subscr_cache,
777 show_subscr_cache_cmd,
778 "show subscriber cache",
779 SHOW_STR "Show information about subscribers\n"
780 "Display contents of subscriber cache\n")
781{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100782 struct vlr_subscr *vsub;
783 int count = 0;
784
785 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
786 if (++count > 100) {
787 vty_out(vty, "%% More than %d subscribers in cache,"
788 " stopping here.%s", count-1, VTY_NEWLINE);
789 break;
790 }
791 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
792 subscr_dump_full_vty(vty, vsub);
Harald Welte69c54a82018-02-09 20:41:14 +0100793 }
794
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200795 return CMD_SUCCESS;
796}
797
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100798DEFUN(sms_send_pend,
799 sms_send_pend_cmd,
800 "sms send pending",
801 "SMS related commands\n" "SMS Sending related commands\n"
802 "Send all pending SMS")
803{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100804 struct gsm_sms *sms;
805 unsigned long long sms_id = 0;
806
807 while (1) {
808 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
809 if (!sms)
810 break;
811
812 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700813 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100814
815 sms_id = sms->id + 1;
816 }
817
818 return CMD_SUCCESS;
819}
820
821DEFUN(sms_delete_expired,
822 sms_delete_expired_cmd,
823 "sms delete expired",
824 "SMS related commands\n" "SMS Database related commands\n"
825 "Delete all expired SMS")
826{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100827 struct gsm_sms *sms;
828 unsigned long long sms_id = 0;
829 long long num_deleted = 0;
830
831 while (1) {
832 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
833 if (!sms)
834 break;
835
836 /* Skip SMS which are currently queued for sending. */
837 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
838 continue;
839
840 /* Expiration check is performed by the DB layer. */
841 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
842 num_deleted++;
843
844 sms_id = sms->id + 1;
845 }
846
847 if (num_deleted == 0) {
848 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
849 return CMD_WARNING;
850 }
851
852 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
853 return CMD_SUCCESS;
854}
855
856static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +0200857 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100858 char *str, uint8_t tp_pid)
859{
860 struct gsm_network *net = receiver->vlr->user_ctx;
861 struct gsm_sms *sms;
862
Harald Welte39b55482018-04-09 19:19:33 +0200863 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100864 sms->protocol_id = tp_pid;
865
866 /* store in database for the queue */
867 if (db_sms_store(sms) != 0) {
868 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
869 sms_free(sms);
870 return CMD_WARNING;
871 }
872 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
873
874 sms_free(sms);
875 sms_queue_trigger(net->sms_queue);
876 return CMD_SUCCESS;
877}
878
879static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
880 const char *type,
881 const char *id)
882{
883 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
884 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id);
885 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
886 return vlr_subscr_find_by_imsi(gsmnet->vlr, id);
887 else if (!strcmp(type, "tmsi"))
888 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id));
889
890 return NULL;
891}
892#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
893#define SUBSCR_HELP "Operations on a Subscriber\n" \
894 "Identify subscriber by MSISDN (phone number)\n" \
895 "Legacy alias for 'msisdn'\n" \
896 "Identify subscriber by IMSI\n" \
897 "Identify subscriber by TMSI\n" \
898 "Identify subscriber by database ID\n" \
899 "Identifier for the subscriber\n"
900
901DEFUN(show_subscr,
902 show_subscr_cmd,
903 "show subscriber " SUBSCR_TYPES " ID",
904 SHOW_STR SUBSCR_HELP)
905{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100906 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
907 argv[1]);
908
909 if (!vsub) {
910 vty_out(vty, "%% No subscriber found for %s %s%s",
911 argv[0], argv[1], VTY_NEWLINE);
912 return CMD_WARNING;
913 }
914
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100915 /* In the vty output to the user, exclude this local use count added by vlr_subscr_get() in get_vsub_by_argv().
916 * This works, because: for get_vsub_by_argv() to succeed, there *must* have been at least one use count before
917 * 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 +0100918 vlr_subscr_put(vsub);
919
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100920 subscr_dump_full_vty(vty, vsub);
921
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100922 return CMD_SUCCESS;
923}
924
925DEFUN(subscriber_create,
926 subscriber_create_cmd,
927 "subscriber create imsi ID",
928 "Operations on a Subscriber\n" \
929 "Create new subscriber\n" \
930 "Identify the subscriber by his IMSI\n" \
931 "Identifier for the subscriber\n")
932{
933 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
934 VTY_NEWLINE);
935 return CMD_WARNING;
936}
937
938DEFUN(subscriber_send_pending_sms,
939 subscriber_send_pending_sms_cmd,
940 "subscriber " SUBSCR_TYPES " ID sms pending-send",
941 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
942{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100943 struct vlr_subscr *vsub;
944 struct gsm_sms *sms;
945
946 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
947 if (!vsub) {
948 vty_out(vty, "%% No subscriber found for %s %s%s",
949 argv[0], argv[1], VTY_NEWLINE);
950 return CMD_WARNING;
951 }
952
953 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
954 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700955 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100956
957 vlr_subscr_put(vsub);
958
959 return CMD_SUCCESS;
960}
961
Neels Hofmeyrf90496f2019-03-06 16:19:50 +0100962DEFUN(subscriber_sms_delete_all,
963 subscriber_sms_delete_all_cmd,
964 "subscriber " SUBSCR_TYPES " ID sms delete-all",
965 SUBSCR_HELP "SMS Operations\n"
966 "Delete all SMS to be delivered to this subscriber"
967 " -- WARNING: the SMS data for all unsent SMS for this subscriber"
968 " WILL BE LOST.\n")
969{
970 struct vlr_subscr *vsub;
971
972 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
973 if (!vsub) {
974 vty_out(vty, "%% No subscriber found for %s %s%s",
975 argv[0], argv[1], VTY_NEWLINE);
976 return CMD_WARNING;
977 }
978
979 db_sms_delete_by_msisdn(vsub->msisdn);
980
981 vlr_subscr_put(vsub);
982
983 return CMD_SUCCESS;
984}
985
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100986DEFUN(subscriber_send_sms,
987 subscriber_send_sms_cmd,
988 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
989 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
990{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100991 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200992 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100993 char *str;
994 int rc;
995
996 if (!vsub) {
997 vty_out(vty, "%% No subscriber found for %s %s%s",
998 argv[0], argv[1], VTY_NEWLINE);
999 rc = CMD_WARNING;
1000 goto err;
1001 }
1002
Harald Welte39b55482018-04-09 19:19:33 +02001003 if (!strcmp(argv[2], "msisdn"))
1004 sender_msisdn = argv[3];
1005 else {
1006 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1007 if (!sender) {
1008 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1009 rc = CMD_WARNING;
1010 goto err;
1011 }
1012 sender_msisdn = sender->msisdn;
1013 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001014 }
1015
1016 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001017 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001018 talloc_free(str);
1019
1020err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001021 if (vsub)
1022 vlr_subscr_put(vsub);
1023
1024 return rc;
1025}
1026
1027DEFUN(subscriber_silent_sms,
1028 subscriber_silent_sms_cmd,
1029
1030 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
1031 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
1032{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001033 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +02001034 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001035 char *str;
1036 int rc;
1037
1038 if (!vsub) {
1039 vty_out(vty, "%% No subscriber found for %s %s%s",
1040 argv[0], argv[1], VTY_NEWLINE);
1041 rc = CMD_WARNING;
1042 goto err;
1043 }
1044
Harald Welte39b55482018-04-09 19:19:33 +02001045 if (!strcmp(argv[2], "msisdn")) {
1046 sender_msisdn = argv[3];
1047 } else {
1048 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1049 if (!sender) {
1050 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1051 rc = CMD_WARNING;
1052 goto err;
1053 }
1054 sender_msisdn = sender->msisdn;
1055 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001056 }
1057
1058 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001059 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001060 talloc_free(str);
1061
1062err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001063 if (vsub)
1064 vlr_subscr_put(vsub);
1065
1066 return rc;
1067}
1068
1069#define CHAN_TYPES "(any|tch/f|tch/any|sdcch)"
1070#define CHAN_TYPE_HELP \
1071 "Any channel\n" \
1072 "TCH/F channel\n" \
1073 "Any TCH channel\n" \
1074 "SDCCH channel\n"
1075
1076DEFUN(subscriber_silent_call_start,
1077 subscriber_silent_call_start_cmd,
1078 "subscriber " SUBSCR_TYPES " ID silent-call start (any|tch/f|tch/any|sdcch)",
1079 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
1080 CHAN_TYPE_HELP)
1081{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001082 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1083 int rc, type;
1084
1085 if (!vsub) {
1086 vty_out(vty, "%% No subscriber found for %s %s%s",
1087 argv[0], argv[1], VTY_NEWLINE);
1088 return CMD_WARNING;
1089 }
1090
1091 if (!strcmp(argv[2], "tch/f"))
1092 type = RSL_CHANNEED_TCH_F;
1093 else if (!strcmp(argv[2], "tch/any"))
1094 type = RSL_CHANNEED_TCH_ForH;
1095 else if (!strcmp(argv[2], "sdcch"))
1096 type = RSL_CHANNEED_SDCCH;
1097 else
1098 type = RSL_CHANNEED_ANY; /* Defaults to ANY */
1099
1100 rc = gsm_silent_call_start(vsub, vty, type);
1101 switch (rc) {
1102 case -ENODEV:
1103 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
1104 break;
1105 default:
1106 if (rc)
1107 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
1108 else
1109 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
1110 break;
1111 }
1112
1113 vlr_subscr_put(vsub);
1114 return rc ? CMD_WARNING : CMD_SUCCESS;
1115}
1116
1117DEFUN(subscriber_silent_call_stop,
1118 subscriber_silent_call_stop_cmd,
1119 "subscriber " SUBSCR_TYPES " ID silent-call stop",
1120 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
1121 CHAN_TYPE_HELP)
1122{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001123 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1124 int rc;
1125
1126 if (!vsub) {
1127 vty_out(vty, "%% No subscriber found for %s %s%s",
1128 argv[0], argv[1], VTY_NEWLINE);
1129 return CMD_WARNING;
1130 }
1131
1132 rc = gsm_silent_call_stop(vsub);
1133 switch (rc) {
1134 case -ENODEV:
1135 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
1136 break;
1137 case -ENOENT:
1138 vty_out(vty, "%% Subscriber has no silent call active%s",
1139 VTY_NEWLINE);
1140 break;
1141 default:
1142 if (rc)
1143 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
1144 else
1145 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
1146 break;
1147 }
1148
1149 vlr_subscr_put(vsub);
1150 return rc ? CMD_WARNING : CMD_SUCCESS;
1151}
1152
1153DEFUN(subscriber_ussd_notify,
1154 subscriber_ussd_notify_cmd,
1155 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1156 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1157 "Alerting Level 0\n"
1158 "Alerting Level 1\n"
1159 "Alerting Level 2\n"
1160 "Text of USSD message to send\n")
1161{
1162 char *text;
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001163 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001164 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1165 int level;
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
1173 level = atoi(argv[2]);
1174 text = argv_concat(argv, argc, 3);
1175 if (!text) {
1176 vlr_subscr_put(vsub);
1177 return CMD_WARNING;
1178 }
1179
1180 conn = connection_for_subscr(vsub);
1181 if (!conn) {
1182 vty_out(vty, "%% An active connection is required for %s %s%s",
1183 argv[0], argv[1], VTY_NEWLINE);
1184 vlr_subscr_put(vsub);
1185 talloc_free(text);
1186 return CMD_WARNING;
1187 }
1188
1189 msc_send_ussd_notify(conn, level, text);
Vadim Yanitskiyf20c6b72018-11-29 01:20:58 +07001190 /* FIXME: since we don't allocate a transaction here,
1191 * we use dummy GSM 04.07 transaction ID. */
1192 msc_send_ussd_release_complete(conn, 0x00);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001193
1194 vlr_subscr_put(vsub);
1195 talloc_free(text);
1196 return CMD_SUCCESS;
1197}
1198
1199DEFUN(subscriber_paging,
1200 subscriber_paging_cmd,
1201 "subscriber " SUBSCR_TYPES " ID paging",
1202 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1203{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001204 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1205 struct subscr_request *req;
1206
1207 if (!vsub) {
1208 vty_out(vty, "%% No subscriber found for %s %s%s",
1209 argv[0], argv[1], VTY_NEWLINE);
1210 return CMD_WARNING;
1211 }
1212
Harald Welte0df904d2018-12-03 11:00:04 +01001213 req = subscr_request_conn(vsub, NULL, NULL, "manual Paging from VTY", SGSAP_SERV_IND_CS_CALL);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001214 if (req)
1215 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1216 else
1217 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1218
1219 vlr_subscr_put(vsub);
1220 return req ? CMD_SUCCESS : CMD_WARNING;
1221}
1222
1223static int loop_by_char(uint8_t ch)
1224{
1225 switch (ch) {
1226 case 'a':
1227 return GSM414_LOOP_A;
1228 case 'b':
1229 return GSM414_LOOP_B;
1230 case 'c':
1231 return GSM414_LOOP_C;
1232 case 'd':
1233 return GSM414_LOOP_D;
1234 case 'e':
1235 return GSM414_LOOP_E;
1236 case 'f':
1237 return GSM414_LOOP_F;
1238 case 'i':
1239 return GSM414_LOOP_I;
1240 }
1241 return -1;
1242}
1243
1244DEFUN(subscriber_mstest_close,
1245 subscriber_mstest_close_cmd,
1246 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1247 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1248 "Close a TCH Loop inside the MS\n"
1249 "Loop Type A\n"
1250 "Loop Type B\n"
1251 "Loop Type C\n"
1252 "Loop Type D\n"
1253 "Loop Type E\n"
1254 "Loop Type F\n"
1255 "Loop Type I\n")
1256{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001257 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001258 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1259 const char *loop_str;
1260 int loop_mode;
1261
1262 if (!vsub) {
1263 vty_out(vty, "%% No subscriber found for %s %s%s",
1264 argv[0], argv[1], VTY_NEWLINE);
1265 return CMD_WARNING;
1266 }
1267
1268 loop_str = argv[2];
1269 loop_mode = loop_by_char(loop_str[0]);
1270
1271 conn = connection_for_subscr(vsub);
1272 if (!conn) {
1273 vty_out(vty, "%% An active connection is required for %s %s%s",
1274 argv[0], argv[1], VTY_NEWLINE);
1275 vlr_subscr_put(vsub);
1276 return CMD_WARNING;
1277 }
1278
1279 gsm0414_tx_close_tch_loop_cmd(conn, loop_mode);
1280
1281 return CMD_SUCCESS;
1282}
1283
1284DEFUN(subscriber_mstest_open,
1285 subscriber_mstest_open_cmd,
1286 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1287 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1288 "Open a TCH Loop inside the MS\n")
1289{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001290 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001291 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1292
1293 if (!vsub) {
1294 vty_out(vty, "%% No subscriber found for %s %s%s",
1295 argv[0], argv[1], VTY_NEWLINE);
1296 return CMD_WARNING;
1297 }
1298
1299 conn = connection_for_subscr(vsub);
1300 if (!conn) {
1301 vty_out(vty, "%% An active connection is required for %s %s%s",
1302 argv[0], argv[1], VTY_NEWLINE);
1303 vlr_subscr_put(vsub);
1304 return CMD_WARNING;
1305 }
1306
1307 gsm0414_tx_open_loop_cmd(conn);
1308
1309 return CMD_SUCCESS;
1310}
1311
1312DEFUN(ena_subscr_expire,
1313 ena_subscr_expire_cmd,
1314 "subscriber " SUBSCR_TYPES " ID expire",
1315 SUBSCR_HELP "Expire the subscriber Now\n")
1316{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001317 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1318 argv[1]);
1319
1320 if (!vsub) {
1321 vty_out(vty, "%% No subscriber found for %s %s%s",
1322 argv[0], argv[1], VTY_NEWLINE);
1323 return CMD_WARNING;
1324 }
1325
1326 if (vlr_subscr_expire(vsub))
1327 vty_out(vty, "%% VLR released subscriber %s%s",
1328 vlr_subscr_name(vsub), VTY_NEWLINE);
1329
1330 if (vsub->use_count > 1)
1331 vty_out(vty, "%% Subscriber %s is still in use,"
1332 " should be released soon%s",
1333 vlr_subscr_name(vsub), VTY_NEWLINE);
1334
1335 vlr_subscr_put(vsub);
1336 return CMD_SUCCESS;
1337}
1338
1339static int scall_cbfn(unsigned int subsys, unsigned int signal,
1340 void *handler_data, void *signal_data)
1341{
1342 struct scall_signal_data *sigdata = signal_data;
1343 struct vty *vty = sigdata->data;
1344
1345 switch (signal) {
1346 case S_SCALL_SUCCESS:
1347 vty_out(vty, "%% silent call success%s", VTY_NEWLINE);
1348 break;
1349 case S_SCALL_EXPIRED:
1350 vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE);
1351 break;
1352 }
1353 return 0;
1354}
1355
1356DEFUN(show_stats,
1357 show_stats_cmd,
1358 "show statistics",
1359 SHOW_STR "Display network statistics\n")
1360{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001361 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001362 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1363 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1364 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001365 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001366 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001367 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001368 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001369 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001370 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1371 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001372 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001373 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001374 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1375 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001376 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001377 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001378 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1379 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1380 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001381 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001382 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001383 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1384 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001385 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001386 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001387 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1388 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001389 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001390 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001391 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1392 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1393 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1394 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1395 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001396 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001397 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1398 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1399 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1400 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1401 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001402 return CMD_SUCCESS;
1403}
1404
1405DEFUN(show_smsqueue,
1406 show_smsqueue_cmd,
1407 "show sms-queue",
1408 SHOW_STR "Display SMSqueue statistics\n")
1409{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001410 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001411 return CMD_SUCCESS;
1412}
1413
1414DEFUN(smsqueue_trigger,
1415 smsqueue_trigger_cmd,
1416 "sms-queue trigger",
1417 "SMS Queue\n" "Trigger sending messages\n")
1418{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001419 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001420 return CMD_SUCCESS;
1421}
1422
1423DEFUN(smsqueue_max,
1424 smsqueue_max_cmd,
1425 "sms-queue max-pending <1-500>",
1426 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1427{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001428 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001429 return CMD_SUCCESS;
1430}
1431
1432DEFUN(smsqueue_clear,
1433 smsqueue_clear_cmd,
1434 "sms-queue clear",
1435 "SMS Queue\n" "Clear the queue of pending SMS\n")
1436{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001437 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001438 return CMD_SUCCESS;
1439}
1440
1441DEFUN(smsqueue_fail,
1442 smsqueue_fail_cmd,
1443 "sms-queue max-failure <1-500>",
1444 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1445{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001446 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001447 return CMD_SUCCESS;
1448}
1449
1450
1451DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1452 "mncc-int", "Configure internal MNCC handler")
1453{
1454 vty->node = MNCC_INT_NODE;
1455
1456 return CMD_SUCCESS;
1457}
1458
1459static struct cmd_node mncc_int_node = {
1460 MNCC_INT_NODE,
1461 "%s(config-mncc-int)# ",
1462 1,
1463};
1464
1465static const struct value_string tchf_codec_names[] = {
1466 { GSM48_CMODE_SPEECH_V1, "fr" },
1467 { GSM48_CMODE_SPEECH_EFR, "efr" },
1468 { GSM48_CMODE_SPEECH_AMR, "amr" },
1469 { 0, NULL }
1470};
1471
1472static const struct value_string tchh_codec_names[] = {
1473 { GSM48_CMODE_SPEECH_V1, "hr" },
1474 { GSM48_CMODE_SPEECH_AMR, "amr" },
1475 { 0, NULL }
1476};
1477
1478static int config_write_mncc_int(struct vty *vty)
1479{
1480 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1481 vty_out(vty, " default-codec tch-f %s%s",
1482 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1483 VTY_NEWLINE);
1484 vty_out(vty, " default-codec tch-h %s%s",
1485 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1486 VTY_NEWLINE);
1487
1488 return CMD_SUCCESS;
1489}
1490
1491DEFUN(mnccint_def_codec_f,
1492 mnccint_def_codec_f_cmd,
1493 "default-codec tch-f (fr|efr|amr)",
1494 "Set default codec\n" "Codec for TCH/F\n"
1495 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1496{
1497 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1498
1499 return CMD_SUCCESS;
1500}
1501
1502DEFUN(mnccint_def_codec_h,
1503 mnccint_def_codec_h_cmd,
1504 "default-codec tch-h (hr|amr)",
1505 "Set default codec\n" "Codec for TCH/H\n"
1506 "Half-Rate\n" "Adaptive Multi-Rate\n")
1507{
1508 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1509
1510 return CMD_SUCCESS;
1511}
1512
1513
1514DEFUN(logging_fltr_imsi,
1515 logging_fltr_imsi_cmd,
1516 "logging filter imsi IMSI",
1517 LOGGING_STR FILTER_STR
1518 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1519{
1520 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001521 struct log_target *tgt = osmo_log_vty2tgt(vty);
1522 const char *imsi = argv[0];
1523
1524 if (!tgt)
1525 return CMD_WARNING;
1526
1527 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi);
1528
1529 if (!vlr_subscr) {
1530 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1531 argv[0], VTY_NEWLINE);
1532 return CMD_WARNING;
1533 }
1534
1535 log_set_filter_vlr_subscr(tgt, vlr_subscr);
1536 return CMD_SUCCESS;
1537}
1538
1539static struct cmd_node hlr_node = {
1540 HLR_NODE,
1541 "%s(config-hlr)# ",
1542 1,
1543};
1544
1545DEFUN(cfg_hlr, cfg_hlr_cmd,
1546 "hlr", "Configure connection to the HLR")
1547{
1548 vty->node = HLR_NODE;
1549 return CMD_SUCCESS;
1550}
1551
1552DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1553 "Remote GSUP address of the HLR\n"
1554 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1555{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001556 talloc_free((void*)gsmnet->gsup_server_addr_str);
1557 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1558 return CMD_SUCCESS;
1559}
1560
1561DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1562 "Remote GSUP port of the HLR\n"
1563 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1564{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001565 gsmnet->gsup_server_port = atoi(argv[0]);
1566 return CMD_SUCCESS;
1567}
1568
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001569DEFUN(cfg_hlr_ipa_name,
1570 cfg_hlr_ipa_name_cmd,
1571 "ipa-name NAME",
1572 "Set the IPA name of this MSC\n"
1573 "A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. "
1574 "This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. "
1575 "The default is 'MSC-00-00-00-00-00-00'.\n")
1576{
1577 if (vty->type != VTY_FILE) {
1578 vty_out(vty, "The IPA name cannot be changed at run-time; "
1579 "It can only be set in the configuraton file.%s", VTY_NEWLINE);
1580 return CMD_WARNING;
1581 }
1582
1583 gsmnet->msc_ipa_name = talloc_strdup(gsmnet, argv[0]);
1584 return CMD_SUCCESS;
1585}
1586
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001587static int config_write_hlr(struct vty *vty)
1588{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001589 vty_out(vty, "hlr%s", VTY_NEWLINE);
1590 vty_out(vty, " remote-ip %s%s",
1591 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1592 vty_out(vty, " remote-port %u%s",
1593 gsmnet->gsup_server_port, VTY_NEWLINE);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001594 if (gsmnet->msc_ipa_name)
1595 vty_out(vty, " ipa-name %s%s", gsmnet->msc_ipa_name, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001596 return CMD_SUCCESS;
1597}
1598
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001599void msc_vty_init(struct gsm_network *msc_network)
1600{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001601 OSMO_ASSERT(gsmnet == NULL);
1602 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001603
1604 osmo_stats_vty_add_cmds();
1605
1606 install_element(CONFIG_NODE, &cfg_net_cmd);
1607 install_node(&net_node, config_write_net);
1608 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
1609 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1610 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1611 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
1612 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
1613 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
1614 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
1615 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
1616 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
1617 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
1618 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
1619 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
1620 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001621
1622 install_element(CONFIG_NODE, &cfg_msc_cmd);
1623 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001624 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01001625 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
1626 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02001627 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01001628 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Vadim Yanitskiy64623e12018-11-28 23:05:51 +07001629 install_element(MSC_NODE, &cfg_msc_ncss_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001630 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01001631 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
1632 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Oliver Smith0fec28a2018-12-14 10:52:52 +01001633 install_element(MSC_NODE, &cfg_msc_check_imei_rqd_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001634 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
1635 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01001636 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01001637 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +07001638 install_element(MSC_NODE, &cfg_msc_sms_over_gsup_cmd);
1639 install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001640
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02001641 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001642#ifdef BUILD_IU
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +01001643 ranap_iu_vty_init(MSC_NODE, &msc_network->iu.rab_assign_addr_enc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001644#endif
Harald Welte0df904d2018-12-03 11:00:04 +01001645 sgs_vty_init();
Stefan Sperling617ac802018-02-22 17:58:20 +01001646 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001647
1648 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
1649
1650 install_element_ve(&show_subscr_cmd);
1651 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01001652 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001653 install_element_ve(&show_msc_conn_cmd);
1654 install_element_ve(&show_msc_transaction_cmd);
1655
1656 install_element_ve(&sms_send_pend_cmd);
1657 install_element_ve(&sms_delete_expired_cmd);
1658
1659 install_element_ve(&subscriber_create_cmd);
1660 install_element_ve(&subscriber_send_sms_cmd);
1661 install_element_ve(&subscriber_silent_sms_cmd);
1662 install_element_ve(&subscriber_silent_call_start_cmd);
1663 install_element_ve(&subscriber_silent_call_stop_cmd);
1664 install_element_ve(&subscriber_ussd_notify_cmd);
1665 install_element_ve(&subscriber_mstest_close_cmd);
1666 install_element_ve(&subscriber_mstest_open_cmd);
1667 install_element_ve(&subscriber_paging_cmd);
1668 install_element_ve(&show_stats_cmd);
1669 install_element_ve(&show_smsqueue_cmd);
1670 install_element_ve(&logging_fltr_imsi_cmd);
1671
1672 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
1673 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
1674 install_element(ENABLE_NODE, &smsqueue_max_cmd);
1675 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
1676 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
1677 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001678 install_element(ENABLE_NODE, &subscriber_sms_delete_all_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001679
1680 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1681 install_node(&mncc_int_node, config_write_mncc_int);
1682 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1683 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1684
1685 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
1686
1687 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1688 install_node(&hlr_node, config_write_hlr);
1689 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1690 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001691 install_element(HLR_NODE, &cfg_hlr_ipa_name_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001692}