summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-rw-r--r--main/app.c12
-rw-r--r--main/channel.c103
-rw-r--r--main/cli.c2
-rw-r--r--main/dial.c2
-rw-r--r--main/manager.c9
-rw-r--r--main/pbx.c18
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;