[asterisk-commits] rmudgett: branch 12 r400236 - /branches/12/channels/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Oct 1 16:17:58 CDT 2013


Author: rmudgett
Date: Tue Oct  1 16:17:56 2013
New Revision: 400236

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=400236
Log:
chan_dahdi: Fix analog parking using flash-hook.

Transferring an analog call using a flash-hook to parking would fail to
park the call and result in an invalid ao2 object unref.

* Park the correct bridged channel.

Modified:
    branches/12/channels/chan_dahdi.c
    branches/12/channels/sig_analog.c

Modified: branches/12/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/channels/chan_dahdi.c?view=diff&rev=400236&r1=400235&r2=400236
==============================================================================
--- branches/12/channels/chan_dahdi.c (original)
+++ branches/12/channels/chan_dahdi.c Tue Oct  1 16:17:56 2013
@@ -9722,16 +9722,34 @@
 				getforward = 0;
 				memset(exten, 0, sizeof(exten));
 				len = 0;
-			} else if ((p->transfer || p->canpark) && is_exten_parking &&
-						p->subs[SUB_THREEWAY].owner) {
-				RAII_VAR(struct ast_bridge_channel *, bridge_channel, NULL, ao2_cleanup);
-				/* This is a three way call, the main call being a real channel,
-					and we're parking the first call. */
-				ast_channel_lock(chan);
-				bridge_channel = ast_channel_get_bridge_channel(chan);
-				ast_channel_unlock(chan);
-				if (bridge_channel && !ast_parking_blind_transfer_park(bridge_channel, ast_channel_context(chan), exten)) {
-					ast_verb(3, "Parking call to '%s'\n", ast_channel_name(chan));
+			} else if ((p->transfer || p->canpark) && is_exten_parking
+				&& p->subs[SUB_THREEWAY].owner) {
+				struct ast_bridge_channel *bridge_channel;
+
+				/*
+				 * This is a three way call, the main call being a real channel,
+				 * and we're parking the first call.
+				 */
+				ast_channel_lock(p->subs[SUB_THREEWAY].owner);
+				bridge_channel = ast_channel_get_bridge_channel(p->subs[SUB_THREEWAY].owner);
+				ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
+				if (bridge_channel) {
+					if (!ast_parking_blind_transfer_park(bridge_channel, ast_channel_context(chan), exten)) {
+						/*
+						 * Swap things around between the three-way and real call so we
+						 * can hear where the channel got parked.
+						 */
+						ast_mutex_lock(&p->lock);
+						p->owner = p->subs[SUB_THREEWAY].owner;
+						swap_subs(p, SUB_THREEWAY, SUB_REAL);
+						ast_mutex_unlock(&p->lock);
+
+						ast_verb(3, "%s: Parked call\n", ast_channel_name(chan));
+						ast_hangup(chan);
+						ao2_ref(bridge_channel, -1);
+						goto quit;
+					}
+					ao2_ref(bridge_channel, -1);
 				}
 				break;
 			} else if (p->hidecallerid && !strcmp(exten, "*82")) {

Modified: branches/12/channels/sig_analog.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/channels/sig_analog.c?view=diff&rev=400236&r1=400235&r2=400236
==============================================================================
--- branches/12/channels/sig_analog.c (original)
+++ branches/12/channels/sig_analog.c Tue Oct  1 16:17:56 2013
@@ -2245,18 +2245,35 @@
 				getforward = 0;
 				memset(exten, 0, sizeof(exten));
 				len = 0;
-			} else if ((p->transfer || p->canpark) && is_exten_parking &&
-						p->subs[ANALOG_SUB_THREEWAY].owner) {
+			} else if ((p->transfer || p->canpark) && is_exten_parking
+				&& p->subs[ANALOG_SUB_THREEWAY].owner) {
 				struct ast_bridge_channel *bridge_channel;
-				/* This is a three way call, the main call being a real channel,
-					and we're parking the first call. */
-				ast_channel_lock(chan);
-				bridge_channel = ast_channel_get_bridge_channel(chan);
-				ast_channel_unlock(chan);
-				if (bridge_channel && !ast_parking_blind_transfer_park(bridge_channel, ast_channel_context(chan), exten)) {
-					ast_verb(3, "Parking call to '%s'\n", ast_channel_name(chan));
-				}
-				ao2_ref(bridge_channel, -1);
+
+				/*
+				 * This is a three way call, the main call being a real channel,
+				 * and we're parking the first call.
+				 */
+				ast_channel_lock(p->subs[ANALOG_SUB_THREEWAY].owner);
+				bridge_channel = ast_channel_get_bridge_channel(p->subs[ANALOG_SUB_THREEWAY].owner);
+				ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner);
+				if (bridge_channel) {
+					if (!ast_parking_blind_transfer_park(bridge_channel, ast_channel_context(chan), exten)) {
+						/*
+						 * Swap things around between the three-way and real call so we
+						 * can hear where the channel got parked.
+						 */
+						analog_lock_private(p);
+						analog_set_new_owner(p, p->subs[ANALOG_SUB_THREEWAY].owner);
+						analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
+						analog_unlock_private(p);
+
+						ast_verb(3, "%s: Parked call\n", ast_channel_name(chan));
+						ast_hangup(chan);
+						ao2_ref(bridge_channel, -1);
+						goto quit;
+					}
+					ao2_ref(bridge_channel, -1);
+				}
 				break;
 			} else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) {
 				ast_verb(3, "Blacklisting number %s\n", p->lastcid_num);




More information about the asterisk-commits mailing list