535 lines
15 KiB
C
535 lines
15 KiB
C
/*
|
|
* (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
|
|
* (C) 2023 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
|
|
*
|
|
* All Rights Reserved
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
|
|
#include <osmocom/core/utils.h>
|
|
#include <osmocom/gsm/gsm48.h>
|
|
#include <osmocom/core/talloc.h>
|
|
#include <osmocom/core/signal.h>
|
|
#include <osmocom/core/gsmtap.h>
|
|
#include <osmocom/crypt/auth.h>
|
|
|
|
#include <osmocom/bb/common/vty.h>
|
|
#include <osmocom/bb/common/l23_app.h>
|
|
#include <osmocom/bb/common/osmocom_data.h>
|
|
#include <osmocom/bb/common/ms.h>
|
|
#include <osmocom/bb/common/networks.h>
|
|
#include <osmocom/bb/common/gps.h>
|
|
#include <osmocom/bb/common/l1l2_interface.h>
|
|
#include <osmocom/bb/mobile/mncc.h>
|
|
#include <osmocom/bb/mobile/mncc_ms.h>
|
|
#include <osmocom/bb/mobile/transaction.h>
|
|
#include <osmocom/bb/mobile/vty.h>
|
|
#include <osmocom/bb/mobile/gsm480_ss.h>
|
|
#include <osmocom/bb/mobile/gsm411_sms.h>
|
|
#include <osmocom/vty/telnet_interface.h>
|
|
#include <osmocom/vty/misc.h>
|
|
|
|
bool l23_vty_reading = false;
|
|
|
|
static struct cmd_node ms_node = {
|
|
MS_NODE,
|
|
"%s(ms)# ",
|
|
1
|
|
};
|
|
|
|
static struct cmd_node gsmtap_node = {
|
|
GSMTAP_NODE,
|
|
"%s(gsmtap)# ",
|
|
1
|
|
};
|
|
|
|
static void l23_vty_restart_required_warn(struct vty *vty, struct osmocom_ms *ms)
|
|
{
|
|
if (l23_vty_reading)
|
|
return;
|
|
if (ms->shutdown != MS_SHUTDOWN_NONE)
|
|
return;
|
|
vty_out(vty, "You must restart MS '%s' ('shutdown / no shutdown') for "
|
|
"change to take effect!%s", ms->name, VTY_NEWLINE);
|
|
}
|
|
|
|
struct osmocom_ms *l23_vty_get_ms(const char *name, struct vty *vty)
|
|
{
|
|
struct osmocom_ms *ms;
|
|
|
|
llist_for_each_entry(ms, &ms_list, entity) {
|
|
if (!strcmp(ms->name, name)) {
|
|
if (ms->shutdown != MS_SHUTDOWN_NONE) {
|
|
vty_out(vty, "MS '%s' is admin down.%s", name,
|
|
VTY_NEWLINE);
|
|
return NULL;
|
|
}
|
|
return ms;
|
|
}
|
|
}
|
|
vty_out(vty, "MS name '%s' does not exist.%s", name, VTY_NEWLINE);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/* placeholder for layer23 shared MS info to be dumped */
|
|
void l23_ms_dump(struct osmocom_ms *ms, struct vty *vty)
|
|
{
|
|
char *service = "";
|
|
|
|
if (!ms->started)
|
|
service = ", radio is not started";
|
|
else if (ms->mmlayer.state == GSM48_MM_ST_MM_IDLE) {
|
|
/* current MM idle state */
|
|
switch (ms->mmlayer.substate) {
|
|
case GSM48_MM_SST_NORMAL_SERVICE:
|
|
case GSM48_MM_SST_PLMN_SEARCH_NORMAL:
|
|
service = ", service is normal";
|
|
break;
|
|
case GSM48_MM_SST_LOC_UPD_NEEDED:
|
|
case GSM48_MM_SST_ATTEMPT_UPDATE:
|
|
service = ", service is limited (pending)";
|
|
break;
|
|
case GSM48_MM_SST_NO_CELL_AVAIL:
|
|
service = ", service is unavailable";
|
|
break;
|
|
default:
|
|
if (ms->subscr.sim_valid)
|
|
service = ", service is limited";
|
|
else
|
|
service = ", service is limited "
|
|
"(IMSI detached)";
|
|
break;
|
|
}
|
|
} else
|
|
service = ", MM connection active";
|
|
|
|
vty_out(vty, "MS '%s' is %s%s%s%s", ms->name,
|
|
(ms->shutdown != MS_SHUTDOWN_NONE) ? "administratively " : "",
|
|
(ms->shutdown != MS_SHUTDOWN_NONE || !ms->started) ? "down" : "up",
|
|
(ms->shutdown == MS_SHUTDOWN_NONE) ? service : "",
|
|
VTY_NEWLINE);
|
|
}
|
|
|
|
/* "gsmtap" config */
|
|
gDEFUN(l23_cfg_gsmtap, l23_cfg_gsmtap_cmd, "gsmtap",
|
|
"Configure GSMTAP\n")
|
|
{
|
|
vty->node = GSMTAP_NODE;
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
static const struct value_string gsmtap_sapi_names[] = {
|
|
{ GSMTAP_CHANNEL_BCCH, "BCCH" },
|
|
{ GSMTAP_CHANNEL_CCCH, "CCCH" },
|
|
{ GSMTAP_CHANNEL_RACH, "RACH" },
|
|
{ GSMTAP_CHANNEL_AGCH, "AGCH" },
|
|
{ GSMTAP_CHANNEL_PCH, "PCH" },
|
|
{ GSMTAP_CHANNEL_SDCCH, "SDCCH" },
|
|
{ GSMTAP_CHANNEL_TCH_F, "TCH/F" },
|
|
{ GSMTAP_CHANNEL_TCH_H, "TCH/H" },
|
|
{ GSMTAP_CHANNEL_PACCH, "PACCH" },
|
|
{ GSMTAP_CHANNEL_PDCH, "PDTCH" },
|
|
{ GSMTAP_CHANNEL_PTCCH, "PTCCH" },
|
|
{ GSMTAP_CHANNEL_CBCH51, "CBCH" },
|
|
{ GSMTAP_CHANNEL_ACCH, "SACCH" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const struct value_string gsmtap_categ_gprs_names[] = {
|
|
{ L23_GSMTAP_C_DL_UNKNOWN, "dl-unknown" },
|
|
{ L23_GSMTAP_C_DL_DUMMY, "dl-dummy" },
|
|
{ L23_GSMTAP_C_DL_CTRL, "dl-ctrl" },
|
|
{ L23_GSMTAP_C_DL_DATA_GPRS, "dl-data-gprs" },
|
|
{ L23_GSMTAP_C_DL_DATA_EGPRS, "dl-data-egprs" },
|
|
{ L23_GSMTAP_C_UL_UNKNOWN, "ul-unknown" },
|
|
{ L23_GSMTAP_C_UL_DUMMY, "ul-dummy" },
|
|
{ L23_GSMTAP_C_UL_CTRL, "ul-ctrl" },
|
|
{ L23_GSMTAP_C_UL_DATA_GPRS, "ul-data-gprs" },
|
|
{ L23_GSMTAP_C_UL_DATA_EGPRS, "ul-data-egprs" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const struct value_string gsmtap_categ_gprs_help[] = {
|
|
{ L23_GSMTAP_C_DL_UNKNOWN, "Unknown / Unparseable / Erroneous Downlink Blocks" },
|
|
{ L23_GSMTAP_C_DL_DUMMY, "Downlink Dummy Blocks" },
|
|
{ L23_GSMTAP_C_DL_CTRL, "Downlink Control Blocks" },
|
|
{ L23_GSMTAP_C_DL_DATA_GPRS, "Downlink Data Blocks (GPRS)" },
|
|
{ L23_GSMTAP_C_DL_DATA_EGPRS, "Downlink Data Blocks (EGPRS)" },
|
|
{ L23_GSMTAP_C_UL_UNKNOWN, "Unknown / Unparseable / Erroneous Downlink Blocks" },
|
|
{ L23_GSMTAP_C_UL_DUMMY, "Uplink Dummy Blocks" },
|
|
{ L23_GSMTAP_C_UL_CTRL, "Uplink Control Blocks" },
|
|
{ L23_GSMTAP_C_UL_DATA_GPRS, "Uplink Data Blocks (GPRS)" },
|
|
{ L23_GSMTAP_C_UL_DATA_EGPRS, "Uplink Data Blocks (EGPRS)" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
DEFUN(cfg_gsmtap_gsmtap_remote_host,
|
|
cfg_gsmtap_gsmtap_remote_host_cmd,
|
|
"gsmtap-remote-host [HOSTNAME]",
|
|
"Enable GSMTAP Um logging (see also 'gsmtap-category')\n"
|
|
"Remote IP address or hostname ('localhost' if omitted)\n")
|
|
{
|
|
osmo_talloc_replace_string(l23_ctx, &l23_cfg.gsmtap_remote_host,
|
|
argc > 0 ? argv[0] : "localhost");
|
|
|
|
if (vty->type != VTY_FILE)
|
|
vty_out(vty, "%% This command requires restart%s", VTY_NEWLINE);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN(cfg_gsmtap_no_gsmtap_remote_host,
|
|
cfg_gsmtap_no_gsmtap_remote_host_cmd,
|
|
"no gsmtap-remote-host",
|
|
NO_STR "Disable GSMTAP Um logging\n")
|
|
{
|
|
if (l23_cfg.gsmtap_remote_host)
|
|
TALLOC_FREE(l23_cfg.gsmtap_remote_host);
|
|
|
|
if (vty->type != VTY_FILE)
|
|
vty_out(vty, "%% This command requires restart%s", VTY_NEWLINE);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN(cfg_gsmtap_gsmtap_sapi_all, cfg_gsmtap_gsmtap_sapi_all_cmd,
|
|
"gsmtap-sapi (enable-all|disable-all)",
|
|
"Enable/disable sending of UL/DL messages over GSMTAP\n"
|
|
"Enable all kinds of messages (all SAPI)\n"
|
|
"Disable all kinds of messages (all SAPI)\n")
|
|
{
|
|
if (argv[0][0] == 'e')
|
|
l23_cfg.gsmtap_sapi_mask = UINT32_MAX;
|
|
else
|
|
l23_cfg.gsmtap_sapi_mask = 0x00;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN(cfg_gsmtap_gsmtap_sapi, cfg_gsmtap_gsmtap_sapi_cmd,
|
|
"HIDDEN", "HIDDEN")
|
|
{
|
|
int sapi;
|
|
|
|
sapi = get_string_value(gsmtap_sapi_names, argv[0]);
|
|
OSMO_ASSERT(sapi >= 0);
|
|
l23_cfg.gsmtap_sapi_mask |= (1 << sapi);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN(cfg_gsmtap_no_gsmtap_sapi, cfg_gsmtap_no_gsmtap_sapi_cmd,
|
|
"HIDDEN", "HIDDEN")
|
|
{
|
|
int sapi;
|
|
|
|
sapi = get_string_value(gsmtap_sapi_names, argv[0]);
|
|
OSMO_ASSERT(sapi >= 0);
|
|
|
|
l23_cfg.gsmtap_sapi_mask &= ~(1 << sapi);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN(cfg_gsmtap_gsmtap_categ_gprs_all, cfg_gsmtap_gsmtap_categ_gprs_all_cmd,
|
|
"gsmtap-category gprs (enable-all|disable-all)",
|
|
"Enable/disable sending of UL/DL messages over GSMTAP\n"
|
|
"Enable all kinds of messages (all categories)\n"
|
|
"Disable all kinds of messages (all categories)\n")
|
|
{
|
|
|
|
if (strcmp(argv[0], "enable-all") == 0)
|
|
l23_cfg.gsmtap_categ_gprs_mask = UINT32_MAX;
|
|
else
|
|
l23_cfg.gsmtap_categ_gprs_mask = 0x00;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN(cfg_gsmtap_gsmtap_categ_gprs, cfg_gsmtap_gsmtap_categ_gprs_cmd, "HIDDEN", "HIDDEN")
|
|
{
|
|
int categ;
|
|
|
|
categ = get_string_value(gsmtap_categ_gprs_names, argv[0]);
|
|
if (categ < 0)
|
|
return CMD_WARNING;
|
|
|
|
l23_cfg.gsmtap_categ_gprs_mask |= (1 << categ);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN(cfg_gsmtap_no_gsmtap_categ_gprs, cfg_gsmtap_no_gsmtap_categ_gprs_cmd, "HIDDEN", "HIDDEN")
|
|
{
|
|
int categ;
|
|
|
|
categ = get_string_value(gsmtap_categ_gprs_names, argv[0]);
|
|
if (categ < 0)
|
|
return CMD_WARNING;
|
|
|
|
l23_cfg.gsmtap_categ_gprs_mask &= ~(1 << categ);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
|
|
gDEFUN(l23_show_ms, l23_show_ms_cmd, "show ms [MS_NAME]",
|
|
SHOW_STR "Display available MS entities\n")
|
|
{
|
|
struct osmocom_ms *ms;
|
|
|
|
if (argc) {
|
|
llist_for_each_entry(ms, &ms_list, entity) {
|
|
if (!strcmp(ms->name, argv[0])) {
|
|
l23_ms_dump(ms, vty);
|
|
return CMD_SUCCESS;
|
|
}
|
|
}
|
|
vty_out(vty, "MS name '%s' does not exist.%s", argv[0],
|
|
VTY_NEWLINE);
|
|
return CMD_WARNING;
|
|
}
|
|
|
|
llist_for_each_entry(ms, &ms_list, entity) {
|
|
l23_ms_dump(ms, vty);
|
|
vty_out(vty, "%s", VTY_NEWLINE);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* per MS config */
|
|
gDEFUN(l23_cfg_ms, l23_cfg_ms_cmd, "ms MS_NAME",
|
|
"Select a mobile station to configure\nName of MS (see \"show ms\")")
|
|
{
|
|
struct osmocom_ms *ms;
|
|
|
|
llist_for_each_entry(ms, &ms_list, entity) {
|
|
if (!strcmp(ms->name, argv[0])) {
|
|
vty->index = ms;
|
|
vty->node = MS_NODE;
|
|
return CMD_SUCCESS;
|
|
}
|
|
}
|
|
|
|
vty_out(vty, "MS name '%s' does not exits%s", argv[0],
|
|
VTY_NEWLINE);
|
|
return CMD_WARNING;
|
|
}
|
|
|
|
DEFUN(cfg_ms_layer2, cfg_ms_layer2_cmd, "layer2-socket PATH",
|
|
"Define socket path to connect between layer 2 and layer 1\n"
|
|
"Unix socket, default '" L2_DEFAULT_SOCKET_PATH "'")
|
|
{
|
|
struct osmocom_ms *ms = vty->index;
|
|
struct gsm_settings *set = &ms->settings;
|
|
|
|
OSMO_STRLCPY_ARRAY(set->layer2_socket_path, argv[0]);
|
|
|
|
l23_vty_restart_required_warn(vty, ms);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN(cfg_ms_no_shutdown, cfg_ms_no_shutdown_cmd, "no shutdown",
|
|
NO_STR "Activate and run MS")
|
|
{
|
|
struct osmocom_ms *ms = vty->index;
|
|
|
|
struct osmobb_l23_vty_sig_data data;
|
|
memset(&data, 0, sizeof(data));
|
|
|
|
data.vty = vty;
|
|
data.ms_start.ms = ms;
|
|
data.ms_start.rc = CMD_SUCCESS;
|
|
osmo_signal_dispatch(SS_L23_VTY, S_L23_VTY_MS_START, &data);
|
|
|
|
return data.ms_start.rc;
|
|
}
|
|
|
|
DEFUN(cfg_ms_shutdown, cfg_ms_shutdown_cmd, "shutdown",
|
|
"Shut down and deactivate MS")
|
|
{
|
|
struct osmocom_ms *ms = vty->index;
|
|
|
|
struct osmobb_l23_vty_sig_data data;
|
|
memset(&data, 0, sizeof(data));
|
|
|
|
data.vty = vty;
|
|
data.ms_stop.ms = ms;
|
|
data.ms_stop.force = false;
|
|
data.ms_stop.rc = CMD_SUCCESS;
|
|
osmo_signal_dispatch(SS_L23_VTY, S_L23_VTY_MS_STOP, &data);
|
|
|
|
return data.ms_stop.rc;
|
|
}
|
|
|
|
DEFUN(cfg_ms_shutdown_force, cfg_ms_shutdown_force_cmd, "shutdown force",
|
|
"Shut down and deactivate MS\nDo not perform IMSI detach")
|
|
{
|
|
struct osmocom_ms *ms = vty->index;
|
|
|
|
struct osmobb_l23_vty_sig_data data;
|
|
memset(&data, 0, sizeof(data));
|
|
|
|
data.vty = vty;
|
|
data.ms_stop.ms = ms;
|
|
data.ms_stop.force = true;
|
|
data.ms_stop.rc = CMD_SUCCESS;
|
|
osmo_signal_dispatch(SS_L23_VTY, S_L23_VTY_MS_STOP, &data);
|
|
|
|
return data.ms_stop.rc;
|
|
}
|
|
|
|
static int l23_vty_config_write_gsmtap_node(struct vty *vty)
|
|
{
|
|
const char *sapi_buf;
|
|
unsigned int i;
|
|
|
|
vty_out(vty, "gsmtap%s", VTY_NEWLINE);
|
|
|
|
if (l23_cfg.gsmtap_remote_host)
|
|
vty_out(vty, " gsmtap-remote-host %s%s", l23_cfg.gsmtap_remote_host, VTY_NEWLINE);
|
|
else
|
|
vty_out(vty, " no gsmtap-remote-host%s", VTY_NEWLINE);
|
|
|
|
for (i = 0; i < sizeof(uint32_t) * 8; i++) {
|
|
if (l23_cfg.gsmtap_sapi_mask & ((uint32_t) 1 << i)) {
|
|
sapi_buf = get_value_string_or_null(gsmtap_sapi_names, i);
|
|
if (sapi_buf == NULL)
|
|
continue;
|
|
sapi_buf = osmo_str_tolower(sapi_buf);
|
|
vty_out(vty, " gsmtap-sapi %s%s", sapi_buf, VTY_NEWLINE);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < 32; i++) {
|
|
if (l23_cfg.gsmtap_categ_gprs_mask & ((uint32_t)1 << i)) {
|
|
const char *category_buf;
|
|
if (!(category_buf = get_value_string_or_null(gsmtap_categ_gprs_names, i)))
|
|
continue;
|
|
vty_out(vty, " gsmtap-category gprs %s%s", category_buf, VTY_NEWLINE);
|
|
}
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
void l23_vty_config_write_ms_node(struct vty *vty, const struct osmocom_ms *ms, const char *prefix)
|
|
{
|
|
size_t prefix_len = strlen(prefix);
|
|
char *prefix_content = alloca(prefix_len + 1 + 1);
|
|
|
|
memcpy(prefix_content, prefix, prefix_len);
|
|
prefix_content[prefix_len] = ' ';
|
|
prefix_content[prefix_len + 1] = '\0';
|
|
|
|
vty_out(vty, "%sms %s%s", prefix, ms->name, VTY_NEWLINE);
|
|
l23_vty_config_write_ms_node_contents(vty, ms, prefix_content);
|
|
l23_vty_config_write_ms_node_contents_final(vty, ms, prefix_content);
|
|
}
|
|
|
|
/* placeholder for shared VTY commands */
|
|
void l23_vty_config_write_ms_node_contents(struct vty *vty, const struct osmocom_ms *ms, const char *prefix)
|
|
{
|
|
const struct gsm_settings *set = &ms->settings;
|
|
|
|
vty_out(vty, "%slayer2-socket %s%s", prefix, set->layer2_socket_path,
|
|
VTY_NEWLINE);
|
|
}
|
|
|
|
/* placeholder for shared VTY commands. Must be put at the end of the node: */
|
|
void l23_vty_config_write_ms_node_contents_final(struct vty *vty, const struct osmocom_ms *ms, const char *prefix)
|
|
{
|
|
/* no shutdown must be written to config, because shutdown is default */
|
|
vty_out(vty, "%s%sshutdown%s", prefix, (ms->shutdown != MS_SHUTDOWN_NONE) ? "" : "no ",
|
|
VTY_NEWLINE);
|
|
vty_out(vty, "!%s", VTY_NEWLINE);
|
|
}
|
|
|
|
static void l23_vty_init_gsmtap(void)
|
|
{
|
|
cfg_gsmtap_gsmtap_sapi_cmd.string = vty_cmd_string_from_valstr(l23_ctx, gsmtap_sapi_names,
|
|
"gsmtap-sapi (",
|
|
"|", ")", VTY_DO_LOWER);
|
|
cfg_gsmtap_gsmtap_sapi_cmd.doc = vty_cmd_string_from_valstr(l23_ctx, gsmtap_sapi_names,
|
|
"Enable sending of UL/DL messages over GSMTAP\n",
|
|
"\n", "", 0);
|
|
|
|
cfg_gsmtap_no_gsmtap_sapi_cmd.string = vty_cmd_string_from_valstr(l23_ctx, gsmtap_sapi_names,
|
|
"no gsmtap-sapi (",
|
|
"|", ")", VTY_DO_LOWER);
|
|
cfg_gsmtap_no_gsmtap_sapi_cmd.doc = vty_cmd_string_from_valstr(l23_ctx, gsmtap_sapi_names,
|
|
NO_STR "Disable sending of UL/DL messages over GSMTAP\n",
|
|
"\n", "", 0);
|
|
|
|
|
|
cfg_gsmtap_gsmtap_categ_gprs_cmd.string = vty_cmd_string_from_valstr(l23_ctx, gsmtap_categ_gprs_names,
|
|
"gsmtap-category gprs (",
|
|
"|", ")", VTY_DO_LOWER);
|
|
cfg_gsmtap_gsmtap_categ_gprs_cmd.doc = vty_cmd_string_from_valstr(l23_ctx, gsmtap_categ_gprs_help,
|
|
"GSMTAP Category\n" "GPRS\n",
|
|
"\n", "", 0);
|
|
cfg_gsmtap_no_gsmtap_categ_gprs_cmd.string = vty_cmd_string_from_valstr(l23_ctx, gsmtap_categ_gprs_names,
|
|
"no gsmtap-category gprs (",
|
|
"|", ")", VTY_DO_LOWER);
|
|
cfg_gsmtap_no_gsmtap_categ_gprs_cmd.doc = vty_cmd_string_from_valstr(l23_ctx, gsmtap_categ_gprs_help,
|
|
NO_STR "GSMTAP Category\n" "GPRS\n",
|
|
"\n", "", 0);
|
|
|
|
install_element(CONFIG_NODE, &l23_cfg_gsmtap_cmd);
|
|
|
|
install_node(&gsmtap_node, l23_vty_config_write_gsmtap_node);
|
|
install_element(GSMTAP_NODE, &cfg_gsmtap_gsmtap_remote_host_cmd);
|
|
install_element(GSMTAP_NODE, &cfg_gsmtap_no_gsmtap_remote_host_cmd);
|
|
install_element(GSMTAP_NODE, &cfg_gsmtap_gsmtap_sapi_all_cmd);
|
|
install_element(GSMTAP_NODE, &cfg_gsmtap_gsmtap_sapi_cmd);
|
|
install_element(GSMTAP_NODE, &cfg_gsmtap_no_gsmtap_sapi_cmd);
|
|
install_element(GSMTAP_NODE, &cfg_gsmtap_gsmtap_categ_gprs_all_cmd);
|
|
install_element(GSMTAP_NODE, &cfg_gsmtap_gsmtap_categ_gprs_cmd);
|
|
install_element(GSMTAP_NODE, &cfg_gsmtap_no_gsmtap_categ_gprs_cmd);
|
|
}
|
|
|
|
int l23_vty_init(int (*config_write_ms_node_cb)(struct vty *), osmo_signal_cbfn *l23_vty_signal_cb)
|
|
{
|
|
struct l23_app_info *app;
|
|
unsigned int app_supp_opt = 0x00;
|
|
int rc = 0;
|
|
|
|
app = l23_app_info();
|
|
if (app && app->cfg_supported != NULL)
|
|
app_supp_opt = app->cfg_supported();
|
|
|
|
if (app_supp_opt & L23_OPT_TAP)
|
|
l23_vty_init_gsmtap();
|
|
|
|
install_node(&ms_node, config_write_ms_node_cb);
|
|
install_element(MS_NODE, &cfg_ms_layer2_cmd);
|
|
install_element(MS_NODE, &cfg_ms_shutdown_cmd);
|
|
install_element(MS_NODE, &cfg_ms_shutdown_force_cmd);
|
|
install_element(MS_NODE, &cfg_ms_no_shutdown_cmd);
|
|
|
|
/* Register the talloc context introspection command */
|
|
osmo_talloc_vty_add_cmds();
|
|
if (l23_vty_signal_cb)
|
|
rc = osmo_signal_register_handler(SS_L23_VTY, l23_vty_signal_cb, NULL);
|
|
return rc;
|
|
}
|
|
|