blob: 201d2aa1a0fc44b8f99cc652ff81f6fa5eee13fd [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>
46#include <osmocom/msc/gsm_data.h>
47#include <osmocom/msc/gsm_subscriber.h>
48#include <osmocom/msc/vlr.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010049#include <osmocom/msc/transaction.h>
50#include <osmocom/msc/db.h>
Maxc51609a2018-11-09 17:13:00 +010051#include <osmocom/msc/a_iface.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010052#include <osmocom/msc/sms_queue.h>
53#include <osmocom/msc/silent_call.h>
54#include <osmocom/msc/gsm_04_80.h>
55#include <osmocom/msc/gsm_04_14.h>
56#include <osmocom/msc/signal.h>
57#include <osmocom/msc/mncc_int.h>
Vadim Yanitskiy1b891302018-08-04 01:33:08 +070058#include <osmocom/msc/rrlp.h>
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010059
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010060static struct gsm_network *gsmnet = NULL;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010061
62struct cmd_node net_node = {
63 GSMNET_NODE,
64 "%s(config-net)# ",
65 1,
66};
67
68#define NETWORK_STR "Configure the GSM network\n"
69#define CODE_CMD_STR "Code commands\n"
70#define NAME_CMD_STR "Name Commands\n"
71#define NAME_STR "Name to use\n"
72
73DEFUN(cfg_net,
74 cfg_net_cmd,
75 "network", NETWORK_STR)
76{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +010077 vty->index = gsmnet;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010078 vty->node = GSMNET_NODE;
79
80 return CMD_SUCCESS;
81}
82
83DEFUN(cfg_net_ncc,
84 cfg_net_ncc_cmd,
85 "network country code <1-999>",
86 "Set the GSM network country code\n"
87 "Country commands\n"
88 CODE_CMD_STR
89 "Network Country Code to use\n")
90{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +010091 gsmnet->plmn.mcc = atoi(argv[0]);
92
93 return CMD_SUCCESS;
94}
95
96DEFUN(cfg_net_mnc,
97 cfg_net_mnc_cmd,
98 "mobile network code <0-999>",
99 "Set the GSM mobile network code\n"
100 "Network Commands\n"
101 CODE_CMD_STR
102 "Mobile Network Code to use\n")
103{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100104 uint16_t mnc;
105 bool mnc_3_digits;
106
107 if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
108 vty_out(vty, "%% Error decoding MNC: %s%s", argv[0], VTY_NEWLINE);
109 return CMD_WARNING;
110 }
111
112 gsmnet->plmn.mnc = mnc;
113 gsmnet->plmn.mnc_3_digits = mnc_3_digits;
114
115 return CMD_SUCCESS;
116}
117
118DEFUN(cfg_net_name_short,
119 cfg_net_name_short_cmd,
120 "short name NAME",
121 "Set the short GSM network name\n" NAME_CMD_STR NAME_STR)
122{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100123 osmo_talloc_replace_string(gsmnet, &gsmnet->name_short, argv[0]);
124 return CMD_SUCCESS;
125}
126
127DEFUN(cfg_net_name_long,
128 cfg_net_name_long_cmd,
129 "long name NAME",
130 "Set the long GSM network name\n" NAME_CMD_STR NAME_STR)
131{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100132 osmo_talloc_replace_string(gsmnet, &gsmnet->name_long, argv[0]);
133 return CMD_SUCCESS;
134}
135
136DEFUN(cfg_net_encryption,
137 cfg_net_encryption_cmd,
138 "encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]",
139 "Encryption options\n"
140 "GSM A5 Air Interface Encryption\n"
141 "A5/n Algorithm Number\n"
142 "A5/n Algorithm Number\n"
143 "A5/n Algorithm Number\n"
144 "A5/n Algorithm Number\n")
145{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100146 unsigned int i;
147
148 gsmnet->a5_encryption_mask = 0;
149 for (i = 0; i < argc; i++)
150 gsmnet->a5_encryption_mask |= (1 << atoi(argv[i]));
151
152 return CMD_SUCCESS;
153}
154
155DEFUN(cfg_net_authentication,
156 cfg_net_authentication_cmd,
157 "authentication (optional|required)",
158 "Whether to enforce MS authentication in 2G\n"
159 "Allow MS to attach via 2G BSC without authentication\n"
160 "Always do authentication\n")
161{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100162 gsmnet->authentication_required = (argv[0][0] == 'r') ? true : false;
163
164 return CMD_SUCCESS;
165}
166
167DEFUN(cfg_net_rrlp_mode, cfg_net_rrlp_mode_cmd,
168 "rrlp mode (none|ms-based|ms-preferred|ass-preferred)",
169 "Radio Resource Location Protocol\n"
170 "Set the Radio Resource Location Protocol Mode\n"
171 "Don't send RRLP request\n"
172 "Request MS-based location\n"
173 "Request any location, prefer MS-based\n"
174 "Request any location, prefer MS-assisted\n")
175{
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700176 gsmnet->rrlp.mode = msc_rrlp_mode_parse(argv[0]);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100177
178 return CMD_SUCCESS;
179}
180
181DEFUN(cfg_net_mm_info, cfg_net_mm_info_cmd,
182 "mm info (0|1)",
183 "Mobility Management\n"
184 "Send MM INFO after LOC UPD ACCEPT\n"
185 "Disable\n" "Enable\n")
186{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100187 gsmnet->send_mm_info = atoi(argv[0]);
188
189 return CMD_SUCCESS;
190}
191
192DEFUN(cfg_net_timezone,
193 cfg_net_timezone_cmd,
194 "timezone <-19-19> (0|15|30|45)",
195 "Set the Timezone Offset of the network\n"
196 "Timezone offset (hours)\n"
197 "Timezone offset (00 minutes)\n"
198 "Timezone offset (15 minutes)\n"
199 "Timezone offset (30 minutes)\n"
200 "Timezone offset (45 minutes)\n"
201 )
202{
203 struct gsm_network *net = vty->index;
204 int tzhr = atoi(argv[0]);
205 int tzmn = atoi(argv[1]);
206
207 net->tz.hr = tzhr;
208 net->tz.mn = tzmn;
209 net->tz.dst = 0;
210 net->tz.override = 1;
211
212 return CMD_SUCCESS;
213}
214
215DEFUN(cfg_net_timezone_dst,
216 cfg_net_timezone_dst_cmd,
217 "timezone <-19-19> (0|15|30|45) <0-2>",
218 "Set the Timezone Offset of the network\n"
219 "Timezone offset (hours)\n"
220 "Timezone offset (00 minutes)\n"
221 "Timezone offset (15 minutes)\n"
222 "Timezone offset (30 minutes)\n"
223 "Timezone offset (45 minutes)\n"
224 "DST offset (hours)\n"
225 )
226{
227 struct gsm_network *net = vty->index;
228 int tzhr = atoi(argv[0]);
229 int tzmn = atoi(argv[1]);
230 int tzdst = atoi(argv[2]);
231
232 net->tz.hr = tzhr;
233 net->tz.mn = tzmn;
234 net->tz.dst = tzdst;
235 net->tz.override = 1;
236
237 return CMD_SUCCESS;
238}
239
240DEFUN(cfg_net_no_timezone,
241 cfg_net_no_timezone_cmd,
242 "no timezone",
243 NO_STR
244 "Disable network timezone override, use system tz\n")
245{
246 struct gsm_network *net = vty->index;
247
248 net->tz.override = 0;
249
250 return CMD_SUCCESS;
251}
252
253DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
254 "periodic location update <6-1530>",
255 "Periodic Location Updating Interval\n"
256 "Periodic Location Updating Interval\n"
257 "Periodic Location Updating Interval\n"
258 "Periodic Location Updating Interval in Minutes\n")
259{
260 struct gsm_network *net = vty->index;
261
262 net->t3212 = atoi(argv[0]) / 6;
263
264 return CMD_SUCCESS;
265}
266
267DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
268 "no periodic location update",
269 NO_STR
270 "Periodic Location Updating Interval\n"
271 "Periodic Location Updating Interval\n"
272 "Periodic Location Updating Interval\n")
273{
274 struct gsm_network *net = vty->index;
275
276 net->t3212 = 0;
277
278 return CMD_SUCCESS;
279}
280
281static int config_write_net(struct vty *vty)
282{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100283 int i;
284
285 vty_out(vty, "network%s", VTY_NEWLINE);
286 vty_out(vty, " network country code %s%s", osmo_mcc_name(gsmnet->plmn.mcc), VTY_NEWLINE);
287 vty_out(vty, " mobile network code %s%s",
288 osmo_mnc_name(gsmnet->plmn.mnc, gsmnet->plmn.mnc_3_digits), VTY_NEWLINE);
289 vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
290 vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
291 vty_out(vty, " encryption a5");
292 for (i = 0; i < 8; i++) {
293 if (gsmnet->a5_encryption_mask & (1 << i))
294 vty_out(vty, " %u", i);
295 }
296 vty_out(vty, "%s", VTY_NEWLINE);
297 vty_out(vty, " authentication %s%s",
298 gsmnet->authentication_required ? "required" : "optional", VTY_NEWLINE);
Vadim Yanitskiy1b891302018-08-04 01:33:08 +0700299 vty_out(vty, " rrlp mode %s%s", msc_rrlp_mode_name(gsmnet->rrlp.mode),
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100300 VTY_NEWLINE);
301 vty_out(vty, " mm info %u%s", gsmnet->send_mm_info, VTY_NEWLINE);
302 if (gsmnet->tz.override != 0) {
303 if (gsmnet->tz.dst)
304 vty_out(vty, " timezone %d %d %d%s",
305 gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
306 VTY_NEWLINE);
307 else
308 vty_out(vty, " timezone %d %d%s",
309 gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
310 }
311 if (gsmnet->t3212 == 0)
312 vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
313 else
314 vty_out(vty, " periodic location update %u%s",
315 gsmnet->t3212 * 6, VTY_NEWLINE);
316
317 if (gsmnet->emergency.route_to_msisdn) {
318 vty_out(vty, " emergency-call route-to-msisdn %s%s",
319 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
320 }
321
322 return CMD_SUCCESS;
323}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200324
325static struct cmd_node msc_node = {
326 MSC_NODE,
327 "%s(config-msc)# ",
328 1,
329};
330
331DEFUN(cfg_msc, cfg_msc_cmd,
332 "msc", "Configure MSC options")
333{
334 vty->node = MSC_NODE;
335 return CMD_SUCCESS;
336}
337
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100338#define MNCC_STR "Configure Mobile Network Call Control\n"
339#define MNCC_GUARD_TIMEOUT_STR "Set global guard timer for mncc interface activity\n"
340#define MNCC_GUARD_TIMEOUT_VALUE_STR "guard timer value (sec.)\n"
341
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100342DEFUN(cfg_msc_mncc_internal,
343 cfg_msc_mncc_internal_cmd,
344 "mncc internal",
345 MNCC_STR "Use internal MNCC handler (default; changes need a program restart)\n")
346{
347 gsm_network_set_mncc_sock_path(gsmnet, NULL);
348 return CMD_SUCCESS;
349}
350
351DEFUN(cfg_msc_mncc_external,
352 cfg_msc_mncc_external_cmd,
353 "mncc external MNCC_SOCKET_PATH",
354 MNCC_STR "Use external MNCC handler (changes need a program restart)\n"
355 "File system path to create the MNCC unix domain socket at\n")
356{
357 gsm_network_set_mncc_sock_path(gsmnet, argv[0]);
358 return CMD_SUCCESS;
359}
360
Philipp Maier9ca7b312018-10-10 17:00:49 +0200361DEFUN(cfg_msc_mncc_guard_timeout,
362 cfg_msc_mncc_guard_timeout_cmd,
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100363 "mncc guard-timeout <0-255>",
364 MNCC_STR
365 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR)
Philipp Maier9ca7b312018-10-10 17:00:49 +0200366{
367 gsmnet->mncc_guard_timeout = atoi(argv[0]);
368 return CMD_SUCCESS;
369}
370
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100371ALIAS_DEPRECATED(cfg_msc_mncc_guard_timeout,
372 cfg_msc_deprecated_mncc_guard_timeout_cmd,
373 "mncc-guard-timeout <0-255>",
374 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR);
375
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200376DEFUN(cfg_msc_assign_tmsi, cfg_msc_assign_tmsi_cmd,
377 "assign-tmsi",
378 "Assign TMSI during Location Updating.\n")
379{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200380 gsmnet->vlr->cfg.assign_tmsi = true;
381 return CMD_SUCCESS;
382}
383
384DEFUN(cfg_msc_no_assign_tmsi, cfg_msc_no_assign_tmsi_cmd,
385 "no assign-tmsi",
386 NO_STR "Assign TMSI during Location Updating.\n")
387{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200388 gsmnet->vlr->cfg.assign_tmsi = false;
389 return CMD_SUCCESS;
390}
391
Philipp Maierfbf66102017-04-09 12:32:51 +0200392DEFUN(cfg_msc_cs7_instance_a,
393 cfg_msc_cs7_instance_a_cmd,
394 "cs7-instance-a <0-15>",
395 "Set SS7 to be used by the A-Interface.\n" "SS7 instance reference number\n")
396{
Philipp Maierfbf66102017-04-09 12:32:51 +0200397 gsmnet->a.cs7_instance = atoi(argv[0]);
398 return CMD_SUCCESS;
399}
400
401DEFUN(cfg_msc_cs7_instance_iu,
402 cfg_msc_cs7_instance_iu_cmd,
403 "cs7-instance-iu <0-15>",
404 "Set SS7 to be used by the Iu-Interface.\n" "SS7 instance reference number\n")
405{
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100406#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200407 gsmnet->iu.cs7_instance = atoi(argv[0]);
408 return CMD_SUCCESS;
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100409#else
410 vty_out(vty, "WARNING: 'cs7-instance-iu' without effect: built without Iu support%s",
411 VTY_NEWLINE);
412 return CMD_WARNING;
413#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200414}
415
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100416DEFUN(cfg_msc_auth_tuple_max_reuse_count, cfg_msc_auth_tuple_max_reuse_count_cmd,
417 "auth-tuple-max-reuse-count <-1-2147483647>",
418 "Configure authentication tuple re-use\n"
419 "0 to use each auth tuple at most once (default), >0 to limit re-use, -1 to re-use infinitely (vulnerable!).\n")
420{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100421 gsmnet->vlr->cfg.auth_tuple_max_reuse_count = atoi(argv[0]);
422 return CMD_SUCCESS;
423}
424
425DEFUN(cfg_msc_auth_tuple_reuse_on_error, cfg_msc_auth_tuple_reuse_on_error_cmd,
426 "auth-tuple-reuse-on-error (0|1)",
427 "Configure authentication tuple re-use when HLR is not responsive\n"
428 "0 = never re-use auth tuples beyond auth-tuple-max-reuse-count (default)\n"
429 "1 = if the HLR does not deliver new tuples, do re-use already available old ones.\n")
430{
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100431 gsmnet->vlr->cfg.auth_reuse_old_sets_on_error = atoi(argv[0]) ? true : false;
432 return CMD_SUCCESS;
433}
434
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100435DEFUN(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd,
436 "paging response-timer (default|<1-65535>)",
437 "Configure Paging\n"
438 "Set Paging timeout, the minimum time to pass between (unsuccessful) Pagings sent towards"
439 " BSS or RNC\n"
440 "Set to default timeout (" OSMO_STRINGIFY_VAL(MSC_PAGING_RESPONSE_TIMER_DEFAULT) " seconds)\n"
441 "Set paging timeout in seconds\n")
442{
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100443 if (!strcmp(argv[1], "default"))
444 gsmnet->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
445 else
446 gsmnet->paging_response_timer = atoi(argv[0]);
447 return CMD_SUCCESS;
448}
449
Harald Welte69c54a82018-02-09 20:41:14 +0100450DEFUN(cfg_msc_emergency_msisdn, cfg_msc_emergency_msisdn_cmd,
451 "emergency-call route-to-msisdn MSISDN",
452 "Configure Emergency Call Behaviour\n"
453 "MSISDN to which Emergency Calls are Dispatched\n"
454 "MSISDN (E.164 Phone Number)\n")
455{
Harald Welte69c54a82018-02-09 20:41:14 +0100456 osmo_talloc_replace_string(gsmnet, &gsmnet->emergency.route_to_msisdn, argv[0]);
457
458 return CMD_SUCCESS;
459}
460
Stefan Sperlingafa030d2018-12-06 12:06:59 +0100461DEFUN(cfg_msc_ipa_name,
462 cfg_msc_ipa_name_cmd,
463 "ipa-name NAME",
464 "Set the IPA name of this MSC\n"
465 "A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. "
466 "This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. "
467 "The default is 'MSC-00-00-00-00-00-00'.\n")
468{
Stefan Sperlingb361ea72018-12-18 18:57:41 +0100469 if (vty->type != VTY_FILE) {
Stefan Sperling1051c422018-12-13 10:16:49 +0100470 vty_out(vty, "The IPA name cannot be changed at run-time; "
471 "It can only be set in the configuraton file.%s", VTY_NEWLINE);
472 return CMD_WARNING;
473 }
474
Stefan Sperlingafa030d2018-12-06 12:06:59 +0100475 gsmnet->msc_ipa_name = talloc_strdup(gsmnet, argv[0]);
476 return CMD_SUCCESS;
477}
478
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700479/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
480DEFUN(cfg_msc_sms_over_gsup, cfg_msc_sms_over_gsup_cmd,
481 "sms-over-gsup",
482 "Enable routing of SMS messages over GSUP\n")
483{
484 gsmnet->sms_over_gsup = true;
485 return CMD_SUCCESS;
486}
487
488/* TODO: to be deprecated as soon as we rip SMS handling out (see OS#3587) */
489DEFUN(cfg_msc_no_sms_over_gsup, cfg_msc_no_sms_over_gsup_cmd,
490 "no sms-over-gsup",
491 NO_STR "Disable routing of SMS messages over GSUP\n")
492{
493 gsmnet->sms_over_gsup = false;
494 return CMD_SUCCESS;
495}
496
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200497static int config_write_msc(struct vty *vty)
498{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200499 vty_out(vty, "msc%s", VTY_NEWLINE);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100500 if (gsmnet->mncc_sock_path)
501 vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE);
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100502 vty_out(vty, " mncc guard-timeout %i%s",
Philipp Maier9ca7b312018-10-10 17:00:49 +0200503 gsmnet->mncc_guard_timeout, VTY_NEWLINE);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200504 vty_out(vty, " %sassign-tmsi%s",
505 gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
506
Philipp Maierfbf66102017-04-09 12:32:51 +0200507 vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
508 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100509#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200510 vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance,
511 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100512#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200513
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100514 if (gsmnet->vlr->cfg.auth_tuple_max_reuse_count)
515 vty_out(vty, " auth-tuple-max-reuse-count %d%s",
516 OSMO_MAX(-1, gsmnet->vlr->cfg.auth_tuple_max_reuse_count),
517 VTY_NEWLINE);
518 if (gsmnet->vlr->cfg.auth_reuse_old_sets_on_error)
519 vty_out(vty, " auth-tuple-reuse-on-error 1%s",
520 VTY_NEWLINE);
521
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100522 if (gsmnet->paging_response_timer != MSC_PAGING_RESPONSE_TIMER_DEFAULT)
523 vty_out(vty, " paging response-timer %u%s", gsmnet->paging_response_timer, VTY_NEWLINE);
524
Harald Welte69c54a82018-02-09 20:41:14 +0100525 if (gsmnet->emergency.route_to_msisdn) {
526 vty_out(vty, " emergency-call route-to-msisdn %s%s",
527 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
528 }
529
Stefan Sperlingafa030d2018-12-06 12:06:59 +0100530 if (gsmnet->msc_ipa_name)
531 vty_out(vty, " ipa-name %s%s", gsmnet->msc_ipa_name, VTY_NEWLINE);
532
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +0700533 if (gsmnet->sms_over_gsup)
534 vty_out(vty, " sms-over-gsup%s", VTY_NEWLINE);
535
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +0200536 mgcp_client_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200537#ifdef BUILD_IU
Neels Hofmeyr00e82d62017-07-05 15:19:52 +0200538 ranap_iu_vty_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200539#endif
540
541 return CMD_SUCCESS;
542}
543
Maxc51609a2018-11-09 17:13:00 +0100544DEFUN(show_bsc, show_bsc_cmd,
545 "show bsc", SHOW_STR "BSC\n")
546{
547 struct bsc_context *bsc_ctx;
548 struct osmo_ss7_instance *ss7 = osmo_ss7_instance_find(gsmnet->a.cs7_instance);
549
550 llist_for_each_entry(bsc_ctx, &gsmnet->a.bscs, list) {
551 vty_out(vty, "BSC %s%s", osmo_sccp_addr_name(ss7, &bsc_ctx->bsc_addr), VTY_NEWLINE);
552 }
553
554 return CMD_SUCCESS;
555}
556
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100557static void vty_conn_hdr(struct vty *vty)
558{
559 vty_out(vty, "--ConnId ------------Subscriber RAN --LAC Use --Tokens C A5 State%s",
560 VTY_NEWLINE);
561}
562
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100563static void vty_dump_one_conn(struct vty *vty, const struct ran_conn *conn)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100564{
565 vty_out(vty, "%08x %22s %3s %5u %3u %08x %c /%1u %27s %s",
566 conn->a.conn_id,
567 conn->vsub ? vlr_subscr_name(conn->vsub) : "-",
568 conn->via_ran == RAN_UTRAN_IU ? "Iu" : "A",
569 conn->lac,
570 conn->use_count,
571 conn->use_tokens,
572 conn->received_cm_service_request ? 'C' : '-',
Neels Hofmeyrf41658d2018-11-30 04:35:50 +0100573 conn->geran_encr.alg_id,
Neels Hofmeyr4d3a66b2018-03-31 18:45:59 +0200574 conn->fi ? osmo_fsm_inst_state_name(conn->fi) : "-",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100575 VTY_NEWLINE);
576}
577
578DEFUN(show_msc_conn, show_msc_conn_cmd,
579 "show connection", SHOW_STR "Subscriber Connections\n")
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200580{
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100581 struct ran_conn *conn;
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200582
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100583 vty_conn_hdr(vty);
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100584 llist_for_each_entry(conn, &gsmnet->ran_conns, entry)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100585 vty_dump_one_conn(vty, conn);
586
587 return CMD_SUCCESS;
588}
589
590static void vty_trans_hdr(struct vty *vty)
591{
592 vty_out(vty, "------------Subscriber --ConnId -P TI -CallRef Proto%s",
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200593 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100594}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200595
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100596static const char *get_trans_proto_str(const struct gsm_trans *trans)
597{
598 static char buf[256];
599
600 switch (trans->protocol) {
601 case GSM48_PDISC_CC:
602 snprintf(buf, sizeof(buf), "%s %4u %4u",
603 gsm48_cc_state_name(trans->cc.state),
604 trans->cc.Tcurrent,
605 trans->cc.T308_second);
606 break;
607 case GSM48_PDISC_SMS:
608 snprintf(buf, sizeof(buf), "%s %s",
609 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
610 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
611 break;
612 default:
613 buf[0] = '\0';
614 break;
615 }
616
617 return buf;
618}
619
620static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
621{
622 vty_out(vty, "%22s %08x %s %02u %08x %s%s",
623 trans->vsub ? vlr_subscr_name(trans->vsub) : "-",
624 trans->conn ? trans->conn->a.conn_id : 0,
625 gsm48_pdisc_name(trans->protocol),
626 trans->transaction_id,
627 trans->callref,
628 get_trans_proto_str(trans), VTY_NEWLINE);
629}
630
631DEFUN(show_msc_transaction, show_msc_transaction_cmd,
632 "show transaction", SHOW_STR "Transactions\n")
633{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100634 struct gsm_trans *trans;
635
636 vty_trans_hdr(vty);
637 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
638 vty_dump_one_trans(vty, trans);
639
640 return CMD_SUCCESS;
641}
642
643static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
644{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100645 struct gsm_trans *trans;
646 int reqs;
647 struct llist_head *entry;
648
649 if (strlen(vsub->name))
650 vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
651 if (strlen(vsub->msisdn))
652 vty_out(vty, " Extension: %s%s", vsub->msisdn,
653 VTY_NEWLINE);
654 vty_out(vty, " LAC: %d/0x%x%s",
Max7d41d872018-12-19 11:48:33 +0100655 vsub->cgi.lai.lac, vsub->cgi.lai.lac, VTY_NEWLINE);
Philipp Maier2a0ac3b2018-12-17 10:03:50 +0100656 vty_out(vty, " RAN: %s%s",
657 ran_type_name(vsub->cs.attached_via_ran), VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100658 vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
659 if (vsub->tmsi != GSM_RESERVED_TMSI)
660 vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
661 VTY_NEWLINE);
662 if (vsub->tmsi_new != GSM_RESERVED_TMSI)
663 vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
664 VTY_NEWLINE);
Philipp Maier6d71ccf2018-12-14 13:30:14 +0100665 if (vsub->imei[0] != '\0')
666 vty_out(vty, " IMEI: %s%s", vsub->imei, VTY_NEWLINE);
667 if (vsub->imeisv[0] != '\0')
668 vty_out(vty, " IMEISV: %s%s", vsub->imeisv, VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100669
Philipp Maier89561bc2018-12-14 13:34:25 +0100670 vty_out(vty, " Flags: %s", VTY_NEWLINE);
671 vty_out(vty, " IMSI detached: %s%s",
672 vsub->imsi_detached_flag ? "true" : "false", VTY_NEWLINE);
673 vty_out(vty, " Conf. by radio contact: %s%s",
674 vsub->conf_by_radio_contact_ind ? "true" : "false",
675 VTY_NEWLINE);
676 vty_out(vty, " Subscr. data conf. by HLR: %s%s",
677 vsub->sub_dataconf_by_hlr_ind ? "true" : "false", VTY_NEWLINE);
678 vty_out(vty, " Location conf. in HLR: %s%s",
679 vsub->loc_conf_in_hlr_ind ? "true" : "false", VTY_NEWLINE);
680 vty_out(vty, " Subscriber dormant: %s%s",
681 vsub->dormant_ind ? "true" : "false", VTY_NEWLINE);
682 vty_out(vty, " Received cancel locataion: %s%s",
683 vsub->cancel_loc_rx ? "true" : "false", VTY_NEWLINE);
684 vty_out(vty, " MS not reachable: %s%s",
685 vsub->ms_not_reachable_flag ? "true" : "false", VTY_NEWLINE);
686 vty_out(vty, " LA allowed: %s%s",
687 vsub->la_allowed ? "true" : "false", VTY_NEWLINE);
688
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100689#if 0
690 /* TODO: add this to vlr_subscr? */
691 if (vsub->auth_info.auth_algo != AUTH_ALGO_NONE) {
692 struct gsm_auth_info *i = &vsub->auth_info;
693 vty_out(vty, " A3A8 algorithm id: %d%s",
694 i->auth_algo, VTY_NEWLINE);
695 vty_out(vty, " A3A8 Ki: %s%s",
696 osmo_hexdump(i->a3a8_ki, i->a3a8_ki_len),
697 VTY_NEWLINE);
698 }
699#endif
700
701 if (vsub->last_tuple) {
Neels Hofmeyr8b6e5362018-11-30 02:57:33 +0100702 struct vlr_auth_tuple *t = vsub->last_tuple;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100703 vty_out(vty, " A3A8 last tuple (used %d times):%s",
704 t->use_count, VTY_NEWLINE);
705 vty_out(vty, " seq # : %d%s",
706 t->key_seq, VTY_NEWLINE);
707 vty_out(vty, " RAND : %s%s",
708 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
709 VTY_NEWLINE);
710 vty_out(vty, " SRES : %s%s",
711 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
712 VTY_NEWLINE);
713 vty_out(vty, " Kc : %s%s",
714 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
715 VTY_NEWLINE);
716 }
717
718 reqs = 0;
719 llist_for_each(entry, &vsub->cs.requests)
720 reqs += 1;
721 vty_out(vty, " Paging: %s paging for %d requests%s",
722 vsub->cs.is_paging ? "is" : "not", reqs, VTY_NEWLINE);
723 vty_out(vty, " Use count: %u%s", vsub->use_count, VTY_NEWLINE);
724
725 /* Connection */
726 if (vsub->msc_conn_ref) {
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100727 struct ran_conn *conn = vsub->msc_conn_ref;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100728 vty_conn_hdr(vty);
729 vty_dump_one_conn(vty, conn);
730 }
731
732 /* Transactions */
733 vty_trans_hdr(vty);
734 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
735 if (trans->vsub != vsub)
736 continue;
737 vty_dump_one_trans(vty, trans);
738 }
739}
740
741/* Subscriber */
742DEFUN(show_subscr_cache,
743 show_subscr_cache_cmd,
744 "show subscriber cache",
745 SHOW_STR "Show information about subscribers\n"
746 "Display contents of subscriber cache\n")
747{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100748 struct vlr_subscr *vsub;
749 int count = 0;
750
751 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
752 if (++count > 100) {
753 vty_out(vty, "%% More than %d subscribers in cache,"
754 " stopping here.%s", count-1, VTY_NEWLINE);
755 break;
756 }
757 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
758 subscr_dump_full_vty(vty, vsub);
Harald Welte69c54a82018-02-09 20:41:14 +0100759 }
760
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200761 return CMD_SUCCESS;
762}
763
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100764DEFUN(sms_send_pend,
765 sms_send_pend_cmd,
766 "sms send pending",
767 "SMS related commands\n" "SMS Sending related commands\n"
768 "Send all pending SMS")
769{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100770 struct gsm_sms *sms;
771 unsigned long long sms_id = 0;
772
773 while (1) {
774 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
775 if (!sms)
776 break;
777
778 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700779 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100780
781 sms_id = sms->id + 1;
782 }
783
784 return CMD_SUCCESS;
785}
786
787DEFUN(sms_delete_expired,
788 sms_delete_expired_cmd,
789 "sms delete expired",
790 "SMS related commands\n" "SMS Database related commands\n"
791 "Delete all expired SMS")
792{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100793 struct gsm_sms *sms;
794 unsigned long long sms_id = 0;
795 long long num_deleted = 0;
796
797 while (1) {
798 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
799 if (!sms)
800 break;
801
802 /* Skip SMS which are currently queued for sending. */
803 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
804 continue;
805
806 /* Expiration check is performed by the DB layer. */
807 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
808 num_deleted++;
809
810 sms_id = sms->id + 1;
811 }
812
813 if (num_deleted == 0) {
814 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
815 return CMD_WARNING;
816 }
817
818 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
819 return CMD_SUCCESS;
820}
821
822static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +0200823 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100824 char *str, uint8_t tp_pid)
825{
826 struct gsm_network *net = receiver->vlr->user_ctx;
827 struct gsm_sms *sms;
828
Harald Welte39b55482018-04-09 19:19:33 +0200829 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100830 sms->protocol_id = tp_pid;
831
832 /* store in database for the queue */
833 if (db_sms_store(sms) != 0) {
834 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
835 sms_free(sms);
836 return CMD_WARNING;
837 }
838 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
839
840 sms_free(sms);
841 sms_queue_trigger(net->sms_queue);
842 return CMD_SUCCESS;
843}
844
845static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
846 const char *type,
847 const char *id)
848{
849 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
850 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id);
851 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
852 return vlr_subscr_find_by_imsi(gsmnet->vlr, id);
853 else if (!strcmp(type, "tmsi"))
854 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id));
855
856 return NULL;
857}
858#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
859#define SUBSCR_HELP "Operations on a Subscriber\n" \
860 "Identify subscriber by MSISDN (phone number)\n" \
861 "Legacy alias for 'msisdn'\n" \
862 "Identify subscriber by IMSI\n" \
863 "Identify subscriber by TMSI\n" \
864 "Identify subscriber by database ID\n" \
865 "Identifier for the subscriber\n"
866
867DEFUN(show_subscr,
868 show_subscr_cmd,
869 "show subscriber " SUBSCR_TYPES " ID",
870 SHOW_STR SUBSCR_HELP)
871{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100872 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
873 argv[1]);
874
875 if (!vsub) {
876 vty_out(vty, "%% No subscriber found for %s %s%s",
877 argv[0], argv[1], VTY_NEWLINE);
878 return CMD_WARNING;
879 }
880
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100881 /* In the vty output to the user, exclude this local use count added by vlr_subscr_get() in get_vsub_by_argv().
882 * This works, because: for get_vsub_by_argv() to succeed, there *must* have been at least one use count before
883 * this, and since this is not multi-threaded, this vlr_subscr_put() cannot possibly reach a count of 0. */
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100884 vlr_subscr_put(vsub);
885
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100886 subscr_dump_full_vty(vty, vsub);
887
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100888 return CMD_SUCCESS;
889}
890
891DEFUN(subscriber_create,
892 subscriber_create_cmd,
893 "subscriber create imsi ID",
894 "Operations on a Subscriber\n" \
895 "Create new subscriber\n" \
896 "Identify the subscriber by his IMSI\n" \
897 "Identifier for the subscriber\n")
898{
899 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
900 VTY_NEWLINE);
901 return CMD_WARNING;
902}
903
904DEFUN(subscriber_send_pending_sms,
905 subscriber_send_pending_sms_cmd,
906 "subscriber " SUBSCR_TYPES " ID sms pending-send",
907 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
908{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100909 struct vlr_subscr *vsub;
910 struct gsm_sms *sms;
911
912 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
913 if (!vsub) {
914 vty_out(vty, "%% No subscriber found for %s %s%s",
915 argv[0], argv[1], VTY_NEWLINE);
916 return CMD_WARNING;
917 }
918
919 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
920 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700921 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100922
923 vlr_subscr_put(vsub);
924
925 return CMD_SUCCESS;
926}
927
928DEFUN(subscriber_send_sms,
929 subscriber_send_sms_cmd,
930 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
931 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
932{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100933 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200934 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100935 char *str;
936 int rc;
937
938 if (!vsub) {
939 vty_out(vty, "%% No subscriber found for %s %s%s",
940 argv[0], argv[1], VTY_NEWLINE);
941 rc = CMD_WARNING;
942 goto err;
943 }
944
Harald Welte39b55482018-04-09 19:19:33 +0200945 if (!strcmp(argv[2], "msisdn"))
946 sender_msisdn = argv[3];
947 else {
948 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
949 if (!sender) {
950 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
951 rc = CMD_WARNING;
952 goto err;
953 }
954 sender_msisdn = sender->msisdn;
955 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100956 }
957
958 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +0200959 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100960 talloc_free(str);
961
962err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100963 if (vsub)
964 vlr_subscr_put(vsub);
965
966 return rc;
967}
968
969DEFUN(subscriber_silent_sms,
970 subscriber_silent_sms_cmd,
971
972 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
973 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
974{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100975 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200976 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100977 char *str;
978 int rc;
979
980 if (!vsub) {
981 vty_out(vty, "%% No subscriber found for %s %s%s",
982 argv[0], argv[1], VTY_NEWLINE);
983 rc = CMD_WARNING;
984 goto err;
985 }
986
Harald Welte39b55482018-04-09 19:19:33 +0200987 if (!strcmp(argv[2], "msisdn")) {
988 sender_msisdn = argv[3];
989 } else {
990 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
991 if (!sender) {
992 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
993 rc = CMD_WARNING;
994 goto err;
995 }
996 sender_msisdn = sender->msisdn;
997 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100998 }
999
1000 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +02001001 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001002 talloc_free(str);
1003
1004err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001005 if (vsub)
1006 vlr_subscr_put(vsub);
1007
1008 return rc;
1009}
1010
1011#define CHAN_TYPES "(any|tch/f|tch/any|sdcch)"
1012#define CHAN_TYPE_HELP \
1013 "Any channel\n" \
1014 "TCH/F channel\n" \
1015 "Any TCH channel\n" \
1016 "SDCCH channel\n"
1017
1018DEFUN(subscriber_silent_call_start,
1019 subscriber_silent_call_start_cmd,
1020 "subscriber " SUBSCR_TYPES " ID silent-call start (any|tch/f|tch/any|sdcch)",
1021 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
1022 CHAN_TYPE_HELP)
1023{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001024 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1025 int rc, type;
1026
1027 if (!vsub) {
1028 vty_out(vty, "%% No subscriber found for %s %s%s",
1029 argv[0], argv[1], VTY_NEWLINE);
1030 return CMD_WARNING;
1031 }
1032
1033 if (!strcmp(argv[2], "tch/f"))
1034 type = RSL_CHANNEED_TCH_F;
1035 else if (!strcmp(argv[2], "tch/any"))
1036 type = RSL_CHANNEED_TCH_ForH;
1037 else if (!strcmp(argv[2], "sdcch"))
1038 type = RSL_CHANNEED_SDCCH;
1039 else
1040 type = RSL_CHANNEED_ANY; /* Defaults to ANY */
1041
1042 rc = gsm_silent_call_start(vsub, vty, type);
1043 switch (rc) {
1044 case -ENODEV:
1045 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
1046 break;
1047 default:
1048 if (rc)
1049 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
1050 else
1051 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
1052 break;
1053 }
1054
1055 vlr_subscr_put(vsub);
1056 return rc ? CMD_WARNING : CMD_SUCCESS;
1057}
1058
1059DEFUN(subscriber_silent_call_stop,
1060 subscriber_silent_call_stop_cmd,
1061 "subscriber " SUBSCR_TYPES " ID silent-call stop",
1062 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
1063 CHAN_TYPE_HELP)
1064{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001065 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1066 int rc;
1067
1068 if (!vsub) {
1069 vty_out(vty, "%% No subscriber found for %s %s%s",
1070 argv[0], argv[1], VTY_NEWLINE);
1071 return CMD_WARNING;
1072 }
1073
1074 rc = gsm_silent_call_stop(vsub);
1075 switch (rc) {
1076 case -ENODEV:
1077 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
1078 break;
1079 case -ENOENT:
1080 vty_out(vty, "%% Subscriber has no silent call active%s",
1081 VTY_NEWLINE);
1082 break;
1083 default:
1084 if (rc)
1085 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
1086 else
1087 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
1088 break;
1089 }
1090
1091 vlr_subscr_put(vsub);
1092 return rc ? CMD_WARNING : CMD_SUCCESS;
1093}
1094
1095DEFUN(subscriber_ussd_notify,
1096 subscriber_ussd_notify_cmd,
1097 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1098 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1099 "Alerting Level 0\n"
1100 "Alerting Level 1\n"
1101 "Alerting Level 2\n"
1102 "Text of USSD message to send\n")
1103{
1104 char *text;
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001105 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001106 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1107 int level;
1108
1109 if (!vsub) {
1110 vty_out(vty, "%% No subscriber found for %s %s%s",
1111 argv[0], argv[1], VTY_NEWLINE);
1112 return CMD_WARNING;
1113 }
1114
1115 level = atoi(argv[2]);
1116 text = argv_concat(argv, argc, 3);
1117 if (!text) {
1118 vlr_subscr_put(vsub);
1119 return CMD_WARNING;
1120 }
1121
1122 conn = connection_for_subscr(vsub);
1123 if (!conn) {
1124 vty_out(vty, "%% An active connection is required for %s %s%s",
1125 argv[0], argv[1], VTY_NEWLINE);
1126 vlr_subscr_put(vsub);
1127 talloc_free(text);
1128 return CMD_WARNING;
1129 }
1130
1131 msc_send_ussd_notify(conn, level, text);
1132 msc_send_ussd_release_complete(conn);
1133
1134 vlr_subscr_put(vsub);
1135 talloc_free(text);
1136 return CMD_SUCCESS;
1137}
1138
1139DEFUN(subscriber_paging,
1140 subscriber_paging_cmd,
1141 "subscriber " SUBSCR_TYPES " ID paging",
1142 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1143{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001144 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1145 struct subscr_request *req;
1146
1147 if (!vsub) {
1148 vty_out(vty, "%% No subscriber found for %s %s%s",
1149 argv[0], argv[1], VTY_NEWLINE);
1150 return CMD_WARNING;
1151 }
1152
1153 req = subscr_request_conn(vsub, NULL, NULL, "manual Paging from VTY");
1154 if (req)
1155 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1156 else
1157 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1158
1159 vlr_subscr_put(vsub);
1160 return req ? CMD_SUCCESS : CMD_WARNING;
1161}
1162
1163static int loop_by_char(uint8_t ch)
1164{
1165 switch (ch) {
1166 case 'a':
1167 return GSM414_LOOP_A;
1168 case 'b':
1169 return GSM414_LOOP_B;
1170 case 'c':
1171 return GSM414_LOOP_C;
1172 case 'd':
1173 return GSM414_LOOP_D;
1174 case 'e':
1175 return GSM414_LOOP_E;
1176 case 'f':
1177 return GSM414_LOOP_F;
1178 case 'i':
1179 return GSM414_LOOP_I;
1180 }
1181 return -1;
1182}
1183
1184DEFUN(subscriber_mstest_close,
1185 subscriber_mstest_close_cmd,
1186 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1187 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1188 "Close a TCH Loop inside the MS\n"
1189 "Loop Type A\n"
1190 "Loop Type B\n"
1191 "Loop Type C\n"
1192 "Loop Type D\n"
1193 "Loop Type E\n"
1194 "Loop Type F\n"
1195 "Loop Type I\n")
1196{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001197 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001198 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1199 const char *loop_str;
1200 int loop_mode;
1201
1202 if (!vsub) {
1203 vty_out(vty, "%% No subscriber found for %s %s%s",
1204 argv[0], argv[1], VTY_NEWLINE);
1205 return CMD_WARNING;
1206 }
1207
1208 loop_str = argv[2];
1209 loop_mode = loop_by_char(loop_str[0]);
1210
1211 conn = connection_for_subscr(vsub);
1212 if (!conn) {
1213 vty_out(vty, "%% An active connection is required for %s %s%s",
1214 argv[0], argv[1], VTY_NEWLINE);
1215 vlr_subscr_put(vsub);
1216 return CMD_WARNING;
1217 }
1218
1219 gsm0414_tx_close_tch_loop_cmd(conn, loop_mode);
1220
1221 return CMD_SUCCESS;
1222}
1223
1224DEFUN(subscriber_mstest_open,
1225 subscriber_mstest_open_cmd,
1226 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1227 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1228 "Open a TCH Loop inside the MS\n")
1229{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001230 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001231 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1232
1233 if (!vsub) {
1234 vty_out(vty, "%% No subscriber found for %s %s%s",
1235 argv[0], argv[1], VTY_NEWLINE);
1236 return CMD_WARNING;
1237 }
1238
1239 conn = connection_for_subscr(vsub);
1240 if (!conn) {
1241 vty_out(vty, "%% An active connection is required for %s %s%s",
1242 argv[0], argv[1], VTY_NEWLINE);
1243 vlr_subscr_put(vsub);
1244 return CMD_WARNING;
1245 }
1246
1247 gsm0414_tx_open_loop_cmd(conn);
1248
1249 return CMD_SUCCESS;
1250}
1251
1252DEFUN(ena_subscr_expire,
1253 ena_subscr_expire_cmd,
1254 "subscriber " SUBSCR_TYPES " ID expire",
1255 SUBSCR_HELP "Expire the subscriber Now\n")
1256{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001257 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1258 argv[1]);
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 if (vlr_subscr_expire(vsub))
1267 vty_out(vty, "%% VLR released subscriber %s%s",
1268 vlr_subscr_name(vsub), VTY_NEWLINE);
1269
1270 if (vsub->use_count > 1)
1271 vty_out(vty, "%% Subscriber %s is still in use,"
1272 " should be released soon%s",
1273 vlr_subscr_name(vsub), VTY_NEWLINE);
1274
1275 vlr_subscr_put(vsub);
1276 return CMD_SUCCESS;
1277}
1278
1279static int scall_cbfn(unsigned int subsys, unsigned int signal,
1280 void *handler_data, void *signal_data)
1281{
1282 struct scall_signal_data *sigdata = signal_data;
1283 struct vty *vty = sigdata->data;
1284
1285 switch (signal) {
1286 case S_SCALL_SUCCESS:
1287 vty_out(vty, "%% silent call success%s", VTY_NEWLINE);
1288 break;
1289 case S_SCALL_EXPIRED:
1290 vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE);
1291 break;
1292 }
1293 return 0;
1294}
1295
1296DEFUN(show_stats,
1297 show_stats_cmd,
1298 "show statistics",
1299 SHOW_STR "Display network statistics\n")
1300{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001301 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001302 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1303 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1304 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001305 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001306 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001307 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001308 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001309 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001310 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1311 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001312 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001313 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001314 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1315 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001316 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001317 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001318 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1319 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1320 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001321 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001322 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001323 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1324 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001325 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001326 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001327 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1328 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001329 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001330 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001331 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1332 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1333 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1334 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1335 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001336 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001337 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1338 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1339 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1340 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1341 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001342 return CMD_SUCCESS;
1343}
1344
1345DEFUN(show_smsqueue,
1346 show_smsqueue_cmd,
1347 "show sms-queue",
1348 SHOW_STR "Display SMSqueue statistics\n")
1349{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001350 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001351 return CMD_SUCCESS;
1352}
1353
1354DEFUN(smsqueue_trigger,
1355 smsqueue_trigger_cmd,
1356 "sms-queue trigger",
1357 "SMS Queue\n" "Trigger sending messages\n")
1358{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001359 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001360 return CMD_SUCCESS;
1361}
1362
1363DEFUN(smsqueue_max,
1364 smsqueue_max_cmd,
1365 "sms-queue max-pending <1-500>",
1366 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1367{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001368 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001369 return CMD_SUCCESS;
1370}
1371
1372DEFUN(smsqueue_clear,
1373 smsqueue_clear_cmd,
1374 "sms-queue clear",
1375 "SMS Queue\n" "Clear the queue of pending SMS\n")
1376{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001377 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001378 return CMD_SUCCESS;
1379}
1380
1381DEFUN(smsqueue_fail,
1382 smsqueue_fail_cmd,
1383 "sms-queue max-failure <1-500>",
1384 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1385{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001386 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001387 return CMD_SUCCESS;
1388}
1389
1390
1391DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1392 "mncc-int", "Configure internal MNCC handler")
1393{
1394 vty->node = MNCC_INT_NODE;
1395
1396 return CMD_SUCCESS;
1397}
1398
1399static struct cmd_node mncc_int_node = {
1400 MNCC_INT_NODE,
1401 "%s(config-mncc-int)# ",
1402 1,
1403};
1404
1405static const struct value_string tchf_codec_names[] = {
1406 { GSM48_CMODE_SPEECH_V1, "fr" },
1407 { GSM48_CMODE_SPEECH_EFR, "efr" },
1408 { GSM48_CMODE_SPEECH_AMR, "amr" },
1409 { 0, NULL }
1410};
1411
1412static const struct value_string tchh_codec_names[] = {
1413 { GSM48_CMODE_SPEECH_V1, "hr" },
1414 { GSM48_CMODE_SPEECH_AMR, "amr" },
1415 { 0, NULL }
1416};
1417
1418static int config_write_mncc_int(struct vty *vty)
1419{
1420 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1421 vty_out(vty, " default-codec tch-f %s%s",
1422 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1423 VTY_NEWLINE);
1424 vty_out(vty, " default-codec tch-h %s%s",
1425 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1426 VTY_NEWLINE);
1427
1428 return CMD_SUCCESS;
1429}
1430
1431DEFUN(mnccint_def_codec_f,
1432 mnccint_def_codec_f_cmd,
1433 "default-codec tch-f (fr|efr|amr)",
1434 "Set default codec\n" "Codec for TCH/F\n"
1435 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1436{
1437 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1438
1439 return CMD_SUCCESS;
1440}
1441
1442DEFUN(mnccint_def_codec_h,
1443 mnccint_def_codec_h_cmd,
1444 "default-codec tch-h (hr|amr)",
1445 "Set default codec\n" "Codec for TCH/H\n"
1446 "Half-Rate\n" "Adaptive Multi-Rate\n")
1447{
1448 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1449
1450 return CMD_SUCCESS;
1451}
1452
1453
1454DEFUN(logging_fltr_imsi,
1455 logging_fltr_imsi_cmd,
1456 "logging filter imsi IMSI",
1457 LOGGING_STR FILTER_STR
1458 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1459{
1460 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001461 struct log_target *tgt = osmo_log_vty2tgt(vty);
1462 const char *imsi = argv[0];
1463
1464 if (!tgt)
1465 return CMD_WARNING;
1466
1467 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi);
1468
1469 if (!vlr_subscr) {
1470 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1471 argv[0], VTY_NEWLINE);
1472 return CMD_WARNING;
1473 }
1474
1475 log_set_filter_vlr_subscr(tgt, vlr_subscr);
1476 return CMD_SUCCESS;
1477}
1478
1479static struct cmd_node hlr_node = {
1480 HLR_NODE,
1481 "%s(config-hlr)# ",
1482 1,
1483};
1484
1485DEFUN(cfg_hlr, cfg_hlr_cmd,
1486 "hlr", "Configure connection to the HLR")
1487{
1488 vty->node = HLR_NODE;
1489 return CMD_SUCCESS;
1490}
1491
1492DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1493 "Remote GSUP address of the HLR\n"
1494 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1495{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001496 talloc_free((void*)gsmnet->gsup_server_addr_str);
1497 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1498 return CMD_SUCCESS;
1499}
1500
1501DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1502 "Remote GSUP port of the HLR\n"
1503 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1504{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001505 gsmnet->gsup_server_port = atoi(argv[0]);
1506 return CMD_SUCCESS;
1507}
1508
1509static int config_write_hlr(struct vty *vty)
1510{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001511 vty_out(vty, "hlr%s", VTY_NEWLINE);
1512 vty_out(vty, " remote-ip %s%s",
1513 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1514 vty_out(vty, " remote-port %u%s",
1515 gsmnet->gsup_server_port, VTY_NEWLINE);
1516 return CMD_SUCCESS;
1517}
1518
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001519void msc_vty_init(struct gsm_network *msc_network)
1520{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001521 OSMO_ASSERT(gsmnet == NULL);
1522 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001523
1524 osmo_stats_vty_add_cmds();
1525
1526 install_element(CONFIG_NODE, &cfg_net_cmd);
1527 install_node(&net_node, config_write_net);
1528 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
1529 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1530 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1531 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
1532 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
1533 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
1534 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
1535 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
1536 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
1537 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
1538 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
1539 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
1540 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001541
1542 install_element(CONFIG_NODE, &cfg_msc_cmd);
1543 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001544 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01001545 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
1546 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02001547 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01001548 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001549 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01001550 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
1551 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001552 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
1553 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01001554 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01001555 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Stefan Sperlingafa030d2018-12-06 12:06:59 +01001556 install_element(MSC_NODE, &cfg_msc_ipa_name_cmd);
Vadim Yanitskiyf40e46f2018-11-20 06:20:53 +07001557 install_element(MSC_NODE, &cfg_msc_sms_over_gsup_cmd);
1558 install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001559
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02001560 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001561#ifdef BUILD_IU
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +01001562 ranap_iu_vty_init(MSC_NODE, &msc_network->iu.rab_assign_addr_enc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001563#endif
Stefan Sperling617ac802018-02-22 17:58:20 +01001564 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001565
1566 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
1567
1568 install_element_ve(&show_subscr_cmd);
1569 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01001570 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001571 install_element_ve(&show_msc_conn_cmd);
1572 install_element_ve(&show_msc_transaction_cmd);
1573
1574 install_element_ve(&sms_send_pend_cmd);
1575 install_element_ve(&sms_delete_expired_cmd);
1576
1577 install_element_ve(&subscriber_create_cmd);
1578 install_element_ve(&subscriber_send_sms_cmd);
1579 install_element_ve(&subscriber_silent_sms_cmd);
1580 install_element_ve(&subscriber_silent_call_start_cmd);
1581 install_element_ve(&subscriber_silent_call_stop_cmd);
1582 install_element_ve(&subscriber_ussd_notify_cmd);
1583 install_element_ve(&subscriber_mstest_close_cmd);
1584 install_element_ve(&subscriber_mstest_open_cmd);
1585 install_element_ve(&subscriber_paging_cmd);
1586 install_element_ve(&show_stats_cmd);
1587 install_element_ve(&show_smsqueue_cmd);
1588 install_element_ve(&logging_fltr_imsi_cmd);
1589
1590 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
1591 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
1592 install_element(ENABLE_NODE, &smsqueue_max_cmd);
1593 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
1594 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
1595 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
1596
1597 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1598 install_node(&mncc_int_node, config_write_mncc_int);
1599 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1600 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1601
1602 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
1603
1604 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1605 install_node(&hlr_node, config_write_hlr);
1606 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1607 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001608}