diff --git a/openbsc/include/openbsc/e1_input.h b/openbsc/include/openbsc/e1_input.h index 93f9c527..ca8d5a65 100644 --- a/openbsc/include/openbsc/e1_input.h +++ b/openbsc/include/openbsc/e1_input.h @@ -114,11 +114,17 @@ struct e1inp_line { /* register a driver with the E1 core */ int e1inp_driver_register(struct e1inp_driver *drv); +/* fine a previously registered driver */ +struct e1inp_driver *e1inp_driver_find(const char *name); + /* register a line with the E1 core */ int e1inp_line_register(struct e1inp_line *line); -/* ensure a certain line exists, return pointer to it */ -struct e1inp_line *e1inp_line_get_create(u_int8_t e1_nr); +/* get a line by its ID */ +struct e1inp_line *e1inp_line_get(u_int8_t e1_nr); + +/* create a line in the E1 input core */ +struct e1inp_line *e1inp_line_create(u_int8_t e1_nr, const char *driver_name); /* find a sign_link for given TEI and SAPI in a TS */ struct e1inp_sign_link * @@ -169,4 +175,7 @@ int ipaccess_setup(struct gsm_network *gsmnet); extern struct llist_head e1inp_driver_list; extern struct llist_head e1inp_line_list; +int e1inp_vty_init(void); +void e1inp_init(void); + #endif /* _E1_INPUT_H */ diff --git a/openbsc/include/openbsc/vty.h b/openbsc/include/openbsc/vty.h index 5cdd204d..1be81a7f 100644 --- a/openbsc/include/openbsc/vty.h +++ b/openbsc/include/openbsc/vty.h @@ -29,6 +29,7 @@ enum bsc_vty_node { NS_NODE, BSSGP_NODE, OML_NODE, + E1INP_NODE, NAT_NODE, NAT_BSC_NODE, MSC_NODE, diff --git a/openbsc/src/Makefile.am b/openbsc/src/Makefile.am index 290bc069..351b2699 100644 --- a/openbsc/src/Makefile.am +++ b/openbsc/src/Makefile.am @@ -19,7 +19,8 @@ noinst_LIBRARIES = libbsc.a libmsc.a libvty.a libmgcp.a libbsc_a_SOURCES = abis_rsl.c abis_nm.c gsm_data.c gsm_04_08_utils.c \ chan_alloc.c debug.c socket.c abis_nm_vty.c \ gsm_subscriber_base.c subchan_demux.c bsc_rll.c transaction.c \ - trau_frame.c trau_mux.c paging.c e1_config.c e1_input.c \ + trau_frame.c trau_mux.c paging.c \ + e1_config.c e1_input.c e1_input_vty.c \ input/misdn.c input/ipaccess.c handover_logic.c \ talloc_ctx.c system_information.c rest_octets.c \ bts_siemens_bs11.c bts_ipaccess_nanobts.c mncc_upqueue.c \ diff --git a/openbsc/src/bsc_hack.c b/openbsc/src/bsc_hack.c index 11499ab4..dacaad38 100644 --- a/openbsc/src/bsc_hack.c +++ b/openbsc/src/bsc_hack.c @@ -238,6 +238,8 @@ int main(int argc, char **argv) bts_model_bs11_init(); bts_model_nanobts_init(); + e1inp_init(); + /* enable filters */ log_set_all_filter(stderr_target, 1); diff --git a/openbsc/src/bsc_vty.c b/openbsc/src/bsc_vty.c index 97093016..739d9aa2 100644 --- a/openbsc/src/bsc_vty.c +++ b/openbsc/src/bsc_vty.c @@ -2702,6 +2702,7 @@ int bsc_vty_init(void) install_element(ENABLE_NODE, &pdch_act_cmd); abis_nm_vty_init(); + e1inp_vty_init(); bsc_vty_init_extra(); diff --git a/openbsc/src/e1_config.c b/openbsc/src/e1_config.c index dd787207..f781b9e2 100644 --- a/openbsc/src/e1_config.c +++ b/openbsc/src/e1_config.c @@ -51,7 +51,7 @@ int e1_reconfig_ts(struct gsm_bts_trx_ts *ts) if (!e1_link->e1_ts) return 0; - line = e1inp_line_get_create(e1_link->e1_nr); + line = e1inp_line_get(e1_link->e1_nr); if (!line) return -ENOMEM; @@ -81,7 +81,7 @@ int e1_reconfig_trx(struct gsm_bts_trx *trx) return -EINVAL; /* RSL Link */ - line = e1inp_line_get_create(e1_link->e1_nr); + line = e1inp_line_get(e1_link->e1_nr); if (!line) return -ENOMEM; sign_ts = &line->ts[e1_link->e1_ts-1]; @@ -114,7 +114,7 @@ int e1_reconfig_bts(struct gsm_bts *bts) return -EINVAL; /* OML link */ - line = e1inp_line_get_create(e1_link->e1_nr); + line = e1inp_line_get(e1_link->e1_nr); if (!line) return -ENOMEM; sign_ts = &line->ts[e1_link->e1_ts-1]; diff --git a/openbsc/src/e1_input.c b/openbsc/src/e1_input.c index 45231c39..923d7db0 100644 --- a/openbsc/src/e1_input.c +++ b/openbsc/src/e1_input.c @@ -322,7 +322,7 @@ int e1inp_ts_config(struct e1inp_ts *ts, struct e1inp_line *line, return 0; } -static struct e1inp_line *e1inp_line_get(u_int8_t e1_nr) +struct e1inp_line *e1inp_line_get(u_int8_t e1_nr) { struct e1inp_line *e1i_line; @@ -334,6 +334,37 @@ static struct e1inp_line *e1inp_line_get(u_int8_t e1_nr) return NULL; } +struct e1inp_line *e1inp_line_create(u_int8_t e1_nr, const char *driver_name) +{ + struct e1inp_driver *driver; + struct e1inp_line *line; + int i; + + line = e1inp_line_get(e1_nr); + if (line) + return NULL; + + driver = e1inp_driver_find(driver_name); + if (!driver) + return NULL; + + line = talloc_zero(tall_bsc_ctx, struct e1inp_line); + if (!line) + return NULL; + + line->driver = driver; + + line->num = e1_nr; + for (i = 0; i < NUM_E1_TS; i++) { + line->ts[i].num = i+1; + line->ts[i].line = line; + } + llist_add_tail(&line->list, &e1inp_line_list); + + return line; +} + +#if 0 struct e1inp_line *e1inp_line_get_create(u_int8_t e1_nr) { struct e1inp_line *line; @@ -356,6 +387,7 @@ struct e1inp_line *e1inp_line_get_create(u_int8_t e1_nr) return line; } +#endif static struct e1inp_ts *e1inp_ts_get(u_int8_t e1_nr, u_int8_t ts_nr) { @@ -536,10 +568,23 @@ int e1inp_event(struct e1inp_ts *ts, int evt, u_int8_t tei, u_int8_t sapi) /* register a driver with the E1 core */ int e1inp_driver_register(struct e1inp_driver *drv) { + printf("registering driver %s\n", drv->name); llist_add_tail(&drv->list, &e1inp_driver_list); return 0; } +struct e1inp_driver *e1inp_driver_find(const char *name) +{ + struct e1inp_driver *drv; + + printf("trying to find driver %s\n", name); + llist_for_each_entry(drv, &e1inp_driver_list, list) { + if (!strcasecmp(name, drv->name)) + return drv; + } + return NULL; +} + int e1inp_line_update(struct e1inp_line *line) { if (line->driver && line->driver->line_update) @@ -563,9 +608,13 @@ static int e1i_sig_cb(unsigned int subsys, unsigned int signal, return 0; } -static __attribute__((constructor)) void on_dso_load_e1_inp(void) +void e1inp_misdn_init(void); + +void e1inp_init(void) { tall_sigl_ctx = talloc_named_const(tall_bsc_ctx, 1, "e1inp_sign_link"); register_signal_handler(SS_GLOBAL, e1i_sig_cb, NULL); + + e1inp_misdn_init(); } diff --git a/openbsc/src/e1_input_vty.c b/openbsc/src/e1_input_vty.c new file mode 100644 index 00000000..6d44a95b --- /dev/null +++ b/openbsc/src/e1_input_vty.c @@ -0,0 +1,99 @@ +/* OpenBSC E1 vty interface */ +/* (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 Affero 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 "../bscconfig.h" + +#define E1_DRIVER_NAMES "(misdn)" +#define E1_DRIVER_HELP "mISDN supported E1 Card\n" + +DEFUN(cfg_e1line_driver, cfg_e1_line_driver_cmd, + "e1_line <0-255> driver " E1_DRIVER_NAMES, + "Configure E1/T1/J1 Line\n" "Line Number\n" "Set driver for this line\n" + E1_DRIVER_HELP) +{ + struct e1inp_line *line; + int e1_nr = atoi(argv[0]); + + line = e1inp_line_get(e1_nr); + if (line) { + vty_out(vty, "%% Line %d already exists%s", e1_nr, VTY_NEWLINE); + return CMD_WARNING; + } + line = e1inp_line_create(e1_nr, argv[1]); + if (!line) { + vty_out(vty, "%% Error creating line %d%s", e1_nr, VTY_NEWLINE); + return CMD_WARNING; + } + + return CMD_SUCCESS; +} + +DEFUN(cfg_e1inp, cfg_e1inp_cmd, + "e1_input", + "Configure E1/T1/J1 TDM input\n") +{ + vty->node = E1INP_NODE; + + return CMD_SUCCESS; +} + +static int e1inp_config_write(struct vty *vty) +{ + struct e1inp_line *line; + + llist_for_each_entry(line, &e1inp_line_list, list) { + vty_out(vty, " e1_line %u driver %s%s", line->num, + line->driver->name, VTY_NEWLINE); + } + return CMD_SUCCESS; +} + +struct cmd_node e1inp_node = { + E1INP_NODE, + "%s(e1_input)#", + 1, +}; + +int e1inp_vty_init(void) +{ + install_element(CONFIG_NODE, &cfg_e1inp_cmd); + install_node(&e1inp_node, e1inp_config_write); + install_element(E1INP_NODE, &cfg_e1_line_driver_cmd); + + return 0; +} diff --git a/openbsc/src/input/misdn.c b/openbsc/src/input/misdn.c index 1f24a278..77b1fd89 100644 --- a/openbsc/src/input/misdn.c +++ b/openbsc/src/input/misdn.c @@ -386,7 +386,7 @@ static int activate_bchan(struct e1inp_line *line, int ts, int act) static int mi_e1_line_update(struct e1inp_line *line); struct e1inp_driver misdn_driver = { - .name = "mISDNuser", + .name = "mISDN", .want_write = ts_want_write, .default_delay = 50000, .line_update = &mi_e1_line_update, @@ -486,16 +486,6 @@ static int mi_e1_line_update(struct e1inp_line *line) struct mISDN_devinfo devinfo; int sk, ret, cnt; - if (!line->driver) { - /* this must be the first update */ - line->driver = &misdn_driver; - } else { - /* this is a subsequent update */ - /* FIXME: first close all sockets */ - fprintf(stderr, "incremental line updates not supported yet\n"); - return 0; - } - if (line->driver != &misdn_driver) return -EINVAL; @@ -544,7 +534,7 @@ static int mi_e1_line_update(struct e1inp_line *line) return 0; } -static __attribute__((constructor)) void on_dso_load_sms(void) +void e1inp_misdn_init(void) { /* register the driver with the core */ e1inp_driver_register(&misdn_driver);