[Asterisk-cvs] asterisk channel.c,1.244,1.245 rtp.c,1.147,1.148

markster markster
Thu Oct 13 14:33:15 CDT 2005


Update of /usr/cvsroot/asterisk
In directory mongoose.digium.com:/tmp/cvs-serv20883

Modified Files:
	channel.c rtp.c 
Log Message:
Fix call timeouts with rtp bridge etc (bug #5252)


Index: channel.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channel.c,v
retrieving revision 1.244
retrieving revision 1.245
diff -u -d -r1.244 -r1.245
--- channel.c	4 Oct 2005 23:28:57 -0000	1.244
+++ channel.c	13 Oct 2005 18:27:53 -0000	1.245
@@ -264,12 +264,14 @@
 void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
 {
 	time_t	myt;
+	struct ast_frame fr = { AST_FRAME_NULL, };
 
 	time(&myt);
 	if (offset)
 		chan->whentohangup = myt + offset;
 	else
 		chan->whentohangup = 0;
+	ast_queue_frame(chan, &fr);
 	return;
 }
 
@@ -2947,18 +2949,16 @@
 	check = ast_autoservice_stop(peer);
 }
 
-static enum ast_bridge_result ast_generic_bridge(int *playitagain, int *playit, struct ast_channel *c0, struct ast_channel *c1,
-			      struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
+static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct ast_channel *c1,
+			      struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc, int toms)
 {
 	/* Copy voice back and forth between the two channels. */
 	struct ast_channel *cs[3];
-	int to;
 	struct ast_frame *f;
 	struct ast_channel *who = NULL;
 	enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
 	int o0nativeformats;
 	int o1nativeformats;
-	long elapsed_ms=0, time_left_ms=0;
 	int watch_c0_dtmf;
 	int watch_c1_dtmf;
 	void *pvt0, *pvt1;
@@ -2980,34 +2980,7 @@
 			res = AST_BRIDGE_RETRY;
 			break;
 		}
-		/* timestamp */
-		if (config->timelimit) {
-			/* If there is a time limit, return now */
-			elapsed_ms = ast_tvdiff_ms(ast_tvnow(), config->start_time);
-			time_left_ms = config->timelimit - elapsed_ms;
-
-			if (*playitagain &&
-			    ((ast_test_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING)) ||
-			     (ast_test_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING))) &&
-			    (config->play_warning && time_left_ms <= config->play_warning)) { 
-				if (config->warning_freq == 0 || time_left_ms == config->play_warning || (time_left_ms % config->warning_freq) <= 50) {
-					res = AST_BRIDGE_RETRY;
-					break;
-				}
-			}
-			if (time_left_ms <= 0) {
-				res = AST_BRIDGE_RETRY;
-				break;
-			}
-			if (time_left_ms >= 5000 && *playit) {
-				res = AST_BRIDGE_RETRY;
-				break;
-			}
-			to = time_left_ms;
-		} else	
-			to = -1;
-
-		who = ast_waitfor_n(cs, 2, &to);
+		who = ast_waitfor_n(cs, 2, &toms);
 		if (!who) {
 			ast_log(LOG_DEBUG, "Nobody there, continuing...\n"); 
 			if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
@@ -3089,10 +3062,11 @@
 	int firstpass;
 	int o0nativeformats;
 	int o1nativeformats;
-	long elapsed_ms=0, time_left_ms=0;
-	int playit=0, playitagain=1, first_time=1;
+	long time_left_ms=0;
+	struct timeval nexteventts = { 0, };
 	char caller_warning = 0;
 	char callee_warning = 0;
+	int to;
 
 	if (c0->_bridge) {
 		ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
@@ -3144,24 +3118,24 @@
 	o0nativeformats = c0->nativeformats;
 	o1nativeformats = c1->nativeformats;
 
+	if (config->timelimit) {
+		nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
+		if (caller_warning || callee_warning)
+			nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000));
+	}
+
 	for (/* ever */;;) {
+		to = -1;
 		if (config->timelimit) {
-			elapsed_ms = ast_tvdiff_ms(ast_tvnow(), config->start_time);
-			time_left_ms = config->timelimit - elapsed_ms;
+			struct timeval now;
+			now = ast_tvnow();
+			to = ast_tvdiff_ms(nexteventts, now);
+			if (to < 0)
+				to = 0;
+			time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
+			if (time_left_ms < to)
+				to = time_left_ms;
 
-			if (playitagain && (caller_warning || callee_warning) && (config->play_warning && time_left_ms <= config->play_warning)) { 
-				/* narrowing down to the end */
-				if (config->warning_freq == 0) {
-					playit = 1;
-					first_time = 0;
-					playitagain = 0;
-				} else if (first_time) {
-					playit = 1;
-					first_time = 0;
-				} else if ((time_left_ms % config->warning_freq) <= 50) {
-					playit = 1;
-				}
-			}
 			if (time_left_ms <= 0) {
 				if (caller_warning && config->end_sound)
 					bridge_playfile(c0, c1, config->end_sound, 0);
@@ -3173,12 +3147,18 @@
 				res = 0;
 				break;
 			}
-			if (time_left_ms >= 5000 && playit) {
-				if (caller_warning && config->warning_sound && config->play_warning)
-					bridge_playfile(c0, c1, config->warning_sound, time_left_ms / 1000);
-				if (callee_warning && config->warning_sound && config->play_warning)
-					bridge_playfile(c1, c0, config->warning_sound, time_left_ms / 1000);
-				playit = 0;
+			
+			if (!to) {
+				if (time_left_ms >= 5000) {
+					if (caller_warning && config->warning_sound && config->play_warning)
+						bridge_playfile(c0, c1, config->warning_sound, time_left_ms / 1000);
+					if (callee_warning && config->warning_sound && config->play_warning)
+						bridge_playfile(c1, c0, config->warning_sound, time_left_ms / 1000);
+				}
+				if (config->warning_freq) {
+					nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000));
+				} else
+					nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
 			}
 		}
 
@@ -3218,7 +3198,7 @@
 				ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name);
 			ast_set_flag(c0, AST_FLAG_NBRIDGE);
 			ast_set_flag(c1, AST_FLAG_NBRIDGE);
-			if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc)) == AST_BRIDGE_COMPLETE) {
+			if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) {
 				manager_event(EVENT_FLAG_CALL, "Unlink", 
 					      "Channel1: %s\r\n"
 					      "Channel2: %s\r\n"
@@ -3275,8 +3255,7 @@
 			o0nativeformats = c0->nativeformats;
 			o1nativeformats = c1->nativeformats;
 		}
-
-		res = ast_generic_bridge(&playitagain, &playit, c0, c1, config, fo, rc);
+		res = ast_generic_bridge(c0, c1, config, fo, rc, to);
 		if (res != AST_BRIDGE_RETRY)
 			break;
 	}

Index: rtp.c
===================================================================
RCS file: /usr/cvsroot/asterisk/rtp.c,v
retrieving revision 1.147
retrieving revision 1.148
diff -u -d -r1.147 -r1.148
--- rtp.c	12 Oct 2005 20:45:18 -0000	1.147
+++ rtp.c	13 Oct 2005 18:27:53 -0000	1.148
@@ -1499,7 +1499,7 @@
 /* ast_rtp_bridge: Bridge calls. If possible and allowed, initiate
 	re-invite so the peers exchange media directly outside 
 	of Asterisk. */
-enum ast_bridge_result ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
+enum ast_bridge_result ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
 {
 	struct ast_frame *f;
 	struct ast_channel *who, *cs[3];
@@ -1513,7 +1513,6 @@
 	char iabuf[INET_ADDRSTRLEN];
 	
 	void *pvt0, *pvt1;
-	int to;
 	int codec0,codec1, oldcodec0, oldcodec1;
 	
 	memset(&vt0, 0, sizeof(vt0));
@@ -1635,7 +1634,6 @@
 				}
 				return AST_BRIDGE_RETRY;
 		}
-		to = -1;
 		/* Now check if they have changed address */
 		ast_rtp_get_peer(p1, &t1);
 		ast_rtp_get_peer(p0, &t0);
@@ -1677,7 +1675,7 @@
 			memcpy(&vac0, &vt0, sizeof(vac0));
 			oldcodec0 = codec0;
 		}
-		who = ast_waitfor_n(cs, 2, &to);
+		who = ast_waitfor_n(cs, 2, &timeoutms);
 		if (!who) {
 			if (option_debug)
 				ast_log(LOG_DEBUG, "Ooh, empty read...\n");




More information about the svn-commits mailing list