[asterisk-commits] mmichelson: branch mmichelson/more_transfer r388894 - /team/mmichelson/more_t...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed May 15 16:02:44 CDT 2013
Author: mmichelson
Date: Wed May 15 16:02:42 2013
New Revision: 388894
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=388894
Log:
Filling in the attended_transfer_bridge() function.
Modified:
team/mmichelson/more_transfer/main/bridging.c
Modified: team/mmichelson/more_transfer/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/more_transfer/main/bridging.c?view=diff&rev=388894&r1=388893&r2=388894
==============================================================================
--- team/mmichelson/more_transfer/main/bridging.c (original)
+++ team/mmichelson/more_transfer/main/bridging.c Wed May 15 16:02:42 2013
@@ -59,6 +59,7 @@
#include "asterisk/features.h"
#include "asterisk/cli.h"
#include "asterisk/parking.h"
+#include "asterisk/core_local.h"
/*! All bridges container. */
static struct ao2_container *bridges;
@@ -4869,22 +4870,55 @@
return AST_BRIDGE_TRANSFER_SUCCESS;
}
-static enum ast_transfer_result attended_transfer_bridge(struct ast_channel *chan_bridged,
- struct ast_channel *chan_unbridged, struct ast_bridge *bridge)
-{
- /* This needs to do the following:
- * 1) Create a local channel
- * 2) Masquerade the local ;2 channel into the chan_unbridged channel
- * 3) Add the local ;1 channel to the bridge (swapping the chan_bridged out).
- *
- * The problem is that we've got a bit of a dicey situation with the local
- * channel for now. When we request a local channel, all we have is the ;1 channel.
- * We don't have the ability to masquerade the ;2 side the way we'd like. For now
- * this function is a stub;
- */
-
-/* BUGBUG This needs unreal channel support */
- return AST_BRIDGE_TRANSFER_INVALID;
+/*!
+ * \brief Perform an attended transfer of a bridge
+ *
+ * This performs an attended transfer of an entire bridge to a target.
+ * The target varies, depending on what bridges exist during the transfer
+ * attempt.
+ *
+ * If two bridges exist, then a local channel is created to link the two
+ * bridges together. Local channel optimization may result in the bridges
+ * merging.
+ *
+ * If only one bridge exists, then a local channel is created with one end
+ * placed into the existing bridge and the other end masquerading into
+ * the unbridged channel.
+ *
+ * \param chan1 Transferer channel. Guaranteed to be bridged.
+ * \param chan2 Other transferer channel. May or may not be bridged.
+ * \param bridge1 Bridge that chan1 is in. Guaranteed to be non-NULL.
+ * \param bridge2 Bridge that chan2 is in. If NULL, then chan2 is not bridged.
+ * \retval AST_BRIDGE_TRANSFER_FAIL Internal error occurred
+ * \retval AST_BRIDGE_TRANSFER_SUCCESS Succesfully transferred the bridge
+ */
+static enum ast_transfer_result attended_transfer_bridge(struct ast_channel *chan1,
+ struct ast_channel *chan2, struct ast_bridge *bridge1, struct ast_bridge *bridge2)
+{
+ struct ast_channel *local_chan;
+ int cause;
+
+ local_chan = ast_request("Local", ast_channel_nativeformats(chan1), chan1,
+ "BridgeAttendedTransfer", &cause);
+
+ if (!local_chan) {
+ return AST_BRIDGE_TRANSFER_FAIL;
+ }
+
+ if (bridge2) {
+ ast_local_setup_bridge(local_chan, bridge2, chan2, NULL);
+ } else {
+ ast_local_setup_masquerade(local_chan, chan2);
+ }
+
+ ast_call(local_chan, "BridgeAttendedTransfer", 0);
+
+ if (ast_bridge_impart(bridge1, local_chan, chan1, NULL, 1)) {
+ ast_hangup(local_chan);
+ return AST_BRIDGE_TRANSFER_FAIL;
+ }
+
+ return AST_BRIDGE_TRANSFER_SUCCESS;
}
/*!
@@ -5162,13 +5196,8 @@
/* Let's get the easy one out of the way first */
if (to_transferee_bridge && to_target_bridge) {
- /* This needs to do the following:
- * 1) Create a local channel
- * 2) Impart the local ;1 channel to to_transferee_bridge, swapping out to_transferee
- * 3) Impart the local ;2 channel to to_target_bridge, swapping out to_target
- */
-/* BUGBUG This needs unreal channel support */
- return AST_BRIDGE_TRANSFER_INVALID;
+ return attended_transfer_bridge(to_transferee, to_transfer_target,
+ to_transferee_bridge, to_target_bridge);
}
the_bridge = to_transferee_bridge ?: to_target_bridge;
@@ -5199,7 +5228,7 @@
}
if (do_bridge_transfer) {
- return attended_transfer_bridge(chan_bridged, chan_unbridged, the_bridge);
+ return attended_transfer_bridge(chan_bridged, chan_unbridged, the_bridge, NULL);
}
transferee = get_transferee(channels, chan_bridged);
More information about the asterisk-commits
mailing list