blob: 46d3cf9db273b75b2b76a3e2754446b1b20ec7b1 [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
Keith Whyte1587ffb2020-08-28 13:36:58 +0200429DEFUN(cfg_sms_database, cfg_sms_database_cmd,
430 "sms-database PATH",
431 "Set the path to the MSC-SMS database file\n"
432 "Relative or absolute file system path to the database file (default is '" SMS_DEFAULT_DB_FILE_PATH "')\n")
433{
434 osmo_talloc_replace_string(gsmnet, &gsmnet->sms_db_file_path, argv[0]);
435 return CMD_SUCCESS;
436}
437
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100438DEFUN(cfg_msc_mncc_internal,
439 cfg_msc_mncc_internal_cmd,
440 "mncc internal",
441 MNCC_STR "Use internal MNCC handler (default; changes need a program restart)\n")
442{
443 gsm_network_set_mncc_sock_path(gsmnet, NULL);
444 return CMD_SUCCESS;
445}
446
447DEFUN(cfg_msc_mncc_external,
448 cfg_msc_mncc_external_cmd,
449 "mncc external MNCC_SOCKET_PATH",
450 MNCC_STR "Use external MNCC handler (changes need a program restart)\n"
451 "File system path to create the MNCC unix domain socket at\n")
452{
453 gsm_network_set_mncc_sock_path(gsmnet, argv[0]);
454 return CMD_SUCCESS;
455}
456
Philipp Maier9ca7b312018-10-10 17:00:49 +0200457DEFUN(cfg_msc_mncc_guard_timeout,
458 cfg_msc_mncc_guard_timeout_cmd,
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100459 "mncc guard-timeout <0-255>",
460 MNCC_STR
461 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR)
Philipp Maier9ca7b312018-10-10 17:00:49 +0200462{
463 gsmnet->mncc_guard_timeout = atoi(argv[0]);
464 return CMD_SUCCESS;
465}
466
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100467ALIAS_DEPRECATED(cfg_msc_mncc_guard_timeout,
468 cfg_msc_deprecated_mncc_guard_timeout_cmd,
469 "mncc-guard-timeout <0-255>",
470 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR);
471
Vadim Yanitskiy64623e12018-11-28 23:05:51 +0700472#define NCSS_STR "Configure call independent Supplementary Services\n"
473
474DEFUN(cfg_msc_ncss_guard_timeout,
475 cfg_msc_ncss_guard_timeout_cmd,
476 "ncss guard-timeout <0-255>",
477 NCSS_STR "Set guard timer for session activity\n"
478 "guard timer value (sec.), or 0 to disable\n")
479{
480 gsmnet->ncss_guard_timeout = atoi(argv[0]);
481 return CMD_SUCCESS;
482}
483
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200484DEFUN(cfg_msc_assign_tmsi, cfg_msc_assign_tmsi_cmd,
485 "assign-tmsi",
486 "Assign TMSI during Location Updating.\n")
487{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200488 gsmnet->vlr->cfg.assign_tmsi = true;
489 return CMD_SUCCESS;
490}
491
492DEFUN(cfg_msc_no_assign_tmsi, cfg_msc_no_assign_tmsi_cmd,
493 "no assign-tmsi",
494 NO_STR "Assign TMSI during Location Updating.\n")
495{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200496 gsmnet->vlr->cfg.assign_tmsi = false;
497 return CMD_SUCCESS;
498}
499
Philipp Maierfbf66102017-04-09 12:32:51 +0200500DEFUN(cfg_msc_cs7_instance_a,
501 cfg_msc_cs7_instance_a_cmd,
502 "cs7-instance-a <0-15>",
503 "Set SS7 to be used by the A-Interface.\n" "SS7 instance reference number\n")
504{
Philipp Maierfbf66102017-04-09 12:32:51 +0200505 gsmnet->a.cs7_instance = atoi(argv[0]);
506 return CMD_SUCCESS;
507}
508
509DEFUN(cfg_msc_cs7_instance_iu,
510 cfg_msc_cs7_instance_iu_cmd,
511 "cs7-instance-iu <0-15>",
512 "Set SS7 to be used by the Iu-Interface.\n" "SS7 instance reference number\n")
513{
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100514#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200515 gsmnet->iu.cs7_instance = atoi(argv[0]);
516 return CMD_SUCCESS;
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100517#else
518 vty_out(vty, "WARNING: 'cs7-instance-iu' without effect: built without Iu support%s",
519 VTY_NEWLINE);
520 return CMD_WARNING;
521#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200522}
523
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100524DEFUN(cfg_msc_auth_tuple_max_reuse_count, cfg_msc_auth_tuple_max_reuse_count_cmd,
525 "auth-tuple-max-reuse-count <-1-2147483647>",
526 "Configure authentication tuple re-use\n"
527 "0 to use each auth tuple at most once (default), >0 to limit re-use, -1 to re-use infinitely (vulnerable!).\n")
528{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100529 gsmnet->vlr->cfg.auth_tuple_max_reuse_count = atoi(argv[0]);
530 return CMD_SUCCESS;
531}
532
533DEFUN(cfg_msc_auth_tuple_reuse_on_error, cfg_msc_auth_tuple_reuse_on_error_cmd,
534 "auth-tuple-reuse-on-error (0|1)",
535 "Configure authentication tuple re-use when HLR is not responsive\n"
Oliver Smithd6e24fd2019-01-09 10:46:43 +0100536 "Never re-use auth tuples beyond auth-tuple-max-reuse-count (default)\n"
537 "If the HLR does not deliver new tuples, do re-use already available old ones.\n")
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100538{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100539 gsmnet->vlr->cfg.auth_reuse_old_sets_on_error = atoi(argv[0]) ? true : false;
540 return CMD_SUCCESS;
541}
542
Oliver Smith0fec28a2018-12-14 10:52:52 +0100543DEFUN(cfg_msc_check_imei_rqd, cfg_msc_check_imei_rqd_cmd,
Oliver Smith03ded912019-05-02 10:40:50 +0200544 "check-imei-rqd (0|1|early)",
Oliver Smith0fec28a2018-12-14 10:52:52 +0100545 "Send each IMEI to the EIR to ask if it is permitted or not. The EIR is implemented as part of OsmoHLR, "
546 "and can optionally save the IMEI in the HLR.\n"
547 "Do not send IMEIs to the EIR\n"
Oliver Smith03ded912019-05-02 10:40:50 +0200548 "Send each IMEI to the EIR\n"
549 "Send each IMEI to the EIR, and do it at the start of the location update. This allows the EIR to receive the"
550 " 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 +0100551{
Oliver Smith03ded912019-05-02 10:40:50 +0200552 if (strcmp(argv[0], "0") == 0) {
553 gsmnet->vlr->cfg.check_imei_rqd = false;
554 gsmnet->vlr->cfg.retrieve_imeisv_early = false;
555 } else if (strcmp(argv[0], "1") == 0) {
556 gsmnet->vlr->cfg.check_imei_rqd = true;
557 gsmnet->vlr->cfg.retrieve_imeisv_early = false;
558 } else if (strcmp(argv[0], "early") == 0) {
559 gsmnet->vlr->cfg.check_imei_rqd = true;
560 gsmnet->vlr->cfg.retrieve_imeisv_early = true;
561 }
Oliver Smith0fec28a2018-12-14 10:52:52 +0100562 return CMD_SUCCESS;
563}
564
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100565DEFUN(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd,
566 "paging response-timer (default|<1-65535>)",
567 "Configure Paging\n"
568 "Set Paging timeout, the minimum time to pass between (unsuccessful) Pagings sent towards"
569 " BSS or RNC\n"
570 "Set to default timeout (" OSMO_STRINGIFY_VAL(MSC_PAGING_RESPONSE_TIMER_DEFAULT) " seconds)\n"
571 "Set paging timeout in seconds\n")
572{
Pau Espin Pedrolb08a3802019-09-16 19:01:37 +0200573 if (!strcmp(argv[0], "default"))
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100574 gsmnet->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
575 else
576 gsmnet->paging_response_timer = atoi(argv[0]);
577 return CMD_SUCCESS;
578}
579
Harald Welte69c54a82018-02-09 20:41:14 +0100580DEFUN(cfg_msc_emergency_msisdn, cfg_msc_emergency_msisdn_cmd,
581 "emergency-call route-to-msisdn MSISDN",
582 "Configure Emergency Call Behaviour\n"
583 "MSISDN to which Emergency Calls are Dispatched\n"
584 "MSISDN (E.164 Phone Number)\n")
585{
Harald Welte69c54a82018-02-09 20:41:14 +0100586 osmo_talloc_replace_string(gsmnet, &gsmnet->emergency.route_to_msisdn, argv[0]);
587
588 return CMD_SUCCESS;
589}
590
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700591/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
592DEFUN(cfg_msc_sms_over_gsup, cfg_msc_sms_over_gsup_cmd,
593 "sms-over-gsup",
594 "Enable routing of SMS messages over GSUP\n")
595{
596 gsmnet->sms_over_gsup = true;
597 return CMD_SUCCESS;
598}
599
600/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
601DEFUN(cfg_msc_no_sms_over_gsup, cfg_msc_no_sms_over_gsup_cmd,
602 "no sms-over-gsup",
603 NO_STR "Disable routing of SMS messages over GSUP\n")
604{
605 gsmnet->sms_over_gsup = false;
606 return CMD_SUCCESS;
607}
608
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100609/* FIXME: This should rather be in the form of
610 * handover-number range 001234xxx
611 * and
612 * handover-number range 001234xxx FIRST LAST
613 */
614DEFUN(cfg_msc_handover_number_range, cfg_msc_handover_number_range_cmd,
615 "handover-number range MSISDN_FIRST MSISDN_LAST",
616 "Configure a range of MSISDN to be assigned to incoming inter-MSC Handovers for call forwarding.\n"
617 "Configure a handover number range\n"
618 "First Handover Number MSISDN\n"
619 "Last Handover Number MSISDN\n")
620{
621 char *endp;
622 uint64_t range_start;
623 uint64_t range_end;
624
625 /* FIXME leading zeros?? */
626
627 errno = 0;
628 range_start = strtoull(argv[0], &endp, 10);
629 if (errno || *endp != '\0') {
630 vty_out(vty, "%% Error parsing handover-number range start: %s%s",
631 argv[0], VTY_NEWLINE);
632 return CMD_WARNING;
633 }
634
635 errno = 0;
636 range_end = strtoull(argv[1], &endp, 10);
637 if (errno || *endp != '\0') {
638 vty_out(vty, "%% Error parsing handover-number range end: %s%s",
639 argv[1], VTY_NEWLINE);
640 return CMD_WARNING;
641 }
642
643 if (range_start > range_end) {
644 vty_out(vty, "%% Error: handover-number range end must be > than the range start, but"
645 " %"PRIu64" > %"PRIu64"%s", range_start, range_end, VTY_NEWLINE);
646 return CMD_WARNING;
647 }
648
649 gsmnet->handover_number.range_start = range_start;
650 gsmnet->handover_number.range_end = range_end;
651 return CMD_SUCCESS;
652}
653
Pau Espin Pedrol4faff9e2019-05-06 19:29:11 +0200654#define OSMUX_STR "RTP multiplexing\n"
655DEFUN(cfg_msc_osmux,
656 cfg_msc_osmux_cmd,
657 "osmux (on|off|only)",
658 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
659{
660 if (strcmp(argv[0], "off") == 0)
661 gsmnet->use_osmux = OSMUX_USAGE_OFF;
662 else if (strcmp(argv[0], "on") == 0)
663 gsmnet->use_osmux = OSMUX_USAGE_ON;
664 else if (strcmp(argv[0], "only") == 0)
665 gsmnet->use_osmux = OSMUX_USAGE_ONLY;
666
667 return CMD_SUCCESS;
668}
669
Neels Hofmeyr9aac5c22020-05-27 00:04:26 +0200670#define NRI_STR "Mapping of Network Resource Indicators to this MSC, for MSC pooling\n"
671DEFUN(cfg_msc_nri_bitlen, cfg_msc_nri_bitlen_cmd,
672 "nri bitlen <0-15>",
673 NRI_STR
674 "Set number of NRI bits to place in TMSI identities (always starting just after the most significant octet)\n"
675 "bit count (default: " OSMO_STRINGIFY_VAL(NRI_BITLEN_DEFAULT) ")\n")
676{
677 gsmnet->vlr->cfg.nri_bitlen = atoi(argv[0]);
678 return CMD_SUCCESS;
679}
680
681#define NRI_STR "Mapping of Network Resource Indicators to this MSC, for MSC pooling\n"
682#define NRI_ARGS_TO_STR_FMT "%s%s%s"
683#define NRI_ARGS_TO_STR_ARGS(ARGC, ARGV) ARGV[0], (ARGC>1)? ".." : "", (ARGC>1)? ARGV[1] : ""
684#define NRI_FIRST_LAST_STR "First value of the NRI value range, should not surpass the configured 'nri bitlen'.\n" \
685 "Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the" \
686 " first value; if omitted, apply only the first value.\n"
687
688DEFUN(cfg_msc_nri_add, cfg_msc_nri_add_cmd,
689 "nri add <0-32767> [<0-32767>]",
690 NRI_STR "Add NRI value or range to the NRI mapping for this MSC\n"
691 NRI_FIRST_LAST_STR)
692{
693 const char *message;
694 int rc = osmo_nri_ranges_vty_add(&message, NULL, gsmnet->vlr->cfg.nri_ranges, argc, argv, gsmnet->vlr->cfg.nri_bitlen);
695 if (message) {
696 vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));
697 }
698 if (rc < 0)
699 return CMD_WARNING;
700 return CMD_SUCCESS;
701}
702
703DEFUN(cfg_msc_nri_del, cfg_msc_nri_del_cmd,
704 "nri del <0-32767> [<0-32767>]",
705 NRI_STR "Remove NRI value or range from the NRI mapping for this MSC\n"
706 NRI_FIRST_LAST_STR)
707{
708 const char *message;
709 int rc = osmo_nri_ranges_vty_del(&message, NULL, gsmnet->vlr->cfg.nri_ranges, argc, argv);
710 if (message) {
711 vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));
712 }
713 if (rc < 0)
714 return CMD_WARNING;
715 return CMD_SUCCESS;
716}
717
718static void msc_write_nri(struct vty *vty)
719{
720 struct osmo_nri_range *r;
721
722 llist_for_each_entry(r, &gsmnet->vlr->cfg.nri_ranges->entries, entry) {
723 if (osmo_nri_range_validate(r, 255))
724 vty_out(vty, " %% INVALID RANGE:");
725 vty_out(vty, " nri add %d", r->first);
726 if (r->first != r->last)
727 vty_out(vty, " %d", r->last);
728 vty_out(vty, "%s", VTY_NEWLINE);
729 }
730}
731
732DEFUN(show_nri, show_nri_cmd,
733 "show nri",
734 SHOW_STR NRI_STR)
735{
736 msc_write_nri(vty);
737 return CMD_SUCCESS;
738}
739
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200740static int config_write_msc(struct vty *vty)
741{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200742 vty_out(vty, "msc%s", VTY_NEWLINE);
Keith Whyte1587ffb2020-08-28 13:36:58 +0200743 if (gsmnet->sms_db_file_path && strcmp(gsmnet->sms_db_file_path, SMS_DEFAULT_DB_FILE_PATH))
744 vty_out(vty, " sms-database %s%s", gsmnet->sms_db_file_path, VTY_NEWLINE);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100745 if (gsmnet->mncc_sock_path)
746 vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE);
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100747 vty_out(vty, " mncc guard-timeout %i%s",
Philipp Maier9ca7b312018-10-10 17:00:49 +0200748 gsmnet->mncc_guard_timeout, VTY_NEWLINE);
Vadim Yanitskiy64623e12018-11-28 23:05:51 +0700749 vty_out(vty, " ncss guard-timeout %i%s",
750 gsmnet->ncss_guard_timeout, VTY_NEWLINE);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200751 vty_out(vty, " %sassign-tmsi%s",
752 gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
753
Philipp Maierfbf66102017-04-09 12:32:51 +0200754 vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
755 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100756#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200757 vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance,
758 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100759#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200760
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100761 if (gsmnet->vlr->cfg.auth_tuple_max_reuse_count)
762 vty_out(vty, " auth-tuple-max-reuse-count %d%s",
763 OSMO_MAX(-1, gsmnet->vlr->cfg.auth_tuple_max_reuse_count),
764 VTY_NEWLINE);
765 if (gsmnet->vlr->cfg.auth_reuse_old_sets_on_error)
766 vty_out(vty, " auth-tuple-reuse-on-error 1%s",
767 VTY_NEWLINE);
768
Oliver Smith03ded912019-05-02 10:40:50 +0200769 if (gsmnet->vlr->cfg.check_imei_rqd) {
770 if (gsmnet->vlr->cfg.retrieve_imeisv_early)
771 vty_out(vty, " check-imei-rqd early%s", VTY_NEWLINE);
772 else
773 vty_out(vty, " check-imei-rqd 1%s", VTY_NEWLINE);
774 }
Oliver Smith0fec28a2018-12-14 10:52:52 +0100775
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100776 if (gsmnet->paging_response_timer != MSC_PAGING_RESPONSE_TIMER_DEFAULT)
777 vty_out(vty, " paging response-timer %u%s", gsmnet->paging_response_timer, VTY_NEWLINE);
778
Harald Welte69c54a82018-02-09 20:41:14 +0100779 if (gsmnet->emergency.route_to_msisdn) {
780 vty_out(vty, " emergency-call route-to-msisdn %s%s",
781 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
782 }
783
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700784 if (gsmnet->sms_over_gsup)
785 vty_out(vty, " sms-over-gsup%s", VTY_NEWLINE);
786
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100787 if (gsmnet->handover_number.range_start || gsmnet->handover_number.range_end)
788 vty_out(vty, " handover-number range %"PRIu64" %"PRIu64"%s",
789 gsmnet->handover_number.range_start, gsmnet->handover_number.range_end,
790 VTY_NEWLINE);
791
Pau Espin Pedrol4faff9e2019-05-06 19:29:11 +0200792 if (gsmnet->use_osmux != OSMUX_USAGE_OFF) {
793 vty_out(vty, " osmux %s%s", gsmnet->use_osmux == OSMUX_USAGE_ON ? "on" : "only",
794 VTY_NEWLINE);
795 }
796
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +0200797 mgcp_client_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200798#ifdef BUILD_IU
Neels Hofmeyr00e82d62017-07-05 15:19:52 +0200799 ranap_iu_vty_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200800#endif
801
Neels Hofmeyr880b9502019-05-09 02:01:55 +0200802 neighbor_ident_vty_write(vty);
803
Vadim Yanitskiyffc7f392020-01-18 18:39:41 +0700804 /* Timer introspection commands (generic osmo_tdef API) */
805 osmo_tdef_vty_groups_write(vty, " ");
806
Neels Hofmeyr9aac5c22020-05-27 00:04:26 +0200807 msc_write_nri(vty);
808
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200809 return CMD_SUCCESS;
810}
811
Maxc51609a2018-11-09 17:13:00 +0100812DEFUN(show_bsc, show_bsc_cmd,
813 "show bsc", SHOW_STR "BSC\n")
814{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100815 struct ran_peer *rp;
816 llist_for_each_entry(rp, &gsmnet->a.sri->ran_peers, entry) {
817 vty_out(vty, "BSC %s %s%s",
818 osmo_sccp_inst_addr_name(gsmnet->a.sri->sccp, &rp->peer_addr),
819 osmo_fsm_inst_state_name(rp->fi),
820 VTY_NEWLINE);
Maxc51609a2018-11-09 17:13:00 +0100821 }
822
823 return CMD_SUCCESS;
824}
825
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100826static const char *get_trans_proto_str(const struct gsm_trans *trans)
827{
828 static char buf[256];
829
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100830 switch (trans->type) {
831 case TRANS_CC:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100832 snprintf(buf, sizeof(buf), "%s %4u %4u",
833 gsm48_cc_state_name(trans->cc.state),
834 trans->cc.Tcurrent,
835 trans->cc.T308_second);
836 break;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100837 case TRANS_SMS:
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700838 snprintf(buf, sizeof(buf), "CP:%s RP:%s",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100839 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
840 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
841 break;
842 default:
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700843 return NULL;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100844 }
845
846 return buf;
847}
848
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700849/* Prefix a given format string with a given amount of spaces */
850#define MSC_VTY_DUMP(vty, offset, fmt, args...) \
851 vty_out(vty, "%*s" fmt, offset, "", ##args)
852
Neels Hofmeyr4014e482019-06-21 02:00:58 +0200853/* Print value of a named flag, prefixed with a given amount of spaces */
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700854#define MSC_VTY_DUMP_FLAG(vty, offset, name, flag) \
855 MSC_VTY_DUMP(vty, offset + 2, "%s: %*s%s%s", \
856 name, 30 - (int)strlen(name), "", \
857 flag ? "true" : "false", \
858 VTY_NEWLINE)
859
860enum msc_vty_dump_flags {
861 MSC_VTY_DUMP_F_SUBSCR = (1 << 0),
862 MSC_VTY_DUMP_F_CONNECTION = (1 << 1),
863 MSC_VTY_DUMP_F_TRANSACTION = (1 << 2),
864};
865
866static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans,
867 int offset, uint8_t dump_flags)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100868{
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700869 const char *proto_str;
870
871 if (dump_flags & MSC_VTY_DUMP_F_SUBSCR) {
872 MSC_VTY_DUMP(vty, offset, "Subscriber: %s%s",
873 vlr_subscr_name(msc_a_vsub(trans->msc_a)),
874 VTY_NEWLINE);
875 }
876
877 if (dump_flags & MSC_VTY_DUMP_F_CONNECTION) {
Neels Hofmeyr4014e482019-06-21 02:00:58 +0200878 /* (If msc_a exists, there *must* be a non-null msc_a->c.msub) */
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700879 MSC_VTY_DUMP(vty, offset, "RAN connection: %s%s",
880 trans->msc_a ? msub_ran_conn_name(trans->msc_a->c.msub)
881 : "(not established)",
882 VTY_NEWLINE);
883 }
884
885 MSC_VTY_DUMP(vty, offset, "Unique (global) identifier: 0x%08x%s",
886 trans->callref, VTY_NEWLINE);
887 MSC_VTY_DUMP(vty, offset, "GSM 04.07 identifier (%s): %u%s",
888 (trans->transaction_id & 0x08) ? "MO" : "MT",
889 trans->transaction_id,
890 VTY_NEWLINE);
891
892 MSC_VTY_DUMP(vty, offset, "Type: %s%s",
893 trans_type_name(trans->type),
894 VTY_NEWLINE);
895
896 if ((proto_str = get_trans_proto_str(trans))) {
897 MSC_VTY_DUMP(vty, offset, "Protocol specific: %s%s",
898 proto_str, VTY_NEWLINE);
899 }
900}
901
902static void vty_dump_one_conn(struct vty *vty, const struct msub *msub,
903 int offset, uint8_t dump_flags)
904{
905 struct vlr_subscr *vsub = msub_vsub(msub);
906 struct msc_a *msc_a = msub_msc_a(msub);
907 char buf[128];
908
909 if (dump_flags & MSC_VTY_DUMP_F_SUBSCR) {
910 dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
911 MSC_VTY_DUMP(vty, offset, "Subscriber: %s%s",
912 vlr_subscr_name(vsub),
913 VTY_NEWLINE);
914 }
915
916 MSC_VTY_DUMP(vty, offset, "RAN connection: %s%s",
917 msub_ran_conn_name(msub),
918 VTY_NEWLINE);
919 MSC_VTY_DUMP(vty, offset, "RAN connection state: %s%s",
920 osmo_fsm_inst_state_name(msc_a->c.fi),
921 VTY_NEWLINE);
922
923 if (vsub) {
924 MSC_VTY_DUMP(vty, offset, "LAC / cell ID: %u / %u%s",
Neels Hofmeyr41c03332020-06-24 15:02:27 +0200925 msc_a->via_cell.lai.lac, msc_a->via_cell.cell_identity,
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700926 VTY_NEWLINE);
927 }
928
929 MSC_VTY_DUMP(vty, offset, "Use count total: %d%s",
930 osmo_use_count_total(&msc_a->use_count),
931 VTY_NEWLINE);
932 MSC_VTY_DUMP(vty, offset, "Use count: %s%s",
933 osmo_use_count_name_buf(buf, sizeof(buf), &msc_a->use_count),
934 VTY_NEWLINE);
935
936 /* Transactions of this connection */
937 if (dump_flags & MSC_VTY_DUMP_F_TRANSACTION) {
938 struct gsm_trans *trans;
939 unsigned int i = 0;
940
941 /* Both subscriber and connection info is already printed */
942 dump_flags = dump_flags &~ MSC_VTY_DUMP_F_CONNECTION;
943 dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
944
945 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
946 if (trans->msc_a != msc_a)
947 continue;
948 MSC_VTY_DUMP(vty, offset, "Transaction #%02u: %s",
949 i++, VTY_NEWLINE);
950 vty_dump_one_trans(vty, trans, offset + 2, dump_flags);
951 }
952 }
953}
954
955static void vty_dump_one_subscr(struct vty *vty, struct vlr_subscr *vsub,
956 int offset, uint8_t dump_flags)
957{
Vadim Yanitskiy09ce3dc2019-07-09 00:34:29 +0700958 struct timespec now;
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700959 char buf[128];
960
Vadim Yanitskiydcf28682019-05-29 22:34:13 +0700961 if (vsub->name[0] != '\0') {
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700962 MSC_VTY_DUMP(vty, offset, "Name: '%s'%s",
963 vsub->name, VTY_NEWLINE);
964 }
Vadim Yanitskiydcf28682019-05-29 22:34:13 +0700965 if (vsub->msisdn[0] != '\0') {
Vadim Yanitskiy80149172019-05-16 06:13:29 +0700966 MSC_VTY_DUMP(vty, offset, "MSISDN: %s%s",
967 vsub->msisdn, VTY_NEWLINE);
968 }
969
970 MSC_VTY_DUMP(vty, offset, "LAC / cell ID: %u / %u%s",
971 vsub->cgi.lai.lac, vsub->cgi.cell_identity,
972 VTY_NEWLINE);
973 MSC_VTY_DUMP(vty, offset, "RAN type: %s%s",
974 osmo_rat_type_name(vsub->cs.attached_via_ran),
975 VTY_NEWLINE);
976
977 MSC_VTY_DUMP(vty, offset, "IMSI: %s%s",
978 vsub->imsi, VTY_NEWLINE);
979 if (vsub->tmsi != GSM_RESERVED_TMSI) {
980 MSC_VTY_DUMP(vty, offset, "TMSI: %08X%s",
981 vsub->tmsi, VTY_NEWLINE);
982 }
983 if (vsub->tmsi_new != GSM_RESERVED_TMSI) {
984 MSC_VTY_DUMP(vty, offset, "New TMSI: %08X%s",
985 vsub->tmsi_new, VTY_NEWLINE);
986 }
987 if (vsub->imei[0] != '\0') {
988 MSC_VTY_DUMP(vty, offset, "IMEI: %s%s",
989 vsub->imei, VTY_NEWLINE);
990 }
991 if (vsub->imeisv[0] != '\0') {
992 MSC_VTY_DUMP(vty, offset, "IMEISV: %s%s",
993 vsub->imeisv, VTY_NEWLINE);
994 }
995
996 MSC_VTY_DUMP(vty, offset, "Flags: %s", VTY_NEWLINE);
997 MSC_VTY_DUMP_FLAG(vty, offset, "IMSI detached",
998 vsub->imsi_detached_flag);
999 MSC_VTY_DUMP_FLAG(vty, offset, "Conf. by radio contact",
1000 vsub->conf_by_radio_contact_ind);
1001 MSC_VTY_DUMP_FLAG(vty, offset, "Subscr. data conf. by HLR",
1002 vsub->sub_dataconf_by_hlr_ind);
1003 MSC_VTY_DUMP_FLAG(vty, offset, "Location conf. in HLR",
1004 vsub->loc_conf_in_hlr_ind);
1005 MSC_VTY_DUMP_FLAG(vty, offset, "Subscriber dormant",
1006 vsub->dormant_ind);
1007 MSC_VTY_DUMP_FLAG(vty, offset, "Received cancel location",
1008 vsub->cancel_loc_rx);
1009 MSC_VTY_DUMP_FLAG(vty, offset, "MS not reachable",
1010 vsub->ms_not_reachable_flag);
1011 MSC_VTY_DUMP_FLAG(vty, offset, "LA allowed",
1012 vsub->la_allowed);
1013
1014 if (vsub->last_tuple) {
1015 struct vlr_auth_tuple *t = vsub->last_tuple;
1016 MSC_VTY_DUMP(vty, offset, "A3A8 last tuple (used %d times): %s",
1017 t->use_count, VTY_NEWLINE);
1018 MSC_VTY_DUMP(vty, offset + 2, "seq # : %d%s",
1019 t->key_seq, VTY_NEWLINE);
1020 MSC_VTY_DUMP(vty, offset + 2, "RAND : %s%s",
1021 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
1022 VTY_NEWLINE);
1023 MSC_VTY_DUMP(vty, offset + 2, "SRES : %s%s",
1024 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
1025 VTY_NEWLINE);
1026 MSC_VTY_DUMP(vty, offset + 2, "Kc : %s%s",
1027 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
1028 VTY_NEWLINE);
1029 }
1030
Vadim Yanitskiyfc2b0192020-01-18 07:20:14 +07001031 if (!vlr_timer(vsub->vlr, 3212)) {
Vadim Yanitskiy09ce3dc2019-07-09 00:34:29 +07001032 MSC_VTY_DUMP(vty, offset, "Expires: never (T3212 is disabled)%s",
1033 VTY_NEWLINE);
1034 } else if (vsub->expire_lu == VLR_SUBSCRIBER_NO_EXPIRATION) {
1035 MSC_VTY_DUMP(vty, offset, "Expires: never%s",
1036 VTY_NEWLINE);
1037 } else if (osmo_clock_gettime(CLOCK_MONOTONIC, &now) == 0) {
1038 MSC_VTY_DUMP(vty, offset, "Expires: in %ld min %ld sec%s",
1039 (vsub->expire_lu - now.tv_sec) / 60,
1040 (vsub->expire_lu - now.tv_sec) % 60,
1041 VTY_NEWLINE);
1042 }
1043
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001044 MSC_VTY_DUMP(vty, offset, "Paging: %s paging for %d requests%s",
1045 vsub->cs.is_paging ? "is" : "not",
1046 llist_count(&vsub->cs.requests),
1047 VTY_NEWLINE);
1048
1049 /* SGs related */
1050 MSC_VTY_DUMP(vty, offset, "SGs-state: %s%s",
1051 osmo_fsm_inst_state_name(vsub->sgs_fsm),
1052 VTY_NEWLINE);
1053 MSC_VTY_DUMP(vty, offset, "SGs-MME: %s%s",
Vadim Yanitskiydcf28682019-05-29 22:34:13 +07001054 vsub->sgs.mme_name[0] != '\0' ? vsub->sgs.mme_name : "(none)",
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001055 VTY_NEWLINE);
1056
1057 MSC_VTY_DUMP(vty, offset, "Use count total: %d%s",
1058 osmo_use_count_total(&vsub->use_count),
1059 VTY_NEWLINE);
1060 MSC_VTY_DUMP(vty, offset, "Use count: %s%s",
1061 osmo_use_count_name_buf(buf, sizeof(buf), &vsub->use_count),
1062 VTY_NEWLINE);
1063
1064 /* Connection(s) and/or transactions of this subscriber */
1065 if (dump_flags & MSC_VTY_DUMP_F_CONNECTION) {
1066 struct msub *msub = msub_for_vsub(vsub);
1067 if (!msub)
1068 return;
1069
1070 /* Subscriber info is already printed */
1071 dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
1072
1073 MSC_VTY_DUMP(vty, offset, "Connection: %s", VTY_NEWLINE);
1074 vty_dump_one_conn(vty, msub, offset + 2, dump_flags);
1075 } else if (dump_flags & MSC_VTY_DUMP_F_TRANSACTION) {
1076 struct gsm_trans *trans;
1077 unsigned int i = 0;
1078
1079 /* Subscriber info is already printed */
1080 dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
1081 /* Do not print connection info, but mention it */
1082 dump_flags |= MSC_VTY_DUMP_F_CONNECTION;
1083
1084 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
1085 if (trans->vsub != vsub)
1086 continue;
1087 MSC_VTY_DUMP(vty, offset, "Transaction #%02u: %s",
1088 i++, VTY_NEWLINE);
1089 vty_dump_one_trans(vty, trans, offset + 2, dump_flags);
1090 }
1091 }
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001092}
1093
1094DEFUN(show_msc_transaction, show_msc_transaction_cmd,
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001095 "show transaction",
1096 SHOW_STR "Transactions\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001097{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001098 struct gsm_trans *trans;
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001099 uint8_t flags = 0x00;
1100 unsigned int i = 0;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001101
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001102 flags |= MSC_VTY_DUMP_F_CONNECTION;
1103 flags |= MSC_VTY_DUMP_F_SUBSCR;
1104
1105 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
1106 vty_out(vty, " Transaction #%02u: %s", i++, VTY_NEWLINE);
1107 vty_dump_one_trans(vty, trans, 4, flags);
1108 }
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001109
1110 return CMD_SUCCESS;
1111}
1112
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001113DEFUN(show_msc_conn, show_msc_conn_cmd,
1114 "show connection [trans]",
1115 SHOW_STR "Subscriber Connections\n"
1116 "Show child transactions of each connection\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001117{
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001118 uint8_t flags = 0x00;
1119 unsigned int i = 0;
1120 struct msub *msub;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001121
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001122 if (argc > 0)
1123 flags |= MSC_VTY_DUMP_F_TRANSACTION;
1124 flags |= MSC_VTY_DUMP_F_SUBSCR;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001125
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001126 llist_for_each_entry(msub, &msub_list, entry) {
1127 vty_out(vty, " Connection #%02u: %s", i++, VTY_NEWLINE);
1128 vty_dump_one_conn(vty, msub, 4, flags);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001129 }
1130
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001131 return CMD_SUCCESS;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001132}
1133
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001134#define SUBSCR_FLAGS "[(conn|trans|conn+trans)]"
1135#define SUBSCR_FLAGS_HELP \
1136 "Show child connections\n" \
1137 "Show child transactions\n" \
1138 "Show child connections and transactions\n"
1139
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001140/* Subscriber */
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001141DEFUN(show_subscr_cache, show_subscr_cache_cmd,
1142 "show subscriber cache " SUBSCR_FLAGS,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001143 SHOW_STR "Show information about subscribers\n"
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001144 "Display contents of subscriber cache\n"
1145 SUBSCR_FLAGS_HELP)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001146{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001147 struct vlr_subscr *vsub;
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001148 unsigned int count = 0;
1149 uint8_t flags = 0x00;
1150 unsigned int i = 0;
1151
1152 if (argc && strcmp(argv[0], "conn") == 0)
1153 flags |= MSC_VTY_DUMP_F_CONNECTION;
1154 else if (argc && strcmp(argv[0], "trans") == 0)
1155 flags |= MSC_VTY_DUMP_F_TRANSACTION;
1156 else if (argc && strcmp(argv[0], "conn+trans") == 0)
1157 flags |= MSC_VTY_DUMP_F_CONNECTION | MSC_VTY_DUMP_F_TRANSACTION;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001158
1159 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
1160 if (++count > 100) {
1161 vty_out(vty, "%% More than %d subscribers in cache,"
1162 " stopping here.%s", count-1, VTY_NEWLINE);
1163 break;
1164 }
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001165 vty_out(vty, " Subscriber #%02u: %s", i++, VTY_NEWLINE);
1166 vty_dump_one_subscr(vty, vsub, 4, flags);
Harald Welte69c54a82018-02-09 20:41:14 +01001167 }
1168
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001169 return CMD_SUCCESS;
1170}
1171
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001172DEFUN(sms_send_pend,
1173 sms_send_pend_cmd,
1174 "sms send pending",
1175 "SMS related commands\n" "SMS Sending related commands\n"
1176 "Send all pending SMS")
1177{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001178 struct gsm_sms *sms;
1179 unsigned long long sms_id = 0;
1180
1181 while (1) {
1182 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
1183 if (!sms)
1184 break;
1185
1186 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +07001187 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001188
1189 sms_id = sms->id + 1;
1190 }
1191
1192 return CMD_SUCCESS;
1193}
1194
1195DEFUN(sms_delete_expired,
1196 sms_delete_expired_cmd,
1197 "sms delete expired",
1198 "SMS related commands\n" "SMS Database related commands\n"
1199 "Delete all expired SMS")
1200{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001201 struct gsm_sms *sms;
1202 unsigned long long sms_id = 0;
1203 long long num_deleted = 0;
1204
1205 while (1) {
1206 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
1207 if (!sms)
1208 break;
1209
1210 /* Skip SMS which are currently queued for sending. */
1211 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
1212 continue;
1213
1214 /* Expiration check is performed by the DB layer. */
1215 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
1216 num_deleted++;
1217
1218 sms_id = sms->id + 1;
1219 }
1220
1221 if (num_deleted == 0) {
1222 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
1223 return CMD_WARNING;
1224 }
1225
1226 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
1227 return CMD_SUCCESS;
1228}
1229
1230static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +02001231 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001232 char *str, uint8_t tp_pid)
1233{
1234 struct gsm_network *net = receiver->vlr->user_ctx;
1235 struct gsm_sms *sms;
1236
Harald Welte39b55482018-04-09 19:19:33 +02001237 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Vadim Yanitskiydb4839c2019-12-01 18:52:58 +07001238 if (!sms) {
1239 LOGP(DLSMS, LOGL_ERROR, "Failed to allocate SMS\n");
1240 return CMD_WARNING;
1241 }
1242
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001243 sms->protocol_id = tp_pid;
1244
1245 /* store in database for the queue */
1246 if (db_sms_store(sms) != 0) {
1247 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
1248 sms_free(sms);
1249 return CMD_WARNING;
1250 }
1251 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
1252
1253 sms_free(sms);
1254 sms_queue_trigger(net->sms_queue);
1255 return CMD_SUCCESS;
1256}
1257
1258static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
1259 const char *type,
1260 const char *id)
1261{
1262 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001263 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001264 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001265 return vlr_subscr_find_by_imsi(gsmnet->vlr, id, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001266 else if (!strcmp(type, "tmsi"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001267 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id), VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001268
1269 return NULL;
1270}
1271#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
1272#define SUBSCR_HELP "Operations on a Subscriber\n" \
1273 "Identify subscriber by MSISDN (phone number)\n" \
1274 "Legacy alias for 'msisdn'\n" \
1275 "Identify subscriber by IMSI\n" \
1276 "Identify subscriber by TMSI\n" \
Vadim Yanitskiy3ccd8232019-05-16 01:35:23 +07001277 "Legacy alias for 'imsi'\n" \
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001278 "Identifier for the subscriber\n"
1279
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001280DEFUN(show_subscr, show_subscr_cmd,
1281 "show subscriber " SUBSCR_TYPES " ID " SUBSCR_FLAGS,
1282 SHOW_STR SUBSCR_HELP SUBSCR_FLAGS_HELP)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001283{
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001284 struct vlr_subscr *vsub;
1285 uint8_t flags = 0x00;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001286
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001287 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001288 if (!vsub) {
1289 vty_out(vty, "%% No subscriber found for %s %s%s",
1290 argv[0], argv[1], VTY_NEWLINE);
1291 return CMD_WARNING;
1292 }
1293
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +01001294 /* In the vty output to the user, exclude this local use count added by vlr_subscr_get() in get_vsub_by_argv().
1295 * This works, because: for get_vsub_by_argv() to succeed, there *must* have been at least one use count before
1296 * 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 +01001297 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001298
Vadim Yanitskiy80149172019-05-16 06:13:29 +07001299 if (argc > 2 && strcmp(argv[2], "conn") == 0)
1300 flags |= MSC_VTY_DUMP_F_CONNECTION;
1301 else if (argc > 2 && strcmp(argv[2], "trans") == 0)
1302 flags |= MSC_VTY_DUMP_F_TRANSACTION;
1303 else if (argc > 2 && strcmp(argv[2], "conn+trans") == 0)
1304 flags |= MSC_VTY_DUMP_F_CONNECTION | MSC_VTY_DUMP_F_TRANSACTION;
1305
1306 vty_out(vty, " Subscriber: %s", VTY_NEWLINE);
1307 vty_dump_one_subscr(vty, vsub, 4, flags);
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +01001308
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001309 return CMD_SUCCESS;
1310}
1311
Vadim Yanitskiyb7ddbf32020-01-20 21:30:09 +07001312DEFUN_DEPRECATED(subscriber_create, subscriber_create_cmd,
1313 "subscriber create imsi ID",
1314 "Operations on a Subscriber\n"
1315 "Create new subscriber\n"
1316 "Identify the subscriber by his IMSI\n"
1317 "Identifier for the subscriber\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001318{
1319 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
1320 VTY_NEWLINE);
1321 return CMD_WARNING;
1322}
1323
1324DEFUN(subscriber_send_pending_sms,
1325 subscriber_send_pending_sms_cmd,
1326 "subscriber " SUBSCR_TYPES " ID sms pending-send",
1327 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
1328{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001329 struct vlr_subscr *vsub;
1330 struct gsm_sms *sms;
1331
1332 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1333 if (!vsub) {
1334 vty_out(vty, "%% No subscriber found for %s %s%s",
1335 argv[0], argv[1], VTY_NEWLINE);
1336 return CMD_WARNING;
1337 }
1338
1339 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
1340 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +07001341 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001342
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001343 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001344
1345 return CMD_SUCCESS;
1346}
1347
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001348DEFUN(subscriber_sms_delete_all,
1349 subscriber_sms_delete_all_cmd,
1350 "subscriber " SUBSCR_TYPES " ID sms delete-all",
1351 SUBSCR_HELP "SMS Operations\n"
1352 "Delete all SMS to be delivered to this subscriber"
1353 " -- WARNING: the SMS data for all unsent SMS for this subscriber"
1354 " WILL BE LOST.\n")
1355{
1356 struct vlr_subscr *vsub;
1357
1358 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1359 if (!vsub) {
1360 vty_out(vty, "%% No subscriber found for %s %s%s",
1361 argv[0], argv[1], VTY_NEWLINE);
1362 return CMD_WARNING;
1363 }
1364
1365 db_sms_delete_by_msisdn(vsub->msisdn);
1366
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001367 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001368
1369 return CMD_SUCCESS;
1370}
1371
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001372DEFUN(subscriber_send_sms,
1373 subscriber_send_sms_cmd,
1374 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
1375 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
1376{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001377 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +02001378 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001379 char *str;
1380 int rc;
1381
1382 if (!vsub) {
1383 vty_out(vty, "%% No subscriber found for %s %s%s",
1384 argv[0], argv[1], VTY_NEWLINE);
1385 rc = CMD_WARNING;
1386 goto err;
1387 }
1388
Harald Welte39b55482018-04-09 19:19:33 +02001389 if (!strcmp(argv[2], "msisdn"))
1390 sender_msisdn = argv[3];
1391 else {
1392 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1393 if (!sender) {
1394 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1395 rc = CMD_WARNING;
1396 goto err;
1397 }
1398 sender_msisdn = sender->msisdn;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001399 vlr_subscr_put(sender, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001400 }
1401
1402 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001403 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001404 talloc_free(str);
1405
1406err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001407 if (vsub)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001408 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001409
1410 return rc;
1411}
1412
1413DEFUN(subscriber_silent_sms,
1414 subscriber_silent_sms_cmd,
1415
1416 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
1417 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
1418{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001419 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +02001420 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001421 char *str;
1422 int rc;
1423
1424 if (!vsub) {
1425 vty_out(vty, "%% No subscriber found for %s %s%s",
1426 argv[0], argv[1], VTY_NEWLINE);
1427 rc = CMD_WARNING;
1428 goto err;
1429 }
1430
Harald Welte39b55482018-04-09 19:19:33 +02001431 if (!strcmp(argv[2], "msisdn")) {
1432 sender_msisdn = argv[3];
1433 } else {
1434 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1435 if (!sender) {
1436 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1437 rc = CMD_WARNING;
1438 goto err;
1439 }
1440 sender_msisdn = sender->msisdn;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001441 vlr_subscr_put(sender, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001442 }
1443
1444 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001445 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001446 talloc_free(str);
1447
1448err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001449 if (vsub)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001450 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001451
1452 return rc;
1453}
1454
Sylvain Munaut93558302019-02-14 20:13:08 +01001455#define CHAN_TYPES "(any|tch/f|tch/h|tch/any|sdcch)"
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001456#define CHAN_TYPE_HELP \
1457 "Any channel\n" \
1458 "TCH/F channel\n" \
Sylvain Munaut93558302019-02-14 20:13:08 +01001459 "TCH/H channel\n" \
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001460 "Any TCH channel\n" \
1461 "SDCCH channel\n"
1462
Sylvain Munaut93558302019-02-14 20:13:08 +01001463#define CHAN_MODES "(signalling|speech-hr|speech-fr|speech-efr|speech-amr)"
1464#define CHAN_MODE_HELP \
1465 "Signalling only\n" \
1466 "Speech with HR codec\n" \
1467 "Speech with FR codec\n" \
1468 "Speech with EFR codec\n" \
1469 "Speech with AMR codec\n"
1470
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001471DEFUN(subscriber_silent_call_start,
1472 subscriber_silent_call_start_cmd,
Sylvain Munaut93558302019-02-14 20:13:08 +01001473 "subscriber " SUBSCR_TYPES " ID silent-call start " CHAN_TYPES " " CHAN_MODES " [IP] [<0-65535>]",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001474 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
Sylvain Munaut93558302019-02-14 20:13:08 +01001475 CHAN_TYPE_HELP CHAN_MODE_HELP
1476 "Target IP for RTP traffic (default 127.0.0.1)\n"
1477 "Target port for RTP traffic (default: 4000)\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001478{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001479 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Sylvain Munaut93558302019-02-14 20:13:08 +01001480 struct gsm0808_channel_type ct;
1481 const char *ip;
1482 uint16_t port;
1483 int rc, speech;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001484
1485 if (!vsub) {
1486 vty_out(vty, "%% No subscriber found for %s %s%s",
1487 argv[0], argv[1], VTY_NEWLINE);
1488 return CMD_WARNING;
1489 }
1490
Sylvain Munaut93558302019-02-14 20:13:08 +01001491 memset(&ct, 0x00, sizeof(ct));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001492
Sylvain Munaut93558302019-02-14 20:13:08 +01001493 if (!strcmp(argv[3], "signalling")) {
1494 ct.ch_indctr = GSM0808_CHAN_SIGN;
1495 ct.perm_spch[0] = 0; /* Spare but required */
1496 ct.perm_spch_len = 1;
1497 } else if (!strcmp(argv[3], "speech-hr")) {
1498 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1499 ct.perm_spch[0] = GSM0808_PERM_HR1;
1500 ct.perm_spch_len = 1;
1501 } else if (!strcmp(argv[3], "speech-fr")) {
1502 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1503 ct.perm_spch[0] = GSM0808_PERM_FR1;
1504 ct.perm_spch_len = 1;
1505 } else if (!strcmp(argv[3], "speech-efr")) {
1506 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1507 ct.perm_spch[0] = GSM0808_PERM_FR2;
1508 ct.perm_spch_len = 1;
1509 } else if (!strcmp(argv[3], "speech-amr")) {
1510 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1511 ct.perm_spch[0] = GSM0808_PERM_FR3;
1512 ct.perm_spch[1] = GSM0808_PERM_HR3;
1513 ct.perm_spch_len = 2;
1514 }
1515
1516 speech = ct.ch_indctr == GSM0808_CHAN_SPEECH;
1517
1518 if (!strcmp(argv[2], "tch/f"))
1519 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_BM : GSM0808_SIGN_FULL_BM;
1520 else if (!strcmp(argv[2], "tch/h"))
1521 ct.ch_rate_type = speech ? GSM0808_SPEECH_HALF_LM : GSM0808_SIGN_HALF_LM;
1522 else if (!strcmp(argv[2], "tch/any"))
1523 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_FULL_PREF;
1524 else if (!strcmp(argv[2], "sdcch")) {
1525 if (speech) {
1526 vty_out(vty, "Can't request speech on SDCCH%s", VTY_NEWLINE);
1527 return CMD_WARNING;
1528 }
1529 ct.ch_rate_type = GSM0808_SIGN_SDCCH;
1530 } else
1531 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_ANY;
1532
1533 ip = argc >= 5 ? argv[4] : "127.0.0.1";
1534 port = argc >= 6 ? atoi(argv[5]) : 4000;
1535
1536 rc = gsm_silent_call_start(vsub, &ct, ip, port, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001537 switch (rc) {
1538 case -ENODEV:
1539 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
1540 break;
1541 default:
1542 if (rc)
1543 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
1544 else
1545 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
1546 break;
1547 }
1548
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001549 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001550 return rc ? CMD_WARNING : CMD_SUCCESS;
1551}
1552
1553DEFUN(subscriber_silent_call_stop,
1554 subscriber_silent_call_stop_cmd,
1555 "subscriber " SUBSCR_TYPES " ID silent-call stop",
1556 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
1557 CHAN_TYPE_HELP)
1558{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001559 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1560 int rc;
1561
1562 if (!vsub) {
1563 vty_out(vty, "%% No subscriber found for %s %s%s",
1564 argv[0], argv[1], VTY_NEWLINE);
1565 return CMD_WARNING;
1566 }
1567
1568 rc = gsm_silent_call_stop(vsub);
1569 switch (rc) {
1570 case -ENODEV:
1571 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
1572 break;
1573 case -ENOENT:
1574 vty_out(vty, "%% Subscriber has no silent call active%s",
1575 VTY_NEWLINE);
1576 break;
1577 default:
1578 if (rc)
1579 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
1580 else
1581 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
1582 break;
1583 }
1584
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001585 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001586 return rc ? CMD_WARNING : CMD_SUCCESS;
1587}
1588
1589DEFUN(subscriber_ussd_notify,
1590 subscriber_ussd_notify_cmd,
1591 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1592 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1593 "Alerting Level 0\n"
1594 "Alerting Level 1\n"
1595 "Alerting Level 2\n"
1596 "Text of USSD message to send\n")
1597{
1598 char *text;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001599 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001600 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1601 int level;
1602
1603 if (!vsub) {
1604 vty_out(vty, "%% No subscriber found for %s %s%s",
1605 argv[0], argv[1], VTY_NEWLINE);
1606 return CMD_WARNING;
1607 }
1608
1609 level = atoi(argv[2]);
1610 text = argv_concat(argv, argc, 3);
1611 if (!text) {
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001612 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001613 return CMD_WARNING;
1614 }
1615
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001616 msc_a = msc_a_for_vsub(vsub, true);
1617 if (!msc_a || msc_a->c.remote_to) {
1618 vty_out(vty, "%% An active connection and local MSC-A role is required for %s %s%s",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001619 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001620 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001621 talloc_free(text);
1622 return CMD_WARNING;
1623 }
1624
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001625 msc_send_ussd_notify(msc_a, level, text);
Vadim Yanitskiyf20c6b72018-11-29 01:20:58 +07001626 /* FIXME: since we don't allocate a transaction here,
1627 * we use dummy GSM 04.07 transaction ID. */
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001628 msc_send_ussd_release_complete(msc_a, 0x00);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001629
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_SUCCESS;
1633}
1634
1635DEFUN(subscriber_paging,
1636 subscriber_paging_cmd,
1637 "subscriber " SUBSCR_TYPES " ID paging",
1638 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1639{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001640 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001641 struct paging_request *req;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001642
1643 if (!vsub) {
1644 vty_out(vty, "%% No subscriber found for %s %s%s",
1645 argv[0], argv[1], VTY_NEWLINE);
1646 return CMD_WARNING;
1647 }
1648
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001649 req = paging_request_start(vsub, PAGING_CAUSE_CALL_CONVERSATIONAL,
1650 NULL, NULL, "manual Paging from VTY");
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001651 if (req)
1652 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1653 else
1654 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1655
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001656 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001657 return req ? CMD_SUCCESS : CMD_WARNING;
1658}
1659
1660static int loop_by_char(uint8_t ch)
1661{
1662 switch (ch) {
1663 case 'a':
1664 return GSM414_LOOP_A;
1665 case 'b':
1666 return GSM414_LOOP_B;
1667 case 'c':
1668 return GSM414_LOOP_C;
1669 case 'd':
1670 return GSM414_LOOP_D;
1671 case 'e':
1672 return GSM414_LOOP_E;
1673 case 'f':
1674 return GSM414_LOOP_F;
1675 case 'i':
1676 return GSM414_LOOP_I;
1677 }
1678 return -1;
1679}
1680
1681DEFUN(subscriber_mstest_close,
1682 subscriber_mstest_close_cmd,
1683 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1684 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1685 "Close a TCH Loop inside the MS\n"
1686 "Loop Type A\n"
1687 "Loop Type B\n"
1688 "Loop Type C\n"
1689 "Loop Type D\n"
1690 "Loop Type E\n"
1691 "Loop Type F\n"
1692 "Loop Type I\n")
1693{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001694 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001695 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1696 const char *loop_str;
1697 int loop_mode;
1698
1699 if (!vsub) {
1700 vty_out(vty, "%% No subscriber found for %s %s%s",
1701 argv[0], argv[1], VTY_NEWLINE);
1702 return CMD_WARNING;
1703 }
1704
1705 loop_str = argv[2];
1706 loop_mode = loop_by_char(loop_str[0]);
1707
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001708 msc_a = msc_a_for_vsub(vsub, true);
1709 if (!msc_a) {
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001710 vty_out(vty, "%% An active connection is required for %s %s%s",
1711 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001712 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001713 return CMD_WARNING;
1714 }
1715
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001716 gsm0414_tx_close_tch_loop_cmd(msc_a, loop_mode);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001717
Vadim Yanitskiy817ad902020-07-29 05:47:01 +07001718 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001719 return CMD_SUCCESS;
1720}
1721
1722DEFUN(subscriber_mstest_open,
1723 subscriber_mstest_open_cmd,
1724 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1725 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1726 "Open a TCH Loop inside the MS\n")
1727{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001728 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001729 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1730
1731 if (!vsub) {
1732 vty_out(vty, "%% No subscriber found for %s %s%s",
1733 argv[0], argv[1], VTY_NEWLINE);
1734 return CMD_WARNING;
1735 }
1736
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001737 msc_a = msc_a_for_vsub(vsub, true);
1738 if (!msc_a) {
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001739 vty_out(vty, "%% An active connection is required for %s %s%s",
1740 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001741 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001742 return CMD_WARNING;
1743 }
1744
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001745 gsm0414_tx_open_loop_cmd(msc_a);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001746
Vadim Yanitskiy817ad902020-07-29 05:47:01 +07001747 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001748 return CMD_SUCCESS;
1749}
1750
1751DEFUN(ena_subscr_expire,
1752 ena_subscr_expire_cmd,
1753 "subscriber " SUBSCR_TYPES " ID expire",
1754 SUBSCR_HELP "Expire the subscriber Now\n")
1755{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001756 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1757 argv[1]);
1758
1759 if (!vsub) {
1760 vty_out(vty, "%% No subscriber found for %s %s%s",
1761 argv[0], argv[1], VTY_NEWLINE);
1762 return CMD_WARNING;
1763 }
1764
1765 if (vlr_subscr_expire(vsub))
1766 vty_out(vty, "%% VLR released subscriber %s%s",
1767 vlr_subscr_name(vsub), VTY_NEWLINE);
1768
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001769 if (osmo_use_count_total(&vsub->use_count) > 1)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001770 vty_out(vty, "%% Subscriber %s is still in use,"
1771 " should be released soon%s",
1772 vlr_subscr_name(vsub), VTY_NEWLINE);
1773
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001774 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001775 return CMD_SUCCESS;
1776}
1777
1778static int scall_cbfn(unsigned int subsys, unsigned int signal,
1779 void *handler_data, void *signal_data)
1780{
1781 struct scall_signal_data *sigdata = signal_data;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001782 struct vty *vty = sigdata->vty;
1783
1784 if (!vty_is_active(vty))
1785 return 0;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001786
1787 switch (signal) {
1788 case S_SCALL_SUCCESS:
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001789 vty_out(vty, "%% Silent call success%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001790 break;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001791 case S_SCALL_FAILED:
1792 vty_out(vty, "%% Silent call failed%s", VTY_NEWLINE);
1793 break;
1794 case S_SCALL_DETACHED:
1795 vty_out(vty, "%% Silent call ended%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001796 break;
1797 }
1798 return 0;
1799}
1800
1801DEFUN(show_stats,
1802 show_stats_cmd,
1803 "show statistics",
1804 SHOW_STR "Display network statistics\n")
1805{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001806 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001807 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1808 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1809 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001810 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001811 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001812 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001813 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001814 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001815 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1816 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001817 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001818 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001819 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1820 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001821 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001822 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001823 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1824 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1825 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001826 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001827 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001828 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1829 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001830 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001831 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001832 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1833 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001834 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001835 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001836 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1837 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1838 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1839 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1840 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001841 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001842 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1843 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1844 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1845 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1846 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001847 return CMD_SUCCESS;
1848}
1849
1850DEFUN(show_smsqueue,
1851 show_smsqueue_cmd,
1852 "show sms-queue",
1853 SHOW_STR "Display SMSqueue statistics\n")
1854{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001855 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001856 return CMD_SUCCESS;
1857}
1858
1859DEFUN(smsqueue_trigger,
1860 smsqueue_trigger_cmd,
1861 "sms-queue trigger",
1862 "SMS Queue\n" "Trigger sending messages\n")
1863{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001864 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001865 return CMD_SUCCESS;
1866}
1867
1868DEFUN(smsqueue_max,
1869 smsqueue_max_cmd,
1870 "sms-queue max-pending <1-500>",
1871 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1872{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001873 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001874 return CMD_SUCCESS;
1875}
1876
1877DEFUN(smsqueue_clear,
1878 smsqueue_clear_cmd,
1879 "sms-queue clear",
1880 "SMS Queue\n" "Clear the queue of pending SMS\n")
1881{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001882 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001883 return CMD_SUCCESS;
1884}
1885
1886DEFUN(smsqueue_fail,
1887 smsqueue_fail_cmd,
1888 "sms-queue max-failure <1-500>",
1889 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1890{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001891 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001892 return CMD_SUCCESS;
1893}
1894
1895
1896DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1897 "mncc-int", "Configure internal MNCC handler")
1898{
1899 vty->node = MNCC_INT_NODE;
1900
1901 return CMD_SUCCESS;
1902}
1903
1904static struct cmd_node mncc_int_node = {
1905 MNCC_INT_NODE,
1906 "%s(config-mncc-int)# ",
1907 1,
1908};
1909
1910static const struct value_string tchf_codec_names[] = {
1911 { GSM48_CMODE_SPEECH_V1, "fr" },
1912 { GSM48_CMODE_SPEECH_EFR, "efr" },
1913 { GSM48_CMODE_SPEECH_AMR, "amr" },
1914 { 0, NULL }
1915};
1916
1917static const struct value_string tchh_codec_names[] = {
1918 { GSM48_CMODE_SPEECH_V1, "hr" },
1919 { GSM48_CMODE_SPEECH_AMR, "amr" },
1920 { 0, NULL }
1921};
1922
1923static int config_write_mncc_int(struct vty *vty)
1924{
1925 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1926 vty_out(vty, " default-codec tch-f %s%s",
1927 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1928 VTY_NEWLINE);
1929 vty_out(vty, " default-codec tch-h %s%s",
1930 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1931 VTY_NEWLINE);
1932
1933 return CMD_SUCCESS;
1934}
1935
1936DEFUN(mnccint_def_codec_f,
1937 mnccint_def_codec_f_cmd,
1938 "default-codec tch-f (fr|efr|amr)",
1939 "Set default codec\n" "Codec for TCH/F\n"
1940 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1941{
1942 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1943
1944 return CMD_SUCCESS;
1945}
1946
1947DEFUN(mnccint_def_codec_h,
1948 mnccint_def_codec_h_cmd,
1949 "default-codec tch-h (hr|amr)",
1950 "Set default codec\n" "Codec for TCH/H\n"
1951 "Half-Rate\n" "Adaptive Multi-Rate\n")
1952{
1953 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1954
1955 return CMD_SUCCESS;
1956}
1957
1958
1959DEFUN(logging_fltr_imsi,
1960 logging_fltr_imsi_cmd,
1961 "logging filter imsi IMSI",
1962 LOGGING_STR FILTER_STR
1963 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1964{
1965 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001966 struct log_target *tgt = osmo_log_vty2tgt(vty);
1967 const char *imsi = argv[0];
1968
1969 if (!tgt)
1970 return CMD_WARNING;
1971
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001972 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001973
1974 if (!vlr_subscr) {
1975 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1976 argv[0], VTY_NEWLINE);
1977 return CMD_WARNING;
1978 }
1979
1980 log_set_filter_vlr_subscr(tgt, vlr_subscr);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001981 vlr_subscr_put(vlr_subscr, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001982 return CMD_SUCCESS;
1983}
1984
1985static struct cmd_node hlr_node = {
1986 HLR_NODE,
1987 "%s(config-hlr)# ",
1988 1,
1989};
1990
1991DEFUN(cfg_hlr, cfg_hlr_cmd,
1992 "hlr", "Configure connection to the HLR")
1993{
1994 vty->node = HLR_NODE;
1995 return CMD_SUCCESS;
1996}
1997
1998DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1999 "Remote GSUP address of the HLR\n"
2000 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
2001{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002002 talloc_free((void*)gsmnet->gsup_server_addr_str);
2003 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
2004 return CMD_SUCCESS;
2005}
2006
2007DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
2008 "Remote GSUP port of the HLR\n"
2009 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
2010{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002011 gsmnet->gsup_server_port = atoi(argv[0]);
2012 return CMD_SUCCESS;
2013}
2014
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01002015DEFUN(cfg_hlr_ipa_name,
2016 cfg_hlr_ipa_name_cmd,
2017 "ipa-name NAME",
2018 "Set the IPA name of this MSC\n"
2019 "A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. "
2020 "This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. "
2021 "The default is 'MSC-00-00-00-00-00-00'.\n")
2022{
2023 if (vty->type != VTY_FILE) {
2024 vty_out(vty, "The IPA name cannot be changed at run-time; "
Martin Hauke3f07dac2019-11-14 17:49:08 +01002025 "It can only be set in the configuration file.%s", VTY_NEWLINE);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01002026 return CMD_WARNING;
2027 }
2028
2029 gsmnet->msc_ipa_name = talloc_strdup(gsmnet, argv[0]);
2030 return CMD_SUCCESS;
2031}
2032
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002033static int config_write_hlr(struct vty *vty)
2034{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002035 vty_out(vty, "hlr%s", VTY_NEWLINE);
2036 vty_out(vty, " remote-ip %s%s",
2037 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
2038 vty_out(vty, " remote-port %u%s",
2039 gsmnet->gsup_server_port, VTY_NEWLINE);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01002040 if (gsmnet->msc_ipa_name)
2041 vty_out(vty, " ipa-name %s%s", gsmnet->msc_ipa_name, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002042 return CMD_SUCCESS;
2043}
2044
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02002045void msc_vty_init(struct gsm_network *msc_network)
2046{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01002047 OSMO_ASSERT(gsmnet == NULL);
2048 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002049
2050 osmo_stats_vty_add_cmds();
2051
2052 install_element(CONFIG_NODE, &cfg_net_cmd);
2053 install_node(&net_node, config_write_net);
2054 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
2055 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
2056 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
2057 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
2058 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
Neels Hofmeyr4dfb2ba2019-08-13 16:00:37 +02002059 install_element(GSMNET_NODE, &cfg_net_encryption_uea_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002060 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
2061 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
2062 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
2063 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
2064 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
2065 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
2066 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
2067 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Keith Whyte991bb422019-08-08 15:43:40 +02002068 install_element(GSMNET_NODE, &cfg_net_call_wait_cmd);
2069 install_element(GSMNET_NODE, &cfg_net_no_call_wait_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02002070
2071 install_element(CONFIG_NODE, &cfg_msc_cmd);
2072 install_node(&msc_node, config_write_msc);
Keith Whyte1587ffb2020-08-28 13:36:58 +02002073 install_element(MSC_NODE, &cfg_sms_database_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02002074 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01002075 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
2076 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02002077 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01002078 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Vadim Yanitskiy64623e12018-11-28 23:05:51 +07002079 install_element(MSC_NODE, &cfg_msc_ncss_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02002080 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01002081 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
2082 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Oliver Smith0fec28a2018-12-14 10:52:52 +01002083 install_element(MSC_NODE, &cfg_msc_check_imei_rqd_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02002084 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
2085 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01002086 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01002087 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +07002088 install_element(MSC_NODE, &cfg_msc_sms_over_gsup_cmd);
2089 install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd);
Pau Espin Pedrol4faff9e2019-05-06 19:29:11 +02002090 install_element(MSC_NODE, &cfg_msc_osmux_cmd);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01002091 install_element(MSC_NODE, &cfg_msc_handover_number_range_cmd);
Neels Hofmeyr9aac5c22020-05-27 00:04:26 +02002092 install_element(MSC_NODE, &cfg_msc_nri_bitlen_cmd);
2093 install_element(MSC_NODE, &cfg_msc_nri_add_cmd);
2094 install_element(MSC_NODE, &cfg_msc_nri_del_cmd);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01002095
2096 neighbor_ident_vty_init(msc_network);
Philipp Maierfbf66102017-04-09 12:32:51 +02002097
Vadim Yanitskiyffc7f392020-01-18 18:39:41 +07002098 /* Timer configuration commands (generic osmo_tdef API) */
2099 osmo_tdef_vty_groups_init(MSC_NODE, msc_tdef_group);
2100
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02002101 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02002102#ifdef BUILD_IU
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01002103 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 +02002104#endif
Harald Welte0df904d2018-12-03 11:00:04 +01002105 sgs_vty_init();
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01002106
Stefan Sperling617ac802018-02-22 17:58:20 +01002107 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002108
2109 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
2110
2111 install_element_ve(&show_subscr_cmd);
2112 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01002113 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002114 install_element_ve(&show_msc_conn_cmd);
2115 install_element_ve(&show_msc_transaction_cmd);
Neels Hofmeyr9aac5c22020-05-27 00:04:26 +02002116 install_element_ve(&show_nri_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002117
2118 install_element_ve(&sms_send_pend_cmd);
2119 install_element_ve(&sms_delete_expired_cmd);
2120
2121 install_element_ve(&subscriber_create_cmd);
2122 install_element_ve(&subscriber_send_sms_cmd);
2123 install_element_ve(&subscriber_silent_sms_cmd);
2124 install_element_ve(&subscriber_silent_call_start_cmd);
2125 install_element_ve(&subscriber_silent_call_stop_cmd);
2126 install_element_ve(&subscriber_ussd_notify_cmd);
2127 install_element_ve(&subscriber_mstest_close_cmd);
2128 install_element_ve(&subscriber_mstest_open_cmd);
2129 install_element_ve(&subscriber_paging_cmd);
2130 install_element_ve(&show_stats_cmd);
2131 install_element_ve(&show_smsqueue_cmd);
2132 install_element_ve(&logging_fltr_imsi_cmd);
2133
2134 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
2135 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
2136 install_element(ENABLE_NODE, &smsqueue_max_cmd);
2137 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
2138 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
2139 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01002140 install_element(ENABLE_NODE, &subscriber_sms_delete_all_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01002141
2142 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
2143 install_node(&mncc_int_node, config_write_mncc_int);
2144 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
2145 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
2146
2147 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
2148
2149 install_element(CONFIG_NODE, &cfg_hlr_cmd);
2150 install_node(&hlr_node, config_write_hlr);
2151 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
2152 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01002153 install_element(HLR_NODE, &cfg_hlr_ipa_name_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02002154}