blob: b39775f2eca7a10929a9cb2a14e77d508982b7b4 [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 Sperling1051c422018-12-13 10:16:49 +0100469 if (!msc_parsing_config_file) {
470 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
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200479static int config_write_msc(struct vty *vty)
480{
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200481 vty_out(vty, "msc%s", VTY_NEWLINE);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +0100482 if (gsmnet->mncc_sock_path)
483 vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE);
Neels Hofmeyr05c56802018-12-05 01:07:03 +0100484 vty_out(vty, " mncc guard-timeout %i%s",
Philipp Maier9ca7b312018-10-10 17:00:49 +0200485 gsmnet->mncc_guard_timeout, VTY_NEWLINE);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200486 vty_out(vty, " %sassign-tmsi%s",
487 gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
488
Philipp Maierfbf66102017-04-09 12:32:51 +0200489 vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
490 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100491#if BUILD_IU
Philipp Maierfbf66102017-04-09 12:32:51 +0200492 vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance,
493 VTY_NEWLINE);
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +0100494#endif
Philipp Maierfbf66102017-04-09 12:32:51 +0200495
Neels Hofmeyr97ce0152017-10-29 02:10:38 +0100496 if (gsmnet->vlr->cfg.auth_tuple_max_reuse_count)
497 vty_out(vty, " auth-tuple-max-reuse-count %d%s",
498 OSMO_MAX(-1, gsmnet->vlr->cfg.auth_tuple_max_reuse_count),
499 VTY_NEWLINE);
500 if (gsmnet->vlr->cfg.auth_reuse_old_sets_on_error)
501 vty_out(vty, " auth-tuple-reuse-on-error 1%s",
502 VTY_NEWLINE);
503
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100504 if (gsmnet->paging_response_timer != MSC_PAGING_RESPONSE_TIMER_DEFAULT)
505 vty_out(vty, " paging response-timer %u%s", gsmnet->paging_response_timer, VTY_NEWLINE);
506
Harald Welte69c54a82018-02-09 20:41:14 +0100507 if (gsmnet->emergency.route_to_msisdn) {
508 vty_out(vty, " emergency-call route-to-msisdn %s%s",
509 gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
510 }
511
Stefan Sperlingafa030d2018-12-06 12:06:59 +0100512 if (gsmnet->msc_ipa_name)
513 vty_out(vty, " ipa-name %s%s", gsmnet->msc_ipa_name, VTY_NEWLINE);
514
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +0200515 mgcp_client_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200516#ifdef BUILD_IU
Neels Hofmeyr00e82d62017-07-05 15:19:52 +0200517 ranap_iu_vty_config_write(vty, " ");
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200518#endif
519
520 return CMD_SUCCESS;
521}
522
Maxc51609a2018-11-09 17:13:00 +0100523DEFUN(show_bsc, show_bsc_cmd,
524 "show bsc", SHOW_STR "BSC\n")
525{
526 struct bsc_context *bsc_ctx;
527 struct osmo_ss7_instance *ss7 = osmo_ss7_instance_find(gsmnet->a.cs7_instance);
528
529 llist_for_each_entry(bsc_ctx, &gsmnet->a.bscs, list) {
530 vty_out(vty, "BSC %s%s", osmo_sccp_addr_name(ss7, &bsc_ctx->bsc_addr), VTY_NEWLINE);
531 }
532
533 return CMD_SUCCESS;
534}
535
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100536static void vty_conn_hdr(struct vty *vty)
537{
538 vty_out(vty, "--ConnId ------------Subscriber RAN --LAC Use --Tokens C A5 State%s",
539 VTY_NEWLINE);
540}
541
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100542static void vty_dump_one_conn(struct vty *vty, const struct ran_conn *conn)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100543{
544 vty_out(vty, "%08x %22s %3s %5u %3u %08x %c /%1u %27s %s",
545 conn->a.conn_id,
546 conn->vsub ? vlr_subscr_name(conn->vsub) : "-",
547 conn->via_ran == RAN_UTRAN_IU ? "Iu" : "A",
548 conn->lac,
549 conn->use_count,
550 conn->use_tokens,
551 conn->received_cm_service_request ? 'C' : '-',
Neels Hofmeyrf41658d2018-11-30 04:35:50 +0100552 conn->geran_encr.alg_id,
Neels Hofmeyr4d3a66b2018-03-31 18:45:59 +0200553 conn->fi ? osmo_fsm_inst_state_name(conn->fi) : "-",
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100554 VTY_NEWLINE);
555}
556
557DEFUN(show_msc_conn, show_msc_conn_cmd,
558 "show connection", SHOW_STR "Subscriber Connections\n")
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200559{
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100560 struct ran_conn *conn;
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200561
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100562 vty_conn_hdr(vty);
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100563 llist_for_each_entry(conn, &gsmnet->ran_conns, entry)
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100564 vty_dump_one_conn(vty, conn);
565
566 return CMD_SUCCESS;
567}
568
569static void vty_trans_hdr(struct vty *vty)
570{
571 vty_out(vty, "------------Subscriber --ConnId -P TI -CallRef Proto%s",
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200572 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100573}
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200574
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100575static const char *get_trans_proto_str(const struct gsm_trans *trans)
576{
577 static char buf[256];
578
579 switch (trans->protocol) {
580 case GSM48_PDISC_CC:
581 snprintf(buf, sizeof(buf), "%s %4u %4u",
582 gsm48_cc_state_name(trans->cc.state),
583 trans->cc.Tcurrent,
584 trans->cc.T308_second);
585 break;
586 case GSM48_PDISC_SMS:
587 snprintf(buf, sizeof(buf), "%s %s",
588 gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
589 gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
590 break;
591 default:
592 buf[0] = '\0';
593 break;
594 }
595
596 return buf;
597}
598
599static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
600{
601 vty_out(vty, "%22s %08x %s %02u %08x %s%s",
602 trans->vsub ? vlr_subscr_name(trans->vsub) : "-",
603 trans->conn ? trans->conn->a.conn_id : 0,
604 gsm48_pdisc_name(trans->protocol),
605 trans->transaction_id,
606 trans->callref,
607 get_trans_proto_str(trans), VTY_NEWLINE);
608}
609
610DEFUN(show_msc_transaction, show_msc_transaction_cmd,
611 "show transaction", SHOW_STR "Transactions\n")
612{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100613 struct gsm_trans *trans;
614
615 vty_trans_hdr(vty);
616 llist_for_each_entry(trans, &gsmnet->trans_list, entry)
617 vty_dump_one_trans(vty, trans);
618
619 return CMD_SUCCESS;
620}
621
622static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
623{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100624 struct gsm_trans *trans;
625 int reqs;
626 struct llist_head *entry;
627
628 if (strlen(vsub->name))
629 vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
630 if (strlen(vsub->msisdn))
631 vty_out(vty, " Extension: %s%s", vsub->msisdn,
632 VTY_NEWLINE);
633 vty_out(vty, " LAC: %d/0x%x%s",
634 vsub->lac, vsub->lac, VTY_NEWLINE);
635 vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
636 if (vsub->tmsi != GSM_RESERVED_TMSI)
637 vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
638 VTY_NEWLINE);
639 if (vsub->tmsi_new != GSM_RESERVED_TMSI)
640 vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
641 VTY_NEWLINE);
642
Philipp Maier89561bc2018-12-14 13:34:25 +0100643 vty_out(vty, " Flags: %s", VTY_NEWLINE);
644 vty_out(vty, " IMSI detached: %s%s",
645 vsub->imsi_detached_flag ? "true" : "false", VTY_NEWLINE);
646 vty_out(vty, " Conf. by radio contact: %s%s",
647 vsub->conf_by_radio_contact_ind ? "true" : "false",
648 VTY_NEWLINE);
649 vty_out(vty, " Subscr. data conf. by HLR: %s%s",
650 vsub->sub_dataconf_by_hlr_ind ? "true" : "false", VTY_NEWLINE);
651 vty_out(vty, " Location conf. in HLR: %s%s",
652 vsub->loc_conf_in_hlr_ind ? "true" : "false", VTY_NEWLINE);
653 vty_out(vty, " Subscriber dormant: %s%s",
654 vsub->dormant_ind ? "true" : "false", VTY_NEWLINE);
655 vty_out(vty, " Received cancel locataion: %s%s",
656 vsub->cancel_loc_rx ? "true" : "false", VTY_NEWLINE);
657 vty_out(vty, " MS not reachable: %s%s",
658 vsub->ms_not_reachable_flag ? "true" : "false", VTY_NEWLINE);
659 vty_out(vty, " LA allowed: %s%s",
660 vsub->la_allowed ? "true" : "false", VTY_NEWLINE);
661
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100662#if 0
663 /* TODO: add this to vlr_subscr? */
664 if (vsub->auth_info.auth_algo != AUTH_ALGO_NONE) {
665 struct gsm_auth_info *i = &vsub->auth_info;
666 vty_out(vty, " A3A8 algorithm id: %d%s",
667 i->auth_algo, VTY_NEWLINE);
668 vty_out(vty, " A3A8 Ki: %s%s",
669 osmo_hexdump(i->a3a8_ki, i->a3a8_ki_len),
670 VTY_NEWLINE);
671 }
672#endif
673
674 if (vsub->last_tuple) {
Neels Hofmeyr8b6e5362018-11-30 02:57:33 +0100675 struct vlr_auth_tuple *t = vsub->last_tuple;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100676 vty_out(vty, " A3A8 last tuple (used %d times):%s",
677 t->use_count, VTY_NEWLINE);
678 vty_out(vty, " seq # : %d%s",
679 t->key_seq, VTY_NEWLINE);
680 vty_out(vty, " RAND : %s%s",
681 osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
682 VTY_NEWLINE);
683 vty_out(vty, " SRES : %s%s",
684 osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
685 VTY_NEWLINE);
686 vty_out(vty, " Kc : %s%s",
687 osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
688 VTY_NEWLINE);
689 }
690
691 reqs = 0;
692 llist_for_each(entry, &vsub->cs.requests)
693 reqs += 1;
694 vty_out(vty, " Paging: %s paging for %d requests%s",
695 vsub->cs.is_paging ? "is" : "not", reqs, VTY_NEWLINE);
696 vty_out(vty, " Use count: %u%s", vsub->use_count, VTY_NEWLINE);
697
698 /* Connection */
699 if (vsub->msc_conn_ref) {
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100700 struct ran_conn *conn = vsub->msc_conn_ref;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100701 vty_conn_hdr(vty);
702 vty_dump_one_conn(vty, conn);
703 }
704
705 /* Transactions */
706 vty_trans_hdr(vty);
707 llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
708 if (trans->vsub != vsub)
709 continue;
710 vty_dump_one_trans(vty, trans);
711 }
712}
713
714/* Subscriber */
715DEFUN(show_subscr_cache,
716 show_subscr_cache_cmd,
717 "show subscriber cache",
718 SHOW_STR "Show information about subscribers\n"
719 "Display contents of subscriber cache\n")
720{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100721 struct vlr_subscr *vsub;
722 int count = 0;
723
724 llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
725 if (++count > 100) {
726 vty_out(vty, "%% More than %d subscribers in cache,"
727 " stopping here.%s", count-1, VTY_NEWLINE);
728 break;
729 }
730 vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
731 subscr_dump_full_vty(vty, vsub);
Harald Welte69c54a82018-02-09 20:41:14 +0100732 }
733
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200734 return CMD_SUCCESS;
735}
736
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100737DEFUN(sms_send_pend,
738 sms_send_pend_cmd,
739 "sms send pending",
740 "SMS related commands\n" "SMS Sending related commands\n"
741 "Send all pending SMS")
742{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100743 struct gsm_sms *sms;
744 unsigned long long sms_id = 0;
745
746 while (1) {
747 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
748 if (!sms)
749 break;
750
751 if (sms->receiver)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700752 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100753
754 sms_id = sms->id + 1;
755 }
756
757 return CMD_SUCCESS;
758}
759
760DEFUN(sms_delete_expired,
761 sms_delete_expired_cmd,
762 "sms delete expired",
763 "SMS related commands\n" "SMS Database related commands\n"
764 "Delete all expired SMS")
765{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100766 struct gsm_sms *sms;
767 unsigned long long sms_id = 0;
768 long long num_deleted = 0;
769
770 while (1) {
771 sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
772 if (!sms)
773 break;
774
775 /* Skip SMS which are currently queued for sending. */
776 if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
777 continue;
778
779 /* Expiration check is performed by the DB layer. */
780 if (db_sms_delete_expired_message_by_id(sms->id) == 0)
781 num_deleted++;
782
783 sms_id = sms->id + 1;
784 }
785
786 if (num_deleted == 0) {
787 vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
788 return CMD_WARNING;
789 }
790
791 vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
792 return CMD_SUCCESS;
793}
794
795static int _send_sms_str(struct vlr_subscr *receiver,
Harald Welte39b55482018-04-09 19:19:33 +0200796 const char *sender_msisdn,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100797 char *str, uint8_t tp_pid)
798{
799 struct gsm_network *net = receiver->vlr->user_ctx;
800 struct gsm_sms *sms;
801
Harald Welte39b55482018-04-09 19:19:33 +0200802 sms = sms_from_text(receiver, sender_msisdn, 0, str);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100803 sms->protocol_id = tp_pid;
804
805 /* store in database for the queue */
806 if (db_sms_store(sms) != 0) {
807 LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
808 sms_free(sms);
809 return CMD_WARNING;
810 }
811 LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
812
813 sms_free(sms);
814 sms_queue_trigger(net->sms_queue);
815 return CMD_SUCCESS;
816}
817
818static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
819 const char *type,
820 const char *id)
821{
822 if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
823 return vlr_subscr_find_by_msisdn(gsmnet->vlr, id);
824 else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
825 return vlr_subscr_find_by_imsi(gsmnet->vlr, id);
826 else if (!strcmp(type, "tmsi"))
827 return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id));
828
829 return NULL;
830}
831#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
832#define SUBSCR_HELP "Operations on a Subscriber\n" \
833 "Identify subscriber by MSISDN (phone number)\n" \
834 "Legacy alias for 'msisdn'\n" \
835 "Identify subscriber by IMSI\n" \
836 "Identify subscriber by TMSI\n" \
837 "Identify subscriber by database ID\n" \
838 "Identifier for the subscriber\n"
839
840DEFUN(show_subscr,
841 show_subscr_cmd,
842 "show subscriber " SUBSCR_TYPES " ID",
843 SHOW_STR SUBSCR_HELP)
844{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100845 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
846 argv[1]);
847
848 if (!vsub) {
849 vty_out(vty, "%% No subscriber found for %s %s%s",
850 argv[0], argv[1], VTY_NEWLINE);
851 return CMD_WARNING;
852 }
853
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100854 /* In the vty output to the user, exclude this local use count added by vlr_subscr_get() in get_vsub_by_argv().
855 * This works, because: for get_vsub_by_argv() to succeed, there *must* have been at least one use count before
856 * 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 +0100857 vlr_subscr_put(vsub);
858
Neels Hofmeyr14c6f3e2018-12-12 04:02:29 +0100859 subscr_dump_full_vty(vty, vsub);
860
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100861 return CMD_SUCCESS;
862}
863
864DEFUN(subscriber_create,
865 subscriber_create_cmd,
866 "subscriber create imsi ID",
867 "Operations on a Subscriber\n" \
868 "Create new subscriber\n" \
869 "Identify the subscriber by his IMSI\n" \
870 "Identifier for the subscriber\n")
871{
872 vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
873 VTY_NEWLINE);
874 return CMD_WARNING;
875}
876
877DEFUN(subscriber_send_pending_sms,
878 subscriber_send_pending_sms_cmd,
879 "subscriber " SUBSCR_TYPES " ID sms pending-send",
880 SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
881{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100882 struct vlr_subscr *vsub;
883 struct gsm_sms *sms;
884
885 vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
886 if (!vsub) {
887 vty_out(vty, "%% No subscriber found for %s %s%s",
888 argv[0], argv[1], VTY_NEWLINE);
889 return CMD_WARNING;
890 }
891
892 sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
893 if (sms)
Vadim Yanitskiy24e025e2018-11-22 15:42:39 +0700894 gsm411_send_sms(gsmnet, sms->receiver, sms);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100895
896 vlr_subscr_put(vsub);
897
898 return CMD_SUCCESS;
899}
900
901DEFUN(subscriber_send_sms,
902 subscriber_send_sms_cmd,
903 "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
904 SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
905{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100906 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200907 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100908 char *str;
909 int rc;
910
911 if (!vsub) {
912 vty_out(vty, "%% No subscriber found for %s %s%s",
913 argv[0], argv[1], VTY_NEWLINE);
914 rc = CMD_WARNING;
915 goto err;
916 }
917
Harald Welte39b55482018-04-09 19:19:33 +0200918 if (!strcmp(argv[2], "msisdn"))
919 sender_msisdn = argv[3];
920 else {
921 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
922 if (!sender) {
923 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
924 rc = CMD_WARNING;
925 goto err;
926 }
927 sender_msisdn = sender->msisdn;
928 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100929 }
930
931 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +0200932 rc = _send_sms_str(vsub, sender_msisdn, str, 0);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100933 talloc_free(str);
934
935err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100936 if (vsub)
937 vlr_subscr_put(vsub);
938
939 return rc;
940}
941
942DEFUN(subscriber_silent_sms,
943 subscriber_silent_sms_cmd,
944
945 "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
946 SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
947{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100948 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
Harald Welte39b55482018-04-09 19:19:33 +0200949 const char *sender_msisdn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100950 char *str;
951 int rc;
952
953 if (!vsub) {
954 vty_out(vty, "%% No subscriber found for %s %s%s",
955 argv[0], argv[1], VTY_NEWLINE);
956 rc = CMD_WARNING;
957 goto err;
958 }
959
Harald Welte39b55482018-04-09 19:19:33 +0200960 if (!strcmp(argv[2], "msisdn")) {
961 sender_msisdn = argv[3];
962 } else {
963 struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
964 if (!sender) {
965 vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
966 rc = CMD_WARNING;
967 goto err;
968 }
969 sender_msisdn = sender->msisdn;
970 vlr_subscr_put(sender);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100971 }
972
973 str = argv_concat(argv, argc, 4);
Harald Welte39b55482018-04-09 19:19:33 +0200974 rc = _send_sms_str(vsub, sender_msisdn, str, 64);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100975 talloc_free(str);
976
977err:
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100978 if (vsub)
979 vlr_subscr_put(vsub);
980
981 return rc;
982}
983
984#define CHAN_TYPES "(any|tch/f|tch/any|sdcch)"
985#define CHAN_TYPE_HELP \
986 "Any channel\n" \
987 "TCH/F channel\n" \
988 "Any TCH channel\n" \
989 "SDCCH channel\n"
990
991DEFUN(subscriber_silent_call_start,
992 subscriber_silent_call_start_cmd,
993 "subscriber " SUBSCR_TYPES " ID silent-call start (any|tch/f|tch/any|sdcch)",
994 SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
995 CHAN_TYPE_HELP)
996{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +0100997 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
998 int rc, type;
999
1000 if (!vsub) {
1001 vty_out(vty, "%% No subscriber found for %s %s%s",
1002 argv[0], argv[1], VTY_NEWLINE);
1003 return CMD_WARNING;
1004 }
1005
1006 if (!strcmp(argv[2], "tch/f"))
1007 type = RSL_CHANNEED_TCH_F;
1008 else if (!strcmp(argv[2], "tch/any"))
1009 type = RSL_CHANNEED_TCH_ForH;
1010 else if (!strcmp(argv[2], "sdcch"))
1011 type = RSL_CHANNEED_SDCCH;
1012 else
1013 type = RSL_CHANNEED_ANY; /* Defaults to ANY */
1014
1015 rc = gsm_silent_call_start(vsub, vty, type);
1016 switch (rc) {
1017 case -ENODEV:
1018 vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
1019 break;
1020 default:
1021 if (rc)
1022 vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
1023 else
1024 vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
1025 break;
1026 }
1027
1028 vlr_subscr_put(vsub);
1029 return rc ? CMD_WARNING : CMD_SUCCESS;
1030}
1031
1032DEFUN(subscriber_silent_call_stop,
1033 subscriber_silent_call_stop_cmd,
1034 "subscriber " SUBSCR_TYPES " ID silent-call stop",
1035 SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
1036 CHAN_TYPE_HELP)
1037{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001038 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1039 int rc;
1040
1041 if (!vsub) {
1042 vty_out(vty, "%% No subscriber found for %s %s%s",
1043 argv[0], argv[1], VTY_NEWLINE);
1044 return CMD_WARNING;
1045 }
1046
1047 rc = gsm_silent_call_stop(vsub);
1048 switch (rc) {
1049 case -ENODEV:
1050 vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
1051 break;
1052 case -ENOENT:
1053 vty_out(vty, "%% Subscriber has no silent call active%s",
1054 VTY_NEWLINE);
1055 break;
1056 default:
1057 if (rc)
1058 vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
1059 else
1060 vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
1061 break;
1062 }
1063
1064 vlr_subscr_put(vsub);
1065 return rc ? CMD_WARNING : CMD_SUCCESS;
1066}
1067
1068DEFUN(subscriber_ussd_notify,
1069 subscriber_ussd_notify_cmd,
1070 "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
1071 SUBSCR_HELP "Send a USSD notify to the subscriber\n"
1072 "Alerting Level 0\n"
1073 "Alerting Level 1\n"
1074 "Alerting Level 2\n"
1075 "Text of USSD message to send\n")
1076{
1077 char *text;
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001078 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001079 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1080 int level;
1081
1082 if (!vsub) {
1083 vty_out(vty, "%% No subscriber found for %s %s%s",
1084 argv[0], argv[1], VTY_NEWLINE);
1085 return CMD_WARNING;
1086 }
1087
1088 level = atoi(argv[2]);
1089 text = argv_concat(argv, argc, 3);
1090 if (!text) {
1091 vlr_subscr_put(vsub);
1092 return CMD_WARNING;
1093 }
1094
1095 conn = connection_for_subscr(vsub);
1096 if (!conn) {
1097 vty_out(vty, "%% An active connection is required for %s %s%s",
1098 argv[0], argv[1], VTY_NEWLINE);
1099 vlr_subscr_put(vsub);
1100 talloc_free(text);
1101 return CMD_WARNING;
1102 }
1103
1104 msc_send_ussd_notify(conn, level, text);
1105 msc_send_ussd_release_complete(conn);
1106
1107 vlr_subscr_put(vsub);
1108 talloc_free(text);
1109 return CMD_SUCCESS;
1110}
1111
1112DEFUN(subscriber_paging,
1113 subscriber_paging_cmd,
1114 "subscriber " SUBSCR_TYPES " ID paging",
1115 SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
1116{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001117 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1118 struct subscr_request *req;
1119
1120 if (!vsub) {
1121 vty_out(vty, "%% No subscriber found for %s %s%s",
1122 argv[0], argv[1], VTY_NEWLINE);
1123 return CMD_WARNING;
1124 }
1125
1126 req = subscr_request_conn(vsub, NULL, NULL, "manual Paging from VTY");
1127 if (req)
1128 vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
1129 else
1130 vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
1131
1132 vlr_subscr_put(vsub);
1133 return req ? CMD_SUCCESS : CMD_WARNING;
1134}
1135
1136static int loop_by_char(uint8_t ch)
1137{
1138 switch (ch) {
1139 case 'a':
1140 return GSM414_LOOP_A;
1141 case 'b':
1142 return GSM414_LOOP_B;
1143 case 'c':
1144 return GSM414_LOOP_C;
1145 case 'd':
1146 return GSM414_LOOP_D;
1147 case 'e':
1148 return GSM414_LOOP_E;
1149 case 'f':
1150 return GSM414_LOOP_F;
1151 case 'i':
1152 return GSM414_LOOP_I;
1153 }
1154 return -1;
1155}
1156
1157DEFUN(subscriber_mstest_close,
1158 subscriber_mstest_close_cmd,
1159 "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
1160 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1161 "Close a TCH Loop inside the MS\n"
1162 "Loop Type A\n"
1163 "Loop Type B\n"
1164 "Loop Type C\n"
1165 "Loop Type D\n"
1166 "Loop Type E\n"
1167 "Loop Type F\n"
1168 "Loop Type I\n")
1169{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001170 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001171 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1172 const char *loop_str;
1173 int loop_mode;
1174
1175 if (!vsub) {
1176 vty_out(vty, "%% No subscriber found for %s %s%s",
1177 argv[0], argv[1], VTY_NEWLINE);
1178 return CMD_WARNING;
1179 }
1180
1181 loop_str = argv[2];
1182 loop_mode = loop_by_char(loop_str[0]);
1183
1184 conn = connection_for_subscr(vsub);
1185 if (!conn) {
1186 vty_out(vty, "%% An active connection is required for %s %s%s",
1187 argv[0], argv[1], VTY_NEWLINE);
1188 vlr_subscr_put(vsub);
1189 return CMD_WARNING;
1190 }
1191
1192 gsm0414_tx_close_tch_loop_cmd(conn, loop_mode);
1193
1194 return CMD_SUCCESS;
1195}
1196
1197DEFUN(subscriber_mstest_open,
1198 subscriber_mstest_open_cmd,
1199 "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
1200 SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
1201 "Open a TCH Loop inside the MS\n")
1202{
Neels Hofmeyrc036b792018-11-29 22:37:51 +01001203 struct ran_conn *conn;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001204 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
1205
1206 if (!vsub) {
1207 vty_out(vty, "%% No subscriber found for %s %s%s",
1208 argv[0], argv[1], VTY_NEWLINE);
1209 return CMD_WARNING;
1210 }
1211
1212 conn = connection_for_subscr(vsub);
1213 if (!conn) {
1214 vty_out(vty, "%% An active connection is required for %s %s%s",
1215 argv[0], argv[1], VTY_NEWLINE);
1216 vlr_subscr_put(vsub);
1217 return CMD_WARNING;
1218 }
1219
1220 gsm0414_tx_open_loop_cmd(conn);
1221
1222 return CMD_SUCCESS;
1223}
1224
1225DEFUN(ena_subscr_expire,
1226 ena_subscr_expire_cmd,
1227 "subscriber " SUBSCR_TYPES " ID expire",
1228 SUBSCR_HELP "Expire the subscriber Now\n")
1229{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001230 struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
1231 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 if (vlr_subscr_expire(vsub))
1240 vty_out(vty, "%% VLR released subscriber %s%s",
1241 vlr_subscr_name(vsub), VTY_NEWLINE);
1242
1243 if (vsub->use_count > 1)
1244 vty_out(vty, "%% Subscriber %s is still in use,"
1245 " should be released soon%s",
1246 vlr_subscr_name(vsub), VTY_NEWLINE);
1247
1248 vlr_subscr_put(vsub);
1249 return CMD_SUCCESS;
1250}
1251
1252static int scall_cbfn(unsigned int subsys, unsigned int signal,
1253 void *handler_data, void *signal_data)
1254{
1255 struct scall_signal_data *sigdata = signal_data;
1256 struct vty *vty = sigdata->data;
1257
1258 switch (signal) {
1259 case S_SCALL_SUCCESS:
1260 vty_out(vty, "%% silent call success%s", VTY_NEWLINE);
1261 break;
1262 case S_SCALL_EXPIRED:
1263 vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE);
1264 break;
1265 }
1266 return 0;
1267}
1268
1269DEFUN(show_stats,
1270 show_stats_cmd,
1271 "show statistics",
1272 SHOW_STR "Display network statistics\n")
1273{
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001274 vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001275 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
1276 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
1277 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001278 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001279 vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001280 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001281 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001282 vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001283 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
1284 gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001285 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001286 vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001287 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
1288 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001289 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001290 vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001291 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
1292 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
1293 gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001294 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001295 vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001296 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
1297 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001298 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001299 vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001300 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
1301 gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001302 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001303 vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001304 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
1305 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1306 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
1307 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
1308 VTY_NEWLINE);
Pau Espin Pedrol37106232018-11-19 11:10:37 +01001309 vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
Vadim Yanitskiy8e25cc52018-06-23 03:32:20 +07001310 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
1311 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1312 gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
1313 - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
1314 VTY_NEWLINE);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001315 return CMD_SUCCESS;
1316}
1317
1318DEFUN(show_smsqueue,
1319 show_smsqueue_cmd,
1320 "show sms-queue",
1321 SHOW_STR "Display SMSqueue statistics\n")
1322{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001323 sms_queue_stats(gsmnet->sms_queue, vty);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001324 return CMD_SUCCESS;
1325}
1326
1327DEFUN(smsqueue_trigger,
1328 smsqueue_trigger_cmd,
1329 "sms-queue trigger",
1330 "SMS Queue\n" "Trigger sending messages\n")
1331{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001332 sms_queue_trigger(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001333 return CMD_SUCCESS;
1334}
1335
1336DEFUN(smsqueue_max,
1337 smsqueue_max_cmd,
1338 "sms-queue max-pending <1-500>",
1339 "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
1340{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001341 sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001342 return CMD_SUCCESS;
1343}
1344
1345DEFUN(smsqueue_clear,
1346 smsqueue_clear_cmd,
1347 "sms-queue clear",
1348 "SMS Queue\n" "Clear the queue of pending SMS\n")
1349{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001350 sms_queue_clear(gsmnet->sms_queue);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001351 return CMD_SUCCESS;
1352}
1353
1354DEFUN(smsqueue_fail,
1355 smsqueue_fail_cmd,
1356 "sms-queue max-failure <1-500>",
1357 "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
1358{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001359 sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001360 return CMD_SUCCESS;
1361}
1362
1363
1364DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
1365 "mncc-int", "Configure internal MNCC handler")
1366{
1367 vty->node = MNCC_INT_NODE;
1368
1369 return CMD_SUCCESS;
1370}
1371
1372static struct cmd_node mncc_int_node = {
1373 MNCC_INT_NODE,
1374 "%s(config-mncc-int)# ",
1375 1,
1376};
1377
1378static const struct value_string tchf_codec_names[] = {
1379 { GSM48_CMODE_SPEECH_V1, "fr" },
1380 { GSM48_CMODE_SPEECH_EFR, "efr" },
1381 { GSM48_CMODE_SPEECH_AMR, "amr" },
1382 { 0, NULL }
1383};
1384
1385static const struct value_string tchh_codec_names[] = {
1386 { GSM48_CMODE_SPEECH_V1, "hr" },
1387 { GSM48_CMODE_SPEECH_AMR, "amr" },
1388 { 0, NULL }
1389};
1390
1391static int config_write_mncc_int(struct vty *vty)
1392{
1393 vty_out(vty, "mncc-int%s", VTY_NEWLINE);
1394 vty_out(vty, " default-codec tch-f %s%s",
1395 get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
1396 VTY_NEWLINE);
1397 vty_out(vty, " default-codec tch-h %s%s",
1398 get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
1399 VTY_NEWLINE);
1400
1401 return CMD_SUCCESS;
1402}
1403
1404DEFUN(mnccint_def_codec_f,
1405 mnccint_def_codec_f_cmd,
1406 "default-codec tch-f (fr|efr|amr)",
1407 "Set default codec\n" "Codec for TCH/F\n"
1408 "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
1409{
1410 mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
1411
1412 return CMD_SUCCESS;
1413}
1414
1415DEFUN(mnccint_def_codec_h,
1416 mnccint_def_codec_h_cmd,
1417 "default-codec tch-h (hr|amr)",
1418 "Set default codec\n" "Codec for TCH/H\n"
1419 "Half-Rate\n" "Adaptive Multi-Rate\n")
1420{
1421 mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
1422
1423 return CMD_SUCCESS;
1424}
1425
1426
1427DEFUN(logging_fltr_imsi,
1428 logging_fltr_imsi_cmd,
1429 "logging filter imsi IMSI",
1430 LOGGING_STR FILTER_STR
1431 "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
1432{
1433 struct vlr_subscr *vlr_subscr;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001434 struct log_target *tgt = osmo_log_vty2tgt(vty);
1435 const char *imsi = argv[0];
1436
1437 if (!tgt)
1438 return CMD_WARNING;
1439
1440 vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi);
1441
1442 if (!vlr_subscr) {
1443 vty_out(vty, "%%no subscriber with IMSI(%s)%s",
1444 argv[0], VTY_NEWLINE);
1445 return CMD_WARNING;
1446 }
1447
1448 log_set_filter_vlr_subscr(tgt, vlr_subscr);
1449 return CMD_SUCCESS;
1450}
1451
1452static struct cmd_node hlr_node = {
1453 HLR_NODE,
1454 "%s(config-hlr)# ",
1455 1,
1456};
1457
1458DEFUN(cfg_hlr, cfg_hlr_cmd,
1459 "hlr", "Configure connection to the HLR")
1460{
1461 vty->node = HLR_NODE;
1462 return CMD_SUCCESS;
1463}
1464
1465DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
1466 "Remote GSUP address of the HLR\n"
1467 "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
1468{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001469 talloc_free((void*)gsmnet->gsup_server_addr_str);
1470 gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
1471 return CMD_SUCCESS;
1472}
1473
1474DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
1475 "Remote GSUP port of the HLR\n"
1476 "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
1477{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001478 gsmnet->gsup_server_port = atoi(argv[0]);
1479 return CMD_SUCCESS;
1480}
1481
1482static int config_write_hlr(struct vty *vty)
1483{
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001484 vty_out(vty, "hlr%s", VTY_NEWLINE);
1485 vty_out(vty, " remote-ip %s%s",
1486 gsmnet->gsup_server_addr_str, VTY_NEWLINE);
1487 vty_out(vty, " remote-port %u%s",
1488 gsmnet->gsup_server_port, VTY_NEWLINE);
1489 return CMD_SUCCESS;
1490}
1491
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001492void msc_vty_init(struct gsm_network *msc_network)
1493{
Neels Hofmeyr84a1f7a2018-03-22 15:33:12 +01001494 OSMO_ASSERT(gsmnet == NULL);
1495 gsmnet = msc_network;
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001496
1497 osmo_stats_vty_add_cmds();
1498
1499 install_element(CONFIG_NODE, &cfg_net_cmd);
1500 install_node(&net_node, config_write_net);
1501 install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
1502 install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
1503 install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
1504 install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
1505 install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
1506 install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
1507 install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
1508 install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
1509 install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
1510 install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
1511 install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
1512 install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
1513 install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001514
1515 install_element(CONFIG_NODE, &cfg_msc_cmd);
1516 install_node(&msc_node, config_write_msc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001517 install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
Neels Hofmeyr80447eb2018-12-05 01:11:28 +01001518 install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
1519 install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
Philipp Maier9ca7b312018-10-10 17:00:49 +02001520 install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
Neels Hofmeyr05c56802018-12-05 01:07:03 +01001521 install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001522 install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
Neels Hofmeyr97ce0152017-10-29 02:10:38 +01001523 install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
1524 install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001525 install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
1526 install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +01001527 install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
Harald Welte69c54a82018-02-09 20:41:14 +01001528 install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
Stefan Sperlingafa030d2018-12-06 12:06:59 +01001529 install_element(MSC_NODE, &cfg_msc_ipa_name_cmd);
Philipp Maierfbf66102017-04-09 12:32:51 +02001530
Neels Hofmeyr6c8afe12017-09-04 01:03:58 +02001531 mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001532#ifdef BUILD_IU
Neels Hofmeyr21adb2b2018-03-15 12:55:46 +01001533 ranap_iu_vty_init(MSC_NODE, &msc_network->iu.rab_assign_addr_enc);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001534#endif
Stefan Sperling617ac802018-02-22 17:58:20 +01001535 osmo_fsm_vty_add_cmds();
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001536
1537 osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
1538
1539 install_element_ve(&show_subscr_cmd);
1540 install_element_ve(&show_subscr_cache_cmd);
Maxc51609a2018-11-09 17:13:00 +01001541 install_element_ve(&show_bsc_cmd);
Neels Hofmeyr7c075a22018-03-22 14:50:20 +01001542 install_element_ve(&show_msc_conn_cmd);
1543 install_element_ve(&show_msc_transaction_cmd);
1544
1545 install_element_ve(&sms_send_pend_cmd);
1546 install_element_ve(&sms_delete_expired_cmd);
1547
1548 install_element_ve(&subscriber_create_cmd);
1549 install_element_ve(&subscriber_send_sms_cmd);
1550 install_element_ve(&subscriber_silent_sms_cmd);
1551 install_element_ve(&subscriber_silent_call_start_cmd);
1552 install_element_ve(&subscriber_silent_call_stop_cmd);
1553 install_element_ve(&subscriber_ussd_notify_cmd);
1554 install_element_ve(&subscriber_mstest_close_cmd);
1555 install_element_ve(&subscriber_mstest_open_cmd);
1556 install_element_ve(&subscriber_paging_cmd);
1557 install_element_ve(&show_stats_cmd);
1558 install_element_ve(&show_smsqueue_cmd);
1559 install_element_ve(&logging_fltr_imsi_cmd);
1560
1561 install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
1562 install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
1563 install_element(ENABLE_NODE, &smsqueue_max_cmd);
1564 install_element(ENABLE_NODE, &smsqueue_clear_cmd);
1565 install_element(ENABLE_NODE, &smsqueue_fail_cmd);
1566 install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
1567
1568 install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
1569 install_node(&mncc_int_node, config_write_mncc_int);
1570 install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
1571 install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
1572
1573 install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
1574
1575 install_element(CONFIG_NODE, &cfg_hlr_cmd);
1576 install_node(&hlr_node, config_write_hlr);
1577 install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
1578 install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +02001579}