From 5bda46030049dd61f9dba7758814c1d8e8316c86 Mon Sep 17 00:00:00 2001 From: Michael Cargile Date: Tue, 5 Nov 2019 13:16:48 -0500 Subject: [PATCH] app_amd: Fixed timeout issue ASTERISK_28143 attempted to fix an issue where calls with no audio would never timeout. It did so by adding AST_FRAME_NULL as a frame type to process in its calculations. Unfortunately these frames seem to show up at irregular time intervals. This resulted in app_amd returning prematurely most of the time. * Removed AST_FRAME_NULL from the calculations * Added a check to see how much time has actually passed since app_amd began ASTERISK-28608 Change-Id: I642a21b02d389b17e40ccd5357754b034c3daa42 --- apps/app_amd.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/apps/app_amd.c b/apps/app_amd.c index 1a0af3fa2d..39d0b79a94 100644 --- a/apps/app_amd.c +++ b/apps/app_amd.c @@ -162,8 +162,10 @@ static int dfltMaxWaitTimeForFrame = 50; static void isAnsweringMachine(struct ast_channel *chan, const char *data) { int res = 0; + int audioFrameCount = 0; struct ast_frame *f = NULL; struct ast_dsp *silenceDetector = NULL; + struct timeval amd_tvstart; int dspsilence = 0, framelength = 0; RAII_VAR(struct ast_format *, readFormat, NULL, ao2_cleanup); int inInitialSilence = 1; @@ -275,6 +277,9 @@ static void isAnsweringMachine(struct ast_channel *chan, const char *data) /* Set silence threshold to specified value */ ast_dsp_set_threshold(silenceDetector, silenceThreshold); + /* Set our start time so we can tie the loop to real world time and not RTP updates */ + amd_tvstart = ast_tvnow(); + /* Now we go into a loop waiting for frames from the channel */ while ((res = ast_waitfor(chan, 2 * maxWaitTimeForFrame)) > -1) { int ms = 0; @@ -293,7 +298,24 @@ static void isAnsweringMachine(struct ast_channel *chan, const char *data) break; } - if (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_NULL || f->frametype == AST_FRAME_CNG) { + /* Check to make sure we haven't gone over our real-world timeout in case frames get stalled for whatever reason */ + if ( (ast_tvdiff_ms(ast_tvnow(), amd_tvstart)) > totalAnalysisTime ) { + ast_frfree(f); + strcpy(amdStatus , "NOTSURE"); + if ( audioFrameCount == 0 ) { + ast_verb(3, "AMD: Channel [%s]. No audio data received in [%d] seconds.\n", ast_channel_name(chan), totalAnalysisTime); + sprintf(amdCause , "NOAUDIODATA-%d", iTotalTime); + break; + } + ast_verb(3, "AMD: Channel [%s]. Timeout...\n", ast_channel_name(chan)); + sprintf(amdCause , "TOOLONG-%d", iTotalTime); + break; + } + + if (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_CNG) { + /* keep track of the number of audio frames we get */ + audioFrameCount++; + /* Figure out how long the frame is in milliseconds */ if (f->frametype == AST_FRAME_VOICE) { framelength = (ast_codec_samples_count(f) / DEFAULT_SAMPLES_PER_MS);