blob: 2990735722993be7d4b1bf96867b89f0b910c51b [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,
458 "check-imei-rqd (0|1)",
459 "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"
462 "Send each IMEI to the EIR\n")
463{
464 gsmnet->vlr->cfg.check_imei_rqd = atoi(argv[0]) ? true : false;
465 return CMD_SUCCESS;
466}
467
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100468DEFUN(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd,
469 "paging response-timer (default|<1-65535>)",
470 "Configure Paging\n"
471 "Set Paging timeout, the minimum time to pass between (unsuccessful) Pagings sent towards"
472 " BSS or RNC\n"
473 "Set to default timeout (" OSMO_STRINGIFY_VAL(MSC_PAGING_RESPONSE_TIMER_DEFAULT) " seconds)\n"
474 "Set paging timeout in seconds\n")
475{
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100476 if (!strcmp(argv[1], "default"))
477 gsmnet->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
478 else
479 gsmnet->paging_response_timer = atoi(argv[0]);
480 return CMD_SUCCESS;
481}
482
Harald Welte69c54a82018-02-09 20:41:14 +0100483DEFUN(cfg_msc_emergency_msisdn, cfg_msc_emergency_msisdn_cmd,
484 "emergency-call route-to-msisdn MSISDN",
485 "Configure Emergency Call Behaviour\n"
486 "MSISDN to which Emergency Calls are Dispatched\n"
487 "MSISDN (E.164 Phone Number)\n")
488{
Harald Welte69c54a82018-02-09 20:41:14 +0100489 osmo_talloc_replace_string(gsmnet, &gsmnet->emergency.route_to_msisdn, argv[0]);
490
491 return CMD_SUCCESS;
492}
493
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700494/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
495DEFUN(cfg_msc_sms_over_gsup, cfg_msc_sms_over_gsup_cmd,
496 "sms-over-gsup",
497 "Enable routing of SMS messages over GSUP\n")
498{
499 gsmnet->sms_over_gsup = true;
500 return CMD_SUCCESS;
501}
502
503/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
504DEFUN(cfg_msc_no_sms_over_gsup, cfg_msc_no_sms_over_gsup_cmd,
505 "no sms-over-gsup",
506 NO_STR "Disable routing of SMS messages over GSUP\n")
507{
508 gsmnet->sms_over_gsup = false;
509 return CMD_SUCCESS;
510}
511
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100512/* FIXME: This should rather be in the form of
513 * handover-number range 001234xxx
514 * and
515 * handover-number range 001234xxx FIRST LAST
516 */
517DEFUN(cfg_msc_handover_number_range, cfg_msc_handover_number_range_cmd,
518 "handover-number range MSISDN_FIRST MSISDN_LAST",
519 "Configure a range of MSISDN to be assigned to incoming inter-MSC Handovers for call forwarding.\n"
520 "Configure a handover number range\n"
521 "First Handover Number MSISDN\n"
522 "Last Handover Number MSISDN\n")
523{
524 char *endp;
525 uint64_t range_start;
526 uint64_t range_end;
527
528 /* FIXME leading zeros?? */
529
530 errno = 0;
531 range_start = strtoull(argv[0], &endp, 10);
532 if (errno || *endp != '\0') {
533 vty_out(vty, "%% Error parsing handover-number range start: %s%s",
534 argv[0], VTY_NEWLINE);
535 return CMD_WARNING;
536 }
537
538 errno = 0;
539 range_end = strtoull(argv[1], &endp, 10);
540 if (errno || *endp != '\0') {
541 vty_out(vty, "%% Error parsing handover-number range end: %s%s",
542 argv[1], VTY_NEWLINE);
543 return CMD_WARNING;
544 }
545
546 if (range_start > range_end) {
547 vty_out(vty, "%% Error: handover-number range end must be > than the range start, but"
548 " %"PRIu64" > %"PRIu64"%s", range_start, range_end, VTY_NEWLINE);
549 return CMD_WARNING;
550 }
551
552 gsmnet->handover_number.range_start = range_start;
553 gsmnet->handover_number.range_end = range_end;
554 return CMD_SUCCESS;
555}
556
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200557static int config_write_msc(struct vty *vty)
558{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200559 vty_out(vty, "msc%s", VTY_NEWLINE);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100560 if (gsmnet->mncc_sock_path)
561 vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE);
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100562 vty_out(vty, " mncc guard-timeout %i%s",
Philipp Maier9ca7b312018-10-10 17:00:49 +0200563 gsmnet->mncc_guard_timeout, VTY_NEWLINE);
Vadim Yanitskiy64623e12018-11-28 23:05:51 +0700564 vty_out(vty, " ncss guard-timeout %i%s",
565 gsmnet->ncss_guard_timeout, VTY_NEWLINE);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200566 vty_out(vty, " %sassign-tmsi%s",
567 gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
568
Philipp Maierfbf66102017-04-09 12:32:51 +0200569 vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
570 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100571#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200572 vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance,
573 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100574#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200575
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100576 if (gsmnet->vlr->cfg.auth_tuple_max_reuse_count)
577 vty_out(vty, " auth-tuple-max-reuse-count %d%s",
578 OSMO_MAX(-1, gsmnet->vlr->cfg.auth_tuple_max_reuse_count),
579 VTY_NEWLINE);
580 if (gsmnet->vlr->cfg.auth_reuse_old_sets_on_error)
581 vty_out(vty, " auth-tuple-reuse-on-error 1%s",
582 VTY_NEWLINE);
583
Oliver Smith0fec28a2018-12-14 10:52:52 +0100584 if (gsmnet->vlr->cfg.check_imei_rqd)
585 vty_out(vty, " check-imei-rqd 1 %s",
586 VTY_NEWLINE);
587
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100588 if (gsmnet->paging_response_timer != MSC_PAGING_RESPONSE_TIMER_DEFAULT)
589 vty_out(vty, " paging response-timer %u%s", gsmnet->paging_response_timer, VTY_NEWLINE);
590
Harald Welte69c54a82018-02-09 20:41:14 +0100591 if (gsmnet->emergency.route_to_msisdn) {
592 vty_out(vty, " emergency-call route-to-msisdn %s%s",
593 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
594 }
595
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700596 if (gsmnet->sms_over_gsup)
597 vty_out(vty, " sms-over-gsup%s", VTY_NEWLINE);
598
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100599 if (gsmnet->handover_number.range_start || gsmnet->handover_number.range_end)
600 vty_out(vty, " handover-number range %"PRIu64" %"PRIu64"%s",
601 gsmnet->handover_number.range_start, gsmnet->handover_number.range_end,
602 VTY_NEWLINE);
603
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +0200604 mgcp_client_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200605#ifdef BUILD_IU
Neels Hofmeyr00e82d62017-07-05 15:19:52 +0200606 ranap_iu_vty_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200607#endif
608
Neels Hofmeyr880b9502019-05-09 02:01:55 +0200609 neighbor_ident_vty_write(vty);
610
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200611 return CMD_SUCCESS;
612}
613
Maxc51609a2018-11-09 17:13:00 +0100614DEFUN(show_bsc, show_bsc_cmd,
615 "show bsc", SHOW_STR "BSC\n")
616{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100617 struct ran_peer *rp;
618 llist_for_each_entry(rp, &gsmnet->a.sri->ran_peers, entry) {
619 vty_out(vty, "BSC %s %s%s",
620 osmo_sccp_inst_addr_name(gsmnet->a.sri->sccp, &rp->peer_addr),
621 osmo_fsm_inst_state_name(rp->fi),
622 VTY_NEWLINE);
Maxc51609a2018-11-09 17:13:00 +0100623 }
624
625 return CMD_SUCCESS;
626}
627
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100628/*
629_Subscriber_______________________________________ _LAC_ _RAN___________________ _MSC-A_state_________ _MSC-A_use_
630IMSI-123456789012345:MSISDN-12345:TMSI-0x12345678 1 GERAN-A-4294967295:A5-3 WAIT_CLASSMARK_UPDATE 2=cm_service,trans_cc
631IMSI-123456789012356:MSISDN-234567:TMSI-0x123ABC78 65535 UTRAN-Iu-4294967295 COMMUNICATING 2=cm_service,trans_sms
632IMSI-123456789012367:MSISDN-98712345890:TMSI-0xF.. - EUTRAN-SGs RELEASING 0=none
633IMSI-123456789012378:HONR-12345432101 2 MSC-901-700-423:9876 REMOTE_MSC_A 1=inter_msc
634*/
635static void vty_dump_one_conn(struct vty *vty, const struct msub *msub, int *idx)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100636{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100637 struct msc_a *msc_a = msub_msc_a(msub);
638 struct vlr_subscr *vsub = msub_vsub(msub);
639 char buf[128];
Max45df98b2019-01-17 18:44:33 +0100640
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100641 if (!(*idx))
642 vty_out(vty,
643 "_Subscriber_______________________________________ _LAC_ _RAN___________________"
644 " _MSC-A_state_________ _MSC-A_use_%s",
Max45df98b2019-01-17 18:44:33 +0100645 VTY_NEWLINE);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100646 (*idx)++;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100647
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100648 vty_out(vty, "%50s %5u %23s %20s %d=%s%s",
649 vlr_subscr_short_name(msub_vsub(msub), 50),
650 vsub ? vsub->cgi.lai.lac : 0,
651 msub_ran_conn_name(msub),
652 osmo_fsm_inst_state_name(msc_a->c.fi),
653 osmo_use_count_total(&msc_a->use_count),
654 osmo_use_count_name_buf(buf, sizeof(buf), &msc_a->use_count),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100655 VTY_NEWLINE);
656}
657
658DEFUN(show_msc_conn, show_msc_conn_cmd,
659 "show connection", SHOW_STR "Subscriber Connections\n")
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200660{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100661 struct msub *msub;
662 int idx = 0;
663 llist_for_each_entry(msub, &msub_list, entry) {
664 vty_dump_one_conn(vty, msub, &idx);
665 }
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100666 return CMD_SUCCESS;
667}
668
669static void vty_trans_hdr(struct vty *vty)
670{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100671 if (llist_empty(&gsmnet->trans_list))
672 return;
Max45df98b2019-01-17 18:44:33 +0100673
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100674 vty_out(vty,
675 "_Subscriber_______________________________________ _RAN___________________"
676 " _P__ TI CallRef_ _state_%s",
677 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100678}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200679
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100680static const char *get_trans_proto_str(const struct gsm_trans *trans)
681{
682 static char buf[256];
683
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100684 switch (trans->type) {
685 case TRANS_CC:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100686 snprintf(buf, sizeof(buf), "%s %4u %4u",
687 gsm48_cc_state_name(trans->cc.state),
688 trans->cc.Tcurrent,
689 trans->cc.T308_second);
690 break;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100691 case TRANS_SMS:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100692 snprintf(buf, sizeof(buf), "%s %s",
693 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
694 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
695 break;
696 default:
697 buf[0] = '\0';
698 break;
699 }
700
701 return buf;
702}
703
704static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
705{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100706 vty_out(vty, "%50s %23s %4s %02u %08x %s%s",
707 vlr_subscr_short_name(msc_a_vsub(trans->msc_a), 50),
708 msub_ran_conn_name(trans->msc_a->c.msub),
709 trans_type_name(trans->type),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100710 trans->transaction_id,
711 trans->callref,
Max45df98b2019-01-17 18:44:33 +0100712 get_trans_proto_str(trans),
Max45df98b2019-01-17 18:44:33 +0100713 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100714}
715
716DEFUN(show_msc_transaction, show_msc_transaction_cmd,
717 "show transaction", SHOW_STR "Transactions\n")
718{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100719 struct gsm_trans *trans;
720
721 vty_trans_hdr(vty);
722 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
723 vty_dump_one_trans(vty, trans);
724
725 return CMD_SUCCESS;
726}
727
728static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
729{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100730 struct gsm_trans *trans;
731 int reqs;
732 struct llist_head *entry;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100733 char buf[128];
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100734
735 if (strlen(vsub->name))
736 vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
737 if (strlen(vsub->msisdn))
738 vty_out(vty, " Extension: %s%s", vsub->msisdn,
739 VTY_NEWLINE);
740 vty_out(vty, " LAC: %d/0x%x%s",
Max7d41d872018-12-19 11:48:33 +0100741 vsub->cgi.lai.lac, vsub->cgi.lai.lac, VTY_NEWLINE);
Philipp Maier2a0ac3b2018-12-17 10:03:50 +0100742 vty_out(vty, " RAN: %s%s",
Neels Hofmeyr7814a832018-12-26 00:40:18 +0100743 osmo_rat_type_name(vsub->cs.attached_via_ran), VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100744 vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
745 if (vsub->tmsi != GSM_RESERVED_TMSI)
746 vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
747 VTY_NEWLINE);
748 if (vsub->tmsi_new != GSM_RESERVED_TMSI)
749 vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
750 VTY_NEWLINE);
Philipp Maier6d71ccf2018-12-14 13:30:14 +0100751 if (vsub->imei[0] != '\0')
752 vty_out(vty, " IMEI: %s%s", vsub->imei, VTY_NEWLINE);
753 if (vsub->imeisv[0] != '\0')
754 vty_out(vty, " IMEISV: %s%s", vsub->imeisv, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100755
Philipp Maier89561bc2018-12-14 13:34:25 +0100756 vty_out(vty, " Flags: %s", VTY_NEWLINE);
757 vty_out(vty, " IMSI detached: %s%s",
758 vsub->imsi_detached_flag ? "true" : "false", VTY_NEWLINE);
759 vty_out(vty, " Conf. by radio contact: %s%s",
760 vsub->conf_by_radio_contact_ind ? "true" : "false",
761 VTY_NEWLINE);
762 vty_out(vty, " Subscr. data conf. by HLR: %s%s",
763 vsub->sub_dataconf_by_hlr_ind ? "true" : "false", VTY_NEWLINE);
764 vty_out(vty, " Location conf. in HLR: %s%s",
765 vsub->loc_conf_in_hlr_ind ? "true" : "false", VTY_NEWLINE);
766 vty_out(vty, " Subscriber dormant: %s%s",
767 vsub->dormant_ind ? "true" : "false", VTY_NEWLINE);
768 vty_out(vty, " Received cancel locataion: %s%s",
769 vsub->cancel_loc_rx ? "true" : "false", VTY_NEWLINE);
770 vty_out(vty, " MS not reachable: %s%s",
771 vsub->ms_not_reachable_flag ? "true" : "false", VTY_NEWLINE);
772 vty_out(vty, " LA allowed: %s%s",
773 vsub->la_allowed ? "true" : "false", VTY_NEWLINE);
774
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100775 if (vsub->last_tuple) {
Neels Hofmeyr8b6e5362018-11-30 02:57:33 +0100776 struct vlr_auth_tuple *t = vsub->last_tuple;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100777 vty_out(vty, " A3A8 last tuple (used %d times):%s",
778 t->use_count, VTY_NEWLINE);
779 vty_out(vty, " seq # : %d%s",
780 t->key_seq, VTY_NEWLINE);
781 vty_out(vty, " RAND : %s%s",
782 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
783 VTY_NEWLINE);
784 vty_out(vty, " SRES : %s%s",
785 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
786 VTY_NEWLINE);
787 vty_out(vty, " Kc : %s%s",
788 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
789 VTY_NEWLINE);
790 }
791
792 reqs = 0;
793 llist_for_each(entry, &vsub->cs.requests)
794 reqs += 1;
795 vty_out(vty, " Paging: %s paging for %d requests%s",
796 vsub->cs.is_paging ? "is" : "not", reqs, VTY_NEWLINE);
Harald Welte0df904d2018-12-03 11:00:04 +0100797
798 /* SGs related */
799 vty_out(vty, " SGs-state: %s%s",
800 osmo_fsm_inst_state_name(vsub->sgs_fsm), VTY_NEWLINE);
Vadim Yanitskiy477cbc62019-02-23 16:59:16 +0700801 if (strlen(vsub->sgs.mme_name))
Harald Welte0df904d2018-12-03 11:00:04 +0100802 vty_out(vty, " SGs-MME: %s%s", vsub->sgs.mme_name, VTY_NEWLINE);
803 else
804 vty_out(vty, " SGs-MME: (none)%s", VTY_NEWLINE);
805
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100806 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 +0100807
808 /* Connection */
809 if (vsub->msc_conn_ref) {
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100810 struct msub *msub = vsub->msc_conn_ref;
811 int idx = 0;
812 if (msub) {
813 vty_dump_one_conn(vty, msub, &idx);
814 }
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100815 }
816
817 /* Transactions */
818 vty_trans_hdr(vty);
819 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
820 if (trans->vsub != vsub)
821 continue;
822 vty_dump_one_trans(vty, trans);
823 }
824}
825
826/* Subscriber */
827DEFUN(show_subscr_cache,
828 show_subscr_cache_cmd,
829 "show subscriber cache",
830 SHOW_STR "Show information about subscribers\n"
831 "Display contents of subscriber cache\n")
832{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100833 struct vlr_subscr *vsub;
834 int count = 0;
835
836 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
837 if (++count > 100) {
838 vty_out(vty, "%% More than %d subscribers in cache,"
839 " stopping here.%s", count-1, VTY_NEWLINE);
840 break;
841 }
842 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
843 subscr_dump_full_vty(vty, vsub);
Harald Welte69c54a82018-02-09 20:41:14 +0100844 }
845
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200846 return CMD_SUCCESS;
847}
848
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100849DEFUN(sms_send_pend,
850 sms_send_pend_cmd,
851 "sms send pending",
852 "SMS related commands\n" "SMS Sending related commands\n"
853 "Send all pending SMS")
854{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100855 struct gsm_sms *sms;
856 unsigned long long sms_id = 0;
857
858 while (1) {
859 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
860 if (!sms)
861 break;
862
863 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700864 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100865
866 sms_id = sms->id + 1;
867 }
868
869 return CMD_SUCCESS;
870}
871
872DEFUN(sms_delete_expired,
873 sms_delete_expired_cmd,
874 "sms delete expired",
875 "SMS related commands\n" "SMS Database related commands\n"
876 "Delete all expired SMS")
877{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100878 struct gsm_sms *sms;
879 unsigned long long sms_id = 0;
880 long long num_deleted = 0;
881
882 while (1) {
883 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
884 if (!sms)
885 break;
886
887 /* Skip SMS which are currently queued for sending. */
888 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
889 continue;
890
891 /* Expiration check is performed by the DB layer. */
892 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
893 num_deleted++;
894
895 sms_id = sms->id + 1;
896 }
897
898 if (num_deleted == 0) {
899 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
900 return CMD_WARNING;
901 }
902
903 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
904 return CMD_SUCCESS;
905}
906
907static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +0200908 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100909 char *str, uint8_t tp_pid)
910{
911 struct gsm_network *net = receiver->vlr->user_ctx;
912 struct gsm_sms *sms;
913
Harald Welte39b55482018-04-09 19:19:33 +0200914 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100915 sms->protocol_id = tp_pid;
916
917 /* store in database for the queue */
918 if (db_sms_store(sms) != 0) {
919 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
920 sms_free(sms);
921 return CMD_WARNING;
922 }
923 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
924
925 sms_free(sms);
926 sms_queue_trigger(net->sms_queue);
927 return CMD_SUCCESS;
928}
929
930static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
931 const char *type,
932 const char *id)
933{
934 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100935 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100936 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100937 return vlr_subscr_find_by_imsi(gsmnet->vlr, id, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100938 else if (!strcmp(type, "tmsi"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100939 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id), VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100940
941 return NULL;
942}
943#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
944#define SUBSCR_HELP "Operations on a Subscriber\n" \
945 "Identify subscriber by MSISDN (phone number)\n" \
946 "Legacy alias for 'msisdn'\n" \
947 "Identify subscriber by IMSI\n" \
948 "Identify subscriber by TMSI\n" \
949 "Identify subscriber by database ID\n" \
950 "Identifier for the subscriber\n"
951
952DEFUN(show_subscr,
953 show_subscr_cmd,
954 "show subscriber " SUBSCR_TYPES " ID",
955 SHOW_STR SUBSCR_HELP)
956{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100957 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
958 argv[1]);
959
960 if (!vsub) {
961 vty_out(vty, "%% No subscriber found for %s %s%s",
962 argv[0], argv[1], VTY_NEWLINE);
963 return CMD_WARNING;
964 }
965
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100966 /* In the vty output to the user, exclude this local use count added by vlr_subscr_get() in get_vsub_by_argv().
967 * This works, because: for get_vsub_by_argv() to succeed, there *must* have been at least one use count before
968 * 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 +0100969 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100970
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100971 subscr_dump_full_vty(vty, vsub);
972
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100973 return CMD_SUCCESS;
974}
975
976DEFUN(subscriber_create,
977 subscriber_create_cmd,
978 "subscriber create imsi ID",
979 "Operations on a Subscriber\n" \
980 "Create new subscriber\n" \
981 "Identify the subscriber by his IMSI\n" \
982 "Identifier for the subscriber\n")
983{
984 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
985 VTY_NEWLINE);
986 return CMD_WARNING;
987}
988
989DEFUN(subscriber_send_pending_sms,
990 subscriber_send_pending_sms_cmd,
991 "subscriber " SUBSCR_TYPES " ID sms pending-send",
992 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
993{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100994 struct vlr_subscr *vsub;
995 struct gsm_sms *sms;
996
997 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
998 if (!vsub) {
999 vty_out(vty, "%% No subscriber found for %s %s%s",
1000 argv[0], argv[1], VTY_NEWLINE);
1001 return CMD_WARNING;
1002 }
1003
1004 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
1005 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +07001006 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001007
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001008 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001009
1010 return CMD_SUCCESS;
1011}
1012
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001013DEFUN(subscriber_sms_delete_all,
1014 subscriber_sms_delete_all_cmd,
1015 "subscriber " SUBSCR_TYPES " ID sms delete-all",
1016 SUBSCR_HELP "SMS Operations\n"
1017 "Delete all SMS to be delivered to this subscriber"
1018 " -- WARNING: the SMS data for all unsent SMS for this subscriber"
1019 " WILL BE LOST.\n")
1020{
1021 struct vlr_subscr *vsub;
1022
1023 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1024 if (!vsub) {
1025 vty_out(vty, "%% No subscriber found for %s %s%s",
1026 argv[0], argv[1], VTY_NEWLINE);
1027 return CMD_WARNING;
1028 }
1029
1030 db_sms_delete_by_msisdn(vsub->msisdn);
1031
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001032 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001033
1034 return CMD_SUCCESS;
1035}
1036
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001037DEFUN(subscriber_send_sms,
1038 subscriber_send_sms_cmd,
1039 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
1040 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
1041{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001042 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +02001043 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001044 char *str;
1045 int rc;
1046
1047 if (!vsub) {
1048 vty_out(vty, "%% No subscriber found for %s %s%s",
1049 argv[0], argv[1], VTY_NEWLINE);
1050 rc = CMD_WARNING;
1051 goto err;
1052 }
1053
Harald Welte39b55482018-04-09 19:19:33 +02001054 if (!strcmp(argv[2], "msisdn"))
1055 sender_msisdn = argv[3];
1056 else {
1057 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1058 if (!sender) {
1059 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1060 rc = CMD_WARNING;
1061 goto err;
1062 }
1063 sender_msisdn = sender->msisdn;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001064 vlr_subscr_put(sender, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001065 }
1066
1067 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001068 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001069 talloc_free(str);
1070
1071err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001072 if (vsub)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001073 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001074
1075 return rc;
1076}
1077
1078DEFUN(subscriber_silent_sms,
1079 subscriber_silent_sms_cmd,
1080
1081 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
1082 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
1083{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001084 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +02001085 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001086 char *str;
1087 int rc;
1088
1089 if (!vsub) {
1090 vty_out(vty, "%% No subscriber found for %s %s%s",
1091 argv[0], argv[1], VTY_NEWLINE);
1092 rc = CMD_WARNING;
1093 goto err;
1094 }
1095
Harald Welte39b55482018-04-09 19:19:33 +02001096 if (!strcmp(argv[2], "msisdn")) {
1097 sender_msisdn = argv[3];
1098 } else {
1099 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1100 if (!sender) {
1101 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1102 rc = CMD_WARNING;
1103 goto err;
1104 }
1105 sender_msisdn = sender->msisdn;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001106 vlr_subscr_put(sender, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001107 }
1108
1109 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001110 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001111 talloc_free(str);
1112
1113err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001114 if (vsub)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001115 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001116
1117 return rc;
1118}
1119
Sylvain Munaut93558302019-02-14 20:13:08 +01001120#define CHAN_TYPES "(any|tch/f|tch/h|tch/any|sdcch)"
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001121#define CHAN_TYPE_HELP \
1122 "Any channel\n" \
1123 "TCH/F channel\n" \
Sylvain Munaut93558302019-02-14 20:13:08 +01001124 "TCH/H channel\n" \
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001125 "Any TCH channel\n" \
1126 "SDCCH channel\n"
1127
Sylvain Munaut93558302019-02-14 20:13:08 +01001128#define CHAN_MODES "(signalling|speech-hr|speech-fr|speech-efr|speech-amr)"
1129#define CHAN_MODE_HELP \
1130 "Signalling only\n" \
1131 "Speech with HR codec\n" \
1132 "Speech with FR codec\n" \
1133 "Speech with EFR codec\n" \
1134 "Speech with AMR codec\n"
1135
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001136DEFUN(subscriber_silent_call_start,
1137 subscriber_silent_call_start_cmd,
Sylvain Munaut93558302019-02-14 20:13:08 +01001138 "subscriber " SUBSCR_TYPES " ID silent-call start " CHAN_TYPES " " CHAN_MODES " [IP] [<0-65535>]",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001139 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
Sylvain Munaut93558302019-02-14 20:13:08 +01001140 CHAN_TYPE_HELP CHAN_MODE_HELP
1141 "Target IP for RTP traffic (default 127.0.0.1)\n"
1142 "Target port for RTP traffic (default: 4000)\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001143{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001144 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Sylvain Munaut93558302019-02-14 20:13:08 +01001145 struct gsm0808_channel_type ct;
1146 const char *ip;
1147 uint16_t port;
1148 int rc, speech;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001149
1150 if (!vsub) {
1151 vty_out(vty, "%% No subscriber found for %s %s%s",
1152 argv[0], argv[1], VTY_NEWLINE);
1153 return CMD_WARNING;
1154 }
1155
Sylvain Munaut93558302019-02-14 20:13:08 +01001156 memset(&ct, 0x00, sizeof(ct));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001157
Sylvain Munaut93558302019-02-14 20:13:08 +01001158 if (!strcmp(argv[3], "signalling")) {
1159 ct.ch_indctr = GSM0808_CHAN_SIGN;
1160 ct.perm_spch[0] = 0; /* Spare but required */
1161 ct.perm_spch_len = 1;
1162 } else if (!strcmp(argv[3], "speech-hr")) {
1163 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1164 ct.perm_spch[0] = GSM0808_PERM_HR1;
1165 ct.perm_spch_len = 1;
1166 } else if (!strcmp(argv[3], "speech-fr")) {
1167 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1168 ct.perm_spch[0] = GSM0808_PERM_FR1;
1169 ct.perm_spch_len = 1;
1170 } else if (!strcmp(argv[3], "speech-efr")) {
1171 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1172 ct.perm_spch[0] = GSM0808_PERM_FR2;
1173 ct.perm_spch_len = 1;
1174 } else if (!strcmp(argv[3], "speech-amr")) {
1175 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1176 ct.perm_spch[0] = GSM0808_PERM_FR3;
1177 ct.perm_spch[1] = GSM0808_PERM_HR3;
1178 ct.perm_spch_len = 2;
1179 }
1180
1181 speech = ct.ch_indctr == GSM0808_CHAN_SPEECH;
1182
1183 if (!strcmp(argv[2], "tch/f"))
1184 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_BM : GSM0808_SIGN_FULL_BM;
1185 else if (!strcmp(argv[2], "tch/h"))
1186 ct.ch_rate_type = speech ? GSM0808_SPEECH_HALF_LM : GSM0808_SIGN_HALF_LM;
1187 else if (!strcmp(argv[2], "tch/any"))
1188 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_FULL_PREF;
1189 else if (!strcmp(argv[2], "sdcch")) {
1190 if (speech) {
1191 vty_out(vty, "Can't request speech on SDCCH%s", VTY_NEWLINE);
1192 return CMD_WARNING;
1193 }
1194 ct.ch_rate_type = GSM0808_SIGN_SDCCH;
1195 } else
1196 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_ANY;
1197
1198 ip = argc >= 5 ? argv[4] : "127.0.0.1";
1199 port = argc >= 6 ? atoi(argv[5]) : 4000;
1200
1201 rc = gsm_silent_call_start(vsub, &ct, ip, port, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001202 switch (rc) {
1203 case -ENODEV:
1204 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
1205 break;
1206 default:
1207 if (rc)
1208 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
1209 else
1210 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
1211 break;
1212 }
1213
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001214 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001215 return rc ? CMD_WARNING : CMD_SUCCESS;
1216}
1217
1218DEFUN(subscriber_silent_call_stop,
1219 subscriber_silent_call_stop_cmd,
1220 "subscriber " SUBSCR_TYPES " ID silent-call stop",
1221 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
1222 CHAN_TYPE_HELP)
1223{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001224 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1225 int rc;
1226
1227 if (!vsub) {
1228 vty_out(vty, "%% No subscriber found for %s %s%s",
1229 argv[0], argv[1], VTY_NEWLINE);
1230 return CMD_WARNING;
1231 }
1232
1233 rc = gsm_silent_call_stop(vsub);
1234 switch (rc) {
1235 case -ENODEV:
1236 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
1237 break;
1238 case -ENOENT:
1239 vty_out(vty, "%% Subscriber has no silent call active%s",
1240 VTY_NEWLINE);
1241 break;
1242 default:
1243 if (rc)
1244 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
1245 else
1246 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
1247 break;
1248 }
1249
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001250 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001251 return rc ? CMD_WARNING : CMD_SUCCESS;
1252}
1253
1254DEFUN(subscriber_ussd_notify,
1255 subscriber_ussd_notify_cmd,
1256 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1257 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1258 "Alerting Level 0\n"
1259 "Alerting Level 1\n"
1260 "Alerting Level 2\n"
1261 "Text of USSD message to send\n")
1262{
1263 char *text;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001264 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001265 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1266 int level;
1267
1268 if (!vsub) {
1269 vty_out(vty, "%% No subscriber found for %s %s%s",
1270 argv[0], argv[1], VTY_NEWLINE);
1271 return CMD_WARNING;
1272 }
1273
1274 level = atoi(argv[2]);
1275 text = argv_concat(argv, argc, 3);
1276 if (!text) {
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001277 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001278 return CMD_WARNING;
1279 }
1280
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001281 msc_a = msc_a_for_vsub(vsub, true);
1282 if (!msc_a || msc_a->c.remote_to) {
1283 vty_out(vty, "%% An active connection and local MSC-A role is required for %s %s%s",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001284 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001285 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001286 talloc_free(text);
1287 return CMD_WARNING;
1288 }
1289
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001290 msc_send_ussd_notify(msc_a, level, text);
Vadim Yanitskiyf20c6b72018-11-29 01:20:58 +07001291 /* FIXME: since we don't allocate a transaction here,
1292 * we use dummy GSM 04.07 transaction ID. */
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001293 msc_send_ussd_release_complete(msc_a, 0x00);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001294
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001295 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001296 talloc_free(text);
1297 return CMD_SUCCESS;
1298}
1299
1300DEFUN(subscriber_paging,
1301 subscriber_paging_cmd,
1302 "subscriber " SUBSCR_TYPES " ID paging",
1303 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1304{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001305 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001306 struct paging_request *req;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001307
1308 if (!vsub) {
1309 vty_out(vty, "%% No subscriber found for %s %s%s",
1310 argv[0], argv[1], VTY_NEWLINE);
1311 return CMD_WARNING;
1312 }
1313
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001314 req = paging_request_start(vsub, PAGING_CAUSE_CALL_CONVERSATIONAL,
1315 NULL, NULL, "manual Paging from VTY");
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001316 if (req)
1317 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1318 else
1319 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1320
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001321 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001322 return req ? CMD_SUCCESS : CMD_WARNING;
1323}
1324
1325static int loop_by_char(uint8_t ch)
1326{
1327 switch (ch) {
1328 case 'a':
1329 return GSM414_LOOP_A;
1330 case 'b':
1331 return GSM414_LOOP_B;
1332 case 'c':
1333 return GSM414_LOOP_C;
1334 case 'd':
1335 return GSM414_LOOP_D;
1336 case 'e':
1337 return GSM414_LOOP_E;
1338 case 'f':
1339 return GSM414_LOOP_F;
1340 case 'i':
1341 return GSM414_LOOP_I;
1342 }
1343 return -1;
1344}
1345
1346DEFUN(subscriber_mstest_close,
1347 subscriber_mstest_close_cmd,
1348 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1349 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1350 "Close a TCH Loop inside the MS\n"
1351 "Loop Type A\n"
1352 "Loop Type B\n"
1353 "Loop Type C\n"
1354 "Loop Type D\n"
1355 "Loop Type E\n"
1356 "Loop Type F\n"
1357 "Loop Type I\n")
1358{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001359 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001360 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1361 const char *loop_str;
1362 int loop_mode;
1363
1364 if (!vsub) {
1365 vty_out(vty, "%% No subscriber found for %s %s%s",
1366 argv[0], argv[1], VTY_NEWLINE);
1367 return CMD_WARNING;
1368 }
1369
1370 loop_str = argv[2];
1371 loop_mode = loop_by_char(loop_str[0]);
1372
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001373 msc_a = msc_a_for_vsub(vsub, true);
1374 if (!msc_a) {
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001375 vty_out(vty, "%% An active connection is required for %s %s%s",
1376 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001377 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001378 return CMD_WARNING;
1379 }
1380
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001381 gsm0414_tx_close_tch_loop_cmd(msc_a, loop_mode);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001382
1383 return CMD_SUCCESS;
1384}
1385
1386DEFUN(subscriber_mstest_open,
1387 subscriber_mstest_open_cmd,
1388 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1389 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1390 "Open a TCH Loop inside the MS\n")
1391{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001392 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001393 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1394
1395 if (!vsub) {
1396 vty_out(vty, "%% No subscriber found for %s %s%s",
1397 argv[0], argv[1], VTY_NEWLINE);
1398 return CMD_WARNING;
1399 }
1400
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001401 msc_a = msc_a_for_vsub(vsub, true);
1402 if (!msc_a) {
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001403 vty_out(vty, "%% An active connection is required for %s %s%s",
1404 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001405 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001406 return CMD_WARNING;
1407 }
1408
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001409 gsm0414_tx_open_loop_cmd(msc_a);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001410
1411 return CMD_SUCCESS;
1412}
1413
1414DEFUN(ena_subscr_expire,
1415 ena_subscr_expire_cmd,
1416 "subscriber " SUBSCR_TYPES " ID expire",
1417 SUBSCR_HELP "Expire the subscriber Now\n")
1418{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001419 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1420 argv[1]);
1421
1422 if (!vsub) {
1423 vty_out(vty, "%% No subscriber found for %s %s%s",
1424 argv[0], argv[1], VTY_NEWLINE);
1425 return CMD_WARNING;
1426 }
1427
1428 if (vlr_subscr_expire(vsub))
1429 vty_out(vty, "%% VLR released subscriber %s%s",
1430 vlr_subscr_name(vsub), VTY_NEWLINE);
1431
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001432 if (osmo_use_count_total(&vsub->use_count) > 1)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001433 vty_out(vty, "%% Subscriber %s is still in use,"
1434 " should be released soon%s",
1435 vlr_subscr_name(vsub), VTY_NEWLINE);
1436
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001437 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001438 return CMD_SUCCESS;
1439}
1440
1441static int scall_cbfn(unsigned int subsys, unsigned int signal,
1442 void *handler_data, void *signal_data)
1443{
1444 struct scall_signal_data *sigdata = signal_data;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001445 struct vty *vty = sigdata->vty;
1446
1447 if (!vty_is_active(vty))
1448 return 0;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001449
1450 switch (signal) {
1451 case S_SCALL_SUCCESS:
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001452 vty_out(vty, "%% Silent call success%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001453 break;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001454 case S_SCALL_FAILED:
1455 vty_out(vty, "%% Silent call failed%s", VTY_NEWLINE);
1456 break;
1457 case S_SCALL_DETACHED:
1458 vty_out(vty, "%% Silent call ended%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001459 break;
1460 }
1461 return 0;
1462}
1463
1464DEFUN(show_stats,
1465 show_stats_cmd,
1466 "show statistics",
1467 SHOW_STR "Display network statistics\n")
1468{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001469 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001470 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1471 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1472 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001473 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001474 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001475 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001476 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001477 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001478 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1479 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001480 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001481 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001482 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1483 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001484 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001485 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001486 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1487 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1488 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001489 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001490 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001491 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1492 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001493 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001494 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001495 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1496 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001497 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001498 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001499 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1500 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1501 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1502 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1503 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001504 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001505 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1506 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1507 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1508 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1509 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001510 return CMD_SUCCESS;
1511}
1512
1513DEFUN(show_smsqueue,
1514 show_smsqueue_cmd,
1515 "show sms-queue",
1516 SHOW_STR "Display SMSqueue statistics\n")
1517{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001518 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001519 return CMD_SUCCESS;
1520}
1521
1522DEFUN(smsqueue_trigger,
1523 smsqueue_trigger_cmd,
1524 "sms-queue trigger",
1525 "SMS Queue\n" "Trigger sending messages\n")
1526{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001527 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001528 return CMD_SUCCESS;
1529}
1530
1531DEFUN(smsqueue_max,
1532 smsqueue_max_cmd,
1533 "sms-queue max-pending <1-500>",
1534 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1535{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001536 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001537 return CMD_SUCCESS;
1538}
1539
1540DEFUN(smsqueue_clear,
1541 smsqueue_clear_cmd,
1542 "sms-queue clear",
1543 "SMS Queue\n" "Clear the queue of pending SMS\n")
1544{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001545 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001546 return CMD_SUCCESS;
1547}
1548
1549DEFUN(smsqueue_fail,
1550 smsqueue_fail_cmd,
1551 "sms-queue max-failure <1-500>",
1552 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1553{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001554 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001555 return CMD_SUCCESS;
1556}
1557
1558
1559DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1560 "mncc-int", "Configure internal MNCC handler")
1561{
1562 vty->node = MNCC_INT_NODE;
1563
1564 return CMD_SUCCESS;
1565}
1566
1567static struct cmd_node mncc_int_node = {
1568 MNCC_INT_NODE,
1569 "%s(config-mncc-int)# ",
1570 1,
1571};
1572
1573static const struct value_string tchf_codec_names[] = {
1574 { GSM48_CMODE_SPEECH_V1, "fr" },
1575 { GSM48_CMODE_SPEECH_EFR, "efr" },
1576 { GSM48_CMODE_SPEECH_AMR, "amr" },
1577 { 0, NULL }
1578};
1579
1580static const struct value_string tchh_codec_names[] = {
1581 { GSM48_CMODE_SPEECH_V1, "hr" },
1582 { GSM48_CMODE_SPEECH_AMR, "amr" },
1583 { 0, NULL }
1584};
1585
1586static int config_write_mncc_int(struct vty *vty)
1587{
1588 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1589 vty_out(vty, " default-codec tch-f %s%s",
1590 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1591 VTY_NEWLINE);
1592 vty_out(vty, " default-codec tch-h %s%s",
1593 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1594 VTY_NEWLINE);
1595
1596 return CMD_SUCCESS;
1597}
1598
1599DEFUN(mnccint_def_codec_f,
1600 mnccint_def_codec_f_cmd,
1601 "default-codec tch-f (fr|efr|amr)",
1602 "Set default codec\n" "Codec for TCH/F\n"
1603 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1604{
1605 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1606
1607 return CMD_SUCCESS;
1608}
1609
1610DEFUN(mnccint_def_codec_h,
1611 mnccint_def_codec_h_cmd,
1612 "default-codec tch-h (hr|amr)",
1613 "Set default codec\n" "Codec for TCH/H\n"
1614 "Half-Rate\n" "Adaptive Multi-Rate\n")
1615{
1616 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1617
1618 return CMD_SUCCESS;
1619}
1620
1621
1622DEFUN(logging_fltr_imsi,
1623 logging_fltr_imsi_cmd,
1624 "logging filter imsi IMSI",
1625 LOGGING_STR FILTER_STR
1626 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1627{
1628 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001629 struct log_target *tgt = osmo_log_vty2tgt(vty);
1630 const char *imsi = argv[0];
1631
1632 if (!tgt)
1633 return CMD_WARNING;
1634
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001635 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001636
1637 if (!vlr_subscr) {
1638 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1639 argv[0], VTY_NEWLINE);
1640 return CMD_WARNING;
1641 }
1642
1643 log_set_filter_vlr_subscr(tgt, vlr_subscr);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001644 vlr_subscr_put(vlr_subscr, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001645 return CMD_SUCCESS;
1646}
1647
1648static struct cmd_node hlr_node = {
1649 HLR_NODE,
1650 "%s(config-hlr)# ",
1651 1,
1652};
1653
1654DEFUN(cfg_hlr, cfg_hlr_cmd,
1655 "hlr", "Configure connection to the HLR")
1656{
1657 vty->node = HLR_NODE;
1658 return CMD_SUCCESS;
1659}
1660
1661DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1662 "Remote GSUP address of the HLR\n"
1663 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1664{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001665 talloc_free((void*)gsmnet->gsup_server_addr_str);
1666 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1667 return CMD_SUCCESS;
1668}
1669
1670DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1671 "Remote GSUP port of the HLR\n"
1672 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1673{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001674 gsmnet->gsup_server_port = atoi(argv[0]);
1675 return CMD_SUCCESS;
1676}
1677
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001678DEFUN(cfg_hlr_ipa_name,
1679 cfg_hlr_ipa_name_cmd,
1680 "ipa-name NAME",
1681 "Set the IPA name of this MSC\n"
1682 "A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. "
1683 "This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. "
1684 "The default is 'MSC-00-00-00-00-00-00'.\n")
1685{
1686 if (vty->type != VTY_FILE) {
1687 vty_out(vty, "The IPA name cannot be changed at run-time; "
1688 "It can only be set in the configuraton file.%s", VTY_NEWLINE);
1689 return CMD_WARNING;
1690 }
1691
1692 gsmnet->msc_ipa_name = talloc_strdup(gsmnet, argv[0]);
1693 return CMD_SUCCESS;
1694}
1695
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001696static int config_write_hlr(struct vty *vty)
1697{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001698 vty_out(vty, "hlr%s", VTY_NEWLINE);
1699 vty_out(vty, " remote-ip %s%s",
1700 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1701 vty_out(vty, " remote-port %u%s",
1702 gsmnet->gsup_server_port, VTY_NEWLINE);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001703 if (gsmnet->msc_ipa_name)
1704 vty_out(vty, " ipa-name %s%s", gsmnet->msc_ipa_name, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001705 return CMD_SUCCESS;
1706}
1707
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001708void msc_vty_init(struct gsm_network *msc_network)
1709{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001710 OSMO_ASSERT(gsmnet == NULL);
1711 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001712
1713 osmo_stats_vty_add_cmds();
1714
1715 install_element(CONFIG_NODE, &cfg_net_cmd);
1716 install_node(&net_node, config_write_net);
1717 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
1718 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1719 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1720 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
1721 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
1722 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
1723 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
1724 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
1725 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
1726 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
1727 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
1728 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
1729 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001730
1731 install_element(CONFIG_NODE, &cfg_msc_cmd);
1732 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001733 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01001734 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
1735 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02001736 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01001737 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Vadim Yanitskiy64623e12018-11-28 23:05:51 +07001738 install_element(MSC_NODE, &cfg_msc_ncss_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001739 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01001740 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
1741 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Oliver Smith0fec28a2018-12-14 10:52:52 +01001742 install_element(MSC_NODE, &cfg_msc_check_imei_rqd_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001743 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
1744 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01001745 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01001746 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +07001747 install_element(MSC_NODE, &cfg_msc_sms_over_gsup_cmd);
1748 install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001749 install_element(MSC_NODE, &cfg_msc_handover_number_range_cmd);
1750
1751 neighbor_ident_vty_init(msc_network);
Philipp Maierfbf66102017-04-09 12:32:51 +02001752
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02001753 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001754#ifdef BUILD_IU
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001755 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 +02001756#endif
Harald Welte0df904d2018-12-03 11:00:04 +01001757 sgs_vty_init();
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001758
Stefan Sperling617ac802018-02-22 17:58:20 +01001759 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001760
1761 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
1762
1763 install_element_ve(&show_subscr_cmd);
1764 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01001765 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001766 install_element_ve(&show_msc_conn_cmd);
1767 install_element_ve(&show_msc_transaction_cmd);
1768
1769 install_element_ve(&sms_send_pend_cmd);
1770 install_element_ve(&sms_delete_expired_cmd);
1771
1772 install_element_ve(&subscriber_create_cmd);
1773 install_element_ve(&subscriber_send_sms_cmd);
1774 install_element_ve(&subscriber_silent_sms_cmd);
1775 install_element_ve(&subscriber_silent_call_start_cmd);
1776 install_element_ve(&subscriber_silent_call_stop_cmd);
1777 install_element_ve(&subscriber_ussd_notify_cmd);
1778 install_element_ve(&subscriber_mstest_close_cmd);
1779 install_element_ve(&subscriber_mstest_open_cmd);
1780 install_element_ve(&subscriber_paging_cmd);
1781 install_element_ve(&show_stats_cmd);
1782 install_element_ve(&show_smsqueue_cmd);
1783 install_element_ve(&logging_fltr_imsi_cmd);
1784
1785 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
1786 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
1787 install_element(ENABLE_NODE, &smsqueue_max_cmd);
1788 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
1789 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
1790 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001791 install_element(ENABLE_NODE, &subscriber_sms_delete_all_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001792
1793 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1794 install_node(&mncc_int_node, config_write_mncc_int);
1795 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1796 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1797
1798 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
1799
1800 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1801 install_node(&hlr_node, config_write_hlr);
1802 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1803 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001804 install_element(HLR_NODE, &cfg_hlr_ipa_name_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001805}