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:
Harald Welte 2010-05-16 20:52:23 +02:00
parent 88907a2f92
commit dcccb1818d
15 changed files with 153 additions and 120 deletions

View File

@ -21,23 +21,20 @@
#ifndef TELNET_INTERFACE_H
#define TELNET_INTERFACE_H
#include "gsm_data.h"
#include <openbsc/debug.h>
#include <osmocore/logging.h>
#include <osmocore/select.h>
#include <vty/vty.h>
struct telnet_connection {
struct llist_head entry;
struct gsm_network *network;
void *priv;
struct bsc_fd fd;
struct vty *vty;
struct log_target *dbg;
};
void telnet_init(struct gsm_network *network, int port);
int bsc_vty_init(struct gsm_network *net);
int telnet_init(void *tall_ctx, void *priv, int port);
#endif

View File

@ -129,7 +129,7 @@ static inline char *vty_newline(struct vty *vty)
/* Prototypes. */
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_reset (void);
struct vty *vty_new (void);

View File

@ -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);

View File

@ -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) {

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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);