mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 04:11:08 +00:00
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
This commit is contained in:
@@ -162,8 +162,10 @@ static int dfltMaxWaitTimeForFrame = 50;
|
|||||||
static void isAnsweringMachine(struct ast_channel *chan, const char *data)
|
static void isAnsweringMachine(struct ast_channel *chan, const char *data)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
int audioFrameCount = 0;
|
||||||
struct ast_frame *f = NULL;
|
struct ast_frame *f = NULL;
|
||||||
struct ast_dsp *silenceDetector = NULL;
|
struct ast_dsp *silenceDetector = NULL;
|
||||||
|
struct timeval amd_tvstart;
|
||||||
int dspsilence = 0, framelength = 0;
|
int dspsilence = 0, framelength = 0;
|
||||||
RAII_VAR(struct ast_format *, readFormat, NULL, ao2_cleanup);
|
RAII_VAR(struct ast_format *, readFormat, NULL, ao2_cleanup);
|
||||||
int inInitialSilence = 1;
|
int inInitialSilence = 1;
|
||||||
@@ -275,6 +277,9 @@ static void isAnsweringMachine(struct ast_channel *chan, const char *data)
|
|||||||
/* Set silence threshold to specified value */
|
/* Set silence threshold to specified value */
|
||||||
ast_dsp_set_threshold(silenceDetector, silenceThreshold);
|
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 */
|
/* Now we go into a loop waiting for frames from the channel */
|
||||||
while ((res = ast_waitfor(chan, 2 * maxWaitTimeForFrame)) > -1) {
|
while ((res = ast_waitfor(chan, 2 * maxWaitTimeForFrame)) > -1) {
|
||||||
int ms = 0;
|
int ms = 0;
|
||||||
@@ -293,7 +298,24 @@ static void isAnsweringMachine(struct ast_channel *chan, const char *data)
|
|||||||
break;
|
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 */
|
/* Figure out how long the frame is in milliseconds */
|
||||||
if (f->frametype == AST_FRAME_VOICE) {
|
if (f->frametype == AST_FRAME_VOICE) {
|
||||||
framelength = (ast_codec_samples_count(f) / DEFAULT_SAMPLES_PER_MS);
|
framelength = (ast_codec_samples_count(f) / DEFAULT_SAMPLES_PER_MS);
|
||||||
|
Reference in New Issue
Block a user