summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjim <jim@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2004-09-11 15:48:45 +0000
committerjim <jim@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2004-09-11 15:48:45 +0000
commitf06574ef3bfd9f51cef6a61d000ff4249993b4fa (patch)
tree1c4d8fbf79c255e078a47a3ba65719c1bcb2b3d0
parent59246a32c6a5ef3d01820542437f6eca6d4af4d6 (diff)
Added outbound pulse dialing
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@457 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rwxr-xr-xzaptel.c84
-rwxr-xr-xzaptel.h12
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;