blob: 0c07bc217893c57645aa980167a7b4766ef12bb2 [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>
Pau Espin Pedrol4faff9e2019-05-06 19:29:11 +020062#include <osmocom/msc/osmux.h>
Vadim Yanitskiy1b891302018-08-04 01:33:08 +070063#include <osmocom/msc/rrlp.h>
Harald Welte0df904d2018-12-03 11:00:04 +010064#include <osmocom/msc/vlr_sgs.h>
65#include <osmocom/msc/sgs_vty.h>
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010066#include <osmocom/msc/sccp_ran.h>
67#include <osmocom/msc/ran_peer.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010068
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010069static struct gsm_network *gsmnet = NULL;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010070
71struct cmd_node net_node = {
72 GSMNET_NODE,
73 "%s(config-net)# ",
74 1,
75};
76
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +010077#define VSUB_USE_VTY "VTY"
78
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010079#define NETWORK_STR "Configure the GSM network\n"
80#define CODE_CMD_STR "Code commands\n"
81#define NAME_CMD_STR "Name Commands\n"
82#define NAME_STR "Name to use\n"
83
84DEFUN(cfg_net,
85 cfg_net_cmd,
86 "network", NETWORK_STR)
87{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010088 vty->index = gsmnet;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010089 vty->node = GSMNET_NODE;
90
91 return CMD_SUCCESS;
92}
93
94DEFUN(cfg_net_ncc,
95 cfg_net_ncc_cmd,
96 "network country code <1-999>",
97 "Set the GSM network country code\n"
98 "Country commands\n"
99 CODE_CMD_STR
100 "Network Country Code to use\n")
101{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100102 gsmnet->plmn.mcc = atoi(argv[0]);
103
104 return CMD_SUCCESS;
105}
106
107DEFUN(cfg_net_mnc,
108 cfg_net_mnc_cmd,
109 "mobile network code <0-999>",
110 "Set the GSM mobile network code\n"
111 "Network Commands\n"
112 CODE_CMD_STR
113 "Mobile Network Code to use\n")
114{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100115 uint16_t mnc;
116 bool mnc_3_digits;
117
118 if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
119 vty_out(vty, "%% Error decoding MNC: %s%s", argv[0], VTY_NEWLINE);
120 return CMD_WARNING;
121 }
122
123 gsmnet->plmn.mnc = mnc;
124 gsmnet->plmn.mnc_3_digits = mnc_3_digits;
125
126 return CMD_SUCCESS;
127}
128
129DEFUN(cfg_net_name_short,
130 cfg_net_name_short_cmd,
131 "short name NAME",
132 "Set the short GSM network name\n" NAME_CMD_STR NAME_STR)
133{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100134 osmo_talloc_replace_string(gsmnet, &gsmnet->name_short, argv[0]);
135 return CMD_SUCCESS;
136}
137
138DEFUN(cfg_net_name_long,
139 cfg_net_name_long_cmd,
140 "long name NAME",
141 "Set the long GSM network name\n" NAME_CMD_STR NAME_STR)
142{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100143 osmo_talloc_replace_string(gsmnet, &gsmnet->name_long, argv[0]);
144 return CMD_SUCCESS;
145}
146
147DEFUN(cfg_net_encryption,
148 cfg_net_encryption_cmd,
149 "encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]",
150 "Encryption options\n"
151 "GSM A5 Air Interface Encryption\n"
152 "A5/n Algorithm Number\n"
153 "A5/n Algorithm Number\n"
154 "A5/n Algorithm Number\n"
155 "A5/n Algorithm Number\n")
156{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100157 unsigned int i;
158
159 gsmnet->a5_encryption_mask = 0;
160 for (i = 0; i < argc; i++)
161 gsmnet->a5_encryption_mask |= (1 << atoi(argv[i]));
162
163 return CMD_SUCCESS;
164}
165
166DEFUN(cfg_net_authentication,
167 cfg_net_authentication_cmd,
168 "authentication (optional|required)",
169 "Whether to enforce MS authentication in 2G\n"
170 "Allow MS to attach via 2G BSC without authentication\n"
171 "Always do authentication\n")
172{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100173 gsmnet->authentication_required = (argv[0][0] == 'r') ? true : false;
174
175 return CMD_SUCCESS;
176}
177
178DEFUN(cfg_net_rrlp_mode, cfg_net_rrlp_mode_cmd,
179 "rrlp mode (none|ms-based|ms-preferred|ass-preferred)",
180 "Radio Resource Location Protocol\n"
181 "Set the Radio Resource Location Protocol Mode\n"
182 "Don't send RRLP request\n"
183 "Request MS-based location\n"
184 "Request any location, prefer MS-based\n"
185 "Request any location, prefer MS-assisted\n")
186{
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700187 gsmnet->rrlp.mode = msc_rrlp_mode_parse(argv[0]);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100188
189 return CMD_SUCCESS;
190}
191
192DEFUN(cfg_net_mm_info, cfg_net_mm_info_cmd,
193 "mm info (0|1)",
194 "Mobility Management\n"
195 "Send MM INFO after LOC UPD ACCEPT\n"
196 "Disable\n" "Enable\n")
197{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100198 gsmnet->send_mm_info = atoi(argv[0]);
199
200 return CMD_SUCCESS;
201}
202
203DEFUN(cfg_net_timezone,
204 cfg_net_timezone_cmd,
205 "timezone <-19-19> (0|15|30|45)",
206 "Set the Timezone Offset of the network\n"
207 "Timezone offset (hours)\n"
208 "Timezone offset (00 minutes)\n"
209 "Timezone offset (15 minutes)\n"
210 "Timezone offset (30 minutes)\n"
211 "Timezone offset (45 minutes)\n"
212 )
213{
214 struct gsm_network *net = vty->index;
215 int tzhr = atoi(argv[0]);
216 int tzmn = atoi(argv[1]);
217
218 net->tz.hr = tzhr;
219 net->tz.mn = tzmn;
220 net->tz.dst = 0;
221 net->tz.override = 1;
222
223 return CMD_SUCCESS;
224}
225
226DEFUN(cfg_net_timezone_dst,
227 cfg_net_timezone_dst_cmd,
228 "timezone <-19-19> (0|15|30|45) <0-2>",
229 "Set the Timezone Offset of the network\n"
230 "Timezone offset (hours)\n"
231 "Timezone offset (00 minutes)\n"
232 "Timezone offset (15 minutes)\n"
233 "Timezone offset (30 minutes)\n"
234 "Timezone offset (45 minutes)\n"
235 "DST offset (hours)\n"
236 )
237{
238 struct gsm_network *net = vty->index;
239 int tzhr = atoi(argv[0]);
240 int tzmn = atoi(argv[1]);
241 int tzdst = atoi(argv[2]);
242
243 net->tz.hr = tzhr;
244 net->tz.mn = tzmn;
245 net->tz.dst = tzdst;
246 net->tz.override = 1;
247
248 return CMD_SUCCESS;
249}
250
251DEFUN(cfg_net_no_timezone,
252 cfg_net_no_timezone_cmd,
253 "no timezone",
254 NO_STR
255 "Disable network timezone override, use system tz\n")
256{
257 struct gsm_network *net = vty->index;
258
259 net->tz.override = 0;
260
261 return CMD_SUCCESS;
262}
263
264DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
265 "periodic location update <6-1530>",
266 "Periodic Location Updating Interval\n"
267 "Periodic Location Updating Interval\n"
268 "Periodic Location Updating Interval\n"
269 "Periodic Location Updating Interval in Minutes\n")
270{
271 struct gsm_network *net = vty->index;
272
273 net->t3212 = atoi(argv[0]) / 6;
274
275 return CMD_SUCCESS;
276}
277
278DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
279 "no periodic location update",
280 NO_STR
281 "Periodic Location Updating Interval\n"
282 "Periodic Location Updating Interval\n"
283 "Periodic Location Updating Interval\n")
284{
285 struct gsm_network *net = vty->index;
286
287 net->t3212 = 0;
288
289 return CMD_SUCCESS;
290}
291
292static int config_write_net(struct vty *vty)
293{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100294 int i;
295
296 vty_out(vty, "network%s", VTY_NEWLINE);
297 vty_out(vty, " network country code %s%s", osmo_mcc_name(gsmnet->plmn.mcc), VTY_NEWLINE);
298 vty_out(vty, " mobile network code %s%s",
299 osmo_mnc_name(gsmnet->plmn.mnc, gsmnet->plmn.mnc_3_digits), VTY_NEWLINE);
300 vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
301 vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
302 vty_out(vty, " encryption a5");
303 for (i = 0; i < 8; i++) {
304 if (gsmnet->a5_encryption_mask & (1 << i))
305 vty_out(vty, " %u", i);
306 }
307 vty_out(vty, "%s", VTY_NEWLINE);
308 vty_out(vty, " authentication %s%s",
309 gsmnet->authentication_required ? "required" : "optional", VTY_NEWLINE);
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700310 vty_out(vty, " rrlp mode %s%s", msc_rrlp_mode_name(gsmnet->rrlp.mode),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100311 VTY_NEWLINE);
312 vty_out(vty, " mm info %u%s", gsmnet->send_mm_info, VTY_NEWLINE);
313 if (gsmnet->tz.override != 0) {
314 if (gsmnet->tz.dst)
315 vty_out(vty, " timezone %d %d %d%s",
316 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
317 VTY_NEWLINE);
318 else
319 vty_out(vty, " timezone %d %d%s",
320 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
321 }
322 if (gsmnet->t3212 == 0)
323 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
324 else
325 vty_out(vty, " periodic location update %u%s",
326 gsmnet->t3212 * 6, VTY_NEWLINE);
327
328 if (gsmnet->emergency.route_to_msisdn) {
329 vty_out(vty, " emergency-call route-to-msisdn %s%s",
330 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
331 }
332
333 return CMD_SUCCESS;
334}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200335
336static struct cmd_node msc_node = {
337 MSC_NODE,
338 "%s(config-msc)# ",
339 1,
340};
341
342DEFUN(cfg_msc, cfg_msc_cmd,
343 "msc", "Configure MSC options")
344{
345 vty->node = MSC_NODE;
346 return CMD_SUCCESS;
347}
348
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100349#define MNCC_STR "Configure Mobile Network Call Control\n"
350#define MNCC_GUARD_TIMEOUT_STR "Set global guard timer for mncc interface activity\n"
351#define MNCC_GUARD_TIMEOUT_VALUE_STR "guard timer value (sec.)\n"
352
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100353DEFUN(cfg_msc_mncc_internal,
354 cfg_msc_mncc_internal_cmd,
355 "mncc internal",
356 MNCC_STR "Use internal MNCC handler (default; changes need a program restart)\n")
357{
358 gsm_network_set_mncc_sock_path(gsmnet, NULL);
359 return CMD_SUCCESS;
360}
361
362DEFUN(cfg_msc_mncc_external,
363 cfg_msc_mncc_external_cmd,
364 "mncc external MNCC_SOCKET_PATH",
365 MNCC_STR "Use external MNCC handler (changes need a program restart)\n"
366 "File system path to create the MNCC unix domain socket at\n")
367{
368 gsm_network_set_mncc_sock_path(gsmnet, argv[0]);
369 return CMD_SUCCESS;
370}
371
Philipp Maier9ca7b312018-10-10 17:00:49 +0200372DEFUN(cfg_msc_mncc_guard_timeout,
373 cfg_msc_mncc_guard_timeout_cmd,
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100374 "mncc guard-timeout <0-255>",
375 MNCC_STR
376 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR)
Philipp Maier9ca7b312018-10-10 17:00:49 +0200377{
378 gsmnet->mncc_guard_timeout = atoi(argv[0]);
379 return CMD_SUCCESS;
380}
381
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100382ALIAS_DEPRECATED(cfg_msc_mncc_guard_timeout,
383 cfg_msc_deprecated_mncc_guard_timeout_cmd,
384 "mncc-guard-timeout <0-255>",
385 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR);
386
Vadim Yanitskiy64623e12018-11-28 23:05:51 +0700387#define NCSS_STR "Configure call independent Supplementary Services\n"
388
389DEFUN(cfg_msc_ncss_guard_timeout,
390 cfg_msc_ncss_guard_timeout_cmd,
391 "ncss guard-timeout <0-255>",
392 NCSS_STR "Set guard timer for session activity\n"
393 "guard timer value (sec.), or 0 to disable\n")
394{
395 gsmnet->ncss_guard_timeout = atoi(argv[0]);
396 return CMD_SUCCESS;
397}
398
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200399DEFUN(cfg_msc_assign_tmsi, cfg_msc_assign_tmsi_cmd,
400 "assign-tmsi",
401 "Assign TMSI during Location Updating.\n")
402{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200403 gsmnet->vlr->cfg.assign_tmsi = true;
404 return CMD_SUCCESS;
405}
406
407DEFUN(cfg_msc_no_assign_tmsi, cfg_msc_no_assign_tmsi_cmd,
408 "no assign-tmsi",
409 NO_STR "Assign TMSI during Location Updating.\n")
410{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200411 gsmnet->vlr->cfg.assign_tmsi = false;
412 return CMD_SUCCESS;
413}
414
Philipp Maierfbf66102017-04-09 12:32:51 +0200415DEFUN(cfg_msc_cs7_instance_a,
416 cfg_msc_cs7_instance_a_cmd,
417 "cs7-instance-a <0-15>",
418 "Set SS7 to be used by the A-Interface.\n" "SS7 instance reference number\n")
419{
Philipp Maierfbf66102017-04-09 12:32:51 +0200420 gsmnet->a.cs7_instance = atoi(argv[0]);
421 return CMD_SUCCESS;
422}
423
424DEFUN(cfg_msc_cs7_instance_iu,
425 cfg_msc_cs7_instance_iu_cmd,
426 "cs7-instance-iu <0-15>",
427 "Set SS7 to be used by the Iu-Interface.\n" "SS7 instance reference number\n")
428{
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100429#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200430 gsmnet->iu.cs7_instance = atoi(argv[0]);
431 return CMD_SUCCESS;
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100432#else
433 vty_out(vty, "WARNING: 'cs7-instance-iu' without effect: built without Iu support%s",
434 VTY_NEWLINE);
435 return CMD_WARNING;
436#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200437}
438
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100439DEFUN(cfg_msc_auth_tuple_max_reuse_count, cfg_msc_auth_tuple_max_reuse_count_cmd,
440 "auth-tuple-max-reuse-count <-1-2147483647>",
441 "Configure authentication tuple re-use\n"
442 "0 to use each auth tuple at most once (default), >0 to limit re-use, -1 to re-use infinitely (vulnerable!).\n")
443{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100444 gsmnet->vlr->cfg.auth_tuple_max_reuse_count = atoi(argv[0]);
445 return CMD_SUCCESS;
446}
447
448DEFUN(cfg_msc_auth_tuple_reuse_on_error, cfg_msc_auth_tuple_reuse_on_error_cmd,
449 "auth-tuple-reuse-on-error (0|1)",
450 "Configure authentication tuple re-use when HLR is not responsive\n"
Oliver Smithd6e24fd2019-01-09 10:46:43 +0100451 "Never re-use auth tuples beyond auth-tuple-max-reuse-count (default)\n"
452 "If the HLR does not deliver new tuples, do re-use already available old ones.\n")
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100453{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100454 gsmnet->vlr->cfg.auth_reuse_old_sets_on_error = atoi(argv[0]) ? true : false;
455 return CMD_SUCCESS;
456}
457
Oliver Smith0fec28a2018-12-14 10:52:52 +0100458DEFUN(cfg_msc_check_imei_rqd, cfg_msc_check_imei_rqd_cmd,
Oliver Smith03ded912019-05-02 10:40:50 +0200459 "check-imei-rqd (0|1|early)",
Oliver Smith0fec28a2018-12-14 10:52:52 +0100460 "Send each IMEI to the EIR to ask if it is permitted or not. The EIR is implemented as part of OsmoHLR, "
461 "and can optionally save the IMEI in the HLR.\n"
462 "Do not send IMEIs to the EIR\n"
Oliver Smith03ded912019-05-02 10:40:50 +0200463 "Send each IMEI to the EIR\n"
464 "Send each IMEI to the EIR, and do it at the start of the location update. This allows the EIR to receive the"
465 " IMEI, even if the MS would get rejected when the MSC sends the location update request to the HLR.\n")
Oliver Smith0fec28a2018-12-14 10:52:52 +0100466{
Oliver Smith03ded912019-05-02 10:40:50 +0200467 if (strcmp(argv[0], "0") == 0) {
468 gsmnet->vlr->cfg.check_imei_rqd = false;
469 gsmnet->vlr->cfg.retrieve_imeisv_early = false;
470 } else if (strcmp(argv[0], "1") == 0) {
471 gsmnet->vlr->cfg.check_imei_rqd = true;
472 gsmnet->vlr->cfg.retrieve_imeisv_early = false;
473 } else if (strcmp(argv[0], "early") == 0) {
474 gsmnet->vlr->cfg.check_imei_rqd = true;
475 gsmnet->vlr->cfg.retrieve_imeisv_early = true;
476 }
Oliver Smith0fec28a2018-12-14 10:52:52 +0100477 return CMD_SUCCESS;
478}
479
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100480DEFUN(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd,
481 "paging response-timer (default|<1-65535>)",
482 "Configure Paging\n"
483 "Set Paging timeout, the minimum time to pass between (unsuccessful) Pagings sent towards"
484 " BSS or RNC\n"
485 "Set to default timeout (" OSMO_STRINGIFY_VAL(MSC_PAGING_RESPONSE_TIMER_DEFAULT) " seconds)\n"
486 "Set paging timeout in seconds\n")
487{
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100488 if (!strcmp(argv[1], "default"))
489 gsmnet->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
490 else
491 gsmnet->paging_response_timer = atoi(argv[0]);
492 return CMD_SUCCESS;
493}
494
Harald Welte69c54a82018-02-09 20:41:14 +0100495DEFUN(cfg_msc_emergency_msisdn, cfg_msc_emergency_msisdn_cmd,
496 "emergency-call route-to-msisdn MSISDN",
497 "Configure Emergency Call Behaviour\n"
498 "MSISDN to which Emergency Calls are Dispatched\n"
499 "MSISDN (E.164 Phone Number)\n")
500{
Harald Welte69c54a82018-02-09 20:41:14 +0100501 osmo_talloc_replace_string(gsmnet, &gsmnet->emergency.route_to_msisdn, argv[0]);
502
503 return CMD_SUCCESS;
504}
505
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700506/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
507DEFUN(cfg_msc_sms_over_gsup, cfg_msc_sms_over_gsup_cmd,
508 "sms-over-gsup",
509 "Enable routing of SMS messages over GSUP\n")
510{
511 gsmnet->sms_over_gsup = true;
512 return CMD_SUCCESS;
513}
514
515/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
516DEFUN(cfg_msc_no_sms_over_gsup, cfg_msc_no_sms_over_gsup_cmd,
517 "no sms-over-gsup",
518 NO_STR "Disable routing of SMS messages over GSUP\n")
519{
520 gsmnet->sms_over_gsup = false;
521 return CMD_SUCCESS;
522}
523
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100524/* FIXME: This should rather be in the form of
525 * handover-number range 001234xxx
526 * and
527 * handover-number range 001234xxx FIRST LAST
528 */
529DEFUN(cfg_msc_handover_number_range, cfg_msc_handover_number_range_cmd,
530 "handover-number range MSISDN_FIRST MSISDN_LAST",
531 "Configure a range of MSISDN to be assigned to incoming inter-MSC Handovers for call forwarding.\n"
532 "Configure a handover number range\n"
533 "First Handover Number MSISDN\n"
534 "Last Handover Number MSISDN\n")
535{
536 char *endp;
537 uint64_t range_start;
538 uint64_t range_end;
539
540 /* FIXME leading zeros?? */
541
542 errno = 0;
543 range_start = strtoull(argv[0], &endp, 10);
544 if (errno || *endp != '\0') {
545 vty_out(vty, "%% Error parsing handover-number range start: %s%s",
546 argv[0], VTY_NEWLINE);
547 return CMD_WARNING;
548 }
549
550 errno = 0;
551 range_end = strtoull(argv[1], &endp, 10);
552 if (errno || *endp != '\0') {
553 vty_out(vty, "%% Error parsing handover-number range end: %s%s",
554 argv[1], VTY_NEWLINE);
555 return CMD_WARNING;
556 }
557
558 if (range_start > range_end) {
559 vty_out(vty, "%% Error: handover-number range end must be > than the range start, but"
560 " %"PRIu64" > %"PRIu64"%s", range_start, range_end, VTY_NEWLINE);
561 return CMD_WARNING;
562 }
563
564 gsmnet->handover_number.range_start = range_start;
565 gsmnet->handover_number.range_end = range_end;
566 return CMD_SUCCESS;
567}
568
Pau Espin Pedrol4faff9e2019-05-06 19:29:11 +0200569#define OSMUX_STR "RTP multiplexing\n"
570DEFUN(cfg_msc_osmux,
571 cfg_msc_osmux_cmd,
572 "osmux (on|off|only)",
573 OSMUX_STR "Enable OSMUX\n" "Disable OSMUX\n" "Only use OSMUX\n")
574{
575 if (strcmp(argv[0], "off") == 0)
576 gsmnet->use_osmux = OSMUX_USAGE_OFF;
577 else if (strcmp(argv[0], "on") == 0)
578 gsmnet->use_osmux = OSMUX_USAGE_ON;
579 else if (strcmp(argv[0], "only") == 0)
580 gsmnet->use_osmux = OSMUX_USAGE_ONLY;
581
582 return CMD_SUCCESS;
583}
584
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200585static int config_write_msc(struct vty *vty)
586{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200587 vty_out(vty, "msc%s", VTY_NEWLINE);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100588 if (gsmnet->mncc_sock_path)
589 vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE);
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100590 vty_out(vty, " mncc guard-timeout %i%s",
Philipp Maier9ca7b312018-10-10 17:00:49 +0200591 gsmnet->mncc_guard_timeout, VTY_NEWLINE);
Vadim Yanitskiy64623e12018-11-28 23:05:51 +0700592 vty_out(vty, " ncss guard-timeout %i%s",
593 gsmnet->ncss_guard_timeout, VTY_NEWLINE);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200594 vty_out(vty, " %sassign-tmsi%s",
595 gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
596
Philipp Maierfbf66102017-04-09 12:32:51 +0200597 vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
598 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100599#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200600 vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance,
601 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100602#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200603
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100604 if (gsmnet->vlr->cfg.auth_tuple_max_reuse_count)
605 vty_out(vty, " auth-tuple-max-reuse-count %d%s",
606 OSMO_MAX(-1, gsmnet->vlr->cfg.auth_tuple_max_reuse_count),
607 VTY_NEWLINE);
608 if (gsmnet->vlr->cfg.auth_reuse_old_sets_on_error)
609 vty_out(vty, " auth-tuple-reuse-on-error 1%s",
610 VTY_NEWLINE);
611
Oliver Smith03ded912019-05-02 10:40:50 +0200612 if (gsmnet->vlr->cfg.check_imei_rqd) {
613 if (gsmnet->vlr->cfg.retrieve_imeisv_early)
614 vty_out(vty, " check-imei-rqd early%s", VTY_NEWLINE);
615 else
616 vty_out(vty, " check-imei-rqd 1%s", VTY_NEWLINE);
617 }
Oliver Smith0fec28a2018-12-14 10:52:52 +0100618
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100619 if (gsmnet->paging_response_timer != MSC_PAGING_RESPONSE_TIMER_DEFAULT)
620 vty_out(vty, " paging response-timer %u%s", gsmnet->paging_response_timer, VTY_NEWLINE);
621
Harald Welte69c54a82018-02-09 20:41:14 +0100622 if (gsmnet->emergency.route_to_msisdn) {
623 vty_out(vty, " emergency-call route-to-msisdn %s%s",
624 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
625 }
626
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700627 if (gsmnet->sms_over_gsup)
628 vty_out(vty, " sms-over-gsup%s", VTY_NEWLINE);
629
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100630 if (gsmnet->handover_number.range_start || gsmnet->handover_number.range_end)
631 vty_out(vty, " handover-number range %"PRIu64" %"PRIu64"%s",
632 gsmnet->handover_number.range_start, gsmnet->handover_number.range_end,
633 VTY_NEWLINE);
634
Pau Espin Pedrol4faff9e2019-05-06 19:29:11 +0200635 if (gsmnet->use_osmux != OSMUX_USAGE_OFF) {
636 vty_out(vty, " osmux %s%s", gsmnet->use_osmux == OSMUX_USAGE_ON ? "on" : "only",
637 VTY_NEWLINE);
638 }
639
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +0200640 mgcp_client_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200641#ifdef BUILD_IU
Neels Hofmeyr00e82d62017-07-05 15:19:52 +0200642 ranap_iu_vty_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200643#endif
644
Neels Hofmeyr880b9502019-05-09 02:01:55 +0200645 neighbor_ident_vty_write(vty);
646
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200647 return CMD_SUCCESS;
648}
649
Maxc51609a2018-11-09 17:13:00 +0100650DEFUN(show_bsc, show_bsc_cmd,
651 "show bsc", SHOW_STR "BSC\n")
652{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100653 struct ran_peer *rp;
654 llist_for_each_entry(rp, &gsmnet->a.sri->ran_peers, entry) {
655 vty_out(vty, "BSC %s %s%s",
656 osmo_sccp_inst_addr_name(gsmnet->a.sri->sccp, &rp->peer_addr),
657 osmo_fsm_inst_state_name(rp->fi),
658 VTY_NEWLINE);
Maxc51609a2018-11-09 17:13:00 +0100659 }
660
661 return CMD_SUCCESS;
662}
663
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100664/*
665_Subscriber_______________________________________ _LAC_ _RAN___________________ _MSC-A_state_________ _MSC-A_use_
666IMSI-123456789012345:MSISDN-12345:TMSI-0x12345678 1 GERAN-A-4294967295:A5-3 WAIT_CLASSMARK_UPDATE 2=cm_service,trans_cc
667IMSI-123456789012356:MSISDN-234567:TMSI-0x123ABC78 65535 UTRAN-Iu-4294967295 COMMUNICATING 2=cm_service,trans_sms
668IMSI-123456789012367:MSISDN-98712345890:TMSI-0xF.. - EUTRAN-SGs RELEASING 0=none
669IMSI-123456789012378:HONR-12345432101 2 MSC-901-700-423:9876 REMOTE_MSC_A 1=inter_msc
670*/
671static void vty_dump_one_conn(struct vty *vty, const struct msub *msub, int *idx)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100672{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100673 struct msc_a *msc_a = msub_msc_a(msub);
674 struct vlr_subscr *vsub = msub_vsub(msub);
675 char buf[128];
Max45df98b2019-01-17 18:44:33 +0100676
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100677 if (!(*idx))
678 vty_out(vty,
679 "_Subscriber_______________________________________ _LAC_ _RAN___________________"
680 " _MSC-A_state_________ _MSC-A_use_%s",
Max45df98b2019-01-17 18:44:33 +0100681 VTY_NEWLINE);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100682 (*idx)++;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100683
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100684 vty_out(vty, "%50s %5u %23s %20s %d=%s%s",
685 vlr_subscr_short_name(msub_vsub(msub), 50),
686 vsub ? vsub->cgi.lai.lac : 0,
687 msub_ran_conn_name(msub),
688 osmo_fsm_inst_state_name(msc_a->c.fi),
689 osmo_use_count_total(&msc_a->use_count),
690 osmo_use_count_name_buf(buf, sizeof(buf), &msc_a->use_count),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100691 VTY_NEWLINE);
692}
693
694DEFUN(show_msc_conn, show_msc_conn_cmd,
695 "show connection", SHOW_STR "Subscriber Connections\n")
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200696{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100697 struct msub *msub;
698 int idx = 0;
699 llist_for_each_entry(msub, &msub_list, entry) {
700 vty_dump_one_conn(vty, msub, &idx);
701 }
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100702 return CMD_SUCCESS;
703}
704
705static void vty_trans_hdr(struct vty *vty)
706{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100707 if (llist_empty(&gsmnet->trans_list))
708 return;
Max45df98b2019-01-17 18:44:33 +0100709
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100710 vty_out(vty,
711 "_Subscriber_______________________________________ _RAN___________________"
712 " _P__ TI CallRef_ _state_%s",
713 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100714}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200715
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100716static const char *get_trans_proto_str(const struct gsm_trans *trans)
717{
718 static char buf[256];
719
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100720 switch (trans->type) {
721 case TRANS_CC:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100722 snprintf(buf, sizeof(buf), "%s %4u %4u",
723 gsm48_cc_state_name(trans->cc.state),
724 trans->cc.Tcurrent,
725 trans->cc.T308_second);
726 break;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100727 case TRANS_SMS:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100728 snprintf(buf, sizeof(buf), "%s %s",
729 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
730 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
731 break;
732 default:
733 buf[0] = '\0';
734 break;
735 }
736
737 return buf;
738}
739
740static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
741{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100742 vty_out(vty, "%50s %23s %4s %02u %08x %s%s",
743 vlr_subscr_short_name(msc_a_vsub(trans->msc_a), 50),
744 msub_ran_conn_name(trans->msc_a->c.msub),
745 trans_type_name(trans->type),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100746 trans->transaction_id,
747 trans->callref,
Max45df98b2019-01-17 18:44:33 +0100748 get_trans_proto_str(trans),
Max45df98b2019-01-17 18:44:33 +0100749 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100750}
751
752DEFUN(show_msc_transaction, show_msc_transaction_cmd,
753 "show transaction", SHOW_STR "Transactions\n")
754{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100755 struct gsm_trans *trans;
756
757 vty_trans_hdr(vty);
758 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
759 vty_dump_one_trans(vty, trans);
760
761 return CMD_SUCCESS;
762}
763
764static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
765{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100766 struct gsm_trans *trans;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100767 char buf[128];
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100768
769 if (strlen(vsub->name))
770 vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
771 if (strlen(vsub->msisdn))
772 vty_out(vty, " Extension: %s%s", vsub->msisdn,
773 VTY_NEWLINE);
774 vty_out(vty, " LAC: %d/0x%x%s",
Max7d41d872018-12-19 11:48:33 +0100775 vsub->cgi.lai.lac, vsub->cgi.lai.lac, VTY_NEWLINE);
Philipp Maier2a0ac3b2018-12-17 10:03:50 +0100776 vty_out(vty, " RAN: %s%s",
Neels Hofmeyr7814a832018-12-26 00:40:18 +0100777 osmo_rat_type_name(vsub->cs.attached_via_ran), VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100778 vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
779 if (vsub->tmsi != GSM_RESERVED_TMSI)
780 vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
781 VTY_NEWLINE);
782 if (vsub->tmsi_new != GSM_RESERVED_TMSI)
783 vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
784 VTY_NEWLINE);
Philipp Maier6d71ccf2018-12-14 13:30:14 +0100785 if (vsub->imei[0] != '\0')
786 vty_out(vty, " IMEI: %s%s", vsub->imei, VTY_NEWLINE);
787 if (vsub->imeisv[0] != '\0')
788 vty_out(vty, " IMEISV: %s%s", vsub->imeisv, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100789
Philipp Maier89561bc2018-12-14 13:34:25 +0100790 vty_out(vty, " Flags: %s", VTY_NEWLINE);
791 vty_out(vty, " IMSI detached: %s%s",
792 vsub->imsi_detached_flag ? "true" : "false", VTY_NEWLINE);
793 vty_out(vty, " Conf. by radio contact: %s%s",
794 vsub->conf_by_radio_contact_ind ? "true" : "false",
795 VTY_NEWLINE);
796 vty_out(vty, " Subscr. data conf. by HLR: %s%s",
797 vsub->sub_dataconf_by_hlr_ind ? "true" : "false", VTY_NEWLINE);
798 vty_out(vty, " Location conf. in HLR: %s%s",
799 vsub->loc_conf_in_hlr_ind ? "true" : "false", VTY_NEWLINE);
800 vty_out(vty, " Subscriber dormant: %s%s",
801 vsub->dormant_ind ? "true" : "false", VTY_NEWLINE);
802 vty_out(vty, " Received cancel locataion: %s%s",
803 vsub->cancel_loc_rx ? "true" : "false", VTY_NEWLINE);
804 vty_out(vty, " MS not reachable: %s%s",
805 vsub->ms_not_reachable_flag ? "true" : "false", VTY_NEWLINE);
806 vty_out(vty, " LA allowed: %s%s",
807 vsub->la_allowed ? "true" : "false", VTY_NEWLINE);
808
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100809 if (vsub->last_tuple) {
Neels Hofmeyr8b6e5362018-11-30 02:57:33 +0100810 struct vlr_auth_tuple *t = vsub->last_tuple;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100811 vty_out(vty, " A3A8 last tuple (used %d times):%s",
812 t->use_count, VTY_NEWLINE);
813 vty_out(vty, " seq # : %d%s",
814 t->key_seq, VTY_NEWLINE);
815 vty_out(vty, " RAND : %s%s",
816 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
817 VTY_NEWLINE);
818 vty_out(vty, " SRES : %s%s",
819 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
820 VTY_NEWLINE);
821 vty_out(vty, " Kc : %s%s",
822 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
823 VTY_NEWLINE);
824 }
825
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100826 vty_out(vty, " Paging: %s paging for %d requests%s",
Vadim Yanitskiy56e722f2019-05-16 01:53:31 +0700827 vsub->cs.is_paging ? "is" : "not",
828 llist_count(&vsub->cs.requests),
829 VTY_NEWLINE);
Harald Welte0df904d2018-12-03 11:00:04 +0100830
831 /* SGs related */
832 vty_out(vty, " SGs-state: %s%s",
833 osmo_fsm_inst_state_name(vsub->sgs_fsm), VTY_NEWLINE);
Vadim Yanitskiy477cbc62019-02-23 16:59:16 +0700834 if (strlen(vsub->sgs.mme_name))
Harald Welte0df904d2018-12-03 11:00:04 +0100835 vty_out(vty, " SGs-MME: %s%s", vsub->sgs.mme_name, VTY_NEWLINE);
836 else
837 vty_out(vty, " SGs-MME: (none)%s", VTY_NEWLINE);
838
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100839 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 +0100840
841 /* Connection */
842 if (vsub->msc_conn_ref) {
Vadim Yanitskiy23d42d62019-05-16 00:56:30 +0700843 struct msub *msub = msub_for_vsub(vsub);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100844 int idx = 0;
845 if (msub) {
846 vty_dump_one_conn(vty, msub, &idx);
847 }
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100848 }
849
850 /* Transactions */
851 vty_trans_hdr(vty);
852 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
853 if (trans->vsub != vsub)
854 continue;
855 vty_dump_one_trans(vty, trans);
856 }
857}
858
859/* Subscriber */
860DEFUN(show_subscr_cache,
861 show_subscr_cache_cmd,
862 "show subscriber cache",
863 SHOW_STR "Show information about subscribers\n"
864 "Display contents of subscriber cache\n")
865{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100866 struct vlr_subscr *vsub;
867 int count = 0;
868
869 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
870 if (++count > 100) {
871 vty_out(vty, "%% More than %d subscribers in cache,"
872 " stopping here.%s", count-1, VTY_NEWLINE);
873 break;
874 }
875 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
876 subscr_dump_full_vty(vty, vsub);
Harald Welte69c54a82018-02-09 20:41:14 +0100877 }
878
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200879 return CMD_SUCCESS;
880}
881
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100882DEFUN(sms_send_pend,
883 sms_send_pend_cmd,
884 "sms send pending",
885 "SMS related commands\n" "SMS Sending related commands\n"
886 "Send all pending SMS")
887{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100888 struct gsm_sms *sms;
889 unsigned long long sms_id = 0;
890
891 while (1) {
892 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
893 if (!sms)
894 break;
895
896 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700897 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100898
899 sms_id = sms->id + 1;
900 }
901
902 return CMD_SUCCESS;
903}
904
905DEFUN(sms_delete_expired,
906 sms_delete_expired_cmd,
907 "sms delete expired",
908 "SMS related commands\n" "SMS Database related commands\n"
909 "Delete all expired SMS")
910{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100911 struct gsm_sms *sms;
912 unsigned long long sms_id = 0;
913 long long num_deleted = 0;
914
915 while (1) {
916 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
917 if (!sms)
918 break;
919
920 /* Skip SMS which are currently queued for sending. */
921 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
922 continue;
923
924 /* Expiration check is performed by the DB layer. */
925 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
926 num_deleted++;
927
928 sms_id = sms->id + 1;
929 }
930
931 if (num_deleted == 0) {
932 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
933 return CMD_WARNING;
934 }
935
936 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
937 return CMD_SUCCESS;
938}
939
940static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +0200941 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100942 char *str, uint8_t tp_pid)
943{
944 struct gsm_network *net = receiver->vlr->user_ctx;
945 struct gsm_sms *sms;
946
Harald Welte39b55482018-04-09 19:19:33 +0200947 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100948 sms->protocol_id = tp_pid;
949
950 /* store in database for the queue */
951 if (db_sms_store(sms) != 0) {
952 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
953 sms_free(sms);
954 return CMD_WARNING;
955 }
956 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
957
958 sms_free(sms);
959 sms_queue_trigger(net->sms_queue);
960 return CMD_SUCCESS;
961}
962
963static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
964 const char *type,
965 const char *id)
966{
967 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100968 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100969 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100970 return vlr_subscr_find_by_imsi(gsmnet->vlr, id, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100971 else if (!strcmp(type, "tmsi"))
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100972 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id), VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100973
974 return NULL;
975}
976#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
977#define SUBSCR_HELP "Operations on a Subscriber\n" \
978 "Identify subscriber by MSISDN (phone number)\n" \
979 "Legacy alias for 'msisdn'\n" \
980 "Identify subscriber by IMSI\n" \
981 "Identify subscriber by TMSI\n" \
Vadim Yanitskiy3ccd8232019-05-16 01:35:23 +0700982 "Legacy alias for 'imsi'\n" \
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100983 "Identifier for the subscriber\n"
984
985DEFUN(show_subscr,
986 show_subscr_cmd,
987 "show subscriber " SUBSCR_TYPES " ID",
988 SHOW_STR SUBSCR_HELP)
989{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100990 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
991 argv[1]);
992
993 if (!vsub) {
994 vty_out(vty, "%% No subscriber found for %s %s%s",
995 argv[0], argv[1], VTY_NEWLINE);
996 return CMD_WARNING;
997 }
998
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100999 /* In the vty output to the user, exclude this local use count added by vlr_subscr_get() in get_vsub_by_argv().
1000 * This works, because: for get_vsub_by_argv() to succeed, there *must* have been at least one use count before
1001 * 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 +01001002 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001003
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +01001004 subscr_dump_full_vty(vty, vsub);
1005
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001006 return CMD_SUCCESS;
1007}
1008
1009DEFUN(subscriber_create,
1010 subscriber_create_cmd,
1011 "subscriber create imsi ID",
1012 "Operations on a Subscriber\n" \
1013 "Create new subscriber\n" \
1014 "Identify the subscriber by his IMSI\n" \
1015 "Identifier for the subscriber\n")
1016{
1017 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
1018 VTY_NEWLINE);
1019 return CMD_WARNING;
1020}
1021
1022DEFUN(subscriber_send_pending_sms,
1023 subscriber_send_pending_sms_cmd,
1024 "subscriber " SUBSCR_TYPES " ID sms pending-send",
1025 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
1026{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001027 struct vlr_subscr *vsub;
1028 struct gsm_sms *sms;
1029
1030 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1031 if (!vsub) {
1032 vty_out(vty, "%% No subscriber found for %s %s%s",
1033 argv[0], argv[1], VTY_NEWLINE);
1034 return CMD_WARNING;
1035 }
1036
1037 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
1038 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +07001039 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001040
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001041 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001042
1043 return CMD_SUCCESS;
1044}
1045
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001046DEFUN(subscriber_sms_delete_all,
1047 subscriber_sms_delete_all_cmd,
1048 "subscriber " SUBSCR_TYPES " ID sms delete-all",
1049 SUBSCR_HELP "SMS Operations\n"
1050 "Delete all SMS to be delivered to this subscriber"
1051 " -- WARNING: the SMS data for all unsent SMS for this subscriber"
1052 " WILL BE LOST.\n")
1053{
1054 struct vlr_subscr *vsub;
1055
1056 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1057 if (!vsub) {
1058 vty_out(vty, "%% No subscriber found for %s %s%s",
1059 argv[0], argv[1], VTY_NEWLINE);
1060 return CMD_WARNING;
1061 }
1062
1063 db_sms_delete_by_msisdn(vsub->msisdn);
1064
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001065 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001066
1067 return CMD_SUCCESS;
1068}
1069
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001070DEFUN(subscriber_send_sms,
1071 subscriber_send_sms_cmd,
1072 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
1073 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
1074{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001075 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +02001076 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001077 char *str;
1078 int rc;
1079
1080 if (!vsub) {
1081 vty_out(vty, "%% No subscriber found for %s %s%s",
1082 argv[0], argv[1], VTY_NEWLINE);
1083 rc = CMD_WARNING;
1084 goto err;
1085 }
1086
Harald Welte39b55482018-04-09 19:19:33 +02001087 if (!strcmp(argv[2], "msisdn"))
1088 sender_msisdn = argv[3];
1089 else {
1090 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1091 if (!sender) {
1092 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1093 rc = CMD_WARNING;
1094 goto err;
1095 }
1096 sender_msisdn = sender->msisdn;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001097 vlr_subscr_put(sender, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001098 }
1099
1100 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001101 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001102 talloc_free(str);
1103
1104err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001105 if (vsub)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001106 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001107
1108 return rc;
1109}
1110
1111DEFUN(subscriber_silent_sms,
1112 subscriber_silent_sms_cmd,
1113
1114 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
1115 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
1116{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001117 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +02001118 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001119 char *str;
1120 int rc;
1121
1122 if (!vsub) {
1123 vty_out(vty, "%% No subscriber found for %s %s%s",
1124 argv[0], argv[1], VTY_NEWLINE);
1125 rc = CMD_WARNING;
1126 goto err;
1127 }
1128
Harald Welte39b55482018-04-09 19:19:33 +02001129 if (!strcmp(argv[2], "msisdn")) {
1130 sender_msisdn = argv[3];
1131 } else {
1132 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
1133 if (!sender) {
1134 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
1135 rc = CMD_WARNING;
1136 goto err;
1137 }
1138 sender_msisdn = sender->msisdn;
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001139 vlr_subscr_put(sender, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001140 }
1141
1142 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001143 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001144 talloc_free(str);
1145
1146err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001147 if (vsub)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001148 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001149
1150 return rc;
1151}
1152
Sylvain Munaut93558302019-02-14 20:13:08 +01001153#define CHAN_TYPES "(any|tch/f|tch/h|tch/any|sdcch)"
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001154#define CHAN_TYPE_HELP \
1155 "Any channel\n" \
1156 "TCH/F channel\n" \
Sylvain Munaut93558302019-02-14 20:13:08 +01001157 "TCH/H channel\n" \
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001158 "Any TCH channel\n" \
1159 "SDCCH channel\n"
1160
Sylvain Munaut93558302019-02-14 20:13:08 +01001161#define CHAN_MODES "(signalling|speech-hr|speech-fr|speech-efr|speech-amr)"
1162#define CHAN_MODE_HELP \
1163 "Signalling only\n" \
1164 "Speech with HR codec\n" \
1165 "Speech with FR codec\n" \
1166 "Speech with EFR codec\n" \
1167 "Speech with AMR codec\n"
1168
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001169DEFUN(subscriber_silent_call_start,
1170 subscriber_silent_call_start_cmd,
Sylvain Munaut93558302019-02-14 20:13:08 +01001171 "subscriber " SUBSCR_TYPES " ID silent-call start " CHAN_TYPES " " CHAN_MODES " [IP] [<0-65535>]",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001172 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
Sylvain Munaut93558302019-02-14 20:13:08 +01001173 CHAN_TYPE_HELP CHAN_MODE_HELP
1174 "Target IP for RTP traffic (default 127.0.0.1)\n"
1175 "Target port for RTP traffic (default: 4000)\n")
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001176{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001177 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Sylvain Munaut93558302019-02-14 20:13:08 +01001178 struct gsm0808_channel_type ct;
1179 const char *ip;
1180 uint16_t port;
1181 int rc, speech;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001182
1183 if (!vsub) {
1184 vty_out(vty, "%% No subscriber found for %s %s%s",
1185 argv[0], argv[1], VTY_NEWLINE);
1186 return CMD_WARNING;
1187 }
1188
Sylvain Munaut93558302019-02-14 20:13:08 +01001189 memset(&ct, 0x00, sizeof(ct));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001190
Sylvain Munaut93558302019-02-14 20:13:08 +01001191 if (!strcmp(argv[3], "signalling")) {
1192 ct.ch_indctr = GSM0808_CHAN_SIGN;
1193 ct.perm_spch[0] = 0; /* Spare but required */
1194 ct.perm_spch_len = 1;
1195 } else if (!strcmp(argv[3], "speech-hr")) {
1196 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1197 ct.perm_spch[0] = GSM0808_PERM_HR1;
1198 ct.perm_spch_len = 1;
1199 } else if (!strcmp(argv[3], "speech-fr")) {
1200 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1201 ct.perm_spch[0] = GSM0808_PERM_FR1;
1202 ct.perm_spch_len = 1;
1203 } else if (!strcmp(argv[3], "speech-efr")) {
1204 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1205 ct.perm_spch[0] = GSM0808_PERM_FR2;
1206 ct.perm_spch_len = 1;
1207 } else if (!strcmp(argv[3], "speech-amr")) {
1208 ct.ch_indctr = GSM0808_CHAN_SPEECH;
1209 ct.perm_spch[0] = GSM0808_PERM_FR3;
1210 ct.perm_spch[1] = GSM0808_PERM_HR3;
1211 ct.perm_spch_len = 2;
1212 }
1213
1214 speech = ct.ch_indctr == GSM0808_CHAN_SPEECH;
1215
1216 if (!strcmp(argv[2], "tch/f"))
1217 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_BM : GSM0808_SIGN_FULL_BM;
1218 else if (!strcmp(argv[2], "tch/h"))
1219 ct.ch_rate_type = speech ? GSM0808_SPEECH_HALF_LM : GSM0808_SIGN_HALF_LM;
1220 else if (!strcmp(argv[2], "tch/any"))
1221 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_FULL_PREF;
1222 else if (!strcmp(argv[2], "sdcch")) {
1223 if (speech) {
1224 vty_out(vty, "Can't request speech on SDCCH%s", VTY_NEWLINE);
1225 return CMD_WARNING;
1226 }
1227 ct.ch_rate_type = GSM0808_SIGN_SDCCH;
1228 } else
1229 ct.ch_rate_type = speech ? GSM0808_SPEECH_FULL_PREF : GSM0808_SIGN_ANY;
1230
1231 ip = argc >= 5 ? argv[4] : "127.0.0.1";
1232 port = argc >= 6 ? atoi(argv[5]) : 4000;
1233
1234 rc = gsm_silent_call_start(vsub, &ct, ip, port, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001235 switch (rc) {
1236 case -ENODEV:
1237 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
1238 break;
1239 default:
1240 if (rc)
1241 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
1242 else
1243 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
1244 break;
1245 }
1246
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001247 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001248 return rc ? CMD_WARNING : CMD_SUCCESS;
1249}
1250
1251DEFUN(subscriber_silent_call_stop,
1252 subscriber_silent_call_stop_cmd,
1253 "subscriber " SUBSCR_TYPES " ID silent-call stop",
1254 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
1255 CHAN_TYPE_HELP)
1256{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001257 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1258 int rc;
1259
1260 if (!vsub) {
1261 vty_out(vty, "%% No subscriber found for %s %s%s",
1262 argv[0], argv[1], VTY_NEWLINE);
1263 return CMD_WARNING;
1264 }
1265
1266 rc = gsm_silent_call_stop(vsub);
1267 switch (rc) {
1268 case -ENODEV:
1269 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
1270 break;
1271 case -ENOENT:
1272 vty_out(vty, "%% Subscriber has no silent call active%s",
1273 VTY_NEWLINE);
1274 break;
1275 default:
1276 if (rc)
1277 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
1278 else
1279 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
1280 break;
1281 }
1282
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001283 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001284 return rc ? CMD_WARNING : CMD_SUCCESS;
1285}
1286
1287DEFUN(subscriber_ussd_notify,
1288 subscriber_ussd_notify_cmd,
1289 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1290 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1291 "Alerting Level 0\n"
1292 "Alerting Level 1\n"
1293 "Alerting Level 2\n"
1294 "Text of USSD message to send\n")
1295{
1296 char *text;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001297 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001298 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1299 int level;
1300
1301 if (!vsub) {
1302 vty_out(vty, "%% No subscriber found for %s %s%s",
1303 argv[0], argv[1], VTY_NEWLINE);
1304 return CMD_WARNING;
1305 }
1306
1307 level = atoi(argv[2]);
1308 text = argv_concat(argv, argc, 3);
1309 if (!text) {
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001310 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001311 return CMD_WARNING;
1312 }
1313
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001314 msc_a = msc_a_for_vsub(vsub, true);
1315 if (!msc_a || msc_a->c.remote_to) {
1316 vty_out(vty, "%% An active connection and local MSC-A role is required for %s %s%s",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001317 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001318 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001319 talloc_free(text);
1320 return CMD_WARNING;
1321 }
1322
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001323 msc_send_ussd_notify(msc_a, level, text);
Vadim Yanitskiyf20c6b72018-11-29 01:20:58 +07001324 /* FIXME: since we don't allocate a transaction here,
1325 * we use dummy GSM 04.07 transaction ID. */
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001326 msc_send_ussd_release_complete(msc_a, 0x00);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001327
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001328 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001329 talloc_free(text);
1330 return CMD_SUCCESS;
1331}
1332
1333DEFUN(subscriber_paging,
1334 subscriber_paging_cmd,
1335 "subscriber " SUBSCR_TYPES " ID paging",
1336 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1337{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001338 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001339 struct paging_request *req;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001340
1341 if (!vsub) {
1342 vty_out(vty, "%% No subscriber found for %s %s%s",
1343 argv[0], argv[1], VTY_NEWLINE);
1344 return CMD_WARNING;
1345 }
1346
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001347 req = paging_request_start(vsub, PAGING_CAUSE_CALL_CONVERSATIONAL,
1348 NULL, NULL, "manual Paging from VTY");
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001349 if (req)
1350 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1351 else
1352 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1353
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001354 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001355 return req ? CMD_SUCCESS : CMD_WARNING;
1356}
1357
1358static int loop_by_char(uint8_t ch)
1359{
1360 switch (ch) {
1361 case 'a':
1362 return GSM414_LOOP_A;
1363 case 'b':
1364 return GSM414_LOOP_B;
1365 case 'c':
1366 return GSM414_LOOP_C;
1367 case 'd':
1368 return GSM414_LOOP_D;
1369 case 'e':
1370 return GSM414_LOOP_E;
1371 case 'f':
1372 return GSM414_LOOP_F;
1373 case 'i':
1374 return GSM414_LOOP_I;
1375 }
1376 return -1;
1377}
1378
1379DEFUN(subscriber_mstest_close,
1380 subscriber_mstest_close_cmd,
1381 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1382 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1383 "Close a TCH Loop inside the MS\n"
1384 "Loop Type A\n"
1385 "Loop Type B\n"
1386 "Loop Type C\n"
1387 "Loop Type D\n"
1388 "Loop Type E\n"
1389 "Loop Type F\n"
1390 "Loop Type I\n")
1391{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001392 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001393 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1394 const char *loop_str;
1395 int loop_mode;
1396
1397 if (!vsub) {
1398 vty_out(vty, "%% No subscriber found for %s %s%s",
1399 argv[0], argv[1], VTY_NEWLINE);
1400 return CMD_WARNING;
1401 }
1402
1403 loop_str = argv[2];
1404 loop_mode = loop_by_char(loop_str[0]);
1405
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001406 msc_a = msc_a_for_vsub(vsub, true);
1407 if (!msc_a) {
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001408 vty_out(vty, "%% An active connection is required for %s %s%s",
1409 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001410 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001411 return CMD_WARNING;
1412 }
1413
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001414 gsm0414_tx_close_tch_loop_cmd(msc_a, loop_mode);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001415
1416 return CMD_SUCCESS;
1417}
1418
1419DEFUN(subscriber_mstest_open,
1420 subscriber_mstest_open_cmd,
1421 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1422 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1423 "Open a TCH Loop inside the MS\n")
1424{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001425 struct msc_a *msc_a;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001426 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1427
1428 if (!vsub) {
1429 vty_out(vty, "%% No subscriber found for %s %s%s",
1430 argv[0], argv[1], VTY_NEWLINE);
1431 return CMD_WARNING;
1432 }
1433
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001434 msc_a = msc_a_for_vsub(vsub, true);
1435 if (!msc_a) {
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001436 vty_out(vty, "%% An active connection is required for %s %s%s",
1437 argv[0], argv[1], VTY_NEWLINE);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001438 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001439 return CMD_WARNING;
1440 }
1441
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001442 gsm0414_tx_open_loop_cmd(msc_a);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001443
1444 return CMD_SUCCESS;
1445}
1446
1447DEFUN(ena_subscr_expire,
1448 ena_subscr_expire_cmd,
1449 "subscriber " SUBSCR_TYPES " ID expire",
1450 SUBSCR_HELP "Expire the subscriber Now\n")
1451{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001452 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1453 argv[1]);
1454
1455 if (!vsub) {
1456 vty_out(vty, "%% No subscriber found for %s %s%s",
1457 argv[0], argv[1], VTY_NEWLINE);
1458 return CMD_WARNING;
1459 }
1460
1461 if (vlr_subscr_expire(vsub))
1462 vty_out(vty, "%% VLR released subscriber %s%s",
1463 vlr_subscr_name(vsub), VTY_NEWLINE);
1464
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001465 if (osmo_use_count_total(&vsub->use_count) > 1)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001466 vty_out(vty, "%% Subscriber %s is still in use,"
1467 " should be released soon%s",
1468 vlr_subscr_name(vsub), VTY_NEWLINE);
1469
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001470 vlr_subscr_put(vsub, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001471 return CMD_SUCCESS;
1472}
1473
1474static int scall_cbfn(unsigned int subsys, unsigned int signal,
1475 void *handler_data, void *signal_data)
1476{
1477 struct scall_signal_data *sigdata = signal_data;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001478 struct vty *vty = sigdata->vty;
1479
1480 if (!vty_is_active(vty))
1481 return 0;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001482
1483 switch (signal) {
1484 case S_SCALL_SUCCESS:
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001485 vty_out(vty, "%% Silent call success%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001486 break;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001487 case S_SCALL_FAILED:
1488 vty_out(vty, "%% Silent call failed%s", VTY_NEWLINE);
1489 break;
1490 case S_SCALL_DETACHED:
1491 vty_out(vty, "%% Silent call ended%s", VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001492 break;
1493 }
1494 return 0;
1495}
1496
1497DEFUN(show_stats,
1498 show_stats_cmd,
1499 "show statistics",
1500 SHOW_STR "Display network statistics\n")
1501{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001502 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001503 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1504 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1505 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001506 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001507 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001508 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001509 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001510 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001511 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1512 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001513 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001514 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001515 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1516 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001517 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001518 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001519 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1520 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1521 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001522 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001523 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001524 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1525 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001526 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001527 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001528 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1529 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001530 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001531 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001532 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1533 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1534 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1535 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1536 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001537 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001538 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1539 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1540 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1541 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1542 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001543 return CMD_SUCCESS;
1544}
1545
1546DEFUN(show_smsqueue,
1547 show_smsqueue_cmd,
1548 "show sms-queue",
1549 SHOW_STR "Display SMSqueue statistics\n")
1550{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001551 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001552 return CMD_SUCCESS;
1553}
1554
1555DEFUN(smsqueue_trigger,
1556 smsqueue_trigger_cmd,
1557 "sms-queue trigger",
1558 "SMS Queue\n" "Trigger sending messages\n")
1559{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001560 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001561 return CMD_SUCCESS;
1562}
1563
1564DEFUN(smsqueue_max,
1565 smsqueue_max_cmd,
1566 "sms-queue max-pending <1-500>",
1567 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1568{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001569 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001570 return CMD_SUCCESS;
1571}
1572
1573DEFUN(smsqueue_clear,
1574 smsqueue_clear_cmd,
1575 "sms-queue clear",
1576 "SMS Queue\n" "Clear the queue of pending SMS\n")
1577{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001578 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001579 return CMD_SUCCESS;
1580}
1581
1582DEFUN(smsqueue_fail,
1583 smsqueue_fail_cmd,
1584 "sms-queue max-failure <1-500>",
1585 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1586{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001587 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001588 return CMD_SUCCESS;
1589}
1590
1591
1592DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1593 "mncc-int", "Configure internal MNCC handler")
1594{
1595 vty->node = MNCC_INT_NODE;
1596
1597 return CMD_SUCCESS;
1598}
1599
1600static struct cmd_node mncc_int_node = {
1601 MNCC_INT_NODE,
1602 "%s(config-mncc-int)# ",
1603 1,
1604};
1605
1606static const struct value_string tchf_codec_names[] = {
1607 { GSM48_CMODE_SPEECH_V1, "fr" },
1608 { GSM48_CMODE_SPEECH_EFR, "efr" },
1609 { GSM48_CMODE_SPEECH_AMR, "amr" },
1610 { 0, NULL }
1611};
1612
1613static const struct value_string tchh_codec_names[] = {
1614 { GSM48_CMODE_SPEECH_V1, "hr" },
1615 { GSM48_CMODE_SPEECH_AMR, "amr" },
1616 { 0, NULL }
1617};
1618
1619static int config_write_mncc_int(struct vty *vty)
1620{
1621 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1622 vty_out(vty, " default-codec tch-f %s%s",
1623 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1624 VTY_NEWLINE);
1625 vty_out(vty, " default-codec tch-h %s%s",
1626 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1627 VTY_NEWLINE);
1628
1629 return CMD_SUCCESS;
1630}
1631
1632DEFUN(mnccint_def_codec_f,
1633 mnccint_def_codec_f_cmd,
1634 "default-codec tch-f (fr|efr|amr)",
1635 "Set default codec\n" "Codec for TCH/F\n"
1636 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1637{
1638 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1639
1640 return CMD_SUCCESS;
1641}
1642
1643DEFUN(mnccint_def_codec_h,
1644 mnccint_def_codec_h_cmd,
1645 "default-codec tch-h (hr|amr)",
1646 "Set default codec\n" "Codec for TCH/H\n"
1647 "Half-Rate\n" "Adaptive Multi-Rate\n")
1648{
1649 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1650
1651 return CMD_SUCCESS;
1652}
1653
1654
1655DEFUN(logging_fltr_imsi,
1656 logging_fltr_imsi_cmd,
1657 "logging filter imsi IMSI",
1658 LOGGING_STR FILTER_STR
1659 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1660{
1661 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001662 struct log_target *tgt = osmo_log_vty2tgt(vty);
1663 const char *imsi = argv[0];
1664
1665 if (!tgt)
1666 return CMD_WARNING;
1667
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001668 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001669
1670 if (!vlr_subscr) {
1671 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1672 argv[0], VTY_NEWLINE);
1673 return CMD_WARNING;
1674 }
1675
1676 log_set_filter_vlr_subscr(tgt, vlr_subscr);
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01001677 vlr_subscr_put(vlr_subscr, VSUB_USE_VTY);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001678 return CMD_SUCCESS;
1679}
1680
1681static struct cmd_node hlr_node = {
1682 HLR_NODE,
1683 "%s(config-hlr)# ",
1684 1,
1685};
1686
1687DEFUN(cfg_hlr, cfg_hlr_cmd,
1688 "hlr", "Configure connection to the HLR")
1689{
1690 vty->node = HLR_NODE;
1691 return CMD_SUCCESS;
1692}
1693
1694DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1695 "Remote GSUP address of the HLR\n"
1696 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1697{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001698 talloc_free((void*)gsmnet->gsup_server_addr_str);
1699 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1700 return CMD_SUCCESS;
1701}
1702
1703DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1704 "Remote GSUP port of the HLR\n"
1705 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1706{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001707 gsmnet->gsup_server_port = atoi(argv[0]);
1708 return CMD_SUCCESS;
1709}
1710
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001711DEFUN(cfg_hlr_ipa_name,
1712 cfg_hlr_ipa_name_cmd,
1713 "ipa-name NAME",
1714 "Set the IPA name of this MSC\n"
1715 "A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. "
1716 "This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. "
1717 "The default is 'MSC-00-00-00-00-00-00'.\n")
1718{
1719 if (vty->type != VTY_FILE) {
1720 vty_out(vty, "The IPA name cannot be changed at run-time; "
1721 "It can only be set in the configuraton file.%s", VTY_NEWLINE);
1722 return CMD_WARNING;
1723 }
1724
1725 gsmnet->msc_ipa_name = talloc_strdup(gsmnet, argv[0]);
1726 return CMD_SUCCESS;
1727}
1728
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001729static int config_write_hlr(struct vty *vty)
1730{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001731 vty_out(vty, "hlr%s", VTY_NEWLINE);
1732 vty_out(vty, " remote-ip %s%s",
1733 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1734 vty_out(vty, " remote-port %u%s",
1735 gsmnet->gsup_server_port, VTY_NEWLINE);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001736 if (gsmnet->msc_ipa_name)
1737 vty_out(vty, " ipa-name %s%s", gsmnet->msc_ipa_name, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001738 return CMD_SUCCESS;
1739}
1740
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001741void msc_vty_init(struct gsm_network *msc_network)
1742{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001743 OSMO_ASSERT(gsmnet == NULL);
1744 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001745
1746 osmo_stats_vty_add_cmds();
1747
1748 install_element(CONFIG_NODE, &cfg_net_cmd);
1749 install_node(&net_node, config_write_net);
1750 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
1751 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1752 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1753 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
1754 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
1755 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
1756 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
1757 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
1758 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
1759 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
1760 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
1761 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
1762 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001763
1764 install_element(CONFIG_NODE, &cfg_msc_cmd);
1765 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001766 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01001767 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
1768 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02001769 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01001770 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Vadim Yanitskiy64623e12018-11-28 23:05:51 +07001771 install_element(MSC_NODE, &cfg_msc_ncss_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001772 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01001773 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
1774 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Oliver Smith0fec28a2018-12-14 10:52:52 +01001775 install_element(MSC_NODE, &cfg_msc_check_imei_rqd_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001776 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
1777 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01001778 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01001779 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +07001780 install_element(MSC_NODE, &cfg_msc_sms_over_gsup_cmd);
1781 install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd);
Pau Espin Pedrol4faff9e2019-05-06 19:29:11 +02001782 install_element(MSC_NODE, &cfg_msc_osmux_cmd);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001783 install_element(MSC_NODE, &cfg_msc_handover_number_range_cmd);
1784
1785 neighbor_ident_vty_init(msc_network);
Philipp Maierfbf66102017-04-09 12:32:51 +02001786
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02001787 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001788#ifdef BUILD_IU
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001789 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 +02001790#endif
Harald Welte0df904d2018-12-03 11:00:04 +01001791 sgs_vty_init();
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001792
Stefan Sperling617ac802018-02-22 17:58:20 +01001793 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001794
1795 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
1796
1797 install_element_ve(&show_subscr_cmd);
1798 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01001799 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001800 install_element_ve(&show_msc_conn_cmd);
1801 install_element_ve(&show_msc_transaction_cmd);
1802
1803 install_element_ve(&sms_send_pend_cmd);
1804 install_element_ve(&sms_delete_expired_cmd);
1805
1806 install_element_ve(&subscriber_create_cmd);
1807 install_element_ve(&subscriber_send_sms_cmd);
1808 install_element_ve(&subscriber_silent_sms_cmd);
1809 install_element_ve(&subscriber_silent_call_start_cmd);
1810 install_element_ve(&subscriber_silent_call_stop_cmd);
1811 install_element_ve(&subscriber_ussd_notify_cmd);
1812 install_element_ve(&subscriber_mstest_close_cmd);
1813 install_element_ve(&subscriber_mstest_open_cmd);
1814 install_element_ve(&subscriber_paging_cmd);
1815 install_element_ve(&show_stats_cmd);
1816 install_element_ve(&show_smsqueue_cmd);
1817 install_element_ve(&logging_fltr_imsi_cmd);
1818
1819 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
1820 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
1821 install_element(ENABLE_NODE, &smsqueue_max_cmd);
1822 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
1823 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
1824 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
Neels Hofmeyrf90496f2019-03-06 16:19:50 +01001825 install_element(ENABLE_NODE, &subscriber_sms_delete_all_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001826
1827 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1828 install_node(&mncc_int_node, config_write_mncc_int);
1829 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1830 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1831
1832 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
1833
1834 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1835 install_node(&hlr_node, config_write_hlr);
1836 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1837 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr3a3ed9b2018-12-20 00:46:40 +01001838 install_element(HLR_NODE, &cfg_hlr_ipa_name_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001839}