From 6d7b78bde165f39dcd9033f0c5386f5699801233 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 4 Sep 2011 22:42:03 +0200 Subject: add minimal configuration file support this config file allows configuration of unit id, oml ip, and local rtp bind IP. --- src/common/bts.c | 18 ++- src/common/rsl.c | 3 +- src/common/vty.c | 280 +++++++++++++++++++++++++++++++++++++++++++++- src/osmo-bts-sysmo/main.c | 41 ++++--- 4 files changed, 316 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/common/bts.c b/src/common/bts.c index 6dd0362c..ee4808aa 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -44,12 +44,20 @@ #include +struct gsm_network bts_gsmnet = { + .bts_list = { &bts_gsmnet.bts_list, &bts_gsmnet.bts_list }, + .num_bts = 0, +}; + void *tall_bts_ctx; int bts_init(struct gsm_bts *bts) { struct gsm_bts_role_bts *btsb; struct gsm_bts_trx *trx; + int rc; + + bts->band = GSM_BAND_1800; bts->role = btsb = talloc_zero(bts, struct gsm_bts_role_bts); @@ -77,7 +85,15 @@ int bts_init(struct gsm_bts *bts) osmo_rtp_init(tall_bts_ctx); - return bts_model_init(bts); + rc = bts_model_init(bts); + if (rc < 0) + return rc; + + /* add to list of BTSs */ + llist_add_tail(&bts->list, &bts_gsmnet.bts_list); + bts_gsmnet.num_bts++; + + return rc; } static void shutdown_timer_cb(void *data) diff --git a/src/common/rsl.c b/src/common/rsl.c index 29a0fb71..b9046f35 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -1129,6 +1129,7 @@ static int rsl_rx_ipac_XXcx(struct msgb *msg) struct abis_rsl_dchan_hdr *dch = msgb_l2(msg); struct tlv_parsed tp; struct gsm_lchan *lchan = msg->lchan; + struct gsm_bts_role_bts *btsb = bts_role_bts(msg->lchan->ts->trx->bts); const uint8_t *payload_type, *speech_mode, *payload_type2; const uint32_t *connect_ip; const uint16_t *connect_port; @@ -1186,7 +1187,7 @@ static int rsl_rx_ipac_XXcx(struct msgb *msg) #warning remove hard-coded IP address rc = osmo_rtp_socket_bind(lchan->abis_ip.rtp_socket, - "192.168.100.239", -1); + btsb->rtp_bind_host, -1); if (rc < 0) { LOGP(DRSL, LOGL_ERROR, "%s IPAC Failed to bind RTP/RTCP sockets\n", diff --git a/src/common/vty.c b/src/common/vty.c index d2cda2fb..c170ab4d 100644 --- a/src/common/vty.c +++ b/src/common/vty.c @@ -1,11 +1,47 @@ +/* OsmoBTS VTY interface */ -#include -#include +/* (C) 2011 by Harald Welte + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ +#include +#include +#include + +#include +#include #include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include #include + enum node_type bts_vty_go_parent(struct vty *vty) { switch (vty->node) { @@ -18,6 +54,8 @@ enum node_type bts_vty_go_parent(struct vty *vty) int bts_vty_is_config_node(struct vty *vty, int node) { switch (node) { + case BTS_NODE: + return 1; default: return 0; } @@ -55,7 +93,243 @@ struct vty_app_info bts_vty_info = { }; const char *osmobts_copyright = - "Copyright (C) 2010, 2011 by Harald Welte and Andreas Eversberg\r\n" + "Copyright (C) 2010, 2011 by Harald Welte, Andreas Eversberg and On-Waves\r\n" "License AGPLv3+: GNU AGPL version 3 or later \r\n" "This is free software: you are free to change and redistribute it.\r\n" "There is NO WARRANTY, to the extent permitted by law.\r\n"; + +extern struct gsm_network bts_gsmnet; + +struct gsm_network *gsmnet_from_vty(struct vty *v) +{ + return &bts_gsmnet; +} + +struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num) +{ + struct gsm_bts *bts; + + if (num >= net->num_bts) + return NULL; + + llist_for_each_entry(bts, &net->bts_list, list) { + if (bts->nr == num) + return bts; + } + + return NULL; +} + +static struct cmd_node bts_node = { + BTS_NODE, + "%s(bts)#", + 1, +}; + +static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts) +{ + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + + vty_out(vty, "bts %u%s", bts->nr, VTY_NEWLINE); + if (bts->description) + vty_out(vty, " description %s%s", bts->description, VTY_NEWLINE); + vty_out(vty, " band %s%s", gsm_band_name(bts->band), VTY_NEWLINE); + vty_out(vty, " ipa unit-id %u %u%s", + bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE); + vty_out(vty, " oml remote-ip %s%s", btsb->bsc_oml_host, VTY_NEWLINE); + vty_out(vty, " rtp bind-ip %s%s", btsb->rtp_bind_host, VTY_NEWLINE); +} + +int config_write_bts(struct vty *vty) +{ + struct gsm_network *net = gsmnet_from_vty(vty); + struct gsm_bts *bts; + + llist_for_each_entry(bts, &net->bts_list, list) + config_write_bts_single(vty, bts); + + return CMD_SUCCESS; +} + +/* per-BTS configuration */ +DEFUN(cfg_bts, + cfg_bts_cmd, + "bts BTS_NR", + "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; + + if (bts_nr >= gsmnet->num_bts) { + vty_out(vty, "%% Unknown BTS number %u (num %u)%s", + bts_nr, gsmnet->num_bts, VTY_NEWLINE); + return CMD_WARNING; + } else + bts = gsm_bts_num(gsmnet, bts_nr); + + vty->index = bts; + vty->index_sub = &bts->description; + vty->node = BTS_NODE; + + return CMD_SUCCESS; +} + +#warning merge with OpenBSC? +DEFUN(cfg_bts_unit_id, + cfg_bts_unit_id_cmd, + "ipa unit-id <0-65534> <0-255>", + "Set the ip.access BTS Unit ID of this BTS\n") +{ + struct gsm_bts *bts = vty->index; + int site_id = atoi(argv[0]); + int bts_id = atoi(argv[1]); + + bts->ip_access.site_id = site_id; + bts->ip_access.bts_id = bts_id; + + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_band, + cfg_bts_band_cmd, + "band (450|480|750|810|850|900|1800|1900)", + "Set the frequency band of this BTS\n" "Frequency band\n") +{ + struct gsm_bts *bts = vty->index; + int band = gsm_band_parse(argv[0]); + + if (band < 0) { + vty_out(vty, "%% BAND %d is not a valid GSM band%s", + band, VTY_NEWLINE); + return CMD_WARNING; + } + + bts->band = band; + + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_oml_ip, + cfg_bts_oml_ip_cmd, + "oml remote-ip A.B.C.D", + "OML Parameters\n" "OML IP Address\n" "OML IP Address\n") +{ + struct gsm_bts *bts = vty->index; + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + + if (btsb->bsc_oml_host) + talloc_free(btsb->bsc_oml_host); + + btsb->bsc_oml_host = talloc_strdup(btsb, argv[0]); + + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_rtp_bind_ip, + cfg_bts_rtp_bind_ip_cmd, + "rtp bind-ip A.B.C.D", + "RTP Parameters\n" "RTP local bind IP Address\n" "RTP local bind IP Address\n") +{ + struct gsm_bts *bts = vty->index; + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + + if (btsb->rtp_bind_host) + talloc_free(btsb->rtp_bind_host); + + btsb->rtp_bind_host = talloc_strdup(btsb, argv[0]); + + return CMD_SUCCESS; +} +/* ====================================================================== + * SHOW + * ======================================================================*/ + +static void net_dump_nmstate(struct vty *vty, struct gsm_nm_state *nms) +{ + vty_out(vty,"Oper '%s', Admin %u, Avail '%s'%s", + abis_nm_opstate_name(nms->operational), nms->administrative, + abis_nm_avail_name(nms->availability), VTY_NEWLINE); +} + +static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts) +{ + vty_out(vty, "BTS %u is of %s type in band %s, has CI %u LAC %u, " + "BSIC %u, TSC %u and %u TRX%s", + bts->nr, "FIXME", gsm_band_name(bts->band), + bts->cell_identity, + bts->location_area_code, bts->bsic, bts->tsc, + bts->num_trx, VTY_NEWLINE); + vty_out(vty, " Description: %s%s", + bts->description ? bts->description : "(null)", VTY_NEWLINE); + vty_out(vty, " Unit ID: %u/%u/0, OML Stream ID 0x%02x%s", + bts->ip_access.site_id, bts->ip_access.bts_id, + bts->oml_tei, VTY_NEWLINE); + vty_out(vty, " NM State: "); + net_dump_nmstate(vty, &bts->mo.nm_state); + vty_out(vty, " Site Mgr NM State: "); + net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state); +#if 0 + vty_out(vty, " Paging: %u pending requests, %u free slots%s", + paging_pending_requests_nr(bts), + bts->paging.available_slots, VTY_NEWLINE); + if (is_ipaccess_bts(bts)) { + vty_out(vty, " OML Link state: %s.%s", + bts->oml_link ? "connected" : "disconnected", VTY_NEWLINE); + } else { + vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE); + e1isl_dump_vty(vty, bts->oml_link); + } + + /* FIXME: chan_desc */ + memset(&pl, 0, sizeof(pl)); + bts_chan_load(&pl, bts); + vty_out(vty, " Current Channel Load:%s", VTY_NEWLINE); + dump_pchan_load_vty(vty, " ", &pl); +#endif +} + + +DEFUN(show_bts, show_bts_cmd, "show bts <0-255>", + SHOW_STR "Display information about a BTS\n" + "BTS number") +{ + struct gsm_network *net = gsmnet_from_vty(vty); + int bts_nr; + + if (argc != 0) { + /* use the BTS number that the user has specified */ + bts_nr = atoi(argv[0]); + if (bts_nr >= net->num_bts) { + vty_out(vty, "%% can't find BTS '%s'%s", argv[0], + VTY_NEWLINE); + return CMD_WARNING; + } + bts_dump_vty(vty, gsm_bts_num(net, bts_nr)); + return CMD_SUCCESS; + } + /* print all BTS's */ + for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) + bts_dump_vty(vty, gsm_bts_num(net, bts_nr)); + + return CMD_SUCCESS; +} + + +int bts_vty_init(const struct log_info *cat) +{ + install_element_ve(&show_bts_cmd); + + logging_vty_add_cmds(cat); + + install_node(&bts_node, config_write_bts); + install_element(CONFIG_NODE, &cfg_bts_cmd); + install_default(BTS_NODE); + install_element(BTS_NODE, &cfg_bts_unit_id_cmd); + install_element(BTS_NODE, &cfg_bts_oml_ip_cmd); + install_element(BTS_NODE, &cfg_bts_rtp_bind_ip_cmd); + install_element(BTS_NODE, &cfg_bts_band_cmd); + install_element(BTS_NODE, &cfg_description_cmd); + install_element(BTS_NODE, &cfg_no_description_cmd); +} diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index e09caae4..35ac9eeb 100644 --- a/src/osmo-bts-sysmo/main.c +++ b/src/osmo-bts-sysmo/main.c @@ -47,7 +47,6 @@ const uint8_t abis_mac[6] = { 0,1,2,3,4,5 }; /* FIXME: generate from git */ const char *software_version = "0815"; -static const char *bsc_host = NULL; static const char *config_file = "osmo-bts.cfg"; extern const char *osmobts_copyright; static int daemonize = 0; @@ -103,7 +102,6 @@ static void print_help() " -T --timestamp Prefix every log line with a timestamp\n" " -V --version Print version information and exit\n" " -e --log-level Set a global log-level\n" - " -B --bsc-host Specify host-name of the BSC\n" " -p --dsp-trace Set DSP trace flags\n" ); } @@ -123,12 +121,11 @@ static void handle_options(int argc, char **argv) { "timestamp", 0, 0, 'T' }, { "version", 0, 0, 'V' }, { "log-level", 1, 0, 'e' }, - { "bsc-host", 1, 0, 'B' }, { "dsp-trace", 1, 0, 'p' }, { 0, 0, 0, 0 } }; - c = getopt_long(argc, argv, "hd:Dc:sTVe:B:p:", + c = getopt_long(argc, argv, "hc:d:Dc:sTVe:p:", long_options, &option_idx); if (c == -1) break; @@ -160,9 +157,6 @@ static void handle_options(int argc, char **argv) case 'e': log_set_log_level(osmo_stderr_target, atoi(optarg)); break; - case 'B': - bsc_host = strdup(optarg); - break; case 'p': dsp_trace = strtoul(optarg, NULL, 16); break; @@ -195,6 +189,7 @@ static void signal_handler(int signal) int main(int argc, char **argv) { + struct gsm_bts_role_bts *btsb; struct ipabis_link *link; void *tall_msgb_ctx; int rc; @@ -205,13 +200,24 @@ int main(int argc, char **argv) bts_log_init(NULL); + vty_init(&bts_vty_info); + bts_vty_init(&bts_log_info); + bts = gsm_bts_alloc(tall_bts_ctx); + if (bts_init(bts) < 0) { + fprintf(stderr, "unable to to open bts\n"); + exit(1); + } + btsb = bts_role_bts(bts); - vty_init(&bts_vty_info); - logging_vty_add_cmds(&bts_log_info); - //bts_vty_init(& + handle_options(argc, argv); - /* FIXME: parse 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); + exit(1); + } rc = telnet_init(tall_bts_ctx, NULL, 4241); if (rc < 0) { @@ -219,25 +225,18 @@ int main(int argc, char **argv) exit(1); } - handle_options(argc, argv); - - if (!bsc_host) { - fprintf(stderr, "You need to specify the BSC hostname\n"); - exit(2); - } - signal(SIGINT, &signal_handler); //signal(SIGABRT, &signal_handler); signal(SIGUSR1, &signal_handler); signal(SIGUSR2, &signal_handler); osmo_init_ignore_signals(); - if (bts_init(bts) < 0) { - fprintf(stderr, "unable to to open bts\n"); + if (!btsb->bsc_oml_host) { + fprintf(stderr, "Cannot start BTS without knowing BSC OML IP\n"); exit(1); } - link = link_init(bts, bsc_host); + link = link_init(bts, btsb->bsc_oml_host); if (!link) { fprintf(stderr, "unable to connect to BSC\n"); exit(1); -- cgit v1.2.3