aboutsummaryrefslogtreecommitdiffstats
path: root/src/input
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2011-09-13 23:49:04 +0100
committerHarald Welte <laforge@gnumonks.org>2011-09-25 23:37:47 +0200
commitc2889512c4fb4585fc5ef2980937dde64f687f0a (patch)
tree0eb16a11a7a838e129e4b46c8fe304113c0b2e0c /src/input
parenta0d9331cb13be85fb89fdf6973c50f0514a66bb3 (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.c69
-rw-r--r--src/input/misdn.c6
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);