[svn-commits] russell: branch russell/issue_12658 r162996 - in /team/russell/issue_12658: i...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Dec 11 08:42:26 CST 2008


Author: russell
Date: Thu Dec 11 08:42:25 2008
New Revision: 162996

URL: http://svn.digium.com/view/asterisk?view=rev&rev=162996
Log:
Add the first part of the fix for issue #12658.  This fixes a scenario where
autoservice can cause the order of received digits to be swapped.  The error
edge case occurred when there were DTMF frames on the channel readq at the
time that the channel is taken out of autoservice, and deferred signaling
frames are getting put back on the readq.

Modified:
    team/russell/issue_12658/include/asterisk/channel.h
    team/russell/issue_12658/main/autoservice.c
    team/russell/issue_12658/main/channel.c

Modified: team/russell/issue_12658/include/asterisk/channel.h
URL: http://svn.digium.com/view/asterisk/team/russell/issue_12658/include/asterisk/channel.h?view=diff&rev=162996&r1=162995&r2=162996
==============================================================================
--- team/russell/issue_12658/include/asterisk/channel.h (original)
+++ team/russell/issue_12658/include/asterisk/channel.h Thu Dec 11 08:42:25 2008
@@ -632,6 +632,20 @@
 /*! \brief Queue an outgoing frame */
 int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f);
 
+/*!
+ * \brief Queue an outgoing frame to the head of the frame queue
+ *
+ * \param chan the channel to queue the frame on
+ * \param f the frame to queue.  Note that this frame will be duplicated by
+ *        this function.  It is the responsibility of the caller to handle
+ *        freeing the memory associated with the frame being passed if
+ *        necessary.
+ *
+ * \retval 0 success
+ * \retval non-zero failure
+ */
+int ast_queue_frame_head(struct ast_channel *chan, struct ast_frame *f);
+
 /*! \brief Queue a hangup frame */
 int ast_queue_hangup(struct ast_channel *chan);
 

Modified: team/russell/issue_12658/main/autoservice.c
URL: http://svn.digium.com/view/asterisk/team/russell/issue_12658/main/autoservice.c?view=diff&rev=162996&r1=162995&r2=162996
==============================================================================
--- team/russell/issue_12658/main/autoservice.c (original)
+++ team/russell/issue_12658/main/autoservice.c Thu Dec 11 08:42:25 2008
@@ -61,6 +61,9 @@
 	 *  it gets stopped for the last time. */
 	unsigned int use_count;
 	unsigned int orig_end_dtmf_flag:1;
+	/*! Frames go on at the head of deferred_frames, so we have the frames
+	 *  from newest to oldest.  As we put them at the head of the readq, we'll
+	 *  end up with them in the right order for the channel's readq. */
 	AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames;
 	AST_LIST_ENTRY(asent) list;
 };
@@ -166,7 +169,7 @@
 				}
 				
 				if ((dup_f = ast_frdup(defer_frame))) {
-					AST_LIST_INSERT_TAIL(&ents[i]->deferred_frames, dup_f, frame_list);
+					AST_LIST_INSERT_HEAD(&ents[i]->deferred_frames, dup_f, frame_list);
 				}
 				
 				break;
@@ -298,10 +301,12 @@
 		ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
 	}
 
+	ast_channel_lock(chan);
 	while ((f = AST_LIST_REMOVE_HEAD(&as->deferred_frames, frame_list))) {
-		ast_queue_frame(chan, f);
+		ast_queue_frame_head(chan, f);
 		ast_frfree(f);
 	}
+	ast_channel_unlock(chan);
 
 	free(as);
 

Modified: team/russell/issue_12658/main/channel.c
URL: http://svn.digium.com/view/asterisk/team/russell/issue_12658/main/channel.c?view=diff&rev=162996&r1=162995&r2=162996
==============================================================================
--- team/russell/issue_12658/main/channel.c (original)
+++ team/russell/issue_12658/main/channel.c Thu Dec 11 08:42:25 2008
@@ -899,7 +899,7 @@
 }
 
 /*! \brief Queue an outgoing media frame */
-int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
+static int __ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin, int head)
 {
 	struct ast_frame *f;
 	struct ast_frame *cur;
@@ -908,9 +908,9 @@
 
 	/* Build us a copy and free the original one */
 	if (!(f = ast_frdup(fin))) {
-		ast_log(LOG_WARNING, "Unable to duplicate frame\n");
 		return -1;
 	}
+
 	ast_channel_lock(chan);
 
 	/* See if the last frame on the queue is a hangup, if so don't queue anything */
@@ -938,11 +938,18 @@
 			return 0;
 		}
 	}
-	AST_LIST_INSERT_TAIL(&chan->readq, f, frame_list);
+
+	if (head) {
+		AST_LIST_INSERT_HEAD(&chan->readq, f, frame_list);
+	} else {
+		AST_LIST_INSERT_TAIL(&chan->readq, f, frame_list);
+	}
+
 	if (chan->alertpipe[1] > -1) {
-		if (write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
+		if (write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah)) {
 			ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n",
 				chan->name, f->frametype, f->subclass, qlen, strerror(errno));
+		}
 #ifdef HAVE_DAHDI
 	} else if (chan->timingfd > -1) {
 		ioctl(chan->timingfd, DAHDI_TIMERPING, &blah);
@@ -950,8 +957,20 @@
 	} else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
 		pthread_kill(chan->blocker, SIGURG);
 	}
+
 	ast_channel_unlock(chan);
+
 	return 0;
+}
+
+int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
+{
+	return __ast_queue_frame(chan, fin, 0);
+}
+
+int ast_queue_frame_head(struct ast_channel *chan, struct ast_frame *fin)
+{
+	return __ast_queue_frame(chan, fin, 1);
 }
 
 /*! \brief Queue a hangup frame for channel */




More information about the svn-commits mailing list