Index: drivers/dahdi/wctdm.c =================================================================== --- drivers/dahdi/wctdm.c (revision 4441) +++ drivers/dahdi/wctdm.c (working copy) @@ -228,6 +228,8 @@ int lastpol; int polarity; int polaritydebounce; + int readcid; + unsigned int cidtimer; } fxo; struct fxs { int oldrxhook; @@ -291,6 +293,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); @@ -383,6 +386,31 @@ } } #endif + +static inline void wctdm_dtmfcheck_fakepolarity(struct wctdm *wc, int card, int x) +{ + int sample; + /* only look for sound on the line if dtmf flag is on, it is an fxo card and line is onhook */ + if (!dtmf || !(wc->cardflag & (1 << card)) || !(wc->modtype[card] == MOD_TYPE_FXO) || wc->mod[card].fxo.offhook ) + return; + + /* don't look for noise if we're already processing it, or there is a ringing tone */ + if(!wc->mod[card].fxo.readcid && !wc->mod[card].fxo.wasringing && + wc->intcount > wc->mod[card].fxo.cidtimer + 400 ) { + sample = DAHDI_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+1); + dahdi_qevent_lock(&wc->chans[card], DAHDI_EVENT_POLARITY); + } + } else if(wc->mod[card].fxo.readcid && wc->intcount > wc->mod[card].fxo.cidtimer + 2000) { + /* reset flags if it's been a while */ + 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; @@ -397,21 +425,29 @@ #ifdef __BIG_ENDIAN if (wc->cardflag & (1 << 3)) wc->chans[3].readchunk[x] = (readchunk[x]) & 0xff; + wctdm_dtmfcheck_fakepolarity(wc, 3, x); if (wc->cardflag & (1 << 2)) wc->chans[2].readchunk[x] = (readchunk[x] >> 8) & 0xff; + wctdm_dtmfcheck_fakepolarity(wc, 2, x); if (wc->cardflag & (1 << 1)) wc->chans[1].readchunk[x] = (readchunk[x] >> 16) & 0xff; + wctdm_dtmfcheck_fakepolarity(wc, 1, x); if (wc->cardflag & (1 << 0)) wc->chans[0].readchunk[x] = (readchunk[x] >> 24) & 0xff; + wctdm_dtmfcheck_fakepolarity(wc, 0, x); #else if (wc->cardflag & (1 << 3)) wc->chans[3].readchunk[x] = (readchunk[x] >> 24) & 0xff; + wctdm_dtmfcheck_fakepolarity(wc, 3, x); if (wc->cardflag & (1 << 2)) wc->chans[2].readchunk[x] = (readchunk[x] >> 16) & 0xff; + wctdm_dtmfcheck_fakepolarity(wc, 2, x); if (wc->cardflag & (1 << 1)) wc->chans[1].readchunk[x] = (readchunk[x] >> 8) & 0xff; + wctdm_dtmfcheck_fakepolarity(wc, 1, x); if (wc->cardflag & (1 << 0)) wc->chans[0].readchunk[x] = (readchunk[x]) & 0xff; + wctdm_dtmfcheck_fakepolarity(wc, 0, x); #endif } #ifdef AUDIO_RINGCHECK @@ -786,6 +822,8 @@ } else if (!res) { if ((fxo->ringdebounce == 0) && fxo->wasringing) { fxo->wasringing = 0; + fxo->readcid = 0; + fxo->cidtimer = wc->intcount; if (debug) printk("NO RING on %d/%d!\n", wc->span.spanno, card + 1); dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_OFFHOOK); @@ -802,6 +840,8 @@ if (fxo->ringdebounce >= DAHDI_CHUNKSIZE * ringdebounce) { if (!fxo->wasringing) { fxo->wasringing = 1; + fxo->readcid = 0; + fxo->cidtimer = wc->intcount; dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_RING); if (debug) printk("RING on %d/%d!\n", wc->span.spanno, card + 1); @@ -2489,6 +2529,7 @@ module_param(battthresh, uint, 0600); module_param(ringdebounce, int, 0600); module_param(fwringdetect, int, 0600); +module_param(dtmf, int, 0600); module_param(alawoverride, int, 0600); module_param(fastpickup, int, 0600); module_param(fxotxgain, int, 0600); Index: drivers/dahdi/wctdm24xxp/wctdm24xxp.h =================================================================== --- drivers/dahdi/wctdm24xxp/wctdm24xxp.h (revision 4441) +++ drivers/dahdi/wctdm24xxp/wctdm24xxp.h (working copy) @@ -230,6 +230,8 @@ int lastpol; int polarity; int polaritydebounce; + int readcid; + unsigned int cidtimer; } fxo; struct fxs { int oldrxhook; Index: drivers/dahdi/wctdm24xxp/base.c =================================================================== --- drivers/dahdi/wctdm24xxp/base.c (revision 4441) +++ drivers/dahdi/wctdm24xxp/base.c (working copy) @@ -212,6 +212,7 @@ /* See vpmnlptype = 4 for more info */ static int vpmnlpmaxsupp = 0; #endif +static int dtmf = 0; static int wctdm_init_proslic(struct wctdm *wc, int card, int fast , int manual, int sane); @@ -840,6 +841,30 @@ #endif } +static inline void wctdm_dtmfcheck_fakepolarity(struct wctdm *wc, int card, int x) +{ + int sample; + /* only look for sound on the line if dtmf flag is on, it is an fxo card and line is onhook */ + if (!dtmf || !(wc->cardflag & (1 << card)) || !(wc->modtype[card] == MOD_TYPE_FXO) || wc->mods[card].fxo.offhook ) + return; + + /* don't look for noise if we're already processing it, or there is a ringing tone */ + if (!wc->mods[card].fxo.readcid && !wc->mods[card].fxo.wasringing && + wc->intcount > wc->mods[card].fxo.cidtimer + 400 ) { + sample = DAHDI_XLAW(wc->chans[card].readchunk[x], (&(wc->chans[card]))); + if (sample > 16000 || sample < -16000) { + wc->mods[card].fxo.readcid = 1; + wc->mods[card].fxo.cidtimer = wc->intcount; + if (debug) printk("DTMF CLIP on %i\n",card+1); + dahdi_qevent_lock(&wc->chans[card], DAHDI_EVENT_POLARITY); + } + } else if (wc->mods[card].fxo.readcid && wc->intcount > wc->mods[card].fxo.cidtimer + 2000) { + /* reset flags if it's been a while */ + wc->mods[card].fxo.cidtimer = wc->intcount; + wc->mods[card].fxo.readcid = 0; + } +} + static inline void wctdm_receiveprep(struct wctdm *wc, unsigned char *readchunk) { int x,y; @@ -863,6 +888,7 @@ } } cmd_decifer(wc, readchunk, y); + wctdm_dtmfcheck_fakepolarity(wc,y,x); } #ifdef VPM_SUPPORT if (wc->vpm) { @@ -1156,6 +1182,8 @@ } else if (!res) { if ((fxo->ringdebounce == 0) && fxo->wasringing) { fxo->wasringing = 0; + fxo->readcid = 0; + fxo->cidtimer = wc->intcount; if (debug) printk("NO RING on %d/%d!\n", wc->span.spanno, card + 1); dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_OFFHOOK); @@ -1183,6 +1211,8 @@ if (fxo->ringdebounce <= 0) { if (fxo->wasringing) { fxo->wasringing = 0; + fxo->readcid = 0; + fxo->cidtimer = wc->intcount; dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_OFFHOOK); if (debug) printk("NO RING on %d/%d!\n", wc->span.spanno, card + 1); @@ -3997,6 +4027,7 @@ module_param(fxsrxgain, int, 0600); module_param(ringdebounce, int, 0600); module_param(fwringdetect, int, 0600); +module_param(dtmf, int, 0600); module_param(latency, int, 0600); #ifdef VPM_SUPPORT module_param(vpmsupport, int, 0600);