--- asterisk-1.4.18.1/apps/app_dial.c	2008-01-22 17:31:17.000000000 +0000
+++ asterisk-1.4.18.1/apps/app_dial.c	2008-03-31 13:46:34.000000000 +0100
@@ -27,6 +27,7 @@
 
 /*** MODULEINFO
         <depend>chan_local</depend>
+		<depend>Curl</depend>
  ***/
 
 
@@ -67,6 +68,7 @@
 #include "asterisk/privacy.h"
 #include "asterisk/stringfields.h"
 #include "asterisk/global_datastores.h"
+#include <curl/curl.h>
 
 static char *app = "Dial";
 
@@ -135,9 +137,19 @@
 "           the DTMF sequence defined for call parking in features.conf.\n"
 "    K    - Allow the calling party to enable parking of the call by sending\n"
 "           the DTMF sequence defined for call parking in features.conf.\n"
-"    L(x[:y][:z]) - Limit the call to 'x' ms. Play a warning when 'y' ms are\n"
-"           left. Repeat the warning every 'z' ms. The following special\n"
-"           variables can be used with this option:\n"
+"    L(x[:y][:z][:rtcc url]) - Limit the call to 'x' ms. Play a warning when 'y' ms are\n"
+"           left. Repeat the warning every 'z' ms.\n"
+"           If a real-time call control (rtcc) URL is specified it will be is\n"
+"			specified it will be periodically called via Curl. The return value\n"
+"			will be added to x to set the duration of the call.\n"
+"           Header values added appended to the URL querystring are:\n"
+"            - accountcode, the accountcode of the caller if set,\n"
+"			 - dst, the destination for the call,\n"
+"            - duration, the length of time in seconds that the call has been up,\n"
+"            - timelimit, the current time limit in seconds that has been set on the call,\n"
+"		     - channelid, the unique channel id assigned to the caller (source).\n"
+"		     - seqno, sequence number of the rtcc check, incremented after each call.\n"
+"			The following special variables can be used with this option:\n"
 "           * LIMIT_PLAYAUDIO_CALLER   yes|no (default yes)\n"
 "                                      Play sounds to the caller.\n"
 "           * LIMIT_PLAYAUDIO_CALLEE   yes|no\n"
@@ -146,6 +158,17 @@
 "           * LIMIT_CONNECT_FILE       File to play when call begins.\n"
 "           * LIMIT_WARNING_FILE       File to play as warning if 'y' is defined.\n"
 "                                      The default is to say the time remaining.\n"
+"			* RTCC_INTERVAL			   The interval in ms at which the the real-time call\n"
+"									   control URL will be called (60000 by default).\n"
+"			* RTCC_INIT_INTERVAL	   The first interval in ms after the call is\n"
+"									   answered that the first real-time request should\n"
+"									   be made, defaults to RTCC_INTERVAL.\n"
+"			* RTCC_EXPIRY_INTERVAL     Allows for a method of operation where the rtcc\n"
+"									   is made when there is only this amount of time \n"
+"									   remaining. If this is set it overrules the interval\n"
+"									   settings. By default it is disbaled.\n"
+"			* RTCC_START_SEQNUM		   Start sequence number for the real-time call\n"
+"									   control requests. Defaults to 1.\n"
 "    m([class]) - Provide hold music to the calling party until a requested\n"
 "           channel answers. A specific MusicOnHold class can be\n"
 "           specified.\n"
@@ -219,6 +242,29 @@
 "  The 'dialargs' are specified in the same format that arguments are provided\n"
 "to the Dial application.\n";
 
+#define RTCC_CURLTIMEOUT_SECONDS 5					/* The timeout value for a Curl call after which it will be cancelled. */
+#define RTCC_INTERVAL_MILLISECONDS 60000			/* The default interval at which the rtcc check will be made. */
+#define RTCC_MININTERVAL_MILLISECONDS 5000			/* The minimum interval at which the rtcc check will be made when using an expiry iterval. */
+#define RTCC_SEQNUM_START 1							/* The default start value for the real-time call control sequence number. */
+
+static pthread_t rtcc_thread = AST_PTHREADT_NULL;	/* The thread the real-time call control scheduler will be run on. */
+static struct sched_context* rtcc_sched_con;		/* The real-time call control scheduling context. */
+
+/* Structure passed to the real-time call control scheduler after a call has been answered. */
+struct rtcc_struct 
+{
+	struct ast_bridge_config * config;
+	const char * caller_accountcode;
+	const char * caller_channel_id;
+	const char * caller_exten;
+	const char * callcontrol_url;
+	const char * answered_channel_num;	/* The number of the answered channel, used for Dial commands that can have multiple channels specified. */
+	int seqnum;							/* Inceremented for each real-time call control check. */
+	int rtcc_check_interval;
+	int rtcc_expiry_interval;			/* Calculates the interval by subtracting this value from the time remaining. */
+	int hungup;
+};
+
 enum {
 	OPT_ANNOUNCE =		(1 << 0),
 	OPT_RESETCDR =		(1 << 1),
@@ -802,6 +848,173 @@
 	return 0;
 }
 
+
+/* Callback function for the real-time call control Curl method. The Curl method must return an
+   integer value which indicates how long the call should be extended by in milliseconds. */
+static size_t rtcc_curl_write(void *buffer, size_t size, size_t nmemb, void *userp)
+{
+	int timelimit = atoi((const char*)buffer);
+	*(int*)userp = timelimit;
+	return nmemb;
+}
+
+/* The function that will be preiodically called by the real-time call control thread on calls
+   that have requested real-time call control. The function makes a Curl call to the URL passed in 
+   in the origial Dial command and usees the return value to extend the length of the call or 
+   terminate it. */
+static int rtcccallback(const void* data) {
+	CURL *curl;
+	CURLcode res;
+	struct rtcc_struct * rtcc_data = (struct rtcc_struct *)data;
+	char callcontrol_url [1024];
+	int timelimit = 0;
+	long int timelimit_seconds = 0;
+	long int time_remaining = 0;
+	int next_rtcc_check = 0; //rtcc_data->rtcc_check_interval;	/* Used as the return value and dictates when the next real-time call control check will be perfomed. */
+	struct timeval call_duration;
+
+	ast_log(LOG_DEBUG, "call control accountcode=%s, dst=%s.\n", rtcc_data->caller_accountcode, rtcc_data->caller_exten);
+
+	if(rtcc_data->hungup) {
+		ast_log(LOG_DEBUG, "call control for %s to %s on completed bridge, halting.\n", rtcc_data->caller_accountcode, rtcc_data->caller_exten);
+		ast_free(rtcc_data);
+		return 0;
+	}
+
+	curl = curl_easy_init();
+	if(curl) {
+		call_duration = ast_tvsub(ast_tvnow(), rtcc_data->config->start_time);
+		timelimit_seconds = rtcc_data->config->timelimit / 1000;
+
+		/* Constuct the real-time call control URL. */
+		if(strchr(rtcc_data->callcontrol_url, '?')) {
+			sprintf(callcontrol_url, "%s&accountcode=%s&dst=%s&duration=%li&timelimit=%li&channelid=%s&seqno=%i&anschan=%s", rtcc_data->callcontrol_url,  rtcc_data->caller_accountcode, rtcc_data->caller_exten, call_duration.tv_sec, timelimit_seconds, rtcc_data->caller_channel_id, rtcc_data->seqnum, rtcc_data->answered_channel_num);
+		}
+		else {
+			sprintf(callcontrol_url, "%s?accountcode=%s&dst=%s&duration=%li&timelimit=%li&channelid=%s&seqno=%i&anschan=%s", rtcc_data->callcontrol_url,  rtcc_data->caller_accountcode, rtcc_data->caller_exten, call_duration.tv_sec, timelimit_seconds, rtcc_data->caller_channel_id, rtcc_data->seqnum, rtcc_data->answered_channel_num);
+		}
+		ast_log(LOG_DEBUG, "call control url %s", callcontrol_url);
+
+		curl_easy_setopt(curl, CURLOPT_URL, callcontrol_url);
+		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &timelimit);
+		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, rtcc_curl_write);
+		curl_easy_setopt(curl, CURLOPT_TIMEOUT, RTCC_CURLTIMEOUT_SECONDS);
+		curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, RTCC_CURLTIMEOUT_SECONDS);
+		res = curl_easy_perform(curl);
+
+		if(res == 0) {
+			/* Extend the call. */
+			if(rtcc_data->config && !rtcc_data->hungup) {
+				rtcc_data->config->timelimit += (timelimit * 1000);
+				rtcc_data->config->nexteventts = ast_tvadd(rtcc_data->config->nexteventts, ast_samp2tv(timelimit, 1));
+
+				timelimit_seconds = rtcc_data->config->timelimit / 1000;
+				time_remaining = timelimit_seconds - ast_tvsub(ast_tvnow(), rtcc_data->config->start_time).tv_sec;
+				ast_verbose(VERBOSE_PREFIX_3 "rtcc reserved %is for %s to %s (channelid=%s), time remaining %lis.\n", timelimit, rtcc_data->caller_accountcode, rtcc_data->caller_exten, rtcc_data->caller_channel_id, time_remaining);
+
+				if(timelimit < 0) {
+					/* If a timelimit of less than 0 is returned by the real-time call control server it means it wants to hangup the call or it's the last reservation. In either case no further call control checks are required for this call. */
+					next_rtcc_check	= 0;
+				}
+				else {
+					if(rtcc_data->rtcc_expiry_interval > 0) {
+						next_rtcc_check	= (time_remaining * 1000 - rtcc_data->rtcc_expiry_interval > RTCC_MININTERVAL_MILLISECONDS) ? time_remaining * 1000 - rtcc_data->rtcc_expiry_interval : RTCC_MININTERVAL_MILLISECONDS;
+					} else {
+						next_rtcc_check	= rtcc_data->rtcc_check_interval;
+					}
+				}
+			}
+		} else {
+			ast_log(LOG_WARNING, "Call control curl error from %s (%i) %s.\n", callcontrol_url, res, curl_easy_strerror(res));
+		}
+
+		rtcc_data->seqnum += 1;
+		curl_easy_cleanup(curl);
+	}
+
+	/* Call could have been hungup while waiting for Curl call to return. */
+	if(rtcc_data->hungup) {
+		ast_log(LOG_DEBUG, "call control for %s to %s on completed bridge, halting.\n", rtcc_data->caller_accountcode, rtcc_data->caller_exten);
+		ast_free(rtcc_data);
+		return 0;
+	}
+
+	return next_rtcc_check;
+}
+
+/*  Checks the time limits on in-progress calls that have requested real-time call control.
+	Calls that have requested control add an entry to the real-time call control schedule and
+	then periodically have their time limit updated by this function. */
+static void* monitor_rtcc_sched(void * data)
+{
+	ast_mutex_t rtcc_mutex;
+	ast_cond_t rtcc_cond;
+	struct timespec timeout = {0,0};
+	struct timeval now;
+
+	ast_mutex_init(&rtcc_mutex);
+	ast_cond_init(&rtcc_cond, NULL);
+
+	ast_log(LOG_DEBUG, "Call control monitor thread starting.\n");
+
+	for(;;)
+	{
+		ast_sched_runq(rtcc_sched_con);
+		
+		int nexteventms = ast_sched_wait(rtcc_sched_con);
+		if(nexteventms == -1)  {
+			break;
+		}
+
+		now = ast_tvadd(ast_tvnow(), ast_samp2tv(nexteventms, 1000));
+		timeout.tv_sec = now.tv_sec;
+		timeout.tv_nsec = now.tv_usec * 1000;
+
+		ast_mutex_lock(&rtcc_mutex);
+		ast_cond_timedwait(&rtcc_cond, &rtcc_mutex, &timeout);
+		ast_mutex_unlock(&rtcc_mutex);
+	}
+
+	ast_log(LOG_DEBUG, "Call control monitor thread stopping.\n");
+
+	ast_mutex_destroy(&rtcc_mutex);
+	ast_cond_destroy(&rtcc_cond);
+
+	rtcc_thread = AST_PTHREADT_NULL;
+
+	return 0;
+}
+
+/* Starts the thread to monitor the real-time call control schedule. The schedule
+   contains the list of all calls that are availing of real-time call control and
+   allows them to be monitored by a single thread. */
+static int start_rtcc_thread(void)
+{
+	AST_MUTEX_DEFINE_STATIC(rtcc_threadcontrol_lock);
+	
+	ast_log(LOG_DEBUG, "Call control thread starting.\n");
+	
+	/* If we're supposed to be stopped -- stay stopped */
+	if (rtcc_thread == AST_PTHREADT_STOP)
+		return 0;
+	ast_mutex_lock(&rtcc_threadcontrol_lock);
+	if (rtcc_thread == pthread_self()) {
+		ast_mutex_unlock(&rtcc_threadcontrol_lock);
+		ast_log(LOG_WARNING, "Cannot kill myself.\n");
+		return -1;
+	}
+	if (rtcc_thread == AST_PTHREADT_NULL) {
+		/* Start a new real-time call control thread */
+		if (ast_pthread_create_background(&rtcc_thread, NULL, monitor_rtcc_sched, NULL) < 0) {
+			ast_mutex_unlock(&rtcc_threadcontrol_lock);
+			ast_log(LOG_ERROR, "Unable to start call control thread.\n");
+			return -1;
+		}
+	}
+	ast_mutex_unlock(&rtcc_threadcontrol_lock);
+	return 0;
+}
+
 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags, int *continue_exec)
 {
 	int res = -1;
@@ -845,6 +1058,13 @@
 	char *opt_args[OPT_ARG_ARRAY_SIZE];
 	struct ast_datastore *datastore = NULL;
 	int fulldial = 0, num_dialed = 0;
+	struct rtcc_struct * rtcc_data = NULL;
+	char * callcontrol_url_str = NULL;
+	int rtcc_interval = RTCC_INTERVAL_MILLISECONDS;	
+	int rtcc_init_interval =  RTCC_INTERVAL_MILLISECONDS;
+	int rtcc_expiry_interval = 0;
+	int rtcc_seqnum = RTCC_SEQNUM_START;
+	int schedId = 0;
 
 	if (ast_strlen_zero(data)) {
 		ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
@@ -895,18 +1115,23 @@
 	}
 
 	if (ast_test_flag(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
-		char *limit_str, *warning_str, *warnfreq_str;
+		char *optionslimit_str, *limit_str, *warning_str, *warnfreq_str;
 		const char *var;
 
-		warnfreq_str = opt_args[OPT_ARG_DURATION_LIMIT];
-		limit_str = strsep(&warnfreq_str, ":");
-		warning_str = strsep(&warnfreq_str, ":");
+		optionslimit_str = opt_args[OPT_ARG_DURATION_LIMIT];
+		limit_str = strsep(&optionslimit_str, ":");
+		warning_str = strsep(&optionslimit_str, ":");
 
 		timelimit = atol(limit_str);
 		if (warning_str)
 			play_warning = atol(warning_str);
-		if (warnfreq_str)
+		if (optionslimit_str) {
+			warnfreq_str = strsep(&optionslimit_str, ":");
 			warning_freq = atol(warnfreq_str);
+		}
+		if (optionslimit_str) {
+			callcontrol_url_str = optionslimit_str;
+		}
 
 		if (!timelimit) {
 			ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
@@ -947,10 +1172,38 @@
 		var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
 		start_sound = S_OR(var, NULL);	/* XXX not much of a point in doing this! */
 
+		var = pbx_builtin_getvar_helper(chan, "RTCC_INTERVAL");
+		if(!ast_strlen_zero(var)) {
+			rtcc_interval = atoi(var);
+			if(rtcc_interval <= 0) {
+				rtcc_interval = RTCC_INTERVAL_MILLISECONDS;
+			}
+			rtcc_init_interval = rtcc_interval;
+		}
+
+		var = pbx_builtin_getvar_helper(chan, "RTCC_INIT_INTERVAL");
+		if(!ast_strlen_zero(var)) {
+			rtcc_init_interval = atoi(var);
+
+			if(rtcc_init_interval <= 0) {
+				rtcc_init_interval = rtcc_interval;
+			}
+		}
+
+		var = pbx_builtin_getvar_helper(chan, "RTCC_EXPIRY_INTERVAL");
+		if(!ast_strlen_zero(var)) {
+			rtcc_expiry_interval = atoi(var);
+		}
+
+		var = pbx_builtin_getvar_helper(chan, "RTCC_START_SEQNUM");
+		if(!ast_strlen_zero(var)) {
+			rtcc_seqnum = atoi(var);
+		}
+
 		/* undo effect of S(x) in case they are both used */
 		calldurationlimit = 0;
 		/* more efficient to do it like S(x) does since no advanced opts */
-		if (!play_warning && !start_sound && !end_sound && timelimit) {
+		if (!play_warning && !start_sound && !end_sound && !callcontrol_url_str && timelimit) {
 			calldurationlimit = timelimit / 1000;
 			if (option_verbose > 2)
 				ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
@@ -962,6 +1215,11 @@
 			ast_verbose(VERBOSE_PREFIX_4 "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
 			ast_verbose(VERBOSE_PREFIX_4 "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
 			ast_verbose(VERBOSE_PREFIX_4 "warning_freq   = %ld\n", warning_freq);
+			ast_verbose(VERBOSE_PREFIX_4 "rtcc_url       = %s\n", callcontrol_url_str);
+			ast_verbose(VERBOSE_PREFIX_4 "rtcc_interval  = %i\n", rtcc_interval);
+			ast_verbose(VERBOSE_PREFIX_4 "rtcc_initintvl = %i\n", rtcc_init_interval);
+			ast_verbose(VERBOSE_PREFIX_4 "rtcc_expintvl  = %i\n", rtcc_expiry_interval);
+			ast_verbose(VERBOSE_PREFIX_4 "rtcc_seqnum    = %i\n", rtcc_seqnum);
 			ast_verbose(VERBOSE_PREFIX_4 "start_sound    = %s\n", start_sound);
 			ast_verbose(VERBOSE_PREFIX_4 "warning_sound  = %s\n", warning_sound);
 			ast_verbose(VERBOSE_PREFIX_4 "end_sound      = %s\n", end_sound);
@@ -1364,6 +1622,7 @@
 		if (!number)
 			number = numsubst;
 		pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
+		
  		if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
 			if (option_debug)
  				ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", args.url);
@@ -1703,7 +1962,51 @@
 				ast_channel_setoption(chan,
 					AST_OPTION_OPRMODE,&oprmode,sizeof(struct oprmode),0);
 			}
+
+			/* If real-time call control requested initiate once answered. */
+			if(callcontrol_url_str)
+			{
+				if(!rtcc_sched_con) {
+					rtcc_sched_con = sched_context_create();
+				}
+
+				/* Add new rtcc job to schedule. */
+				int initial_interval = rtcc_init_interval;
+				if(rtcc_expiry_interval > 0) {
+					initial_interval = timelimit - rtcc_expiry_interval;
+				}
+
+				rtcc_data = ast_malloc(sizeof(*rtcc_data));
+				rtcc_data->config = &config;
+				rtcc_data->caller_accountcode = chan->accountcode;
+				rtcc_data->caller_exten = chan->exten;
+				rtcc_data->caller_channel_id = chan->uniqueid;
+				rtcc_data->answered_channel_num = number;
+				rtcc_data->callcontrol_url = callcontrol_url_str;
+				rtcc_data->hungup = 0;
+				rtcc_data->rtcc_check_interval = rtcc_interval;
+				rtcc_data->rtcc_expiry_interval = rtcc_expiry_interval;
+				rtcc_data->seqnum = rtcc_seqnum;
+				schedId = ast_sched_add_variable(rtcc_sched_con, initial_interval, &rtcccallback, rtcc_data, 1);
+
+				if(rtcc_thread == AST_PTHREADT_NULL) {
+					start_rtcc_thread();
+				}
+			}
+
 			res = ast_bridge_call(chan,peer,&config);
+
+			if(rtcc_data)
+			{
+				rtcc_data->hungup = 1;
+
+				/* Remove rtcc job from schedule. */
+				if(ast_sched_when(rtcc_sched_con, schedId) != -1) {	
+				  ast_sched_del(rtcc_sched_con, schedId);
+				  ast_free(rtcc_data);
+				} 
+			}
+
 			time(&end_time);
 			{
 				char toast[80];
--- asterisk-1.4.18.1/include/asterisk/channel.h	2008-01-28 17:15:41.000000000 +0000
+++ asterisk-1.4.18.1/include/asterisk/channel.h	2008-03-31 12:34:59.000000000 +0100
@@ -520,6 +520,7 @@
 	const char *start_sound;
 	int firstpass;
 	unsigned int flags;
+	struct timeval nexteventts;
 };
 
 struct chanmon;
--- asterisk-1.4.18.1/main/channel.c	2008-01-28 17:15:41.000000000 +0000
+++ asterisk-1.4.18.1/main/channel.c	2008-03-31 12:40:59.000000000 +0100
@@ -3677,7 +3677,7 @@
 
 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, struct timeval bridge_end)
+						 struct ast_channel **rc)
 {
 	/* Copy voice back and forth between the two channels. */
 	struct ast_channel *cs[3];
@@ -3715,8 +3715,8 @@
 			res = AST_BRIDGE_RETRY;
 			break;
 		}
-		if (bridge_end.tv_sec) {
-			to = ast_tvdiff_ms(bridge_end, ast_tvnow());
+		if (config->nexteventts.tv_sec) {
+			to = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
 			if (to <= 0) {
 				if (config->timelimit)
 					res = AST_BRIDGE_RETRY;
@@ -3831,7 +3831,6 @@
 	int o0nativeformats;
 	int o1nativeformats;
 	long time_left_ms=0;
-	struct timeval nexteventts = { 0, };
 	char caller_warning = 0;
 	char callee_warning = 0;
 
@@ -3887,11 +3886,11 @@
 	o1nativeformats = c1->nativeformats;
 
 	if (config->feature_timer) {
-		nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000));
+		config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000));
 	} else if (config->timelimit) {
-		nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
+		config->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));
+			config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(config->play_warning, 1000));
 	}
 
 	if (!c0->tech->send_digit_begin)
@@ -3905,9 +3904,9 @@
 
 		to = -1;
 
-		if (!ast_tvzero(nexteventts)) {
+		if (!ast_tvzero(config->nexteventts)) {
 			now = ast_tvnow();
-			to = ast_tvdiff_ms(nexteventts, now);
+			to = ast_tvdiff_ms(config->nexteventts, now);
 			if (to <= 0) {
 				if (!config->timelimit) {
 					res = AST_BRIDGE_COMPLETE;
@@ -3943,9 +3942,9 @@
 						bridge_playfile(c1, c0, config->warning_sound, t);
 				}
 				if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000)))
-					nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000));
+					config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000));
 				else
-					nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
+					config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
 			}
 		}
 
@@ -4054,7 +4053,7 @@
 			o0nativeformats = c0->nativeformats;
 			o1nativeformats = c1->nativeformats;
 		}
-		res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts);
+		res = ast_generic_bridge(c0, c1, config, fo, rc);
 		if (res != AST_BRIDGE_RETRY)
 			break;
 	}
