diff options
author | twilson <twilson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-10-13 22:58:43 +0000 |
---|---|---|
committer | twilson <twilson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-10-13 22:58:43 +0000 |
commit | b56e3d1921719fa54414df0a3de495029b67ce49 (patch) | |
tree | e4df77e1c81d80357a65157bfadf19af77f7311b /main | |
parent | 37315bb32c1d6a32cb6ee02b038136cd9249860c (diff) |
Merged revisions 291577 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r291577 | twilson | 2010-10-13 15:45:15 -0700 (Wed, 13 Oct 2010) | 21 lines
Don't ignore frames that have been queued when softhangup'd
When an outgoing call is answered and hung up by the far end *very* quickly, we
may not read any frames and therefor end up with a call that displays the wrong
disposition/DIALSTATUS. The reason is because ast_queue_hangup() immediately
sets the _softhangup flag on the channel and then queues the HANGUP control
frame, but __ast_read refuses to read any frames if ast_check_hangup() indicates
that a hangup request has been made (which it will if _softhangup is set). So,
we end up losing control frames.
This change makes __ast_read continue to read frames even if a soft hangup has
been requested. It queues a hangup frame to make sure that __ast_read() will
still eventually return NULL.
Much thanks to David Vossel for all of the reviews, discussion, and help!
(closes issue #16946)
Reported by: davidw
Review: https://reviewboard.asterisk.org/r/740/
........
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.2@291580 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main')
-rw-r--r-- | main/channel.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/main/channel.c b/main/channel.c index f60f76c78..7df055810 100644 --- a/main/channel.c +++ b/main/channel.c @@ -2731,7 +2731,18 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio) if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) { if (chan->generator) ast_deactivate_generator(chan); - goto done; + + /* It is possible for chan->_softhangup to be set, yet there still be control + * frames that still need to be read. Instead of just going to 'done' in the + * case of ast_check_hangup(), we instead need to send the HANGUP frame so that + * it can mark the end of the read queue. If there are frames to be read, + * ast_queue_control will be called repeatedly, but will only queue one hangup + * frame. */ + if (ast_check_hangup(chan)) { + ast_queue_control(chan, AST_CONTROL_HANGUP); + } else { + goto done; + } } #ifdef AST_DEVMODE |