[asterisk-commits] rmudgett: branch 10 r375965 - in /branches/10: ./ include/asterisk/ main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Nov 6 12:27:25 CST 2012


Author: rmudgett
Date: Tue Nov  6 12:27:19 2012
New Revision: 375965

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=375965
Log:
Fix stuck DTMF when bridge is broken.

When a bridge is broken by an AMI Redirect action or the ChannelRedirect
application, an in progress DTMF digit could be stuck sending forever.

* Made simulate a DTMF end event when a bridge is broken and a DTMF digit
was in progress.

(closes issue ASTERISK-20492)
Reported by: Jeremiah Gowdy
Patches:
      bridge_end_dtmf-v3.patch.txt (license #6358) patch uploaded by Jeremiah Gowdy
      Modified to jira_asterisk_20492_v1.8.patch
      jira_asterisk_20492_v1.8.patch (license #5621) patch uploaded by rmudgett
Tested by: rmudgett

Review: https://reviewboard.asterisk.org/r/2169/
........

Merged revisions 375964 from http://svn.asterisk.org/svn/asterisk/branches/1.8

Modified:
    branches/10/   (props changed)
    branches/10/.cleancount
    branches/10/include/asterisk/channel.h
    branches/10/include/asterisk/features.h
    branches/10/main/channel.c
    branches/10/main/features.c

Propchange: branches/10/
------------------------------------------------------------------------------
Binary property 'branch-1.8-merged' - no diff available.

Modified: branches/10/.cleancount
URL: http://svnview.digium.com/svn/asterisk/branches/10/.cleancount?view=diff&rev=375965&r1=375964&r2=375965
==============================================================================
--- branches/10/.cleancount (original)
+++ branches/10/.cleancount Tue Nov  6 12:27:19 2012
@@ -1,3 +1,1 @@
-39
-
-
+40

Modified: branches/10/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/branches/10/include/asterisk/channel.h?view=diff&rev=375965&r1=375964&r2=375965
==============================================================================
--- branches/10/include/asterisk/channel.h (original)
+++ branches/10/include/asterisk/channel.h Tue Nov  6 12:27:19 2012
@@ -874,6 +874,8 @@
 	char macrocontext[AST_MAX_CONTEXT];		/*!< Macro: Current non-macro context. See app_macro.c */
 	char macroexten[AST_MAX_EXTENSION];		/*!< Macro: Current non-macro extension. See app_macro.c */
 	char emulate_dtmf_digit;			/*!< Digit being emulated */
+	char sending_dtmf_digit;			/*!< Digit this channel is currently sending out. (zero if not sending) */
+	struct timeval sending_dtmf_tv;		/*!< The time this channel started sending the current digit. (Invalid if sending_dtmf_digit is zero.) */
 };
 
 /*! \brief ast_channel_tech Properties */

Modified: branches/10/include/asterisk/features.h
URL: http://svnview.digium.com/svn/asterisk/branches/10/include/asterisk/features.h?view=diff&rev=375965&r1=375964&r2=375965
==============================================================================
--- branches/10/include/asterisk/features.h (original)
+++ branches/10/include/asterisk/features.h Tue Nov  6 12:27:19 2012
@@ -169,6 +169,18 @@
 /*! \brief Determine system call pickup extension */
 const char *ast_pickup_ext(void);
 
+/*!
+ * \brief Simulate a DTMF end on a broken bridge channel.
+ *
+ * \param chan Channel sending DTMF that has not ended.
+ * \param digit DTMF digit to stop.
+ * \param start DTMF digit start time.
+ * \param why Reason bridge broken.
+ *
+ * \return Nothing
+ */
+void ast_bridge_end_dtmf(struct ast_channel *chan, char digit, struct timeval start, const char *why);
+
 /*! \brief Bridge a call, optionally allowing redirection */
 int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer,struct ast_bridge_config *config);
 

Modified: branches/10/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/branches/10/main/channel.c?view=diff&rev=375965&r1=375964&r2=375965
==============================================================================
--- branches/10/main/channel.c (original)
+++ branches/10/main/channel.c Tue Nov  6 12:27:19 2012
@@ -71,6 +71,7 @@
 #include "asterisk/stringfields.h"
 #include "asterisk/global_datastores.h"
 #include "asterisk/data.h"
+#include "asterisk/features.h"
 
 #ifdef HAVE_EPOLL
 #include <sys/epoll.h>
@@ -4740,6 +4741,11 @@
 	if (!chan->tech->send_digit_begin)
 		return 0;
 
+	ast_channel_lock(chan);
+	chan->sending_dtmf_digit = digit;
+	chan->sending_dtmf_tv = ast_tvnow();
+	ast_channel_unlock(chan);
+
 	if (!chan->tech->send_digit_begin(chan, digit))
 		return 0;
 
@@ -4762,6 +4768,12 @@
 int ast_senddigit_end(struct ast_channel *chan, char digit, unsigned int duration)
 {
 	int res = -1;
+
+	ast_channel_lock(chan);
+	if (chan->sending_dtmf_digit == digit) {
+		chan->sending_dtmf_digit = 0;
+	}
+	ast_channel_unlock(chan);
 
 	if (chan->tech->send_digit_end)
 		res = chan->tech->send_digit_end(chan, digit, duration);
@@ -6711,6 +6723,8 @@
 	char orig[AST_CHANNEL_NAME];
 	char masqn[AST_CHANNEL_NAME];
 	char zombn[AST_CHANNEL_NAME];
+	char clone_sending_dtmf_digit;
+	struct timeval clone_sending_dtmf_tv;
 
 	/* XXX This operation is a bit odd.  We're essentially putting the guts of
 	 * the clone channel into the original channel.  Start by killing off the
@@ -6820,6 +6834,10 @@
 	free_translation(clonechan);
 	free_translation(original);
 
+	/* Save the current DTMF digit being sent if any. */
+	clone_sending_dtmf_digit = clonechan->sending_dtmf_digit;
+	clone_sending_dtmf_tv = clonechan->sending_dtmf_tv;
+
 	/* Save the original name */
 	ast_copy_string(orig, original->name, sizeof(orig));
 	/* Save the new name */
@@ -7063,6 +7081,15 @@
 	}
 
 	ast_channel_unlock(clonechan);
+
+	if (clone_sending_dtmf_digit) {
+		/*
+		 * The clonechan was sending a DTMF digit that was not completed
+		 * before the masquerade.
+		 */
+		ast_bridge_end_dtmf(original, clone_sending_dtmf_digit, clone_sending_dtmf_tv,
+			"masquerade");
+	}
 
 	/*
 	 * If an indication is currently playing, maintain it on the

Modified: branches/10/main/features.c
URL: http://svnview.digium.com/svn/asterisk/branches/10/main/features.c?view=diff&rev=375965&r1=375964&r2=375965
==============================================================================
--- branches/10/main/features.c (original)
+++ branches/10/main/features.c Tue Nov  6 12:27:19 2012
@@ -3910,6 +3910,24 @@
 	ast_channel_unlock(chan);
 }
 
+void ast_bridge_end_dtmf(struct ast_channel *chan, char digit, struct timeval start, const char *why)
+{
+	int dead;
+	long duration;
+
+	ast_channel_lock(chan);
+	dead = ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan);
+	ast_channel_unlock(chan);
+	if (dead) {
+		return;
+	}
+
+	duration = ast_tvdiff_ms(ast_tvnow(), start);
+	ast_senddigit_end(chan, digit, duration);
+	ast_log(LOG_DTMF, "DTMF end '%c' simulated on %s due to %s, duration %ld ms\n",
+		digit, chan->name, why, duration);
+}
+
 /*!
  * \brief bridge the call and set CDR
  *
@@ -4357,6 +4375,15 @@
 	ast_cel_report_event(chan, AST_CEL_BRIDGE_END, NULL, NULL, peer);
 
 before_you_go:
+	if (chan->sending_dtmf_digit) {
+		ast_bridge_end_dtmf(chan, chan->sending_dtmf_digit, chan->sending_dtmf_tv,
+			"bridge end");
+	}
+	if (peer->sending_dtmf_digit) {
+		ast_bridge_end_dtmf(peer, peer->sending_dtmf_digit, peer->sending_dtmf_tv,
+			"bridge end");
+	}
+
 	/* Just in case something weird happened and we didn't clean up the silence generator... */
 	if (silgen) {
 		ast_channel_stop_silence_generator(who == chan ? peer : chan, silgen);




More information about the asterisk-commits mailing list