diff options
Diffstat (limited to 'main')
-rw-r--r-- | main/app.c | 12 | ||||
-rw-r--r-- | main/channel.c | 103 | ||||
-rw-r--r-- | main/cli.c | 2 | ||||
-rw-r--r-- | main/dial.c | 2 | ||||
-rw-r--r-- | main/manager.c | 9 | ||||
-rw-r--r-- | main/pbx.c | 18 |
6 files changed, 76 insertions, 70 deletions
diff --git a/main/app.c b/main/app.c index e5c712948..868f44dbd 100644 --- a/main/app.c +++ b/main/app.c @@ -72,7 +72,7 @@ int ast_app_dtget(struct ast_channel *chan, const char *context, char *collect, 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 @@ int ast_app_getdata(struct ast_channel *c, const char *prompt, char *s, int maxl } 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 @@ int ast_app_getdata(struct ast_channel *c, const char *prompt, char *s, int maxl 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 @@ static int ivr_dispatch(struct ast_channel *chan, struct ast_ivr_option *option, 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 @@ static int read_newoption(struct ast_channel *chan, struct ast_ivr_menu *menu, c 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); diff --git a/main/channel.c b/main/channel.c index 351d64198..2cb2bc336 100644 --- a/main/channel.c +++ b/main/channel.c @@ -464,9 +464,9 @@ int ast_check_hangup(struct ast_channel *chan) 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 @@ int ast_shutting_down(void) } /*! \brief Set when to hangup channel */ -void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset) +void ast_channel_setwhentohangup_tv(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; } +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(struct ast_channel *chan, time_t offset) +int ast_channel_cmpwhentohangup_tv(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); +} + +int ast_channel_cmpwhentohangup(struct ast_channel *chan, time_t offset) +{ + struct timeval tv = { offset, }; + return ast_channel_cmpwhentohangup_tv(chan, tv); } /*! \brief Register a new telephony channel in Asterisk */ @@ -1793,8 +1800,8 @@ struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, 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 @@ struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, 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 @@ struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, *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 @@ static struct ast_channel *ast_waitfor_nandfds_simple(struct ast_channel *chan, 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 @@ static struct ast_channel *ast_waitfor_nandfds_simple(struct ast_channel *chan, } /* 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 @@ static struct ast_channel *ast_waitfor_nandfds_simple(struct ast_channel *chan, } /* 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 @@ static struct ast_channel *ast_waitfor_nandfds_complex(struct ast_channel **c, i 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 @@ static struct ast_channel *ast_waitfor_nandfds_complex(struct ast_channel **c, i 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 @@ static struct ast_channel *ast_waitfor_nandfds_complex(struct ast_channel **c, i rms = *ms; if (whentohangup) { - rms = whentohangup * 1000; + rms = whentohangup; if (*ms >= 0 && *ms < rms) rms = *ms; } @@ -2073,9 +2076,9 @@ static struct ast_channel *ast_waitfor_nandfds_complex(struct ast_channel **c, i } 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]; diff --git a/main/cli.c b/main/cli.c index 11d6671d8..400678006 100644 --- a/main/cli.c +++ b/main/cli.c @@ -1064,7 +1064,7 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar 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)"), diff --git a/main/dial.c b/main/dial.c index ae6ea55fc..377d73b31 100644 --- a/main/dial.c +++ b/main/dial.c @@ -266,7 +266,7 @@ static int begin_dial_channel(struct ast_dial_channel *channel, struct ast_chann 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) { diff --git a/main/manager.c b/main/manager.c index 82cf5647c..1067c3ccb 100644 --- a/main/manager.c +++ b/main/manager.c @@ -2367,13 +2367,14 @@ static int action_timeout(struct mansession *s, const struct message *m) { 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 @@ static int action_timeout(struct mansession *s, const struct message *m) 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; diff --git a/main/pbx.c b/main/pbx.c index 92588bd92..dafd0cccf 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -3534,7 +3534,7 @@ static int collect_digits(struct ast_channel *c, int waittime, char *buf, int bu buf[pos++] = digit; buf[pos] = '\0'; } - waittime = c->pbx->dtimeout; + waittime = c->pbx->dtimeoutms; } } return 0; @@ -3567,8 +3567,8 @@ static int __ast_pbx_run(struct ast_channel *c) } } /* 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 @@ static int __ast_pbx_run(struct ast_channel *c) 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 @@ static int __ast_pbx_run(struct ast_channel *c) } 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 @@ static int __ast_pbx_run(struct ast_channel *c) } 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 @@ static int pbx_builtin_waitexten(struct ast_channel *chan, void *data) 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; |