diff options
author | mattf <mattf@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2005-01-08 00:05:24 +0000 |
---|---|---|
committer | mattf <mattf@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2005-01-08 00:05:24 +0000 |
commit | f59bc698cc7f139b93a9c51eb65f342a789e725f (patch) | |
tree | 24921b81b0417c112be5db999a4fd2de0c0041cd | |
parent | 3ac20515e24dba5119fa2d5b06157d81d84e9cc3 (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-x | fxotune.c | 262 | ||||
-rwxr-xr-x | wctdm.c | 204 | ||||
-rwxr-xr-x | wctdm.h | 17 |
3 files changed, 344 insertions, 139 deletions
@@ -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; } @@ -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 { @@ -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 */ |