diff options
author | Harald Welte <laforge@gnumonks.org> | 2011-09-13 23:49:04 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2011-09-25 23:37:47 +0200 |
commit | c2889512c4fb4585fc5ef2980937dde64f687f0a (patch) | |
tree | 0eb16a11a7a838e129e4b46c8fe304113c0b2e0c /src/input | |
parent | a0d9331cb13be85fb89fdf6973c50f0514a66bb3 (diff) |
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.
Diffstat (limited to 'src/input')
-rw-r--r-- | src/input/dahdi.c | 69 | ||||
-rw-r--r-- | src/input/misdn.c | 6 |
2 files changed, 70 insertions, 5 deletions
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); |