[svn-commits] kpfleming: branch kpfleming/echocanparams r3507 - /team/kpfleming/echocanparams/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Dec 18 09:35:19 CST 2007


Author: kpfleming
Date: Tue Dec 18 09:35:19 2007
New Revision: 3507

URL: http://svn.digium.com/view/zaptel?view=rev&rev=3507
Log:
initial work to enhance echocan interface so that parameters can be supplied when channels are turned on

Added:
    team/kpfleming/echocanparams/
      - copied from r3505, branches/1.4/
Modified:
    team/kpfleming/echocanparams/zaptel-base.c
    team/kpfleming/echocanparams/zaptel.h

Modified: team/kpfleming/echocanparams/zaptel-base.c
URL: http://svn.digium.com/view/zaptel/team/kpfleming/echocanparams/zaptel-base.c?view=diff&rev=3507&r1=3505&r2=3507
==============================================================================
--- team/kpfleming/echocanparams/zaptel-base.c (original)
+++ team/kpfleming/echocanparams/zaptel-base.c Tue Dec 18 09:35:19 2007
@@ -4308,6 +4308,92 @@
 }
 #endif
 
+static int ioctl_echocancel(struct zt_chan *chan, struct zt_echocanparams *ecp, void *data)
+{
+	struct echo_can_state *ec, *tec;
+	int ret;
+	unsigned long flags;
+
+	if (ecp->param_count > 8)
+		return -EINVAL;
+
+	if (ecp->tap_length == 0) {
+		/* disable mode, don't need to inspect params */
+		spin_lock_irqsave(&chan->lock, flags);
+		tec = chan->ec;
+		chan->echocancel = 0;
+		chan->ec = NULL;
+		chan->echostate = ECHO_STATE_IDLE;
+		chan->echolastupdate = 0;
+		chan->echotimer = 0;
+		spin_unlock_irqrestore(&chan->lock, flags);
+		if (chan->span && chan->span->echocan)
+			chan->span->echocan(chan, 0);
+		if (tec)
+			echo_can_free(tec);
+
+		return 0;
+	}
+
+	/* if parameters were supplied and this channel's span provides an echocan,
+	   but not one that takes params, then we must punt here and return an error */
+	if (ecp->param_count && chan->span && chan->span->echocan &&
+	    !chan->span->echocan_with_params)
+		return -EINVAL;
+	
+	/* enable mode, need the params */
+	struct zt_echocanparam params[ecp->param_count];
+	
+	if (copy_from_user(params, (struct zt_echocanparam *) data, sizeof(params)))
+		return -EFAULT;
+	
+	spin_lock_irqsave(&chan->lock, flags);
+	tec = chan->ec;
+	chan->ec = NULL;
+	spin_unlock_irqrestore(&chan->lock, flags);
+	
+	ret = -ENOTTY;
+	
+	/* attempt to use the span's echo canceler; fall back to built-in
+	   if it fails (but not if an error occurs) */
+	if (chan->span && chan->span->echocan_with_params)
+		ret = chan->span->echocan_with_params(chan, ecp, params);
+	
+	if (ret == -ENOTTY) {
+		switch (ecp->tap_length) {
+		case 32:
+		case 64:
+		case 128:
+		case 256:
+		case 512:
+		case 1024:
+			break;
+		default:
+			ecp->tap_length = deftaps;
+		}
+		
+		if (!(ec = echo_can_create(ecp, params))) {
+			if (tec)
+				echo_can_free(tec);
+			return -ENOMEM;
+		}
+		
+		spin_lock_irqsave(&chan->lock, flags);
+		chan->echocancel = ecp->tap_length;
+		chan->ec = ec;
+		chan->echostate = ECHO_STATE_IDLE;
+		chan->echolastupdate = 0;
+		chan->echotimer = 0;
+		echo_can_disable_detector_init(&chan->txecdis);
+		echo_can_disable_detector_init(&chan->rxecdis);
+		spin_unlock_irqrestore(&chan->lock, flags);
+	}
+	if (tec)
+		echo_can_free(tec);
+
+	return 0;
+}
+
 static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit)
 {
 	struct zt_chan *chan = chans[unit];
@@ -4317,6 +4403,7 @@
 	int oldconf;
 	void *rxgain=NULL;
 	struct echo_can_state *ec, *tec;
+	struct zt_echocanparams ecp;
 
 	if (!chan)
 		return -ENOSYS;
@@ -4481,62 +4568,20 @@
 	case ZT_ECHOCANCEL:
 		if (!(chan->flags & ZT_FLAG_AUDIO))
 			return -EINVAL;
-		get_user(j, (int *)data);
-		if (j) {
-			spin_lock_irqsave(&chan->lock, flags);
-			/* If we had an old echo can, zap it now */
-			tec = chan->ec;
-			chan->ec = NULL;
-			/* Attempt hardware native echo can */
-			spin_unlock_irqrestore(&chan->lock, flags);
-
-			if (chan->span && chan->span->echocan)
-				ret = chan->span->echocan(chan, j);
-			else
-				ret = -ENOTTY;
-
-			if (ret) {
-				/* Use built-in echo can */
-				if ((j == 32) ||
-				    (j == 64) ||
-				    (j == 128) ||
-				    (j == 256) ||
-				    (j == 512) ||
-				    (j == 1024)) {
-					/* Okay */
-				} else {
-					j = deftaps;
-				}
-				ec = echo_can_create(j, 0);
-				if (!ec)
-					return -ENOMEM;
-				spin_lock_irqsave(&chan->lock, flags);
-				chan->echocancel = j;
-				chan->ec = ec;
-				chan->echostate = ECHO_STATE_IDLE;
-				chan->echolastupdate = 0;
-				chan->echotimer = 0;
-				echo_can_disable_detector_init(&chan->txecdis);
-				echo_can_disable_detector_init(&chan->rxecdis);
-				spin_unlock_irqrestore(&chan->lock, flags);
-			}
-			if (tec)
-				echo_can_free(tec);
-		} else {
-			spin_lock_irqsave(&chan->lock, flags);
-			tec = chan->ec;
-			chan->echocancel = 0;
-			chan->ec = NULL;
-			chan->echostate = ECHO_STATE_IDLE;
-			chan->echolastupdate = 0;
-			chan->echotimer = 0;
-			spin_unlock_irqrestore(&chan->lock, flags);
-			/* Attempt hardware native echo can */
-			if (chan->span && chan->span->echocan)
-				chan->span->echocan(chan, 0);
-			if (tec)
-				echo_can_free(tec);
-		}
+		if (copy_from_user(&ecp, (struct zt_echocanparams *) data, sizeof(ecp)))
+			return -EFAULT;
+		data += sizeof(ecp);
+		if ((ret = ioctl_echocancel(chan, &ecp, (void *) data)))
+			return ret;
+		break;
+	case ZT_ECHOCANCEL_V1:
+		if (!(chan->flags & ZT_FLAG_AUDIO))
+			return -EINVAL;
+		get_user(j, (int *) data);
+		ecp.tap_length = j;
+		ecp.param_count = 0;
+		if ((ret = ioctl_echocancel(chan, &ecp, (void *) data)))
+			return ret;
 		break;
 	case ZT_ECHOTRAIN:
 		get_user(j, (int *)data); /* get pre-training time from user */

Modified: team/kpfleming/echocanparams/zaptel.h
URL: http://svn.digium.com/view/zaptel/team/kpfleming/echocanparams/zaptel.h?view=diff&rev=3507&r1=3505&r2=3507
==============================================================================
--- team/kpfleming/echocanparams/zaptel.h (original)
+++ team/kpfleming/echocanparams/zaptel.h Tue Dec 18 09:35:19 2007
@@ -560,11 +560,18 @@
 
 /*
  * Enable or disable echo cancellation on a channel 
+ *
+ * For ECHOCANCEL_V1:
  * The number is zero to disable echo cancellation and non-zero
  * to enable echo cancellation.  If the number is between 32
- * and 256, it will also set the number of taps in the echo canceller
- */
-#define ZT_ECHOCANCEL		_IOW (ZT_CODE, 33, int)
+ * and 1024, it will also set the number of taps in the echo canceller
+ *
+ * For ECHOCANCEL:
+ * The structure contains parameters that should be passed to the
+ * echo canceler instance for the selected channel.
+ */
+#define ZT_ECHOCANCEL_V1	_IOW (ZT_CODE, 33, int)
+#define ZT_ECHOCANCEL		_IOW (ZT_CODE, 33, struct zt_echocanparams)
 
 /*
  * Return a channel's channel number (useful for the /dev/zap/pseudo type interfaces 
@@ -866,6 +873,17 @@
 
 struct zt_ring_cadence {
 	int ringcadence[ZT_MAX_CADENCE];
+};
+
+struct zt_echocanparam {
+	char name[8];
+	unsigned int value;
+};
+
+struct zt_echocanparams {
+	unsigned int tap_length;		/* 8 taps per millisecond */
+	unsigned int param_count;		/* number of parameters supplied */
+	/* immediately follow this structure with zt_echocanparam structures */
 };
 
 struct zt_tone_def_header {
@@ -1165,7 +1183,7 @@
 void echo_can_init(void);
 void echo_chan_shutdown(void);
 void echo_can_identify(char *buf, size_t len);
-struct echo_can_state *echo_can_create(int len, int adaption_mode);
+struct echo_can_state *echo_can_create(struct zt_echocanparams *ecp, struct zt_echocanparam *p);
 void echo_can_free(struct echo_can_state *ec);
 short echo_can_update(struct echo_can_state *ec, short iref, short isig);
 void echo_can_array_update(struct echo_can_state *ec, short *iref, short *isig);
@@ -1514,8 +1532,10 @@
 	/* Opt: IOCTL */
 	int (*ioctl)(struct zt_chan *chan, unsigned int cmd, unsigned long data);
 	
-	/* Opt: Native echo cancellation */
+	/* Opt: Native echo cancellation (simple) */
 	int (*echocan)(struct zt_chan *chan, int ecval);
+
+	int (*echocan_with_params)(struct zt_chan *chan, struct zt_echocanparams *ecp, struct zt_echocanparam *p);
 
 	/* Okay, now we get to the signalling.  You have several options: */
 




More information about the svn-commits mailing list