blob: 8c119001a67870f8f6f2e66cbcf1d9616aac96ee [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"
428 "0 = never re-use auth tuples beyond auth-tuple-max-reuse-count (default)\n"
429 "1 = if the HLR does not deliver new tuples, do re-use already available old ones.\n")
430{
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
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100435DEFUN(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd,
436 "paging response-timer (default|<1-65535>)",
437 "Configure Paging\n"
438 "Set Paging timeout, the minimum time to pass between (unsuccessful) Pagings sent towards"
439 " BSS or RNC\n"
440 "Set to default timeout (" OSMO_STRINGIFY_VAL(MSC_PAGING_RESPONSE_TIMER_DEFAULT) " seconds)\n"
441 "Set paging timeout in seconds\n")
442{
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100443 if (!strcmp(argv[1], "default"))
444 gsmnet->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
445 else
446 gsmnet->paging_response_timer = atoi(argv[0]);
447 return CMD_SUCCESS;
448}
449
Harald Welte69c54a82018-02-09 20:41:14 +0100450DEFUN(cfg_msc_emergency_msisdn, cfg_msc_emergency_msisdn_cmd,
451 "emergency-call route-to-msisdn MSISDN",
452 "Configure Emergency Call Behaviour\n"
453 "MSISDN to which Emergency Calls are Dispatched\n"
454 "MSISDN (E.164 Phone Number)\n")
455{
Harald Welte69c54a82018-02-09 20:41:14 +0100456 osmo_talloc_replace_string(gsmnet, &gsmnet->emergency.route_to_msisdn, argv[0]);
457
458 return CMD_SUCCESS;
459}
460
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700461/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
462DEFUN(cfg_msc_sms_over_gsup, cfg_msc_sms_over_gsup_cmd,
463 "sms-over-gsup",
464 "Enable routing of SMS messages over GSUP\n")
465{
466 gsmnet->sms_over_gsup = true;
467 return CMD_SUCCESS;
468}
469
470/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
471DEFUN(cfg_msc_no_sms_over_gsup, cfg_msc_no_sms_over_gsup_cmd,
472 "no sms-over-gsup",
473 NO_STR "Disable routing of SMS messages over GSUP\n")
474{
475 gsmnet->sms_over_gsup = false;
476 return CMD_SUCCESS;
477}
478
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200479static int config_write_msc(struct vty *vty)
480{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200481 vty_out(vty, "msc%s", VTY_NEWLINE);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100482 if (gsmnet->mncc_sock_path)
483 vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE);
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100484 vty_out(vty, " mncc guard-timeout %i%s",
Philipp Maier9ca7b312018-10-10 17:00:49 +0200485 gsmnet->mncc_guard_timeout, VTY_NEWLINE);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200486 vty_out(vty, " %sassign-tmsi%s",
487 gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
488
Philipp Maierfbf66102017-04-09 12:32:51 +0200489 vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
490 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100491#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200492 vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance,
493 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100494#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200495
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100496 if (gsmnet->vlr->cfg.auth_tuple_max_reuse_count)
497 vty_out(vty, " auth-tuple-max-reuse-count %d%s",
498 OSMO_MAX(-1, gsmnet->vlr->cfg.auth_tuple_max_reuse_count),
499 VTY_NEWLINE);
500 if (gsmnet->vlr->cfg.auth_reuse_old_sets_on_error)
501 vty_out(vty, " auth-tuple-reuse-on-error 1%s",
502 VTY_NEWLINE);
503
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100504 if (gsmnet->paging_response_timer != MSC_PAGING_RESPONSE_TIMER_DEFAULT)
505 vty_out(vty, " paging response-timer %u%s", gsmnet->paging_response_timer, VTY_NEWLINE);
506
Harald Welte69c54a82018-02-09 20:41:14 +0100507 if (gsmnet->emergency.route_to_msisdn) {
508 vty_out(vty, " emergency-call route-to-msisdn %s%s",
509 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
510 }
511
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700512 if (gsmnet->sms_over_gsup)
513 vty_out(vty, " sms-over-gsup%s", VTY_NEWLINE);
514
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +0200515 mgcp_client_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200516#ifdef BUILD_IU
Neels Hofmeyr00e82d62017-07-05 15:19:52 +0200517 ranap_iu_vty_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200518#endif
519
520 return CMD_SUCCESS;
521}
522
Maxc51609a2018-11-09 17:13:00 +0100523DEFUN(show_bsc, show_bsc_cmd,
524 "show bsc", SHOW_STR "BSC\n")
525{
526 struct bsc_context *bsc_ctx;
527 struct osmo_ss7_instance *ss7 = osmo_ss7_instance_find(gsmnet->a.cs7_instance);
528
529 llist_for_each_entry(bsc_ctx, &gsmnet->a.bscs, list) {
530 vty_out(vty, "BSC %s%s", osmo_sccp_addr_name(ss7, &bsc_ctx->bsc_addr), VTY_NEWLINE);
531 }
532
533 return CMD_SUCCESS;
534}
535
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100536static void vty_conn_hdr(struct vty *vty)
537{
538 vty_out(vty, "--ConnId ------------Subscriber RAN --LAC Use --Tokens C A5 State%s",
539 VTY_NEWLINE);
540}
541
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100542static void vty_dump_one_conn(struct vty *vty, const struct ran_conn *conn)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100543{
544 vty_out(vty, "%08x %22s %3s %5u %3u %08x %c /%1u %27s %s",
545 conn->a.conn_id,
546 conn->vsub ? vlr_subscr_name(conn->vsub) : "-",
547 conn->via_ran == RAN_UTRAN_IU ? "Iu" : "A",
548 conn->lac,
549 conn->use_count,
550 conn->use_tokens,
551 conn->received_cm_service_request ? 'C' : '-',
Neels Hofmeyrf41658d2018-11-30 04:35:50 +0100552 conn->geran_encr.alg_id,
Neels Hofmeyr4d3a66b2018-03-31 18:45:59 +0200553 conn->fi ? osmo_fsm_inst_state_name(conn->fi) : "-",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100554 VTY_NEWLINE);
555}
556
557DEFUN(show_msc_conn, show_msc_conn_cmd,
558 "show connection", SHOW_STR "Subscriber Connections\n")
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200559{
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100560 struct ran_conn *conn;
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200561
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100562 vty_conn_hdr(vty);
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100563 llist_for_each_entry(conn, &gsmnet->ran_conns, entry)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100564 vty_dump_one_conn(vty, conn);
565
566 return CMD_SUCCESS;
567}
568
569static void vty_trans_hdr(struct vty *vty)
570{
571 vty_out(vty, "------------Subscriber --ConnId -P TI -CallRef Proto%s",
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200572 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100573}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200574
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100575static const char *get_trans_proto_str(const struct gsm_trans *trans)
576{
577 static char buf[256];
578
579 switch (trans->protocol) {
580 case GSM48_PDISC_CC:
581 snprintf(buf, sizeof(buf), "%s %4u %4u",
582 gsm48_cc_state_name(trans->cc.state),
583 trans->cc.Tcurrent,
584 trans->cc.T308_second);
585 break;
586 case GSM48_PDISC_SMS:
587 snprintf(buf, sizeof(buf), "%s %s",
588 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
589 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
590 break;
591 default:
592 buf[0] = '\0';
593 break;
594 }
595
596 return buf;
597}
598
599static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
600{
601 vty_out(vty, "%22s %08x %s %02u %08x %s%s",
602 trans->vsub ? vlr_subscr_name(trans->vsub) : "-",
603 trans->conn ? trans->conn->a.conn_id : 0,
604 gsm48_pdisc_name(trans->protocol),
605 trans->transaction_id,
606 trans->callref,
607 get_trans_proto_str(trans), VTY_NEWLINE);
608}
609
610DEFUN(show_msc_transaction, show_msc_transaction_cmd,
611 "show transaction", SHOW_STR "Transactions\n")
612{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100613 struct gsm_trans *trans;
614
615 vty_trans_hdr(vty);
616 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
617 vty_dump_one_trans(vty, trans);
618
619 return CMD_SUCCESS;
620}
621
622static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
623{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100624 struct gsm_trans *trans;
625 int reqs;
626 struct llist_head *entry;
627
628 if (strlen(vsub->name))
629 vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
630 if (strlen(vsub->msisdn))
631 vty_out(vty, " Extension: %s%s", vsub->msisdn,
632 VTY_NEWLINE);
633 vty_out(vty, " LAC: %d/0x%x%s",
Max7d41d872018-12-19 11:48:33 +0100634 vsub->cgi.lai.lac, vsub->cgi.lai.lac, VTY_NEWLINE);
Philipp Maier2a0ac3b2018-12-17 10:03:50 +0100635 vty_out(vty, " RAN: %s%s",
636 ran_type_name(vsub->cs.attached_via_ran), VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100637 vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
638 if (vsub->tmsi != GSM_RESERVED_TMSI)
639 vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
640 VTY_NEWLINE);
641 if (vsub->tmsi_new != GSM_RESERVED_TMSI)
642 vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
643 VTY_NEWLINE);
Philipp Maier6d71ccf2018-12-14 13:30:14 +0100644 if (vsub->imei[0] != '\0')
645 vty_out(vty, " IMEI: %s%s", vsub->imei, VTY_NEWLINE);
646 if (vsub->imeisv[0] != '\0')
647 vty_out(vty, " IMEISV: %s%s", vsub->imeisv, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100648
Philipp Maier89561bc2018-12-14 13:34:25 +0100649 vty_out(vty, " Flags: %s", VTY_NEWLINE);
650 vty_out(vty, " IMSI detached: %s%s",
651 vsub->imsi_detached_flag ? "true" : "false", VTY_NEWLINE);
652 vty_out(vty, " Conf. by radio contact: %s%s",
653 vsub->conf_by_radio_contact_ind ? "true" : "false",
654 VTY_NEWLINE);
655 vty_out(vty, " Subscr. data conf. by HLR: %s%s",
656 vsub->sub_dataconf_by_hlr_ind ? "true" : "false", VTY_NEWLINE);
657 vty_out(vty, " Location conf. in HLR: %s%s",
658 vsub->loc_conf_in_hlr_ind ? "true" : "false", VTY_NEWLINE);
659 vty_out(vty, " Subscriber dormant: %s%s",
660 vsub->dormant_ind ? "true" : "false", VTY_NEWLINE);
661 vty_out(vty, " Received cancel locataion: %s%s",
662 vsub->cancel_loc_rx ? "true" : "false", VTY_NEWLINE);
663 vty_out(vty, " MS not reachable: %s%s",
664 vsub->ms_not_reachable_flag ? "true" : "false", VTY_NEWLINE);
665 vty_out(vty, " LA allowed: %s%s",
666 vsub->la_allowed ? "true" : "false", VTY_NEWLINE);
667
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100668#if 0
669 /* TODO: add this to vlr_subscr? */
670 if (vsub->auth_info.auth_algo != AUTH_ALGO_NONE) {
671 struct gsm_auth_info *i = &vsub->auth_info;
672 vty_out(vty, " A3A8 algorithm id: %d%s",
673 i->auth_algo, VTY_NEWLINE);
674 vty_out(vty, " A3A8 Ki: %s%s",
675 osmo_hexdump(i->a3a8_ki, i->a3a8_ki_len),
676 VTY_NEWLINE);
677 }
678#endif
679
680 if (vsub->last_tuple) {
Neels Hofmeyr8b6e5362018-11-30 02:57:33 +0100681 struct vlr_auth_tuple *t = vsub->last_tuple;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100682 vty_out(vty, " A3A8 last tuple (used %d times):%s",
683 t->use_count, VTY_NEWLINE);
684 vty_out(vty, " seq # : %d%s",
685 t->key_seq, VTY_NEWLINE);
686 vty_out(vty, " RAND : %s%s",
687 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
688 VTY_NEWLINE);
689 vty_out(vty, " SRES : %s%s",
690 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
691 VTY_NEWLINE);
692 vty_out(vty, " Kc : %s%s",
693 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
694 VTY_NEWLINE);
695 }
696
697 reqs = 0;
698 llist_for_each(entry, &vsub->cs.requests)
699 reqs += 1;
700 vty_out(vty, " Paging: %s paging for %d requests%s",
701 vsub->cs.is_paging ? "is" : "not", reqs, VTY_NEWLINE);
702 vty_out(vty, " Use count: %u%s", vsub->use_count, VTY_NEWLINE);
703
704 /* Connection */
705 if (vsub->msc_conn_ref) {
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100706 struct ran_conn *conn = vsub->msc_conn_ref;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100707 vty_conn_hdr(vty);
708 vty_dump_one_conn(vty, conn);
709 }
710
711 /* Transactions */
712 vty_trans_hdr(vty);
713 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
714 if (trans->vsub != vsub)
715 continue;
716 vty_dump_one_trans(vty, trans);
717 }
718}
719
720/* Subscriber */
721DEFUN(show_subscr_cache,
722 show_subscr_cache_cmd,
723 "show subscriber cache",
724 SHOW_STR "Show information about subscribers\n"
725 "Display contents of subscriber cache\n")
726{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100727 struct vlr_subscr *vsub;
728 int count = 0;
729
730 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
731 if (++count > 100) {
732 vty_out(vty, "%% More than %d subscribers in cache,"
733 " stopping here.%s", count-1, VTY_NEWLINE);
734 break;
735 }
736 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
737 subscr_dump_full_vty(vty, vsub);
Harald Welte69c54a82018-02-09 20:41:14 +0100738 }
739
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200740 return CMD_SUCCESS;
741}
742
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100743DEFUN(sms_send_pend,
744 sms_send_pend_cmd,
745 "sms send pending",
746 "SMS related commands\n" "SMS Sending related commands\n"
747 "Send all pending SMS")
748{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100749 struct gsm_sms *sms;
750 unsigned long long sms_id = 0;
751
752 while (1) {
753 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
754 if (!sms)
755 break;
756
757 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700758 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100759
760 sms_id = sms->id + 1;
761 }
762
763 return CMD_SUCCESS;
764}
765
766DEFUN(sms_delete_expired,
767 sms_delete_expired_cmd,
768 "sms delete expired",
769 "SMS related commands\n" "SMS Database related commands\n"
770 "Delete all expired SMS")
771{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100772 struct gsm_sms *sms;
773 unsigned long long sms_id = 0;
774 long long num_deleted = 0;
775
776 while (1) {
777 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
778 if (!sms)
779 break;
780
781 /* Skip SMS which are currently queued for sending. */
782 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
783 continue;
784
785 /* Expiration check is performed by the DB layer. */
786 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
787 num_deleted++;
788
789 sms_id = sms->id + 1;
790 }
791
792 if (num_deleted == 0) {
793 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
794 return CMD_WARNING;
795 }
796
797 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
798 return CMD_SUCCESS;
799}
800
801static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +0200802 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100803 char *str, uint8_t tp_pid)
804{
805 struct gsm_network *net = receiver->vlr->user_ctx;
806 struct gsm_sms *sms;
807
Harald Welte39b55482018-04-09 19:19:33 +0200808 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100809 sms->protocol_id = tp_pid;
810
811 /* store in database for the queue */
812 if (db_sms_store(sms) != 0) {
813 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
814 sms_free(sms);
815 return CMD_WARNING;
816 }
817 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
818
819 sms_free(sms);
820 sms_queue_trigger(net->sms_queue);
821 return CMD_SUCCESS;
822}
823
824static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
825 const char *type,
826 const char *id)
827{
828 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
829 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id);
830 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
831 return vlr_subscr_find_by_imsi(gsmnet->vlr, id);
832 else if (!strcmp(type, "tmsi"))
833 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id));
834
835 return NULL;
836}
837#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
838#define SUBSCR_HELP "Operations on a Subscriber\n" \
839 "Identify subscriber by MSISDN (phone number)\n" \
840 "Legacy alias for 'msisdn'\n" \
841 "Identify subscriber by IMSI\n" \
842 "Identify subscriber by TMSI\n" \
843 "Identify subscriber by database ID\n" \
844 "Identifier for the subscriber\n"
845
846DEFUN(show_subscr,
847 show_subscr_cmd,
848 "show subscriber " SUBSCR_TYPES " ID",
849 SHOW_STR SUBSCR_HELP)
850{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100851 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
852 argv[1]);
853
854 if (!vsub) {
855 vty_out(vty, "%% No subscriber found for %s %s%s",
856 argv[0], argv[1], VTY_NEWLINE);
857 return CMD_WARNING;
858 }
859
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100860 /* In the vty output to the user, exclude this local use count added by vlr_subscr_get() in get_vsub_by_argv().
861 * This works, because: for get_vsub_by_argv() to succeed, there *must* have been at least one use count before
862 * 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 +0100863 vlr_subscr_put(vsub);
864
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100865 subscr_dump_full_vty(vty, vsub);
866
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100867 return CMD_SUCCESS;
868}
869
870DEFUN(subscriber_create,
871 subscriber_create_cmd,
872 "subscriber create imsi ID",
873 "Operations on a Subscriber\n" \
874 "Create new subscriber\n" \
875 "Identify the subscriber by his IMSI\n" \
876 "Identifier for the subscriber\n")
877{
878 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
879 VTY_NEWLINE);
880 return CMD_WARNING;
881}
882
883DEFUN(subscriber_send_pending_sms,
884 subscriber_send_pending_sms_cmd,
885 "subscriber " SUBSCR_TYPES " ID sms pending-send",
886 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
887{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100888 struct vlr_subscr *vsub;
889 struct gsm_sms *sms;
890
891 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
892 if (!vsub) {
893 vty_out(vty, "%% No subscriber found for %s %s%s",
894 argv[0], argv[1], VTY_NEWLINE);
895 return CMD_WARNING;
896 }
897
898 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
899 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700900 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100901
902 vlr_subscr_put(vsub);
903
904 return CMD_SUCCESS;
905}
906
907DEFUN(subscriber_send_sms,
908 subscriber_send_sms_cmd,
909 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
910 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
911{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100912 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200913 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100914 char *str;
915 int rc;
916
917 if (!vsub) {
918 vty_out(vty, "%% No subscriber found for %s %s%s",
919 argv[0], argv[1], VTY_NEWLINE);
920 rc = CMD_WARNING;
921 goto err;
922 }
923
Harald Welte39b55482018-04-09 19:19:33 +0200924 if (!strcmp(argv[2], "msisdn"))
925 sender_msisdn = argv[3];
926 else {
927 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
928 if (!sender) {
929 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
930 rc = CMD_WARNING;
931 goto err;
932 }
933 sender_msisdn = sender->msisdn;
934 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100935 }
936
937 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +0200938 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100939 talloc_free(str);
940
941err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100942 if (vsub)
943 vlr_subscr_put(vsub);
944
945 return rc;
946}
947
948DEFUN(subscriber_silent_sms,
949 subscriber_silent_sms_cmd,
950
951 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
952 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
953{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100954 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200955 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100956 char *str;
957 int rc;
958
959 if (!vsub) {
960 vty_out(vty, "%% No subscriber found for %s %s%s",
961 argv[0], argv[1], VTY_NEWLINE);
962 rc = CMD_WARNING;
963 goto err;
964 }
965
Harald Welte39b55482018-04-09 19:19:33 +0200966 if (!strcmp(argv[2], "msisdn")) {
967 sender_msisdn = argv[3];
968 } else {
969 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
970 if (!sender) {
971 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
972 rc = CMD_WARNING;
973 goto err;
974 }
975 sender_msisdn = sender->msisdn;
976 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100977 }
978
979 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +0200980 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100981 talloc_free(str);
982
983err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100984 if (vsub)
985 vlr_subscr_put(vsub);
986
987 return rc;
988}
989
990#define CHAN_TYPES "(any|tch/f|tch/any|sdcch)"
991#define CHAN_TYPE_HELP \
992 "Any channel\n" \
993 "TCH/F channel\n" \
994 "Any TCH channel\n" \
995 "SDCCH channel\n"
996
997DEFUN(subscriber_silent_call_start,
998 subscriber_silent_call_start_cmd,
999 "subscriber " SUBSCR_TYPES " ID silent-call start (any|tch/f|tch/any|sdcch)",
1000 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
1001 CHAN_TYPE_HELP)
1002{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001003 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1004 int rc, type;
1005
1006 if (!vsub) {
1007 vty_out(vty, "%% No subscriber found for %s %s%s",
1008 argv[0], argv[1], VTY_NEWLINE);
1009 return CMD_WARNING;
1010 }
1011
1012 if (!strcmp(argv[2], "tch/f"))
1013 type = RSL_CHANNEED_TCH_F;
1014 else if (!strcmp(argv[2], "tch/any"))
1015 type = RSL_CHANNEED_TCH_ForH;
1016 else if (!strcmp(argv[2], "sdcch"))
1017 type = RSL_CHANNEED_SDCCH;
1018 else
1019 type = RSL_CHANNEED_ANY; /* Defaults to ANY */
1020
1021 rc = gsm_silent_call_start(vsub, vty, type);
1022 switch (rc) {
1023 case -ENODEV:
1024 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
1025 break;
1026 default:
1027 if (rc)
1028 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
1029 else
1030 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
1031 break;
1032 }
1033
1034 vlr_subscr_put(vsub);
1035 return rc ? CMD_WARNING : CMD_SUCCESS;
1036}
1037
1038DEFUN(subscriber_silent_call_stop,
1039 subscriber_silent_call_stop_cmd,
1040 "subscriber " SUBSCR_TYPES " ID silent-call stop",
1041 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
1042 CHAN_TYPE_HELP)
1043{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001044 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1045 int rc;
1046
1047 if (!vsub) {
1048 vty_out(vty, "%% No subscriber found for %s %s%s",
1049 argv[0], argv[1], VTY_NEWLINE);
1050 return CMD_WARNING;
1051 }
1052
1053 rc = gsm_silent_call_stop(vsub);
1054 switch (rc) {
1055 case -ENODEV:
1056 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
1057 break;
1058 case -ENOENT:
1059 vty_out(vty, "%% Subscriber has no silent call active%s",
1060 VTY_NEWLINE);
1061 break;
1062 default:
1063 if (rc)
1064 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
1065 else
1066 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
1067 break;
1068 }
1069
1070 vlr_subscr_put(vsub);
1071 return rc ? CMD_WARNING : CMD_SUCCESS;
1072}
1073
1074DEFUN(subscriber_ussd_notify,
1075 subscriber_ussd_notify_cmd,
1076 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1077 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1078 "Alerting Level 0\n"
1079 "Alerting Level 1\n"
1080 "Alerting Level 2\n"
1081 "Text of USSD message to send\n")
1082{
1083 char *text;
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001084 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001085 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1086 int level;
1087
1088 if (!vsub) {
1089 vty_out(vty, "%% No subscriber found for %s %s%s",
1090 argv[0], argv[1], VTY_NEWLINE);
1091 return CMD_WARNING;
1092 }
1093
1094 level = atoi(argv[2]);
1095 text = argv_concat(argv, argc, 3);
1096 if (!text) {
1097 vlr_subscr_put(vsub);
1098 return CMD_WARNING;
1099 }
1100
1101 conn = connection_for_subscr(vsub);
1102 if (!conn) {
1103 vty_out(vty, "%% An active connection is required for %s %s%s",
1104 argv[0], argv[1], VTY_NEWLINE);
1105 vlr_subscr_put(vsub);
1106 talloc_free(text);
1107 return CMD_WARNING;
1108 }
1109
1110 msc_send_ussd_notify(conn, level, text);
1111 msc_send_ussd_release_complete(conn);
1112
1113 vlr_subscr_put(vsub);
1114 talloc_free(text);
1115 return CMD_SUCCESS;
1116}
1117
1118DEFUN(subscriber_paging,
1119 subscriber_paging_cmd,
1120 "subscriber " SUBSCR_TYPES " ID paging",
1121 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1122{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001123 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1124 struct subscr_request *req;
1125
1126 if (!vsub) {
1127 vty_out(vty, "%% No subscriber found for %s %s%s",
1128 argv[0], argv[1], VTY_NEWLINE);
1129 return CMD_WARNING;
1130 }
1131
1132 req = subscr_request_conn(vsub, NULL, NULL, "manual Paging from VTY");
1133 if (req)
1134 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1135 else
1136 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1137
1138 vlr_subscr_put(vsub);
1139 return req ? CMD_SUCCESS : CMD_WARNING;
1140}
1141
1142static int loop_by_char(uint8_t ch)
1143{
1144 switch (ch) {
1145 case 'a':
1146 return GSM414_LOOP_A;
1147 case 'b':
1148 return GSM414_LOOP_B;
1149 case 'c':
1150 return GSM414_LOOP_C;
1151 case 'd':
1152 return GSM414_LOOP_D;
1153 case 'e':
1154 return GSM414_LOOP_E;
1155 case 'f':
1156 return GSM414_LOOP_F;
1157 case 'i':
1158 return GSM414_LOOP_I;
1159 }
1160 return -1;
1161}
1162
1163DEFUN(subscriber_mstest_close,
1164 subscriber_mstest_close_cmd,
1165 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1166 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1167 "Close a TCH Loop inside the MS\n"
1168 "Loop Type A\n"
1169 "Loop Type B\n"
1170 "Loop Type C\n"
1171 "Loop Type D\n"
1172 "Loop Type E\n"
1173 "Loop Type F\n"
1174 "Loop Type I\n")
1175{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001176 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001177 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1178 const char *loop_str;
1179 int loop_mode;
1180
1181 if (!vsub) {
1182 vty_out(vty, "%% No subscriber found for %s %s%s",
1183 argv[0], argv[1], VTY_NEWLINE);
1184 return CMD_WARNING;
1185 }
1186
1187 loop_str = argv[2];
1188 loop_mode = loop_by_char(loop_str[0]);
1189
1190 conn = connection_for_subscr(vsub);
1191 if (!conn) {
1192 vty_out(vty, "%% An active connection is required for %s %s%s",
1193 argv[0], argv[1], VTY_NEWLINE);
1194 vlr_subscr_put(vsub);
1195 return CMD_WARNING;
1196 }
1197
1198 gsm0414_tx_close_tch_loop_cmd(conn, loop_mode);
1199
1200 return CMD_SUCCESS;
1201}
1202
1203DEFUN(subscriber_mstest_open,
1204 subscriber_mstest_open_cmd,
1205 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1206 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1207 "Open a TCH Loop inside the MS\n")
1208{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001209 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001210 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1211
1212 if (!vsub) {
1213 vty_out(vty, "%% No subscriber found for %s %s%s",
1214 argv[0], argv[1], VTY_NEWLINE);
1215 return CMD_WARNING;
1216 }
1217
1218 conn = connection_for_subscr(vsub);
1219 if (!conn) {
1220 vty_out(vty, "%% An active connection is required for %s %s%s",
1221 argv[0], argv[1], VTY_NEWLINE);
1222 vlr_subscr_put(vsub);
1223 return CMD_WARNING;
1224 }
1225
1226 gsm0414_tx_open_loop_cmd(conn);
1227
1228 return CMD_SUCCESS;
1229}
1230
1231DEFUN(ena_subscr_expire,
1232 ena_subscr_expire_cmd,
1233 "subscriber " SUBSCR_TYPES " ID expire",
1234 SUBSCR_HELP "Expire the subscriber Now\n")
1235{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001236 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1237 argv[1]);
1238
1239 if (!vsub) {
1240 vty_out(vty, "%% No subscriber found for %s %s%s",
1241 argv[0], argv[1], VTY_NEWLINE);
1242 return CMD_WARNING;
1243 }
1244
1245 if (vlr_subscr_expire(vsub))
1246 vty_out(vty, "%% VLR released subscriber %s%s",
1247 vlr_subscr_name(vsub), VTY_NEWLINE);
1248
1249 if (vsub->use_count > 1)
1250 vty_out(vty, "%% Subscriber %s is still in use,"
1251 " should be released soon%s",
1252 vlr_subscr_name(vsub), VTY_NEWLINE);
1253
1254 vlr_subscr_put(vsub);
1255 return CMD_SUCCESS;
1256}
1257
1258static int scall_cbfn(unsigned int subsys, unsigned int signal,
1259 void *handler_data, void *signal_data)
1260{
1261 struct scall_signal_data *sigdata = signal_data;
1262 struct vty *vty = sigdata->data;
1263
1264 switch (signal) {
1265 case S_SCALL_SUCCESS:
1266 vty_out(vty, "%% silent call success%s", VTY_NEWLINE);
1267 break;
1268 case S_SCALL_EXPIRED:
1269 vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE);
1270 break;
1271 }
1272 return 0;
1273}
1274
1275DEFUN(show_stats,
1276 show_stats_cmd,
1277 "show statistics",
1278 SHOW_STR "Display network statistics\n")
1279{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001280 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001281 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1282 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1283 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001284 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001285 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001286 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001287 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001288 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001289 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1290 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001291 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001292 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001293 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1294 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001295 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001296 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001297 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1298 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1299 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001300 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001301 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001302 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1303 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001304 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001305 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001306 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1307 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001308 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001309 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001310 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1311 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1312 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1313 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1314 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001315 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001316 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1317 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1318 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1319 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1320 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001321 return CMD_SUCCESS;
1322}
1323
1324DEFUN(show_smsqueue,
1325 show_smsqueue_cmd,
1326 "show sms-queue",
1327 SHOW_STR "Display SMSqueue statistics\n")
1328{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001329 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001330 return CMD_SUCCESS;
1331}
1332
1333DEFUN(smsqueue_trigger,
1334 smsqueue_trigger_cmd,
1335 "sms-queue trigger",
1336 "SMS Queue\n" "Trigger sending messages\n")
1337{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001338 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001339 return CMD_SUCCESS;
1340}
1341
1342DEFUN(smsqueue_max,
1343 smsqueue_max_cmd,
1344 "sms-queue max-pending <1-500>",
1345 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1346{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001347 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001348 return CMD_SUCCESS;
1349}
1350
1351DEFUN(smsqueue_clear,
1352 smsqueue_clear_cmd,
1353 "sms-queue clear",
1354 "SMS Queue\n" "Clear the queue of pending SMS\n")
1355{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001356 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001357 return CMD_SUCCESS;
1358}
1359
1360DEFUN(smsqueue_fail,
1361 smsqueue_fail_cmd,
1362 "sms-queue max-failure <1-500>",
1363 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1364{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001365 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001366 return CMD_SUCCESS;
1367}
1368
1369
1370DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1371 "mncc-int", "Configure internal MNCC handler")
1372{
1373 vty->node = MNCC_INT_NODE;
1374
1375 return CMD_SUCCESS;
1376}
1377
1378static struct cmd_node mncc_int_node = {
1379 MNCC_INT_NODE,
1380 "%s(config-mncc-int)# ",
1381 1,
1382};
1383
1384static const struct value_string tchf_codec_names[] = {
1385 { GSM48_CMODE_SPEECH_V1, "fr" },
1386 { GSM48_CMODE_SPEECH_EFR, "efr" },
1387 { GSM48_CMODE_SPEECH_AMR, "amr" },
1388 { 0, NULL }
1389};
1390
1391static const struct value_string tchh_codec_names[] = {
1392 { GSM48_CMODE_SPEECH_V1, "hr" },
1393 { GSM48_CMODE_SPEECH_AMR, "amr" },
1394 { 0, NULL }
1395};
1396
1397static int config_write_mncc_int(struct vty *vty)
1398{
1399 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1400 vty_out(vty, " default-codec tch-f %s%s",
1401 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1402 VTY_NEWLINE);
1403 vty_out(vty, " default-codec tch-h %s%s",
1404 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1405 VTY_NEWLINE);
1406
1407 return CMD_SUCCESS;
1408}
1409
1410DEFUN(mnccint_def_codec_f,
1411 mnccint_def_codec_f_cmd,
1412 "default-codec tch-f (fr|efr|amr)",
1413 "Set default codec\n" "Codec for TCH/F\n"
1414 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1415{
1416 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1417
1418 return CMD_SUCCESS;
1419}
1420
1421DEFUN(mnccint_def_codec_h,
1422 mnccint_def_codec_h_cmd,
1423 "default-codec tch-h (hr|amr)",
1424 "Set default codec\n" "Codec for TCH/H\n"
1425 "Half-Rate\n" "Adaptive Multi-Rate\n")
1426{
1427 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1428
1429 return CMD_SUCCESS;
1430}
1431
1432
1433DEFUN(logging_fltr_imsi,
1434 logging_fltr_imsi_cmd,
1435 "logging filter imsi IMSI",
1436 LOGGING_STR FILTER_STR
1437 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1438{
1439 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001440 struct log_target *tgt = osmo_log_vty2tgt(vty);
1441 const char *imsi = argv[0];
1442
1443 if (!tgt)
1444 return CMD_WARNING;
1445
1446 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi);
1447
1448 if (!vlr_subscr) {
1449 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1450 argv[0], VTY_NEWLINE);
1451 return CMD_WARNING;
1452 }
1453
1454 log_set_filter_vlr_subscr(tgt, vlr_subscr);
1455 return CMD_SUCCESS;
1456}
1457
1458static struct cmd_node hlr_node = {
1459 HLR_NODE,
1460 "%s(config-hlr)# ",
1461 1,
1462};
1463
1464DEFUN(cfg_hlr, cfg_hlr_cmd,
1465 "hlr", "Configure connection to the HLR")
1466{
1467 vty->node = HLR_NODE;
1468 return CMD_SUCCESS;
1469}
1470
1471DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1472 "Remote GSUP address of the HLR\n"
1473 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1474{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001475 talloc_free((void*)gsmnet->gsup_server_addr_str);
1476 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1477 return CMD_SUCCESS;
1478}
1479
1480DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1481 "Remote GSUP port of the HLR\n"
1482 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1483{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001484 gsmnet->gsup_server_port = atoi(argv[0]);
1485 return CMD_SUCCESS;
1486}
1487
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001488DEFUN(cfg_hlr_ipa_name,
1489 cfg_hlr_ipa_name_cmd,
1490 "ipa-name NAME",
1491 "Set the IPA name of this MSC\n"
1492 "A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. "
1493 "This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. "
1494 "The default is 'MSC-00-00-00-00-00-00'.\n")
1495{
1496 if (vty->type != VTY_FILE) {
1497 vty_out(vty, "The IPA name cannot be changed at run-time; "
1498 "It can only be set in the configuraton file.%s", VTY_NEWLINE);
1499 return CMD_WARNING;
1500 }
1501
1502 gsmnet->msc_ipa_name = talloc_strdup(gsmnet, argv[0]);
1503 return CMD_SUCCESS;
1504}
1505
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001506static int config_write_hlr(struct vty *vty)
1507{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001508 vty_out(vty, "hlr%s", VTY_NEWLINE);
1509 vty_out(vty, " remote-ip %s%s",
1510 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1511 vty_out(vty, " remote-port %u%s",
1512 gsmnet->gsup_server_port, VTY_NEWLINE);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001513 if (gsmnet->msc_ipa_name)
1514 vty_out(vty, " ipa-name %s%s", gsmnet->msc_ipa_name, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001515 return CMD_SUCCESS;
1516}
1517
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001518void msc_vty_init(struct gsm_network *msc_network)
1519{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001520 OSMO_ASSERT(gsmnet == NULL);
1521 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001522
1523 osmo_stats_vty_add_cmds();
1524
1525 install_element(CONFIG_NODE, &cfg_net_cmd);
1526 install_node(&net_node, config_write_net);
1527 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
1528 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1529 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1530 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
1531 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
1532 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
1533 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
1534 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
1535 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
1536 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
1537 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
1538 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
1539 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001540
1541 install_element(CONFIG_NODE, &cfg_msc_cmd);
1542 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001543 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01001544 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
1545 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02001546 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01001547 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001548 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01001549 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
1550 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001551 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
1552 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01001553 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01001554 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +07001555 install_element(MSC_NODE, &cfg_msc_sms_over_gsup_cmd);
1556 install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001557
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02001558 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001559#ifdef BUILD_IU
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +01001560 ranap_iu_vty_init(MSC_NODE, &msc_network->iu.rab_assign_addr_enc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001561#endif
Stefan Sperling617ac802018-02-22 17:58:20 +01001562 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001563
1564 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
1565
1566 install_element_ve(&show_subscr_cmd);
1567 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01001568 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001569 install_element_ve(&show_msc_conn_cmd);
1570 install_element_ve(&show_msc_transaction_cmd);
1571
1572 install_element_ve(&sms_send_pend_cmd);
1573 install_element_ve(&sms_delete_expired_cmd);
1574
1575 install_element_ve(&subscriber_create_cmd);
1576 install_element_ve(&subscriber_send_sms_cmd);
1577 install_element_ve(&subscriber_silent_sms_cmd);
1578 install_element_ve(&subscriber_silent_call_start_cmd);
1579 install_element_ve(&subscriber_silent_call_stop_cmd);
1580 install_element_ve(&subscriber_ussd_notify_cmd);
1581 install_element_ve(&subscriber_mstest_close_cmd);
1582 install_element_ve(&subscriber_mstest_open_cmd);
1583 install_element_ve(&subscriber_paging_cmd);
1584 install_element_ve(&show_stats_cmd);
1585 install_element_ve(&show_smsqueue_cmd);
1586 install_element_ve(&logging_fltr_imsi_cmd);
1587
1588 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
1589 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
1590 install_element(ENABLE_NODE, &smsqueue_max_cmd);
1591 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
1592 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
1593 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
1594
1595 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1596 install_node(&mncc_int_node, config_write_mncc_int);
1597 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1598 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1599
1600 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
1601
1602 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1603 install_node(&hlr_node, config_write_hlr);
1604 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1605 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001606 install_element(HLR_NODE, &cfg_hlr_ipa_name_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001607}