[svn-commits] rmudgett: branch group/v14_colp r164356 - in /team/group/v14_colp: ./ apps/ m...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Dec 15 12:31:32 CST 2008


Author: rmudgett
Date: Mon Dec 15 12:31:31 2008
New Revision: 164356

URL: http://svn.digium.com/view/asterisk?view=rev&rev=164356
Log:
Resolved conflict and restarted automerge.

Merged revisions 164201,164204 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
  r164201 | russell | 2008-12-15 08:31:37 -0600 (Mon, 15 Dec 2008) | 31 lines
  
  Handle a case where a call can be bridged to a channel that is still ringing.
  
  The issue that was reported was about a case where a RINGING channel got 
  redirected to an extension to pick up a call from parking.  Once the parked 
  call got taken out of parking, it heard silence until the other side answered.  
  Ideally, the caller that was parked would get a ringing indication.  This patch
  fixes this case so that the caller receives ringback once it comes out of 
  parking until the other side answers.
  
  The fixes are:
  
   - Make sure we remember that a channel was an outgoing channel when doing 
     a masquerade.  This prevents an erroneous ast_answer() call on the channel,
     which causes a bogus 200 OK to be sent in the case of SIP.
  
   - Add some additional comments to explain related parts of code.
  
   - Update the handling of the ast_channel visible_indication field.  Storing 
     values that are not stateful is pointless.  Control frames that are events 
     or commands should be ignored.
  
   - When a bridge first starts, check to see if the peer channel needs to be 
     given ringing indication because the calling side is still ringing.
  
   - Rework ast_indicate_data() a bit for the sake of readability.
  
  (closes issue #13747)
  Reported by: davidw
  Tested by: russell
  Review: http://reviewboard.digium.com/r/90/
........
  r164204 | file | 2008-12-15 09:05:08 -0600 (Mon, 15 Dec 2008) | 4 lines
  
  Can we try not to assign an unsigned int to -1?
  (closes issue #14074)
  Reported by: wetwired
........

Modified:
    team/group/v14_colp/   (props changed)
    team/group/v14_colp/apps/app_dial.c
    team/group/v14_colp/main/channel.c
    team/group/v14_colp/res/res_features.c

Propchange: team/group/v14_colp/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/group/v14_colp/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Mon Dec 15 12:31:31 2008
@@ -1,1 +1,1 @@
-/branches/1.4:1-164092
+/branches/1.4:1-164307

Modified: team/group/v14_colp/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/group/v14_colp/apps/app_dial.c?view=diff&rev=164356&r1=164355&r2=164356
==============================================================================
--- team/group/v14_colp/apps/app_dial.c (original)
+++ team/group/v14_colp/apps/app_dial.c Mon Dec 15 12:31:31 2008
@@ -924,7 +924,7 @@
 	char numsubst[256];
 	char *cid_num = NULL, *cid_name = NULL;
 	int privdb_val = 0;
-	unsigned int calldurationlimit = -1;
+	int calldurationlimit = -1;
 	long timelimit = 0;
 	long play_warning = 0;
 	long warning_freq = 0;

Modified: team/group/v14_colp/main/channel.c
URL: http://svn.digium.com/view/asterisk/team/group/v14_colp/main/channel.c?view=diff&rev=164356&r1=164355&r2=164356
==============================================================================
--- team/group/v14_colp/main/channel.c (original)
+++ team/group/v14_colp/main/channel.c Mon Dec 15 12:31:31 2008
@@ -2883,12 +2883,53 @@
 	return ast_indicate_data(chan, condition, NULL, 0);
 }
 
-int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
-{
-	int res = -1;
+static int attribute_const is_visible_indication(enum ast_control_frame_type condition)
+{
+	/* Don't include a default case here so that we get compiler warnings
+	 * when a new type is added. */
+
+	switch (condition) {
+	case AST_CONTROL_PROGRESS:
+	case AST_CONTROL_PROCEEDING:
+	case AST_CONTROL_VIDUPDATE:
+	case AST_CONTROL_SRCUPDATE:
+	case AST_CONTROL_RADIO_KEY:
+	case AST_CONTROL_RADIO_UNKEY:
+	case AST_CONTROL_OPTION:
+	case AST_CONTROL_WINK:
+	case AST_CONTROL_FLASH:
+	case AST_CONTROL_OFFHOOK:
+	case AST_CONTROL_TAKEOFFHOOK:
+	case AST_CONTROL_ANSWER:
+	case AST_CONTROL_HANGUP:
+	case AST_CONTROL_CONNECTED_LINE:
+	case AST_CONTROL_REDIRECTING:
+		break;
+
+	case AST_CONTROL_CONGESTION:
+	case AST_CONTROL_BUSY:
+	case AST_CONTROL_RINGING:
+	case AST_CONTROL_RING:
+	case AST_CONTROL_HOLD:
+	case AST_CONTROL_UNHOLD:
+		return 1;
+	}
+
+	return 0;
+}
+
+int ast_indicate_data(struct ast_channel *chan, int _condition,
+		const void *data, size_t datalen)
+{
+	/* By using an enum, we'll get compiler warnings for values not handled 
+	 * in switch statements. */
+	enum ast_control_frame_type condition = _condition;
+	const struct ind_tone_zone_sound *ts = NULL;
+	int res;
 
 	ast_channel_lock(chan);
-	/* Stop if we're a zombie or need a soft hangup */
+
+	/* Don't bother if the channel is about to go away, anyway. */
 	if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
 		ast_channel_unlock(chan);
 		return -1;
@@ -2923,59 +2964,80 @@
 	default:
 		break;
 	}	/* end switch */
-	if (chan->tech->indicate)
+	if (chan->tech->indicate) {
+		/* See if the channel driver can handle this condition. */
 		res = chan->tech->indicate(chan, condition, data, datalen);
+	} else {
+		res = -1;
+	}
+
 	ast_channel_unlock(chan);
-	if (!chan->tech->indicate || res) {
-		/*
-		 * Device does not support (that) indication, lets fake
-		 * it by doing our own tone generation. (PM2002)
-		 */
-		if (condition < 0)
-			ast_playtones_stop(chan);
-		else {
-			const struct ind_tone_zone_sound *ts = NULL;
-			switch (condition) {
-			case AST_CONTROL_RINGING:
-				ts = ast_get_indication_tone(chan->zone, "ring");
-				break;
-			case AST_CONTROL_BUSY:
-				ts = ast_get_indication_tone(chan->zone, "busy");
-				break;
-			case AST_CONTROL_CONGESTION:
-				ts = ast_get_indication_tone(chan->zone, "congestion");
-				break;
-			}
-			if (ts && ts->data[0]) {
-				if (option_debug)
-					ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
-				ast_playtones_start(chan,0,ts->data, 1);
-				res = 0;
-				chan->visible_indication = condition;
-			} else if (condition == AST_CONTROL_PROGRESS) {
-				/* ast_playtones_stop(chan); */
-			} else if (condition == AST_CONTROL_PROCEEDING) {
-				/* Do nothing, really */
-			} else if (condition == AST_CONTROL_HOLD) {
-				/* Do nothing.... */
-			} else if (condition == AST_CONTROL_UNHOLD) {
-				/* Do nothing.... */
-			} else if (condition == AST_CONTROL_VIDUPDATE) {
-				/* Do nothing.... */
-			} else if (condition == AST_CONTROL_SRCUPDATE) {
-				/* Do nothing... */
-			} else if (condition == AST_CONTROL_CONNECTED_LINE) {
-				/* Already handled above... */
-			} else if (condition == AST_CONTROL_REDIRECTING) {
-				/* Already handled above... */
-			} else {
-				/* not handled */
-				ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
-				res = -1;
-			}
-		}
-	} else
+
+	if (chan->tech->indicate && !res) {
+		/* The channel driver successfully handled this indication */
+		if (is_visible_indication(condition)) {
+			chan->visible_indication = condition;
+		}
+		return 0;
+	}
+
+	/* The channel driver does not support this indication, let's fake
+	 * it by doing our own tone generation if applicable. */
+
+	if (_condition < 0) {
+		/* Stop any tones that are playing */
+		ast_playtones_stop(chan);
+		return 0;
+	}
+
+	/* Handle conditions that we have tones for. */
+	switch (condition) {
+	case AST_CONTROL_RINGING:
+		ts = ast_get_indication_tone(chan->zone, "ring");
+		break;
+	case AST_CONTROL_BUSY:
+		ts = ast_get_indication_tone(chan->zone, "busy");
+		break;
+	case AST_CONTROL_CONGESTION:
+		ts = ast_get_indication_tone(chan->zone, "congestion");
+		break;
+	case AST_CONTROL_PROGRESS:
+	case AST_CONTROL_PROCEEDING:
+	case AST_CONTROL_VIDUPDATE:
+	case AST_CONTROL_SRCUPDATE:
+	case AST_CONTROL_RADIO_KEY:
+	case AST_CONTROL_RADIO_UNKEY:
+	case AST_CONTROL_OPTION:
+	case AST_CONTROL_WINK:
+	case AST_CONTROL_FLASH:
+	case AST_CONTROL_OFFHOOK:
+	case AST_CONTROL_TAKEOFFHOOK:
+	case AST_CONTROL_ANSWER:
+	case AST_CONTROL_HANGUP:
+	case AST_CONTROL_RING:
+	case AST_CONTROL_HOLD:
+	case AST_CONTROL_UNHOLD:
+	case AST_CONTROL_CONNECTED_LINE:
+	case AST_CONTROL_REDIRECTING:
+		/* Nothing left to do for these. */
+		res = 0;
+		break;
+	}
+
+	if (ts && ts->data[0]) {
+		/* We have a tone to play, yay. */
+		if (option_debug) {
+				ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
+		}
+		ast_playtones_start(chan, 0, ts->data, 1);
+		res = 0;
 		chan->visible_indication = condition;
+	}
+
+	if (res) {
+		/* not handled */
+		ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
+	}
 
 	return res;
 }
@@ -4105,7 +4167,7 @@
 	/* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
 	/* Application and data remain the same */
 	/* Clone exception  becomes real one, as with fdno */
-	ast_copy_flags(original, clone, AST_FLAG_EXCEPTION);
+	ast_copy_flags(original, clone, AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING);
 	original->fdno = clone->fdno;
 	/* Schedule context remains the same */
 	/* Stream stuff stays the same */
@@ -4160,9 +4222,17 @@
 		ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)!  Bad things may happen.\n",
 			original->tech->type, original->name);
 
-	/* If an indication is currently playing maintain it on the channel that is taking the place of original */
-	if (original->visible_indication)
+	/* 
+	 * If an indication is currently playing, maintain it on the channel 
+	 * that is taking the place of original 
+	 *
+	 * This is needed because the masquerade is swapping out in the internals
+	 * of this channel, and the new channel private data needs to be made
+	 * aware of the current visible indication (RINGING, CONGESTION, etc.)
+	 */
+	if (original->visible_indication) {
 		ast_indicate(original, original->visible_indication);
+	}
 	
 	/* Now, at this point, the "clone" channel is totally F'd up.  We mark it as
 	   a zombie so nothing tries to touch it.  If it's already been marked as a

Modified: team/group/v14_colp/res/res_features.c
URL: http://svn.digium.com/view/asterisk/team/group/v14_colp/res/res_features.c?view=diff&rev=164356&r1=164355&r2=164356
==============================================================================
--- team/group/v14_colp/res/res_features.c (original)
+++ team/group/v14_colp/res/res_features.c Mon Dec 15 12:31:31 2008
@@ -1485,8 +1485,16 @@
 	if (chan && peer) {
 		pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name);
 		pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name);
-	} else if (chan)
+	} else if (chan) {
 		pbx_builtin_setvar_helper(chan, "BLINDTRANSFER", NULL);
+	}
+
+	/* This is an interesting case.  One example is if a ringing channel gets redirected to
+	 * an extension that picks up a parked call.  This will make sure that the call taken
+	 * out of parking gets told that the channel it just got bridged to is still ringing. */
+	if (chan->_state == AST_STATE_RINGING && peer->visible_indication != AST_CONTROL_RINGING) {
+		ast_indicate(peer, AST_CONTROL_RINGING);
+	}
 
 	if (monitor_ok) {
 		const char *monitor_exec;




More information about the svn-commits mailing list