blob: 2adb2a45caa069ea8ab5f53d3920a8c7a441ffdf [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
962DEFUN(subscriber_send_sms,
963 subscriber_send_sms_cmd,
964 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
965 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
966{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100967 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200968 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100969 char *str;
970 int rc;
971
972 if (!vsub) {
973 vty_out(vty, "%% No subscriber found for %s %s%s",
974 argv[0], argv[1], VTY_NEWLINE);
975 rc = CMD_WARNING;
976 goto err;
977 }
978
Harald Welte39b55482018-04-09 19:19:33 +0200979 if (!strcmp(argv[2], "msisdn"))
980 sender_msisdn = argv[3];
981 else {
982 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
983 if (!sender) {
984 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
985 rc = CMD_WARNING;
986 goto err;
987 }
988 sender_msisdn = sender->msisdn;
989 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100990 }
991
992 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +0200993 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100994 talloc_free(str);
995
996err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100997 if (vsub)
998 vlr_subscr_put(vsub);
999
1000 return rc;
1001}
1002
1003DEFUN(subscriber_silent_sms,
1004 subscriber_silent_sms_cmd,
1005
1006 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
1007 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
1008{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001009 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +02001010 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001011 char *str;
1012 int rc;
1013
1014 if (!vsub) {
1015 vty_out(vty, "%% No subscriber found for %s %s%s",
1016 argv[0], argv[1], VTY_NEWLINE);
1017 rc = CMD_WARNING;
1018 goto err;
1019 }
1020
Harald Welte39b55482018-04-09 19:19:33 +02001021 if (!strcmp(argv[2], "msisdn")) {
1022 sender_msisdn = argv[3];
1023 } else {
1024 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1025 if (!sender) {
1026 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1027 rc = CMD_WARNING;
1028 goto err;
1029 }
1030 sender_msisdn = sender->msisdn;
1031 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001032 }
1033
1034 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001035 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001036 talloc_free(str);
1037
1038err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001039 if (vsub)
1040 vlr_subscr_put(vsub);
1041
1042 return rc;
1043}
1044
1045#define CHAN_TYPES "(any|tch/f|tch/any|sdcch)"
1046#define CHAN_TYPE_HELP \
1047 "Any channel\n" \
1048 "TCH/F channel\n" \
1049 "Any TCH channel\n" \
1050 "SDCCH channel\n"
1051
1052DEFUN(subscriber_silent_call_start,
1053 subscriber_silent_call_start_cmd,
1054 "subscriber " SUBSCR_TYPES " ID silent-call start (any|tch/f|tch/any|sdcch)",
1055 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
1056 CHAN_TYPE_HELP)
1057{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001058 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1059 int rc, type;
1060
1061 if (!vsub) {
1062 vty_out(vty, "%% No subscriber found for %s %s%s",
1063 argv[0], argv[1], VTY_NEWLINE);
1064 return CMD_WARNING;
1065 }
1066
1067 if (!strcmp(argv[2], "tch/f"))
1068 type = RSL_CHANNEED_TCH_F;
1069 else if (!strcmp(argv[2], "tch/any"))
1070 type = RSL_CHANNEED_TCH_ForH;
1071 else if (!strcmp(argv[2], "sdcch"))
1072 type = RSL_CHANNEED_SDCCH;
1073 else
1074 type = RSL_CHANNEED_ANY; /* Defaults to ANY */
1075
1076 rc = gsm_silent_call_start(vsub, vty, type);
1077 switch (rc) {
1078 case -ENODEV:
1079 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
1080 break;
1081 default:
1082 if (rc)
1083 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
1084 else
1085 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
1086 break;
1087 }
1088
1089 vlr_subscr_put(vsub);
1090 return rc ? CMD_WARNING : CMD_SUCCESS;
1091}
1092
1093DEFUN(subscriber_silent_call_stop,
1094 subscriber_silent_call_stop_cmd,
1095 "subscriber " SUBSCR_TYPES " ID silent-call stop",
1096 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
1097 CHAN_TYPE_HELP)
1098{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001099 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1100 int rc;
1101
1102 if (!vsub) {
1103 vty_out(vty, "%% No subscriber found for %s %s%s",
1104 argv[0], argv[1], VTY_NEWLINE);
1105 return CMD_WARNING;
1106 }
1107
1108 rc = gsm_silent_call_stop(vsub);
1109 switch (rc) {
1110 case -ENODEV:
1111 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
1112 break;
1113 case -ENOENT:
1114 vty_out(vty, "%% Subscriber has no silent call active%s",
1115 VTY_NEWLINE);
1116 break;
1117 default:
1118 if (rc)
1119 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
1120 else
1121 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
1122 break;
1123 }
1124
1125 vlr_subscr_put(vsub);
1126 return rc ? CMD_WARNING : CMD_SUCCESS;
1127}
1128
1129DEFUN(subscriber_ussd_notify,
1130 subscriber_ussd_notify_cmd,
1131 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1132 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1133 "Alerting Level 0\n"
1134 "Alerting Level 1\n"
1135 "Alerting Level 2\n"
1136 "Text of USSD message to send\n")
1137{
1138 char *text;
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001139 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001140 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1141 int level;
1142
1143 if (!vsub) {
1144 vty_out(vty, "%% No subscriber found for %s %s%s",
1145 argv[0], argv[1], VTY_NEWLINE);
1146 return CMD_WARNING;
1147 }
1148
1149 level = atoi(argv[2]);
1150 text = argv_concat(argv, argc, 3);
1151 if (!text) {
1152 vlr_subscr_put(vsub);
1153 return CMD_WARNING;
1154 }
1155
1156 conn = connection_for_subscr(vsub);
1157 if (!conn) {
1158 vty_out(vty, "%% An active connection is required for %s %s%s",
1159 argv[0], argv[1], VTY_NEWLINE);
1160 vlr_subscr_put(vsub);
1161 talloc_free(text);
1162 return CMD_WARNING;
1163 }
1164
1165 msc_send_ussd_notify(conn, level, text);
Vadim Yanitskiyf20c6b72018-11-29 01:20:58 +07001166 /* FIXME: since we don't allocate a transaction here,
1167 * we use dummy GSM 04.07 transaction ID. */
1168 msc_send_ussd_release_complete(conn, 0x00);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001169
1170 vlr_subscr_put(vsub);
1171 talloc_free(text);
1172 return CMD_SUCCESS;
1173}
1174
1175DEFUN(subscriber_paging,
1176 subscriber_paging_cmd,
1177 "subscriber " SUBSCR_TYPES " ID paging",
1178 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1179{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001180 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1181 struct subscr_request *req;
1182
1183 if (!vsub) {
1184 vty_out(vty, "%% No subscriber found for %s %s%s",
1185 argv[0], argv[1], VTY_NEWLINE);
1186 return CMD_WARNING;
1187 }
1188
Harald Welte0df904d2018-12-03 11:00:04 +01001189 req = subscr_request_conn(vsub, NULL, NULL, "manual Paging from VTY", SGSAP_SERV_IND_CS_CALL);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001190 if (req)
1191 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1192 else
1193 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1194
1195 vlr_subscr_put(vsub);
1196 return req ? CMD_SUCCESS : CMD_WARNING;
1197}
1198
1199static int loop_by_char(uint8_t ch)
1200{
1201 switch (ch) {
1202 case 'a':
1203 return GSM414_LOOP_A;
1204 case 'b':
1205 return GSM414_LOOP_B;
1206 case 'c':
1207 return GSM414_LOOP_C;
1208 case 'd':
1209 return GSM414_LOOP_D;
1210 case 'e':
1211 return GSM414_LOOP_E;
1212 case 'f':
1213 return GSM414_LOOP_F;
1214 case 'i':
1215 return GSM414_LOOP_I;
1216 }
1217 return -1;
1218}
1219
1220DEFUN(subscriber_mstest_close,
1221 subscriber_mstest_close_cmd,
1222 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1223 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1224 "Close a TCH Loop inside the MS\n"
1225 "Loop Type A\n"
1226 "Loop Type B\n"
1227 "Loop Type C\n"
1228 "Loop Type D\n"
1229 "Loop Type E\n"
1230 "Loop Type F\n"
1231 "Loop Type I\n")
1232{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001233 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001234 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1235 const char *loop_str;
1236 int loop_mode;
1237
1238 if (!vsub) {
1239 vty_out(vty, "%% No subscriber found for %s %s%s",
1240 argv[0], argv[1], VTY_NEWLINE);
1241 return CMD_WARNING;
1242 }
1243
1244 loop_str = argv[2];
1245 loop_mode = loop_by_char(loop_str[0]);
1246
1247 conn = connection_for_subscr(vsub);
1248 if (!conn) {
1249 vty_out(vty, "%% An active connection is required for %s %s%s",
1250 argv[0], argv[1], VTY_NEWLINE);
1251 vlr_subscr_put(vsub);
1252 return CMD_WARNING;
1253 }
1254
1255 gsm0414_tx_close_tch_loop_cmd(conn, loop_mode);
1256
1257 return CMD_SUCCESS;
1258}
1259
1260DEFUN(subscriber_mstest_open,
1261 subscriber_mstest_open_cmd,
1262 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1263 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1264 "Open a TCH Loop inside the MS\n")
1265{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001266 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001267 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1268
1269 if (!vsub) {
1270 vty_out(vty, "%% No subscriber found for %s %s%s",
1271 argv[0], argv[1], VTY_NEWLINE);
1272 return CMD_WARNING;
1273 }
1274
1275 conn = connection_for_subscr(vsub);
1276 if (!conn) {
1277 vty_out(vty, "%% An active connection is required for %s %s%s",
1278 argv[0], argv[1], VTY_NEWLINE);
1279 vlr_subscr_put(vsub);
1280 return CMD_WARNING;
1281 }
1282
1283 gsm0414_tx_open_loop_cmd(conn);
1284
1285 return CMD_SUCCESS;
1286}
1287
1288DEFUN(ena_subscr_expire,
1289 ena_subscr_expire_cmd,
1290 "subscriber " SUBSCR_TYPES " ID expire",
1291 SUBSCR_HELP "Expire the subscriber Now\n")
1292{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001293 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1294 argv[1]);
1295
1296 if (!vsub) {
1297 vty_out(vty, "%% No subscriber found for %s %s%s",
1298 argv[0], argv[1], VTY_NEWLINE);
1299 return CMD_WARNING;
1300 }
1301
1302 if (vlr_subscr_expire(vsub))
1303 vty_out(vty, "%% VLR released subscriber %s%s",
1304 vlr_subscr_name(vsub), VTY_NEWLINE);
1305
1306 if (vsub->use_count > 1)
1307 vty_out(vty, "%% Subscriber %s is still in use,"
1308 " should be released soon%s",
1309 vlr_subscr_name(vsub), VTY_NEWLINE);
1310
1311 vlr_subscr_put(vsub);
1312 return CMD_SUCCESS;
1313}
1314
1315static int scall_cbfn(unsigned int subsys, unsigned int signal,
1316 void *handler_data, void *signal_data)
1317{
1318 struct scall_signal_data *sigdata = signal_data;
1319 struct vty *vty = sigdata->data;
1320
1321 switch (signal) {
1322 case S_SCALL_SUCCESS:
1323 vty_out(vty, "%% silent call success%s", VTY_NEWLINE);
1324 break;
1325 case S_SCALL_EXPIRED:
1326 vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE);
1327 break;
1328 }
1329 return 0;
1330}
1331
1332DEFUN(show_stats,
1333 show_stats_cmd,
1334 "show statistics",
1335 SHOW_STR "Display network statistics\n")
1336{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001337 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001338 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1339 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1340 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001341 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001342 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001343 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001344 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001345 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001346 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1347 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001348 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001349 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001350 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1351 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001352 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001353 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001354 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1355 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1356 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001357 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001358 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001359 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1360 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001361 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001362 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001363 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1364 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001365 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001366 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001367 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1368 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1369 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1370 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1371 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001372 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001373 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1374 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1375 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1376 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1377 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001378 return CMD_SUCCESS;
1379}
1380
1381DEFUN(show_smsqueue,
1382 show_smsqueue_cmd,
1383 "show sms-queue",
1384 SHOW_STR "Display SMSqueue statistics\n")
1385{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001386 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001387 return CMD_SUCCESS;
1388}
1389
1390DEFUN(smsqueue_trigger,
1391 smsqueue_trigger_cmd,
1392 "sms-queue trigger",
1393 "SMS Queue\n" "Trigger sending messages\n")
1394{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001395 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001396 return CMD_SUCCESS;
1397}
1398
1399DEFUN(smsqueue_max,
1400 smsqueue_max_cmd,
1401 "sms-queue max-pending <1-500>",
1402 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1403{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001404 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001405 return CMD_SUCCESS;
1406}
1407
1408DEFUN(smsqueue_clear,
1409 smsqueue_clear_cmd,
1410 "sms-queue clear",
1411 "SMS Queue\n" "Clear the queue of pending SMS\n")
1412{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001413 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001414 return CMD_SUCCESS;
1415}
1416
1417DEFUN(smsqueue_fail,
1418 smsqueue_fail_cmd,
1419 "sms-queue max-failure <1-500>",
1420 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1421{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001422 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001423 return CMD_SUCCESS;
1424}
1425
1426
1427DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1428 "mncc-int", "Configure internal MNCC handler")
1429{
1430 vty->node = MNCC_INT_NODE;
1431
1432 return CMD_SUCCESS;
1433}
1434
1435static struct cmd_node mncc_int_node = {
1436 MNCC_INT_NODE,
1437 "%s(config-mncc-int)# ",
1438 1,
1439};
1440
1441static const struct value_string tchf_codec_names[] = {
1442 { GSM48_CMODE_SPEECH_V1, "fr" },
1443 { GSM48_CMODE_SPEECH_EFR, "efr" },
1444 { GSM48_CMODE_SPEECH_AMR, "amr" },
1445 { 0, NULL }
1446};
1447
1448static const struct value_string tchh_codec_names[] = {
1449 { GSM48_CMODE_SPEECH_V1, "hr" },
1450 { GSM48_CMODE_SPEECH_AMR, "amr" },
1451 { 0, NULL }
1452};
1453
1454static int config_write_mncc_int(struct vty *vty)
1455{
1456 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1457 vty_out(vty, " default-codec tch-f %s%s",
1458 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1459 VTY_NEWLINE);
1460 vty_out(vty, " default-codec tch-h %s%s",
1461 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1462 VTY_NEWLINE);
1463
1464 return CMD_SUCCESS;
1465}
1466
1467DEFUN(mnccint_def_codec_f,
1468 mnccint_def_codec_f_cmd,
1469 "default-codec tch-f (fr|efr|amr)",
1470 "Set default codec\n" "Codec for TCH/F\n"
1471 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1472{
1473 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1474
1475 return CMD_SUCCESS;
1476}
1477
1478DEFUN(mnccint_def_codec_h,
1479 mnccint_def_codec_h_cmd,
1480 "default-codec tch-h (hr|amr)",
1481 "Set default codec\n" "Codec for TCH/H\n"
1482 "Half-Rate\n" "Adaptive Multi-Rate\n")
1483{
1484 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1485
1486 return CMD_SUCCESS;
1487}
1488
1489
1490DEFUN(logging_fltr_imsi,
1491 logging_fltr_imsi_cmd,
1492 "logging filter imsi IMSI",
1493 LOGGING_STR FILTER_STR
1494 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1495{
1496 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001497 struct log_target *tgt = osmo_log_vty2tgt(vty);
1498 const char *imsi = argv[0];
1499
1500 if (!tgt)
1501 return CMD_WARNING;
1502
1503 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi);
1504
1505 if (!vlr_subscr) {
1506 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1507 argv[0], VTY_NEWLINE);
1508 return CMD_WARNING;
1509 }
1510
1511 log_set_filter_vlr_subscr(tgt, vlr_subscr);
1512 return CMD_SUCCESS;
1513}
1514
1515static struct cmd_node hlr_node = {
1516 HLR_NODE,
1517 "%s(config-hlr)# ",
1518 1,
1519};
1520
1521DEFUN(cfg_hlr, cfg_hlr_cmd,
1522 "hlr", "Configure connection to the HLR")
1523{
1524 vty->node = HLR_NODE;
1525 return CMD_SUCCESS;
1526}
1527
1528DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1529 "Remote GSUP address of the HLR\n"
1530 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1531{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001532 talloc_free((void*)gsmnet->gsup_server_addr_str);
1533 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1534 return CMD_SUCCESS;
1535}
1536
1537DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1538 "Remote GSUP port of the HLR\n"
1539 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1540{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001541 gsmnet->gsup_server_port = atoi(argv[0]);
1542 return CMD_SUCCESS;
1543}
1544
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001545DEFUN(cfg_hlr_ipa_name,
1546 cfg_hlr_ipa_name_cmd,
1547 "ipa-name NAME",
1548 "Set the IPA name of this MSC\n"
1549 "A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. "
1550 "This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. "
1551 "The default is 'MSC-00-00-00-00-00-00'.\n")
1552{
1553 if (vty->type != VTY_FILE) {
1554 vty_out(vty, "The IPA name cannot be changed at run-time; "
1555 "It can only be set in the configuraton file.%s", VTY_NEWLINE);
1556 return CMD_WARNING;
1557 }
1558
1559 gsmnet->msc_ipa_name = talloc_strdup(gsmnet, argv[0]);
1560 return CMD_SUCCESS;
1561}
1562
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001563static int config_write_hlr(struct vty *vty)
1564{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001565 vty_out(vty, "hlr%s", VTY_NEWLINE);
1566 vty_out(vty, " remote-ip %s%s",
1567 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1568 vty_out(vty, " remote-port %u%s",
1569 gsmnet->gsup_server_port, VTY_NEWLINE);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001570 if (gsmnet->msc_ipa_name)
1571 vty_out(vty, " ipa-name %s%s", gsmnet->msc_ipa_name, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001572 return CMD_SUCCESS;
1573}
1574
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001575void msc_vty_init(struct gsm_network *msc_network)
1576{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001577 OSMO_ASSERT(gsmnet == NULL);
1578 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001579
1580 osmo_stats_vty_add_cmds();
1581
1582 install_element(CONFIG_NODE, &cfg_net_cmd);
1583 install_node(&net_node, config_write_net);
1584 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
1585 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1586 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1587 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
1588 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
1589 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
1590 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
1591 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
1592 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
1593 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
1594 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
1595 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
1596 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001597
1598 install_element(CONFIG_NODE, &cfg_msc_cmd);
1599 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001600 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01001601 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
1602 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02001603 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01001604 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Vadim Yanitskiy64623e12018-11-28 23:05:51 +07001605 install_element(MSC_NODE, &cfg_msc_ncss_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001606 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01001607 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
1608 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Oliver Smith0fec28a2018-12-14 10:52:52 +01001609 install_element(MSC_NODE, &cfg_msc_check_imei_rqd_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001610 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
1611 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01001612 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01001613 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +07001614 install_element(MSC_NODE, &cfg_msc_sms_over_gsup_cmd);
1615 install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001616
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02001617 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001618#ifdef BUILD_IU
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +01001619 ranap_iu_vty_init(MSC_NODE, &msc_network->iu.rab_assign_addr_enc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001620#endif
Harald Welte0df904d2018-12-03 11:00:04 +01001621 sgs_vty_init();
Stefan Sperling617ac802018-02-22 17:58:20 +01001622 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001623
1624 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
1625
1626 install_element_ve(&show_subscr_cmd);
1627 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01001628 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001629 install_element_ve(&show_msc_conn_cmd);
1630 install_element_ve(&show_msc_transaction_cmd);
1631
1632 install_element_ve(&sms_send_pend_cmd);
1633 install_element_ve(&sms_delete_expired_cmd);
1634
1635 install_element_ve(&subscriber_create_cmd);
1636 install_element_ve(&subscriber_send_sms_cmd);
1637 install_element_ve(&subscriber_silent_sms_cmd);
1638 install_element_ve(&subscriber_silent_call_start_cmd);
1639 install_element_ve(&subscriber_silent_call_stop_cmd);
1640 install_element_ve(&subscriber_ussd_notify_cmd);
1641 install_element_ve(&subscriber_mstest_close_cmd);
1642 install_element_ve(&subscriber_mstest_open_cmd);
1643 install_element_ve(&subscriber_paging_cmd);
1644 install_element_ve(&show_stats_cmd);
1645 install_element_ve(&show_smsqueue_cmd);
1646 install_element_ve(&logging_fltr_imsi_cmd);
1647
1648 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
1649 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
1650 install_element(ENABLE_NODE, &smsqueue_max_cmd);
1651 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
1652 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
1653 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
1654
1655 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1656 install_node(&mncc_int_node, config_write_mncc_int);
1657 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1658 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1659
1660 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
1661
1662 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1663 install_node(&hlr_node, config_write_hlr);
1664 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1665 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001666 install_element(HLR_NODE, &cfg_hlr_ipa_name_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001667}