blob: 93d093f5b242b27722ce4cb38967345a0a7820e2 [file] [log] [blame]
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001/* MSC interface to quagga VTY */
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002/* (C) 2016-2018 by sysmocom s.m.f.c. GmbH <info@sysmocom.de>
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02003 * Based on OpenBSC interface to quagga VTY (libmsc/vty_interface_layer3.c)
Harald Welte7b222aa2017-12-23 19:30:32 +01004 * (C) 2009-2017 by Harald Welte <laforge@gnumonks.org>
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02005 * (C) 2009-2011 by Holger Hans Peter Freyther
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23/* NOTE: I would have liked to call this the MSC_NODE instead of the MSC_NODE,
24 * but MSC_NODE already exists to configure a remote MSC for osmo-bsc. */
25
Neels Hofmeyr00e82d62017-07-05 15:19:52 +020026#include "../../bscconfig.h"
27
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020028#include <inttypes.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010029#include <limits.h>
30
31#include <osmocom/gsm/protocol/gsm_08_58.h>
32#include <osmocom/gsm/protocol/gsm_04_14.h>
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020033
Maxc51609a2018-11-09 17:13:00 +010034#include <osmocom/sigtran/sccp_helpers.h>
35
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020036#include <osmocom/vty/command.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010037#include <osmocom/vty/logging.h>
Stefan Sperling617ac802018-02-22 17:58:20 +010038#include <osmocom/vty/misc.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010039#include <osmocom/vty/stats.h>
40
Neels Hofmeyr00e82d62017-07-05 15:19:52 +020041#ifdef BUILD_IU
42#include <osmocom/ranap/iu_client.h>
43#endif
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020044
Neels Hofmeyr90843962017-09-04 15:04:35 +020045#include <osmocom/msc/vty.h>
46#include <osmocom/msc/gsm_data.h>
47#include <osmocom/msc/gsm_subscriber.h>
48#include <osmocom/msc/vlr.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010049#include <osmocom/msc/transaction.h>
50#include <osmocom/msc/db.h>
Maxc51609a2018-11-09 17:13:00 +010051#include <osmocom/msc/a_iface.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010052#include <osmocom/msc/sms_queue.h>
53#include <osmocom/msc/silent_call.h>
54#include <osmocom/msc/gsm_04_80.h>
55#include <osmocom/msc/gsm_04_14.h>
56#include <osmocom/msc/signal.h>
57#include <osmocom/msc/mncc_int.h>
Vadim Yanitskiy1b891302018-08-04 01:33:08 +070058#include <osmocom/msc/rrlp.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010059
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010060static struct gsm_network *gsmnet = NULL;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010061
62struct cmd_node net_node = {
63 GSMNET_NODE,
64 "%s(config-net)# ",
65 1,
66};
67
68#define NETWORK_STR "Configure the GSM network\n"
69#define CODE_CMD_STR "Code commands\n"
70#define NAME_CMD_STR "Name Commands\n"
71#define NAME_STR "Name to use\n"
72
73DEFUN(cfg_net,
74 cfg_net_cmd,
75 "network", NETWORK_STR)
76{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010077 vty->index = gsmnet;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010078 vty->node = GSMNET_NODE;
79
80 return CMD_SUCCESS;
81}
82
83DEFUN(cfg_net_ncc,
84 cfg_net_ncc_cmd,
85 "network country code <1-999>",
86 "Set the GSM network country code\n"
87 "Country commands\n"
88 CODE_CMD_STR
89 "Network Country Code to use\n")
90{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010091 gsmnet->plmn.mcc = atoi(argv[0]);
92
93 return CMD_SUCCESS;
94}
95
96DEFUN(cfg_net_mnc,
97 cfg_net_mnc_cmd,
98 "mobile network code <0-999>",
99 "Set the GSM mobile network code\n"
100 "Network Commands\n"
101 CODE_CMD_STR
102 "Mobile Network Code to use\n")
103{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100104 uint16_t mnc;
105 bool mnc_3_digits;
106
107 if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
108 vty_out(vty, "%% Error decoding MNC: %s%s", argv[0], VTY_NEWLINE);
109 return CMD_WARNING;
110 }
111
112 gsmnet->plmn.mnc = mnc;
113 gsmnet->plmn.mnc_3_digits = mnc_3_digits;
114
115 return CMD_SUCCESS;
116}
117
118DEFUN(cfg_net_name_short,
119 cfg_net_name_short_cmd,
120 "short name NAME",
121 "Set the short GSM network name\n" NAME_CMD_STR NAME_STR)
122{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100123 osmo_talloc_replace_string(gsmnet, &gsmnet->name_short, argv[0]);
124 return CMD_SUCCESS;
125}
126
127DEFUN(cfg_net_name_long,
128 cfg_net_name_long_cmd,
129 "long name NAME",
130 "Set the long GSM network name\n" NAME_CMD_STR NAME_STR)
131{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100132 osmo_talloc_replace_string(gsmnet, &gsmnet->name_long, argv[0]);
133 return CMD_SUCCESS;
134}
135
136DEFUN(cfg_net_encryption,
137 cfg_net_encryption_cmd,
138 "encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]",
139 "Encryption options\n"
140 "GSM A5 Air Interface Encryption\n"
141 "A5/n Algorithm Number\n"
142 "A5/n Algorithm Number\n"
143 "A5/n Algorithm Number\n"
144 "A5/n Algorithm Number\n")
145{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100146 unsigned int i;
147
148 gsmnet->a5_encryption_mask = 0;
149 for (i = 0; i < argc; i++)
150 gsmnet->a5_encryption_mask |= (1 << atoi(argv[i]));
151
152 return CMD_SUCCESS;
153}
154
155DEFUN(cfg_net_authentication,
156 cfg_net_authentication_cmd,
157 "authentication (optional|required)",
158 "Whether to enforce MS authentication in 2G\n"
159 "Allow MS to attach via 2G BSC without authentication\n"
160 "Always do authentication\n")
161{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100162 gsmnet->authentication_required = (argv[0][0] == 'r') ? true : false;
163
164 return CMD_SUCCESS;
165}
166
167DEFUN(cfg_net_rrlp_mode, cfg_net_rrlp_mode_cmd,
168 "rrlp mode (none|ms-based|ms-preferred|ass-preferred)",
169 "Radio Resource Location Protocol\n"
170 "Set the Radio Resource Location Protocol Mode\n"
171 "Don't send RRLP request\n"
172 "Request MS-based location\n"
173 "Request any location, prefer MS-based\n"
174 "Request any location, prefer MS-assisted\n")
175{
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700176 gsmnet->rrlp.mode = msc_rrlp_mode_parse(argv[0]);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100177
178 return CMD_SUCCESS;
179}
180
181DEFUN(cfg_net_mm_info, cfg_net_mm_info_cmd,
182 "mm info (0|1)",
183 "Mobility Management\n"
184 "Send MM INFO after LOC UPD ACCEPT\n"
185 "Disable\n" "Enable\n")
186{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100187 gsmnet->send_mm_info = atoi(argv[0]);
188
189 return CMD_SUCCESS;
190}
191
192DEFUN(cfg_net_timezone,
193 cfg_net_timezone_cmd,
194 "timezone <-19-19> (0|15|30|45)",
195 "Set the Timezone Offset of the network\n"
196 "Timezone offset (hours)\n"
197 "Timezone offset (00 minutes)\n"
198 "Timezone offset (15 minutes)\n"
199 "Timezone offset (30 minutes)\n"
200 "Timezone offset (45 minutes)\n"
201 )
202{
203 struct gsm_network *net = vty->index;
204 int tzhr = atoi(argv[0]);
205 int tzmn = atoi(argv[1]);
206
207 net->tz.hr = tzhr;
208 net->tz.mn = tzmn;
209 net->tz.dst = 0;
210 net->tz.override = 1;
211
212 return CMD_SUCCESS;
213}
214
215DEFUN(cfg_net_timezone_dst,
216 cfg_net_timezone_dst_cmd,
217 "timezone <-19-19> (0|15|30|45) <0-2>",
218 "Set the Timezone Offset of the network\n"
219 "Timezone offset (hours)\n"
220 "Timezone offset (00 minutes)\n"
221 "Timezone offset (15 minutes)\n"
222 "Timezone offset (30 minutes)\n"
223 "Timezone offset (45 minutes)\n"
224 "DST offset (hours)\n"
225 )
226{
227 struct gsm_network *net = vty->index;
228 int tzhr = atoi(argv[0]);
229 int tzmn = atoi(argv[1]);
230 int tzdst = atoi(argv[2]);
231
232 net->tz.hr = tzhr;
233 net->tz.mn = tzmn;
234 net->tz.dst = tzdst;
235 net->tz.override = 1;
236
237 return CMD_SUCCESS;
238}
239
240DEFUN(cfg_net_no_timezone,
241 cfg_net_no_timezone_cmd,
242 "no timezone",
243 NO_STR
244 "Disable network timezone override, use system tz\n")
245{
246 struct gsm_network *net = vty->index;
247
248 net->tz.override = 0;
249
250 return CMD_SUCCESS;
251}
252
253DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
254 "periodic location update <6-1530>",
255 "Periodic Location Updating Interval\n"
256 "Periodic Location Updating Interval\n"
257 "Periodic Location Updating Interval\n"
258 "Periodic Location Updating Interval in Minutes\n")
259{
260 struct gsm_network *net = vty->index;
261
262 net->t3212 = atoi(argv[0]) / 6;
263
264 return CMD_SUCCESS;
265}
266
267DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
268 "no periodic location update",
269 NO_STR
270 "Periodic Location Updating Interval\n"
271 "Periodic Location Updating Interval\n"
272 "Periodic Location Updating Interval\n")
273{
274 struct gsm_network *net = vty->index;
275
276 net->t3212 = 0;
277
278 return CMD_SUCCESS;
279}
280
281static int config_write_net(struct vty *vty)
282{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100283 int i;
284
285 vty_out(vty, "network%s", VTY_NEWLINE);
286 vty_out(vty, " network country code %s%s", osmo_mcc_name(gsmnet->plmn.mcc), VTY_NEWLINE);
287 vty_out(vty, " mobile network code %s%s",
288 osmo_mnc_name(gsmnet->plmn.mnc, gsmnet->plmn.mnc_3_digits), VTY_NEWLINE);
289 vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
290 vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
291 vty_out(vty, " encryption a5");
292 for (i = 0; i < 8; i++) {
293 if (gsmnet->a5_encryption_mask & (1 << i))
294 vty_out(vty, " %u", i);
295 }
296 vty_out(vty, "%s", VTY_NEWLINE);
297 vty_out(vty, " authentication %s%s",
298 gsmnet->authentication_required ? "required" : "optional", VTY_NEWLINE);
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700299 vty_out(vty, " rrlp mode %s%s", msc_rrlp_mode_name(gsmnet->rrlp.mode),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100300 VTY_NEWLINE);
301 vty_out(vty, " mm info %u%s", gsmnet->send_mm_info, VTY_NEWLINE);
302 if (gsmnet->tz.override != 0) {
303 if (gsmnet->tz.dst)
304 vty_out(vty, " timezone %d %d %d%s",
305 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
306 VTY_NEWLINE);
307 else
308 vty_out(vty, " timezone %d %d%s",
309 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
310 }
311 if (gsmnet->t3212 == 0)
312 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
313 else
314 vty_out(vty, " periodic location update %u%s",
315 gsmnet->t3212 * 6, VTY_NEWLINE);
316
317 if (gsmnet->emergency.route_to_msisdn) {
318 vty_out(vty, " emergency-call route-to-msisdn %s%s",
319 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
320 }
321
322 return CMD_SUCCESS;
323}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200324
325static struct cmd_node msc_node = {
326 MSC_NODE,
327 "%s(config-msc)# ",
328 1,
329};
330
331DEFUN(cfg_msc, cfg_msc_cmd,
332 "msc", "Configure MSC options")
333{
334 vty->node = MSC_NODE;
335 return CMD_SUCCESS;
336}
337
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100338#define MNCC_STR "Configure Mobile Network Call Control\n"
339#define MNCC_GUARD_TIMEOUT_STR "Set global guard timer for mncc interface activity\n"
340#define MNCC_GUARD_TIMEOUT_VALUE_STR "guard timer value (sec.)\n"
341
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100342DEFUN(cfg_msc_mncc_internal,
343 cfg_msc_mncc_internal_cmd,
344 "mncc internal",
345 MNCC_STR "Use internal MNCC handler (default; changes need a program restart)\n")
346{
347 gsm_network_set_mncc_sock_path(gsmnet, NULL);
348 return CMD_SUCCESS;
349}
350
351DEFUN(cfg_msc_mncc_external,
352 cfg_msc_mncc_external_cmd,
353 "mncc external MNCC_SOCKET_PATH",
354 MNCC_STR "Use external MNCC handler (changes need a program restart)\n"
355 "File system path to create the MNCC unix domain socket at\n")
356{
357 gsm_network_set_mncc_sock_path(gsmnet, argv[0]);
358 return CMD_SUCCESS;
359}
360
Philipp Maier9ca7b312018-10-10 17:00:49 +0200361DEFUN(cfg_msc_mncc_guard_timeout,
362 cfg_msc_mncc_guard_timeout_cmd,
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100363 "mncc guard-timeout <0-255>",
364 MNCC_STR
365 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR)
Philipp Maier9ca7b312018-10-10 17:00:49 +0200366{
367 gsmnet->mncc_guard_timeout = atoi(argv[0]);
368 return CMD_SUCCESS;
369}
370
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100371ALIAS_DEPRECATED(cfg_msc_mncc_guard_timeout,
372 cfg_msc_deprecated_mncc_guard_timeout_cmd,
373 "mncc-guard-timeout <0-255>",
374 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR);
375
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200376DEFUN(cfg_msc_assign_tmsi, cfg_msc_assign_tmsi_cmd,
377 "assign-tmsi",
378 "Assign TMSI during Location Updating.\n")
379{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200380 gsmnet->vlr->cfg.assign_tmsi = true;
381 return CMD_SUCCESS;
382}
383
384DEFUN(cfg_msc_no_assign_tmsi, cfg_msc_no_assign_tmsi_cmd,
385 "no assign-tmsi",
386 NO_STR "Assign TMSI during Location Updating.\n")
387{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200388 gsmnet->vlr->cfg.assign_tmsi = false;
389 return CMD_SUCCESS;
390}
391
Philipp Maierfbf66102017-04-09 12:32:51 +0200392DEFUN(cfg_msc_cs7_instance_a,
393 cfg_msc_cs7_instance_a_cmd,
394 "cs7-instance-a <0-15>",
395 "Set SS7 to be used by the A-Interface.\n" "SS7 instance reference number\n")
396{
Philipp Maierfbf66102017-04-09 12:32:51 +0200397 gsmnet->a.cs7_instance = atoi(argv[0]);
398 return CMD_SUCCESS;
399}
400
401DEFUN(cfg_msc_cs7_instance_iu,
402 cfg_msc_cs7_instance_iu_cmd,
403 "cs7-instance-iu <0-15>",
404 "Set SS7 to be used by the Iu-Interface.\n" "SS7 instance reference number\n")
405{
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100406#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200407 gsmnet->iu.cs7_instance = atoi(argv[0]);
408 return CMD_SUCCESS;
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100409#else
410 vty_out(vty, "WARNING: 'cs7-instance-iu' without effect: built without Iu support%s",
411 VTY_NEWLINE);
412 return CMD_WARNING;
413#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200414}
415
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100416DEFUN(cfg_msc_auth_tuple_max_reuse_count, cfg_msc_auth_tuple_max_reuse_count_cmd,
417 "auth-tuple-max-reuse-count <-1-2147483647>",
418 "Configure authentication tuple re-use\n"
419 "0 to use each auth tuple at most once (default), >0 to limit re-use, -1 to re-use infinitely (vulnerable!).\n")
420{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100421 gsmnet->vlr->cfg.auth_tuple_max_reuse_count = atoi(argv[0]);
422 return CMD_SUCCESS;
423}
424
425DEFUN(cfg_msc_auth_tuple_reuse_on_error, cfg_msc_auth_tuple_reuse_on_error_cmd,
426 "auth-tuple-reuse-on-error (0|1)",
427 "Configure authentication tuple re-use when HLR is not responsive\n"
Oliver Smithd6e24fd2019-01-09 10:46:43 +0100428 "Never re-use auth tuples beyond auth-tuple-max-reuse-count (default)\n"
429 "If the HLR does not deliver new tuples, do re-use already available old ones.\n")
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100430{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100431 gsmnet->vlr->cfg.auth_reuse_old_sets_on_error = atoi(argv[0]) ? true : false;
432 return CMD_SUCCESS;
433}
434
Oliver Smith0fec28a2018-12-14 10:52:52 +0100435DEFUN(cfg_msc_check_imei_rqd, cfg_msc_check_imei_rqd_cmd,
436 "check-imei-rqd (0|1)",
437 "Send each IMEI to the EIR to ask if it is permitted or not. The EIR is implemented as part of OsmoHLR, "
438 "and can optionally save the IMEI in the HLR.\n"
439 "Do not send IMEIs to the EIR\n"
440 "Send each IMEI to the EIR\n")
441{
442 gsmnet->vlr->cfg.check_imei_rqd = atoi(argv[0]) ? true : false;
443 return CMD_SUCCESS;
444}
445
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100446DEFUN(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd,
447 "paging response-timer (default|<1-65535>)",
448 "Configure Paging\n"
449 "Set Paging timeout, the minimum time to pass between (unsuccessful) Pagings sent towards"
450 " BSS or RNC\n"
451 "Set to default timeout (" OSMO_STRINGIFY_VAL(MSC_PAGING_RESPONSE_TIMER_DEFAULT) " seconds)\n"
452 "Set paging timeout in seconds\n")
453{
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100454 if (!strcmp(argv[1], "default"))
455 gsmnet->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
456 else
457 gsmnet->paging_response_timer = atoi(argv[0]);
458 return CMD_SUCCESS;
459}
460
Harald Welte69c54a82018-02-09 20:41:14 +0100461DEFUN(cfg_msc_emergency_msisdn, cfg_msc_emergency_msisdn_cmd,
462 "emergency-call route-to-msisdn MSISDN",
463 "Configure Emergency Call Behaviour\n"
464 "MSISDN to which Emergency Calls are Dispatched\n"
465 "MSISDN (E.164 Phone Number)\n")
466{
Harald Welte69c54a82018-02-09 20:41:14 +0100467 osmo_talloc_replace_string(gsmnet, &gsmnet->emergency.route_to_msisdn, argv[0]);
468
469 return CMD_SUCCESS;
470}
471
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700472/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
473DEFUN(cfg_msc_sms_over_gsup, cfg_msc_sms_over_gsup_cmd,
474 "sms-over-gsup",
475 "Enable routing of SMS messages over GSUP\n")
476{
477 gsmnet->sms_over_gsup = true;
478 return CMD_SUCCESS;
479}
480
481/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
482DEFUN(cfg_msc_no_sms_over_gsup, cfg_msc_no_sms_over_gsup_cmd,
483 "no sms-over-gsup",
484 NO_STR "Disable routing of SMS messages over GSUP\n")
485{
486 gsmnet->sms_over_gsup = false;
487 return CMD_SUCCESS;
488}
489
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200490static int config_write_msc(struct vty *vty)
491{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200492 vty_out(vty, "msc%s", VTY_NEWLINE);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100493 if (gsmnet->mncc_sock_path)
494 vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE);
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100495 vty_out(vty, " mncc guard-timeout %i%s",
Philipp Maier9ca7b312018-10-10 17:00:49 +0200496 gsmnet->mncc_guard_timeout, VTY_NEWLINE);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200497 vty_out(vty, " %sassign-tmsi%s",
498 gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
499
Philipp Maierfbf66102017-04-09 12:32:51 +0200500 vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
501 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100502#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200503 vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance,
504 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100505#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200506
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100507 if (gsmnet->vlr->cfg.auth_tuple_max_reuse_count)
508 vty_out(vty, " auth-tuple-max-reuse-count %d%s",
509 OSMO_MAX(-1, gsmnet->vlr->cfg.auth_tuple_max_reuse_count),
510 VTY_NEWLINE);
511 if (gsmnet->vlr->cfg.auth_reuse_old_sets_on_error)
512 vty_out(vty, " auth-tuple-reuse-on-error 1%s",
513 VTY_NEWLINE);
514
Oliver Smith0fec28a2018-12-14 10:52:52 +0100515 if (gsmnet->vlr->cfg.check_imei_rqd)
516 vty_out(vty, " check-imei-rqd 1 %s",
517 VTY_NEWLINE);
518
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100519 if (gsmnet->paging_response_timer != MSC_PAGING_RESPONSE_TIMER_DEFAULT)
520 vty_out(vty, " paging response-timer %u%s", gsmnet->paging_response_timer, VTY_NEWLINE);
521
Harald Welte69c54a82018-02-09 20:41:14 +0100522 if (gsmnet->emergency.route_to_msisdn) {
523 vty_out(vty, " emergency-call route-to-msisdn %s%s",
524 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
525 }
526
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700527 if (gsmnet->sms_over_gsup)
528 vty_out(vty, " sms-over-gsup%s", VTY_NEWLINE);
529
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +0200530 mgcp_client_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200531#ifdef BUILD_IU
Neels Hofmeyr00e82d62017-07-05 15:19:52 +0200532 ranap_iu_vty_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200533#endif
534
535 return CMD_SUCCESS;
536}
537
Maxc51609a2018-11-09 17:13:00 +0100538DEFUN(show_bsc, show_bsc_cmd,
539 "show bsc", SHOW_STR "BSC\n")
540{
541 struct bsc_context *bsc_ctx;
542 struct osmo_ss7_instance *ss7 = osmo_ss7_instance_find(gsmnet->a.cs7_instance);
543
544 llist_for_each_entry(bsc_ctx, &gsmnet->a.bscs, list) {
545 vty_out(vty, "BSC %s%s", osmo_sccp_addr_name(ss7, &bsc_ctx->bsc_addr), VTY_NEWLINE);
546 }
547
548 return CMD_SUCCESS;
549}
550
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100551static void vty_conn_hdr(struct vty *vty)
552{
Max45df98b2019-01-17 18:44:33 +0100553 unsigned lnum = 0;
554 struct ran_conn *conn;
555
556 llist_for_each_entry(conn, &gsmnet->ran_conns, entry)
557 lnum++;
558
559 if (lnum)
560 vty_out(vty, "--ConnId RAN --LAC Use --Tokens C A5 State ------------ Subscriber%s",
561 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100562}
563
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100564static void vty_dump_one_conn(struct vty *vty, const struct ran_conn *conn)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100565{
Max45df98b2019-01-17 18:44:33 +0100566 vty_out(vty, "%08x %3s %5u %3u %08x %c /%1u %27s %22s%s",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100567 conn->a.conn_id,
Neels Hofmeyr7814a832018-12-26 00:40:18 +0100568 conn->via_ran == OSMO_RAT_UTRAN_IU ? "Iu" : "A",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100569 conn->lac,
570 conn->use_count,
571 conn->use_tokens,
572 conn->received_cm_service_request ? 'C' : '-',
Neels Hofmeyrf41658d2018-11-30 04:35:50 +0100573 conn->geran_encr.alg_id,
Neels Hofmeyr4d3a66b2018-03-31 18:45:59 +0200574 conn->fi ? osmo_fsm_inst_state_name(conn->fi) : "-",
Max45df98b2019-01-17 18:44:33 +0100575 conn->vsub ? vlr_subscr_name(conn->vsub) : "-",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100576 VTY_NEWLINE);
577}
578
579DEFUN(show_msc_conn, show_msc_conn_cmd,
580 "show connection", SHOW_STR "Subscriber Connections\n")
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200581{
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100582 struct ran_conn *conn;
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200583
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100584 vty_conn_hdr(vty);
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100585 llist_for_each_entry(conn, &gsmnet->ran_conns, entry)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100586 vty_dump_one_conn(vty, conn);
587
588 return CMD_SUCCESS;
589}
590
591static void vty_trans_hdr(struct vty *vty)
592{
Max45df98b2019-01-17 18:44:33 +0100593 unsigned lnum = 0;
594 struct gsm_trans *trans;
595
596 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
597 lnum++;
598
599 if (lnum)
600 vty_out(vty, "--ConnId -P TI -CallRef [--- Proto ---] ------------ Subscriber%s",
601 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100602}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200603
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100604static const char *get_trans_proto_str(const struct gsm_trans *trans)
605{
606 static char buf[256];
607
608 switch (trans->protocol) {
609 case GSM48_PDISC_CC:
610 snprintf(buf, sizeof(buf), "%s %4u %4u",
611 gsm48_cc_state_name(trans->cc.state),
612 trans->cc.Tcurrent,
613 trans->cc.T308_second);
614 break;
615 case GSM48_PDISC_SMS:
616 snprintf(buf, sizeof(buf), "%s %s",
617 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
618 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
619 break;
620 default:
621 buf[0] = '\0';
622 break;
623 }
624
625 return buf;
626}
627
628static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
629{
Max45df98b2019-01-17 18:44:33 +0100630 vty_out(vty, "%08x %s %02u %08x [%s] %22s%s",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100631 trans->conn ? trans->conn->a.conn_id : 0,
632 gsm48_pdisc_name(trans->protocol),
633 trans->transaction_id,
634 trans->callref,
Max45df98b2019-01-17 18:44:33 +0100635 get_trans_proto_str(trans),
636 trans->vsub ? vlr_subscr_name(trans->vsub) : "-",
637 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100638}
639
640DEFUN(show_msc_transaction, show_msc_transaction_cmd,
641 "show transaction", SHOW_STR "Transactions\n")
642{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100643 struct gsm_trans *trans;
644
645 vty_trans_hdr(vty);
646 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
647 vty_dump_one_trans(vty, trans);
648
649 return CMD_SUCCESS;
650}
651
652static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
653{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100654 struct gsm_trans *trans;
655 int reqs;
656 struct llist_head *entry;
657
658 if (strlen(vsub->name))
659 vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
660 if (strlen(vsub->msisdn))
661 vty_out(vty, " Extension: %s%s", vsub->msisdn,
662 VTY_NEWLINE);
663 vty_out(vty, " LAC: %d/0x%x%s",
Max7d41d872018-12-19 11:48:33 +0100664 vsub->cgi.lai.lac, vsub->cgi.lai.lac, VTY_NEWLINE);
Philipp Maier2a0ac3b2018-12-17 10:03:50 +0100665 vty_out(vty, " RAN: %s%s",
Neels Hofmeyr7814a832018-12-26 00:40:18 +0100666 osmo_rat_type_name(vsub->cs.attached_via_ran), VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100667 vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
668 if (vsub->tmsi != GSM_RESERVED_TMSI)
669 vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
670 VTY_NEWLINE);
671 if (vsub->tmsi_new != GSM_RESERVED_TMSI)
672 vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
673 VTY_NEWLINE);
Philipp Maier6d71ccf2018-12-14 13:30:14 +0100674 if (vsub->imei[0] != '\0')
675 vty_out(vty, " IMEI: %s%s", vsub->imei, VTY_NEWLINE);
676 if (vsub->imeisv[0] != '\0')
677 vty_out(vty, " IMEISV: %s%s", vsub->imeisv, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100678
Philipp Maier89561bc2018-12-14 13:34:25 +0100679 vty_out(vty, " Flags: %s", VTY_NEWLINE);
680 vty_out(vty, " IMSI detached: %s%s",
681 vsub->imsi_detached_flag ? "true" : "false", VTY_NEWLINE);
682 vty_out(vty, " Conf. by radio contact: %s%s",
683 vsub->conf_by_radio_contact_ind ? "true" : "false",
684 VTY_NEWLINE);
685 vty_out(vty, " Subscr. data conf. by HLR: %s%s",
686 vsub->sub_dataconf_by_hlr_ind ? "true" : "false", VTY_NEWLINE);
687 vty_out(vty, " Location conf. in HLR: %s%s",
688 vsub->loc_conf_in_hlr_ind ? "true" : "false", VTY_NEWLINE);
689 vty_out(vty, " Subscriber dormant: %s%s",
690 vsub->dormant_ind ? "true" : "false", VTY_NEWLINE);
691 vty_out(vty, " Received cancel locataion: %s%s",
692 vsub->cancel_loc_rx ? "true" : "false", VTY_NEWLINE);
693 vty_out(vty, " MS not reachable: %s%s",
694 vsub->ms_not_reachable_flag ? "true" : "false", VTY_NEWLINE);
695 vty_out(vty, " LA allowed: %s%s",
696 vsub->la_allowed ? "true" : "false", VTY_NEWLINE);
697
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100698#if 0
699 /* TODO: add this to vlr_subscr? */
700 if (vsub->auth_info.auth_algo != AUTH_ALGO_NONE) {
701 struct gsm_auth_info *i = &vsub->auth_info;
702 vty_out(vty, " A3A8 algorithm id: %d%s",
703 i->auth_algo, VTY_NEWLINE);
704 vty_out(vty, " A3A8 Ki: %s%s",
705 osmo_hexdump(i->a3a8_ki, i->a3a8_ki_len),
706 VTY_NEWLINE);
707 }
708#endif
709
710 if (vsub->last_tuple) {
Neels Hofmeyr8b6e5362018-11-30 02:57:33 +0100711 struct vlr_auth_tuple *t = vsub->last_tuple;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100712 vty_out(vty, " A3A8 last tuple (used %d times):%s",
713 t->use_count, VTY_NEWLINE);
714 vty_out(vty, " seq # : %d%s",
715 t->key_seq, VTY_NEWLINE);
716 vty_out(vty, " RAND : %s%s",
717 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
718 VTY_NEWLINE);
719 vty_out(vty, " SRES : %s%s",
720 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
721 VTY_NEWLINE);
722 vty_out(vty, " Kc : %s%s",
723 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
724 VTY_NEWLINE);
725 }
726
727 reqs = 0;
728 llist_for_each(entry, &vsub->cs.requests)
729 reqs += 1;
730 vty_out(vty, " Paging: %s paging for %d requests%s",
731 vsub->cs.is_paging ? "is" : "not", reqs, VTY_NEWLINE);
732 vty_out(vty, " Use count: %u%s", vsub->use_count, VTY_NEWLINE);
733
734 /* Connection */
735 if (vsub->msc_conn_ref) {
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100736 struct ran_conn *conn = vsub->msc_conn_ref;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100737 vty_conn_hdr(vty);
738 vty_dump_one_conn(vty, conn);
739 }
740
741 /* Transactions */
742 vty_trans_hdr(vty);
743 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
744 if (trans->vsub != vsub)
745 continue;
746 vty_dump_one_trans(vty, trans);
747 }
748}
749
750/* Subscriber */
751DEFUN(show_subscr_cache,
752 show_subscr_cache_cmd,
753 "show subscriber cache",
754 SHOW_STR "Show information about subscribers\n"
755 "Display contents of subscriber cache\n")
756{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100757 struct vlr_subscr *vsub;
758 int count = 0;
759
760 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
761 if (++count > 100) {
762 vty_out(vty, "%% More than %d subscribers in cache,"
763 " stopping here.%s", count-1, VTY_NEWLINE);
764 break;
765 }
766 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
767 subscr_dump_full_vty(vty, vsub);
Harald Welte69c54a82018-02-09 20:41:14 +0100768 }
769
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200770 return CMD_SUCCESS;
771}
772
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100773DEFUN(sms_send_pend,
774 sms_send_pend_cmd,
775 "sms send pending",
776 "SMS related commands\n" "SMS Sending related commands\n"
777 "Send all pending SMS")
778{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100779 struct gsm_sms *sms;
780 unsigned long long sms_id = 0;
781
782 while (1) {
783 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
784 if (!sms)
785 break;
786
787 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700788 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100789
790 sms_id = sms->id + 1;
791 }
792
793 return CMD_SUCCESS;
794}
795
796DEFUN(sms_delete_expired,
797 sms_delete_expired_cmd,
798 "sms delete expired",
799 "SMS related commands\n" "SMS Database related commands\n"
800 "Delete all expired SMS")
801{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100802 struct gsm_sms *sms;
803 unsigned long long sms_id = 0;
804 long long num_deleted = 0;
805
806 while (1) {
807 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
808 if (!sms)
809 break;
810
811 /* Skip SMS which are currently queued for sending. */
812 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
813 continue;
814
815 /* Expiration check is performed by the DB layer. */
816 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
817 num_deleted++;
818
819 sms_id = sms->id + 1;
820 }
821
822 if (num_deleted == 0) {
823 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
824 return CMD_WARNING;
825 }
826
827 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
828 return CMD_SUCCESS;
829}
830
831static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +0200832 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100833 char *str, uint8_t tp_pid)
834{
835 struct gsm_network *net = receiver->vlr->user_ctx;
836 struct gsm_sms *sms;
837
Harald Welte39b55482018-04-09 19:19:33 +0200838 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100839 sms->protocol_id = tp_pid;
840
841 /* store in database for the queue */
842 if (db_sms_store(sms) != 0) {
843 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
844 sms_free(sms);
845 return CMD_WARNING;
846 }
847 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
848
849 sms_free(sms);
850 sms_queue_trigger(net->sms_queue);
851 return CMD_SUCCESS;
852}
853
854static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
855 const char *type,
856 const char *id)
857{
858 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
859 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id);
860 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
861 return vlr_subscr_find_by_imsi(gsmnet->vlr, id);
862 else if (!strcmp(type, "tmsi"))
863 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id));
864
865 return NULL;
866}
867#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
868#define SUBSCR_HELP "Operations on a Subscriber\n" \
869 "Identify subscriber by MSISDN (phone number)\n" \
870 "Legacy alias for 'msisdn'\n" \
871 "Identify subscriber by IMSI\n" \
872 "Identify subscriber by TMSI\n" \
873 "Identify subscriber by database ID\n" \
874 "Identifier for the subscriber\n"
875
876DEFUN(show_subscr,
877 show_subscr_cmd,
878 "show subscriber " SUBSCR_TYPES " ID",
879 SHOW_STR SUBSCR_HELP)
880{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100881 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
882 argv[1]);
883
884 if (!vsub) {
885 vty_out(vty, "%% No subscriber found for %s %s%s",
886 argv[0], argv[1], VTY_NEWLINE);
887 return CMD_WARNING;
888 }
889
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100890 /* In the vty output to the user, exclude this local use count added by vlr_subscr_get() in get_vsub_by_argv().
891 * This works, because: for get_vsub_by_argv() to succeed, there *must* have been at least one use count before
892 * 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 +0100893 vlr_subscr_put(vsub);
894
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100895 subscr_dump_full_vty(vty, vsub);
896
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100897 return CMD_SUCCESS;
898}
899
900DEFUN(subscriber_create,
901 subscriber_create_cmd,
902 "subscriber create imsi ID",
903 "Operations on a Subscriber\n" \
904 "Create new subscriber\n" \
905 "Identify the subscriber by his IMSI\n" \
906 "Identifier for the subscriber\n")
907{
908 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
909 VTY_NEWLINE);
910 return CMD_WARNING;
911}
912
913DEFUN(subscriber_send_pending_sms,
914 subscriber_send_pending_sms_cmd,
915 "subscriber " SUBSCR_TYPES " ID sms pending-send",
916 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
917{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100918 struct vlr_subscr *vsub;
919 struct gsm_sms *sms;
920
921 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
922 if (!vsub) {
923 vty_out(vty, "%% No subscriber found for %s %s%s",
924 argv[0], argv[1], VTY_NEWLINE);
925 return CMD_WARNING;
926 }
927
928 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
929 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700930 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100931
932 vlr_subscr_put(vsub);
933
934 return CMD_SUCCESS;
935}
936
937DEFUN(subscriber_send_sms,
938 subscriber_send_sms_cmd,
939 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
940 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
941{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100942 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200943 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100944 char *str;
945 int rc;
946
947 if (!vsub) {
948 vty_out(vty, "%% No subscriber found for %s %s%s",
949 argv[0], argv[1], VTY_NEWLINE);
950 rc = CMD_WARNING;
951 goto err;
952 }
953
Harald Welte39b55482018-04-09 19:19:33 +0200954 if (!strcmp(argv[2], "msisdn"))
955 sender_msisdn = argv[3];
956 else {
957 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
958 if (!sender) {
959 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
960 rc = CMD_WARNING;
961 goto err;
962 }
963 sender_msisdn = sender->msisdn;
964 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100965 }
966
967 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +0200968 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100969 talloc_free(str);
970
971err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100972 if (vsub)
973 vlr_subscr_put(vsub);
974
975 return rc;
976}
977
978DEFUN(subscriber_silent_sms,
979 subscriber_silent_sms_cmd,
980
981 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
982 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
983{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100984 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200985 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100986 char *str;
987 int rc;
988
989 if (!vsub) {
990 vty_out(vty, "%% No subscriber found for %s %s%s",
991 argv[0], argv[1], VTY_NEWLINE);
992 rc = CMD_WARNING;
993 goto err;
994 }
995
Harald Welte39b55482018-04-09 19:19:33 +0200996 if (!strcmp(argv[2], "msisdn")) {
997 sender_msisdn = argv[3];
998 } else {
999 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1000 if (!sender) {
1001 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1002 rc = CMD_WARNING;
1003 goto err;
1004 }
1005 sender_msisdn = sender->msisdn;
1006 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001007 }
1008
1009 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001010 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001011 talloc_free(str);
1012
1013err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001014 if (vsub)
1015 vlr_subscr_put(vsub);
1016
1017 return rc;
1018}
1019
1020#define CHAN_TYPES "(any|tch/f|tch/any|sdcch)"
1021#define CHAN_TYPE_HELP \
1022 "Any channel\n" \
1023 "TCH/F channel\n" \
1024 "Any TCH channel\n" \
1025 "SDCCH channel\n"
1026
1027DEFUN(subscriber_silent_call_start,
1028 subscriber_silent_call_start_cmd,
1029 "subscriber " SUBSCR_TYPES " ID silent-call start (any|tch/f|tch/any|sdcch)",
1030 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
1031 CHAN_TYPE_HELP)
1032{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001033 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1034 int rc, type;
1035
1036 if (!vsub) {
1037 vty_out(vty, "%% No subscriber found for %s %s%s",
1038 argv[0], argv[1], VTY_NEWLINE);
1039 return CMD_WARNING;
1040 }
1041
1042 if (!strcmp(argv[2], "tch/f"))
1043 type = RSL_CHANNEED_TCH_F;
1044 else if (!strcmp(argv[2], "tch/any"))
1045 type = RSL_CHANNEED_TCH_ForH;
1046 else if (!strcmp(argv[2], "sdcch"))
1047 type = RSL_CHANNEED_SDCCH;
1048 else
1049 type = RSL_CHANNEED_ANY; /* Defaults to ANY */
1050
1051 rc = gsm_silent_call_start(vsub, vty, type);
1052 switch (rc) {
1053 case -ENODEV:
1054 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
1055 break;
1056 default:
1057 if (rc)
1058 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
1059 else
1060 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
1061 break;
1062 }
1063
1064 vlr_subscr_put(vsub);
1065 return rc ? CMD_WARNING : CMD_SUCCESS;
1066}
1067
1068DEFUN(subscriber_silent_call_stop,
1069 subscriber_silent_call_stop_cmd,
1070 "subscriber " SUBSCR_TYPES " ID silent-call stop",
1071 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
1072 CHAN_TYPE_HELP)
1073{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001074 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1075 int rc;
1076
1077 if (!vsub) {
1078 vty_out(vty, "%% No subscriber found for %s %s%s",
1079 argv[0], argv[1], VTY_NEWLINE);
1080 return CMD_WARNING;
1081 }
1082
1083 rc = gsm_silent_call_stop(vsub);
1084 switch (rc) {
1085 case -ENODEV:
1086 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
1087 break;
1088 case -ENOENT:
1089 vty_out(vty, "%% Subscriber has no silent call active%s",
1090 VTY_NEWLINE);
1091 break;
1092 default:
1093 if (rc)
1094 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
1095 else
1096 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
1097 break;
1098 }
1099
1100 vlr_subscr_put(vsub);
1101 return rc ? CMD_WARNING : CMD_SUCCESS;
1102}
1103
1104DEFUN(subscriber_ussd_notify,
1105 subscriber_ussd_notify_cmd,
1106 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1107 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1108 "Alerting Level 0\n"
1109 "Alerting Level 1\n"
1110 "Alerting Level 2\n"
1111 "Text of USSD message to send\n")
1112{
1113 char *text;
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001114 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001115 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1116 int level;
1117
1118 if (!vsub) {
1119 vty_out(vty, "%% No subscriber found for %s %s%s",
1120 argv[0], argv[1], VTY_NEWLINE);
1121 return CMD_WARNING;
1122 }
1123
1124 level = atoi(argv[2]);
1125 text = argv_concat(argv, argc, 3);
1126 if (!text) {
1127 vlr_subscr_put(vsub);
1128 return CMD_WARNING;
1129 }
1130
1131 conn = connection_for_subscr(vsub);
1132 if (!conn) {
1133 vty_out(vty, "%% An active connection is required for %s %s%s",
1134 argv[0], argv[1], VTY_NEWLINE);
1135 vlr_subscr_put(vsub);
1136 talloc_free(text);
1137 return CMD_WARNING;
1138 }
1139
1140 msc_send_ussd_notify(conn, level, text);
1141 msc_send_ussd_release_complete(conn);
1142
1143 vlr_subscr_put(vsub);
1144 talloc_free(text);
1145 return CMD_SUCCESS;
1146}
1147
1148DEFUN(subscriber_paging,
1149 subscriber_paging_cmd,
1150 "subscriber " SUBSCR_TYPES " ID paging",
1151 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1152{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001153 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1154 struct subscr_request *req;
1155
1156 if (!vsub) {
1157 vty_out(vty, "%% No subscriber found for %s %s%s",
1158 argv[0], argv[1], VTY_NEWLINE);
1159 return CMD_WARNING;
1160 }
1161
1162 req = subscr_request_conn(vsub, NULL, NULL, "manual Paging from VTY");
1163 if (req)
1164 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1165 else
1166 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1167
1168 vlr_subscr_put(vsub);
1169 return req ? CMD_SUCCESS : CMD_WARNING;
1170}
1171
1172static int loop_by_char(uint8_t ch)
1173{
1174 switch (ch) {
1175 case 'a':
1176 return GSM414_LOOP_A;
1177 case 'b':
1178 return GSM414_LOOP_B;
1179 case 'c':
1180 return GSM414_LOOP_C;
1181 case 'd':
1182 return GSM414_LOOP_D;
1183 case 'e':
1184 return GSM414_LOOP_E;
1185 case 'f':
1186 return GSM414_LOOP_F;
1187 case 'i':
1188 return GSM414_LOOP_I;
1189 }
1190 return -1;
1191}
1192
1193DEFUN(subscriber_mstest_close,
1194 subscriber_mstest_close_cmd,
1195 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1196 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1197 "Close a TCH Loop inside the MS\n"
1198 "Loop Type A\n"
1199 "Loop Type B\n"
1200 "Loop Type C\n"
1201 "Loop Type D\n"
1202 "Loop Type E\n"
1203 "Loop Type F\n"
1204 "Loop Type I\n")
1205{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001206 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001207 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1208 const char *loop_str;
1209 int loop_mode;
1210
1211 if (!vsub) {
1212 vty_out(vty, "%% No subscriber found for %s %s%s",
1213 argv[0], argv[1], VTY_NEWLINE);
1214 return CMD_WARNING;
1215 }
1216
1217 loop_str = argv[2];
1218 loop_mode = loop_by_char(loop_str[0]);
1219
1220 conn = connection_for_subscr(vsub);
1221 if (!conn) {
1222 vty_out(vty, "%% An active connection is required for %s %s%s",
1223 argv[0], argv[1], VTY_NEWLINE);
1224 vlr_subscr_put(vsub);
1225 return CMD_WARNING;
1226 }
1227
1228 gsm0414_tx_close_tch_loop_cmd(conn, loop_mode);
1229
1230 return CMD_SUCCESS;
1231}
1232
1233DEFUN(subscriber_mstest_open,
1234 subscriber_mstest_open_cmd,
1235 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1236 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1237 "Open a TCH Loop inside the MS\n")
1238{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001239 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001240 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1241
1242 if (!vsub) {
1243 vty_out(vty, "%% No subscriber found for %s %s%s",
1244 argv[0], argv[1], VTY_NEWLINE);
1245 return CMD_WARNING;
1246 }
1247
1248 conn = connection_for_subscr(vsub);
1249 if (!conn) {
1250 vty_out(vty, "%% An active connection is required for %s %s%s",
1251 argv[0], argv[1], VTY_NEWLINE);
1252 vlr_subscr_put(vsub);
1253 return CMD_WARNING;
1254 }
1255
1256 gsm0414_tx_open_loop_cmd(conn);
1257
1258 return CMD_SUCCESS;
1259}
1260
1261DEFUN(ena_subscr_expire,
1262 ena_subscr_expire_cmd,
1263 "subscriber " SUBSCR_TYPES " ID expire",
1264 SUBSCR_HELP "Expire the subscriber Now\n")
1265{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001266 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1267 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 if (vlr_subscr_expire(vsub))
1276 vty_out(vty, "%% VLR released subscriber %s%s",
1277 vlr_subscr_name(vsub), VTY_NEWLINE);
1278
1279 if (vsub->use_count > 1)
1280 vty_out(vty, "%% Subscriber %s is still in use,"
1281 " should be released soon%s",
1282 vlr_subscr_name(vsub), VTY_NEWLINE);
1283
1284 vlr_subscr_put(vsub);
1285 return CMD_SUCCESS;
1286}
1287
1288static int scall_cbfn(unsigned int subsys, unsigned int signal,
1289 void *handler_data, void *signal_data)
1290{
1291 struct scall_signal_data *sigdata = signal_data;
1292 struct vty *vty = sigdata->data;
1293
1294 switch (signal) {
1295 case S_SCALL_SUCCESS:
1296 vty_out(vty, "%% silent call success%s", VTY_NEWLINE);
1297 break;
1298 case S_SCALL_EXPIRED:
1299 vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE);
1300 break;
1301 }
1302 return 0;
1303}
1304
1305DEFUN(show_stats,
1306 show_stats_cmd,
1307 "show statistics",
1308 SHOW_STR "Display network statistics\n")
1309{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001310 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001311 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1312 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1313 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001314 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001315 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001316 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001317 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001318 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001319 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1320 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001321 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001322 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001323 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1324 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001325 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001326 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001327 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1328 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1329 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001330 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001331 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001332 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1333 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001334 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001335 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001336 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1337 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001338 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001339 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001340 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1341 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1342 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1343 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1344 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001345 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001346 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1347 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1348 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1349 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1350 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001351 return CMD_SUCCESS;
1352}
1353
1354DEFUN(show_smsqueue,
1355 show_smsqueue_cmd,
1356 "show sms-queue",
1357 SHOW_STR "Display SMSqueue statistics\n")
1358{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001359 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001360 return CMD_SUCCESS;
1361}
1362
1363DEFUN(smsqueue_trigger,
1364 smsqueue_trigger_cmd,
1365 "sms-queue trigger",
1366 "SMS Queue\n" "Trigger sending messages\n")
1367{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001368 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001369 return CMD_SUCCESS;
1370}
1371
1372DEFUN(smsqueue_max,
1373 smsqueue_max_cmd,
1374 "sms-queue max-pending <1-500>",
1375 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1376{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001377 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001378 return CMD_SUCCESS;
1379}
1380
1381DEFUN(smsqueue_clear,
1382 smsqueue_clear_cmd,
1383 "sms-queue clear",
1384 "SMS Queue\n" "Clear the queue of pending SMS\n")
1385{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001386 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001387 return CMD_SUCCESS;
1388}
1389
1390DEFUN(smsqueue_fail,
1391 smsqueue_fail_cmd,
1392 "sms-queue max-failure <1-500>",
1393 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1394{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001395 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001396 return CMD_SUCCESS;
1397}
1398
1399
1400DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1401 "mncc-int", "Configure internal MNCC handler")
1402{
1403 vty->node = MNCC_INT_NODE;
1404
1405 return CMD_SUCCESS;
1406}
1407
1408static struct cmd_node mncc_int_node = {
1409 MNCC_INT_NODE,
1410 "%s(config-mncc-int)# ",
1411 1,
1412};
1413
1414static const struct value_string tchf_codec_names[] = {
1415 { GSM48_CMODE_SPEECH_V1, "fr" },
1416 { GSM48_CMODE_SPEECH_EFR, "efr" },
1417 { GSM48_CMODE_SPEECH_AMR, "amr" },
1418 { 0, NULL }
1419};
1420
1421static const struct value_string tchh_codec_names[] = {
1422 { GSM48_CMODE_SPEECH_V1, "hr" },
1423 { GSM48_CMODE_SPEECH_AMR, "amr" },
1424 { 0, NULL }
1425};
1426
1427static int config_write_mncc_int(struct vty *vty)
1428{
1429 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1430 vty_out(vty, " default-codec tch-f %s%s",
1431 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1432 VTY_NEWLINE);
1433 vty_out(vty, " default-codec tch-h %s%s",
1434 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1435 VTY_NEWLINE);
1436
1437 return CMD_SUCCESS;
1438}
1439
1440DEFUN(mnccint_def_codec_f,
1441 mnccint_def_codec_f_cmd,
1442 "default-codec tch-f (fr|efr|amr)",
1443 "Set default codec\n" "Codec for TCH/F\n"
1444 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1445{
1446 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1447
1448 return CMD_SUCCESS;
1449}
1450
1451DEFUN(mnccint_def_codec_h,
1452 mnccint_def_codec_h_cmd,
1453 "default-codec tch-h (hr|amr)",
1454 "Set default codec\n" "Codec for TCH/H\n"
1455 "Half-Rate\n" "Adaptive Multi-Rate\n")
1456{
1457 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1458
1459 return CMD_SUCCESS;
1460}
1461
1462
1463DEFUN(logging_fltr_imsi,
1464 logging_fltr_imsi_cmd,
1465 "logging filter imsi IMSI",
1466 LOGGING_STR FILTER_STR
1467 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1468{
1469 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001470 struct log_target *tgt = osmo_log_vty2tgt(vty);
1471 const char *imsi = argv[0];
1472
1473 if (!tgt)
1474 return CMD_WARNING;
1475
1476 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi);
1477
1478 if (!vlr_subscr) {
1479 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1480 argv[0], VTY_NEWLINE);
1481 return CMD_WARNING;
1482 }
1483
1484 log_set_filter_vlr_subscr(tgt, vlr_subscr);
1485 return CMD_SUCCESS;
1486}
1487
1488static struct cmd_node hlr_node = {
1489 HLR_NODE,
1490 "%s(config-hlr)# ",
1491 1,
1492};
1493
1494DEFUN(cfg_hlr, cfg_hlr_cmd,
1495 "hlr", "Configure connection to the HLR")
1496{
1497 vty->node = HLR_NODE;
1498 return CMD_SUCCESS;
1499}
1500
1501DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1502 "Remote GSUP address of the HLR\n"
1503 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1504{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001505 talloc_free((void*)gsmnet->gsup_server_addr_str);
1506 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1507 return CMD_SUCCESS;
1508}
1509
1510DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1511 "Remote GSUP port of the HLR\n"
1512 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1513{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001514 gsmnet->gsup_server_port = atoi(argv[0]);
1515 return CMD_SUCCESS;
1516}
1517
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001518DEFUN(cfg_hlr_ipa_name,
1519 cfg_hlr_ipa_name_cmd,
1520 "ipa-name NAME",
1521 "Set the IPA name of this MSC\n"
1522 "A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. "
1523 "This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. "
1524 "The default is 'MSC-00-00-00-00-00-00'.\n")
1525{
1526 if (vty->type != VTY_FILE) {
1527 vty_out(vty, "The IPA name cannot be changed at run-time; "
1528 "It can only be set in the configuraton file.%s", VTY_NEWLINE);
1529 return CMD_WARNING;
1530 }
1531
1532 gsmnet->msc_ipa_name = talloc_strdup(gsmnet, argv[0]);
1533 return CMD_SUCCESS;
1534}
1535
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001536static int config_write_hlr(struct vty *vty)
1537{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001538 vty_out(vty, "hlr%s", VTY_NEWLINE);
1539 vty_out(vty, " remote-ip %s%s",
1540 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1541 vty_out(vty, " remote-port %u%s",
1542 gsmnet->gsup_server_port, VTY_NEWLINE);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001543 if (gsmnet->msc_ipa_name)
1544 vty_out(vty, " ipa-name %s%s", gsmnet->msc_ipa_name, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001545 return CMD_SUCCESS;
1546}
1547
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001548void msc_vty_init(struct gsm_network *msc_network)
1549{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001550 OSMO_ASSERT(gsmnet == NULL);
1551 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001552
1553 osmo_stats_vty_add_cmds();
1554
1555 install_element(CONFIG_NODE, &cfg_net_cmd);
1556 install_node(&net_node, config_write_net);
1557 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
1558 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1559 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1560 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
1561 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
1562 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
1563 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
1564 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
1565 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
1566 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
1567 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
1568 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
1569 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001570
1571 install_element(CONFIG_NODE, &cfg_msc_cmd);
1572 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001573 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01001574 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
1575 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02001576 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01001577 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001578 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01001579 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
1580 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Oliver Smith0fec28a2018-12-14 10:52:52 +01001581 install_element(MSC_NODE, &cfg_msc_check_imei_rqd_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001582 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
1583 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01001584 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01001585 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +07001586 install_element(MSC_NODE, &cfg_msc_sms_over_gsup_cmd);
1587 install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001588
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02001589 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001590#ifdef BUILD_IU
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +01001591 ranap_iu_vty_init(MSC_NODE, &msc_network->iu.rab_assign_addr_enc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001592#endif
Stefan Sperling617ac802018-02-22 17:58:20 +01001593 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001594
1595 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
1596
1597 install_element_ve(&show_subscr_cmd);
1598 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01001599 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001600 install_element_ve(&show_msc_conn_cmd);
1601 install_element_ve(&show_msc_transaction_cmd);
1602
1603 install_element_ve(&sms_send_pend_cmd);
1604 install_element_ve(&sms_delete_expired_cmd);
1605
1606 install_element_ve(&subscriber_create_cmd);
1607 install_element_ve(&subscriber_send_sms_cmd);
1608 install_element_ve(&subscriber_silent_sms_cmd);
1609 install_element_ve(&subscriber_silent_call_start_cmd);
1610 install_element_ve(&subscriber_silent_call_stop_cmd);
1611 install_element_ve(&subscriber_ussd_notify_cmd);
1612 install_element_ve(&subscriber_mstest_close_cmd);
1613 install_element_ve(&subscriber_mstest_open_cmd);
1614 install_element_ve(&subscriber_paging_cmd);
1615 install_element_ve(&show_stats_cmd);
1616 install_element_ve(&show_smsqueue_cmd);
1617 install_element_ve(&logging_fltr_imsi_cmd);
1618
1619 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
1620 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
1621 install_element(ENABLE_NODE, &smsqueue_max_cmd);
1622 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
1623 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
1624 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
1625
1626 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1627 install_node(&mncc_int_node, config_write_mncc_int);
1628 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1629 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1630
1631 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
1632
1633 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1634 install_node(&hlr_node, config_write_hlr);
1635 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1636 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001637 install_element(HLR_NODE, &cfg_hlr_ipa_name_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001638}