[asterisk-commits] branch group/autoconf_and_menuselect r20542 - /team/group/autoconf_and_menuse...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Sun Apr 16 09:55:04 MST 2006


Author: russell
Date: Sun Apr 16 11:55:02 2006
New Revision: 20542

URL: http://svn.digium.com/view/asterisk?rev=20542&view=rev
Log:
Merged revisions 20453-20454,20456,20477,20484,20511-20514,20540 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

........
r20453 | rizzo | 2006-04-16 09:27:58 -0400 (Sun, 16 Apr 2006) | 4 lines

Localize some variables documenting their usage.
Comment a possible problem with locking.


........
r20454 | rizzo | 2006-04-16 09:58:43 -0400 (Sun, 16 Apr 2006) | 9 lines

- replace some nested 'if' with '&&'
- bring the short case at the top of an 'if' statement
  (also fix misformatting)
- replace several 'if' with the '?' operator;
 
- invert the condition on an 'if' to reduce the nesting depth 
  (reindentation to be done later).


........
r20456 | rizzo | 2006-04-16 10:00:17 -0400 (Sun, 16 Apr 2006) | 3 lines

remove an extra lock.


........
r20477 | rizzo | 2006-04-16 10:03:43 -0400 (Sun, 16 Apr 2006) | 3 lines

add a missing ast_channel_unlock() evidenced by previous commits.


........
r20484 | rizzo | 2006-04-16 10:14:16 -0400 (Sun, 16 Apr 2006) | 3 lines

properly reindent a block


........
r20511 | rizzo | 2006-04-16 11:13:39 -0400 (Sun, 16 Apr 2006) | 11 lines

simplify function __ast_request_and_dial() as follows:
- handle immediately failures in ast_request();
  This removes the need for checking 'chan' multiple times afterwards.
- handle immediately failures in ast_call(), by moving the one-line
  case at the top of the 'if' statement;
- use ast_strlen_zero in several places instead of expanding it inline;
- make outstate always a valid pointer;
On passing mark an unclear statement and replace a magic number
with sizeof(tmp).


........
r20512 | rizzo | 2006-04-16 11:22:13 -0400 (Sun, 16 Apr 2006) | 3 lines

avoid returning in the middle of a switch() in  ast_answer()


........
r20513 | rizzo | 2006-04-16 11:27:58 -0400 (Sun, 16 Apr 2006) | 3 lines

move common code in one place


........
r20514 | rizzo | 2006-04-16 11:51:53 -0400 (Sun, 16 Apr 2006) | 3 lines

simplify logic in ast_generic_bridge()


........
r20540 | rizzo | 2006-04-16 12:04:24 -0400 (Sun, 16 Apr 2006) | 3 lines

move common conditions to the outside block.


........

Modified:
    team/group/autoconf_and_menuselect/   (props changed)
    team/group/autoconf_and_menuselect/channel.c

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

Propchange: team/group/autoconf_and_menuselect/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Sun Apr 16 11:55:02 2006
@@ -1,1 +1,1 @@
-/trunk:1-20428
+/trunk:1-20541

Modified: team/group/autoconf_and_menuselect/channel.c
URL: http://svn.digium.com/view/asterisk/team/group/autoconf_and_menuselect/channel.c?rev=20542&r1=20541&r2=20542&view=diff
==============================================================================
--- team/group/autoconf_and_menuselect/channel.c (original)
+++ team/group/autoconf_and_menuselect/channel.c Sun Apr 16 11:55:02 2006
@@ -1496,8 +1496,6 @@
 		ast_setstate(chan, AST_STATE_UP);
 		if (chan->cdr)
 			ast_cdr_answer(chan->cdr);
-		ast_channel_unlock(chan);
-		return res;
 		break;
 	case AST_STATE_UP:
 		if (chan->cdr)
@@ -1505,7 +1503,7 @@
 		break;
 	}
 	ast_channel_unlock(chan);
-	return 0;
+	return res;
 }
 
 void ast_deactivate_generator(struct ast_channel *chan)
@@ -1825,14 +1823,10 @@
 
 static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
 {
-	struct ast_frame *f = NULL;
+	struct ast_frame *f = NULL;	/* the return value */
 	int blah;
 	int prestate;
-#ifdef HAVE_ZAPTEL
-	int (*func)(void *);
-	void *data;
-	int res;
-#endif
+
 	ast_channel_lock(chan);
 	if (chan->masq) {
 		if (ast_do_masquerade(chan)) {
@@ -1869,6 +1863,8 @@
 		read(chan->alertpipe[0], &blah, sizeof(blah));
 #ifdef HAVE_ZAPTEL
 	if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD && ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
+		int res;
+
 		ast_clear_flag(chan, AST_FLAG_EXCEPTION);
 		blah = -1;
 		/* IF we can't get event, assume it's an expired as-per the old interface */
@@ -1885,17 +1881,14 @@
 			}
 		} else if (blah == ZT_EVENT_TIMER_EXPIRED) {
 			ioctl(chan->timingfd, ZT_TIMERACK, &blah);
-			func = chan->timingfunc;
-			data = chan->timingdata;
-			ast_channel_unlock(chan);
-			if (func) {
-#if 0
-				ast_log(LOG_DEBUG, "Calling private function\n");
-#endif			
+			if (chan->timingfunc) {
+				/* save a copy of func/data before unlocking the channel */
+				int (*func)(void *) = chan->timingfunc;
+				void *data = chan->timingdata;
+				ast_channel_unlock(chan);
 				func(data);
 			} else {
 				blah = 0;
-				ast_channel_lock(chan);
 				ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
 				chan->timingdata = NULL;
 				ast_channel_unlock(chan);
@@ -1912,6 +1905,7 @@
 		chan->generatordata = NULL;     /* reset to let ast_write get through */
 		chan->generator->generate(chan, tmp, -1, -1);
 		chan->generatordata = tmp;
+		ast_channel_unlock(chan);
 		return &ast_null_frame;
 	}
 
@@ -1936,12 +1930,10 @@
 			}
 			/* Clear the exception flag */
 			ast_clear_flag(chan, AST_FLAG_EXCEPTION);
-		} else {
-			if (chan->tech->read)
-				f = chan->tech->read(chan);
-			else
-				ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
-		}
+		} else if (chan->tech->read)
+			f = chan->tech->read(chan);
+		else
+			ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
 	}
 
 	if (f) {
@@ -2020,10 +2012,8 @@
 					}
 				}
 
-				if (chan->readtrans) {
-					if (!(f = ast_translate(chan->readtrans, f, 1)))
-						f = &ast_null_frame;
-				}
+				if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL)
+					f = &ast_null_frame;
 
 				/* Run generator sitting on the line if timing device not available
 				* and synchronous generation of outgoing frames is necessary       */
@@ -2116,7 +2106,9 @@
 		 * Device does not support (that) indication, lets fake
 		 * it by doing our own tone generation. (PM2002)
 		 */
-		if (condition >= 0) {
+		if (condition < 0)
+			ast_playtones_stop(chan);
+		else {
 			const struct tone_zone_sound *ts = NULL;
 			switch (condition) {
 			case AST_CONTROL_RINGING:
@@ -2149,7 +2141,6 @@
 				res = -1;
 			}
 		}
-		else ast_playtones_stop(chan);
 	}
 	return res;
 }
@@ -2287,6 +2278,7 @@
 {
 	int res = -1;
 	struct ast_frame *f = NULL;
+
 	/* Stop if we're a zombie or need a soft hangup */
 	ast_channel_lock(chan);
 	if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))  {
@@ -2294,12 +2286,10 @@
 		return -1;
 	}
 	/* Handle any pending masquerades */
-	if (chan->masq) {
-		if (ast_do_masquerade(chan)) {
-			ast_log(LOG_WARNING, "Failed to perform masquerade\n");
-			ast_channel_unlock(chan);
-			return -1;
-		}
+	if (chan->masq && ast_do_masquerade(chan)) {
+		ast_log(LOG_WARNING, "Failed to perform masquerade\n");
+		ast_channel_unlock(chan);
+		return -1;
 	}
 	if (chan->masqr) {
 		ast_channel_unlock(chan);
@@ -2323,16 +2313,12 @@
 		ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n");
 		break;
 	case AST_FRAME_DTMF_BEGIN:
-		if (chan->tech->send_digit_begin)
-			res = chan->tech->send_digit_begin(chan, fr->subclass);
-		else
-			res = 0;
+		res = (chan->tech->send_digit_begin == NULL) ? 0 :
+			chan->tech->send_digit_begin(chan, fr->subclass);
 		break;
 	case AST_FRAME_DTMF_END:
-		if (chan->tech->send_digit_end)
-			res = chan->tech->send_digit_end(chan);
-		else
-			res = 0;
+		res = (chan->tech->send_digit_end == NULL) ? 0 :
+			chan->tech->send_digit_end(chan);
 		break;
 	case AST_FRAME_DTMF:
 		ast_clear_flag(chan, AST_FLAG_BLOCKING);
@@ -2342,67 +2328,64 @@
 		CHECK_BLOCKING(chan);
 		break;
 	case AST_FRAME_TEXT:
-		if (chan->tech->send_text)
-			res = chan->tech->send_text(chan, (char *) fr->data);
-		else
-			res = 0;
+		res = (chan->tech->send_text == NULL) ? 0 :
+			chan->tech->send_text(chan, (char *) fr->data);
 		break;
 	case AST_FRAME_HTML:
-		if (chan->tech->send_html)
-			res = chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
-		else
-			res = 0;
+		res = (chan->tech->send_html == NULL) ? 0 :
+			chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
 		break;
 	case AST_FRAME_VIDEO:
 		/* XXX Handle translation of video codecs one day XXX */
-		if (chan->tech->write_video)
-			res = chan->tech->write_video(chan, fr);
-		else
-			res = 0;
+		res = (chan->tech->write_video == NULL) ? 0 :
+			chan->tech->write_video(chan, fr);
 		break;
 	case AST_FRAME_VOICE:
-		if (chan->tech->write) {
-			/* Bypass translator if we're writing format in the raw write format.  This
-			   allows mixing of native / non-native formats */
-			if (fr->subclass == chan->rawwriteformat)
-				f = fr;
-			else
-				f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
-			if (f) {
-				if (chan->spies)
-					queue_frame_to_spies(chan, f, SPY_WRITE);
-
-				if (chan->monitor && chan->monitor->write_stream) {
+		if (chan->tech->write == NULL)
+			break;
+
+		/* Bypass translator if we're writing format in the raw write format.  This
+		   allows mixing of native / non-native formats */
+		if (fr->subclass == chan->rawwriteformat)
+			f = fr;
+		else
+			f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
+		if (f == NULL) {
+			res = 0;
+		} else {
+			if (chan->spies)
+				queue_frame_to_spies(chan, f, SPY_WRITE);
+
+			if (chan->monitor && chan->monitor->write_stream) {
 #ifndef MONITOR_CONSTANT_DELAY
-					int jump = chan->insmpl - chan->outsmpl - 4 * f->samples;
-					if (jump >= 0) {
-						if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1)
-							ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
-						chan->outsmpl += jump + 4 * f->samples;
-					} else
-						chan->outsmpl += f->samples;
+				int jump = chan->insmpl - chan->outsmpl - 4 * f->samples;
+				if (jump >= 0) {
+					if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1)
+						ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
+					chan->outsmpl += jump + 4 * f->samples;
+				} else
+					chan->outsmpl += f->samples;
 #else
-					int jump = chan->insmpl - chan->outsmpl;
-					if (jump - MONITOR_DELAY >= 0) {
-						if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
-							ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
-						chan->outsmpl += jump;
-					} else
-						chan->outsmpl += f->samples;
+				int jump = chan->insmpl - chan->outsmpl;
+				if (jump - MONITOR_DELAY >= 0) {
+					if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
+						ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
+					chan->outsmpl += jump;
+				} else
+					chan->outsmpl += f->samples;
 #endif
-					if (chan->monitor->state == AST_MONITOR_RUNNING) {
-						if (ast_writestream(chan->monitor->write_stream, f) < 0)
-							ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
-					}
+				if (chan->monitor->state == AST_MONITOR_RUNNING) {
+					if (ast_writestream(chan->monitor->write_stream, f) < 0)
+						ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
 				}
-
-				res = chan->tech->write(chan, f);
-			} else
-				res = 0;
-		}
-	}
-
-	if (f && (f != fr))
+			}
+
+			res = chan->tech->write(chan, f);
+		}
+		break;	
+	}
+
+	if (f && f != fr)
 		ast_frfree(f);
 	ast_clear_flag(chan, AST_FLAG_BLOCKING);
 	/* Consider a write failure to force a soft hangup */
@@ -2478,101 +2461,100 @@
 
 struct ast_channel *__ast_request_and_dial(const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
 {
-	int state = 0;
+	int dummy_outstate;
 	int cause = 0;
 	struct ast_channel *chan;
-	struct ast_frame *f;
 	int res = 0;
 	
+	if (outstate)
+		*outstate = 0;
+	else
+		outstate = &dummy_outstate;	/* make outstate always a valid pointer */
+
 	chan = ast_request(type, format, data, &cause);
-	if (chan) {
-		if (oh) {
-			if (oh->vars)	
-				ast_set_variables(chan, oh->vars);
-			if (oh->cid_num && *oh->cid_num && oh->cid_name && *oh->cid_name)
-				ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
-			if (oh->parent_channel)
-				ast_channel_inherit_variables(oh->parent_channel, chan);
-			if (oh->account)
-				ast_cdr_setaccount(chan, oh->account);	
-		}
-		ast_set_callerid(chan, cid_num, cid_name, cid_num);
-
-		if (!ast_call(chan, data, 0)) {
-			res = 1;	/* in case chan->_state is already AST_STATE_UP */
-			while (timeout && (chan->_state != AST_STATE_UP)) {
-				res = ast_waitfor(chan, timeout);
-				if (res < 0) {
-					/* Something not cool, or timed out */
+	if (!chan) {
+		ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
+		/* compute error and return */
+		if (cause == AST_CAUSE_BUSY)
+			*outstate = AST_CONTROL_BUSY;
+		else if (cause == AST_CAUSE_CONGESTION)
+			*outstate = AST_CONTROL_CONGESTION;
+		return NULL;
+	}
+
+	if (oh) {
+		if (oh->vars)	
+			ast_set_variables(chan, oh->vars);
+		/* XXX why is this necessary, for the parent_channel perhaps ? */
+		if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name))
+			ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
+		if (oh->parent_channel)
+			ast_channel_inherit_variables(oh->parent_channel, chan);
+		if (oh->account)
+			ast_cdr_setaccount(chan, oh->account);	
+	}
+	ast_set_callerid(chan, cid_num, cid_name, cid_num);
+
+	if (ast_call(chan, data, 0)) {	/* ast_call failed... */
+		ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
+	} else {
+		res = 1;	/* mark success in case chan->_state is already AST_STATE_UP */
+		while (timeout && chan->_state != AST_STATE_UP) {
+			struct ast_frame *f;
+			res = ast_waitfor(chan, timeout);
+			if (res <= 0) /* error, timeout, or done */
+				break;
+			if (timeout > -1)
+				timeout = res;
+			f = ast_read(chan);
+			if (!f) {
+				*outstate = AST_CONTROL_HANGUP;
+				res = 0;
+				break;
+			}
+			if (f->frametype == AST_FRAME_CONTROL) {
+				switch (f->subclass) {
+				case AST_CONTROL_RINGING:	/* record but keep going */
+					*outstate = f->subclass;
 					break;
+
+				case AST_CONTROL_BUSY:
+				case AST_CONTROL_CONGESTION:
+				case AST_CONTROL_ANSWER:
+					*outstate = f->subclass;
+					timeout = 0;		/* trick to force exit from the while() */
+					break;
+
+				case AST_CONTROL_PROGRESS:	/* Ignore */
+				case -1:			/* Ignore -- just stopping indications */
+					break;
+
+				default:
+					ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
 				}
-				/* If done, break out */
-				if (!res)
-					break;
-				if (timeout > -1)
-					timeout = res;
-				f = ast_read(chan);
-				if (!f) {
-					state = AST_CONTROL_HANGUP;
-					res = 0;
-					break;
-				}
-				if (f->frametype == AST_FRAME_CONTROL) {
-					if (f->subclass == AST_CONTROL_RINGING)
-						state = AST_CONTROL_RINGING;
-					else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
-						state = f->subclass;
-						ast_frfree(f);
-						break;
-					} else if (f->subclass == AST_CONTROL_ANSWER) {
-						state = f->subclass;
-						ast_frfree(f);
-						break;
-					} else if (f->subclass == AST_CONTROL_PROGRESS) {
-						/* Ignore */
-					} else if (f->subclass == -1) {
-						/* Ignore -- just stopping indications */
-					} else {
-						ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
-					}
-				}
-				ast_frfree(f);
 			}
-		} else
-			ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
-	} else {
-		ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
-		switch(cause) {
-		case AST_CAUSE_BUSY:
-			state = AST_CONTROL_BUSY;
-			break;
-		case AST_CAUSE_CONGESTION:
-			state = AST_CONTROL_CONGESTION;
-			break;
-		}
-	}
-	if (chan) {
-		/* Final fixups */
-		if (oh) {
-			if (oh->context && *oh->context)
-				ast_copy_string(chan->context, oh->context, sizeof(chan->context));
-			if (oh->exten && *oh->exten)
-				ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
-			if (oh->priority)	
-				chan->priority = oh->priority;
-		}
-		if (chan->_state == AST_STATE_UP)
-			state = AST_CONTROL_ANSWER;
-	}
-	if (outstate)
-		*outstate = state;
-	if (chan && res <= 0) {
-		if (!chan->cdr && (chan->cdr = ast_cdr_alloc())) {
+			ast_frfree(f);
+		}
+	}
+
+	/* Final fixups */
+	if (oh) {
+		if (!ast_strlen_zero(oh->context))
+			ast_copy_string(chan->context, oh->context, sizeof(chan->context));
+		if (!ast_strlen_zero(oh->exten))
+			ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
+		if (oh->priority)	
+			chan->priority = oh->priority;
+	}
+	if (chan->_state == AST_STATE_UP)
+		*outstate = AST_CONTROL_ANSWER;
+
+	if (res <= 0) {
+		if (!chan->cdr && (chan->cdr = ast_cdr_alloc()))
 			ast_cdr_init(chan->cdr, chan);
-		}
 		if (chan->cdr) {
 			char tmp[256];
-			snprintf(tmp, 256, "%s/%s", type, (char *)data);
+			snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data);
 			ast_cdr_setapp(chan->cdr,"Dial",tmp);
 			ast_cdr_update(chan);
 			ast_cdr_start(chan->cdr);
@@ -3295,7 +3277,6 @@
 	/* Copy voice back and forth between the two channels. */
 	struct ast_channel *cs[3];
 	struct ast_frame *f;
-	struct ast_channel *who = NULL;
 	enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
 	int o0nativeformats;
 	int o1nativeformats;
@@ -3314,6 +3295,8 @@
 	watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
 
 	for (;;) {
+		struct ast_channel *who, *other;
+
 		if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
 		    (o0nativeformats != c0->nativeformats) ||
 		    (o1nativeformats != c1->nativeformats)) {
@@ -3351,10 +3334,12 @@
 			break;
 		}
 
+		other = (who == c0) ? c1 : c0; /* the 'other' channel */
+
 		if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
 			if ((f->subclass == AST_CONTROL_HOLD) || (f->subclass == AST_CONTROL_UNHOLD) ||
 			    (f->subclass == AST_CONTROL_VIDUPDATE)) {
-				ast_indicate(who == c0 ? c1 : c0, f->subclass);
+				ast_indicate(other, f->subclass);
 			} else {
 				*fo = f;
 				*rc = who;
@@ -3372,28 +3357,20 @@
 		    (f->frametype == AST_FRAME_MODEM) ||
 #endif
 		    (f->frametype == AST_FRAME_TEXT)) {
-			if (f->frametype == AST_FRAME_DTMF) {
-				if (((who == c0) && watch_c0_dtmf) ||
-				    ((who == c1) && watch_c1_dtmf)) {
-					*rc = who;
-					*fo = f;
-					res = AST_BRIDGE_COMPLETE;
-					ast_log(LOG_DEBUG, "Got DTMF on channel (%s)\n", who->name);
-					break;
-				} else {
-					goto tackygoto;
-				}
-			} else {
-#if 0
-				ast_log(LOG_DEBUG, "Read from %s\n", who->name);
-				if (who == last)
-					ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name);
-				last = who;
-#endif
-tackygoto:
-				ast_write((who == c0) ? c1 : c0, f);
+			/* monitored dtmf causes exit from bridge */
+			int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf;
+
+			if (f->frametype == AST_FRAME_DTMF && monitored_source) {
+				*fo = f;
+				*rc = who;
+				res = AST_BRIDGE_COMPLETE;
+				ast_log(LOG_DEBUG, "Got DTMF on channel (%s)\n", who->name);
+				break;
 			}
-		}
+			/* other frames go to the other side */
+			ast_write(other, f);
+		}
+		/* XXX do we want to pass on also frames not matched above ? */
 		ast_frfree(f);
 
 		/* Swap who gets priority */
@@ -3488,10 +3465,10 @@
 			if (time_left_ms < to)
 				to = time_left_ms;
 
-			if (time_left_ms <= 0) {
-				if (caller_warning && config->end_sound)
+			if (time_left_ms <= 0 && config->end_sound) {
+				if (caller_warning)
 					bridge_playfile(c0, c1, config->end_sound, 0);
-				if (callee_warning && config->end_sound)
+				if (callee_warning)
 					bridge_playfile(c1, c0, config->end_sound, 0);
 				*fo = NULL;
 				if (who)
@@ -3501,14 +3478,12 @@
 			}
 			
 			if (!to) {
-				if (time_left_ms >= 5000) {
-					/* force the time left to round up if appropriate */
-					if (caller_warning && config->warning_sound && config->play_warning)
-						bridge_playfile(c0, c1, config->warning_sound,
-								(time_left_ms + 500) / 1000);
-					if (callee_warning && config->warning_sound && config->play_warning)
-						bridge_playfile(c1, c0, config->warning_sound,
-								(time_left_ms + 500) / 1000);
+				if (time_left_ms >= 5000 && config->warning_sound && config->play_warning) {
+					int t = (time_left_ms + 500) / 1000; /* round to nearest second */
+					if (caller_warning)
+						bridge_playfile(c0, c1, config->warning_sound, t);
+					if (callee_warning)
+						bridge_playfile(c1, c0, config->warning_sound, t);
 				}
 				if (config->warning_freq) {
 					nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000));
@@ -3961,8 +3936,6 @@
 			result = spy->read_queue.head;
 			spy->read_queue.head = NULL;
 			spy->read_queue.samples = 0;
-			ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH);
-			return result;
 		} else {
 			if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST)) {
 				for (result = spy->write_queue.head; result; result = result->next)
@@ -3971,9 +3944,9 @@
 			result = spy->write_queue.head;
 			spy->write_queue.head = NULL;
 			spy->write_queue.samples = 0;
-			ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH);
-			return result;
-		}
+		}
+		ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH);
+		return result;
 	}
 
 	if ((spy->read_queue.samples < samples) || (spy->write_queue.samples < samples))



More information about the asterisk-commits mailing list