summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormattf <mattf@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2005-01-08 00:05:24 +0000
committermattf <mattf@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2005-01-08 00:05:24 +0000
commitf59bc698cc7f139b93a9c51eb65f342a789e725f (patch)
tree24921b81b0417c112be5db999a4fd2de0c0041cd
parent3ac20515e24dba5119fa2d5b06157d81d84e9cc3 (diff)
More TDM card echo API modifications. Making the fxotune program automatically
find the correct coefficients for the module. Lots of neat stuff. git-svn-id: http://svn.digium.com/svn/zaptel/trunk@531 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rwxr-xr-xfxotune.c262
-rwxr-xr-xwctdm.c204
-rwxr-xr-xwctdm.h17
3 files changed, 344 insertions, 139 deletions
diff --git a/fxotune.c b/fxotune.c
index 6bdaeba..a11ba90 100755
--- a/fxotune.c
+++ b/fxotune.c
@@ -1,3 +1,16 @@
+/*
+ * This file and contents thereof are licensed under the terms and
+ * conditions of the Gnu Public License version 2. For more information
+ * (including terms and conditions) see http://www.gnu.org/
+ *
+ * fxotune.c -- A utility for tuning the various settings on the fxo
+ * modules for the TDM400 cards.
+ *
+ * by Matthew Fredrickson
+ *
+ * (C) 2004 Digium, Inc.
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
@@ -5,42 +18,251 @@
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <unistd.h>
#include <fcntl.h>
#include <linux/zaptel.h>
#include "wctdm.h"
+#include "fxotune.h"
+#include "zaptel.h"
+
+
+static int testduration = 100; /* Test the line for x milliseconds */
+static int readduration = 100 * 2;
+
+static char *zappath = "/dev/zap";
+static char *configfile = "/etc/fxotune.conf";
+
+static char *usage =
+"Usage: fxotest\n"
+" -i : Tests for FXO modules and sets echo coefficients\n"
+" -s : Sets the FXO modules echo coefficients on your system to the best settings\n";
+
+#define OUT_OF_BOUNDS(x) ((x) < 0 || (x) > 255)
+
+int process_readbuf(short *ibuf, int isize, short *obuf, int osize)
+{
+ int i = 0;
+ short *samples = ibuf;
+ short minsample = samples[0];
+
+ for (i = 0; i < isize/2; i++) {
+ if (samples[i] < minsample)
+ minsample = samples[i];
+ }
+ return minsample;
+}
+
+/* Returns index in echocan table with the lowest power pulse readback
+ * -1 means the device is not an FXO module or fails */
+int echo_tune(int whichzap)
+{
+ short bestval = 32355;
+ int bestindex = -1;
+ int i = 0;
+ int res = 0;
+ int total = sizeof(echo_trys) / sizeof(struct wctdm_echo_coefs);
+ int randdev;
+ short *outbuf = NULL, *inbuf = NULL;
+ int obufsize = testduration * 8 * 2; /* In one milisecond there are 8 samples of 2 byte length */
+ int ibufsize = readduration * 8 * 2;
+
+
+ randdev = open("/dev/random", O_RDONLY);
+ if (randdev < 0) {
+ fprintf(stdout, "Unable to open /dev/random: %s\n", strerror(errno));
+ return -1;
+ }
+ outbuf = malloc(obufsize);
+ if (!outbuf) {
+ fprintf(stdout, "Malloc failed on outbuf. Bad, bad, bad...\n");
+ exit(-1);
+ }
+
+ res = read(randdev, outbuf, obufsize);
+ if (res <= 0) {
+ fprintf(stdout, "WARNING: could not read from /dev/random: %s\n", strerror(errno));
+ return -1;
+ }
+
+ if (res != obufsize) {
+ fprintf(stdout, "Could not read request %d bytes from /dev/random. Using only %d\n", obufsize, res);
+ ibufsize = res;
+ }
+
+ close(randdev);
+
+ outbuf = malloc(readduration);
+ if (!outbuf) {
+ fprintf(stdout, "Malloc failed on readbuf. Bad, bad, bad....\n");
+ exit(-1);
+ }
+
+ for (i = 0; i < total; i++) {
+ int x;
+
+ /* Set echo settings */
+ if (ioctl(whichzap, WCTDM_SET_ECHOTUNE, &echo_trys[i])) {
+ fprintf(stdout, "Unable to set echo params: %s\n", strerror(errno));
+ return -1;
+ }
+
+ x = 1;
+ if (ioctl(whichzap, ZT_SETLINEAR, &x)) {
+ fprintf(stdout, "Unable to set channel to signed linear mode.\n");
+ return -1;
+ }
+
+ /* Take off hook */
+ x = ZT_OFFHOOK;
+ if(ioctl(whichzap, ZT_HOOK, &x)) {
+ fprintf(stdout, "Unable to set hook state.\n");
+ return -1;
+ }
+
+ /* write samples */
+ res = write(whichzap, outbuf, obufsize);
+ if (res < 0) {
+ fprintf(stdout, "Unable to write: %s\n", strerror(errno));
+ return -1;
+ }
+
+ if (res != obufsize) {
+ fprintf(stdout, "Only could write %d of %d bytes.\n", res, obufsize);
+ return -1;
+ }
+
+ res = read(whichzap, inbuf, ibufsize);
+ if (res < 0) {
+ fprintf(stdout, "Error in read: %s\n", strerror(errno));
+ return -1;
+ }
+ if (res != ibufsize) {
+ fprintf(stdout, "Only could read %d of %d bytes.\n", res, ibufsize);
+ if (res > 0)
+ ibufsize = res;
+ else {
+ fprintf(stdout, "Cannot read from device\n");
+ return -1;
+ }
+ }
+
+ res = process_readbuf(outbuf, obufsize, inbuf, ibufsize);
+ /* Check to see if the echo values */
+ if (res < bestval) {
+ bestval = res;
+ bestindex = i;
+ }
+ }
+
+ return 0;
+
+}
+
int main (int argc , char **argv)
{
char zapdev[80] = "";
+ int i = 0;
int fd;
-
- if (argc < 4) {
- fprintf(stdout, "Usage:\n");
- fprintf(stdout, "%s [zap device] echocan [0-7]\n", argv[0]);
- exit(1);
+ int res = 0;
+ int configfd;
+
+ if (argc != 2) {
+ /* Show usage */
+ fputs(usage, stdout);
+ return -1;
}
- strncpy(zapdev, argv[1], sizeof(zapdev));
+ if (!strcasecmp(argv[1], "-s")) {
+ for (i = 0;res != EOF; i++) {
+ struct wctdm_echo_coefs mycoefs;
+ char completezappath[56] = "";
+ int myzap,myacim,mycoef1,mycoef2,mycoef3,mycoef4,mycoef5,mycoef6,mycoef7,mycoef8;
+ FILE *fp = NULL;
+
+ fp = fopen(configfile, "r");
+
+ res = fscanf(fp, "%d=%d,%d,%d,%d,%d,%d,%d,%d,%d",&myzap,&myacim,&mycoef1,
+ &mycoef2,&mycoef3,&mycoef4,&mycoef5,&mycoef6,&mycoef7,
+ &mycoef8);
+
+ if (res == EOF) {
+ break;
+ }
+
+ /* Check to be sure conversion is done correctly */
+ if (OUT_OF_BOUNDS(myacim) || OUT_OF_BOUNDS(mycoef1)||
+ OUT_OF_BOUNDS(mycoef2)|| OUT_OF_BOUNDS(mycoef3)||
+ OUT_OF_BOUNDS(mycoef4)|| OUT_OF_BOUNDS(mycoef5)||
+ OUT_OF_BOUNDS(mycoef6)|| OUT_OF_BOUNDS(mycoef7)|| OUT_OF_BOUNDS(mycoef8)) {
+
+ fprintf(stdout, "Bounds check error on inputs from %s:%d\n", configfile, i+1);
+ return -1;
+ }
+
+ mycoefs.acim = myacim;
+ mycoefs.coef1 = mycoef1;
+ mycoefs.coef2 = mycoef2;
+ mycoefs.coef3 = mycoef3;
+ mycoefs.coef4 = mycoef4;
+ mycoefs.coef5 = mycoef5;
+ mycoefs.coef6 = mycoef6;
+ mycoefs.coef7 = mycoef7;
+ mycoefs.coef8 = mycoef8;
+
+ snprintf(completezappath, sizeof(completezappath), "%s/%d", zappath, myzap);
+ fd = open(completezappath, O_RDWR);
+
+ if (fd < 0) {
+ fprintf(stdout, "open error on %s: %s\n", completezappath, strerror(errno));
+ return -1;
+ }
- fd = open(zapdev, O_RDWR);
- if (fd < 0) {
- fprintf(stderr, "open: %s\n", strerror(errno));
- exit(1);
+ if (ioctl(fd, WCTDM_SET_ECHOTUNE, &mycoefs)) {
+ fprintf(stdout, "echotune: %s\n", strerror(errno));
+ return -1;
+ }
+ }
+
+ return 0;
}
- if (!strcasecmp(argv[2], "echocan")) {
- int modeno = atoi(argv[3]);
+ if (!strcasecmp(argv[1], "-i")) {
+ configfd = open(configfile, O_CREAT|O_TRUNC|O_WRONLY);
- if (modeno < 0 || modeno > 7) {
- fprintf(stdout, "Echo canceller coefficient settings must be between 0 and 7.\n");
- exit(1);
+ if (configfd < 0) {
+ fprintf(stdout, "open: %s\n", strerror(errno));
+ return -1;
}
- if (ioctl(fd, WCTDM_SET_ECHOTUNE, &modeno)) {
- fprintf(stdout, "echotune: %s\n", strerror(errno));
- exit(1);
+ for (i = 0; i < 255; i++) {
+ snprintf(zapdev, sizeof(zapdev), "%s/%d", zappath, i);
+
+ fd = open(zapdev, O_RDWR);
+ if (fd < 0) {
+ fprintf(stdout, "open(%s): %s\n", zapdev, strerror(errno));
+ return -1;
+ }
+
+ res = echo_tune(fd);
+ if (res > -1) {
+ /* Do output to file */
+ int len = 0;
+ static char output[255] = "";
+ snprintf(output, sizeof(output), "%d=%d,%d,%d,%d,%d,%d,%d,%d,%d", i,
+ echo_trys[i].acim, echo_trys[i].coef1, echo_trys[i].coef2,
+ echo_trys[i].coef3, echo_trys[i].coef4, echo_trys[i].coef5,
+ echo_trys[i].coef6, echo_trys[i].coef7, echo_trys[i].coef8 );
+
+ len = strlen(output);
+ res = write(configfd, output, strlen(output));
+ if (res != len) {
+ fprintf(stdout, "Unable to write line \"%s\" to file.\n", output);
+ return -1;
+ }
+ }
}
- exit(0);
}
- exit(0);
+
+ return 0;
}
diff --git a/wctdm.c b/wctdm.c
index 03f3105..136c97d 100755
--- a/wctdm.c
+++ b/wctdm.c
@@ -119,115 +119,86 @@ static struct fxo_mode {
int acim;
int ring_osc;
int ring_x;
- int echoentry;
} fxo_modes[] =
{
- { "FCC", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 }, /* US, Canada */
- { "TBR21", 0, 0, 0, 0, 1, 0x3, 0, 0x2, 0x7e6c, 0x023a, 0 },
+ { "FCC", 0, 0, 0, 0, 0, 0x3, 0, 0, }, /* US, Canada */
+ { "TBR21", 0, 0, 0, 0, 1, 0x3, 0, 0x2, 0x7e6c, 0x023a, },
/* Austria, Belgium, Denmark, Finland, France, Germany,
Greece, Iceland, Ireland, Italy, Luxembourg, Netherlands,
Norway, Portugal, Spain, Sweden, Switzerland, and UK */
- { "ARGENTINA", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
- { "AUSTRALIA", 1, 0, 0, 0, 0, 0, 0x3, 0x3, 0 },
- { "AUSTRIA", 0, 1, 0, 0, 1, 0x3, 0, 0x3, 0 },
- { "BAHRAIN", 0, 0, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "BELGIUM", 0, 1, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "BRAZIL", 0, 0, 0, 0, 0, 0, 0x3, 0, 0 },
- { "BULGARIA", 0, 0, 0, 0, 1, 0x3, 0x0, 0x3, 0 },
- { "CANADA", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
- { "CHILE", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
- { "CHINA", 0, 0, 0, 0, 0, 0, 0x3, 0xf, 0 },
- { "COLUMBIA", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
- { "CROATIA", 0, 0, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "CYRPUS", 0, 0, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "CZECH", 0, 0, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "DENMARK", 0, 1, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "ECUADOR", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
- { "EGYPT", 0, 0, 0, 0, 0, 0, 0x3, 0, 0 },
- { "ELSALVADOR", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
- { "FINLAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "FRANCE", 0, 1, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "GERMANY", 0, 1, 0, 0, 1, 0x3, 0, 0x3, 0 },
- { "GREECE", 0, 1, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "GUAM", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
- { "HONGKONG", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
- { "HUNGARY", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
- { "ICELAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "INDIA", 0, 0, 0, 0, 0, 0x3, 0, 0x4, 0 },
- { "INDONESIA", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
- { "IRELAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "ISRAEL", 0, 0, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "ITALY", 0, 1, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "JAPAN", 0, 0, 0, 0, 0, 0, 0x3, 0, 0 },
- { "JORDAN", 0, 0, 0, 0, 0, 0, 0x3, 0, 0 },
- { "KAZAKHSTAN", 0, 0, 0, 0, 0, 0x3, 0, 0 },
- { "KUWAIT", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
- { "LATVIA", 0, 0, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "LEBANON", 0, 0, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "LUXEMBOURG", 0, 1, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "MACAO", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
- { "MALAYSIA", 0, 0, 0, 0, 0, 0, 0x3, 0, 0 }, /* Current loop >= 20ma */
- { "MALTA", 0, 0, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "MEXICO", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
- { "MOROCCO", 0, 0, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "NETHERLANDS", 0, 1, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "NEWZEALAND", 0, 0, 0, 0, 0, 0x3, 0, 0x4, 0 },
- { "NIGERIA", 0, 0, 0, 0, 0x1, 0x3, 0, 0x2, 0 },
- { "NORWAY", 0, 1, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "OMAN", 0, 0, 0, 0, 0, 0, 0x3, 0, 0 },
- { "PAKISTAN", 0, 0, 0, 0, 0, 0, 0x3, 0, 0 },
- { "PERU", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
- { "PHILIPPINES", 0, 0, 0, 0, 0, 0, 0x3, 0, 0 },
- { "POLAND", 0, 0, 1, 1, 0, 0x3, 0, 0, 0 },
- { "PORTUGAL", 0, 1, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "ROMANIA", 0, 0, 0, 0, 0, 3, 0, 0, 0 },
- { "RUSSIA", 0, 0, 0, 0, 0, 0, 0x3, 0, 0 },
- { "SAUDIARABIA", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
- { "SINGAPORE", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
- { "SLOVAKIA", 0, 0, 0, 0, 0, 0x3, 0, 0x3, 0 },
- { "SLOVENIA", 0, 0, 0, 0, 0, 0x3, 0, 0x2, 0 },
- { "SOUTHAFRICA", 1, 0, 1, 0, 0, 0x3, 0, 0x3, 0 },
- { "SOUTHKOREA", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
- { "SPAIN", 0, 1, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "SWEDEN", 0, 1, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "SWITZERLAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, 0 },
- { "SYRIA", 0, 0, 0, 0, 0, 0, 0x3, 0, 0 },
- { "TAIWAN", 0, 0, 0, 0, 0, 0, 0x3, 0, 0 },
- { "THAILAND", 0, 0, 0, 0, 0, 0, 0x3, 0, 0 },
- { "UAE", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
- { "UK", 0, 1, 0, 0, 1, 0x3, 0, 0x5, 0 },
- { "USA", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
- { "YEMEN", 0, 0, 0, 0, 0, 0x3, 0, 0, 0 },
+ { "ARGENTINA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
+ { "AUSTRALIA", 1, 0, 0, 0, 0, 0, 0x3, 0x3, },
+ { "AUSTRIA", 0, 1, 0, 0, 1, 0x3, 0, 0x3, },
+ { "BAHRAIN", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
+ { "BELGIUM", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
+ { "BRAZIL", 0, 0, 0, 0, 0, 0, 0x3, 0, },
+ { "BULGARIA", 0, 0, 0, 0, 1, 0x3, 0x0, 0x3, },
+ { "CANADA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
+ { "CHILE", 0, 0, 0, 0, 0, 0x3, 0, 0, },
+ { "CHINA", 0, 0, 0, 0, 0, 0, 0x3, 0xf, },
+ { "COLUMBIA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
+ { "CROATIA", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
+ { "CYRPUS", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
+ { "CZECH", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
+ { "DENMARK", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
+ { "ECUADOR", 0, 0, 0, 0, 0, 0x3, 0, 0, },
+ { "EGYPT", 0, 0, 0, 0, 0, 0, 0x3, 0, },
+ { "ELSALVADOR", 0, 0, 0, 0, 0, 0x3, 0, 0, },
+ { "FINLAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
+ { "FRANCE", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
+ { "GERMANY", 0, 1, 0, 0, 1, 0x3, 0, 0x3, },
+ { "GREECE", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
+ { "GUAM", 0, 0, 0, 0, 0, 0x3, 0, 0, },
+ { "HONGKONG", 0, 0, 0, 0, 0, 0x3, 0, 0, },
+ { "HUNGARY", 0, 0, 0, 0, 0, 0x3, 0, 0, },
+ { "ICELAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
+ { "INDIA", 0, 0, 0, 0, 0, 0x3, 0, 0x4, },
+ { "INDONESIA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
+ { "IRELAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
+ { "ISRAEL", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
+ { "ITALY", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
+ { "JAPAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
+ { "JORDAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
+ { "KAZAKHSTAN", 0, 0, 0, 0, 0, 0x3, 0, },
+ { "KUWAIT", 0, 0, 0, 0, 0, 0x3, 0, 0, },
+ { "LATVIA", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
+ { "LEBANON", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
+ { "LUXEMBOURG", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
+ { "MACAO", 0, 0, 0, 0, 0, 0x3, 0, 0, },
+ { "MALAYSIA", 0, 0, 0, 0, 0, 0, 0x3, 0, }, /* Current loop >= 20ma */
+ { "MALTA", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
+ { "MEXICO", 0, 0, 0, 0, 0, 0x3, 0, 0, },
+ { "MOROCCO", 0, 0, 0, 0, 1, 0x3, 0, 0x2, },
+ { "NETHERLANDS", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
+ { "NEWZEALAND", 0, 0, 0, 0, 0, 0x3, 0, 0x4, },
+ { "NIGERIA", 0, 0, 0, 0, 0x1, 0x3, 0, 0x2, },
+ { "NORWAY", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
+ { "OMAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
+ { "PAKISTAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
+ { "PERU", 0, 0, 0, 0, 0, 0x3, 0, 0, },
+ { "PHILIPPINES", 0, 0, 0, 0, 0, 0, 0x3, 0, },
+ { "POLAND", 0, 0, 1, 1, 0, 0x3, 0, 0, },
+ { "PORTUGAL", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
+ { "ROMANIA", 0, 0, 0, 0, 0, 3, 0, 0, },
+ { "RUSSIA", 0, 0, 0, 0, 0, 0, 0x3, 0, },
+ { "SAUDIARABIA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
+ { "SINGAPORE", 0, 0, 0, 0, 0, 0x3, 0, 0, },
+ { "SLOVAKIA", 0, 0, 0, 0, 0, 0x3, 0, 0x3, },
+ { "SLOVENIA", 0, 0, 0, 0, 0, 0x3, 0, 0x2, },
+ { "SOUTHAFRICA", 1, 0, 1, 0, 0, 0x3, 0, 0x3, },
+ { "SOUTHKOREA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
+ { "SPAIN", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
+ { "SWEDEN", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
+ { "SWITZERLAND", 0, 1, 0, 0, 1, 0x3, 0, 0x2, },
+ { "SYRIA", 0, 0, 0, 0, 0, 0, 0x3, 0, },
+ { "TAIWAN", 0, 0, 0, 0, 0, 0, 0x3, 0, },
+ { "THAILAND", 0, 0, 0, 0, 0, 0, 0x3, 0, },
+ { "UAE", 0, 0, 0, 0, 0, 0x3, 0, 0, },
+ { "UK", 0, 1, 0, 0, 1, 0x3, 0, 0x5, },
+ { "USA", 0, 0, 0, 0, 0, 0x3, 0, 0, },
+ { "YEMEN", 0, 0, 0, 0, 0, 0x3, 0, 0, },
};
-struct echo_zone {
- struct regs {
- int acim;
- int coef1;
- int coef2;
- int coef3;
- int coef4;
- int coef5;
- int coef6;
- int coef7;
- int coef8;
- } vals[8];
-} echo_zones[] =
-{
- {{
- { 0, 0, 0, 0, 0, 0, 0, 0, 0},
- { 10, 0, 6, 1, 254, 2, 255, 0, 0},
- { 3, 255, 255, 0, 1, 0, 0, 0, 0},
- { 3, 1, 253, 253, 2, 255, 0, 0, 0},
- { 9, 254, 251, 255, 2, 0, 1, 0, 0},
- { 5, 3, 251, 250, 2, 254, 0, 0, 255},
- { 8, 253, 2, 244, 255, 10, 244, 3, 253},
- { 10, 249, 244, 8, 12, 245, 252, 0, 1},
- }}
-};
-
-
-
#ifdef STANDALONE_ZAPATA
#include "zaptel.h"
#else
@@ -1617,9 +1588,9 @@ static int wctdm_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long dat
struct wctdm_stats stats;
struct wctdm_regs regs;
struct wctdm_regop regop;
+ struct wctdm_echo_coefs echoregs;
struct wctdm *wc = chan->pvt;
int x;
- int whichecho = -1;
switch (cmd) {
case ZT_ONHOOKTRANSFER:
if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
@@ -1677,27 +1648,22 @@ static int wctdm_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long dat
}
break;
case WCTDM_SET_ECHOTUNE:
- whichecho = fxo_modes[_opermode].echoentry;
-
- if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXO)
- return -EINVAL;
-
- if (get_user(x, (int *)data))
+ if (copy_from_user(&echoregs, (struct wctdm_echo_coefs*)data, sizeof(echoregs)))
return -EFAULT;
- if (x > -1 && x < 8) {
+ if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXO) {
/* Set the ACIM register */
- wctdm_setreg(wc, chan->chanpos - 1, 30, echo_zones[whichecho].vals[x].acim);
+ wctdm_setreg(wc, chan->chanpos - 1, 30, echoregs.acim);
/* Set the digital echo canceller registers */
- wctdm_setreg(wc, chan->chanpos - 1, 45, echo_zones[whichecho].vals[x].coef1);
- wctdm_setreg(wc, chan->chanpos - 1, 46, echo_zones[whichecho].vals[x].coef2);
- wctdm_setreg(wc, chan->chanpos - 1, 47, echo_zones[whichecho].vals[x].coef3);
- wctdm_setreg(wc, chan->chanpos - 1, 48, echo_zones[whichecho].vals[x].coef4);
- wctdm_setreg(wc, chan->chanpos - 1, 49, echo_zones[whichecho].vals[x].coef5);
- wctdm_setreg(wc, chan->chanpos - 1, 50, echo_zones[whichecho].vals[x].coef6);
- wctdm_setreg(wc, chan->chanpos - 1, 51, echo_zones[whichecho].vals[x].coef7);
- wctdm_setreg(wc, chan->chanpos - 1, 52, echo_zones[whichecho].vals[x].coef8);
+ wctdm_setreg(wc, chan->chanpos - 1, 45, echoregs.coef1);
+ wctdm_setreg(wc, chan->chanpos - 1, 46, echoregs.coef2);
+ wctdm_setreg(wc, chan->chanpos - 1, 47, echoregs.coef3);
+ wctdm_setreg(wc, chan->chanpos - 1, 48, echoregs.coef4);
+ wctdm_setreg(wc, chan->chanpos - 1, 49, echoregs.coef5);
+ wctdm_setreg(wc, chan->chanpos - 1, 50, echoregs.coef6);
+ wctdm_setreg(wc, chan->chanpos - 1, 51, echoregs.coef7);
+ wctdm_setreg(wc, chan->chanpos - 1, 52, echoregs.coef8);
break;
} else {
diff --git a/wctdm.h b/wctdm.h
index 6501b79..93540d5 100755
--- a/wctdm.h
+++ b/wctdm.h
@@ -23,6 +23,9 @@
*
*/
+#ifndef _WCTDM_H
+#define _WCTDM_H
+
#include <linux/ioctl.h>
#define NUM_REGS 109
@@ -45,8 +48,22 @@ struct wctdm_regop {
unsigned short val;
};
+struct wctdm_echo_coefs {
+ unsigned char acim;
+ unsigned char coef1;
+ unsigned char coef2;
+ unsigned char coef3;
+ unsigned char coef4;
+ unsigned char coef5;
+ unsigned char coef6;
+ unsigned char coef7;
+ unsigned char coef8;
+};
+
#define WCTDM_GET_STATS _IOR (ZT_CODE, 60, struct wctdm_stats)
#define WCTDM_GET_REGS _IOR (ZT_CODE, 61, struct wctdm_regs)
#define WCTDM_SET_REG _IOW (ZT_CODE, 62, struct wctdm_regop)
#define WCTDM_SET_ECHOTUNE _IOW (ZT_CODE, 63, int)
+
+#endif /* _WCTDM_H */