diff options
author | jim <jim@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2004-11-04 20:04:53 +0000 |
---|---|---|
committer | jim <jim@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2004-11-04 20:04:53 +0000 |
commit | 7e99207e834bd395443af5f88453b0aea65d3315 (patch) | |
tree | 37bdd5563db7c329733f31693fa75e7b634a8529 /ztcfg.c | |
parent | b420103c9e0c8eaf5bf9c0b040642f08539a487f (diff) |
Added support for Zapata Telephony Quad PCI Radio Interface card.
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@489 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'ztcfg.c')
-rwxr-xr-x | ztcfg.c | 429 |
1 files changed, 425 insertions, 4 deletions
@@ -25,7 +25,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Primary Author: Mark Spencer <markster@linux-support.net> - * + * Radio Support by Jim Dixon <jim@lambdatel.com> */ #include <stdio.h> @@ -43,6 +43,8 @@ #define NUM_SPANS ZT_MAX_SPANS +#define NUM_TONES 15 + /* Assume no more than 1024 dynamics */ #define NUM_DYNAMIC 1024 @@ -52,6 +54,13 @@ static FILE *cf; static char *filename=CONFIG_FILENAME; +int rxtones[NUM_TONES + 1],rxtags[NUM_TONES + 1],txtones[NUM_TONES + 1]; +int bursttime = 0, debouncetime = 0, invertcor = 0, exttone = 0, corthresh = 0; + +int corthreshes[] = {3125,6250,9375,12500,15625,18750,21875,25000,0} ; + +static int toneindex = 1; + #define DEBUG_READER (1 << 0) #define DEBUG_PARSER (1 << 1) #define DEBUG_APPLY (1 << 2) @@ -85,6 +94,8 @@ static char zonestoload[ZT_TONE_ZONE_MAX][10]; static int numzones = 0; +static int fd = -1; + static char *lbostr[] = { "0 db (CSU)/0-133 feet (DSX-1)", "133-266 feet (DSX-1)", @@ -102,6 +113,28 @@ static char *laws[] = { "A-law" }; +int ind_ioctl(int channo, int fd, int op, void *data) +{ +ZT_INDIRECT_DATA ind; + + ind.chan = channo; + ind.op = op; + ind.data = data; + return ioctl(fd,ZT_INDIRECT,&ind); +} + +static void clear_fields() +{ + + memset(rxtones,0,sizeof(rxtones)); + memset(rxtags,0,sizeof(rxtags)); + memset(txtones,0,sizeof(txtones)); + bursttime = 0; + debouncetime = 0; + invertcor = 0; + exttone = 0; +} + static int error(char *fmt, ...) { int res; @@ -558,6 +591,382 @@ static int unimplemented(char *keyword, char *args) } #endif + +/* Radio functions */ + +int ctcss(char *keyword, char *args) +{ + static char *realargs[10]; + int argc; + int res; + int rxtone; + int rxtag; + int txtone; + int isdcs = 0; + argc = res = parseargs(args, realargs, 3, ','); + if (res != 3) { + error("Incorrect number of arguments to 'ctcss' (should be <rxtone>,<rxtag>,<txtone>)\n"); + } + res = sscanf(realargs[0], "%d", &rxtone); + if ((res == 1) && (rxtone < 1)) + res = -1; + if (res != 1) { + error("Invalid rxtone '%s', should be a number > 0.\n", realargs[0]); + } + res = sscanf(realargs[1], "%i", &rxtag); + if ((res == 1) && (rxtag < 0)) + res = -1; + if (res != 1) { + error("Invalid rxtag '%s', should be a number > 0.\n", realargs[1]); + } + if ((*realargs[2] == 'D') || (*realargs[2] == 'd')) + { + realargs[2]++; + isdcs = 0x8000; + } + res = sscanf(realargs[2], "%d", &txtone); + if ((res == 1) && (rxtag < 0)) + res = -1; + if (res != 1) { + error("Invalid txtone '%s', should be a number > 0.\n", realargs[2]); + } + + if (toneindex >= NUM_TONES) + { + error("Cannot specify more then %d CTCSS tones\n",NUM_TONES); + } + rxtones[toneindex] = rxtone; + rxtags[toneindex] = rxtag; + txtones[toneindex] = txtone | isdcs; + toneindex++; + return 0; +} + +int dcsrx(char *keyword, char *args) +{ + static char *realargs[10]; + int argc; + int res; + int rxtone; + argc = res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'dcsrx' (should be <rxtone>)\n"); + } + res = sscanf(realargs[0], "%d", &rxtone); + if ((res == 1) && (rxtone < 1)) + res = -1; + if (res != 1) { + error("Invalid rxtone '%s', should be a number > 0.\n", realargs[0]); + } + + rxtones[0] = rxtone; + return 0; +} + +int tx(char *keyword, char *args) +{ + static char *realargs[10]; + int argc; + int res; + int txtone; + int isdcs = 0; + argc = res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'tx' (should be <txtone>)\n"); + } + if ((*realargs[0] == 'D') || (*realargs[0] == 'd')) + { + realargs[0]++; + isdcs = 0x8000; + } + res = sscanf(realargs[0], "%d", &txtone); + if ((res == 1) && (txtone < 1)) + res = -1; + if (res != 1) { + error("Invalid tx (tone) '%s', should be a number > 0.\n", realargs[0]); + } + + txtones[0] = txtone | isdcs; + return 0; +} + +int debounce_time(char *keyword, char *args) +{ + static char *realargs[10]; + int argc; + int res; + int val; + argc = res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'debouncetime' (should be <value>)\n"); + } + res = sscanf(realargs[0], "%d", &val); + if ((res == 1) && (val < 1)) + res = -1; + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + } + + debouncetime = val; + return 0; +} + +int burst_time(char *keyword, char *args) +{ + static char *realargs[10]; + int argc; + int res; + int val; + argc = res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'bursttime' (should be <value>)\n"); + } + res = sscanf(realargs[0], "%d", &val); + if ((res == 1) && (val < 1)) + res = -1; + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + } + + bursttime = val; + return 0; +} + +int invert_cor(char *keyword, char *args) +{ + static char *realargs[10]; + int argc; + int res; + int val; + argc = res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'invertcor' (should be <value>)\n"); + } + if ((*realargs[0] == 'y') || (*realargs[0] == 'Y')) val = 1; + else if ((*realargs[0] == 'n') || (*realargs[0] == 'N')) val = 0; + else + { + res = sscanf(realargs[0], "%d", &val); + if ((res == 1) && (val < 0)) + res = -1; + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + } + } + invertcor = (val > 0); + return 0; +} + +int ext_tone(char *keyword, char *args) +{ + static char *realargs[10]; + int argc; + int res; + int val; + argc = res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'exttone' (should be <value>)\n"); + } + if ((*realargs[0] == 'y') || (*realargs[0] == 'Y')) val = 1; + else if ((*realargs[0] == 'n') || (*realargs[0] == 'N')) val = 0; + else if ((*realargs[0] == 'i') || (*realargs[0] == 'I')) val = 2; + else + { + res = sscanf(realargs[0], "%d", &val); + if ((res == 1) && (val < 0)) + res = -1; + if (val > 2) res = -1; + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + } + } + exttone = val; + return 0; +} + +int cor_thresh(char *keyword, char *args) +{ + static char *realargs[10]; + int argc; + int res; + int val; + int x = 0; + argc = res = parseargs(args, realargs, 1, ','); + if (res != 1) { + error("Incorrect number of arguments to 'corthresh' (should be <value>)\n"); + } + res = sscanf(realargs[0], "%d", &val); + if ((res == 1) && (val < 1)) + res = -1; + for(x = 0; corthreshes[x]; x++) + { + if (corthreshes[x] == val) break; + } + if (!corthreshes[x]) res = -1; + if (res != 1) { + error("Invalid value '%s', should be a number > 0.\n", realargs[0]); + } + corthresh = x; + return 0; +} + +int rad_apply_channels(int chans[], char *argstr) +{ + char *args[ZT_MAX_CHANNELS+1]; + char *range[3]; + int res,x, res2,y; + int chan; + int start, finish; + char argcopy[256]; + res = parseargs(argstr, args, ZT_MAX_CHANNELS, ','); + if (res < 0) + error("Too many arguments... Max is %d\n", ZT_MAX_CHANNELS); + for (x=0;x<res;x++) { + if (strchr(args[x], '-')) { + /* It's a range */ + strncpy(argcopy, args[x], sizeof(argcopy)); + res2 = parseargs(argcopy, range, 2, '-'); + if (res2 != 2) { + error("Syntax error in range '%s'. Should be <val1>-<val2>.\n", args[x]); + return -1; + } + res2 =sscanf(range[0], "%i", &start); + if (res2 != 1) { + error("Syntax error. Start of range '%s' should be a number from 1 to %d\n", args[x], ZT_MAX_CHANNELS - 1); + return -1; + } else if ((start < 1) || (start >= ZT_MAX_CHANNELS)) { + error("Start of range '%s' must be between 1 and %d (not '%d')\n", args[x], ZT_MAX_CHANNELS - 1, start); + return -1; + } + res2 =sscanf(range[1], "%i", &finish); + if (res2 != 1) { + error("Syntax error. End of range '%s' should be a number from 1 to %d\n", args[x], ZT_MAX_CHANNELS - 1); + return -1; + } else if ((finish < 1) || (finish >= ZT_MAX_CHANNELS)) { + error("end of range '%s' must be between 1 and %d (not '%d')\n", args[x], ZT_MAX_CHANNELS - 1, finish); + return -1; + } + if (start > finish) { + error("Range '%s' should start before it ends\n", args[x]); + return -1; + } + for (y=start;y<=finish;y++) + chans[y]=1; + } else { + /* It's a single channel */ + res2 =sscanf(args[x], "%i", &chan); + if (res2 != 1) { + error("Syntax error. Channel should be a number from 1 to %d, not '%s'\n", ZT_MAX_CHANNELS - 1, args[x]); + return -1; + } else if ((chan < 1) || (chan >= ZT_MAX_CHANNELS)) { + error("Channel must be between 1 and %d (not '%d')\n", ZT_MAX_CHANNELS - 1, chan); + return -1; + } + chans[chan]=1; + } + } + return res; +} + +static int rad_chanconfig(char *keyword, char *args) +{ + int chans[ZT_MAX_CHANNELS]; + int res = 0; + int x,i,n; + struct zt_radio_param p; + + bzero(chans, sizeof(chans)); + res = rad_apply_channels(chans, args); + if (res <= 0) + return -1; + for (x=1;x<ZT_MAX_CHANNELS;x++) { + if (chans[x]) { + + p.radpar = ZT_RADPAR_NUMTONES; + if (ind_ioctl(x,fd,ZT_RADIO_GETPARAM,&p) == -1) + error("Cannot get number of tones chanel %d\n",x); + n = p.data; + if (!rxtones[0]) for(i = 1; i <= n; i++) + { + if (rxtones[i]) + { + p.radpar = ZT_RADPAR_RXTONE; + p.index = i; + p.data = rxtones[i]; + if (ind_ioctl(x,fd,ZT_RADIO_SETPARAM,&p) == -1) + error("Cannot set rxtone on channel %d\n",x); + } + if (rxtags[i]) + { + p.radpar = ZT_RADPAR_RXTONECLASS; + p.index = i; + p.data = rxtags[i]; + if (ind_ioctl(x,fd,ZT_RADIO_SETPARAM,&p) == -1) + error("Cannot set rxtag on channel %d\n",x); + } + if (txtones[i]) + { + p.radpar = ZT_RADPAR_RXTONE; + p.index = i; + p.data = txtones[i]; + if (ind_ioctl(x,fd,ZT_RADIO_SETPARAM,&p) == -1) + error("Cannot set txtone on channel %d\n",x); + } + } else { /* if we have DCS receive */ + p.radpar = ZT_RADPAR_RXTONE; + p.index = 0; + p.data = rxtones[0]; + if (ind_ioctl(x,fd,ZT_RADIO_SETPARAM,&p) == -1) + error("Cannot set DCS rxtone on channel %d\n",x); + } + if (txtones[0]) + { + p.radpar = ZT_RADPAR_TXTONE; + p.index = 0; + p.data = txtones[0]; + if (ind_ioctl(x,fd,ZT_RADIO_SETPARAM,&p) == -1) + error("Cannot set default txtone on channel %d\n",x); + } + if (debouncetime) + { + p.radpar = ZT_RADPAR_DEBOUNCETIME; + p.data = debouncetime; + if (ind_ioctl(x,fd,ZT_RADIO_SETPARAM,&p) == -1) + error("Cannot set debouncetime on channel %d\n",x); + } + if (bursttime) + { + p.radpar = ZT_RADPAR_BURSTTIME; + p.data = bursttime; + if (ind_ioctl(x,fd,ZT_RADIO_SETPARAM,&p) == -1) + error("Cannot set bursttime on channel %d\n",x); + } + if (invertcor) + { + p.radpar = ZT_RADPAR_INVERTCOR; + p.data = invertcor; + if (ind_ioctl(x,fd,ZT_RADIO_SETPARAM,&p) == -1) + error("Cannot set invertcor on channel %d\n",x); + } + if (exttone) + { + p.radpar = ZT_RADPAR_EXTRXTONE; + p.data = exttone; + if (ind_ioctl(x,fd,ZT_RADIO_SETPARAM,&p) == -1) + error("Cannot set exttone on channel %d\n",x); + } + p.radpar = ZT_RADPAR_CORTHRESH; + p.data = corthresh; + if (ind_ioctl(x,fd,ZT_RADIO_SETPARAM,&p) == -1) + error("Cannot set corthresh on channel %d\n",x); + } + } + clear_fields(); + return 0; +} + +/* End Radio functions */ + static void printconfig() { int x,y; @@ -635,6 +1044,17 @@ static struct handler { { "alaw", setlaw }, { "mulaw", setlaw }, { "deflaw", setlaw }, + { "ctcss", ctcss }, + { "dcsrx", dcsrx }, + { "rxdcs", dcsrx }, + { "tx", tx }, + { "debouncetime", debounce_time }, + { "bursttime", burst_time }, + { "exttone", ext_tone }, + { "invertcor", invert_cor }, + { "corthresh", cor_thresh }, + { "channel", rad_chanconfig }, + { "channels", rad_chanconfig }, }; static char *readline() @@ -680,7 +1100,6 @@ int main(int argc, char *argv[]) char *buf; char *key, *value; int x,found; - int fd; while((c = getopt(argc, argv, "thc:vs")) != -1) { switch(c) { case 'c': @@ -703,6 +1122,9 @@ int main(int argc, char *argv[]) break; } } + if (fd == -1) fd = open(MASTER_DEVICE, O_RDWR); + if (fd < 0) + error("Unable to open master device '%s'\n", MASTER_DEVICE); cf = fopen(filename, "r"); if (cf) { while((buf = readline())) { @@ -748,7 +1170,7 @@ int main(int argc, char *argv[]) printf("About to open Master device\n"); fflush(stdout); } - fd = open(MASTER_DEVICE, O_RDWR); + if (fd == -1) fd = open(MASTER_DEVICE, O_RDWR); if (fd < 0) error("Unable to open master device '%s'\n", MASTER_DEVICE); else { @@ -821,7 +1243,6 @@ int main(int argc, char *argv[]) } } } - close(fd); } } } else { |