[asterisk-commits] jrose: branch jrose/bridge_projects r387588 - in /team/jrose/bridge_projects:...

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


Author: jrose
Date: Fri May  3 12:25:41 2013
New Revision: 387588

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=387588
Log:
automerge stuff

Modified:
    team/jrose/bridge_projects/   (props changed)
    team/jrose/bridge_projects/apps/app_stack.c
    team/jrose/bridge_projects/bridges/bridge_builtin_features.c
    team/jrose/bridge_projects/build_tools/post_process_documentation.py
    team/jrose/bridge_projects/channels/chan_dahdi.c
    team/jrose/bridge_projects/channels/chan_gulp.c
    team/jrose/bridge_projects/channels/chan_iax2.c
    team/jrose/bridge_projects/channels/chan_local.c
    team/jrose/bridge_projects/channels/chan_mgcp.c
    team/jrose/bridge_projects/channels/chan_sip.c
    team/jrose/bridge_projects/channels/chan_skinny.c
    team/jrose/bridge_projects/channels/chan_unistim.c
    team/jrose/bridge_projects/channels/sig_analog.c
    team/jrose/bridge_projects/channels/sip/include/sip.h
    team/jrose/bridge_projects/include/asterisk/acl.h
    team/jrose/bridge_projects/include/asterisk/bridging.h
    team/jrose/bridge_projects/include/asterisk/channel.h
    team/jrose/bridge_projects/include/asterisk/event_defs.h
    team/jrose/bridge_projects/include/asterisk/json.h
    team/jrose/bridge_projects/main/bridging.c
    team/jrose/bridge_projects/main/channel.c
    team/jrose/bridge_projects/main/event.c
    team/jrose/bridge_projects/main/json.c
    team/jrose/bridge_projects/main/loader.c
    team/jrose/bridge_projects/main/manager.c
    team/jrose/bridge_projects/main/manager_bridging.c
    team/jrose/bridge_projects/main/named_acl.c
    team/jrose/bridge_projects/main/utils.c
    team/jrose/bridge_projects/res/res_rtp_asterisk.c
    team/jrose/bridge_projects/res/res_sip_sdp_rtp.c
    team/jrose/bridge_projects/utils/Makefile

Propchange: team/jrose/bridge_projects/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.

Propchange: team/jrose/bridge_projects/
------------------------------------------------------------------------------
--- bridge_construction-integrated (original)
+++ bridge_construction-integrated Fri May  3 12:25:41 2013
@@ -1,1 +1,1 @@
-/trunk:1-386991
+/trunk:1-387545

Propchange: team/jrose/bridge_projects/
------------------------------------------------------------------------------
--- bridge_projects-integrated (original)
+++ bridge_projects-integrated Fri May  3 12:25:41 2013
@@ -1,1 +1,1 @@
-/team/group/bridge_construction:1-387006
+/team/group/bridge_construction:1-387587

Modified: team/jrose/bridge_projects/apps/app_stack.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/apps/app_stack.c?view=diff&rev=387588&r1=387587&r2=387588
==============================================================================
--- team/jrose/bridge_projects/apps/app_stack.c (original)
+++ team/jrose/bridge_projects/apps/app_stack.c Fri May  3 12:25:41 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/jrose/bridge_projects/bridges/bridge_builtin_features.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/bridges/bridge_builtin_features.c?view=diff&rev=387588&r1=387587&r2=387588
==============================================================================
--- team/jrose/bridge_projects/bridges/bridge_builtin_features.c (original)
+++ team/jrose/bridge_projects/bridges/bridge_builtin_features.c Fri May  3 12:25:41 2013
@@ -361,10 +361,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/jrose/bridge_projects/build_tools/post_process_documentation.py
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/build_tools/post_process_documentation.py?view=diff&rev=387588&r1=387587&r2=387588
==============================================================================
--- team/jrose/bridge_projects/build_tools/post_process_documentation.py (original)
+++ team/jrose/bridge_projects/build_tools/post_process_documentation.py Fri May  3 12:25:41 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/jrose/bridge_projects/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/channels/chan_dahdi.c?view=diff&rev=387588&r1=387587&r2=387588
==============================================================================
--- team/jrose/bridge_projects/channels/chan_dahdi.c (original)
+++ team/jrose/bridge_projects/channels/chan_dahdi.c Fri May  3 12:25:41 2013
@@ -5150,9 +5150,12 @@
 				if (drc) {
 					k = drc_sample(k, drc);
 				}
-				k = (float)k*linear_gain;
-				if (k > 32767) k = 32767;
-				if (k < -32767) k = -32767;
+				k = (float)k * linear_gain;
+				if (k > 32767) {
+					k = 32767;
+				} else if (k < -32768) {
+					k = -32768;
+				}
 				g->txgain[j] = AST_LIN2A(k);
 			} else {
 				g->txgain[j] = j;
@@ -5166,9 +5169,12 @@
 				if (drc) {
 					k = drc_sample(k, drc);
 				}
-				k = (float)k*linear_gain;
-				if (k > 32767) k = 32767;
-				if (k < -32767) k = -32767;
+				k = (float)k * linear_gain;
+				if (k > 32767) {
+					k = 32767;
+				} else if (k < -32768) {
+					k = -32768;
+				}
 				g->txgain[j] = AST_LIN2MU(k);
 
 			} else {
@@ -5193,9 +5199,12 @@
 				if (drc) {
 					k = drc_sample(k, drc);
 				}
-				k = (float)k*linear_gain;
-				if (k > 32767) k = 32767;
-				if (k < -32767) k = -32767;
+				k = (float)k * linear_gain;
+				if (k > 32767) {
+					k = 32767;
+				} else if (k < -32768) {
+					k = -32768;
+				}
 				g->rxgain[j] = AST_LIN2A(k);
 			} else {
 				g->rxgain[j] = j;
@@ -5209,9 +5218,12 @@
 				if (drc) {
 					k = drc_sample(k, drc);
 				}
-				k = (float)k*linear_gain;
-				if (k > 32767) k = 32767;
-				if (k < -32767) k = -32767;
+				k = (float)k * linear_gain;
+				if (k > 32767) {
+					k = 32767;
+				} else if (k < -32768) {
+					k = -32768;
+				}
 				g->rxgain[j] = AST_LIN2MU(k);
 			} else {
 				g->rxgain[j] = j;
@@ -6547,8 +6559,7 @@
 				p->owner = p->subs[SUB_REAL].owner;
 				if (ast_channel_state(p->owner) != AST_STATE_UP)
 					p->subs[SUB_REAL].needanswer = 1;
-				if (ast_bridged_channel(p->subs[SUB_REAL].owner))
-					ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
+				ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
 			} else if (p->subs[SUB_THREEWAY].dfd > -1) {
 				swap_subs(p, SUB_THREEWAY, SUB_REAL);
 				unalloc_sub(p, SUB_THREEWAY);
@@ -6569,7 +6580,7 @@
 			if (p->subs[SUB_CALLWAIT].inthreeway) {
 				/* This is actually part of a three way, placed on hold.  Place the third part
 				   on music on hold now */
-				if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
+				if (p->subs[SUB_THREEWAY].owner) {
 					ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
 						S_OR(p->mohsuggest, NULL),
 						!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
@@ -6584,7 +6595,7 @@
 			if (p->subs[SUB_CALLWAIT].inthreeway) {
 				/* The other party of the three way call is currently in a call-wait state.
 				   Start music on hold for them, and take the main guy out of the third call */
-				if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
+				if (p->subs[SUB_CALLWAIT].owner) {
 					ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
 						S_OR(p->mohsuggest, NULL),
 						!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
@@ -7838,11 +7849,10 @@
 	   together (but then, why would we want to?) */
 	if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
 		/* The three-way person we're about to transfer to could still be in MOH, so
-		   stop if now if appropriate */
-		if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
-			ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD);
+		   stop it now */
+		ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD);
 		if (ast_channel_state(p->subs[SUB_REAL].owner) == AST_STATE_RINGING) {
-			ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
+			ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_RINGING);
 		}
 		if (ast_channel_state(p->subs[SUB_THREEWAY].owner) == AST_STATE_RING) {
 			tone_zone_play_tone(p->subs[SUB_THREEWAY].dfd, DAHDI_TONE_RINGTONE);
@@ -7858,7 +7868,7 @@
 	} else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
 		ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
 		if (ast_channel_state(p->subs[SUB_THREEWAY].owner) == AST_STATE_RINGING) {
-			ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
+			ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_RINGING);
 		}
 		if (ast_channel_state(p->subs[SUB_REAL].owner) == AST_STATE_RING) {
 			tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
@@ -8524,8 +8534,7 @@
 				/* Make sure it stops ringing */
 				dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK);
 				/* Okay -- probably call waiting*/
-				if (ast_bridged_channel(p->owner))
-					ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
+				ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
 				p->subs[idx].needunhold = 1;
 				break;
 			case AST_STATE_RESERVED:
@@ -8679,17 +8688,15 @@
 				p->cidcwexpire = 0;
 				p->cid_suppress_expire = 0;
 				/* Start music on hold if appropriate */
-				if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
+				if (!p->subs[SUB_CALLWAIT].inthreeway) {
 					ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
 						S_OR(p->mohsuggest, NULL),
 						!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
 				}
 				p->subs[SUB_CALLWAIT].needhold = 1;
-				if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
-					ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD,
-						S_OR(p->mohsuggest, NULL),
-						!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
-				}
+				ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD,
+					S_OR(p->mohsuggest, NULL),
+					!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
 				p->subs[SUB_REAL].needunhold = 1;
 			} else if (!p->subs[SUB_THREEWAY].owner) {
 				if (!p->threewaycalling) {
@@ -8766,12 +8773,10 @@
 					} else {
 						ast_verb(3, "Started three way call on channel %d\n", p->channel);
 
-						/* Start music on hold if appropriate */
-						if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
-							ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
-								S_OR(p->mohsuggest, NULL),
-								!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
-						}
+						/* Start music on hold */
+						ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
+							S_OR(p->mohsuggest, NULL),
+							!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
 						p->subs[SUB_THREEWAY].needhold = 1;
 					}
 					ast_callid_threadstorage_auto_clean(callid, callid_created);
@@ -8808,7 +8813,7 @@
 							swap_subs(p, SUB_THREEWAY, SUB_REAL);
 							otherindex = SUB_REAL;
 						}
-						if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner))
+						if (p->subs[otherindex].owner)
 							ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD);
 						p->subs[otherindex].needunhold = 1;
 						p->owner = p->subs[SUB_REAL].owner;
@@ -8817,7 +8822,7 @@
 						swap_subs(p, SUB_THREEWAY, SUB_REAL);
 						ast_channel_softhangup_internal_flag_add(p->subs[SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
 						p->owner = p->subs[SUB_REAL].owner;
-						if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner))
+						if (p->subs[SUB_REAL].owner)
 							ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
 						p->subs[SUB_REAL].needunhold = 1;
 						dahdi_enable_ec(p);
@@ -9011,7 +9016,7 @@
 			(res != DAHDI_EVENT_HOOKCOMPLETE)) {
 			ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res);
 			p->owner = p->subs[SUB_REAL].owner;
-			if (p->owner && ast_bridged_channel(p->owner))
+			if (p->owner)
 				ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
 			p->subs[SUB_REAL].needunhold = 1;
 		}
@@ -9056,8 +9061,7 @@
 				p->callwaitingrepeat = 0;
 				p->cidcwexpire = 0;
 				p->cid_suppress_expire = 0;
-				if (ast_bridged_channel(p->owner))
-					ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
+				ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
 				p->subs[SUB_REAL].needunhold = 1;
 			} else
 				ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
@@ -9605,15 +9609,15 @@
 		return -1;
 	}
 	if (p->dialing) {
-		ast_debug(1, "Dropping frame since I'm still dialing on %s...\n",ast_channel_name(ast));
+		ast_debug(5, "Dropping frame since I'm still dialing on %s...\n",ast_channel_name(ast));
 		return 0;
 	}
 	if (!p->owner) {
-		ast_debug(1, "Dropping frame since there is no active owner on %s...\n",ast_channel_name(ast));
+		ast_debug(5, "Dropping frame since there is no active owner on %s...\n",ast_channel_name(ast));
 		return 0;
 	}
 	if (p->cidspill) {
-		ast_debug(1, "Dropping frame since I've still got a callerid spill on %s...\n",
+		ast_debug(5, "Dropping frame since I've still got a callerid spill on %s...\n",
 			ast_channel_name(ast));
 		return 0;
 	}
@@ -10694,8 +10698,7 @@
 					swap_subs(p, SUB_REAL, SUB_THREEWAY);
 					unalloc_sub(p, SUB_THREEWAY);
 					p->owner = p->subs[SUB_REAL].owner;
-					if (ast_bridged_channel(p->subs[SUB_REAL].owner))
-						ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
+					ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
 					ast_hangup(chan);
 					goto quit;
 				} else {

Modified: team/jrose/bridge_projects/channels/chan_gulp.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/channels/chan_gulp.c?view=diff&rev=387588&r1=387587&r2=387588
==============================================================================
--- team/jrose/bridge_projects/channels/chan_gulp.c (original)
+++ team/jrose/bridge_projects/channels/chan_gulp.c Fri May  3 12:25:41 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/jrose/bridge_projects/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/channels/chan_iax2.c?view=diff&rev=387588&r1=387587&r2=387588
==============================================================================
--- team/jrose/bridge_projects/channels/chan_iax2.c (original)
+++ team/jrose/bridge_projects/channels/chan_iax2.c Fri May  3 12:25:41 2013
@@ -284,7 +284,7 @@
 static char regcontext[AST_MAX_CONTEXT] = "";
 
 static struct ast_event_sub *network_change_event_subscription; /*!< subscription id for network change events */
-static struct ast_event_sub *acl_change_event_subscription; /*!< subscription id for ACL change events */
+static struct stasis_subscription *acl_change_sub; /*!< subscription id for ACL change events */
 static int network_change_event_sched_id = -1;
 
 static int maxauthreq = 3;
@@ -1255,7 +1255,7 @@
 static int replace_callno(const void *obj);
 static void sched_delay_remove(struct sockaddr_in *sin, callno_entry entry);
 static void network_change_event_cb(const struct ast_event *, void *);
-static void acl_change_event_cb(const struct ast_event *, void *);
+static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message);
 
 static struct ast_channel_tech iax2_tech = {
 	.type = "IAX2",
@@ -1338,18 +1338,18 @@
 	}
 }
 
-static void acl_change_event_subscribe(void)
-{
-	if (!acl_change_event_subscription) {
-		acl_change_event_subscription = ast_event_subscribe(AST_EVENT_ACL_CHANGE,
-			acl_change_event_cb, "IAX2 ACL Change", NULL, AST_EVENT_IE_END);
-	}
-}
-
-static void acl_change_event_unsubscribe(void)
-{
-	if (acl_change_event_subscription) {
-		acl_change_event_subscription = ast_event_unsubscribe(acl_change_event_subscription);
+static void acl_change_stasis_subscribe(void)
+{
+	if (!acl_change_sub) {
+		acl_change_sub = stasis_subscribe(ast_acl_topic(),
+			acl_change_stasis_cb, NULL);
+	}
+}
+
+static void acl_change_stasis_unsubscribe(void)
+{
+	if (acl_change_sub) {
+		acl_change_sub = stasis_unsubscribe(acl_change_sub);
 	}
 }
 
@@ -1375,8 +1375,13 @@
 
 }
 
-static void acl_change_event_cb(const struct ast_event *event, void *userdata)
-{
+static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub,
+	struct stasis_topic *topic, struct stasis_message *message)
+{
+	if (stasis_message_type(message) != ast_named_acl_change_type()) {
+		return;
+	}
+
 	ast_log(LOG_NOTICE, "Reloading chan_iax2 in response to ACL change event.\n");
 	reload_config(1);
 }
@@ -10421,21 +10426,21 @@
 
 					ast_set_flag64(iaxs[fr->callno], IAX_QUELCH);
 					if (ies.musiconhold) {
+						const char *moh_suggest;
+
 						iax2_lock_owner(fr->callno);
 						if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
 							break;
 						}
-						if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
-							const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
-
-							/*
-							 * We already hold the owner lock so we do not
-							 * need to check iaxs[fr->callno] after it returns.
-							 */
-							iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
-								S_OR(moh_suggest, NULL),
-								!ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
-						}
+
+						/*
+						 * We already hold the owner lock so we do not
+						 * need to check iaxs[fr->callno] after it returns.
+						 */
+						moh_suggest = iaxs[fr->callno]->mohsuggest;
+						iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
+							S_OR(moh_suggest, NULL),
+							!ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
 						ast_channel_unlock(iaxs[fr->callno]->owner);
 					}
 				}
@@ -10460,13 +10465,12 @@
 					if (!iaxs[fr->callno]->owner) {
 						break;
 					}
-					if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
-						/*
-						 * We already hold the owner lock so we do not
-						 * need to check iaxs[fr->callno] after it returns.
-						 */
-						iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
-					}
+
+					/*
+					 * We already hold the owner lock so we do not
+					 * need to check iaxs[fr->callno] after it returns.
+					 */
+					iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
 					ast_channel_unlock(iaxs[fr->callno]->owner);
 				}
 				break;
@@ -12700,7 +12704,7 @@
 	}
 
 	if (subscribe_acl_change) {
-		acl_change_event_subscribe();
+		acl_change_stasis_subscribe();
 	}
 
 	return peer;
@@ -12972,7 +12976,7 @@
 	}
 
 	if (subscribe_acl_change) {
-		acl_change_event_subscribe();
+		acl_change_stasis_subscribe();
 	}
 
 	return user;
@@ -14284,7 +14288,7 @@
 	int x;
 
 	network_change_event_unsubscribe();
-	acl_change_event_unsubscribe();
+	acl_change_stasis_unsubscribe();
 
 	ast_manager_unregister("IAXpeers");
 	ast_manager_unregister("IAXpeerlist");

Modified: team/jrose/bridge_projects/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/channels/chan_local.c?view=diff&rev=387588&r1=387587&r2=387588
==============================================================================
--- team/jrose/bridge_projects/channels/chan_local.c (original)
+++ team/jrose/bridge_projects/channels/chan_local.c Fri May  3 12:25:41 2013
@@ -21,7 +21,7 @@
  * \author Mark Spencer <markster at digium.com>
  *
  * \brief Local Proxy Channel
- * 
+ *
  * \ingroup channel_drivers
  */
 
@@ -78,11 +78,6 @@
 static const char tdesc[] = "Local Proxy Channel Driver";
 
 #define IS_OUTBOUND(a,b) (a == b->chan ? 1 : 0)
-
-/* right now we are treating the locals astobj2 container as a
- * list.  If there is ever a reason to make this more efficient
- * increasing the bucket size would help. */
-static const int BUCKET_SIZE = 1;
 
 static struct ao2_container *locals;
 
@@ -135,21 +130,21 @@
 	.setoption = local_setoption,
 };
 
-/*! \brief the local pvt structure for all channels
-
-	The local channel pvt has two ast_chan objects - the "owner" and the "next channel", the outbound channel
-
-	ast_chan owner -> local_pvt -> ast_chan chan -> yet-another-pvt-depending-on-channel-type
-
-*/
+/*!
+ * \brief the local pvt structure for all channels
+ *
+ * The local channel pvt has two ast_chan objects - the "owner" and the "next channel", the outbound channel
+ *
+ * ast_chan owner -> local_pvt -> ast_chan chan -> yet-another-pvt-depending-on-channel-type
+ */
 struct local_pvt {
+	struct ast_channel *owner;      /*!< Master Channel - Bridging happens here */
+	struct ast_channel *chan;       /*!< Outbound channel - PBX is run here */
+	struct ast_format_cap *reqcap;  /*!< Requested format capabilities */
+	struct ast_jb_conf jb_conf;     /*!< jitterbuffer configuration for this local channel */
 	unsigned int flags;             /*!< Private flags */
 	char context[AST_MAX_CONTEXT];  /*!< Context to call */
 	char exten[AST_MAX_EXTENSION];  /*!< Extension to call */
-	struct ast_format_cap *reqcap;  /*!< Requested format capabilities */
-	struct ast_jb_conf jb_conf;     /*!< jitterbuffer configuration for this local channel */
-	struct ast_channel *owner;      /*!< Master Channel - Bridging happens here */
-	struct ast_channel *chan;       /*!< Outbound channel - PBX is run here */
 };
 
 #define LOCAL_LAUNCHED_PBX    (1 << 0) /*!< PBX was launched */
@@ -215,7 +210,7 @@
 }
 
 /* Called with ast locked */
-static int local_setoption(struct ast_channel *ast, int option, void * data, int datalen)
+static int local_setoption(struct ast_channel *ast, int option, void *data, int datalen)
 {
 	int res = 0;
 	struct local_pvt *p;
@@ -293,7 +288,7 @@
 	if (!context) {
 		ast_log(LOG_WARNING,
 			"Someone used Local/%s somewhere without a @context. This is bad.\n", data);
-		return AST_DEVICE_INVALID;	
+		return AST_DEVICE_INVALID;
 	}
 	*context++ = '\0';
 
@@ -330,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) {
@@ -345,37 +340,28 @@
 	}
 
 	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;
 }
 
-/*! \brief queue a frame on a to either the p->owner or p->chan
+/*!
+ * \brief queue a frame onto either the p->owner or p->chan
  *
  * \note the local_pvt MUST have it's ref count bumped before entering this function and
  * decremented after this function is called.  This is a side effect of the deadlock
@@ -390,7 +376,6 @@
 
 	/* Recalculate outbound channel */
 	other = isoutbound ? p->owner : p->chan;
-
 	if (!other) {
 		return 0;
 	}
@@ -438,6 +423,7 @@
 	if (isoutbound) {
 		/* Pass along answer since somebody answered us */
 		struct ast_frame answer = { AST_FRAME_CONTROL, { AST_CONTROL_ANSWER } };
+
 		res = local_queue_frame(p, isoutbound, &answer, ast, 1);
 	} else {
 		ast_log(LOG_WARNING, "Huh?  Local is being asked to answer?\n");
@@ -514,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;
@@ -532,8 +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);
@@ -565,6 +560,7 @@
 	} else if (condition == AST_CONTROL_CONNECTED_LINE || condition == AST_CONTROL_REDIRECTING) {
 		struct ast_channel *this_channel;
 		struct ast_channel *the_other_channel;
+
 		/* A connected line update frame may only contain a partial amount of data, such
 		 * as just a source, or just a ton, and not the full amount of information. However,
 		 * the collected information is all stored in the outgoing channel's connectedline
@@ -583,6 +579,7 @@
 		}
 		if (the_other_channel) {
 			unsigned char frame_data[1024];
+
 			if (condition == AST_CONTROL_CONNECTED_LINE) {
 				if (isoutbound) {
 					ast_connected_line_copy_to_caller(ast_channel_caller(the_other_channel), ast_channel_connected(this_channel));
@@ -611,10 +608,10 @@
 			f.datalen = datalen;
 			res = local_queue_frame(p, isoutbound, &f, ast, 1);
 
-			if (!res && (condition == AST_CONTROL_T38_PARAMETERS) &&
-			    (datalen == sizeof(struct ast_control_t38_parameters))) {
+			if (!res && condition == AST_CONTROL_T38_PARAMETERS
+				&& datalen == sizeof(struct ast_control_t38_parameters)) {
 				const struct ast_control_t38_parameters *parameters = data;
-				
+
 				if (parameters->request_response == AST_T38_REQUEST_PARMS) {
 					res = AST_T38_REQUEST_PARMS;
 				}
@@ -815,7 +812,7 @@
 		S_COR(ast_channel_caller(owner)->id.number.valid, ast_channel_caller(owner)->id.number.str, NULL))) {
 		ast_log(LOG_NOTICE, "No such extension/context %s@%s while calling Local channel\n", exten, context);
 		res = -1;
-		chan = ast_channel_unref(chan); /* we already unlocked it, so clear it hear so the cleanup label won't touch it. */
+		chan = ast_channel_unref(chan); /* we already unlocked it, so clear it here so the cleanup label won't touch it. */
 		goto return_cleanup;
 	}
 
@@ -845,20 +842,22 @@
 		</managerEventInstance>
 	***/
 	manager_event(EVENT_FLAG_CALL, "LocalBridge",
-		      "Channel1: %s\r\n"
-		      "Channel2: %s\r\n"
-		      "Uniqueid1: %s\r\n"
-		      "Uniqueid2: %s\r\n"
-		      "Context: %s\r\n"
-		      "Exten: %s\r\n"
-		      "LocalOptimization: %s\r\n",
-			ast_channel_name(p->owner), ast_channel_name(p->chan), ast_channel_uniqueid(p->owner), ast_channel_uniqueid(p->chan),
-			p->context, p->exten,
-			ast_test_flag(p, LOCAL_NO_OPTIMIZATION) ? "Yes" : "No");
+		"Channel1: %s\r\n"
+		"Channel2: %s\r\n"
+		"Uniqueid1: %s\r\n"
+		"Uniqueid2: %s\r\n"
+		"Context: %s\r\n"
+		"Exten: %s\r\n"
+		"LocalOptimization: %s\r\n",
+		ast_channel_name(p->owner), ast_channel_name(p->chan),
+		ast_channel_uniqueid(p->owner), ast_channel_uniqueid(p->chan),
+		p->context, p->exten,
+		ast_test_flag(p, LOCAL_NO_OPTIMIZATION) ? "Yes" : "No");
 
 
 	/* Start switch on sub channel */
-	if (!(res = ast_pbx_start(chan))) {
+	res = ast_pbx_start(chan);
+	if (!res) {
 		ao2_lock(p);
 		ast_set_flag(p, LOCAL_LAUNCHED_PBX);
 		ao2_unlock(p);
@@ -951,7 +950,6 @@
 	if (!p->owner && !p->chan) {
 		ao2_unlock(p);
 
-		/* Remove from list */
 		ao2_unlink(locals, p);
 		ao2_ref(p, -1);
 		p = NULL;
@@ -1036,8 +1034,7 @@
 			if (ast_test_flag(tmp, LOCAL_NO_OPTIMIZATION))
 				ast_set_flag(&tmp->jb_conf, AST_JB_ENABLED);
 			else {
-				ast_log(LOG_ERROR, "You must use the 'n' option for chan_local "
-					"to use the 'j' option to enable the jitterbuffer\n");
+				ast_log(LOG_ERROR, "You must use the 'n' option with the 'j' option to enable the jitter buffer\n");
 			}
 		}
 		if (strchr(opts, 'm')) {
@@ -1053,7 +1050,6 @@
 	ast_copy_string(tmp->context, c ? c : "default", sizeof(tmp->context));
 	ast_copy_string(tmp->exten, parse, sizeof(tmp->exten));
 
-	/* Add to list */
 	ao2_link(locals, tmp);
 
 	return tmp; /* this is returned with a ref */
@@ -1062,75 +1058,64 @@
 /*! \brief Start new local channel */
 static struct ast_channel *local_new(struct local_pvt *p, int state, const char *linkedid, struct ast_callid *callid)
 {
-	struct ast_channel *tmp = NULL, *tmp2 = NULL;
+	struct ast_channel *owner;
+	struct ast_channel *chan;
 	struct ast_format fmt;
 	int generated_seqno = ast_atomic_fetchadd_int((int *)&name_sequence, +1);
-	const char *t;
-	int ama;
-
-	/* Allocate two new Asterisk channels */
-	/* safe accountcode */
-	if (p->owner && ast_channel_accountcode(p->owner))
-		t = ast_channel_accountcode(p->owner);
-	else
-		t = "";
-
-	if (p->owner)
-		ama = ast_channel_amaflags(p->owner);
-	else
-		ama = 0;
-
-	/* Make sure that the ;2 channel gets the same linkedid as ;1. You can't pass linkedid to both
-	 * allocations since if linkedid isn't set, then each channel will generate its own linkedid. */
-	if (!(tmp = ast_channel_alloc(1, state, 0, 0, t, p->exten, p->context, linkedid, ama, "Local/%s@%s-%08x;1", p->exten, p->context, generated_seqno))
-		|| !(tmp2 = ast_channel_alloc(1, AST_STATE_RING, 0, 0, t, p->exten, p->context, ast_channel_linkedid(tmp), ama, "Local/%s@%s-%08x;2", p->exten, p->context, generated_seqno))) {
-		if (tmp) {
-			tmp = ast_channel_release(tmp);
+
+	/*
+	 * Allocate two new Asterisk channels
+	 *
+	 * Make sure that the ;2 channel gets the same linkedid as ;1.
+	 * You can't pass linkedid to both allocations since if linkedid
+	 * isn't set, then each channel will generate its own linkedid.
+	 */
+	if (!(owner = ast_channel_alloc(1, state, NULL, NULL, NULL,
+			p->exten, p->context, linkedid, 0,
+			"Local/%s@%s-%08x;1", p->exten, p->context, generated_seqno))
+		|| !(chan = ast_channel_alloc(1, AST_STATE_RING, NULL, NULL, NULL,
+			p->exten, p->context, ast_channel_linkedid(owner), 0,
+			"Local/%s@%s-%08x;2", p->exten, p->context, generated_seqno))) {
+		if (owner) {
+			owner = ast_channel_release(owner);
 		}
 		ast_log(LOG_WARNING, "Unable to allocate channel structure(s)\n");
 		return NULL;
 	}
 
 	if (callid) {
-		ast_channel_callid_set(tmp, callid);
-		ast_channel_callid_set(tmp2, callid);
-	}
-
-	ast_channel_tech_set(tmp, &local_tech);
-	ast_channel_tech_set(tmp2, &local_tech);
-
-	ast_format_cap_copy(ast_channel_nativeformats(tmp), p->reqcap);
-	ast_format_cap_copy(ast_channel_nativeformats(tmp2), p->reqcap);
+		ast_channel_callid_set(owner, callid);
+		ast_channel_callid_set(chan, callid);
+	}
+
+	ast_channel_tech_set(owner, &local_tech);
+	ast_channel_tech_set(chan, &local_tech);
+	ast_channel_tech_pvt_set(owner, p);
+	ast_channel_tech_pvt_set(chan, p);
+
+	ast_format_cap_copy(ast_channel_nativeformats(owner), p->reqcap);
+	ast_format_cap_copy(ast_channel_nativeformats(chan), p->reqcap);
 
 	/* Determine our read/write format and set it on each channel */
 	ast_best_codec(p->reqcap, &fmt);
-	ast_format_copy(ast_channel_writeformat(tmp), &fmt);
-	ast_format_copy(ast_channel_writeformat(tmp2), &fmt);
-	ast_format_copy(ast_channel_rawwriteformat(tmp), &fmt);
-	ast_format_copy(ast_channel_rawwriteformat(tmp2), &fmt);
-	ast_format_copy(ast_channel_readformat(tmp), &fmt);
-	ast_format_copy(ast_channel_readformat(tmp2), &fmt);
-	ast_format_copy(ast_channel_rawreadformat(tmp), &fmt);
-	ast_format_copy(ast_channel_rawreadformat(tmp2), &fmt);
-
-	ast_channel_tech_pvt_set(tmp, p);
-	ast_channel_tech_pvt_set(tmp2, p);
-
-	ast_set_flag(ast_channel_flags(tmp), AST_FLAG_DISABLE_DEVSTATE_CACHE);
-	ast_set_flag(ast_channel_flags(tmp2), AST_FLAG_DISABLE_DEVSTATE_CACHE);
-
-	p->owner = tmp;
-	p->chan = tmp2;
-
-	ast_channel_context_set(tmp, p->context);
-	ast_channel_context_set(tmp2, p->context);
-	ast_channel_exten_set(tmp2, p->exten);
-	ast_channel_priority_set(tmp, 1);
-	ast_channel_priority_set(tmp2, 1);
-
-	ast_jb_configure(tmp, &p->jb_conf);
-
-	return tmp;
+	ast_format_copy(ast_channel_writeformat(owner), &fmt);
+	ast_format_copy(ast_channel_writeformat(chan), &fmt);
+	ast_format_copy(ast_channel_rawwriteformat(owner), &fmt);
+	ast_format_copy(ast_channel_rawwriteformat(chan), &fmt);
+	ast_format_copy(ast_channel_readformat(owner), &fmt);
+	ast_format_copy(ast_channel_readformat(chan), &fmt);
+	ast_format_copy(ast_channel_rawreadformat(owner), &fmt);
+	ast_format_copy(ast_channel_rawreadformat(chan), &fmt);
+
+	ast_set_flag(ast_channel_flags(owner), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+	ast_set_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+
+	p->owner = owner;
+	p->chan = chan;
+
+	ast_jb_configure(owner, &p->jb_conf);
+
+	return owner;
 }
 
 /*! \brief Part of PBX interface */
@@ -1211,43 +1196,31 @@
 static int manager_optimize_away(struct mansession *s, const struct message *m)
 {
 	const char *channel;
-	struct local_pvt *p, *tmp = NULL;
-	struct ast_channel *c;
-	int found = 0;
-	struct ao2_iterator it;
+	struct local_pvt *p;
+	struct local_pvt *found;
+	struct ast_channel *chan;
 
 	channel = astman_get_header(m, "Channel");
-
 	if (ast_strlen_zero(channel)) {
 		astman_send_error(s, m, "'Channel' not specified.");
 		return 0;
 	}
 
-	c = ast_channel_get_by_name(channel);
-	if (!c) {
+	chan = ast_channel_get_by_name(channel);
+	if (!chan) {
 		astman_send_error(s, m, "Channel does not exist.");
 		return 0;
 	}
 
-	p = ast_channel_tech_pvt(c);
-	ast_channel_unref(c);
-	c = NULL;
-
-	it = ao2_iterator_init(locals, 0);
-	while ((tmp = ao2_iterator_next(&it))) {
-		if (tmp == p) {
-			ao2_lock(tmp);
-			found = 1;
-			ast_clear_flag(tmp, LOCAL_NO_OPTIMIZATION);
-			ao2_unlock(tmp);
-			ao2_ref(tmp, -1);
-			break;
-		}
-		ao2_ref(tmp, -1);
-	}
-	ao2_iterator_destroy(&it);
-
+	p = ast_channel_tech_pvt(chan);
+	ast_channel_unref(chan);
+
+	found = p ? ao2_find(locals, p, 0) : NULL;
 	if (found) {
+		ao2_lock(found);
+		ast_clear_flag(found, LOCAL_NO_OPTIMIZATION);
+		ao2_unlock(found);
+		ao2_ref(found, -1);
 		astman_send_ack(s, m, "Queued channel to be optimized away");
 	} else {
 		astman_send_error(s, m, "Unable to find channel");
@@ -1270,7 +1243,8 @@
 	}
 	ast_format_cap_add_all(local_tech.capabilities);
 
-	if (!(locals = ao2_container_alloc(BUCKET_SIZE, NULL, locals_cmp_cb))) {
+	locals = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, locals_cmp_cb);
+	if (!locals) {
 		ast_format_cap_destroy(local_tech.capabilities);
 		return AST_MODULE_LOAD_FAILURE;
 	}

Modified: team/jrose/bridge_projects/channels/chan_mgcp.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/channels/chan_mgcp.c?view=diff&rev=387588&r1=387587&r2=387588
==============================================================================
--- team/jrose/bridge_projects/channels/chan_mgcp.c (original)
+++ team/jrose/bridge_projects/channels/chan_mgcp.c Fri May  3 12:25:41 2013
@@ -3226,11 +3226,10 @@
 	   together (but then, why would we want to?) */
 	if (ast_bridged_channel(p->sub->owner)) {
 		/* The three-way person we're about to transfer to could still be in MOH, so
-		   stop if now if appropriate */
-		if (ast_bridged_channel(p->sub->next->owner))
-			ast_queue_control(p->sub->next->owner, AST_CONTROL_UNHOLD);
+		   stop it now */
+		ast_queue_control(p->sub->next->owner, AST_CONTROL_UNHOLD);
 		if (ast_channel_state(p->sub->owner) == AST_STATE_RINGING) {

[... 2893 lines stripped ...]



More information about the asterisk-commits mailing list