summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zaptel.c16
-rw-r--r--zaptel.h9
2 files changed, 23 insertions, 2 deletions
diff --git a/zaptel.c b/zaptel.c
index c9e5b76..809d660 100644
--- a/zaptel.c
+++ b/zaptel.c
@@ -1031,7 +1031,7 @@ static void close_channel(struct zt_chan *chan)
chan->txgain = defgain;
chan->gainalloc = 0;
chan->eventinidx = chan->eventoutidx = 0;
- chan->flags &= ~(ZT_FLAG_LINEAR | ZT_FLAG_PPP | ZT_FLAG_SIGFREEZE);
+ chan->flags &= ~(ZT_FLAG_LOOPED | ZT_FLAG_LINEAR | ZT_FLAG_PPP | ZT_FLAG_SIGFREEZE);
zt_set_law(chan,0);
@@ -4371,6 +4371,16 @@ static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cm
put_user(chan->rxsig, (int *)data);
rv = 0;
break;
+ case ZT_LOOPBACK:
+ get_user(j, (int *)data);
+ spin_lock_irqsave(&chan->lock, flags);
+ if (j)
+ chan->flags |= ZT_FLAG_LOOPED;
+ else
+ chan->flags &= ~ZT_FLAG_LOOPED;
+ spin_unlock_irqrestore(&chan->lock, flags);
+ rv = 0;
+ break;
case ZT_HOOK:
get_user(j,(int *)data);
if (chan->flags & ZT_FLAG_CLEAR)
@@ -5163,6 +5173,10 @@ out in the later versions, and is put back now. */
zt_init_tone_state(&ms->ts, ms->curtone);
}
}
+ } else if (ms->flags & ZT_FLAG_LOOPED) {
+ for (x = 0; x < bytes; x++)
+ txb[x] = ms->readchunk[x];
+ bytes = 0;
} else if (ms->flags & ZT_FLAG_HDLC) {
for (x=0;x<bytes;x++) {
/* Okay, if we're HDLC, then transmit a flag by default */
diff --git a/zaptel.h b/zaptel.h
index 1c034b9..22679d2 100644
--- a/zaptel.h
+++ b/zaptel.h
@@ -614,6 +614,12 @@ struct zt_versioninfo {
#define ZT_GETVERSION _IOR(ZT_CODE, 57, struct zt_versioninfo)
/*
+ * Put the channel in loopback mode (receive from the channel is
+ * transmitted back on the interface)
+ */
+#define ZT_LOOPBACK _IOW(ZT_CODE, 58, int)
+
+/*
* 60-80 are reserved for private drivers
* 80-85 are reserved for dynamic span stuff
*/
@@ -1070,7 +1076,7 @@ struct zt_chan {
u_char swritechunk[ZT_MAX_CHUNKSIZE]; /* Buffer to be written */
u_char *readchunk; /* Actual place to read from */
u_char sreadchunk[ZT_MAX_CHUNKSIZE]; /* Preallocated static area */
-
+
/* Pointer to tx and rx gain tables */
u_char *rxgain;
u_char *txgain;
@@ -1281,6 +1287,7 @@ typedef enum {
#define ZT_FLAG_T1PPP (1 << 15)
#define ZT_FLAG_SIGFREEZE (1 << 16) /* Freeze signalling */
#define ZT_FLAG_NOSTDTXRX (1 << 17) /* Do NOT do standard transmit and receive on every interrupt */
+#define ZT_FLAG_LOOPED (1 << 18) /* Loopback the receive data from the channel to the transmit */
struct zt_span {
spinlock_t lock;