summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/app_amd.c83
1 files changed, 54 insertions, 29 deletions
diff --git a/apps/app_amd.c b/apps/app_amd.c
index 850fda37c..f44c1af20 100644
--- a/apps/app_amd.c
+++ b/apps/app_amd.c
@@ -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 );