blob: bd369ae9f0a1756cc2deb414d4f32e2c0815b187 [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;
745 int reqs;
746 struct llist_head *entry;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100747 char buf[128];
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100748
749 if (strlen(vsub->name))
750 vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
751 if (strlen(vsub->msisdn))
752 vty_out(vty, " Extension: %s%s", vsub->msisdn,
753 VTY_NEWLINE);
754 vty_out(vty, " LAC: %d/0x%x%s",
Max7d41d872018-12-19 11:48:33 +0100755 vsub->cgi.lai.lac, vsub->cgi.lai.lac, VTY_NEWLINE);
Philipp Maier2a0ac3b2018-12-17 10:03:50 +0100756 vty_out(vty, " RAN: %s%s",
Neels Hofmeyr7814a832018-12-26 00:40:18 +0100757 osmo_rat_type_name(vsub->cs.attached_via_ran), VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100758 vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
759 if (vsub->tmsi != GSM_RESERVED_TMSI)
760 vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
761 VTY_NEWLINE);
762 if (vsub->tmsi_new != GSM_RESERVED_TMSI)
763 vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
764 VTY_NEWLINE);
Philipp Maier6d71ccf2018-12-14 13:30:14 +0100765 if (vsub->imei[0] != '\0')
766 vty_out(vty, " IMEI: %s%s", vsub->imei, VTY_NEWLINE);
767 if (vsub->imeisv[0] != '\0')
768 vty_out(vty, " IMEISV: %s%s", vsub->imeisv, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100769
Philipp Maier89561bc2018-12-14 13:34:25 +0100770 vty_out(vty, " Flags: %s", VTY_NEWLINE);
771 vty_out(vty, " IMSI detached: %s%s",
772 vsub->imsi_detached_flag ? "true" : "false", VTY_NEWLINE);
773 vty_out(vty, " Conf. by radio contact: %s%s",
774 vsub->conf_by_radio_contact_ind ? "true" : "false",
775 VTY_NEWLINE);
776 vty_out(vty, " Subscr. data conf. by HLR: %s%s",
777 vsub->sub_dataconf_by_hlr_ind ? "true" : "false", VTY_NEWLINE);
778 vty_out(vty, " Location conf. in HLR: %s%s",
779 vsub->loc_conf_in_hlr_ind ? "true" : "false", VTY_NEWLINE);
780 vty_out(vty, " Subscriber dormant: %s%s",
781 vsub->dormant_ind ? "true" : "false", VTY_NEWLINE);
782 vty_out(vty, " Received cancel locataion: %s%s",
783 vsub->cancel_loc_rx ? "true" : "false", VTY_NEWLINE);
784 vty_out(vty, " MS not reachable: %s%s",
785 vsub->ms_not_reachable_flag ? "true" : "false", VTY_NEWLINE);
786 vty_out(vty, " LA allowed: %s%s",
787 vsub->la_allowed ? "true" : "false", VTY_NEWLINE);
788
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100789 if (vsub->last_tuple) {
Neels Hofmeyr8b6e5362018-11-30 02:57:33 +0100790 struct vlr_auth_tuple *t = vsub->last_tuple;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100791 vty_out(vty, " A3A8 last tuple (used %d times):%s",
792 t->use_count, VTY_NEWLINE);
793 vty_out(vty, " seq # : %d%s",
794 t->key_seq, VTY_NEWLINE);
795 vty_out(vty, " RAND : %s%s",
796 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
797 VTY_NEWLINE);
798 vty_out(vty, " SRES : %s%s",
799 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
800 VTY_NEWLINE);
801 vty_out(vty, " Kc : %s%s",
802 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
803 VTY_NEWLINE);
804 }
805
806 reqs = 0;
807 llist_for_each(entry, &vsub->cs.requests)
808 reqs += 1;
809 vty_out(vty, " Paging: %s paging for %d requests%s",
810 vsub->cs.is_paging ? "is" : "not", reqs, VTY_NEWLINE);
Harald Welte0df904d2018-12-03 11:00:04 +0100811
812 /* SGs related */
813 vty_out(vty, " SGs-state: %s%s",
814 osmo_fsm_inst_state_name(vsub->sgs_fsm), VTY_NEWLINE);
Vadim Yanitskiy477cbc62019-02-23 16:59:16 +0700815 if (strlen(vsub->sgs.mme_name))
Harald Welte0df904d2018-12-03 11:00:04 +0100816 vty_out(vty, " SGs-MME: %s%s", vsub->sgs.mme_name, VTY_NEWLINE);
817 else
818 vty_out(vty, " SGs-MME: (none)%s", VTY_NEWLINE);
819
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100820 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 +0100821
822 /* Connection */
823 if (vsub->msc_conn_ref) {
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100824 struct msub *msub = vsub->msc_conn_ref;
825 int idx = 0;
826 if (msub) {
827 vty_dump_one_conn(vty, msub, &idx);
828 }
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100829 }
830
831 /* Transactions */
832 vty_trans_hdr(vty);
833 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
834 if (trans->vsub != vsub)
835 continue;
836 vty_dump_one_trans(vty, trans);
837 }
838}
839
840/* Subscriber */
841DEFUN(show_subscr_cache,
842 show_subscr_cache_cmd,
843 "show subscriber cache",
844 SHOW_STR "Show information about subscribers\n"
845 "Display contents of subscriber cache\n")
846{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100847 struct vlr_subscr *vsub;
848 int count = 0;
849
850 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
851 if (++count > 100) {
852 vty_out(vty, "%% More than %d subscribers in cache,"
853 " stopping here.%s", count-1, VTY_NEWLINE);
854 break;
855 }
856 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
857 subscr_dump_full_vty(vty, vsub);
Harald Welte69c54a82018-02-09 20:41:14 +0100858 }
859
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200860 return CMD_SUCCESS;
861}
862
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100863DEFUN(sms_send_pend,
864 sms_send_pend_cmd,
865 "sms send pending",
866 "SMS related commands\n" "SMS Sending related commands\n"
867 "Send all pending SMS")
868{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100869 struct gsm_sms *sms;
870 unsigned long long sms_id = 0;
871
872 while (1) {
873 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
874 if (!sms)
875 break;
876
877 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700878 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100879
880 sms_id = sms->id + 1;
881 }
882
883 return CMD_SUCCESS;
884}
885
886DEFUN(sms_delete_expired,
887 sms_delete_expired_cmd,
888 "sms delete expired",
889 "SMS related commands\n" "SMS Database related commands\n"
890 "Delete all expired SMS")
891{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100892 struct gsm_sms *sms;
893 unsigned long long sms_id = 0;
894 long long num_deleted = 0;
895
896 while (1) {
897 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
898 if (!sms)
899 break;
900
901 /* Skip SMS which are currently queued for sending. */
902 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
903 continue;
904
905 /* Expiration check is performed by the DB layer. */
906 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
907 num_deleted++;
908
909 sms_id = sms->id + 1;
910 }
911
912 if (num_deleted == 0) {
913 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
914 return CMD_WARNING;
915 }
916
917 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
918 return CMD_SUCCESS;
919}
920
921static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +0200922 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100923 char *str, uint8_t tp_pid)
924{
925 struct gsm_network *net = receiver->vlr->user_ctx;
926 struct gsm_sms *sms;
927
Harald Welte39b55482018-04-09 19:19:33 +0200928 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100929 sms->protocol_id = tp_pid;
930
931 /* store in database for the queue */
932 if (db_sms_store(sms) != 0) {
933 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
934 sms_free(sms);
935 return CMD_WARNING;
936 }
937 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
938
939 sms_free(sms);
940 sms_queue_trigger(net->sms_queue);
941 return CMD_SUCCESS;
942}
943
944static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
945 const char *type,
946 const char *id)
947{
948 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100949 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100950 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100951 return vlr_subscr_find_by_imsi(gsmnet->vlr, id, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100952 else if (!strcmp(type, "tmsi"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100953 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id), VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100954
955 return NULL;
956}
957#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
958#define SUBSCR_HELP "Operations on a Subscriber\n" \
959 "Identify subscriber by MSISDN (phone number)\n" \
960 "Legacy alias for 'msisdn'\n" \
961 "Identify subscriber by IMSI\n" \
962 "Identify subscriber by TMSI\n" \
963 "Identify subscriber by database ID\n" \
964 "Identifier for the subscriber\n"
965
966DEFUN(show_subscr,
967 show_subscr_cmd,
968 "show subscriber " SUBSCR_TYPES " ID",
969 SHOW_STR SUBSCR_HELP)
970{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100971 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
972 argv[1]);
973
974 if (!vsub) {
975 vty_out(vty, "%% No subscriber found for %s %s%s",
976 argv[0], argv[1], VTY_NEWLINE);
977 return CMD_WARNING;
978 }
979
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100980 /* In the vty output to the user, exclude this local use count added by vlr_subscr_get() in get_vsub_by_argv().
981 * This works, because: for get_vsub_by_argv() to succeed, there *must* have been at least one use count before
982 * 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 +0100983 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100984
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100985 subscr_dump_full_vty(vty, vsub);
986
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100987 return CMD_SUCCESS;
988}
989
990DEFUN(subscriber_create,
991 subscriber_create_cmd,
992 "subscriber create imsi ID",
993 "Operations on a Subscriber\n" \
994 "Create new subscriber\n" \
995 "Identify the subscriber by his IMSI\n" \
996 "Identifier for the subscriber\n")
997{
998 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
999 VTY_NEWLINE);
1000 return CMD_WARNING;
1001}
1002
1003DEFUN(subscriber_send_pending_sms,
1004 subscriber_send_pending_sms_cmd,
1005 "subscriber " SUBSCR_TYPES " ID sms pending-send",
1006 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
1007{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001008 struct vlr_subscr *vsub;
1009 struct gsm_sms *sms;
1010
1011 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1012 if (!vsub) {
1013 vty_out(vty, "%% No subscriber found for %s %s%s",
1014 argv[0], argv[1], VTY_NEWLINE);
1015 return CMD_WARNING;
1016 }
1017
1018 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
1019 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +07001020 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001021
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001022 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001023
1024 return CMD_SUCCESS;
1025}
1026
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001027DEFUN(subscriber_sms_delete_all,
1028 subscriber_sms_delete_all_cmd,
1029 "subscriber " SUBSCR_TYPES " ID sms delete-all",
1030 SUBSCR_HELP "SMS Operations\n"
1031 "Delete all SMS to be delivered to this subscriber"
1032 " -- WARNING: the SMS data for all unsent SMS for this subscriber"
1033 " WILL BE LOST.\n")
1034{
1035 struct vlr_subscr *vsub;
1036
1037 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1038 if (!vsub) {
1039 vty_out(vty, "%% No subscriber found for %s %s%s",
1040 argv[0], argv[1], VTY_NEWLINE);
1041 return CMD_WARNING;
1042 }
1043
1044 db_sms_delete_by_msisdn(vsub->msisdn);
1045
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001046 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001047
1048 return CMD_SUCCESS;
1049}
1050
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001051DEFUN(subscriber_send_sms,
1052 subscriber_send_sms_cmd,
1053 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
1054 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
1055{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001056 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +02001057 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001058 char *str;
1059 int rc;
1060
1061 if (!vsub) {
1062 vty_out(vty, "%% No subscriber found for %s %s%s",
1063 argv[0], argv[1], VTY_NEWLINE);
1064 rc = CMD_WARNING;
1065 goto err;
1066 }
1067
Harald Welte39b55482018-04-09 19:19:33 +02001068 if (!strcmp(argv[2], "msisdn"))
1069 sender_msisdn = argv[3];
1070 else {
1071 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1072 if (!sender) {
1073 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1074 rc = CMD_WARNING;
1075 goto err;
1076 }
1077 sender_msisdn = sender->msisdn;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001078 vlr_subscr_put(sender, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001079 }
1080
1081 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001082 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001083 talloc_free(str);
1084
1085err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001086 if (vsub)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001087 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001088
1089 return rc;
1090}
1091
1092DEFUN(subscriber_silent_sms,
1093 subscriber_silent_sms_cmd,
1094
1095 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
1096 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
1097{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001098 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +02001099 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001100 char *str;
1101 int rc;
1102
1103 if (!vsub) {
1104 vty_out(vty, "%% No subscriber found for %s %s%s",
1105 argv[0], argv[1], VTY_NEWLINE);
1106 rc = CMD_WARNING;
1107 goto err;
1108 }
1109
Harald Welte39b55482018-04-09 19:19:33 +02001110 if (!strcmp(argv[2], "msisdn")) {
1111 sender_msisdn = argv[3];
1112 } else {
1113 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1114 if (!sender) {
1115 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1116 rc = CMD_WARNING;
1117 goto err;
1118 }
1119 sender_msisdn = sender->msisdn;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001120 vlr_subscr_put(sender, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001121 }
1122
1123 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001124 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001125 talloc_free(str);
1126
1127err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001128 if (vsub)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001129 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001130
1131 return rc;
1132}
1133
Sylvain Munaut93558302019-02-14 20:13:08 +01001134#define CHAN_TYPES "(any|tch/f|tch/h|tch/any|sdcch)"
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001135#define CHAN_TYPE_HELP \
1136 "Any channel\n" \
1137 "TCH/F channel\n" \
Sylvain Munaut93558302019-02-14 20:13:08 +01001138 "TCH/H channel\n" \
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001139 "Any TCH channel\n" \
1140 "SDCCH channel\n"
1141
Sylvain Munaut93558302019-02-14 20:13:08 +01001142#define CHAN_MODES "(signalling|speech-hr|speech-fr|speech-efr|speech-amr)"
1143#define CHAN_MODE_HELP \
1144 "Signalling only\n" \
1145 "Speech with HR codec\n" \
1146 "Speech with FR codec\n" \
1147 "Speech with EFR codec\n" \
1148 "Speech with AMR codec\n"
1149
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001150DEFUN(subscriber_silent_call_start,
1151 subscriber_silent_call_start_cmd,
Sylvain Munaut93558302019-02-14 20:13:08 +01001152 "subscriber " SUBSCR_TYPES " ID silent-call start " CHAN_TYPES " " CHAN_MODES " [IP] [<0-65535>]",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001153 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
Sylvain Munaut93558302019-02-14 20:13:08 +01001154 CHAN_TYPE_HELP CHAN_MODE_HELP
1155 "Target IP for RTP traffic (default 127.0.0.1)\n"
1156 "Target port for RTP traffic (default: 4000)\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001157{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001158 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Sylvain Munaut93558302019-02-14 20:13:08 +01001159 struct gsm0808_channel_type ct;
1160 const char *ip;
1161 uint16_t port;
1162 int rc, speech;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001163
1164 if (!vsub) {
1165 vty_out(vty, "%% No subscriber found for %s %s%s",
1166 argv[0], argv[1], VTY_NEWLINE);
1167 return CMD_WARNING;
1168 }
1169
Sylvain Munaut93558302019-02-14 20:13:08 +01001170 memset(&ct, 0x00, sizeof(ct));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001171
Sylvain Munaut93558302019-02-14 20:13:08 +01001172 if (!strcmp(argv[3], "signalling")) {
1173 ct.ch_indctr = GSM0808_CHAN_SIGN;
1174 ct.perm_spch[0] = 0; /* Spare but required */
1175 ct.perm_spch_len = 1;
1176 } else if (!strcmp(argv[3], "speech-hr")) {
1177 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1178 ct.perm_spch[0] = GSM0808_PERM_HR1;
1179 ct.perm_spch_len = 1;
1180 } else if (!strcmp(argv[3], "speech-fr")) {
1181 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1182 ct.perm_spch[0] = GSM0808_PERM_FR1;
1183 ct.perm_spch_len = 1;
1184 } else if (!strcmp(argv[3], "speech-efr")) {
1185 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1186 ct.perm_spch[0] = GSM0808_PERM_FR2;
1187 ct.perm_spch_len = 1;
1188 } else if (!strcmp(argv[3], "speech-amr")) {
1189 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1190 ct.perm_spch[0] = GSM0808_PERM_FR3;
1191 ct.perm_spch[1] = GSM0808_PERM_HR3;
1192 ct.perm_spch_len = 2;
1193 }
1194
1195 speech = ct.ch_indctr == GSM0808_CHAN_SPEECH;
1196
1197 if (!strcmp(argv[2], "tch/f"))
1198 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_BM : GSM0808_SIGN_FULL_BM;
1199 else if (!strcmp(argv[2], "tch/h"))
1200 ct.ch_rate_type = speech ? GSM0808_SPEECH_HALF_LM : GSM0808_SIGN_HALF_LM;
1201 else if (!strcmp(argv[2], "tch/any"))
1202 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_FULL_PREF;
1203 else if (!strcmp(argv[2], "sdcch")) {
1204 if (speech) {
1205 vty_out(vty, "Can't request speech on SDCCH%s", VTY_NEWLINE);
1206 return CMD_WARNING;
1207 }
1208 ct.ch_rate_type = GSM0808_SIGN_SDCCH;
1209 } else
1210 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_ANY;
1211
1212 ip = argc >= 5 ? argv[4] : "127.0.0.1";
1213 port = argc >= 6 ? atoi(argv[5]) : 4000;
1214
1215 rc = gsm_silent_call_start(vsub, &ct, ip, port, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001216 switch (rc) {
1217 case -ENODEV:
1218 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
1219 break;
1220 default:
1221 if (rc)
1222 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
1223 else
1224 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
1225 break;
1226 }
1227
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001228 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001229 return rc ? CMD_WARNING : CMD_SUCCESS;
1230}
1231
1232DEFUN(subscriber_silent_call_stop,
1233 subscriber_silent_call_stop_cmd,
1234 "subscriber " SUBSCR_TYPES " ID silent-call stop",
1235 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
1236 CHAN_TYPE_HELP)
1237{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001238 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1239 int rc;
1240
1241 if (!vsub) {
1242 vty_out(vty, "%% No subscriber found for %s %s%s",
1243 argv[0], argv[1], VTY_NEWLINE);
1244 return CMD_WARNING;
1245 }
1246
1247 rc = gsm_silent_call_stop(vsub);
1248 switch (rc) {
1249 case -ENODEV:
1250 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
1251 break;
1252 case -ENOENT:
1253 vty_out(vty, "%% Subscriber has no silent call active%s",
1254 VTY_NEWLINE);
1255 break;
1256 default:
1257 if (rc)
1258 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
1259 else
1260 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
1261 break;
1262 }
1263
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001264 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001265 return rc ? CMD_WARNING : CMD_SUCCESS;
1266}
1267
1268DEFUN(subscriber_ussd_notify,
1269 subscriber_ussd_notify_cmd,
1270 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1271 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1272 "Alerting Level 0\n"
1273 "Alerting Level 1\n"
1274 "Alerting Level 2\n"
1275 "Text of USSD message to send\n")
1276{
1277 char *text;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001278 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001279 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1280 int level;
1281
1282 if (!vsub) {
1283 vty_out(vty, "%% No subscriber found for %s %s%s",
1284 argv[0], argv[1], VTY_NEWLINE);
1285 return CMD_WARNING;
1286 }
1287
1288 level = atoi(argv[2]);
1289 text = argv_concat(argv, argc, 3);
1290 if (!text) {
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001291 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001292 return CMD_WARNING;
1293 }
1294
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001295 msc_a = msc_a_for_vsub(vsub, true);
1296 if (!msc_a || msc_a->c.remote_to) {
1297 vty_out(vty, "%% An active connection and local MSC-A role is required for %s %s%s",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001298 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001299 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001300 talloc_free(text);
1301 return CMD_WARNING;
1302 }
1303
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001304 msc_send_ussd_notify(msc_a, level, text);
Vadim Yanitskiyf20c6b72018-11-29 01:20:58 +07001305 /* FIXME: since we don't allocate a transaction here,
1306 * we use dummy GSM 04.07 transaction ID. */
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001307 msc_send_ussd_release_complete(msc_a, 0x00);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001308
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001309 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001310 talloc_free(text);
1311 return CMD_SUCCESS;
1312}
1313
1314DEFUN(subscriber_paging,
1315 subscriber_paging_cmd,
1316 "subscriber " SUBSCR_TYPES " ID paging",
1317 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1318{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001319 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001320 struct paging_request *req;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001321
1322 if (!vsub) {
1323 vty_out(vty, "%% No subscriber found for %s %s%s",
1324 argv[0], argv[1], VTY_NEWLINE);
1325 return CMD_WARNING;
1326 }
1327
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001328 req = paging_request_start(vsub, PAGING_CAUSE_CALL_CONVERSATIONAL,
1329 NULL, NULL, "manual Paging from VTY");
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001330 if (req)
1331 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1332 else
1333 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1334
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001335 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001336 return req ? CMD_SUCCESS : CMD_WARNING;
1337}
1338
1339static int loop_by_char(uint8_t ch)
1340{
1341 switch (ch) {
1342 case 'a':
1343 return GSM414_LOOP_A;
1344 case 'b':
1345 return GSM414_LOOP_B;
1346 case 'c':
1347 return GSM414_LOOP_C;
1348 case 'd':
1349 return GSM414_LOOP_D;
1350 case 'e':
1351 return GSM414_LOOP_E;
1352 case 'f':
1353 return GSM414_LOOP_F;
1354 case 'i':
1355 return GSM414_LOOP_I;
1356 }
1357 return -1;
1358}
1359
1360DEFUN(subscriber_mstest_close,
1361 subscriber_mstest_close_cmd,
1362 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1363 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1364 "Close a TCH Loop inside the MS\n"
1365 "Loop Type A\n"
1366 "Loop Type B\n"
1367 "Loop Type C\n"
1368 "Loop Type D\n"
1369 "Loop Type E\n"
1370 "Loop Type F\n"
1371 "Loop Type I\n")
1372{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001373 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001374 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1375 const char *loop_str;
1376 int loop_mode;
1377
1378 if (!vsub) {
1379 vty_out(vty, "%% No subscriber found for %s %s%s",
1380 argv[0], argv[1], VTY_NEWLINE);
1381 return CMD_WARNING;
1382 }
1383
1384 loop_str = argv[2];
1385 loop_mode = loop_by_char(loop_str[0]);
1386
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001387 msc_a = msc_a_for_vsub(vsub, true);
1388 if (!msc_a) {
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001389 vty_out(vty, "%% An active connection is required for %s %s%s",
1390 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001391 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001392 return CMD_WARNING;
1393 }
1394
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001395 gsm0414_tx_close_tch_loop_cmd(msc_a, loop_mode);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001396
1397 return CMD_SUCCESS;
1398}
1399
1400DEFUN(subscriber_mstest_open,
1401 subscriber_mstest_open_cmd,
1402 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1403 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1404 "Open a TCH Loop inside the MS\n")
1405{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001406 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001407 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1408
1409 if (!vsub) {
1410 vty_out(vty, "%% No subscriber found for %s %s%s",
1411 argv[0], argv[1], VTY_NEWLINE);
1412 return CMD_WARNING;
1413 }
1414
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001415 msc_a = msc_a_for_vsub(vsub, true);
1416 if (!msc_a) {
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001417 vty_out(vty, "%% An active connection is required for %s %s%s",
1418 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001419 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001420 return CMD_WARNING;
1421 }
1422
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001423 gsm0414_tx_open_loop_cmd(msc_a);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001424
1425 return CMD_SUCCESS;
1426}
1427
1428DEFUN(ena_subscr_expire,
1429 ena_subscr_expire_cmd,
1430 "subscriber " SUBSCR_TYPES " ID expire",
1431 SUBSCR_HELP "Expire the subscriber Now\n")
1432{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001433 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1434 argv[1]);
1435
1436 if (!vsub) {
1437 vty_out(vty, "%% No subscriber found for %s %s%s",
1438 argv[0], argv[1], VTY_NEWLINE);
1439 return CMD_WARNING;
1440 }
1441
1442 if (vlr_subscr_expire(vsub))
1443 vty_out(vty, "%% VLR released subscriber %s%s",
1444 vlr_subscr_name(vsub), VTY_NEWLINE);
1445
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001446 if (osmo_use_count_total(&vsub->use_count) > 1)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001447 vty_out(vty, "%% Subscriber %s is still in use,"
1448 " should be released soon%s",
1449 vlr_subscr_name(vsub), VTY_NEWLINE);
1450
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001451 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001452 return CMD_SUCCESS;
1453}
1454
1455static int scall_cbfn(unsigned int subsys, unsigned int signal,
1456 void *handler_data, void *signal_data)
1457{
1458 struct scall_signal_data *sigdata = signal_data;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001459 struct vty *vty = sigdata->vty;
1460
1461 if (!vty_is_active(vty))
1462 return 0;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001463
1464 switch (signal) {
1465 case S_SCALL_SUCCESS:
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001466 vty_out(vty, "%% Silent call success%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001467 break;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001468 case S_SCALL_FAILED:
1469 vty_out(vty, "%% Silent call failed%s", VTY_NEWLINE);
1470 break;
1471 case S_SCALL_DETACHED:
1472 vty_out(vty, "%% Silent call ended%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001473 break;
1474 }
1475 return 0;
1476}
1477
1478DEFUN(show_stats,
1479 show_stats_cmd,
1480 "show statistics",
1481 SHOW_STR "Display network statistics\n")
1482{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001483 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001484 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1485 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1486 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001487 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001488 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001489 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001490 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001491 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001492 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1493 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001494 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001495 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001496 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1497 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001498 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001499 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001500 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1501 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1502 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001503 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001504 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001505 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1506 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001507 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001508 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001509 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1510 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001511 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001512 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001513 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1514 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1515 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1516 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1517 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001518 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001519 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1520 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1521 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1522 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1523 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001524 return CMD_SUCCESS;
1525}
1526
1527DEFUN(show_smsqueue,
1528 show_smsqueue_cmd,
1529 "show sms-queue",
1530 SHOW_STR "Display SMSqueue statistics\n")
1531{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001532 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001533 return CMD_SUCCESS;
1534}
1535
1536DEFUN(smsqueue_trigger,
1537 smsqueue_trigger_cmd,
1538 "sms-queue trigger",
1539 "SMS Queue\n" "Trigger sending messages\n")
1540{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001541 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001542 return CMD_SUCCESS;
1543}
1544
1545DEFUN(smsqueue_max,
1546 smsqueue_max_cmd,
1547 "sms-queue max-pending <1-500>",
1548 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1549{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001550 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001551 return CMD_SUCCESS;
1552}
1553
1554DEFUN(smsqueue_clear,
1555 smsqueue_clear_cmd,
1556 "sms-queue clear",
1557 "SMS Queue\n" "Clear the queue of pending SMS\n")
1558{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001559 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001560 return CMD_SUCCESS;
1561}
1562
1563DEFUN(smsqueue_fail,
1564 smsqueue_fail_cmd,
1565 "sms-queue max-failure <1-500>",
1566 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1567{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001568 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001569 return CMD_SUCCESS;
1570}
1571
1572
1573DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1574 "mncc-int", "Configure internal MNCC handler")
1575{
1576 vty->node = MNCC_INT_NODE;
1577
1578 return CMD_SUCCESS;
1579}
1580
1581static struct cmd_node mncc_int_node = {
1582 MNCC_INT_NODE,
1583 "%s(config-mncc-int)# ",
1584 1,
1585};
1586
1587static const struct value_string tchf_codec_names[] = {
1588 { GSM48_CMODE_SPEECH_V1, "fr" },
1589 { GSM48_CMODE_SPEECH_EFR, "efr" },
1590 { GSM48_CMODE_SPEECH_AMR, "amr" },
1591 { 0, NULL }
1592};
1593
1594static const struct value_string tchh_codec_names[] = {
1595 { GSM48_CMODE_SPEECH_V1, "hr" },
1596 { GSM48_CMODE_SPEECH_AMR, "amr" },
1597 { 0, NULL }
1598};
1599
1600static int config_write_mncc_int(struct vty *vty)
1601{
1602 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1603 vty_out(vty, " default-codec tch-f %s%s",
1604 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1605 VTY_NEWLINE);
1606 vty_out(vty, " default-codec tch-h %s%s",
1607 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1608 VTY_NEWLINE);
1609
1610 return CMD_SUCCESS;
1611}
1612
1613DEFUN(mnccint_def_codec_f,
1614 mnccint_def_codec_f_cmd,
1615 "default-codec tch-f (fr|efr|amr)",
1616 "Set default codec\n" "Codec for TCH/F\n"
1617 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1618{
1619 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1620
1621 return CMD_SUCCESS;
1622}
1623
1624DEFUN(mnccint_def_codec_h,
1625 mnccint_def_codec_h_cmd,
1626 "default-codec tch-h (hr|amr)",
1627 "Set default codec\n" "Codec for TCH/H\n"
1628 "Half-Rate\n" "Adaptive Multi-Rate\n")
1629{
1630 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1631
1632 return CMD_SUCCESS;
1633}
1634
1635
1636DEFUN(logging_fltr_imsi,
1637 logging_fltr_imsi_cmd,
1638 "logging filter imsi IMSI",
1639 LOGGING_STR FILTER_STR
1640 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1641{
1642 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001643 struct log_target *tgt = osmo_log_vty2tgt(vty);
1644 const char *imsi = argv[0];
1645
1646 if (!tgt)
1647 return CMD_WARNING;
1648
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001649 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001650
1651 if (!vlr_subscr) {
1652 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1653 argv[0], VTY_NEWLINE);
1654 return CMD_WARNING;
1655 }
1656
1657 log_set_filter_vlr_subscr(tgt, vlr_subscr);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001658 vlr_subscr_put(vlr_subscr, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001659 return CMD_SUCCESS;
1660}
1661
1662static struct cmd_node hlr_node = {
1663 HLR_NODE,
1664 "%s(config-hlr)# ",
1665 1,
1666};
1667
1668DEFUN(cfg_hlr, cfg_hlr_cmd,
1669 "hlr", "Configure connection to the HLR")
1670{
1671 vty->node = HLR_NODE;
1672 return CMD_SUCCESS;
1673}
1674
1675DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1676 "Remote GSUP address of the HLR\n"
1677 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1678{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001679 talloc_free((void*)gsmnet->gsup_server_addr_str);
1680 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1681 return CMD_SUCCESS;
1682}
1683
1684DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1685 "Remote GSUP port of the HLR\n"
1686 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1687{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001688 gsmnet->gsup_server_port = atoi(argv[0]);
1689 return CMD_SUCCESS;
1690}
1691
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001692DEFUN(cfg_hlr_ipa_name,
1693 cfg_hlr_ipa_name_cmd,
1694 "ipa-name NAME",
1695 "Set the IPA name of this MSC\n"
1696 "A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. "
1697 "This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. "
1698 "The default is 'MSC-00-00-00-00-00-00'.\n")
1699{
1700 if (vty->type != VTY_FILE) {
1701 vty_out(vty, "The IPA name cannot be changed at run-time; "
1702 "It can only be set in the configuraton file.%s", VTY_NEWLINE);
1703 return CMD_WARNING;
1704 }
1705
1706 gsmnet->msc_ipa_name = talloc_strdup(gsmnet, argv[0]);
1707 return CMD_SUCCESS;
1708}
1709
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001710static int config_write_hlr(struct vty *vty)
1711{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001712 vty_out(vty, "hlr%s", VTY_NEWLINE);
1713 vty_out(vty, " remote-ip %s%s",
1714 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1715 vty_out(vty, " remote-port %u%s",
1716 gsmnet->gsup_server_port, VTY_NEWLINE);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001717 if (gsmnet->msc_ipa_name)
1718 vty_out(vty, " ipa-name %s%s", gsmnet->msc_ipa_name, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001719 return CMD_SUCCESS;
1720}
1721
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001722void msc_vty_init(struct gsm_network *msc_network)
1723{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001724 OSMO_ASSERT(gsmnet == NULL);
1725 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001726
1727 osmo_stats_vty_add_cmds();
1728
1729 install_element(CONFIG_NODE, &cfg_net_cmd);
1730 install_node(&net_node, config_write_net);
1731 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
1732 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1733 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1734 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
1735 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
1736 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
1737 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
1738 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
1739 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
1740 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
1741 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
1742 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
1743 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001744
1745 install_element(CONFIG_NODE, &cfg_msc_cmd);
1746 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001747 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01001748 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
1749 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02001750 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01001751 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Vadim Yanitskiy64623e12018-11-28 23:05:51 +07001752 install_element(MSC_NODE, &cfg_msc_ncss_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001753 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01001754 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
1755 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Oliver Smith0fec28a2018-12-14 10:52:52 +01001756 install_element(MSC_NODE, &cfg_msc_check_imei_rqd_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001757 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
1758 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01001759 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01001760 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +07001761 install_element(MSC_NODE, &cfg_msc_sms_over_gsup_cmd);
1762 install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001763 install_element(MSC_NODE, &cfg_msc_handover_number_range_cmd);
1764
1765 neighbor_ident_vty_init(msc_network);
Philipp Maierfbf66102017-04-09 12:32:51 +02001766
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02001767 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001768#ifdef BUILD_IU
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001769 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 +02001770#endif
Harald Welte0df904d2018-12-03 11:00:04 +01001771 sgs_vty_init();
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001772
Stefan Sperling617ac802018-02-22 17:58:20 +01001773 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001774
1775 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
1776
1777 install_element_ve(&show_subscr_cmd);
1778 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01001779 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001780 install_element_ve(&show_msc_conn_cmd);
1781 install_element_ve(&show_msc_transaction_cmd);
1782
1783 install_element_ve(&sms_send_pend_cmd);
1784 install_element_ve(&sms_delete_expired_cmd);
1785
1786 install_element_ve(&subscriber_create_cmd);
1787 install_element_ve(&subscriber_send_sms_cmd);
1788 install_element_ve(&subscriber_silent_sms_cmd);
1789 install_element_ve(&subscriber_silent_call_start_cmd);
1790 install_element_ve(&subscriber_silent_call_stop_cmd);
1791 install_element_ve(&subscriber_ussd_notify_cmd);
1792 install_element_ve(&subscriber_mstest_close_cmd);
1793 install_element_ve(&subscriber_mstest_open_cmd);
1794 install_element_ve(&subscriber_paging_cmd);
1795 install_element_ve(&show_stats_cmd);
1796 install_element_ve(&show_smsqueue_cmd);
1797 install_element_ve(&logging_fltr_imsi_cmd);
1798
1799 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
1800 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
1801 install_element(ENABLE_NODE, &smsqueue_max_cmd);
1802 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
1803 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
1804 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001805 install_element(ENABLE_NODE, &subscriber_sms_delete_all_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001806
1807 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1808 install_node(&mncc_int_node, config_write_mncc_int);
1809 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1810 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1811
1812 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
1813
1814 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1815 install_node(&hlr_node, config_write_hlr);
1816 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1817 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001818 install_element(HLR_NODE, &cfg_hlr_ipa_name_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001819}