diff -u chk-out-versions/chan_zap.c decadic/chan_zap.c --- chk-out-versions/chan_zap.c 2007-09-17 17:32:17.000000000 +0200 +++ decadic/chan_zap.c 2007-09-17 17:57:40.000000000 +0200 @@ -178,6 +178,7 @@ #define SIG_FXSKS ZT_SIG_FXSKS #define SIG_FXOLS ZT_SIG_FXOLS #define SIG_FXOGS ZT_SIG_FXOGS +#define SIG_FXODS ZT_SIG_FXODS #define SIG_FXOKS ZT_SIG_FXOKS #define SIG_PRI ZT_SIG_CLEAR #define SIG_SF ZT_SIG_SF @@ -469,6 +470,7 @@ unsigned int priexclusive:1; unsigned int pulse:1; unsigned int pulsedial:1; /*!< whether a pulse dial phone is detected */ + unsigned int decadicdid:1; /*!< when decadic DID is in progress */ unsigned int restrictcid:1; /*!< Whether restrict the callerid -> only send ANI */ unsigned int threewaycalling:1; unsigned int transfer:1; @@ -1192,6 +1194,8 @@ return "FXO Groundstart"; case SIG_FXOKS: return "FXO Kewlstart"; + case SIG_FXODS: + return "FXO Decadicstart"; case SIG_PRI: return "PRI Signalling"; case SIG_SF: @@ -1812,6 +1816,7 @@ case SIG_FXOLS: case SIG_FXOGS: case SIG_FXOKS: + case SIG_FXODS: if (p->owner == ast) { /* Normal ring, on hook */ @@ -1851,11 +1856,18 @@ } if (c) { p->dop.op = ZT_DIAL_OP_REPLACE; - snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c); + snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "%s%s", p->pulse ? "P": "Tw", c); ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c); + /* Decadic DID starts here */ + if (p->sig == SIG_FXODS) p->decadicdid = 1; } else { p->dop.dialstr[0] = '\0'; } + + /* Decadic dialing (DID), but only with a number to dial */ + if (c && (p->sig == SIG_FXODS)) + x = ZT_START; + else x = ZT_RING; if (ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x) && (errno != EINPROGRESS)) { ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno)); @@ -2560,6 +2572,7 @@ p->digital = 0; p->faxhandled = 0; p->pulsedial = 0; + p->decadicdid = 0; p->onhooktime = time(NULL); #ifdef HAVE_PRI p->proceeding = 0; @@ -2639,6 +2652,7 @@ case SIG_FXOGS: case SIG_FXOLS: case SIG_FXOKS: + case SIG_FXODS: res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par); if (!res) { #if 0 @@ -2769,6 +2783,7 @@ case SIG_FXOLS: case SIG_FXOGS: case SIG_FXOKS: + case SIG_FXODS: /* Pick up the line */ ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name); if (p->hanguponpolarityswitch) { @@ -3845,11 +3860,22 @@ case SIG_FXOLS: case SIG_FXOGS: case SIG_FXOKS: + case SIG_FXODS: p->onhooktime = time(NULL); p->msgstate = -1; /* Check for some special conditions regarding call waiting */ if (index == SUB_REAL) { /* The normal line was hung up */ + + if ((p->sig == SIG_FXODS) && p->decadicdid) { + /* DID accepted number, wait for real off-hook */ + p->decadicdid = 0; + ast_log(LOG_DEBUG, "FXO Decadic DID accepted, channel %d\n", p->channel); + if (p->dialing) { + ast_log(LOG_WARNING, "Still dialing when FXO Decadic DID accepted, channel %d\n", p->channel); + } + break; + } if (p->subs[SUB_CALLWAIT].owner) { /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */ swap_subs(p, SUB_CALLWAIT, SUB_REAL); @@ -3998,8 +4024,12 @@ case SIG_FXOLS: case SIG_FXOGS: case SIG_FXOKS: + case SIG_FXODS: switch (ast->_state) { case AST_STATE_RINGING: + if (p->sig == SIG_FXODS && p->decadicdid) { + ast_log(LOG_DEBUG, "FXO Decadic DID ready to dial, channel %d\n", p->channel); + } else { zt_enable_ec(p); zt_train_ec(p); p->subs[index].f.frametype = AST_FRAME_CONTROL; @@ -4007,6 +4037,7 @@ /* Make sure it stops ringing */ zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); ast_log(LOG_DEBUG, "channel %d answered\n", p->channel); + } if (p->cidspill) { /* Cancel any running CallerID spill */ free(p->cidspill); @@ -4032,7 +4063,10 @@ p->dialing = 1; } p->dop.dialstr[0] = '\0'; - ast_setstate(ast, AST_STATE_DIALING); + if (p->sig == SIG_FXODS && p->decadicdid) { + /* Stay in ringing state until the real answer */ + } + else ast_setstate(ast, AST_STATE_DIALING); } else ast_setstate(ast, AST_STATE_UP); return &p->subs[index].f; @@ -4184,6 +4218,7 @@ case SIG_FXOLS: case SIG_FXOGS: case SIG_FXOKS: + case SIG_FXODS: ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n", index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd); p->callwaitcas = 0; @@ -4193,6 +4228,12 @@ goto winkflashdone; } + if ((p->sig == SIG_FXODS) && p->decadicdid) { + ast_log(LOG_DEBUG, "Winkflash ignored during decadic DID channel %d\n", p->channel); + + break; + } + if (p->subs[SUB_CALLWAIT].owner) { /* Swap to call-wait */ swap_subs(p, SUB_REAL, SUB_CALLWAIT); @@ -5288,7 +5329,7 @@ if (state == AST_STATE_RING) tmp->rings = 1; tmp->tech_pvt = i; - if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) { + if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS) || (i->sig == SIG_FXODS)) { /* Only FXO signalled stuff can be picked up */ tmp->callgroup = i->callgroup; tmp->pickupgroup = i->pickupgroup; @@ -5764,6 +5805,7 @@ case SIG_FXOLS: case SIG_FXOGS: case SIG_FXOKS: + case SIG_FXODS: /* Read the first digit */ timeout = firstdigittimeout; /* If starting a threeway call, never timeout on the first digit so someone @@ -6576,6 +6618,7 @@ case SIG_FXOLS: case SIG_FXOGS: case SIG_FXOKS: + case SIG_FXODS: res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK); if (res && (errno == EBUSY)) break; @@ -6678,6 +6721,7 @@ switch (i->sig) { case SIG_FXOLS: case SIG_FXOGS: + case SIG_FXODS: case SIG_FEATD: case SIG_FEATDMF: case SIG_FEATDMF_TA: @@ -7168,7 +7212,7 @@ destroy_zt_pvt(&tmp); return NULL; } - if (p.sigtype != (conf.chan.sig & 0x3ffff)) { + if (p.sigtype != (conf.chan.sig & 0xbffff)) { ast_log(LOG_ERROR, "Signalling requested on channel %d is %s but line is in %s signalling\n", channel, sig2str(conf.chan.sig), sig2str(p.sigtype)); destroy_zt_pvt(&tmp); return NULL; @@ -7348,11 +7392,22 @@ p.rxflashtime = conf.timing.rxflashtime; if (conf.timing.debouncetime >= 0) p.debouncetime = conf.timing.debouncetime; + if (conf.timing.pulsecountzerofirst >= 0) + p.pulsecountzerofirst = conf.timing.pulsecountzerofirst; + if (conf.timing.pulsebreaktime >= 0) + p.pulsebreaktime = conf.timing.pulsebreaktime; + if (conf.timing.pulsemaketime >= 0) + p.pulsemaketime = conf.timing.pulsemaketime; + if (conf.timing.pulseaftertime >= 0) + p.pulseaftertime = conf.timing.pulseaftertime; } /* dont set parms on a pseudo-channel (or CRV) */ if (tmp->subs[SUB_REAL].zfd >= 0) { + ast_log(LOG_DEBUG, "Setting pulse parameters: zf=%d mk=%d brk=%d after=%d\n", + p.pulsecountzerofirst, p.pulsemaketime, p.pulsebreaktime, p.pulseaftertime); + res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p); if (res < 0) { ast_log(LOG_ERROR, "Unable to set parameters\n"); @@ -7383,7 +7438,7 @@ tmp->radio = conf.chan.radio; tmp->ringt_base = ringt_base; tmp->firstradio = 0; - if ((conf.chan.sig == SIG_FXOKS) || (conf.chan.sig == SIG_FXOLS) || (conf.chan.sig == SIG_FXOGS)) + if ((conf.chan.sig == SIG_FXOKS) || (conf.chan.sig == SIG_FXOLS) || (conf.chan.sig == SIG_FXOGS) || (conf.chan.sig == SIG_FXODS)) tmp->permcallwaiting = conf.chan.callwaiting; else tmp->permcallwaiting = 0; @@ -7565,7 +7620,7 @@ } /* We're at least busy at this point */ if (busy) { - if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS)) + if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS) || (p->sig == SIG_FXODS)) *busy = 1; } /* If do not disturb, definitely not */ @@ -7624,7 +7679,7 @@ } /* If it's not an FXO, forget about call wait */ - if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) + if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS) && (p->sig != SIG_FXODS)) return 0; if (!p->callwaiting) { @@ -7829,7 +7884,9 @@ #endif if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) { +/* if (option_debug) +*/ ast_log(LOG_DEBUG, "Using channel %d\n", p->channel); if (p->inalarm) goto next; @@ -10622,6 +10679,14 @@ confp->chan.hidecalleridname = ast_true(v->value); } else if (!strcasecmp(v->name, "pulsedial")) { confp->chan.pulse = ast_true(v->value); + } else if (!strcasecmp(v->name, "zaptel.pulse.countzerofirst")) { + confp->timing.pulsecountzerofirst = atoi(v->value); + } else if (!strcasecmp(v->name, "zaptel.pulse.break")) { + confp->timing.pulsebreaktime = atoi(v->value); + } else if (!strcasecmp(v->name, "zaptel.pulse.make")) { + confp->timing.pulsemaketime = atoi(v->value); + } else if (!strcasecmp(v->name, "zaptel.pulse.pause")) { + confp->timing.pulseaftertime = atoi(v->value); } else if (!strcasecmp(v->name, "callreturn")) { confp->chan.callreturn = ast_true(v->value); } else if (!strcasecmp(v->name, "callwaiting")) { @@ -10726,6 +10791,9 @@ } else if (!strcasecmp(v->value, "fxo_ks")) { confp->chan.sig = SIG_FXOKS; confp->chan.radio = 0; + } else if (!strcasecmp(v->value, "fxo_ds")) { + confp->chan.sig = SIG_FXODS; + confp->chan.radio = 0; } else if (!strcasecmp(v->value, "fxs_rx")) { confp->chan.sig = SIG_FXSKS; confp->chan.radio = 1; diff -u chk-out-versions/zaptel-base.c decadic/zaptel-base.c --- chk-out-versions/zaptel-base.c 2007-09-17 17:33:43.000000000 +0200 +++ decadic/zaptel-base.c 2007-09-17 17:57:40.000000000 +0200 @@ -235,7 +235,7 @@ ZT_TXSTATE_FLASH,ZT_TXSTATE_DEBOUNCE,ZT_TXSTATE_AFTERSTART, ZT_TXSTATE_RINGON,ZT_TXSTATE_RINGOFF,ZT_TXSTATE_KEWL, ZT_TXSTATE_AFTERKEWL,ZT_TXSTATE_PULSEBREAK,ZT_TXSTATE_PULSEMAKE, - ZT_TXSTATE_PULSEAFTER + ZT_TXSTATE_PULSEAFTER, ZT_TXSTATE_DECADIC_IDLE } ZT_TXSTATE_t; typedef short sumtype[ZT_MAX_CHUNKSIZE]; @@ -400,7 +400,7 @@ static struct zt_zone *tone_zones[ZT_TONE_ZONE_MAX]; -#define NUM_SIGS 10 +#define NUM_SIGS 11 #ifdef AGGRESSIVE_SUPPRESSOR @@ -454,6 +454,7 @@ { ZT_SIG_FXSKS,ZT_BBIT | ZT_BBIT | ((ZT_ABIT | ZT_BBIT) << 8)}, { ZT_SIG_FXOLS,0 | (ZT_ABIT << 8)}, { ZT_SIG_FXOGS,ZT_BBIT | ((ZT_ABIT | ZT_BBIT) << 8)}, + { ZT_SIG_FXODS,0 | (ZT_ABIT << 8)}, /* FXO_DS RBS untested */ { ZT_SIG_FXOKS,0 | (ZT_ABIT << 8)}, { ZT_SIG_SF, 0}, { ZT_SIG_EM_E1, ZT_DBIT | ((ZT_ABIT | ZT_DBIT) << 8) }, @@ -492,6 +493,8 @@ return "FXOKS"; case ZT_SIG_FXOGS: return "FXOGS"; + case ZT_SIG_FXODS: + return "FXODS"; case ZT_SIG_EM: return "E&M"; case ZT_SIG_EM_E1: @@ -2020,6 +2023,8 @@ { ZT_SIG_FXOLS, ZT_BBIT | ZT_DBIT, ZT_BBIT | ZT_DBIT, 0, 0 }, /* FXO Loopstart */ { ZT_SIG_FXOGS, ZT_ABIT | ZT_BBIT | ZT_CBIT | ZT_DBIT, ZT_BBIT | ZT_DBIT, 0, 0 }, /* FXO Groundstart */ + { ZT_SIG_FXODS, ZT_BBIT | ZT_DBIT, ZT_BBIT | ZT_DBIT, 0, + ZT_ABIT | ZT_BBIT | ZT_CBIT | ZT_DBIT }, /* FXO Decadicstart - RBS bits untested */ { ZT_SIG_FXOKS, ZT_BBIT | ZT_DBIT, ZT_BBIT | ZT_DBIT, 0, ZT_ABIT | ZT_BBIT | ZT_CBIT | ZT_DBIT }, /* FXO Kewlstart */ { ZT_SIG_SF, ZT_BBIT | ZT_CBIT | ZT_DBIT, @@ -2073,6 +2078,9 @@ if (chan->span->hooksig) { if (chan->txhooksig != txsig) { chan->txhooksig = txsig; +#ifdef CONFIG_ZAPATA_DEBUG + printk("Hooksig for channel %s state %d in %d signalling, pdialcount: %d\n", chan->name, txsig, chan->sig, chan->pdialcount); +#endif chan->span->hooksig(chan, txsig); } chan->otimer = timeout * ZT_CHUNKSIZE; /* Otimer is timer in samples */ @@ -2130,12 +2138,26 @@ } else if ((chan->sig == ZT_SIG_FXOKS) && (chan->txstate != ZT_TXSTATE_ONHOOK)) { /* Do RBS signalling on the channel's behalf */ zt_rbs_sethook(chan, ZT_TXSIG_KEWL, ZT_TXSTATE_KEWL, ZT_KEWLTIME); + } else if ((chan->sig == ZT_SIG_FXODS) && (chan->txstate != ZT_TXSTATE_DECADIC_IDLE)) { + /* Decadicstart hangup means go to idle state, battery off */ +#ifdef CONFIG_ZAPATA_DEBUG + printk("Decadic rbs hangup chan: %d %s\n", chan->channo, chan->name); +#endif + zt_rbs_sethook(chan, ZT_TXSIG_KEWL, ZT_TXSTATE_DECADIC_IDLE, 0); } else 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) { - if (chan->txhooksig != ZT_ONHOOK) { + if (chan->sig == ZT_SIG_FXODS) { + if (chan->txhooksig != ZT_DECIDLE) { +#ifdef CONFIG_ZAPATA_DEBUG + printk("Decadic sethook hangup chan: %d %s\n", chan->channo, chan->name); +#endif + chan->txhooksig = ZT_DECIDLE; + res = chan->span->sethook(chan, ZT_DECIDLE); + } + } else if (chan->txhooksig != ZT_ONHOOK) { chan->txhooksig = ZT_ONHOOK; res = chan->span->sethook(chan, ZT_ONHOOK); } else @@ -2219,6 +2241,7 @@ chan->rxwinktime = ZT_DEFAULT_RXWINKTIME; chan->rxflashtime = ZT_DEFAULT_RXFLASHTIME; chan->debouncetime = ZT_DEFAULT_DEBOUNCETIME; + chan->pulsecountzerofirst = 0; chan->pulsemaketime = ZT_DEFAULT_PULSEMAKETIME; chan->pulsebreaktime = ZT_DEFAULT_PULSEBREAKTIME; chan->pulseaftertime = ZT_DEFAULT_PULSEAFTERTIME; @@ -2739,6 +2762,10 @@ { char c; /* Called with chan->lock held */ +#ifdef CONFIG_ZAPATA_DEBUG + printk("__do_dtmf: chan %s, txdialbuf '%s'\n", chan->name, chan->txdialbuf); + +#endif while (strlen(chan->txdialbuf)) { c = chan->txdialbuf[0]; /* Skooch */ @@ -2762,11 +2789,16 @@ default: if (chan->digitmode == DIGIT_MODE_PULSE) { - if ((c >= '0') && (c <= '9') && (chan->txhooksig == ZT_TXSIG_OFFHOOK)) + if ((c >= '0') && (c <= '9') && ((chan->txhooksig == ZT_TXSIG_OFFHOOK) || ((chan->sig == ZT_SIG_FXODS) && (chan->txhooksig == ZT_TXSIG_ONHOOK)))) { + /* Pulse count may start at zero or one */ chan->pdialcount = c - '0'; + if (chan->pulsecountzerofirst) ++chan->pdialcount; /* a '0' is ten pulses */ - if (!chan->pdialcount) chan->pdialcount = 10; + else if (!chan->pdialcount) chan->pdialcount = 10; +#ifdef CONFIG_ZAPATA_DEBUG + printk("Init pdialcount: %d txdialbuf '%s', channel %s\n", chan->pdialcount, chan->txdialbuf, chan->name); +#endif zt_rbs_sethook(chan, ZT_TXSIG_ONHOOK, ZT_TXSTATE_PULSEBREAK, chan->pulsebreaktime); return; @@ -2784,6 +2816,10 @@ } } } +#ifdef CONFIG_ZAPATA_DEBUG + printk("__do_dtmf: chan %s, end of number, txdialbuf '%s'\n", chan->name, chan->txdialbuf); +#endif + /* Notify userspace process if there is nothing left */ chan->dialing = 0; __qevent(chan, ZT_EVENT_DIALCOMPLETE); @@ -3029,6 +3065,7 @@ if (return_master) stack.param.channo |= chan->master->channo << 16; + stack.param.pulsecountzerofirst = chan->pulsecountzerofirst; stack.param.pulsemaketime = chan->pulsemaketime; stack.param.pulsebreaktime = chan->pulsebreaktime; stack.param.pulseaftertime = chan->pulseaftertime; @@ -3069,6 +3106,7 @@ chan->rxwinktime = stack.param.rxwinktime; chan->rxflashtime = stack.param.rxflashtime; chan->debouncetime = stack.param.debouncetime; + chan->pulsecountzerofirst = stack.param.pulsecountzerofirst; chan->pulsemaketime = stack.param.pulsemaketime; chan->pulsebreaktime = stack.param.pulsebreaktime; chan->pulseaftertime = stack.param.pulseaftertime; @@ -4488,6 +4526,10 @@ return -EINVAL; /* if no span, just do nothing */ if (!chan->span) return(0); +#ifdef CONFIG_ZAPATA_DEBUG + printk("zt_chan_ioctl, ZT_HOOK: chan %s, hookstate %d\n", chan->name, j); +#endif + spin_lock_irqsave(&chan->lock, flags); /* if dialing, stop it */ chan->curtone = NULL; @@ -4513,10 +4555,16 @@ zt_rbs_sethook(chan, ZT_TXSIG_OFFHOOK, ZT_TXSTATE_DEBOUNCE, chan->debouncetime); spin_unlock_irqrestore(&chan->lock, flags); break; - case ZT_RING: case ZT_START: + if ((chan->sig == ZT_SIG_FXODS) && (chan->txstate == ZT_TXSTATE_DECADIC_IDLE)) { + /* Decadicstart DID init */ + zt_rbs_sethook(chan, ZT_TXSIG_ONHOOK, ZT_TXSTATE_ONHOOK, 0); + break; + } + /* fall through */ + case ZT_RING: spin_lock_irqsave(&chan->lock, flags); - if (chan->txstate != ZT_TXSTATE_ONHOOK) { + if ((chan->txstate != ZT_TXSTATE_ONHOOK) && !((chan->sig == ZT_SIG_FXODS) && (chan->txstate == ZT_TXSTATE_DECADIC_IDLE))) { spin_unlock_irqrestore(&chan->lock, flags); return -EBUSY; } @@ -4567,6 +4615,11 @@ zt_rbs_sethook(chan, ZT_TXSIG_ONHOOK, ZT_TXSTATE_ONHOOK, 0); spin_unlock_irqrestore(&chan->lock, flags); break; + case ZT_DECIDLE: + spin_lock_irqsave(&chan->lock, flags); + zt_rbs_sethook(chan, ZT_TXSIG_KEWL, ZT_TXSTATE_DECADIC_IDLE, 0); + spin_unlock_irqrestore(&chan->lock, flags); + break; default: return -EINVAL; } @@ -5369,6 +5422,7 @@ { case ZT_SIG_FXOLS: /* if FXO, its definitely on hook */ case ZT_SIG_FXOGS: + case ZT_SIG_FXODS: case ZT_SIG_FXOKS: __qevent(chan,ZT_EVENT_ONHOOK); chan->gotgs = 0; @@ -5499,8 +5553,13 @@ break; case ZT_TXSTATE_PULSEBREAK: + if (chan->sig == ZT_SIG_FXODS) { + zt_rbs_sethook(chan, ZT_TXSIG_KEWL, ZT_TXSTATE_PULSEMAKE, + chan->pulsemaketime); + } else { zt_rbs_sethook(chan, ZT_TXSIG_OFFHOOK, ZT_TXSTATE_PULSEMAKE, chan->pulsemaketime); + } wake_up_interruptible(&chan->txstateq); break; @@ -5513,13 +5572,29 @@ ZT_TXSTATE_PULSEBREAK, chan->pulsebreaktime); break; } + if (chan->sig == ZT_SIG_FXODS) { + zt_rbs_sethook(chan, ZT_TXSIG_ONHOOK, ZT_TXSTATE_PULSEAFTER, + chan->pulseaftertime); + } else { chan->txstate = ZT_TXSTATE_PULSEAFTER; chan->otimer = chan->pulseaftertime * ZT_CHUNKSIZE; + } +#ifdef CONFIG_ZAPATA_DEBUG + printk("End of last pulse chan %s, signalling %d\n", chan->name, chan->sig); +#endif + wake_up_interruptible(&chan->txstateq); break; case ZT_TXSTATE_PULSEAFTER: +#ifdef CONFIG_ZAPATA_DEBUG + printk("In pulseAfter chan %s, signalling %d\n", chan->name, chan->sig); +#endif + if (chan->sig == ZT_SIG_FXODS) { + chan->txstate = ZT_TXSTATE_ONHOOK; + } else { chan->txstate = ZT_TXSTATE_OFFHOOK; + } __do_dtmf(chan); wake_up_interruptible(&chan->txstateq); break; @@ -5649,6 +5724,7 @@ /* fall through intentionally */ case ZT_SIG_FXOLS: /* FXO Loopstart */ case ZT_SIG_FXOKS: /* FXO Kewlstart */ + case ZT_SIG_FXODS: /* FXO Decadicstart */ switch(rxsig) { case ZT_RXSIG_OFFHOOK: /* went off hook */ /* if asserti ng ring, stop it */ @@ -5694,6 +5770,9 @@ if (chan->txstate == ZT_TXSTATE_KEWL) chan->kewlonhook = 1; break; +#ifdef CONFIG_ZAPATA_DEBUG + printk("On hook on channel %d, itimer = %d, kewlonhook = %d\n", chan->channo, chan->itimer, chan->kewlonhook); +#endif default: break; } @@ -5730,6 +5809,7 @@ /* Fall through */ case ZT_SIG_EM: /* E and M */ case ZT_SIG_EM_E1: + case ZT_SIG_FXODS: /* FXO Decadicstart */ case ZT_SIG_FXOLS: /* FXO Loopstart */ case ZT_SIG_FXOKS: /* FXO Kewlstart */ if (cursig & ZT_ABIT) /* off hook */ @@ -6247,7 +6327,9 @@ ms->infcs = PPP_INITFCS; ms->readn[ms->inreadbuf] = ms->readidx[ms->inreadbuf]; #ifdef CONFIG_ZAPATA_DEBUG +/*** printk("EOF, len is %d\n", ms->readn[ms->inreadbuf]); +****/ #endif #if defined(CONFIG_ZAPATA_NET) || defined(CONFIG_ZAPATA_PPP) if (ms->flags & (ZT_FLAG_NETDEV | ZT_FLAG_PPP)) { diff -u chk-out-versions/zaptel.h decadic/zaptel.h --- chk-out-versions/zaptel.h 2007-09-17 17:33:43.000000000 +0200 +++ decadic/zaptel.h 2007-09-17 17:57:40.000000000 +0200 @@ -121,6 +121,7 @@ #define ZT_SIG_FXOLS ((1 << 3) | __ZT_SIG_FXO) /* FXO, Loopstart */ #define ZT_SIG_FXOGS ((1 << 4) | __ZT_SIG_FXO) /* FXO, Groupstart */ #define ZT_SIG_FXOKS ((1 << 5) | __ZT_SIG_FXO) /* FXO, Kewlstart */ +#define ZT_SIG_FXODS ((1 << 19) | __ZT_SIG_FXO) /* FXO, Decadicstart */ #define ZT_SIG_EM (1 << 6) /* Ear & Mouth (E&M) */ @@ -203,6 +204,7 @@ int rxwinktime; int rxflashtime; int debouncetime; +int pulsecountzerofirst; int pulsebreaktime; int pulsemaketime; int pulseaftertime; @@ -879,6 +881,9 @@ /* Value for ZT_HOOK, turn ringer off */ #define ZT_RINGOFF 6 +/* Value for ZT_HOOK, decadic idle */ +#define ZT_DECIDLE 7 + /* Ret. Value for GET/WAIT Event, no event */ #define ZT_EVENT_NONE 0 @@ -1275,6 +1280,7 @@ int rxwinktime; /* rx wink time (ms) */ int rxflashtime; /* rx flash time (ms) */ int debouncetime; /* FXS GS sig debounce time (ms) */ + int pulsecountzerofirst; /* if pulse count starts at zero */ int pulsebreaktime; /* pulse line open time (ms) */ int pulsemaketime; /* pulse line closed time (ms) */ int pulseaftertime; /* pulse time between digits (ms) */ diff -u chk-out-versions/ztcfg.c decadic/ztcfg.c --- chk-out-versions/ztcfg.c 2007-09-17 17:33:43.000000000 +0200 +++ decadic/ztcfg.c 2007-09-17 17:57:40.000000000 +0200 @@ -142,6 +142,8 @@ return "FXO Groundstart"; case ZT_SIG_FXOKS: return "FXO Kewlstart"; + case ZT_SIG_FXODS: + return "FXO Decadicstart"; case ZT_SIG_CAS: return "CAS / User"; case ZT_SIG_DACS: @@ -513,6 +515,9 @@ } else if (!strcasecmp(keyword, "fxoks")) { cc[x].sigtype = ZT_SIG_FXOKS; sig[x] = sigtype_to_str(cc[x].sigtype); + } else if (!strcasecmp(keyword, "fxods")) { + cc[x].sigtype = ZT_SIG_FXODS; + sig[x] = sigtype_to_str(cc[x].sigtype); } else if (!strcasecmp(keyword, "cas") || !strcasecmp(keyword, "user")) { if (parse_idle(&cc[x].idlebits, idle)) return -1; @@ -1196,6 +1201,7 @@ { "fxols", chanconfig }, { "fxogs", chanconfig }, { "fxoks", chanconfig }, + { "fxods", chanconfig }, { "rawhdlc", chanconfig }, { "nethdlc", chanconfig }, { "fcshdlc", chanconfig },