blob: a3237cd3de2a3d7579489621aec1b437f35faa30 [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
609 return CMD_SUCCESS;
610}
611
Maxc51609a2018-11-09 17:13:00 +0100612DEFUN(show_bsc, show_bsc_cmd,
613 "show bsc", SHOW_STR "BSC\n")
614{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100615 struct ran_peer *rp;
616 llist_for_each_entry(rp, &gsmnet->a.sri->ran_peers, entry) {
617 vty_out(vty, "BSC %s %s%s",
618 osmo_sccp_inst_addr_name(gsmnet->a.sri->sccp, &rp->peer_addr),
619 osmo_fsm_inst_state_name(rp->fi),
620 VTY_NEWLINE);
Maxc51609a2018-11-09 17:13:00 +0100621 }
622
623 return CMD_SUCCESS;
624}
625
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100626/*
627_Subscriber_______________________________________ _LAC_ _RAN___________________ _MSC-A_state_________ _MSC-A_use_
628IMSI-123456789012345:MSISDN-12345:TMSI-0x12345678 1 GERAN-A-4294967295:A5-3 WAIT_CLASSMARK_UPDATE 2=cm_service,trans_cc
629IMSI-123456789012356:MSISDN-234567:TMSI-0x123ABC78 65535 UTRAN-Iu-4294967295 COMMUNICATING 2=cm_service,trans_sms
630IMSI-123456789012367:MSISDN-98712345890:TMSI-0xF.. - EUTRAN-SGs RELEASING 0=none
631IMSI-123456789012378:HONR-12345432101 2 MSC-901-700-423:9876 REMOTE_MSC_A 1=inter_msc
632*/
633static void vty_dump_one_conn(struct vty *vty, const struct msub *msub, int *idx)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100634{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100635 struct msc_a *msc_a = msub_msc_a(msub);
636 struct vlr_subscr *vsub = msub_vsub(msub);
637 char buf[128];
Max45df98b2019-01-17 18:44:33 +0100638
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100639 if (!(*idx))
640 vty_out(vty,
641 "_Subscriber_______________________________________ _LAC_ _RAN___________________"
642 " _MSC-A_state_________ _MSC-A_use_%s",
Max45df98b2019-01-17 18:44:33 +0100643 VTY_NEWLINE);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100644 (*idx)++;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100645
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100646 vty_out(vty, "%50s %5u %23s %20s %d=%s%s",
647 vlr_subscr_short_name(msub_vsub(msub), 50),
648 vsub ? vsub->cgi.lai.lac : 0,
649 msub_ran_conn_name(msub),
650 osmo_fsm_inst_state_name(msc_a->c.fi),
651 osmo_use_count_total(&msc_a->use_count),
652 osmo_use_count_name_buf(buf, sizeof(buf), &msc_a->use_count),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100653 VTY_NEWLINE);
654}
655
656DEFUN(show_msc_conn, show_msc_conn_cmd,
657 "show connection", SHOW_STR "Subscriber Connections\n")
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200658{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100659 struct msub *msub;
660 int idx = 0;
661 llist_for_each_entry(msub, &msub_list, entry) {
662 vty_dump_one_conn(vty, msub, &idx);
663 }
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100664 return CMD_SUCCESS;
665}
666
667static void vty_trans_hdr(struct vty *vty)
668{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100669 if (llist_empty(&gsmnet->trans_list))
670 return;
Max45df98b2019-01-17 18:44:33 +0100671
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100672 vty_out(vty,
673 "_Subscriber_______________________________________ _RAN___________________"
674 " _P__ TI CallRef_ _state_%s",
675 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100676}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200677
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100678static const char *get_trans_proto_str(const struct gsm_trans *trans)
679{
680 static char buf[256];
681
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100682 switch (trans->type) {
683 case TRANS_CC:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100684 snprintf(buf, sizeof(buf), "%s %4u %4u",
685 gsm48_cc_state_name(trans->cc.state),
686 trans->cc.Tcurrent,
687 trans->cc.T308_second);
688 break;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100689 case TRANS_SMS:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100690 snprintf(buf, sizeof(buf), "%s %s",
691 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
692 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
693 break;
694 default:
695 buf[0] = '\0';
696 break;
697 }
698
699 return buf;
700}
701
702static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
703{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100704 vty_out(vty, "%50s %23s %4s %02u %08x %s%s",
705 vlr_subscr_short_name(msc_a_vsub(trans->msc_a), 50),
706 msub_ran_conn_name(trans->msc_a->c.msub),
707 trans_type_name(trans->type),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100708 trans->transaction_id,
709 trans->callref,
Max45df98b2019-01-17 18:44:33 +0100710 get_trans_proto_str(trans),
Max45df98b2019-01-17 18:44:33 +0100711 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100712}
713
714DEFUN(show_msc_transaction, show_msc_transaction_cmd,
715 "show transaction", SHOW_STR "Transactions\n")
716{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100717 struct gsm_trans *trans;
718
719 vty_trans_hdr(vty);
720 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
721 vty_dump_one_trans(vty, trans);
722
723 return CMD_SUCCESS;
724}
725
726static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
727{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100728 struct gsm_trans *trans;
729 int reqs;
730 struct llist_head *entry;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100731 char buf[128];
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100732
733 if (strlen(vsub->name))
734 vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
735 if (strlen(vsub->msisdn))
736 vty_out(vty, " Extension: %s%s", vsub->msisdn,
737 VTY_NEWLINE);
738 vty_out(vty, " LAC: %d/0x%x%s",
Max7d41d872018-12-19 11:48:33 +0100739 vsub->cgi.lai.lac, vsub->cgi.lai.lac, VTY_NEWLINE);
Philipp Maier2a0ac3b2018-12-17 10:03:50 +0100740 vty_out(vty, " RAN: %s%s",
Neels Hofmeyr7814a832018-12-26 00:40:18 +0100741 osmo_rat_type_name(vsub->cs.attached_via_ran), VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100742 vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
743 if (vsub->tmsi != GSM_RESERVED_TMSI)
744 vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
745 VTY_NEWLINE);
746 if (vsub->tmsi_new != GSM_RESERVED_TMSI)
747 vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
748 VTY_NEWLINE);
Philipp Maier6d71ccf2018-12-14 13:30:14 +0100749 if (vsub->imei[0] != '\0')
750 vty_out(vty, " IMEI: %s%s", vsub->imei, VTY_NEWLINE);
751 if (vsub->imeisv[0] != '\0')
752 vty_out(vty, " IMEISV: %s%s", vsub->imeisv, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100753
Philipp Maier89561bc2018-12-14 13:34:25 +0100754 vty_out(vty, " Flags: %s", VTY_NEWLINE);
755 vty_out(vty, " IMSI detached: %s%s",
756 vsub->imsi_detached_flag ? "true" : "false", VTY_NEWLINE);
757 vty_out(vty, " Conf. by radio contact: %s%s",
758 vsub->conf_by_radio_contact_ind ? "true" : "false",
759 VTY_NEWLINE);
760 vty_out(vty, " Subscr. data conf. by HLR: %s%s",
761 vsub->sub_dataconf_by_hlr_ind ? "true" : "false", VTY_NEWLINE);
762 vty_out(vty, " Location conf. in HLR: %s%s",
763 vsub->loc_conf_in_hlr_ind ? "true" : "false", VTY_NEWLINE);
764 vty_out(vty, " Subscriber dormant: %s%s",
765 vsub->dormant_ind ? "true" : "false", VTY_NEWLINE);
766 vty_out(vty, " Received cancel locataion: %s%s",
767 vsub->cancel_loc_rx ? "true" : "false", VTY_NEWLINE);
768 vty_out(vty, " MS not reachable: %s%s",
769 vsub->ms_not_reachable_flag ? "true" : "false", VTY_NEWLINE);
770 vty_out(vty, " LA allowed: %s%s",
771 vsub->la_allowed ? "true" : "false", VTY_NEWLINE);
772
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100773 if (vsub->last_tuple) {
Neels Hofmeyr8b6e5362018-11-30 02:57:33 +0100774 struct vlr_auth_tuple *t = vsub->last_tuple;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100775 vty_out(vty, " A3A8 last tuple (used %d times):%s",
776 t->use_count, VTY_NEWLINE);
777 vty_out(vty, " seq # : %d%s",
778 t->key_seq, VTY_NEWLINE);
779 vty_out(vty, " RAND : %s%s",
780 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
781 VTY_NEWLINE);
782 vty_out(vty, " SRES : %s%s",
783 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
784 VTY_NEWLINE);
785 vty_out(vty, " Kc : %s%s",
786 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
787 VTY_NEWLINE);
788 }
789
790 reqs = 0;
791 llist_for_each(entry, &vsub->cs.requests)
792 reqs += 1;
793 vty_out(vty, " Paging: %s paging for %d requests%s",
794 vsub->cs.is_paging ? "is" : "not", reqs, VTY_NEWLINE);
Harald Welte0df904d2018-12-03 11:00:04 +0100795
796 /* SGs related */
797 vty_out(vty, " SGs-state: %s%s",
798 osmo_fsm_inst_state_name(vsub->sgs_fsm), VTY_NEWLINE);
Vadim Yanitskiy477cbc62019-02-23 16:59:16 +0700799 if (strlen(vsub->sgs.mme_name))
Harald Welte0df904d2018-12-03 11:00:04 +0100800 vty_out(vty, " SGs-MME: %s%s", vsub->sgs.mme_name, VTY_NEWLINE);
801 else
802 vty_out(vty, " SGs-MME: (none)%s", VTY_NEWLINE);
803
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100804 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 +0100805
806 /* Connection */
807 if (vsub->msc_conn_ref) {
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100808 struct msub *msub = vsub->msc_conn_ref;
809 int idx = 0;
810 if (msub) {
811 vty_dump_one_conn(vty, msub, &idx);
812 }
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100813 }
814
815 /* Transactions */
816 vty_trans_hdr(vty);
817 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
818 if (trans->vsub != vsub)
819 continue;
820 vty_dump_one_trans(vty, trans);
821 }
822}
823
824/* Subscriber */
825DEFUN(show_subscr_cache,
826 show_subscr_cache_cmd,
827 "show subscriber cache",
828 SHOW_STR "Show information about subscribers\n"
829 "Display contents of subscriber cache\n")
830{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100831 struct vlr_subscr *vsub;
832 int count = 0;
833
834 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
835 if (++count > 100) {
836 vty_out(vty, "%% More than %d subscribers in cache,"
837 " stopping here.%s", count-1, VTY_NEWLINE);
838 break;
839 }
840 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
841 subscr_dump_full_vty(vty, vsub);
Harald Welte69c54a82018-02-09 20:41:14 +0100842 }
843
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200844 return CMD_SUCCESS;
845}
846
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100847DEFUN(sms_send_pend,
848 sms_send_pend_cmd,
849 "sms send pending",
850 "SMS related commands\n" "SMS Sending related commands\n"
851 "Send all pending SMS")
852{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100853 struct gsm_sms *sms;
854 unsigned long long sms_id = 0;
855
856 while (1) {
857 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
858 if (!sms)
859 break;
860
861 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700862 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100863
864 sms_id = sms->id + 1;
865 }
866
867 return CMD_SUCCESS;
868}
869
870DEFUN(sms_delete_expired,
871 sms_delete_expired_cmd,
872 "sms delete expired",
873 "SMS related commands\n" "SMS Database related commands\n"
874 "Delete all expired SMS")
875{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100876 struct gsm_sms *sms;
877 unsigned long long sms_id = 0;
878 long long num_deleted = 0;
879
880 while (1) {
881 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
882 if (!sms)
883 break;
884
885 /* Skip SMS which are currently queued for sending. */
886 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
887 continue;
888
889 /* Expiration check is performed by the DB layer. */
890 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
891 num_deleted++;
892
893 sms_id = sms->id + 1;
894 }
895
896 if (num_deleted == 0) {
897 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
898 return CMD_WARNING;
899 }
900
901 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
902 return CMD_SUCCESS;
903}
904
905static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +0200906 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100907 char *str, uint8_t tp_pid)
908{
909 struct gsm_network *net = receiver->vlr->user_ctx;
910 struct gsm_sms *sms;
911
Harald Welte39b55482018-04-09 19:19:33 +0200912 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100913 sms->protocol_id = tp_pid;
914
915 /* store in database for the queue */
916 if (db_sms_store(sms) != 0) {
917 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
918 sms_free(sms);
919 return CMD_WARNING;
920 }
921 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
922
923 sms_free(sms);
924 sms_queue_trigger(net->sms_queue);
925 return CMD_SUCCESS;
926}
927
928static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
929 const char *type,
930 const char *id)
931{
932 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100933 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100934 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100935 return vlr_subscr_find_by_imsi(gsmnet->vlr, id, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100936 else if (!strcmp(type, "tmsi"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100937 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id), VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100938
939 return NULL;
940}
941#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
942#define SUBSCR_HELP "Operations on a Subscriber\n" \
943 "Identify subscriber by MSISDN (phone number)\n" \
944 "Legacy alias for 'msisdn'\n" \
945 "Identify subscriber by IMSI\n" \
946 "Identify subscriber by TMSI\n" \
947 "Identify subscriber by database ID\n" \
948 "Identifier for the subscriber\n"
949
950DEFUN(show_subscr,
951 show_subscr_cmd,
952 "show subscriber " SUBSCR_TYPES " ID",
953 SHOW_STR SUBSCR_HELP)
954{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100955 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
956 argv[1]);
957
958 if (!vsub) {
959 vty_out(vty, "%% No subscriber found for %s %s%s",
960 argv[0], argv[1], VTY_NEWLINE);
961 return CMD_WARNING;
962 }
963
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100964 /* In the vty output to the user, exclude this local use count added by vlr_subscr_get() in get_vsub_by_argv().
965 * This works, because: for get_vsub_by_argv() to succeed, there *must* have been at least one use count before
966 * 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 +0100967 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100968
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100969 subscr_dump_full_vty(vty, vsub);
970
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100971 return CMD_SUCCESS;
972}
973
974DEFUN(subscriber_create,
975 subscriber_create_cmd,
976 "subscriber create imsi ID",
977 "Operations on a Subscriber\n" \
978 "Create new subscriber\n" \
979 "Identify the subscriber by his IMSI\n" \
980 "Identifier for the subscriber\n")
981{
982 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
983 VTY_NEWLINE);
984 return CMD_WARNING;
985}
986
987DEFUN(subscriber_send_pending_sms,
988 subscriber_send_pending_sms_cmd,
989 "subscriber " SUBSCR_TYPES " ID sms pending-send",
990 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
991{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100992 struct vlr_subscr *vsub;
993 struct gsm_sms *sms;
994
995 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
996 if (!vsub) {
997 vty_out(vty, "%% No subscriber found for %s %s%s",
998 argv[0], argv[1], VTY_NEWLINE);
999 return CMD_WARNING;
1000 }
1001
1002 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
1003 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +07001004 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001005
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001006 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001007
1008 return CMD_SUCCESS;
1009}
1010
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001011DEFUN(subscriber_sms_delete_all,
1012 subscriber_sms_delete_all_cmd,
1013 "subscriber " SUBSCR_TYPES " ID sms delete-all",
1014 SUBSCR_HELP "SMS Operations\n"
1015 "Delete all SMS to be delivered to this subscriber"
1016 " -- WARNING: the SMS data for all unsent SMS for this subscriber"
1017 " WILL BE LOST.\n")
1018{
1019 struct vlr_subscr *vsub;
1020
1021 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1022 if (!vsub) {
1023 vty_out(vty, "%% No subscriber found for %s %s%s",
1024 argv[0], argv[1], VTY_NEWLINE);
1025 return CMD_WARNING;
1026 }
1027
1028 db_sms_delete_by_msisdn(vsub->msisdn);
1029
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001030 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001031
1032 return CMD_SUCCESS;
1033}
1034
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001035DEFUN(subscriber_send_sms,
1036 subscriber_send_sms_cmd,
1037 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
1038 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
1039{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001040 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +02001041 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001042 char *str;
1043 int rc;
1044
1045 if (!vsub) {
1046 vty_out(vty, "%% No subscriber found for %s %s%s",
1047 argv[0], argv[1], VTY_NEWLINE);
1048 rc = CMD_WARNING;
1049 goto err;
1050 }
1051
Harald Welte39b55482018-04-09 19:19:33 +02001052 if (!strcmp(argv[2], "msisdn"))
1053 sender_msisdn = argv[3];
1054 else {
1055 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1056 if (!sender) {
1057 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1058 rc = CMD_WARNING;
1059 goto err;
1060 }
1061 sender_msisdn = sender->msisdn;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001062 vlr_subscr_put(sender, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001063 }
1064
1065 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001066 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001067 talloc_free(str);
1068
1069err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001070 if (vsub)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001071 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001072
1073 return rc;
1074}
1075
1076DEFUN(subscriber_silent_sms,
1077 subscriber_silent_sms_cmd,
1078
1079 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
1080 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
1081{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001082 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +02001083 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001084 char *str;
1085 int rc;
1086
1087 if (!vsub) {
1088 vty_out(vty, "%% No subscriber found for %s %s%s",
1089 argv[0], argv[1], VTY_NEWLINE);
1090 rc = CMD_WARNING;
1091 goto err;
1092 }
1093
Harald Welte39b55482018-04-09 19:19:33 +02001094 if (!strcmp(argv[2], "msisdn")) {
1095 sender_msisdn = argv[3];
1096 } else {
1097 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1098 if (!sender) {
1099 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1100 rc = CMD_WARNING;
1101 goto err;
1102 }
1103 sender_msisdn = sender->msisdn;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001104 vlr_subscr_put(sender, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001105 }
1106
1107 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001108 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001109 talloc_free(str);
1110
1111err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001112 if (vsub)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001113 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001114
1115 return rc;
1116}
1117
Sylvain Munaut93558302019-02-14 20:13:08 +01001118#define CHAN_TYPES "(any|tch/f|tch/h|tch/any|sdcch)"
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001119#define CHAN_TYPE_HELP \
1120 "Any channel\n" \
1121 "TCH/F channel\n" \
Sylvain Munaut93558302019-02-14 20:13:08 +01001122 "TCH/H channel\n" \
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001123 "Any TCH channel\n" \
1124 "SDCCH channel\n"
1125
Sylvain Munaut93558302019-02-14 20:13:08 +01001126#define CHAN_MODES "(signalling|speech-hr|speech-fr|speech-efr|speech-amr)"
1127#define CHAN_MODE_HELP \
1128 "Signalling only\n" \
1129 "Speech with HR codec\n" \
1130 "Speech with FR codec\n" \
1131 "Speech with EFR codec\n" \
1132 "Speech with AMR codec\n"
1133
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001134DEFUN(subscriber_silent_call_start,
1135 subscriber_silent_call_start_cmd,
Sylvain Munaut93558302019-02-14 20:13:08 +01001136 "subscriber " SUBSCR_TYPES " ID silent-call start " CHAN_TYPES " " CHAN_MODES " [IP] [<0-65535>]",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001137 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
Sylvain Munaut93558302019-02-14 20:13:08 +01001138 CHAN_TYPE_HELP CHAN_MODE_HELP
1139 "Target IP for RTP traffic (default 127.0.0.1)\n"
1140 "Target port for RTP traffic (default: 4000)\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001141{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001142 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Sylvain Munaut93558302019-02-14 20:13:08 +01001143 struct gsm0808_channel_type ct;
1144 const char *ip;
1145 uint16_t port;
1146 int rc, speech;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001147
1148 if (!vsub) {
1149 vty_out(vty, "%% No subscriber found for %s %s%s",
1150 argv[0], argv[1], VTY_NEWLINE);
1151 return CMD_WARNING;
1152 }
1153
Sylvain Munaut93558302019-02-14 20:13:08 +01001154 memset(&ct, 0x00, sizeof(ct));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001155
Sylvain Munaut93558302019-02-14 20:13:08 +01001156 if (!strcmp(argv[3], "signalling")) {
1157 ct.ch_indctr = GSM0808_CHAN_SIGN;
1158 ct.perm_spch[0] = 0; /* Spare but required */
1159 ct.perm_spch_len = 1;
1160 } else if (!strcmp(argv[3], "speech-hr")) {
1161 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1162 ct.perm_spch[0] = GSM0808_PERM_HR1;
1163 ct.perm_spch_len = 1;
1164 } else if (!strcmp(argv[3], "speech-fr")) {
1165 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1166 ct.perm_spch[0] = GSM0808_PERM_FR1;
1167 ct.perm_spch_len = 1;
1168 } else if (!strcmp(argv[3], "speech-efr")) {
1169 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1170 ct.perm_spch[0] = GSM0808_PERM_FR2;
1171 ct.perm_spch_len = 1;
1172 } else if (!strcmp(argv[3], "speech-amr")) {
1173 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1174 ct.perm_spch[0] = GSM0808_PERM_FR3;
1175 ct.perm_spch[1] = GSM0808_PERM_HR3;
1176 ct.perm_spch_len = 2;
1177 }
1178
1179 speech = ct.ch_indctr == GSM0808_CHAN_SPEECH;
1180
1181 if (!strcmp(argv[2], "tch/f"))
1182 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_BM : GSM0808_SIGN_FULL_BM;
1183 else if (!strcmp(argv[2], "tch/h"))
1184 ct.ch_rate_type = speech ? GSM0808_SPEECH_HALF_LM : GSM0808_SIGN_HALF_LM;
1185 else if (!strcmp(argv[2], "tch/any"))
1186 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_FULL_PREF;
1187 else if (!strcmp(argv[2], "sdcch")) {
1188 if (speech) {
1189 vty_out(vty, "Can't request speech on SDCCH%s", VTY_NEWLINE);
1190 return CMD_WARNING;
1191 }
1192 ct.ch_rate_type = GSM0808_SIGN_SDCCH;
1193 } else
1194 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_ANY;
1195
1196 ip = argc >= 5 ? argv[4] : "127.0.0.1";
1197 port = argc >= 6 ? atoi(argv[5]) : 4000;
1198
1199 rc = gsm_silent_call_start(vsub, &ct, ip, port, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001200 switch (rc) {
1201 case -ENODEV:
1202 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
1203 break;
1204 default:
1205 if (rc)
1206 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
1207 else
1208 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
1209 break;
1210 }
1211
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001212 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001213 return rc ? CMD_WARNING : CMD_SUCCESS;
1214}
1215
1216DEFUN(subscriber_silent_call_stop,
1217 subscriber_silent_call_stop_cmd,
1218 "subscriber " SUBSCR_TYPES " ID silent-call stop",
1219 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
1220 CHAN_TYPE_HELP)
1221{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001222 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1223 int rc;
1224
1225 if (!vsub) {
1226 vty_out(vty, "%% No subscriber found for %s %s%s",
1227 argv[0], argv[1], VTY_NEWLINE);
1228 return CMD_WARNING;
1229 }
1230
1231 rc = gsm_silent_call_stop(vsub);
1232 switch (rc) {
1233 case -ENODEV:
1234 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
1235 break;
1236 case -ENOENT:
1237 vty_out(vty, "%% Subscriber has no silent call active%s",
1238 VTY_NEWLINE);
1239 break;
1240 default:
1241 if (rc)
1242 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
1243 else
1244 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
1245 break;
1246 }
1247
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001248 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001249 return rc ? CMD_WARNING : CMD_SUCCESS;
1250}
1251
1252DEFUN(subscriber_ussd_notify,
1253 subscriber_ussd_notify_cmd,
1254 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1255 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1256 "Alerting Level 0\n"
1257 "Alerting Level 1\n"
1258 "Alerting Level 2\n"
1259 "Text of USSD message to send\n")
1260{
1261 char *text;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001262 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001263 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1264 int level;
1265
1266 if (!vsub) {
1267 vty_out(vty, "%% No subscriber found for %s %s%s",
1268 argv[0], argv[1], VTY_NEWLINE);
1269 return CMD_WARNING;
1270 }
1271
1272 level = atoi(argv[2]);
1273 text = argv_concat(argv, argc, 3);
1274 if (!text) {
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001275 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001276 return CMD_WARNING;
1277 }
1278
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001279 msc_a = msc_a_for_vsub(vsub, true);
1280 if (!msc_a || msc_a->c.remote_to) {
1281 vty_out(vty, "%% An active connection and local MSC-A role is required for %s %s%s",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001282 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001283 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001284 talloc_free(text);
1285 return CMD_WARNING;
1286 }
1287
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001288 msc_send_ussd_notify(msc_a, level, text);
Vadim Yanitskiyf20c6b72018-11-29 01:20:58 +07001289 /* FIXME: since we don't allocate a transaction here,
1290 * we use dummy GSM 04.07 transaction ID. */
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001291 msc_send_ussd_release_complete(msc_a, 0x00);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001292
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001293 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001294 talloc_free(text);
1295 return CMD_SUCCESS;
1296}
1297
1298DEFUN(subscriber_paging,
1299 subscriber_paging_cmd,
1300 "subscriber " SUBSCR_TYPES " ID paging",
1301 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1302{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001303 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001304 struct paging_request *req;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001305
1306 if (!vsub) {
1307 vty_out(vty, "%% No subscriber found for %s %s%s",
1308 argv[0], argv[1], VTY_NEWLINE);
1309 return CMD_WARNING;
1310 }
1311
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001312 req = paging_request_start(vsub, PAGING_CAUSE_CALL_CONVERSATIONAL,
1313 NULL, NULL, "manual Paging from VTY");
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001314 if (req)
1315 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1316 else
1317 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1318
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001319 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001320 return req ? CMD_SUCCESS : CMD_WARNING;
1321}
1322
1323static int loop_by_char(uint8_t ch)
1324{
1325 switch (ch) {
1326 case 'a':
1327 return GSM414_LOOP_A;
1328 case 'b':
1329 return GSM414_LOOP_B;
1330 case 'c':
1331 return GSM414_LOOP_C;
1332 case 'd':
1333 return GSM414_LOOP_D;
1334 case 'e':
1335 return GSM414_LOOP_E;
1336 case 'f':
1337 return GSM414_LOOP_F;
1338 case 'i':
1339 return GSM414_LOOP_I;
1340 }
1341 return -1;
1342}
1343
1344DEFUN(subscriber_mstest_close,
1345 subscriber_mstest_close_cmd,
1346 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1347 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1348 "Close a TCH Loop inside the MS\n"
1349 "Loop Type A\n"
1350 "Loop Type B\n"
1351 "Loop Type C\n"
1352 "Loop Type D\n"
1353 "Loop Type E\n"
1354 "Loop Type F\n"
1355 "Loop Type I\n")
1356{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001357 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001358 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1359 const char *loop_str;
1360 int loop_mode;
1361
1362 if (!vsub) {
1363 vty_out(vty, "%% No subscriber found for %s %s%s",
1364 argv[0], argv[1], VTY_NEWLINE);
1365 return CMD_WARNING;
1366 }
1367
1368 loop_str = argv[2];
1369 loop_mode = loop_by_char(loop_str[0]);
1370
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001371 msc_a = msc_a_for_vsub(vsub, true);
1372 if (!msc_a) {
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001373 vty_out(vty, "%% An active connection is required for %s %s%s",
1374 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001375 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001376 return CMD_WARNING;
1377 }
1378
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001379 gsm0414_tx_close_tch_loop_cmd(msc_a, loop_mode);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001380
1381 return CMD_SUCCESS;
1382}
1383
1384DEFUN(subscriber_mstest_open,
1385 subscriber_mstest_open_cmd,
1386 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1387 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1388 "Open a TCH Loop inside the MS\n")
1389{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001390 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001391 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1392
1393 if (!vsub) {
1394 vty_out(vty, "%% No subscriber found for %s %s%s",
1395 argv[0], argv[1], VTY_NEWLINE);
1396 return CMD_WARNING;
1397 }
1398
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001399 msc_a = msc_a_for_vsub(vsub, true);
1400 if (!msc_a) {
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001401 vty_out(vty, "%% An active connection is required for %s %s%s",
1402 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001403 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001404 return CMD_WARNING;
1405 }
1406
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001407 gsm0414_tx_open_loop_cmd(msc_a);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001408
1409 return CMD_SUCCESS;
1410}
1411
1412DEFUN(ena_subscr_expire,
1413 ena_subscr_expire_cmd,
1414 "subscriber " SUBSCR_TYPES " ID expire",
1415 SUBSCR_HELP "Expire the subscriber Now\n")
1416{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001417 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1418 argv[1]);
1419
1420 if (!vsub) {
1421 vty_out(vty, "%% No subscriber found for %s %s%s",
1422 argv[0], argv[1], VTY_NEWLINE);
1423 return CMD_WARNING;
1424 }
1425
1426 if (vlr_subscr_expire(vsub))
1427 vty_out(vty, "%% VLR released subscriber %s%s",
1428 vlr_subscr_name(vsub), VTY_NEWLINE);
1429
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001430 if (osmo_use_count_total(&vsub->use_count) > 1)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001431 vty_out(vty, "%% Subscriber %s is still in use,"
1432 " should be released soon%s",
1433 vlr_subscr_name(vsub), VTY_NEWLINE);
1434
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001435 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001436 return CMD_SUCCESS;
1437}
1438
1439static int scall_cbfn(unsigned int subsys, unsigned int signal,
1440 void *handler_data, void *signal_data)
1441{
1442 struct scall_signal_data *sigdata = signal_data;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001443 struct vty *vty = sigdata->vty;
1444
1445 if (!vty_is_active(vty))
1446 return 0;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001447
1448 switch (signal) {
1449 case S_SCALL_SUCCESS:
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001450 vty_out(vty, "%% Silent call success%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001451 break;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001452 case S_SCALL_FAILED:
1453 vty_out(vty, "%% Silent call failed%s", VTY_NEWLINE);
1454 break;
1455 case S_SCALL_DETACHED:
1456 vty_out(vty, "%% Silent call ended%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001457 break;
1458 }
1459 return 0;
1460}
1461
1462DEFUN(show_stats,
1463 show_stats_cmd,
1464 "show statistics",
1465 SHOW_STR "Display network statistics\n")
1466{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001467 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001468 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1469 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1470 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001471 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001472 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001473 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001474 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001475 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001476 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1477 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001478 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001479 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001480 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1481 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001482 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001483 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001484 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1485 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1486 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001487 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001488 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001489 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1490 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001491 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001492 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001493 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1494 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001495 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001496 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001497 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1498 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1499 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1500 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1501 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001502 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001503 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1504 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1505 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1506 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1507 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001508 return CMD_SUCCESS;
1509}
1510
1511DEFUN(show_smsqueue,
1512 show_smsqueue_cmd,
1513 "show sms-queue",
1514 SHOW_STR "Display SMSqueue statistics\n")
1515{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001516 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001517 return CMD_SUCCESS;
1518}
1519
1520DEFUN(smsqueue_trigger,
1521 smsqueue_trigger_cmd,
1522 "sms-queue trigger",
1523 "SMS Queue\n" "Trigger sending messages\n")
1524{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001525 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001526 return CMD_SUCCESS;
1527}
1528
1529DEFUN(smsqueue_max,
1530 smsqueue_max_cmd,
1531 "sms-queue max-pending <1-500>",
1532 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1533{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001534 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001535 return CMD_SUCCESS;
1536}
1537
1538DEFUN(smsqueue_clear,
1539 smsqueue_clear_cmd,
1540 "sms-queue clear",
1541 "SMS Queue\n" "Clear the queue of pending SMS\n")
1542{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001543 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001544 return CMD_SUCCESS;
1545}
1546
1547DEFUN(smsqueue_fail,
1548 smsqueue_fail_cmd,
1549 "sms-queue max-failure <1-500>",
1550 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1551{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001552 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001553 return CMD_SUCCESS;
1554}
1555
1556
1557DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1558 "mncc-int", "Configure internal MNCC handler")
1559{
1560 vty->node = MNCC_INT_NODE;
1561
1562 return CMD_SUCCESS;
1563}
1564
1565static struct cmd_node mncc_int_node = {
1566 MNCC_INT_NODE,
1567 "%s(config-mncc-int)# ",
1568 1,
1569};
1570
1571static const struct value_string tchf_codec_names[] = {
1572 { GSM48_CMODE_SPEECH_V1, "fr" },
1573 { GSM48_CMODE_SPEECH_EFR, "efr" },
1574 { GSM48_CMODE_SPEECH_AMR, "amr" },
1575 { 0, NULL }
1576};
1577
1578static const struct value_string tchh_codec_names[] = {
1579 { GSM48_CMODE_SPEECH_V1, "hr" },
1580 { GSM48_CMODE_SPEECH_AMR, "amr" },
1581 { 0, NULL }
1582};
1583
1584static int config_write_mncc_int(struct vty *vty)
1585{
1586 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1587 vty_out(vty, " default-codec tch-f %s%s",
1588 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1589 VTY_NEWLINE);
1590 vty_out(vty, " default-codec tch-h %s%s",
1591 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1592 VTY_NEWLINE);
1593
1594 return CMD_SUCCESS;
1595}
1596
1597DEFUN(mnccint_def_codec_f,
1598 mnccint_def_codec_f_cmd,
1599 "default-codec tch-f (fr|efr|amr)",
1600 "Set default codec\n" "Codec for TCH/F\n"
1601 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1602{
1603 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1604
1605 return CMD_SUCCESS;
1606}
1607
1608DEFUN(mnccint_def_codec_h,
1609 mnccint_def_codec_h_cmd,
1610 "default-codec tch-h (hr|amr)",
1611 "Set default codec\n" "Codec for TCH/H\n"
1612 "Half-Rate\n" "Adaptive Multi-Rate\n")
1613{
1614 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1615
1616 return CMD_SUCCESS;
1617}
1618
1619
1620DEFUN(logging_fltr_imsi,
1621 logging_fltr_imsi_cmd,
1622 "logging filter imsi IMSI",
1623 LOGGING_STR FILTER_STR
1624 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1625{
1626 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001627 struct log_target *tgt = osmo_log_vty2tgt(vty);
1628 const char *imsi = argv[0];
1629
1630 if (!tgt)
1631 return CMD_WARNING;
1632
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001633 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001634
1635 if (!vlr_subscr) {
1636 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1637 argv[0], VTY_NEWLINE);
1638 return CMD_WARNING;
1639 }
1640
1641 log_set_filter_vlr_subscr(tgt, vlr_subscr);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001642 vlr_subscr_put(vlr_subscr, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001643 return CMD_SUCCESS;
1644}
1645
1646static struct cmd_node hlr_node = {
1647 HLR_NODE,
1648 "%s(config-hlr)# ",
1649 1,
1650};
1651
1652DEFUN(cfg_hlr, cfg_hlr_cmd,
1653 "hlr", "Configure connection to the HLR")
1654{
1655 vty->node = HLR_NODE;
1656 return CMD_SUCCESS;
1657}
1658
1659DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1660 "Remote GSUP address of the HLR\n"
1661 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1662{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001663 talloc_free((void*)gsmnet->gsup_server_addr_str);
1664 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1665 return CMD_SUCCESS;
1666}
1667
1668DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1669 "Remote GSUP port of the HLR\n"
1670 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1671{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001672 gsmnet->gsup_server_port = atoi(argv[0]);
1673 return CMD_SUCCESS;
1674}
1675
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001676DEFUN(cfg_hlr_ipa_name,
1677 cfg_hlr_ipa_name_cmd,
1678 "ipa-name NAME",
1679 "Set the IPA name of this MSC\n"
1680 "A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. "
1681 "This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. "
1682 "The default is 'MSC-00-00-00-00-00-00'.\n")
1683{
1684 if (vty->type != VTY_FILE) {
1685 vty_out(vty, "The IPA name cannot be changed at run-time; "
1686 "It can only be set in the configuraton file.%s", VTY_NEWLINE);
1687 return CMD_WARNING;
1688 }
1689
1690 gsmnet->msc_ipa_name = talloc_strdup(gsmnet, argv[0]);
1691 return CMD_SUCCESS;
1692}
1693
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001694static int config_write_hlr(struct vty *vty)
1695{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001696 vty_out(vty, "hlr%s", VTY_NEWLINE);
1697 vty_out(vty, " remote-ip %s%s",
1698 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1699 vty_out(vty, " remote-port %u%s",
1700 gsmnet->gsup_server_port, VTY_NEWLINE);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001701 if (gsmnet->msc_ipa_name)
1702 vty_out(vty, " ipa-name %s%s", gsmnet->msc_ipa_name, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001703 return CMD_SUCCESS;
1704}
1705
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001706void msc_vty_init(struct gsm_network *msc_network)
1707{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001708 OSMO_ASSERT(gsmnet == NULL);
1709 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001710
1711 osmo_stats_vty_add_cmds();
1712
1713 install_element(CONFIG_NODE, &cfg_net_cmd);
1714 install_node(&net_node, config_write_net);
1715 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
1716 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1717 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1718 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
1719 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
1720 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
1721 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
1722 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
1723 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
1724 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
1725 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
1726 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
1727 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001728
1729 install_element(CONFIG_NODE, &cfg_msc_cmd);
1730 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001731 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01001732 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
1733 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02001734 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01001735 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Vadim Yanitskiy64623e12018-11-28 23:05:51 +07001736 install_element(MSC_NODE, &cfg_msc_ncss_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001737 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01001738 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
1739 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Oliver Smith0fec28a2018-12-14 10:52:52 +01001740 install_element(MSC_NODE, &cfg_msc_check_imei_rqd_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001741 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
1742 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01001743 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01001744 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +07001745 install_element(MSC_NODE, &cfg_msc_sms_over_gsup_cmd);
1746 install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001747 install_element(MSC_NODE, &cfg_msc_handover_number_range_cmd);
1748
1749 neighbor_ident_vty_init(msc_network);
Philipp Maierfbf66102017-04-09 12:32:51 +02001750
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02001751 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001752#ifdef BUILD_IU
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001753 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 +02001754#endif
Harald Welte0df904d2018-12-03 11:00:04 +01001755 sgs_vty_init();
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001756
Stefan Sperling617ac802018-02-22 17:58:20 +01001757 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001758
1759 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
1760
1761 install_element_ve(&show_subscr_cmd);
1762 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01001763 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001764 install_element_ve(&show_msc_conn_cmd);
1765 install_element_ve(&show_msc_transaction_cmd);
1766
1767 install_element_ve(&sms_send_pend_cmd);
1768 install_element_ve(&sms_delete_expired_cmd);
1769
1770 install_element_ve(&subscriber_create_cmd);
1771 install_element_ve(&subscriber_send_sms_cmd);
1772 install_element_ve(&subscriber_silent_sms_cmd);
1773 install_element_ve(&subscriber_silent_call_start_cmd);
1774 install_element_ve(&subscriber_silent_call_stop_cmd);
1775 install_element_ve(&subscriber_ussd_notify_cmd);
1776 install_element_ve(&subscriber_mstest_close_cmd);
1777 install_element_ve(&subscriber_mstest_open_cmd);
1778 install_element_ve(&subscriber_paging_cmd);
1779 install_element_ve(&show_stats_cmd);
1780 install_element_ve(&show_smsqueue_cmd);
1781 install_element_ve(&logging_fltr_imsi_cmd);
1782
1783 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
1784 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
1785 install_element(ENABLE_NODE, &smsqueue_max_cmd);
1786 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
1787 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
1788 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001789 install_element(ENABLE_NODE, &subscriber_sms_delete_all_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001790
1791 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1792 install_node(&mncc_int_node, config_write_mncc_int);
1793 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1794 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1795
1796 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
1797
1798 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1799 install_node(&hlr_node, config_write_hlr);
1800 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1801 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001802 install_element(HLR_NODE, &cfg_hlr_ipa_name_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001803}