blob: 29deb5e82707451811fb4b6963839a5f18e9cef5 [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 Hofmeyr4ac80092019-03-04 02:46:37 +010026#include "config.h"
Neels Hofmeyr00e82d62017-07-05 15:19:52 +020027
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020028#include <inttypes.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010029#include <limits.h>
30
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010031#include <osmocom/core/use_count.h>
32
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010033#include <osmocom/gsm/protocol/gsm_08_58.h>
34#include <osmocom/gsm/protocol/gsm_04_14.h>
Philipp Maier8fa2dbe2019-03-19 18:51:37 +010035#include <osmocom/gsm/protocol/gsm_08_08.h>
Neels Hofmeyr9aac5c22020-05-27 00:04:26 +020036#include <osmocom/gsm/gsm23236.h>
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020037
Maxc51609a2018-11-09 17:13:00 +010038#include <osmocom/sigtran/sccp_helpers.h>
39
Vadim Yanitskiyffc7f392020-01-18 18:39:41 +070040#include <osmocom/vty/tdef_vty.h>
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020041#include <osmocom/vty/command.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010042#include <osmocom/vty/logging.h>
Stefan Sperling617ac802018-02-22 17:58:20 +010043#include <osmocom/vty/misc.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010044#include <osmocom/vty/stats.h>
45
Neels Hofmeyr00e82d62017-07-05 15:19:52 +020046#ifdef BUILD_IU
47#include <osmocom/ranap/iu_client.h>
48#endif
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020049
Neels Hofmeyr90843962017-09-04 15:04:35 +020050#include <osmocom/msc/vty.h>
51#include <osmocom/msc/gsm_data.h>
52#include <osmocom/msc/gsm_subscriber.h>
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010053#include <osmocom/msc/msub.h>
54#include <osmocom/msc/msc_a.h>
Neels Hofmeyr90843962017-09-04 15:04:35 +020055#include <osmocom/msc/vlr.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010056#include <osmocom/msc/transaction.h>
57#include <osmocom/msc/db.h>
58#include <osmocom/msc/sms_queue.h>
59#include <osmocom/msc/silent_call.h>
60#include <osmocom/msc/gsm_04_80.h>
61#include <osmocom/msc/gsm_04_14.h>
62#include <osmocom/msc/signal.h>
63#include <osmocom/msc/mncc_int.h>
Pau Espin Pedrol4faff9e2019-05-06 19:29:11 +020064#include <osmocom/msc/osmux.h>
Vadim Yanitskiy1b891302018-08-04 01:33:08 +070065#include <osmocom/msc/rrlp.h>
Harald Welte0df904d2018-12-03 11:00:04 +010066#include <osmocom/msc/vlr_sgs.h>
67#include <osmocom/msc/sgs_vty.h>
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010068#include <osmocom/msc/sccp_ran.h>
69#include <osmocom/msc/ran_peer.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010070
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010071static struct gsm_network *gsmnet = NULL;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010072
Vadim Yanitskiy9b56cd82020-01-25 06:38:44 +070073static struct cmd_node net_node = {
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010074 GSMNET_NODE,
75 "%s(config-net)# ",
76 1,
77};
78
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +010079#define VSUB_USE_VTY "VTY"
80
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010081#define NETWORK_STR "Configure the GSM network\n"
82#define CODE_CMD_STR "Code commands\n"
83#define NAME_CMD_STR "Name Commands\n"
84#define NAME_STR "Name to use\n"
85
86DEFUN(cfg_net,
87 cfg_net_cmd,
88 "network", NETWORK_STR)
89{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010090 vty->index = gsmnet;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010091 vty->node = GSMNET_NODE;
92
93 return CMD_SUCCESS;
94}
95
96DEFUN(cfg_net_ncc,
97 cfg_net_ncc_cmd,
98 "network country code <1-999>",
99 "Set the GSM network country code\n"
100 "Country commands\n"
101 CODE_CMD_STR
102 "Network Country Code to use\n")
103{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100104 gsmnet->plmn.mcc = atoi(argv[0]);
105
106 return CMD_SUCCESS;
107}
108
109DEFUN(cfg_net_mnc,
110 cfg_net_mnc_cmd,
111 "mobile network code <0-999>",
112 "Set the GSM mobile network code\n"
113 "Network Commands\n"
114 CODE_CMD_STR
115 "Mobile Network Code to use\n")
116{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100117 uint16_t mnc;
118 bool mnc_3_digits;
119
120 if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
121 vty_out(vty, "%% Error decoding MNC: %s%s", argv[0], VTY_NEWLINE);
122 return CMD_WARNING;
123 }
124
125 gsmnet->plmn.mnc = mnc;
126 gsmnet->plmn.mnc_3_digits = mnc_3_digits;
127
128 return CMD_SUCCESS;
129}
130
131DEFUN(cfg_net_name_short,
132 cfg_net_name_short_cmd,
133 "short name NAME",
134 "Set the short GSM network name\n" NAME_CMD_STR NAME_STR)
135{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100136 osmo_talloc_replace_string(gsmnet, &gsmnet->name_short, argv[0]);
137 return CMD_SUCCESS;
138}
139
140DEFUN(cfg_net_name_long,
141 cfg_net_name_long_cmd,
142 "long name NAME",
143 "Set the long GSM network name\n" NAME_CMD_STR NAME_STR)
144{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100145 osmo_talloc_replace_string(gsmnet, &gsmnet->name_long, argv[0]);
146 return CMD_SUCCESS;
147}
148
Neels Hofmeyr4dfb2ba2019-08-13 16:00:37 +0200149#define ENCRYPTION_STR "Encryption options\n"
150
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100151DEFUN(cfg_net_encryption,
152 cfg_net_encryption_cmd,
153 "encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]",
Neels Hofmeyr4dfb2ba2019-08-13 16:00:37 +0200154 ENCRYPTION_STR
155 "GSM A5 Air Interface Encryption.\n"
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100156 "A5/n Algorithm Number\n"
157 "A5/n Algorithm Number\n"
158 "A5/n Algorithm Number\n"
159 "A5/n Algorithm Number\n")
160{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100161 unsigned int i;
162
163 gsmnet->a5_encryption_mask = 0;
164 for (i = 0; i < argc; i++)
165 gsmnet->a5_encryption_mask |= (1 << atoi(argv[i]));
166
167 return CMD_SUCCESS;
168}
169
Neels Hofmeyr4dfb2ba2019-08-13 16:00:37 +0200170/* So far just a boolean switch, a future patch might add individual config for UEA1 and UEA2, see OS#4143 */
171DEFUN(cfg_net_encryption_uea,
172 cfg_net_encryption_uea_cmd,
173 "encryption uea <0-2> [<0-2>] [<0-2>]",
174 ENCRYPTION_STR
175 "UTRAN (3G) encryption algorithms to allow: 0 = UEA0 (no encryption), 1 = UEA1, 2 = UEA2."
176 " NOTE: the current implementation does not allow free choice of combining encryption algorithms yet."
177 " The only valid settings are either 'encryption uea 0' or 'encryption uea 1 2'.\n"
178 "UEAn Algorithm Number\n"
179 "UEAn Algorithm Number\n"
180 "UEAn Algorithm Number\n"
181 )
182{
183 unsigned int i;
184 uint8_t mask = 0;
185
186 for (i = 0; i < argc; i++)
187 mask |= (1 << atoi(argv[i]));
188
189 if (mask == (1 << 0)) {
190 /* UEA0. Disable encryption. */
191 gsmnet->uea_encryption = false;
192 } else if (mask == ((1 << 1) | (1 << 2))) {
193 /* UEA1 and UEA2. Enable encryption. */
194 gsmnet->uea_encryption = true;
195 } else {
196 vty_out(vty,
197 "%% Error: the current implementation does not allow free choice of combining%s"
198 "%% encryption algorithms yet. The only valid settings are either%s"
199 "%% encryption uea 0%s"
200 "%% or%s"
201 "%% encryption uea 1 2%s",
202 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
203 return CMD_WARNING;
204 }
205
206 return CMD_SUCCESS;
207}
208
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100209DEFUN(cfg_net_authentication,
210 cfg_net_authentication_cmd,
211 "authentication (optional|required)",
212 "Whether to enforce MS authentication in 2G\n"
213 "Allow MS to attach via 2G BSC without authentication\n"
214 "Always do authentication\n")
215{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100216 gsmnet->authentication_required = (argv[0][0] == 'r') ? true : false;
217
218 return CMD_SUCCESS;
219}
220
221DEFUN(cfg_net_rrlp_mode, cfg_net_rrlp_mode_cmd,
222 "rrlp mode (none|ms-based|ms-preferred|ass-preferred)",
223 "Radio Resource Location Protocol\n"
224 "Set the Radio Resource Location Protocol Mode\n"
225 "Don't send RRLP request\n"
226 "Request MS-based location\n"
227 "Request any location, prefer MS-based\n"
228 "Request any location, prefer MS-assisted\n")
229{
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700230 gsmnet->rrlp.mode = msc_rrlp_mode_parse(argv[0]);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100231
232 return CMD_SUCCESS;
233}
234
235DEFUN(cfg_net_mm_info, cfg_net_mm_info_cmd,
236 "mm info (0|1)",
237 "Mobility Management\n"
238 "Send MM INFO after LOC UPD ACCEPT\n"
239 "Disable\n" "Enable\n")
240{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100241 gsmnet->send_mm_info = atoi(argv[0]);
242
243 return CMD_SUCCESS;
244}
245
246DEFUN(cfg_net_timezone,
247 cfg_net_timezone_cmd,
248 "timezone <-19-19> (0|15|30|45)",
249 "Set the Timezone Offset of the network\n"
250 "Timezone offset (hours)\n"
251 "Timezone offset (00 minutes)\n"
252 "Timezone offset (15 minutes)\n"
253 "Timezone offset (30 minutes)\n"
254 "Timezone offset (45 minutes)\n"
255 )
256{
257 struct gsm_network *net = vty->index;
258 int tzhr = atoi(argv[0]);
259 int tzmn = atoi(argv[1]);
260
261 net->tz.hr = tzhr;
262 net->tz.mn = tzmn;
263 net->tz.dst = 0;
264 net->tz.override = 1;
265
266 return CMD_SUCCESS;
267}
268
269DEFUN(cfg_net_timezone_dst,
270 cfg_net_timezone_dst_cmd,
271 "timezone <-19-19> (0|15|30|45) <0-2>",
272 "Set the Timezone Offset of the network\n"
273 "Timezone offset (hours)\n"
274 "Timezone offset (00 minutes)\n"
275 "Timezone offset (15 minutes)\n"
276 "Timezone offset (30 minutes)\n"
277 "Timezone offset (45 minutes)\n"
278 "DST offset (hours)\n"
279 )
280{
281 struct gsm_network *net = vty->index;
282 int tzhr = atoi(argv[0]);
283 int tzmn = atoi(argv[1]);
284 int tzdst = atoi(argv[2]);
285
286 net->tz.hr = tzhr;
287 net->tz.mn = tzmn;
288 net->tz.dst = tzdst;
289 net->tz.override = 1;
290
291 return CMD_SUCCESS;
292}
293
294DEFUN(cfg_net_no_timezone,
295 cfg_net_no_timezone_cmd,
296 "no timezone",
297 NO_STR
298 "Disable network timezone override, use system tz\n")
299{
300 struct gsm_network *net = vty->index;
301
302 net->tz.override = 0;
303
304 return CMD_SUCCESS;
305}
306
Vadim Yanitskiyfc2b0192020-01-18 07:20:14 +0700307/* NOTE: actually this is subscriber expiration timeout */
308#define PER_LOC_UPD_STR "Periodic Location Updating Interval\n"
309
310DEFUN_DEPRECATED(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
311 "periodic location update <6-1530>",
312 PER_LOC_UPD_STR PER_LOC_UPD_STR PER_LOC_UPD_STR
313 "Periodic Location Updating Interval in Minutes\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100314{
Vadim Yanitskiyfc2b0192020-01-18 07:20:14 +0700315 int minutes = atoi(argv[0]);
316 int rc;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100317
Vadim Yanitskiyfc2b0192020-01-18 07:20:14 +0700318 vty_out(vty, "%% 'periodic location update' is now deprecated: "
319 "use 'timer T3212' to change subscriber expiration "
320 "timeout.%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100321
Vadim Yanitskiyfc2b0192020-01-18 07:20:14 +0700322 /* We used to double this value and add a minute when scheduling the
323 * expiration timer. Let's emulate the old behaviour here. */
324 minutes = minutes * 2 + 1;
325 vty_out(vty, "%% Setting T3212 to %d minutes "
326 "(emulating the old behaviour).%s",
327 minutes, VTY_NEWLINE);
328
329 rc = osmo_tdef_set(msc_tdefs_vlr, 3212, minutes, OSMO_TDEF_M);
330 return rc ? CMD_WARNING : CMD_SUCCESS;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100331}
332
Vadim Yanitskiyfc2b0192020-01-18 07:20:14 +0700333DEFUN_DEPRECATED(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
334 "no periodic location update",
335 NO_STR PER_LOC_UPD_STR PER_LOC_UPD_STR PER_LOC_UPD_STR)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100336{
Vadim Yanitskiyfc2b0192020-01-18 07:20:14 +0700337 int rc;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100338
Vadim Yanitskiyfc2b0192020-01-18 07:20:14 +0700339 vty_out(vty, "%% 'periodic location update' is now deprecated: "
340 "use 'timer T3212' to change subscriber expiration "
341 "timeout.%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100342
Vadim Yanitskiyfc2b0192020-01-18 07:20:14 +0700343 rc = osmo_tdef_set(msc_tdefs_vlr, 3212, 0, OSMO_TDEF_M);
344 return rc ? CMD_WARNING : CMD_SUCCESS;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100345}
346
Keith Whyte991bb422019-08-08 15:43:40 +0200347DEFUN(cfg_net_call_wait, cfg_net_call_wait_cmd,
348 "call-waiting",
349 "Enable Call Waiting on the Network\n")
350{
351 struct gsm_network *net = vty->index;
352
353 net->call_waiting = true;
354
355 return CMD_SUCCESS;
356}
357
358DEFUN(cfg_net_no_call_wait, cfg_net_no_call_wait_cmd,
359 "no call-waiting",
360 NO_STR
361 "Disable Call Waiting on the Network\n")
362{
363 struct gsm_network *net = vty->index;
364
365 net->call_waiting = false;
366
367 return CMD_SUCCESS;
368}
369
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100370static int config_write_net(struct vty *vty)
371{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100372 int i;
373
374 vty_out(vty, "network%s", VTY_NEWLINE);
375 vty_out(vty, " network country code %s%s", osmo_mcc_name(gsmnet->plmn.mcc), VTY_NEWLINE);
376 vty_out(vty, " mobile network code %s%s",
377 osmo_mnc_name(gsmnet->plmn.mnc, gsmnet->plmn.mnc_3_digits), VTY_NEWLINE);
378 vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
379 vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
380 vty_out(vty, " encryption a5");
381 for (i = 0; i < 8; i++) {
382 if (gsmnet->a5_encryption_mask & (1 << i))
383 vty_out(vty, " %u", i);
384 }
385 vty_out(vty, "%s", VTY_NEWLINE);
Neels Hofmeyr4dfb2ba2019-08-13 16:00:37 +0200386
387 if (!gsmnet->uea_encryption)
388 vty_out(vty, " encryption uea 0%s", VTY_NEWLINE);
389 else
390 vty_out(vty, " encryption uea 1 2%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100391 vty_out(vty, " authentication %s%s",
392 gsmnet->authentication_required ? "required" : "optional", VTY_NEWLINE);
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700393 vty_out(vty, " rrlp mode %s%s", msc_rrlp_mode_name(gsmnet->rrlp.mode),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100394 VTY_NEWLINE);
395 vty_out(vty, " mm info %u%s", gsmnet->send_mm_info, VTY_NEWLINE);
396 if (gsmnet->tz.override != 0) {
397 if (gsmnet->tz.dst)
398 vty_out(vty, " timezone %d %d %d%s",
399 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
400 VTY_NEWLINE);
401 else
402 vty_out(vty, " timezone %d %d%s",
403 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
404 }
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100405
Keith Whyte991bb422019-08-08 15:43:40 +0200406 if (!gsmnet->call_waiting)
407 vty_out(vty, " no call-waiting%s", VTY_NEWLINE);
408
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100409 return CMD_SUCCESS;
410}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200411
412static struct cmd_node msc_node = {
413 MSC_NODE,
414 "%s(config-msc)# ",
415 1,
416};
417
418DEFUN(cfg_msc, cfg_msc_cmd,
419 "msc", "Configure MSC options")
420{
421 vty->node = MSC_NODE;
422 return CMD_SUCCESS;
423}
424
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100425#define MNCC_STR "Configure Mobile Network Call Control\n"
426#define MNCC_GUARD_TIMEOUT_STR "Set global guard timer for mncc interface activity\n"
427#define MNCC_GUARD_TIMEOUT_VALUE_STR "guard timer value (sec.)\n"
428
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100429DEFUN(cfg_msc_mncc_internal,
430 cfg_msc_mncc_internal_cmd,
431 "mncc internal",
432 MNCC_STR "Use internal MNCC handler (default; changes need a program restart)\n")
433{
434 gsm_network_set_mncc_sock_path(gsmnet, NULL);
435 return CMD_SUCCESS;
436}
437
438DEFUN(cfg_msc_mncc_external,
439 cfg_msc_mncc_external_cmd,
440 "mncc external MNCC_SOCKET_PATH",
441 MNCC_STR "Use external MNCC handler (changes need a program restart)\n"
442 "File system path to create the MNCC unix domain socket at\n")
443{
444 gsm_network_set_mncc_sock_path(gsmnet, argv[0]);
445 return CMD_SUCCESS;
446}
447
Philipp Maier9ca7b312018-10-10 17:00:49 +0200448DEFUN(cfg_msc_mncc_guard_timeout,
449 cfg_msc_mncc_guard_timeout_cmd,
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100450 "mncc guard-timeout <0-255>",
451 MNCC_STR
452 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR)
Philipp Maier9ca7b312018-10-10 17:00:49 +0200453{
454 gsmnet->mncc_guard_timeout = atoi(argv[0]);
455 return CMD_SUCCESS;
456}
457
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100458ALIAS_DEPRECATED(cfg_msc_mncc_guard_timeout,
459 cfg_msc_deprecated_mncc_guard_timeout_cmd,
460 "mncc-guard-timeout <0-255>",
461 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR);
462
Vadim Yanitskiy64623e12018-11-28 23:05:51 +0700463#define NCSS_STR "Configure call independent Supplementary Services\n"
464
465DEFUN(cfg_msc_ncss_guard_timeout,
466 cfg_msc_ncss_guard_timeout_cmd,
467 "ncss guard-timeout <0-255>",
468 NCSS_STR "Set guard timer for session activity\n"
469 "guard timer value (sec.), or 0 to disable\n")
470{
471 gsmnet->ncss_guard_timeout = atoi(argv[0]);
472 return CMD_SUCCESS;
473}
474
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200475DEFUN(cfg_msc_assign_tmsi, cfg_msc_assign_tmsi_cmd,
476 "assign-tmsi",
477 "Assign TMSI during Location Updating.\n")
478{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200479 gsmnet->vlr->cfg.assign_tmsi = true;
480 return CMD_SUCCESS;
481}
482
483DEFUN(cfg_msc_no_assign_tmsi, cfg_msc_no_assign_tmsi_cmd,
484 "no assign-tmsi",
485 NO_STR "Assign TMSI during Location Updating.\n")
486{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200487 gsmnet->vlr->cfg.assign_tmsi = false;
488 return CMD_SUCCESS;
489}
490
Philipp Maierfbf66102017-04-09 12:32:51 +0200491DEFUN(cfg_msc_cs7_instance_a,
492 cfg_msc_cs7_instance_a_cmd,
493 "cs7-instance-a <0-15>",
494 "Set SS7 to be used by the A-Interface.\n" "SS7 instance reference number\n")
495{
Philipp Maierfbf66102017-04-09 12:32:51 +0200496 gsmnet->a.cs7_instance = atoi(argv[0]);
497 return CMD_SUCCESS;
498}
499
500DEFUN(cfg_msc_cs7_instance_iu,
501 cfg_msc_cs7_instance_iu_cmd,
502 "cs7-instance-iu <0-15>",
503 "Set SS7 to be used by the Iu-Interface.\n" "SS7 instance reference number\n")
504{
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100505#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200506 gsmnet->iu.cs7_instance = atoi(argv[0]);
507 return CMD_SUCCESS;
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100508#else
509 vty_out(vty, "WARNING: 'cs7-instance-iu' without effect: built without Iu support%s",
510 VTY_NEWLINE);
511 return CMD_WARNING;
512#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200513}
514
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100515DEFUN(cfg_msc_auth_tuple_max_reuse_count, cfg_msc_auth_tuple_max_reuse_count_cmd,
516 "auth-tuple-max-reuse-count <-1-2147483647>",
517 "Configure authentication tuple re-use\n"
518 "0 to use each auth tuple at most once (default), >0 to limit re-use, -1 to re-use infinitely (vulnerable!).\n")
519{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100520 gsmnet->vlr->cfg.auth_tuple_max_reuse_count = atoi(argv[0]);
521 return CMD_SUCCESS;
522}
523
524DEFUN(cfg_msc_auth_tuple_reuse_on_error, cfg_msc_auth_tuple_reuse_on_error_cmd,
525 "auth-tuple-reuse-on-error (0|1)",
526 "Configure authentication tuple re-use when HLR is not responsive\n"
Oliver Smithd6e24fd2019-01-09 10:46:43 +0100527 "Never re-use auth tuples beyond auth-tuple-max-reuse-count (default)\n"
528 "If the HLR does not deliver new tuples, do re-use already available old ones.\n")
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100529{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100530 gsmnet->vlr->cfg.auth_reuse_old_sets_on_error = atoi(argv[0]) ? true : false;
531 return CMD_SUCCESS;
532}
533
Oliver Smith0fec28a2018-12-14 10:52:52 +0100534DEFUN(cfg_msc_check_imei_rqd, cfg_msc_check_imei_rqd_cmd,
Oliver Smith03ded912019-05-02 10:40:50 +0200535 "check-imei-rqd (0|1|early)",
Oliver Smith0fec28a2018-12-14 10:52:52 +0100536 "Send each IMEI to the EIR to ask if it is permitted or not. The EIR is implemented as part of OsmoHLR, "
537 "and can optionally save the IMEI in the HLR.\n"
538 "Do not send IMEIs to the EIR\n"
Oliver Smith03ded912019-05-02 10:40:50 +0200539 "Send each IMEI to the EIR\n"
540 "Send each IMEI to the EIR, and do it at the start of the location update. This allows the EIR to receive the"
541 " IMEI, even if the MS would get rejected when the MSC sends the location update request to the HLR.\n")
Oliver Smith0fec28a2018-12-14 10:52:52 +0100542{
Oliver Smith03ded912019-05-02 10:40:50 +0200543 if (strcmp(argv[0], "0") == 0) {
544 gsmnet->vlr->cfg.check_imei_rqd = false;
545 gsmnet->vlr->cfg.retrieve_imeisv_early = false;
546 } else if (strcmp(argv[0], "1") == 0) {
547 gsmnet->vlr->cfg.check_imei_rqd = true;
548 gsmnet->vlr->cfg.retrieve_imeisv_early = false;
549 } else if (strcmp(argv[0], "early") == 0) {
550 gsmnet->vlr->cfg.check_imei_rqd = true;
551 gsmnet->vlr->cfg.retrieve_imeisv_early = true;
552 }
Oliver Smith0fec28a2018-12-14 10:52:52 +0100553 return CMD_SUCCESS;
554}
555
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100556DEFUN(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd,
557 "paging response-timer (default|<1-65535>)",
558 "Configure Paging\n"
559 "Set Paging timeout, the minimum time to pass between (unsuccessful) Pagings sent towards"
560 " BSS or RNC\n"
561 "Set to default timeout (" OSMO_STRINGIFY_VAL(MSC_PAGING_RESPONSE_TIMER_DEFAULT) " seconds)\n"
562 "Set paging timeout in seconds\n")
563{
Pau Espin Pedrolb08a3802019-09-16 19:01:37 +0200564 if (!strcmp(argv[0], "default"))
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100565 gsmnet->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
566 else
567 gsmnet->paging_response_timer = atoi(argv[0]);
568 return CMD_SUCCESS;
569}
570
Harald Welte69c54a82018-02-09 20:41:14 +0100571DEFUN(cfg_msc_emergency_msisdn, cfg_msc_emergency_msisdn_cmd,
572 "emergency-call route-to-msisdn MSISDN",
573 "Configure Emergency Call Behaviour\n"
574 "MSISDN to which Emergency Calls are Dispatched\n"
575 "MSISDN (E.164 Phone Number)\n")
576{
Harald Welte69c54a82018-02-09 20:41:14 +0100577 osmo_talloc_replace_string(gsmnet, &gsmnet->emergency.route_to_msisdn, argv[0]);
578
579 return CMD_SUCCESS;
580}
581
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700582/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
583DEFUN(cfg_msc_sms_over_gsup, cfg_msc_sms_over_gsup_cmd,
584 "sms-over-gsup",
585 "Enable routing of SMS messages over GSUP\n")
586{
587 gsmnet->sms_over_gsup = true;
588 return CMD_SUCCESS;
589}
590
591/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
592DEFUN(cfg_msc_no_sms_over_gsup, cfg_msc_no_sms_over_gsup_cmd,
593 "no sms-over-gsup",
594 NO_STR "Disable routing of SMS messages over GSUP\n")
595{
596 gsmnet->sms_over_gsup = false;
597 return CMD_SUCCESS;
598}
599
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100600/* FIXME: This should rather be in the form of
601 * handover-number range 001234xxx
602 * and
603 * handover-number range 001234xxx FIRST LAST
604 */
605DEFUN(cfg_msc_handover_number_range, cfg_msc_handover_number_range_cmd,
606 "handover-number range MSISDN_FIRST MSISDN_LAST",
607 "Configure a range of MSISDN to be assigned to incoming inter-MSC Handovers for call forwarding.\n"
608 "Configure a handover number range\n"
609 "First Handover Number MSISDN\n"
610 "Last Handover Number MSISDN\n")
611{
612 char *endp;
613 uint64_t range_start;
614 uint64_t range_end;
615
616 /* FIXME leading zeros?? */
617
618 errno = 0;
619 range_start = strtoull(argv[0], &endp, 10);
620 if (errno || *endp != '\0') {
621 vty_out(vty, "%% Error parsing handover-number range start: %s%s",
622 argv[0], VTY_NEWLINE);
623 return CMD_WARNING;
624 }
625
626 errno = 0;
627 range_end = strtoull(argv[1], &endp, 10);
628 if (errno || *endp != '\0') {
629 vty_out(vty, "%% Error parsing handover-number range end: %s%s",
630 argv[1], VTY_NEWLINE);
631 return CMD_WARNING;
632 }
633
634 if (range_start > range_end) {
635 vty_out(vty, "%% Error: handover-number range end must be > than the range start, but"
636 " %"PRIu64" > %"PRIu64"%s", range_start, range_end, VTY_NEWLINE);
637 return CMD_WARNING;
638 }
639
640 gsmnet->handover_number.range_start = range_start;
641 gsmnet->handover_number.range_end = range_end;
642 return CMD_SUCCESS;
643}
644
Pau Espin Pedrol4faff9e2019-05-06 19:29:11 +0200645#define OSMUX_STR "RTP multiplexing\n"
646DEFUN(cfg_msc_osmux,
647 cfg_msc_osmux_cmd,
648 "osmux (on|off|only)",
649 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
650{
651 if (strcmp(argv[0], "off") == 0)
652 gsmnet->use_osmux = OSMUX_USAGE_OFF;
653 else if (strcmp(argv[0], "on") == 0)
654 gsmnet->use_osmux = OSMUX_USAGE_ON;
655 else if (strcmp(argv[0], "only") == 0)
656 gsmnet->use_osmux = OSMUX_USAGE_ONLY;
657
658 return CMD_SUCCESS;
659}
660
Neels Hofmeyr9aac5c22020-05-27 00:04:26 +0200661#define NRI_STR "Mapping of Network Resource Indicators to this MSC, for MSC pooling\n"
662DEFUN(cfg_msc_nri_bitlen, cfg_msc_nri_bitlen_cmd,
663 "nri bitlen <0-15>",
664 NRI_STR
665 "Set number of NRI bits to place in TMSI identities (always starting just after the most significant octet)\n"
666 "bit count (default: " OSMO_STRINGIFY_VAL(NRI_BITLEN_DEFAULT) ")\n")
667{
668 gsmnet->vlr->cfg.nri_bitlen = atoi(argv[0]);
669 return CMD_SUCCESS;
670}
671
672#define NRI_STR "Mapping of Network Resource Indicators to this MSC, for MSC pooling\n"
673#define NRI_ARGS_TO_STR_FMT "%s%s%s"
674#define NRI_ARGS_TO_STR_ARGS(ARGC, ARGV) ARGV[0], (ARGC>1)? ".." : "", (ARGC>1)? ARGV[1] : ""
675#define NRI_FIRST_LAST_STR "First value of the NRI value range, should not surpass the configured 'nri bitlen'.\n" \
676 "Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the" \
677 " first value; if omitted, apply only the first value.\n"
678
679DEFUN(cfg_msc_nri_add, cfg_msc_nri_add_cmd,
680 "nri add <0-32767> [<0-32767>]",
681 NRI_STR "Add NRI value or range to the NRI mapping for this MSC\n"
682 NRI_FIRST_LAST_STR)
683{
684 const char *message;
685 int rc = osmo_nri_ranges_vty_add(&message, NULL, gsmnet->vlr->cfg.nri_ranges, argc, argv, gsmnet->vlr->cfg.nri_bitlen);
686 if (message) {
687 vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));
688 }
689 if (rc < 0)
690 return CMD_WARNING;
691 return CMD_SUCCESS;
692}
693
694DEFUN(cfg_msc_nri_del, cfg_msc_nri_del_cmd,
695 "nri del <0-32767> [<0-32767>]",
696 NRI_STR "Remove NRI value or range from the NRI mapping for this MSC\n"
697 NRI_FIRST_LAST_STR)
698{
699 const char *message;
700 int rc = osmo_nri_ranges_vty_del(&message, NULL, gsmnet->vlr->cfg.nri_ranges, argc, argv);
701 if (message) {
702 vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));
703 }
704 if (rc < 0)
705 return CMD_WARNING;
706 return CMD_SUCCESS;
707}
708
709static void msc_write_nri(struct vty *vty)
710{
711 struct osmo_nri_range *r;
712
713 llist_for_each_entry(r, &gsmnet->vlr->cfg.nri_ranges->entries, entry) {
714 if (osmo_nri_range_validate(r, 255))
715 vty_out(vty, " %% INVALID RANGE:");
716 vty_out(vty, " nri add %d", r->first);
717 if (r->first != r->last)
718 vty_out(vty, " %d", r->last);
719 vty_out(vty, "%s", VTY_NEWLINE);
720 }
721}
722
723DEFUN(show_nri, show_nri_cmd,
724 "show nri",
725 SHOW_STR NRI_STR)
726{
727 msc_write_nri(vty);
728 return CMD_SUCCESS;
729}
730
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200731static int config_write_msc(struct vty *vty)
732{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200733 vty_out(vty, "msc%s", VTY_NEWLINE);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100734 if (gsmnet->mncc_sock_path)
735 vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE);
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100736 vty_out(vty, " mncc guard-timeout %i%s",
Philipp Maier9ca7b312018-10-10 17:00:49 +0200737 gsmnet->mncc_guard_timeout, VTY_NEWLINE);
Vadim Yanitskiy64623e12018-11-28 23:05:51 +0700738 vty_out(vty, " ncss guard-timeout %i%s",
739 gsmnet->ncss_guard_timeout, VTY_NEWLINE);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200740 vty_out(vty, " %sassign-tmsi%s",
741 gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
742
Philipp Maierfbf66102017-04-09 12:32:51 +0200743 vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
744 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100745#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200746 vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance,
747 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100748#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200749
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100750 if (gsmnet->vlr->cfg.auth_tuple_max_reuse_count)
751 vty_out(vty, " auth-tuple-max-reuse-count %d%s",
752 OSMO_MAX(-1, gsmnet->vlr->cfg.auth_tuple_max_reuse_count),
753 VTY_NEWLINE);
754 if (gsmnet->vlr->cfg.auth_reuse_old_sets_on_error)
755 vty_out(vty, " auth-tuple-reuse-on-error 1%s",
756 VTY_NEWLINE);
757
Oliver Smith03ded912019-05-02 10:40:50 +0200758 if (gsmnet->vlr->cfg.check_imei_rqd) {
759 if (gsmnet->vlr->cfg.retrieve_imeisv_early)
760 vty_out(vty, " check-imei-rqd early%s", VTY_NEWLINE);
761 else
762 vty_out(vty, " check-imei-rqd 1%s", VTY_NEWLINE);
763 }
Oliver Smith0fec28a2018-12-14 10:52:52 +0100764
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100765 if (gsmnet->paging_response_timer != MSC_PAGING_RESPONSE_TIMER_DEFAULT)
766 vty_out(vty, " paging response-timer %u%s", gsmnet->paging_response_timer, VTY_NEWLINE);
767
Harald Welte69c54a82018-02-09 20:41:14 +0100768 if (gsmnet->emergency.route_to_msisdn) {
769 vty_out(vty, " emergency-call route-to-msisdn %s%s",
770 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
771 }
772
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700773 if (gsmnet->sms_over_gsup)
774 vty_out(vty, " sms-over-gsup%s", VTY_NEWLINE);
775
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100776 if (gsmnet->handover_number.range_start || gsmnet->handover_number.range_end)
777 vty_out(vty, " handover-number range %"PRIu64" %"PRIu64"%s",
778 gsmnet->handover_number.range_start, gsmnet->handover_number.range_end,
779 VTY_NEWLINE);
780
Pau Espin Pedrol4faff9e2019-05-06 19:29:11 +0200781 if (gsmnet->use_osmux != OSMUX_USAGE_OFF) {
782 vty_out(vty, " osmux %s%s", gsmnet->use_osmux == OSMUX_USAGE_ON ? "on" : "only",
783 VTY_NEWLINE);
784 }
785
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +0200786 mgcp_client_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200787#ifdef BUILD_IU
Neels Hofmeyr00e82d62017-07-05 15:19:52 +0200788 ranap_iu_vty_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200789#endif
790
Neels Hofmeyr880b9502019-05-09 02:01:55 +0200791 neighbor_ident_vty_write(vty);
792
Vadim Yanitskiyffc7f392020-01-18 18:39:41 +0700793 /* Timer introspection commands (generic osmo_tdef API) */
794 osmo_tdef_vty_groups_write(vty, " ");
795
Neels Hofmeyr9aac5c22020-05-27 00:04:26 +0200796 msc_write_nri(vty);
797
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200798 return CMD_SUCCESS;
799}
800
Maxc51609a2018-11-09 17:13:00 +0100801DEFUN(show_bsc, show_bsc_cmd,
802 "show bsc", SHOW_STR "BSC\n")
803{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100804 struct ran_peer *rp;
805 llist_for_each_entry(rp, &gsmnet->a.sri->ran_peers, entry) {
806 vty_out(vty, "BSC %s %s%s",
807 osmo_sccp_inst_addr_name(gsmnet->a.sri->sccp, &rp->peer_addr),
808 osmo_fsm_inst_state_name(rp->fi),
809 VTY_NEWLINE);
Maxc51609a2018-11-09 17:13:00 +0100810 }
811
812 return CMD_SUCCESS;
813}
814
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100815static const char *get_trans_proto_str(const struct gsm_trans *trans)
816{
817 static char buf[256];
818
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100819 switch (trans->type) {
820 case TRANS_CC:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100821 snprintf(buf, sizeof(buf), "%s %4u %4u",
822 gsm48_cc_state_name(trans->cc.state),
823 trans->cc.Tcurrent,
824 trans->cc.T308_second);
825 break;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100826 case TRANS_SMS:
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700827 snprintf(buf, sizeof(buf), "CP:%s RP:%s",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100828 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
829 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
830 break;
831 default:
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700832 return NULL;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100833 }
834
835 return buf;
836}
837
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700838/* Prefix a given format string with a given amount of spaces */
839#define MSC_VTY_DUMP(vty, offset, fmt, args...) \
840 vty_out(vty, "%*s" fmt, offset, "", ##args)
841
Neels Hofmeyr4014e482019-06-21 02:00:58 +0200842/* Print value of a named flag, prefixed with a given amount of spaces */
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700843#define MSC_VTY_DUMP_FLAG(vty, offset, name, flag) \
844 MSC_VTY_DUMP(vty, offset + 2, "%s: %*s%s%s", \
845 name, 30 - (int)strlen(name), "", \
846 flag ? "true" : "false", \
847 VTY_NEWLINE)
848
849enum msc_vty_dump_flags {
850 MSC_VTY_DUMP_F_SUBSCR = (1 << 0),
851 MSC_VTY_DUMP_F_CONNECTION = (1 << 1),
852 MSC_VTY_DUMP_F_TRANSACTION = (1 << 2),
853};
854
855static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans,
856 int offset, uint8_t dump_flags)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100857{
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700858 const char *proto_str;
859
860 if (dump_flags & MSC_VTY_DUMP_F_SUBSCR) {
861 MSC_VTY_DUMP(vty, offset, "Subscriber: %s%s",
862 vlr_subscr_name(msc_a_vsub(trans->msc_a)),
863 VTY_NEWLINE);
864 }
865
866 if (dump_flags & MSC_VTY_DUMP_F_CONNECTION) {
Neels Hofmeyr4014e482019-06-21 02:00:58 +0200867 /* (If msc_a exists, there *must* be a non-null msc_a->c.msub) */
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700868 MSC_VTY_DUMP(vty, offset, "RAN connection: %s%s",
869 trans->msc_a ? msub_ran_conn_name(trans->msc_a->c.msub)
870 : "(not established)",
871 VTY_NEWLINE);
872 }
873
874 MSC_VTY_DUMP(vty, offset, "Unique (global) identifier: 0x%08x%s",
875 trans->callref, VTY_NEWLINE);
876 MSC_VTY_DUMP(vty, offset, "GSM 04.07 identifier (%s): %u%s",
877 (trans->transaction_id & 0x08) ? "MO" : "MT",
878 trans->transaction_id,
879 VTY_NEWLINE);
880
881 MSC_VTY_DUMP(vty, offset, "Type: %s%s",
882 trans_type_name(trans->type),
883 VTY_NEWLINE);
884
885 if ((proto_str = get_trans_proto_str(trans))) {
886 MSC_VTY_DUMP(vty, offset, "Protocol specific: %s%s",
887 proto_str, VTY_NEWLINE);
888 }
889}
890
891static void vty_dump_one_conn(struct vty *vty, const struct msub *msub,
892 int offset, uint8_t dump_flags)
893{
894 struct vlr_subscr *vsub = msub_vsub(msub);
895 struct msc_a *msc_a = msub_msc_a(msub);
896 char buf[128];
897
898 if (dump_flags & MSC_VTY_DUMP_F_SUBSCR) {
899 dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
900 MSC_VTY_DUMP(vty, offset, "Subscriber: %s%s",
901 vlr_subscr_name(vsub),
902 VTY_NEWLINE);
903 }
904
905 MSC_VTY_DUMP(vty, offset, "RAN connection: %s%s",
906 msub_ran_conn_name(msub),
907 VTY_NEWLINE);
908 MSC_VTY_DUMP(vty, offset, "RAN connection state: %s%s",
909 osmo_fsm_inst_state_name(msc_a->c.fi),
910 VTY_NEWLINE);
911
912 if (vsub) {
913 MSC_VTY_DUMP(vty, offset, "LAC / cell ID: %u / %u%s",
914 vsub->cgi.lai.lac, vsub->cgi.cell_identity,
915 VTY_NEWLINE);
916 }
917
918 MSC_VTY_DUMP(vty, offset, "Use count total: %d%s",
919 osmo_use_count_total(&msc_a->use_count),
920 VTY_NEWLINE);
921 MSC_VTY_DUMP(vty, offset, "Use count: %s%s",
922 osmo_use_count_name_buf(buf, sizeof(buf), &msc_a->use_count),
923 VTY_NEWLINE);
924
925 /* Transactions of this connection */
926 if (dump_flags & MSC_VTY_DUMP_F_TRANSACTION) {
927 struct gsm_trans *trans;
928 unsigned int i = 0;
929
930 /* Both subscriber and connection info is already printed */
931 dump_flags = dump_flags &~ MSC_VTY_DUMP_F_CONNECTION;
932 dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
933
934 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
935 if (trans->msc_a != msc_a)
936 continue;
937 MSC_VTY_DUMP(vty, offset, "Transaction #%02u: %s",
938 i++, VTY_NEWLINE);
939 vty_dump_one_trans(vty, trans, offset + 2, dump_flags);
940 }
941 }
942}
943
944static void vty_dump_one_subscr(struct vty *vty, struct vlr_subscr *vsub,
945 int offset, uint8_t dump_flags)
946{
Vadim Yanitskiy09ce3dc2019-07-09 00:34:29 +0700947 struct timespec now;
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700948 char buf[128];
949
Vadim Yanitskiydcf28682019-05-29 22:34:13 +0700950 if (vsub->name[0] != '\0') {
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700951 MSC_VTY_DUMP(vty, offset, "Name: '%s'%s",
952 vsub->name, VTY_NEWLINE);
953 }
Vadim Yanitskiydcf28682019-05-29 22:34:13 +0700954 if (vsub->msisdn[0] != '\0') {
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700955 MSC_VTY_DUMP(vty, offset, "MSISDN: %s%s",
956 vsub->msisdn, VTY_NEWLINE);
957 }
958
959 MSC_VTY_DUMP(vty, offset, "LAC / cell ID: %u / %u%s",
960 vsub->cgi.lai.lac, vsub->cgi.cell_identity,
961 VTY_NEWLINE);
962 MSC_VTY_DUMP(vty, offset, "RAN type: %s%s",
963 osmo_rat_type_name(vsub->cs.attached_via_ran),
964 VTY_NEWLINE);
965
966 MSC_VTY_DUMP(vty, offset, "IMSI: %s%s",
967 vsub->imsi, VTY_NEWLINE);
968 if (vsub->tmsi != GSM_RESERVED_TMSI) {
969 MSC_VTY_DUMP(vty, offset, "TMSI: %08X%s",
970 vsub->tmsi, VTY_NEWLINE);
971 }
972 if (vsub->tmsi_new != GSM_RESERVED_TMSI) {
973 MSC_VTY_DUMP(vty, offset, "New TMSI: %08X%s",
974 vsub->tmsi_new, VTY_NEWLINE);
975 }
976 if (vsub->imei[0] != '\0') {
977 MSC_VTY_DUMP(vty, offset, "IMEI: %s%s",
978 vsub->imei, VTY_NEWLINE);
979 }
980 if (vsub->imeisv[0] != '\0') {
981 MSC_VTY_DUMP(vty, offset, "IMEISV: %s%s",
982 vsub->imeisv, VTY_NEWLINE);
983 }
984
985 MSC_VTY_DUMP(vty, offset, "Flags: %s", VTY_NEWLINE);
986 MSC_VTY_DUMP_FLAG(vty, offset, "IMSI detached",
987 vsub->imsi_detached_flag);
988 MSC_VTY_DUMP_FLAG(vty, offset, "Conf. by radio contact",
989 vsub->conf_by_radio_contact_ind);
990 MSC_VTY_DUMP_FLAG(vty, offset, "Subscr. data conf. by HLR",
991 vsub->sub_dataconf_by_hlr_ind);
992 MSC_VTY_DUMP_FLAG(vty, offset, "Location conf. in HLR",
993 vsub->loc_conf_in_hlr_ind);
994 MSC_VTY_DUMP_FLAG(vty, offset, "Subscriber dormant",
995 vsub->dormant_ind);
996 MSC_VTY_DUMP_FLAG(vty, offset, "Received cancel location",
997 vsub->cancel_loc_rx);
998 MSC_VTY_DUMP_FLAG(vty, offset, "MS not reachable",
999 vsub->ms_not_reachable_flag);
1000 MSC_VTY_DUMP_FLAG(vty, offset, "LA allowed",
1001 vsub->la_allowed);
1002
1003 if (vsub->last_tuple) {
1004 struct vlr_auth_tuple *t = vsub->last_tuple;
1005 MSC_VTY_DUMP(vty, offset, "A3A8 last tuple (used %d times): %s",
1006 t->use_count, VTY_NEWLINE);
1007 MSC_VTY_DUMP(vty, offset + 2, "seq # : %d%s",
1008 t->key_seq, VTY_NEWLINE);
1009 MSC_VTY_DUMP(vty, offset + 2, "RAND : %s%s",
1010 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
1011 VTY_NEWLINE);
1012 MSC_VTY_DUMP(vty, offset + 2, "SRES : %s%s",
1013 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
1014 VTY_NEWLINE);
1015 MSC_VTY_DUMP(vty, offset + 2, "Kc : %s%s",
1016 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
1017 VTY_NEWLINE);
1018 }
1019
Vadim Yanitskiyfc2b0192020-01-18 07:20:14 +07001020 if (!vlr_timer(vsub->vlr, 3212)) {
Vadim Yanitskiy09ce3dc2019-07-09 00:34:29 +07001021 MSC_VTY_DUMP(vty, offset, "Expires: never (T3212 is disabled)%s",
1022 VTY_NEWLINE);
1023 } else if (vsub->expire_lu == VLR_SUBSCRIBER_NO_EXPIRATION) {
1024 MSC_VTY_DUMP(vty, offset, "Expires: never%s",
1025 VTY_NEWLINE);
1026 } else if (osmo_clock_gettime(CLOCK_MONOTONIC, &now) == 0) {
1027 MSC_VTY_DUMP(vty, offset, "Expires: in %ld min %ld sec%s",
1028 (vsub->expire_lu - now.tv_sec) / 60,
1029 (vsub->expire_lu - now.tv_sec) % 60,
1030 VTY_NEWLINE);
1031 }
1032
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001033 MSC_VTY_DUMP(vty, offset, "Paging: %s paging for %d requests%s",
1034 vsub->cs.is_paging ? "is" : "not",
1035 llist_count(&vsub->cs.requests),
1036 VTY_NEWLINE);
1037
1038 /* SGs related */
1039 MSC_VTY_DUMP(vty, offset, "SGs-state: %s%s",
1040 osmo_fsm_inst_state_name(vsub->sgs_fsm),
1041 VTY_NEWLINE);
1042 MSC_VTY_DUMP(vty, offset, "SGs-MME: %s%s",
Vadim Yanitskiydcf28682019-05-29 22:34:13 +07001043 vsub->sgs.mme_name[0] != '\0' ? vsub->sgs.mme_name : "(none)",
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001044 VTY_NEWLINE);
1045
1046 MSC_VTY_DUMP(vty, offset, "Use count total: %d%s",
1047 osmo_use_count_total(&vsub->use_count),
1048 VTY_NEWLINE);
1049 MSC_VTY_DUMP(vty, offset, "Use count: %s%s",
1050 osmo_use_count_name_buf(buf, sizeof(buf), &vsub->use_count),
1051 VTY_NEWLINE);
1052
1053 /* Connection(s) and/or transactions of this subscriber */
1054 if (dump_flags & MSC_VTY_DUMP_F_CONNECTION) {
1055 struct msub *msub = msub_for_vsub(vsub);
1056 if (!msub)
1057 return;
1058
1059 /* Subscriber info is already printed */
1060 dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
1061
1062 MSC_VTY_DUMP(vty, offset, "Connection: %s", VTY_NEWLINE);
1063 vty_dump_one_conn(vty, msub, offset + 2, dump_flags);
1064 } else if (dump_flags & MSC_VTY_DUMP_F_TRANSACTION) {
1065 struct gsm_trans *trans;
1066 unsigned int i = 0;
1067
1068 /* Subscriber info is already printed */
1069 dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
1070 /* Do not print connection info, but mention it */
1071 dump_flags |= MSC_VTY_DUMP_F_CONNECTION;
1072
1073 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
1074 if (trans->vsub != vsub)
1075 continue;
1076 MSC_VTY_DUMP(vty, offset, "Transaction #%02u: %s",
1077 i++, VTY_NEWLINE);
1078 vty_dump_one_trans(vty, trans, offset + 2, dump_flags);
1079 }
1080 }
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001081}
1082
1083DEFUN(show_msc_transaction, show_msc_transaction_cmd,
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001084 "show transaction",
1085 SHOW_STR "Transactions\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001086{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001087 struct gsm_trans *trans;
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001088 uint8_t flags = 0x00;
1089 unsigned int i = 0;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001090
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001091 flags |= MSC_VTY_DUMP_F_CONNECTION;
1092 flags |= MSC_VTY_DUMP_F_SUBSCR;
1093
1094 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
1095 vty_out(vty, " Transaction #%02u: %s", i++, VTY_NEWLINE);
1096 vty_dump_one_trans(vty, trans, 4, flags);
1097 }
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001098
1099 return CMD_SUCCESS;
1100}
1101
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001102DEFUN(show_msc_conn, show_msc_conn_cmd,
1103 "show connection [trans]",
1104 SHOW_STR "Subscriber Connections\n"
1105 "Show child transactions of each connection\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001106{
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001107 uint8_t flags = 0x00;
1108 unsigned int i = 0;
1109 struct msub *msub;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001110
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001111 if (argc > 0)
1112 flags |= MSC_VTY_DUMP_F_TRANSACTION;
1113 flags |= MSC_VTY_DUMP_F_SUBSCR;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001114
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001115 llist_for_each_entry(msub, &msub_list, entry) {
1116 vty_out(vty, " Connection #%02u: %s", i++, VTY_NEWLINE);
1117 vty_dump_one_conn(vty, msub, 4, flags);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001118 }
1119
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001120 return CMD_SUCCESS;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001121}
1122
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001123#define SUBSCR_FLAGS "[(conn|trans|conn+trans)]"
1124#define SUBSCR_FLAGS_HELP \
1125 "Show child connections\n" \
1126 "Show child transactions\n" \
1127 "Show child connections and transactions\n"
1128
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001129/* Subscriber */
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001130DEFUN(show_subscr_cache, show_subscr_cache_cmd,
1131 "show subscriber cache " SUBSCR_FLAGS,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001132 SHOW_STR "Show information about subscribers\n"
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001133 "Display contents of subscriber cache\n"
1134 SUBSCR_FLAGS_HELP)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001135{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001136 struct vlr_subscr *vsub;
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001137 unsigned int count = 0;
1138 uint8_t flags = 0x00;
1139 unsigned int i = 0;
1140
1141 if (argc && strcmp(argv[0], "conn") == 0)
1142 flags |= MSC_VTY_DUMP_F_CONNECTION;
1143 else if (argc && strcmp(argv[0], "trans") == 0)
1144 flags |= MSC_VTY_DUMP_F_TRANSACTION;
1145 else if (argc && strcmp(argv[0], "conn+trans") == 0)
1146 flags |= MSC_VTY_DUMP_F_CONNECTION | MSC_VTY_DUMP_F_TRANSACTION;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001147
1148 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
1149 if (++count > 100) {
1150 vty_out(vty, "%% More than %d subscribers in cache,"
1151 " stopping here.%s", count-1, VTY_NEWLINE);
1152 break;
1153 }
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001154 vty_out(vty, " Subscriber #%02u: %s", i++, VTY_NEWLINE);
1155 vty_dump_one_subscr(vty, vsub, 4, flags);
Harald Welte69c54a82018-02-09 20:41:14 +01001156 }
1157
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001158 return CMD_SUCCESS;
1159}
1160
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001161DEFUN(sms_send_pend,
1162 sms_send_pend_cmd,
1163 "sms send pending",
1164 "SMS related commands\n" "SMS Sending related commands\n"
1165 "Send all pending SMS")
1166{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001167 struct gsm_sms *sms;
1168 unsigned long long sms_id = 0;
1169
1170 while (1) {
1171 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
1172 if (!sms)
1173 break;
1174
1175 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +07001176 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001177
1178 sms_id = sms->id + 1;
1179 }
1180
1181 return CMD_SUCCESS;
1182}
1183
1184DEFUN(sms_delete_expired,
1185 sms_delete_expired_cmd,
1186 "sms delete expired",
1187 "SMS related commands\n" "SMS Database related commands\n"
1188 "Delete all expired SMS")
1189{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001190 struct gsm_sms *sms;
1191 unsigned long long sms_id = 0;
1192 long long num_deleted = 0;
1193
1194 while (1) {
1195 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
1196 if (!sms)
1197 break;
1198
1199 /* Skip SMS which are currently queued for sending. */
1200 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
1201 continue;
1202
1203 /* Expiration check is performed by the DB layer. */
1204 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
1205 num_deleted++;
1206
1207 sms_id = sms->id + 1;
1208 }
1209
1210 if (num_deleted == 0) {
1211 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
1212 return CMD_WARNING;
1213 }
1214
1215 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
1216 return CMD_SUCCESS;
1217}
1218
1219static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +02001220 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001221 char *str, uint8_t tp_pid)
1222{
1223 struct gsm_network *net = receiver->vlr->user_ctx;
1224 struct gsm_sms *sms;
1225
Harald Welte39b55482018-04-09 19:19:33 +02001226 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Vadim Yanitskiydb4839c2019-12-01 18:52:58 +07001227 if (!sms) {
1228 LOGP(DLSMS, LOGL_ERROR, "Failed to allocate SMS\n");
1229 return CMD_WARNING;
1230 }
1231
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001232 sms->protocol_id = tp_pid;
1233
1234 /* store in database for the queue */
1235 if (db_sms_store(sms) != 0) {
1236 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
1237 sms_free(sms);
1238 return CMD_WARNING;
1239 }
1240 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
1241
1242 sms_free(sms);
1243 sms_queue_trigger(net->sms_queue);
1244 return CMD_SUCCESS;
1245}
1246
1247static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
1248 const char *type,
1249 const char *id)
1250{
1251 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001252 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001253 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001254 return vlr_subscr_find_by_imsi(gsmnet->vlr, id, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001255 else if (!strcmp(type, "tmsi"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001256 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id), VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001257
1258 return NULL;
1259}
1260#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
1261#define SUBSCR_HELP "Operations on a Subscriber\n" \
1262 "Identify subscriber by MSISDN (phone number)\n" \
1263 "Legacy alias for 'msisdn'\n" \
1264 "Identify subscriber by IMSI\n" \
1265 "Identify subscriber by TMSI\n" \
Vadim Yanitskiy3ccd8232019-05-16 01:35:23 +07001266 "Legacy alias for 'imsi'\n" \
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001267 "Identifier for the subscriber\n"
1268
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001269DEFUN(show_subscr, show_subscr_cmd,
1270 "show subscriber " SUBSCR_TYPES " ID " SUBSCR_FLAGS,
1271 SHOW_STR SUBSCR_HELP SUBSCR_FLAGS_HELP)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001272{
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001273 struct vlr_subscr *vsub;
1274 uint8_t flags = 0x00;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001275
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001276 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001277 if (!vsub) {
1278 vty_out(vty, "%% No subscriber found for %s %s%s",
1279 argv[0], argv[1], VTY_NEWLINE);
1280 return CMD_WARNING;
1281 }
1282
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +01001283 /* In the vty output to the user, exclude this local use count added by vlr_subscr_get() in get_vsub_by_argv().
1284 * This works, because: for get_vsub_by_argv() to succeed, there *must* have been at least one use count before
1285 * this, and since this is not multi-threaded, this vlr_subscr_put() cannot possibly reach a count of 0. */
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001286 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001287
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001288 if (argc > 2 && strcmp(argv[2], "conn") == 0)
1289 flags |= MSC_VTY_DUMP_F_CONNECTION;
1290 else if (argc > 2 && strcmp(argv[2], "trans") == 0)
1291 flags |= MSC_VTY_DUMP_F_TRANSACTION;
1292 else if (argc > 2 && strcmp(argv[2], "conn+trans") == 0)
1293 flags |= MSC_VTY_DUMP_F_CONNECTION | MSC_VTY_DUMP_F_TRANSACTION;
1294
1295 vty_out(vty, " Subscriber: %s", VTY_NEWLINE);
1296 vty_dump_one_subscr(vty, vsub, 4, flags);
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +01001297
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001298 return CMD_SUCCESS;
1299}
1300
Vadim Yanitskiyb7ddbf32020-01-20 21:30:09 +07001301DEFUN_DEPRECATED(subscriber_create, subscriber_create_cmd,
1302 "subscriber create imsi ID",
1303 "Operations on a Subscriber\n"
1304 "Create new subscriber\n"
1305 "Identify the subscriber by his IMSI\n"
1306 "Identifier for the subscriber\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001307{
1308 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
1309 VTY_NEWLINE);
1310 return CMD_WARNING;
1311}
1312
1313DEFUN(subscriber_send_pending_sms,
1314 subscriber_send_pending_sms_cmd,
1315 "subscriber " SUBSCR_TYPES " ID sms pending-send",
1316 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
1317{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001318 struct vlr_subscr *vsub;
1319 struct gsm_sms *sms;
1320
1321 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1322 if (!vsub) {
1323 vty_out(vty, "%% No subscriber found for %s %s%s",
1324 argv[0], argv[1], VTY_NEWLINE);
1325 return CMD_WARNING;
1326 }
1327
1328 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
1329 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +07001330 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001331
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001332 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001333
1334 return CMD_SUCCESS;
1335}
1336
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001337DEFUN(subscriber_sms_delete_all,
1338 subscriber_sms_delete_all_cmd,
1339 "subscriber " SUBSCR_TYPES " ID sms delete-all",
1340 SUBSCR_HELP "SMS Operations\n"
1341 "Delete all SMS to be delivered to this subscriber"
1342 " -- WARNING: the SMS data for all unsent SMS for this subscriber"
1343 " WILL BE LOST.\n")
1344{
1345 struct vlr_subscr *vsub;
1346
1347 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1348 if (!vsub) {
1349 vty_out(vty, "%% No subscriber found for %s %s%s",
1350 argv[0], argv[1], VTY_NEWLINE);
1351 return CMD_WARNING;
1352 }
1353
1354 db_sms_delete_by_msisdn(vsub->msisdn);
1355
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001356 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001357
1358 return CMD_SUCCESS;
1359}
1360
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001361DEFUN(subscriber_send_sms,
1362 subscriber_send_sms_cmd,
1363 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
1364 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
1365{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001366 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +02001367 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001368 char *str;
1369 int rc;
1370
1371 if (!vsub) {
1372 vty_out(vty, "%% No subscriber found for %s %s%s",
1373 argv[0], argv[1], VTY_NEWLINE);
1374 rc = CMD_WARNING;
1375 goto err;
1376 }
1377
Harald Welte39b55482018-04-09 19:19:33 +02001378 if (!strcmp(argv[2], "msisdn"))
1379 sender_msisdn = argv[3];
1380 else {
1381 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1382 if (!sender) {
1383 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1384 rc = CMD_WARNING;
1385 goto err;
1386 }
1387 sender_msisdn = sender->msisdn;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001388 vlr_subscr_put(sender, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001389 }
1390
1391 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001392 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001393 talloc_free(str);
1394
1395err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001396 if (vsub)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001397 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001398
1399 return rc;
1400}
1401
1402DEFUN(subscriber_silent_sms,
1403 subscriber_silent_sms_cmd,
1404
1405 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
1406 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
1407{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001408 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +02001409 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001410 char *str;
1411 int rc;
1412
1413 if (!vsub) {
1414 vty_out(vty, "%% No subscriber found for %s %s%s",
1415 argv[0], argv[1], VTY_NEWLINE);
1416 rc = CMD_WARNING;
1417 goto err;
1418 }
1419
Harald Welte39b55482018-04-09 19:19:33 +02001420 if (!strcmp(argv[2], "msisdn")) {
1421 sender_msisdn = argv[3];
1422 } else {
1423 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1424 if (!sender) {
1425 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1426 rc = CMD_WARNING;
1427 goto err;
1428 }
1429 sender_msisdn = sender->msisdn;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001430 vlr_subscr_put(sender, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001431 }
1432
1433 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001434 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001435 talloc_free(str);
1436
1437err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001438 if (vsub)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001439 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001440
1441 return rc;
1442}
1443
Sylvain Munaut93558302019-02-14 20:13:08 +01001444#define CHAN_TYPES "(any|tch/f|tch/h|tch/any|sdcch)"
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001445#define CHAN_TYPE_HELP \
1446 "Any channel\n" \
1447 "TCH/F channel\n" \
Sylvain Munaut93558302019-02-14 20:13:08 +01001448 "TCH/H channel\n" \
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001449 "Any TCH channel\n" \
1450 "SDCCH channel\n"
1451
Sylvain Munaut93558302019-02-14 20:13:08 +01001452#define CHAN_MODES "(signalling|speech-hr|speech-fr|speech-efr|speech-amr)"
1453#define CHAN_MODE_HELP \
1454 "Signalling only\n" \
1455 "Speech with HR codec\n" \
1456 "Speech with FR codec\n" \
1457 "Speech with EFR codec\n" \
1458 "Speech with AMR codec\n"
1459
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001460DEFUN(subscriber_silent_call_start,
1461 subscriber_silent_call_start_cmd,
Sylvain Munaut93558302019-02-14 20:13:08 +01001462 "subscriber " SUBSCR_TYPES " ID silent-call start " CHAN_TYPES " " CHAN_MODES " [IP] [<0-65535>]",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001463 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
Sylvain Munaut93558302019-02-14 20:13:08 +01001464 CHAN_TYPE_HELP CHAN_MODE_HELP
1465 "Target IP for RTP traffic (default 127.0.0.1)\n"
1466 "Target port for RTP traffic (default: 4000)\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001467{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001468 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Sylvain Munaut93558302019-02-14 20:13:08 +01001469 struct gsm0808_channel_type ct;
1470 const char *ip;
1471 uint16_t port;
1472 int rc, speech;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001473
1474 if (!vsub) {
1475 vty_out(vty, "%% No subscriber found for %s %s%s",
1476 argv[0], argv[1], VTY_NEWLINE);
1477 return CMD_WARNING;
1478 }
1479
Sylvain Munaut93558302019-02-14 20:13:08 +01001480 memset(&ct, 0x00, sizeof(ct));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001481
Sylvain Munaut93558302019-02-14 20:13:08 +01001482 if (!strcmp(argv[3], "signalling")) {
1483 ct.ch_indctr = GSM0808_CHAN_SIGN;
1484 ct.perm_spch[0] = 0; /* Spare but required */
1485 ct.perm_spch_len = 1;
1486 } else if (!strcmp(argv[3], "speech-hr")) {
1487 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1488 ct.perm_spch[0] = GSM0808_PERM_HR1;
1489 ct.perm_spch_len = 1;
1490 } else if (!strcmp(argv[3], "speech-fr")) {
1491 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1492 ct.perm_spch[0] = GSM0808_PERM_FR1;
1493 ct.perm_spch_len = 1;
1494 } else if (!strcmp(argv[3], "speech-efr")) {
1495 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1496 ct.perm_spch[0] = GSM0808_PERM_FR2;
1497 ct.perm_spch_len = 1;
1498 } else if (!strcmp(argv[3], "speech-amr")) {
1499 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1500 ct.perm_spch[0] = GSM0808_PERM_FR3;
1501 ct.perm_spch[1] = GSM0808_PERM_HR3;
1502 ct.perm_spch_len = 2;
1503 }
1504
1505 speech = ct.ch_indctr == GSM0808_CHAN_SPEECH;
1506
1507 if (!strcmp(argv[2], "tch/f"))
1508 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_BM : GSM0808_SIGN_FULL_BM;
1509 else if (!strcmp(argv[2], "tch/h"))
1510 ct.ch_rate_type = speech ? GSM0808_SPEECH_HALF_LM : GSM0808_SIGN_HALF_LM;
1511 else if (!strcmp(argv[2], "tch/any"))
1512 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_FULL_PREF;
1513 else if (!strcmp(argv[2], "sdcch")) {
1514 if (speech) {
1515 vty_out(vty, "Can't request speech on SDCCH%s", VTY_NEWLINE);
1516 return CMD_WARNING;
1517 }
1518 ct.ch_rate_type = GSM0808_SIGN_SDCCH;
1519 } else
1520 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_ANY;
1521
1522 ip = argc >= 5 ? argv[4] : "127.0.0.1";
1523 port = argc >= 6 ? atoi(argv[5]) : 4000;
1524
1525 rc = gsm_silent_call_start(vsub, &ct, ip, port, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001526 switch (rc) {
1527 case -ENODEV:
1528 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
1529 break;
1530 default:
1531 if (rc)
1532 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
1533 else
1534 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
1535 break;
1536 }
1537
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001538 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001539 return rc ? CMD_WARNING : CMD_SUCCESS;
1540}
1541
1542DEFUN(subscriber_silent_call_stop,
1543 subscriber_silent_call_stop_cmd,
1544 "subscriber " SUBSCR_TYPES " ID silent-call stop",
1545 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
1546 CHAN_TYPE_HELP)
1547{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001548 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1549 int rc;
1550
1551 if (!vsub) {
1552 vty_out(vty, "%% No subscriber found for %s %s%s",
1553 argv[0], argv[1], VTY_NEWLINE);
1554 return CMD_WARNING;
1555 }
1556
1557 rc = gsm_silent_call_stop(vsub);
1558 switch (rc) {
1559 case -ENODEV:
1560 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
1561 break;
1562 case -ENOENT:
1563 vty_out(vty, "%% Subscriber has no silent call active%s",
1564 VTY_NEWLINE);
1565 break;
1566 default:
1567 if (rc)
1568 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
1569 else
1570 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
1571 break;
1572 }
1573
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001574 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001575 return rc ? CMD_WARNING : CMD_SUCCESS;
1576}
1577
1578DEFUN(subscriber_ussd_notify,
1579 subscriber_ussd_notify_cmd,
1580 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1581 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1582 "Alerting Level 0\n"
1583 "Alerting Level 1\n"
1584 "Alerting Level 2\n"
1585 "Text of USSD message to send\n")
1586{
1587 char *text;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001588 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001589 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1590 int level;
1591
1592 if (!vsub) {
1593 vty_out(vty, "%% No subscriber found for %s %s%s",
1594 argv[0], argv[1], VTY_NEWLINE);
1595 return CMD_WARNING;
1596 }
1597
1598 level = atoi(argv[2]);
1599 text = argv_concat(argv, argc, 3);
1600 if (!text) {
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001601 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001602 return CMD_WARNING;
1603 }
1604
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001605 msc_a = msc_a_for_vsub(vsub, true);
1606 if (!msc_a || msc_a->c.remote_to) {
1607 vty_out(vty, "%% An active connection and local MSC-A role is required for %s %s%s",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001608 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001609 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001610 talloc_free(text);
1611 return CMD_WARNING;
1612 }
1613
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001614 msc_send_ussd_notify(msc_a, level, text);
Vadim Yanitskiyf20c6b72018-11-29 01:20:58 +07001615 /* FIXME: since we don't allocate a transaction here,
1616 * we use dummy GSM 04.07 transaction ID. */
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001617 msc_send_ussd_release_complete(msc_a, 0x00);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001618
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001619 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001620 talloc_free(text);
1621 return CMD_SUCCESS;
1622}
1623
1624DEFUN(subscriber_paging,
1625 subscriber_paging_cmd,
1626 "subscriber " SUBSCR_TYPES " ID paging",
1627 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1628{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001629 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001630 struct paging_request *req;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001631
1632 if (!vsub) {
1633 vty_out(vty, "%% No subscriber found for %s %s%s",
1634 argv[0], argv[1], VTY_NEWLINE);
1635 return CMD_WARNING;
1636 }
1637
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001638 req = paging_request_start(vsub, PAGING_CAUSE_CALL_CONVERSATIONAL,
1639 NULL, NULL, "manual Paging from VTY");
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001640 if (req)
1641 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1642 else
1643 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1644
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001645 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001646 return req ? CMD_SUCCESS : CMD_WARNING;
1647}
1648
1649static int loop_by_char(uint8_t ch)
1650{
1651 switch (ch) {
1652 case 'a':
1653 return GSM414_LOOP_A;
1654 case 'b':
1655 return GSM414_LOOP_B;
1656 case 'c':
1657 return GSM414_LOOP_C;
1658 case 'd':
1659 return GSM414_LOOP_D;
1660 case 'e':
1661 return GSM414_LOOP_E;
1662 case 'f':
1663 return GSM414_LOOP_F;
1664 case 'i':
1665 return GSM414_LOOP_I;
1666 }
1667 return -1;
1668}
1669
1670DEFUN(subscriber_mstest_close,
1671 subscriber_mstest_close_cmd,
1672 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1673 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1674 "Close a TCH Loop inside the MS\n"
1675 "Loop Type A\n"
1676 "Loop Type B\n"
1677 "Loop Type C\n"
1678 "Loop Type D\n"
1679 "Loop Type E\n"
1680 "Loop Type F\n"
1681 "Loop Type I\n")
1682{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001683 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001684 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1685 const char *loop_str;
1686 int loop_mode;
1687
1688 if (!vsub) {
1689 vty_out(vty, "%% No subscriber found for %s %s%s",
1690 argv[0], argv[1], VTY_NEWLINE);
1691 return CMD_WARNING;
1692 }
1693
1694 loop_str = argv[2];
1695 loop_mode = loop_by_char(loop_str[0]);
1696
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001697 msc_a = msc_a_for_vsub(vsub, true);
1698 if (!msc_a) {
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001699 vty_out(vty, "%% An active connection is required for %s %s%s",
1700 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001701 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001702 return CMD_WARNING;
1703 }
1704
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001705 gsm0414_tx_close_tch_loop_cmd(msc_a, loop_mode);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001706
1707 return CMD_SUCCESS;
1708}
1709
1710DEFUN(subscriber_mstest_open,
1711 subscriber_mstest_open_cmd,
1712 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1713 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1714 "Open a TCH Loop inside the MS\n")
1715{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001716 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001717 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1718
1719 if (!vsub) {
1720 vty_out(vty, "%% No subscriber found for %s %s%s",
1721 argv[0], argv[1], VTY_NEWLINE);
1722 return CMD_WARNING;
1723 }
1724
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001725 msc_a = msc_a_for_vsub(vsub, true);
1726 if (!msc_a) {
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001727 vty_out(vty, "%% An active connection is required for %s %s%s",
1728 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001729 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001730 return CMD_WARNING;
1731 }
1732
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001733 gsm0414_tx_open_loop_cmd(msc_a);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001734
1735 return CMD_SUCCESS;
1736}
1737
1738DEFUN(ena_subscr_expire,
1739 ena_subscr_expire_cmd,
1740 "subscriber " SUBSCR_TYPES " ID expire",
1741 SUBSCR_HELP "Expire the subscriber Now\n")
1742{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001743 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1744 argv[1]);
1745
1746 if (!vsub) {
1747 vty_out(vty, "%% No subscriber found for %s %s%s",
1748 argv[0], argv[1], VTY_NEWLINE);
1749 return CMD_WARNING;
1750 }
1751
1752 if (vlr_subscr_expire(vsub))
1753 vty_out(vty, "%% VLR released subscriber %s%s",
1754 vlr_subscr_name(vsub), VTY_NEWLINE);
1755
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001756 if (osmo_use_count_total(&vsub->use_count) > 1)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001757 vty_out(vty, "%% Subscriber %s is still in use,"
1758 " should be released soon%s",
1759 vlr_subscr_name(vsub), VTY_NEWLINE);
1760
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001761 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001762 return CMD_SUCCESS;
1763}
1764
1765static int scall_cbfn(unsigned int subsys, unsigned int signal,
1766 void *handler_data, void *signal_data)
1767{
1768 struct scall_signal_data *sigdata = signal_data;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001769 struct vty *vty = sigdata->vty;
1770
1771 if (!vty_is_active(vty))
1772 return 0;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001773
1774 switch (signal) {
1775 case S_SCALL_SUCCESS:
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001776 vty_out(vty, "%% Silent call success%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001777 break;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001778 case S_SCALL_FAILED:
1779 vty_out(vty, "%% Silent call failed%s", VTY_NEWLINE);
1780 break;
1781 case S_SCALL_DETACHED:
1782 vty_out(vty, "%% Silent call ended%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001783 break;
1784 }
1785 return 0;
1786}
1787
1788DEFUN(show_stats,
1789 show_stats_cmd,
1790 "show statistics",
1791 SHOW_STR "Display network statistics\n")
1792{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001793 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001794 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1795 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1796 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001797 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001798 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001799 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001800 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001801 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001802 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1803 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001804 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001805 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001806 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1807 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001808 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001809 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001810 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1811 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1812 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001813 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001814 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001815 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1816 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001817 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001818 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001819 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1820 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001821 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001822 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001823 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1824 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1825 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1826 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1827 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001828 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001829 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1830 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1831 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1832 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1833 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001834 return CMD_SUCCESS;
1835}
1836
1837DEFUN(show_smsqueue,
1838 show_smsqueue_cmd,
1839 "show sms-queue",
1840 SHOW_STR "Display SMSqueue statistics\n")
1841{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001842 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001843 return CMD_SUCCESS;
1844}
1845
1846DEFUN(smsqueue_trigger,
1847 smsqueue_trigger_cmd,
1848 "sms-queue trigger",
1849 "SMS Queue\n" "Trigger sending messages\n")
1850{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001851 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001852 return CMD_SUCCESS;
1853}
1854
1855DEFUN(smsqueue_max,
1856 smsqueue_max_cmd,
1857 "sms-queue max-pending <1-500>",
1858 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1859{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001860 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001861 return CMD_SUCCESS;
1862}
1863
1864DEFUN(smsqueue_clear,
1865 smsqueue_clear_cmd,
1866 "sms-queue clear",
1867 "SMS Queue\n" "Clear the queue of pending SMS\n")
1868{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001869 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001870 return CMD_SUCCESS;
1871}
1872
1873DEFUN(smsqueue_fail,
1874 smsqueue_fail_cmd,
1875 "sms-queue max-failure <1-500>",
1876 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1877{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001878 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001879 return CMD_SUCCESS;
1880}
1881
1882
1883DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1884 "mncc-int", "Configure internal MNCC handler")
1885{
1886 vty->node = MNCC_INT_NODE;
1887
1888 return CMD_SUCCESS;
1889}
1890
1891static struct cmd_node mncc_int_node = {
1892 MNCC_INT_NODE,
1893 "%s(config-mncc-int)# ",
1894 1,
1895};
1896
1897static const struct value_string tchf_codec_names[] = {
1898 { GSM48_CMODE_SPEECH_V1, "fr" },
1899 { GSM48_CMODE_SPEECH_EFR, "efr" },
1900 { GSM48_CMODE_SPEECH_AMR, "amr" },
1901 { 0, NULL }
1902};
1903
1904static const struct value_string tchh_codec_names[] = {
1905 { GSM48_CMODE_SPEECH_V1, "hr" },
1906 { GSM48_CMODE_SPEECH_AMR, "amr" },
1907 { 0, NULL }
1908};
1909
1910static int config_write_mncc_int(struct vty *vty)
1911{
1912 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1913 vty_out(vty, " default-codec tch-f %s%s",
1914 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1915 VTY_NEWLINE);
1916 vty_out(vty, " default-codec tch-h %s%s",
1917 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1918 VTY_NEWLINE);
1919
1920 return CMD_SUCCESS;
1921}
1922
1923DEFUN(mnccint_def_codec_f,
1924 mnccint_def_codec_f_cmd,
1925 "default-codec tch-f (fr|efr|amr)",
1926 "Set default codec\n" "Codec for TCH/F\n"
1927 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1928{
1929 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1930
1931 return CMD_SUCCESS;
1932}
1933
1934DEFUN(mnccint_def_codec_h,
1935 mnccint_def_codec_h_cmd,
1936 "default-codec tch-h (hr|amr)",
1937 "Set default codec\n" "Codec for TCH/H\n"
1938 "Half-Rate\n" "Adaptive Multi-Rate\n")
1939{
1940 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1941
1942 return CMD_SUCCESS;
1943}
1944
1945
1946DEFUN(logging_fltr_imsi,
1947 logging_fltr_imsi_cmd,
1948 "logging filter imsi IMSI",
1949 LOGGING_STR FILTER_STR
1950 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1951{
1952 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001953 struct log_target *tgt = osmo_log_vty2tgt(vty);
1954 const char *imsi = argv[0];
1955
1956 if (!tgt)
1957 return CMD_WARNING;
1958
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001959 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001960
1961 if (!vlr_subscr) {
1962 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1963 argv[0], VTY_NEWLINE);
1964 return CMD_WARNING;
1965 }
1966
1967 log_set_filter_vlr_subscr(tgt, vlr_subscr);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001968 vlr_subscr_put(vlr_subscr, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001969 return CMD_SUCCESS;
1970}
1971
1972static struct cmd_node hlr_node = {
1973 HLR_NODE,
1974 "%s(config-hlr)# ",
1975 1,
1976};
1977
1978DEFUN(cfg_hlr, cfg_hlr_cmd,
1979 "hlr", "Configure connection to the HLR")
1980{
1981 vty->node = HLR_NODE;
1982 return CMD_SUCCESS;
1983}
1984
1985DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1986 "Remote GSUP address of the HLR\n"
1987 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1988{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001989 talloc_free((void*)gsmnet->gsup_server_addr_str);
1990 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1991 return CMD_SUCCESS;
1992}
1993
1994DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1995 "Remote GSUP port of the HLR\n"
1996 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1997{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001998 gsmnet->gsup_server_port = atoi(argv[0]);
1999 return CMD_SUCCESS;
2000}
2001
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01002002DEFUN(cfg_hlr_ipa_name,
2003 cfg_hlr_ipa_name_cmd,
2004 "ipa-name NAME",
2005 "Set the IPA name of this MSC\n"
2006 "A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. "
2007 "This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. "
2008 "The default is 'MSC-00-00-00-00-00-00'.\n")
2009{
2010 if (vty->type != VTY_FILE) {
2011 vty_out(vty, "The IPA name cannot be changed at run-time; "
Martin Hauke3f07dac2019-11-14 17:49:08 +01002012 "It can only be set in the configuration file.%s", VTY_NEWLINE);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01002013 return CMD_WARNING;
2014 }
2015
2016 gsmnet->msc_ipa_name = talloc_strdup(gsmnet, argv[0]);
2017 return CMD_SUCCESS;
2018}
2019
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002020static int config_write_hlr(struct vty *vty)
2021{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002022 vty_out(vty, "hlr%s", VTY_NEWLINE);
2023 vty_out(vty, " remote-ip %s%s",
2024 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
2025 vty_out(vty, " remote-port %u%s",
2026 gsmnet->gsup_server_port, VTY_NEWLINE);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01002027 if (gsmnet->msc_ipa_name)
2028 vty_out(vty, " ipa-name %s%s", gsmnet->msc_ipa_name, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002029 return CMD_SUCCESS;
2030}
2031
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02002032void msc_vty_init(struct gsm_network *msc_network)
2033{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01002034 OSMO_ASSERT(gsmnet == NULL);
2035 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002036
2037 osmo_stats_vty_add_cmds();
2038
2039 install_element(CONFIG_NODE, &cfg_net_cmd);
2040 install_node(&net_node, config_write_net);
2041 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
2042 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
2043 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
2044 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
2045 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
Neels Hofmeyr4dfb2ba2019-08-13 16:00:37 +02002046 install_element(GSMNET_NODE, &cfg_net_encryption_uea_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002047 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
2048 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
2049 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
2050 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
2051 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
2052 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
2053 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
2054 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Keith Whyte991bb422019-08-08 15:43:40 +02002055 install_element(GSMNET_NODE, &cfg_net_call_wait_cmd);
2056 install_element(GSMNET_NODE, &cfg_net_no_call_wait_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02002057
2058 install_element(CONFIG_NODE, &cfg_msc_cmd);
2059 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02002060 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01002061 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
2062 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02002063 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01002064 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Vadim Yanitskiy64623e12018-11-28 23:05:51 +07002065 install_element(MSC_NODE, &cfg_msc_ncss_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02002066 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01002067 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
2068 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Oliver Smith0fec28a2018-12-14 10:52:52 +01002069 install_element(MSC_NODE, &cfg_msc_check_imei_rqd_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02002070 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
2071 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01002072 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01002073 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +07002074 install_element(MSC_NODE, &cfg_msc_sms_over_gsup_cmd);
2075 install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd);
Pau Espin Pedrol4faff9e2019-05-06 19:29:11 +02002076 install_element(MSC_NODE, &cfg_msc_osmux_cmd);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01002077 install_element(MSC_NODE, &cfg_msc_handover_number_range_cmd);
Neels Hofmeyr9aac5c22020-05-27 00:04:26 +02002078 install_element(MSC_NODE, &cfg_msc_nri_bitlen_cmd);
2079 install_element(MSC_NODE, &cfg_msc_nri_add_cmd);
2080 install_element(MSC_NODE, &cfg_msc_nri_del_cmd);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01002081
2082 neighbor_ident_vty_init(msc_network);
Philipp Maierfbf66102017-04-09 12:32:51 +02002083
Vadim Yanitskiyffc7f392020-01-18 18:39:41 +07002084 /* Timer configuration commands (generic osmo_tdef API) */
2085 osmo_tdef_vty_groups_init(MSC_NODE, msc_tdef_group);
2086
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02002087 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02002088#ifdef BUILD_IU
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01002089 ranap_iu_vty_init(MSC_NODE, (enum ranap_nsap_addr_enc*)&msc_network->iu.rab_assign_addr_enc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02002090#endif
Harald Welte0df904d2018-12-03 11:00:04 +01002091 sgs_vty_init();
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01002092
Stefan Sperling617ac802018-02-22 17:58:20 +01002093 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002094
2095 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
2096
2097 install_element_ve(&show_subscr_cmd);
2098 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01002099 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002100 install_element_ve(&show_msc_conn_cmd);
2101 install_element_ve(&show_msc_transaction_cmd);
Neels Hofmeyr9aac5c22020-05-27 00:04:26 +02002102 install_element_ve(&show_nri_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002103
2104 install_element_ve(&sms_send_pend_cmd);
2105 install_element_ve(&sms_delete_expired_cmd);
2106
2107 install_element_ve(&subscriber_create_cmd);
2108 install_element_ve(&subscriber_send_sms_cmd);
2109 install_element_ve(&subscriber_silent_sms_cmd);
2110 install_element_ve(&subscriber_silent_call_start_cmd);
2111 install_element_ve(&subscriber_silent_call_stop_cmd);
2112 install_element_ve(&subscriber_ussd_notify_cmd);
2113 install_element_ve(&subscriber_mstest_close_cmd);
2114 install_element_ve(&subscriber_mstest_open_cmd);
2115 install_element_ve(&subscriber_paging_cmd);
2116 install_element_ve(&show_stats_cmd);
2117 install_element_ve(&show_smsqueue_cmd);
2118 install_element_ve(&logging_fltr_imsi_cmd);
2119
2120 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
2121 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
2122 install_element(ENABLE_NODE, &smsqueue_max_cmd);
2123 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
2124 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
2125 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01002126 install_element(ENABLE_NODE, &subscriber_sms_delete_all_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002127
2128 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
2129 install_node(&mncc_int_node, config_write_mncc_int);
2130 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
2131 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
2132
2133 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
2134
2135 install_element(CONFIG_NODE, &cfg_hlr_cmd);
2136 install_node(&hlr_node, config_write_hlr);
2137 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
2138 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01002139 install_element(HLR_NODE, &cfg_hlr_ipa_name_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02002140}