diff options
author | markster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2002-12-02 03:02:14 +0000 |
---|---|---|
committer | markster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2002-12-02 03:02:14 +0000 |
commit | c15162e2ccf8747e2cb0af39a1ba04955701f15d (patch) | |
tree | a81e94dd59e92e6739540b7cbdea4bb23180e750 | |
parent | 70c27a0518c63a604b3e4ab78ebc717b009d1b52 (diff) |
Version 0.3.3 from FTP
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@133 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rwxr-xr-x | Makefile | 70 | ||||
-rwxr-xr-x | mec-2.h | 274 | ||||
-rwxr-xr-x | wcusb.c | 93 |
3 files changed, 103 insertions, 334 deletions
@@ -64,12 +64,15 @@ KFLAGS+=-DDEFAULT_TONE_ZONE=$(DEFAULTZONE) KFLAGS+=-DSTANDALONE_ZAPATA CFLAGS+=-DSTANDALONE_ZAPATA -MODCONF=$(shell if [ -d /etc/modutils ]; then echo "/etc/modutils/zaptel"; elif [ -f /etc/modules.conf ]; then echo /etc/modules.conf; else echo /etc/conf.modules ; fi) +INSTALL_PREFIX= + +MODCONF=$(shell if [ -d $(INSTALL_PREFIX)/etc/modutils ]; then echo "$(INSTALL_PREFIX)/etc/modutils/zaptel"; elif [ -f $(INSTALL_PREFIX)/etc/modules.conf ]; then echo $(INSTALL_PREFIX)/etc/modules.conf; else echo $(INSTALL_PREFIX)/etc/conf.modules ; fi) TZOBJS=zonedata.lo tonezone.lo LIBTONEZONE=libtonezone.so.1.0 -MODULES=zaptel.o tor2.o torisa.o wcusb.o wcfxsusb.o wcfxo.o wcfxs.o \ +MODULES=zaptel.o tor2.o torisa.o wcusb.o wcfxo.o wcfxs.o \ ztdynamic.o ztd-eth.o wct1xxp.o # ztdummy.o +#MODULES+=wcfxsusb.o ZTTOOL=$(shell if [ -f /usr/include/newt.h ]; then echo zttool; fi) #PRIMARY=wcfxsusb PRIMARY=torisa @@ -141,6 +144,8 @@ zaptel.c: tones.h zttool.o: zttool.c zaptel.h +ztprovision.o: ztprovision.c zaptel.h + ztmonitor.o: ztmonitor.c zaptel.h ztspeed.o: ztspeed.c @@ -149,6 +154,9 @@ ztspeed.o: ztspeed.c zttool: zttool.o $(CC) -o zttool zttool.o -lnewt +ztprovision: ztprovision.o + $(CC) -o ztprovision ztprovision.o -lnewt + ztmonitor: ztmonitor.o $(CC) -o ztmonitor ztmonitor.o @@ -178,34 +186,38 @@ fxstest: fxstest.o $(CC) -o fxstest fxstest.o -ltonezone devices: - mkdir -p /dev/zap - rm -f /dev/zap/ctl - rm -f /dev/zap/channel - rm -f /dev/zap/pseudo - mknod /dev/zap/ctl c 196 0 - mknod /dev/zap/channel c 196 254 - mknod /dev/zap/pseudo c 196 255 + mkdir -p $(INSTALL_PREFIX)/dev/zap + rm -f $(INSTALL_PREFIX)/dev/zap/ctl + rm -f $(INSTALL_PREFIX)/dev/zap/channel + rm -f $(INSTALL_PREFIX)/dev/zap/pseudo + mknod $(INSTALL_PREFIX)/dev/zap/ctl c 196 0 + mknod $(INSTALL_PREFIX)/dev/zap/channel c 196 254 + mknod $(INSTALL_PREFIX)/dev/zap/pseudo c 196 255 N=1; \ while [ $$N -lt 253 ]; do \ - rm -f /dev/zap/$$N; \ - mknod /dev/zap/$$N c 196 $$N; \ + rm -f $(INSTALL_PREFIX)/dev/zap/$$N; \ + mknod $(INSTALL_PREFIX)/dev/zap/$$N c 196 $$N; \ N=$$[$$N+1]; \ done install: all devices - install -m 755 ztcfg /sbin - if [ -f sethdlc ]; then install -m 755 sethdlc /sbin ; fi - if [ -f zttool ]; then install -m 755 zttool /sbin; fi - mkdir -p /lib/modules/`uname -r`/misc + mkdir -p $(INSTALL_PREFIX)/sbin + install -m 755 ztcfg $(INSTALL_PREFIX)/sbin + if [ -f sethdlc ]; then install -m 755 sethdlc $(INSTALL_PREFIX)/sbin ; fi + if [ -f zttool ]; then install -m 755 zttool $(INSTALL_PREFIX)/sbin; fi + mkdir -p $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc for x in $(MODULES); do \ - install -m 644 $$x /lib/modules/`uname -r`/misc ; \ + install -m 644 $$x $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc ; \ done - mkdir -p /usr/lib - install -m 755 $(LIBTONEZONE) /usr/lib - install -m 644 zaptel.h /usr/include/linux - install -m 644 torisa.h /usr/include/linux - install -m 644 tonezone.h /usr/include - ( cd /usr/lib ; rm -f libtonezone.so ; ln -sf $(LIBTONEZONE) libtonezone.so ) + if ! [ -f wcfxsusb.o ]; then \ + rm -f $(INTALL_PREFIX)/lib/modules/`uname -r`/misc/wcfxsusb.o; \ + fi + mkdir -p $(INSTALL_PREFIX)/usr/lib + install -m 755 $(LIBTONEZONE) $(INSTALL_PREFIX)/usr/lib + install -m 644 zaptel.h $(INSTALL_PREFIX)/usr/include/linux + install -m 644 torisa.h $(INSTALL_PREFIX)/usr/include/linux + install -m 644 tonezone.h $(INSTALL_PREFIX)/usr/include + ( cd $(INSTALL_PREFIX)/usr/lib ; rm -f libtonezone.so ; ln -sf $(LIBTONEZONE) libtonezone.so ) /sbin/ldconfig if [ -f $(MODCONF) ]; then mv -f $(MODCONF) $(MODCONF).bak ; fi @@ -241,20 +253,20 @@ install: all devices /sbin/update-modules ; \ fi -/sbin/depmod -a - [ -f /etc/zaptel.conf ] || install -m 644 zaptel.conf.sample /etc/zaptel.conf + [ -f $(INSTALL_PREFIX)/etc/zaptel.conf ] || install -m 644 zaptel.conf.sample $(INSTALL_PREFIX)/etc/zaptel.conf config: - if [ -d /etc/rc.d/init.d ]; then \ - install -m 755 zaptel.init /etc/rc.d/init.d/zaptel; \ + if [ -d $(INSTALL_PREFIX)/etc/rc.d/init.d ]; then \ + install -m 755 zaptel.init $(INSTALL_PREFIX)/etc/rc.d/init.d/zaptel; \ chkconfig --add zaptel; \ - elif [ -d /etc/init.d ]; then \ - install -m 755 zaptel.init /etc/init.d/zaptel; \ + elif [ -d $(INSTALL_PREFIX)/etc/init.d ]; then \ + install -m 755 zaptel.init $(INSTALL_PREFIX)/etc/init.d/zaptel; \ fi if [ ! -f /etc/sysconfig/zaptel ]; then \ - install -m 644 zaptel.sysconfig /etc/sysconfig/zaptel; \ + install -m 644 zaptel.sysconfig $(INSTALL_PREFIX)/etc/sysconfig/zaptel; \ fi if [ -d /etc/sysconfig/network-scripts ]; then \ - install -m 755 ifup-hdlc /etc/sysconfig/network-scripts/ifup-hdlc; \ + install -m 755 ifup-hdlc $(INSTALL_PREFIX)/etc/sysconfig/network-scripts/ifup-hdlc; \ fi clean: diff --git a/mec-2.h b/mec-2.h deleted file mode 100755 index b6f1f80..0000000 --- a/mec-2.h +++ /dev/null @@ -1,274 +0,0 @@ -/* - * New pass at a good echo canceller - * - * Mark Spencer <markster@linux-support.net> - * - * This time, we'll try floating point first... - * - */ - -#ifndef _MECNEW_H -#define _MECNEW_H - -typedef float FLOAT; -/* typedef double FLOAT; */ - -#ifdef __KERNEL__ -#define MALLOC(a) kmalloc(a, GFP_KERNEL) -#defien FREE(a) kfree(a) -#else -#include <malloc.h> -#define MALLOC(a) malloc(a) -#define FREE(a) free(a) -#endif - -#define HANGT 600 - -#define DEFAULT_N 128 -#define DEFAULT_M 16 - -#define DEFAULT_T0 5 -#define SAMPLE_FREQ 8000 -#define DEFAULT_TAU 1 - -#define MAX_BETA 16 / DEFAULT_M - - -#define SUPPR -12.0 /* db */ -#define EC_MIN_DB_VALUE -70.0 /* db */ - - -#ifdef GEN_CONST -#define _CUTOFF pow(2.0, -15.0) -static FLOAT CUTOFF; - -#define _ALPHA_ST pow(2.0, -5.0) -static FLOAT ALPHA_ST; - -#define _ALPHA_YT pow(2.0, -5.0) -static FLOAT ALPHA_YT; - -#define _SIGMA_LU pow(2.0, -7.0) -static FLOAT SIGMA_LU; - -#define _SIGMA_LY pow(2.0, -7.0) -static FLOAT SIGMA_LY; - -#define _DEFAULT_BETA1 pow(2.0, -12.0) /* Choose -13.0 for 256 taps, they - recommend -11.0 for 128 taps */ -static FLOAT DEFAULT_BETA1; - -#define _MIN_BETA _DEFAULT_BETA1 * pow(2.0, -4.0) -static FLOAT MIN_BETA; - -#define _EC_MIN_VALUE pow(10, EC_MIN_DB_VALUE/10.0) -static FLOAT EC_MIN_VALUE; -#else -#include "mec-2-const.h" -#endif - -#define SUPPR_FLOOR -64.0 -#define SUPPR_CEIL -24.0 -#define RES_SUPR_FACTOR -20.0 - -typedef struct mecnew { - /* Big arrays first */ - - FLOAT a_d[DEFAULT_N]; /* Coefficients */ - - FLOAT y_d[2 * (DEFAULT_N + DEFAULT_M)]; /* Circular buf reference */ - FLOAT s_d[2 * (DEFAULT_N + DEFAULT_M)]; /* Circular buf signal */ - int yspos; /* Position in circular buf */ - - FLOAT e_d[2 * DEFAULT_M]; - int eupos; - - FLOAT y_tilde_d[2 * DEFAULT_N]; /* Reference signal */ - int ytpos; - - /* Now some things to keep track of */ - FLOAT s_tilde_d; /* Near-end speech detector */ - int HCNTR_d; - int start_speech_d; - - FLOAT Ly_d; /* Power computations */ - FLOAT Lu_d; - - int i_d; /* Absolute time */ - FLOAT beta1_d; - FLOAT beta2_d; - - int flag_d; - -} echo_can_state_t; - -static inline echo_can_state_t *echo_can_create(int taps, int adaption) -{ - echo_can_state_t *ec; -#ifdef GEN_CONST - /* Initialize constants */ - ALPHA_ST = _ALPHA_ST; - ALPHA_YT = _ALPHA_YT; - SIGMA_LU = _SIGMA_LU; - SIGMA_LY = _SIGMA_LY; - DEFAULT_BETA1 = _DEFAULT_BETA1; - MIN_BETA = _MIN_BETA; - EC_MIN_VALUE = _EC_MIN_VALUE; - CUTOFF = _CUTOFF; -#endif - ec = MALLOC(sizeof(echo_can_state_t)); - - if (ec) { - memset(ec, 0, sizeof(echo_can_state_t)); - ec->Ly_d = CUTOFF; - ec->flag_d = 1; - ec->beta1_d = DEFAULT_BETA1; - ec->beta2_d = DEFAULT_BETA1; - } - return ec; -} - -/* Features */ -/* #define DECAY_BETA_OVER_TIME */ -/* #define ADJUST_SUPRESSION */ - -static inline short echo_can_update(echo_can_state_t *ec, short _ref, short _sig) -{ - FLOAT ref = ((FLOAT) _ref) / 32767.0; - FLOAT sig = ((FLOAT) _sig) / 32767.0; - FLOAT r = 0.0; - FLOAT u_suppr; - FLOAT Py; - FLOAT two_beta; - FLOAT max_y_tilde; - FLOAT grad; - FLOAT suppr_value; - - int k,m; - int rpos, rpos2; - - /* Save reference and signal */ - ec->y_d[ec->yspos] = ref; - ec->y_d[ec->yspos + DEFAULT_M + DEFAULT_N] = ref; - - ec->s_d[ec->yspos] = sig; - ec->s_d[ec->yspos + DEFAULT_M + DEFAULT_N] = sig; - - /* Convolute the current estimated echo */ - for (k = 0; k < DEFAULT_N; k++) { - rpos = ec->yspos - k + (DEFAULT_N + DEFAULT_M); - r += ec->a_d[k] * ec->y_d[rpos]; - } - - u_suppr = sig - r; - - ec->e_d[ec->eupos] = u_suppr; - ec->e_d[ec->eupos + DEFAULT_M] = u_suppr; - - /* Update near-end speech detector */ - ec->s_tilde_d = (1.0 - ALPHA_ST) * ec->s_tilde_d + - (ALPHA_ST * fabs(sig)); - - /* XXX Maybe just keep track of the last one in - a separate variable or something XXX */ - rpos = ec->ytpos + DEFAULT_N - 1; - - ec->y_tilde_d[ec->ytpos] = (1.0 - ALPHA_YT) * ec->y_tilde_d[rpos] + - (ALPHA_YT * fabs(ref)); - - ec->y_tilde_d[ec->ytpos + DEFAULT_N] = ec->y_tilde_d[ec->ytpos]; - - Py = ec->Ly_d * ec->Ly_d; - - if (ec->HCNTR_d > 0) - Py = 1.0; - -#ifdef DECAY_BETA_OVER_TIME - /* XXX OMG what is all this crap about, surely we can do some - IIR filter or something to simulate this nonsense. All - this is supposed to do is decay beta over time XXX */ - if (ec->start_speech_d != 0) { - if (ec->i_d > (DEFAULT_T0 + ec->start_speech_d) * (SAMPLE_FREQ)) { - ec->beta2_d = ec->beta1_d * exp((-1.0/DEFAULT_TAU) * - ((ec->i_d / (FLOAT) SAMPLE_FREQ) - - DEFAULT_T0 - ec->start_speech_d)); - if (ec->beta2_d < MIN_BETA) - ec->beta2_d = MIN_BETA; - } - } else { - ec->beta2_d = ec->beta1_d; - } -#endif - two_beta = ec->beta2_d / Py; - - if (two_beta > MAX_BETA) - two_beta = MAX_BETA; - - ec->Lu_d = ((1.0 - SIGMA_LU) * ec->Lu_d) + - (SIGMA_LU * fabs(u_suppr)); - - ec->Ly_d = ((1.0 - SIGMA_LY) * ec->Ly_d) + - (SIGMA_LY * fabs(ref)); - - if (ec->Ly_d < CUTOFF) - ec->Ly_d = CUTOFF; - - max_y_tilde = 0.0; - - for (k=0;k<DEFAULT_N;k++) { - if (max_y_tilde < ec->y_tilde_d[k]) - max_y_tilde = ec->y_tilde_d[k]; - } - - if (ec->s_tilde_d > (0.2 * max_y_tilde)) { - ec->HCNTR_d = HANGT; - } else if (ec->HCNTR_d) { - ec->HCNTR_d--; - } - - if ((ec->HCNTR_d == 0) && (ec->i_d % DEFAULT_M == 0)) { - /* Update coefficients */ - for (k=0; k < DEFAULT_N; k++) { - grad = 0.0; - for (m = 0; m < DEFAULT_M; m++) { - rpos = ec->eupos - m + DEFAULT_M; - rpos2 = ec->yspos-m-k + DEFAULT_M + DEFAULT_N; - grad += ec->e_d[rpos] * ec->y_d[rpos2]; - } - ec->a_d[k] += two_beta * grad; - } - } - - if (ec->flag_d == 1) { - ec->start_speech_d = ec->i_d / (FLOAT)SAMPLE_FREQ; - ec->flag_d = 0; - } - -#ifdef ADJUST_SUPPRESSION - suppr_value = pow(10, SUPPR / 10.0); - - /* XXX Reverse logic so that it operates on actual value instead - of dB XXX */ - - if ((ec->HCNTR_d == 0) && ((ec->Lu_d/ec->Ly_d) < suppr_value) && - ((ec->Lu_d/ec->Ly_d) > EC_MIN_VALUE)) { - FLOAT suppr_factor = (1/(FLOAT)(SUPPR_FLOOR-SUPPR_CEIL)) * 10 - * log(ec->Lu_d/ec->Ly_d) - - SUPPR_CEIL/(FLOAT)(SUPPR_FLOOR - SUPPR_CEIL); - - u_suppr = pow(10.0,(suppr_factor) * RES_SUPR_FACTOR/10.0) * u_suppr; - } -#endif - - /* Increment everything */ - - ec->i_d++; - - ec->yspos = (ec->yspos + 1) % (DEFAULT_N + DEFAULT_M); - ec->eupos = (ec->eupos + 1) % DEFAULT_M; - ec->ytpos = (ec->ytpos + 1) % DEFAULT_N; - - return (short)(u_suppr * 32767.0); -} - -#endif /* _MECNEW_H */ @@ -28,7 +28,7 @@ this is set, we only transit on hook for some time after a ring (POWERSAVE_TIMEOUT) */ -#define PROSLIC_POWERSAVE +/* #define PROSLIC_POWERSAVE */ #define POWERSAVE_TIME 4000 #include <linux/kernel.h> @@ -113,7 +113,6 @@ static alpha indirect_regs[] = }; static int debug = 0; -static int devcount = 0; #define FLAG_FLIP_RELAYS (1 << 0) @@ -811,7 +810,7 @@ static void wcusb_read_complete(struct urb *q) switch (p->sample) { case STREAM_NORMAL: for (x = 0; x < ZT_CHUNKSIZE; x++) { - p->chan.readchunk[x] = ZT_LIN2MU(chunk[x]); + p->chan.readchunk[x] = ZT_LIN2MU(le16_to_cpu(chunk[x])); } break; case STREAM_DTMF: @@ -867,7 +866,7 @@ static void wcusb_write_complete(struct urb *q) zt_transmit(&p->span); for (x = 0; x < ZT_CHUNKSIZE; x++) { - chunk[x] = ZT_MULAW(p->chan.writechunk[x]); + chunk[x] = cpu_to_le16(ZT_MULAW(p->chan.writechunk[x])); } q->dev = p->dev; @@ -1054,6 +1053,7 @@ static int wc_usb_close(struct zt_chan *chan) /* Someone unplugged us while we were running, so now that the program exited, we can release our resources */ zt_unregister(&p->span); + ifaces[p->pos] = NULL; if (p->pvt_data) kfree(p->pvt_data); kfree(p); @@ -1062,16 +1062,20 @@ static int wc_usb_close(struct zt_chan *chan) return 0; } -static struct wc_usb_pvt *wc_detect_device(struct usb_device *dev) +static struct wc_usb_pvt *wc_detect_device(struct usb_device *dev, struct wc_usb_pvt *orig) { - struct wc_usb_pvt *p = kmalloc(sizeof(struct wc_usb_pvt), GFP_KERNEL); - + struct wc_usb_pvt *p; + + p = orig; if (!p) { - printk("wcusb: kmalloc failed\n"); - return NULL; - } + p = kmalloc(sizeof(struct wc_usb_pvt), GFP_KERNEL); + if (!p) { + printk("wcusb: kmalloc failed\n"); + return NULL; + } - memset(p, 0, sizeof(struct wc_usb_pvt)); + memset(p, 0, sizeof(struct wc_usb_pvt)); + } p->dev = dev; #ifdef PROSLIC_POWERSAVE @@ -1109,9 +1113,16 @@ static int wc_set_zaptel(struct wc_usb_pvt *p) { int x; - sprintf(p->span.name, "WCUSB/%d", devcount); - sprintf(p->span.desc,"%s %d", p->span.name, devcount); - sprintf(p->chan.name, "WCUSB/%d/%d", devcount, 0); + for (x = 0; x < WC_MAX_IFACES; x++) + if (!ifaces[x]) break; + if (x >= WC_MAX_IFACES) { + printk("wcusb: Too many interfaces\n"); + return -1; + } + + sprintf(p->span.name, "WCUSB/%d", x); + sprintf(p->span.desc,"%s %d", p->span.name, x); + sprintf(p->chan.name, "WCUSB/%d/%d", x, 0); p->chan.sigcap = ZT_SIG_FXOKS | ZT_SIG_FXOLS | ZT_SIG_FXOGS; /* We're capabable of both FXOKS and FXOLS */ p->chan.chanpos = 1; @@ -1122,18 +1133,12 @@ static int wc_set_zaptel(struct wc_usb_pvt *p) p->span.open = wc_usb_open; p->span.close = wc_usb_close; - for (x = 0; x < WC_MAX_IFACES; x++) - if (!ifaces[x]) break; - if (x >= WC_MAX_IFACES) { - printk("wcusb: Too many interfaces\n"); - return -1; - } - - p->pos = x; - p->span.flags = ZT_FLAG_RBS; - init_waitqueue_head(&p->span.maintq); - p->span.pvt = p; - p->chan.pvt = p; + ifaces[x] = p; + p->pos = x; + p->span.flags = ZT_FLAG_RBS; + init_waitqueue_head(&p->span.maintq); + p->span.pvt = p; + p->chan.pvt = p; /* Set the stream to just pass the data from the device uninhibited */ p->sample = STREAM_NORMAL; @@ -1151,7 +1156,25 @@ static void *wc_usb_probe(struct usb_device *dev, unsigned int ifnum, const stru struct wc_usb_pvt *p = NULL; struct wc_usb_desc *d = (struct wc_usb_desc *)id->driver_info; - if (!(p = wc_detect_device(dev))) { + int x; + for (x=0;x<WC_MAX_IFACES;x++) { + /* Find first dead or empty space */ + p = ifaces[x]; + if (!p) { + if (debug) + printk("Device slot %d is free\n", x); + break; + } + if (p->dead) { + if (debug) + printk("Device slot %d can be revived\n", x); + break; + } + if (debug) + printk("Device slot %d is still in use\n", x); + } + + if (!(p = wc_detect_device(dev, p))) { printk("wcusb: No wcusb devices found\n"); return NULL; } @@ -1175,7 +1198,7 @@ static void *wc_usb_probe(struct usb_device *dev, unsigned int ifnum, const stru flip_relays(p, 1); } - if (wc_set_zaptel(p)) { + if (!p->dead && wc_set_zaptel(p)) { printk("wcusb: Error in starting the zaptel stuff\n"); goto cleanup; } @@ -1185,9 +1208,16 @@ static void *wc_usb_probe(struct usb_device *dev, unsigned int ifnum, const stru goto cleanup; } - printk("wcusb: Found a %s\n", d->name); + if (p->dead) + printk("wcusb: Rekindling a %s (%s)\n", d->name, p->span.name); + else + printk("wcusb: Found a %s (%s)\n", d->name, p->span.name); - devcount++; /* Increase our device count */ + /* Reset deadness */ + p->dead = 0; + /* Clear alarms */ + p->span.alarms = 0; + zt_alarm_notify(&p->span); return p; cleanup: @@ -1207,10 +1237,12 @@ static void wc_usb_disconnect(struct usb_device *dev, void *ptr) struct wc_usb_pvt *p = ptr; if (ptr) { StopTransmit(p); + p->dev = NULL; if (!p->usecount) { zt_unregister(&p->span); if (p->pvt_data) kfree(p->pvt_data); + ifaces[p->pos] = NULL; kfree(ptr); } else { /* Generate alarm and note that we're dead */ @@ -1219,7 +1251,6 @@ static void wc_usb_disconnect(struct usb_device *dev, void *ptr) p->dead = 1; } } - devcount--; printk("wcusb: Removed a Wildcard device\n"); return; } |