[svn-commits] rmeyerriecks: linux/trunk r9491 - in /linux/trunk: drivers/dahdi/ include/dahdi/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Nov 19 11:34:31 CST 2010


Author: rmeyerriecks
Date: Fri Nov 19 11:34:25 2010
New Revision: 9491

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=9491
Log:
dahdi: adding ss7 pcap support to dahdi.

Adding the patch from the issue with various fixups to fit style and
checkpatch

(issue #16831)
Reported by: tsearle
Patches:
      driver_v2.patch uploaded by tsearle (license 373)
Signed-off-by: Russ Meyerriecks <rmeyerriecks at digium.com>
Acked-by: Shaun Ruffell <sruffell at digium.com>

Modified:
    linux/trunk/drivers/dahdi/dahdi-base.c
    linux/trunk/include/dahdi/kernel.h
    linux/trunk/include/dahdi/user.h

Modified: linux/trunk/drivers/dahdi/dahdi-base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/dahdi-base.c?view=diff&rev=9491&r1=9490&r2=9491
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi-base.c (original)
+++ linux/trunk/drivers/dahdi/dahdi-base.c Fri Nov 19 11:34:25 2010
@@ -2801,9 +2801,32 @@
 	if (chan) {
 		/* Chan lock protects contents against potentially non atomic accesses.
 		 * So if the pointer setting is not atomic, we should protect */
+		if (chan->srcmirror) {
+			struct dahdi_chan *const srcmirror = chan->srcmirror;
+			spin_lock_irqsave(&srcmirror->lock, flags);
+			if (chan == srcmirror->txmirror) {
+				module_printk(KERN_INFO, "Chan %d tx mirror " \
+					      "to %d stopped\n",
+					      srcmirror->txmirror->channo,
+					      srcmirror->channo);
+				srcmirror->txmirror = NULL;
+			}
+
+			if (chan == srcmirror->rxmirror) {
+				module_printk(KERN_INFO, "Chan %d rx mirror " \
+					      "to %d stopped\n",
+					      srcmirror->rxmirror->channo,
+					      srcmirror->channo);
+				chan->srcmirror->rxmirror = NULL;
+			}
+			spin_unlock_irqrestore(&chan->srcmirror->lock, flags);
+		}
+
 		spin_lock_irqsave(&chan->lock, flags);
 		chan->file = NULL;
 		file->private_data = NULL;
+		chan->srcmirror = NULL;
+
 		spin_unlock_irqrestore(&chan->lock, flags);
 		close_channel(chan);
 		clear_bit(DAHDI_FLAGBIT_OPEN, &chan->flags);
@@ -5019,6 +5042,93 @@
 	return ret;
 }
 
+static int dahdi_ioctl_rxmirror(struct file *file, unsigned long data)
+{
+	int res;
+	int i;
+	unsigned long flags;
+	struct dahdi_chan *const chan = chan_from_file(file);
+	struct dahdi_chan *srcmirror;
+
+	if (!chan || chan->srcmirror)
+		return -ENODEV;
+
+	res = get_user(i, (int __user *)data);
+	if (res)
+		return res;
+
+	srcmirror = chan_from_num(i);
+	if (!srcmirror)
+		return -EINVAL;
+
+	module_printk(KERN_INFO, "Chan %d rx mirrored to %d\n",
+		      srcmirror->channo, chan->channo);
+
+	spin_lock_irqsave(&srcmirror->lock, flags);
+	if (srcmirror->rxmirror == NULL)
+		srcmirror->rxmirror = chan;
+
+	spin_unlock_irqrestore(&srcmirror->lock, flags);
+	if (srcmirror->rxmirror != chan) {
+		module_printk(KERN_INFO, "Chan %d cannot be rxmirrored, " \
+			      "already in use\n", srcmirror->channo);
+		return -EFAULT;
+	}
+
+	spin_lock_irqsave(&chan->lock, flags);
+	chan->srcmirror = srcmirror;
+	chan->flags = srcmirror->flags;
+	chan->sig =  srcmirror->sig;
+	clear_bit(DAHDI_FLAGBIT_OPEN, &chan->flags);
+	spin_unlock_irqrestore(&chan->lock, flags);
+
+	return 0;
+}
+
+static int dahdi_ioctl_txmirror(struct file *file, unsigned long data)
+{
+	int res;
+	int i;
+	unsigned long flags;
+	struct dahdi_chan *const chan = chan_from_file(file);
+	struct dahdi_chan *srcmirror;
+
+	if (!chan || chan->srcmirror)
+		return -ENODEV;
+
+	res = get_user(i, (int __user *)data);
+	if (res)
+		return res;
+
+	srcmirror = chan_from_num(i);
+	if (!srcmirror)
+		return -EINVAL;
+
+	module_printk(KERN_INFO, "Chan %d tx mirrored to %d\n",
+		      srcmirror->channo, chan->channo);
+
+	spin_lock_irqsave(&srcmirror->lock, flags);
+	srcmirror->txmirror = chan;
+	if (srcmirror->txmirror == NULL)
+		srcmirror->txmirror = chan;
+	spin_unlock_irqrestore(&srcmirror->lock, flags);
+
+	if (srcmirror->txmirror != chan) {
+		module_printk(KERN_INFO, "Chan %d cannot be txmirrored, " \
+			      "already in use\n", i);
+		return -EFAULT;
+	}
+
+	spin_lock_irqsave(&chan->lock, flags);
+	chan->srcmirror = srcmirror;
+	chan->flags = srcmirror->flags;
+	chan->sig =  srcmirror->sig;
+	clear_bit(DAHDI_FLAGBIT_OPEN, &chan->flags);
+	spin_unlock_irqrestore(&chan->lock, flags);
+
+	return 0;
+}
+
 static int
 dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd,
 			  unsigned long data)
@@ -5035,6 +5145,12 @@
 	if (!chan)
 		return -EINVAL;
 	switch(cmd) {
+	case DAHDI_RXMIRROR:
+		return dahdi_ioctl_rxmirror(file, data);
+
+	case DAHDI_TXMIRROR:
+		return dahdi_ioctl_txmirror(file, data);
+
 	case DAHDI_DIALING:
 		spin_lock_irqsave(&chan->lock, flags);
 		j = chan->dialing;
@@ -6545,8 +6661,15 @@
 		txb[x] = ms->txgain[txb[x]];
 }
 
+static void __putbuf_chunk(struct dahdi_chan *ss, unsigned char *rxb,
+			   int bytes);
+
 static inline void __dahdi_getbuf_chunk(struct dahdi_chan *ss, unsigned char *txb)
 {
+
+
+	unsigned char *orig_txb = txb;
+
 	/* Called with ss->lock held */
 	/* We transmit data from our master channel */
 	struct dahdi_chan *ms = ss->master;
@@ -6707,6 +6830,12 @@
 			memset(txb, DAHDI_LIN2X(0, ms), bytes);	/* Lastly we use silence on telephony channels */
 			bytes = 0;
 		}
+	}
+
+	if (ss->txmirror) {
+		spin_lock(&ss->txmirror->lock);
+		__putbuf_chunk(ss->txmirror, orig_txb, DAHDI_CHUNKSIZE);
+		spin_unlock(&ss->txmirror->lock);
 	}
 }
 
@@ -7590,7 +7719,7 @@
 }
 
 /* HDLC (or other) receiver buffer functions for read side */
-static inline void __putbuf_chunk(struct dahdi_chan *ss, unsigned char *rxb, int bytes)
+static void __putbuf_chunk(struct dahdi_chan *ss, unsigned char *rxb, int bytes)
 {
 	/* We transmit data from our master channel */
 	/* Called with ss->lock held */
@@ -7606,7 +7735,6 @@
 	int abort=0;
 	int res;
 	int left, x;
-
 
 	while(bytes) {
 #if defined(CONFIG_DAHDI_NET)  || defined(CONFIG_DAHDI_PPP)
@@ -7877,11 +8005,18 @@
 		}
 #endif
 	}
+
 }
 
 static inline void __dahdi_putbuf_chunk(struct dahdi_chan *ss, unsigned char *rxb)
 {
 	__putbuf_chunk(ss, rxb, DAHDI_CHUNKSIZE);
+
+	if (ss->rxmirror) {
+		spin_lock(&ss->rxmirror->lock);
+		__putbuf_chunk(ss->rxmirror, rxb, DAHDI_CHUNKSIZE);
+		spin_unlock(&ss->rxmirror->lock);
+	}
 }
 
 static void __dahdi_hdlc_abort(struct dahdi_chan *ss, int event)

Modified: linux/trunk/include/dahdi/kernel.h
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/include/dahdi/kernel.h?view=diff&rev=9491&r1=9490&r2=9491
==============================================================================
--- linux/trunk/include/dahdi/kernel.h (original)
+++ linux/trunk/include/dahdi/kernel.h Fri Nov 19 11:34:25 2010
@@ -444,6 +444,9 @@
 	struct file *file;	/*!< File structure */
 	
 	
+	struct dahdi_chan	*rxmirror;  /*!< channel we mirror reads to */
+	struct dahdi_chan	*txmirror;  /*!< channel we mirror writes to */
+	struct dahdi_chan	*srcmirror; /*!< channel we mirror from */
 	struct dahdi_span	*span;			/*!< Span we're a member of */
 	int		sig;			/*!< Signalling */
 	int		sigcap;			/*!< Capability for signalling */

Modified: linux/trunk/include/dahdi/user.h
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/include/dahdi/user.h?view=diff&rev=9491&r1=9490&r2=9491
==============================================================================
--- linux/trunk/include/dahdi/user.h (original)
+++ linux/trunk/include/dahdi/user.h Fri Nov 19 11:34:25 2010
@@ -1076,6 +1076,12 @@
 
 #define DAHDI_ECHOCANCEL_FAX_MODE	_IOW(DAHDI_CODE, 102, int)
 
+/*
+ * Defines which channel to receive mirrored traffic from
+ */
+#define DAHDI_RXMIRROR			_IOW(DAHDI_CODE, 103, int)
+#define DAHDI_TXMIRROR			_IOW(DAHDI_CODE, 104, int)
+
 /* Get current status IOCTL */
 /* Defines for Radio Status (dahdi_radio_stat.radstat) bits */
 




More information about the svn-commits mailing list