aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/e1_input.c3
-rw-r--r--src/e1_input_vty.c28
-rw-r--r--src/input/dahdi.c69
-rw-r--r--src/input/misdn.c6
4 files changed, 97 insertions, 9 deletions
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);