blob: 5c58221a1376fecdfabb0cc4048c6939cb6b2b37 [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 Hofmeyr84da6b12016-05-20 21:59:55 +020036
Maxc51609a2018-11-09 17:13:00 +010037#include <osmocom/sigtran/sccp_helpers.h>
38
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020039#include <osmocom/vty/command.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010040#include <osmocom/vty/logging.h>
Stefan Sperling617ac802018-02-22 17:58:20 +010041#include <osmocom/vty/misc.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010042#include <osmocom/vty/stats.h>
43
Neels Hofmeyr00e82d62017-07-05 15:19:52 +020044#ifdef BUILD_IU
45#include <osmocom/ranap/iu_client.h>
46#endif
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020047
Neels Hofmeyr90843962017-09-04 15:04:35 +020048#include <osmocom/msc/vty.h>
49#include <osmocom/msc/gsm_data.h>
50#include <osmocom/msc/gsm_subscriber.h>
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010051#include <osmocom/msc/msub.h>
52#include <osmocom/msc/msc_a.h>
Neels Hofmeyr90843962017-09-04 15:04:35 +020053#include <osmocom/msc/vlr.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010054#include <osmocom/msc/transaction.h>
55#include <osmocom/msc/db.h>
56#include <osmocom/msc/sms_queue.h>
57#include <osmocom/msc/silent_call.h>
58#include <osmocom/msc/gsm_04_80.h>
59#include <osmocom/msc/gsm_04_14.h>
60#include <osmocom/msc/signal.h>
61#include <osmocom/msc/mncc_int.h>
Vadim Yanitskiy1b891302018-08-04 01:33:08 +070062#include <osmocom/msc/rrlp.h>
Harald Welte0df904d2018-12-03 11:00:04 +010063#include <osmocom/msc/vlr_sgs.h>
64#include <osmocom/msc/sgs_vty.h>
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010065#include <osmocom/msc/sccp_ran.h>
66#include <osmocom/msc/ran_peer.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010067
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010068static struct gsm_network *gsmnet = NULL;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010069
70struct cmd_node net_node = {
71 GSMNET_NODE,
72 "%s(config-net)# ",
73 1,
74};
75
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +010076#define VSUB_USE_VTY "VTY"
77
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010078#define NETWORK_STR "Configure the GSM network\n"
79#define CODE_CMD_STR "Code commands\n"
80#define NAME_CMD_STR "Name Commands\n"
81#define NAME_STR "Name to use\n"
82
83DEFUN(cfg_net,
84 cfg_net_cmd,
85 "network", NETWORK_STR)
86{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010087 vty->index = gsmnet;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010088 vty->node = GSMNET_NODE;
89
90 return CMD_SUCCESS;
91}
92
93DEFUN(cfg_net_ncc,
94 cfg_net_ncc_cmd,
95 "network country code <1-999>",
96 "Set the GSM network country code\n"
97 "Country commands\n"
98 CODE_CMD_STR
99 "Network Country Code to use\n")
100{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100101 gsmnet->plmn.mcc = atoi(argv[0]);
102
103 return CMD_SUCCESS;
104}
105
106DEFUN(cfg_net_mnc,
107 cfg_net_mnc_cmd,
108 "mobile network code <0-999>",
109 "Set the GSM mobile network code\n"
110 "Network Commands\n"
111 CODE_CMD_STR
112 "Mobile Network Code to use\n")
113{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100114 uint16_t mnc;
115 bool mnc_3_digits;
116
117 if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
118 vty_out(vty, "%% Error decoding MNC: %s%s", argv[0], VTY_NEWLINE);
119 return CMD_WARNING;
120 }
121
122 gsmnet->plmn.mnc = mnc;
123 gsmnet->plmn.mnc_3_digits = mnc_3_digits;
124
125 return CMD_SUCCESS;
126}
127
128DEFUN(cfg_net_name_short,
129 cfg_net_name_short_cmd,
130 "short name NAME",
131 "Set the short GSM network name\n" NAME_CMD_STR NAME_STR)
132{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100133 osmo_talloc_replace_string(gsmnet, &gsmnet->name_short, argv[0]);
134 return CMD_SUCCESS;
135}
136
137DEFUN(cfg_net_name_long,
138 cfg_net_name_long_cmd,
139 "long name NAME",
140 "Set the long GSM network name\n" NAME_CMD_STR NAME_STR)
141{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100142 osmo_talloc_replace_string(gsmnet, &gsmnet->name_long, argv[0]);
143 return CMD_SUCCESS;
144}
145
146DEFUN(cfg_net_encryption,
147 cfg_net_encryption_cmd,
148 "encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]",
149 "Encryption options\n"
150 "GSM A5 Air Interface Encryption\n"
151 "A5/n Algorithm Number\n"
152 "A5/n Algorithm Number\n"
153 "A5/n Algorithm Number\n"
154 "A5/n Algorithm Number\n")
155{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100156 unsigned int i;
157
158 gsmnet->a5_encryption_mask = 0;
159 for (i = 0; i < argc; i++)
160 gsmnet->a5_encryption_mask |= (1 << atoi(argv[i]));
161
162 return CMD_SUCCESS;
163}
164
165DEFUN(cfg_net_authentication,
166 cfg_net_authentication_cmd,
167 "authentication (optional|required)",
168 "Whether to enforce MS authentication in 2G\n"
169 "Allow MS to attach via 2G BSC without authentication\n"
170 "Always do authentication\n")
171{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100172 gsmnet->authentication_required = (argv[0][0] == 'r') ? true : false;
173
174 return CMD_SUCCESS;
175}
176
177DEFUN(cfg_net_rrlp_mode, cfg_net_rrlp_mode_cmd,
178 "rrlp mode (none|ms-based|ms-preferred|ass-preferred)",
179 "Radio Resource Location Protocol\n"
180 "Set the Radio Resource Location Protocol Mode\n"
181 "Don't send RRLP request\n"
182 "Request MS-based location\n"
183 "Request any location, prefer MS-based\n"
184 "Request any location, prefer MS-assisted\n")
185{
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700186 gsmnet->rrlp.mode = msc_rrlp_mode_parse(argv[0]);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100187
188 return CMD_SUCCESS;
189}
190
191DEFUN(cfg_net_mm_info, cfg_net_mm_info_cmd,
192 "mm info (0|1)",
193 "Mobility Management\n"
194 "Send MM INFO after LOC UPD ACCEPT\n"
195 "Disable\n" "Enable\n")
196{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100197 gsmnet->send_mm_info = atoi(argv[0]);
198
199 return CMD_SUCCESS;
200}
201
202DEFUN(cfg_net_timezone,
203 cfg_net_timezone_cmd,
204 "timezone <-19-19> (0|15|30|45)",
205 "Set the Timezone Offset of the network\n"
206 "Timezone offset (hours)\n"
207 "Timezone offset (00 minutes)\n"
208 "Timezone offset (15 minutes)\n"
209 "Timezone offset (30 minutes)\n"
210 "Timezone offset (45 minutes)\n"
211 )
212{
213 struct gsm_network *net = vty->index;
214 int tzhr = atoi(argv[0]);
215 int tzmn = atoi(argv[1]);
216
217 net->tz.hr = tzhr;
218 net->tz.mn = tzmn;
219 net->tz.dst = 0;
220 net->tz.override = 1;
221
222 return CMD_SUCCESS;
223}
224
225DEFUN(cfg_net_timezone_dst,
226 cfg_net_timezone_dst_cmd,
227 "timezone <-19-19> (0|15|30|45) <0-2>",
228 "Set the Timezone Offset of the network\n"
229 "Timezone offset (hours)\n"
230 "Timezone offset (00 minutes)\n"
231 "Timezone offset (15 minutes)\n"
232 "Timezone offset (30 minutes)\n"
233 "Timezone offset (45 minutes)\n"
234 "DST offset (hours)\n"
235 )
236{
237 struct gsm_network *net = vty->index;
238 int tzhr = atoi(argv[0]);
239 int tzmn = atoi(argv[1]);
240 int tzdst = atoi(argv[2]);
241
242 net->tz.hr = tzhr;
243 net->tz.mn = tzmn;
244 net->tz.dst = tzdst;
245 net->tz.override = 1;
246
247 return CMD_SUCCESS;
248}
249
250DEFUN(cfg_net_no_timezone,
251 cfg_net_no_timezone_cmd,
252 "no timezone",
253 NO_STR
254 "Disable network timezone override, use system tz\n")
255{
256 struct gsm_network *net = vty->index;
257
258 net->tz.override = 0;
259
260 return CMD_SUCCESS;
261}
262
263DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
264 "periodic location update <6-1530>",
265 "Periodic Location Updating Interval\n"
266 "Periodic Location Updating Interval\n"
267 "Periodic Location Updating Interval\n"
268 "Periodic Location Updating Interval in Minutes\n")
269{
270 struct gsm_network *net = vty->index;
271
272 net->t3212 = atoi(argv[0]) / 6;
273
274 return CMD_SUCCESS;
275}
276
277DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
278 "no periodic location update",
279 NO_STR
280 "Periodic Location Updating Interval\n"
281 "Periodic Location Updating Interval\n"
282 "Periodic Location Updating Interval\n")
283{
284 struct gsm_network *net = vty->index;
285
286 net->t3212 = 0;
287
288 return CMD_SUCCESS;
289}
290
291static int config_write_net(struct vty *vty)
292{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100293 int i;
294
295 vty_out(vty, "network%s", VTY_NEWLINE);
296 vty_out(vty, " network country code %s%s", osmo_mcc_name(gsmnet->plmn.mcc), VTY_NEWLINE);
297 vty_out(vty, " mobile network code %s%s",
298 osmo_mnc_name(gsmnet->plmn.mnc, gsmnet->plmn.mnc_3_digits), VTY_NEWLINE);
299 vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
300 vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
301 vty_out(vty, " encryption a5");
302 for (i = 0; i < 8; i++) {
303 if (gsmnet->a5_encryption_mask & (1 << i))
304 vty_out(vty, " %u", i);
305 }
306 vty_out(vty, "%s", VTY_NEWLINE);
307 vty_out(vty, " authentication %s%s",
308 gsmnet->authentication_required ? "required" : "optional", VTY_NEWLINE);
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700309 vty_out(vty, " rrlp mode %s%s", msc_rrlp_mode_name(gsmnet->rrlp.mode),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100310 VTY_NEWLINE);
311 vty_out(vty, " mm info %u%s", gsmnet->send_mm_info, VTY_NEWLINE);
312 if (gsmnet->tz.override != 0) {
313 if (gsmnet->tz.dst)
314 vty_out(vty, " timezone %d %d %d%s",
315 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
316 VTY_NEWLINE);
317 else
318 vty_out(vty, " timezone %d %d%s",
319 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
320 }
321 if (gsmnet->t3212 == 0)
322 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
323 else
324 vty_out(vty, " periodic location update %u%s",
325 gsmnet->t3212 * 6, VTY_NEWLINE);
326
327 if (gsmnet->emergency.route_to_msisdn) {
328 vty_out(vty, " emergency-call route-to-msisdn %s%s",
329 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
330 }
331
332 return CMD_SUCCESS;
333}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200334
335static struct cmd_node msc_node = {
336 MSC_NODE,
337 "%s(config-msc)# ",
338 1,
339};
340
341DEFUN(cfg_msc, cfg_msc_cmd,
342 "msc", "Configure MSC options")
343{
344 vty->node = MSC_NODE;
345 return CMD_SUCCESS;
346}
347
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100348#define MNCC_STR "Configure Mobile Network Call Control\n"
349#define MNCC_GUARD_TIMEOUT_STR "Set global guard timer for mncc interface activity\n"
350#define MNCC_GUARD_TIMEOUT_VALUE_STR "guard timer value (sec.)\n"
351
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100352DEFUN(cfg_msc_mncc_internal,
353 cfg_msc_mncc_internal_cmd,
354 "mncc internal",
355 MNCC_STR "Use internal MNCC handler (default; changes need a program restart)\n")
356{
357 gsm_network_set_mncc_sock_path(gsmnet, NULL);
358 return CMD_SUCCESS;
359}
360
361DEFUN(cfg_msc_mncc_external,
362 cfg_msc_mncc_external_cmd,
363 "mncc external MNCC_SOCKET_PATH",
364 MNCC_STR "Use external MNCC handler (changes need a program restart)\n"
365 "File system path to create the MNCC unix domain socket at\n")
366{
367 gsm_network_set_mncc_sock_path(gsmnet, argv[0]);
368 return CMD_SUCCESS;
369}
370
Philipp Maier9ca7b312018-10-10 17:00:49 +0200371DEFUN(cfg_msc_mncc_guard_timeout,
372 cfg_msc_mncc_guard_timeout_cmd,
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100373 "mncc guard-timeout <0-255>",
374 MNCC_STR
375 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR)
Philipp Maier9ca7b312018-10-10 17:00:49 +0200376{
377 gsmnet->mncc_guard_timeout = atoi(argv[0]);
378 return CMD_SUCCESS;
379}
380
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100381ALIAS_DEPRECATED(cfg_msc_mncc_guard_timeout,
382 cfg_msc_deprecated_mncc_guard_timeout_cmd,
383 "mncc-guard-timeout <0-255>",
384 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR);
385
Vadim Yanitskiy64623e12018-11-28 23:05:51 +0700386#define NCSS_STR "Configure call independent Supplementary Services\n"
387
388DEFUN(cfg_msc_ncss_guard_timeout,
389 cfg_msc_ncss_guard_timeout_cmd,
390 "ncss guard-timeout <0-255>",
391 NCSS_STR "Set guard timer for session activity\n"
392 "guard timer value (sec.), or 0 to disable\n")
393{
394 gsmnet->ncss_guard_timeout = atoi(argv[0]);
395 return CMD_SUCCESS;
396}
397
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200398DEFUN(cfg_msc_assign_tmsi, cfg_msc_assign_tmsi_cmd,
399 "assign-tmsi",
400 "Assign TMSI during Location Updating.\n")
401{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200402 gsmnet->vlr->cfg.assign_tmsi = true;
403 return CMD_SUCCESS;
404}
405
406DEFUN(cfg_msc_no_assign_tmsi, cfg_msc_no_assign_tmsi_cmd,
407 "no assign-tmsi",
408 NO_STR "Assign TMSI during Location Updating.\n")
409{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200410 gsmnet->vlr->cfg.assign_tmsi = false;
411 return CMD_SUCCESS;
412}
413
Philipp Maierfbf66102017-04-09 12:32:51 +0200414DEFUN(cfg_msc_cs7_instance_a,
415 cfg_msc_cs7_instance_a_cmd,
416 "cs7-instance-a <0-15>",
417 "Set SS7 to be used by the A-Interface.\n" "SS7 instance reference number\n")
418{
Philipp Maierfbf66102017-04-09 12:32:51 +0200419 gsmnet->a.cs7_instance = atoi(argv[0]);
420 return CMD_SUCCESS;
421}
422
423DEFUN(cfg_msc_cs7_instance_iu,
424 cfg_msc_cs7_instance_iu_cmd,
425 "cs7-instance-iu <0-15>",
426 "Set SS7 to be used by the Iu-Interface.\n" "SS7 instance reference number\n")
427{
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100428#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200429 gsmnet->iu.cs7_instance = atoi(argv[0]);
430 return CMD_SUCCESS;
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100431#else
432 vty_out(vty, "WARNING: 'cs7-instance-iu' without effect: built without Iu support%s",
433 VTY_NEWLINE);
434 return CMD_WARNING;
435#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200436}
437
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100438DEFUN(cfg_msc_auth_tuple_max_reuse_count, cfg_msc_auth_tuple_max_reuse_count_cmd,
439 "auth-tuple-max-reuse-count <-1-2147483647>",
440 "Configure authentication tuple re-use\n"
441 "0 to use each auth tuple at most once (default), >0 to limit re-use, -1 to re-use infinitely (vulnerable!).\n")
442{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100443 gsmnet->vlr->cfg.auth_tuple_max_reuse_count = atoi(argv[0]);
444 return CMD_SUCCESS;
445}
446
447DEFUN(cfg_msc_auth_tuple_reuse_on_error, cfg_msc_auth_tuple_reuse_on_error_cmd,
448 "auth-tuple-reuse-on-error (0|1)",
449 "Configure authentication tuple re-use when HLR is not responsive\n"
Oliver Smithd6e24fd2019-01-09 10:46:43 +0100450 "Never re-use auth tuples beyond auth-tuple-max-reuse-count (default)\n"
451 "If the HLR does not deliver new tuples, do re-use already available old ones.\n")
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100452{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100453 gsmnet->vlr->cfg.auth_reuse_old_sets_on_error = atoi(argv[0]) ? true : false;
454 return CMD_SUCCESS;
455}
456
Oliver Smith0fec28a2018-12-14 10:52:52 +0100457DEFUN(cfg_msc_check_imei_rqd, cfg_msc_check_imei_rqd_cmd,
Oliver Smith03ded912019-05-02 10:40:50 +0200458 "check-imei-rqd (0|1|early)",
Oliver Smith0fec28a2018-12-14 10:52:52 +0100459 "Send each IMEI to the EIR to ask if it is permitted or not. The EIR is implemented as part of OsmoHLR, "
460 "and can optionally save the IMEI in the HLR.\n"
461 "Do not send IMEIs to the EIR\n"
Oliver Smith03ded912019-05-02 10:40:50 +0200462 "Send each IMEI to the EIR\n"
463 "Send each IMEI to the EIR, and do it at the start of the location update. This allows the EIR to receive the"
464 " 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 +0100465{
Oliver Smith03ded912019-05-02 10:40:50 +0200466 if (strcmp(argv[0], "0") == 0) {
467 gsmnet->vlr->cfg.check_imei_rqd = false;
468 gsmnet->vlr->cfg.retrieve_imeisv_early = false;
469 } else if (strcmp(argv[0], "1") == 0) {
470 gsmnet->vlr->cfg.check_imei_rqd = true;
471 gsmnet->vlr->cfg.retrieve_imeisv_early = false;
472 } else if (strcmp(argv[0], "early") == 0) {
473 gsmnet->vlr->cfg.check_imei_rqd = true;
474 gsmnet->vlr->cfg.retrieve_imeisv_early = true;
475 }
Oliver Smith0fec28a2018-12-14 10:52:52 +0100476 return CMD_SUCCESS;
477}
478
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100479DEFUN(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd,
480 "paging response-timer (default|<1-65535>)",
481 "Configure Paging\n"
482 "Set Paging timeout, the minimum time to pass between (unsuccessful) Pagings sent towards"
483 " BSS or RNC\n"
484 "Set to default timeout (" OSMO_STRINGIFY_VAL(MSC_PAGING_RESPONSE_TIMER_DEFAULT) " seconds)\n"
485 "Set paging timeout in seconds\n")
486{
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100487 if (!strcmp(argv[1], "default"))
488 gsmnet->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
489 else
490 gsmnet->paging_response_timer = atoi(argv[0]);
491 return CMD_SUCCESS;
492}
493
Harald Welte69c54a82018-02-09 20:41:14 +0100494DEFUN(cfg_msc_emergency_msisdn, cfg_msc_emergency_msisdn_cmd,
495 "emergency-call route-to-msisdn MSISDN",
496 "Configure Emergency Call Behaviour\n"
497 "MSISDN to which Emergency Calls are Dispatched\n"
498 "MSISDN (E.164 Phone Number)\n")
499{
Harald Welte69c54a82018-02-09 20:41:14 +0100500 osmo_talloc_replace_string(gsmnet, &gsmnet->emergency.route_to_msisdn, argv[0]);
501
502 return CMD_SUCCESS;
503}
504
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700505/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
506DEFUN(cfg_msc_sms_over_gsup, cfg_msc_sms_over_gsup_cmd,
507 "sms-over-gsup",
508 "Enable routing of SMS messages over GSUP\n")
509{
510 gsmnet->sms_over_gsup = true;
511 return CMD_SUCCESS;
512}
513
514/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
515DEFUN(cfg_msc_no_sms_over_gsup, cfg_msc_no_sms_over_gsup_cmd,
516 "no sms-over-gsup",
517 NO_STR "Disable routing of SMS messages over GSUP\n")
518{
519 gsmnet->sms_over_gsup = false;
520 return CMD_SUCCESS;
521}
522
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100523/* FIXME: This should rather be in the form of
524 * handover-number range 001234xxx
525 * and
526 * handover-number range 001234xxx FIRST LAST
527 */
528DEFUN(cfg_msc_handover_number_range, cfg_msc_handover_number_range_cmd,
529 "handover-number range MSISDN_FIRST MSISDN_LAST",
530 "Configure a range of MSISDN to be assigned to incoming inter-MSC Handovers for call forwarding.\n"
531 "Configure a handover number range\n"
532 "First Handover Number MSISDN\n"
533 "Last Handover Number MSISDN\n")
534{
535 char *endp;
536 uint64_t range_start;
537 uint64_t range_end;
538
539 /* FIXME leading zeros?? */
540
541 errno = 0;
542 range_start = strtoull(argv[0], &endp, 10);
543 if (errno || *endp != '\0') {
544 vty_out(vty, "%% Error parsing handover-number range start: %s%s",
545 argv[0], VTY_NEWLINE);
546 return CMD_WARNING;
547 }
548
549 errno = 0;
550 range_end = strtoull(argv[1], &endp, 10);
551 if (errno || *endp != '\0') {
552 vty_out(vty, "%% Error parsing handover-number range end: %s%s",
553 argv[1], VTY_NEWLINE);
554 return CMD_WARNING;
555 }
556
557 if (range_start > range_end) {
558 vty_out(vty, "%% Error: handover-number range end must be > than the range start, but"
559 " %"PRIu64" > %"PRIu64"%s", range_start, range_end, VTY_NEWLINE);
560 return CMD_WARNING;
561 }
562
563 gsmnet->handover_number.range_start = range_start;
564 gsmnet->handover_number.range_end = range_end;
565 return CMD_SUCCESS;
566}
567
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200568static int config_write_msc(struct vty *vty)
569{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200570 vty_out(vty, "msc%s", VTY_NEWLINE);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100571 if (gsmnet->mncc_sock_path)
572 vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE);
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100573 vty_out(vty, " mncc guard-timeout %i%s",
Philipp Maier9ca7b312018-10-10 17:00:49 +0200574 gsmnet->mncc_guard_timeout, VTY_NEWLINE);
Vadim Yanitskiy64623e12018-11-28 23:05:51 +0700575 vty_out(vty, " ncss guard-timeout %i%s",
576 gsmnet->ncss_guard_timeout, VTY_NEWLINE);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200577 vty_out(vty, " %sassign-tmsi%s",
578 gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
579
Philipp Maierfbf66102017-04-09 12:32:51 +0200580 vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
581 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100582#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200583 vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance,
584 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100585#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200586
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100587 if (gsmnet->vlr->cfg.auth_tuple_max_reuse_count)
588 vty_out(vty, " auth-tuple-max-reuse-count %d%s",
589 OSMO_MAX(-1, gsmnet->vlr->cfg.auth_tuple_max_reuse_count),
590 VTY_NEWLINE);
591 if (gsmnet->vlr->cfg.auth_reuse_old_sets_on_error)
592 vty_out(vty, " auth-tuple-reuse-on-error 1%s",
593 VTY_NEWLINE);
594
Oliver Smith03ded912019-05-02 10:40:50 +0200595 if (gsmnet->vlr->cfg.check_imei_rqd) {
596 if (gsmnet->vlr->cfg.retrieve_imeisv_early)
597 vty_out(vty, " check-imei-rqd early%s", VTY_NEWLINE);
598 else
599 vty_out(vty, " check-imei-rqd 1%s", VTY_NEWLINE);
600 }
Oliver Smith0fec28a2018-12-14 10:52:52 +0100601
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100602 if (gsmnet->paging_response_timer != MSC_PAGING_RESPONSE_TIMER_DEFAULT)
603 vty_out(vty, " paging response-timer %u%s", gsmnet->paging_response_timer, VTY_NEWLINE);
604
Harald Welte69c54a82018-02-09 20:41:14 +0100605 if (gsmnet->emergency.route_to_msisdn) {
606 vty_out(vty, " emergency-call route-to-msisdn %s%s",
607 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
608 }
609
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700610 if (gsmnet->sms_over_gsup)
611 vty_out(vty, " sms-over-gsup%s", VTY_NEWLINE);
612
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100613 if (gsmnet->handover_number.range_start || gsmnet->handover_number.range_end)
614 vty_out(vty, " handover-number range %"PRIu64" %"PRIu64"%s",
615 gsmnet->handover_number.range_start, gsmnet->handover_number.range_end,
616 VTY_NEWLINE);
617
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +0200618 mgcp_client_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200619#ifdef BUILD_IU
Neels Hofmeyr00e82d62017-07-05 15:19:52 +0200620 ranap_iu_vty_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200621#endif
622
Neels Hofmeyr880b9502019-05-09 02:01:55 +0200623 neighbor_ident_vty_write(vty);
624
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200625 return CMD_SUCCESS;
626}
627
Maxc51609a2018-11-09 17:13:00 +0100628DEFUN(show_bsc, show_bsc_cmd,
629 "show bsc", SHOW_STR "BSC\n")
630{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100631 struct ran_peer *rp;
632 llist_for_each_entry(rp, &gsmnet->a.sri->ran_peers, entry) {
633 vty_out(vty, "BSC %s %s%s",
634 osmo_sccp_inst_addr_name(gsmnet->a.sri->sccp, &rp->peer_addr),
635 osmo_fsm_inst_state_name(rp->fi),
636 VTY_NEWLINE);
Maxc51609a2018-11-09 17:13:00 +0100637 }
638
639 return CMD_SUCCESS;
640}
641
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100642/*
643_Subscriber_______________________________________ _LAC_ _RAN___________________ _MSC-A_state_________ _MSC-A_use_
644IMSI-123456789012345:MSISDN-12345:TMSI-0x12345678 1 GERAN-A-4294967295:A5-3 WAIT_CLASSMARK_UPDATE 2=cm_service,trans_cc
645IMSI-123456789012356:MSISDN-234567:TMSI-0x123ABC78 65535 UTRAN-Iu-4294967295 COMMUNICATING 2=cm_service,trans_sms
646IMSI-123456789012367:MSISDN-98712345890:TMSI-0xF.. - EUTRAN-SGs RELEASING 0=none
647IMSI-123456789012378:HONR-12345432101 2 MSC-901-700-423:9876 REMOTE_MSC_A 1=inter_msc
648*/
649static void vty_dump_one_conn(struct vty *vty, const struct msub *msub, int *idx)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100650{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100651 struct msc_a *msc_a = msub_msc_a(msub);
652 struct vlr_subscr *vsub = msub_vsub(msub);
653 char buf[128];
Max45df98b2019-01-17 18:44:33 +0100654
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100655 if (!(*idx))
656 vty_out(vty,
657 "_Subscriber_______________________________________ _LAC_ _RAN___________________"
658 " _MSC-A_state_________ _MSC-A_use_%s",
Max45df98b2019-01-17 18:44:33 +0100659 VTY_NEWLINE);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100660 (*idx)++;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100661
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100662 vty_out(vty, "%50s %5u %23s %20s %d=%s%s",
663 vlr_subscr_short_name(msub_vsub(msub), 50),
664 vsub ? vsub->cgi.lai.lac : 0,
665 msub_ran_conn_name(msub),
666 osmo_fsm_inst_state_name(msc_a->c.fi),
667 osmo_use_count_total(&msc_a->use_count),
668 osmo_use_count_name_buf(buf, sizeof(buf), &msc_a->use_count),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100669 VTY_NEWLINE);
670}
671
672DEFUN(show_msc_conn, show_msc_conn_cmd,
673 "show connection", SHOW_STR "Subscriber Connections\n")
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200674{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100675 struct msub *msub;
676 int idx = 0;
677 llist_for_each_entry(msub, &msub_list, entry) {
678 vty_dump_one_conn(vty, msub, &idx);
679 }
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100680 return CMD_SUCCESS;
681}
682
683static void vty_trans_hdr(struct vty *vty)
684{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100685 if (llist_empty(&gsmnet->trans_list))
686 return;
Max45df98b2019-01-17 18:44:33 +0100687
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100688 vty_out(vty,
689 "_Subscriber_______________________________________ _RAN___________________"
690 " _P__ TI CallRef_ _state_%s",
691 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100692}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200693
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100694static const char *get_trans_proto_str(const struct gsm_trans *trans)
695{
696 static char buf[256];
697
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100698 switch (trans->type) {
699 case TRANS_CC:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100700 snprintf(buf, sizeof(buf), "%s %4u %4u",
701 gsm48_cc_state_name(trans->cc.state),
702 trans->cc.Tcurrent,
703 trans->cc.T308_second);
704 break;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100705 case TRANS_SMS:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100706 snprintf(buf, sizeof(buf), "%s %s",
707 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
708 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
709 break;
710 default:
711 buf[0] = '\0';
712 break;
713 }
714
715 return buf;
716}
717
718static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
719{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100720 vty_out(vty, "%50s %23s %4s %02u %08x %s%s",
721 vlr_subscr_short_name(msc_a_vsub(trans->msc_a), 50),
722 msub_ran_conn_name(trans->msc_a->c.msub),
723 trans_type_name(trans->type),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100724 trans->transaction_id,
725 trans->callref,
Max45df98b2019-01-17 18:44:33 +0100726 get_trans_proto_str(trans),
Max45df98b2019-01-17 18:44:33 +0100727 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100728}
729
730DEFUN(show_msc_transaction, show_msc_transaction_cmd,
731 "show transaction", SHOW_STR "Transactions\n")
732{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100733 struct gsm_trans *trans;
734
735 vty_trans_hdr(vty);
736 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
737 vty_dump_one_trans(vty, trans);
738
739 return CMD_SUCCESS;
740}
741
742static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
743{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100744 struct gsm_trans *trans;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100745 char buf[128];
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100746
747 if (strlen(vsub->name))
748 vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
749 if (strlen(vsub->msisdn))
750 vty_out(vty, " Extension: %s%s", vsub->msisdn,
751 VTY_NEWLINE);
752 vty_out(vty, " LAC: %d/0x%x%s",
Max7d41d872018-12-19 11:48:33 +0100753 vsub->cgi.lai.lac, vsub->cgi.lai.lac, VTY_NEWLINE);
Philipp Maier2a0ac3b2018-12-17 10:03:50 +0100754 vty_out(vty, " RAN: %s%s",
Neels Hofmeyr7814a832018-12-26 00:40:18 +0100755 osmo_rat_type_name(vsub->cs.attached_via_ran), VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100756 vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
757 if (vsub->tmsi != GSM_RESERVED_TMSI)
758 vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
759 VTY_NEWLINE);
760 if (vsub->tmsi_new != GSM_RESERVED_TMSI)
761 vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
762 VTY_NEWLINE);
Philipp Maier6d71ccf2018-12-14 13:30:14 +0100763 if (vsub->imei[0] != '\0')
764 vty_out(vty, " IMEI: %s%s", vsub->imei, VTY_NEWLINE);
765 if (vsub->imeisv[0] != '\0')
766 vty_out(vty, " IMEISV: %s%s", vsub->imeisv, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100767
Philipp Maier89561bc2018-12-14 13:34:25 +0100768 vty_out(vty, " Flags: %s", VTY_NEWLINE);
769 vty_out(vty, " IMSI detached: %s%s",
770 vsub->imsi_detached_flag ? "true" : "false", VTY_NEWLINE);
771 vty_out(vty, " Conf. by radio contact: %s%s",
772 vsub->conf_by_radio_contact_ind ? "true" : "false",
773 VTY_NEWLINE);
774 vty_out(vty, " Subscr. data conf. by HLR: %s%s",
775 vsub->sub_dataconf_by_hlr_ind ? "true" : "false", VTY_NEWLINE);
776 vty_out(vty, " Location conf. in HLR: %s%s",
777 vsub->loc_conf_in_hlr_ind ? "true" : "false", VTY_NEWLINE);
778 vty_out(vty, " Subscriber dormant: %s%s",
779 vsub->dormant_ind ? "true" : "false", VTY_NEWLINE);
780 vty_out(vty, " Received cancel locataion: %s%s",
781 vsub->cancel_loc_rx ? "true" : "false", VTY_NEWLINE);
782 vty_out(vty, " MS not reachable: %s%s",
783 vsub->ms_not_reachable_flag ? "true" : "false", VTY_NEWLINE);
784 vty_out(vty, " LA allowed: %s%s",
785 vsub->la_allowed ? "true" : "false", VTY_NEWLINE);
786
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100787 if (vsub->last_tuple) {
Neels Hofmeyr8b6e5362018-11-30 02:57:33 +0100788 struct vlr_auth_tuple *t = vsub->last_tuple;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100789 vty_out(vty, " A3A8 last tuple (used %d times):%s",
790 t->use_count, VTY_NEWLINE);
791 vty_out(vty, " seq # : %d%s",
792 t->key_seq, VTY_NEWLINE);
793 vty_out(vty, " RAND : %s%s",
794 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
795 VTY_NEWLINE);
796 vty_out(vty, " SRES : %s%s",
797 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
798 VTY_NEWLINE);
799 vty_out(vty, " Kc : %s%s",
800 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
801 VTY_NEWLINE);
802 }
803
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100804 vty_out(vty, " Paging: %s paging for %d requests%s",
Vadim Yanitskiy56e722f2019-05-16 01:53:31 +0700805 vsub->cs.is_paging ? "is" : "not",
806 llist_count(&vsub->cs.requests),
807 VTY_NEWLINE);
Harald Welte0df904d2018-12-03 11:00:04 +0100808
809 /* SGs related */
810 vty_out(vty, " SGs-state: %s%s",
811 osmo_fsm_inst_state_name(vsub->sgs_fsm), VTY_NEWLINE);
Vadim Yanitskiy477cbc62019-02-23 16:59:16 +0700812 if (strlen(vsub->sgs.mme_name))
Harald Welte0df904d2018-12-03 11:00:04 +0100813 vty_out(vty, " SGs-MME: %s%s", vsub->sgs.mme_name, VTY_NEWLINE);
814 else
815 vty_out(vty, " SGs-MME: (none)%s", VTY_NEWLINE);
816
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100817 vty_out(vty, " Use: %s%s", osmo_use_count_name_buf(buf, sizeof(buf), &vsub->use_count), VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100818
819 /* Connection */
820 if (vsub->msc_conn_ref) {
Vadim Yanitskiy23d42d62019-05-16 00:56:30 +0700821 struct msub *msub = msub_for_vsub(vsub);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100822 int idx = 0;
823 if (msub) {
824 vty_dump_one_conn(vty, msub, &idx);
825 }
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100826 }
827
828 /* Transactions */
829 vty_trans_hdr(vty);
830 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
831 if (trans->vsub != vsub)
832 continue;
833 vty_dump_one_trans(vty, trans);
834 }
835}
836
837/* Subscriber */
838DEFUN(show_subscr_cache,
839 show_subscr_cache_cmd,
840 "show subscriber cache",
841 SHOW_STR "Show information about subscribers\n"
842 "Display contents of subscriber cache\n")
843{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100844 struct vlr_subscr *vsub;
845 int count = 0;
846
847 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
848 if (++count > 100) {
849 vty_out(vty, "%% More than %d subscribers in cache,"
850 " stopping here.%s", count-1, VTY_NEWLINE);
851 break;
852 }
853 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
854 subscr_dump_full_vty(vty, vsub);
Harald Welte69c54a82018-02-09 20:41:14 +0100855 }
856
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200857 return CMD_SUCCESS;
858}
859
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100860DEFUN(sms_send_pend,
861 sms_send_pend_cmd,
862 "sms send pending",
863 "SMS related commands\n" "SMS Sending related commands\n"
864 "Send all pending SMS")
865{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100866 struct gsm_sms *sms;
867 unsigned long long sms_id = 0;
868
869 while (1) {
870 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
871 if (!sms)
872 break;
873
874 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700875 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100876
877 sms_id = sms->id + 1;
878 }
879
880 return CMD_SUCCESS;
881}
882
883DEFUN(sms_delete_expired,
884 sms_delete_expired_cmd,
885 "sms delete expired",
886 "SMS related commands\n" "SMS Database related commands\n"
887 "Delete all expired SMS")
888{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100889 struct gsm_sms *sms;
890 unsigned long long sms_id = 0;
891 long long num_deleted = 0;
892
893 while (1) {
894 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
895 if (!sms)
896 break;
897
898 /* Skip SMS which are currently queued for sending. */
899 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
900 continue;
901
902 /* Expiration check is performed by the DB layer. */
903 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
904 num_deleted++;
905
906 sms_id = sms->id + 1;
907 }
908
909 if (num_deleted == 0) {
910 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
911 return CMD_WARNING;
912 }
913
914 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
915 return CMD_SUCCESS;
916}
917
918static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +0200919 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100920 char *str, uint8_t tp_pid)
921{
922 struct gsm_network *net = receiver->vlr->user_ctx;
923 struct gsm_sms *sms;
924
Harald Welte39b55482018-04-09 19:19:33 +0200925 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100926 sms->protocol_id = tp_pid;
927
928 /* store in database for the queue */
929 if (db_sms_store(sms) != 0) {
930 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
931 sms_free(sms);
932 return CMD_WARNING;
933 }
934 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
935
936 sms_free(sms);
937 sms_queue_trigger(net->sms_queue);
938 return CMD_SUCCESS;
939}
940
941static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
942 const char *type,
943 const char *id)
944{
945 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100946 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100947 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100948 return vlr_subscr_find_by_imsi(gsmnet->vlr, id, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100949 else if (!strcmp(type, "tmsi"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100950 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id), VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100951
952 return NULL;
953}
954#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
955#define SUBSCR_HELP "Operations on a Subscriber\n" \
956 "Identify subscriber by MSISDN (phone number)\n" \
957 "Legacy alias for 'msisdn'\n" \
958 "Identify subscriber by IMSI\n" \
959 "Identify subscriber by TMSI\n" \
Vadim Yanitskiy3ccd8232019-05-16 01:35:23 +0700960 "Legacy alias for 'imsi'\n" \
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100961 "Identifier for the subscriber\n"
962
963DEFUN(show_subscr,
964 show_subscr_cmd,
965 "show subscriber " SUBSCR_TYPES " ID",
966 SHOW_STR SUBSCR_HELP)
967{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100968 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
969 argv[1]);
970
971 if (!vsub) {
972 vty_out(vty, "%% No subscriber found for %s %s%s",
973 argv[0], argv[1], VTY_NEWLINE);
974 return CMD_WARNING;
975 }
976
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100977 /* In the vty output to the user, exclude this local use count added by vlr_subscr_get() in get_vsub_by_argv().
978 * This works, because: for get_vsub_by_argv() to succeed, there *must* have been at least one use count before
979 * 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 +0100980 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100981
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100982 subscr_dump_full_vty(vty, vsub);
983
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100984 return CMD_SUCCESS;
985}
986
987DEFUN(subscriber_create,
988 subscriber_create_cmd,
989 "subscriber create imsi ID",
990 "Operations on a Subscriber\n" \
991 "Create new subscriber\n" \
992 "Identify the subscriber by his IMSI\n" \
993 "Identifier for the subscriber\n")
994{
995 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
996 VTY_NEWLINE);
997 return CMD_WARNING;
998}
999
1000DEFUN(subscriber_send_pending_sms,
1001 subscriber_send_pending_sms_cmd,
1002 "subscriber " SUBSCR_TYPES " ID sms pending-send",
1003 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
1004{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001005 struct vlr_subscr *vsub;
1006 struct gsm_sms *sms;
1007
1008 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1009 if (!vsub) {
1010 vty_out(vty, "%% No subscriber found for %s %s%s",
1011 argv[0], argv[1], VTY_NEWLINE);
1012 return CMD_WARNING;
1013 }
1014
1015 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
1016 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +07001017 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001018
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001019 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001020
1021 return CMD_SUCCESS;
1022}
1023
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001024DEFUN(subscriber_sms_delete_all,
1025 subscriber_sms_delete_all_cmd,
1026 "subscriber " SUBSCR_TYPES " ID sms delete-all",
1027 SUBSCR_HELP "SMS Operations\n"
1028 "Delete all SMS to be delivered to this subscriber"
1029 " -- WARNING: the SMS data for all unsent SMS for this subscriber"
1030 " WILL BE LOST.\n")
1031{
1032 struct vlr_subscr *vsub;
1033
1034 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1035 if (!vsub) {
1036 vty_out(vty, "%% No subscriber found for %s %s%s",
1037 argv[0], argv[1], VTY_NEWLINE);
1038 return CMD_WARNING;
1039 }
1040
1041 db_sms_delete_by_msisdn(vsub->msisdn);
1042
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001043 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001044
1045 return CMD_SUCCESS;
1046}
1047
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001048DEFUN(subscriber_send_sms,
1049 subscriber_send_sms_cmd,
1050 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
1051 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
1052{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001053 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +02001054 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001055 char *str;
1056 int rc;
1057
1058 if (!vsub) {
1059 vty_out(vty, "%% No subscriber found for %s %s%s",
1060 argv[0], argv[1], VTY_NEWLINE);
1061 rc = CMD_WARNING;
1062 goto err;
1063 }
1064
Harald Welte39b55482018-04-09 19:19:33 +02001065 if (!strcmp(argv[2], "msisdn"))
1066 sender_msisdn = argv[3];
1067 else {
1068 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1069 if (!sender) {
1070 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1071 rc = CMD_WARNING;
1072 goto err;
1073 }
1074 sender_msisdn = sender->msisdn;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001075 vlr_subscr_put(sender, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001076 }
1077
1078 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001079 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001080 talloc_free(str);
1081
1082err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001083 if (vsub)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001084 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001085
1086 return rc;
1087}
1088
1089DEFUN(subscriber_silent_sms,
1090 subscriber_silent_sms_cmd,
1091
1092 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
1093 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
1094{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001095 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +02001096 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001097 char *str;
1098 int rc;
1099
1100 if (!vsub) {
1101 vty_out(vty, "%% No subscriber found for %s %s%s",
1102 argv[0], argv[1], VTY_NEWLINE);
1103 rc = CMD_WARNING;
1104 goto err;
1105 }
1106
Harald Welte39b55482018-04-09 19:19:33 +02001107 if (!strcmp(argv[2], "msisdn")) {
1108 sender_msisdn = argv[3];
1109 } else {
1110 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1111 if (!sender) {
1112 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1113 rc = CMD_WARNING;
1114 goto err;
1115 }
1116 sender_msisdn = sender->msisdn;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001117 vlr_subscr_put(sender, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001118 }
1119
1120 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001121 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001122 talloc_free(str);
1123
1124err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001125 if (vsub)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001126 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001127
1128 return rc;
1129}
1130
Sylvain Munaut93558302019-02-14 20:13:08 +01001131#define CHAN_TYPES "(any|tch/f|tch/h|tch/any|sdcch)"
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001132#define CHAN_TYPE_HELP \
1133 "Any channel\n" \
1134 "TCH/F channel\n" \
Sylvain Munaut93558302019-02-14 20:13:08 +01001135 "TCH/H channel\n" \
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001136 "Any TCH channel\n" \
1137 "SDCCH channel\n"
1138
Sylvain Munaut93558302019-02-14 20:13:08 +01001139#define CHAN_MODES "(signalling|speech-hr|speech-fr|speech-efr|speech-amr)"
1140#define CHAN_MODE_HELP \
1141 "Signalling only\n" \
1142 "Speech with HR codec\n" \
1143 "Speech with FR codec\n" \
1144 "Speech with EFR codec\n" \
1145 "Speech with AMR codec\n"
1146
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001147DEFUN(subscriber_silent_call_start,
1148 subscriber_silent_call_start_cmd,
Sylvain Munaut93558302019-02-14 20:13:08 +01001149 "subscriber " SUBSCR_TYPES " ID silent-call start " CHAN_TYPES " " CHAN_MODES " [IP] [<0-65535>]",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001150 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
Sylvain Munaut93558302019-02-14 20:13:08 +01001151 CHAN_TYPE_HELP CHAN_MODE_HELP
1152 "Target IP for RTP traffic (default 127.0.0.1)\n"
1153 "Target port for RTP traffic (default: 4000)\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001154{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001155 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Sylvain Munaut93558302019-02-14 20:13:08 +01001156 struct gsm0808_channel_type ct;
1157 const char *ip;
1158 uint16_t port;
1159 int rc, speech;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001160
1161 if (!vsub) {
1162 vty_out(vty, "%% No subscriber found for %s %s%s",
1163 argv[0], argv[1], VTY_NEWLINE);
1164 return CMD_WARNING;
1165 }
1166
Sylvain Munaut93558302019-02-14 20:13:08 +01001167 memset(&ct, 0x00, sizeof(ct));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001168
Sylvain Munaut93558302019-02-14 20:13:08 +01001169 if (!strcmp(argv[3], "signalling")) {
1170 ct.ch_indctr = GSM0808_CHAN_SIGN;
1171 ct.perm_spch[0] = 0; /* Spare but required */
1172 ct.perm_spch_len = 1;
1173 } else if (!strcmp(argv[3], "speech-hr")) {
1174 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1175 ct.perm_spch[0] = GSM0808_PERM_HR1;
1176 ct.perm_spch_len = 1;
1177 } else if (!strcmp(argv[3], "speech-fr")) {
1178 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1179 ct.perm_spch[0] = GSM0808_PERM_FR1;
1180 ct.perm_spch_len = 1;
1181 } else if (!strcmp(argv[3], "speech-efr")) {
1182 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1183 ct.perm_spch[0] = GSM0808_PERM_FR2;
1184 ct.perm_spch_len = 1;
1185 } else if (!strcmp(argv[3], "speech-amr")) {
1186 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1187 ct.perm_spch[0] = GSM0808_PERM_FR3;
1188 ct.perm_spch[1] = GSM0808_PERM_HR3;
1189 ct.perm_spch_len = 2;
1190 }
1191
1192 speech = ct.ch_indctr == GSM0808_CHAN_SPEECH;
1193
1194 if (!strcmp(argv[2], "tch/f"))
1195 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_BM : GSM0808_SIGN_FULL_BM;
1196 else if (!strcmp(argv[2], "tch/h"))
1197 ct.ch_rate_type = speech ? GSM0808_SPEECH_HALF_LM : GSM0808_SIGN_HALF_LM;
1198 else if (!strcmp(argv[2], "tch/any"))
1199 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_FULL_PREF;
1200 else if (!strcmp(argv[2], "sdcch")) {
1201 if (speech) {
1202 vty_out(vty, "Can't request speech on SDCCH%s", VTY_NEWLINE);
1203 return CMD_WARNING;
1204 }
1205 ct.ch_rate_type = GSM0808_SIGN_SDCCH;
1206 } else
1207 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_ANY;
1208
1209 ip = argc >= 5 ? argv[4] : "127.0.0.1";
1210 port = argc >= 6 ? atoi(argv[5]) : 4000;
1211
1212 rc = gsm_silent_call_start(vsub, &ct, ip, port, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001213 switch (rc) {
1214 case -ENODEV:
1215 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
1216 break;
1217 default:
1218 if (rc)
1219 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
1220 else
1221 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
1222 break;
1223 }
1224
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001225 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001226 return rc ? CMD_WARNING : CMD_SUCCESS;
1227}
1228
1229DEFUN(subscriber_silent_call_stop,
1230 subscriber_silent_call_stop_cmd,
1231 "subscriber " SUBSCR_TYPES " ID silent-call stop",
1232 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
1233 CHAN_TYPE_HELP)
1234{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001235 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1236 int rc;
1237
1238 if (!vsub) {
1239 vty_out(vty, "%% No subscriber found for %s %s%s",
1240 argv[0], argv[1], VTY_NEWLINE);
1241 return CMD_WARNING;
1242 }
1243
1244 rc = gsm_silent_call_stop(vsub);
1245 switch (rc) {
1246 case -ENODEV:
1247 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
1248 break;
1249 case -ENOENT:
1250 vty_out(vty, "%% Subscriber has no silent call active%s",
1251 VTY_NEWLINE);
1252 break;
1253 default:
1254 if (rc)
1255 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
1256 else
1257 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
1258 break;
1259 }
1260
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001261 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001262 return rc ? CMD_WARNING : CMD_SUCCESS;
1263}
1264
1265DEFUN(subscriber_ussd_notify,
1266 subscriber_ussd_notify_cmd,
1267 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1268 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1269 "Alerting Level 0\n"
1270 "Alerting Level 1\n"
1271 "Alerting Level 2\n"
1272 "Text of USSD message to send\n")
1273{
1274 char *text;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001275 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001276 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1277 int level;
1278
1279 if (!vsub) {
1280 vty_out(vty, "%% No subscriber found for %s %s%s",
1281 argv[0], argv[1], VTY_NEWLINE);
1282 return CMD_WARNING;
1283 }
1284
1285 level = atoi(argv[2]);
1286 text = argv_concat(argv, argc, 3);
1287 if (!text) {
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001288 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001289 return CMD_WARNING;
1290 }
1291
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001292 msc_a = msc_a_for_vsub(vsub, true);
1293 if (!msc_a || msc_a->c.remote_to) {
1294 vty_out(vty, "%% An active connection and local MSC-A role is required for %s %s%s",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001295 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001296 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001297 talloc_free(text);
1298 return CMD_WARNING;
1299 }
1300
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001301 msc_send_ussd_notify(msc_a, level, text);
Vadim Yanitskiyf20c6b72018-11-29 01:20:58 +07001302 /* FIXME: since we don't allocate a transaction here,
1303 * we use dummy GSM 04.07 transaction ID. */
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001304 msc_send_ussd_release_complete(msc_a, 0x00);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001305
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001306 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001307 talloc_free(text);
1308 return CMD_SUCCESS;
1309}
1310
1311DEFUN(subscriber_paging,
1312 subscriber_paging_cmd,
1313 "subscriber " SUBSCR_TYPES " ID paging",
1314 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1315{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001316 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001317 struct paging_request *req;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001318
1319 if (!vsub) {
1320 vty_out(vty, "%% No subscriber found for %s %s%s",
1321 argv[0], argv[1], VTY_NEWLINE);
1322 return CMD_WARNING;
1323 }
1324
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001325 req = paging_request_start(vsub, PAGING_CAUSE_CALL_CONVERSATIONAL,
1326 NULL, NULL, "manual Paging from VTY");
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001327 if (req)
1328 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1329 else
1330 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1331
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001332 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001333 return req ? CMD_SUCCESS : CMD_WARNING;
1334}
1335
1336static int loop_by_char(uint8_t ch)
1337{
1338 switch (ch) {
1339 case 'a':
1340 return GSM414_LOOP_A;
1341 case 'b':
1342 return GSM414_LOOP_B;
1343 case 'c':
1344 return GSM414_LOOP_C;
1345 case 'd':
1346 return GSM414_LOOP_D;
1347 case 'e':
1348 return GSM414_LOOP_E;
1349 case 'f':
1350 return GSM414_LOOP_F;
1351 case 'i':
1352 return GSM414_LOOP_I;
1353 }
1354 return -1;
1355}
1356
1357DEFUN(subscriber_mstest_close,
1358 subscriber_mstest_close_cmd,
1359 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1360 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1361 "Close a TCH Loop inside the MS\n"
1362 "Loop Type A\n"
1363 "Loop Type B\n"
1364 "Loop Type C\n"
1365 "Loop Type D\n"
1366 "Loop Type E\n"
1367 "Loop Type F\n"
1368 "Loop Type I\n")
1369{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001370 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001371 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1372 const char *loop_str;
1373 int loop_mode;
1374
1375 if (!vsub) {
1376 vty_out(vty, "%% No subscriber found for %s %s%s",
1377 argv[0], argv[1], VTY_NEWLINE);
1378 return CMD_WARNING;
1379 }
1380
1381 loop_str = argv[2];
1382 loop_mode = loop_by_char(loop_str[0]);
1383
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001384 msc_a = msc_a_for_vsub(vsub, true);
1385 if (!msc_a) {
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001386 vty_out(vty, "%% An active connection is required for %s %s%s",
1387 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001388 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001389 return CMD_WARNING;
1390 }
1391
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001392 gsm0414_tx_close_tch_loop_cmd(msc_a, loop_mode);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001393
1394 return CMD_SUCCESS;
1395}
1396
1397DEFUN(subscriber_mstest_open,
1398 subscriber_mstest_open_cmd,
1399 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1400 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1401 "Open a TCH Loop inside the MS\n")
1402{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001403 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001404 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1405
1406 if (!vsub) {
1407 vty_out(vty, "%% No subscriber found for %s %s%s",
1408 argv[0], argv[1], VTY_NEWLINE);
1409 return CMD_WARNING;
1410 }
1411
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001412 msc_a = msc_a_for_vsub(vsub, true);
1413 if (!msc_a) {
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001414 vty_out(vty, "%% An active connection is required for %s %s%s",
1415 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001416 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001417 return CMD_WARNING;
1418 }
1419
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001420 gsm0414_tx_open_loop_cmd(msc_a);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001421
1422 return CMD_SUCCESS;
1423}
1424
1425DEFUN(ena_subscr_expire,
1426 ena_subscr_expire_cmd,
1427 "subscriber " SUBSCR_TYPES " ID expire",
1428 SUBSCR_HELP "Expire the subscriber Now\n")
1429{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001430 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1431 argv[1]);
1432
1433 if (!vsub) {
1434 vty_out(vty, "%% No subscriber found for %s %s%s",
1435 argv[0], argv[1], VTY_NEWLINE);
1436 return CMD_WARNING;
1437 }
1438
1439 if (vlr_subscr_expire(vsub))
1440 vty_out(vty, "%% VLR released subscriber %s%s",
1441 vlr_subscr_name(vsub), VTY_NEWLINE);
1442
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001443 if (osmo_use_count_total(&vsub->use_count) > 1)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001444 vty_out(vty, "%% Subscriber %s is still in use,"
1445 " should be released soon%s",
1446 vlr_subscr_name(vsub), VTY_NEWLINE);
1447
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001448 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001449 return CMD_SUCCESS;
1450}
1451
1452static int scall_cbfn(unsigned int subsys, unsigned int signal,
1453 void *handler_data, void *signal_data)
1454{
1455 struct scall_signal_data *sigdata = signal_data;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001456 struct vty *vty = sigdata->vty;
1457
1458 if (!vty_is_active(vty))
1459 return 0;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001460
1461 switch (signal) {
1462 case S_SCALL_SUCCESS:
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001463 vty_out(vty, "%% Silent call success%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001464 break;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001465 case S_SCALL_FAILED:
1466 vty_out(vty, "%% Silent call failed%s", VTY_NEWLINE);
1467 break;
1468 case S_SCALL_DETACHED:
1469 vty_out(vty, "%% Silent call ended%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001470 break;
1471 }
1472 return 0;
1473}
1474
1475DEFUN(show_stats,
1476 show_stats_cmd,
1477 "show statistics",
1478 SHOW_STR "Display network statistics\n")
1479{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001480 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001481 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1482 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1483 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001484 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001485 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001486 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001487 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001488 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001489 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1490 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001491 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001492 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001493 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1494 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001495 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001496 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001497 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1498 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1499 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001500 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001501 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001502 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1503 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001504 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001505 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001506 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1507 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001508 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001509 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001510 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1511 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1512 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1513 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1514 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001515 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001516 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1517 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1518 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1519 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1520 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001521 return CMD_SUCCESS;
1522}
1523
1524DEFUN(show_smsqueue,
1525 show_smsqueue_cmd,
1526 "show sms-queue",
1527 SHOW_STR "Display SMSqueue statistics\n")
1528{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001529 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001530 return CMD_SUCCESS;
1531}
1532
1533DEFUN(smsqueue_trigger,
1534 smsqueue_trigger_cmd,
1535 "sms-queue trigger",
1536 "SMS Queue\n" "Trigger sending messages\n")
1537{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001538 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001539 return CMD_SUCCESS;
1540}
1541
1542DEFUN(smsqueue_max,
1543 smsqueue_max_cmd,
1544 "sms-queue max-pending <1-500>",
1545 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1546{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001547 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001548 return CMD_SUCCESS;
1549}
1550
1551DEFUN(smsqueue_clear,
1552 smsqueue_clear_cmd,
1553 "sms-queue clear",
1554 "SMS Queue\n" "Clear the queue of pending SMS\n")
1555{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001556 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001557 return CMD_SUCCESS;
1558}
1559
1560DEFUN(smsqueue_fail,
1561 smsqueue_fail_cmd,
1562 "sms-queue max-failure <1-500>",
1563 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1564{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001565 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001566 return CMD_SUCCESS;
1567}
1568
1569
1570DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1571 "mncc-int", "Configure internal MNCC handler")
1572{
1573 vty->node = MNCC_INT_NODE;
1574
1575 return CMD_SUCCESS;
1576}
1577
1578static struct cmd_node mncc_int_node = {
1579 MNCC_INT_NODE,
1580 "%s(config-mncc-int)# ",
1581 1,
1582};
1583
1584static const struct value_string tchf_codec_names[] = {
1585 { GSM48_CMODE_SPEECH_V1, "fr" },
1586 { GSM48_CMODE_SPEECH_EFR, "efr" },
1587 { GSM48_CMODE_SPEECH_AMR, "amr" },
1588 { 0, NULL }
1589};
1590
1591static const struct value_string tchh_codec_names[] = {
1592 { GSM48_CMODE_SPEECH_V1, "hr" },
1593 { GSM48_CMODE_SPEECH_AMR, "amr" },
1594 { 0, NULL }
1595};
1596
1597static int config_write_mncc_int(struct vty *vty)
1598{
1599 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1600 vty_out(vty, " default-codec tch-f %s%s",
1601 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1602 VTY_NEWLINE);
1603 vty_out(vty, " default-codec tch-h %s%s",
1604 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1605 VTY_NEWLINE);
1606
1607 return CMD_SUCCESS;
1608}
1609
1610DEFUN(mnccint_def_codec_f,
1611 mnccint_def_codec_f_cmd,
1612 "default-codec tch-f (fr|efr|amr)",
1613 "Set default codec\n" "Codec for TCH/F\n"
1614 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1615{
1616 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1617
1618 return CMD_SUCCESS;
1619}
1620
1621DEFUN(mnccint_def_codec_h,
1622 mnccint_def_codec_h_cmd,
1623 "default-codec tch-h (hr|amr)",
1624 "Set default codec\n" "Codec for TCH/H\n"
1625 "Half-Rate\n" "Adaptive Multi-Rate\n")
1626{
1627 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1628
1629 return CMD_SUCCESS;
1630}
1631
1632
1633DEFUN(logging_fltr_imsi,
1634 logging_fltr_imsi_cmd,
1635 "logging filter imsi IMSI",
1636 LOGGING_STR FILTER_STR
1637 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1638{
1639 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001640 struct log_target *tgt = osmo_log_vty2tgt(vty);
1641 const char *imsi = argv[0];
1642
1643 if (!tgt)
1644 return CMD_WARNING;
1645
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001646 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001647
1648 if (!vlr_subscr) {
1649 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1650 argv[0], VTY_NEWLINE);
1651 return CMD_WARNING;
1652 }
1653
1654 log_set_filter_vlr_subscr(tgt, vlr_subscr);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001655 vlr_subscr_put(vlr_subscr, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001656 return CMD_SUCCESS;
1657}
1658
1659static struct cmd_node hlr_node = {
1660 HLR_NODE,
1661 "%s(config-hlr)# ",
1662 1,
1663};
1664
1665DEFUN(cfg_hlr, cfg_hlr_cmd,
1666 "hlr", "Configure connection to the HLR")
1667{
1668 vty->node = HLR_NODE;
1669 return CMD_SUCCESS;
1670}
1671
1672DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1673 "Remote GSUP address of the HLR\n"
1674 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1675{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001676 talloc_free((void*)gsmnet->gsup_server_addr_str);
1677 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1678 return CMD_SUCCESS;
1679}
1680
1681DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1682 "Remote GSUP port of the HLR\n"
1683 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1684{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001685 gsmnet->gsup_server_port = atoi(argv[0]);
1686 return CMD_SUCCESS;
1687}
1688
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001689DEFUN(cfg_hlr_ipa_name,
1690 cfg_hlr_ipa_name_cmd,
1691 "ipa-name NAME",
1692 "Set the IPA name of this MSC\n"
1693 "A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. "
1694 "This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. "
1695 "The default is 'MSC-00-00-00-00-00-00'.\n")
1696{
1697 if (vty->type != VTY_FILE) {
1698 vty_out(vty, "The IPA name cannot be changed at run-time; "
1699 "It can only be set in the configuraton file.%s", VTY_NEWLINE);
1700 return CMD_WARNING;
1701 }
1702
1703 gsmnet->msc_ipa_name = talloc_strdup(gsmnet, argv[0]);
1704 return CMD_SUCCESS;
1705}
1706
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001707static int config_write_hlr(struct vty *vty)
1708{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001709 vty_out(vty, "hlr%s", VTY_NEWLINE);
1710 vty_out(vty, " remote-ip %s%s",
1711 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1712 vty_out(vty, " remote-port %u%s",
1713 gsmnet->gsup_server_port, VTY_NEWLINE);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001714 if (gsmnet->msc_ipa_name)
1715 vty_out(vty, " ipa-name %s%s", gsmnet->msc_ipa_name, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001716 return CMD_SUCCESS;
1717}
1718
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001719void msc_vty_init(struct gsm_network *msc_network)
1720{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001721 OSMO_ASSERT(gsmnet == NULL);
1722 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001723
1724 osmo_stats_vty_add_cmds();
1725
1726 install_element(CONFIG_NODE, &cfg_net_cmd);
1727 install_node(&net_node, config_write_net);
1728 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
1729 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1730 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1731 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
1732 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
1733 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
1734 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
1735 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
1736 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
1737 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
1738 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
1739 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
1740 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001741
1742 install_element(CONFIG_NODE, &cfg_msc_cmd);
1743 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001744 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01001745 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
1746 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02001747 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01001748 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Vadim Yanitskiy64623e12018-11-28 23:05:51 +07001749 install_element(MSC_NODE, &cfg_msc_ncss_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001750 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01001751 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
1752 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Oliver Smith0fec28a2018-12-14 10:52:52 +01001753 install_element(MSC_NODE, &cfg_msc_check_imei_rqd_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001754 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
1755 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01001756 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01001757 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +07001758 install_element(MSC_NODE, &cfg_msc_sms_over_gsup_cmd);
1759 install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001760 install_element(MSC_NODE, &cfg_msc_handover_number_range_cmd);
1761
1762 neighbor_ident_vty_init(msc_network);
Philipp Maierfbf66102017-04-09 12:32:51 +02001763
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02001764 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001765#ifdef BUILD_IU
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001766 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 +02001767#endif
Harald Welte0df904d2018-12-03 11:00:04 +01001768 sgs_vty_init();
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001769
Stefan Sperling617ac802018-02-22 17:58:20 +01001770 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001771
1772 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
1773
1774 install_element_ve(&show_subscr_cmd);
1775 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01001776 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001777 install_element_ve(&show_msc_conn_cmd);
1778 install_element_ve(&show_msc_transaction_cmd);
1779
1780 install_element_ve(&sms_send_pend_cmd);
1781 install_element_ve(&sms_delete_expired_cmd);
1782
1783 install_element_ve(&subscriber_create_cmd);
1784 install_element_ve(&subscriber_send_sms_cmd);
1785 install_element_ve(&subscriber_silent_sms_cmd);
1786 install_element_ve(&subscriber_silent_call_start_cmd);
1787 install_element_ve(&subscriber_silent_call_stop_cmd);
1788 install_element_ve(&subscriber_ussd_notify_cmd);
1789 install_element_ve(&subscriber_mstest_close_cmd);
1790 install_element_ve(&subscriber_mstest_open_cmd);
1791 install_element_ve(&subscriber_paging_cmd);
1792 install_element_ve(&show_stats_cmd);
1793 install_element_ve(&show_smsqueue_cmd);
1794 install_element_ve(&logging_fltr_imsi_cmd);
1795
1796 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
1797 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
1798 install_element(ENABLE_NODE, &smsqueue_max_cmd);
1799 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
1800 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
1801 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001802 install_element(ENABLE_NODE, &subscriber_sms_delete_all_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001803
1804 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1805 install_node(&mncc_int_node, config_write_mncc_int);
1806 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1807 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1808
1809 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
1810
1811 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1812 install_node(&hlr_node, config_write_hlr);
1813 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1814 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001815 install_element(HLR_NODE, &cfg_hlr_ipa_name_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001816}