[asterisk-commits] mmichelson: branch mmichelson/transfer r387512 - in /team/mmichelson/transfer...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu May 2 14:58:12 CDT 2013
Author: mmichelson
Date: Thu May 2 14:58:10 2013
New Revision: 387512
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=387512
Log:
REsolve conflict and reset automerge.
Modified:
team/mmichelson/transfer/ (props changed)
team/mmichelson/transfer/bridges/bridge_builtin_features.c
team/mmichelson/transfer/channels/chan_local.c
team/mmichelson/transfer/include/asterisk/bridging.h
team/mmichelson/transfer/include/asterisk/channel.h
team/mmichelson/transfer/main/bridging.c
team/mmichelson/transfer/main/channel.c
Propchange: team/mmichelson/transfer/
------------------------------------------------------------------------------
automerge = *
Propchange: team/mmichelson/transfer/
------------------------------------------------------------------------------
--- bridge_construction-integrated (original)
+++ bridge_construction-integrated Thu May 2 14:58:10 2013
@@ -1,1 +1,1 @@
-/trunk:1-387423
+/trunk:1-387485
Propchange: team/mmichelson/transfer/
------------------------------------------------------------------------------
--- transfer-integrated (original)
+++ transfer-integrated Thu May 2 14:58:10 2013
@@ -1,1 +1,1 @@
-/team/group/bridge_construction:1-387471
+/team/group/bridge_construction:1-387511
Modified: team/mmichelson/transfer/bridges/bridge_builtin_features.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer/bridges/bridge_builtin_features.c?view=diff&rev=387512&r1=387511&r2=387512
==============================================================================
--- team/mmichelson/transfer/bridges/bridge_builtin_features.c (original)
+++ team/mmichelson/transfer/bridges/bridge_builtin_features.c Thu May 2 14:58:10 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/transfer/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer/channels/chan_local.c?view=diff&rev=387512&r1=387511&r2=387512
==============================================================================
--- team/mmichelson/transfer/channels/chan_local.c (original)
+++ team/mmichelson/transfer/channels/chan_local.c Thu May 2 14:58:10 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/transfer/include/asterisk/bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer/include/asterisk/bridging.h?view=diff&rev=387512&r1=387511&r2=387512
==============================================================================
--- team/mmichelson/transfer/include/asterisk/bridging.h (original)
+++ team/mmichelson/transfer/include/asterisk/bridging.h Thu May 2 14:58:10 2013
@@ -1440,6 +1440,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/transfer/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer/include/asterisk/channel.h?view=diff&rev=387512&r1=387511&r2=387512
==============================================================================
--- team/mmichelson/transfer/include/asterisk/channel.h (original)
+++ team/mmichelson/transfer/include/asterisk/channel.h Thu May 2 14:58:10 2013
@@ -4137,33 +4137,50 @@
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);
+
#endif /* _ASTERISK_CHANNEL_H */
Modified: team/mmichelson/transfer/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer/main/bridging.c?view=diff&rev=387512&r1=387511&r2=387512
==============================================================================
--- team/mmichelson/transfer/main/bridging.c (original)
+++ team/mmichelson/transfer/main/bridging.c Thu May 2 14:58:10 2013
@@ -2325,6 +2325,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);
@@ -2357,9 +2365,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);
}
@@ -2393,7 +2398,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);
}
@@ -3137,7 +3144,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);
@@ -3395,7 +3405,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)) {
@@ -3404,7 +3417,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);
@@ -3517,9 +3533,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;
+ }
}
}
@@ -4708,6 +4725,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.
Modified: team/mmichelson/transfer/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer/main/channel.c?view=diff&rev=387512&r1=387511&r2=387512
==============================================================================
--- team/mmichelson/transfer/main/channel.c (original)
+++ team/mmichelson/transfer/main/channel.c Thu May 2 14:58:10 2013
@@ -11259,43 +11259,43 @@
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);
+}
+
+struct ast_bridge *ast_channel_get_bridge(const struct ast_channel *chan)
+{
+ 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;
+ }
+
+ peer = ast_bridge_peer(bridge, chan);
+ ao2_ref(bridge, -1);
+ return peer;
}
struct ast_bridge *ast_channel_get_bridge(const struct ast_channel *chan)
More information about the asterisk-commits
mailing list