--- /root/zaptel-1.4.11/kernel/wctdm.c 2008-04-24 15:17:12.000000000 -0300 +++ wctdm.c 2008-05-12 17:53:11.000000000 -0300 @@ -229,6 +229,8 @@ int lastpol; int polarity; int polaritydebounce; + int readcid; + unsigned int cidtimer; } fxo; struct fxs { int oldrxhook; @@ -292,6 +294,7 @@ static int fxorxgain = 0; static int fxstxgain = 0; static int fxsrxgain = 0; +static int dtmf = 0; static int wctdm_init_proslic(struct wctdm *wc, int card, int fast , int manual, int sane); @@ -373,6 +376,7 @@ if (!wc->mod[card].fxo.offhook) zt_hooksig(&wc->chans[card], ZT_RXSIG_RING); wc->mod[card].fxo.ring = 1; + wc->mod[card].fxo.readcid = 1; } if (wc->mod[card].fxo.ring && !wc->mod[card].fxo.pegcount) { /* No more ring */ @@ -380,10 +384,33 @@ printk("NO RING on %d/%d!\n", wc->span.spanno, card + 1); zt_hooksig(&wc->chans[card], ZT_RXSIG_OFFHOOK); wc->mod[card].fxo.ring = 0; + wc->mod[card].fxo.cidtimer = wc->intcount; + wc->mod[card].fxo.readcid = 0; } } } #endif + +static inline void wctdm_dtmfcheck_fakepolarity(struct wctdm *wc, int card, int x) +{ + int sample; + if (dtmf && (wc->cardflag & (1 << card)) && wc->modtype[card] == MOD_TYPE_FXO && !wc->mod[card].fxo.offhook ) { + if(!wc->mod[card].fxo.readcid && !wc->mod[card].fxo.wasringing && + wc->intcount > wc->mod[card].fxo.cidtimer + 400) { + sample = ZT_XLAW(wc->chans[card].readchunk[x], (&(wc->chans[card]))); + if (sample > 16000 || sample < -16000) { + wc->mod[card].fxo.readcid = 1; + wc->mod[card].fxo.cidtimer = wc->intcount; + if (debug) printk("DTMF CLIP on %i\n",card); + zt_qevent_lock(&wc->chans[card], ZT_EVENT_POLARITY); + } + } else if(wc->intcount > wc->mod[card].fxo.cidtimer + 2000) { + wc->mod[card].fxo.cidtimer = wc->intcount; + wc->mod[card].fxo.readcid = 0; + } + } +} + static inline void wctdm_receiveprep(struct wctdm *wc, unsigned char ints) { volatile unsigned int *readchunk; @@ -414,6 +441,10 @@ if (wc->cardflag & (1 << 0)) wc->chans[0].readchunk[x] = (readchunk[x]) & 0xff; #endif + wctdm_dtmfcheck_fakepolarity(wc,0,x); + wctdm_dtmfcheck_fakepolarity(wc,1,x); + wctdm_dtmfcheck_fakepolarity(wc,2,x); + wctdm_dtmfcheck_fakepolarity(wc,3,x); } #ifdef AUDIO_RINGCHECK for (x=0;xcards;x++) @@ -787,6 +818,8 @@ } else if (!res) { if ((fxo->ringdebounce == 0) && fxo->wasringing) { fxo->wasringing = 0; + wc->mod[card].fxo.readcid = 0; + wc->mod[card].fxo.cidtimer = wc->intcount; if (debug) printk("NO RING on %d/%d!\n", wc->span.spanno, card + 1); zt_hooksig(&wc->chans[card], ZT_RXSIG_OFFHOOK); @@ -909,18 +942,18 @@ fxo->battdebounce = battdebounce / MS_PER_CHECK_HOOK; } } - } - if (fxo->lastpol >= 0) { - if (b < 0) { - fxo->lastpol = -1; - fxo->polaritydebounce = POLARITY_DEBOUNCE / MS_PER_CHECK_HOOK; - } - } - if (fxo->lastpol <= 0) { - if (b > 0) { - fxo->lastpol = 1; - fxo->polaritydebounce = POLARITY_DEBOUNCE / MS_PER_CHECK_HOOK; + if (fxo->lastpol >= 0) { + if (b < 0) { + fxo->lastpol = -1; + fxo->polaritydebounce = POLARITY_DEBOUNCE / MS_PER_CHECK_HOOK; + } + } + if (fxo->lastpol <= 0) { + if (b > 0) { + fxo->lastpol = 1; + fxo->polaritydebounce = POLARITY_DEBOUNCE / MS_PER_CHECK_HOOK; + } } } @@ -2523,6 +2556,7 @@ module_param(fxorxgain, int, 0600); module_param(fxstxgain, int, 0600); module_param(fxsrxgain, int, 0600); +module_param(dtmf, int, 0600); #else MODULE_PARM(debug, "i"); MODULE_PARM(loopcurrent, "i");