summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTzafrir Cohen <tzafrir.cohen@xorcom.com>2011-11-02 20:10:06 +0000
committerTzafrir Cohen <tzafrir.cohen@xorcom.com>2011-11-02 20:10:06 +0000
commit142f48d0d460adeeea779a1ab4c5dda7495d6308 (patch)
treef93b2feaa9260d8fa09d8d4f4a7dbb9da86d3867
parentbfa413298ae251fdd60df09a0924763cd8089a72 (diff)
dahdi_cfg: add '-S <spanno>' and '-C <chan-ranges>'
* dahdi_cfg -S <num>: only apply changes to span <num>. * If span is analog (no 'span=<num>,<channels>,...' statement in system.conf), we need to set range: -C <channels> * With the <basechan> and <channels> attributes in sysfs we easily configure each device on the fly. Simply run: dahdi_cfg -S <spanno> -C <basechan>+<channels>-1 from udev script Signed-off-by: Oron Peled <oron.peled@xorcom.com> Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com> git-svn-id: http://svn.asterisk.org/svn/dahdi/tools/trunk@10306 a0bf4364-ded3-4de4-8d8a-66a801d63aff
-rw-r--r--dahdi_cfg.c116
-rw-r--r--doc/dahdi_cfg.816
2 files changed, 129 insertions, 3 deletions
diff --git a/dahdi_cfg.c b/dahdi_cfg.c
index f8ae052..cb23ae9 100644
--- a/dahdi_cfg.c
+++ b/dahdi_cfg.c
@@ -85,6 +85,13 @@ static struct dahdi_lineconfig lc[DAHDI_MAX_SPANS];
static struct dahdi_chanconfig cc[DAHDI_MAX_CHANNELS];
+static int current_span = 0;
+static int only_span = 0;
+static int restrict_channels = 0;
+static int selected_channels[DAHDI_MAX_CHANNELS];
+static int chan2span[DAHDI_MAX_CHANNELS];
+static int declared_spans[DAHDI_MAX_SPANS];
+
static struct dahdi_attach_echocan ae[DAHDI_MAX_CHANNELS];
static struct dahdi_dynamic_span zds[NUM_DYNAMIC];
@@ -228,6 +235,35 @@ static char *trim(char *buf)
return buf;
}
+static int skip_channel(int x)
+{
+ int spanno = chan2span[x];
+
+ if (restrict_channels) {
+ if (!selected_channels[x])
+ return 1;
+ /* sanity check */
+ if (only_span) {
+ if (spanno != 0 && only_span != spanno) {
+ fprintf(stderr,
+ "Only span %d. Skip selected channel %d from span %d\n",
+ only_span, x, spanno);
+ return 1;
+ }
+ }
+ } else {
+ if (only_span && !declared_spans[only_span]) {
+ fprintf(stderr,
+ "Error: analog span %d given to '-S', without '-C' restriction.\n",
+ only_span);
+ exit(1);
+ }
+ if (only_span && only_span != spanno)
+ return 1;
+ }
+ return 0;
+}
+
static int parseargs(char *input, char *output[], int maxargs, char sep)
{
char *c;
@@ -311,6 +347,8 @@ int spanconfig(char *keyword, char *args)
error("Span number should be a valid span number, not '%s'\n", realargs[0]);
return -1;
}
+ current_span = span;
+ declared_spans[span] = 1;
res = sscanf(realargs[1], "%d", &timing);
if ((res != 1) || (timing < 0) || (timing > MAX_TIMING)) {
error("Timing should be a number from 0 to %d, not '%s'\n",
@@ -482,6 +520,7 @@ static int chanconfig(char *keyword, char *args)
int master=0;
int dacschan = 0;
char *idle;
+ int is_digital;
bzero(chans, sizeof(chans));
strtok(args, ":");
idle = strtok(NULL, ":");
@@ -493,6 +532,7 @@ static int chanconfig(char *keyword, char *args)
if (res <= 0)
return -1;
for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
+ is_digital = 0;
if (chans[x]) {
if (slineno[x]) {
error("Channel %d already configured as '%s' at line %d\n", x, sig[x], slineno[x]);
@@ -538,6 +578,7 @@ static int chanconfig(char *keyword, char *args)
return -1;
cc[x].sigtype = DAHDI_SIG_CAS;
sig[x] = sigtype_to_str(cc[x].sigtype);
+ is_digital = 1;
} else if (!strcasecmp(keyword, "dacs")) {
/* Setup channel for monitor */
cc[x].idlebits = dacschan;
@@ -548,6 +589,7 @@ static int chanconfig(char *keyword, char *args)
cc[dacschan].sigtype = DAHDI_SIG_DACS;
sig[x] = sigtype_to_str(cc[dacschan].sigtype);
dacschan++;
+ is_digital = 1;
} else if (!strcasecmp(keyword, "dacsrbs")) {
/* Setup channel for monitor */
cc[x].idlebits = dacschan;
@@ -557,6 +599,7 @@ static int chanconfig(char *keyword, char *args)
cc[dacschan].idlebits = x;
cc[dacschan].sigtype = DAHDI_SIG_DACS_RBS;
sig[x] = sigtype_to_str(cc[dacschan].sigtype);
+ is_digital = 1;
dacschan++;
} else if (!strcasecmp(keyword, "unused")) {
cc[x].sigtype = 0;
@@ -564,6 +607,7 @@ static int chanconfig(char *keyword, char *args)
} else if (!strcasecmp(keyword, "indclear") || !strcasecmp(keyword, "bchan")) {
cc[x].sigtype = DAHDI_SIG_CLEAR;
sig[x] = sigtype_to_str(cc[x].sigtype);
+ is_digital = 1;
} else if (!strcasecmp(keyword, "clear")) {
sig[x] = sigtype_to_str(DAHDI_SIG_CLEAR);
if (master) {
@@ -573,6 +617,7 @@ static int chanconfig(char *keyword, char *args)
cc[x].sigtype = DAHDI_SIG_CLEAR;
master = x;
}
+ is_digital = 1;
} else if (!strcasecmp(keyword, "rawhdlc")) {
sig[x] = sigtype_to_str(DAHDI_SIG_HDLCRAW);
if (master) {
@@ -582,6 +627,7 @@ static int chanconfig(char *keyword, char *args)
cc[x].sigtype = DAHDI_SIG_HDLCRAW;
master = x;
}
+ is_digital = 1;
} else if (!strcasecmp(keyword, "nethdlc")) {
sig[x] = sigtype_to_str(DAHDI_SIG_HDLCNET);
memset(cc[x].netdev_name, 0, sizeof(cc[x].netdev_name));
@@ -595,6 +641,7 @@ static int chanconfig(char *keyword, char *args)
}
master = x;
}
+ is_digital = 1;
} else if (!strcasecmp(keyword, "fcshdlc")) {
sig[x] = sigtype_to_str(DAHDI_SIG_HDLCFCS);
if (master) {
@@ -604,18 +651,26 @@ static int chanconfig(char *keyword, char *args)
cc[x].sigtype = DAHDI_SIG_HDLCFCS;
master = x;
}
+ is_digital = 1;
} else if (!strcasecmp(keyword, "dchan")) {
sig[x] = "D-channel";
cc[x].sigtype = DAHDI_SIG_HDLCFCS;
+ is_digital = 1;
} else if (!strcasecmp(keyword, "hardhdlc")) {
sig[x] = "Hardware assisted D-channel";
cc[x].sigtype = DAHDI_SIG_HARDHDLC;
+ is_digital = 1;
} else if (!strcasecmp(keyword, "mtp2")) {
sig[x] = "MTP2";
cc[x].sigtype = DAHDI_SIG_MTP2;
+ is_digital = 1;
} else {
fprintf(stderr, "Huh? (%s)\n", keyword);
}
+ if (is_digital)
+ chan2span[x] = current_span;
+ else
+ current_span = 0;
}
}
return 0;
@@ -667,6 +722,8 @@ static void apply_fiftysix(void)
int chanfd;
for (x = 1; x < DAHDI_MAX_CHANNELS; x++) {
+ if (skip_channel(x))
+ continue;
chanfd = open("/dev/dahdi/channel", O_RDWR);
if (chanfd == -1) {
fprintf(stderr,
@@ -1227,6 +1284,8 @@ static void printconfig(int fd)
"Configuration\n"
"======================\n\n", vi.version, vi.echo_canceller);
for (x = 0; x < spans; x++) {
+ if (only_span && only_span != x)
+ continue;
printf("SPAN %d: %3s/%4s Build-out: %s\n",
lc[x].span,
(lc[x].lineconfig & DAHDI_CONFIG_D4 ? "D4" :
@@ -1244,6 +1303,8 @@ static void printconfig(int fd)
if (verbose > 1) {
printf("\nChannel map:\n\n");
for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
+ if (skip_channel(x))
+ continue;
if ((cc[x].sigtype != DAHDI_SIG_SLAVE) && (cc[x].sigtype)) {
configs++;
ps = 0;
@@ -1267,6 +1328,8 @@ static void printconfig(int fd)
}
} else {
for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
+ if (skip_channel(x))
+ continue;
if (cc[x].sigtype)
configs++;
}
@@ -1361,11 +1424,39 @@ static void usage(char *argv0, int exitcode)
" -h -- Generate this help statement\n"
" -s -- Shutdown spans only\n"
" -t -- Test mode only, do not apply\n"
+ " -C <chan_list> -- Only configure specified channels\n"
+ " -S <spanno> -- Only configure specified span\n"
" -v -- Verbose (more -v's means more verbose)\n"
,c);
exit(exitcode);
}
+static int chan_restrict(char *str)
+{
+ if (apply_channels(selected_channels, str) < 0)
+ return 0;
+ restrict_channels = 1;
+ return 1;
+}
+
+static int span_restrict(char *str)
+{
+ long spanno;
+ char *endptr;
+
+ spanno = strtol(str, &endptr, 10);
+ if (endptr == str) {
+ fprintf(stderr, "Missing valid span number after '-S'\n");
+ return 0;
+ }
+ if (*endptr != '\0') {
+ fprintf(stderr, "Extra garbage after span number in '-S'\n");
+ return 0;
+ }
+ only_span = spanno;
+ return 1;
+}
+
int main(int argc, char *argv[])
{
int c;
@@ -1373,7 +1464,7 @@ int main(int argc, char *argv[])
char *key, *value;
int x,found;
- while((c = getopt(argc, argv, "fthc:vsd::")) != -1) {
+ while((c = getopt(argc, argv, "fthc:vsd::C:S:")) != -1) {
switch(c) {
case 'c':
filename=optarg;
@@ -1396,6 +1487,14 @@ int main(int argc, char *argv[])
case 's':
stopmode = 1;
break;
+ case 'C':
+ if (!chan_restrict(optarg))
+ usage(argv[0], 1);
+ break;
+ case 'S':
+ if (!span_restrict(optarg))
+ usage(argv[0], 1);
+ break;
case 'd':
if (optarg)
debug = atoi(optarg);
@@ -1478,6 +1577,8 @@ finish:
}
if (stopmode) {
for (x=0;x<spans;x++) {
+ if (only_span && x != only_span)
+ continue;
if (ioctl(fd, DAHDI_SHUTDOWN, &lc[x].span)) {
fprintf(stderr, "DAHDI shutdown failed: %s\n", strerror(errno));
close(fd);
@@ -1487,6 +1588,8 @@ finish:
exit(1);
}
for (x=0;x<spans;x++) {
+ if (only_span && x != only_span)
+ continue;
if (ioctl(fd, DAHDI_SPANCONFIG, lc + x)) {
fprintf(stderr, "DAHDI_SPANCONFIG failed on span %d: %s (%d)\n", lc[x].span, strerror(errno), errno);
close(fd);
@@ -1504,7 +1607,14 @@ finish:
struct dahdi_params current_state;
int master;
int needupdate = force;
-
+
+ if (skip_channel(x)) {
+ if (debug & DEBUG_APPLY) {
+ printf("Skip device %d\n", x);
+ fflush(stdout);
+ }
+ continue;
+ }
if (debug & DEBUG_APPLY) {
printf("Configuring device %d\n", x);
fflush(stdout);
@@ -1657,6 +1767,8 @@ finish:
}
}
for (x=0;x<spans;x++) {
+ if (only_span && x != only_span)
+ continue;
if (ioctl(fd, DAHDI_STARTUP, &lc[x].span)) {
fprintf(stderr, "DAHDI startup failed: %s\n", strerror(errno));
close(fd);
diff --git a/doc/dahdi_cfg.8 b/doc/dahdi_cfg.8
index 7a1fe88..5e1eaa2 100644
--- a/doc/dahdi_cfg.8
+++ b/doc/dahdi_cfg.8
@@ -4,7 +4,7 @@
dahdi_cfg \- configures DAHDI kernel modules from /etc/dahdi/system.conf
.SH SYNOPSIS
-.B dahdi_cfg [\-c \fICFG_FILE\fB] [\-s] [\-f] [\-t] [\-v [\-v ... ] ]
+.B dahdi_cfg [\-c \fICFG_FILE\fB] [\-S\fINUM\fB [-S\fICHANS\fB]] [\-s] [\-f] [\-t] [\-v [\-v ... ] ]
.B dahdi_cfg \-h
@@ -26,11 +26,25 @@ Use an alternative configuration file instead of
.I /etc/dahdi/system.conf
.RE
+.B \-C \fICHANNELS
+.RS
+Only apply changes to channels in the specified range. Only
+applicable when \-S is in use.
+.RE
+
.B \-s
.RS
Only shutdown spans.
.RE
+.B \-S \fISPAN
+.RS
+Only apply changes to span no. \fISPAN\fR. For a digital span (with
+a 'span=' line in the configuration file) this will do. For an analog
+span you'll have to explicitly tell dahdi_cfg the range of channels,
+using \-C .
+.RE
+
.B \-f
.RS
Always configure every channel, even if it appears not to have changed.