[asterisk-commits] file: branch file/bridging r106792 - /team/file/bridging/main/bridging.c
SVN commits to the Asterisk project
asterisk-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 asterisk-commits
mailing list