From dcccb1818da12041d08469ce2ab2ccd191187100 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 16 May 2010 20:52:23 +0200 Subject: 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. --- openbsc/src/bsc_hack.c | 10 +++++- openbsc/src/bsc_init.c | 12 +++++-- openbsc/src/gprs/gb_proxy_main.c | 20 +++++------- openbsc/src/gprs/gb_proxy_vty.c | 2 +- openbsc/src/gprs/sgsn_main.c | 20 +++++------- openbsc/src/gprs/sgsn_vty.c | 2 +- openbsc/src/mgcp/mgcp_main.c | 20 +++++------- openbsc/src/mgcp/mgcp_vty.c | 2 +- openbsc/src/telnet_interface.c | 54 ++++++++++++++++---------------- openbsc/src/vty/vty.c | 17 +++++----- openbsc/src/vty_interface.c | 64 ++++++++++++++++++++++++++++---------- openbsc/src/vty_interface_cmds.c | 11 ++++--- openbsc/src/vty_interface_layer3.c | 28 ++++++++++------- 13 files changed, 149 insertions(+), 113 deletions(-) (limited to 'openbsc/src') 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 #include +#include + +#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 +/* (C) 2008-2010 by Harald Welte * (C) 2009 by Holger Hans Peter Freyther * 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 #include -#include -#include -#include -#include -#include #include -#include -#include -#include #include -#include +#include +#include #include @@ -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 -#include +#include +#include #include +#include +#include +#include +#include + #include #include #include -#include - 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 #include -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); -- cgit v1.2.3