Index: apps/app_read.c =================================================================== --- apps/app_read.c (revision 100676) +++ apps/app_read.c (working copy) @@ -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); Index: apps/app_dumpchan.c =================================================================== --- apps/app_dumpchan.c (revision 100676) +++ apps/app_dumpchan.c (working copy) @@ -113,7 +113,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, Index: apps/app_dial.c =================================================================== --- apps/app_dial.c (revision 100676) +++ apps/app_dial.c (working copy) @@ -1437,7 +1437,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)); @@ -1767,7 +1767,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)) { if (option_verbose > 2) @@ -1892,7 +1893,7 @@ if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_KEEPALIVE)) { if (calldurationlimit) - chan->whentohangup = 0; + memset(&chan->whentohangup, 0, sizeof(chan->whentohangup)); res = 0; } Index: apps/app_readexten.c =================================================================== --- apps/app_readexten.c (revision 100676) +++ apps/app_readexten.c (working copy) @@ -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); Index: apps/app_disa.c =================================================================== --- apps/app_disa.c (revision 100676) +++ apps/app_disa.c (working copy) @@ -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]; Index: apps/app_speech_utils.c =================================================================== --- apps/app_speech_utils.c (revision 100676) +++ apps/app_speech_utils.c (working copy) @@ -496,7 +496,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; @@ -526,7 +526,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; @@ -583,8 +583,8 @@ /* Do timeout check (shared between audio/dtmf) */ if ((!quieted || strlen(dtmf)) && started == 1) { - time(¤t); - if ((current-start) >= timeout) { + current = ast_tvnow(); + if ((ast_tvdiff_ms(start, current)) >= timeout) { done = 1; if (f) ast_frfree(f); @@ -613,7 +613,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 */ @@ -672,10 +672,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)); /* If the maximum length of the DTMF has been reached, stop now */ Index: apps/app_queue.c =================================================================== --- apps/app_queue.c (revision 100676) +++ apps/app_queue.c (working copy) @@ -2114,7 +2114,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); Index: funcs/func_timeout.c =================================================================== --- funcs/func_timeout.c (revision 100676) +++ funcs/func_timeout.c (working copy) @@ -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(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; Index: include/asterisk/channel.h =================================================================== --- include/asterisk/channel.h (revision 100676) +++ include/asterisk/channel.h (working copy) @@ -428,7 +428,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 */ @@ -872,12 +872,12 @@ * 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, 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 relative to the current time of when to hang up * * This function sets the absolute time out on a channel (when to hang up). * @@ -886,7 +886,7 @@ * * \return Nothing */ -void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset); +void ast_channel_setwhentohangup(struct ast_channel *chan, struct timeval offset); /*! * \brief Answer a channel Index: include/asterisk/pbx.h =================================================================== --- include/asterisk/pbx.h (revision 100676) +++ include/asterisk/pbx.h (working copy) @@ -110,8 +110,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 (seconds) */ + int rtimeoutms; /*!< Timeout for response (seconds) */ }; Index: main/channel.c =================================================================== --- main/channel.c (revision 100676) +++ main/channel.c (working copy) @@ -321,9 +321,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; @@ -376,32 +376,27 @@ } /*! \brief Set when to hangup channel */ -void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset) +void ast_channel_setwhentohangup(struct ast_channel *chan, struct timeval offset) { - chan->whentohangup = offset ? time(NULL) + offset : 0; + chan->whentohangup = ast_tvzero(offset) ? offset : ast_tvadd(offset, ast_tvnow()); ast_queue_frame(chan, &ast_null_frame); return; } /*! \brief Compare a offset with when to hangup channel */ -int ast_channel_cmpwhentohangup(struct ast_channel *chan, time_t offset) +int ast_channel_cmpwhentohangup(struct ast_channel *chan, struct timeval offset) { - time_t whentohangup; + struct timeval whentohangup; - if (!chan->whentohangup) - return (offset == 0) ? 0 : -1; + if (ast_tvzero(chan->whentohangup)) + return ast_tvzero(offset) ? 0 : -1; - if (!offset) /* XXX why is this special? */ + if (ast_tvzero(offset)) return 1; - whentohangup = offset + time(NULL); + whentohangup = ast_tvadd(offset, ast_tvnow()); - if (chan->whentohangup < whentohangup) - return 1; - else if (chan->whentohangup == whentohangup) - return 0; - else - return -1; + return ast_tvdiff_ms(whentohangup, chan->whentohangup); } /*! \brief Register a new telephony channel in Asterisk */ @@ -1633,8 +1628,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; @@ -1659,25 +1654,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; } @@ -1723,10 +1718,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]; @@ -1775,8 +1770,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; @@ -1791,18 +1785,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); @@ -1827,9 +1819,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; } @@ -1863,8 +1854,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++) { @@ -1875,15 +1866,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]); @@ -1892,7 +1883,7 @@ rms = *ms; if (whentohangup) { - rms = whentohangup * 1000; + rms = whentohangup; if (*ms >= 0 && *ms < rms) rms = *ms; } @@ -1912,9 +1903,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]; Index: main/manager.c =================================================================== --- main/manager.c (revision 100676) +++ main/manager.c (working copy) @@ -2120,13 +2120,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; } @@ -2135,7 +2136,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(c, tv); ast_channel_unlock(c); astman_send_ack(s, m, "Timeout Set"); return 0; Index: main/app.c =================================================================== --- main/app.c (revision 100676) +++ main/app.c (working copy) @@ -71,7 +71,7 @@ maxlen = size; if (!timeout && chan->pbx) - timeout = chan->pbx->dtimeout; + timeout = chan->pbx->dtimeoutms / 1000.0; else if (!timeout) timeout = 5; @@ -129,8 +129,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; @@ -141,7 +141,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)) @@ -1408,7 +1408,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; @@ -1461,7 +1461,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); Index: main/cli.c =================================================================== --- main/cli.c (revision 100676) +++ main/cli.c (working copy) @@ -1061,7 +1061,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 : "", ast_bridged_channel(c) ? ast_bridged_channel(c)->name : "", c->context, c->exten, c->priority, c->callgroup, c->pickupgroup, ( c->appl ? c->appl : "(N/A)" ), ( c-> data ? S_OR(c->data, "(Empty)") : "(None)"), Index: main/dial.c =================================================================== --- main/dial.c (revision 100676) +++ main/dial.c (working copy) @@ -265,7 +265,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) { Index: main/pbx.c =================================================================== --- main/pbx.c (revision 100677) +++ main/pbx.c (working copy) @@ -3215,7 +3215,7 @@ buf[pos++] = digit; buf[pos] = '\0'; } - waittime = c->pbx->dtimeout; + waittime = c->pbx->dtimeoutms; } } return 0; @@ -3248,8 +3248,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); @@ -3281,12 +3281,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 (ast_check_hangup(c)) { ast_debug(1, "Extension %s, priority %d returned normally even though call was hung up\n", @@ -3366,9 +3366,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) @@ -7024,7 +7024,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; Index: res/res_agi.c =================================================================== --- res/res_agi.c (revision 100676) +++ res/res_agi.c (working copy) @@ -999,9 +999,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))) { @@ -1417,18 +1417,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(chan, whentohangup); ast_agi_fdprintf(chan, agi->fd, "200 result=0\n"); return RESULT_SUCCESS; }