From f06574ef3bfd9f51cef6a61d000ff4249993b4fa Mon Sep 17 00:00:00 2001 From: jim Date: Sat, 11 Sep 2004 15:48:45 +0000 Subject: Added outbound pulse dialing git-svn-id: http://svn.digium.com/svn/zaptel/trunk@457 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- zaptel.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 76 insertions(+), 8 deletions(-) (limited to 'zaptel.c') diff --git a/zaptel.c b/zaptel.c index d656492..c3088d7 100755 --- a/zaptel.c +++ b/zaptel.c @@ -203,7 +203,9 @@ typedef enum {ZT_TXSTATE_ONHOOK,ZT_TXSTATE_OFFHOOK,ZT_TXSTATE_START, ZT_TXSTATE_PREWINK,ZT_TXSTATE_WINK,ZT_TXSTATE_PREFLASH, ZT_TXSTATE_FLASH,ZT_TXSTATE_DEBOUNCE,ZT_TXSTATE_AFTERSTART, ZT_TXSTATE_RINGON,ZT_TXSTATE_RINGOFF,ZT_TXSTATE_KEWL, - ZT_TXSTATE_AFTERKEWL} ZT_TXSTATE_t; + ZT_TXSTATE_AFTERKEWL,ZT_TXSTATE_PULSEBREAK,ZT_TXSTATE_PULSEMAKE, + ZT_TXSTATE_PULSEAFTER + } ZT_TXSTATE_t; typedef short sumtype[ZT_MAX_CHUNKSIZE]; @@ -268,6 +270,7 @@ of the next sample chunk's data (next time around the world). #define DIGIT_MODE_DTMF 0 #define DIGIT_MODE_MFV1 1 +#define DIGIT_MODE_PULSE 2 #include "digits.h" @@ -903,6 +906,7 @@ static void close_channel(struct zt_chan *chan) chan->curtone = NULL; chan->curzone = NULL; chan->cadencepos = 0; + chan->pdialcount = 0; zt_hangup(chan); chan->itimerset = chan->itimer = 0; chan->pulsecount = 0; @@ -1011,6 +1015,7 @@ static int start_tone(struct zt_chan *chan, int tone) /* Stop the current tone, no matter what */ chan->tonep = 0; chan->curtone = NULL; + chan->pdialcount = 0; chan->txdialbuf[0] = '\0'; chan->dialing = 0; if ((tone >= ZT_TONE_MAX) || (tone < -1)) @@ -1654,11 +1659,12 @@ static ssize_t zt_chan_write(struct file *file, const char *usrbuf, size_t count return -EINVAL; for(;;) { spin_lock_irqsave(&chan->lock, flags); - if (chan->curtone && !(chan->flags & ZT_FLAG_PSEUDO)) { + if ((chan->curtone || chan->pdialcount) && !(chan->flags & ZT_FLAG_PSEUDO)) { chan->curtone = NULL; chan->tonep = 0; chan->dialing = 0; chan->txdialbuf[0] = '\0'; + chan->pdialcount = 0; } if (chan->eventinidx != chan->eventoutidx) { spin_unlock_irqrestore(&chan->lock, flags); @@ -1947,6 +1953,7 @@ static int zt_hangup(struct zt_chan *chan) chan->dialing = 0; chan->afterdialingtimer = 0; chan->curtone = NULL; + chan->pdialcount = 0; chan->cadencepos = 0; chan->txdialbuf[0] = 0; return res; @@ -2001,6 +2008,9 @@ static int initialize_channel(struct zt_chan *chan) chan->rxwinktime = ZT_DEFAULT_RXWINKTIME; chan->rxflashtime = ZT_DEFAULT_RXFLASHTIME; chan->debouncetime = ZT_DEFAULT_DEBOUNCETIME; + chan->pulsemaketime = ZT_DEFAULT_PULSEMAKETIME; + chan->pulsebreaktime = ZT_DEFAULT_PULSEBREAKTIME; + chan->pulseaftertime = ZT_DEFAULT_PULSEAFTERTIME; /* Initialize RBS timers */ chan->itimerset = chan->itimer = chan->otimer = 0; @@ -2031,6 +2041,7 @@ static int initialize_channel(struct zt_chan *chan) chan->gotgs = 0; chan->curtone = NULL; chan->tonep = 0; + chan->pdialcount = 0; set_tone_zone(chan, -1); if (chan->gainalloc && chan->rxgain) rxgain = chan->rxgain; @@ -2495,13 +2506,31 @@ static void __do_dtmf(struct zt_chan *chan) chan->digitmode = DIGIT_MODE_MFV1; chan->tonep = 0; break; - default: - chan->curtone = zt_dtmf_tone(c, (chan->digitmode == DIGIT_MODE_MFV1)); + case 'P': + case 'p': + chan->digitmode = DIGIT_MODE_PULSE; chan->tonep = 0; - /* All done */ - if (chan->curtone) { - zt_init_tone_state(&chan->ts, chan->curtone); - return; + break; + default: + if (chan->digitmode == DIGIT_MODE_PULSE) + { + if ((c >= '0') && (c <= '9') && (chan->txhooksig == ZT_TXSIG_OFFHOOK)) + { + chan->pdialcount = c - '0'; + /* a '0' is ten pulses */ + if (!chan->pdialcount) chan->pdialcount = 10; + zt_rbs_sethook(chan, ZT_TXSIG_ONHOOK, + ZT_TXSTATE_PULSEBREAK, chan->pulsebreaktime); + return; + } + } else { + chan->curtone = zt_dtmf_tone(c, (chan->digitmode == DIGIT_MODE_MFV1)); + chan->tonep = 0; + /* All done */ + if (chan->curtone) { + zt_init_tone_state(&chan->ts, chan->curtone); + return; + } } } } @@ -2722,6 +2751,9 @@ static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int c stack.param.rxflashtime = chan->rxflashtime; stack.param.debouncetime = chan->debouncetime; stack.param.channo = chan->channo; + stack.param.pulsemaketime = chan->pulsemaketime; + stack.param.pulsebreaktime = chan->pulsebreaktime; + stack.param.pulseaftertime = chan->pulseaftertime; if (chan->span) stack.param.spanno = chan->span->spanno; else stack.param.spanno = 0; strncpy(stack.param.name, chan->name, sizeof(stack.param.name) - 1); @@ -2756,6 +2788,9 @@ static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int c chan->rxwinktime = stack.param.rxwinktime; chan->rxflashtime = stack.param.rxflashtime; chan->debouncetime = stack.param.debouncetime; + chan->pulsemaketime = stack.param.pulsemaketime; + chan->pulsebreaktime = stack.param.pulsebreaktime; + chan->pulseaftertime = stack.param.pulseaftertime; break; case ZT_GETGAINS: /* get gain stuff */ if (copy_from_user(&stack.gain,(struct zt_gains *) data,sizeof(stack.gain))) @@ -3335,6 +3370,7 @@ static int zt_chanandpseudo_ioctl(struct inode *inode, struct file *file, unsign chan->dialing = 0; chan->txdialbuf[0] = '\0'; chan->tonep = 0; + chan->pdialcount = 0; break; case ZT_DIAL_OP_REPLACE: strcpy(chan->txdialbuf, stack.tdo.dialstr); @@ -4031,6 +4067,12 @@ static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cm return -EINVAL; /* if no span, just do nothing */ if (!chan->span) return(0); + /* if dialing, stop it */ + chan->curtone = NULL; + chan->dialing = 0; + chan->txdialbuf[0] = '\0'; + chan->tonep = 0; + chan->pdialcount = 0; get_user(j,(int *)data); if (chan->span->flags & ZT_FLAG_RBS) { switch (j) { @@ -4935,6 +4977,32 @@ static inline void __rbs_otimer_expire(struct zt_chan *chan) chan->gotgs = 0; break; + case ZT_TXSTATE_PULSEBREAK: + zt_rbs_sethook(chan, ZT_TXSIG_OFFHOOK, ZT_TXSTATE_PULSEMAKE, + chan->pulsemaketime); + wake_up_interruptible(&chan->txstateq); + break; + + case ZT_TXSTATE_PULSEMAKE: + if (chan->pdialcount) + chan->pdialcount--; + if (chan->pdialcount) + { + zt_rbs_sethook(chan, ZT_TXSIG_ONHOOK, + ZT_TXSTATE_PULSEBREAK, chan->pulsebreaktime); + break; + } + chan->txstate = ZT_TXSTATE_PULSEAFTER; + chan->otimer = chan->pulseaftertime * 8; + wake_up_interruptible(&chan->txstateq); + break; + + case ZT_TXSTATE_PULSEAFTER: + chan->txstate = ZT_TXSTATE_OFFHOOK; + __do_dtmf(chan); + wake_up_interruptible(&chan->txstateq); + break; + default: break; } -- cgit v1.2.3