[svn-commits] russell: branch russell/issue_13747 r164199 - /team/russell/issue_13747/main/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Dec 15 08:09:25 CST 2008


Author: russell
Date: Mon Dec 15 08:09:25 2008
New Revision: 164199

URL: http://svn.digium.com/view/asterisk?view=rev&rev=164199
Log:
Re-work ast_indicate_data() for readability

Modified:
    team/russell/issue_13747/main/channel.c

Modified: team/russell/issue_13747/main/channel.c
URL: http://svn.digium.com/view/asterisk/team/russell/issue_13747/main/channel.c?view=diff&rev=164199&r1=164198&r2=164199
==============================================================================
--- team/russell/issue_13747/main/channel.c (original)
+++ team/russell/issue_13747/main/channel.c Mon Dec 15 08:09:25 2008
@@ -2448,8 +2448,46 @@
 	return ast_indicate_data(chan, condition, NULL, 0);
 }
 
-int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
-{
+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:
+		return 0;
+
+	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 = -1;
 
 	ast_channel_lock(chan);
@@ -2461,85 +2499,74 @@
 	}
 
 	if (chan->tech->indicate) {
+		/* See if the channel driver can handle this condition. */
 		res = chan->tech->indicate(chan, condition, data, datalen);
 	}
 
 	ast_channel_unlock(chan);
 
-	if (!chan->tech->indicate || res) {
-		/*
-		 * Device does not support (that) indication, lets fake
-		 * it by doing our own tone generation.
-		 */
-		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 {
-				/* not handled */
-				ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
-				res = -1;
-			}
-		}
-	} else {
-		/* Use an enum so that the following switch statement warns us if it doesn't
-		 * handle a control frame type. */
-		enum ast_control_frame_type control = condition;
-
-		/* There are some conditions where we don't want to store them off as
-		 * visible indications.  List them here. */
-		switch (control) {
-		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:
-			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:
+	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:
+		/* 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;




More information about the svn-commits mailing list