summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2005-09-29 02:29:17 +0000
committerkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2005-09-29 02:29:17 +0000
commitbb9675a0268c73b0ad7c8af51b47967e99cda828 (patch)
treea019aeb8d83f2e84e0589c51033f89e0fb9745ae
parent29c4eb44ca49102abd9e20ba4694e0492e214627 (diff)
update ztcfg to only reconfigured changed channels unless 'force' parameter is supplied
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@781 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rwxr-xr-xdoc/ztcfg.85
-rwxr-xr-xzaptel.c13
-rwxr-xr-xzaptel.h2
-rwxr-xr-xztcfg.c152
4 files changed, 138 insertions, 34 deletions
diff --git a/doc/ztcfg.8 b/doc/ztcfg.8
index 3b7aba5..07a1c65 100755
--- a/doc/ztcfg.8
+++ b/doc/ztcfg.8
@@ -9,7 +9,7 @@
ztcfg \- reads and loads zaptel.conf
.SH SYNOPSIS
-\fBztcfg\fR [ \fB-c \fICFG_FILE\fB \fR ] [ \fB-s\fR ] [ \fB-t\fR ] [ \fB-v [ -v\fI ...\fB ]\fR ]
+\fBztcfg\fR [ \fB-c \fICFG_FILE\fB \fR ] [ \fB-s\fR ] [ \fB-f\fR ] [ \fB-t\fR ] [ \fB-v [ -v\fI ...\fB ]\fR ]
\fBztcfg\fR [ \fB-h\fR ]
@@ -30,6 +30,9 @@ Use an alternative configuration file instead of
\fB-s\fR
Only shutdown spans.
.TP
+\fB-f\fR
+Always configure every channel, even if it appears not to have changed.
+.TP
\fB-t\fR
Test mode. Don't do anything, just report what you
wanted to do.
diff --git a/zaptel.c b/zaptel.c
index 6a68ffe..6c7c596 100755
--- a/zaptel.c
+++ b/zaptel.c
@@ -2761,9 +2761,9 @@ static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int c
copy_from_user(&stack.param,(struct zt_params *)data,sizeof(stack.param));
/* check to see if the caller wants to receive our master channel number */
- if (stack.param.channo & 0x40000000) {
+ if (stack.param.channo & ZT_GET_PARAMS_RETURN_MASTER) {
return_master = 1;
- stack.param.channo &= ~0x40000000;
+ stack.param.channo &= ~ZT_GET_PARAMS_RETURN_MASTER;
}
/* Pick the right channo's */
@@ -2774,10 +2774,6 @@ static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int c
VALID_CHANNEL(stack.param.channo);
chan = chans[stack.param.channo];
- /* if requested, put the master channel number in the top 16 bits of the result */
- if (return_master)
- stack.param.channo |= chan->master->channo << 16;
-
/* point to relevant structure */
stack.param.sigtype = chan->sig; /* get signalling type */
/* return non-zero if rx not in idle state */
@@ -2817,6 +2813,11 @@ static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int c
stack.param.rxflashtime = chan->rxflashtime;
stack.param.debouncetime = chan->debouncetime;
stack.param.channo = chan->channo;
+
+ /* if requested, put the master channel number in the top 16 bits of the result */
+ if (return_master)
+ stack.param.channo |= chan->master->channo << 16;
+
stack.param.pulsemaketime = chan->pulsemaketime;
stack.param.pulsebreaktime = chan->pulsebreaktime;
stack.param.pulseaftertime = chan->pulseaftertime;
diff --git a/zaptel.h b/zaptel.h
index bb872e1..6a64b3f 100755
--- a/zaptel.h
+++ b/zaptel.h
@@ -162,6 +162,8 @@
#endif
#endif
+#define ZT_GET_PARAMS_RETURN_MASTER 0x40000000
+
typedef struct zt_params
{
int channo; /* Channel number */
diff --git a/ztcfg.c b/ztcfg.c
index 82cd2c0..044e451 100755
--- a/ztcfg.c
+++ b/ztcfg.c
@@ -76,7 +76,7 @@ static struct zt_chanconfig cc[ZT_MAX_CHANNELS];
static struct zt_dynamic_span zds[NUM_DYNAMIC];
-static char *sig[ZT_MAX_CHANNELS]; /* Signalling */
+static const char *sig[ZT_MAX_CHANNELS]; /* Signalling */
static int slineno[ZT_MAX_CHANNELS]; /* Line number where signalling specified */
@@ -86,6 +86,8 @@ static int fo_real = 1;
static int verbose = 0;
+static int force = 0;
+
static int stopmode = 0;
static int numdynamic = 0;
@@ -96,7 +98,7 @@ static int numzones = 0;
static int fd = -1;
-static char *lbostr[] = {
+static const char *lbostr[] = {
"0 db (CSU)/0-133 feet (DSX-1)",
"133-266 feet (DSX-1)",
"266-399 feet (DSX-1)",
@@ -107,12 +109,54 @@ static char *lbostr[] = {
"-22.5db (CSU)"
};
-static char *laws[] = {
+static const char *laws[] = {
"Default",
"Mu-law",
"A-law"
};
+static const char *sigtype_to_str(const int sig)
+{
+ switch (sig) {
+ case 0:
+ return "Unused";
+ case ZT_SIG_EM:
+ return "E & M";
+ case ZT_SIG_EM_E1:
+ return "E & M E1";
+ case ZT_SIG_FXSLS:
+ return "FXS Loopstart";
+ case ZT_SIG_FXSGS:
+ return "FXS Groundstart";
+ case ZT_SIG_FXSKS:
+ return "FXS Kewlstart";
+ case ZT_SIG_FXOLS:
+ return "FXO Loopstart";
+ case ZT_SIG_FXOGS:
+ return "FXO Groundstart";
+ case ZT_SIG_FXOKS:
+ return "FXO Kewlstart";
+ case ZT_SIG_CAS:
+ return "CAS / User";
+ case ZT_SIG_DACS:
+ return "DACS";
+ case ZT_SIG_DACS_RBS:
+ return "DACS w/RBS";
+ case ZT_SIG_CLEAR:
+ return "Clear channel";
+ case ZT_SIG_SLAVE:
+ return "Slave channel";
+ case ZT_SIG_HDLCRAW:
+ return "Raw HDLC";
+ case ZT_SIG_HDLCNET:
+ return "Network HDLC";
+ case ZT_SIG_HDLCFCS:
+ return "HDLC with FCS check";
+ default:
+ return "Unknown";
+ }
+}
+
int ind_ioctl(int channo, int fd, int op, void *data)
{
ZT_INDIRECT_DATA ind;
@@ -434,62 +478,62 @@ static int chanconfig(char *keyword, char *args)
cc[x].master = x;
slineno[x] = lineno;
if (!strcasecmp(keyword, "e&m")) {
- sig[x] = "E & M";
cc[x].sigtype = ZT_SIG_EM;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
} else if (!strcasecmp(keyword, "e&me1")) {
- sig[x] = "E & M E1";
cc[x].sigtype = ZT_SIG_EM_E1;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
} else if (!strcasecmp(keyword, "fxsls")) {
- sig[x] = "FXS Loopstart";
cc[x].sigtype = ZT_SIG_FXSLS;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
} else if (!strcasecmp(keyword, "fxsgs")) {
- sig[x] = "FXS Groundstart";
cc[x].sigtype = ZT_SIG_FXSGS;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
} else if (!strcasecmp(keyword, "fxsks")) {
- sig[x] = "FXS Kewlstart";
cc[x].sigtype = ZT_SIG_FXSKS;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
} else if (!strcasecmp(keyword, "fxols")) {
- sig[x] = "FXO Loopstart";
cc[x].sigtype = ZT_SIG_FXOLS;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
} else if (!strcasecmp(keyword, "fxogs")) {
- sig[x] = "FXO Groundstart";
cc[x].sigtype = ZT_SIG_FXOGS;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
} else if (!strcasecmp(keyword, "fxoks")) {
- sig[x] = "FXO Kewlstart";
cc[x].sigtype = ZT_SIG_FXOKS;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
} else if (!strcasecmp(keyword, "cas") || !strcasecmp(keyword, "user")) {
if (parse_idle(&cc[x].idlebits, idle))
return -1;
- sig[x] = "CAS / User";
cc[x].sigtype = ZT_SIG_CAS;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
} else if (!strcasecmp(keyword, "dacs")) {
/* Setup channel for monitor */
cc[x].idlebits = dacschan;
cc[x].sigtype = ZT_SIG_DACS;
- sig[x] = "DACS";
+ sig[x] = sigtype_to_str(cc[x].sigtype);
/* Setup inverse */
cc[dacschan].idlebits = x;
cc[dacschan].sigtype = ZT_SIG_DACS;
- sig[dacschan] = "DACS";
+ sig[x] = sigtype_to_str(cc[dacschan].sigtype);
dacschan++;
} else if (!strcasecmp(keyword, "dacsrbs")) {
/* Setup channel for monitor */
cc[x].idlebits = dacschan;
cc[x].sigtype = ZT_SIG_DACS_RBS;
- sig[x] = "DACS w/ RBS";
+ sig[x] = sigtype_to_str(cc[x].sigtype);
/* Setup inverse */
cc[dacschan].idlebits = x;
cc[dacschan].sigtype = ZT_SIG_DACS_RBS;
- sig[dacschan] = "DACS w/ RBS";
+ sig[x] = sigtype_to_str(cc[dacschan].sigtype);
dacschan++;
} else if (!strcasecmp(keyword, "unused")) {
- sig[x] = "Unused";
cc[x].sigtype = 0;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
} else if (!strcasecmp(keyword, "indclear") || !strcasecmp(keyword, "bchan")) {
- sig[x] = "Individual Clear channel";
cc[x].sigtype = ZT_SIG_CLEAR;
+ sig[x] = sigtype_to_str(cc[x].sigtype);
} else if (!strcasecmp(keyword, "clear")) {
- sig[x] = "Clear channel";
+ sig[x] = sigtype_to_str(ZT_SIG_CLEAR);
if (master) {
cc[x].sigtype = ZT_SIG_SLAVE;
cc[x].master = master;
@@ -498,7 +542,7 @@ static int chanconfig(char *keyword, char *args)
master = x;
}
} else if (!strcasecmp(keyword, "rawhdlc")) {
- sig[x] = "Raw HDLC";
+ sig[x] = sigtype_to_str(ZT_SIG_HDLCRAW);
if (master) {
cc[x].sigtype = ZT_SIG_SLAVE;
cc[x].master = master;
@@ -507,7 +551,7 @@ static int chanconfig(char *keyword, char *args)
master = x;
}
} else if (!strcasecmp(keyword, "nethdlc")) {
- sig[x] = "Network HDLC";
+ sig[x] = sigtype_to_str(ZT_SIG_HDLCNET);
if (master) {
cc[x].sigtype = ZT_SIG_SLAVE;
cc[x].master = master;
@@ -516,7 +560,7 @@ static int chanconfig(char *keyword, char *args)
master = x;
}
} else if (!strcasecmp(keyword, "fcshdlc")) {
- sig[x] = "HDLC with FCS check";
+ sig[x] = sigtype_to_str(ZT_SIG_HDLCFCS);
if (master) {
cc[x].sigtype = ZT_SIG_SLAVE;
cc[x].master = master;
@@ -1094,11 +1138,12 @@ static void usage(char *argv0, int exitcode)
"Usage: %s [options]\n"
" Valid options are:\n"
" -c <filename> -- Use <filename> instead of " CONFIG_FILENAME "\n"
- " -h -- Generate this help statement\n"
- " -v -- Verbose (more -v's means more verbose)\n"
" -d [level] -- Generate debugging output. (Default level is 1.)\n"
- " -t -- Test mode only, do not apply\n"
+ " -f -- Always reconfigure every channel\n"
+ " -h -- Generate this help statement\n"
" -s -- Shutdown spans only\n"
+ " -t -- Test mode only, do not apply\n"
+ " -v -- Verbose (more -v's means more verbose)\n"
,c);
exit(exitcode);
}
@@ -1109,7 +1154,7 @@ int main(int argc, char *argv[])
char *buf;
char *key, *value;
int x,found;
- while((c = getopt(argc, argv, "thc:vsd::")) != -1) {
+ while((c = getopt(argc, argv, "fthc:vsd::")) != -1) {
switch(c) {
case 'c':
filename=optarg;
@@ -1123,6 +1168,9 @@ int main(int argc, char *argv[])
case 'v':
verbose++;
break;
+ case 'f':
+ force++;
+ break;
case 't':
fo_real = 0;
break;
@@ -1217,11 +1265,61 @@ int main(int argc, char *argv[])
}
}
for (x=1;x<ZT_MAX_CHANNELS;x++) {
+ struct zt_params current_state;
+ int master;
+ int needupdate = force;
+
if (debug & DEBUG_APPLY) {
printf("Configuring device %d\n", x);
fflush(stdout);
}
- if (cc[x].sigtype && ioctl(fd, ZT_CHANCONFIG, &cc[x])) {
+ if (!cc[x].sigtype)
+ continue;
+
+ if (!force) {
+ memset(&current_state, 0, sizeof(current_state));
+ current_state.channo = cc[x].chan | ZT_GET_PARAMS_RETURN_MASTER;
+ if (ioctl(fd, ZT_GET_PARAMS, &current_state)) {
+ fprintf(stderr, "ZT_GET_PARAMS failed on channel %d: %s (%d)\n", x, strerror(errno), errno);
+ close(fd);
+ exit(1);
+ }
+ master = current_state.channo >> 16;
+
+ if (cc[x].sigtype != current_state.sigtype) {
+ needupdate++;
+ if (verbose > 1)
+ printf("Changing signalling on channel %d from %s to %s\n",
+ cc[x].chan, sigtype_to_str(current_state.sigtype),
+ sigtype_to_str(cc[x].sigtype));
+ }
+
+ if ((cc[x].deflaw != ZT_LAW_DEFAULT) && (cc[x].deflaw != current_state.curlaw)) {
+ needupdate++;
+ if (verbose > 1)
+ printf("Changing law on channel %d from %s to %s\n",
+ cc[x].chan, laws[current_state.curlaw],
+ laws[cc[x].deflaw]);
+ }
+
+ if (cc[x].master != master) {
+ needupdate++;
+ if (verbose > 1)
+ printf("Changing master of channel %d from %d to %d\n",
+ cc[x].chan, master,
+ cc[x].master);
+ }
+
+ if (cc[x].idlebits != current_state.idlebits) {
+ needupdate++;
+ if (verbose > 1)
+ printf("Changing idle bits of channel %d from %d to %d\n",
+ cc[x].chan, current_state.idlebits,
+ cc[x].idlebits);
+ }
+ }
+
+ if (needupdate && ioctl(fd, ZT_CHANCONFIG, &cc[x])) {
fprintf(stderr, "ZT_CHANCONFIG failed on channel %d: %s (%d)\n", x, strerror(errno), errno);
if (errno == EINVAL) {
fprintf(stderr, "Did you forget that FXS interfaces are configured with FXO signalling\n"