[svn-commits] jrose: branch 12 r420934 - in /branches/12: apps/ include/asterisk/ main/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Aug 13 10:21:15 CDT 2014


Author: jrose
Date: Wed Aug 13 10:21:07 2014
New Revision: 420934

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=420934
Log:
Bridges: Fix feature interruption/unintended kick caused by external actions

If a manager or CLI user attached a mixmonitor to a call running a dynamic
bridge feature while in a bridge, the feature would be interrupted and the
channel would be forcibly kicked out of the bridge (usually ending the call
during a simple 1 to 1 call). This would also occur during any similar action
that could set the unbridge soft hangup flag, so the fix for this was to
remove unbridge from the soft hangup flags and make it a separate thing all
together.

ASTERISK-24027 #close
Reported by: mjordan
Review: https://reviewboard.asterisk.org/r/3900/


Modified:
    branches/12/apps/app_chanspy.c
    branches/12/apps/app_mixmonitor.c
    branches/12/apps/app_stack.c
    branches/12/include/asterisk/channel.h
    branches/12/main/bridge_after.c
    branches/12/main/bridge_channel.c
    branches/12/main/channel.c
    branches/12/main/channel_internal_api.c
    branches/12/main/framehook.c
    branches/12/main/pbx.c

Modified: branches/12/apps/app_chanspy.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/apps/app_chanspy.c?view=diff&rev=420934&r1=420933&r2=420934
==============================================================================
--- branches/12/apps/app_chanspy.c (original)
+++ branches/12/apps/app_chanspy.c Wed Aug 13 10:21:07 2014
@@ -504,7 +504,7 @@
 	if (!res) {
 		ast_channel_lock(autochan->chan);
 		if (ast_channel_is_bridged(autochan->chan)) {
-			ast_softhangup_nolock(autochan->chan, AST_SOFTHANGUP_UNBRIDGE);
+			ast_channel_set_unbridged_nolock(autochan->chan, 1);
 		}
 		ast_channel_unlock(autochan->chan);
 	}

Modified: branches/12/apps/app_mixmonitor.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/apps/app_mixmonitor.c?view=diff&rev=420934&r1=420933&r2=420934
==============================================================================
--- branches/12/apps/app_mixmonitor.c (original)
+++ branches/12/apps/app_mixmonitor.c Wed Aug 13 10:21:07 2014
@@ -421,7 +421,7 @@
 	if (!res) {
 		ast_channel_lock(chan);
 		if (ast_channel_is_bridged(chan)) {
-			ast_softhangup_nolock(chan, AST_SOFTHANGUP_UNBRIDGE);
+			ast_channel_set_unbridged_nolock(chan, 1);
 		}
 		ast_channel_unlock(chan);
 	}

Modified: branches/12/apps/app_stack.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/apps/app_stack.c?view=diff&rev=420934&r1=420933&r2=420934
==============================================================================
--- branches/12/apps/app_stack.c (original)
+++ branches/12/apps/app_stack.c Wed Aug 13 10:21:07 2014
@@ -976,10 +976,9 @@
 
 	/* Save non-hangup softhangup flags. */
 	saved_hangup_flags = ast_channel_softhangup_internal_flag(chan)
-		& (AST_SOFTHANGUP_ASYNCGOTO | AST_SOFTHANGUP_UNBRIDGE);
+		& AST_SOFTHANGUP_ASYNCGOTO;
 	if (saved_hangup_flags) {
-		ast_channel_clear_softhangup(chan,
-			AST_SOFTHANGUP_ASYNCGOTO | AST_SOFTHANGUP_UNBRIDGE);
+		ast_channel_clear_softhangup(chan, AST_SOFTHANGUP_ASYNCGOTO);
 	}
 
 	/* Save autoloop flag */
@@ -1028,10 +1027,6 @@
 		 */
 		do {
 			/* Check for hangup. */
-			if (ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_UNBRIDGE) {
-				saved_hangup_flags |= AST_SOFTHANGUP_UNBRIDGE;
-				ast_channel_clear_softhangup(chan, AST_SOFTHANGUP_UNBRIDGE);
-			}
 			if (ast_check_hangup(chan)) {
 				if (ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_ASYNCGOTO) {
 					ast_log(LOG_ERROR, "%s An async goto just messed up our execution location.\n",

Modified: branches/12/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/branches/12/include/asterisk/channel.h?view=diff&rev=420934&r1=420933&r2=420934
==============================================================================
--- branches/12/include/asterisk/channel.h (original)
+++ branches/12/include/asterisk/channel.h Wed Aug 13 10:21:07 2014
@@ -1049,11 +1049,6 @@
 	 */
 	AST_SOFTHANGUP_EXPLICIT =  (1 << 5),
 	/*!
-	 * Used to request that the bridge core re-evaluate the current
-	 * bridging technology in use by the bridge this channel is in.
-	 */
-	AST_SOFTHANGUP_UNBRIDGE =  (1 << 6),
-	/*!
 	 * Used to indicate that the channel is currently executing hangup
 	 * logic in the dialplan. The channel has been hungup when this is
 	 * set.
@@ -1534,6 +1529,40 @@
 int ast_check_hangup(struct ast_channel *chan);
 
 int ast_check_hangup_locked(struct ast_channel *chan);
+
+/*! \brief This function will check if the bridge needs to be re-evaluated due to
+ *         external changes.
+ *
+ *  \param chan Channel on which to check the unbridge_eval flag
+ *
+ *  \return Returns 0 if the flag is down or 1 if the flag is up.
+ */
+int ast_channel_unbridged(struct ast_channel *chan);
+
+/*! \brief ast_channel_unbridged variant. Use this if the channel
+ *         is already locked prior to calling.
+ *
+ *  \param chan Channel on which to check the unbridge flag
+ *
+ *  \return Returns 0 if the flag is down or 1 if the flag is up.
+ */
+int ast_channel_unbridged_nolock(struct ast_channel *chan);
+
+/*! \brief Sets the unbridged flag and queues a NULL frame on the channel to trigger
+ *         a check by bridge_channel_wait
+ *
+ *  \param chan Which channel is having its unbridged value set
+ *  \param value What the unbridge value is being set to
+ */
+void ast_channel_set_unbridged(struct ast_channel *chan, int value);
+
+/*! \brief Variant of ast_channel_set_unbridged. Use this if the channel
+ *         is already locked prior to calling.
+ *
+ *  \param chan Which channel is having its unbridged value set
+ *  \param value What the unbridge value is being set to
+ */
+void ast_channel_set_unbridged_nolock(struct ast_channel *chan, int value);
 
 /*!
  * \brief Lock the given channel, then request softhangup on the channel with the given causecode

Modified: branches/12/main/bridge_after.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/main/bridge_after.c?view=diff&rev=420934&r1=420933&r2=420934
==============================================================================
--- branches/12/main/bridge_after.c (original)
+++ branches/12/main/bridge_after.c Wed Aug 13 10:21:07 2014
@@ -452,9 +452,9 @@
 	int goto_failed = -1;
 
 	/* We are going to be leaving the bridging system now;
-	 * clear any pending UNBRIDGE flags
+	 * clear any pending unbridge flags
 	 */
-	ast_channel_clear_softhangup(chan, AST_SOFTHANGUP_UNBRIDGE);
+	ast_channel_set_unbridged(chan, 0);
 
 	/* Determine if we are going to setup a dialplan location and where. */
 	if (ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_ASYNCGOTO) {

Modified: branches/12/main/bridge_channel.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/main/bridge_channel.c?view=diff&rev=420934&r1=420933&r2=420934
==============================================================================
--- branches/12/main/bridge_channel.c (original)
+++ branches/12/main/bridge_channel.c Wed Aug 13 10:21:07 2014
@@ -2269,8 +2269,8 @@
 		ms = bridge_channel_next_interval(bridge_channel);
 		chan = ast_waitfor_nandfds(&bridge_channel->chan, 1,
 			&bridge_channel->alert_pipe[0], 1, NULL, &outfd, &ms);
-		if (ast_channel_softhangup_internal_flag(bridge_channel->chan) & AST_SOFTHANGUP_UNBRIDGE) {
-			ast_channel_clear_softhangup(bridge_channel->chan, AST_SOFTHANGUP_UNBRIDGE);
+		if (ast_channel_unbridged(bridge_channel->chan)) {
+			ast_channel_set_unbridged(bridge_channel->chan, 0);
 			ast_bridge_channel_lock_bridge(bridge_channel);
 			bridge_channel->bridge->reconfigured = 1;
 			bridge_reconfigured(bridge_channel->bridge, 0);

Modified: branches/12/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/main/channel.c?view=diff&rev=420934&r1=420933&r2=420934
==============================================================================
--- branches/12/main/channel.c (original)
+++ branches/12/main/channel.c Wed Aug 13 10:21:07 2014
@@ -10182,11 +10182,11 @@
 int ast_channel_is_leaving_bridge(struct ast_channel *chan)
 {
 	int hangup_flags = ast_channel_softhangup_internal_flag(chan);
-	int hangup_test = hangup_flags & (AST_SOFTHANGUP_ASYNCGOTO | AST_SOFTHANGUP_UNBRIDGE);
-
-	/* This function should only return true if either ASYNCGOTO
-	 * or UNBRIDGE is set, or both flags are set. It should return
-	 * false if any other flag is set.
+	int hangup_test = hangup_flags & AST_SOFTHANGUP_ASYNCGOTO;
+
+	/* This function should only return true if only the ASYNCGOTO
+	 * is set. It should false if any other flag is set or if the
+	 * ASYNCGOTO flag is not set.
 	 */
 	return (hangup_test && (hangup_test == hangup_flags));
 }
@@ -10479,7 +10479,7 @@
 	ast_channel_lock(chan);
 	dead = ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)
 		|| (ast_channel_softhangup_internal_flag(chan)
-			& ~(AST_SOFTHANGUP_ASYNCGOTO | AST_SOFTHANGUP_UNBRIDGE));
+			& ~AST_SOFTHANGUP_ASYNCGOTO);
 	ast_channel_unlock(chan);
 	if (dead) {
 		/* Channel is a zombie or a real hangup. */

Modified: branches/12/main/channel_internal_api.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/main/channel_internal_api.c?view=diff&rev=420934&r1=420933&r2=420934
==============================================================================
--- branches/12/main/channel_internal_api.c (original)
+++ branches/12/main/channel_internal_api.c Wed Aug 13 10:21:07 2014
@@ -173,6 +173,8 @@
 							 *   See \arg \ref AstFileDesc */
 	int softhangup;				/*!< Whether or not we have been hung up...  Do not set this value
 							 *   directly, use ast_softhangup() */
+	int unbridged;              /*!< If non-zero, the bridge core needs to re-evaluate the current
+	                                 bridging technology which is in use by this channel's bridge. */
 	int fdno;					/*!< Which fd had an event detected on */
 	int streamid;					/*!< For streaming playback, the schedule ID */
 	int vstreamid;					/*!< For streaming video playback, the schedule ID */
@@ -377,7 +379,6 @@
 	ast_data_add_bool(data_softhangup, "timeout", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_TIMEOUT);
 	ast_data_add_bool(data_softhangup, "appunload", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_APPUNLOAD);
 	ast_data_add_bool(data_softhangup, "explicit", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_EXPLICIT);
-	ast_data_add_bool(data_softhangup, "unbridge", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_UNBRIDGE);
 
 	/* channel flags */
 	data_flags = ast_data_add_node(tree, "flags");
@@ -1115,6 +1116,33 @@
 	chan ->softhangup &= ~value;
 }
 
+int ast_channel_unbridged_nolock(struct ast_channel *chan)
+{
+	return chan->unbridged;
+}
+
+int ast_channel_unbridged(struct ast_channel *chan)
+{
+	int res;
+	ast_channel_lock(chan);
+	res = ast_channel_unbridged_nolock(chan);
+	ast_channel_unlock(chan);
+	return res;
+}
+
+void ast_channel_set_unbridged_nolock(struct ast_channel *chan, int value)
+{
+	chan->unbridged = value;
+	ast_queue_frame(chan, &ast_null_frame);
+}
+
+void ast_channel_set_unbridged(struct ast_channel *chan, int value)
+{
+	ast_channel_lock(chan);
+	ast_channel_set_unbridged_nolock(chan, value);
+	ast_channel_unlock(chan);
+}
+
 void ast_channel_callid_cleanup(struct ast_channel *chan)
 {
 	if (chan->callid) {

Modified: branches/12/main/framehook.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/main/framehook.c?view=diff&rev=420934&r1=420933&r2=420934
==============================================================================
--- branches/12/main/framehook.c (original)
+++ branches/12/main/framehook.c Wed Aug 13 10:21:07 2014
@@ -170,7 +170,7 @@
 	}
 
 	if (ast_channel_is_bridged(chan)) {
-		ast_softhangup_nolock(chan, AST_SOFTHANGUP_UNBRIDGE);
+		ast_channel_set_unbridged_nolock(chan, 1);
 	}
 
 	return framehook->id;
@@ -199,7 +199,7 @@
 	AST_LIST_TRAVERSE_SAFE_END;
 
 	if (ast_channel_is_bridged(chan)) {
-		ast_softhangup_nolock(chan, AST_SOFTHANGUP_UNBRIDGE);
+		ast_channel_set_unbridged_nolock(chan, 1);
 	}
 
 	return res;

Modified: branches/12/main/pbx.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/main/pbx.c?view=diff&rev=420934&r1=420933&r2=420934
==============================================================================
--- branches/12/main/pbx.c (original)
+++ branches/12/main/pbx.c Wed Aug 13 10:21:07 2014
@@ -6311,11 +6311,6 @@
 			S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL),
 			&found, 1))) {
 
-			/* Defensively clear the UNBRIDGE flag in case it leaked
-			 * out of the bridging framework. UNBRIDE never implies
-			 * that a channel is hung up.
-			 */
-			ast_channel_clear_softhangup(c, AST_SOFTHANGUP_UNBRIDGE);
 			if (!ast_check_hangup(c)) {
 				ast_channel_priority_set(c, ast_channel_priority(c) + 1);
 				continue;




More information about the svn-commits mailing list