VTY: decouple telnet_interface from 'struct gsmnet'
We want the VTY and telnet code to be independent from the BSC application(s). As a side note, we also like to eliminate static global variables for 'struct gsm_network' all over the code. As such, telnet_init() is now passed along a "private" pointer, which getst stored in telnet_connection.priv. This telnet_connection is then stored in vty->priv, which in turn gets dereferenced if anyone needs a reference to 'struct gsm_network' from the BSC vty code. Also: * vty_init() now calls cmd_init() * the ugliness that telnet_init() calls back into the application by means of bsc_vty_init() function has been removed. * telnet_init() now returns any errors, so the main program can exit e.g. if the port is already in use.
This commit is contained in:
parent
88907a2f92
commit
dcccb1818d
|
@ -21,23 +21,20 @@
|
||||||
#ifndef TELNET_INTERFACE_H
|
#ifndef TELNET_INTERFACE_H
|
||||||
#define TELNET_INTERFACE_H
|
#define TELNET_INTERFACE_H
|
||||||
|
|
||||||
#include "gsm_data.h"
|
#include <osmocore/logging.h>
|
||||||
#include <openbsc/debug.h>
|
|
||||||
#include <osmocore/select.h>
|
#include <osmocore/select.h>
|
||||||
|
|
||||||
#include <vty/vty.h>
|
#include <vty/vty.h>
|
||||||
|
|
||||||
struct telnet_connection {
|
struct telnet_connection {
|
||||||
struct llist_head entry;
|
struct llist_head entry;
|
||||||
struct gsm_network *network;
|
void *priv;
|
||||||
struct bsc_fd fd;
|
struct bsc_fd fd;
|
||||||
struct vty *vty;
|
struct vty *vty;
|
||||||
struct log_target *dbg;
|
struct log_target *dbg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void telnet_init(struct gsm_network *network, int port);
|
int telnet_init(void *tall_ctx, void *priv, int port);
|
||||||
|
|
||||||
int bsc_vty_init(struct gsm_network *net);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -129,7 +129,7 @@ static inline char *vty_newline(struct vty *vty)
|
||||||
|
|
||||||
/* Prototypes. */
|
/* Prototypes. */
|
||||||
void vty_init(const char *name, const char *version, const char *copyright);
|
void vty_init(const char *name, const char *version, const char *copyright);
|
||||||
int vty_read_config_file(const char *file_name);
|
int vty_read_config_file(const char *file_name, void *priv);
|
||||||
void vty_init_vtysh (void);
|
void vty_init_vtysh (void);
|
||||||
void vty_reset (void);
|
void vty_reset (void);
|
||||||
struct vty *vty_new (void);
|
struct vty *vty_new (void);
|
||||||
|
|
|
@ -37,11 +37,16 @@
|
||||||
#include <osmocore/talloc.h>
|
#include <osmocore/talloc.h>
|
||||||
#include <openbsc/signal.h>
|
#include <openbsc/signal.h>
|
||||||
|
|
||||||
|
#include <vty/command.h>
|
||||||
|
|
||||||
|
#include "../bscconfig.h"
|
||||||
|
|
||||||
/* MCC and MNC for the Location Area Identifier */
|
/* MCC and MNC for the Location Area Identifier */
|
||||||
static struct log_target *stderr_target;
|
static struct log_target *stderr_target;
|
||||||
struct gsm_network *bsc_gsmnet = 0;
|
struct gsm_network *bsc_gsmnet = 0;
|
||||||
static const char *database_name = "hlr.sqlite3";
|
static const char *database_name = "hlr.sqlite3";
|
||||||
static const char *config_file = "openbsc.cfg";
|
static const char *config_file = "openbsc.cfg";
|
||||||
|
extern const char *openbsc_copyright;
|
||||||
|
|
||||||
/* timer to store statistics */
|
/* timer to store statistics */
|
||||||
#define DB_SYNC_INTERVAL 60, 0
|
#define DB_SYNC_INTERVAL 60, 0
|
||||||
|
@ -213,7 +218,10 @@ int main(int argc, char **argv)
|
||||||
/* enable filters */
|
/* enable filters */
|
||||||
log_set_all_filter(stderr_target, 1);
|
log_set_all_filter(stderr_target, 1);
|
||||||
|
|
||||||
/* This needs to precede handle_options() as it calls vty_init() */
|
/* This needs to precede handle_options() */
|
||||||
|
vty_init("OpenBSC", PACKAGE_VERSION, openbsc_copyright);
|
||||||
|
bsc_vty_init();
|
||||||
|
|
||||||
rc = bsc_bootstrap_network(mncc_recv, config_file);
|
rc = bsc_bootstrap_network(mncc_recv, config_file);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* A hackish minimal BSC (+MSC +HLR) implementation */
|
/* A hackish minimal BSC (+MSC +HLR) implementation */
|
||||||
|
|
||||||
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
|
/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
|
||||||
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
|
@ -1062,6 +1062,7 @@ static int bootstrap_bts(struct gsm_bts *bts)
|
||||||
int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, int, void *),
|
int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, int, void *),
|
||||||
const char *config_file)
|
const char *config_file)
|
||||||
{
|
{
|
||||||
|
struct telnet_connection dummy_conn;
|
||||||
struct gsm_bts *bts;
|
struct gsm_bts *bts;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -1073,13 +1074,18 @@ int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, int, void *),
|
||||||
bsc_gsmnet->name_long = talloc_strdup(bsc_gsmnet, "OpenBSC");
|
bsc_gsmnet->name_long = talloc_strdup(bsc_gsmnet, "OpenBSC");
|
||||||
bsc_gsmnet->name_short = talloc_strdup(bsc_gsmnet, "OpenBSC");
|
bsc_gsmnet->name_short = talloc_strdup(bsc_gsmnet, "OpenBSC");
|
||||||
|
|
||||||
telnet_init(bsc_gsmnet, 4242);
|
/* our vty command code expects vty->priv to point to a telnet_connection */
|
||||||
rc = vty_read_config_file(config_file);
|
dummy_conn.priv = bsc_gsmnet;
|
||||||
|
rc = vty_read_config_file(config_file, &dummy_conn);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
LOGP(DNM, LOGL_FATAL, "Failed to parse the config file: '%s'\n", config_file);
|
LOGP(DNM, LOGL_FATAL, "Failed to parse the config file: '%s'\n", config_file);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = telnet_init(tall_bsc_ctx, bsc_gsmnet, 4242);
|
||||||
|
if (rc < 0)
|
||||||
|
return rc;
|
||||||
|
|
||||||
register_signal_handler(SS_NM, nm_sig_cb, NULL);
|
register_signal_handler(SS_NM, nm_sig_cb, NULL);
|
||||||
|
|
||||||
llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
|
llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
|
||||||
|
|
|
@ -205,12 +205,18 @@ int main(int argc, char **argv)
|
||||||
log_add_target(stderr_target);
|
log_add_target(stderr_target);
|
||||||
log_set_all_filter(stderr_target, 1);
|
log_set_all_filter(stderr_target, 1);
|
||||||
|
|
||||||
telnet_init(&dummy_network, 4246);
|
vty_init("Osmocom Gb Proxy", PACKAGE_VERSION, openbsc_copyright);
|
||||||
|
openbsc_vty_add_cmds();
|
||||||
|
gbproxy_vty_init();
|
||||||
|
|
||||||
handle_options(argc, argv);
|
handle_options(argc, argv);
|
||||||
|
|
||||||
rate_ctr_init(tall_bsc_ctx);
|
rate_ctr_init(tall_bsc_ctx);
|
||||||
|
|
||||||
|
rc = telnet_init(tall_bsc_ctx, &dummy_network, 4246);
|
||||||
|
if (rc < 0)
|
||||||
|
exit(1);
|
||||||
|
|
||||||
bssgp_nsi = gprs_ns_instantiate(&proxy_ns_cb);
|
bssgp_nsi = gprs_ns_instantiate(&proxy_ns_cb);
|
||||||
if (!bssgp_nsi) {
|
if (!bssgp_nsi) {
|
||||||
LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n");
|
LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n");
|
||||||
|
@ -247,15 +253,3 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gsm_network;
|
|
||||||
int bsc_vty_init(struct gsm_network *dummy)
|
|
||||||
{
|
|
||||||
cmd_init(1);
|
|
||||||
vty_init("Osmocom Gb Proxy", PACKAGE_VERSION, openbsc_copyright);
|
|
||||||
|
|
||||||
openbsc_vty_add_cmds();
|
|
||||||
gbproxy_vty_init();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -175,7 +175,7 @@ int gbproxy_parse_config(const char *config_file, struct gbproxy_config *cfg)
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
g_cfg = cfg;
|
g_cfg = cfg;
|
||||||
rc = vty_read_config_file(config_file);
|
rc = vty_read_config_file(config_file, NULL);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
|
fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -138,8 +138,14 @@ int main(int argc, char **argv)
|
||||||
log_add_target(stderr_target);
|
log_add_target(stderr_target);
|
||||||
log_set_all_filter(stderr_target, 1);
|
log_set_all_filter(stderr_target, 1);
|
||||||
|
|
||||||
|
vty_init("Osmocom SGSN", PACKAGE_VERSION, openbsc_copyright);
|
||||||
|
openbsc_vty_add_cmds();
|
||||||
|
sgsn_vty_init();
|
||||||
|
|
||||||
rate_ctr_init(tall_bsc_ctx);
|
rate_ctr_init(tall_bsc_ctx);
|
||||||
telnet_init(&dummy_network, 4245);
|
rc = telnet_init(tall_bsc_ctx, &dummy_network, 4245);
|
||||||
|
if (rc < 0)
|
||||||
|
exit(1);
|
||||||
|
|
||||||
sgsn_nsi = gprs_ns_instantiate(&sgsn_ns_cb);
|
sgsn_nsi = gprs_ns_instantiate(&sgsn_ns_cb);
|
||||||
if (!sgsn_nsi) {
|
if (!sgsn_nsi) {
|
||||||
|
@ -166,15 +172,3 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gsm_network;
|
|
||||||
int bsc_vty_init(struct gsm_network *dummy)
|
|
||||||
{
|
|
||||||
cmd_init(1);
|
|
||||||
vty_init("Osmocom SGSN", PACKAGE_VERSION, openbsc_copyright);
|
|
||||||
|
|
||||||
openbsc_vty_add_cmds();
|
|
||||||
sgsn_vty_init();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -139,7 +139,7 @@ int sgsn_parse_config(const char *config_file, struct sgsn_config *cfg)
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
g_cfg = cfg;
|
g_cfg = cfg;
|
||||||
rc = vty_read_config_file(config_file);
|
rc = vty_read_config_file(config_file, NULL);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
|
fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -193,7 +193,9 @@ int main(int argc, char** argv)
|
||||||
if (!cfg)
|
if (!cfg)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
telnet_init(&dummy_network, 4243);
|
vty_init("OpenBSC MGCP", PACKAGE_VERSION, openbsc_copyright);
|
||||||
|
openbsc_vty_add_cmds();
|
||||||
|
mgcp_vty_init();
|
||||||
|
|
||||||
handle_options(argc, argv);
|
handle_options(argc, argv);
|
||||||
|
|
||||||
|
@ -201,6 +203,10 @@ int main(int argc, char** argv)
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
rc = telnet_init(tall_bsc_ctx, &dummy_network, 4243);
|
||||||
|
if (rc < 0)
|
||||||
|
return rc;
|
||||||
|
|
||||||
/* set some callbacks */
|
/* set some callbacks */
|
||||||
cfg->reset_cb = mgcp_rsip_cb;
|
cfg->reset_cb = mgcp_rsip_cb;
|
||||||
cfg->change_cb = mgcp_change_cb;
|
cfg->change_cb = mgcp_change_cb;
|
||||||
|
@ -253,15 +259,3 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gsm_network;
|
|
||||||
int bsc_vty_init(struct gsm_network *dummy)
|
|
||||||
{
|
|
||||||
cmd_init(1);
|
|
||||||
vty_init("OpenBSC MGCP", PACKAGE_VERSION, openbsc_copyright);
|
|
||||||
|
|
||||||
openbsc_vty_add_cmds();
|
|
||||||
mgcp_vty_init();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -267,7 +267,7 @@ int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg)
|
||||||
int i, rc;
|
int i, rc;
|
||||||
|
|
||||||
g_cfg = cfg;
|
g_cfg = cfg;
|
||||||
rc = vty_read_config_file(config_file);
|
rc = vty_read_config_file(config_file, NULL);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
|
fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -25,17 +25,10 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <openbsc/telnet_interface.h>
|
|
||||||
#include <openbsc/gsm_subscriber.h>
|
|
||||||
#include <openbsc/chan_alloc.h>
|
|
||||||
#include <openbsc/gsm_04_08.h>
|
|
||||||
#include <openbsc/gsm_04_11.h>
|
|
||||||
#include <osmocore/msgb.h>
|
#include <osmocore/msgb.h>
|
||||||
#include <openbsc/abis_rsl.h>
|
|
||||||
#include <openbsc/paging.h>
|
|
||||||
#include <openbsc/signal.h>
|
|
||||||
#include <osmocore/talloc.h>
|
#include <osmocore/talloc.h>
|
||||||
#include <openbsc/debug.h>
|
#include <osmocore/logging.h>
|
||||||
|
#include <openbsc/telnet_interface.h>
|
||||||
|
|
||||||
#include <vty/buffer.h>
|
#include <vty/buffer.h>
|
||||||
|
|
||||||
|
@ -53,21 +46,19 @@ static struct bsc_fd server_socket = {
|
||||||
.priv_nr = 0,
|
.priv_nr = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
void telnet_init(struct gsm_network *network, int port)
|
int telnet_init(void *tall_ctx, void *priv, int port)
|
||||||
{
|
{
|
||||||
struct sockaddr_in sock_addr;
|
struct sockaddr_in sock_addr;
|
||||||
int fd, on = 1;
|
int fd, rc, on = 1;
|
||||||
|
|
||||||
tall_telnet_ctx = talloc_named_const(tall_bsc_ctx, 1,
|
tall_telnet_ctx = talloc_named_const(tall_ctx, 1,
|
||||||
"telnet_connection");
|
"telnet_connection");
|
||||||
|
|
||||||
bsc_vty_init(network);
|
|
||||||
|
|
||||||
fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
LOGP(DNM, LOGL_ERROR, "Telnet interface socket creation failed\n");
|
LOGP(0, LOGL_ERROR, "Telnet interface socket creation failed\n");
|
||||||
return;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
||||||
|
@ -77,19 +68,25 @@ void telnet_init(struct gsm_network *network, int port)
|
||||||
sock_addr.sin_port = htons(port);
|
sock_addr.sin_port = htons(port);
|
||||||
sock_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
sock_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||||
|
|
||||||
if (bind(fd, (struct sockaddr*)&sock_addr, sizeof(sock_addr)) < 0) {
|
rc = bind(fd, (struct sockaddr*)&sock_addr, sizeof(sock_addr));
|
||||||
LOGP(DNM, LOGL_ERROR, "Telnet interface failed to bind\n");
|
if (bind < 0) {
|
||||||
return;
|
LOGP(0, LOGL_ERROR, "Telnet interface failed to bind\n");
|
||||||
|
close(fd);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listen(fd, 0) < 0) {
|
rc = listen(fd, 0);
|
||||||
LOGP(DNM, LOGL_ERROR, "Telnet interface failed to listen\n");
|
if (rc < 0) {
|
||||||
return;
|
LOGP(0, LOGL_ERROR, "Telnet interface failed to listen\n");
|
||||||
|
close(fd);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
server_socket.data = network;
|
server_socket.data = priv;
|
||||||
server_socket.fd = fd;
|
server_socket.fd = fd;
|
||||||
bsc_register_fd(&server_socket);
|
bsc_register_fd(&server_socket);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern const char *openbsc_copyright;
|
extern const char *openbsc_copyright;
|
||||||
|
@ -152,13 +149,12 @@ static int telnet_new_connection(struct bsc_fd *fd, unsigned int what)
|
||||||
int new_connection = accept(fd->fd, (struct sockaddr*)&sockaddr, &len);
|
int new_connection = accept(fd->fd, (struct sockaddr*)&sockaddr, &len);
|
||||||
|
|
||||||
if (new_connection < 0) {
|
if (new_connection < 0) {
|
||||||
LOGP(DNM, LOGL_ERROR, "telnet accept failed\n");
|
LOGP(0, LOGL_ERROR, "telnet accept failed\n");
|
||||||
return -1;
|
return new_connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
connection = talloc_zero(tall_telnet_ctx, struct telnet_connection);
|
connection = talloc_zero(tall_telnet_ctx, struct telnet_connection);
|
||||||
connection->network = (struct gsm_network*)fd->data;
|
connection->priv = fd->data;
|
||||||
connection->fd.data = connection;
|
connection->fd.data = connection;
|
||||||
connection->fd.fd = new_connection;
|
connection->fd.fd = new_connection;
|
||||||
connection->fd.when = BSC_FD_READ;
|
connection->fd.when = BSC_FD_READ;
|
||||||
|
@ -170,7 +166,9 @@ static int telnet_new_connection(struct bsc_fd *fd, unsigned int what)
|
||||||
|
|
||||||
connection->vty = vty_create(new_connection, connection);
|
connection->vty = vty_create(new_connection, connection);
|
||||||
if (!connection->vty) {
|
if (!connection->vty) {
|
||||||
LOGP(DNM, LOGL_ERROR, "couldn't create VTY\n");
|
LOGP(0, LOGL_ERROR, "couldn't create VTY\n");
|
||||||
|
close(new_connection);
|
||||||
|
talloc_free(connection);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1354,7 +1354,7 @@ int vty_read(struct vty *vty)
|
||||||
|
|
||||||
/* Read up configuration file */
|
/* Read up configuration file */
|
||||||
static int
|
static int
|
||||||
vty_read_file(FILE *confp)
|
vty_read_file(FILE *confp, void *priv)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct vty *vty;
|
struct vty *vty;
|
||||||
|
@ -1363,6 +1363,7 @@ vty_read_file(FILE *confp)
|
||||||
vty->fd = 0;
|
vty->fd = 0;
|
||||||
vty->type = VTY_FILE;
|
vty->type = VTY_FILE;
|
||||||
vty->node = CONFIG_NODE;
|
vty->node = CONFIG_NODE;
|
||||||
|
vty->priv = priv;
|
||||||
|
|
||||||
ret = config_from_file(vty, confp);
|
ret = config_from_file(vty, confp);
|
||||||
|
|
||||||
|
@ -1634,14 +1635,16 @@ extern void *tall_bsc_ctx;
|
||||||
/* Install vty's own commands like `who' command. */
|
/* Install vty's own commands like `who' command. */
|
||||||
void vty_init(const char *name, const char *version, const char *copyright)
|
void vty_init(const char *name, const char *version, const char *copyright)
|
||||||
{
|
{
|
||||||
host.prog_name = name;
|
|
||||||
host.prog_version = version;
|
|
||||||
host.prog_copyright = copyright;
|
|
||||||
|
|
||||||
tall_vty_ctx = talloc_named_const(NULL, 0, "vty");
|
tall_vty_ctx = talloc_named_const(NULL, 0, "vty");
|
||||||
tall_vty_vec_ctx = talloc_named_const(tall_vty_ctx, 0, "vty_vector");
|
tall_vty_vec_ctx = talloc_named_const(tall_vty_ctx, 0, "vty_vector");
|
||||||
tall_vty_cmd_ctx = talloc_named_const(tall_vty_ctx, 0, "vty_command");
|
tall_vty_cmd_ctx = talloc_named_const(tall_vty_ctx, 0, "vty_command");
|
||||||
|
|
||||||
|
cmd_init(1);
|
||||||
|
|
||||||
|
host.prog_name = name;
|
||||||
|
host.prog_version = version;
|
||||||
|
host.prog_copyright = copyright;
|
||||||
|
|
||||||
/* For further configuration read, preserve current directory. */
|
/* For further configuration read, preserve current directory. */
|
||||||
vty_save_cwd();
|
vty_save_cwd();
|
||||||
|
|
||||||
|
@ -1664,7 +1667,7 @@ void vty_init(const char *name, const char *version, const char *copyright)
|
||||||
install_element(VTY_NODE, &no_vty_login_cmd);
|
install_element(VTY_NODE, &no_vty_login_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int vty_read_config_file(const char *file_name)
|
int vty_read_config_file(const char *file_name, void *priv)
|
||||||
{
|
{
|
||||||
FILE *cfile;
|
FILE *cfile;
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -1673,7 +1676,7 @@ int vty_read_config_file(const char *file_name)
|
||||||
if (!cfile)
|
if (!cfile)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
rc = vty_read_file(cfile);
|
rc = vty_read_file(cfile, priv);
|
||||||
fclose(cfile);
|
fclose(cfile);
|
||||||
|
|
||||||
host_config_set(file_name);
|
host_config_set(file_name);
|
||||||
|
|
|
@ -43,8 +43,6 @@
|
||||||
|
|
||||||
#include "../bscconfig.h"
|
#include "../bscconfig.h"
|
||||||
|
|
||||||
static struct gsm_network *gsmnet;
|
|
||||||
|
|
||||||
/* FIXME: this should go to some common file */
|
/* FIXME: this should go to some common file */
|
||||||
static const struct value_string gprs_ns_timer_strs[] = {
|
static const struct value_string gprs_ns_timer_strs[] = {
|
||||||
{ 0, "tns-block" },
|
{ 0, "tns-block" },
|
||||||
|
@ -96,6 +94,12 @@ struct cmd_node ts_node = {
|
||||||
1,
|
1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct gsm_network *gsmnet_from_vty(struct vty *v)
|
||||||
|
{
|
||||||
|
struct telnet_connection *conn = v->priv;
|
||||||
|
return (struct gsm_network *) conn->priv;
|
||||||
|
}
|
||||||
|
|
||||||
static int dummy_config_write(struct vty *v)
|
static int dummy_config_write(struct vty *v)
|
||||||
{
|
{
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
@ -161,7 +165,7 @@ static void net_dump_vty(struct vty *vty, struct gsm_network *net)
|
||||||
DEFUN(show_net, show_net_cmd, "show network",
|
DEFUN(show_net, show_net_cmd, "show network",
|
||||||
SHOW_STR "Display information about a GSM NETWORK\n")
|
SHOW_STR "Display information about a GSM NETWORK\n")
|
||||||
{
|
{
|
||||||
struct gsm_network *net = gsmnet;
|
struct gsm_network *net = gsmnet_from_vty(vty);
|
||||||
net_dump_vty(vty, net);
|
net_dump_vty(vty, net);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
@ -235,7 +239,7 @@ DEFUN(show_bts, show_bts_cmd, "show bts [number]",
|
||||||
SHOW_STR "Display information about a BTS\n"
|
SHOW_STR "Display information about a BTS\n"
|
||||||
"BTS number")
|
"BTS number")
|
||||||
{
|
{
|
||||||
struct gsm_network *net = gsmnet;
|
struct gsm_network *net = gsmnet_from_vty(vty);
|
||||||
int bts_nr;
|
int bts_nr;
|
||||||
|
|
||||||
if (argc != 0) {
|
if (argc != 0) {
|
||||||
|
@ -410,6 +414,7 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
|
||||||
|
|
||||||
static int config_write_bts(struct vty *v)
|
static int config_write_bts(struct vty *v)
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(v);
|
||||||
struct gsm_bts *bts;
|
struct gsm_bts *bts;
|
||||||
|
|
||||||
llist_for_each_entry(bts, &gsmnet->bts_list, list)
|
llist_for_each_entry(bts, &gsmnet->bts_list, list)
|
||||||
|
@ -420,6 +425,8 @@ static int config_write_bts(struct vty *v)
|
||||||
|
|
||||||
static int config_write_net(struct vty *vty)
|
static int config_write_net(struct vty *vty)
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
|
|
||||||
vty_out(vty, "network%s", VTY_NEWLINE);
|
vty_out(vty, "network%s", VTY_NEWLINE);
|
||||||
vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
|
vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
|
||||||
vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
|
vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
|
||||||
|
@ -491,7 +498,7 @@ DEFUN(show_trx,
|
||||||
"BTS Number\n"
|
"BTS Number\n"
|
||||||
"TRX Number\n")
|
"TRX Number\n")
|
||||||
{
|
{
|
||||||
struct gsm_network *net = gsmnet;
|
struct gsm_network *net = gsmnet_from_vty(vty);
|
||||||
struct gsm_bts *bts = NULL;
|
struct gsm_bts *bts = NULL;
|
||||||
struct gsm_bts_trx *trx;
|
struct gsm_bts_trx *trx;
|
||||||
int bts_nr, trx_nr;
|
int bts_nr, trx_nr;
|
||||||
|
@ -557,7 +564,7 @@ DEFUN(show_ts,
|
||||||
SHOW_STR "Display information about a TS\n"
|
SHOW_STR "Display information about a TS\n"
|
||||||
"BTS Number\n" "TRX Number\n" "Timeslot Number\n")
|
"BTS Number\n" "TRX Number\n" "Timeslot Number\n")
|
||||||
{
|
{
|
||||||
struct gsm_network *net = gsmnet;
|
struct gsm_network *net = gsmnet_from_vty(vty);
|
||||||
struct gsm_bts *bts;
|
struct gsm_bts *bts;
|
||||||
struct gsm_bts_trx *trx;
|
struct gsm_bts_trx *trx;
|
||||||
struct gsm_bts_trx_ts *ts;
|
struct gsm_bts_trx_ts *ts;
|
||||||
|
@ -717,7 +724,7 @@ static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
|
||||||
static int lchan_summary(struct vty *vty, int argc, const char **argv,
|
static int lchan_summary(struct vty *vty, int argc, const char **argv,
|
||||||
void (*dump_cb)(struct vty *, struct gsm_lchan *))
|
void (*dump_cb)(struct vty *, struct gsm_lchan *))
|
||||||
{
|
{
|
||||||
struct gsm_network *net = gsmnet;
|
struct gsm_network *net = gsmnet_from_vty(vty);
|
||||||
struct gsm_bts *bts;
|
struct gsm_bts *bts;
|
||||||
struct gsm_bts_trx *trx;
|
struct gsm_bts_trx *trx;
|
||||||
struct gsm_bts_trx_ts *ts;
|
struct gsm_bts_trx_ts *ts;
|
||||||
|
@ -935,7 +942,7 @@ DEFUN(show_paging,
|
||||||
SHOW_STR "Display information about paging reuqests of a BTS\n"
|
SHOW_STR "Display information about paging reuqests of a BTS\n"
|
||||||
"BTS Number\n")
|
"BTS Number\n")
|
||||||
{
|
{
|
||||||
struct gsm_network *net = gsmnet;
|
struct gsm_network *net = gsmnet_from_vty(vty);
|
||||||
struct gsm_bts *bts;
|
struct gsm_bts *bts;
|
||||||
int bts_nr;
|
int bts_nr;
|
||||||
|
|
||||||
|
@ -966,7 +973,7 @@ DEFUN(cfg_net,
|
||||||
cfg_net_cmd,
|
cfg_net_cmd,
|
||||||
"network", NETWORK_STR)
|
"network", NETWORK_STR)
|
||||||
{
|
{
|
||||||
vty->index = gsmnet;
|
vty->index = gsmnet_from_vty(vty);
|
||||||
vty->node = GSMNET_NODE;
|
vty->node = GSMNET_NODE;
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
@ -978,6 +985,8 @@ DEFUN(cfg_net_ncc,
|
||||||
"network country code <1-999>",
|
"network country code <1-999>",
|
||||||
"Set the GSM network country code")
|
"Set the GSM network country code")
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
|
|
||||||
gsmnet->country_code = atoi(argv[0]);
|
gsmnet->country_code = atoi(argv[0]);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
@ -988,6 +997,8 @@ DEFUN(cfg_net_mnc,
|
||||||
"mobile network code <1-999>",
|
"mobile network code <1-999>",
|
||||||
"Set the GSM mobile network code")
|
"Set the GSM mobile network code")
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
|
|
||||||
gsmnet->network_code = atoi(argv[0]);
|
gsmnet->network_code = atoi(argv[0]);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
@ -998,6 +1009,8 @@ DEFUN(cfg_net_name_short,
|
||||||
"short name NAME",
|
"short name NAME",
|
||||||
"Set the short GSM network name")
|
"Set the short GSM network name")
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
|
|
||||||
if (gsmnet->name_short)
|
if (gsmnet->name_short)
|
||||||
talloc_free(gsmnet->name_short);
|
talloc_free(gsmnet->name_short);
|
||||||
|
|
||||||
|
@ -1011,6 +1024,8 @@ DEFUN(cfg_net_name_long,
|
||||||
"long name NAME",
|
"long name NAME",
|
||||||
"Set the long GSM network name")
|
"Set the long GSM network name")
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
|
|
||||||
if (gsmnet->name_long)
|
if (gsmnet->name_long)
|
||||||
talloc_free(gsmnet->name_long);
|
talloc_free(gsmnet->name_long);
|
||||||
|
|
||||||
|
@ -1029,6 +1044,7 @@ DEFUN(cfg_net_auth_policy,
|
||||||
"Use SMS-token based authentication\n")
|
"Use SMS-token based authentication\n")
|
||||||
{
|
{
|
||||||
enum gsm_auth_policy policy = gsm_auth_policy_parse(argv[0]);
|
enum gsm_auth_policy policy = gsm_auth_policy_parse(argv[0]);
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
|
|
||||||
gsmnet->auth_policy = policy;
|
gsmnet->auth_policy = policy;
|
||||||
|
|
||||||
|
@ -1040,6 +1056,8 @@ DEFUN(cfg_net_reject_cause,
|
||||||
"location updating reject cause <2-111>",
|
"location updating reject cause <2-111>",
|
||||||
"Set the reject cause of location updating reject\n")
|
"Set the reject cause of location updating reject\n")
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
|
|
||||||
gsmnet->reject_cause = atoi(argv[0]);
|
gsmnet->reject_cause = atoi(argv[0]);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
@ -1052,6 +1070,8 @@ DEFUN(cfg_net_encryption,
|
||||||
"A5 encryption\n" "A5/0: No encryption\n"
|
"A5 encryption\n" "A5/0: No encryption\n"
|
||||||
"A5/1: Encryption\n" "A5/2: Export-grade Encryption\n")
|
"A5/1: Encryption\n" "A5/2: Export-grade Encryption\n")
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
|
|
||||||
gsmnet->a5_encryption= atoi(argv[0]);
|
gsmnet->a5_encryption= atoi(argv[0]);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
@ -1063,6 +1083,8 @@ DEFUN(cfg_net_neci,
|
||||||
"New Establish Cause Indication\n"
|
"New Establish Cause Indication\n"
|
||||||
"Don't set the NECI bit\n" "Set the NECI bit\n")
|
"Don't set the NECI bit\n" "Set the NECI bit\n")
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
|
|
||||||
gsmnet->neci = atoi(argv[0]);
|
gsmnet->neci = atoi(argv[0]);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1076,6 +1098,8 @@ DEFUN(cfg_net_rrlp_mode, cfg_net_rrlp_mode_cmd,
|
||||||
"Request any location, prefer MS-based\n"
|
"Request any location, prefer MS-based\n"
|
||||||
"Request any location, prefer MS-assisted\n")
|
"Request any location, prefer MS-assisted\n")
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
|
|
||||||
gsmnet->rrlp.mode = rrlp_mode_parse(argv[0]);
|
gsmnet->rrlp.mode = rrlp_mode_parse(argv[0]);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
@ -1085,6 +1109,8 @@ DEFUN(cfg_net_mm_info, cfg_net_mm_info_cmd,
|
||||||
"mm info (0|1)",
|
"mm info (0|1)",
|
||||||
"Whether to send MM INFO after LOC UPD ACCEPT")
|
"Whether to send MM INFO after LOC UPD ACCEPT")
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
|
|
||||||
gsmnet->send_mm_info = atoi(argv[0]);
|
gsmnet->send_mm_info = atoi(argv[0]);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
@ -1099,6 +1125,7 @@ DEFUN(cfg_net_handover, cfg_net_handover_cmd,
|
||||||
"Perform in-call handover\n")
|
"Perform in-call handover\n")
|
||||||
{
|
{
|
||||||
int enable = atoi(argv[0]);
|
int enable = atoi(argv[0]);
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
|
|
||||||
if (enable && ipacc_rtp_direct) {
|
if (enable && ipacc_rtp_direct) {
|
||||||
vty_out(vty, "%% Cannot enable handover unless RTP Proxy mode "
|
vty_out(vty, "%% Cannot enable handover unless RTP Proxy mode "
|
||||||
|
@ -1121,6 +1148,7 @@ DEFUN(cfg_net_ho_win_rxlev_avg, cfg_net_ho_win_rxlev_avg_cmd,
|
||||||
HO_WIN_RXLEV_STR
|
HO_WIN_RXLEV_STR
|
||||||
"How many RxLev measurements are used for averaging")
|
"How many RxLev measurements are used for averaging")
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
gsmnet->handover.win_rxlev_avg = atoi(argv[0]);
|
gsmnet->handover.win_rxlev_avg = atoi(argv[0]);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1130,6 +1158,7 @@ DEFUN(cfg_net_ho_win_rxqual_avg, cfg_net_ho_win_rxqual_avg_cmd,
|
||||||
HO_WIN_RXQUAL_STR
|
HO_WIN_RXQUAL_STR
|
||||||
"How many RxQual measurements are used for averaging")
|
"How many RxQual measurements are used for averaging")
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
gsmnet->handover.win_rxqual_avg = atoi(argv[0]);
|
gsmnet->handover.win_rxqual_avg = atoi(argv[0]);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1139,6 +1168,7 @@ DEFUN(cfg_net_ho_win_rxlev_neigh_avg, cfg_net_ho_win_rxlev_avg_neigh_cmd,
|
||||||
HO_WIN_RXLEV_STR
|
HO_WIN_RXLEV_STR
|
||||||
"How many RxQual measurements are used for averaging")
|
"How many RxQual measurements are used for averaging")
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
gsmnet->handover.win_rxlev_avg_neigh = atoi(argv[0]);
|
gsmnet->handover.win_rxlev_avg_neigh = atoi(argv[0]);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1148,6 +1178,7 @@ DEFUN(cfg_net_ho_pwr_interval, cfg_net_ho_pwr_interval_cmd,
|
||||||
HO_PBUDGET_STR
|
HO_PBUDGET_STR
|
||||||
"How often to check if we have a better cell (SACCH frames)")
|
"How often to check if we have a better cell (SACCH frames)")
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
gsmnet->handover.pwr_interval = atoi(argv[0]);
|
gsmnet->handover.pwr_interval = atoi(argv[0]);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1157,6 +1188,7 @@ DEFUN(cfg_net_ho_pwr_hysteresis, cfg_net_ho_pwr_hysteresis_cmd,
|
||||||
HO_PBUDGET_STR
|
HO_PBUDGET_STR
|
||||||
"How many dB does a neighbor to be stronger to become a HO candidate")
|
"How many dB does a neighbor to be stronger to become a HO candidate")
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
gsmnet->handover.pwr_hysteresis = atoi(argv[0]);
|
gsmnet->handover.pwr_hysteresis = atoi(argv[0]);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1166,6 +1198,7 @@ DEFUN(cfg_net_ho_max_distance, cfg_net_ho_max_distance_cmd,
|
||||||
HANDOVER_STR
|
HANDOVER_STR
|
||||||
"How big is the maximum timing advance before HO is forced")
|
"How big is the maximum timing advance before HO is forced")
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
gsmnet->handover.max_distance = atoi(argv[0]);
|
gsmnet->handover.max_distance = atoi(argv[0]);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1177,6 +1210,7 @@ DEFUN(cfg_net_ho_max_distance, cfg_net_ho_max_distance_cmd,
|
||||||
"Configure GSM Timers\n" \
|
"Configure GSM Timers\n" \
|
||||||
doc) \
|
doc) \
|
||||||
{ \
|
{ \
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty); \
|
||||||
int value = atoi(argv[0]); \
|
int value = atoi(argv[0]); \
|
||||||
\
|
\
|
||||||
if (value < 0 || value > 65535) { \
|
if (value < 0 || value > 65535) { \
|
||||||
|
@ -1209,6 +1243,7 @@ DEFUN(cfg_bts,
|
||||||
"Select a BTS to configure\n"
|
"Select a BTS to configure\n"
|
||||||
"BTS Number\n")
|
"BTS Number\n")
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
int bts_nr = atoi(argv[0]);
|
int bts_nr = atoi(argv[0]);
|
||||||
struct gsm_bts *bts;
|
struct gsm_bts *bts;
|
||||||
|
|
||||||
|
@ -1943,16 +1978,11 @@ DEFUN(cfg_ts_e1_subslot,
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int bsc_vty_init_extra(struct gsm_network *net);
|
extern int bsc_vty_init_extra(void);
|
||||||
extern const char *openbsc_copyright;
|
extern const char *openbsc_copyright;
|
||||||
|
|
||||||
int bsc_vty_init(struct gsm_network *net)
|
int bsc_vty_init(void)
|
||||||
{
|
{
|
||||||
gsmnet = net;
|
|
||||||
|
|
||||||
cmd_init(1);
|
|
||||||
vty_init("OpenBSC", PACKAGE_VERSION, openbsc_copyright);
|
|
||||||
|
|
||||||
install_element_ve(&show_net_cmd);
|
install_element_ve(&show_net_cmd);
|
||||||
install_element_ve(&show_bts_cmd);
|
install_element_ve(&show_bts_cmd);
|
||||||
install_element_ve(&show_trx_cmd);
|
install_element_ve(&show_trx_cmd);
|
||||||
|
@ -2063,7 +2093,7 @@ int bsc_vty_init(struct gsm_network *net)
|
||||||
install_element(TS_NODE, &cfg_ts_pchan_cmd);
|
install_element(TS_NODE, &cfg_ts_pchan_cmd);
|
||||||
install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
|
install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
|
||||||
|
|
||||||
bsc_vty_init_extra(net);
|
bsc_vty_init_extra();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,17 +19,20 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <openbsc/vty.h>
|
#include <stdlib.h>
|
||||||
#include <openbsc/telnet_interface.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <osmocore/talloc.h>
|
#include <osmocore/talloc.h>
|
||||||
|
|
||||||
|
#include <openbsc/vty.h>
|
||||||
|
#include <openbsc/telnet_interface.h>
|
||||||
|
#include <openbsc/gsm_data.h>
|
||||||
|
#include <openbsc/debug.h>
|
||||||
|
|
||||||
#include <vty/command.h>
|
#include <vty/command.h>
|
||||||
#include <vty/buffer.h>
|
#include <vty/buffer.h>
|
||||||
#include <vty/vty.h>
|
#include <vty/vty.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
static void _vty_output(struct log_target *tgt, const char *line)
|
static void _vty_output(struct log_target *tgt, const char *line)
|
||||||
{
|
{
|
||||||
struct vty *vty = tgt->tgt_vty.vty;
|
struct vty *vty = tgt->tgt_vty.vty;
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
#include <openbsc/debug.h>
|
#include <openbsc/debug.h>
|
||||||
#include <openbsc/vty.h>
|
#include <openbsc/vty.h>
|
||||||
|
|
||||||
static struct gsm_network *gsmnet;
|
extern struct gsm_network *gsmnet_from_vty(struct vty *v);
|
||||||
|
|
||||||
struct cmd_node subscr_node = {
|
struct cmd_node subscr_node = {
|
||||||
SUBSCR_NODE,
|
SUBSCR_NODE,
|
||||||
|
@ -103,6 +103,7 @@ DEFUN(cfg_subscr,
|
||||||
"subscriber IMSI",
|
"subscriber IMSI",
|
||||||
"Select a Subscriber to configure\n")
|
"Select a Subscriber to configure\n")
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
const char *imsi = argv[0];
|
const char *imsi = argv[0];
|
||||||
struct gsm_subscriber *subscr;
|
struct gsm_subscriber *subscr;
|
||||||
|
|
||||||
|
@ -175,6 +176,7 @@ DEFUN(show_subscr,
|
||||||
"show subscriber [IMSI]",
|
"show subscriber [IMSI]",
|
||||||
SHOW_STR "Display information about a subscriber\n")
|
SHOW_STR "Display information about a subscriber\n")
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
const char *imsi;
|
const char *imsi;
|
||||||
struct gsm_subscriber *subscr;
|
struct gsm_subscriber *subscr;
|
||||||
|
|
||||||
|
@ -218,6 +220,7 @@ DEFUN(sms_send_pend,
|
||||||
"sms send pending",
|
"sms send pending",
|
||||||
"Send all pending SMS")
|
"Send all pending SMS")
|
||||||
{
|
{
|
||||||
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
struct gsm_sms *sms;
|
struct gsm_sms *sms;
|
||||||
int id = 0;
|
int id = 0;
|
||||||
|
|
||||||
|
@ -250,7 +253,7 @@ struct gsm_sms *sms_from_text(struct gsm_subscriber *receiver, const char *text)
|
||||||
strncpy(sms->text, text, sizeof(sms->text)-1);
|
strncpy(sms->text, text, sizeof(sms->text)-1);
|
||||||
|
|
||||||
/* FIXME: don't use ID 1 static */
|
/* FIXME: don't use ID 1 static */
|
||||||
sms->sender = subscr_get_by_id(gsmnet, 1);
|
sms->sender = subscr_get_by_id(receiver->net, 1);
|
||||||
sms->reply_path_req = 0;
|
sms->reply_path_req = 0;
|
||||||
sms->status_rep_req = 0;
|
sms->status_rep_req = 0;
|
||||||
sms->ud_hdr_ind = 0;
|
sms->ud_hdr_ind = 0;
|
||||||
|
@ -275,7 +278,8 @@ static int _send_sms_str(struct gsm_subscriber *receiver, char *str,
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct gsm_subscriber *get_subscr_by_argv(const char *type,
|
static struct gsm_subscriber *get_subscr_by_argv(struct gsm_network *gsmnet,
|
||||||
|
const char *type,
|
||||||
const char *id)
|
const char *id)
|
||||||
{
|
{
|
||||||
if (!strcmp(type, "extension"))
|
if (!strcmp(type, "extension"))
|
||||||
|
@ -302,7 +306,8 @@ DEFUN(subscriber_send_sms,
|
||||||
"subscriber " SUBSCR_TYPES " EXTEN sms send .LINE",
|
"subscriber " SUBSCR_TYPES " EXTEN sms send .LINE",
|
||||||
SUBSCR_HELP "SMS Operations\n" "Send SMS\n" "Actual SMS Text")
|
SUBSCR_HELP "SMS Operations\n" "Send SMS\n" "Actual SMS Text")
|
||||||
{
|
{
|
||||||
struct gsm_subscriber *subscr = get_subscr_by_argv(argv[0], argv[1]);
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
|
struct gsm_subscriber *subscr = get_subscr_by_argv(gsmnet, argv[0], argv[1]);
|
||||||
char *str;
|
char *str;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -326,7 +331,8 @@ DEFUN(subscriber_silent_sms,
|
||||||
SUBSCR_HELP
|
SUBSCR_HELP
|
||||||
"Silent SMS Operation\n" "Send Silent SMS\n" "Actual SMS text\n")
|
"Silent SMS Operation\n" "Send Silent SMS\n" "Actual SMS text\n")
|
||||||
{
|
{
|
||||||
struct gsm_subscriber *subscr = get_subscr_by_argv(argv[0], argv[1]);
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
|
struct gsm_subscriber *subscr = get_subscr_by_argv(gsmnet, argv[0], argv[1]);
|
||||||
char *str;
|
char *str;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -358,7 +364,8 @@ DEFUN(subscriber_silent_call_start,
|
||||||
SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
|
SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
|
||||||
CHAN_TYPE_HELP)
|
CHAN_TYPE_HELP)
|
||||||
{
|
{
|
||||||
struct gsm_subscriber *subscr = get_subscr_by_argv(argv[0], argv[1]);
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
|
struct gsm_subscriber *subscr = get_subscr_by_argv(gsmnet, argv[0], argv[1]);
|
||||||
int rc, type;
|
int rc, type;
|
||||||
|
|
||||||
if (!subscr) {
|
if (!subscr) {
|
||||||
|
@ -395,7 +402,8 @@ DEFUN(subscriber_silent_call_stop,
|
||||||
SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
|
SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
|
||||||
CHAN_TYPE_HELP)
|
CHAN_TYPE_HELP)
|
||||||
{
|
{
|
||||||
struct gsm_subscriber *subscr = get_subscr_by_argv(argv[0], argv[1]);
|
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||||
|
struct gsm_subscriber *subscr = get_subscr_by_argv(gsmnet, argv[0], argv[1]);
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!subscr) {
|
if (!subscr) {
|
||||||
|
@ -526,7 +534,7 @@ DEFUN(show_stats,
|
||||||
"show statistics",
|
"show statistics",
|
||||||
SHOW_STR "Display network statistics\n")
|
SHOW_STR "Display network statistics\n")
|
||||||
{
|
{
|
||||||
struct gsm_network *net = gsmnet;
|
struct gsm_network *net = gsmnet_from_vty(vty);
|
||||||
|
|
||||||
openbsc_vty_print_statistics(vty, net);
|
openbsc_vty_print_statistics(vty, net);
|
||||||
vty_out(vty, "Location Update : %lu attach, %lu normal, %lu periodic%s",
|
vty_out(vty, "Location Update : %lu attach, %lu normal, %lu periodic%s",
|
||||||
|
@ -556,10 +564,8 @@ DEFUN(show_stats,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int bsc_vty_init_extra(struct gsm_network *net)
|
int bsc_vty_init_extra(void)
|
||||||
{
|
{
|
||||||
gsmnet = net;
|
|
||||||
|
|
||||||
register_signal_handler(SS_SCALL, scall_cbfn, NULL);
|
register_signal_handler(SS_SCALL, scall_cbfn, NULL);
|
||||||
|
|
||||||
install_element_ve(&show_subscr_cmd);
|
install_element_ve(&show_subscr_cmd);
|
||||||
|
|
Loading…
Reference in New Issue