[asterisk-commits] rmudgett: branch 1.4 r318734 - in /branches/1.4: apps/ channels/ res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu May 12 20:10:07 CDT 2011


Author: rmudgett
Date: Thu May 12 20:09:40 2011
New Revision: 318734

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=318734
Log:
Merged revisions 318671 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.8

* The applicable fixes for v1.4 are the SIP deadlock and the in progress
masquerade check for multiple parties trying to pickup the same call.
      issue18654_v1.4.patch uploaded by rmudgett (license 664)

* Backported to v1.6.2.
      issue18654_v1.6.2.patch uploaded by rmudgett (license 664)

........
  r318671 | alecdavis | 2011-05-13 10:52:08 +1200 (Fri, 13 May 2011) | 30 lines

  Fix directed group pickup feature code *8 with pickupsounds enabled

  Since 1.6.2, the new pickupsound and pickupfailsound in features.conf cause many issues.

  1). chan_sip:handle_request_invite() shouldn't be playing out the fail/success audio, as it has 'netlock' locked.
  2). dialplan applications for directed_pickups shouldn't beep.
  3). feature code for directed pickup should beep on success/failure if configured.

  Created a sip_pickup() thread to handle the pickup and playout the audio, spawned from handle_request_invite.

  Moved app_directed:pickup_do() to features:ast_do_pickup().

  Functions below, all now use the new ast_do_pickup()
  app_directed_pickup.c:
     pickup_by_channel()
     pickup_by_exten()
     pickup_by_mark()
     pickup_by_part()
  features.c:
     ast_pickup_call()

  (closes issue #18654)
  Reported by: Docent
  Patches:
        ast_do_pickup_1.8_trunk.diff.txt uploaded by alecdavis (license 585)
  Tested by: lmadsen, francesco_r, amilcar, isis242, alecdavis, irroot, rymkus, loloski, rmudgett

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

Modified:
    branches/1.4/apps/app_directed_pickup.c
    branches/1.4/channels/chan_sip.c
    branches/1.4/res/res_features.c

Modified: branches/1.4/apps/app_directed_pickup.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/apps/app_directed_pickup.c?view=diff&rev=318734&r1=318733&r2=318734
==============================================================================
--- branches/1.4/apps/app_directed_pickup.c (original)
+++ branches/1.4/apps/app_directed_pickup.c Thu May 12 20:09:40 2011
@@ -54,39 +54,45 @@
 "10 at PICKUPMARK, this application tries to find a channel which has defined a channel variable with the same content\n"
 "as \"extension\".";
 
-/* Perform actual pickup between two channels */
+/*!
+ * \internal
+ * \brief Perform actual pickup between two channels.
+ * \note Must remain in sync with same function in res/res_features.c.
+ */
 static int pickup_do(struct ast_channel *chan, struct ast_channel *target)
 {
-	int res = 0;
-
 	if (option_debug)
 		ast_log(LOG_DEBUG, "Call pickup on '%s' by '%s'\n", target->name, chan->name);
 
-	if ((res = ast_answer(chan))) {
+	if (ast_answer(chan)) {
 		ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
 		return -1;
 	}
 
-	if ((res = ast_queue_control(chan, AST_CONTROL_ANSWER))) {
+	if (ast_queue_control(chan, AST_CONTROL_ANSWER)) {
 		ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n", chan->name);
 		return -1;
 	}
 
-	if ((res = ast_channel_masquerade(target, chan))) {
+	if (ast_channel_masquerade(target, chan)) {
 		ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, target->name);
 		return -1;
 	}
 
-	return res;
+	return 0;
 }
 
 /* Helper function that determines whether a channel is capable of being picked up */
 static int can_pickup(struct ast_channel *chan)
 {
-	if (!chan->pbx && (chan->_state == AST_STATE_RINGING || chan->_state == AST_STATE_RING || chan->_state == AST_STATE_DOWN))
+	if (!chan->pbx && !chan->masq &&
+		!ast_test_flag(chan, AST_FLAG_ZOMBIE) &&
+		(chan->_state == AST_STATE_RINGING ||
+		 chan->_state == AST_STATE_RING ||
+		 chan->_state == AST_STATE_DOWN)) {
 		return 1;
-	else
-		return 0;
+	}
+	return 0;
 }
 
 /* Attempt to pick up specified extension with context */

Modified: branches/1.4/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/channels/chan_sip.c?view=diff&rev=318734&r1=318733&r2=318734
==============================================================================
--- branches/1.4/channels/chan_sip.c (original)
+++ branches/1.4/channels/chan_sip.c Thu May 12 20:09:40 2011
@@ -15867,6 +15867,7 @@
 
 					/* Unlock locks so ast_hangup can do its magic */
 					ast_mutex_unlock(&c->lock);
+					*nounlock = 1;
 					ast_mutex_unlock(&p->lock);
 					ast_hangup(c);
 					ast_mutex_lock(&p->lock);
@@ -15875,7 +15876,9 @@
 			} else {	/* Pickup call in call group */
 				ast_channel_unlock(c);
 				*nounlock = 1;
+				ast_mutex_unlock(&p->lock);
 				if (ast_pickup_call(c)) {
+					ast_mutex_lock(&p->lock);
 					ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid);
 					if (ast_test_flag(req, SIP_PKT_IGNORE))
 						transmit_response(p, "503 Unavailable", req);	/* OEJ - Right answer? */
@@ -15886,13 +15889,11 @@
 					ast_mutex_unlock(&p->lock);
 					c->hangupcause = AST_CAUSE_CALL_REJECTED;
 				} else {
-					ast_mutex_unlock(&p->lock);
-					ast_setstate(c, AST_STATE_DOWN);
 					c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
 				}
-				p->invitestate = INV_COMPLETED;
 				ast_hangup(c);
 				ast_mutex_lock(&p->lock);
+				p->invitestate = INV_COMPLETED;
 				c = NULL;
 			}
 			break;

Modified: branches/1.4/res/res_features.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.4/res/res_features.c?view=diff&rev=318734&r1=318733&r2=318734
==============================================================================
--- branches/1.4/res/res_features.c (original)
+++ branches/1.4/res/res_features.c Thu May 12 20:09:40 2011
@@ -3374,6 +3374,34 @@
 }
 
 
+/*!
+ * \internal
+ * \brief Perform actual pickup between two channels.
+ * \note Must remain in sync with same function in apps/app_directed_pickup.c.
+ */
+static int pickup_do(struct ast_channel *chan, struct ast_channel *target)
+{
+	if (option_debug)
+		ast_log(LOG_DEBUG, "Call pickup on '%s' by '%s'\n", target->name, chan->name);
+
+	if (ast_answer(chan)) {
+		ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
+		return -1;
+	}
+
+	if (ast_queue_control(chan, AST_CONTROL_ANSWER)) {
+		ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n", chan->name);
+		return -1;
+	}
+
+	if (ast_channel_masquerade(target, chan)) {
+		ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, target->name);
+		return -1;
+	}
+
+	return 0;
+}
+
 int ast_pickup_call(struct ast_channel *chan)
 {
 	struct ast_channel *cur = NULL;
@@ -3385,27 +3413,21 @@
 			(chan->pickupgroup & cur->callgroup) &&
 			((cur->_state == AST_STATE_RINGING) ||
 			 (cur->_state == AST_STATE_RING)) &&
-			!cur->masq) {
+			!cur->masq &&
+			!ast_test_flag(cur, AST_FLAG_ZOMBIE)) {
 			 	break;
 		}
 		ast_channel_unlock(cur);
 	}
 	if (cur) {
-		if (option_debug)
-			ast_log(LOG_DEBUG, "Call pickup on chan '%s' by '%s'\n",cur->name, chan->name);
-		res = ast_answer(chan);
-		if (res)
-			ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
-		res = ast_queue_control(chan, AST_CONTROL_ANSWER);
-		if (res)
-			ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n", chan->name);
-		res = ast_channel_masquerade(cur, chan);
-		if (res)
-			ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, cur->name);		/* Done */
+		res = pickup_do(chan, cur);
+		if (res) {
+			ast_log(LOG_WARNING, "pickup %s failed by %s\n", cur->name, chan->name);
+		}
 		ast_channel_unlock(cur);
 	} else	{
 		if (option_debug)
-			ast_log(LOG_DEBUG, "No call pickup possible...\n");
+			ast_log(LOG_DEBUG, "No call pickup possible... for %s\n", chan->name);
 	}
 	return res;
 }




More information about the asterisk-commits mailing list