[svn-commits] rmudgett: trunk r356523 - in /trunk: ./ channels/chan_sip.c main/features.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Feb 23 14:14:58 CST 2012


Author: rmudgett
Date: Thu Feb 23 14:14:54 2012
New Revision: 356523

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=356523
Log:
Fix blind transfer parking issues if the dialed extension is not recognized as a parking extension.

Custom parking extensions may not be coded such that the first and only
extension priority is the Park application.  These custom parking
extensions will not be recognized as parking extensions.  When a call is
blind transferred to an extension that is not recognized as a parking
extension, the normal blind transfer code causes the transferred channel
to start executing dialplan.  Calls that get parked in this manner do not
know the original channel name that parked the call so the original parker
could never be called back if the parked call is not retrieved before the
timeout time.  The parking space is also announced to the call being
parked as a side effect of not knowing the original parking channel.

* Fix handling of BLINDTRANSFER channel variable for call parking.

* Fixed SIP blind transfer using the wrong dialplan context variable to
check for the parking extension.

(closes issue ASTERISK-19322)
Reported by: aragon
Tested by: rmudgett, jparker

Review: https://reviewboard.asterisk.org/r/1730/

JIRA AST-766
........

Merged revisions 356521 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 356522 from http://svn.asterisk.org/svn/asterisk/branches/10

Modified:
    trunk/   (props changed)
    trunk/channels/chan_sip.c
    trunk/main/features.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-10-merged' - no diff available.

Modified: trunk/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_sip.c?view=diff&rev=356523&r1=356522&r2=356523
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Thu Feb 23 14:14:54 2012
@@ -24389,7 +24389,7 @@
 	sip_pvt_unlock(p);
 
 	/* Parking a call.  DO NOT hold any locks while calling ast_parking_ext_valid() */
-	if (localtransfer && ast_parking_ext_valid(refer_to, current.chan1, ast_channel_context(current.chan1))) {
+	if (localtransfer && ast_parking_ext_valid(refer_to, current.chan1, refer_to_context)) {
 		sip_pvt_lock(p);
 		ast_clear_flag(&p->flags[0], SIP_GOTREFER);
 		p->refer->status = REFER_200OK;
@@ -24418,7 +24418,7 @@
 		}
 
 		/* DO NOT hold any locks while calling sip_park */
-		if (sip_park(current.chan2, current.chan1, req, seqno, refer_to, ast_channel_context(current.chan1))) {
+		if (sip_park(current.chan2, current.chan1, req, seqno, refer_to, refer_to_context)) {
 			sip_pvt_lock(p);
 			transmit_notify_with_sipfrag(p, seqno, "500 Internal Server Error", TRUE);
 		} else {

Modified: trunk/main/features.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/features.c?view=diff&rev=356523&r1=356522&r2=356523
==============================================================================
--- trunk/main/features.c (original)
+++ trunk/main/features.c Thu Feb 23 14:14:54 2012
@@ -784,6 +784,7 @@
 	struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
 	const char *app_at_exten;
 
+	ast_debug(4, "Checking if %s@%s is a parking exten\n", exten_str, context);
 	exten = pbx_find_extension(chan, NULL, &q, context, exten_str, 1, NULL, NULL,
 		E_MATCH);
 	if (!exten) {
@@ -1388,7 +1389,7 @@
 static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, struct ast_park_call_args *args)
 {
 	struct parkeduser *pu = args->pu;
-	const char *event_from;
+	const char *event_from;		/*!< Channel name that is parking the call. */
 	char app_data[AST_MAX_EXTENSION + AST_MAX_CONTEXT];
 
 	if (pu == NULL) {
@@ -1407,10 +1408,10 @@
 	if (chan != peer) {
 		if (ast_test_flag(args, AST_PARK_OPT_RINGING)) {
 			pu->hold_method = AST_CONTROL_RINGING;
-			ast_indicate(pu->chan, AST_CONTROL_RINGING);
+			ast_indicate(chan, AST_CONTROL_RINGING);
 		} else {
 			pu->hold_method = AST_CONTROL_HOLD;
-			ast_indicate_data(pu->chan, AST_CONTROL_HOLD, 
+			ast_indicate_data(chan, AST_CONTROL_HOLD,
 				S_OR(pu->parkinglot->cfg.mohclass, NULL),
 				!ast_strlen_zero(pu->parkinglot->cfg.mohclass) ? strlen(pu->parkinglot->cfg.mohclass) + 1 : 0);
 		}
@@ -1421,7 +1422,9 @@
 	if (args->extout)
 		*(args->extout) = pu->parkingnum;
 
-	if (peer) { 
+	if (peer) {
+		event_from = S_OR(args->orig_chan_name, ast_channel_name(peer));
+
 		/*
 		 * This is so ugly that it hurts, but implementing
 		 * get_base_channel() on local channels could have ugly side
@@ -1436,7 +1439,7 @@
 			char other_side[AST_CHANNEL_NAME];
 			char *c;
 
-			ast_copy_string(other_side, S_OR(args->orig_chan_name, ast_channel_name(peer)), sizeof(other_side));
+			ast_copy_string(other_side, event_from, sizeof(other_side));
 			if ((c = strrchr(other_side, ';'))) {
 				*++c = '1';
 			}
@@ -1449,8 +1452,11 @@
 				tmpchan = ast_channel_unref(tmpchan);
 			}
 		} else {
-			ast_copy_string(pu->peername, S_OR(args->orig_chan_name, ast_channel_name(peer)), sizeof(pu->peername));
-		}
+			ast_copy_string(pu->peername, event_from, sizeof(pu->peername));
+		}
+	} else {
+		event_from = S_OR(pbx_builtin_getvar_helper(chan, "BLINDTRANSFER"),
+			ast_channel_name(chan));
 	}
 
 	/*
@@ -1486,18 +1492,12 @@
 	/* Wake up the (presumably select()ing) thread */
 	pthread_kill(parking_thread, SIGURG);
 	ast_verb(2, "Parked %s on %d (lot %s). Will timeout back to extension [%s] %s, %d in %d seconds\n",
-		ast_channel_name(pu->chan), pu->parkingnum, pu->parkinglot->name,
+		ast_channel_name(chan), pu->parkingnum, pu->parkinglot->name,
 		pu->context, pu->exten, pu->priority, (pu->parkingtime / 1000));
 
-	ast_cel_report_event(pu->chan, AST_CEL_PARK_START, NULL, pu->parkinglot->name, peer);
-
-	if (peer) {
-		event_from = ast_channel_name(peer);
-	} else {
-		event_from = pbx_builtin_getvar_helper(chan, "BLINDTRANSFER");
-	}
-
-	ast_manager_event(pu->chan, EVENT_FLAG_CALL, "ParkedCall",
+	ast_cel_report_event(chan, AST_CEL_PARK_START, NULL, pu->parkinglot->name, peer);
+
+	ast_manager_event(chan, EVENT_FLAG_CALL, "ParkedCall",
 		"Exten: %s\r\n"
 		"Channel: %s\r\n"
 		"Parkinglot: %s\r\n"
@@ -1508,14 +1508,19 @@
 		"ConnectedLineNum: %s\r\n"
 		"ConnectedLineName: %s\r\n"
 		"Uniqueid: %s\r\n",
-		pu->parkingexten, ast_channel_name(pu->chan), pu->parkinglot->name, event_from ? event_from : "",
+		pu->parkingexten, ast_channel_name(chan), pu->parkinglot->name, event_from,
 		(long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
-		S_COR(pu->chan->caller.id.number.valid, pu->chan->caller.id.number.str, "<unknown>"),
-		S_COR(pu->chan->caller.id.name.valid, pu->chan->caller.id.name.str, "<unknown>"),
-		S_COR(pu->chan->connected.id.number.valid, pu->chan->connected.id.number.str, "<unknown>"),
-		S_COR(pu->chan->connected.id.name.valid, pu->chan->connected.id.name.str, "<unknown>"),
-		ast_channel_uniqueid(pu->chan)
+		S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<unknown>"),
+		S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"),
+		S_COR(chan->connected.id.number.valid, chan->connected.id.number.str, "<unknown>"),
+		S_COR(chan->connected.id.name.valid, chan->connected.id.name.str, "<unknown>"),
+		ast_channel_uniqueid(chan)
 		);
+	ast_debug(4, "peer: %s\n", peer ? ast_channel_name(peer) : "-No peer-");
+	ast_debug(4, "args->orig_chan_name: %s\n", args->orig_chan_name ? args->orig_chan_name : "-none-");
+	ast_debug(4, "pu->peername: %s\n", pu->peername);
+	ast_debug(4, "AMI ParkedCall Channel: %s\n", ast_channel_name(chan));
+	ast_debug(4, "AMI ParkedCall From: %s\n", event_from);
 
 	if (peer && adsipark && ast_adsi_available(peer)) {
 		adsi_announce_park(peer, pu->parkingexten);	/* Only supports parking numbers */
@@ -1550,7 +1555,7 @@
 	if (peer == chan) { /* pu->notquiteyet = 1 */
 		/* Wake up parking thread if we're really done */
 		pu->hold_method = AST_CONTROL_HOLD;
-		ast_indicate_data(pu->chan, AST_CONTROL_HOLD, 
+		ast_indicate_data(chan, AST_CONTROL_HOLD,
 			S_OR(pu->parkinglot->cfg.mohclass, NULL),
 			!ast_strlen_zero(pu->parkinglot->cfg.mohclass) ? strlen(pu->parkinglot->cfg.mohclass) + 1 : 0);
 		pu->notquiteyet = 0;
@@ -3876,6 +3881,10 @@
 
 	pbx_builtin_setvar_helper(chan, "BRIDGEPEER", ast_channel_name(peer));
 	pbx_builtin_setvar_helper(peer, "BRIDGEPEER", ast_channel_name(chan));
+
+	/* Clear any BLINDTRANSFER since the transfer has completed. */
+	pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
+	pbx_builtin_setvar_helper(peer, "BLINDTRANSFER", NULL);
 
 	set_bridge_features_on_config(config, pbx_builtin_getvar_helper(chan, "BRIDGE_FEATURES"));
 	add_features_datastores(chan, peer, config);
@@ -4920,13 +4929,7 @@
 /*! \brief Park a call */
 static int park_call_exec(struct ast_channel *chan, const char *data)
 {
-	/* Cache the original channel name in case we get masqueraded in the middle
-	 * of a park--it is still theoretically possible for a transfer to happen before
-	 * we get here, but it is _really_ unlikely */
-	char *orig_chan_name = ast_strdupa(ast_channel_name(chan));
-	struct ast_park_call_args args = {
-		.orig_chan_name = orig_chan_name,
-	};
+	struct ast_park_call_args args = { 0, };
 	struct ast_flags flags = { 0 };
 	char orig_exten[AST_MAX_EXTENSION];
 	int orig_priority;
@@ -4934,6 +4937,19 @@
 	const char *pl_name;
 	char *parse;
 	struct park_app_args app_args;
+
+	/*
+	 * Cache the original channel name because we are going to
+	 * masquerade the channel.  Prefer the BLINDTRANSFER channel
+	 * name over this channel name.  BLINDTRANSFER could be set if
+	 * the parking access extension did not get detected and we are
+	 * executing the Park application from the dialplan.
+	 *
+	 * The orig_chan_name is used to return the call to the
+	 * originator on parking timeout.
+	 */
+	args.orig_chan_name = ast_strdupa(S_OR(
+		pbx_builtin_getvar_helper(chan, "BLINDTRANSFER"), ast_channel_name(chan)));
 
 	/* Answer if call is not up */
 	if (ast_channel_state(chan) != AST_STATE_UP) {




More information about the svn-commits mailing list