diff options
authortwilson <twilson@f38db490-d61c-443f-a65b-d21fe96a405b>2010-10-13 23:01:56 +0000
committertwilson <twilson@f38db490-d61c-443f-a65b-d21fe96a405b>2010-10-13 23:01:56 +0000
commit117aaf9bce95f3f5963dd37e4b014d5dc49920d0 (patch)
parentcc921f6a349c8d58183721170a1c3e7732900792 (diff)
Merged revisions 291580 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r291580 | twilson | 2010-10-13 15:58:43 -0700 (Wed, 13 Oct 2010) | 28 lines 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.8@291581 f38db490-d61c-443f-a65b-d21fe96a405b
1 files changed, 12 insertions, 1 deletions
diff --git a/main/channel.c b/main/channel.c
index 120138b43..135b0068f 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -3611,7 +3611,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)
- 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;
+ }