[asterisk-commits] russell: branch russell/issue_13747 r164199 - /team/russell/issue_13747/main/
SVN commits to the Asterisk project
asterisk-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 asterisk-commits
mailing list