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.astersk.org/svn/dahdi/tools/trunk@10306 17933a7a-c749-41c5-a318-cba88f637d49
This commit is contained in:
parent
541435eac7
commit
ba070152fc
114
dahdi_cfg.c
114
dahdi_cfg.c
@ -85,6 +85,13 @@ static struct dahdi_lineconfig lc[DAHDI_MAX_SPANS];
|
|||||||
|
|
||||||
static struct dahdi_chanconfig cc[DAHDI_MAX_CHANNELS];
|
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_attach_echocan ae[DAHDI_MAX_CHANNELS];
|
||||||
|
|
||||||
static struct dahdi_dynamic_span zds[NUM_DYNAMIC];
|
static struct dahdi_dynamic_span zds[NUM_DYNAMIC];
|
||||||
@ -228,6 +235,35 @@ static char *trim(char *buf)
|
|||||||
return 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)
|
static int parseargs(char *input, char *output[], int maxargs, char sep)
|
||||||
{
|
{
|
||||||
char *c;
|
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]);
|
error("Span number should be a valid span number, not '%s'\n", realargs[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
current_span = span;
|
||||||
|
declared_spans[span] = 1;
|
||||||
res = sscanf(realargs[1], "%d", &timing);
|
res = sscanf(realargs[1], "%d", &timing);
|
||||||
if ((res != 1) || (timing < 0) || (timing > MAX_TIMING)) {
|
if ((res != 1) || (timing < 0) || (timing > MAX_TIMING)) {
|
||||||
error("Timing should be a number from 0 to %d, not '%s'\n",
|
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 master=0;
|
||||||
int dacschan = 0;
|
int dacschan = 0;
|
||||||
char *idle;
|
char *idle;
|
||||||
|
int is_digital;
|
||||||
bzero(chans, sizeof(chans));
|
bzero(chans, sizeof(chans));
|
||||||
strtok(args, ":");
|
strtok(args, ":");
|
||||||
idle = strtok(NULL, ":");
|
idle = strtok(NULL, ":");
|
||||||
@ -493,6 +532,7 @@ static int chanconfig(char *keyword, char *args)
|
|||||||
if (res <= 0)
|
if (res <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
|
for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
|
||||||
|
is_digital = 0;
|
||||||
if (chans[x]) {
|
if (chans[x]) {
|
||||||
if (slineno[x]) {
|
if (slineno[x]) {
|
||||||
error("Channel %d already configured as '%s' at line %d\n", x, sig[x], 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;
|
return -1;
|
||||||
cc[x].sigtype = DAHDI_SIG_CAS;
|
cc[x].sigtype = DAHDI_SIG_CAS;
|
||||||
sig[x] = sigtype_to_str(cc[x].sigtype);
|
sig[x] = sigtype_to_str(cc[x].sigtype);
|
||||||
|
is_digital = 1;
|
||||||
} else if (!strcasecmp(keyword, "dacs")) {
|
} else if (!strcasecmp(keyword, "dacs")) {
|
||||||
/* Setup channel for monitor */
|
/* Setup channel for monitor */
|
||||||
cc[x].idlebits = dacschan;
|
cc[x].idlebits = dacschan;
|
||||||
@ -548,6 +589,7 @@ static int chanconfig(char *keyword, char *args)
|
|||||||
cc[dacschan].sigtype = DAHDI_SIG_DACS;
|
cc[dacschan].sigtype = DAHDI_SIG_DACS;
|
||||||
sig[x] = sigtype_to_str(cc[dacschan].sigtype);
|
sig[x] = sigtype_to_str(cc[dacschan].sigtype);
|
||||||
dacschan++;
|
dacschan++;
|
||||||
|
is_digital = 1;
|
||||||
} else if (!strcasecmp(keyword, "dacsrbs")) {
|
} else if (!strcasecmp(keyword, "dacsrbs")) {
|
||||||
/* Setup channel for monitor */
|
/* Setup channel for monitor */
|
||||||
cc[x].idlebits = dacschan;
|
cc[x].idlebits = dacschan;
|
||||||
@ -557,6 +599,7 @@ static int chanconfig(char *keyword, char *args)
|
|||||||
cc[dacschan].idlebits = x;
|
cc[dacschan].idlebits = x;
|
||||||
cc[dacschan].sigtype = DAHDI_SIG_DACS_RBS;
|
cc[dacschan].sigtype = DAHDI_SIG_DACS_RBS;
|
||||||
sig[x] = sigtype_to_str(cc[dacschan].sigtype);
|
sig[x] = sigtype_to_str(cc[dacschan].sigtype);
|
||||||
|
is_digital = 1;
|
||||||
dacschan++;
|
dacschan++;
|
||||||
} else if (!strcasecmp(keyword, "unused")) {
|
} else if (!strcasecmp(keyword, "unused")) {
|
||||||
cc[x].sigtype = 0;
|
cc[x].sigtype = 0;
|
||||||
@ -564,6 +607,7 @@ static int chanconfig(char *keyword, char *args)
|
|||||||
} else if (!strcasecmp(keyword, "indclear") || !strcasecmp(keyword, "bchan")) {
|
} else if (!strcasecmp(keyword, "indclear") || !strcasecmp(keyword, "bchan")) {
|
||||||
cc[x].sigtype = DAHDI_SIG_CLEAR;
|
cc[x].sigtype = DAHDI_SIG_CLEAR;
|
||||||
sig[x] = sigtype_to_str(cc[x].sigtype);
|
sig[x] = sigtype_to_str(cc[x].sigtype);
|
||||||
|
is_digital = 1;
|
||||||
} else if (!strcasecmp(keyword, "clear")) {
|
} else if (!strcasecmp(keyword, "clear")) {
|
||||||
sig[x] = sigtype_to_str(DAHDI_SIG_CLEAR);
|
sig[x] = sigtype_to_str(DAHDI_SIG_CLEAR);
|
||||||
if (master) {
|
if (master) {
|
||||||
@ -573,6 +617,7 @@ static int chanconfig(char *keyword, char *args)
|
|||||||
cc[x].sigtype = DAHDI_SIG_CLEAR;
|
cc[x].sigtype = DAHDI_SIG_CLEAR;
|
||||||
master = x;
|
master = x;
|
||||||
}
|
}
|
||||||
|
is_digital = 1;
|
||||||
} else if (!strcasecmp(keyword, "rawhdlc")) {
|
} else if (!strcasecmp(keyword, "rawhdlc")) {
|
||||||
sig[x] = sigtype_to_str(DAHDI_SIG_HDLCRAW);
|
sig[x] = sigtype_to_str(DAHDI_SIG_HDLCRAW);
|
||||||
if (master) {
|
if (master) {
|
||||||
@ -582,6 +627,7 @@ static int chanconfig(char *keyword, char *args)
|
|||||||
cc[x].sigtype = DAHDI_SIG_HDLCRAW;
|
cc[x].sigtype = DAHDI_SIG_HDLCRAW;
|
||||||
master = x;
|
master = x;
|
||||||
}
|
}
|
||||||
|
is_digital = 1;
|
||||||
} else if (!strcasecmp(keyword, "nethdlc")) {
|
} else if (!strcasecmp(keyword, "nethdlc")) {
|
||||||
sig[x] = sigtype_to_str(DAHDI_SIG_HDLCNET);
|
sig[x] = sigtype_to_str(DAHDI_SIG_HDLCNET);
|
||||||
memset(cc[x].netdev_name, 0, sizeof(cc[x].netdev_name));
|
memset(cc[x].netdev_name, 0, sizeof(cc[x].netdev_name));
|
||||||
@ -595,6 +641,7 @@ static int chanconfig(char *keyword, char *args)
|
|||||||
}
|
}
|
||||||
master = x;
|
master = x;
|
||||||
}
|
}
|
||||||
|
is_digital = 1;
|
||||||
} else if (!strcasecmp(keyword, "fcshdlc")) {
|
} else if (!strcasecmp(keyword, "fcshdlc")) {
|
||||||
sig[x] = sigtype_to_str(DAHDI_SIG_HDLCFCS);
|
sig[x] = sigtype_to_str(DAHDI_SIG_HDLCFCS);
|
||||||
if (master) {
|
if (master) {
|
||||||
@ -604,18 +651,26 @@ static int chanconfig(char *keyword, char *args)
|
|||||||
cc[x].sigtype = DAHDI_SIG_HDLCFCS;
|
cc[x].sigtype = DAHDI_SIG_HDLCFCS;
|
||||||
master = x;
|
master = x;
|
||||||
}
|
}
|
||||||
|
is_digital = 1;
|
||||||
} else if (!strcasecmp(keyword, "dchan")) {
|
} else if (!strcasecmp(keyword, "dchan")) {
|
||||||
sig[x] = "D-channel";
|
sig[x] = "D-channel";
|
||||||
cc[x].sigtype = DAHDI_SIG_HDLCFCS;
|
cc[x].sigtype = DAHDI_SIG_HDLCFCS;
|
||||||
|
is_digital = 1;
|
||||||
} else if (!strcasecmp(keyword, "hardhdlc")) {
|
} else if (!strcasecmp(keyword, "hardhdlc")) {
|
||||||
sig[x] = "Hardware assisted D-channel";
|
sig[x] = "Hardware assisted D-channel";
|
||||||
cc[x].sigtype = DAHDI_SIG_HARDHDLC;
|
cc[x].sigtype = DAHDI_SIG_HARDHDLC;
|
||||||
|
is_digital = 1;
|
||||||
} else if (!strcasecmp(keyword, "mtp2")) {
|
} else if (!strcasecmp(keyword, "mtp2")) {
|
||||||
sig[x] = "MTP2";
|
sig[x] = "MTP2";
|
||||||
cc[x].sigtype = DAHDI_SIG_MTP2;
|
cc[x].sigtype = DAHDI_SIG_MTP2;
|
||||||
|
is_digital = 1;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Huh? (%s)\n", keyword);
|
fprintf(stderr, "Huh? (%s)\n", keyword);
|
||||||
}
|
}
|
||||||
|
if (is_digital)
|
||||||
|
chan2span[x] = current_span;
|
||||||
|
else
|
||||||
|
current_span = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -667,6 +722,8 @@ static void apply_fiftysix(void)
|
|||||||
int chanfd;
|
int chanfd;
|
||||||
|
|
||||||
for (x = 1; x < DAHDI_MAX_CHANNELS; x++) {
|
for (x = 1; x < DAHDI_MAX_CHANNELS; x++) {
|
||||||
|
if (skip_channel(x))
|
||||||
|
continue;
|
||||||
chanfd = open("/dev/dahdi/channel", O_RDWR);
|
chanfd = open("/dev/dahdi/channel", O_RDWR);
|
||||||
if (chanfd == -1) {
|
if (chanfd == -1) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -1227,6 +1284,8 @@ static void printconfig(int fd)
|
|||||||
"Configuration\n"
|
"Configuration\n"
|
||||||
"======================\n\n", vi.version, vi.echo_canceller);
|
"======================\n\n", vi.version, vi.echo_canceller);
|
||||||
for (x = 0; x < spans; x++) {
|
for (x = 0; x < spans; x++) {
|
||||||
|
if (only_span && only_span != x)
|
||||||
|
continue;
|
||||||
printf("SPAN %d: %3s/%4s Build-out: %s\n",
|
printf("SPAN %d: %3s/%4s Build-out: %s\n",
|
||||||
lc[x].span,
|
lc[x].span,
|
||||||
(lc[x].lineconfig & DAHDI_CONFIG_D4 ? "D4" :
|
(lc[x].lineconfig & DAHDI_CONFIG_D4 ? "D4" :
|
||||||
@ -1244,6 +1303,8 @@ static void printconfig(int fd)
|
|||||||
if (verbose > 1) {
|
if (verbose > 1) {
|
||||||
printf("\nChannel map:\n\n");
|
printf("\nChannel map:\n\n");
|
||||||
for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
|
for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
|
||||||
|
if (skip_channel(x))
|
||||||
|
continue;
|
||||||
if ((cc[x].sigtype != DAHDI_SIG_SLAVE) && (cc[x].sigtype)) {
|
if ((cc[x].sigtype != DAHDI_SIG_SLAVE) && (cc[x].sigtype)) {
|
||||||
configs++;
|
configs++;
|
||||||
ps = 0;
|
ps = 0;
|
||||||
@ -1267,6 +1328,8 @@ static void printconfig(int fd)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
|
for (x=1;x<DAHDI_MAX_CHANNELS;x++) {
|
||||||
|
if (skip_channel(x))
|
||||||
|
continue;
|
||||||
if (cc[x].sigtype)
|
if (cc[x].sigtype)
|
||||||
configs++;
|
configs++;
|
||||||
}
|
}
|
||||||
@ -1361,11 +1424,39 @@ static void usage(char *argv0, int exitcode)
|
|||||||
" -h -- Generate this help statement\n"
|
" -h -- Generate this help statement\n"
|
||||||
" -s -- Shutdown spans only\n"
|
" -s -- Shutdown spans only\n"
|
||||||
" -t -- Test mode only, do not apply\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"
|
" -v -- Verbose (more -v's means more verbose)\n"
|
||||||
,c);
|
,c);
|
||||||
exit(exitcode);
|
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 main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
@ -1373,7 +1464,7 @@ int main(int argc, char *argv[])
|
|||||||
char *key, *value;
|
char *key, *value;
|
||||||
int x,found;
|
int x,found;
|
||||||
|
|
||||||
while((c = getopt(argc, argv, "fthc:vsd::")) != -1) {
|
while((c = getopt(argc, argv, "fthc:vsd::C:S:")) != -1) {
|
||||||
switch(c) {
|
switch(c) {
|
||||||
case 'c':
|
case 'c':
|
||||||
filename=optarg;
|
filename=optarg;
|
||||||
@ -1396,6 +1487,14 @@ int main(int argc, char *argv[])
|
|||||||
case 's':
|
case 's':
|
||||||
stopmode = 1;
|
stopmode = 1;
|
||||||
break;
|
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':
|
case 'd':
|
||||||
if (optarg)
|
if (optarg)
|
||||||
debug = atoi(optarg);
|
debug = atoi(optarg);
|
||||||
@ -1478,6 +1577,8 @@ finish:
|
|||||||
}
|
}
|
||||||
if (stopmode) {
|
if (stopmode) {
|
||||||
for (x=0;x<spans;x++) {
|
for (x=0;x<spans;x++) {
|
||||||
|
if (only_span && x != only_span)
|
||||||
|
continue;
|
||||||
if (ioctl(fd, DAHDI_SHUTDOWN, &lc[x].span)) {
|
if (ioctl(fd, DAHDI_SHUTDOWN, &lc[x].span)) {
|
||||||
fprintf(stderr, "DAHDI shutdown failed: %s\n", strerror(errno));
|
fprintf(stderr, "DAHDI shutdown failed: %s\n", strerror(errno));
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -1487,6 +1588,8 @@ finish:
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
for (x=0;x<spans;x++) {
|
for (x=0;x<spans;x++) {
|
||||||
|
if (only_span && x != only_span)
|
||||||
|
continue;
|
||||||
if (ioctl(fd, DAHDI_SPANCONFIG, lc + x)) {
|
if (ioctl(fd, DAHDI_SPANCONFIG, lc + x)) {
|
||||||
fprintf(stderr, "DAHDI_SPANCONFIG failed on span %d: %s (%d)\n", lc[x].span, strerror(errno), errno);
|
fprintf(stderr, "DAHDI_SPANCONFIG failed on span %d: %s (%d)\n", lc[x].span, strerror(errno), errno);
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -1505,6 +1608,13 @@ finish:
|
|||||||
int master;
|
int master;
|
||||||
int needupdate = force;
|
int needupdate = force;
|
||||||
|
|
||||||
|
if (skip_channel(x)) {
|
||||||
|
if (debug & DEBUG_APPLY) {
|
||||||
|
printf("Skip device %d\n", x);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (debug & DEBUG_APPLY) {
|
if (debug & DEBUG_APPLY) {
|
||||||
printf("Configuring device %d\n", x);
|
printf("Configuring device %d\n", x);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
@ -1657,6 +1767,8 @@ finish:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (x=0;x<spans;x++) {
|
for (x=0;x<spans;x++) {
|
||||||
|
if (only_span && x != only_span)
|
||||||
|
continue;
|
||||||
if (ioctl(fd, DAHDI_STARTUP, &lc[x].span)) {
|
if (ioctl(fd, DAHDI_STARTUP, &lc[x].span)) {
|
||||||
fprintf(stderr, "DAHDI startup failed: %s\n", strerror(errno));
|
fprintf(stderr, "DAHDI startup failed: %s\n", strerror(errno));
|
||||||
close(fd);
|
close(fd);
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
dahdi_cfg \- configures DAHDI kernel modules from /etc/dahdi/system.conf
|
dahdi_cfg \- configures DAHDI kernel modules from /etc/dahdi/system.conf
|
||||||
.SH SYNOPSIS
|
.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
|
.B dahdi_cfg \-h
|
||||||
|
|
||||||
@ -26,11 +26,25 @@ Use an alternative configuration file instead of
|
|||||||
.I /etc/dahdi/system.conf
|
.I /etc/dahdi/system.conf
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
|
.B \-C \fICHANNELS
|
||||||
|
.RS
|
||||||
|
Only apply changes to channels in the specified range. Only
|
||||||
|
applicable when \-S is in use.
|
||||||
|
.RE
|
||||||
|
|
||||||
.B \-s
|
.B \-s
|
||||||
.RS
|
.RS
|
||||||
Only shutdown spans.
|
Only shutdown spans.
|
||||||
.RE
|
.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
|
.B \-f
|
||||||
.RS
|
.RS
|
||||||
Always configure every channel, even if it appears not to have changed.
|
Always configure every channel, even if it appears not to have changed.
|
||||||
|
Loading…
Reference in New Issue
Block a user