blob: 1fdf560624398789df37893d0e82719c6affd74f [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{
553 vty_out(vty, "--ConnId ------------Subscriber RAN --LAC Use --Tokens C A5 State%s",
554 VTY_NEWLINE);
555}
556
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100557static void vty_dump_one_conn(struct vty *vty, const struct ran_conn *conn)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100558{
559 vty_out(vty, "%08x %22s %3s %5u %3u %08x %c /%1u %27s %s",
560 conn->a.conn_id,
561 conn->vsub ? vlr_subscr_name(conn->vsub) : "-",
Neels Hofmeyr7814a832018-12-26 00:40:18 +0100562 conn->via_ran == OSMO_RAT_UTRAN_IU ? "Iu" : "A",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100563 conn->lac,
564 conn->use_count,
565 conn->use_tokens,
566 conn->received_cm_service_request ? 'C' : '-',
Neels Hofmeyrf41658d2018-11-30 04:35:50 +0100567 conn->geran_encr.alg_id,
Neels Hofmeyr4d3a66b2018-03-31 18:45:59 +0200568 conn->fi ? osmo_fsm_inst_state_name(conn->fi) : "-",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100569 VTY_NEWLINE);
570}
571
572DEFUN(show_msc_conn, show_msc_conn_cmd,
573 "show connection", SHOW_STR "Subscriber Connections\n")
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200574{
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100575 struct ran_conn *conn;
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200576
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100577 vty_conn_hdr(vty);
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100578 llist_for_each_entry(conn, &gsmnet->ran_conns, entry)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100579 vty_dump_one_conn(vty, conn);
580
581 return CMD_SUCCESS;
582}
583
584static void vty_trans_hdr(struct vty *vty)
585{
586 vty_out(vty, "------------Subscriber --ConnId -P TI -CallRef Proto%s",
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200587 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100588}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200589
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100590static const char *get_trans_proto_str(const struct gsm_trans *trans)
591{
592 static char buf[256];
593
594 switch (trans->protocol) {
595 case GSM48_PDISC_CC:
596 snprintf(buf, sizeof(buf), "%s %4u %4u",
597 gsm48_cc_state_name(trans->cc.state),
598 trans->cc.Tcurrent,
599 trans->cc.T308_second);
600 break;
601 case GSM48_PDISC_SMS:
602 snprintf(buf, sizeof(buf), "%s %s",
603 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
604 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
605 break;
606 default:
607 buf[0] = '\0';
608 break;
609 }
610
611 return buf;
612}
613
614static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
615{
616 vty_out(vty, "%22s %08x %s %02u %08x %s%s",
617 trans->vsub ? vlr_subscr_name(trans->vsub) : "-",
618 trans->conn ? trans->conn->a.conn_id : 0,
619 gsm48_pdisc_name(trans->protocol),
620 trans->transaction_id,
621 trans->callref,
622 get_trans_proto_str(trans), VTY_NEWLINE);
623}
624
625DEFUN(show_msc_transaction, show_msc_transaction_cmd,
626 "show transaction", SHOW_STR "Transactions\n")
627{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100628 struct gsm_trans *trans;
629
630 vty_trans_hdr(vty);
631 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
632 vty_dump_one_trans(vty, trans);
633
634 return CMD_SUCCESS;
635}
636
637static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
638{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100639 struct gsm_trans *trans;
640 int reqs;
641 struct llist_head *entry;
642
643 if (strlen(vsub->name))
644 vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
645 if (strlen(vsub->msisdn))
646 vty_out(vty, " Extension: %s%s", vsub->msisdn,
647 VTY_NEWLINE);
648 vty_out(vty, " LAC: %d/0x%x%s",
Max7d41d872018-12-19 11:48:33 +0100649 vsub->cgi.lai.lac, vsub->cgi.lai.lac, VTY_NEWLINE);
Philipp Maier2a0ac3b2018-12-17 10:03:50 +0100650 vty_out(vty, " RAN: %s%s",
Neels Hofmeyr7814a832018-12-26 00:40:18 +0100651 osmo_rat_type_name(vsub->cs.attached_via_ran), VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100652 vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
653 if (vsub->tmsi != GSM_RESERVED_TMSI)
654 vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
655 VTY_NEWLINE);
656 if (vsub->tmsi_new != GSM_RESERVED_TMSI)
657 vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
658 VTY_NEWLINE);
Philipp Maier6d71ccf2018-12-14 13:30:14 +0100659 if (vsub->imei[0] != '\0')
660 vty_out(vty, " IMEI: %s%s", vsub->imei, VTY_NEWLINE);
661 if (vsub->imeisv[0] != '\0')
662 vty_out(vty, " IMEISV: %s%s", vsub->imeisv, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100663
Philipp Maier89561bc2018-12-14 13:34:25 +0100664 vty_out(vty, " Flags: %s", VTY_NEWLINE);
665 vty_out(vty, " IMSI detached: %s%s",
666 vsub->imsi_detached_flag ? "true" : "false", VTY_NEWLINE);
667 vty_out(vty, " Conf. by radio contact: %s%s",
668 vsub->conf_by_radio_contact_ind ? "true" : "false",
669 VTY_NEWLINE);
670 vty_out(vty, " Subscr. data conf. by HLR: %s%s",
671 vsub->sub_dataconf_by_hlr_ind ? "true" : "false", VTY_NEWLINE);
672 vty_out(vty, " Location conf. in HLR: %s%s",
673 vsub->loc_conf_in_hlr_ind ? "true" : "false", VTY_NEWLINE);
674 vty_out(vty, " Subscriber dormant: %s%s",
675 vsub->dormant_ind ? "true" : "false", VTY_NEWLINE);
676 vty_out(vty, " Received cancel locataion: %s%s",
677 vsub->cancel_loc_rx ? "true" : "false", VTY_NEWLINE);
678 vty_out(vty, " MS not reachable: %s%s",
679 vsub->ms_not_reachable_flag ? "true" : "false", VTY_NEWLINE);
680 vty_out(vty, " LA allowed: %s%s",
681 vsub->la_allowed ? "true" : "false", VTY_NEWLINE);
682
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100683#if 0
684 /* TODO: add this to vlr_subscr? */
685 if (vsub->auth_info.auth_algo != AUTH_ALGO_NONE) {
686 struct gsm_auth_info *i = &vsub->auth_info;
687 vty_out(vty, " A3A8 algorithm id: %d%s",
688 i->auth_algo, VTY_NEWLINE);
689 vty_out(vty, " A3A8 Ki: %s%s",
690 osmo_hexdump(i->a3a8_ki, i->a3a8_ki_len),
691 VTY_NEWLINE);
692 }
693#endif
694
695 if (vsub->last_tuple) {
Neels Hofmeyr8b6e5362018-11-30 02:57:33 +0100696 struct vlr_auth_tuple *t = vsub->last_tuple;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100697 vty_out(vty, " A3A8 last tuple (used %d times):%s",
698 t->use_count, VTY_NEWLINE);
699 vty_out(vty, " seq # : %d%s",
700 t->key_seq, VTY_NEWLINE);
701 vty_out(vty, " RAND : %s%s",
702 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
703 VTY_NEWLINE);
704 vty_out(vty, " SRES : %s%s",
705 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
706 VTY_NEWLINE);
707 vty_out(vty, " Kc : %s%s",
708 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
709 VTY_NEWLINE);
710 }
711
712 reqs = 0;
713 llist_for_each(entry, &vsub->cs.requests)
714 reqs += 1;
715 vty_out(vty, " Paging: %s paging for %d requests%s",
716 vsub->cs.is_paging ? "is" : "not", reqs, VTY_NEWLINE);
717 vty_out(vty, " Use count: %u%s", vsub->use_count, VTY_NEWLINE);
718
719 /* Connection */
720 if (vsub->msc_conn_ref) {
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100721 struct ran_conn *conn = vsub->msc_conn_ref;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100722 vty_conn_hdr(vty);
723 vty_dump_one_conn(vty, conn);
724 }
725
726 /* Transactions */
727 vty_trans_hdr(vty);
728 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
729 if (trans->vsub != vsub)
730 continue;
731 vty_dump_one_trans(vty, trans);
732 }
733}
734
735/* Subscriber */
736DEFUN(show_subscr_cache,
737 show_subscr_cache_cmd,
738 "show subscriber cache",
739 SHOW_STR "Show information about subscribers\n"
740 "Display contents of subscriber cache\n")
741{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100742 struct vlr_subscr *vsub;
743 int count = 0;
744
745 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
746 if (++count > 100) {
747 vty_out(vty, "%% More than %d subscribers in cache,"
748 " stopping here.%s", count-1, VTY_NEWLINE);
749 break;
750 }
751 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
752 subscr_dump_full_vty(vty, vsub);
Harald Welte69c54a82018-02-09 20:41:14 +0100753 }
754
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200755 return CMD_SUCCESS;
756}
757
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100758DEFUN(sms_send_pend,
759 sms_send_pend_cmd,
760 "sms send pending",
761 "SMS related commands\n" "SMS Sending related commands\n"
762 "Send all pending SMS")
763{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100764 struct gsm_sms *sms;
765 unsigned long long sms_id = 0;
766
767 while (1) {
768 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
769 if (!sms)
770 break;
771
772 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700773 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100774
775 sms_id = sms->id + 1;
776 }
777
778 return CMD_SUCCESS;
779}
780
781DEFUN(sms_delete_expired,
782 sms_delete_expired_cmd,
783 "sms delete expired",
784 "SMS related commands\n" "SMS Database related commands\n"
785 "Delete all expired SMS")
786{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100787 struct gsm_sms *sms;
788 unsigned long long sms_id = 0;
789 long long num_deleted = 0;
790
791 while (1) {
792 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
793 if (!sms)
794 break;
795
796 /* Skip SMS which are currently queued for sending. */
797 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
798 continue;
799
800 /* Expiration check is performed by the DB layer. */
801 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
802 num_deleted++;
803
804 sms_id = sms->id + 1;
805 }
806
807 if (num_deleted == 0) {
808 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
809 return CMD_WARNING;
810 }
811
812 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
813 return CMD_SUCCESS;
814}
815
816static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +0200817 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100818 char *str, uint8_t tp_pid)
819{
820 struct gsm_network *net = receiver->vlr->user_ctx;
821 struct gsm_sms *sms;
822
Harald Welte39b55482018-04-09 19:19:33 +0200823 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100824 sms->protocol_id = tp_pid;
825
826 /* store in database for the queue */
827 if (db_sms_store(sms) != 0) {
828 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
829 sms_free(sms);
830 return CMD_WARNING;
831 }
832 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
833
834 sms_free(sms);
835 sms_queue_trigger(net->sms_queue);
836 return CMD_SUCCESS;
837}
838
839static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
840 const char *type,
841 const char *id)
842{
843 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
844 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id);
845 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
846 return vlr_subscr_find_by_imsi(gsmnet->vlr, id);
847 else if (!strcmp(type, "tmsi"))
848 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id));
849
850 return NULL;
851}
852#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
853#define SUBSCR_HELP "Operations on a Subscriber\n" \
854 "Identify subscriber by MSISDN (phone number)\n" \
855 "Legacy alias for 'msisdn'\n" \
856 "Identify subscriber by IMSI\n" \
857 "Identify subscriber by TMSI\n" \
858 "Identify subscriber by database ID\n" \
859 "Identifier for the subscriber\n"
860
861DEFUN(show_subscr,
862 show_subscr_cmd,
863 "show subscriber " SUBSCR_TYPES " ID",
864 SHOW_STR SUBSCR_HELP)
865{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100866 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
867 argv[1]);
868
869 if (!vsub) {
870 vty_out(vty, "%% No subscriber found for %s %s%s",
871 argv[0], argv[1], VTY_NEWLINE);
872 return CMD_WARNING;
873 }
874
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100875 /* In the vty output to the user, exclude this local use count added by vlr_subscr_get() in get_vsub_by_argv().
876 * This works, because: for get_vsub_by_argv() to succeed, there *must* have been at least one use count before
877 * 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 +0100878 vlr_subscr_put(vsub);
879
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100880 subscr_dump_full_vty(vty, vsub);
881
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100882 return CMD_SUCCESS;
883}
884
885DEFUN(subscriber_create,
886 subscriber_create_cmd,
887 "subscriber create imsi ID",
888 "Operations on a Subscriber\n" \
889 "Create new subscriber\n" \
890 "Identify the subscriber by his IMSI\n" \
891 "Identifier for the subscriber\n")
892{
893 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
894 VTY_NEWLINE);
895 return CMD_WARNING;
896}
897
898DEFUN(subscriber_send_pending_sms,
899 subscriber_send_pending_sms_cmd,
900 "subscriber " SUBSCR_TYPES " ID sms pending-send",
901 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
902{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100903 struct vlr_subscr *vsub;
904 struct gsm_sms *sms;
905
906 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
907 if (!vsub) {
908 vty_out(vty, "%% No subscriber found for %s %s%s",
909 argv[0], argv[1], VTY_NEWLINE);
910 return CMD_WARNING;
911 }
912
913 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
914 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700915 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100916
917 vlr_subscr_put(vsub);
918
919 return CMD_SUCCESS;
920}
921
922DEFUN(subscriber_send_sms,
923 subscriber_send_sms_cmd,
924 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
925 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
926{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100927 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200928 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100929 char *str;
930 int rc;
931
932 if (!vsub) {
933 vty_out(vty, "%% No subscriber found for %s %s%s",
934 argv[0], argv[1], VTY_NEWLINE);
935 rc = CMD_WARNING;
936 goto err;
937 }
938
Harald Welte39b55482018-04-09 19:19:33 +0200939 if (!strcmp(argv[2], "msisdn"))
940 sender_msisdn = argv[3];
941 else {
942 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
943 if (!sender) {
944 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
945 rc = CMD_WARNING;
946 goto err;
947 }
948 sender_msisdn = sender->msisdn;
949 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100950 }
951
952 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +0200953 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100954 talloc_free(str);
955
956err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100957 if (vsub)
958 vlr_subscr_put(vsub);
959
960 return rc;
961}
962
963DEFUN(subscriber_silent_sms,
964 subscriber_silent_sms_cmd,
965
966 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
967 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
968{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100969 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200970 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100971 char *str;
972 int rc;
973
974 if (!vsub) {
975 vty_out(vty, "%% No subscriber found for %s %s%s",
976 argv[0], argv[1], VTY_NEWLINE);
977 rc = CMD_WARNING;
978 goto err;
979 }
980
Harald Welte39b55482018-04-09 19:19:33 +0200981 if (!strcmp(argv[2], "msisdn")) {
982 sender_msisdn = argv[3];
983 } else {
984 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
985 if (!sender) {
986 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
987 rc = CMD_WARNING;
988 goto err;
989 }
990 sender_msisdn = sender->msisdn;
991 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100992 }
993
994 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +0200995 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100996 talloc_free(str);
997
998err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100999 if (vsub)
1000 vlr_subscr_put(vsub);
1001
1002 return rc;
1003}
1004
1005#define CHAN_TYPES "(any|tch/f|tch/any|sdcch)"
1006#define CHAN_TYPE_HELP \
1007 "Any channel\n" \
1008 "TCH/F channel\n" \
1009 "Any TCH channel\n" \
1010 "SDCCH channel\n"
1011
1012DEFUN(subscriber_silent_call_start,
1013 subscriber_silent_call_start_cmd,
1014 "subscriber " SUBSCR_TYPES " ID silent-call start (any|tch/f|tch/any|sdcch)",
1015 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
1016 CHAN_TYPE_HELP)
1017{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001018 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1019 int rc, type;
1020
1021 if (!vsub) {
1022 vty_out(vty, "%% No subscriber found for %s %s%s",
1023 argv[0], argv[1], VTY_NEWLINE);
1024 return CMD_WARNING;
1025 }
1026
1027 if (!strcmp(argv[2], "tch/f"))
1028 type = RSL_CHANNEED_TCH_F;
1029 else if (!strcmp(argv[2], "tch/any"))
1030 type = RSL_CHANNEED_TCH_ForH;
1031 else if (!strcmp(argv[2], "sdcch"))
1032 type = RSL_CHANNEED_SDCCH;
1033 else
1034 type = RSL_CHANNEED_ANY; /* Defaults to ANY */
1035
1036 rc = gsm_silent_call_start(vsub, vty, type);
1037 switch (rc) {
1038 case -ENODEV:
1039 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
1040 break;
1041 default:
1042 if (rc)
1043 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
1044 else
1045 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
1046 break;
1047 }
1048
1049 vlr_subscr_put(vsub);
1050 return rc ? CMD_WARNING : CMD_SUCCESS;
1051}
1052
1053DEFUN(subscriber_silent_call_stop,
1054 subscriber_silent_call_stop_cmd,
1055 "subscriber " SUBSCR_TYPES " ID silent-call stop",
1056 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
1057 CHAN_TYPE_HELP)
1058{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001059 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1060 int rc;
1061
1062 if (!vsub) {
1063 vty_out(vty, "%% No subscriber found for %s %s%s",
1064 argv[0], argv[1], VTY_NEWLINE);
1065 return CMD_WARNING;
1066 }
1067
1068 rc = gsm_silent_call_stop(vsub);
1069 switch (rc) {
1070 case -ENODEV:
1071 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
1072 break;
1073 case -ENOENT:
1074 vty_out(vty, "%% Subscriber has no silent call active%s",
1075 VTY_NEWLINE);
1076 break;
1077 default:
1078 if (rc)
1079 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
1080 else
1081 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
1082 break;
1083 }
1084
1085 vlr_subscr_put(vsub);
1086 return rc ? CMD_WARNING : CMD_SUCCESS;
1087}
1088
1089DEFUN(subscriber_ussd_notify,
1090 subscriber_ussd_notify_cmd,
1091 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1092 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1093 "Alerting Level 0\n"
1094 "Alerting Level 1\n"
1095 "Alerting Level 2\n"
1096 "Text of USSD message to send\n")
1097{
1098 char *text;
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001099 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001100 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1101 int level;
1102
1103 if (!vsub) {
1104 vty_out(vty, "%% No subscriber found for %s %s%s",
1105 argv[0], argv[1], VTY_NEWLINE);
1106 return CMD_WARNING;
1107 }
1108
1109 level = atoi(argv[2]);
1110 text = argv_concat(argv, argc, 3);
1111 if (!text) {
1112 vlr_subscr_put(vsub);
1113 return CMD_WARNING;
1114 }
1115
1116 conn = connection_for_subscr(vsub);
1117 if (!conn) {
1118 vty_out(vty, "%% An active connection is required for %s %s%s",
1119 argv[0], argv[1], VTY_NEWLINE);
1120 vlr_subscr_put(vsub);
1121 talloc_free(text);
1122 return CMD_WARNING;
1123 }
1124
1125 msc_send_ussd_notify(conn, level, text);
1126 msc_send_ussd_release_complete(conn);
1127
1128 vlr_subscr_put(vsub);
1129 talloc_free(text);
1130 return CMD_SUCCESS;
1131}
1132
1133DEFUN(subscriber_paging,
1134 subscriber_paging_cmd,
1135 "subscriber " SUBSCR_TYPES " ID paging",
1136 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1137{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001138 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1139 struct subscr_request *req;
1140
1141 if (!vsub) {
1142 vty_out(vty, "%% No subscriber found for %s %s%s",
1143 argv[0], argv[1], VTY_NEWLINE);
1144 return CMD_WARNING;
1145 }
1146
1147 req = subscr_request_conn(vsub, NULL, NULL, "manual Paging from VTY");
1148 if (req)
1149 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1150 else
1151 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1152
1153 vlr_subscr_put(vsub);
1154 return req ? CMD_SUCCESS : CMD_WARNING;
1155}
1156
1157static int loop_by_char(uint8_t ch)
1158{
1159 switch (ch) {
1160 case 'a':
1161 return GSM414_LOOP_A;
1162 case 'b':
1163 return GSM414_LOOP_B;
1164 case 'c':
1165 return GSM414_LOOP_C;
1166 case 'd':
1167 return GSM414_LOOP_D;
1168 case 'e':
1169 return GSM414_LOOP_E;
1170 case 'f':
1171 return GSM414_LOOP_F;
1172 case 'i':
1173 return GSM414_LOOP_I;
1174 }
1175 return -1;
1176}
1177
1178DEFUN(subscriber_mstest_close,
1179 subscriber_mstest_close_cmd,
1180 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1181 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1182 "Close a TCH Loop inside the MS\n"
1183 "Loop Type A\n"
1184 "Loop Type B\n"
1185 "Loop Type C\n"
1186 "Loop Type D\n"
1187 "Loop Type E\n"
1188 "Loop Type F\n"
1189 "Loop Type I\n")
1190{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001191 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001192 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1193 const char *loop_str;
1194 int loop_mode;
1195
1196 if (!vsub) {
1197 vty_out(vty, "%% No subscriber found for %s %s%s",
1198 argv[0], argv[1], VTY_NEWLINE);
1199 return CMD_WARNING;
1200 }
1201
1202 loop_str = argv[2];
1203 loop_mode = loop_by_char(loop_str[0]);
1204
1205 conn = connection_for_subscr(vsub);
1206 if (!conn) {
1207 vty_out(vty, "%% An active connection is required for %s %s%s",
1208 argv[0], argv[1], VTY_NEWLINE);
1209 vlr_subscr_put(vsub);
1210 return CMD_WARNING;
1211 }
1212
1213 gsm0414_tx_close_tch_loop_cmd(conn, loop_mode);
1214
1215 return CMD_SUCCESS;
1216}
1217
1218DEFUN(subscriber_mstest_open,
1219 subscriber_mstest_open_cmd,
1220 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1221 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1222 "Open a TCH Loop inside the MS\n")
1223{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001224 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001225 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1226
1227 if (!vsub) {
1228 vty_out(vty, "%% No subscriber found for %s %s%s",
1229 argv[0], argv[1], VTY_NEWLINE);
1230 return CMD_WARNING;
1231 }
1232
1233 conn = connection_for_subscr(vsub);
1234 if (!conn) {
1235 vty_out(vty, "%% An active connection is required for %s %s%s",
1236 argv[0], argv[1], VTY_NEWLINE);
1237 vlr_subscr_put(vsub);
1238 return CMD_WARNING;
1239 }
1240
1241 gsm0414_tx_open_loop_cmd(conn);
1242
1243 return CMD_SUCCESS;
1244}
1245
1246DEFUN(ena_subscr_expire,
1247 ena_subscr_expire_cmd,
1248 "subscriber " SUBSCR_TYPES " ID expire",
1249 SUBSCR_HELP "Expire the subscriber Now\n")
1250{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001251 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1252 argv[1]);
1253
1254 if (!vsub) {
1255 vty_out(vty, "%% No subscriber found for %s %s%s",
1256 argv[0], argv[1], VTY_NEWLINE);
1257 return CMD_WARNING;
1258 }
1259
1260 if (vlr_subscr_expire(vsub))
1261 vty_out(vty, "%% VLR released subscriber %s%s",
1262 vlr_subscr_name(vsub), VTY_NEWLINE);
1263
1264 if (vsub->use_count > 1)
1265 vty_out(vty, "%% Subscriber %s is still in use,"
1266 " should be released soon%s",
1267 vlr_subscr_name(vsub), VTY_NEWLINE);
1268
1269 vlr_subscr_put(vsub);
1270 return CMD_SUCCESS;
1271}
1272
1273static int scall_cbfn(unsigned int subsys, unsigned int signal,
1274 void *handler_data, void *signal_data)
1275{
1276 struct scall_signal_data *sigdata = signal_data;
1277 struct vty *vty = sigdata->data;
1278
1279 switch (signal) {
1280 case S_SCALL_SUCCESS:
1281 vty_out(vty, "%% silent call success%s", VTY_NEWLINE);
1282 break;
1283 case S_SCALL_EXPIRED:
1284 vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE);
1285 break;
1286 }
1287 return 0;
1288}
1289
1290DEFUN(show_stats,
1291 show_stats_cmd,
1292 "show statistics",
1293 SHOW_STR "Display network statistics\n")
1294{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001295 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001296 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1297 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1298 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001299 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001300 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001301 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001302 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001303 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001304 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1305 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001306 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001307 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001308 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1309 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001310 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001311 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001312 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1313 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1314 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001315 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001316 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001317 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1318 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001319 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001320 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001321 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1322 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001323 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001324 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001325 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1326 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1327 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1328 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1329 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001330 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001331 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1332 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1333 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1334 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1335 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001336 return CMD_SUCCESS;
1337}
1338
1339DEFUN(show_smsqueue,
1340 show_smsqueue_cmd,
1341 "show sms-queue",
1342 SHOW_STR "Display SMSqueue statistics\n")
1343{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001344 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001345 return CMD_SUCCESS;
1346}
1347
1348DEFUN(smsqueue_trigger,
1349 smsqueue_trigger_cmd,
1350 "sms-queue trigger",
1351 "SMS Queue\n" "Trigger sending messages\n")
1352{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001353 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001354 return CMD_SUCCESS;
1355}
1356
1357DEFUN(smsqueue_max,
1358 smsqueue_max_cmd,
1359 "sms-queue max-pending <1-500>",
1360 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1361{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001362 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001363 return CMD_SUCCESS;
1364}
1365
1366DEFUN(smsqueue_clear,
1367 smsqueue_clear_cmd,
1368 "sms-queue clear",
1369 "SMS Queue\n" "Clear the queue of pending SMS\n")
1370{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001371 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001372 return CMD_SUCCESS;
1373}
1374
1375DEFUN(smsqueue_fail,
1376 smsqueue_fail_cmd,
1377 "sms-queue max-failure <1-500>",
1378 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1379{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001380 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001381 return CMD_SUCCESS;
1382}
1383
1384
1385DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1386 "mncc-int", "Configure internal MNCC handler")
1387{
1388 vty->node = MNCC_INT_NODE;
1389
1390 return CMD_SUCCESS;
1391}
1392
1393static struct cmd_node mncc_int_node = {
1394 MNCC_INT_NODE,
1395 "%s(config-mncc-int)# ",
1396 1,
1397};
1398
1399static const struct value_string tchf_codec_names[] = {
1400 { GSM48_CMODE_SPEECH_V1, "fr" },
1401 { GSM48_CMODE_SPEECH_EFR, "efr" },
1402 { GSM48_CMODE_SPEECH_AMR, "amr" },
1403 { 0, NULL }
1404};
1405
1406static const struct value_string tchh_codec_names[] = {
1407 { GSM48_CMODE_SPEECH_V1, "hr" },
1408 { GSM48_CMODE_SPEECH_AMR, "amr" },
1409 { 0, NULL }
1410};
1411
1412static int config_write_mncc_int(struct vty *vty)
1413{
1414 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1415 vty_out(vty, " default-codec tch-f %s%s",
1416 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1417 VTY_NEWLINE);
1418 vty_out(vty, " default-codec tch-h %s%s",
1419 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1420 VTY_NEWLINE);
1421
1422 return CMD_SUCCESS;
1423}
1424
1425DEFUN(mnccint_def_codec_f,
1426 mnccint_def_codec_f_cmd,
1427 "default-codec tch-f (fr|efr|amr)",
1428 "Set default codec\n" "Codec for TCH/F\n"
1429 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1430{
1431 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1432
1433 return CMD_SUCCESS;
1434}
1435
1436DEFUN(mnccint_def_codec_h,
1437 mnccint_def_codec_h_cmd,
1438 "default-codec tch-h (hr|amr)",
1439 "Set default codec\n" "Codec for TCH/H\n"
1440 "Half-Rate\n" "Adaptive Multi-Rate\n")
1441{
1442 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1443
1444 return CMD_SUCCESS;
1445}
1446
1447
1448DEFUN(logging_fltr_imsi,
1449 logging_fltr_imsi_cmd,
1450 "logging filter imsi IMSI",
1451 LOGGING_STR FILTER_STR
1452 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1453{
1454 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001455 struct log_target *tgt = osmo_log_vty2tgt(vty);
1456 const char *imsi = argv[0];
1457
1458 if (!tgt)
1459 return CMD_WARNING;
1460
1461 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi);
1462
1463 if (!vlr_subscr) {
1464 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1465 argv[0], VTY_NEWLINE);
1466 return CMD_WARNING;
1467 }
1468
1469 log_set_filter_vlr_subscr(tgt, vlr_subscr);
1470 return CMD_SUCCESS;
1471}
1472
1473static struct cmd_node hlr_node = {
1474 HLR_NODE,
1475 "%s(config-hlr)# ",
1476 1,
1477};
1478
1479DEFUN(cfg_hlr, cfg_hlr_cmd,
1480 "hlr", "Configure connection to the HLR")
1481{
1482 vty->node = HLR_NODE;
1483 return CMD_SUCCESS;
1484}
1485
1486DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1487 "Remote GSUP address of the HLR\n"
1488 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1489{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001490 talloc_free((void*)gsmnet->gsup_server_addr_str);
1491 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1492 return CMD_SUCCESS;
1493}
1494
1495DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1496 "Remote GSUP port of the HLR\n"
1497 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1498{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001499 gsmnet->gsup_server_port = atoi(argv[0]);
1500 return CMD_SUCCESS;
1501}
1502
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001503DEFUN(cfg_hlr_ipa_name,
1504 cfg_hlr_ipa_name_cmd,
1505 "ipa-name NAME",
1506 "Set the IPA name of this MSC\n"
1507 "A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. "
1508 "This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. "
1509 "The default is 'MSC-00-00-00-00-00-00'.\n")
1510{
1511 if (vty->type != VTY_FILE) {
1512 vty_out(vty, "The IPA name cannot be changed at run-time; "
1513 "It can only be set in the configuraton file.%s", VTY_NEWLINE);
1514 return CMD_WARNING;
1515 }
1516
1517 gsmnet->msc_ipa_name = talloc_strdup(gsmnet, argv[0]);
1518 return CMD_SUCCESS;
1519}
1520
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001521static int config_write_hlr(struct vty *vty)
1522{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001523 vty_out(vty, "hlr%s", VTY_NEWLINE);
1524 vty_out(vty, " remote-ip %s%s",
1525 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1526 vty_out(vty, " remote-port %u%s",
1527 gsmnet->gsup_server_port, VTY_NEWLINE);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001528 if (gsmnet->msc_ipa_name)
1529 vty_out(vty, " ipa-name %s%s", gsmnet->msc_ipa_name, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001530 return CMD_SUCCESS;
1531}
1532
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001533void msc_vty_init(struct gsm_network *msc_network)
1534{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001535 OSMO_ASSERT(gsmnet == NULL);
1536 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001537
1538 osmo_stats_vty_add_cmds();
1539
1540 install_element(CONFIG_NODE, &cfg_net_cmd);
1541 install_node(&net_node, config_write_net);
1542 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
1543 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1544 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1545 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
1546 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
1547 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
1548 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
1549 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
1550 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
1551 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
1552 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
1553 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
1554 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001555
1556 install_element(CONFIG_NODE, &cfg_msc_cmd);
1557 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001558 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01001559 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
1560 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02001561 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01001562 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001563 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01001564 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
1565 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Oliver Smith0fec28a2018-12-14 10:52:52 +01001566 install_element(MSC_NODE, &cfg_msc_check_imei_rqd_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001567 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
1568 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01001569 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01001570 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +07001571 install_element(MSC_NODE, &cfg_msc_sms_over_gsup_cmd);
1572 install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001573
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02001574 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001575#ifdef BUILD_IU
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +01001576 ranap_iu_vty_init(MSC_NODE, &msc_network->iu.rab_assign_addr_enc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001577#endif
Stefan Sperling617ac802018-02-22 17:58:20 +01001578 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001579
1580 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
1581
1582 install_element_ve(&show_subscr_cmd);
1583 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01001584 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001585 install_element_ve(&show_msc_conn_cmd);
1586 install_element_ve(&show_msc_transaction_cmd);
1587
1588 install_element_ve(&sms_send_pend_cmd);
1589 install_element_ve(&sms_delete_expired_cmd);
1590
1591 install_element_ve(&subscriber_create_cmd);
1592 install_element_ve(&subscriber_send_sms_cmd);
1593 install_element_ve(&subscriber_silent_sms_cmd);
1594 install_element_ve(&subscriber_silent_call_start_cmd);
1595 install_element_ve(&subscriber_silent_call_stop_cmd);
1596 install_element_ve(&subscriber_ussd_notify_cmd);
1597 install_element_ve(&subscriber_mstest_close_cmd);
1598 install_element_ve(&subscriber_mstest_open_cmd);
1599 install_element_ve(&subscriber_paging_cmd);
1600 install_element_ve(&show_stats_cmd);
1601 install_element_ve(&show_smsqueue_cmd);
1602 install_element_ve(&logging_fltr_imsi_cmd);
1603
1604 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
1605 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
1606 install_element(ENABLE_NODE, &smsqueue_max_cmd);
1607 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
1608 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
1609 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
1610
1611 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1612 install_node(&mncc_int_node, config_write_mncc_int);
1613 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1614 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1615
1616 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
1617
1618 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1619 install_node(&hlr_node, config_write_hlr);
1620 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1621 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001622 install_element(HLR_NODE, &cfg_hlr_ipa_name_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001623}