misdn.patch

来自「一个非常美妙的proxy。功能强大。基于sip的协议。如果还要的话」· PATCH 代码 · 共 2,345 行 · 第 1/5 页

PATCH
2,345
字号
+	+	for (i = 0 ; i < 256 ; i++) {+		unsigned char sample = 0 ;+		for (k = 0; k<8; k++) {+			if ( i & 1 << k ) sample |= 0x80 >>  k;+		}+		flip_table[i] = sample;+	}+}++static unsigned char * flip_buf_bits ( unsigned char * buf , int len)+{+	int i;+	char * start = buf;+	+	for (i = 0 ; i < len; i++) {+		buf[i] = flip_table[buf[i]];+	}+	+	return start;+}++++void+dsp_cancel_tx(dsp_t *dsp, u8 *data, int len)+{+	if (!dsp ) return ;+	if (!data) return;+	+	if (dsp->txbuflen + len < ECHOCAN_BUFLEN) {+		memcpy(&dsp->txbuf[dsp->txbuflen],data,len);+		dsp->txbuflen+=len;+	} else {+		printk("ECHOCAN: TXBUF Overflow len:%d newlen:%d\n",dsp->txbuflen,len);+		dsp->txbuflen=0;+	}+	+}++void+dsp_cancel_rx(dsp_t *dsp, u8 *data, int len)+{+	if (!dsp ) return ;+	if (!data) return;+	+	if (len <= dsp->txbuflen) {+		char tmp[ECHOCAN_BUFLEN];+		+		int delta=dsp->txbuflen-len;+		+		memcpy(tmp,&dsp->txbuf[len],delta);+		+		flip_buf_bits(data,len);+		flip_buf_bits(dsp->txbuf,len);+		bchdev_echocancel_chunk(dsp, data, dsp->txbuf, len);+		flip_buf_bits(data,len);+		+		memcpy(dsp->txbuf,tmp,delta);+		dsp->txbuflen=delta;+		//dsp->txbuflen=0;+		+		//bchdev_echocancel_chunk(dsp,  dsp->txbuf, data, len);+	} else {+		printk("ECHOCAN: TXBUF Underrun len:%d newlen:%d\n",dsp->txbuflen,len);+	}+	+}++int+dsp_cancel_init(dsp_t *dsp, int deftaps, int training, int delay)+{+	+	if (!dsp) return -1;+	+	printk("DSP_CANCEL_INIT called\n");+	+	if (delay < 0)+	{+		printk("Disabling EC\n");+		dsp->cancel_enable = 0;+		+		dsp->txbuflen=0;+		+		bchdev_echocancel_deactivate(dsp);+		+		return(0);+	}+	+	dsp->txbuflen=0;+	dsp->rxbuflen=0;+	+	+	bchdev_echocancel_activate(dsp,deftaps, training);+	+	printk("Enabling EC\n");+	dsp->cancel_enable = 1;+	return(0);+}++++++/*****************************************************/+#define __ECHO_STATE_MUTE                       (1 << 8)+#define ECHO_STATE_IDLE                         (0)+#define ECHO_STATE_PRETRAINING          (1 | (__ECHO_STATE_MUTE))+#define ECHO_STATE_STARTTRAINING        (2 | (__ECHO_STATE_MUTE))+#define ECHO_STATE_AWAITINGECHO         (3 | (__ECHO_STATE_MUTE))+#define ECHO_STATE_TRAINING                     (4 | (__ECHO_STATE_MUTE))+#define ECHO_STATE_ACTIVE                       (5)++#define AMI_MASK 0x55+++static unsigned char linear2alaw (short linear)+{+	int mask;+	int seg;+	int pcm_val;+	static int seg_end[8] =+		{+			0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF+		};+    +	pcm_val = linear;+	if (pcm_val >= 0)+	{+		/* Sign (7th) bit = 1 */+		mask = AMI_MASK | 0x80;+	}+	else+	{+		/* Sign bit = 0 */+		mask = AMI_MASK;+		pcm_val = -pcm_val;+	}++	/* Convert the scaled magnitude to segment number. */+	for (seg = 0;  seg < 8;  seg++)+	{+		if (pcm_val <= seg_end[seg])+			break;+	}+	/* Combine the sign, segment, and quantization bits. */+	return  ((seg << 4) | ((pcm_val >> ((seg)  ?  (seg + 3)  :  4)) & 0x0F)) ^ mask;+}++/*- End of function --------------------------------------------------------*/++static short int alaw2linear (uint8_t alaw)+{+	int i;+	int seg;++	alaw ^= AMI_MASK;+	i = ((alaw & 0x0F) << 4);+	seg = (((int) alaw & 0x70) >> 4);+	if (seg)+		i = (i + 0x100) << (seg - 1);+	return (short int) ((alaw & 0x80)  ?  i  :  -i);+}+++/** @return string of given echo cancellation state */+char* bchdev_echocancel_statestr(uint16_t state)+{+  switch(state) {+  case ECHO_STATE_IDLE:+    return "idle";+    break;+  case ECHO_STATE_PRETRAINING:+    return "pre-training";+    break;+  case ECHO_STATE_STARTTRAINING:+    return "transmit impulse";+    break;+  case ECHO_STATE_AWAITINGECHO:+    return "awaiting echo";+    break;+  case ECHO_STATE_TRAINING:+    return "training start";+    break;+  case ECHO_STATE_ACTIVE:+    return "training finished";+    break;+  default:+    return "unknown";+  }+}++/** Changes state of echo cancellation to given state */+void bchdev_echocancel_setstate(dsp_t* dev, uint16_t state)+{+  char* statestr = bchdev_echocancel_statestr(state);+  +  printk("bchdev: echo cancel state %d (%s)\n", state & 0xff, statestr);+  if (state == ECHO_STATE_ACTIVE)+	  printk("bchdev: %d taps trained\n", dev->echolastupdate);+  dev->echostate = state;+}++static int buf_size=0;+static int ec_timer=2000;+//static int ec_timer=1000;+++/** Activates echo cancellation for the given bch_dev, device must have been locked before! */+int bchdev_echocancel_activate(dsp_t* dev, int deftaps, int training)+{+  int taps;+  +  if (! dev) return -EINVAL;+  +  if (dev->ec && dev->ecdis_rd && dev->ecdis_wr) {+	  // already active+    return 0;+  }+  +  if (deftaps>0) {+	  taps=deftaps;+  } else {+	  taps=128;+  }+  +  +  switch (buf_size) {+  case  0: taps +=    0; break;+  case  1: taps +=  256-128; break;+  case  2: taps +=  512-128; break;+  default: taps += 1024-128;+  }+  +  if (!dev->ec) dev->ec = echo_can_create(taps, 0);+  if (!dev->ec) {+	  return -ENOMEM;+  }+  +  dev->echolastupdate = 0;++  if (!training) {+	  dev->echotimer=0;+	  bchdev_echocancel_setstate(dev, ECHO_STATE_IDLE);+  } else {+	  if (training<10) +		  training= ec_timer;+	  +	  dev->echotimer      = training;+	  bchdev_echocancel_setstate(dev, ECHO_STATE_PRETRAINING);++  }+  +  if (!dev->ecdis_rd) dev->ecdis_rd = kmalloc(sizeof(echo_can_disable_detector_state_t), GFP_KERNEL);+  if (!dev->ecdis_rd) {+	  kfree(dev->ec); dev->ec = NULL;+	  return -ENOMEM;+  }+  echo_can_disable_detector_init(dev->ecdis_rd);+  +  if (!dev->ecdis_wr) dev->ecdis_wr = kmalloc(sizeof(echo_can_disable_detector_state_t), GFP_KERNEL);+  if (!dev->ecdis_wr) {+	  kfree(dev->ec); dev->ec = NULL;+	  kfree(dev->ecdis_rd); dev->ecdis_rd = NULL;+    return -ENOMEM;+  }+  echo_can_disable_detector_init(dev->ecdis_wr);++  return 0;+}++/** Deactivates echo cancellation for the given bch_dev, device must have been locked before! */+void bchdev_echocancel_deactivate(dsp_t* dev)+{+  if (! dev) return;++  //chan_misdn_log("bchdev: deactivating echo cancellation on port=%04x, chan=%02x\n", dev->stack->port, dev->channel);+  +  if (dev->ec) echo_can_free(dev->ec);+  dev->ec = NULL;+  +  dev->echolastupdate = 0;+  dev->echotimer      = 0;+  bchdev_echocancel_setstate(dev, ECHO_STATE_IDLE);++  if (dev->ecdis_rd) kfree(dev->ecdis_rd);+  dev->ecdis_rd = NULL;+  +  if (dev->ecdis_wr) kfree(dev->ecdis_wr);+  dev->ecdis_wr = NULL;+}++/** Processes one TX- and one RX-packet with echocancellation */+void bchdev_echocancel_chunk(dsp_t* dev, uint8_t *rxchunk, uint8_t *txchunk, uint16_t size)+{+  int16_t rxlin, txlin;+  uint16_t pos;++  /* Perform echo cancellation on a chunk if requested */+  if (dev->ec) {+    if (dev->echostate & __ECHO_STATE_MUTE) {+      if (dev->echostate == ECHO_STATE_STARTTRAINING) {+	// Transmit impulse now+	txchunk[0] = linear2alaw(16384);+	memset(txchunk+1, 0, size-1);+	bchdev_echocancel_setstate(dev, ECHO_STATE_TRAINING); //AWAITINGECHO);+      } else {+	// train the echo cancellation+	for (pos = 0; pos < size; pos++) {+	  rxlin = alaw2linear(rxchunk[pos]);+	  txlin = alaw2linear(txchunk[pos]);+	  if (dev->echostate == ECHO_STATE_PRETRAINING) {+	    if (dev->echotimer <= 0) {+	      dev->echotimer = 0;+	      bchdev_echocancel_setstate(dev, ECHO_STATE_STARTTRAINING);+	    } else {+	      dev->echotimer--;+	    }+	  }+	  if ((dev->echostate == ECHO_STATE_AWAITINGECHO) && (txlin > 8000)) {+	    dev->echolastupdate = 0;+	    bchdev_echocancel_setstate(dev, ECHO_STATE_TRAINING);+	  }+	  if (dev->echostate == ECHO_STATE_TRAINING) {+	    if (echo_can_traintap(dev->ec, dev->echolastupdate++, rxlin)) {+	      bchdev_echocancel_setstate(dev, ECHO_STATE_ACTIVE);+	    }+	  }++	  rxchunk[pos] = linear2alaw(0);+	  txchunk[pos] = linear2alaw(0);+	}+      }+    } else {+      for (pos = 0; pos < size; pos++) {+	rxlin = alaw2linear(rxchunk[pos]);+	txlin = alaw2linear(txchunk[pos]);++	if (echo_can_disable_detector_update(dev->ecdis_rd, rxlin) || +	    echo_can_disable_detector_update(dev->ecdis_wr, txlin)) {+	  bchdev_echocancel_deactivate(dev);+	  printk("EC: Fax detected, EC disabled\n");+	  return ;+	} else	{+	  rxlin = echo_can_update(dev->ec, txlin, rxlin);+	  rxchunk[pos] = linear2alaw(rxlin);+	}+      }+    }+  }+}++/******************************************************/diff -u -r -P /tmp/mISDN/drivers/isdn/hardware/mISDN/dsp_core.c mISDN/drivers/isdn/hardware/mISDN/dsp_core.c--- /tmp/mISDN/drivers/isdn/hardware/mISDN/dsp_core.c	2005-01-29 17:15:21.000000000 +0100+++ mISDN/drivers/isdn/hardware/mISDN/dsp_core.c	2005-12-02 09:57:08.000000000 +0100@@ -42,17 +42,11 @@  *             v             |  *       +-----+-------------+-----+  *       |(3)(4)                   |- *       |                         |- *       |                         |  *       |           CMX           |  *       |                         |- *       |                         |- *       |                         |- *       |                         |  *       |           +-------------+  *       |           |       ^  *       |           |       |- *       |           |       |  *       |+---------+|  +----+----+  *       ||(1)      ||  |(5)      |  *       ||         ||  |         |@@ -62,7 +56,6 @@  *       |+----+----+|  +----+----+  *       +-----+-----+       ^  *             |             | - *             |             |  *             v             |  *        +----+----+   +----+----+  *        |(5)      |   |(2)      |@@ -74,8 +67,18 @@  *             |             ^   *             |             |  *             v             |+ *        +----+-------------+----++ *        |(7)                    |+ *        |                       |+ *        |   Echo Cancellation   |+ *        |                       |+ *        |                       |+ *        +----+-------------+----++ *             |             ^ + *             |             |+ *             v             |  *        +----+----+   +----+----+- *        |(7)      |   |(7)      |+ *        |(8)      |   |(8)      |  *        |         |   |         |  *        | Encrypt |   | Decrypt |  *        |         |   |         |@@ -115,6 +118,13 @@  * data to/form upper layer may be swithed on/off individually without loosing  * features of CMX, Tones and DTMF.  *+ * Echo Cancellation: Sometimes we like to cancel echo from the interface.+ * Note that a VoIP call may not have echo caused by the IP phone. The echo+ * is generated by the telephone line connected to it. Because the delay+ * is high, it becomes an echo. RESULT: Echo Cachelation is required if+ * both echo AND delay is applied to an interface.+ * Remember that software CMX always generates a more or less delay.+ *  * If all used features can be realized in hardware, and if transmit and/or  * receive data ist disabled, the card may not send/receive any data at all.  * Not receiving is usefull if only announcements are played. Not sending is@@ -215,6 +225,9 @@ 			printk(KERN_ERR "%s: failed to create tx packet\n", __FUNCTION__); 			return; 		}+		/* if echo cancellation is enabled */+		if (dsp->cancel_enable)+			dsp_cancel_tx(dsp, nskb->data, nskb->len); 		/* crypt if enabled */ 		if (dsp->bf_enable) 			dsp_bf_encrypt(dsp, nskb->data, nskb->len);@@ -380,6 +393,34 @@ 			if (dsp_debug & DEBUG_DSP_CMX) 				dsp_cmx_debug(dsp); 			break;+		case ECHOCAN_ON: /* turn echo calcellation on */+			+			if (len<4) {+				ret = -EINVAL;+				break;+			}+			int ec_arr[2];+			+			memcpy(&ec_arr,data,sizeof(ec_arr));+			+			+			printk("data[0]: %d data[1]: %d, len :%d\n",ec_arr[0],+			       ec_arr[1] ,len);+			+			if (dsp_debug & DEBUG_DSP_CORE)+				printk(KERN_DEBUG "%s: turn echo cancelation on (delay=%d attenuation-shift=%d\n", __FUNCTION__, ec_arr[0], ec_arr[1]);+			+			ret = dsp_cancel_init(dsp, ec_arr[0], ec_arr[1] ,1);+			+			dsp_cmx_hardware(dsp->conf, dsp);+			break;+		case ECHOCAN_OFF: /* turn echo calcellation off */+			if (dsp_debug & DEBUG_DSP_CORE)+				printk(KERN_DEBUG "%s: turn echo cancelation off\n", __FUNCTION__);+			+			ret = dsp_cancel_init(dsp, 0,0,-1);+			dsp_cmx_hardware(dsp->conf, dsp);+			break; 		case BF_ENABLE_KEY: /* turn blowfish on */ 			if (len<4 || len>56) { 				ret = -EINVAL;@@ -522,6 +563,9 @@ 			/* decrypt if enabled */ 			if (dsp->bf_enable) 				dsp_bf_decrypt(dsp, skb->data, skb->len);+			/* if echo cancellation is enabled */+			if (dsp->cancel_enable)+				dsp_cancel_rx(dsp, skb->data, skb->len); 			/* check if dtmf soft decoding is turned on */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?