From c2889512c4fb4585fc5ef2980937dde64f687f0a Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 13 Sep 2011 23:49:04 +0100 Subject: e1_input: add 'port_nr' field and support DAHDI T1 cards the "e1_line <0-255> port <0-255>" vty command allows the user to set which physical port/card number should be represented by the given virtual e1_line. Furthermore, we now actually query the DAHDI hardware to determine the number of ports of a given span (e.g. only 24 in case of T1) instead of blindly assuming there are 31 timeslots on each port. This specifically will fix T1 timeslot (/dev/dahdi/%u) calculation in setups with multiple DAHDI spans/ports and a T1 span != span 1. --- src/e1_input.c | 3 ++- src/e1_input_vty.c | 28 +++++++++++++++++++--- src/input/dahdi.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/input/misdn.c | 6 ++--- 4 files changed, 97 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/e1_input.c b/src/e1_input.c index ad0778a..cad39aa 100644 --- a/src/e1_input.c +++ b/src/e1_input.c @@ -337,7 +337,8 @@ e1inp_line_create(uint8_t e1_nr, const char *driver_name) line->rate_ctr = rate_ctr_group_alloc(line, &e1inp_ctr_g_d, line->num); - for (i = 0; i < NUM_E1_TS; i++) { + line->num_ts = NUM_E1_TS; + for (i = 0; i < line->num_ts; i++) { line->ts[i].num = i+1; line->ts[i].line = line; } diff --git a/src/e1_input_vty.c b/src/e1_input_vty.c index bcc0251..10c4687 100644 --- a/src/e1_input_vty.c +++ b/src/e1_input_vty.c @@ -69,6 +69,25 @@ DEFUN(cfg_e1line_driver, cfg_e1_line_driver_cmd, return CMD_SUCCESS; } +DEFUN(cfg_e1line_port, cfg_e1_line_port_cmd, + "e1_line <0-255> port <0-255>" + E1_LINE_HELP, "Set physical port/span/card number\n" + "E1/T1 Port/Span/Card number\n") +{ + struct e1inp_line *line; + int e1_nr = atoi(argv[0]); + + line = e1inp_line_find(e1_nr); + if (!line) { + vty_out(vty, "%% Line %d doesn't exist%s", e1_nr, VTY_NEWLINE); + return CMD_WARNING; + } + + line->port_nr = atoi(argv[1]); + + return CMD_SUCCESS; +} + DEFUN(cfg_e1line_name, cfg_e1_line_name_cmd, "e1_line <0-255> name .LINE", E1_LINE_HELP "Set name for this line\n" "Human readable name\n") @@ -111,6 +130,8 @@ static int e1inp_config_write(struct vty *vty) 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); + vty_out(vty, " e1_line %u port %u%s", line->num, + line->port_nr, VTY_NEWLINE); if (line->name) vty_out(vty, " e1_line %u name %s%s", line->num, line->name, VTY_NEWLINE); @@ -200,7 +221,7 @@ DEFUN(show_e1ts, if (argc == 0) { llist_for_each_entry(line, &e1inp_line_list, list) { - for (ts_nr = 0; ts_nr < NUM_E1_TS; ts_nr++) { + for (ts_nr = 0; ts_nr < line->num_ts; ts_nr++) { ts = &line->ts[ts_nr]; e1ts_dump_vty(vty, ts); } @@ -224,7 +245,7 @@ DEFUN(show_e1ts, } if (argc >= 2) { ts_nr = atoi(argv[1]); - if (ts_nr >= NUM_E1_TS) { + if (ts_nr >= line->num_ts) { vty_out(vty, "E1 timeslot %s is invalid%s", argv[1], VTY_NEWLINE); return CMD_WARNING; @@ -233,7 +254,7 @@ DEFUN(show_e1ts, e1ts_dump_vty(vty, ts); return CMD_SUCCESS; } else { - for (ts_nr = 0; ts_nr < NUM_E1_TS; ts_nr++) { + for (ts_nr = 0; ts_nr < line->num_ts; ts_nr++) { ts = &line->ts[ts_nr]; e1ts_dump_vty(vty, ts); } @@ -254,6 +275,7 @@ int e1inp_vty_init(void) install_element(CONFIG_NODE, &cfg_e1inp_cmd); install_node(&e1inp_node, e1inp_config_write); install_element(L_E1INP_NODE, &cfg_e1_line_driver_cmd); + install_element(L_E1INP_NODE, &cfg_e1_line_port_cmd); install_element(L_E1INP_NODE, &cfg_e1_line_name_cmd); install_element_ve(&show_e1drv_cmd); diff --git a/src/input/dahdi.c b/src/input/dahdi.c index 66bf53f..75331cc 100644 --- a/src/input/dahdi.c +++ b/src/input/dahdi.c @@ -51,6 +51,62 @@ #define TS1_ALLOC_SIZE 300 +struct span_cfg { + struct llist_head list; + + unsigned int span_nr; + unsigned int chan_base; + unsigned int chan_num; +}; + +static struct span_cfg *span_cfgs[DAHDI_MAX_SPANS]; + +static int reread_span_cfgs(void) +{ + struct dahdi_spaninfo si; + unsigned int basechan = 1; + int i; + int fd; + + if ((fd = open("/dev/dahdi/ctl", O_RDWR)) < 0) { + LOGP(DLMI, LOGL_ERROR, "Unable to open DAHDI ctl: %s\n", + strerror(errno)); + return -EIO; + } + + for (i = 1; i < DAHDI_MAX_SPANS; i++) { + struct span_cfg *scfg; + + /* clear any old cached information */ + if (span_cfgs[i]) { + talloc_free(span_cfgs[i]); + span_cfgs[i] = NULL; + } + + memset(&si, 0, sizeof(si)); + si.spanno = i; + if (ioctl(fd, DAHDI_SPANSTAT, &si)) + continue; + + /* create and link new span_cfg */ + scfg = talloc_zero(NULL, struct span_cfg); + if (!scfg) { + close(fd); + return -ENOMEM; + } + scfg->span_nr = i; + scfg->chan_num = si.totalchans; + scfg->chan_base = basechan; + span_cfgs[i] = scfg; + + basechan += si.totalchans; + } + + close(fd); + + return 0; +} + /* Corresponds to dahdi/user.h, only PRI related events */ static const struct value_string dahdi_evt_names[] = { { DAHDI_EVENT_NONE, "NONE" }, @@ -383,10 +439,19 @@ void dahdi_set_bufinfo(int fd, int as_sigchan) static int dahdi_e1_setup(struct e1inp_line *line) { + struct span_cfg *scfg; int ts, ret; + reread_span_cfgs(); + + scfg = span_cfgs[line->port_nr]; + if (!scfg) + return -EIO; + + line->num_ts = scfg->chan_num; + /* TS0 is CRC4, don't need any fd for it */ - for (ts = 1; ts < NUM_E1_TS; ts++) { + for (ts = 1; ts <= scfg->chan_num; ts++) { unsigned int idx = ts-1; char openstr[128]; struct e1inp_ts *e1i_ts = &line->ts[idx]; @@ -400,7 +465,7 @@ static int dahdi_e1_setup(struct e1inp_line *line) /* DAHDI device names/numbers just keep incrementing * even over multiple boards. So TS1 of the second * board will be 32 */ - dev_nr = line->num * (NUM_E1_TS-1) + ts; + dev_nr = scfg->chan_base + idx; bfd->data = line; bfd->priv_nr = ts; diff --git a/src/input/misdn.c b/src/input/misdn.c index 716c1e7..fce6150 100644 --- a/src/input/misdn.c +++ b/src/input/misdn.c @@ -495,7 +495,7 @@ static int mi_e1_setup(struct e1inp_line *line, int release_l2) memset(&addr, 0, sizeof(addr)); addr.family = AF_ISDN; - addr.dev = line->num; + addr.dev = line->port_nr; switch (e1i_ts->type) { case E1INP_TS_TYPE_SIGN: if (mline->use_userspace_lapd) { @@ -579,11 +579,11 @@ static int _mi_e1_line_update(struct e1inp_line *line) //DEBUGP(DLMI,"%d device%s found\n", cnt, (cnt==1)?"":"s"); printf("%d device%s found\n", cnt, (cnt==1)?"":"s"); #if 1 - devinfo.id = line->num; + devinfo.id = line->port_nr; ret = ioctl(sk, IMGETDEVINFO, &devinfo); if (ret < 0) { fprintf(stdout, "error getting info for device %d: %s\n", - line->num, strerror(errno)); + line->port_nr, strerror(errno)); return -ENODEV; } fprintf(stdout, " id: %d\n", devinfo.id); -- cgit v1.2.3