aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2010-05-16 20:52:23 +0200
committerHarald Welte <laforge@gnumonks.org>2010-05-16 20:52:23 +0200
commitdcccb1818da12041d08469ce2ab2ccd191187100 (patch)
treef2bb70dd3b130e8afa4c8c4c2a8e7689867843ec /openbsc/src
parent88907a2f92523c56bf5250c3c75230601eb2f604 (diff)
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.
Diffstat (limited to 'openbsc/src')
-rw-r--r--openbsc/src/bsc_hack.c10
-rw-r--r--openbsc/src/bsc_init.c12
-rw-r--r--openbsc/src/gprs/gb_proxy_main.c20
-rw-r--r--openbsc/src/gprs/gb_proxy_vty.c2
-rw-r--r--openbsc/src/gprs/sgsn_main.c20
-rw-r--r--openbsc/src/gprs/sgsn_vty.c2
-rw-r--r--openbsc/src/mgcp/mgcp_main.c20
-rw-r--r--openbsc/src/mgcp/mgcp_vty.c2
-rw-r--r--openbsc/src/telnet_interface.c54
-rw-r--r--openbsc/src/vty/vty.c17
-rw-r--r--openbsc/src/vty_interface.c64
-rw-r--r--openbsc/src/vty_interface_cmds.c11
-rw-r--r--openbsc/src/vty_interface_layer3.c28
13 files changed, 149 insertions, 113 deletions
diff --git a/openbsc/src/bsc_hack.c b/openbsc/src/bsc_hack.c
index 74351229f..fa058aa4c 100644
--- a/openbsc/src/bsc_hack.c
+++ b/openbsc/src/bsc_hack.c
@@ -37,11 +37,16 @@
#include <osmocore/talloc.h>
#include <openbsc/signal.h>
+#include <vty/command.h>
+
+#include "../bscconfig.h"
+
/* MCC and MNC for the Location Area Identifier */
static struct log_target *stderr_target;
struct gsm_network *bsc_gsmnet = 0;
static const char *database_name = "hlr.sqlite3";
static const char *config_file = "openbsc.cfg";
+extern const char *openbsc_copyright;
/* timer to store statistics */
#define DB_SYNC_INTERVAL 60, 0
@@ -213,7 +218,10 @@ int main(int argc, char **argv)
/* enable filters */
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);
if (rc < 0)
exit(1);
diff --git a/openbsc/src/bsc_init.c b/openbsc/src/bsc_init.c
index 77446a2c1..7db4d3137 100644
--- a/openbsc/src/bsc_init.c
+++ b/openbsc/src/bsc_init.c
@@ -1,6 +1,6 @@
/* 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>
* 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 *),
const char *config_file)
{
+ struct telnet_connection dummy_conn;
struct gsm_bts *bts;
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_short = talloc_strdup(bsc_gsmnet, "OpenBSC");
- telnet_init(bsc_gsmnet, 4242);
- rc = vty_read_config_file(config_file);
+ /* our vty command code expects vty->priv to point to a telnet_connection */
+ dummy_conn.priv = bsc_gsmnet;
+ rc = vty_read_config_file(config_file, &dummy_conn);
if (rc < 0) {
LOGP(DNM, LOGL_FATAL, "Failed to parse the config file: '%s'\n", config_file);
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);
llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
diff --git a/openbsc/src/gprs/gb_proxy_main.c b/openbsc/src/gprs/gb_proxy_main.c
index 9cd73e17d..e450d1fe6 100644
--- a/openbsc/src/gprs/gb_proxy_main.c
+++ b/openbsc/src/gprs/gb_proxy_main.c
@@ -205,12 +205,18 @@ int main(int argc, char **argv)
log_add_target(stderr_target);
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);
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);
if (!bssgp_nsi) {
LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n");
@@ -247,15 +253,3 @@ int main(int argc, char **argv)
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;
-}
-
diff --git a/openbsc/src/gprs/gb_proxy_vty.c b/openbsc/src/gprs/gb_proxy_vty.c
index a8501d11c..7ee2833ed 100644
--- a/openbsc/src/gprs/gb_proxy_vty.c
+++ b/openbsc/src/gprs/gb_proxy_vty.c
@@ -175,7 +175,7 @@ int gbproxy_parse_config(const char *config_file, struct gbproxy_config *cfg)
int rc;
g_cfg = cfg;
- rc = vty_read_config_file(config_file);
+ rc = vty_read_config_file(config_file, NULL);
if (rc < 0) {
fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
return rc;
diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c
index 81b130b12..aaad654e6 100644
--- a/openbsc/src/gprs/sgsn_main.c
+++ b/openbsc/src/gprs/sgsn_main.c
@@ -138,8 +138,14 @@ int main(int argc, char **argv)
log_add_target(stderr_target);
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);
- 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);
if (!sgsn_nsi) {
@@ -166,15 +172,3 @@ int main(int argc, char **argv)
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;
-}
-
diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c
index d56a27904..c16e1912f 100644
--- a/openbsc/src/gprs/sgsn_vty.c
+++ b/openbsc/src/gprs/sgsn_vty.c
@@ -139,7 +139,7 @@ int sgsn_parse_config(const char *config_file, struct sgsn_config *cfg)
int rc;
g_cfg = cfg;
- rc = vty_read_config_file(config_file);
+ rc = vty_read_config_file(config_file, NULL);
if (rc < 0) {
fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
return rc;
diff --git a/openbsc/src/mgcp/mgcp_main.c b/openbsc/src/mgcp/mgcp_main.c
index fd03c9943..63955e7d5 100644
--- a/openbsc/src/mgcp/mgcp_main.c
+++ b/openbsc/src/mgcp/mgcp_main.c
@@ -193,7 +193,9 @@ int main(int argc, char** argv)
if (!cfg)
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);
@@ -201,6 +203,10 @@ int main(int argc, char** argv)
if (rc < 0)
return rc;
+ rc = telnet_init(tall_bsc_ctx, &dummy_network, 4243);
+ if (rc < 0)
+ return rc;
+
/* set some callbacks */
cfg->reset_cb = mgcp_rsip_cb;
cfg->change_cb = mgcp_change_cb;
@@ -253,15 +259,3 @@ int main(int argc, char** argv)
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;
-}
-
diff --git a/openbsc/src/mgcp/mgcp_vty.c b/openbsc/src/mgcp/mgcp_vty.c
index 2804ce9b7..1e76839a3 100644
--- a/openbsc/src/mgcp/mgcp_vty.c
+++ b/openbsc/src/mgcp/mgcp_vty.c
@@ -267,7 +267,7 @@ int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg)
int i, rc;
g_cfg = cfg;
- rc = vty_read_config_file(config_file);
+ rc = vty_read_config_file(config_file, NULL);
if (rc < 0) {
fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
return rc;
diff --git a/openbsc/src/telnet_interface.c b/openbsc/src/telnet_interface.c
index 853cdf9a1..37e1c25ec 100644
--- a/openbsc/src/telnet_interface.c
+++ b/openbsc/src/telnet_interface.c
@@ -25,17 +25,10 @@
#include <string.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 <openbsc/abis_rsl.h>
-#include <openbsc/paging.h>
-#include <openbsc/signal.h>
#include <osmocore/talloc.h>
-#include <openbsc/debug.h>
+#include <osmocore/logging.h>
+#include <openbsc/telnet_interface.h>
#include <vty/buffer.h>
@@ -53,21 +46,19 @@ static struct bsc_fd server_socket = {
.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;
- 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");
- bsc_vty_init(network);
-
fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (fd < 0) {
- LOGP(DNM, LOGL_ERROR, "Telnet interface socket creation failed\n");
- return;
+ LOGP(0, LOGL_ERROR, "Telnet interface socket creation failed\n");
+ return fd;
}
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_addr.s_addr = htonl(INADDR_LOOPBACK);
- if (bind(fd, (struct sockaddr*)&sock_addr, sizeof(sock_addr)) < 0) {
- LOGP(DNM, LOGL_ERROR, "Telnet interface failed to bind\n");
- return;
+ rc = bind(fd, (struct sockaddr*)&sock_addr, sizeof(sock_addr));
+ if (bind < 0) {
+ LOGP(0, LOGL_ERROR, "Telnet interface failed to bind\n");
+ close(fd);
+ return rc;
}
- if (listen(fd, 0) < 0) {
- LOGP(DNM, LOGL_ERROR, "Telnet interface failed to listen\n");
- return;
+ rc = listen(fd, 0);
+ if (rc < 0) {
+ 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;
bsc_register_fd(&server_socket);
+
+ return 0;
}
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);
if (new_connection < 0) {
- LOGP(DNM, LOGL_ERROR, "telnet accept failed\n");
- return -1;
+ LOGP(0, LOGL_ERROR, "telnet accept failed\n");
+ return new_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.fd = new_connection;
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);
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;
}
diff --git a/openbsc/src/vty/vty.c b/openbsc/src/vty/vty.c
index 821c08c5d..438b6c36e 100644
--- a/openbsc/src/vty/vty.c
+++ b/openbsc/src/vty/vty.c
@@ -1354,7 +1354,7 @@ int vty_read(struct vty *vty)
/* Read up configuration file */
static int
-vty_read_file(FILE *confp)
+vty_read_file(FILE *confp, void *priv)
{
int ret;
struct vty *vty;
@@ -1363,6 +1363,7 @@ vty_read_file(FILE *confp)
vty->fd = 0;
vty->type = VTY_FILE;
vty->node = CONFIG_NODE;
+ vty->priv = priv;
ret = config_from_file(vty, confp);
@@ -1634,14 +1635,16 @@ extern void *tall_bsc_ctx;
/* Install vty's own commands like `who' command. */
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_vec_ctx = talloc_named_const(tall_vty_ctx, 0, "vty_vector");
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. */
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);
}
-int vty_read_config_file(const char *file_name)
+int vty_read_config_file(const char *file_name, void *priv)
{
FILE *cfile;
int rc;
@@ -1673,7 +1676,7 @@ int vty_read_config_file(const char *file_name)
if (!cfile)
return -ENOENT;
- rc = vty_read_file(cfile);
+ rc = vty_read_file(cfile, priv);
fclose(cfile);
host_config_set(file_name);
diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c
index eaa0eac1d..e68dffd19 100644
--- a/openbsc/src/vty_interface.c
+++ b/openbsc/src/vty_interface.c
@@ -43,8 +43,6 @@
#include "../bscconfig.h"
-static struct gsm_network *gsmnet;
-
/* FIXME: this should go to some common file */
static const struct value_string gprs_ns_timer_strs[] = {
{ 0, "tns-block" },
@@ -96,6 +94,12 @@ struct cmd_node ts_node = {
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)
{
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",
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);
return CMD_SUCCESS;
@@ -235,7 +239,7 @@ DEFUN(show_bts, show_bts_cmd, "show bts [number]",
SHOW_STR "Display information about a BTS\n"
"BTS number")
{
- struct gsm_network *net = gsmnet;
+ struct gsm_network *net = gsmnet_from_vty(vty);
int bts_nr;
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)
{
+ struct gsm_network *gsmnet = gsmnet_from_vty(v);
struct gsm_bts *bts;
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)
{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+
vty_out(vty, "network%s", 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);
@@ -491,7 +498,7 @@ DEFUN(show_trx,
"BTS 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_trx *trx;
int bts_nr, trx_nr;
@@ -557,7 +564,7 @@ DEFUN(show_ts,
SHOW_STR "Display information about a TS\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_trx *trx;
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,
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_trx *trx;
struct gsm_bts_trx_ts *ts;
@@ -935,7 +942,7 @@ DEFUN(show_paging,
SHOW_STR "Display information about paging reuqests of a BTS\n"
"BTS Number\n")
{
- struct gsm_network *net = gsmnet;
+ struct gsm_network *net = gsmnet_from_vty(vty);
struct gsm_bts *bts;
int bts_nr;
@@ -966,7 +973,7 @@ DEFUN(cfg_net,
cfg_net_cmd,
"network", NETWORK_STR)
{
- vty->index = gsmnet;
+ vty->index = gsmnet_from_vty(vty);
vty->node = GSMNET_NODE;
return CMD_SUCCESS;
@@ -978,6 +985,8 @@ DEFUN(cfg_net_ncc,
"network country code <1-999>",
"Set the GSM network country code")
{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+
gsmnet->country_code = atoi(argv[0]);
return CMD_SUCCESS;
@@ -988,6 +997,8 @@ DEFUN(cfg_net_mnc,
"mobile network code <1-999>",
"Set the GSM mobile network code")
{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+
gsmnet->network_code = atoi(argv[0]);
return CMD_SUCCESS;
@@ -998,6 +1009,8 @@ DEFUN(cfg_net_name_short,
"short name NAME",
"Set the short GSM network name")
{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+
if (gsmnet->name_short)
talloc_free(gsmnet->name_short);
@@ -1011,6 +1024,8 @@ DEFUN(cfg_net_name_long,
"long name NAME",
"Set the long GSM network name")
{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+
if (gsmnet->name_long)
talloc_free(gsmnet->name_long);
@@ -1029,6 +1044,7 @@ DEFUN(cfg_net_auth_policy,
"Use SMS-token based authentication\n")
{
enum gsm_auth_policy policy = gsm_auth_policy_parse(argv[0]);
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
gsmnet->auth_policy = policy;
@@ -1040,6 +1056,8 @@ DEFUN(cfg_net_reject_cause,
"location updating reject cause <2-111>",
"Set the reject cause of location updating reject\n")
{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+
gsmnet->reject_cause = atoi(argv[0]);
return CMD_SUCCESS;
@@ -1052,6 +1070,8 @@ DEFUN(cfg_net_encryption,
"A5 encryption\n" "A5/0: No 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]);
return CMD_SUCCESS;
@@ -1063,6 +1083,8 @@ DEFUN(cfg_net_neci,
"New Establish Cause Indication\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]);
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-assisted\n")
{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+
gsmnet->rrlp.mode = rrlp_mode_parse(argv[0]);
return CMD_SUCCESS;
@@ -1085,6 +1109,8 @@ DEFUN(cfg_net_mm_info, cfg_net_mm_info_cmd,
"mm info (0|1)",
"Whether to send MM INFO after LOC UPD ACCEPT")
{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+
gsmnet->send_mm_info = atoi(argv[0]);
return CMD_SUCCESS;
@@ -1099,6 +1125,7 @@ DEFUN(cfg_net_handover, cfg_net_handover_cmd,
"Perform in-call handover\n")
{
int enable = atoi(argv[0]);
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
if (enable && ipacc_rtp_direct) {
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
"How many RxLev measurements are used for averaging")
{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
gsmnet->handover.win_rxlev_avg = atoi(argv[0]);
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
"How many RxQual measurements are used for averaging")
{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
gsmnet->handover.win_rxqual_avg = atoi(argv[0]);
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
"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]);
return CMD_SUCCESS;
}
@@ -1148,6 +1178,7 @@ DEFUN(cfg_net_ho_pwr_interval, cfg_net_ho_pwr_interval_cmd,
HO_PBUDGET_STR
"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]);
return CMD_SUCCESS;
}
@@ -1157,6 +1188,7 @@ DEFUN(cfg_net_ho_pwr_hysteresis, cfg_net_ho_pwr_hysteresis_cmd,
HO_PBUDGET_STR
"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]);
return CMD_SUCCESS;
}
@@ -1166,6 +1198,7 @@ DEFUN(cfg_net_ho_max_distance, cfg_net_ho_max_distance_cmd,
HANDOVER_STR
"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]);
return CMD_SUCCESS;
}
@@ -1177,6 +1210,7 @@ DEFUN(cfg_net_ho_max_distance, cfg_net_ho_max_distance_cmd,
"Configure GSM Timers\n" \
doc) \
{ \
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty); \
int value = atoi(argv[0]); \
\
if (value < 0 || value > 65535) { \
@@ -1209,6 +1243,7 @@ DEFUN(cfg_bts,
"Select a BTS to configure\n"
"BTS Number\n")
{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
int bts_nr = atoi(argv[0]);
struct gsm_bts *bts;
@@ -1943,16 +1978,11 @@ DEFUN(cfg_ts_e1_subslot,
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;
-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_bts_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_e1_subslot_cmd);
- bsc_vty_init_extra(net);
+ bsc_vty_init_extra();
return 0;
}
diff --git a/openbsc/src/vty_interface_cmds.c b/openbsc/src/vty_interface_cmds.c
index 06eb2a56a..619caf56d 100644
--- a/openbsc/src/vty_interface_cmds.c
+++ b/openbsc/src/vty_interface_cmds.c
@@ -19,17 +19,20 @@
*
*/
-#include <openbsc/vty.h>
-#include <openbsc/telnet_interface.h>
+#include <stdlib.h>
+#include <string.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/buffer.h>
#include <vty/vty.h>
-#include <stdlib.h>
-
static void _vty_output(struct log_target *tgt, const char *line)
{
struct vty *vty = tgt->tgt_vty.vty;
diff --git a/openbsc/src/vty_interface_layer3.c b/openbsc/src/vty_interface_layer3.c
index 202518e0e..c18aef345 100644
--- a/openbsc/src/vty_interface_layer3.c
+++ b/openbsc/src/vty_interface_layer3.c
@@ -43,7 +43,7 @@
#include <openbsc/debug.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 = {
SUBSCR_NODE,
@@ -103,6 +103,7 @@ DEFUN(cfg_subscr,
"subscriber IMSI",
"Select a Subscriber to configure\n")
{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
const char *imsi = argv[0];
struct gsm_subscriber *subscr;
@@ -175,6 +176,7 @@ DEFUN(show_subscr,
"show subscriber [IMSI]",
SHOW_STR "Display information about a subscriber\n")
{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
const char *imsi;
struct gsm_subscriber *subscr;
@@ -218,6 +220,7 @@ DEFUN(sms_send_pend,
"sms send pending",
"Send all pending SMS")
{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
struct gsm_sms *sms;
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);
/* 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->status_rep_req = 0;
sms->ud_hdr_ind = 0;
@@ -275,7 +278,8 @@ static int _send_sms_str(struct gsm_subscriber *receiver, char *str,
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)
{
if (!strcmp(type, "extension"))
@@ -302,7 +306,8 @@ DEFUN(subscriber_send_sms,
"subscriber " SUBSCR_TYPES " EXTEN sms send .LINE",
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;
int rc;
@@ -326,7 +331,8 @@ DEFUN(subscriber_silent_sms,
SUBSCR_HELP
"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;
int rc;
@@ -358,7 +364,8 @@ DEFUN(subscriber_silent_call_start,
SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
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;
if (!subscr) {
@@ -395,7 +402,8 @@ DEFUN(subscriber_silent_call_stop,
SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
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;
if (!subscr) {
@@ -526,7 +534,7 @@ DEFUN(show_stats,
"show statistics",
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);
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);
install_element_ve(&show_subscr_cmd);