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 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- zaptel.h | 12 ++++++++++ 2 files changed, 88 insertions(+), 8 deletions(-) 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; } diff --git a/zaptel.h b/zaptel.h index b3d5483..3c2bdd9 100755 --- a/zaptel.h +++ b/zaptel.h @@ -183,6 +183,9 @@ int starttime; int rxwinktime; int rxflashtime; int debouncetime; +int pulsebreaktime; +int pulsemaketime; +int pulseaftertime; } ZT_PARAMS; typedef struct zt_spaninfo @@ -841,6 +844,9 @@ struct zt_tone_def { /* Structure for zone programming */ #define ZT_DEFAULT_RXWINKTIME 300 /* 300ms longest rx wink (to work with the Atlas) */ #define ZT_DEFAULT_RXFLASHTIME 1250 /* 1250ms longest rx flash */ #define ZT_DEFAULT_DEBOUNCETIME 600 /* 600ms of FXS GS signalling debounce */ +#define ZT_DEFAULT_PULSEMAKETIME 50 /* 50 ms of line closed when dial pulsing */ +#define ZT_DEFAULT_PULSEBREAKTIME 50 /* 50 ms of line open when dial pulsing */ +#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 */ @@ -1010,6 +1016,9 @@ struct zt_chan { int tonep; /* Current position in tone */ struct zt_tone_state ts; /* Tone state */ + /* Pulse dial stuff */ + int pdialcount; /* pulse dial count */ + /* Ring cadence */ int ringcadence[ZT_MAX_CADENCE]; @@ -1070,6 +1079,9 @@ struct zt_chan { int rxwinktime; /* rx wink time (ms) */ int rxflashtime; /* rx flash time (ms) */ int debouncetime; /* FXS GS sig debounce time (ms) */ + int pulsebreaktime; /* pulse line open time (ms) */ + int pulsemaketime; /* pulse line closed time (ms) */ + int pulseaftertime; /* pulse time between digits (ms) */ /* RING debounce timer */ int ringdebtimer; -- cgit v1.2.3