[Asterisk-cvs] zaptel pciradio.c, NONE, 1.1 Makefile, 1.53, 1.54 zaptel.c, 1.97, 1.98 zaptel.conf.sample, 1.14, 1.15 zaptel.h, 1.38, 1.39 ztcfg.c, 1.16, 1.17

jim at lists.digium.com jim at lists.digium.com
Thu Nov 4 15:02:40 CST 2004


Update of /usr/cvsroot/zaptel
In directory mongoose.digium.com:/tmp/cvs-serv10045

Modified Files:
	Makefile zaptel.c zaptel.conf.sample zaptel.h ztcfg.c 
Added Files:
	pciradio.c 
Log Message:
Added support for Zapata Telephony Quad PCI Radio Interface card.


--- NEW FILE: pciradio.c ---
/*
 * PCI RADIO Card  Zapata Telephony PCI Quad Radio Interface driver
 *
 * Written by Jim Dixon <jim at lambdatel.com>
 * Based on previous work by Mark Spencer <markster at linux-support.net>
 * Based on previous works, designs, and archetectures conceived and
 * written by Jim Dixon <jim at lambdatel.com>.
 *
 * Copyright (C) 2001-2004 Jim Dixon / Zapata Telephony.
 *
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
[...1560 lines suppressed...]
	return 0;
}

static void __exit pciradio_cleanup(void)
{
	pci_unregister_driver(&pciradio_driver);
}

MODULE_PARM(debug, "i");
MODULE_DESCRIPTION("Zapate Telephony PCI Radio Card Zaptel Driver");
MODULE_AUTHOR("Jim Dixon <jim at lambdatel.com>");
#ifdef MODULE_LICENSE
MODULE_LICENSE("GPL");
#endif

module_init(pciradio_init);
module_exit(pciradio_cleanup);




Index: Makefile
===================================================================
RCS file: /usr/cvsroot/zaptel/Makefile,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -d -r1.53 -r1.54
--- Makefile	14 Oct 2004 15:22:08 -0000	1.53
+++ Makefile	4 Nov 2004 20:04:53 -0000	1.54
@@ -52,7 +52,7 @@
 TZOBJS=zonedata.lo tonezone.lo
 LIBTONEZONE=libtonezone.so.1.0
 MODULES=zaptel tor2 torisa wcusb wcfxo wcfxs \
-	ztdynamic ztd-eth wct1xxp wct4xxp wcte11xp # ztdummy
+	ztdynamic ztd-eth wct1xxp wct4xxp wcte11xp pciradio # ztdummy
 #MODULES+=wcfxsusb
 
 MODULESO=$(shell for x in $(MODULES); do echo "$$x.o "; done )
@@ -117,6 +117,9 @@
 wcfxs.o:wcfxs.c zaptel.h
 	$(HOSTCC) $(KFLAGS) -c wcfxs.c
 
+pciradio.o:pciradio.c zaptel.h
+	$(HOSTCC) $(KFLAGS) -c pciradio.c
+
 wcs3200p.o:wcs3200p.c zaptel.h
 	$(HOSTCC) $(KFLAGS) -c wcs3200p.c
 

Index: zaptel.c
===================================================================
RCS file: /usr/cvsroot/zaptel/zaptel.c,v
retrieving revision 1.97
retrieving revision 1.98
diff -u -d -r1.97 -r1.98
--- zaptel.c	25 Oct 2004 22:46:19 -0000	1.97
+++ zaptel.c	4 Nov 2004 20:04:53 -0000	1.98
@@ -274,6 +274,8 @@
 
 #include "digits.h"
 
+static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit);
+
 #if defined(CONFIG_ZAPTEL_MMX) || defined(ECHO_CAN_FP)
 /* XXX kernel_fpu_begin() is NOT exported properly (in 2.4), so we have to make
        a local version.  Somebody fix this! XXX */
@@ -2687,6 +2689,7 @@
 	}
 	return 0;
 }
+
 static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int cmd, unsigned long data, int unit)
 {
 	union {
@@ -2989,9 +2992,15 @@
 	struct zt_chan *newmaster;
 	struct zt_dialparams tdp;
 	struct zt_maintinfo maint;
+	struct zt_indirect_data ind;
 	unsigned long flags;
 	int rv;
 	switch(cmd) {
+	case ZT_INDIRECT:
+		if (copy_from_user(&ind, (struct zt_indirect_data *)data, sizeof(ind)))
+			return -EFAULT;
+		VALID_CHANNEL(ind.chan);
+		return zt_chan_ioctl(inode, file, ind.op, (unsigned long) ind.data, ind.chan);
 	case ZT_SPANCONFIG:
 		if (copy_from_user(&lc, (struct zt_lineconfig *)data, sizeof(lc)))
 			return -EFAULT;

Index: zaptel.conf.sample
===================================================================
RCS file: /usr/cvsroot/zaptel/zaptel.conf.sample,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- zaptel.conf.sample	28 Oct 2004 13:24:41 -0000	1.14
+++ zaptel.conf.sample	4 Nov 2004 20:04:53 -0000	1.15
@@ -140,3 +140,64 @@
 #loadzone=sp
 #loadzone=no
 defaultzone=us
+#
+# Section for PCI Radio Interface 
+# (see http://www.zapatatelephony.org/app_rpt.html)
+#
+# The PCI Radio Interface card interfaces up to 4 two-way radios (either
+# a base/mobile radio or repeater system) to Zaptel channels. The driver
+# may work either independent of an application, or with it, through
+# the driver;s ioctl() interface. This file gives you access to specify
+# load-time parameters for Radio channels, so that the driver may run
+# by itself, and just act like a generic Zaptel radio interface.
+#
+# Unlike the rest of this file, you specify a block of parameters, and
+# then the channel(s) to which they apply. CTCSS is specified as a frequency
+# in tenths of hertz, for example 131.8 HZ is specified as 1318. DCS
+# for receive is specified as the code directly, for example 223. DCS for
+# transmit is specified as D and then the code, for example D223.
+#
+# The hardware supports a "community" CTCSS decoder system that has
+# arbitrary transmit CTCSS or DCS codes associated with them, unlike
+# traditional "community" systems that encode the same tone they decode.
+# 
+# this example is a single tone DCS transmit and receive
+#
+# # specify the transmit tone (in DCS mode this stays constant)
+# tx=D371
+# # specify the receive DCS code
+# dcsrx=223
+#
+# this example is a "community" CTCSS (if you only want a single tone, then
+# only specify 1 in the ctcss list)
+#
+# # specify the default transmit tone (when not receiving)
+# tx=1000
+# # Specify the receive freq, the tag (use 0 if none), and the transmit code.
+# # The tag may be used by applications to determine classification of tones.
+# # The tones are to be specified in order of presedence, most important first.
+# # Currently, 15 tones may be specified..
+# ctcss=1318,1,1318
+# ctcss=1862,1,1862
+#
+# The following parameters may be omitted if their default value is acceptible
+#
+# # set the receive debounce time in milliseconds
+# debouncetime=123
+# # set the transmit quiet dropoff burst time in milliseconds
+# bursttime=234
+# # set the COR level threshold (specified in tenths of millivolts)
+# # valid values are {3125,6250,9375,12500,15625,18750,21875,25000}
+# corthresh=12500
+# # Invert COR signal {y,n}
+# invertcor=y
+# # set the external tone mode; yes, no, internal {y,n,i}
+# exttone=y
+#
+# Now apply the configuration to the specified channels:
+#
+# # We are all done with our channel parameters, so now we specify what
+# # channels they apply to
+# channels=1-4
+
+

Index: zaptel.h
===================================================================
RCS file: /usr/cvsroot/zaptel/zaptel.h,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -d -r1.38 -r1.39
--- zaptel.h	27 Sep 2004 19:50:03 -0000	1.38
+++ zaptel.h	4 Nov 2004 20:04:53 -0000	1.39
@@ -304,6 +304,14 @@
 } ZT_DIAL_OPERATION;
 
 
+typedef struct zt_indirect_data
+{
+int	chan;
+int	op;
+void	*data;
+} ZT_INDIRECT_DATA;	
+
+
 /* ioctl definitions */
 #define ZT_CODE	'J'
 
@@ -590,6 +598,12 @@
 #define ZT_GETSIGFREEZE _IOR (ZT_CODE, 55, int)
 
 /*
+ * Do a channel IOCTL from the /dev/zap/ctl interface
+ */
+#define ZT_INDIRECT _IOWR (ZT_CODE, 56, struct zt_indirect_data)
+
+
+/*
  *  60-80 are reserved for private drivers
  *  80-85 are reserved for dynamic span stuff
  */
@@ -1441,4 +1455,92 @@
 
 #endif /* __KERNEL__ */
 
+/* The following is for the PCI RADIO interface only. This is specified in
+this file because external processes need to interact with the device.
+Some devices have private functions used for test/diagnostic only, but
+this is not the case here. */
+
+struct zt_radio_stat {
+	unsigned short ctcode_rx;	/* code of currently received CTCSS 
+					   or DCS, 0 for none */
+	unsigned short ctclass;		/* class of currently received CTCSS or
+					    DCS code */
+	unsigned short ctcode_tx;	/* code of currently encoded CTCSS or
+					   DCS, 0 for none */
+	unsigned char radstat;		/* status bits of radio */
+};
+
+struct zt_radio_param {
+	unsigned short radpar;	/* param identifier */
+	unsigned short index;	/* tone number */
+	int data;		/* pointer to param */
+};
+
+
+/* Get current status IOCTL */
+#define	ZT_RADIO_GETSTAT	_IOR (ZT_CODE, 57, struct zt_radio_stat)
+/* Set a channel parameter IOCTL */
+#define	ZT_RADIO_SETPARAM	_IOW (ZT_CODE, 58, struct zt_radio_param)
+/* Get a channel parameter IOCTL */
+#define	ZT_RADIO_GETPARAM	_IOR (ZT_CODE, 59, struct zt_radio_param)
+
+
+/* Defines for Radio Status (zt_radio_stat.radstat) bits */
+
+#define	ZT_RADSTAT_RX	1	/* currently "receiving " */
+#define	ZT_RADSTAT_TX	2	/* currently "transmitting" */
+#define	ZT_RADSTAT_RXCT	4	/* currently receiving continuous tone with 
+				   current settings */
+#define	ZT_RADSTAT_RXCOR	8	/* currently receiving COR (irrelevant of COR
+				   ignore) */
+#define	ZT_RADSTAT_IGNCOR	16	/* currently ignoring COR */
+#define	ZT_RADSTAT_IGNCT	32	/* currently ignoring CTCSS/DCS decode */
+#define	ZT_RADSTAT_NOENCODE 64	/* currently blocking CTCSS/DCS encode */
+
+/* Defines for Radio Parameters (zt_radio_param.radpar) */
+
+#define	ZT_RADPAR_INVERTCOR 1	/* invert the COR signal (0/1) */
+#define	ZT_RADPAR_IGNORECOR 2	/* ignore the COR signal (0/1) */
+#define	ZT_RADPAR_IGNORECT 3	/* ignore the CTCSS/DCS decode (0/1) */
+#define	ZT_RADPAR_NOENCODE 4	/* block the CTCSS/DCS encode (0/1) */
+#define	ZT_RADPAR_CORTHRESH 5	/* COR trigger threshold (0-7) */
+
+#define	ZT_RADPAR_EXTRXTONE 6	/* 0 means use internal decoder, 1 means UIOA
+				   logic true is CT decode, 2 means UIOA logic
+				   false is CT decode */
+#define	ZT_RADPAR_NUMTONES	7	/* returns maximum tone index (curently 15) */
+#define	ZT_RADPAR_INITTONE	8	/* init all tone indexes to 0 (no tones) */
+#define	ZT_RADPAR_RXTONE	9	/* CTCSS tone, (1-32) or DCS tone (1-777),
+				   or 0 meaning no tone, set index also (1-15) */
+#define	ZT_RADPAR_RXTONECLASS 10	/* Tone class (0-65535), set index also (1-15) */
+#define	ZT_RADPAR_TXTONE 11	/* CTCSS tone (1-32) or DCS tone (1-777) or 0
+				   to indicate no tone, to transmit 
+				   for this tone index (0-32, 0 disables
+				   transmit CTCSS), set index also (0-15) */
+#define	ZT_RADPAR_DEBOUNCETIME 12	/* receive indication debounce time, 
+				   milliseconds (1-999) */
+#define	ZT_RADPAR_BURSTTIME 13	/* end of transmit with no CT tone in
+				   milliseconds (0-999) */
+
+#if	0
+The following are not implemented in the prototype version of the card:
+(UIO will always be an input for external CTCSS decode input)
+
+#define	ZT_RADPAR_UIODATA 14	/* read/write UIOA and UIOB data. Bit 0 is
+				   UIOA, bit 1 is UIOB */
+#define	ZT_RADPAR_UIOMODE 15	/* 0 means UIOA and UIOB are both outputs, 1
+				   means UIOA is input, UIOB is output, 2 
+				   means UIOB is input and UIOA is output,
+				   3 means both UIOA and UIOB are inputs. Note
+				   mode for UIOA is overridden when in
+				   EXTRXTONE mode. */
+
+#define	ZT_RADPAR_EXTDATA 16	/* read/write external byte, set index also
+				   (0-2) */
+#define	ZT_RADPAR_EXTMODE 17	/* set mode for external byte, bitwise a 1
+				    means write, and 0 means read, set index
+				    also (0-2) */
+
+#endif
+
 #endif /* _LINUX_ZAPTEL_H */

Index: ztcfg.c
===================================================================
RCS file: /usr/cvsroot/zaptel/ztcfg.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- ztcfg.c	10 Sep 2004 13:43:51 -0000	1.16
+++ ztcfg.c	4 Nov 2004 20:04:53 -0000	1.17
@@ -25,7 +25,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * Primary Author: Mark Spencer <markster at linux-support.net>
- *
+ * Radio Support by Jim Dixon <jim at 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 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 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 @@
 	"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 @@
 }
 #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 @@
 	{ "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 @@
 	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 @@
 			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 @@
 				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 @@
 						}
 					}
 				}
-				close(fd);
 			}
 		}
 	} else {




More information about the svn-commits mailing list