Index: channels/chan_dahdi.c =================================================================== --- channels/chan_dahdi.c (revision 307185) +++ channels/chan_dahdi.c (working copy) @@ -313,6 +313,7 @@ static int mwilevel = 512; + #ifdef HAVE_PRI static struct ast_channel inuse; #ifdef PRI_GETSET_TIMERS @@ -1042,7 +1043,11 @@ int span; /*!< Span number */ time_t guardtime; /*!< Must wait this much time before using for new call */ int cid_signalling; /*!< CID signalling type bell202 or v23 */ - int cid_start; /*!< CID start indicator, polarity or ring */ + int cid_start; /*!< CID start indicator, polarity or ring or DTMF without warning event */ + int dtmfcid_level; + int dtmfcid_holdoff_state; /*!< State indicator that allows for line to settle before checking for dtmf energy */ + struct timeval dtmfcid_delay; /*!< Time value used for allow line to settle */ + int callingpres; /*!< The value of calling presentation that we're going to use when placing a PRI call */ int callwaitingrepeat; /*!< How many samples to wait before repeating call waiting */ int cidcwexpire; /*!< When to expire our muting for CID/CW */ @@ -1334,6 +1339,7 @@ .cid_signalling = CID_SIG_BELL, .cid_start = CID_START_RING, + .dtmfcid_level = 400, .dahditrcallerid = 0, .use_callerid = 1, .sig = -1, @@ -8456,7 +8462,8 @@ /* If we want caller id, we're in a prering state due to a polarity reversal * and we're set to use a polarity reversal to trigger the start of caller id, * grab the caller id and wait for ringing to start... */ - } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && (p->cid_start == CID_START_POLARITY || p->cid_start == CID_START_POLARITY_IN))) { + } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && (p->cid_start == CID_START_POLARITY || p->cid_start == CID_START_POLARITY_IN || p->cid_start == CID_START_DTMF_NOALERT))) { + /* If set to use DTMF CID signalling, listen for DTMF */ if (p->cid_signalling == CID_SIG_DTMF) { int k = 0; @@ -9658,8 +9665,10 @@ pfds[count].revents = 0; /* If we are monitoring for VMWI or sending CID, we need to read from the channel as well */ - if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk) - pfds[count].events |= POLLIN; + if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk || + (i->cid_start == CID_START_DTMF_NOALERT && (i->sig == SIG_FXSLS || i->sig == SIG_FXSGS || i->sig == SIG_FXSKS))) { + pfds[count].events |= POLLIN; + } count++; } } @@ -9754,7 +9763,7 @@ ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].dfd); continue; } - if (!i->mwimonitor_fsk && !i->mwisendactive) { + if (!i->mwimonitor_fsk && !i->mwisendactive && i->cid_start != CID_START_DTMF_NOALERT) { ast_log(LOG_WARNING, "Whoa.... I'm not looking for MWI or sending MWI but am reading (%d)...\n", i->subs[SUB_REAL].dfd); continue; } @@ -9781,7 +9790,42 @@ i->mwimonitoractive = 1; } } - } + /* If configured to check for a DTMF CID spill that comes without alert (e.g no polarity reversal) */ + } else if (i->cid_start == CID_START_DTMF_NOALERT) { + int energy; + struct timeval now; + /* State machine dtmfcid_holdoff_state allows for the line to settle + * before checking agin for dtmf energy. Presently waits for 500 mS before checking again + */ + if (1 == i->dtmfcid_holdoff_state) { + gettimeofday(&i->dtmfcid_delay, NULL); + i->dtmfcid_holdoff_state = 2; + } else if (2 == i->dtmfcid_holdoff_state) { + gettimeofday(&now, NULL); + if ((int)(now.tv_sec - i->dtmfcid_delay.tv_sec) * 1000000 + (int)now.tv_usec - (int)i->dtmfcid_delay.tv_usec > 500000) { + i->dtmfcid_holdoff_state = 0; + } + } else { + energy = calc_energy((unsigned char *) buf, res, AST_LAW(i)); + if (!i->mwisendactive && energy > i->dtmfcid_level) { + pthread_t threadid; + struct ast_channel *chan; + ast_mutex_unlock(&iflock); + chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0); + if (!chan) { + ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel); + } else { + res = ast_pthread_create_detached(&threadid, NULL, ss_thread, chan); + if (res) { + ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); + } else { + i->dtmfcid_holdoff_state = 1; + } + } + ast_mutex_lock(&iflock); + } + } + } if (i->mwisendactive) { mwi_send_process_buffer(i, res); } @@ -10579,6 +10623,7 @@ tmp->use_callerid = conf->chan.use_callerid; tmp->cid_signalling = conf->chan.cid_signalling; tmp->cid_start = conf->chan.cid_start; + tmp->dtmfcid_level = conf->chan.dtmfcid_level; tmp->dahditrcallerid = conf->chan.dahditrcallerid; tmp->restrictcid = conf->chan.restrictcid; tmp->use_callingpres = conf->chan.use_callingpres; @@ -16306,8 +16351,12 @@ confp->chan.cid_start = CID_START_POLARITY_IN; else if (!strcasecmp(v->value, "polarity")) confp->chan.cid_start = CID_START_POLARITY; + else if (!strcasecmp(v->value, "dtmf")) + confp->chan.cid_start = CID_START_DTMF_NOALERT; else if (ast_true(v->value)) confp->chan.cid_start = CID_START_RING; + } else if (!strcasecmp(v->name, "dtmfcidlevel")) { + confp->chan.dtmfcid_level = atoi(v->value); } else if (!strcasecmp(v->name, "threewaycalling")) { confp->chan.threewaycalling = ast_true(v->value); } else if (!strcasecmp(v->name, "cancallforward")) { Index: include/asterisk/callerid.h =================================================================== --- include/asterisk/callerid.h (revision 307185) +++ include/asterisk/callerid.h (working copy) @@ -63,6 +63,7 @@ #define CID_START_RING 1 #define CID_START_POLARITY 2 #define CID_START_POLARITY_IN 3 +#define CID_START_DTMF_NOALERT 4 /* defines dealing with message waiting indication generation */ /*! MWI SDMF format */