[asterisk-commits] mmichelson: branch mmichelson/more_transfer r387589 - in /team/mmichelson/mor...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri May 3 12:51:42 CDT 2013


Author: mmichelson
Date: Fri May  3 12:51:39 2013
New Revision: 387589

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=387589
Log:
Resolve conflict and reset automerge.


Modified:
    team/mmichelson/more_transfer/   (props changed)
    team/mmichelson/more_transfer/apps/app_stack.c
    team/mmichelson/more_transfer/bridges/bridge_builtin_features.c
    team/mmichelson/more_transfer/build_tools/post_process_documentation.py
    team/mmichelson/more_transfer/channels/chan_gulp.c
    team/mmichelson/more_transfer/channels/chan_local.c
    team/mmichelson/more_transfer/include/asterisk/bridging.h
    team/mmichelson/more_transfer/include/asterisk/channel.h
    team/mmichelson/more_transfer/main/bridging.c
    team/mmichelson/more_transfer/main/channel.c
    team/mmichelson/more_transfer/res/res_sip_sdp_rtp.c

Propchange: team/mmichelson/more_transfer/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/mmichelson/more_transfer/
------------------------------------------------------------------------------
--- bridge_construction-integrated (original)
+++ bridge_construction-integrated Fri May  3 12:51:39 2013
@@ -1,1 +1,1 @@
-/trunk:1-387423
+/trunk:1-387545

Propchange: team/mmichelson/more_transfer/
------------------------------------------------------------------------------
--- more_transfer-integrated (original)
+++ more_transfer-integrated Fri May  3 12:51:39 2013
@@ -1,1 +1,1 @@
-/team/mmichelson/transfer:1-387495
+/team/mmichelson/transfer:1-387588

Propchange: team/mmichelson/more_transfer/
------------------------------------------------------------------------------
--- transfer-integrated (original)
+++ transfer-integrated Fri May  3 12:51:39 2013
@@ -1,1 +1,1 @@
-/team/group/bridge_construction:1-387471
+/team/group/bridge_construction:1-387555

Modified: team/mmichelson/more_transfer/apps/app_stack.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/more_transfer/apps/app_stack.c?view=diff&rev=387589&r1=387588&r2=387589
==============================================================================
--- team/mmichelson/more_transfer/apps/app_stack.c (original)
+++ team/mmichelson/more_transfer/apps/app_stack.c Fri May  3 12:51:39 2013
@@ -40,6 +40,7 @@
 #include "asterisk/manager.h"
 #include "asterisk/channel.h"
 #include "asterisk/agi.h"
+#include "asterisk/stasis_channels.h"
 
 /*** DOCUMENTATION
 	<application name="Gosub" language="en_US">
@@ -202,7 +203,32 @@
 			<para>Cause the channel to execute the specified dialplan subroutine,
 			returning to the dialplan with execution of a Return().</para>
 		</description>
+		<see-also>
+			<ref type="application">GoSub</ref>
+		</see-also>
 	</agi>
+	<managerEvent language="en_US" name="VarSet">
+		<managerEventInstance class="EVENT_FLAG_DIALPLAN">
+			<synopsis>Raised when a variable local to the gosub stack frame is set due to a subroutine call.</synopsis>
+			<syntax>
+				<xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
+				<parameter name="Variable">
+					<para>The LOCAL variable being set.</para>
+					<note><para>The variable name will always be enclosed with
+					<literal>LOCAL()</literal></para></note>
+				</parameter>
+				<parameter name="Value">
+					<para>The new value of the variable.</para>
+				</parameter>
+			</syntax>
+			<see-also>
+				<ref type="application">GoSub</ref>
+				<ref type="agi">gosub</ref>
+				<ref type="function">LOCAL</ref>
+				<ref type="function">LOCAL_PEEK</ref>
+			</see-also>
+		</managerEventInstance>
+	</managerEvent>
  ***/
 
 static const char app_gosub[] = "Gosub";
@@ -235,6 +261,8 @@
 {
 	struct ast_var_t *variables;
 	int found = 0;
+	int len;
+	RAII_VAR(char *, local_buffer, NULL, ast_free);
 
 	/* Does this variable already exist? */
 	AST_LIST_TRAVERSE(&frame->varshead, variables, entries) {
@@ -252,20 +280,13 @@
 		pbx_builtin_setvar_helper(chan, var, value);
 	}
 
-	/*** DOCUMENTATION
-	<managerEventInstance>
-		<synopsis>Raised when a LOCAL channel variable is set due to a subroutine call.</synopsis>
-		<see-also>
-			<ref type="application">GoSub</ref>
-		</see-also>
-	</managerEventInstance>
-	***/
-	manager_event(EVENT_FLAG_DIALPLAN, "VarSet",
-		"Channel: %s\r\n"
-		"Variable: LOCAL(%s)\r\n"
-		"Value: %s\r\n"
-		"Uniqueid: %s\r\n",
-		ast_channel_name(chan), var, value, ast_channel_uniqueid(chan));
+	len = 8 + strlen(var); /* LOCAL() + var */
+	local_buffer = ast_malloc(len);
+	if (!local_buffer) {
+		return 0;
+	}
+	sprintf(local_buffer, "LOCAL(%s)", var);
+	ast_channel_publish_varset(chan, local_buffer, value);
 	return 0;
 }
 

Modified: team/mmichelson/more_transfer/bridges/bridge_builtin_features.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/more_transfer/bridges/bridge_builtin_features.c?view=diff&rev=387589&r1=387588&r2=387589
==============================================================================
--- team/mmichelson/more_transfer/bridges/bridge_builtin_features.c (original)
+++ team/mmichelson/more_transfer/bridges/bridge_builtin_features.c Fri May  3 12:51:39 2013
@@ -349,10 +349,13 @@
  * to fully support existing functionality.  There will be one
  * and only one ast_bridge_channel structure per channel.
  */
-	/* Point the channel back to the original bridge_channel. */
+	/* Point the channel back to the original bridge and bridge_channel. */
+	ast_bridge_channel_lock(bridge_channel);
 	ast_channel_lock(bridge_channel->chan);
 	ast_channel_internal_bridge_channel_set(bridge_channel->chan, bridge_channel);
+	ast_channel_internal_bridge_set(bridge_channel->chan, bridge_channel->bridge);
 	ast_channel_unlock(bridge_channel->chan);
+	ast_bridge_channel_unlock(bridge_channel);
 
 	/* Wait for peer thread to exit bridge and die. */
 	if (!ast_autoservice_start(bridge_channel->chan)) {

Modified: team/mmichelson/more_transfer/build_tools/post_process_documentation.py
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/more_transfer/build_tools/post_process_documentation.py?view=diff&rev=387589&r1=387588&r2=387589
==============================================================================
--- team/mmichelson/more_transfer/build_tools/post_process_documentation.py (original)
+++ team/mmichelson/more_transfer/build_tools/post_process_documentation.py Fri May  3 12:51:39 2013
@@ -22,9 +22,9 @@
 
     def __swap_parameter_documentation(one, two):
         # See who has the better documentation and use it
-        if (one.hasChildNodes()):
+        if (one.hasChildNodes() and not two.hasChildNodes()):
             two.parentNode.replaceChild(one.cloneNode(True), two)
-        elif (two.hasChildNodes()):
+        elif (two.hasChildNodes() and not one.hasChildNodes()):
             one.parentNode.replaceChild(two.cloneNode(True), one)
 
     def __merge_parameter(param, other_instances):

Modified: team/mmichelson/more_transfer/channels/chan_gulp.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/more_transfer/channels/chan_gulp.c?view=diff&rev=387589&r1=387588&r2=387589
==============================================================================
--- team/mmichelson/more_transfer/channels/chan_gulp.c (original)
+++ team/mmichelson/more_transfer/channels/chan_gulp.c Fri May  3 12:51:39 2013
@@ -434,7 +434,7 @@
 	pvt->media[SIP_MEDIA_VIDEO] = ao2_find(session->media, "video", OBJ_KEY);
 	ast_channel_tech_pvt_set(chan, pvt);
 
-	if (ast_format_cap_is_empty(session->req_caps)) {
+	if (ast_format_cap_is_empty(session->req_caps) || !ast_format_cap_has_joint(session->req_caps, session->endpoint->codecs)) {
 		ast_format_cap_copy(ast_channel_nativeformats(chan), session->endpoint->codecs);
 	} else {
 		ast_format_cap_copy(ast_channel_nativeformats(chan), session->req_caps);

Modified: team/mmichelson/more_transfer/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/more_transfer/channels/chan_local.c?view=diff&rev=387589&r1=387588&r2=387589
==============================================================================
--- team/mmichelson/more_transfer/channels/chan_local.c (original)
+++ team/mmichelson/more_transfer/channels/chan_local.c Fri May  3 12:51:39 2013
@@ -325,8 +325,8 @@
 static int local_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
 {
 	struct local_pvt *p;
-	struct ast_channel *bridged = NULL;
-	struct ast_channel *tmp = NULL;
+	struct ast_channel *peer;
+	struct ast_channel *other;
 	int res = 0;
 
 	if (option != AST_OPTION_T38_STATE) {
@@ -340,31 +340,21 @@
 	}
 
 	ao2_lock(p);
-	if (!(tmp = IS_OUTBOUND(ast, p) ? p->owner : p->chan)) {
+	other = IS_OUTBOUND(ast, p) ? p->owner : p->chan;
+	if (!other) {
 		ao2_unlock(p);
 		return -1;
 	}
-	ast_channel_ref(tmp);
+	ast_channel_ref(other);
 	ao2_unlock(p);
 	ast_channel_unlock(ast); /* Held when called, unlock before locking another channel */
 
-	ast_channel_lock(tmp);
-	if (!(bridged = ast_bridged_channel(tmp))) {
-		res = -1;
-		ast_channel_unlock(tmp);
-		goto query_cleanup;
-	}
-	ast_channel_ref(bridged);
-	ast_channel_unlock(tmp);
-
-query_cleanup:
-	if (bridged) {
-		res = ast_channel_queryoption(bridged, option, data, datalen, 0);
-		bridged = ast_channel_unref(bridged);
-	}
-	if (tmp) {
-		tmp = ast_channel_unref(tmp);
-	}
+	peer = ast_channel_bridge_peer(other);
+	if (peer) {
+		res = ast_channel_queryoption(peer, option, data, datalen, 0);
+		ast_channel_unref(peer);
+	}
+	ast_channel_unref(other);
 	ast_channel_lock(ast); /* Lock back before we leave */
 
 	return res;
@@ -510,6 +500,8 @@
 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
 {
 	struct local_pvt *p = ast_channel_tech_pvt(newchan);
+	struct ast_bridge *bridge_owner;
+	struct ast_bridge *bridge_chan;
 
 	if (!p) {
 		return -1;
@@ -528,10 +520,15 @@
 		p->chan = newchan;
 	}
 
+	if (ast_check_hangup(newchan) || !p->owner || !p->chan) {
+		ao2_unlock(p);
+		return 0;
+	}
+
 	/* Do not let a masquerade cause a Local channel to be bridged to itself! */
-	if (!ast_check_hangup(newchan)
-		&& ((p->owner && ast_channel_internal_bridged_channel(p->owner) == p->chan)
-			|| (p->chan && ast_channel_internal_bridged_channel(p->chan) == p->owner))) {
+	bridge_owner = ast_channel_internal_bridge(p->owner);
+	bridge_chan = ast_channel_internal_bridge(p->chan);
+	if (bridge_owner && bridge_owner == bridge_chan) {
 		ast_log(LOG_WARNING, "You can not bridge a Local channel to itself!\n");
 		ao2_unlock(p);
 		ast_queue_hangup(newchan);

Modified: team/mmichelson/more_transfer/include/asterisk/bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/more_transfer/include/asterisk/bridging.h?view=diff&rev=387589&r1=387588&r2=387589
==============================================================================
--- team/mmichelson/more_transfer/include/asterisk/bridging.h (original)
+++ team/mmichelson/more_transfer/include/asterisk/bridging.h Fri May  3 12:51:39 2013
@@ -1275,6 +1275,8 @@
     AST_BRIDGE_TRANSFER_FAIL,
 };
 
+typedef void (*transfer_channel_cb)(struct ast_channel *chan, void *user_data);
+
 /*!
  * \brief Blind transfer target to the extension and context provided
  *
@@ -1285,6 +1287,8 @@
  * Callers may also provide a callback to be called on the channel that will
  * be running dialplan. The user data passed into ast_bridge_transfer_blind
  * will be given as the argument to the callback to be interpreted as desired.
+ * This callback is guaranteed to be called in the same thread as
+ * ast_bridge_transfer_blind() and before ast_bridge_transfer_blind() returns.
  *
  * \note Do not call this function with the transferer or its tech_pvt locked.
  *
@@ -1298,8 +1302,7 @@
  */
 enum ast_transfer_result ast_bridge_transfer_blind(struct ast_channel *transferer,
 		const char *exten, const char *context,
-		void (*new_channel_cb)(struct ast_channel *chan, void *user_data),
-		void *user_data);
+		transfer_channel_cb new_channel_cb, void *user_data);
 
 /*!
  * \brief Attended transfer
@@ -1442,6 +1445,36 @@
  */
 struct ao2_container *ast_bridge_peers(struct ast_bridge *bridge);
 
+/*!
+ * \brief Get the channel's bridge peer only if the bridge is two-party.
+ * \since 12.0.0
+ *
+ * \param bridge The bridge which is already locked.
+ * \param chan Channel desiring the bridge peer channel.
+ *
+ * \note The returned peer channel is the current peer in the
+ * bridge when called.
+ *
+ * \retval NULL Channel not in a bridge or the bridge is not two-party.
+ * \retval non-NULL Reffed peer channel at time of calling.
+ */
+struct ast_channel *ast_bridge_peer_nolock(struct ast_bridge *bridge, struct ast_channel *chan);
+
+/*!
+ * \brief Get the channel's bridge peer only if the bridge is two-party.
+ * \since 12.0.0
+ *
+ * \param bridge The bridge
+ * \param chan Channel desiring the bridge peer channel.
+ *
+ * \note The returned peer channel is the current peer in the
+ * bridge when called.
+ *
+ * \retval NULL Channel not in a bridge or the bridge is not two-party.
+ * \retval non-NULL Reffed peer channel at time of calling.
+ */
+struct ast_channel *ast_bridge_peer(struct ast_bridge *bridge, struct ast_channel *chan);
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif

Modified: team/mmichelson/more_transfer/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/more_transfer/include/asterisk/channel.h?view=diff&rev=387589&r1=387588&r2=387589
==============================================================================
--- team/mmichelson/more_transfer/include/asterisk/channel.h (original)
+++ team/mmichelson/more_transfer/include/asterisk/channel.h Fri May  3 12:51:39 2013
@@ -4137,34 +4137,69 @@
 struct stasis_topic *ast_channel_topic(struct ast_channel *chan);
 
 /*!
- * \since 12
  * \brief Get the bridge associated with a channel
- *
- * The bridge returned has its reference count incremented. Use
- * ao2_cleanup() or ao2_ref() in order to decrement the reference
- * count when you are finished with the bridge.
+ * \since 12.0.0
+ *
+ * \param chan The channel whose bridge we want
+ *
+ * \details
+ * The bridge returned has its reference count incremented.  Use
+ * ao2_cleanup() or ao2_ref() in order to decrement the
+ * reference count when you are finished with the bridge.
  *
  * \note This function expects the channel to be locked prior to
  * being called and will not grab the channel lock.
  *
- * \param chan The channel whose bridge we want
  * \retval NULL No bridge present on the channel
  * \retval non-NULL The bridge the channel is in
  */
 struct ast_bridge *ast_channel_get_bridge(const struct ast_channel *chan);
 
 /*!
- * \since 12
  * \brief Determine if a channel is in a bridge
+ * \since 12.0.0
+ *
+ * \param chan The channel to test
  *
  * \note This function expects the channel to be locked prior to
  * being called and will not grab the channel lock.
  *
- * \param chan The channel to test
  * \retval 0 The channel is not bridged
  * \retval non-zero The channel is bridged
  */
 int ast_channel_is_bridged(const struct ast_channel *chan);
+
+/*!
+ * \brief Get the channel's bridge peer only if the bridge is two-party.
+ * \since 12.0.0
+ *
+ * \param chan Channel desiring the bridge peer channel.
+ *
+ * \note The returned peer channel is the current peer in the
+ * bridge when called.
+ *
+ * \retval NULL Channel not in a bridge or the bridge is not two-party.
+ * \retval non-NULL Reffed peer channel at time of calling.
+ */
+struct ast_channel *ast_channel_bridge_peer(struct ast_channel *chan);
+
+/*!
+ * \brief Get a reference to the channel's bridge pointer.
+ * \since 12.0.0
+ *
+ * \param chan The channel whose bridge channel is desired
+ *
+ * \note This increases the reference count of the bridge_channel.
+ * Use ao2_ref() or ao2_cleanup() to decrement the refcount when
+ * you are finished with it.
+ *
+ * \note It is expected that the channel is locked prior to
+ * placing this call.
+ *
+ * \retval NULL The channel has no bridge_channel
+ * \retval non-NULL A reference to the bridge_channel
+ */
+struct ast_bridge_channel *ast_channel_get_bridge_channel(struct ast_channel *chan);
 
 /*!
  * \since 12

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=387589&r1=387588&r2=387589
==============================================================================
--- team/mmichelson/more_transfer/main/bridging.c (original)
+++ team/mmichelson/more_transfer/main/bridging.c Fri May  3 12:51:39 2013
@@ -2352,6 +2352,14 @@
 		bridge_channel->bridge->uniqueid,
 		bridge_channel, ast_channel_name(bridge_channel->chan));
 
+	/*
+	 * Get "in the bridge" before pushing the channel for any
+	 * masquerades on the channel to happen before bridging.
+	 */
+	ast_channel_lock(bridge_channel->chan);
+	ast_channel_internal_bridge_set(bridge_channel->chan, bridge_channel->bridge);
+	ast_channel_unlock(bridge_channel->chan);
+
 	/* Add the jitterbuffer if the channel requires it */
 	ast_jb_enable_for_channel(bridge_channel->chan);
 
@@ -2384,9 +2392,6 @@
 		ast_bridge_unlock(bridge_channel->bridge);
 		bridge_channel_handle_join(bridge_channel);
 		while (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
-			/* Update bridge pointer on channel */
-			ast_channel_internal_bridge_set(bridge_channel->chan, bridge_channel->bridge);
-
 			/* Wait for something to do. */
 			bridge_channel_wait(bridge_channel);
 		}
@@ -2420,7 +2425,9 @@
 	while (ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT)) {
 		sched_yield();
 	}
+	ast_channel_lock(bridge_channel->chan);
 	ast_channel_internal_bridge_set(bridge_channel->chan, NULL);
+	ast_channel_unlock(bridge_channel->chan);
 
 	ast_bridge_channel_restore_formats(bridge_channel);
 }
@@ -3164,7 +3171,10 @@
 		/* Point to new bridge.*/
 		ao2_ref(dst_bridge, +1);
 		ast_bridge_channel_lock(bridge_channel);
+		ast_channel_lock(bridge_channel->chan);
 		bridge_channel->bridge = dst_bridge;
+		ast_channel_internal_bridge_set(bridge_channel->chan, dst_bridge);
+		ast_channel_unlock(bridge_channel->chan);
 		ast_bridge_channel_unlock(bridge_channel);
 		ao2_ref(src_bridge, -1);
 
@@ -3422,7 +3432,10 @@
 	/* Point to new bridge.*/
 	ao2_ref(dst_bridge, +1);
 	ast_bridge_channel_lock(bridge_channel);
+	ast_channel_lock(bridge_channel->chan);
 	bridge_channel->bridge = dst_bridge;
+	ast_channel_internal_bridge_set(bridge_channel->chan, dst_bridge);
+	ast_channel_unlock(bridge_channel->chan);
 	ast_bridge_channel_unlock(bridge_channel);
 
 	if (bridge_channel_push(bridge_channel)) {
@@ -3431,7 +3444,10 @@
 			/* Point back to original bridge. */
 			ao2_ref(orig_bridge, +1);
 			ast_bridge_channel_lock(bridge_channel);
+			ast_channel_lock(bridge_channel->chan);
 			bridge_channel->bridge = orig_bridge;
+			ast_channel_internal_bridge_set(bridge_channel->chan, orig_bridge);
+			ast_channel_unlock(bridge_channel->chan);
 			ast_bridge_channel_unlock(bridge_channel);
 			ao2_ref(dst_bridge, -1);
 
@@ -3544,9 +3560,10 @@
 	struct ast_bridge_channel *other = NULL;
 
 	if (bridge_channel->in_bridge && bridge->num_channels == 2) {
-		other = AST_LIST_FIRST(&bridge->channels);
-		if (other == bridge_channel) {
-			other = AST_LIST_LAST(&bridge->channels);
+		AST_LIST_TRAVERSE(&bridge->channels, other, entry) {
+			if (other != bridge_channel) {
+				break;
+			}
 		}
 	}
 
@@ -4735,6 +4752,45 @@
 	return channels;
 }
 
+struct ast_channel *ast_bridge_peer_nolock(struct ast_bridge *bridge, struct ast_channel *chan)
+{
+	struct ast_channel *peer = NULL;
+	struct ast_bridge_channel *iter;
+
+	/* Asking for the peer channel only makes sense on a two-party bridge. */
+	if (bridge->num_channels == 2
+		&& bridge->technology->capabilities
+			& (AST_BRIDGE_CAPABILITY_NATIVE | AST_BRIDGE_CAPABILITY_1TO1MIX)) {
+		int in_bridge = 0;
+
+		AST_LIST_TRAVERSE(&bridge->channels, iter, entry) {
+			if (iter->chan != chan) {
+				peer = iter->chan;
+			} else {
+				in_bridge = 1;
+			}
+		}
+		if (in_bridge && peer) {
+			ast_channel_ref(peer);
+		} else {
+			peer = NULL;
+		}
+	}
+
+	return peer;
+}
+
+struct ast_channel *ast_bridge_peer(struct ast_bridge *bridge, struct ast_channel *chan)
+{
+	struct ast_channel *peer;
+
+	ast_bridge_lock(bridge);
+	peer = ast_bridge_peer_nolock(bridge, chan);
+	ast_bridge_unlock(bridge);
+
+	return peer;
+}
+
 /*!
  * \internal
  * \brief Transfer an entire bridge to a specific destination.
@@ -4756,8 +4812,7 @@
  */
 static enum ast_transfer_result blind_transfer_bridge(struct ast_channel *transferer,
 		struct ast_bridge *bridge, const char *exten, const char *context,
-		void (*new_channel_cb)(struct ast_channel *chan, void *user_data),
-		void *user_data)
+		transfer_channel_cb new_channel_cb, void *user_data)
 {
 	struct ast_channel *local;
 	char chan_name[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2];
@@ -4854,11 +4909,38 @@
  */
 static int bridge_channel_queue_blind_transfer(struct ast_channel *transferee,
 		const char *exten, const char *context,
-		void (*new_channel_cb)(struct ast_channel *chan, void *user_data),
-		void *user_data)
+		transfer_channel_cb new_channel_cb, void *user_data)
 {
 	RAII_VAR(struct ast_bridge_channel *, transferee_bridge_channel, NULL, ao2_cleanup);
 	struct blind_transfer_data blind_data;
+
+	ast_channel_lock(transferee);
+	transferee_bridge_channel = ast_channel_get_bridge_channel(transferee);
+	ast_channel_unlock(transferee);
+
+	if (!transferee_bridge_channel) {
+		return -1;
+	}
+
+	if (new_channel_cb) {
+		new_channel_cb(transferee, user_data);
+	}
+
+	ast_copy_string(blind_data.exten, exten, sizeof(blind_data.exten));
+	ast_copy_string(blind_data.context, context, sizeof(blind_data.context));
+
+	/* XXX Why doesn't this function return success/failure? */
+	ast_bridge_channel_queue_action_data(transferee_bridge_channel,
+			AST_BRIDGE_ACTION_BLIND_TRANSFER, &blind_data, sizeof(blind_data));
+
+	return 0;
+}
+
+static int bridge_channel_queue_attended_transfer(struct ast_channel *transferee,
+		struct ast_channel *unbridged_chan)
+{
+	RAII_VAR(struct ast_bridge_channel *, transferee_bridge_channel, NULL, ao2_cleanup);
+	char unbridged_chan_name[AST_CHANNEL_NAME];
 
 	{
 		SCOPED_LOCK(lock, transferee, ast_channel_lock, ast_channel_unlock);
@@ -4869,35 +4951,6 @@
 		ao2_ref(transferee_bridge_channel, +1);
 	}
 
-	if (new_channel_cb) {
-		new_channel_cb(transferee, user_data);
-	}
-
-	ast_copy_string(blind_data.exten, exten, sizeof(blind_data.exten));
-	ast_copy_string(blind_data.context, context, sizeof(blind_data.context));
-
-	/* XXX Why doesn't this function return success/failure? */
-	ast_bridge_channel_queue_action_data(transferee_bridge_channel,
-			AST_BRIDGE_ACTION_BLIND_TRANSFER, &blind_data, sizeof(blind_data));
-
-	return 0;
-}
-
-static int bridge_channel_queue_attended_transfer(struct ast_channel *transferee,
-		struct ast_channel *unbridged_chan)
-{
-	RAII_VAR(struct ast_bridge_channel *, transferee_bridge_channel, NULL, ao2_cleanup);
-	char unbridged_chan_name[AST_CHANNEL_NAME];
-
-	{
-		SCOPED_LOCK(lock, transferee, ast_channel_lock, ast_channel_unlock);
-		transferee_bridge_channel = ast_channel_internal_bridge_channel(transferee);
-		if (!transferee_bridge_channel) {
-			return -1;
-		}
-		ao2_ref(transferee_bridge_channel, +1);
-	}
-
 	ast_copy_string(unbridged_chan_name, ast_channel_name(unbridged_chan),
 			sizeof(unbridged_chan_name));
 
@@ -4926,13 +4979,12 @@
 	RAII_VAR(struct ast_bridge_channel *, transferer_bridge_channel, NULL, ao2_cleanup);
 	struct ast_exten *parking_exten;
 
-	{
-		SCOPED_LOCK(lock, transferer, ast_channel_lock, ast_channel_unlock);
-		transfer_bridge_channel = ast_channel_internal_bridge_channel(transferer);
-		if (!transferer) {
-			return PARKING_FAILURE;
-		}
-		ao2_ref(transferer_bridge_channel, +1);
+	ast_channel_lock(transferer);
+	transfer_bridge_channel = ast_channel_get_bridge_channel(transferer);
+	ast_channel_unlock(transferer);
+
+	if (!transfer_bridge_channel) {
+		return PARKING_FAILURE;
 	}
 
 	parking_exten = ast_get_parking_exten(exten, NULL, context);
@@ -4984,8 +5036,7 @@
 
 enum ast_transfer_result ast_bridge_transfer_blind(struct ast_channel *transferer,
 		const char *exten, const char *context,
-		void (*new_channel_cb)(struct ast_channel *chan, void *user_data),
-		void *user_data)
+		transfer_channel_cb new_channel_cb, void *user_data)
 {
 	RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
 	RAII_VAR(struct ao2_container *, channels, NULL, ao2_cleanup);

Modified: team/mmichelson/more_transfer/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/more_transfer/main/channel.c?view=diff&rev=387589&r1=387588&r2=387589
==============================================================================
--- team/mmichelson/more_transfer/main/channel.c (original)
+++ team/mmichelson/more_transfer/main/channel.c Fri May  3 12:51:39 2013
@@ -11259,40 +11259,6 @@
 	return 0;
 }
 
-/* DO NOT PUT ADDITIONAL FUNCTIONS BELOW THIS BOUNDARY
- *
- * ONLY FUNCTIONS FOR PROVIDING BACKWARDS ABI COMPATIBILITY BELONG HERE
- *
- */
-
-/* Provide binary compatibility for modules that call ast_channel_alloc() directly;
- * newly compiled modules will call __ast_channel_alloc() via the macros in channel.h
- */
-#undef ast_channel_alloc
-struct ast_channel __attribute__((format(printf, 10, 11)))
-	*ast_channel_alloc(int needqueue, int state, const char *cid_num,
-			   const char *cid_name, const char *acctcode,
-			   const char *exten, const char *context,
-			   const char *linkedid, const int amaflag,
-			   const char *name_fmt, ...);
-struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num,
-				      const char *cid_name, const char *acctcode,
-				      const char *exten, const char *context,
-				      const char *linkedid, const int amaflag,
-				      const char *name_fmt, ...)
-{
-	va_list ap;
-	struct ast_channel *result;
-
-
-	va_start(ap, name_fmt);
-	result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
-					linkedid, amaflag, __FILE__, __LINE__, __FUNCTION__, name_fmt, ap);
-	va_end(ap);
-
-	return result;
-}
-
 void ast_channel_unlink(struct ast_channel *chan)
 {
 	ao2_unlink(channels, chan);
@@ -11303,17 +11269,44 @@
 	struct ast_bridge *bridge;
 
 	bridge = ast_channel_internal_bridge(chan);
+	if (bridge) {
+		ao2_ref(bridge, +1);
+	}
+	return bridge;
+}
+
+int ast_channel_is_bridged(const struct ast_channel *chan)
+{
+	return ast_channel_internal_bridge(chan) != NULL;
+}
+
+struct ast_channel *ast_channel_bridge_peer(struct ast_channel *chan)
+{
+	struct ast_channel *peer;
+	struct ast_bridge *bridge;
+
+	/* Get the bridge the channel is in. */
+	ast_channel_lock(chan);
+	bridge = ast_channel_get_bridge(chan);
+	ast_channel_unlock(chan);
 	if (!bridge) {
 		return NULL;
 	}
-	ao2_ref(bridge, +1);
-	return bridge;
-}
-
-int ast_channel_is_bridged(const struct ast_channel *chan)
-{
-	RAII_VAR(struct ast_bridge *, bridge, ast_channel_get_bridge(chan), ao2_cleanup);
-	return bridge != 0;
+
+	peer = ast_bridge_peer(bridge, chan);
+	ao2_ref(bridge, -1);
+	return peer;
+}
+
+struct ast_bridge_channel *ast_channel_get_bridge_channel(struct ast_channel *chan)
+{
+	struct ast_bridge_channel *bridge_channel;
+
+	bridge_channel = ast_channel_internal_bridge_channel(chan);
+	if (bridge_channel) {
+		ao2_ref(bridge_channel, +1);
+	}
+	return bridge_channel;
 }
 
 struct ast_channel *ast_channel_yank(struct ast_channel *yankee)

Modified: team/mmichelson/more_transfer/res/res_sip_sdp_rtp.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/more_transfer/res/res_sip_sdp_rtp.c?view=diff&rev=387589&r1=387588&r2=387589
==============================================================================
--- team/mmichelson/more_transfer/res/res_sip_sdp_rtp.c (original)
+++ team/mmichelson/more_transfer/res/res_sip_sdp_rtp.c Fri May  3 12:51:39 2013
@@ -556,7 +556,7 @@
 
 	if (direct_media_enabled) {
 		ast_format_cap_joint_copy(session->endpoint->codecs, session->direct_media_cap, caps);
-	} else if (ast_format_cap_is_empty(session->req_caps)) {
+	} else if (ast_format_cap_is_empty(session->req_caps) || !ast_format_cap_has_joint(session->req_caps, session->endpoint->codecs)) {
 		ast_format_cap_copy(caps, session->endpoint->codecs);
 	} else {
 		ast_format_cap_joint_copy(session->endpoint->codecs, session->req_caps, caps);




More information about the asterisk-commits mailing list