287 lines
9.0 KiB
Diff
287 lines
9.0 KiB
Diff
diff -dur zaptel-1.0.9.1_original/zaptel.c zaptel/zaptel.c
|
|
--- zaptel-1.0.9.1_original/zaptel.c 2005-08-16 16:27:17.491862664 +0000
|
|
+++ zaptel/zaptel.c 2005-08-16 17:21:24.896182168 +0000
|
|
@@ -289,6 +289,8 @@
|
|
|
|
static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit);
|
|
|
|
+static void sang_zt_ec_chunk_spike_store(struct zt_chan *ss, unsigned char *rxchunk);
|
|
+
|
|
#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 */
|
|
@@ -4113,6 +4115,11 @@
|
|
chan->echostate = ECHO_STATE_IDLE;
|
|
chan->echolastupdate = 0;
|
|
chan->echotimer = 0;
|
|
+ chan->echo_spike_struct.state_bits = SANGOMA_INITIAL_STATE;
|
|
+ chan->echo_spike_struct.sample_len_counter = 0;
|
|
+ if(chan->echo_detect_struct.ed_enabled == 1){
|
|
+ chan->echo_detect_struct.echo_detection_state = ECHO_DETECT_ON;
|
|
+ }
|
|
echo_can_disable_detector_init(&chan->txecdis);
|
|
echo_can_disable_detector_init(&chan->rxecdis);
|
|
}
|
|
@@ -4127,6 +4134,7 @@
|
|
chan->echostate = ECHO_STATE_IDLE;
|
|
chan->echolastupdate = 0;
|
|
chan->echotimer = 0;
|
|
+ chan->echo_detect_struct.echo_detection_state = ECHO_DETECT_OFF;
|
|
/* Attempt hardware native echo can */
|
|
if (chan->span && chan->span->echocan)
|
|
chan->span->echocan(chan, 0);
|
|
@@ -4270,6 +4278,92 @@
|
|
return -EINVAL;
|
|
break;
|
|
#endif
|
|
+ case SANGOMA_GET_ED_STATE:
|
|
+ if(chan->span->ioctl != NULL){
|
|
+ if (chan->span->ioctl(chan, cmd, 0) != 0){
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ copy_to_user((echo_detect_struct_t*)data, &chan->echo_detect_struct,
|
|
+ sizeof(echo_detect_struct_t));
|
|
+ }else{
|
|
+ printk(KERN_INFO "SANGOMA_GET_ED_STATE: channo: %d : chan->span->ioctl == NULL !!\n",
|
|
+ chan->channo);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case SANGOMA_ENABLE_ED:
|
|
+ chan->echo_detect_struct.ed_enabled = 1;
|
|
+ break;
|
|
+
|
|
+ case SANGOMA_DISABLE_ED:
|
|
+ chan->echo_detect_struct.ed_enabled = 0;
|
|
+ break;
|
|
+
|
|
+ case SANGOMA_GET_ECHO_SPIKE_SAMPLE:
|
|
+ if(chan->echo_spike_struct.sample_buffer){
|
|
+ unsigned char *tmp_ptr = (unsigned char*)data;
|
|
+
|
|
+ chan->echo_spike_struct.return_code = SANGOMA_OK;
|
|
+
|
|
+ /* first copy the 'echo_spike_struct_t' structure */
|
|
+ copy_to_user(tmp_ptr, &chan->echo_spike_struct, sizeof(echo_spike_struct_t));
|
|
+
|
|
+ /* second copy the data AFTER the 'echo_spike_struct_t' structure */
|
|
+ copy_to_user (&tmp_ptr[sizeof(echo_spike_struct_t)],
|
|
+ chan->echo_spike_struct.sample_buffer,
|
|
+ SANGOMA_SPIKE_SAMPLE_LEN);
|
|
+
|
|
+ /* free the sample buffer */
|
|
+ kfree(chan->echo_spike_struct.sample_buffer);
|
|
+ chan->echo_spike_struct.sample_buffer = NULL;
|
|
+
|
|
+ chan->echo_spike_struct.state_bits = SANGOMA_INITIAL_STATE;
|
|
+ chan->echo_spike_struct.sample_len_counter = 0;
|
|
+ }else{
|
|
+ unsigned char *tmp_ptr = (unsigned char*)data;
|
|
+
|
|
+ chan->echo_spike_struct.return_code = SANGOMA_NO_ACTIVE_CALL_OR_EC_OFF;
|
|
+ /* copy the 'echo_spike_struct_t' structure */
|
|
+ copy_to_user(tmp_ptr, &chan->echo_spike_struct, sizeof(echo_spike_struct_t));
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case SANGOMA_SEND_SPIKE:
|
|
+ /* allocate EchoTest buffer */
|
|
+ chan->echo_spike_struct.sample_buffer = kmalloc(SANGOMA_SPIKE_SAMPLE_LEN, GFP_KERNEL);
|
|
+ if (chan->echo_spike_struct.sample_buffer == NULL) {
|
|
+ printk(KERN_INFO "channo: %d: Failed to allocate %d bytes for EchoTest storage!!!\n",
|
|
+ chan->channo, SANGOMA_SPIKE_SAMPLE_LEN);
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+
|
|
+ spin_lock_irqsave(&chan->lock, flags);
|
|
+ /* send echo spike */
|
|
+ if (chan->ec) {
|
|
+ chan->echo_spike_struct.state_bits = SANGOMA_INITIAL_STATE;
|
|
+ chan->echo_spike_struct.sample_len_counter = 0;
|
|
+ /* these two lines will make zaptel to send the spike: */
|
|
+ chan->echostate = ECHO_STATE_PRETRAINING;
|
|
+ chan->echotimer = 2048; /*Number of silence bytes to transmit before the spike.
|
|
+ It makes the line clean from noise, so spike is easy
|
|
+ to detect on return.*/
|
|
+ /* must unlock here!! */
|
|
+ spin_unlock_irqrestore(&chan->lock, flags);
|
|
+ }else{
|
|
+ unsigned char *tmp_ptr = (unsigned char*)data;
|
|
+
|
|
+ chan->echo_spike_struct.return_code = SANGOMA_NO_ACTIVE_CALL_OR_EC_OFF;
|
|
+
|
|
+ /* Must unlock here, BEFORE copy_to_user() call.
|
|
+ Or will get warnings from the kernel. */
|
|
+ spin_unlock_irqrestore(&chan->lock, flags);
|
|
+
|
|
+ /* copy the 'echo_spike_struct_t' structure */
|
|
+ copy_to_user(tmp_ptr, &chan->echo_spike_struct, sizeof(echo_spike_struct_t));
|
|
+ }
|
|
+ break;
|
|
+
|
|
default:
|
|
return zt_chanandpseudo_ioctl(inode, file, cmd, data, unit);
|
|
}
|
|
@@ -5325,7 +5419,13 @@
|
|
short rxlin, txlin;
|
|
int x;
|
|
unsigned long flags;
|
|
+ unsigned char rxchunk_backup[ZT_CHUNKSIZE];
|
|
+
|
|
spin_lock_irqsave(&ss->lock, flags);
|
|
+
|
|
+ //original rxchank is modyfied, make a backup copy for future use.
|
|
+ memcpy(rxchunk_backup, rxchunk, ZT_CHUNKSIZE);
|
|
+
|
|
/* Perform echo cancellation on a chunk if necessary */
|
|
if (ss->ec) {
|
|
#if defined(CONFIG_ZAPTEL_MMX) || defined(ECHO_CAN_FP)
|
|
@@ -5345,12 +5445,30 @@
|
|
if ((ss->echostate == ECHO_STATE_AWAITINGECHO) && (txlin > 8000)) {
|
|
ss->echolastupdate = 0;
|
|
ss->echostate = ECHO_STATE_TRAINING;
|
|
+
|
|
+ //printk(KERN_INFO "ss->echostate == ECHO_STATE_AWAITINGECHO\n");
|
|
+
|
|
+ if(ss->echo_spike_struct.state_bits == SANGOMA_INITIAL_STATE){
|
|
+ ss->echo_spike_struct.state_bits = SANGOMA_BUSY_COLLECTING_SAMPLE;
|
|
+ ss->echo_spike_struct.sample_len_counter = 0;
|
|
+ }
|
|
}
|
|
if (ss->echostate == ECHO_STATE_TRAINING) {
|
|
+ //printk(KERN_INFO "rxchunk[%d]: 0x%02X\n", x, rxchunk[x]);
|
|
+
|
|
if (echo_can_traintap(ss->ec, ss->echolastupdate++, rxlin)) {
|
|
#if 0
|
|
printk("Finished training (%d taps trained)!\n", ss->echolastupdate);
|
|
#endif
|
|
+ /*
|
|
+ //sang
|
|
+ printk(KERN_INFO
|
|
+ "span:%d,chan:%d:Finished training (%d taps trained)!\n",
|
|
+ (ss->span ? ss->span->spanno : 0),
|
|
+ ss->channo,
|
|
+ ss->echolastupdate);
|
|
+ */
|
|
+
|
|
ss->echostate = ECHO_STATE_ACTIVE;
|
|
}
|
|
}
|
|
@@ -5364,6 +5482,9 @@
|
|
rxchunk[x] = ZT_LIN2X((int)rxlin, ss);
|
|
}
|
|
}
|
|
+
|
|
+ sang_zt_ec_chunk_spike_store(ss, rxchunk_backup);
|
|
+
|
|
#if defined(CONFIG_ZAPTEL_MMX) || defined(ECHO_CAN_FP)
|
|
kernel_fpu_end();
|
|
#endif
|
|
@@ -6500,3 +6621,60 @@
|
|
|
|
module_init(zt_init);
|
|
module_exit(zt_cleanup);
|
|
+
|
|
+
|
|
+static void sang_zt_ec_chunk_spike_store(struct zt_chan *ss, unsigned char *rxchunk)
|
|
+{
|
|
+ int x;
|
|
+
|
|
+ if(ss->echo_spike_struct.state_bits != SANGOMA_BUSY_COLLECTING_SAMPLE ||
|
|
+ ss->echo_spike_struct.sample_buffer == NULL){
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ //check input values
|
|
+ if(ss->echo_spike_struct.sample_len_counter >= SANGOMA_SPIKE_SAMPLE_LEN){
|
|
+ printk(KERN_INFO "chan: %d: Invalid sample_len_counter! (%d)\n",
|
|
+ ss->channo, ss->echo_spike_struct.sample_len_counter);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if(ss->echo_spike_struct.state_bits == SANGOMA_BUSY_COLLECTING_SAMPLE){
|
|
+
|
|
+ for (x = 0; x < ZT_CHUNKSIZE; x++) {
|
|
+ ss->echo_spike_struct.sample_buffer[ss->echo_spike_struct.sample_len_counter]
|
|
+ = rxchunk[x];
|
|
+
|
|
+ ss->echo_spike_struct.sample_len_counter++;
|
|
+
|
|
+ if(ss->echo_spike_struct.sample_len_counter >= SANGOMA_SPIKE_SAMPLE_LEN){
|
|
+ //finished collecting the sample
|
|
+ ss->echo_spike_struct.state_bits = SANGOMA_FINISHED_COLLECTING_SAMPLE;
|
|
+ break;
|
|
+ }//if()
|
|
+ }//for()
|
|
+ }//if()
|
|
+
|
|
+#if 0
|
|
+ if(ss->echo_spike_struct.state_bits == SANGOMA_FINISHED_COLLECTING_SAMPLE){
|
|
+
|
|
+ printk(KERN_INFO "chan: %d: spike sample buffer(len:%d):\n",
|
|
+ ss->channo, SANGOMA_SPIKE_SAMPLE_LEN);
|
|
+ //print out the sample buffer
|
|
+ for (x = 0; x < SANGOMA_SPIKE_SAMPLE_LEN; x++) {
|
|
+ printk(KERN_INFO "0x%02X\n", ss->echo_spike_struct.sample_buffer[x]);
|
|
+ }
|
|
+ printk(KERN_INFO "end of spike sample buffer\n");
|
|
+
|
|
+ printk(KERN_INFO "chan: %d: LINEAR (ALAW) spike sample buffer(len:%d):\n",
|
|
+ ss->channo, SANGOMA_SPIKE_SAMPLE_LEN);
|
|
+ //print out the sample buffer
|
|
+ for (x = 0; x < SANGOMA_SPIKE_SAMPLE_LEN; x++) {
|
|
+ printk(KERN_INFO "0x%04X\n",
|
|
+ ZT_ALAW(ss->echo_spike_struct.sample_buffer[x]) & 0xFFFF);
|
|
+ }
|
|
+ printk(KERN_INFO "end of spike sample buffer\n");
|
|
+ }
|
|
+#endif
|
|
+}
|
|
+
|
|
diff -dur zaptel-1.0.9.1_original/zaptel.h zaptel/zaptel.h
|
|
--- zaptel-1.0.9.1_original/zaptel.h 2005-08-16 16:27:17.503860840 +0000
|
|
+++ zaptel/zaptel.h 2005-08-16 17:22:11.279130888 +0000
|
|
@@ -61,6 +61,8 @@
|
|
#endif /* CONFIG_DEVFS_FS */
|
|
#include <linux/ioctl.h>
|
|
|
|
+#include <linux/wanpipe_edac_iface.h>
|
|
+
|
|
#ifndef ELAST
|
|
#define ELAST 500
|
|
#endif
|
|
@@ -608,6 +610,21 @@
|
|
* 80-85 are reserved for dynamic span stuff
|
|
*/
|
|
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+#define SANGOMA_GET_ED_STATE _IOR (ZT_CODE, 61, int)
|
|
+#define SANGOMA_ENABLE_ED _IOR (ZT_CODE, 62, int)
|
|
+#define SANGOMA_DISABLE_ED _IOR (ZT_CODE, 63, int)
|
|
+#define SANGOMA_GET_ECHO_SPIKE_SAMPLE _IOR (ZT_CODE, 64, int)
|
|
+#define SANGOMA_SEND_SPIKE _IOR (ZT_CODE, 65, int)
|
|
+
|
|
/*
|
|
* Create a dynamic span
|
|
*/
|
|
@@ -1150,6 +1167,10 @@
|
|
devfs_handle_t fhandle; /* File handle in devfs for the channel */
|
|
devfs_handle_t fhandle_symlink;
|
|
#endif /* CONFIG_DEVFS_FS */
|
|
+
|
|
+ //SANGOMA
|
|
+ echo_detect_struct_t echo_detect_struct;
|
|
+ echo_spike_struct_t echo_spike_struct;
|
|
};
|
|
|
|
/* defines for transmit signalling */
|