Skip to content
Snippets Groups Projects
Commit d42357fa authored by BJ Weschke's avatar BJ Weschke
Browse files

Fix a problem where if the channel was hungup during detection, the...

 Fix a problem where if the channel was hungup during detection, the application wouldn't block indefinitely looking for another frame from that channel. Don't try to do frame size analysis on a frame that isn't voice, only report DEBUG and VERBOSE msgs to the logger channels when the DEBUG and VERBOSE settings are high enough to require it, and some other minor cleanups.



git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@18023 65c4cc65-6c06-0410-ace0-fbb531ad65f3
parent 9bd9bcee
No related branches found
No related tags found
No related merge requests found
......@@ -91,7 +91,7 @@ static int dfltSilenceThreshold = 256;
static void isAnsweringMachine(struct ast_channel *chan, void *data)
{
int res = 0;
int res = 0, ret = 0;
struct ast_frame *f = NULL;
......@@ -136,8 +136,8 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
AST_APP_ARG(argMaximumNumberOfWords);
AST_APP_ARG(argSilenceThreshold);
);
ast_verbose(VERBOSE_PREFIX_3 "AMD: %s %s %s (Fmt: %d)\n", chan->name ,chan->cid.cid_ani, chan->cid.cid_rdnis, chan->readformat);
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "AMD: %s %s %s (Fmt: %d)\n", chan->name ,chan->cid.cid_ani, chan->cid.cid_rdnis, chan->readformat);
/* Lets parse the arguments. */
if (ast_strlen_zero(data)) {
......@@ -180,8 +180,9 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
}
/* Now we're ready to roll! */
ast_verbose(VERBOSE_PREFIX_3 "AMD: initialSilence [%d] greeting [%d] afterGreetingSilence [%d] "
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "AMD: initialSilence [%d] greeting [%d] afterGreetingSilence [%d] "
"totalAnalysisTime [%d] minimumWordLength [%d] betweenWordsSilence [%d] maximumNumberOfWords [%d] silenceThreshold [%d] \n",
initialSilence, greeting, afterGreetingSilence, totalAnalysisTime,
minimumWordLength, betweenWordsSilence, maximumNumberOfWords, silenceThreshold );
......@@ -204,42 +205,56 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
}
ast_dsp_set_threshold(silenceDetector, silenceThreshold );
while (ast_waitfor(chan, -1) > -1)
while ((ret = ast_waitfor(chan, totalAnalysisTime)))
{
f = ast_read(chan);
if (!f ) {
if (ret < 0) {
/* No Frame: Called Party Must Have Dropped */
ast_verbose(VERBOSE_PREFIX_3 "AMD: HANGUP\n");
ast_log(LOG_DEBUG, "Got hangup\n");
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "AMD: HANGUP\n");
if (option_debug)
ast_log(LOG_DEBUG, "Got hangup\n");
strcpy(amdStatus , "HANGUP" );
strcpy(amdCause , "" );
break;
}
framelength = (ast_codec_get_samples(f) / 8);
iTotalTime += framelength;
if (iTotalTime >= totalAnalysisTime ) {
ast_verbose(VERBOSE_PREFIX_3 "AMD: Channel [%s]. Too long...\n", chan->name );
ast_frfree(f);
strcpy(amdStatus , "NOTSURE" );
sprintf(amdCause , "TOOLONG-%d", iTotalTime );
f = ast_read(chan);
if (!f ) {
/* No Frame: Called Party Must Have Dropped */
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "AMD: HANGUP\n");
if (option_debug)
ast_log(LOG_DEBUG, "Got hangup\n");
strcpy(amdStatus , "HANGUP" );
strcpy(amdCause , "" );
break;
}
if (f->frametype == AST_FRAME_VOICE ) {
framelength = (ast_codec_get_samples(f) / DEFAULT_SAMPLES_PER_MS);
iTotalTime += framelength;
if (iTotalTime >= totalAnalysisTime ) {
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "AMD: Channel [%s]. Too long...\n", chan->name );
ast_frfree(f);
strcpy(amdStatus , "NOTSURE" );
sprintf(amdCause , "TOOLONG-%d", iTotalTime );
break;
}
dspsilence = 0;
ast_dsp_silence(silenceDetector, f, &dspsilence);
if (dspsilence ) {
silenceDuration = dspsilence;
/* ast_verbose(VERBOSE_PREFIX_3 "AMD: %d SILENCE: silenceDuration:%d afterGreetingSilence:%d inGreeting:%d\n", currentState, silenceDuration, afterGreetingSilence, inGreeting ); */
if (silenceDuration >= betweenWordsSilence ) {
if (currentState != STATE_IN_SILENCE ) {
previousState = currentState;
ast_verbose(VERBOSE_PREFIX_3 "AMD: Changed state to STATE_IN_SILENCE\n");
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "AMD: Changed state to STATE_IN_SILENCE\n");
}
currentState = STATE_IN_SILENCE;
consecutiveVoiceDuration = 0;
}
if (inInitialSilence == 1 && silenceDuration >= initialSilence ) {
ast_verbose(VERBOSE_PREFIX_3 "AMD: ANSWERING MACHINE: silenceDuration:%d initialSilence:%d\n",
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "AMD: ANSWERING MACHINE: silenceDuration:%d initialSilence:%d\n",
silenceDuration, initialSilence );
ast_frfree(f);
strcpy(amdStatus , "MACHINE" );
......@@ -248,7 +263,8 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
}
if (silenceDuration >= afterGreetingSilence && inGreeting == 1 ) {
ast_verbose(VERBOSE_PREFIX_3 "AMD: HUMAN: silenceDuration:%d afterGreetingSilence:%d\n",
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "AMD: HUMAN: silenceDuration:%d afterGreetingSilence:%d\n",
silenceDuration, afterGreetingSilence );
ast_frfree(f);
strcpy(amdStatus , "HUMAN" );
......@@ -258,21 +274,22 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
} else {
consecutiveVoiceDuration += framelength;
voiceDuration += framelength;
/* ast_verbose(VERBOSE_PREFIX_3 "AMD: %d VOICE: ConsecutiveVoice:%d voiceDuration:%d inGreeting:%d\n", currentState, consecutiveVoiceDuration, voiceDuration, inGreeting ); */
/* If I have enough consecutive voice to say that I am in a Word, I can only increment the
number of words if my previous state was Silence, which means that I moved into a word. */
if (consecutiveVoiceDuration >= minimumWordLength ) {
if (currentState == STATE_IN_SILENCE ) {
iWordsCount++;
ast_verbose(VERBOSE_PREFIX_3 "AMD: Word detected. iWordsCount:%d\n", iWordsCount );
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "AMD: Word detected. iWordsCount:%d\n", iWordsCount );
previousState = currentState;
currentState = STATE_IN_WORD;
}
}
if (iWordsCount >= maximumNumberOfWords ) {
ast_verbose(VERBOSE_PREFIX_3 "AMD: ANSWERING MACHINE: iWordsCount:%d\n", iWordsCount );
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "AMD: ANSWERING MACHINE: iWordsCount:%d\n", iWordsCount );
ast_frfree(f);
strcpy(amdStatus , "MACHINE" );
sprintf(amdCause , "MAXWORDS-%d-%d", iWordsCount, maximumNumberOfWords );
......@@ -280,9 +297,9 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
}
if (inGreeting == 1 && voiceDuration >= greeting ) {
ast_verbose(VERBOSE_PREFIX_3 "AMD: ANSWERING MACHINE: voiceDuration:%d greeting:%d\n",
voiceDuration, greeting );
ast_frfree(f);
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "AMD: ANSWERING MACHINE: voiceDuration:%d greeting:%d\n", voiceDuration, greeting);
ast_frfree(f);
strcpy(amdStatus , "MACHINE" );
sprintf(amdCause , "LONGGREETING-%d-%d", voiceDuration, greeting );
break;
......@@ -296,12 +313,19 @@ static void isAnsweringMachine(struct ast_channel *chan, void *data)
}
ast_frfree(f);
}
if (!ret) {
/* It took too long to get a frame back. Giving up. */
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "AMD: Channel [%s]. Too long...\n", chan->name );
strcpy(amdStatus , "NOTSURE" );
sprintf(amdCause , "TOOLONG-%d", iTotalTime );
}
pbx_builtin_setvar_helper(chan , "AMDSTATUS" , amdStatus );
pbx_builtin_setvar_helper(chan , "AMDCAUSE" , amdCause );
/* If We Started With A Valid Read Format, Return To It... */
if (readFormat) {
if (readFormat && chan->_state == AST_STATE_UP) {
res = ast_set_read_format(chan, readFormat );
if (res)
ast_log(LOG_WARNING, "AMD: Unable to restore read format on '%s'\n", chan->name);
......@@ -371,7 +395,8 @@ static void load_config(void)
}
ast_config_destroy(cfg);
ast_verbose(VERBOSE_PREFIX_3 "AMD defaults: initialSilence [%d] greeting [%d] afterGreetingSilence [%d] "
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "AMD defaults: initialSilence [%d] greeting [%d] afterGreetingSilence [%d] "
"totalAnalysisTime [%d] minimumWordLength [%d] betweenWordsSilence [%d] maximumNumberOfWords [%d] silenceThreshold [%d] \n",
dfltInitialSilence, dfltGreeting, dfltAfterGreetingSilence, dfltTotalAnalysisTime,
dfltMinimumWordLength, dfltBetweenWordsSilence, dfltMaximumNumberOfWords, dfltSilenceThreshold );
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment