diff -Nura zaptel-1.2.18/oslec.h zaptel-1.2.18-oslec/oslec.h --- zaptel-1.2.18/oslec.h 1970-01-01 01:00:00.000000000 +0100 +++ zaptel-1.2.18-oslec/oslec.h 2007-12-30 18:30:52.000000000 +0100 @@ -0,0 +1,24 @@ +/* + oslec.h + David Rowe + 7 Feb 2007 + + Interface for OSLEC module. +*/ + +#ifndef __OSLEC__ + +struct echo_can_state { + void *ec; +}; + +struct echo_can_state *oslec_echo_can_create(int len, int adaption_mode); +void oslec_echo_can_free(struct echo_can_state *ec); +short oslec_echo_can_update(struct echo_can_state *ec, short iref, short isig); +int oslec_echo_can_traintap(struct echo_can_state *ec, int pos, short val); +static inline void echo_can_init(void) {} +static inline void echo_can_shutdown(void) {} +short oslec_hpf_tx(struct echo_can_state *ec, short txlin); + +#endif + diff -Nura zaptel-1.2.18/version.h zaptel-1.2.18-oslec/version.h --- zaptel-1.2.18/version.h 1970-01-01 01:00:00.000000000 +0100 +++ zaptel-1.2.18-oslec/version.h 2007-12-30 18:30:52.000000000 +0100 @@ -0,0 +1,6 @@ +/* + * version.h + * Automatically generated + */ +#define ZAPTEL_VERSION "1.2.13" + diff -Nura zaptel-1.2.18/zaptel-base.c zaptel-1.2.18-oslec/zaptel-base.c --- zaptel-1.2.18/zaptel-base.c 2007-05-18 17:48:55.000000000 +0200 +++ zaptel-1.2.18-oslec/zaptel-base.c 2007-12-30 18:30:52.000000000 +0100 @@ -417,6 +417,15 @@ #include "mg2ec.h" #elif defined(ECHO_CAN_JP1) #include "jpah.h" +/* Start Open Source Line Echo Canceller (OSLEC) -----------------*/ +#elif defined(ECHO_CAN_OSLEC) +#include "oslec.h" +#define echo_can_create oslec_echo_can_create +#define echo_can_free oslec_echo_can_free +#define echo_can_update oslec_echo_can_update +#define echo_can_traintap oslec_echo_can_traintap +#define ZAPTEL_ECHO_CANCELLER "OSLEC" +/* End Open Source Line Echo Canceller (OSLEC) -------------------*/ #else #include "mec3.h" #endif @@ -5588,6 +5597,70 @@ spin_unlock_irqrestore(&chan->lock, flags); } +/* Zaptap code -----------------------------------------------------------*/ + +#define SAMPLE_BUF_SZ 1000 +#define SAMPLE_IDLE 0 +#define SAMPLE_PING 1 +#define SAMPLE_PONG 2 + +DECLARE_WAIT_QUEUE_HEAD(sample_wait); +static int sample_state = 0; +static int samples = 0; +static short *psample; +static short ping[3*SAMPLE_BUF_SZ]; +static short pong[3*SAMPLE_BUF_SZ]; +static int sample_ch = 1; +static int sample_impulse = 0; +static int tmp1,tmp2; + +static inline void sample_echo_before(int channo, short rxlin, short txlin) { + + // Sample echo canceller signals + // Notes: + // 1. Samples are multiplexed in buffer: + // tx sample + // rx sample + // ec sample + // 2. We needs to sample rx here before echo can as it is + // overwritten. + + tmp1++; + tmp2 = channo; + if ((sample_state != SAMPLE_IDLE) && (channo == sample_ch)) { + *psample++ = txlin; + *psample++ = rxlin; + } +} + +static inline void sample_echo_after(int channo, short rxlin) { + + if ((sample_state != SAMPLE_IDLE) && (channo == sample_ch)) { + + *psample++ = rxlin; + + // sample collection ping-pong buffer logic + + samples++; + if (samples >= SAMPLE_BUF_SZ) { + // time to swap buffers + samples = 0; + + if (sample_state == SAMPLE_PING) { + sample_state = SAMPLE_PONG; + psample = pong; + } + else { + sample_state = SAMPLE_PING; + psample = ping; + } + wake_up_interruptible(&sample_wait); + } + } +} + +/* end Zaptap code -----------------------------------------------------*/ + static inline void __zt_ec_chunk(struct zt_chan *ss, unsigned char *rxchunk, const unsigned char *txchunk) { short rxlin, txlin; @@ -5638,7 +5711,9 @@ #if !defined(ZT_EC_ARRAY_UPDATE) for (x=0;xchanno, rxlin, ZT_XLAW(txchunk[x], ss)); /* Zaptap code */ rxlin = echo_can_update(ss->ec, ZT_XLAW(txchunk[x], ss), rxlin); + sample_echo_after(ss->channo, rxlin); /* Zaptap code */ rxchunk[x] = ZT_LIN2X((int)rxlin, ss); } #else /* defined(ZT_EC_ARRAY_UPDATE) */ @@ -6356,6 +6431,8 @@ static void __zt_transmit_chunk(struct zt_chan *chan, unsigned char *buf) { unsigned char silly[ZT_CHUNKSIZE]; + int x; + /* Called with chan->lock locked */ if (!buf) buf = silly; @@ -6370,10 +6447,27 @@ kernel_fpu_end(); #endif } + + /* Start Zaptap code -----------------------------------------*/ + + if (sample_impulse && (samples == 0)) { + + // option impulse insertion, tx stream becomes one + // impulse followed by SAMPLE_BUF_SZ-1 0's + + buf[0] = ZT_LIN2MU(10000); + for (x=1;xlock held */ if (chan->confmode) { /* Pull queued data off the conference */ @@ -6381,6 +6475,7 @@ } else { __zt_transmit_chunk(chan, chan->writechunk); } + } static void __zt_getempty(struct zt_chan *ms, unsigned char *buf) @@ -6774,6 +6869,104 @@ #endif +/* Zaptap code -----------------------------------------------------*/ + +static int sample_open (struct inode *inode, struct file *file) { + printk("sample_open:\n"); + tmp1 = tmp2 = -1; + + psample = ping; + samples = 0; + sample_state = SAMPLE_PING; + + return 0; +} + +static int sample_release (struct inode *inode, struct file *file) { + printk("sample_release: tmp1 = %d tmp2 = %d\n", tmp1, tmp2); + + sample_state = SAMPLE_IDLE; + sample_impulse = 0; + samples = 0; + + return 0; +} + +static ssize_t sample_read(struct file *file, char *buf, + size_t count, loff_t *ppos) { + int err, len; + short *pread; + + /* wait for next buffer to be prepared by ISR, we read + alternate buffer just after transition. + */ + interruptible_sleep_on(&sample_wait); + + if (sample_state == SAMPLE_PING) { + pread = pong; + } + else { + pread = ping; + } + + len = 3*sizeof(short)*SAMPLE_BUF_SZ; + err = copy_to_user(buf, pread, len); + + if (err != 0) + return -EFAULT; + + return len; +} + +/* ioctls for sample */ + +#define SAMPLE_SET_CHANNEL 0 +#define SAMPLE_TX_IMPULSE 1 + +static int sample_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) { + int retval = 0; + + switch ( cmd ) { + case SAMPLE_SET_CHANNEL: + if (copy_from_user(&sample_ch, (int *)arg, sizeof(int))) + return -EFAULT; + printk("sample_ioctl: sample_ch = %d\n", sample_ch); + break; + case SAMPLE_TX_IMPULSE: + sample_impulse = 1; + printk("sample_ioctl: under impulse power\n"); + break; + default: + retval = -EINVAL; + } + + return retval; +} + +// define which file operations are supported +struct file_operations sample_fops = { + .owner = THIS_MODULE, + .llseek = NULL, + .read = sample_read, + .write = NULL, + .readdir= NULL, + .poll = NULL, + .ioctl = sample_ioctl, + .mmap = NULL, + .open = sample_open, + .flush = NULL, + .release= sample_release, + .fsync = NULL, + .fasync = NULL, + .lock = NULL, +}; + +#define SAMPLE_NAME "sample" +#define SAMPLE_MAJOR 33 + +/* end Zaptap code -----------------------------------------------------*/ + static int __init zt_init(void) { int res = 0; @@ -6820,12 +7013,27 @@ #ifdef CONFIG_ZAPTEL_WATCHDOG watchdog_init(); #endif + + /* start Zaptap code ----------------------------------------*/ + + sample_state = SAMPLE_IDLE; + sample_impulse = 0; + if ((res = register_chrdev (SAMPLE_MAJOR, SAMPLE_NAME, &sample_fops))) { + printk(KERN_ERR "Zaptap unable to register 'sample' char driver on %d\n", SAMPLE_MAJOR); + return res; + } + printk("Zaptap registered 'sample' char driver on major %d\n", SAMPLE_MAJOR); + + /* end Zaptap code ------------------------------------------*/ + return res; } static void __exit zt_cleanup(void) { int x; + unregister_chrdev (SAMPLE_MAJOR, SAMPLE_NAME); /* Zaptap code */ + #ifdef CONFIG_PROC_FS remove_proc_entry("zaptel", NULL); #endif diff -Nura zaptel-1.2.18/zconfig.h zaptel-1.2.18-oslec/zconfig.h --- zaptel-1.2.18/zconfig.h 2007-04-24 20:33:29.000000000 +0200 +++ zaptel-1.2.18-oslec/zconfig.h 2007-12-30 18:33:07.000000000 +0100 @@ -58,6 +58,7 @@ * supposed to improve how it performs. If you have echo problems, * try it out! */ /* #define ECHO_CAN_MG2 */ +/* #define ECHO_CAN_OSLEC */ /* * This is only technically an "echo canceller"...