[asterisk-commits] tilghman: trunk r115076 - in /trunk: ./ apps/ funcs/ include/asterisk/ main/ ...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu May 1 18:06:24 CDT 2008


Author: tilghman
Date: Thu May  1 18:06:23 2008
New Revision: 115076

URL: http://svn.digium.com/view/asterisk?view=rev&rev=115076
Log:
Modify TIMEOUT() to be accurate down to the millisecond.
(closes issue #10540)
 Reported by: spendergrass
 Patches: 
       20080417__bug10540.diff.txt uploaded by Corydon76 (license 14)
 Tested by: blitzrage

Modified:
    trunk/CHANGES
    trunk/apps/app_dial.c
    trunk/apps/app_disa.c
    trunk/apps/app_dumpchan.c
    trunk/apps/app_queue.c
    trunk/apps/app_read.c
    trunk/apps/app_readexten.c
    trunk/apps/app_rpt.c
    trunk/apps/app_speech_utils.c
    trunk/funcs/func_timeout.c
    trunk/include/asterisk/channel.h
    trunk/include/asterisk/pbx.h
    trunk/main/app.c
    trunk/main/channel.c
    trunk/main/cli.c
    trunk/main/dial.c
    trunk/main/manager.c
    trunk/main/pbx.c
    trunk/res/res_agi.c

Modified: trunk/CHANGES
URL: http://svn.digium.com/view/asterisk/trunk/CHANGES?view=diff&rev=115076&r1=115075&r2=115076
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Thu May  1 18:06:23 2008
@@ -87,6 +87,10 @@
 -------------------
   * Addresses managed by DNS manager now can check to see if there is a DNS
     SRV record for a given domain and will use that hostname/port if present.
+
+Dialplan function changes
+-------------------------
+ * TIMEOUT() has been modified to be accurate down to the millisecond.
 
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 1.4.X to Asterisk 1.6.0  -------------

Modified: trunk/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_dial.c?view=diff&rev=115076&r1=115075&r2=115076
==============================================================================
--- trunk/apps/app_dial.c (original)
+++ trunk/apps/app_dial.c Thu May  1 18:06:23 2008
@@ -1472,7 +1472,7 @@
 
 		tc->appl = "AppDial";
 		tc->data = "(Outgoing Line)";
-		tc->whentohangup = 0;
+		memset(&tc->whentohangup, 0, sizeof(tc->whentohangup));
 
 		S_REPLACE(tc->cid.cid_num, ast_strdup(chan->cid.cid_num));
 		S_REPLACE(tc->cid.cid_name, ast_strdup(chan->cid.cid_name));
@@ -1839,7 +1839,8 @@
 
 		if (!res) {
 			if (calldurationlimit > 0) {
-				peer->whentohangup = time(NULL) + calldurationlimit;
+				struct timeval whentohangup = { calldurationlimit, 0 };
+				peer->whentohangup = ast_tvadd(ast_tvnow(), whentohangup);
 			}
 			if (!ast_strlen_zero(dtmfcalled)) {
 				ast_verb(3, "Sending DTMF '%s' to the called party.\n", dtmfcalled);
@@ -1967,7 +1968,7 @@
 
 	if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_KEEPALIVE) && (res != AST_PBX_INCOMPLETE)) {
 		if (calldurationlimit)
-			chan->whentohangup = 0;
+			memset(&chan->whentohangup, 0, sizeof(chan->whentohangup));
 		res = 0;
 	}
 

Modified: trunk/apps/app_disa.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_disa.c?view=diff&rev=115076&r1=115075&r2=115076
==============================================================================
--- trunk/apps/app_disa.c (original)
+++ trunk/apps/app_disa.c Thu May  1 18:06:23 2008
@@ -116,8 +116,8 @@
 static int disa_exec(struct ast_channel *chan, void *data)
 {
 	int i = 0, j, k = 0, did_ignore = 0, special_noanswer = 0;
-	int firstdigittimeout = (chan->pbx ? chan->pbx->rtimeout * 1000 : 20000);
-	int digittimeout = (chan->pbx ? chan->pbx->dtimeout * 1000 : 10000);
+	int firstdigittimeout = (chan->pbx ? chan->pbx->rtimeoutms : 20000);
+	int digittimeout = (chan->pbx ? chan->pbx->dtimeoutms : 10000);
 	struct ast_flags flags;
 	char *tmp, exten[AST_MAX_EXTENSION] = "", acctcode[20]="";
 	char pwline[256];

Modified: trunk/apps/app_dumpchan.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_dumpchan.c?view=diff&rev=115076&r1=115075&r2=115076
==============================================================================
--- trunk/apps/app_dumpchan.c (original)
+++ trunk/apps/app_dumpchan.c Thu May  1 18:06:23 2008
@@ -115,7 +115,7 @@
 			ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->rawwriteformat),
 			ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->rawreadformat),
 			c->fds[0], c->fin & ~DEBUGCHAN_FLAG, (c->fin & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
-			c->fout & ~DEBUGCHAN_FLAG, (c->fout & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "", (long)c->whentohangup,
+			c->fout & ~DEBUGCHAN_FLAG, (c->fout & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "", (long)c->whentohangup.tv_sec,
 			hour,
 			min,
 			sec,

Modified: trunk/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_queue.c?view=diff&rev=115076&r1=115075&r2=115076
==============================================================================
--- trunk/apps/app_queue.c (original)
+++ trunk/apps/app_queue.c Thu May  1 18:06:23 2008
@@ -2228,7 +2228,7 @@
 	
 	tmp->chan->appl = "AppQueue";
 	tmp->chan->data = "(Outgoing Line)";
-	tmp->chan->whentohangup = 0;
+	memset(&tmp->chan->whentohangup, 0, sizeof(tmp->chan->whentohangup));
 	if (tmp->chan->cid.cid_num)
 		ast_free(tmp->chan->cid.cid_num);
 	tmp->chan->cid.cid_num = ast_strdup(qe->chan->cid.cid_num);

Modified: trunk/apps/app_read.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_read.c?view=diff&rev=115076&r1=115075&r2=115076
==============================================================================
--- trunk/apps/app_read.c (original)
+++ trunk/apps/app_read.c Thu May  1 18:06:23 2008
@@ -162,7 +162,7 @@
 			ast_stopstream(chan);
 			if (ts && ts->data[0]) {
 				if (!to)
-					to = chan->pbx ? chan->pbx->rtimeout * 1000 : 6000;
+					to = chan->pbx ? chan->pbx->rtimeoutms : 6000;
 				res = ast_playtones_start(chan, 0, ts->data, 0);
 				for (x = 0; x < maxdigits; ) {
 					res = ast_waitfordigit(chan, to);

Modified: trunk/apps/app_readexten.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_readexten.c?view=diff&rev=115076&r1=115075&r2=115076
==============================================================================
--- trunk/apps/app_readexten.c (original)
+++ trunk/apps/app_readexten.c Thu May  1 18:06:23 2008
@@ -121,10 +121,10 @@
 	}
 
 	if (timeout <= 0)
-		timeout = chan->pbx ? chan->pbx->rtimeout * 1000 : 10000;
+		timeout = chan->pbx ? chan->pbx->rtimeoutms : 10000;
 
 	if (digit_timeout <= 0)
-		digit_timeout = chan->pbx ? chan->pbx->dtimeout * 1000 : 5000;
+		digit_timeout = chan->pbx ? chan->pbx->dtimeoutms : 5000;
 
 	if (ast_test_flag(&flags, OPT_INDICATION) && !ast_strlen_zero(arglist.filename))
 		ts = ast_get_indication_tone(chan->zone, arglist.filename);

Modified: trunk/apps/app_rpt.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_rpt.c?view=diff&rev=115076&r1=115075&r2=115076
==============================================================================
--- trunk/apps/app_rpt.c (original)
+++ trunk/apps/app_rpt.c Thu May  1 18:06:23 2008
@@ -297,6 +297,8 @@
 #define FUNCTDELAY 1500
 
 static  pthread_t rpt_master_thread;
+
+struct timeval cancel_atimeout = { 0, 0 };
 
 struct rpt;
 
@@ -2930,7 +2932,7 @@
 		if (l->chan) {
 			ast_set_read_format(l->chan, AST_FORMAT_SLINEAR);
 			ast_set_write_format(l->chan, AST_FORMAT_SLINEAR);
-			l->chan->whentohangup = 0;
+			ast_channel_setwhentohangup_tv(l->chan, cancel_atimeout);
 			l->chan->appl = "Apprpt";
 			l->chan->data = "(Remote Rx)";
 			ast_verb(3, "rpt (remote) initiating call to %s/%s on %s\n",
@@ -3041,7 +3043,7 @@
 		if (l->chan) {
 			ast_set_read_format(l->chan, AST_FORMAT_SLINEAR);
 			ast_set_write_format(l->chan, AST_FORMAT_SLINEAR);
-			l->chan->whentohangup = 0;
+			ast_channel_setwhentohangup_tv(l->chan, cancel_atimeout);
 			l->chan->appl = "Apprpt";
 			l->chan->data = "(Remote Rx)";
 			ast_verb(3, "rpt (remote) initiating call to %s/%s on %s\n",
@@ -5462,7 +5464,7 @@
 	if (l->chan) {
 		ast_set_read_format(l->chan, AST_FORMAT_SLINEAR);
 		ast_set_write_format(l->chan, AST_FORMAT_SLINEAR);
-		l->chan->whentohangup = 0;
+		ast_channel_setwhentohangup_tv(l->chan, cancel_atimeout);
 		l->chan->appl = "Apprpt";
 		l->chan->data = "(Remote Rx)";
 		ast_verb(3, "rpt (attempt_reconnect) initiating call to %s/%s on %s\n",
@@ -5699,7 +5701,7 @@
 		}
 		ast_set_read_format(myrpt->rxchannel, AST_FORMAT_SLINEAR);
 		ast_set_write_format(myrpt->rxchannel, AST_FORMAT_SLINEAR);
-		myrpt->rxchannel->whentohangup = 0;
+		ast_channel_setwhentohangup_tv(myrpt->rxchannel, cancel_atimeout);
 		myrpt->rxchannel->appl = "Apprpt";
 		myrpt->rxchannel->data = "(Repeater Rx)";
 		ast_verb(3, "rpt (Rx) initiating call to %s/%s on %s\n",
@@ -5740,7 +5742,7 @@
 			}			
 			ast_set_read_format(myrpt->txchannel, AST_FORMAT_SLINEAR);
 			ast_set_write_format(myrpt->txchannel, AST_FORMAT_SLINEAR);
-			myrpt->txchannel->whentohangup = 0;
+			ast_channel_setwhentohangup_tv(myrpt->txchannel, cancel_atimeout);
 			myrpt->txchannel->appl = "Apprpt";
 			myrpt->txchannel->data = "(Repeater Tx)";
 			ast_verb(3, "rpt (Tx) initiating call to %s/%s on %s\n",
@@ -7109,7 +7111,7 @@
 	if (myrpt->rxchannel) {
 		ast_set_read_format(myrpt->rxchannel, AST_FORMAT_SLINEAR);
 		ast_set_write_format(myrpt->rxchannel, AST_FORMAT_SLINEAR);
-		myrpt->rxchannel->whentohangup = 0;
+		ast_channel_setwhentohangup_tv(myrpt->rxchannel, cancel_atimeout);
 		myrpt->rxchannel->appl = "Apprpt";
 		myrpt->rxchannel->data = "(Link Rx)";
 		ast_verb(3, "rpt (Rx) initiating call to %s/%s on %s\n",
@@ -7136,7 +7138,7 @@
 		if (myrpt->txchannel) {
 			ast_set_read_format(myrpt->txchannel, AST_FORMAT_SLINEAR);
 			ast_set_write_format(myrpt->txchannel, AST_FORMAT_SLINEAR);
-			myrpt->txchannel->whentohangup = 0;
+			ast_channel_setwhentohangup_tv(myrpt->txchannel, cancel_atimeout);
 			myrpt->txchannel->appl = "Apprpt";
 			myrpt->txchannel->data = "(Link Tx)";
 			ast_verb(3, "rpt (Tx) initiating call to %s/%s on %s\n",

Modified: trunk/apps/app_speech_utils.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_speech_utils.c?view=diff&rev=115076&r1=115075&r2=115076
==============================================================================
--- trunk/apps/app_speech_utils.c (original)
+++ trunk/apps/app_speech_utils.c Thu May  1 18:06:23 2008
@@ -513,7 +513,7 @@
 	struct ast_frame *f = NULL;
 	int oldreadformat = AST_FORMAT_SLINEAR;
 	char dtmf[AST_MAX_EXTENSION] = "";
-	time_t start, current;
+	struct timeval start = { 0, 0 }, current;
 	struct ast_datastore *datastore = NULL;
 	char *parse, *filename_tmp = NULL, *filename = NULL, tmp[2] = "", dtmf_terminator = '#';
 	const char *tmp2 = NULL;
@@ -552,7 +552,7 @@
 		/* Yay sound file */
 		filename_tmp = ast_strdupa(args.soundfile);
 		if (!ast_strlen_zero(args.timeout)) {
-			if ((timeout = atoi(args.timeout)) == 0)
+			if ((timeout = atof(args.timeout) * 1000.0) == 0)
 				timeout = -1;
 		} else
 			timeout = 0;
@@ -612,8 +612,8 @@
 
 		/* Do timeout check (shared between audio/dtmf) */
 		if ((!quieted || strlen(dtmf)) && started == 1) {
-			time(&current);
-			if ((current-start) >= timeout) {
+			current = ast_tvnow();
+			if ((ast_tvdiff_ms(start, current)) >= timeout) {
 				done = 1;
 				if (f)
 					ast_frfree(f);
@@ -642,7 +642,7 @@
 						ast_frfree(f);
 					break;
 				}
-				time(&start);
+				start = ast_tvnow();
 				started = 1;
 			}
 			/* Write audio frame out to speech engine if no DTMF has been received */
@@ -701,10 +701,10 @@
 					}
 					if (!started) {
 						/* Change timeout to be 5 seconds for DTMF input */
-						timeout = (chan->pbx && chan->pbx->dtimeout) ? chan->pbx->dtimeout : 5;
+						timeout = (chan->pbx && chan->pbx->dtimeoutms) ? chan->pbx->dtimeoutms : 5000;
 						started = 1;
 					}
-					time(&start);
+					start = ast_tvnow();
 					snprintf(tmp, sizeof(tmp), "%c", f->subclass);
 					strncat(dtmf, tmp, sizeof(dtmf) - strlen(dtmf) - 1);
 					/* If the maximum length of the DTMF has been reached, stop now */

Modified: trunk/funcs/func_timeout.c
URL: http://svn.digium.com/view/asterisk/trunk/funcs/func_timeout.c?view=diff&rev=115076&r1=115075&r2=115076
==============================================================================
--- trunk/funcs/func_timeout.c (original)
+++ trunk/funcs/func_timeout.c Thu May  1 18:06:23 2008
@@ -37,7 +37,7 @@
 static int timeout_read(struct ast_channel *chan, const char *cmd, char *data,
 			char *buf, size_t len)
 {
-	time_t myt;
+	struct timeval myt;
 
 	if (!chan)
 		return -1;
@@ -50,25 +50,25 @@
 	switch (*data) {
 	case 'a':
 	case 'A':
-		if (chan->whentohangup == 0) {
+		if (ast_tvzero(chan->whentohangup)) {
 			ast_copy_string(buf, "0", len);
 		} else {
-			time(&myt);
-			snprintf(buf, len, "%d", (int) (chan->whentohangup - myt));
+			myt = ast_tvnow();
+			snprintf(buf, len, "%.3f", ast_tvdiff_ms(myt, chan->whentohangup) / 1000.0);
 		}
 		break;
 
 	case 'r':
 	case 'R':
 		if (chan->pbx) {
-			snprintf(buf, len, "%d", chan->pbx->rtimeout);
+			snprintf(buf, len, "%.3f", chan->pbx->rtimeoutms / 1000.0);
 		}
 		break;
 
 	case 'd':
 	case 'D':
 		if (chan->pbx) {
-			snprintf(buf, len, "%d", chan->pbx->dtimeout);
+			snprintf(buf, len, "%.3f", chan->pbx->dtimeoutms / 1000.0);
 		}
 		break;
 
@@ -83,9 +83,10 @@
 static int timeout_write(struct ast_channel *chan, const char *cmd, char *data,
 			 const char *value)
 {
-	int x;
+	double x;
 	char timestr[64];
 	struct ast_tm myt;
+	struct timeval tv;
 
 	if (!chan)
 		return -1;
@@ -98,17 +99,18 @@
 	if (!value)
 		return -1;
 
-	x = atoi(value);
-	if (x < 0)
-		x = 0;
+	if ((sscanf(value, "%ld%lf", (long *)&tv.tv_sec, &x) == 0) || tv.tv_sec < 0)
+		tv.tv_sec = 0;
+	else
+		tv.tv_usec = x * 1000000;
 
 	switch (*data) {
 	case 'a':
 	case 'A':
-		ast_channel_setwhentohangup(chan, x);
+		ast_channel_setwhentohangup_tv(chan, tv);
 		if (VERBOSITY_ATLEAST(3)) {
-			if (chan->whentohangup) {
-				struct timeval tv = { chan->whentohangup, 0 };
+			if (!ast_tvzero(chan->whentohangup)) {
+				tv = ast_tvadd(tv, ast_tvnow());
 				ast_strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S.%3q %Z",
 					ast_localtime(&tv, &myt, NULL));
 				ast_verbose("Channel will hangup at %s.\n", timestr);
@@ -121,16 +123,16 @@
 	case 'r':
 	case 'R':
 		if (chan->pbx) {
-			chan->pbx->rtimeout = x;
-			ast_verb(3, "Response timeout set to %d\n", chan->pbx->rtimeout);
+			chan->pbx->rtimeoutms = tv.tv_sec * 1000 + tv.tv_usec / 1000.0;
+			ast_verb(3, "Response timeout set to %.3f\n", chan->pbx->rtimeoutms / 1000.0);
 		}
 		break;
 
 	case 'd':
 	case 'D':
 		if (chan->pbx) {
-			chan->pbx->dtimeout = x;
-			ast_verb(3, "Digit timeout set to %d\n", chan->pbx->dtimeout);
+			chan->pbx->dtimeoutms = tv.tv_sec * 1000 + tv.tv_usec / 1000.0;
+			ast_verb(3, "Digit timeout set to %.3f\n", chan->pbx->dtimeoutms / 1000.0);
 		}
 		break;
 

Modified: trunk/include/asterisk/channel.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/channel.h?view=diff&rev=115076&r1=115075&r2=115076
==============================================================================
--- trunk/include/asterisk/channel.h (original)
+++ trunk/include/asterisk/channel.h Thu May  1 18:06:23 2008
@@ -455,7 +455,7 @@
 
 	int _softhangup;				/*!< Whether or not we have been hung up...  Do not set this value
 	    							directly, use ast_softhangup() */
-	time_t	whentohangup;				/*!< Non-zero, set to actual time when channel is to be hung up */
+	struct timeval whentohangup;        /*!< Non-zero, set to actual time when channel is to be hung up */
 	pthread_t blocker;				/*!< If anyone is blocking, this is them */
 	ast_mutex_t lock_dont_use;			/*!< Lock a channel for some operations. See ast_channel_lock() */
 	const char *blockproc;				/*!< Procedure causing blocking */
@@ -920,19 +920,20 @@
 
 /*! \brief Compare a offset with the settings of when to hang a channel up 
  * \param chan channel on which to check for hang up
- * \param offset offset in seconds from current time
+ * \param offset offset in seconds and useconds from current time
  * \return 1, 0, or -1
  * This function compares a offset from current time with the absolute time 
  * out on a channel (when to hang up). If the absolute time out on a channel
  * is earlier than current time plus the offset, it returns 1, if the two
  * time values are equal, it return 0, otherwise, it return -1.
  */
-int ast_channel_cmpwhentohangup(struct ast_channel *chan, time_t offset);
+int ast_channel_cmpwhentohangup(struct ast_channel *chan, time_t offset) __attribute__ ((deprecated));
+int ast_channel_cmpwhentohangup_tv(struct ast_channel *chan, struct timeval offset);
 
 /*! \brief Set when to hang a channel up 
  *
  * \param chan channel on which to check for hang up
- * \param offset offset in seconds from current time of when to hang up
+ * \param offset offset in seconds and useconds relative to the current time of when to hang up
  *
  * This function sets the absolute time out on a channel (when to hang up).
  *
@@ -941,7 +942,8 @@
  *
  * \return Nothing
  */
-void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset);
+void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset) __attribute__ ((deprecated));
+void ast_channel_setwhentohangup_tv(struct ast_channel *chan, struct timeval offset);
 
 /*! 
  * \brief Answer a channel

Modified: trunk/include/asterisk/pbx.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/pbx.h?view=diff&rev=115076&r1=115075&r2=115076
==============================================================================
--- trunk/include/asterisk/pbx.h (original)
+++ trunk/include/asterisk/pbx.h Thu May  1 18:06:23 2008
@@ -112,8 +112,8 @@
 int ast_check_timing(const struct ast_timing *i);
 
 struct ast_pbx {
-	int dtimeout;				/*!< Timeout between digits (seconds) */
-	int rtimeout;				/*!< Timeout for response (seconds) */
+	int dtimeoutms;				/*!< Timeout between digits (milliseconds) */
+	int rtimeoutms;				/*!< Timeout for response (milliseconds) */
 };
 
 

Modified: trunk/main/app.c
URL: http://svn.digium.com/view/asterisk/trunk/main/app.c?view=diff&rev=115076&r1=115075&r2=115076
==============================================================================
--- trunk/main/app.c (original)
+++ trunk/main/app.c Thu May  1 18:06:23 2008
@@ -72,7 +72,7 @@
 		maxlen = size;
 	
 	if (!timeout && chan->pbx)
-		timeout = chan->pbx->dtimeout;
+		timeout = chan->pbx->dtimeoutms / 1000.0;
 	else if (!timeout)
 		timeout = 5;
 
@@ -130,8 +130,8 @@
 		}
 		if (ast_strlen_zero(filename)) {
 			/* set timeouts for the last prompt */
-			fto = c->pbx ? c->pbx->rtimeout * 1000 : 6000;
-			to = c->pbx ? c->pbx->dtimeout * 1000 : 2000;
+			fto = c->pbx ? c->pbx->rtimeoutms : 6000;
+			to = c->pbx ? c->pbx->dtimeoutms : 2000;
 
 			if (timeout > 0) 
 				fto = to = timeout;
@@ -142,7 +142,7 @@
 			   get rid of the long timeout between 
 			   prompts, and make it 50ms */
 			fto = 50;
-			to = c->pbx ? c->pbx->dtimeout * 1000 : 2000;
+			to = c->pbx ? c->pbx->dtimeoutms : 2000;
 		}
 		res = ast_readstring(c, s, maxlen, to, fto, "#");
 		if (!ast_strlen_zero(s))
@@ -1431,7 +1431,7 @@
 			res = 0;
 		return res;
 	case AST_ACTION_WAITOPTION:
-		res = ast_waitfordigit(chan, 1000 * (chan->pbx ? chan->pbx->rtimeout : 10));
+		res = ast_waitfordigit(chan, chan->pbx ? chan->pbx->rtimeoutms : 10000);
 		if (!res)
 			return 't';
 		return res;
@@ -1484,7 +1484,7 @@
 	int res = 0;
 	int ms;
 	while (option_matchmore(menu, exten)) {
-		ms = chan->pbx ? chan->pbx->dtimeout : 5000;
+		ms = chan->pbx ? chan->pbx->dtimeoutms : 5000;
 		if (strlen(exten) >= maxexten - 1) 
 			break;
 		res = ast_waitfordigit(chan, ms);

Modified: trunk/main/channel.c
URL: http://svn.digium.com/view/asterisk/trunk/main/channel.c?view=diff&rev=115076&r1=115075&r2=115076
==============================================================================
--- trunk/main/channel.c (original)
+++ trunk/main/channel.c Thu May  1 18:06:23 2008
@@ -464,9 +464,9 @@
 		return 1;
 	if (!chan->tech_pvt)		/* yes if no technology private data */
 		return 1;
-	if (!chan->whentohangup)	/* no if no hangup scheduled */
+	if (ast_tvzero(chan->whentohangup))	/* no if no hangup scheduled */
 		return 0;
-	if (chan->whentohangup > time(NULL)) 	/* no if hangup time has not come yet. */
+	if (ast_tvdiff_ms(chan->whentohangup, ast_tvnow()) > 0) 	/* no if hangup time has not come yet. */
 		return 0;
 	chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;	/* record event */
 	return 1;
@@ -519,32 +519,39 @@
 }
 
 /*! \brief Set when to hangup channel */
-void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
-{
-	chan->whentohangup = offset ? time(NULL) + offset : 0;
+void ast_channel_setwhentohangup_tv(struct ast_channel *chan, struct timeval offset)
+{
+	chan->whentohangup = ast_tvzero(offset) ? offset : ast_tvadd(offset, ast_tvnow());
 	ast_queue_frame(chan, &ast_null_frame);
 	return;
 }
 
+void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
+{
+	struct timeval tv = { offset, };
+	ast_channel_setwhentohangup_tv(chan, tv);
+}
+
 /*! \brief Compare a offset with when to hangup channel */
+int ast_channel_cmpwhentohangup_tv(struct ast_channel *chan, struct timeval offset)
+{
+	struct timeval whentohangup;
+
+	if (ast_tvzero(chan->whentohangup))
+		return ast_tvzero(offset) ? 0 : -1;
+
+	if (ast_tvzero(offset))
+		return 1;
+
+	whentohangup = ast_tvadd(offset, ast_tvnow());
+
+	return ast_tvdiff_ms(whentohangup, chan->whentohangup);
+}
+
 int ast_channel_cmpwhentohangup(struct ast_channel *chan, time_t offset)
 {
-	time_t whentohangup;
-
-	if (!chan->whentohangup)
-		return (offset == 0) ? 0 : -1;
-
-	if (!offset) /* XXX why is this special? */
-		return 1;
-
-	whentohangup = offset + time(NULL);
-
-	if (chan->whentohangup < whentohangup)
-		return 1;
-	else if (chan->whentohangup == whentohangup)
-		return 0;
-	else
-		return -1;
+	struct timeval tv = { offset, };
+	return ast_channel_cmpwhentohangup_tv(chan, tv);
 }
 
 /*! \brief Register a new telephony channel in Asterisk */
@@ -1793,8 +1800,8 @@
 	long rms;
 	int x, y, max;
 	int sz;
-	time_t now = 0;
-	long whentohangup = 0, diff;
+	struct timeval now = { 0, 0 };
+	struct timeval whentohangup = { 0, 0 }, diff;
 	struct ast_channel *winner = NULL;
 	struct fdmap {
 		int chan;
@@ -1820,25 +1827,25 @@
 			ast_channel_unlock(c[x]);
 			return NULL;
 		}
-		if (c[x]->whentohangup) {
-			if (!whentohangup)
-				time(&now);
-			diff = c[x]->whentohangup - now;
-			if (diff < 1) {
+		if (!ast_tvzero(c[x]->whentohangup)) {
+			if (ast_tvzero(whentohangup))
+				now = ast_tvnow();
+			diff = ast_tvsub(c[x]->whentohangup, now);
+			if (diff.tv_sec < 0 || ast_tvzero(diff)) {
 				/* Should already be hungup */
 				c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
 				ast_channel_unlock(c[x]);
 				return c[x];
 			}
-			if (!whentohangup || (diff < whentohangup))
+			if (ast_tvzero(whentohangup) || ast_tvcmp(diff, whentohangup) < 0)
 				whentohangup = diff;
 		}
 		ast_channel_unlock(c[x]);
 	}
 	/* Wait full interval */
 	rms = *ms;
-	if (whentohangup) {
-		rms = whentohangup * 1000;              /* timeout in milliseconds */
+	if (!ast_tvzero(whentohangup)) {
+		rms = whentohangup.tv_sec * 1000 + whentohangup.tv_usec / 1000;              /* timeout in milliseconds */
 		if (*ms >= 0 && *ms < rms)		/* original *ms still smaller */
 			rms =  *ms;
 	}
@@ -1884,10 +1891,10 @@
 			*ms = -1;
 		return NULL;
 	}
-	if (whentohangup) {   /* if we have a timeout, check who expired */
-		time(&now);
+	if (!ast_tvzero(whentohangup)) {   /* if we have a timeout, check who expired */
+		now = ast_tvnow();
 		for (x = 0; x < n; x++) {
-			if (c[x]->whentohangup && now >= c[x]->whentohangup) {
+			if (!ast_tvzero(c[x]->whentohangup) && ast_tvcmp(c[x]->whentohangup, now) <= 0) {
 				c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
 				if (winner == NULL)
 					winner = c[x];
@@ -1936,8 +1943,7 @@
 	struct timeval start = { 0 , 0 };
 	int res = 0;
 	struct epoll_event ev[1];
-	long whentohangup = 0, rms = *ms;
-	time_t now;
+	long diff, rms = *ms;
 	struct ast_channel *winner = NULL;
 	struct ast_epoll_data *aed = NULL;
 
@@ -1952,18 +1958,16 @@
 	}
 
 	/* Figure out their timeout */
-	if (chan->whentohangup) {
-		time(&now);
-		if ((whentohangup = chan->whentohangup - now) < 1) {
+	if (!ast_tvzero(chan->whentohangup)) {
+		if ((diff = ast_tvdiff_ms(chan->whentohangup, ast_tvnow())) < 0) {
 			/* They should already be hungup! */
 			chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
 			ast_channel_unlock(chan);
 			return NULL;
 		}
 		/* If this value is smaller then the current one... make it priority */
-		whentohangup *= 1000;
-		if (rms > whentohangup)
-			rms = whentohangup;
+		if (rms > diff)
+			rms = diff;
 	}
 
 	ast_channel_unlock(chan);
@@ -1988,9 +1992,8 @@
 	}
 
 	/* If this channel has a timeout see if it expired */
-	if (chan->whentohangup) {
-		time(&now);
-		if (now >= chan->whentohangup) {
+	if (!ast_tvzero(chan->whentohangup)) {
+		if (ast_tvdiff_ms(ast_tvnow(), chan->whentohangup) >= 0) {
 			chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
 			winner = chan;
 		}
@@ -2024,8 +2027,8 @@
 	struct timeval start = { 0 , 0 };
 	int res = 0, i;
 	struct epoll_event ev[25] = { { 0, } };
-	long whentohangup = 0, diff, rms = *ms;
-	time_t now;
+	struct timeval now = { 0, 0 };
+	long whentohangup = 0, diff = 0, rms = *ms;
 	struct ast_channel *winner = NULL;
 
 	for (i = 0; i < n; i++) {
@@ -2036,15 +2039,15 @@
 			ast_channel_unlock(c[i]);
 			return NULL;
 		}
-		if (c[i]->whentohangup) {
-			if (!whentohangup)
-				time(&now);
-			if ((diff = c[i]->whentohangup - now) < 1) {
+		if (!ast_tvzero(c[i]->whentohangup)) {
+			if (whentohangup == 0)
+				now = ast_tvnow();
+			if ((diff = ast_tvdiff_ms(c[i]->whentohangup, now)) < 0) {
 				c[i]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
 				ast_channel_unlock(c[i]);
 				return c[i];
 			}
-			if (!whentohangup || (diff < whentohangup))
+			if (!whentohangup || whentohangup > diff)
 				whentohangup = diff;
 		}
 		ast_channel_unlock(c[i]);
@@ -2053,7 +2056,7 @@
 
 	rms = *ms;
 	if (whentohangup) {
-		rms = whentohangup * 1000;
+		rms = whentohangup;
 		if (*ms >= 0 && *ms < rms)
 			rms = *ms;
 	}
@@ -2073,9 +2076,9 @@
 	}
 
 	if (whentohangup) {
-		time(&now);
+		now = ast_tvnow();
 		for (i = 0; i < n; i++) {
-			if (c[i]->whentohangup && now >= c[i]->whentohangup) {
+			if (!ast_tvzero(c[i]->whentohangup) && ast_tvdiff_ms(now, c[i]->whentohangup) >= 0) {
 				c[i]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
 				if (!winner)
 					winner = c[i];

Modified: trunk/main/cli.c
URL: http://svn.digium.com/view/asterisk/trunk/main/cli.c?view=diff&rev=115076&r1=115075&r2=115076
==============================================================================
--- trunk/main/cli.c (original)
+++ trunk/main/cli.c Thu May  1 18:06:23 2008
@@ -1064,7 +1064,7 @@
 		c->fds[0],
 		c->fin & ~DEBUGCHAN_FLAG, (c->fin & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
 		c->fout & ~DEBUGCHAN_FLAG, (c->fout & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
-		(long)c->whentohangup,
+		(long)c->whentohangup.tv_sec,
 		cdrtime, c->_bridge ? c->_bridge->name : "<none>", ast_bridged_channel(c) ? ast_bridged_channel(c)->name : "<none>", 
 		c->context, c->exten, c->priority, c->callgroup, c->pickupgroup, ( c->appl ? c->appl : "(N/A)" ),
 		( c-> data ? S_OR(c->data, "(Empty)") : "(None)"),

Modified: trunk/main/dial.c
URL: http://svn.digium.com/view/asterisk/trunk/main/dial.c?view=diff&rev=115076&r1=115075&r2=115076
==============================================================================
--- trunk/main/dial.c (original)
+++ trunk/main/dial.c Thu May  1 18:06:23 2008
@@ -266,7 +266,7 @@
 
 	channel->owner->appl = "AppDial2";
 	channel->owner->data = "(Outgoing Line)";
-	channel->owner->whentohangup = 0;
+	memset(&channel->owner->whentohangup, 0, sizeof(channel->owner->whentohangup));
 
 	/* Inherit everything from he who spawned this dial */
 	if (chan) {

Modified: trunk/main/manager.c
URL: http://svn.digium.com/view/asterisk/trunk/main/manager.c?view=diff&rev=115076&r1=115075&r2=115076
==============================================================================
--- trunk/main/manager.c (original)
+++ trunk/main/manager.c Thu May  1 18:06:23 2008
@@ -2367,13 +2367,14 @@
 {
 	struct ast_channel *c;
 	const char *name = astman_get_header(m, "Channel");
-	int timeout = atoi(astman_get_header(m, "Timeout"));
+	double timeout = atof(astman_get_header(m, "Timeout"));
+	struct timeval tv = { timeout, 0 };
 
 	if (ast_strlen_zero(name)) {
 		astman_send_error(s, m, "No channel specified");
 		return 0;
 	}
-	if (!timeout) {
+	if (!timeout || timeout < 0) {
 		astman_send_error(s, m, "No timeout specified");
 		return 0;
 	}
@@ -2382,7 +2383,9 @@
 		astman_send_error(s, m, "No such channel");
 		return 0;
 	}
-	ast_channel_setwhentohangup(c, timeout);
+
+	tv.tv_usec = (timeout - tv.tv_sec) * 1000000.0;
+	ast_channel_setwhentohangup_tv(c, tv);
 	ast_channel_unlock(c);
 	astman_send_ack(s, m, "Timeout Set");
 	return 0;

Modified: trunk/main/pbx.c
URL: http://svn.digium.com/view/asterisk/trunk/main/pbx.c?view=diff&rev=115076&r1=115075&r2=115076
==============================================================================
--- trunk/main/pbx.c (original)
+++ trunk/main/pbx.c Thu May  1 18:06:23 2008
@@ -3534,7 +3534,7 @@
 				buf[pos++] = digit;
 				buf[pos] = '\0';
 			}
-			waittime = c->pbx->dtimeout;
+			waittime = c->pbx->dtimeoutms;
 		}
 	}
 	return 0;
@@ -3567,8 +3567,8 @@
 		}
 	}
 	/* Set reasonable defaults */
-	c->pbx->rtimeout = 10;
-	c->pbx->dtimeout = 5;
+	c->pbx->rtimeoutms = 10000;
+	c->pbx->dtimeoutms = 5000;
 
 	autoloopflag = ast_test_flag(c, AST_FLAG_IN_AUTOLOOP);	/* save value to restore at the end */
 	ast_set_flag(c, AST_FLAG_IN_AUTOLOOP);
@@ -3602,12 +3602,12 @@
 			if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c, c->context, "T", 1, c->cid.cid_num)) {
 				set_ext_pri(c, "T", 0); /* 0 will become 1 with the c->priority++; at the end */
 				/* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
-				c->whentohangup = 0;
+				memset(&c->whentohangup, 0, sizeof(c->whentohangup));
 				c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT;
 			} else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
 				pbx_builtin_raise_exception(c, "ABSOLUTETIMEOUT");
 				/* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
-				c->whentohangup = 0;
+				memset(&c->whentohangup, 0, sizeof(c->whentohangup));
 				c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT;
 			} else if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
 				c->_softhangup = 0;
@@ -3664,7 +3664,7 @@
 				} else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c, c->context, "T", 1, c->cid.cid_num)) {
 					set_ext_pri(c, "T", 1); 
 					/* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
-					c->whentohangup = 0;
+					memset(&c->whentohangup, 0, sizeof(c->whentohangup));
 					c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT;
 					continue;
 				} else {
@@ -3707,9 +3707,9 @@
 		} else {	/* keypress received, get more digits for a full extension */
 			int waittime = 0;
 			if (digit)
-				waittime = c->pbx->dtimeout;
+				waittime = c->pbx->dtimeoutms;
 			else if (!autofallthrough)
-				waittime = c->pbx->rtimeout;
+				waittime = c->pbx->rtimeoutms;
 			if (!waittime) {
 				const char *status = pbx_builtin_getvar_helper(c, "DIALSTATUS");
 				if (!status)
@@ -7617,7 +7617,7 @@
 	if (args.timeout && (s = atof(args.timeout)) > 0)
 		 ms = s * 1000.0;
 	else if (chan->pbx)
-		ms = chan->pbx->rtimeout * 1000;
+		ms = chan->pbx->rtimeoutms;
 	else
 		ms = 10000;
 

Modified: trunk/res/res_agi.c
URL: http://svn.digium.com/view/asterisk/trunk/res/res_agi.c?view=diff&rev=115076&r1=115075&r2=115076
==============================================================================
--- trunk/res/res_agi.c (original)
+++ trunk/res/res_agi.c Thu May  1 18:06:23 2008
@@ -980,9 +980,9 @@
 
 	if ( argc == 5 )
 		timeout = atoi(argv[4]);
-	else if (chan->pbx->dtimeout) {
+	else if (chan->pbx->dtimeoutms) {
 		/* by default dtimeout is set to 5sec */
-		timeout = chan->pbx->dtimeout * 1000; /* in msec */
+		timeout = chan->pbx->dtimeoutms; /* in msec */
 	}
 
 	if (!(fs = ast_openstream(chan, argv[2], chan->language))) {
@@ -1398,18 +1398,20 @@
 
 static int handle_autohangup(struct ast_channel *chan, AGI *agi, int argc, char *argv[])
 {
-	int timeout;
+	double timeout;
+	struct timeval whentohangup = { 0, 0 };
 
 	if (argc != 3)
 		return RESULT_SHOWUSAGE;
-	if (sscanf(argv[2], "%d", &timeout) != 1)
+	if (sscanf(argv[2], "%lf", &timeout) != 1)
 		return RESULT_SHOWUSAGE;
 	if (timeout < 0)
 		timeout = 0;
-	if (timeout)
-		chan->whentohangup = time(NULL) + timeout;
-	else
-		chan->whentohangup = 0;
+	if (timeout) {
+		whentohangup.tv_sec = timeout;
+		whentohangup.tv_usec = (timeout - whentohangup.tv_sec) * 1000000.0;
+	}
+	ast_channel_setwhentohangup_tv(chan, whentohangup);
 	ast_agi_fdprintf(chan, agi->fd, "200 result=0\n");
 	return RESULT_SUCCESS;
 }




More information about the asterisk-commits mailing list