blob: 7b111b1dd309e0a8be665e0117829d6164576c7b [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>
Alexander Couzensae167fc2020-09-25 05:25:16 +020070#include <osmocom/msc/ran_infra.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010071
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010072static struct gsm_network *gsmnet = NULL;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010073
Vadim Yanitskiy9b56cd82020-01-25 06:38:44 +070074static struct cmd_node net_node = {
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010075 GSMNET_NODE,
76 "%s(config-net)# ",
77 1,
78};
79
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +010080#define VSUB_USE_VTY "VTY"
81
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010082#define NETWORK_STR "Configure the GSM network\n"
83#define CODE_CMD_STR "Code commands\n"
84#define NAME_CMD_STR "Name Commands\n"
85#define NAME_STR "Name to use\n"
86
87DEFUN(cfg_net,
88 cfg_net_cmd,
89 "network", NETWORK_STR)
90{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010091 vty->index = gsmnet;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010092 vty->node = GSMNET_NODE;
93
94 return CMD_SUCCESS;
95}
96
97DEFUN(cfg_net_ncc,
98 cfg_net_ncc_cmd,
99 "network country code <1-999>",
100 "Set the GSM network country code\n"
101 "Country commands\n"
102 CODE_CMD_STR
103 "Network Country Code to use\n")
104{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100105 gsmnet->plmn.mcc = atoi(argv[0]);
106
107 return CMD_SUCCESS;
108}
109
110DEFUN(cfg_net_mnc,
111 cfg_net_mnc_cmd,
112 "mobile network code <0-999>",
113 "Set the GSM mobile network code\n"
114 "Network Commands\n"
115 CODE_CMD_STR
116 "Mobile Network Code to use\n")
117{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100118 uint16_t mnc;
119 bool mnc_3_digits;
120
121 if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
122 vty_out(vty, "%% Error decoding MNC: %s%s", argv[0], VTY_NEWLINE);
123 return CMD_WARNING;
124 }
125
126 gsmnet->plmn.mnc = mnc;
127 gsmnet->plmn.mnc_3_digits = mnc_3_digits;
128
129 return CMD_SUCCESS;
130}
131
132DEFUN(cfg_net_name_short,
133 cfg_net_name_short_cmd,
134 "short name NAME",
135 "Set the short GSM network name\n" NAME_CMD_STR NAME_STR)
136{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100137 osmo_talloc_replace_string(gsmnet, &gsmnet->name_short, argv[0]);
138 return CMD_SUCCESS;
139}
140
141DEFUN(cfg_net_name_long,
142 cfg_net_name_long_cmd,
143 "long name NAME",
144 "Set the long GSM network name\n" NAME_CMD_STR NAME_STR)
145{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100146 osmo_talloc_replace_string(gsmnet, &gsmnet->name_long, argv[0]);
147 return CMD_SUCCESS;
148}
149
Neels Hofmeyr4dfb2ba2019-08-13 16:00:37 +0200150#define ENCRYPTION_STR "Encryption options\n"
151
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100152DEFUN(cfg_net_encryption,
153 cfg_net_encryption_cmd,
154 "encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]",
Neels Hofmeyr4dfb2ba2019-08-13 16:00:37 +0200155 ENCRYPTION_STR
156 "GSM A5 Air Interface Encryption.\n"
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100157 "A5/n Algorithm Number\n"
158 "A5/n Algorithm Number\n"
159 "A5/n Algorithm Number\n"
160 "A5/n Algorithm Number\n")
161{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100162 unsigned int i;
163
164 gsmnet->a5_encryption_mask = 0;
165 for (i = 0; i < argc; i++)
166 gsmnet->a5_encryption_mask |= (1 << atoi(argv[i]));
167
168 return CMD_SUCCESS;
169}
170
Neels Hofmeyr4dfb2ba2019-08-13 16:00:37 +0200171/* So far just a boolean switch, a future patch might add individual config for UEA1 and UEA2, see OS#4143 */
172DEFUN(cfg_net_encryption_uea,
173 cfg_net_encryption_uea_cmd,
174 "encryption uea <0-2> [<0-2>] [<0-2>]",
175 ENCRYPTION_STR
176 "UTRAN (3G) encryption algorithms to allow: 0 = UEA0 (no encryption), 1 = UEA1, 2 = UEA2."
177 " NOTE: the current implementation does not allow free choice of combining encryption algorithms yet."
178 " The only valid settings are either 'encryption uea 0' or 'encryption uea 1 2'.\n"
179 "UEAn Algorithm Number\n"
180 "UEAn Algorithm Number\n"
181 "UEAn Algorithm Number\n"
182 )
183{
184 unsigned int i;
185 uint8_t mask = 0;
186
187 for (i = 0; i < argc; i++)
188 mask |= (1 << atoi(argv[i]));
189
190 if (mask == (1 << 0)) {
191 /* UEA0. Disable encryption. */
192 gsmnet->uea_encryption = false;
193 } else if (mask == ((1 << 1) | (1 << 2))) {
194 /* UEA1 and UEA2. Enable encryption. */
195 gsmnet->uea_encryption = true;
196 } else {
197 vty_out(vty,
198 "%% Error: the current implementation does not allow free choice of combining%s"
199 "%% encryption algorithms yet. The only valid settings are either%s"
200 "%% encryption uea 0%s"
201 "%% or%s"
202 "%% encryption uea 1 2%s",
203 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
204 return CMD_WARNING;
205 }
206
207 return CMD_SUCCESS;
208}
209
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100210DEFUN(cfg_net_authentication,
211 cfg_net_authentication_cmd,
212 "authentication (optional|required)",
213 "Whether to enforce MS authentication in 2G\n"
214 "Allow MS to attach via 2G BSC without authentication\n"
215 "Always do authentication\n")
216{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100217 gsmnet->authentication_required = (argv[0][0] == 'r') ? true : false;
218
219 return CMD_SUCCESS;
220}
221
222DEFUN(cfg_net_rrlp_mode, cfg_net_rrlp_mode_cmd,
223 "rrlp mode (none|ms-based|ms-preferred|ass-preferred)",
224 "Radio Resource Location Protocol\n"
225 "Set the Radio Resource Location Protocol Mode\n"
226 "Don't send RRLP request\n"
227 "Request MS-based location\n"
228 "Request any location, prefer MS-based\n"
229 "Request any location, prefer MS-assisted\n")
230{
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700231 gsmnet->rrlp.mode = msc_rrlp_mode_parse(argv[0]);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100232
233 return CMD_SUCCESS;
234}
235
236DEFUN(cfg_net_mm_info, cfg_net_mm_info_cmd,
237 "mm info (0|1)",
238 "Mobility Management\n"
239 "Send MM INFO after LOC UPD ACCEPT\n"
240 "Disable\n" "Enable\n")
241{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100242 gsmnet->send_mm_info = atoi(argv[0]);
243
244 return CMD_SUCCESS;
245}
246
247DEFUN(cfg_net_timezone,
248 cfg_net_timezone_cmd,
249 "timezone <-19-19> (0|15|30|45)",
250 "Set the Timezone Offset of the network\n"
251 "Timezone offset (hours)\n"
252 "Timezone offset (00 minutes)\n"
253 "Timezone offset (15 minutes)\n"
254 "Timezone offset (30 minutes)\n"
255 "Timezone offset (45 minutes)\n"
256 )
257{
258 struct gsm_network *net = vty->index;
259 int tzhr = atoi(argv[0]);
260 int tzmn = atoi(argv[1]);
261
262 net->tz.hr = tzhr;
263 net->tz.mn = tzmn;
264 net->tz.dst = 0;
265 net->tz.override = 1;
266
267 return CMD_SUCCESS;
268}
269
270DEFUN(cfg_net_timezone_dst,
271 cfg_net_timezone_dst_cmd,
272 "timezone <-19-19> (0|15|30|45) <0-2>",
273 "Set the Timezone Offset of the network\n"
274 "Timezone offset (hours)\n"
275 "Timezone offset (00 minutes)\n"
276 "Timezone offset (15 minutes)\n"
277 "Timezone offset (30 minutes)\n"
278 "Timezone offset (45 minutes)\n"
279 "DST offset (hours)\n"
280 )
281{
282 struct gsm_network *net = vty->index;
283 int tzhr = atoi(argv[0]);
284 int tzmn = atoi(argv[1]);
285 int tzdst = atoi(argv[2]);
286
287 net->tz.hr = tzhr;
288 net->tz.mn = tzmn;
289 net->tz.dst = tzdst;
290 net->tz.override = 1;
291
292 return CMD_SUCCESS;
293}
294
295DEFUN(cfg_net_no_timezone,
296 cfg_net_no_timezone_cmd,
297 "no timezone",
298 NO_STR
299 "Disable network timezone override, use system tz\n")
300{
301 struct gsm_network *net = vty->index;
302
303 net->tz.override = 0;
304
305 return CMD_SUCCESS;
306}
307
Vadim Yanitskiyfc2b0192020-01-18 07:20:14 +0700308/* NOTE: actually this is subscriber expiration timeout */
309#define PER_LOC_UPD_STR "Periodic Location Updating Interval\n"
310
311DEFUN_DEPRECATED(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
312 "periodic location update <6-1530>",
313 PER_LOC_UPD_STR PER_LOC_UPD_STR PER_LOC_UPD_STR
314 "Periodic Location Updating Interval in Minutes\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100315{
Vadim Yanitskiyfc2b0192020-01-18 07:20:14 +0700316 int minutes = atoi(argv[0]);
317 int rc;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100318
Vadim Yanitskiyfc2b0192020-01-18 07:20:14 +0700319 vty_out(vty, "%% 'periodic location update' is now deprecated: "
320 "use 'timer T3212' to change subscriber expiration "
321 "timeout.%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100322
Vadim Yanitskiyfc2b0192020-01-18 07:20:14 +0700323 /* We used to double this value and add a minute when scheduling the
324 * expiration timer. Let's emulate the old behaviour here. */
325 minutes = minutes * 2 + 1;
326 vty_out(vty, "%% Setting T3212 to %d minutes "
327 "(emulating the old behaviour).%s",
328 minutes, VTY_NEWLINE);
329
330 rc = osmo_tdef_set(msc_tdefs_vlr, 3212, minutes, OSMO_TDEF_M);
331 return rc ? CMD_WARNING : CMD_SUCCESS;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100332}
333
Vadim Yanitskiyfc2b0192020-01-18 07:20:14 +0700334DEFUN_DEPRECATED(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
335 "no periodic location update",
336 NO_STR PER_LOC_UPD_STR PER_LOC_UPD_STR PER_LOC_UPD_STR)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100337{
Vadim Yanitskiyfc2b0192020-01-18 07:20:14 +0700338 int rc;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100339
Vadim Yanitskiyfc2b0192020-01-18 07:20:14 +0700340 vty_out(vty, "%% 'periodic location update' is now deprecated: "
341 "use 'timer T3212' to change subscriber expiration "
342 "timeout.%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100343
Vadim Yanitskiyfc2b0192020-01-18 07:20:14 +0700344 rc = osmo_tdef_set(msc_tdefs_vlr, 3212, 0, OSMO_TDEF_M);
345 return rc ? CMD_WARNING : CMD_SUCCESS;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100346}
347
Keith Whyte991bb422019-08-08 15:43:40 +0200348DEFUN(cfg_net_call_wait, cfg_net_call_wait_cmd,
349 "call-waiting",
350 "Enable Call Waiting on the Network\n")
351{
352 struct gsm_network *net = vty->index;
353
354 net->call_waiting = true;
355
356 return CMD_SUCCESS;
357}
358
359DEFUN(cfg_net_no_call_wait, cfg_net_no_call_wait_cmd,
360 "no call-waiting",
361 NO_STR
362 "Disable Call Waiting on the Network\n")
363{
364 struct gsm_network *net = vty->index;
365
366 net->call_waiting = false;
367
368 return CMD_SUCCESS;
369}
370
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100371static int config_write_net(struct vty *vty)
372{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100373 int i;
374
375 vty_out(vty, "network%s", VTY_NEWLINE);
376 vty_out(vty, " network country code %s%s", osmo_mcc_name(gsmnet->plmn.mcc), VTY_NEWLINE);
377 vty_out(vty, " mobile network code %s%s",
378 osmo_mnc_name(gsmnet->plmn.mnc, gsmnet->plmn.mnc_3_digits), VTY_NEWLINE);
379 vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
380 vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
381 vty_out(vty, " encryption a5");
382 for (i = 0; i < 8; i++) {
383 if (gsmnet->a5_encryption_mask & (1 << i))
384 vty_out(vty, " %u", i);
385 }
386 vty_out(vty, "%s", VTY_NEWLINE);
Neels Hofmeyr4dfb2ba2019-08-13 16:00:37 +0200387
388 if (!gsmnet->uea_encryption)
389 vty_out(vty, " encryption uea 0%s", VTY_NEWLINE);
390 else
391 vty_out(vty, " encryption uea 1 2%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100392 vty_out(vty, " authentication %s%s",
393 gsmnet->authentication_required ? "required" : "optional", VTY_NEWLINE);
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700394 vty_out(vty, " rrlp mode %s%s", msc_rrlp_mode_name(gsmnet->rrlp.mode),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100395 VTY_NEWLINE);
396 vty_out(vty, " mm info %u%s", gsmnet->send_mm_info, VTY_NEWLINE);
397 if (gsmnet->tz.override != 0) {
398 if (gsmnet->tz.dst)
399 vty_out(vty, " timezone %d %d %d%s",
400 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
401 VTY_NEWLINE);
402 else
403 vty_out(vty, " timezone %d %d%s",
404 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
405 }
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100406
Keith Whyte991bb422019-08-08 15:43:40 +0200407 if (!gsmnet->call_waiting)
408 vty_out(vty, " no call-waiting%s", VTY_NEWLINE);
409
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100410 return CMD_SUCCESS;
411}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200412
413static struct cmd_node msc_node = {
414 MSC_NODE,
415 "%s(config-msc)# ",
416 1,
417};
418
419DEFUN(cfg_msc, cfg_msc_cmd,
420 "msc", "Configure MSC options")
421{
422 vty->node = MSC_NODE;
423 return CMD_SUCCESS;
424}
425
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100426#define MNCC_STR "Configure Mobile Network Call Control\n"
427#define MNCC_GUARD_TIMEOUT_STR "Set global guard timer for mncc interface activity\n"
428#define MNCC_GUARD_TIMEOUT_VALUE_STR "guard timer value (sec.)\n"
429
Keith Whyte1587ffb2020-08-28 13:36:58 +0200430DEFUN(cfg_sms_database, cfg_sms_database_cmd,
431 "sms-database PATH",
432 "Set the path to the MSC-SMS database file\n"
433 "Relative or absolute file system path to the database file (default is '" SMS_DEFAULT_DB_FILE_PATH "')\n")
434{
435 osmo_talloc_replace_string(gsmnet, &gsmnet->sms_db_file_path, argv[0]);
436 return CMD_SUCCESS;
437}
438
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100439DEFUN(cfg_msc_mncc_internal,
440 cfg_msc_mncc_internal_cmd,
441 "mncc internal",
442 MNCC_STR "Use internal MNCC handler (default; changes need a program restart)\n")
443{
444 gsm_network_set_mncc_sock_path(gsmnet, NULL);
445 return CMD_SUCCESS;
446}
447
448DEFUN(cfg_msc_mncc_external,
449 cfg_msc_mncc_external_cmd,
450 "mncc external MNCC_SOCKET_PATH",
451 MNCC_STR "Use external MNCC handler (changes need a program restart)\n"
452 "File system path to create the MNCC unix domain socket at\n")
453{
454 gsm_network_set_mncc_sock_path(gsmnet, argv[0]);
455 return CMD_SUCCESS;
456}
457
Philipp Maier9ca7b312018-10-10 17:00:49 +0200458DEFUN(cfg_msc_mncc_guard_timeout,
459 cfg_msc_mncc_guard_timeout_cmd,
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100460 "mncc guard-timeout <0-255>",
461 MNCC_STR
462 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR)
Philipp Maier9ca7b312018-10-10 17:00:49 +0200463{
464 gsmnet->mncc_guard_timeout = atoi(argv[0]);
465 return CMD_SUCCESS;
466}
467
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100468ALIAS_DEPRECATED(cfg_msc_mncc_guard_timeout,
469 cfg_msc_deprecated_mncc_guard_timeout_cmd,
470 "mncc-guard-timeout <0-255>",
471 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR);
472
Vadim Yanitskiy64623e12018-11-28 23:05:51 +0700473#define NCSS_STR "Configure call independent Supplementary Services\n"
474
475DEFUN(cfg_msc_ncss_guard_timeout,
476 cfg_msc_ncss_guard_timeout_cmd,
477 "ncss guard-timeout <0-255>",
478 NCSS_STR "Set guard timer for session activity\n"
479 "guard timer value (sec.), or 0 to disable\n")
480{
481 gsmnet->ncss_guard_timeout = atoi(argv[0]);
482 return CMD_SUCCESS;
483}
484
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200485DEFUN(cfg_msc_assign_tmsi, cfg_msc_assign_tmsi_cmd,
486 "assign-tmsi",
487 "Assign TMSI during Location Updating.\n")
488{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200489 gsmnet->vlr->cfg.assign_tmsi = true;
490 return CMD_SUCCESS;
491}
492
493DEFUN(cfg_msc_no_assign_tmsi, cfg_msc_no_assign_tmsi_cmd,
494 "no assign-tmsi",
495 NO_STR "Assign TMSI during Location Updating.\n")
496{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200497 gsmnet->vlr->cfg.assign_tmsi = false;
498 return CMD_SUCCESS;
499}
500
Philipp Maierfbf66102017-04-09 12:32:51 +0200501DEFUN(cfg_msc_cs7_instance_a,
502 cfg_msc_cs7_instance_a_cmd,
503 "cs7-instance-a <0-15>",
504 "Set SS7 to be used by the A-Interface.\n" "SS7 instance reference number\n")
505{
Philipp Maierfbf66102017-04-09 12:32:51 +0200506 gsmnet->a.cs7_instance = atoi(argv[0]);
507 return CMD_SUCCESS;
508}
509
510DEFUN(cfg_msc_cs7_instance_iu,
511 cfg_msc_cs7_instance_iu_cmd,
512 "cs7-instance-iu <0-15>",
513 "Set SS7 to be used by the Iu-Interface.\n" "SS7 instance reference number\n")
514{
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100515#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200516 gsmnet->iu.cs7_instance = atoi(argv[0]);
517 return CMD_SUCCESS;
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100518#else
519 vty_out(vty, "WARNING: 'cs7-instance-iu' without effect: built without Iu support%s",
520 VTY_NEWLINE);
521 return CMD_WARNING;
522#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200523}
524
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100525DEFUN(cfg_msc_auth_tuple_max_reuse_count, cfg_msc_auth_tuple_max_reuse_count_cmd,
526 "auth-tuple-max-reuse-count <-1-2147483647>",
527 "Configure authentication tuple re-use\n"
528 "0 to use each auth tuple at most once (default), >0 to limit re-use, -1 to re-use infinitely (vulnerable!).\n")
529{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100530 gsmnet->vlr->cfg.auth_tuple_max_reuse_count = atoi(argv[0]);
531 return CMD_SUCCESS;
532}
533
534DEFUN(cfg_msc_auth_tuple_reuse_on_error, cfg_msc_auth_tuple_reuse_on_error_cmd,
535 "auth-tuple-reuse-on-error (0|1)",
536 "Configure authentication tuple re-use when HLR is not responsive\n"
Oliver Smithd6e24fd2019-01-09 10:46:43 +0100537 "Never re-use auth tuples beyond auth-tuple-max-reuse-count (default)\n"
538 "If the HLR does not deliver new tuples, do re-use already available old ones.\n")
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100539{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100540 gsmnet->vlr->cfg.auth_reuse_old_sets_on_error = atoi(argv[0]) ? true : false;
541 return CMD_SUCCESS;
542}
543
Oliver Smith0fec28a2018-12-14 10:52:52 +0100544DEFUN(cfg_msc_check_imei_rqd, cfg_msc_check_imei_rqd_cmd,
Oliver Smith03ded912019-05-02 10:40:50 +0200545 "check-imei-rqd (0|1|early)",
Oliver Smith0fec28a2018-12-14 10:52:52 +0100546 "Send each IMEI to the EIR to ask if it is permitted or not. The EIR is implemented as part of OsmoHLR, "
547 "and can optionally save the IMEI in the HLR.\n"
548 "Do not send IMEIs to the EIR\n"
Oliver Smith03ded912019-05-02 10:40:50 +0200549 "Send each IMEI to the EIR\n"
550 "Send each IMEI to the EIR, and do it at the start of the location update. This allows the EIR to receive the"
551 " 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 +0100552{
Oliver Smith03ded912019-05-02 10:40:50 +0200553 if (strcmp(argv[0], "0") == 0) {
554 gsmnet->vlr->cfg.check_imei_rqd = false;
555 gsmnet->vlr->cfg.retrieve_imeisv_early = false;
556 } else if (strcmp(argv[0], "1") == 0) {
557 gsmnet->vlr->cfg.check_imei_rqd = true;
558 gsmnet->vlr->cfg.retrieve_imeisv_early = false;
559 } else if (strcmp(argv[0], "early") == 0) {
560 gsmnet->vlr->cfg.check_imei_rqd = true;
561 gsmnet->vlr->cfg.retrieve_imeisv_early = true;
562 }
Oliver Smith0fec28a2018-12-14 10:52:52 +0100563 return CMD_SUCCESS;
564}
565
Alexander Couzensae167fc2020-09-25 05:25:16 +0200566DEFUN_DEPRECATED(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd,
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100567 "paging response-timer (default|<1-65535>)",
568 "Configure Paging\n"
569 "Set Paging timeout, the minimum time to pass between (unsuccessful) Pagings sent towards"
570 " BSS or RNC\n"
571 "Set to default timeout (" OSMO_STRINGIFY_VAL(MSC_PAGING_RESPONSE_TIMER_DEFAULT) " seconds)\n"
572 "Set paging timeout in seconds\n")
573{
Alexander Couzensae167fc2020-09-25 05:25:16 +0200574 int rat;
575 int paging_response_timer;
Pau Espin Pedrolb08a3802019-09-16 19:01:37 +0200576 if (!strcmp(argv[0], "default"))
Alexander Couzensae167fc2020-09-25 05:25:16 +0200577 paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100578 else
Alexander Couzensae167fc2020-09-25 05:25:16 +0200579 paging_response_timer = atoi(argv[0]);
580
581 for (rat = 0; rat < OSMO_RAT_COUNT; rat++) {
582 osmo_tdef_set(msc_ran_infra[rat].tdefs, -4, paging_response_timer, OSMO_TDEF_S);
583 }
584
585 vty_out(vty, "%% paging response-timer is deprecated.%s"
586 "%% All ran timer has been modified.%s"
587 "%% use 'timer <geran|utran|sgs> X4 %s' instead%s",
588 VTY_NEWLINE, VTY_NEWLINE, argv[0], VTY_NEWLINE);
589
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100590 return CMD_SUCCESS;
591}
592
Harald Welte69c54a82018-02-09 20:41:14 +0100593DEFUN(cfg_msc_emergency_msisdn, cfg_msc_emergency_msisdn_cmd,
594 "emergency-call route-to-msisdn MSISDN",
595 "Configure Emergency Call Behaviour\n"
596 "MSISDN to which Emergency Calls are Dispatched\n"
597 "MSISDN (E.164 Phone Number)\n")
598{
Harald Welte69c54a82018-02-09 20:41:14 +0100599 osmo_talloc_replace_string(gsmnet, &gsmnet->emergency.route_to_msisdn, argv[0]);
600
601 return CMD_SUCCESS;
602}
603
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700604/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
605DEFUN(cfg_msc_sms_over_gsup, cfg_msc_sms_over_gsup_cmd,
606 "sms-over-gsup",
607 "Enable routing of SMS messages over GSUP\n")
608{
609 gsmnet->sms_over_gsup = true;
610 return CMD_SUCCESS;
611}
612
613/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
614DEFUN(cfg_msc_no_sms_over_gsup, cfg_msc_no_sms_over_gsup_cmd,
615 "no sms-over-gsup",
616 NO_STR "Disable routing of SMS messages over GSUP\n")
617{
618 gsmnet->sms_over_gsup = false;
619 return CMD_SUCCESS;
620}
621
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100622/* FIXME: This should rather be in the form of
623 * handover-number range 001234xxx
624 * and
625 * handover-number range 001234xxx FIRST LAST
626 */
627DEFUN(cfg_msc_handover_number_range, cfg_msc_handover_number_range_cmd,
628 "handover-number range MSISDN_FIRST MSISDN_LAST",
629 "Configure a range of MSISDN to be assigned to incoming inter-MSC Handovers for call forwarding.\n"
630 "Configure a handover number range\n"
631 "First Handover Number MSISDN\n"
632 "Last Handover Number MSISDN\n")
633{
634 char *endp;
635 uint64_t range_start;
636 uint64_t range_end;
637
638 /* FIXME leading zeros?? */
639
640 errno = 0;
641 range_start = strtoull(argv[0], &endp, 10);
642 if (errno || *endp != '\0') {
643 vty_out(vty, "%% Error parsing handover-number range start: %s%s",
644 argv[0], VTY_NEWLINE);
645 return CMD_WARNING;
646 }
647
648 errno = 0;
649 range_end = strtoull(argv[1], &endp, 10);
650 if (errno || *endp != '\0') {
651 vty_out(vty, "%% Error parsing handover-number range end: %s%s",
652 argv[1], VTY_NEWLINE);
653 return CMD_WARNING;
654 }
655
656 if (range_start > range_end) {
657 vty_out(vty, "%% Error: handover-number range end must be > than the range start, but"
658 " %"PRIu64" > %"PRIu64"%s", range_start, range_end, VTY_NEWLINE);
659 return CMD_WARNING;
660 }
661
662 gsmnet->handover_number.range_start = range_start;
663 gsmnet->handover_number.range_end = range_end;
664 return CMD_SUCCESS;
665}
666
Pau Espin Pedrol4faff9e2019-05-06 19:29:11 +0200667#define OSMUX_STR "RTP multiplexing\n"
668DEFUN(cfg_msc_osmux,
669 cfg_msc_osmux_cmd,
670 "osmux (on|off|only)",
671 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
672{
673 if (strcmp(argv[0], "off") == 0)
674 gsmnet->use_osmux = OSMUX_USAGE_OFF;
675 else if (strcmp(argv[0], "on") == 0)
676 gsmnet->use_osmux = OSMUX_USAGE_ON;
677 else if (strcmp(argv[0], "only") == 0)
678 gsmnet->use_osmux = OSMUX_USAGE_ONLY;
679
680 return CMD_SUCCESS;
681}
682
Neels Hofmeyr9aac5c22020-05-27 00:04:26 +0200683#define NRI_STR "Mapping of Network Resource Indicators to this MSC, for MSC pooling\n"
684DEFUN(cfg_msc_nri_bitlen, cfg_msc_nri_bitlen_cmd,
685 "nri bitlen <0-15>",
686 NRI_STR
687 "Set number of NRI bits to place in TMSI identities (always starting just after the most significant octet)\n"
688 "bit count (default: " OSMO_STRINGIFY_VAL(NRI_BITLEN_DEFAULT) ")\n")
689{
690 gsmnet->vlr->cfg.nri_bitlen = atoi(argv[0]);
691 return CMD_SUCCESS;
692}
693
694#define NRI_STR "Mapping of Network Resource Indicators to this MSC, for MSC pooling\n"
695#define NRI_ARGS_TO_STR_FMT "%s%s%s"
696#define NRI_ARGS_TO_STR_ARGS(ARGC, ARGV) ARGV[0], (ARGC>1)? ".." : "", (ARGC>1)? ARGV[1] : ""
697#define NRI_FIRST_LAST_STR "First value of the NRI value range, should not surpass the configured 'nri bitlen'.\n" \
698 "Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the" \
699 " first value; if omitted, apply only the first value.\n"
700
701DEFUN(cfg_msc_nri_add, cfg_msc_nri_add_cmd,
702 "nri add <0-32767> [<0-32767>]",
703 NRI_STR "Add NRI value or range to the NRI mapping for this MSC\n"
704 NRI_FIRST_LAST_STR)
705{
706 const char *message;
707 int rc = osmo_nri_ranges_vty_add(&message, NULL, gsmnet->vlr->cfg.nri_ranges, argc, argv, gsmnet->vlr->cfg.nri_bitlen);
708 if (message) {
709 vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));
710 }
711 if (rc < 0)
712 return CMD_WARNING;
713 return CMD_SUCCESS;
714}
715
716DEFUN(cfg_msc_nri_del, cfg_msc_nri_del_cmd,
717 "nri del <0-32767> [<0-32767>]",
718 NRI_STR "Remove NRI value or range from the NRI mapping for this MSC\n"
719 NRI_FIRST_LAST_STR)
720{
721 const char *message;
722 int rc = osmo_nri_ranges_vty_del(&message, NULL, gsmnet->vlr->cfg.nri_ranges, argc, argv);
723 if (message) {
724 vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));
725 }
726 if (rc < 0)
727 return CMD_WARNING;
728 return CMD_SUCCESS;
729}
730
731static void msc_write_nri(struct vty *vty)
732{
733 struct osmo_nri_range *r;
734
735 llist_for_each_entry(r, &gsmnet->vlr->cfg.nri_ranges->entries, entry) {
736 if (osmo_nri_range_validate(r, 255))
737 vty_out(vty, " %% INVALID RANGE:");
738 vty_out(vty, " nri add %d", r->first);
739 if (r->first != r->last)
740 vty_out(vty, " %d", r->last);
741 vty_out(vty, "%s", VTY_NEWLINE);
742 }
743}
744
745DEFUN(show_nri, show_nri_cmd,
746 "show nri",
747 SHOW_STR NRI_STR)
748{
749 msc_write_nri(vty);
750 return CMD_SUCCESS;
751}
752
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200753static int config_write_msc(struct vty *vty)
754{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200755 vty_out(vty, "msc%s", VTY_NEWLINE);
Keith Whyte1587ffb2020-08-28 13:36:58 +0200756 if (gsmnet->sms_db_file_path && strcmp(gsmnet->sms_db_file_path, SMS_DEFAULT_DB_FILE_PATH))
757 vty_out(vty, " sms-database %s%s", gsmnet->sms_db_file_path, VTY_NEWLINE);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100758 if (gsmnet->mncc_sock_path)
759 vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE);
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100760 vty_out(vty, " mncc guard-timeout %i%s",
Philipp Maier9ca7b312018-10-10 17:00:49 +0200761 gsmnet->mncc_guard_timeout, VTY_NEWLINE);
Vadim Yanitskiy64623e12018-11-28 23:05:51 +0700762 vty_out(vty, " ncss guard-timeout %i%s",
763 gsmnet->ncss_guard_timeout, VTY_NEWLINE);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200764 vty_out(vty, " %sassign-tmsi%s",
765 gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
766
Philipp Maierfbf66102017-04-09 12:32:51 +0200767 vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
768 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100769#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200770 vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance,
771 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100772#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200773
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100774 if (gsmnet->vlr->cfg.auth_tuple_max_reuse_count)
775 vty_out(vty, " auth-tuple-max-reuse-count %d%s",
776 OSMO_MAX(-1, gsmnet->vlr->cfg.auth_tuple_max_reuse_count),
777 VTY_NEWLINE);
778 if (gsmnet->vlr->cfg.auth_reuse_old_sets_on_error)
779 vty_out(vty, " auth-tuple-reuse-on-error 1%s",
780 VTY_NEWLINE);
781
Oliver Smith03ded912019-05-02 10:40:50 +0200782 if (gsmnet->vlr->cfg.check_imei_rqd) {
783 if (gsmnet->vlr->cfg.retrieve_imeisv_early)
784 vty_out(vty, " check-imei-rqd early%s", VTY_NEWLINE);
785 else
786 vty_out(vty, " check-imei-rqd 1%s", VTY_NEWLINE);
787 }
Oliver Smith0fec28a2018-12-14 10:52:52 +0100788
Harald Welte69c54a82018-02-09 20:41:14 +0100789 if (gsmnet->emergency.route_to_msisdn) {
790 vty_out(vty, " emergency-call route-to-msisdn %s%s",
791 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
792 }
793
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700794 if (gsmnet->sms_over_gsup)
795 vty_out(vty, " sms-over-gsup%s", VTY_NEWLINE);
796
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100797 if (gsmnet->handover_number.range_start || gsmnet->handover_number.range_end)
798 vty_out(vty, " handover-number range %"PRIu64" %"PRIu64"%s",
799 gsmnet->handover_number.range_start, gsmnet->handover_number.range_end,
800 VTY_NEWLINE);
801
Pau Espin Pedrol4faff9e2019-05-06 19:29:11 +0200802 if (gsmnet->use_osmux != OSMUX_USAGE_OFF) {
803 vty_out(vty, " osmux %s%s", gsmnet->use_osmux == OSMUX_USAGE_ON ? "on" : "only",
804 VTY_NEWLINE);
805 }
806
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +0200807 mgcp_client_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200808#ifdef BUILD_IU
Neels Hofmeyr00e82d62017-07-05 15:19:52 +0200809 ranap_iu_vty_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200810#endif
811
Neels Hofmeyr880b9502019-05-09 02:01:55 +0200812 neighbor_ident_vty_write(vty);
813
Vadim Yanitskiyffc7f392020-01-18 18:39:41 +0700814 /* Timer introspection commands (generic osmo_tdef API) */
815 osmo_tdef_vty_groups_write(vty, " ");
816
Neels Hofmeyr9aac5c22020-05-27 00:04:26 +0200817 msc_write_nri(vty);
818
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200819 return CMD_SUCCESS;
820}
821
Maxc51609a2018-11-09 17:13:00 +0100822DEFUN(show_bsc, show_bsc_cmd,
823 "show bsc", SHOW_STR "BSC\n")
824{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100825 struct ran_peer *rp;
826 llist_for_each_entry(rp, &gsmnet->a.sri->ran_peers, entry) {
827 vty_out(vty, "BSC %s %s%s",
828 osmo_sccp_inst_addr_name(gsmnet->a.sri->sccp, &rp->peer_addr),
829 osmo_fsm_inst_state_name(rp->fi),
830 VTY_NEWLINE);
Maxc51609a2018-11-09 17:13:00 +0100831 }
832
833 return CMD_SUCCESS;
834}
835
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100836static const char *get_trans_proto_str(const struct gsm_trans *trans)
837{
838 static char buf[256];
839
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100840 switch (trans->type) {
841 case TRANS_CC:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100842 snprintf(buf, sizeof(buf), "%s %4u %4u",
843 gsm48_cc_state_name(trans->cc.state),
844 trans->cc.Tcurrent,
845 trans->cc.T308_second);
846 break;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100847 case TRANS_SMS:
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700848 snprintf(buf, sizeof(buf), "CP:%s RP:%s",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100849 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
850 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
851 break;
852 default:
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700853 return NULL;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100854 }
855
856 return buf;
857}
858
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700859/* Prefix a given format string with a given amount of spaces */
860#define MSC_VTY_DUMP(vty, offset, fmt, args...) \
861 vty_out(vty, "%*s" fmt, offset, "", ##args)
862
Neels Hofmeyr4014e482019-06-21 02:00:58 +0200863/* Print value of a named flag, prefixed with a given amount of spaces */
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700864#define MSC_VTY_DUMP_FLAG(vty, offset, name, flag) \
865 MSC_VTY_DUMP(vty, offset + 2, "%s: %*s%s%s", \
866 name, 30 - (int)strlen(name), "", \
867 flag ? "true" : "false", \
868 VTY_NEWLINE)
869
870enum msc_vty_dump_flags {
871 MSC_VTY_DUMP_F_SUBSCR = (1 << 0),
872 MSC_VTY_DUMP_F_CONNECTION = (1 << 1),
873 MSC_VTY_DUMP_F_TRANSACTION = (1 << 2),
874};
875
876static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans,
877 int offset, uint8_t dump_flags)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100878{
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700879 const char *proto_str;
880
881 if (dump_flags & MSC_VTY_DUMP_F_SUBSCR) {
882 MSC_VTY_DUMP(vty, offset, "Subscriber: %s%s",
883 vlr_subscr_name(msc_a_vsub(trans->msc_a)),
884 VTY_NEWLINE);
885 }
886
887 if (dump_flags & MSC_VTY_DUMP_F_CONNECTION) {
Neels Hofmeyr4014e482019-06-21 02:00:58 +0200888 /* (If msc_a exists, there *must* be a non-null msc_a->c.msub) */
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700889 MSC_VTY_DUMP(vty, offset, "RAN connection: %s%s",
890 trans->msc_a ? msub_ran_conn_name(trans->msc_a->c.msub)
891 : "(not established)",
892 VTY_NEWLINE);
893 }
894
895 MSC_VTY_DUMP(vty, offset, "Unique (global) identifier: 0x%08x%s",
896 trans->callref, VTY_NEWLINE);
897 MSC_VTY_DUMP(vty, offset, "GSM 04.07 identifier (%s): %u%s",
898 (trans->transaction_id & 0x08) ? "MO" : "MT",
899 trans->transaction_id,
900 VTY_NEWLINE);
901
902 MSC_VTY_DUMP(vty, offset, "Type: %s%s",
903 trans_type_name(trans->type),
904 VTY_NEWLINE);
905
906 if ((proto_str = get_trans_proto_str(trans))) {
907 MSC_VTY_DUMP(vty, offset, "Protocol specific: %s%s",
908 proto_str, VTY_NEWLINE);
909 }
910}
911
912static void vty_dump_one_conn(struct vty *vty, const struct msub *msub,
913 int offset, uint8_t dump_flags)
914{
915 struct vlr_subscr *vsub = msub_vsub(msub);
916 struct msc_a *msc_a = msub_msc_a(msub);
917 char buf[128];
918
919 if (dump_flags & MSC_VTY_DUMP_F_SUBSCR) {
920 dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
921 MSC_VTY_DUMP(vty, offset, "Subscriber: %s%s",
922 vlr_subscr_name(vsub),
923 VTY_NEWLINE);
924 }
925
926 MSC_VTY_DUMP(vty, offset, "RAN connection: %s%s",
927 msub_ran_conn_name(msub),
928 VTY_NEWLINE);
929 MSC_VTY_DUMP(vty, offset, "RAN connection state: %s%s",
930 osmo_fsm_inst_state_name(msc_a->c.fi),
931 VTY_NEWLINE);
932
933 if (vsub) {
934 MSC_VTY_DUMP(vty, offset, "LAC / cell ID: %u / %u%s",
Neels Hofmeyr41c03332020-06-24 15:02:27 +0200935 msc_a->via_cell.lai.lac, msc_a->via_cell.cell_identity,
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700936 VTY_NEWLINE);
937 }
938
939 MSC_VTY_DUMP(vty, offset, "Use count total: %d%s",
940 osmo_use_count_total(&msc_a->use_count),
941 VTY_NEWLINE);
942 MSC_VTY_DUMP(vty, offset, "Use count: %s%s",
943 osmo_use_count_name_buf(buf, sizeof(buf), &msc_a->use_count),
944 VTY_NEWLINE);
945
946 /* Transactions of this connection */
947 if (dump_flags & MSC_VTY_DUMP_F_TRANSACTION) {
948 struct gsm_trans *trans;
949 unsigned int i = 0;
950
951 /* Both subscriber and connection info is already printed */
952 dump_flags = dump_flags &~ MSC_VTY_DUMP_F_CONNECTION;
953 dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
954
955 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
956 if (trans->msc_a != msc_a)
957 continue;
958 MSC_VTY_DUMP(vty, offset, "Transaction #%02u: %s",
959 i++, VTY_NEWLINE);
960 vty_dump_one_trans(vty, trans, offset + 2, dump_flags);
961 }
962 }
963}
964
965static void vty_dump_one_subscr(struct vty *vty, struct vlr_subscr *vsub,
966 int offset, uint8_t dump_flags)
967{
Vadim Yanitskiy09ce3dc2019-07-09 00:34:29 +0700968 struct timespec now;
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700969 char buf[128];
970
Vadim Yanitskiydcf28682019-05-29 22:34:13 +0700971 if (vsub->name[0] != '\0') {
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700972 MSC_VTY_DUMP(vty, offset, "Name: '%s'%s",
973 vsub->name, VTY_NEWLINE);
974 }
Vadim Yanitskiydcf28682019-05-29 22:34:13 +0700975 if (vsub->msisdn[0] != '\0') {
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700976 MSC_VTY_DUMP(vty, offset, "MSISDN: %s%s",
977 vsub->msisdn, VTY_NEWLINE);
978 }
979
980 MSC_VTY_DUMP(vty, offset, "LAC / cell ID: %u / %u%s",
981 vsub->cgi.lai.lac, vsub->cgi.cell_identity,
982 VTY_NEWLINE);
983 MSC_VTY_DUMP(vty, offset, "RAN type: %s%s",
984 osmo_rat_type_name(vsub->cs.attached_via_ran),
985 VTY_NEWLINE);
986
987 MSC_VTY_DUMP(vty, offset, "IMSI: %s%s",
988 vsub->imsi, VTY_NEWLINE);
989 if (vsub->tmsi != GSM_RESERVED_TMSI) {
990 MSC_VTY_DUMP(vty, offset, "TMSI: %08X%s",
991 vsub->tmsi, VTY_NEWLINE);
992 }
993 if (vsub->tmsi_new != GSM_RESERVED_TMSI) {
994 MSC_VTY_DUMP(vty, offset, "New TMSI: %08X%s",
995 vsub->tmsi_new, VTY_NEWLINE);
996 }
997 if (vsub->imei[0] != '\0') {
998 MSC_VTY_DUMP(vty, offset, "IMEI: %s%s",
999 vsub->imei, VTY_NEWLINE);
1000 }
1001 if (vsub->imeisv[0] != '\0') {
1002 MSC_VTY_DUMP(vty, offset, "IMEISV: %s%s",
1003 vsub->imeisv, VTY_NEWLINE);
1004 }
1005
1006 MSC_VTY_DUMP(vty, offset, "Flags: %s", VTY_NEWLINE);
1007 MSC_VTY_DUMP_FLAG(vty, offset, "IMSI detached",
1008 vsub->imsi_detached_flag);
1009 MSC_VTY_DUMP_FLAG(vty, offset, "Conf. by radio contact",
1010 vsub->conf_by_radio_contact_ind);
1011 MSC_VTY_DUMP_FLAG(vty, offset, "Subscr. data conf. by HLR",
1012 vsub->sub_dataconf_by_hlr_ind);
1013 MSC_VTY_DUMP_FLAG(vty, offset, "Location conf. in HLR",
1014 vsub->loc_conf_in_hlr_ind);
1015 MSC_VTY_DUMP_FLAG(vty, offset, "Subscriber dormant",
1016 vsub->dormant_ind);
1017 MSC_VTY_DUMP_FLAG(vty, offset, "Received cancel location",
1018 vsub->cancel_loc_rx);
1019 MSC_VTY_DUMP_FLAG(vty, offset, "MS not reachable",
1020 vsub->ms_not_reachable_flag);
1021 MSC_VTY_DUMP_FLAG(vty, offset, "LA allowed",
1022 vsub->la_allowed);
1023
1024 if (vsub->last_tuple) {
1025 struct vlr_auth_tuple *t = vsub->last_tuple;
1026 MSC_VTY_DUMP(vty, offset, "A3A8 last tuple (used %d times): %s",
1027 t->use_count, VTY_NEWLINE);
1028 MSC_VTY_DUMP(vty, offset + 2, "seq # : %d%s",
1029 t->key_seq, VTY_NEWLINE);
1030 MSC_VTY_DUMP(vty, offset + 2, "RAND : %s%s",
1031 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
1032 VTY_NEWLINE);
1033 MSC_VTY_DUMP(vty, offset + 2, "SRES : %s%s",
1034 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
1035 VTY_NEWLINE);
1036 MSC_VTY_DUMP(vty, offset + 2, "Kc : %s%s",
1037 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
1038 VTY_NEWLINE);
1039 }
1040
Vadim Yanitskiyfc2b0192020-01-18 07:20:14 +07001041 if (!vlr_timer(vsub->vlr, 3212)) {
Vadim Yanitskiy09ce3dc2019-07-09 00:34:29 +07001042 MSC_VTY_DUMP(vty, offset, "Expires: never (T3212 is disabled)%s",
1043 VTY_NEWLINE);
1044 } else if (vsub->expire_lu == VLR_SUBSCRIBER_NO_EXPIRATION) {
1045 MSC_VTY_DUMP(vty, offset, "Expires: never%s",
1046 VTY_NEWLINE);
1047 } else if (osmo_clock_gettime(CLOCK_MONOTONIC, &now) == 0) {
1048 MSC_VTY_DUMP(vty, offset, "Expires: in %ld min %ld sec%s",
1049 (vsub->expire_lu - now.tv_sec) / 60,
1050 (vsub->expire_lu - now.tv_sec) % 60,
1051 VTY_NEWLINE);
1052 }
1053
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001054 MSC_VTY_DUMP(vty, offset, "Paging: %s paging for %d requests%s",
1055 vsub->cs.is_paging ? "is" : "not",
1056 llist_count(&vsub->cs.requests),
1057 VTY_NEWLINE);
1058
1059 /* SGs related */
1060 MSC_VTY_DUMP(vty, offset, "SGs-state: %s%s",
1061 osmo_fsm_inst_state_name(vsub->sgs_fsm),
1062 VTY_NEWLINE);
1063 MSC_VTY_DUMP(vty, offset, "SGs-MME: %s%s",
Vadim Yanitskiydcf28682019-05-29 22:34:13 +07001064 vsub->sgs.mme_name[0] != '\0' ? vsub->sgs.mme_name : "(none)",
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001065 VTY_NEWLINE);
1066
1067 MSC_VTY_DUMP(vty, offset, "Use count total: %d%s",
1068 osmo_use_count_total(&vsub->use_count),
1069 VTY_NEWLINE);
1070 MSC_VTY_DUMP(vty, offset, "Use count: %s%s",
1071 osmo_use_count_name_buf(buf, sizeof(buf), &vsub->use_count),
1072 VTY_NEWLINE);
1073
1074 /* Connection(s) and/or transactions of this subscriber */
1075 if (dump_flags & MSC_VTY_DUMP_F_CONNECTION) {
1076 struct msub *msub = msub_for_vsub(vsub);
1077 if (!msub)
1078 return;
1079
1080 /* Subscriber info is already printed */
1081 dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
1082
1083 MSC_VTY_DUMP(vty, offset, "Connection: %s", VTY_NEWLINE);
1084 vty_dump_one_conn(vty, msub, offset + 2, dump_flags);
1085 } else if (dump_flags & MSC_VTY_DUMP_F_TRANSACTION) {
1086 struct gsm_trans *trans;
1087 unsigned int i = 0;
1088
1089 /* Subscriber info is already printed */
1090 dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
1091 /* Do not print connection info, but mention it */
1092 dump_flags |= MSC_VTY_DUMP_F_CONNECTION;
1093
1094 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
1095 if (trans->vsub != vsub)
1096 continue;
1097 MSC_VTY_DUMP(vty, offset, "Transaction #%02u: %s",
1098 i++, VTY_NEWLINE);
1099 vty_dump_one_trans(vty, trans, offset + 2, dump_flags);
1100 }
1101 }
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001102}
1103
1104DEFUN(show_msc_transaction, show_msc_transaction_cmd,
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001105 "show transaction",
1106 SHOW_STR "Transactions\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001107{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001108 struct gsm_trans *trans;
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001109 uint8_t flags = 0x00;
1110 unsigned int i = 0;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001111
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001112 flags |= MSC_VTY_DUMP_F_CONNECTION;
1113 flags |= MSC_VTY_DUMP_F_SUBSCR;
1114
1115 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
1116 vty_out(vty, " Transaction #%02u: %s", i++, VTY_NEWLINE);
1117 vty_dump_one_trans(vty, trans, 4, flags);
1118 }
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001119
1120 return CMD_SUCCESS;
1121}
1122
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001123DEFUN(show_msc_conn, show_msc_conn_cmd,
1124 "show connection [trans]",
1125 SHOW_STR "Subscriber Connections\n"
1126 "Show child transactions of each connection\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001127{
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001128 uint8_t flags = 0x00;
1129 unsigned int i = 0;
1130 struct msub *msub;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001131
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001132 if (argc > 0)
1133 flags |= MSC_VTY_DUMP_F_TRANSACTION;
1134 flags |= MSC_VTY_DUMP_F_SUBSCR;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001135
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001136 llist_for_each_entry(msub, &msub_list, entry) {
1137 vty_out(vty, " Connection #%02u: %s", i++, VTY_NEWLINE);
1138 vty_dump_one_conn(vty, msub, 4, flags);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001139 }
1140
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001141 return CMD_SUCCESS;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001142}
1143
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001144#define SUBSCR_FLAGS "[(conn|trans|conn+trans)]"
1145#define SUBSCR_FLAGS_HELP \
1146 "Show child connections\n" \
1147 "Show child transactions\n" \
1148 "Show child connections and transactions\n"
1149
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001150/* Subscriber */
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001151DEFUN(show_subscr_cache, show_subscr_cache_cmd,
1152 "show subscriber cache " SUBSCR_FLAGS,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001153 SHOW_STR "Show information about subscribers\n"
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001154 "Display contents of subscriber cache\n"
1155 SUBSCR_FLAGS_HELP)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001156{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001157 struct vlr_subscr *vsub;
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001158 unsigned int count = 0;
1159 uint8_t flags = 0x00;
1160 unsigned int i = 0;
1161
1162 if (argc && strcmp(argv[0], "conn") == 0)
1163 flags |= MSC_VTY_DUMP_F_CONNECTION;
1164 else if (argc && strcmp(argv[0], "trans") == 0)
1165 flags |= MSC_VTY_DUMP_F_TRANSACTION;
1166 else if (argc && strcmp(argv[0], "conn+trans") == 0)
1167 flags |= MSC_VTY_DUMP_F_CONNECTION | MSC_VTY_DUMP_F_TRANSACTION;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001168
1169 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
1170 if (++count > 100) {
1171 vty_out(vty, "%% More than %d subscribers in cache,"
1172 " stopping here.%s", count-1, VTY_NEWLINE);
1173 break;
1174 }
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001175 vty_out(vty, " Subscriber #%02u: %s", i++, VTY_NEWLINE);
1176 vty_dump_one_subscr(vty, vsub, 4, flags);
Harald Welte69c54a82018-02-09 20:41:14 +01001177 }
1178
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001179 return CMD_SUCCESS;
1180}
1181
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001182DEFUN(sms_send_pend,
1183 sms_send_pend_cmd,
1184 "sms send pending",
1185 "SMS related commands\n" "SMS Sending related commands\n"
1186 "Send all pending SMS")
1187{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001188 struct gsm_sms *sms;
1189 unsigned long long sms_id = 0;
1190
1191 while (1) {
1192 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
1193 if (!sms)
1194 break;
1195
1196 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +07001197 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001198
1199 sms_id = sms->id + 1;
1200 }
1201
1202 return CMD_SUCCESS;
1203}
1204
1205DEFUN(sms_delete_expired,
1206 sms_delete_expired_cmd,
1207 "sms delete expired",
1208 "SMS related commands\n" "SMS Database related commands\n"
1209 "Delete all expired SMS")
1210{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001211 struct gsm_sms *sms;
1212 unsigned long long sms_id = 0;
1213 long long num_deleted = 0;
1214
1215 while (1) {
1216 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
1217 if (!sms)
1218 break;
1219
1220 /* Skip SMS which are currently queued for sending. */
1221 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
1222 continue;
1223
1224 /* Expiration check is performed by the DB layer. */
1225 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
1226 num_deleted++;
1227
1228 sms_id = sms->id + 1;
1229 }
1230
1231 if (num_deleted == 0) {
1232 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
1233 return CMD_WARNING;
1234 }
1235
1236 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
1237 return CMD_SUCCESS;
1238}
1239
1240static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +02001241 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001242 char *str, uint8_t tp_pid)
1243{
1244 struct gsm_network *net = receiver->vlr->user_ctx;
1245 struct gsm_sms *sms;
1246
Harald Welte39b55482018-04-09 19:19:33 +02001247 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Vadim Yanitskiydb4839c2019-12-01 18:52:58 +07001248 if (!sms) {
1249 LOGP(DLSMS, LOGL_ERROR, "Failed to allocate SMS\n");
1250 return CMD_WARNING;
1251 }
1252
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001253 sms->protocol_id = tp_pid;
1254
1255 /* store in database for the queue */
1256 if (db_sms_store(sms) != 0) {
1257 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
1258 sms_free(sms);
1259 return CMD_WARNING;
1260 }
1261 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
1262
1263 sms_free(sms);
1264 sms_queue_trigger(net->sms_queue);
1265 return CMD_SUCCESS;
1266}
1267
1268static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
1269 const char *type,
1270 const char *id)
1271{
1272 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001273 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001274 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001275 return vlr_subscr_find_by_imsi(gsmnet->vlr, id, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001276 else if (!strcmp(type, "tmsi"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001277 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id), VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001278
1279 return NULL;
1280}
1281#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
1282#define SUBSCR_HELP "Operations on a Subscriber\n" \
1283 "Identify subscriber by MSISDN (phone number)\n" \
1284 "Legacy alias for 'msisdn'\n" \
1285 "Identify subscriber by IMSI\n" \
1286 "Identify subscriber by TMSI\n" \
Vadim Yanitskiy3ccd8232019-05-16 01:35:23 +07001287 "Legacy alias for 'imsi'\n" \
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001288 "Identifier for the subscriber\n"
1289
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001290DEFUN(show_subscr, show_subscr_cmd,
1291 "show subscriber " SUBSCR_TYPES " ID " SUBSCR_FLAGS,
1292 SHOW_STR SUBSCR_HELP SUBSCR_FLAGS_HELP)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001293{
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001294 struct vlr_subscr *vsub;
1295 uint8_t flags = 0x00;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001296
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001297 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001298 if (!vsub) {
1299 vty_out(vty, "%% No subscriber found for %s %s%s",
1300 argv[0], argv[1], VTY_NEWLINE);
1301 return CMD_WARNING;
1302 }
1303
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +01001304 /* In the vty output to the user, exclude this local use count added by vlr_subscr_get() in get_vsub_by_argv().
1305 * This works, because: for get_vsub_by_argv() to succeed, there *must* have been at least one use count before
1306 * 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 +01001307 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001308
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001309 if (argc > 2 && strcmp(argv[2], "conn") == 0)
1310 flags |= MSC_VTY_DUMP_F_CONNECTION;
1311 else if (argc > 2 && strcmp(argv[2], "trans") == 0)
1312 flags |= MSC_VTY_DUMP_F_TRANSACTION;
1313 else if (argc > 2 && strcmp(argv[2], "conn+trans") == 0)
1314 flags |= MSC_VTY_DUMP_F_CONNECTION | MSC_VTY_DUMP_F_TRANSACTION;
1315
1316 vty_out(vty, " Subscriber: %s", VTY_NEWLINE);
1317 vty_dump_one_subscr(vty, vsub, 4, flags);
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +01001318
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001319 return CMD_SUCCESS;
1320}
1321
Vadim Yanitskiyb7ddbf32020-01-20 21:30:09 +07001322DEFUN_DEPRECATED(subscriber_create, subscriber_create_cmd,
1323 "subscriber create imsi ID",
1324 "Operations on a Subscriber\n"
1325 "Create new subscriber\n"
1326 "Identify the subscriber by his IMSI\n"
1327 "Identifier for the subscriber\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001328{
1329 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
1330 VTY_NEWLINE);
1331 return CMD_WARNING;
1332}
1333
1334DEFUN(subscriber_send_pending_sms,
1335 subscriber_send_pending_sms_cmd,
1336 "subscriber " SUBSCR_TYPES " ID sms pending-send",
1337 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
1338{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001339 struct vlr_subscr *vsub;
1340 struct gsm_sms *sms;
1341
1342 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1343 if (!vsub) {
1344 vty_out(vty, "%% No subscriber found for %s %s%s",
1345 argv[0], argv[1], VTY_NEWLINE);
1346 return CMD_WARNING;
1347 }
1348
1349 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
1350 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +07001351 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001352
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001353 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001354
1355 return CMD_SUCCESS;
1356}
1357
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001358DEFUN(subscriber_sms_delete_all,
1359 subscriber_sms_delete_all_cmd,
1360 "subscriber " SUBSCR_TYPES " ID sms delete-all",
1361 SUBSCR_HELP "SMS Operations\n"
1362 "Delete all SMS to be delivered to this subscriber"
1363 " -- WARNING: the SMS data for all unsent SMS for this subscriber"
1364 " WILL BE LOST.\n")
1365{
1366 struct vlr_subscr *vsub;
1367
1368 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1369 if (!vsub) {
1370 vty_out(vty, "%% No subscriber found for %s %s%s",
1371 argv[0], argv[1], VTY_NEWLINE);
1372 return CMD_WARNING;
1373 }
1374
1375 db_sms_delete_by_msisdn(vsub->msisdn);
1376
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001377 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001378
1379 return CMD_SUCCESS;
1380}
1381
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001382DEFUN(subscriber_send_sms,
1383 subscriber_send_sms_cmd,
1384 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
1385 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
1386{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001387 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +02001388 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001389 char *str;
1390 int rc;
1391
1392 if (!vsub) {
1393 vty_out(vty, "%% No subscriber found for %s %s%s",
1394 argv[0], argv[1], VTY_NEWLINE);
1395 rc = CMD_WARNING;
1396 goto err;
1397 }
1398
Harald Welte39b55482018-04-09 19:19:33 +02001399 if (!strcmp(argv[2], "msisdn"))
1400 sender_msisdn = argv[3];
1401 else {
1402 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1403 if (!sender) {
1404 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1405 rc = CMD_WARNING;
1406 goto err;
1407 }
1408 sender_msisdn = sender->msisdn;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001409 vlr_subscr_put(sender, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001410 }
1411
1412 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001413 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001414 talloc_free(str);
1415
1416err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001417 if (vsub)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001418 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001419
1420 return rc;
1421}
1422
1423DEFUN(subscriber_silent_sms,
1424 subscriber_silent_sms_cmd,
1425
1426 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
1427 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
1428{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001429 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +02001430 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001431 char *str;
1432 int rc;
1433
1434 if (!vsub) {
1435 vty_out(vty, "%% No subscriber found for %s %s%s",
1436 argv[0], argv[1], VTY_NEWLINE);
1437 rc = CMD_WARNING;
1438 goto err;
1439 }
1440
Harald Welte39b55482018-04-09 19:19:33 +02001441 if (!strcmp(argv[2], "msisdn")) {
1442 sender_msisdn = argv[3];
1443 } else {
1444 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1445 if (!sender) {
1446 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1447 rc = CMD_WARNING;
1448 goto err;
1449 }
1450 sender_msisdn = sender->msisdn;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001451 vlr_subscr_put(sender, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001452 }
1453
1454 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001455 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001456 talloc_free(str);
1457
1458err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001459 if (vsub)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001460 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001461
1462 return rc;
1463}
1464
Sylvain Munaut93558302019-02-14 20:13:08 +01001465#define CHAN_TYPES "(any|tch/f|tch/h|tch/any|sdcch)"
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001466#define CHAN_TYPE_HELP \
1467 "Any channel\n" \
1468 "TCH/F channel\n" \
Sylvain Munaut93558302019-02-14 20:13:08 +01001469 "TCH/H channel\n" \
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001470 "Any TCH channel\n" \
1471 "SDCCH channel\n"
1472
Sylvain Munaut93558302019-02-14 20:13:08 +01001473#define CHAN_MODES "(signalling|speech-hr|speech-fr|speech-efr|speech-amr)"
1474#define CHAN_MODE_HELP \
1475 "Signalling only\n" \
1476 "Speech with HR codec\n" \
1477 "Speech with FR codec\n" \
1478 "Speech with EFR codec\n" \
1479 "Speech with AMR codec\n"
1480
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001481DEFUN(subscriber_silent_call_start,
1482 subscriber_silent_call_start_cmd,
Sylvain Munaut93558302019-02-14 20:13:08 +01001483 "subscriber " SUBSCR_TYPES " ID silent-call start " CHAN_TYPES " " CHAN_MODES " [IP] [<0-65535>]",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001484 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
Sylvain Munaut93558302019-02-14 20:13:08 +01001485 CHAN_TYPE_HELP CHAN_MODE_HELP
1486 "Target IP for RTP traffic (default 127.0.0.1)\n"
1487 "Target port for RTP traffic (default: 4000)\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001488{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001489 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Sylvain Munaut93558302019-02-14 20:13:08 +01001490 struct gsm0808_channel_type ct;
1491 const char *ip;
1492 uint16_t port;
1493 int rc, speech;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001494
1495 if (!vsub) {
1496 vty_out(vty, "%% No subscriber found for %s %s%s",
1497 argv[0], argv[1], VTY_NEWLINE);
1498 return CMD_WARNING;
1499 }
1500
Sylvain Munaut93558302019-02-14 20:13:08 +01001501 memset(&ct, 0x00, sizeof(ct));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001502
Sylvain Munaut93558302019-02-14 20:13:08 +01001503 if (!strcmp(argv[3], "signalling")) {
1504 ct.ch_indctr = GSM0808_CHAN_SIGN;
1505 ct.perm_spch[0] = 0; /* Spare but required */
1506 ct.perm_spch_len = 1;
1507 } else if (!strcmp(argv[3], "speech-hr")) {
1508 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1509 ct.perm_spch[0] = GSM0808_PERM_HR1;
1510 ct.perm_spch_len = 1;
1511 } else if (!strcmp(argv[3], "speech-fr")) {
1512 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1513 ct.perm_spch[0] = GSM0808_PERM_FR1;
1514 ct.perm_spch_len = 1;
1515 } else if (!strcmp(argv[3], "speech-efr")) {
1516 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1517 ct.perm_spch[0] = GSM0808_PERM_FR2;
1518 ct.perm_spch_len = 1;
1519 } else if (!strcmp(argv[3], "speech-amr")) {
1520 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1521 ct.perm_spch[0] = GSM0808_PERM_FR3;
1522 ct.perm_spch[1] = GSM0808_PERM_HR3;
1523 ct.perm_spch_len = 2;
1524 }
1525
1526 speech = ct.ch_indctr == GSM0808_CHAN_SPEECH;
1527
1528 if (!strcmp(argv[2], "tch/f"))
1529 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_BM : GSM0808_SIGN_FULL_BM;
1530 else if (!strcmp(argv[2], "tch/h"))
1531 ct.ch_rate_type = speech ? GSM0808_SPEECH_HALF_LM : GSM0808_SIGN_HALF_LM;
1532 else if (!strcmp(argv[2], "tch/any"))
1533 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_FULL_PREF;
1534 else if (!strcmp(argv[2], "sdcch")) {
1535 if (speech) {
1536 vty_out(vty, "Can't request speech on SDCCH%s", VTY_NEWLINE);
1537 return CMD_WARNING;
1538 }
1539 ct.ch_rate_type = GSM0808_SIGN_SDCCH;
1540 } else
1541 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_ANY;
1542
1543 ip = argc >= 5 ? argv[4] : "127.0.0.1";
1544 port = argc >= 6 ? atoi(argv[5]) : 4000;
1545
1546 rc = gsm_silent_call_start(vsub, &ct, ip, port, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001547 switch (rc) {
1548 case -ENODEV:
1549 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
1550 break;
1551 default:
1552 if (rc)
1553 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
1554 else
1555 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
1556 break;
1557 }
1558
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001559 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001560 return rc ? CMD_WARNING : CMD_SUCCESS;
1561}
1562
1563DEFUN(subscriber_silent_call_stop,
1564 subscriber_silent_call_stop_cmd,
1565 "subscriber " SUBSCR_TYPES " ID silent-call stop",
1566 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
1567 CHAN_TYPE_HELP)
1568{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001569 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1570 int rc;
1571
1572 if (!vsub) {
1573 vty_out(vty, "%% No subscriber found for %s %s%s",
1574 argv[0], argv[1], VTY_NEWLINE);
1575 return CMD_WARNING;
1576 }
1577
1578 rc = gsm_silent_call_stop(vsub);
1579 switch (rc) {
1580 case -ENODEV:
1581 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
1582 break;
1583 case -ENOENT:
1584 vty_out(vty, "%% Subscriber has no silent call active%s",
1585 VTY_NEWLINE);
1586 break;
1587 default:
1588 if (rc)
1589 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
1590 else
1591 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
1592 break;
1593 }
1594
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001595 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001596 return rc ? CMD_WARNING : CMD_SUCCESS;
1597}
1598
1599DEFUN(subscriber_ussd_notify,
1600 subscriber_ussd_notify_cmd,
1601 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1602 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1603 "Alerting Level 0\n"
1604 "Alerting Level 1\n"
1605 "Alerting Level 2\n"
1606 "Text of USSD message to send\n")
1607{
1608 char *text;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001609 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001610 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1611 int level;
1612
1613 if (!vsub) {
1614 vty_out(vty, "%% No subscriber found for %s %s%s",
1615 argv[0], argv[1], VTY_NEWLINE);
1616 return CMD_WARNING;
1617 }
1618
1619 level = atoi(argv[2]);
1620 text = argv_concat(argv, argc, 3);
1621 if (!text) {
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001622 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001623 return CMD_WARNING;
1624 }
1625
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001626 msc_a = msc_a_for_vsub(vsub, true);
1627 if (!msc_a || msc_a->c.remote_to) {
1628 vty_out(vty, "%% An active connection and local MSC-A role is required for %s %s%s",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001629 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001630 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001631 talloc_free(text);
1632 return CMD_WARNING;
1633 }
1634
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001635 msc_send_ussd_notify(msc_a, level, text);
Vadim Yanitskiyf20c6b72018-11-29 01:20:58 +07001636 /* FIXME: since we don't allocate a transaction here,
1637 * we use dummy GSM 04.07 transaction ID. */
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001638 msc_send_ussd_release_complete(msc_a, 0x00);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001639
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001640 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001641 talloc_free(text);
1642 return CMD_SUCCESS;
1643}
1644
1645DEFUN(subscriber_paging,
1646 subscriber_paging_cmd,
1647 "subscriber " SUBSCR_TYPES " ID paging",
1648 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1649{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001650 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001651 struct paging_request *req;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001652
1653 if (!vsub) {
1654 vty_out(vty, "%% No subscriber found for %s %s%s",
1655 argv[0], argv[1], VTY_NEWLINE);
1656 return CMD_WARNING;
1657 }
1658
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001659 req = paging_request_start(vsub, PAGING_CAUSE_CALL_CONVERSATIONAL,
1660 NULL, NULL, "manual Paging from VTY");
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001661 if (req)
1662 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1663 else
1664 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1665
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001666 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001667 return req ? CMD_SUCCESS : CMD_WARNING;
1668}
1669
1670static int loop_by_char(uint8_t ch)
1671{
1672 switch (ch) {
1673 case 'a':
1674 return GSM414_LOOP_A;
1675 case 'b':
1676 return GSM414_LOOP_B;
1677 case 'c':
1678 return GSM414_LOOP_C;
1679 case 'd':
1680 return GSM414_LOOP_D;
1681 case 'e':
1682 return GSM414_LOOP_E;
1683 case 'f':
1684 return GSM414_LOOP_F;
1685 case 'i':
1686 return GSM414_LOOP_I;
1687 }
1688 return -1;
1689}
1690
1691DEFUN(subscriber_mstest_close,
1692 subscriber_mstest_close_cmd,
1693 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1694 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1695 "Close a TCH Loop inside the MS\n"
1696 "Loop Type A\n"
1697 "Loop Type B\n"
1698 "Loop Type C\n"
1699 "Loop Type D\n"
1700 "Loop Type E\n"
1701 "Loop Type F\n"
1702 "Loop Type I\n")
1703{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001704 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001705 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1706 const char *loop_str;
1707 int loop_mode;
1708
1709 if (!vsub) {
1710 vty_out(vty, "%% No subscriber found for %s %s%s",
1711 argv[0], argv[1], VTY_NEWLINE);
1712 return CMD_WARNING;
1713 }
1714
1715 loop_str = argv[2];
1716 loop_mode = loop_by_char(loop_str[0]);
1717
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001718 msc_a = msc_a_for_vsub(vsub, true);
1719 if (!msc_a) {
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001720 vty_out(vty, "%% An active connection is required for %s %s%s",
1721 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001722 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001723 return CMD_WARNING;
1724 }
1725
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001726 gsm0414_tx_close_tch_loop_cmd(msc_a, loop_mode);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001727
Vadim Yanitskiy817ad902020-07-29 05:47:01 +07001728 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001729 return CMD_SUCCESS;
1730}
1731
1732DEFUN(subscriber_mstest_open,
1733 subscriber_mstest_open_cmd,
1734 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1735 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1736 "Open a TCH Loop inside the MS\n")
1737{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001738 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001739 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1740
1741 if (!vsub) {
1742 vty_out(vty, "%% No subscriber found for %s %s%s",
1743 argv[0], argv[1], VTY_NEWLINE);
1744 return CMD_WARNING;
1745 }
1746
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001747 msc_a = msc_a_for_vsub(vsub, true);
1748 if (!msc_a) {
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001749 vty_out(vty, "%% An active connection is required for %s %s%s",
1750 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001751 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001752 return CMD_WARNING;
1753 }
1754
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001755 gsm0414_tx_open_loop_cmd(msc_a);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001756
Vadim Yanitskiy817ad902020-07-29 05:47:01 +07001757 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001758 return CMD_SUCCESS;
1759}
1760
1761DEFUN(ena_subscr_expire,
1762 ena_subscr_expire_cmd,
1763 "subscriber " SUBSCR_TYPES " ID expire",
1764 SUBSCR_HELP "Expire the subscriber Now\n")
1765{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001766 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1767 argv[1]);
1768
1769 if (!vsub) {
1770 vty_out(vty, "%% No subscriber found for %s %s%s",
1771 argv[0], argv[1], VTY_NEWLINE);
1772 return CMD_WARNING;
1773 }
1774
1775 if (vlr_subscr_expire(vsub))
1776 vty_out(vty, "%% VLR released subscriber %s%s",
1777 vlr_subscr_name(vsub), VTY_NEWLINE);
1778
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001779 if (osmo_use_count_total(&vsub->use_count) > 1)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001780 vty_out(vty, "%% Subscriber %s is still in use,"
1781 " should be released soon%s",
1782 vlr_subscr_name(vsub), VTY_NEWLINE);
1783
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001784 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001785 return CMD_SUCCESS;
1786}
1787
1788static int scall_cbfn(unsigned int subsys, unsigned int signal,
1789 void *handler_data, void *signal_data)
1790{
1791 struct scall_signal_data *sigdata = signal_data;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001792 struct vty *vty = sigdata->vty;
1793
1794 if (!vty_is_active(vty))
1795 return 0;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001796
1797 switch (signal) {
1798 case S_SCALL_SUCCESS:
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001799 vty_out(vty, "%% Silent call success%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001800 break;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001801 case S_SCALL_FAILED:
1802 vty_out(vty, "%% Silent call failed%s", VTY_NEWLINE);
1803 break;
1804 case S_SCALL_DETACHED:
1805 vty_out(vty, "%% Silent call ended%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001806 break;
1807 }
1808 return 0;
1809}
1810
1811DEFUN(show_stats,
1812 show_stats_cmd,
1813 "show statistics",
1814 SHOW_STR "Display network statistics\n")
1815{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001816 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Pau Espin Pedrol2e21a682021-06-04 16:45:44 +02001817 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_ATTACH)->current,
1818 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_NORMAL)->current,
1819 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_PERIODIC)->current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001820 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001821 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Pau Espin Pedrol2e21a682021-06-04 16:45:44 +02001822 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_DETACH)->current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001823 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001824 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Pau Espin Pedrol2e21a682021-06-04 16:45:44 +02001825 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_LOC_UPDATE_COMPLETED)->current,
1826 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_LOC_UPDATE_FAILED)->current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001827 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001828 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Pau Espin Pedrol2e21a682021-06-04 16:45:44 +02001829 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_SMS_SUBMITTED)->current,
1830 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_SMS_NO_RECEIVER)->current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001831 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001832 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Pau Espin Pedrol2e21a682021-06-04 16:45:44 +02001833 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_SMS_DELIVERED)->current,
1834 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_SMS_RP_ERR_MEM)->current,
1835 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_SMS_RP_ERR_OTHER)->current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001836 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001837 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Pau Espin Pedrol2e21a682021-06-04 16:45:44 +02001838 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_CALL_MO_SETUP)->current,
1839 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_CALL_MO_CONNECT_ACK)->current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001840 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001841 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Pau Espin Pedrol2e21a682021-06-04 16:45:44 +02001842 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_CALL_MT_SETUP)->current,
1843 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_CALL_MT_CONNECT)->current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001844 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001845 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Pau Espin Pedrol2e21a682021-06-04 16:45:44 +02001846 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MO_REQUESTS)->current,
1847 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MO_ESTABLISHED)->current,
1848 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MO_REQUESTS)->current
1849 - rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MO_ESTABLISHED)->current,
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001850 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001851 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Pau Espin Pedrol2e21a682021-06-04 16:45:44 +02001852 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MT_REQUESTS)->current,
1853 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MT_ESTABLISHED)->current,
1854 rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MT_REQUESTS)->current
1855 - rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MT_ESTABLISHED)->current,
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001856 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001857 return CMD_SUCCESS;
1858}
1859
1860DEFUN(show_smsqueue,
1861 show_smsqueue_cmd,
1862 "show sms-queue",
1863 SHOW_STR "Display SMSqueue statistics\n")
1864{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001865 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001866 return CMD_SUCCESS;
1867}
1868
1869DEFUN(smsqueue_trigger,
1870 smsqueue_trigger_cmd,
1871 "sms-queue trigger",
1872 "SMS Queue\n" "Trigger sending messages\n")
1873{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001874 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001875 return CMD_SUCCESS;
1876}
1877
1878DEFUN(smsqueue_max,
1879 smsqueue_max_cmd,
1880 "sms-queue max-pending <1-500>",
1881 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1882{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001883 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001884 return CMD_SUCCESS;
1885}
1886
1887DEFUN(smsqueue_clear,
1888 smsqueue_clear_cmd,
1889 "sms-queue clear",
1890 "SMS Queue\n" "Clear the queue of pending SMS\n")
1891{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001892 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001893 return CMD_SUCCESS;
1894}
1895
1896DEFUN(smsqueue_fail,
1897 smsqueue_fail_cmd,
1898 "sms-queue max-failure <1-500>",
1899 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1900{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001901 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001902 return CMD_SUCCESS;
1903}
1904
1905
1906DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1907 "mncc-int", "Configure internal MNCC handler")
1908{
1909 vty->node = MNCC_INT_NODE;
1910
1911 return CMD_SUCCESS;
1912}
1913
1914static struct cmd_node mncc_int_node = {
1915 MNCC_INT_NODE,
1916 "%s(config-mncc-int)# ",
1917 1,
1918};
1919
1920static const struct value_string tchf_codec_names[] = {
1921 { GSM48_CMODE_SPEECH_V1, "fr" },
1922 { GSM48_CMODE_SPEECH_EFR, "efr" },
1923 { GSM48_CMODE_SPEECH_AMR, "amr" },
1924 { 0, NULL }
1925};
1926
1927static const struct value_string tchh_codec_names[] = {
1928 { GSM48_CMODE_SPEECH_V1, "hr" },
1929 { GSM48_CMODE_SPEECH_AMR, "amr" },
1930 { 0, NULL }
1931};
1932
1933static int config_write_mncc_int(struct vty *vty)
1934{
1935 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1936 vty_out(vty, " default-codec tch-f %s%s",
1937 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1938 VTY_NEWLINE);
1939 vty_out(vty, " default-codec tch-h %s%s",
1940 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1941 VTY_NEWLINE);
1942
1943 return CMD_SUCCESS;
1944}
1945
1946DEFUN(mnccint_def_codec_f,
1947 mnccint_def_codec_f_cmd,
1948 "default-codec tch-f (fr|efr|amr)",
1949 "Set default codec\n" "Codec for TCH/F\n"
1950 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1951{
1952 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1953
1954 return CMD_SUCCESS;
1955}
1956
1957DEFUN(mnccint_def_codec_h,
1958 mnccint_def_codec_h_cmd,
1959 "default-codec tch-h (hr|amr)",
1960 "Set default codec\n" "Codec for TCH/H\n"
1961 "Half-Rate\n" "Adaptive Multi-Rate\n")
1962{
1963 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1964
1965 return CMD_SUCCESS;
1966}
1967
1968
1969DEFUN(logging_fltr_imsi,
1970 logging_fltr_imsi_cmd,
1971 "logging filter imsi IMSI",
1972 LOGGING_STR FILTER_STR
1973 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1974{
1975 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001976 struct log_target *tgt = osmo_log_vty2tgt(vty);
1977 const char *imsi = argv[0];
1978
1979 if (!tgt)
1980 return CMD_WARNING;
1981
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001982 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001983
1984 if (!vlr_subscr) {
1985 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1986 argv[0], VTY_NEWLINE);
1987 return CMD_WARNING;
1988 }
1989
1990 log_set_filter_vlr_subscr(tgt, vlr_subscr);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001991 vlr_subscr_put(vlr_subscr, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001992 return CMD_SUCCESS;
1993}
1994
1995static struct cmd_node hlr_node = {
1996 HLR_NODE,
1997 "%s(config-hlr)# ",
1998 1,
1999};
2000
2001DEFUN(cfg_hlr, cfg_hlr_cmd,
2002 "hlr", "Configure connection to the HLR")
2003{
2004 vty->node = HLR_NODE;
2005 return CMD_SUCCESS;
2006}
2007
2008DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
2009 "Remote GSUP address of the HLR\n"
2010 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
2011{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002012 talloc_free((void*)gsmnet->gsup_server_addr_str);
2013 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
2014 return CMD_SUCCESS;
2015}
2016
2017DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
2018 "Remote GSUP port of the HLR\n"
2019 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
2020{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002021 gsmnet->gsup_server_port = atoi(argv[0]);
2022 return CMD_SUCCESS;
2023}
2024
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01002025DEFUN(cfg_hlr_ipa_name,
2026 cfg_hlr_ipa_name_cmd,
2027 "ipa-name NAME",
2028 "Set the IPA name of this MSC\n"
2029 "A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. "
2030 "This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. "
2031 "The default is 'MSC-00-00-00-00-00-00'.\n")
2032{
2033 if (vty->type != VTY_FILE) {
2034 vty_out(vty, "The IPA name cannot be changed at run-time; "
Martin Hauke3f07dac2019-11-14 17:49:08 +01002035 "It can only be set in the configuration file.%s", VTY_NEWLINE);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01002036 return CMD_WARNING;
2037 }
2038
2039 gsmnet->msc_ipa_name = talloc_strdup(gsmnet, argv[0]);
2040 return CMD_SUCCESS;
2041}
2042
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002043static int config_write_hlr(struct vty *vty)
2044{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002045 vty_out(vty, "hlr%s", VTY_NEWLINE);
2046 vty_out(vty, " remote-ip %s%s",
2047 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
2048 vty_out(vty, " remote-port %u%s",
2049 gsmnet->gsup_server_port, VTY_NEWLINE);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01002050 if (gsmnet->msc_ipa_name)
2051 vty_out(vty, " ipa-name %s%s", gsmnet->msc_ipa_name, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002052 return CMD_SUCCESS;
2053}
2054
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02002055void msc_vty_init(struct gsm_network *msc_network)
2056{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01002057 OSMO_ASSERT(gsmnet == NULL);
2058 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002059
2060 osmo_stats_vty_add_cmds();
2061
2062 install_element(CONFIG_NODE, &cfg_net_cmd);
2063 install_node(&net_node, config_write_net);
2064 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
2065 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
2066 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
2067 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
2068 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
Neels Hofmeyr4dfb2ba2019-08-13 16:00:37 +02002069 install_element(GSMNET_NODE, &cfg_net_encryption_uea_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002070 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
2071 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
2072 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
2073 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
2074 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
2075 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
2076 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
2077 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Keith Whyte991bb422019-08-08 15:43:40 +02002078 install_element(GSMNET_NODE, &cfg_net_call_wait_cmd);
2079 install_element(GSMNET_NODE, &cfg_net_no_call_wait_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02002080
2081 install_element(CONFIG_NODE, &cfg_msc_cmd);
2082 install_node(&msc_node, config_write_msc);
Keith Whyte1587ffb2020-08-28 13:36:58 +02002083 install_element(MSC_NODE, &cfg_sms_database_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02002084 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01002085 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
2086 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02002087 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01002088 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Vadim Yanitskiy64623e12018-11-28 23:05:51 +07002089 install_element(MSC_NODE, &cfg_msc_ncss_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02002090 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01002091 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
2092 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Oliver Smith0fec28a2018-12-14 10:52:52 +01002093 install_element(MSC_NODE, &cfg_msc_check_imei_rqd_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02002094 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
2095 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01002096 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01002097 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +07002098 install_element(MSC_NODE, &cfg_msc_sms_over_gsup_cmd);
2099 install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd);
Pau Espin Pedrol4faff9e2019-05-06 19:29:11 +02002100 install_element(MSC_NODE, &cfg_msc_osmux_cmd);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01002101 install_element(MSC_NODE, &cfg_msc_handover_number_range_cmd);
Neels Hofmeyr9aac5c22020-05-27 00:04:26 +02002102 install_element(MSC_NODE, &cfg_msc_nri_bitlen_cmd);
2103 install_element(MSC_NODE, &cfg_msc_nri_add_cmd);
2104 install_element(MSC_NODE, &cfg_msc_nri_del_cmd);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01002105
2106 neighbor_ident_vty_init(msc_network);
Philipp Maierfbf66102017-04-09 12:32:51 +02002107
Vadim Yanitskiyffc7f392020-01-18 18:39:41 +07002108 /* Timer configuration commands (generic osmo_tdef API) */
2109 osmo_tdef_vty_groups_init(MSC_NODE, msc_tdef_group);
2110
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02002111 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02002112#ifdef BUILD_IU
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01002113 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 +02002114#endif
Harald Welte0df904d2018-12-03 11:00:04 +01002115 sgs_vty_init();
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01002116
Stefan Sperling617ac802018-02-22 17:58:20 +01002117 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002118
2119 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
2120
2121 install_element_ve(&show_subscr_cmd);
2122 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01002123 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002124 install_element_ve(&show_msc_conn_cmd);
2125 install_element_ve(&show_msc_transaction_cmd);
Neels Hofmeyr9aac5c22020-05-27 00:04:26 +02002126 install_element_ve(&show_nri_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002127
2128 install_element_ve(&sms_send_pend_cmd);
2129 install_element_ve(&sms_delete_expired_cmd);
2130
2131 install_element_ve(&subscriber_create_cmd);
2132 install_element_ve(&subscriber_send_sms_cmd);
2133 install_element_ve(&subscriber_silent_sms_cmd);
2134 install_element_ve(&subscriber_silent_call_start_cmd);
2135 install_element_ve(&subscriber_silent_call_stop_cmd);
2136 install_element_ve(&subscriber_ussd_notify_cmd);
2137 install_element_ve(&subscriber_mstest_close_cmd);
2138 install_element_ve(&subscriber_mstest_open_cmd);
2139 install_element_ve(&subscriber_paging_cmd);
2140 install_element_ve(&show_stats_cmd);
2141 install_element_ve(&show_smsqueue_cmd);
2142 install_element_ve(&logging_fltr_imsi_cmd);
2143
2144 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
2145 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
2146 install_element(ENABLE_NODE, &smsqueue_max_cmd);
2147 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
2148 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
2149 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01002150 install_element(ENABLE_NODE, &subscriber_sms_delete_all_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002151
2152 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
2153 install_node(&mncc_int_node, config_write_mncc_int);
2154 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
2155 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
2156
2157 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
2158
2159 install_element(CONFIG_NODE, &cfg_hlr_cmd);
2160 install_node(&hlr_node, config_write_hlr);
2161 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
2162 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01002163 install_element(HLR_NODE, &cfg_hlr_ipa_name_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02002164}