From 25de99170fd44d7d5606a8c34a89c4fdf1019e8e Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 30 Apr 2009 15:53:07 +0000 Subject: add new 'ipaccess-config' program to set Unit ID and primary OML NVRAM parameters of ip.access BTS --- include/openbsc/abis_nm.h | 2 +- include/openbsc/e1_input.h | 2 + src/Makefile.am | 5 +- src/e1_config.c | 34 +++++++- src/input/ipaccess.c | 33 ++++++++ src/ipaccess-config.c | 198 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 270 insertions(+), 4 deletions(-) create mode 100644 src/ipaccess-config.c diff --git a/include/openbsc/abis_nm.h b/include/openbsc/abis_nm.h index 1ed4ccedf..f1b00756e 100644 --- a/include/openbsc/abis_nm.h +++ b/include/openbsc/abis_nm.h @@ -345,7 +345,7 @@ enum abis_nm_attr { NM_ATT_IPACC_RSL_BSC_IP = 0x80, NM_ATT_IPACC_RSL_BSC_PORT = 0x81, NM_ATT_IPACC_LOCATION = 0x8e, /* string describing location */ - NM_ATT_IPACC_UNIT_ID = 0x91, + NM_ATT_IPACC_UNIT_ID = 0x91, /* Site/BTS/TRX */ NM_ATT_IPACC_UNIT_NAME = 0x93, /* default: nbts- */ NM_ATT_IPACC_PRIM_OML_IP = 0x95, NM_ATT_IPACC_SEC_OML_IP = 0x96, diff --git a/include/openbsc/e1_input.h b/include/openbsc/e1_input.h index db565bfb4..8b9521d61 100644 --- a/include/openbsc/e1_input.h +++ b/include/openbsc/e1_input.h @@ -2,6 +2,7 @@ #define _E1_INPUT_H #include +#include #include #include @@ -147,6 +148,7 @@ struct subch_mux *e1inp_get_mux(u_int8_t e1_nr, u_int8_t ts_nr); /* e1_config.c */ int e1_config(struct gsm_bts *bts, int cardnr, int release_l2); int ia_config(struct gsm_bts *bts); +int ia_config_connect(struct gsm_bts *bts, struct sockaddr_in *sin); int ipaccess_setup(struct e1inp_line *line); struct llist_head e1inp_driver_list; diff --git a/src/Makefile.am b/src/Makefile.am index b9b3892f7..643bf6759 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ INCLUDES = $(all_includes) -I$(top_srcdir)/include AM_CFLAGS=-Wall -sbin_PROGRAMS = bsc_hack bs11_config ipaccess-find +sbin_PROGRAMS = bsc_hack bs11_config ipaccess-find ipaccess-config noinst_LIBRARIES = libbsc.a libvty.a noinst_HEADERS = vty/cardshell.h @@ -19,3 +19,6 @@ bsc_hack_LDADD = libbsc.a libvty.a -ldl -ldbi -lcrypt bs11_config_SOURCES = bs11_config.c abis_nm.c gsm_data.c msgb.c debug.c select.c timer.c rs232.c tlv_parser.c ipaccess_find_SOURCES = ipaccess-find.c select.c timer.c + +ipaccess_config_SOURCES = ipaccess-config.c +ipaccess_config_LDADD = libbsc.a libvty.a -ldl -ldbi -lcrypt diff --git a/src/e1_config.c b/src/e1_config.c index 4110d489e..02fdb5d83 100644 --- a/src/e1_config.c +++ b/src/e1_config.c @@ -1,6 +1,8 @@ #include #include +#include + #include #include #include @@ -70,7 +72,7 @@ int e1_config(struct gsm_bts *bts, int cardnr, int release_l2) } /* do some compiled-in configuration for our BTS/E1 setup */ -int ia_config(struct gsm_bts *bts) +static struct e1inp_line *__ia_config(struct gsm_bts *bts) { struct e1inp_line *line; struct e1inp_ts *sign_ts, *rsl_ts; @@ -78,7 +80,7 @@ int ia_config(struct gsm_bts *bts) line = malloc(sizeof(*line)); if (!line) - return -ENOMEM; + return NULL; memset(line, 0, sizeof(*line)); /* create E1 timeslots for signalling and TRAU frames */ @@ -97,5 +99,33 @@ int ia_config(struct gsm_bts *bts) bts->oml_link = oml_link; bts->c0->rsl_link = rsl_link; + return line; +} + +/* configure pseudo E1 line in ip.access style and create listening socket */ +int ia_config(struct gsm_bts *bts) +{ + struct e1inp_line *line; + + line = __ia_config(bts); + if (!line) + return -ENOMEM; + return ipaccess_setup(line); } + +/* configure pseudo E1 line in ip.access style and connect to BTS */ +int ia_config_connect(struct gsm_bts *bts, struct sockaddr_in *sin) +{ + struct e1inp_line *line; + + line = __ia_config(bts); + if (!line) + return -ENOMEM; + + /* default port at BTS for incoming connections is 3006 */ + if (sin->sin_port == 0) + sin->sin_port = htons(3006); + + return ipaccess_connect(line, sin); +} diff --git a/src/input/ipaccess.c b/src/input/ipaccess.c index d5291ab04..b4d53bd8f 100644 --- a/src/input/ipaccess.c +++ b/src/input/ipaccess.c @@ -378,6 +378,39 @@ static int make_sock(struct bsc_fd *bfd, u_int16_t port, return 0; } +/* Actively connect to a BTS. Currently used by ipaccess-config.c */ +int ipaccess_connect(struct e1inp_line *line, struct sockaddr_in *sa) +{ + struct e1inp_ts *e1i_ts = &line->ts[0]; + struct bsc_fd *bfd = &e1i_ts->driver.ipaccess.fd; + int ret, on = 1; + + bfd->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + bfd->cb = ipaccess_fd_cb; + bfd->when = BSC_FD_READ | BSC_FD_WRITE; + bfd->data = line; + bfd->priv_nr = 1; + + setsockopt(bfd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + + ret = connect(bfd->fd, (struct sockaddr *) sa, sizeof(*sa)); + if (ret < 0) { + fprintf(stderr, "could not connect socket\n"); + close(bfd->fd); + return ret; + } + + ret = bsc_register_fd(bfd); + if (ret < 0) { + close(bfd->fd); + return ret; + } + + line->driver = &ipaccess_driver; + + return e1inp_line_register(line); +} + int ipaccess_setup(struct e1inp_line *line) { struct ia_e1_handle *e1h; diff --git a/src/ipaccess-config.c b/src/ipaccess-config.c new file mode 100644 index 000000000..b836acdbf --- /dev/null +++ b/src/ipaccess-config.c @@ -0,0 +1,198 @@ +/* ip.access nanoBTS configuration tool */ + +/* (C) 2009 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 General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +#include +#include +#include +#include +#include +#include + +static struct gsm_network *gsmnet; + +static int restart; +static char *prim_oml_ip; +static char *unit_id; + +/* +static u_int8_t prim_oml_attr[] = { 0x95, 0x00, 7, 0x88, 192, 168, 100, 11, 0x00, 0x00 }; +static u_int8_t unit_id_attr[] = { 0x91, 0x00, 9, '2', '3', '4', '2', '/' , '0', '/', '0', 0x00 }; +*/ + +static void bootstrap_om(struct gsm_bts *bts) +{ + int len; + static u_int8_t buf[1024]; + + printf("OML link established\n"); + + if (unit_id) { + len = strlen(unit_id); + if (len > sizeof(buf)-10) + return; + buf[0] = NM_ATT_IPACC_UNIT_ID; + buf[1] = (len+1) >> 8; + buf[2] = (len+1) & 0xff; + memcpy(buf+3, unit_id, len); + buf[3+len] = 0; + printf("setting Unit ID to '%s'\n", unit_id); + abis_nm_ipaccess_set_nvattr(bts, buf, 3+len+1); + } + if (prim_oml_ip) { + struct in_addr ia; + u_int8_t *cur = buf; + + if (!inet_aton(prim_oml_ip, &ia)) { + fprintf(stderr, "invalid IP address: %s\n", + prim_oml_ip); + return; + } + + /* 0x88 + IP + port */ + len = 1 + sizeof(ia) + 2; + + *cur++ = NM_ATT_IPACC_PRIM_OML_IP; + *cur++ = (len) >> 8; + *cur++ = (len) & 0xff; + *cur++ = 0x88; + memcpy(cur, &ia, sizeof(ia)); + cur += sizeof(ia); + *cur++ = 0; + *cur++ = 0; + printf("setting primary OML link IP to '%s'\n", unit_id); + abis_nm_ipaccess_set_nvattr(bts, buf, 3+len); + } + + if (restart) { + printf("restarting BTS\n"); + abis_nm_ipaccess_restart(bts); + } +} + +void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx) +{ + switch (event) { + case EVT_E1_TEI_UP: + switch (type) { + case E1INP_SIGN_OML: + bootstrap_om(trx->bts); + break; + case E1INP_SIGN_RSL: + /* FIXME */ + break; + default: + break; + } + break; + case EVT_E1_TEI_DN: + fprintf(stderr, "Lost some E1 TEI link\n"); + /* FIXME: deal with TEI or L1 link loss */ + break; + default: + break; + } +} + +int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj, + struct gsm_nm_state *old_state, struct gsm_nm_state *new_state) +{ + return 0; +} + +int main(int argc, char **argv) +{ + struct gsm_bts *bts; + struct sockaddr_in sin; + int rc, option_index = 0; + + printf("ipaccess-config (C) 2009 by Harald Welte\n"); + printf("This is FREE SOFTWARE with ABSOLUTELY NO WARRANTY\n\n"); + + while (1) { + int c; + static struct option long_options[] = { + { "unit-id", 1, 0, 'u' }, + { "oml-ip", 1, 0, 'o' }, + { "restart", 0, 0, 'r' }, + }; + + c = getopt_long(argc, argv, "u:o:r", long_options, + &option_index); + + if (c == -1) + break; + + switch (c) { + case 'u': + unit_id = optarg; + break; + case 'o': + prim_oml_ip = optarg; + break; + case 'r': + restart = 1; + break; + } + }; + + if (optind >= argc) { + fprintf(stderr, "you have to specify the IP address of the BTS\n"); + exit(2); + } + + gsmnet = gsm_network_init( 1, GSM_BTS_TYPE_NANOBTS_900, 1, 1); + if (!gsmnet) + exit(1); + + bts = &gsmnet->bts[0]; + + printf("Trying to connect to ip.access BTS ...\n"); + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + inet_aton(argv[optind], &sin.sin_addr); + rc = ia_config_connect(bts, &sin); + if (rc < 0) { + perror("Error connecting to the BTS"); + exit(1); + } + + while (1) { + rc = bsc_select_main(); + if (rc < 0) + exit(3); + } + + exit(0); +} + -- cgit v1.2.3