[svn-commits] file: branch file/bridging r106792 - /team/file/bridging/main/bridging.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Mar 7 13:52:37 CST 2008


Author: file
Date: Fri Mar  7 13:52:36 2008
New Revision: 106792

URL: http://svn.digium.com/view/asterisk?view=rev&rev=106792
Log:
Don't try to depart a channel that is being hung up. As well this adds a DTMF key combination to attended transfers to abort the transfer.

Modified:
    team/file/bridging/main/bridging.c

Modified: team/file/bridging/main/bridging.c
URL: http://svn.digium.com/view/asterisk/team/file/bridging/main/bridging.c?view=diff&rev=106792&r1=106791&r2=106792
==============================================================================
--- team/file/bridging/main/bridging.c (original)
+++ team/file/bridging/main/bridging.c Fri Mar  7 13:52:36 2008
@@ -1066,7 +1066,7 @@
 	ast_mutex_lock(&bridge->lock);
 
 	/* Look for channel in the bridge */
-	if (!(bridge_channel = find_bridge_channel(bridge, chan))) {
+	if (!(bridge_channel = find_bridge_channel(bridge, chan)) || (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_HANGUP)) {
 		ast_mutex_unlock(&bridge->lock);
 		return -1;
 	}
@@ -1341,6 +1341,29 @@
 	return 0;
 }
 
+/*! \brief Attended transfer abort feature */
+static int attended_abort_transfer(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
+{
+	struct ast_bridge_channel *called_bridge_channel = NULL;
+
+	/* It is possible (albeit unlikely) that the bridge channels list may change, so we have to ensure we do all of our magic while locked */
+	ast_mutex_lock(&bridge->lock);
+	if (!(called_bridge_channel = (AST_LIST_FIRST(&bridge->channels) != bridge_channel ? AST_LIST_FIRST(&bridge->channels) : AST_LIST_LAST(&bridge->channels)))) {
+		bridge_channel->state = AST_BRIDGE_CHANNEL_STATE_END;
+		ast_mutex_unlock(&bridge->lock);
+		return 0;
+	}
+
+	/* Now we basically eject the other channel from the bridge. This will cause their thread to hang them up, and our own code to consider the transfer failed. */
+	ast_bridge_change_state(called_bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
+
+	bridge_channel->state = AST_BRIDGE_CHANNEL_STATE_END;
+
+	ast_mutex_unlock(&bridge->lock);
+
+	return 0;
+}
+
 /*! \brief Internal built in feature for attended transfers */
 static int feature_attended_transfer(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 {
@@ -1381,8 +1404,9 @@
 
 	/* Before we join setup a features structure with the hangup option, just in case they want to use DTMF */
 	ast_bridge_features_init(&caller_features);
-	ast_bridge_features_enable(&caller_features, AST_BRIDGE_BUILTIN_HANGUP, "*");
-	ast_bridge_features_hook(&caller_features, "#", attended_threeway_transfer, NULL);
+	ast_bridge_features_enable(&caller_features, AST_BRIDGE_BUILTIN_HANGUP, "*1");
+	ast_bridge_features_hook(&caller_features, "*2", attended_threeway_transfer, NULL);
+	ast_bridge_features_hook(&caller_features, "*3", attended_abort_transfer, NULL);
 
 	/* But for the caller we want to join the bridge in a blocking fashion so we don't spin around in this function doing nothing while waiting */
 	attended_bridge_result = ast_bridge_join(attended_bridge, bridge_channel->chan, NULL, &caller_features);




More information about the svn-commits mailing list