summaryrefslogtreecommitdiff
path: root/zaptel.c
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2003-04-28 21:59:58 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2003-04-28 21:59:58 +0000
commitf8b80a621c18200bc8c5eed436d5d90ac429e2d8 (patch)
tree119f8cd4df269844eaa70c370d22f5193747b435 /zaptel.c
parent1ee245c959a4af5f48691ebaf5c424cc891e24f8 (diff)
Clear out audio stuff when changing between audio and data modes
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@173 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'zaptel.c')
-rwxr-xr-xzaptel.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/zaptel.c b/zaptel.c
index c0cacf3..64df71e 100755
--- a/zaptel.c
+++ b/zaptel.c
@@ -3145,6 +3145,11 @@ static int zt_chanandpseudo_ioctl(struct inode *inode, struct file *file, unsign
get_user(j,(int *)data); /* get conf # */
chan->confmute = j;
break;
+ case ZT_GETCONFMUTE: /* get confmute flag */
+ if (!(chan->flags & ZT_FLAG_AUDIO)) return (-EINVAL);
+ j = chan->confmute;
+ put_user(j,(int *)data); /* get conf # */
+ break;
case ZT_SETTONEZONE:
get_user(j,(int *)data);
spin_lock_irqsave(&chan->lock, flags);
@@ -3413,6 +3418,8 @@ static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cm
unsigned long flags;
int j, rv;
int ret;
+ int oldconf;
+ void *rxgain;
echo_can_state_t *ec, *tec;
if (!chan)
@@ -3424,10 +3431,44 @@ static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cm
if (chan->sig != ZT_SIG_CLEAR) return (-EINVAL);
get_user(j, (int *)data);
if (j) {
+ spin_lock_irqsave(&chan->lock, flags);
chan->flags |= ZT_FLAG_AUDIO;
chan->flags &= ~(ZT_FLAG_HDLC | ZT_FLAG_FCS);
+ spin_unlock_irqrestore(&chan->lock, flags);
} else {
+ /* Coming out of audio mode, also clear all
+ conferencing and gain related info as well
+ as echo canceller */
+ spin_lock_irqsave(&chan->lock, flags);
chan->flags &= ~ZT_FLAG_AUDIO;
+ /* save old conf number, if any */
+ oldconf = chan->confna;
+ /* initialize conference variables */
+ chan->_confn = 0;
+ chan->confna = 0;
+ chan->confmode = 0;
+ chan->confmute = 0;
+ memset(chan->conflast, 0, sizeof(chan->conflast));
+ memset(chan->conflast1, 0, sizeof(chan->conflast1));
+ memset(chan->conflast2, 0, sizeof(chan->conflast2));
+ ec = chan->ec;
+ chan->ec = NULL;
+ /* release conference resource, if any to release */
+ reset_conf(chan);
+ if (chan->gainalloc && chan->rxgain)
+ rxgain = chan->rxgain;
+ else
+ rxgain = NULL;
+
+ chan->rxgain = defgain;
+ chan->txgain = defgain;
+ spin_unlock_irqrestore(&chan->lock, flags);
+
+ if (rxgain)
+ kfree(rxgain);
+ if (ec)
+ echo_can_free(ec);
+ if (oldconf) zt_check_conf(oldconf);
}
break;
case ZT_HDLCPPP: