Update of /usr/cvsroot/zaptel
In directory mongoose.digium.com:/tmp/cvs-serv19729

Modified Files:
      Tag: v1-0
        zaptel.c zaptel.h 
Log Message:
more stuff for 2nd gen support


Index: zaptel.c
===================================================================
RCS file: /usr/cvsroot/zaptel/zaptel.c,v
retrieving revision 1.95.2.5
retrieving revision 1.95.2.6
diff -u -d -r1.95.2.5 -r1.95.2.6
--- zaptel.c    17 Jan 2005 01:58:09 -0000      1.95.2.5
+++ zaptel.c    15 Jun 2005 21:31:22 -0000      1.95.2.6
@@ -140,6 +140,7 @@
 EXPORT_SYMBOL(zt_alarm_notify);
 EXPORT_SYMBOL(zt_set_dynamic_ioctl);
 EXPORT_SYMBOL(zt_ec_chunk);
+EXPORT_SYMBOL(zt_ec_span);
 
 #ifdef CONFIG_PROC_FS
 static struct proc_dir_entry *proc_entries[ZT_MAX_SPANS]; 
@@ -278,6 +279,8 @@
 
 #include "digits.h"
 
+static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int 
cmd, unsigned long data, int unit);
+
 #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 */
@@ -956,6 +959,11 @@
        memset(chan->conflast1, 0, sizeof(chan->conflast1));
        memset(chan->conflast2, 0, sizeof(chan->conflast2));
 
+       if (chan->span && chan->span->echocan)
+               chan->span->echocan(chan, 0);
+       if (chan->span && chan->span->dacs && oldconf)
+               chan->span->dacs(chan, NULL);
+
        spin_unlock_irqrestore(&chan->lock, flags);
 
        if (rxgain)
@@ -1266,7 +1274,9 @@
 #ifdef LINUX26
        hdlc_close(dev);
 #else
+#ifndef CONFIG_OLD_HDLC_API
        hdlc_close(hdlc);
+#endif
 #endif 
 #ifndef LINUX26
        MOD_DEC_USE_COUNT;
@@ -1559,8 +1569,11 @@
                                (chans[x]->confmode == ZT_CONF_DIGITALMON))) {
                                /* Take them out of conference with us */
                                /* release conference resource if any */
-                               if (chans[x]->confna)
+                               if (chans[x]->confna) {
                                        zt_check_conf(chans[x]->confna);
+                                       if (chans[x]->span && 
chans[x]->span->dacs)
+                                               chans[x]->span->dacs(chans[x], 
NULL);
+                               }
                                chans[x]->confna = 0;
                                chans[x]->_confn = 0;
                                chans[x]->confmode = 0;
@@ -1872,8 +1885,10 @@
                return;
        }
        if (chan->span->hooksig) {
-               chan->txhooksig = txsig;
-               chan->span->hooksig(chan, txsig);
+               if (chan->txhooksig != txsig) {
+                       chan->txhooksig = txsig;
+                       chan->span->hooksig(chan, txsig);
+               }
                chan->otimer = timeout * 8;                     /* Otimer is 
timer in samples */
                return;
        } else {
@@ -1933,8 +1948,13 @@
                        zt_rbs_sethook(chan, ZT_TXSIG_ONHOOK, 
ZT_TXSTATE_ONHOOK, 0);
        } else {
                /* Let the driver hang up the line if it wants to  */
-               if (chan->span->sethook)
-                       res = chan->span->sethook(chan, ZT_ONHOOK);
+               if (chan->span->sethook) {
+                       if (chan->txhooksig != ZT_ONHOOK) {
+                               chan->txhooksig = ZT_ONHOOK;
+                               res = chan->span->sethook(chan, ZT_ONHOOK);
+                       } else
+                               res = 0;
+               }
        }
        /* if not registered yet, just return here */
        if (!(chan->flags & ZT_FLAG_REGISTERED)) return res;
@@ -2037,6 +2057,8 @@
        if ((chan->sig & __ZT_SIG_DACS) != __ZT_SIG_DACS) {
                chan->confna = 0;
                chan->confmode = 0;
+               if (chan->span && chan->span->dacs)
+                       chan->span->dacs(chan, NULL);
        }
        chan->_confn = 0;
        memset(chan->conflast, 0, sizeof(chan->conflast));
@@ -2074,6 +2096,8 @@
                chan->ringcadence[0] = chan->starttime;
                chan->ringcadence[1] = ZT_RINGOFFTIME;
        }
+       if (chan->span && chan->span->echocan)
+               chan->span->echocan(chan, 0);
        spin_unlock_irqrestore(&chan->lock, flags);
 
        if (rxgain)
@@ -2691,6 +2715,7 @@
        }
        return 0;
 }
+
 static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int 
cmd, unsigned long data, int unit)
 {
        union {
@@ -2993,9 +3018,15 @@
        struct zt_chan *newmaster;
        struct zt_dialparams tdp;
        struct zt_maintinfo maint;
+       struct zt_indirect_data ind;
        unsigned long flags;
        int rv;
        switch(cmd) {
+       case ZT_INDIRECT:
+               if (copy_from_user(&ind, (struct zt_indirect_data *)data, 
sizeof(ind)))
+                       return -EFAULT;
+               VALID_CHANNEL(ind.chan);
+               return zt_chan_ioctl(inode, file, ind.op, (unsigned long) 
ind.data, ind.chan);
        case ZT_SPANCONFIG:
                if (copy_from_user(&lc, (struct zt_lineconfig *)data, 
sizeof(lc)))
                        return -EFAULT;
@@ -3127,7 +3158,14 @@
                                /* Setup conference properly */
                                chans[ch.chan]->confmode = ZT_CONF_DIGITALMON;
                                chans[ch.chan]->confna = ch.idlebits;
-                       }
+                               if (chans[ch.chan]->span && 
+                                   chans[ch.chan]->span->dacs && 
+                                       chans[ch.idlebits] && 
+                                       chans[ch.chan]->span && 
+                                       (chans[ch.chan]->span->dacs == 
chans[ch.idlebits]->span->dacs)) 
+                                       
chans[ch.chan]->span->dacs(chans[ch.chan], chans[ch.idlebits]);
+                       } else if (chans[ch.chan]->span && 
chans[ch.chan]->span->dacs)
+                               chans[ch.chan]->span->dacs(chans[ch.chan], 
NULL);
                        chans[ch.chan]->master = newmaster;
                        /* Note new slave if we are not our own master */
                        if (newmaster != chans[ch.chan]) {
@@ -3178,7 +3216,7 @@
                                chans[ch.chan]->hdlcnetdev->netdev.close = 
zt_net_close;
                                chans[ch.chan]->hdlcnetdev->netdev.set_mode = 
NULL;
                                chans[ch.chan]->hdlcnetdev->netdev.xmit = 
zt_xmit;
-#endif
+#endif /* NEW_HDLC_INTERFACE */
                                chans[ch.chan]->hdlcnetdev->netdev.netdev.irq = 
chans[ch.chan]->span->irq;
                                
chans[ch.chan]->hdlcnetdev->netdev.netdev.tx_queue_len = 50;
                                res = 
register_hdlc_device(&chans[ch.chan]->hdlcnetdev->netdev);
@@ -3647,6 +3685,14 @@
                chans[i]->_confn = 0;                /* Clear confn */
                zt_check_conf(j);
                zt_check_conf(stack.conf.confno);
+               if (chans[i]->span && chans[i]->span->dacs) {
+                       if ((stack.conf.confmode == ZT_CONF_DIGITALMON) && 
chans[stack.conf.confno]->span &&
+                                       (chans[stack.conf.confno]->span->dacs 
== chans[i]->span->dacs)) {
+                               chans[i]->span->dacs(chans[i], 
chans[stack.conf.confno]);
+                       } else {
+                               chans[i]->span->dacs(chans[i], NULL);
+                       }
+               }
                /* k will be non-zero if in a real conf */
                k = stack.conf.confmode & (ZT_CONF_CONF | ZT_CONF_CONFANN | 
ZT_CONF_CONFMON | ZT_CONF_CONFANNMON | ZT_CONF_REALANDPSEUDO);
                /* if we are going onto a conf */
@@ -3909,6 +3955,8 @@
                          /* initialize conference variables */
                        chan->_confn = 0;
                        chan->confna = 0;
+                       if (chan->span && chan->span->dacs)
+                               chan->span->dacs(chan, NULL);
                        chan->confmode = 0;
                        chan->confmute = 0;
                        memset(chan->conflast, 0, sizeof(chan->conflast));
@@ -3926,6 +3974,9 @@
                        chan->rxgain = defgain;
                        chan->txgain = defgain;
                        chan->gainalloc = 0;
+                       /* Disable any native echo cancellation as well */
+                       if (chan->span && chan->span->echocan)
+                               chan->span->echocan(chan, 0);
                        spin_unlock_irqrestore(&chan->lock, flags);
 
                        if (rxgain)
@@ -3977,6 +4028,8 @@
                                        chan->gainalloc = 0;
                                        chan->flags &= ~ZT_FLAG_AUDIO;
                                        chan->flags |= (ZT_FLAG_PPP | 
ZT_FLAG_HDLC | ZT_FLAG_FCS);
+                                       if (chan->span && chan->span->echocan)
+                                               chan->span->echocan(chan, 0);
                                        if (tec)
                                                echo_can_free(tec);
                                } else
@@ -4023,27 +4076,38 @@
                        return -EINVAL;
                get_user(j, (int *)data);
                if (j) {
-                       if ((j == 32) ||
-                           (j == 64) ||
-                           (j == 128) ||
-                           (j == 256)) {
-                               /* Okay */
-                       } else {
-                               j = deftaps;
-                       }
-                       ec = echo_can_create(j, 0);
-                       if (!ec)
-                               return -ENOMEM;
                        spin_lock_irqsave(&chan->lock, flags);
                        /* If we had an old echo can, zap it now */
                        tec = chan->ec;
-                       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);
+                       chan->ec = NULL;
+                       /* Attempt hardware native echo can */
+                       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)) {
+                                       /* Okay */
+                               } else {
+                                       j = deftaps;
+                               }
+                               spin_unlock_irqrestore(&chan->lock, flags);
+                               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);
@@ -4055,6 +4119,9 @@
                        chan->echostate = ECHO_STATE_IDLE;
                        chan->echolastupdate = 0;
                        chan->echotimer = 0;
+                       /* Attempt hardware native echo can */
+                       if (chan->span && chan->span->echocan)
+                               chan->span->echocan(chan, 0);
                        spin_unlock_irqrestore(&chan->lock, flags);
                        if (tec)
                                echo_can_free(tec);
@@ -4173,9 +4240,12 @@
                        default:
                                return -EINVAL;
                        }
-               } else if (chan->span->sethook) 
-                       chan->span->sethook(chan, j);
-               else
+               } else if (chan->span->sethook) {
+                       if (chan->txhooksig != j) {
+                               chan->txhooksig = j;
+                               chan->span->sethook(chan, j);
+                       }
+               } else
                        return -ENOSYS;
                break;
 #ifdef CONFIG_ZAPATA_PPP
@@ -4589,6 +4659,8 @@
                        /* Do nuffin */
                        break;
                case ZT_CONF_MONITOR:   /* Monitor a channel's rx mode */
+                         /* if a pseudo-channel, ignore */
+                       if (ms->flags & ZT_FLAG_PSEUDO) break;
                        /* Add monitored channel */
                        if (chans[ms->confna]->flags & ZT_FLAG_PSEUDO) {
                                ACSS(getlin, chans[ms->confna]->getlin);
@@ -4599,6 +4671,8 @@
                                txb[x] = ZT_LIN2X(getlin[x], ms);
                        break;
                case ZT_CONF_MONITORTX: /* Monitor a channel's tx mode */
+                         /* if a pseudo-channel, ignore */
+                       if (ms->flags & ZT_FLAG_PSEUDO) break;
                        /* Add monitored channel */
                        if (chans[ms->confna]->flags & ZT_FLAG_PSEUDO) {
                                ACSS(getlin, chans[ms->confna]->putlin);
@@ -4610,6 +4684,8 @@
                                txb[x] = ZT_LIN2X(getlin[x], ms);
                        break;
                case ZT_CONF_MONITORBOTH: /* monitor a channel's rx and tx mode 
*/
+                         /* if a pseudo-channel, ignore */
+                       if (ms->flags & ZT_FLAG_PSEUDO) break;
                        ACSS(getlin, chans[ms->confna]->putlin);
                        ACSS(getlin, chans[ms->confna]->getlin);
                        for (x=0;x<ZT_CHUNKSIZE;x++)
@@ -4894,6 +4970,15 @@
                __qevent(chan,ZT_EVENT_ONHOOK);
                chan->gotgs = 0; 
                break;
+#ifdef EMFLASH
+           case ZT_SIG_EM:
+           case ZT_SIG_EM_E1:
+               if (chan->rxhooksig == ZT_RXSIG_ONHOOK) {
+                       __qevent(chan,ZT_EVENT_ONHOOK); 
+                       break;
+               }
+               /* intentionally fall thru */
+#endif
            default:  /* otherwise, its definitely off hook */
                __qevent(chan,ZT_EVENT_RINGOFFHOOK); 
                break;
@@ -5050,6 +5135,14 @@
                switch(rxsig) {
                    case ZT_RXSIG_OFFHOOK: /* went off hook */
                        /* The interface is going off hook */
+#ifdef EMFLASH
+                       if (chan->itimer)
+                       {
+                               __qevent(chan,ZT_EVENT_WINKFLASH); 
+                               chan->itimerset = chan->itimer = 0;
+                               break;                          
+                       }
+#endif
                        /* set wink timer */
                        chan->itimerset = chan->itimer = chan->rxwinktime * 8;
                        break;
@@ -5058,10 +5151,18 @@
                           Check for WINK, etc */
                        if (chan->itimer)
                                __qevent(chan,ZT_EVENT_WINKFLASH); 
+#ifdef EMFLASH
+                       else {
+                               chan->itimerset = chan->itimer = 
chan->rxflashtime * 8;
+                               chan->gotgs = 0;
+                               break;                          
+                       }
+#else
                        else {
                                __qevent(chan,ZT_EVENT_ONHOOK); 
                                chan->gotgs = 0;
                        }
+#endif
                        chan->itimerset = chan->itimer = 0;
                        break;
                    default:
@@ -5211,7 +5312,7 @@
        spin_unlock_irqrestore(&chan->lock, flags);
 }
 
-void zt_ec_chunk(struct zt_chan *ss, unsigned char *rxchunk, const unsigned 
char *txchunk)
+static inline void __zt_ec_chunk(struct zt_chan *ss, unsigned char *rxchunk, 
const unsigned char *txchunk)
 {
        short rxlin, txlin;
        int x;
@@ -5262,6 +5363,20 @@
        spin_unlock_irqrestore(&ss->lock, flags);
 }
 
+void zt_ec_chunk(struct zt_chan *ss, unsigned char *rxchunk, const unsigned 
char *txchunk)
+{
+       __zt_ec_chunk(ss, rxchunk, txchunk);
+}
+
+void zt_ec_span(struct zt_span *span)
+{
+       int x;
+       for (x = 0; x < span->channels; x++) {
+               if (span->chans[x].ec)
+                       __zt_ec_chunk(&span->chans[x], 
span->chans[x].readchunk, span->chans[x].writechunk);
+       }
+}
+
 /* return 0 if nothing detected, 1 if lack of tone, 2 if presence of tone */
 /* modifies buffer pointed to by 'amp' with notched-out values */
 static inline int sf_detect (sf_detect_state_t *s,

Index: zaptel.h
===================================================================
RCS file: /usr/cvsroot/zaptel/zaptel.h,v
retrieving revision 1.38
retrieving revision 1.38.2.1
diff -u -d -r1.38 -r1.38.2.1
--- zaptel.h    27 Sep 2004 19:50:03 -0000      1.38
+++ zaptel.h    15 Jun 2005 21:31:22 -0000      1.38.2.1
@@ -304,6 +304,14 @@
 } ZT_DIAL_OPERATION;
 
 
+typedef struct zt_indirect_data
+{
+int    chan;
+int    op;
+void   *data;
+} ZT_INDIRECT_DATA;    
+
+
 /* ioctl definitions */
 #define ZT_CODE        'J'
 
@@ -590,6 +598,12 @@
 #define ZT_GETSIGFREEZE _IOR (ZT_CODE, 55, int)
 
 /*
+ * Do a channel IOCTL from the /dev/zap/ctl interface
+ */
+#define ZT_INDIRECT _IOWR (ZT_CODE, 56, struct zt_indirect_data)
+
+
+/*
  *  60-80 are reserved for private drivers
  *  80-85 are reserved for dynamic span stuff
  */
@@ -604,6 +618,12 @@
  */
 #define ZT_DYNAMIC_DESTROY     _IOW (ZT_CODE, 81, struct zt_dynamic_span)
 
+/*
+ * Enable tone detection -- implemented by low level driver
+ */
+#define ZT_TONEDETECT _IOW (ZT_CODE, 91, int)
+
+
 /* 
  * Startup or Shutdown a span
  */
@@ -630,6 +650,9 @@
 
 #define ZT_MAX_CADENCE         16
 
+#define ZT_TONEDETECT_ON       (1 << 0)                /* Detect tones */
+#define ZT_TONEDETECT_MUTE     (1 << 1)                /* Mute audio in 
received channel */
+
 struct zt_ring_cadence {
        int ringcadence [ZT_MAX_CADENCE];
 };
@@ -778,7 +801,8 @@
 #define ZT_EVENT_POLARITY  17
 
 #define ZT_EVENT_PULSEDIGIT (1 << 16)  /* This is OR'd with the digit received 
*/
-#define ZT_EVENT_DTMFDIGIT  (1 << 17)  /* Ditto for DTMF */
+#define ZT_EVENT_DTMFDOWN  (1 << 17)   /* Ditto for DTMF key down event */
+#define ZT_EVENT_DTMFUP (1 << 18)      /* Ditto for DTMF key up event */
 
 /* Flag Value for IOMUX, read avail */
 #define        ZT_IOMUX_READ   1
@@ -849,7 +873,7 @@
 #define        ZT_DEFAULT_PULSEAFTERTIME 750   /* 750ms between dial pulse 
digits */
 
 #define        ZT_MINPULSETIME (15 * 8)        /* 15 ms minimum */
-#define        ZT_MAXPULSETIME (150 * 8)       /* 150 ms maximum */
+#define        ZT_MAXPULSETIME (200 * 8)       /* 200 ms maximum */
 #define        ZT_PULSETIMEOUT ((ZT_MAXPULSETIME / 8) + 50)
 
 #define ZT_RINGTRAILER (50 * 8)        /* Don't consider a ring "over" until 
it's been gone at least this
@@ -1228,6 +1252,9 @@
        /* Opt: IOCTL */
        int (*ioctl)(struct zt_chan *chan, unsigned int cmd, unsigned long 
data);
        
+       /* Opt: Native echo cancellation */
+       int (*echocan)(struct zt_chan *chan, int ecval);
+
        /* Okay, now we get to the signalling.  You have several options: */
 
        /* Option 1: If you're a T1 like interface, you can just provide a
@@ -1247,6 +1274,9 @@
        /* Option 3: If you can't use sig bits, you can write a function
           which handles the individual hook states  */
        int (*sethook)(struct zt_chan *chan, int hookstate);
+       
+       /* Opt: Dacs the contents of chan2 into chan1 if possible */
+       int (*dacs)(struct zt_chan *chan1, struct zt_chan *chan2);
 
        /* Used by zaptel only -- no user servicable parts inside */
        int spanno;                     /* Span number for zaptel */
@@ -1350,6 +1380,7 @@
    not be doing so.  rxchunk is modified in-place */
 
 extern void zt_ec_chunk(struct zt_chan *chan, unsigned char *rxchunk, const 
unsigned char *txchunk);
+extern void zt_ec_span(struct zt_span *span);
 
 /* Don't use these directly -- they're not guaranteed to
    be there. */

_______________________________________________
Asterisk-Cvs mailing list
[email protected]
http://lists.digium.com/mailman/listinfo/asterisk-cvs

Reply via email to