blob: 589eca0773c85d057cd0c69d9f7493500a568945 [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 Hofmeyr00e82d62017-07-05 15:19:52 +020026#include "../../bscconfig.h"
27
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020028#include <inttypes.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010029#include <limits.h>
30
31#include <osmocom/gsm/protocol/gsm_08_58.h>
32#include <osmocom/gsm/protocol/gsm_04_14.h>
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020033
Maxc51609a2018-11-09 17:13:00 +010034#include <osmocom/sigtran/sccp_helpers.h>
35
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020036#include <osmocom/vty/command.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010037#include <osmocom/vty/logging.h>
Stefan Sperling617ac802018-02-22 17:58:20 +010038#include <osmocom/vty/misc.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010039#include <osmocom/vty/stats.h>
40
Neels Hofmeyr00e82d62017-07-05 15:19:52 +020041#ifdef BUILD_IU
42#include <osmocom/ranap/iu_client.h>
43#endif
Neels Hofmeyr84da6b12016-05-20 21:59:55 +020044
Neels Hofmeyr90843962017-09-04 15:04:35 +020045#include <osmocom/msc/vty.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010046#include <osmocom/msc/osmo_msc.h>
Neels Hofmeyr90843962017-09-04 15:04:35 +020047#include <osmocom/msc/gsm_data.h>
48#include <osmocom/msc/gsm_subscriber.h>
49#include <osmocom/msc/vlr.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010050#include <osmocom/msc/transaction.h>
51#include <osmocom/msc/db.h>
Maxc51609a2018-11-09 17:13:00 +010052#include <osmocom/msc/a_iface.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010053#include <osmocom/msc/sms_queue.h>
54#include <osmocom/msc/silent_call.h>
55#include <osmocom/msc/gsm_04_80.h>
56#include <osmocom/msc/gsm_04_14.h>
57#include <osmocom/msc/signal.h>
58#include <osmocom/msc/mncc_int.h>
Vadim Yanitskiy1b891302018-08-04 01:33:08 +070059#include <osmocom/msc/rrlp.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010060
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010061static struct gsm_network *gsmnet = NULL;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010062
63struct cmd_node net_node = {
64 GSMNET_NODE,
65 "%s(config-net)# ",
66 1,
67};
68
69#define NETWORK_STR "Configure the GSM network\n"
70#define CODE_CMD_STR "Code commands\n"
71#define NAME_CMD_STR "Name Commands\n"
72#define NAME_STR "Name to use\n"
73
74DEFUN(cfg_net,
75 cfg_net_cmd,
76 "network", NETWORK_STR)
77{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010078 vty->index = gsmnet;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010079 vty->node = GSMNET_NODE;
80
81 return CMD_SUCCESS;
82}
83
84DEFUN(cfg_net_ncc,
85 cfg_net_ncc_cmd,
86 "network country code <1-999>",
87 "Set the GSM network country code\n"
88 "Country commands\n"
89 CODE_CMD_STR
90 "Network Country Code to use\n")
91{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010092 gsmnet->plmn.mcc = atoi(argv[0]);
93
94 return CMD_SUCCESS;
95}
96
97DEFUN(cfg_net_mnc,
98 cfg_net_mnc_cmd,
99 "mobile network code <0-999>",
100 "Set the GSM mobile network code\n"
101 "Network Commands\n"
102 CODE_CMD_STR
103 "Mobile Network Code to use\n")
104{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100105 uint16_t mnc;
106 bool mnc_3_digits;
107
108 if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
109 vty_out(vty, "%% Error decoding MNC: %s%s", argv[0], VTY_NEWLINE);
110 return CMD_WARNING;
111 }
112
113 gsmnet->plmn.mnc = mnc;
114 gsmnet->plmn.mnc_3_digits = mnc_3_digits;
115
116 return CMD_SUCCESS;
117}
118
119DEFUN(cfg_net_name_short,
120 cfg_net_name_short_cmd,
121 "short name NAME",
122 "Set the short GSM network name\n" NAME_CMD_STR NAME_STR)
123{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100124 osmo_talloc_replace_string(gsmnet, &gsmnet->name_short, argv[0]);
125 return CMD_SUCCESS;
126}
127
128DEFUN(cfg_net_name_long,
129 cfg_net_name_long_cmd,
130 "long name NAME",
131 "Set the long 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_long, argv[0]);
134 return CMD_SUCCESS;
135}
136
137DEFUN(cfg_net_encryption,
138 cfg_net_encryption_cmd,
139 "encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]",
140 "Encryption options\n"
141 "GSM A5 Air Interface Encryption\n"
142 "A5/n Algorithm Number\n"
143 "A5/n Algorithm Number\n"
144 "A5/n Algorithm Number\n"
145 "A5/n Algorithm Number\n")
146{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100147 unsigned int i;
148
149 gsmnet->a5_encryption_mask = 0;
150 for (i = 0; i < argc; i++)
151 gsmnet->a5_encryption_mask |= (1 << atoi(argv[i]));
152
153 return CMD_SUCCESS;
154}
155
156DEFUN(cfg_net_authentication,
157 cfg_net_authentication_cmd,
158 "authentication (optional|required)",
159 "Whether to enforce MS authentication in 2G\n"
160 "Allow MS to attach via 2G BSC without authentication\n"
161 "Always do authentication\n")
162{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100163 gsmnet->authentication_required = (argv[0][0] == 'r') ? true : false;
164
165 return CMD_SUCCESS;
166}
167
168DEFUN(cfg_net_rrlp_mode, cfg_net_rrlp_mode_cmd,
169 "rrlp mode (none|ms-based|ms-preferred|ass-preferred)",
170 "Radio Resource Location Protocol\n"
171 "Set the Radio Resource Location Protocol Mode\n"
172 "Don't send RRLP request\n"
173 "Request MS-based location\n"
174 "Request any location, prefer MS-based\n"
175 "Request any location, prefer MS-assisted\n")
176{
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700177 gsmnet->rrlp.mode = msc_rrlp_mode_parse(argv[0]);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100178
179 return CMD_SUCCESS;
180}
181
182DEFUN(cfg_net_mm_info, cfg_net_mm_info_cmd,
183 "mm info (0|1)",
184 "Mobility Management\n"
185 "Send MM INFO after LOC UPD ACCEPT\n"
186 "Disable\n" "Enable\n")
187{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100188 gsmnet->send_mm_info = atoi(argv[0]);
189
190 return CMD_SUCCESS;
191}
192
193DEFUN(cfg_net_timezone,
194 cfg_net_timezone_cmd,
195 "timezone <-19-19> (0|15|30|45)",
196 "Set the Timezone Offset of the network\n"
197 "Timezone offset (hours)\n"
198 "Timezone offset (00 minutes)\n"
199 "Timezone offset (15 minutes)\n"
200 "Timezone offset (30 minutes)\n"
201 "Timezone offset (45 minutes)\n"
202 )
203{
204 struct gsm_network *net = vty->index;
205 int tzhr = atoi(argv[0]);
206 int tzmn = atoi(argv[1]);
207
208 net->tz.hr = tzhr;
209 net->tz.mn = tzmn;
210 net->tz.dst = 0;
211 net->tz.override = 1;
212
213 return CMD_SUCCESS;
214}
215
216DEFUN(cfg_net_timezone_dst,
217 cfg_net_timezone_dst_cmd,
218 "timezone <-19-19> (0|15|30|45) <0-2>",
219 "Set the Timezone Offset of the network\n"
220 "Timezone offset (hours)\n"
221 "Timezone offset (00 minutes)\n"
222 "Timezone offset (15 minutes)\n"
223 "Timezone offset (30 minutes)\n"
224 "Timezone offset (45 minutes)\n"
225 "DST offset (hours)\n"
226 )
227{
228 struct gsm_network *net = vty->index;
229 int tzhr = atoi(argv[0]);
230 int tzmn = atoi(argv[1]);
231 int tzdst = atoi(argv[2]);
232
233 net->tz.hr = tzhr;
234 net->tz.mn = tzmn;
235 net->tz.dst = tzdst;
236 net->tz.override = 1;
237
238 return CMD_SUCCESS;
239}
240
241DEFUN(cfg_net_no_timezone,
242 cfg_net_no_timezone_cmd,
243 "no timezone",
244 NO_STR
245 "Disable network timezone override, use system tz\n")
246{
247 struct gsm_network *net = vty->index;
248
249 net->tz.override = 0;
250
251 return CMD_SUCCESS;
252}
253
254DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
255 "periodic location update <6-1530>",
256 "Periodic Location Updating Interval\n"
257 "Periodic Location Updating Interval\n"
258 "Periodic Location Updating Interval\n"
259 "Periodic Location Updating Interval in Minutes\n")
260{
261 struct gsm_network *net = vty->index;
262
263 net->t3212 = atoi(argv[0]) / 6;
264
265 return CMD_SUCCESS;
266}
267
268DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
269 "no periodic location update",
270 NO_STR
271 "Periodic Location Updating Interval\n"
272 "Periodic Location Updating Interval\n"
273 "Periodic Location Updating Interval\n")
274{
275 struct gsm_network *net = vty->index;
276
277 net->t3212 = 0;
278
279 return CMD_SUCCESS;
280}
281
282static int config_write_net(struct vty *vty)
283{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100284 int i;
285
286 vty_out(vty, "network%s", VTY_NEWLINE);
287 vty_out(vty, " network country code %s%s", osmo_mcc_name(gsmnet->plmn.mcc), VTY_NEWLINE);
288 vty_out(vty, " mobile network code %s%s",
289 osmo_mnc_name(gsmnet->plmn.mnc, gsmnet->plmn.mnc_3_digits), VTY_NEWLINE);
290 vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
291 vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
292 vty_out(vty, " encryption a5");
293 for (i = 0; i < 8; i++) {
294 if (gsmnet->a5_encryption_mask & (1 << i))
295 vty_out(vty, " %u", i);
296 }
297 vty_out(vty, "%s", VTY_NEWLINE);
298 vty_out(vty, " authentication %s%s",
299 gsmnet->authentication_required ? "required" : "optional", VTY_NEWLINE);
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700300 vty_out(vty, " rrlp mode %s%s", msc_rrlp_mode_name(gsmnet->rrlp.mode),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100301 VTY_NEWLINE);
302 vty_out(vty, " mm info %u%s", gsmnet->send_mm_info, VTY_NEWLINE);
303 if (gsmnet->tz.override != 0) {
304 if (gsmnet->tz.dst)
305 vty_out(vty, " timezone %d %d %d%s",
306 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
307 VTY_NEWLINE);
308 else
309 vty_out(vty, " timezone %d %d%s",
310 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
311 }
312 if (gsmnet->t3212 == 0)
313 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
314 else
315 vty_out(vty, " periodic location update %u%s",
316 gsmnet->t3212 * 6, VTY_NEWLINE);
317
318 if (gsmnet->emergency.route_to_msisdn) {
319 vty_out(vty, " emergency-call route-to-msisdn %s%s",
320 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
321 }
322
323 return CMD_SUCCESS;
324}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200325
326static struct cmd_node msc_node = {
327 MSC_NODE,
328 "%s(config-msc)# ",
329 1,
330};
331
332DEFUN(cfg_msc, cfg_msc_cmd,
333 "msc", "Configure MSC options")
334{
335 vty->node = MSC_NODE;
336 return CMD_SUCCESS;
337}
338
Philipp Maier9ca7b312018-10-10 17:00:49 +0200339DEFUN(cfg_msc_mncc_guard_timeout,
340 cfg_msc_mncc_guard_timeout_cmd,
341 "mncc-guard-timeout <0-255>",
342 "Set global guard timer for mncc interface activity\n"
343 "guard timer value (sec.)")
344{
345 gsmnet->mncc_guard_timeout = atoi(argv[0]);
346 return CMD_SUCCESS;
347}
348
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200349DEFUN(cfg_msc_assign_tmsi, cfg_msc_assign_tmsi_cmd,
350 "assign-tmsi",
351 "Assign TMSI during Location Updating.\n")
352{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200353 gsmnet->vlr->cfg.assign_tmsi = true;
354 return CMD_SUCCESS;
355}
356
357DEFUN(cfg_msc_no_assign_tmsi, cfg_msc_no_assign_tmsi_cmd,
358 "no assign-tmsi",
359 NO_STR "Assign TMSI during Location Updating.\n")
360{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200361 gsmnet->vlr->cfg.assign_tmsi = false;
362 return CMD_SUCCESS;
363}
364
Philipp Maierfbf66102017-04-09 12:32:51 +0200365DEFUN(cfg_msc_cs7_instance_a,
366 cfg_msc_cs7_instance_a_cmd,
367 "cs7-instance-a <0-15>",
368 "Set SS7 to be used by the A-Interface.\n" "SS7 instance reference number\n")
369{
Philipp Maierfbf66102017-04-09 12:32:51 +0200370 gsmnet->a.cs7_instance = atoi(argv[0]);
371 return CMD_SUCCESS;
372}
373
374DEFUN(cfg_msc_cs7_instance_iu,
375 cfg_msc_cs7_instance_iu_cmd,
376 "cs7-instance-iu <0-15>",
377 "Set SS7 to be used by the Iu-Interface.\n" "SS7 instance reference number\n")
378{
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100379#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200380 gsmnet->iu.cs7_instance = atoi(argv[0]);
381 return CMD_SUCCESS;
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100382#else
383 vty_out(vty, "WARNING: 'cs7-instance-iu' without effect: built without Iu support%s",
384 VTY_NEWLINE);
385 return CMD_WARNING;
386#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200387}
388
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100389DEFUN(cfg_msc_auth_tuple_max_reuse_count, cfg_msc_auth_tuple_max_reuse_count_cmd,
390 "auth-tuple-max-reuse-count <-1-2147483647>",
391 "Configure authentication tuple re-use\n"
392 "0 to use each auth tuple at most once (default), >0 to limit re-use, -1 to re-use infinitely (vulnerable!).\n")
393{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100394 gsmnet->vlr->cfg.auth_tuple_max_reuse_count = atoi(argv[0]);
395 return CMD_SUCCESS;
396}
397
398DEFUN(cfg_msc_auth_tuple_reuse_on_error, cfg_msc_auth_tuple_reuse_on_error_cmd,
399 "auth-tuple-reuse-on-error (0|1)",
400 "Configure authentication tuple re-use when HLR is not responsive\n"
401 "0 = never re-use auth tuples beyond auth-tuple-max-reuse-count (default)\n"
402 "1 = if the HLR does not deliver new tuples, do re-use already available old ones.\n")
403{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100404 gsmnet->vlr->cfg.auth_reuse_old_sets_on_error = atoi(argv[0]) ? true : false;
405 return CMD_SUCCESS;
406}
407
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100408DEFUN(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd,
409 "paging response-timer (default|<1-65535>)",
410 "Configure Paging\n"
411 "Set Paging timeout, the minimum time to pass between (unsuccessful) Pagings sent towards"
412 " BSS or RNC\n"
413 "Set to default timeout (" OSMO_STRINGIFY_VAL(MSC_PAGING_RESPONSE_TIMER_DEFAULT) " seconds)\n"
414 "Set paging timeout in seconds\n")
415{
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100416 if (!strcmp(argv[1], "default"))
417 gsmnet->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
418 else
419 gsmnet->paging_response_timer = atoi(argv[0]);
420 return CMD_SUCCESS;
421}
422
Harald Welte69c54a82018-02-09 20:41:14 +0100423DEFUN(cfg_msc_emergency_msisdn, cfg_msc_emergency_msisdn_cmd,
424 "emergency-call route-to-msisdn MSISDN",
425 "Configure Emergency Call Behaviour\n"
426 "MSISDN to which Emergency Calls are Dispatched\n"
427 "MSISDN (E.164 Phone Number)\n")
428{
Harald Welte69c54a82018-02-09 20:41:14 +0100429 osmo_talloc_replace_string(gsmnet, &gsmnet->emergency.route_to_msisdn, argv[0]);
430
431 return CMD_SUCCESS;
432}
433
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200434static int config_write_msc(struct vty *vty)
435{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200436 vty_out(vty, "msc%s", VTY_NEWLINE);
Philipp Maier9ca7b312018-10-10 17:00:49 +0200437 vty_out(vty, " mncc-guard-timeout %i%s",
438 gsmnet->mncc_guard_timeout, VTY_NEWLINE);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200439 vty_out(vty, " %sassign-tmsi%s",
440 gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
441
Philipp Maierfbf66102017-04-09 12:32:51 +0200442 vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
443 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100444#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200445 vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance,
446 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100447#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200448
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100449 if (gsmnet->vlr->cfg.auth_tuple_max_reuse_count)
450 vty_out(vty, " auth-tuple-max-reuse-count %d%s",
451 OSMO_MAX(-1, gsmnet->vlr->cfg.auth_tuple_max_reuse_count),
452 VTY_NEWLINE);
453 if (gsmnet->vlr->cfg.auth_reuse_old_sets_on_error)
454 vty_out(vty, " auth-tuple-reuse-on-error 1%s",
455 VTY_NEWLINE);
456
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100457 if (gsmnet->paging_response_timer != MSC_PAGING_RESPONSE_TIMER_DEFAULT)
458 vty_out(vty, " paging response-timer %u%s", gsmnet->paging_response_timer, VTY_NEWLINE);
459
Harald Welte69c54a82018-02-09 20:41:14 +0100460 if (gsmnet->emergency.route_to_msisdn) {
461 vty_out(vty, " emergency-call route-to-msisdn %s%s",
462 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
463 }
464
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +0200465 mgcp_client_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200466#ifdef BUILD_IU
Neels Hofmeyr00e82d62017-07-05 15:19:52 +0200467 ranap_iu_vty_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200468#endif
469
470 return CMD_SUCCESS;
471}
472
Maxc51609a2018-11-09 17:13:00 +0100473DEFUN(show_bsc, show_bsc_cmd,
474 "show bsc", SHOW_STR "BSC\n")
475{
476 struct bsc_context *bsc_ctx;
477 struct osmo_ss7_instance *ss7 = osmo_ss7_instance_find(gsmnet->a.cs7_instance);
478
479 llist_for_each_entry(bsc_ctx, &gsmnet->a.bscs, list) {
480 vty_out(vty, "BSC %s%s", osmo_sccp_addr_name(ss7, &bsc_ctx->bsc_addr), VTY_NEWLINE);
481 }
482
483 return CMD_SUCCESS;
484}
485
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100486static void vty_conn_hdr(struct vty *vty)
487{
488 vty_out(vty, "--ConnId ------------Subscriber RAN --LAC Use --Tokens C A5 State%s",
489 VTY_NEWLINE);
490}
491
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100492static void vty_dump_one_conn(struct vty *vty, const struct ran_conn *conn)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100493{
494 vty_out(vty, "%08x %22s %3s %5u %3u %08x %c /%1u %27s %s",
495 conn->a.conn_id,
496 conn->vsub ? vlr_subscr_name(conn->vsub) : "-",
497 conn->via_ran == RAN_UTRAN_IU ? "Iu" : "A",
498 conn->lac,
499 conn->use_count,
500 conn->use_tokens,
501 conn->received_cm_service_request ? 'C' : '-',
Neels Hofmeyrf41658d2018-11-30 04:35:50 +0100502 conn->geran_encr.alg_id,
Neels Hofmeyr4d3a66b2018-03-31 18:45:59 +0200503 conn->fi ? osmo_fsm_inst_state_name(conn->fi) : "-",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100504 VTY_NEWLINE);
505}
506
507DEFUN(show_msc_conn, show_msc_conn_cmd,
508 "show connection", SHOW_STR "Subscriber Connections\n")
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200509{
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100510 struct ran_conn *conn;
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200511
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100512 vty_conn_hdr(vty);
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100513 llist_for_each_entry(conn, &gsmnet->ran_conns, entry)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100514 vty_dump_one_conn(vty, conn);
515
516 return CMD_SUCCESS;
517}
518
519static void vty_trans_hdr(struct vty *vty)
520{
521 vty_out(vty, "------------Subscriber --ConnId -P TI -CallRef Proto%s",
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200522 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100523}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200524
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100525static const char *get_trans_proto_str(const struct gsm_trans *trans)
526{
527 static char buf[256];
528
529 switch (trans->protocol) {
530 case GSM48_PDISC_CC:
531 snprintf(buf, sizeof(buf), "%s %4u %4u",
532 gsm48_cc_state_name(trans->cc.state),
533 trans->cc.Tcurrent,
534 trans->cc.T308_second);
535 break;
536 case GSM48_PDISC_SMS:
537 snprintf(buf, sizeof(buf), "%s %s",
538 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
539 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
540 break;
541 default:
542 buf[0] = '\0';
543 break;
544 }
545
546 return buf;
547}
548
549static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
550{
551 vty_out(vty, "%22s %08x %s %02u %08x %s%s",
552 trans->vsub ? vlr_subscr_name(trans->vsub) : "-",
553 trans->conn ? trans->conn->a.conn_id : 0,
554 gsm48_pdisc_name(trans->protocol),
555 trans->transaction_id,
556 trans->callref,
557 get_trans_proto_str(trans), VTY_NEWLINE);
558}
559
560DEFUN(show_msc_transaction, show_msc_transaction_cmd,
561 "show transaction", SHOW_STR "Transactions\n")
562{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100563 struct gsm_trans *trans;
564
565 vty_trans_hdr(vty);
566 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
567 vty_dump_one_trans(vty, trans);
568
569 return CMD_SUCCESS;
570}
571
572static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
573{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100574 struct gsm_trans *trans;
575 int reqs;
576 struct llist_head *entry;
577
578 if (strlen(vsub->name))
579 vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
580 if (strlen(vsub->msisdn))
581 vty_out(vty, " Extension: %s%s", vsub->msisdn,
582 VTY_NEWLINE);
583 vty_out(vty, " LAC: %d/0x%x%s",
584 vsub->lac, vsub->lac, VTY_NEWLINE);
585 vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
586 if (vsub->tmsi != GSM_RESERVED_TMSI)
587 vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
588 VTY_NEWLINE);
589 if (vsub->tmsi_new != GSM_RESERVED_TMSI)
590 vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
591 VTY_NEWLINE);
592
593#if 0
594 /* TODO: add this to vlr_subscr? */
595 if (vsub->auth_info.auth_algo != AUTH_ALGO_NONE) {
596 struct gsm_auth_info *i = &vsub->auth_info;
597 vty_out(vty, " A3A8 algorithm id: %d%s",
598 i->auth_algo, VTY_NEWLINE);
599 vty_out(vty, " A3A8 Ki: %s%s",
600 osmo_hexdump(i->a3a8_ki, i->a3a8_ki_len),
601 VTY_NEWLINE);
602 }
603#endif
604
605 if (vsub->last_tuple) {
606 struct gsm_auth_tuple *t = vsub->last_tuple;
607 vty_out(vty, " A3A8 last tuple (used %d times):%s",
608 t->use_count, VTY_NEWLINE);
609 vty_out(vty, " seq # : %d%s",
610 t->key_seq, VTY_NEWLINE);
611 vty_out(vty, " RAND : %s%s",
612 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
613 VTY_NEWLINE);
614 vty_out(vty, " SRES : %s%s",
615 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
616 VTY_NEWLINE);
617 vty_out(vty, " Kc : %s%s",
618 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
619 VTY_NEWLINE);
620 }
621
622 reqs = 0;
623 llist_for_each(entry, &vsub->cs.requests)
624 reqs += 1;
625 vty_out(vty, " Paging: %s paging for %d requests%s",
626 vsub->cs.is_paging ? "is" : "not", reqs, VTY_NEWLINE);
627 vty_out(vty, " Use count: %u%s", vsub->use_count, VTY_NEWLINE);
628
629 /* Connection */
630 if (vsub->msc_conn_ref) {
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100631 struct ran_conn *conn = vsub->msc_conn_ref;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100632 vty_conn_hdr(vty);
633 vty_dump_one_conn(vty, conn);
634 }
635
636 /* Transactions */
637 vty_trans_hdr(vty);
638 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
639 if (trans->vsub != vsub)
640 continue;
641 vty_dump_one_trans(vty, trans);
642 }
643}
644
645/* Subscriber */
646DEFUN(show_subscr_cache,
647 show_subscr_cache_cmd,
648 "show subscriber cache",
649 SHOW_STR "Show information about subscribers\n"
650 "Display contents of subscriber cache\n")
651{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100652 struct vlr_subscr *vsub;
653 int count = 0;
654
655 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
656 if (++count > 100) {
657 vty_out(vty, "%% More than %d subscribers in cache,"
658 " stopping here.%s", count-1, VTY_NEWLINE);
659 break;
660 }
661 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
662 subscr_dump_full_vty(vty, vsub);
Harald Welte69c54a82018-02-09 20:41:14 +0100663 }
664
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200665 return CMD_SUCCESS;
666}
667
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100668DEFUN(sms_send_pend,
669 sms_send_pend_cmd,
670 "sms send pending",
671 "SMS related commands\n" "SMS Sending related commands\n"
672 "Send all pending SMS")
673{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100674 struct gsm_sms *sms;
675 unsigned long long sms_id = 0;
676
677 while (1) {
678 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
679 if (!sms)
680 break;
681
682 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700683 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100684
685 sms_id = sms->id + 1;
686 }
687
688 return CMD_SUCCESS;
689}
690
691DEFUN(sms_delete_expired,
692 sms_delete_expired_cmd,
693 "sms delete expired",
694 "SMS related commands\n" "SMS Database related commands\n"
695 "Delete all expired SMS")
696{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100697 struct gsm_sms *sms;
698 unsigned long long sms_id = 0;
699 long long num_deleted = 0;
700
701 while (1) {
702 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
703 if (!sms)
704 break;
705
706 /* Skip SMS which are currently queued for sending. */
707 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
708 continue;
709
710 /* Expiration check is performed by the DB layer. */
711 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
712 num_deleted++;
713
714 sms_id = sms->id + 1;
715 }
716
717 if (num_deleted == 0) {
718 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
719 return CMD_WARNING;
720 }
721
722 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
723 return CMD_SUCCESS;
724}
725
726static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +0200727 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100728 char *str, uint8_t tp_pid)
729{
730 struct gsm_network *net = receiver->vlr->user_ctx;
731 struct gsm_sms *sms;
732
Harald Welte39b55482018-04-09 19:19:33 +0200733 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100734 sms->protocol_id = tp_pid;
735
736 /* store in database for the queue */
737 if (db_sms_store(sms) != 0) {
738 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
739 sms_free(sms);
740 return CMD_WARNING;
741 }
742 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
743
744 sms_free(sms);
745 sms_queue_trigger(net->sms_queue);
746 return CMD_SUCCESS;
747}
748
749static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
750 const char *type,
751 const char *id)
752{
753 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
754 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id);
755 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
756 return vlr_subscr_find_by_imsi(gsmnet->vlr, id);
757 else if (!strcmp(type, "tmsi"))
758 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id));
759
760 return NULL;
761}
762#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
763#define SUBSCR_HELP "Operations on a Subscriber\n" \
764 "Identify subscriber by MSISDN (phone number)\n" \
765 "Legacy alias for 'msisdn'\n" \
766 "Identify subscriber by IMSI\n" \
767 "Identify subscriber by TMSI\n" \
768 "Identify subscriber by database ID\n" \
769 "Identifier for the subscriber\n"
770
771DEFUN(show_subscr,
772 show_subscr_cmd,
773 "show subscriber " SUBSCR_TYPES " ID",
774 SHOW_STR SUBSCR_HELP)
775{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100776 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
777 argv[1]);
778
779 if (!vsub) {
780 vty_out(vty, "%% No subscriber found for %s %s%s",
781 argv[0], argv[1], VTY_NEWLINE);
782 return CMD_WARNING;
783 }
784
785 subscr_dump_full_vty(vty, vsub);
786
787 vlr_subscr_put(vsub);
788
789 return CMD_SUCCESS;
790}
791
792DEFUN(subscriber_create,
793 subscriber_create_cmd,
794 "subscriber create imsi ID",
795 "Operations on a Subscriber\n" \
796 "Create new subscriber\n" \
797 "Identify the subscriber by his IMSI\n" \
798 "Identifier for the subscriber\n")
799{
800 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
801 VTY_NEWLINE);
802 return CMD_WARNING;
803}
804
805DEFUN(subscriber_send_pending_sms,
806 subscriber_send_pending_sms_cmd,
807 "subscriber " SUBSCR_TYPES " ID sms pending-send",
808 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
809{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100810 struct vlr_subscr *vsub;
811 struct gsm_sms *sms;
812
813 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
814 if (!vsub) {
815 vty_out(vty, "%% No subscriber found for %s %s%s",
816 argv[0], argv[1], VTY_NEWLINE);
817 return CMD_WARNING;
818 }
819
820 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
821 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700822 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100823
824 vlr_subscr_put(vsub);
825
826 return CMD_SUCCESS;
827}
828
829DEFUN(subscriber_send_sms,
830 subscriber_send_sms_cmd,
831 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
832 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
833{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100834 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200835 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100836 char *str;
837 int rc;
838
839 if (!vsub) {
840 vty_out(vty, "%% No subscriber found for %s %s%s",
841 argv[0], argv[1], VTY_NEWLINE);
842 rc = CMD_WARNING;
843 goto err;
844 }
845
Harald Welte39b55482018-04-09 19:19:33 +0200846 if (!strcmp(argv[2], "msisdn"))
847 sender_msisdn = argv[3];
848 else {
849 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
850 if (!sender) {
851 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
852 rc = CMD_WARNING;
853 goto err;
854 }
855 sender_msisdn = sender->msisdn;
856 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100857 }
858
859 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +0200860 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100861 talloc_free(str);
862
863err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100864 if (vsub)
865 vlr_subscr_put(vsub);
866
867 return rc;
868}
869
870DEFUN(subscriber_silent_sms,
871 subscriber_silent_sms_cmd,
872
873 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
874 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
875{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100876 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200877 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100878 char *str;
879 int rc;
880
881 if (!vsub) {
882 vty_out(vty, "%% No subscriber found for %s %s%s",
883 argv[0], argv[1], VTY_NEWLINE);
884 rc = CMD_WARNING;
885 goto err;
886 }
887
Harald Welte39b55482018-04-09 19:19:33 +0200888 if (!strcmp(argv[2], "msisdn")) {
889 sender_msisdn = argv[3];
890 } else {
891 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
892 if (!sender) {
893 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
894 rc = CMD_WARNING;
895 goto err;
896 }
897 sender_msisdn = sender->msisdn;
898 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100899 }
900
901 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +0200902 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100903 talloc_free(str);
904
905err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100906 if (vsub)
907 vlr_subscr_put(vsub);
908
909 return rc;
910}
911
912#define CHAN_TYPES "(any|tch/f|tch/any|sdcch)"
913#define CHAN_TYPE_HELP \
914 "Any channel\n" \
915 "TCH/F channel\n" \
916 "Any TCH channel\n" \
917 "SDCCH channel\n"
918
919DEFUN(subscriber_silent_call_start,
920 subscriber_silent_call_start_cmd,
921 "subscriber " SUBSCR_TYPES " ID silent-call start (any|tch/f|tch/any|sdcch)",
922 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
923 CHAN_TYPE_HELP)
924{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100925 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
926 int rc, type;
927
928 if (!vsub) {
929 vty_out(vty, "%% No subscriber found for %s %s%s",
930 argv[0], argv[1], VTY_NEWLINE);
931 return CMD_WARNING;
932 }
933
934 if (!strcmp(argv[2], "tch/f"))
935 type = RSL_CHANNEED_TCH_F;
936 else if (!strcmp(argv[2], "tch/any"))
937 type = RSL_CHANNEED_TCH_ForH;
938 else if (!strcmp(argv[2], "sdcch"))
939 type = RSL_CHANNEED_SDCCH;
940 else
941 type = RSL_CHANNEED_ANY; /* Defaults to ANY */
942
943 rc = gsm_silent_call_start(vsub, vty, type);
944 switch (rc) {
945 case -ENODEV:
946 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
947 break;
948 default:
949 if (rc)
950 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
951 else
952 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
953 break;
954 }
955
956 vlr_subscr_put(vsub);
957 return rc ? CMD_WARNING : CMD_SUCCESS;
958}
959
960DEFUN(subscriber_silent_call_stop,
961 subscriber_silent_call_stop_cmd,
962 "subscriber " SUBSCR_TYPES " ID silent-call stop",
963 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
964 CHAN_TYPE_HELP)
965{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100966 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
967 int rc;
968
969 if (!vsub) {
970 vty_out(vty, "%% No subscriber found for %s %s%s",
971 argv[0], argv[1], VTY_NEWLINE);
972 return CMD_WARNING;
973 }
974
975 rc = gsm_silent_call_stop(vsub);
976 switch (rc) {
977 case -ENODEV:
978 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
979 break;
980 case -ENOENT:
981 vty_out(vty, "%% Subscriber has no silent call active%s",
982 VTY_NEWLINE);
983 break;
984 default:
985 if (rc)
986 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
987 else
988 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
989 break;
990 }
991
992 vlr_subscr_put(vsub);
993 return rc ? CMD_WARNING : CMD_SUCCESS;
994}
995
996DEFUN(subscriber_ussd_notify,
997 subscriber_ussd_notify_cmd,
998 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
999 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1000 "Alerting Level 0\n"
1001 "Alerting Level 1\n"
1002 "Alerting Level 2\n"
1003 "Text of USSD message to send\n")
1004{
1005 char *text;
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001006 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001007 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1008 int level;
1009
1010 if (!vsub) {
1011 vty_out(vty, "%% No subscriber found for %s %s%s",
1012 argv[0], argv[1], VTY_NEWLINE);
1013 return CMD_WARNING;
1014 }
1015
1016 level = atoi(argv[2]);
1017 text = argv_concat(argv, argc, 3);
1018 if (!text) {
1019 vlr_subscr_put(vsub);
1020 return CMD_WARNING;
1021 }
1022
1023 conn = connection_for_subscr(vsub);
1024 if (!conn) {
1025 vty_out(vty, "%% An active connection is required for %s %s%s",
1026 argv[0], argv[1], VTY_NEWLINE);
1027 vlr_subscr_put(vsub);
1028 talloc_free(text);
1029 return CMD_WARNING;
1030 }
1031
1032 msc_send_ussd_notify(conn, level, text);
1033 msc_send_ussd_release_complete(conn);
1034
1035 vlr_subscr_put(vsub);
1036 talloc_free(text);
1037 return CMD_SUCCESS;
1038}
1039
1040DEFUN(subscriber_paging,
1041 subscriber_paging_cmd,
1042 "subscriber " SUBSCR_TYPES " ID paging",
1043 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1044{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001045 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1046 struct subscr_request *req;
1047
1048 if (!vsub) {
1049 vty_out(vty, "%% No subscriber found for %s %s%s",
1050 argv[0], argv[1], VTY_NEWLINE);
1051 return CMD_WARNING;
1052 }
1053
1054 req = subscr_request_conn(vsub, NULL, NULL, "manual Paging from VTY");
1055 if (req)
1056 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1057 else
1058 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1059
1060 vlr_subscr_put(vsub);
1061 return req ? CMD_SUCCESS : CMD_WARNING;
1062}
1063
1064static int loop_by_char(uint8_t ch)
1065{
1066 switch (ch) {
1067 case 'a':
1068 return GSM414_LOOP_A;
1069 case 'b':
1070 return GSM414_LOOP_B;
1071 case 'c':
1072 return GSM414_LOOP_C;
1073 case 'd':
1074 return GSM414_LOOP_D;
1075 case 'e':
1076 return GSM414_LOOP_E;
1077 case 'f':
1078 return GSM414_LOOP_F;
1079 case 'i':
1080 return GSM414_LOOP_I;
1081 }
1082 return -1;
1083}
1084
1085DEFUN(subscriber_mstest_close,
1086 subscriber_mstest_close_cmd,
1087 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1088 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1089 "Close a TCH Loop inside the MS\n"
1090 "Loop Type A\n"
1091 "Loop Type B\n"
1092 "Loop Type C\n"
1093 "Loop Type D\n"
1094 "Loop Type E\n"
1095 "Loop Type F\n"
1096 "Loop Type I\n")
1097{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001098 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001099 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1100 const char *loop_str;
1101 int loop_mode;
1102
1103 if (!vsub) {
1104 vty_out(vty, "%% No subscriber found for %s %s%s",
1105 argv[0], argv[1], VTY_NEWLINE);
1106 return CMD_WARNING;
1107 }
1108
1109 loop_str = argv[2];
1110 loop_mode = loop_by_char(loop_str[0]);
1111
1112 conn = connection_for_subscr(vsub);
1113 if (!conn) {
1114 vty_out(vty, "%% An active connection is required for %s %s%s",
1115 argv[0], argv[1], VTY_NEWLINE);
1116 vlr_subscr_put(vsub);
1117 return CMD_WARNING;
1118 }
1119
1120 gsm0414_tx_close_tch_loop_cmd(conn, loop_mode);
1121
1122 return CMD_SUCCESS;
1123}
1124
1125DEFUN(subscriber_mstest_open,
1126 subscriber_mstest_open_cmd,
1127 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1128 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1129 "Open a TCH Loop inside the MS\n")
1130{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001131 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001132 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1133
1134 if (!vsub) {
1135 vty_out(vty, "%% No subscriber found for %s %s%s",
1136 argv[0], argv[1], VTY_NEWLINE);
1137 return CMD_WARNING;
1138 }
1139
1140 conn = connection_for_subscr(vsub);
1141 if (!conn) {
1142 vty_out(vty, "%% An active connection is required for %s %s%s",
1143 argv[0], argv[1], VTY_NEWLINE);
1144 vlr_subscr_put(vsub);
1145 return CMD_WARNING;
1146 }
1147
1148 gsm0414_tx_open_loop_cmd(conn);
1149
1150 return CMD_SUCCESS;
1151}
1152
1153DEFUN(ena_subscr_expire,
1154 ena_subscr_expire_cmd,
1155 "subscriber " SUBSCR_TYPES " ID expire",
1156 SUBSCR_HELP "Expire the subscriber Now\n")
1157{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001158 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1159 argv[1]);
1160
1161 if (!vsub) {
1162 vty_out(vty, "%% No subscriber found for %s %s%s",
1163 argv[0], argv[1], VTY_NEWLINE);
1164 return CMD_WARNING;
1165 }
1166
1167 if (vlr_subscr_expire(vsub))
1168 vty_out(vty, "%% VLR released subscriber %s%s",
1169 vlr_subscr_name(vsub), VTY_NEWLINE);
1170
1171 if (vsub->use_count > 1)
1172 vty_out(vty, "%% Subscriber %s is still in use,"
1173 " should be released soon%s",
1174 vlr_subscr_name(vsub), VTY_NEWLINE);
1175
1176 vlr_subscr_put(vsub);
1177 return CMD_SUCCESS;
1178}
1179
1180static int scall_cbfn(unsigned int subsys, unsigned int signal,
1181 void *handler_data, void *signal_data)
1182{
1183 struct scall_signal_data *sigdata = signal_data;
1184 struct vty *vty = sigdata->data;
1185
1186 switch (signal) {
1187 case S_SCALL_SUCCESS:
1188 vty_out(vty, "%% silent call success%s", VTY_NEWLINE);
1189 break;
1190 case S_SCALL_EXPIRED:
1191 vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE);
1192 break;
1193 }
1194 return 0;
1195}
1196
1197DEFUN(show_stats,
1198 show_stats_cmd,
1199 "show statistics",
1200 SHOW_STR "Display network statistics\n")
1201{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001202 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001203 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1204 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1205 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001206 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001207 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001208 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001209 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001210 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001211 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1212 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001213 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001214 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001215 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1216 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001217 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001218 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001219 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1220 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1221 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001222 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001223 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001224 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1225 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001226 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001227 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001228 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1229 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001230 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001231 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001232 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1233 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1234 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1235 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1236 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001237 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001238 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1239 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1240 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1241 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1242 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001243 return CMD_SUCCESS;
1244}
1245
1246DEFUN(show_smsqueue,
1247 show_smsqueue_cmd,
1248 "show sms-queue",
1249 SHOW_STR "Display SMSqueue statistics\n")
1250{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001251 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001252 return CMD_SUCCESS;
1253}
1254
1255DEFUN(smsqueue_trigger,
1256 smsqueue_trigger_cmd,
1257 "sms-queue trigger",
1258 "SMS Queue\n" "Trigger sending messages\n")
1259{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001260 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001261 return CMD_SUCCESS;
1262}
1263
1264DEFUN(smsqueue_max,
1265 smsqueue_max_cmd,
1266 "sms-queue max-pending <1-500>",
1267 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1268{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001269 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001270 return CMD_SUCCESS;
1271}
1272
1273DEFUN(smsqueue_clear,
1274 smsqueue_clear_cmd,
1275 "sms-queue clear",
1276 "SMS Queue\n" "Clear the queue of pending SMS\n")
1277{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001278 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001279 return CMD_SUCCESS;
1280}
1281
1282DEFUN(smsqueue_fail,
1283 smsqueue_fail_cmd,
1284 "sms-queue max-failure <1-500>",
1285 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1286{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001287 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001288 return CMD_SUCCESS;
1289}
1290
1291
1292DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1293 "mncc-int", "Configure internal MNCC handler")
1294{
1295 vty->node = MNCC_INT_NODE;
1296
1297 return CMD_SUCCESS;
1298}
1299
1300static struct cmd_node mncc_int_node = {
1301 MNCC_INT_NODE,
1302 "%s(config-mncc-int)# ",
1303 1,
1304};
1305
1306static const struct value_string tchf_codec_names[] = {
1307 { GSM48_CMODE_SPEECH_V1, "fr" },
1308 { GSM48_CMODE_SPEECH_EFR, "efr" },
1309 { GSM48_CMODE_SPEECH_AMR, "amr" },
1310 { 0, NULL }
1311};
1312
1313static const struct value_string tchh_codec_names[] = {
1314 { GSM48_CMODE_SPEECH_V1, "hr" },
1315 { GSM48_CMODE_SPEECH_AMR, "amr" },
1316 { 0, NULL }
1317};
1318
1319static int config_write_mncc_int(struct vty *vty)
1320{
1321 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1322 vty_out(vty, " default-codec tch-f %s%s",
1323 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1324 VTY_NEWLINE);
1325 vty_out(vty, " default-codec tch-h %s%s",
1326 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1327 VTY_NEWLINE);
1328
1329 return CMD_SUCCESS;
1330}
1331
1332DEFUN(mnccint_def_codec_f,
1333 mnccint_def_codec_f_cmd,
1334 "default-codec tch-f (fr|efr|amr)",
1335 "Set default codec\n" "Codec for TCH/F\n"
1336 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1337{
1338 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1339
1340 return CMD_SUCCESS;
1341}
1342
1343DEFUN(mnccint_def_codec_h,
1344 mnccint_def_codec_h_cmd,
1345 "default-codec tch-h (hr|amr)",
1346 "Set default codec\n" "Codec for TCH/H\n"
1347 "Half-Rate\n" "Adaptive Multi-Rate\n")
1348{
1349 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1350
1351 return CMD_SUCCESS;
1352}
1353
1354
1355DEFUN(logging_fltr_imsi,
1356 logging_fltr_imsi_cmd,
1357 "logging filter imsi IMSI",
1358 LOGGING_STR FILTER_STR
1359 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1360{
1361 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001362 struct log_target *tgt = osmo_log_vty2tgt(vty);
1363 const char *imsi = argv[0];
1364
1365 if (!tgt)
1366 return CMD_WARNING;
1367
1368 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi);
1369
1370 if (!vlr_subscr) {
1371 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1372 argv[0], VTY_NEWLINE);
1373 return CMD_WARNING;
1374 }
1375
1376 log_set_filter_vlr_subscr(tgt, vlr_subscr);
1377 return CMD_SUCCESS;
1378}
1379
1380static struct cmd_node hlr_node = {
1381 HLR_NODE,
1382 "%s(config-hlr)# ",
1383 1,
1384};
1385
1386DEFUN(cfg_hlr, cfg_hlr_cmd,
1387 "hlr", "Configure connection to the HLR")
1388{
1389 vty->node = HLR_NODE;
1390 return CMD_SUCCESS;
1391}
1392
1393DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1394 "Remote GSUP address of the HLR\n"
1395 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1396{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001397 talloc_free((void*)gsmnet->gsup_server_addr_str);
1398 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1399 return CMD_SUCCESS;
1400}
1401
1402DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1403 "Remote GSUP port of the HLR\n"
1404 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1405{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001406 gsmnet->gsup_server_port = atoi(argv[0]);
1407 return CMD_SUCCESS;
1408}
1409
1410static int config_write_hlr(struct vty *vty)
1411{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001412 vty_out(vty, "hlr%s", VTY_NEWLINE);
1413 vty_out(vty, " remote-ip %s%s",
1414 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1415 vty_out(vty, " remote-port %u%s",
1416 gsmnet->gsup_server_port, VTY_NEWLINE);
1417 return CMD_SUCCESS;
1418}
1419
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001420void msc_vty_init(struct gsm_network *msc_network)
1421{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001422 OSMO_ASSERT(gsmnet == NULL);
1423 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001424
1425 osmo_stats_vty_add_cmds();
1426
1427 install_element(CONFIG_NODE, &cfg_net_cmd);
1428 install_node(&net_node, config_write_net);
1429 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
1430 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1431 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1432 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
1433 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
1434 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
1435 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
1436 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
1437 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
1438 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
1439 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
1440 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
1441 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001442
1443 install_element(CONFIG_NODE, &cfg_msc_cmd);
1444 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001445 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02001446 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001447 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01001448 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
1449 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001450 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
1451 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01001452 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01001453 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001454
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02001455 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001456#ifdef BUILD_IU
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +01001457 ranap_iu_vty_init(MSC_NODE, &msc_network->iu.rab_assign_addr_enc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001458#endif
Stefan Sperling617ac802018-02-22 17:58:20 +01001459 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001460
1461 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
1462
1463 install_element_ve(&show_subscr_cmd);
1464 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01001465 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001466 install_element_ve(&show_msc_conn_cmd);
1467 install_element_ve(&show_msc_transaction_cmd);
1468
1469 install_element_ve(&sms_send_pend_cmd);
1470 install_element_ve(&sms_delete_expired_cmd);
1471
1472 install_element_ve(&subscriber_create_cmd);
1473 install_element_ve(&subscriber_send_sms_cmd);
1474 install_element_ve(&subscriber_silent_sms_cmd);
1475 install_element_ve(&subscriber_silent_call_start_cmd);
1476 install_element_ve(&subscriber_silent_call_stop_cmd);
1477 install_element_ve(&subscriber_ussd_notify_cmd);
1478 install_element_ve(&subscriber_mstest_close_cmd);
1479 install_element_ve(&subscriber_mstest_open_cmd);
1480 install_element_ve(&subscriber_paging_cmd);
1481 install_element_ve(&show_stats_cmd);
1482 install_element_ve(&show_smsqueue_cmd);
1483 install_element_ve(&logging_fltr_imsi_cmd);
1484
1485 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
1486 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
1487 install_element(ENABLE_NODE, &smsqueue_max_cmd);
1488 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
1489 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
1490 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
1491
1492 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1493 install_node(&mncc_int_node, config_write_mncc_int);
1494 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1495 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1496
1497 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
1498
1499 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1500 install_node(&hlr_node, config_write_hlr);
1501 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1502 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001503}