int ast_control_streamfile(struct ast_channel *chan, const char *file, const char *fwd, const char *rev, const char *stop, const char *pause, int skipms)
{
- struct timeval started, ended;
long elapsed = 0,last_elapsed =0;
char *breaks=NULL;
char *end=NULL;
}
for (;;) {
- gettimeofday(&started,NULL);
+ struct timeval started = ast_tvnow();
if (chan)
ast_stopstream(chan);
break;
if (pause != NULL && strchr(pause, res)) {
- gettimeofday(&ended, NULL);
- elapsed = (((ended.tv_sec * 1000) + ended.tv_usec / 1000) - ((started.tv_sec * 1000) + started.tv_usec / 1000) + last_elapsed);
+ elapsed = ast_tvdiff_ms(ast_tvnow(), started) + last_elapsed;
for(;;) {
if (chan)
ast_stopstream(chan);
int i = 0;
int r;
struct ast_frame *f;
- struct timeval now, lastdigittime;
+ struct timeval lastdigittime;
- gettimeofday(&lastdigittime,NULL);
+ lastdigittime = ast_tvnow();
for(;;){
- gettimeofday(&now,NULL);
-
/* if outa time, leave */
- if (ast_tvdiff_ms(&now, &lastdigittime) >
+ if (ast_tvdiff_ms(ast_tvnow(), lastdigittime) >
((i > 0) ? sdto : fdto)){
if(option_verbose >= 4)
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: DTMF Digit Timeout on %s\n", chan->name);
if(i >= length)
break;
- gettimeofday(&lastdigittime,NULL);
+ lastdigittime = ast_tvnow();
}
digit_string[i] = '\0'; /* Nul terminate the end of the digit string */
LOCAL_USER_DECL;
-static int ms_diff(struct timeval *tv1, struct timeval *tv2)
-{
-int ms;
-
- ms = (tv1->tv_sec - tv2->tv_sec) * 1000;
- ms += (tv1->tv_usec - tv2->tv_usec) / 1000;
- return(ms);
-}
-
static void play_dialtone(struct ast_channel *chan, char *mailbox)
{
const struct tone_zone_sound *ts = NULL;
char tmp[256],arg2[256]="",exten[AST_MAX_EXTENSION],acctcode[20]="";
char *ourcontext,*ourcallerid,ourcidname[256],ourcidnum[256],*mailbox;
struct ast_frame *f;
- struct timeval lastout, now, lastdigittime;
+ struct timeval lastdigittime;
int res;
time_t rstart;
FILE *fp;
ast_log(LOG_WARNING, "Unable to set read format to Mu-law on %s\n",chan->name);
return -1;
}
- lastout.tv_sec = lastout.tv_usec = 0;
if (!data || !strlen((char *)data)) {
ast_log(LOG_WARNING, "disa requires an argument (passcode/passcode file)\n");
return -1;
k |= 1; /* We have the password */
ast_log(LOG_DEBUG, "DISA no-password login success\n");
}
- gettimeofday(&lastdigittime,NULL);
+ lastdigittime = ast_tvnow();
play_dialtone(chan, mailbox);
for(;;)
{
- gettimeofday(&now,NULL);
/* if outa time, give em reorder */
- if (ms_diff(&now,&lastdigittime) >
+ if (ast_tvdiff_ms(ast_tvnow(), lastdigittime) >
((k&2) ? digittimeout : firstdigittimeout))
{
ast_log(LOG_DEBUG,"DISA %s entry timeout on chan %s\n",
k|=2; /* We have the first digit */
ast_playtones_stop(chan);
}
- gettimeofday(&lastdigittime,NULL);
+ lastdigittime = ast_tvnow();
/* got a DTMF tone */
if (i < AST_MAX_EXTENSION) /* if still valid number of digits */
{
char cgrp[256];
char pgrp[256];
- gettimeofday(&now, NULL);
+ now = ast_tvnow();
memset(buf,0,size);
if (!c)
return 0;
struct ast_cdr *newcdr = ast_cdr_alloc();
memcpy(newcdr,cdr,sizeof(struct ast_cdr));
ast_cdr_append(cdr,newcdr);
- gettimeofday(&newcdr->start, NULL);
+ newcdr->start = ast_tvnow();
memset(&newcdr->answer, 0, sizeof(newcdr->answer));
memset(&newcdr->varshead, 0, sizeof(newcdr->varshead));
ast_cdr_copy_vars(newcdr, cdr);
int pid = -1;
int owriteformat;
int timeout = 2000;
- struct timeval now, next;
+ struct timeval next;
struct ast_frame *f;
struct myframe {
struct ast_frame f;
return -1;
}
- gettimeofday(&now, NULL);
res = mp3play((char *)data, fds[1]);
if (!strncasecmp((char *)data, "http://", 7)) {
timeout = 10000;
}
/* Wait 1000 ms first */
- next = now;
+ next = ast_tvnow();
next.tv_sec += 1;
if (res >= 0) {
pid = res;
/* Order is important -- there's almost always going to be mp3... we want to prioritize the
user */
for (;;) {
- gettimeofday(&now, NULL);
- ms = (next.tv_sec - now.tv_sec) * 1000;
- ms += (next.tv_usec - now.tv_usec) / 1000;
-#if 0
- printf("ms: %d\n", ms);
-#endif
+ ms = ast_tvdiff_ms(next, ast_tvnow());
if (ms <= 0) {
-#if 0
- {
- static struct timeval last;
- struct timeval tv;
- gettimeofday(&tv, NULL);
- printf("Since last: %ld\n", (tv.tv_sec - last.tv_sec) * 1000 + (tv.tv_usec - last.tv_usec) / 1000);
- last = tv;
- }
-#endif
res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata), timeout);
if (res > 0) {
myf.f.frametype = AST_FRAME_VOICE;
res = 0;
break;
}
- next.tv_usec += res / 2 * 125;
- if (next.tv_usec >= 1000000) {
- next.tv_usec -= 1000000;
- next.tv_sec++;
- }
-#if 0
- printf("Next: %d\n", ms);
-#endif
+ next = ast_tvadd(next, ast_samp2tv(myf.f.samples, 8000));
} else {
ms = ast_waitfor(chan, ms);
if (ms < 0) {
int ms = -1;
int pid = -1;
int owriteformat;
- struct timeval now, next;
+ struct timeval next;
struct ast_frame *f;
struct myframe {
struct ast_frame f;
res = NBScatplay(fds[1]);
/* Wait 1000 ms first */
- next = now;
+ next = ast_tvnow();
next.tv_sec += 1;
if (res >= 0) {
pid = res;
/* Order is important -- there's almost always going to be mp3... we want to prioritize the
user */
for (;;) {
- gettimeofday(&now, NULL);
- ms = (next.tv_sec - now.tv_sec) * 1000;
- ms += (next.tv_usec - now.tv_usec) / 1000;
-#if 0
- printf("ms: %d\n", ms);
-#endif
+ ms = ast_tvdiff_ms(next, ast_tvnow());
if (ms <= 0) {
-#if 0
- {
- static struct timeval last;
- struct timeval tv;
- gettimeofday(&tv, NULL);
- printf("Since last: %ld\n", (tv.tv_sec - last.tv_sec) * 1000 + (tv.tv_usec - last.tv_usec) / 1000);
- last = tv;
- }
-#endif
res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata));
if (res > 0) {
myf.f.frametype = AST_FRAME_VOICE;
res = 0;
break;
}
- next.tv_usec += res / 2 * 125;
- if (next.tv_usec >= 1000000) {
- next.tv_usec -= 1000000;
- next.tv_sec++;
- }
-#if 0
- printf("Next: %d\n", ms);
-#endif
+ next = ast_tvadd(next, ast_samp2tv(myf.f.samples, 8000));
} else {
ms = ast_waitfor(chan, ms);
if (ms < 0) {
if(len < strlen(returnvar))
returnvar[len]='\0';
else
- ast_log(LOG_WARNING,"%s is longer than %d, and %zd \n", file, len, strlen(returnvar));
+ ast_log(LOG_WARNING,"%s is longer than %d, and %d \n", file, len, (int)strlen(returnvar));
}
pbx_builtin_setvar_helper(chan, varname, returnvar);
free(returnvar);
LOCAL_USER_ADD(u);
- gettimeofday(&tv,NULL);
+ tv = ast_tvnow();
unixtime = (time_t)tv.tv_sec;
if( !strcasecmp(chan->language, "da" ) ) {
int i;
if (len > sizeof (buf)) {
- ast_log (LOG_WARNING, "Only doing %zd bytes (%d bytes requested)\n", sizeof (buf) / sizeof (signed short), len);
+ ast_log (LOG_WARNING, "Only doing %d bytes (%d bytes requested)\n", (int)(sizeof (buf) / sizeof (signed short)), len);
len = sizeof (buf);
#ifdef OUTALAW
samples = len;
char *stringp;
struct ast_frame *fr;
int notsilent=0;
- struct timeval start = { 0, 0}, end = {0, 0};
+ struct timeval start = { 0, 0};
int sil = 1000;
int min = 100;
int max = -1;
/* We've been quiet a little while */
if (notsilent) {
/* We had heard some talking */
- gettimeofday(&end, NULL);
- ms = (end.tv_sec - start.tv_sec) * 1000;
- ms += (end.tv_usec - start.tv_usec) / 1000;
+ ms = ast_tvdiff_ms(ast_tvnow(), start);
ms -= sil;
if (ms < 0)
ms = 0;
} else {
if (!notsilent) {
/* Heard some audio, mark the begining of the token */
- gettimeofday(&start, NULL);
+ start = ast_tvnow();
ast_log(LOG_DEBUG, "Start of voice token!\n");
notsilent = 1;
}
int samples=0;
int x;
short *foo;
- struct timeval start, tv;
+ struct timeval start;
struct ast_frame *f;
int rformat;
rformat = chan->readformat;
ast_log(LOG_NOTICE, "Unable to set to linear mode!\n");
return -1;
}
- gettimeofday(&start, NULL);
+ start = ast_tvnow();
for(;;) {
- gettimeofday(&tv, NULL);
- mssofar = (tv.tv_sec - start.tv_sec) * 1000;
- mssofar += (tv.tv_usec - start.tv_usec) / 1000;
+ mssofar = ast_tvdiff_ms(ast_tvnow(), start);
if (mssofar > ms)
break;
res = ast_waitfor(chan, ms - mssofar);
#if 0
/* Set the DIFF_* variables */
localtime_r(&t, &time_now);
- gettimeofday(&tv_now,NULL);
+ tv_now = ast_tvnow();
tnow = tv_now.tv_sec;
localtime_r(&tnow,&time_then);
break;
case 'd': /* date */
memset(&tm, 0, sizeof(struct tm));
- gettimeofday(&tv, NULL);
+ tv = ast_tvnow();
if (localtime_r(&(tv.tv_sec), &tm)) {
strftime(p, sizeof(prompt) - strlen(prompt), "%Y-%m-%d", &tm);
}
#endif
case 't': /* time */
memset(&tm, 0, sizeof(struct tm));
- gettimeofday(&tv, NULL);
+ tv = ast_tvnow();
if (localtime_r(&(tv.tv_sec), &tm)) {
strftime(p, sizeof(prompt) - strlen(prompt), "%H:%M:%S", &tm);
}
chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
if (!ast_test_flag(cdr, AST_CDR_FLAG_POSTED) && !ast_test_flag(cdr, AST_CDR_FLAG_POST_DISABLED))
ast_log(LOG_WARNING, "CDR on channel '%s' not posted\n", chan);
- if (!cdr->end.tv_sec && !cdr->end.tv_usec)
+ if (ast_tvzero(cdr->end))
ast_log(LOG_WARNING, "CDR on channel '%s' lacks end\n", chan);
- if (!cdr->start.tv_sec && !cdr->start.tv_usec)
+ if (ast_tvzero(cdr->start))
ast_log(LOG_WARNING, "CDR on channel '%s' lacks start\n", chan);
ast_cdr_free_vars(cdr, 0);
chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED))
ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
- if (cdr->start.tv_sec || cdr->start.tv_usec)
+ if (!ast_tvzero(cdr->start))
ast_log(LOG_WARNING, "CDR on channel '%s' already started\n", chan);
- gettimeofday(&cdr->start, NULL);
+ cdr->start = ast_tvnow();
}
cdr = cdr->next;
}
ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
if (cdr->disposition < AST_CDR_ANSWERED)
cdr->disposition = AST_CDR_ANSWERED;
- if (!cdr->answer.tv_sec && !cdr->answer.tv_usec) {
- gettimeofday(&cdr->answer, NULL);
- }
+ if (ast_tvzero(cdr->answer))
+ cdr->answer = ast_tvnow();
cdr = cdr->next;
}
}
chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED))
ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
- if (!cdr->start.tv_sec && !cdr->start.tv_usec)
+ if (ast_tvzero(cdr->start))
ast_log(LOG_WARNING, "CDR on channel '%s' has not started\n", chan);
- if (!cdr->end.tv_sec && !cdr->end.tv_usec)
- gettimeofday(&cdr->end, NULL);
+ if (ast_tvzero(cdr->end))
+ cdr->end = ast_tvnow();
cdr = cdr->next;
}
}
chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : "<unknown>";
if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED))
ast_log(LOG_WARNING, "CDR on channel '%s' already posted\n", chan);
- if (!cdr->end.tv_sec && !cdr->end.tv_usec)
+ if (ast_tvzero(cdr->end))
ast_log(LOG_WARNING, "CDR on channel '%s' lacks end\n", chan);
- if (!cdr->start.tv_sec && !cdr->start.tv_usec)
+ if (ast_tvzero(cdr->start))
ast_log(LOG_WARNING, "CDR on channel '%s' lacks start\n", chan);
cdr->duration = cdr->end.tv_sec - cdr->start.tv_sec + (cdr->end.tv_usec - cdr->start.tv_usec) / 1000000;
- if (cdr->answer.tv_sec || cdr->answer.tv_usec)
+ if (!ast_tvzero(cdr->answer))
cdr->billsec = cdr->end.tv_sec - cdr->answer.tv_sec + (cdr->end.tv_usec - cdr->answer.tv_usec) / 1000000;
else
cdr->billsec = 0;
static void *do_cdr(void *data)
{
- struct timeval now;
struct timespec timeout;
int schedms;
int numevents = 0;
for(;;) {
- gettimeofday(&now, NULL);
+ struct timeval now = ast_tvnow();
schedms = ast_sched_wait(sched);
/* this shouldn't happen, but provide a 1 second default just in case */
if (schedms <= 0)
t = tv.tv_sec;
if (strlen(buf) > bufsize - 3)
return -1;
- if (!tv.tv_sec && !tv.tv_usec) {
+ if (ast_tvzero(tv)) {
strncat(buf, ",", bufsize - strlen(buf) - 1);
return 0;
}
char buf[80];
/* To make sure we have date variable if not insert null to SQL */
- if (tv.tv_sec && tv.tv_usec)
+ if (!ast_tvzero(tv))
{
t = tv.tv_sec;
localtime_r(&t, &tm);
int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
{
/* Wait for x amount of time on a file descriptor to have input. */
- struct timeval start, now;
+ struct timeval start;
int res;
int x, y;
int winner = -1;
return -1;
}
if (*ms > 0)
- gettimeofday(&start, NULL);
+ start = ast_tvnow();
y = 0;
for (x=0;x<n;x++) {
if (fds[x] > -1) {
}
}
if (*ms > 0) {
- long passed;
- gettimeofday(&now, NULL);
- passed = (now.tv_sec - start.tv_sec) * 1000;
- passed += (now.tv_usec - start.tv_usec) / 1000;
- if (passed <= *ms)
- *ms -= passed;
- else
+ *ms -= ast_tvdiff_ms(ast_tvnow(), start);
+ if (*ms < 0)
*ms = 0;
}
return winner;
int *exception, int *outfd, int *ms)
{
/* Wait for x amount of time on a file descriptor to have input. */
- struct timeval start, end;
+ struct timeval start;
struct pollfd *pfds;
int res;
long rms;
}
}
if (*ms > 0)
- gettimeofday(&start, NULL);
+ start = ast_tvnow();
res = poll(pfds, max, rms);
if (res < 0) {
for (x=0;x<n;x++)
}
}
if (*ms > 0) {
- long diff;
- gettimeofday(&end, NULL);
- diff = (end.tv_sec - start.tv_sec) * 1000;
- diff += (end.tv_usec - start.tv_usec) / 1000;
- if (diff < *ms)
- *ms -= diff;
- else
+ *ms -= ast_tvdiff_ms(ast_tvnow(), start);
+ if (*ms < 0)
*ms = 0;
}
return winner;
return 0;
}
-static long tvdiff(struct timeval *now, struct timeval *then)
-{
-#if 0
- return (((now->tv_sec * 1000) + now->tv_usec / 1000) - ((then->tv_sec * 1000) + then->tv_usec / 1000));
-#else
- return (now->tv_sec - then->tv_sec) * 1000 + (now->tv_usec - then->tv_usec) / 1000;
-#endif
-}
-
/*--- Find bridged channel */
struct ast_channel *ast_bridged_channel(struct ast_channel *chan)
{
int res=0;
int o0nativeformats;
int o1nativeformats;
- struct timeval precise_now;
long elapsed_ms=0, time_left_ms=0;
cs[0] = c0;
/* timestamp */
if (config->timelimit) {
/* If there is a time limit, return now */
- gettimeofday(&precise_now,NULL);
- elapsed_ms = tvdiff(&precise_now,start_time);
+ elapsed_ms = ast_tvdiff_ms(ast_tvnow(), *start_time);
time_left_ms = config->timelimit - elapsed_ms;
if (*playitagain && ((ast_test_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING)) || (ast_test_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING))) && (config->play_warning && time_left_ms <= config->play_warning)) {
int firstpass;
int o0nativeformats;
int o1nativeformats;
- struct timeval start_time,precise_now;
+ struct timeval start_time;
long elapsed_ms=0, time_left_ms=0;
int playit=0, playitagain=1, first_time=1;
config->firstpass = 0;
/* timestamp */
- gettimeofday(&start_time,NULL);
+ start_time = ast_tvnow();
time_left_ms = config->timelimit;
if ((ast_test_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING)) && config->start_sound && firstpass)
for (/* ever */;;) {
/* timestamp */
if (config->timelimit) {
- gettimeofday(&precise_now,NULL);
- elapsed_ms = tvdiff(&precise_now,&start_time);
+ elapsed_ms = ast_tvdiff_ms(ast_tvnow(), start_time);
time_left_ms = config->timelimit - elapsed_ms;
if (playitagain && ((ast_test_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING)) || (ast_test_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING))) && (config->play_warning && time_left_ms <= config->play_warning)) {
/* If someone reduces the wrapuptime and reloads, we want it
* to change the wrapuptime immediately on all calls */
if (p->wrapuptime > wrapuptime) {
- struct timeval now;
- gettimeofday(&now, NULL);
+ struct timeval now = ast_tvnow();
+ /* XXX check what is this exactly */
/* We won't be pedantic and check the tv_usec val */
if (p->lastdisc.tv_sec > (now.tv_sec + wrapuptime/1000)) {
if (p->chan)
ast_log(LOG_DEBUG, "Bridge on '%s' being cleared (2)\n", p->chan->name);
ast_hangup(p->chan);
- if (p->wrapuptime && p->acknowledged) {
- gettimeofday(&p->lastdisc, NULL);
- p->lastdisc.tv_usec += (p->wrapuptime % 1000) * 1000;
- if (p->lastdisc.tv_usec > 1000000) {
- p->lastdisc.tv_usec -= 1000000;
- p->lastdisc.tv_sec++;
- }
- p->lastdisc.tv_sec += (p->wrapuptime / 1000);
- }
+ if (p->wrapuptime && p->acknowledged)
+ p->lastdisc = ast_tvadd(ast_tvnow(), ast_samp2tv(p->wrapuptime, 1000));
}
p->chan = NULL;
p->acknowledged = 0;
/* If they're dead, go ahead and hang up on the agent now */
if (!ast_strlen_zero(p->loginchan)) {
/* Store last disconnect time */
- if (p->wrapuptime && p->acknowledged) {
- gettimeofday(&p->lastdisc, NULL);
- p->lastdisc.tv_usec += (p->wrapuptime % 1000) * 1000;
- if (p->lastdisc.tv_usec >= 1000000) {
- p->lastdisc.tv_usec -= 1000000;
- p->lastdisc.tv_sec++;
- }
- p->lastdisc.tv_sec += (p->wrapuptime / 1000);
- } else
- memset(&p->lastdisc, 0, sizeof(p->lastdisc));
+ if (p->wrapuptime && p->acknowledged)
+ p->lastdisc = ast_tvadd(ast_tvnow(), ast_samp2tv(p->wrapuptime, 1000));
+ else
+ p->lastdisc = ast_tv(0,0);
if (p->chan) {
/* Recognize the hangup and pass it along immediately */
ast_hangup(p->chan);
/* Not dead -- check availability now */
ast_mutex_lock(&p->lock);
/* Store last disconnect time */
- gettimeofday(&p->lastdisc, NULL);
+ p->lastdisc = ast_tvnow();
ast_mutex_unlock(&p->lock);
}
/* Release ownership of the agent to other threads (presumably running the login app). */
static int agent_cont_sleep( void *data )
{
struct agent_pvt *p;
- struct timeval tv;
int res;
p = (struct agent_pvt *)data;
ast_mutex_lock(&p->lock);
res = p->app_sleep_cond;
if (p->lastdisc.tv_sec) {
- gettimeofday(&tv, NULL);
- if ((tv.tv_sec - p->lastdisc.tv_sec) * 1000 +
- (tv.tv_usec - p->lastdisc.tv_usec) / 1000 > p->wrapuptime)
+ if (ast_tvdiff_ms(ast_tvnow(), p->lastdisc) > p->wrapuptime)
res = 1;
}
ast_mutex_unlock(&p->lock);
if (!p->pending && ((groupmatch && (p->group & groupmatch)) || !strcmp(data, p->agent))) {
if (p->chan || !ast_strlen_zero(p->loginchan))
hasagent++;
- gettimeofday(&tv, NULL);
+ tv = ast_tvnow();
#if 0
ast_log(LOG_NOTICE, "Time now: %ld, Time of lastdisc: %ld\n", tv.tv_sec, p->lastdisc.tv_sec);
#endif
if (!p->lastdisc.tv_sec || (tv.tv_sec > p->lastdisc.tv_sec)) {
- memset(&p->lastdisc, 0, sizeof(p->lastdisc));
+ p->lastdisc = ast_tv(0, 0);
/* Agent must be registered, but not have any active call, and not be in a waiting state */
if (!p->owner && p->chan) {
/* Could still get a fixed agent */
int max_login_tries = maxlogintries;
struct agent_pvt *p;
struct localuser *u;
- struct timeval tv;
int login_state = 0;
char user[AST_MAX_AGENT] = "";
char pass[AST_MAX_AGENT];
ast_mutex_lock(&agentlock);
ast_mutex_lock(&p->lock);
if (p->lastdisc.tv_sec) {
- gettimeofday(&tv, NULL);
- if ((tv.tv_sec - p->lastdisc.tv_sec) * 1000 +
- (tv.tv_usec - p->lastdisc.tv_usec) / 1000 > p->wrapuptime) {
+ if (ast_tvdiff_ms(ast_tvnow(), p->lastdisc) > p->wrapuptime) {
if (option_debug)
ast_log(LOG_DEBUG, "Wrapup time for %s expired!\n", p->agent);
- memset(&p->lastdisc, 0, sizeof(p->lastdisc));
+ p->lastdisc = ast_tv(0, 0);
if (p->ackcall > 1)
check_beep(p, 0);
else
static void update_jbsched(struct chan_iax2_pvt *pvt) {
int when;
- struct timeval tv;
-
- gettimeofday(&tv,NULL);
- when = (tv.tv_sec - pvt->rxcore.tv_sec) * 1000 +
- (tv.tv_usec - pvt->rxcore.tv_usec) / 1000;
+ when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
/* fprintf(stderr, "now = %d, next=%d\n", when, jb_next(pvt->jb)); */
/* to catch up with runq's now */
tv.tv_usec += 1000;
- now = (tv.tv_sec - pvt->rxcore.tv_sec) * 1000 +
- (tv.tv_usec - pvt->rxcore.tv_usec) / 1000;
+ now = ast_tvdiff_ms(tv, pvt->rxcore);
if(now >= (next = jb_next(pvt->jb))) {
ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
af.mallocd = 0;
af.src = "IAX2 JB interpolation";
af.data = NULL;
- af.delivery.tv_sec = pvt->rxcore.tv_sec;
- af.delivery.tv_usec = pvt->rxcore.tv_usec;
- af.delivery.tv_sec += next / 1000;
- af.delivery.tv_usec += (next % 1000) * 1000;
+ af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
af.offset=AST_FRIENDLY_OFFSET;
- if (af.delivery.tv_usec >= 1000000) {
- af.delivery.tv_usec -= 1000000;
- af.delivery.tv_sec += 1;
- }
/* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
* which we'd need to malloc, and then it would free it. That seems like a drag */
ast_log(LOG_DEBUG, "schedule_delivery: call=%d: TS jumped. resyncing rxcore (ts=%d, last=%d)\n",
fr->callno, fr->ts, iaxs[fr->callno]->last);
/* zap rxcore - calc_rxstamp will make a new one based on this frame */
- iaxs[fr->callno]->rxcore.tv_sec = 0;
- iaxs[fr->callno]->rxcore.tv_usec = 0;
+ iaxs[fr->callno]->rxcore = ast_tv(0, 0);
/* wipe "last" if stamps have jumped backwards */
if (x<0)
iaxs[fr->callno]->last = 0;
/* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
- if ( (!fromtrunk) && (iaxs[fr->callno]->rxcore.tv_sec || iaxs[fr->callno]->rxcore.tv_usec) ) {
- fr->af.delivery.tv_sec = iaxs[fr->callno]->rxcore.tv_sec;
- fr->af.delivery.tv_usec = iaxs[fr->callno]->rxcore.tv_usec;
- fr->af.delivery.tv_sec += fr->ts / 1000;
- fr->af.delivery.tv_usec += (fr->ts % 1000) * 1000;
- if (fr->af.delivery.tv_usec >= 1000000) {
- fr->af.delivery.tv_usec -= 1000000;
- fr->af.delivery.tv_sec += 1;
- }
- }
+ if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
+ fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
else {
#if 0
ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
#endif
- fr->af.delivery.tv_sec = 0;
- fr->af.delivery.tv_usec = 0;
+ fr->af.delivery = ast_tv(0,0);
}
#ifndef NEWJB
if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
/* Call has been transferred. We're no longer involved */
gettimeofday(&tv, NULL);
- if (!waittimer.tv_sec && !waittimer.tv_usec) {
- waittimer.tv_sec = tv.tv_sec;
- waittimer.tv_usec = tv.tv_usec;
+ if (ast_tvzero(waittimer)) {
+ waittimer = tv;
} else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
c0->_softhangup |= AST_SOFTHANGUP_DEV;
c1->_softhangup |= AST_SOFTHANGUP_DEV;
long int ms, pred;
tpeer->trunkact = *tv;
- mssincetx = (tv->tv_sec - tpeer->lasttxtime.tv_sec) * 1000 +
- (1000000 + tv->tv_usec - tpeer->lasttxtime.tv_usec) / 1000 - 1000;
- if (mssincetx > 5000 || (!tpeer->txtrunktime.tv_sec && !tpeer->txtrunktime.tv_usec)) {
+ mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
+ if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
/* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
- tpeer->txtrunktime.tv_sec = tv->tv_sec;
- tpeer->txtrunktime.tv_usec = tv->tv_usec;
+ tpeer->txtrunktime = *tv;
tpeer->lastsent = 999999;
}
/* Update last transmit time now */
- tpeer->lasttxtime.tv_sec = tv->tv_sec;
- tpeer->lasttxtime.tv_usec = tv->tv_usec;
+ tpeer->lasttxtime = *tv;
/* Calculate ms offset */
- ms = (tv->tv_sec - tpeer->txtrunktime.tv_sec) * 1000 +
- (1000000 + tv->tv_usec - tpeer->txtrunktime.tv_usec) / 1000 - 1000;
+ ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
/* Predict from last value */
pred = tpeer->lastsent + sampms;
if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
{
long ms; /* NOT unsigned */
- if (!iaxs[callno]->rxcore.tv_sec && !iaxs[callno]->rxcore.tv_usec) {
+ if (ast_tvzero(iaxs[callno]->rxcore)) {
/* Initialize rxcore time if appropriate */
gettimeofday(&iaxs[callno]->rxcore, NULL);
/* Round to nearest 20ms so traces look pretty */
iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
}
/* Calculate difference between trunk and channel */
- ms = (tv->tv_sec - iaxs[callno]->rxcore.tv_sec) * 1000 +
- (1000000 + tv->tv_usec - iaxs[callno]->rxcore.tv_usec) / 1000 - 1000;
+ ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
/* Return as the sum of trunk time and the difference between trunk and real time */
return ms + ts;
}
-static void add_ms(struct timeval *tv, int ms) {
- tv->tv_usec += ms * 1000;
- if(tv->tv_usec > 1000000) {
- tv->tv_usec -= 1000000;
- tv->tv_sec++;
- }
- if(tv->tv_usec < 0) {
- tv->tv_usec += 1000000;
- tv->tv_sec--;
- }
-}
-
static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
{
- struct timeval tv;
int ms;
int voice = 0;
int genuine = 0;
p->notsilenttx = 0;
}
}
- if (!p->offset.tv_sec && !p->offset.tv_usec) {
+ if (ast_tvzero(p->offset)) {
gettimeofday(&p->offset, NULL);
/* Round to nearest 20ms for nice looking traces */
p->offset.tv_usec -= p->offset.tv_usec % 20000;
if (ts)
return ts;
/* If we have a time that the frame arrived, always use it to make our timestamp */
- if (delivery && (delivery->tv_sec || delivery->tv_usec)) {
- ms = (delivery->tv_sec - p->offset.tv_sec) * 1000 +
- (1000000 + delivery->tv_usec - p->offset.tv_usec) / 1000 - 1000;
+ if (delivery && !ast_tvzero(*delivery)) {
+ ms = ast_tvdiff_ms(*delivery, p->offset);
if (option_debug > 2)
ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
} else {
- gettimeofday(&tv, NULL);
- ms = (tv.tv_sec - p->offset.tv_sec) * 1000 +
- (1000000 + tv.tv_usec - p->offset.tv_usec) / 1000 - 1000;
+ ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
if (ms < 0)
ms = 0;
if (voice) {
if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
/* Adjust our txcore, keeping voice and
non-voice synchronized */
- add_ms(&p->offset, (int)(ms - p->nextpred)/10);
+ p->offset = ast_tvadd(p->offset,
+ ast_samp2tv((ms - p->nextpred)/10, 1000)); /* XXX what scale is this ??? */
if (!p->nextpred) {
p->nextpred = ms; /*f->samples / 8;*/
/* Receive from p1, send to p2 */
/* Setup rxcore if necessary on outgoing channel */
- if (!p1->rxcore.tv_sec && !p1->rxcore.tv_usec)
- gettimeofday(&p1->rxcore, NULL);
+ if (ast_tvzero(p1->rxcore))
+ p1->rxcore = ast_tvnow();
/* Setup txcore if necessary on outgoing channel */
- if (!p2->offset.tv_sec && !p2->offset.tv_usec)
- gettimeofday(&p2->offset, NULL);
+ if (ast_tvzero(p2->offset))
+ p2->offset = ast_tvnow();
/* Now, ts is the timestamp of the original packet in the orignal context.
Adding rxcore to it gives us when we would want the packet to be delivered normally.
Subtracting txcore of the outgoing channel gives us what we'd expect */
- ms = (p1->rxcore.tv_sec - p2->offset.tv_sec) * 1000 +
- (1000000 + p1->rxcore.tv_usec - p2->offset.tv_usec) / 1000 - 1000;
+ ms = ast_tvdiff_ms(p1->rxcore, p2->offset);
fakets += ms;
/* FIXME? SLD would rather remove this and leave it to the end system to deal with */
{
/* Returns where in "receive time" we are. That is, how many ms
since we received (or would have received) the frame with timestamp 0 */
- struct timeval tv;
int ms;
#ifdef IAXTESTS
int jit;
#endif /* IAXTESTS */
/* Setup rxcore if necessary */
- if (!p->rxcore.tv_sec && !p->rxcore.tv_usec) {
- gettimeofday(&p->rxcore, NULL);
+ if (ast_tvzero(p->rxcore)) {
+ p->rxcore = ast_tvnow();
if (option_debug)
ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
- p->rxcore.tv_sec -= offset / 1000;
- p->rxcore.tv_usec -= (offset % 1000) * 1000;
- if (p->rxcore.tv_usec < 0) {
- p->rxcore.tv_usec += 1000000;
- p->rxcore.tv_sec -= 1;
- }
+ p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
#if 1
if (option_debug)
ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
#endif
}
- gettimeofday(&tv, NULL);
- ms = (tv.tv_sec - p->rxcore.tv_sec) * 1000 +
- (1000000 + tv.tv_usec - p->rxcore.tv_usec) / 1000 - 1000;
+ ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
#ifdef IAXTESTS
if (test_jit) {
if (!test_jitpct || ((100.0 * rand() / (RAND_MAX + 1.0)) < test_jitpct)) {
ast_mutex_init(&tpeer->lock);
tpeer->lastsent = 9999;
memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
- gettimeofday(&tpeer->trunkact, NULL);
+ tpeer->trunkact = ast_tvnow();
ast_mutex_lock(&tpeer->lock);
tpeer->next = tpeers;
tpeer->sockfd = fd;
ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
return 1;
}
- if (!ts || (!tpeer->rxtrunktime.tv_sec && !tpeer->rxtrunktime.tv_usec)) {
- gettimeofday(&tpeer->rxtrunktime, NULL);
- tpeer->trunkact = tpeer->rxtrunktime;
- } else
- gettimeofday(&tpeer->trunkact, NULL);
+ tpeer->trunkact = ast_tvnow();
+ if (!ts || ast_tvzero(tpeer->rxtrunktime))
+ tpeer->rxtrunktime = tpeer->trunkact;
rxtrunktime = tpeer->rxtrunktime;
ast_mutex_unlock(&tpeer->lock);
while(res >= sizeof(struct ast_iax2_meta_trunk_entry)) {
while(dp) {
next = dp->next;
/* Expire old caches */
- if ((tv.tv_sec > dp->expirey.tv_sec) ||
- ((tv.tv_sec == dp->expirey.tv_sec) && (tv.tv_usec > dp->expirey.tv_usec))) {
+ if (ast_tvcmp(tv, dp->expirey) > 0) {
/* It's expired, let it disappear */
if (prev)
prev->next = dp->next;
p->fr.src = type;
p->fr.offset = 0;
p->fr.mallocd=0;
- p->fr.delivery.tv_sec = 0;
- p->fr.delivery.tv_usec = 0;
+ p->fr.delivery = ast_tv(0,0);
phonee.bytes = ioctl(p->fd, PHONE_EXCEPTION);
if (phonee.bits.dtmf_ready) {
p->fr.src = type;
p->fr.offset = 0;
p->fr.mallocd=0;
- p->fr.delivery.tv_sec = 0;
- p->fr.delivery.tv_usec = 0;
+ p->fr.delivery = ast_tv(0,0);
/* Try to read some data... */
CHECK_BLOCKING(ast);
if (i->dialtone) {
/* Remember we're going to have to come back and play
more dialtones */
- if (!tv.tv_usec && !tv.tv_sec) {
+ if (ast_tvzero(tv)) {
/* If we're due for a dialtone, play one */
if (write(i->fd, DialTone + tonepos, 240) != 240)
ast_log(LOG_WARNING, "Dial tone write error\n");
tonepos += 240;
if (tonepos >= sizeof(DialTone))
tonepos = 0;
- if (!tv.tv_usec && !tv.tv_sec) {
- tv.tv_usec = 30000;
- tv.tv_sec = 0;
+ if (ast_tvzero(tv)) {
+ tv = ast_tv(30000, 0);
}
res = ast_select(n + 1, &rfds, NULL, &efds, &tv);
} else {
res = ast_select(n + 1, &rfds, NULL, &efds, NULL);
- tv.tv_usec = 0;
- tv.tv_sec = 0;
+ tv = ast_tv(0,0);
tonepos = 0;
}
/* Okay, select has finished. Let's see what happened. */
int newstate = 0;
peer = p->peerpoke;
gettimeofday(&tv, NULL);
- pingtime = (tv.tv_sec - peer->ps.tv_sec) * 1000 +
- (tv.tv_usec - peer->ps.tv_usec) / 1000;
+ pingtime = ast_tvdiff_ms(tv, peer->ps);
if (pingtime < 1)
pingtime = 1;
if ((peer->lastms < 0) || (peer->lastms > peer->maxms)) {
struct ast_dsp *vad; /* AST Voice Activation Detection dsp */
- double lastgrunt; /* time stamp (secs since epoc) of last grunt event */
+ struct timeval lastgrunt; /* time stamp of last grunt event */
ast_mutex_t lock; /* This one just protects bridge ptr below */
vpb_bridge_t *bridge;
return (res==VPB_OK)?0:-1;
}
-static double get_time_in_ms()
-{
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return ((double)tv.tv_sec*1000)+((double)tv.tv_usec/1000);
-}
-
/* Caller ID can be located in different positions between the rings depending on your Telco
* Australian (Telstra) callerid starts 700ms after 1st ring and finishes 1.5s after first ring
* Use ANALYSE_CID to record rings and determine location of callerid
static void get_callerid(struct vpb_pvt *p)
{
short buf[CID_MSECS*8]; /* 8kHz sampling rate */
- double cid_record_time;
+ struct timeval cid_record_time;
int rc;
struct ast_channel *owner = p->owner;
/*
if( ast_mutex_trylock(&p->record_lock) == 0 ) {
- cid_record_time = get_time_in_ms();
+ cid_record_time = ast_tvnow();
if (option_verbose>3)
ast_verbose(VERBOSE_PREFIX_4 "CID record - start\n");
vpb_sleep(RING_SKIP);
if (option_verbose>3)
- ast_verbose(VERBOSE_PREFIX_4 "CID record - skipped %fms trailing ring\n",
- get_time_in_ms() - cid_record_time);
- cid_record_time = get_time_in_ms();
+ ast_verbose(VERBOSE_PREFIX_4 "CID record - skipped %ldms trailing ring\n",
+ ast_tvdiff_ms(ast_tvnow(), cid_record_time));
+ cid_record_time = ast_tvnow();
/* Record bit between the rings which contains the callerid */
vpb_record_buf_start(p->handle, VPB_LINEAR);
#endif
if (option_verbose>3)
- ast_verbose(VERBOSE_PREFIX_4 "CID record - recorded %fms between rings\n",
- get_time_in_ms() - cid_record_time);
+ ast_verbose(VERBOSE_PREFIX_4 "CID record - recorded %ldms between rings\n",
+ ast_tvdiff_ms(ast_tvnow(), cid_record_time));
ast_mutex_unlock(&p->record_lock);
}
else if (e->data == VPB_GRUNT) {
- if( ( get_time_in_ms() - p->lastgrunt ) > gruntdetect_timeout ) {
+ if( ( ast_tvdiff_ms(ast_tvnow(), p->lastgrunt) > gruntdetect_timeout ) {
/* Nothing heard on line for a very long time
* Timeout connection */
if (option_verbose > 2)
ast_log(LOG_NOTICE,"%s: Line hangup due of lack of conversation\n",p->dev);
f.subclass = AST_CONTROL_HANGUP;
} else {
- p->lastgrunt = get_time_in_ms();
+ p->lastgrunt = ast_tvnow();
f.frametype = -1;
}
}
{
struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;
int res = 0, fmt = 0;
- struct timeval play_buf_time_start,play_buf_time_finish;
+ struct timeval play_buf_time_start;
/* ast_mutex_lock(&p->lock); */
if(option_verbose>5)
ast_verbose("%s: vpb_write: Writing to channel\n", p->dev);
/* ast_log(LOG_DEBUG, "%s: vpb_write: Applied gain..\n", p->dev); */
-/* gettimeofday(&tv, NULL); */
-/* return ((double)tv.tv_sec*1000)+((double)tv.tv_usec/1000); */
-
if ((p->read_state == 1)&&(p->play_buf_time<5)){
- gettimeofday(&play_buf_time_start,NULL);
+ play_buf_time_start = ast_tvnow();
res = vpb_play_buf_sync(p->handle, (char*)frame->data, frame->datalen);
- if( (res == VPB_OK) && (option_verbose > 5) ) {
+ if( res == VPB_OK && option_verbose > 5 ) {
short * data = (short*)frame->data;
ast_verbose("%s: vpb_write: Wrote chan (codec=%d) %d %d\n", p->dev, fmt, data[0],data[1]);
}
- gettimeofday(&play_buf_time_finish,NULL);
- if (play_buf_time_finish.tv_sec == play_buf_time_start.tv_sec){
- p->play_buf_time=(int)((play_buf_time_finish.tv_usec-play_buf_time_start.tv_usec)/1000);
- /* ast_log(LOG_DEBUG, "%s: vpb_write: Timing start(%d) finish(%d)\n", p->dev,play_buf_time_start.tv_usec,play_buf_time_finish.tv_usec); */
- }
- else {
- p->play_buf_time=(int)((play_buf_time_finish.tv_sec - play_buf_time_start.tv_sec)*100)+(int)((play_buf_time_finish.tv_usec-play_buf_time_start.tv_usec)/1000);
- }
- /* ast_log(LOG_DEBUG, "%s: vpb_write: Wrote data [%d](%d=>%s) to play_buf in [%d]ms..\n", p->dev,frame->datalen,fmt,ast2vpbformatname(frame->subclass),p->play_buf_time); */
+ p->play_buf_time = ast_tvdiff_ms(ast_tvnow(), play_buf_time_start);
}
else {
p->chuck_count++;
me->play_dtmf[0] = '\0';
me->faxhandled =0;
- me->lastgrunt = get_time_in_ms(); /* Assume at least one grunt tone seen now. */
+ me->lastgrunt = ast_tvnow(); /* Assume at least one grunt tone seen now. */
ast_mutex_lock(&usecnt_lock);
usecnt++;
p->dialing = 1;
zt_ring_phone(p);
} else if (p->subs[SUB_THREEWAY].owner) {
- struct timeval tv;
unsigned int mssinceflash;
/* Here we have to retain the lock on both the main channel, the 3-way channel, and
the private structure -- not especially easy or clean */
ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
return NULL;
}
- gettimeofday(&tv, NULL);
- mssinceflash = (tv.tv_sec - p->flashtime.tv_sec) * 1000 + (tv.tv_usec - p->flashtime.tv_usec) / 1000;
+ mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash);
if (mssinceflash < MIN_MS_SINCE_FLASH) {
/* It hasn't been long enough since the last flashook. This is probably a bounce on
(p->polarityonanswerdelay > 0) &&
(p->polarity == POLARITY_REV) &&
(ast->_state == AST_STATE_UP)) {
- struct timeval tv;
- gettimeofday(&tv, NULL);
- if((((tv.tv_sec - p->polaritydelaytv.tv_sec) * 1000) + ((tv.tv_usec - p->polaritydelaytv.tv_usec)/1000)) > p->polarityonanswerdelay) {
+ if(ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
ast_log(LOG_DEBUG, "Hangup due to Reverse Polarity on channel %d\n", p->channel);
ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
p->polarity = POLARITY_IDLE;
p->subs[index].f.mallocd = 0;
p->subs[index].f.offset = 0;
p->subs[index].f.subclass = 0;
- p->subs[index].f.delivery.tv_sec = 0;
- p->subs[index].f.delivery.tv_usec = 0;
+ p->subs[index].f.delivery = ast_tv(0,0);
p->subs[index].f.src = "zt_exception";
p->subs[index].f.data = NULL;
p->subs[index].f.mallocd = 0;
p->subs[index].f.offset = 0;
p->subs[index].f.subclass = 0;
- p->subs[index].f.delivery.tv_sec = 0;
- p->subs[index].f.delivery.tv_usec = 0;
+ p->subs[index].f.delivery = ast_tv(0,0);
p->subs[index].f.src = "zt_read";
p->subs[index].f.data = NULL;
#if 0
printf("nextidle: %d, haveidles: %d, minunsed: %d\n",
nextidle, haveidles, minunused);
- gettimeofday(&tv, NULL);
printf("nextidle: %d, haveidles: %d, ms: %ld, minunsed: %d\n",
- nextidle, haveidles, (tv.tv_sec - lastidle.tv_sec) * 1000 +
- (tv.tv_usec - lastidle.tv_usec) / 1000, minunused);
+ nextidle, haveidles, ast_tvdiff_ms(ast_tvnow(), lastidle), minunused);
#endif
if (nextidle > -1) {
- gettimeofday(&tv, NULL);
- if (((tv.tv_sec - lastidle.tv_sec) * 1000 +
- (tv.tv_usec - lastidle.tv_usec) / 1000) > 1000) {
+ if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) {
/* Don't create a new idle call more than once per second */
snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial);
idle = zt_request("Zap", AST_FORMAT_ULAW, idlen, &cause);
}
}
/* Start with reasonable max */
- lowest.tv_sec = 60;
- lowest.tv_usec = 0;
+ lowest = ast_tv(60, 0);
for (i=0; i<NUM_DCHANS; i++) {
/* Find lowest available d-channel */
if (!pri->dchannels[i])
break;
if ((next = pri_schedule_next(pri->dchans[i]))) {
/* We need relative time here */
- gettimeofday(&tv, NULL);
- tv.tv_sec = next->tv_sec - tv.tv_sec;
- tv.tv_usec = next->tv_usec - tv.tv_usec;
- if (tv.tv_usec < 0) {
- tv.tv_usec += 1000000;
- tv.tv_sec -= 1;
- }
+ tv = ast_tvsub(*next, ast_tvnow());
if (tv.tv_sec < 0) {
- tv.tv_sec = 0;
- tv.tv_usec = 0;
+ tv = ast_tv(0,0);
}
if (doidling || pri->resetting) {
if (tv.tv_sec > 1) {
- tv.tv_sec = 1;
- tv.tv_usec = 0;
+ tv = ast_tv(1, 0);
}
} else {
if (tv.tv_sec > 60) {
- tv.tv_sec = 60;
- tv.tv_usec = 0;
+ tv = ast_tv(60, 0);
}
}
} else if (doidling || pri->resetting) {
/* Make sure we stop at least once per second if we're
monitoring idle channels */
- tv.tv_sec = 1;
- tv.tv_usec = 0;
+ tv = ast_tv(1,0);
} else {
/* Don't poll for more than 60 seconds */
- tv.tv_sec = 60;
- tv.tv_usec = 0;
+ tv = ast_tv(60, 0);
}
- if (!i || (tv.tv_sec < lowest.tv_sec) || ((tv.tv_sec == lowest.tv_sec) && (tv.tv_usec < lowest.tv_usec))) {
- lowest.tv_sec = tv.tv_sec;
- lowest.tv_usec = tv.tv_usec;
+ if (!i || ast_tvcmp(tv, lowest) < 0) {
+ lowest = tv;
}
}
ast_mutex_unlock(&pri->lock);
if (argc != 3)
return RESULT_SHOWUSAGE;
- gettimeofday(&now, NULL);
+ now = ast_tvnow();
c = ast_get_channel_by_name_locked(argv[2]);
if (!c) {
ast_cli(fd, "%s is not a known channel\n", argv[2]);
else
memcpy(s->data + s->len, f->data, f->datalen);
/* If either side is empty, reset the delivery time */
- if (!s->len || (!f->delivery.tv_sec && !f->delivery.tv_usec) ||
- (!s->delivery.tv_sec && !s->delivery.tv_usec))
+ if (!s->len || ast_tvzero(f->delivery) || ast_tvzero(s->delivery)) /* XXX really ? */
s->delivery = f->delivery;
s->len += f->datalen;
return 0;
s->f.offset = AST_FRIENDLY_OFFSET;
s->f.datalen = len;
/* Samples will be improper given VAD, but with VAD the concept really doesn't even exist */
- s->f.samples = len * s->samplesperbyte;
+ s->f.samples = len * s->samplesperbyte; /* XXX rounding */
s->f.delivery = s->delivery;
/* Fill Data */
memcpy(s->f.data, s->data, len);
/* In principle this should all be fine because if we are sending
G.729 VAD, the next timestamp will take over anyawy */
memmove(s->data, s->data + len, s->len);
- if (s->delivery.tv_sec || s->delivery.tv_usec) {
+ if (!ast_tvzero(s->delivery)) {
/* If we have delivery time, increment it, otherwise, leave it at 0 */
- s->delivery.tv_sec += (len * s->samplesperbyte) / 8000.0;
- s->delivery.tv_usec += (((int)(len * s->samplesperbyte)) % 8000) * 125;
- if (s->delivery.tv_usec > 1000000) {
- s->delivery.tv_usec -= 1000000;
- s->delivery.tv_sec += 1;
- }
+ s->delivery = ast_tvadd(s->delivery, ast_samp2tv(s->f.samples, 8000));
}
}
/* Return frame */
{
char *format, *epoch, *timezone;
long epochi;
- struct timeval tv;
struct tm time;
if (data) {
timezone = strsep(&format, "|");
if (epoch && !ast_strlen_zero(epoch) && sscanf(epoch, "%ld", &epochi) == 1) {
- } else if (!gettimeofday(&tv, NULL)) {
- epochi = tv.tv_sec;
} else {
- ast_log(LOG_ERROR, "Cannot gettimeofday() ?!!\n");
- return "";
+ struct timeval tv = ast_tvnow();
+ epochi = tv.tv_sec;
}
ast_localtime(&epochi, &time, timezone);
* \param con Context to dump
* Debugging: Dump the contents of the scheduler to stderr
*/
-extern void ast_sched_dump(struct sched_context *con);
+extern void ast_sched_dump(const struct sched_context *con);
/*!Returns the number of seconds before an event takes place */
/*!
* \return the difference in milliseconds
*/
AST_INLINE_API(
-int ast_tvdiff_ms(const struct timeval *end, const struct timeval *start),
+int ast_tvdiff_ms(struct timeval end, struct timeval start),
{
- return ((end->tv_sec - start->tv_sec) * 1000) + ((end->tv_usec - start->tv_usec) / 1000);
+ return ((end.tv_sec - start.tv_sec) * 1000) + ((end.tv_usec - start.tv_usec) / 1000);
+}
+)
+
+/*!
+ * \brief Returns true if the argument is 0,0
+ */
+AST_INLINE_API(
+int ast_tvzero(const struct timeval t),
+{
+ return (t.tv_sec == 0 && t.tv_usec == 0);
+}
+)
+
+/*!
+ * \brief Compres two \c struct \c timeval instances returning
+ * -1, 0, 1 if the first arg is smaller, equal or greater to the second.
+ */
+AST_INLINE_API(
+int ast_tvcmp(struct timeval _a, struct timeval _b),
+{
+ if (_a.tv_sec < _b.tv_sec)
+ return -1;
+ if (_a.tv_sec > _b.tv_sec)
+ return 1;
+ /* now seconds are equal */
+ if (_a.tv_usec < _b.tv_usec)
+ return -1;
+ if (_a.tv_usec > _b.tv_usec)
+ return 1;
+ return 0;
+}
+)
+
+/*!
+ * \brief Returns true if the two \c struct \c timeval arguments are equal.
+ */
+AST_INLINE_API(
+int ast_tveq(struct timeval _a, struct timeval _b),
+{
+ return (_a.tv_sec == _b.tv_sec && _a.tv_usec == _b.tv_usec);
+}
+)
+
+/*!
+ * \brief Returns current timeval. Meant to replace calls to gettimeofday().
+ */
+AST_INLINE_API(
+struct timeval ast_tvnow(void),
+{
+ struct timeval t;
+ gettimeofday(&t, NULL);
+ return t;
+}
+)
+
+/*!
+ * \brief Returns the sum of two timevals a + b
+ */
+struct timeval ast_tvadd(struct timeval a, struct timeval b);
+
+/*!
+ * \brief Returns the difference of two timevals a - b
+ */
+struct timeval ast_tvsub(struct timeval a, struct timeval b);
+
+/*!
+ * \brief Returns a timeval from sec, usec
+ */
+#if 0
+AST_INLINE_API(
+struct timeval ast_tv(int sec, int usec),
+{
+ struct timeval t = { sec, usec};
+ return t;
+}
+)
+#endif
+AST_INLINE_API(
+struct timeval ast_tv(int sec, int usec),
+{
+ struct timeval t;
+ t.tv_sec = sec;
+ t.tv_usec = usec;
+ return t;
+}
+)
+
+/*!
+ * \brief Returns a timeval corresponding to the duration of n samples at rate r.
+ * Useful to convert samples to timevals, or even milliseconds to timevals
+ * in the form ast_samp2tv(milliseconds, 1000)
+ */
+AST_INLINE_API(
+struct timeval ast_samp2tv(long _nsamp, long _rate),
+{
+ return ast_tv(_nsamp / _rate, (_nsamp % _rate) * (1000000 / _rate));
}
)
char idText[256] = "";
struct ast_channel *c;
char bridge[256];
- struct timeval now;
+ struct timeval now = ast_tvnow();
long elapsed_seconds=0;
int all = !name || ast_strlen_zero(name); /* set if we want all channels */
- gettimeofday(&now, NULL);
astman_send_ack(s, m, "Channel status will follow");
if (id && !ast_strlen_zero(id))
snprintf(idText,256,"ActionID: %s\r\n",id);
return NULL;
}
-static inline int calc_ms(struct timeval *start)
-{
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return ((tv.tv_sec - start->tv_sec) * 1000 + (tv.tv_usec - start->tv_usec) / 1000);
-}
-
static int dundi_query_eid_internal(struct dundi_entity_info *dei, const char *dcontext, dundi_eid *eid, struct dundi_hint_metadata *hmd, int ttl, int blockempty, dundi_eid *avoid[]);
static void *dundi_query_thread(void *data)
*context = '\0';
context++;
}
- gettimeofday(&start, NULL);
+ start = ast_tvnow();
res = dundi_lookup(dr, MAX_RESULTS, NULL, context, tmp, bypass);
if (res < 0)
ast_cli(fd, "%3d. %5d %s/%s (%s)\n", x + 1, dr[x].weight, dr[x].tech, dr[x].dest, dundi_flags2str(fs, sizeof(fs), dr[x].flags));
ast_cli(fd, " from %s, expires in %d s\n", dr[x].eid_str, dr[x].expiration);
}
- ast_cli(fd, "DUNDi lookup completed in %d ms\n", calc_ms(&start));
+ ast_cli(fd, "DUNDi lookup completed in %d ms\n", ast_tvdiff_ms(ast_tvnow(), start));
return RESULT_SUCCESS;
}
*context = '\0';
context++;
}
- gettimeofday(&start, NULL);
+ start = ast_tvnow();
res = dundi_precache(context, tmp);
if (res < 0)
ast_cli(fd, "DUNDi precache returned error.\n");
else if (!res)
ast_cli(fd, "DUNDi precache returned no error.\n");
- ast_cli(fd, "DUNDi lookup completed in %d ms\n", calc_ms(&start));
+ ast_cli(fd, "DUNDi lookup completed in %d ms\n", ast_tvdiff_ms(ast_tvnow(), start));
return RESULT_SUCCESS;
}
if (trans) {
memset(trans, 0, sizeof(struct dundi_transaction));
if (global_storehistory) {
- gettimeofday(&trans->start, NULL);
+ trans->start = ast_tvnow();
ast_set_flag(trans, FLAG_STOREHIST);
}
trans->retranstimer = DUNDI_DEFAULT_RETRANS_TIMER;
{
struct dundi_transaction *cur, *prev;
struct dundi_peer *peer;
- struct timeval tv;
int ms;
int x;
int cnt;
ast_log(LOG_NOTICE, "Peer '%s' has become UNREACHABLE!\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));
peer->lastms = -1;
} else {
- gettimeofday(&tv, NULL);
- ms = (tv.tv_sec - peer->qualtx.tv_sec) * 1000 +
- (tv.tv_usec - peer->qualtx.tv_usec) / 1000;
+ ms = ast_tvdiff_ms(ast_tvnow(), peer->qualtx);
if (ms < 1)
ms = 1;
if (ms < peer->maxms) {
cnt++;
}
}
- peer->lookuptimes[0] = calc_ms(&trans->start);
+ peer->lookuptimes[0] = ast_tvdiff_ms(ast_tvnow(), trans->start);
peer->lookups[0] = malloc(strlen(trans->parent->number) + strlen(trans->parent->dcontext) + 2);
if (peer->lookups[0]) {
sprintf(peer->lookups[0], "%s@%s", trans->parent->number, trans->parent->dcontext);
/* Wait for the cache to populate */
ast_log(LOG_DEBUG, "Waiting for similar request for '%s@%s' for '%s'\n",
dr.number,dr.dcontext,dundi_eid_to_str(eid_str, sizeof(eid_str), &pending->root_eid));
- gettimeofday(&start, NULL);
- while(check_request(pending) && (calc_ms(&start) < ttlms) && (!chan || !chan->_softhangup)) {
+ start = ast_tvnow();
+ while(check_request(pending) && (ast_tvdiff_ms(ast_tvnow(), start) < ttlms) && (!chan || !chan->_softhangup)) {
/* XXX Would be nice to have a way to poll/select here XXX */
+ /* XXX this is a busy wait loop!!! */
usleep(1);
}
/* Continue on as normal, our cache should kick in */
/* Actually perform transactions */
discover_transactions(&dr);
/* Wait for transaction to come back */
- gettimeofday(&start, NULL);
- while(dr.trans && (calc_ms(&start) < ttlms) && (!chan || !chan->_softhangup)) {
+ start = ast_tvnow();
+ while(dr.trans && (ast_tvdiff_ms(ast_tvnow(), start) < ttlms) && (!chan || !chan->_softhangup)) {
ms = 100;
ast_waitfor_n_fd(dr.pfds, 1, &ms, NULL);
}
else
ast_log(LOG_NOTICE, "Weird, expiration = %d, but need to precache for %s@%s?!\n", dr.expiration, dr.number, dr.dcontext);
}
- gettimeofday(&start, NULL);
- while(dr.trans && (calc_ms(&start) < ttlms)) {
+ start = ast_tvnow();
+ while(dr.trans && (ast_tvdiff_ms(ast_tvnow(), start) < ttlms)) {
if (dr.pfds[0] > -1) {
ms = 100;
ast_waitfor_n_fd(dr.pfds, 1, &ms, NULL);
/* Actually perform transactions */
query_transactions(&dr);
/* Wait for transaction to come back */
- gettimeofday(&start, NULL);
- while(dr.trans && (calc_ms(&start) < ttlms))
+ start = ast_tvnow();
+ while(dr.trans && (ast_tvdiff_ms(ast_tvnow(), start) < ttlms))
usleep(1);
res = dr.respcount;
return res;
if (!schedonly)
peer->qualtrans = create_transaction(peer);
if (peer->qualtrans) {
- gettimeofday(&peer->qualtx, NULL);
+ peer->qualtx = ast_tvnow();
ast_set_flag(peer->qualtrans, FLAG_ISQUAL);
dundi_send(peer->qualtrans, DUNDI_COMMAND_NULL, 0, 1, NULL);
}
if (replacelast)
gtk_clist_remove(GTK_CLIST(verb), GTK_CLIST(verb)->rows - 1);
gtk_clist_append(GTK_CLIST(verb), s2);
- if (last.tv_sec || last.tv_usec) {
+ if (!ast_tvzero(last)) {
gdk_threads_leave();
gettimeofday(&tv, NULL);
if (cleanupid > -1)
gtk_timeout_remove(cleanupid);
- ms = (tv.tv_sec - last.tv_sec) * 1000 + (tv.tv_usec - last.tv_usec) / 1000;
+ ms = ast_tvdiff_ms(tv, last);
if (ms < 100) {
/* We just got a message within 100ms, so just schedule an update
in the near future */
{
struct ast_filestream *fs;
struct ast_frame *f;
- struct timeval tv, start;
+ struct timeval start;
long sample_offset = 0;
int res = 0;
int ms;
if (!res)
res = ast_waitstream(chan, argv[4]);
- if (!res) {
+ if (res) {
+ fdprintf(agi->fd, "200 result=%d (randomerror) endpos=%ld\n", res, sample_offset);
+ } else {
fs = ast_writefile(argv[2], argv[3], NULL, O_CREAT | O_WRONLY | (sample_offset ? O_APPEND : 0), 0, 0644);
if (!fs) {
res = -1;
ast_seekstream(fs, sample_offset, SEEK_SET);
ast_truncstream(fs);
- gettimeofday(&start, NULL);
- gettimeofday(&tv, NULL);
- while ((ms < 0) || (((tv.tv_sec - start.tv_sec) * 1000 + (tv.tv_usec - start.tv_usec)/1000) < ms)) {
+ start = ast_tvnow();
+ while ((ms < 0) || ast_tvdiff_ms(ast_tvnow(), start) < ms) {
res = ast_waitfor(chan, -1);
if (res < 0) {
ast_closestream(fs);
break;
}
ast_frfree(f);
- gettimeofday(&tv, NULL);
if (gotsilence)
break;
}
}
fdprintf(agi->fd, "200 result=%d (timeout) endpos=%ld\n", res, sample_offset);
ast_closestream(fs);
- } else
- fdprintf(agi->fd, "200 result=%d (randomerror) endpos=%ld\n", res, sample_offset);
+ }
if (silence > 0) {
res = ast_set_read_format(chan, rfmt);
ast_indicate(pu->chan, AST_CONTROL_HOLD);
ast_moh_start(pu->chan, NULL);
}
- gettimeofday(&pu->start, NULL);
+ pu->start = ast_tvnow();
pu->parkingnum = x;
if (timeout > 0)
pu->parkingtime = timeout;
ast_set_callerid(chan, cid_num, cid_name, cid_num);
if (!ast_call(chan, data, timeout)) {
- struct timeval started, ended;
+ struct timeval started;
int x, len = 0;
char *disconnect_code = NULL, *dialed_code = NULL;
break;
}
x = 0;
- gettimeofday(&started, NULL);
+ started = ast_tvnow();
to = timeout;
while (!ast_check_hangup(caller) && timeout && (chan->_state != AST_STATE_UP)) {
monitor_chans[0] = caller;
active_channel = ast_waitfor_n(monitor_chans, 2, &to);
/* see if the timeout has been violated */
- gettimeofday(&ended,NULL);
- if(ast_tvdiff_ms(&ended, &started) > timeout) {
+ if(ast_tvdiff_ms(ast_tvnow(), started) > timeout) {
state = AST_CONTROL_UNHOLD;
ast_log(LOG_NOTICE, "We exceeded our AT-timeout\n");
break; /*doh! timeout*/
int hasfeatures=0;
int hadfeatures=0;
struct ast_option_header *aoh;
- struct timeval start, end;
+ struct timeval start;
struct ast_bridge_config backup_config;
int allowdisconnect_in,allowdisconnect_out,allowredirect_in,allowredirect_out;
char *monitor_exec;
}
for (;;) {
if (config->timelimit)
- gettimeofday(&start, NULL);
+ start = ast_tvnow();
res = ast_channel_bridge(chan,peer,config,&f, &who);
if (config->timelimit) {
/* Update time limit for next pass */
- gettimeofday(&end, NULL);
- diff = (end.tv_sec - start.tv_sec) * 1000;
- diff += (end.tv_usec - start.tv_usec) / 1000;
+ diff = ast_tvdiff_ms(ast_tvnow(), start);
config->timelimit -= diff;
if (hasfeatures) {
/* Running on backup config, meaning a feature might be being
pu = pu->next;
continue;
}
- gettimeofday(&tv, NULL);
- tms = (tv.tv_sec - pu->start.tv_sec) * 1000 + (tv.tv_usec - pu->start.tv_usec) / 1000;
+ tms = ast_tvdiff_ms(ast_tvnow(), pu->start);
if (tms > pu->parkingtime) {
/* Stop music on hold */
ast_moh_stop(pu->chan);
ast_mutex_unlock(&parking_lock);
rfds = nrfds;
efds = nefds;
- tv.tv_sec = ms / 1000;
- tv.tv_usec = (ms % 1000) * 1000;
+ tv = ast_samp2tv(ms, 1000);
/* Wait for something to happen */
ast_select(max + 1, &rfds, NULL, &efds, (ms > -1) ? &tv : NULL);
pthread_testcancel();
char buf[8192];
short sbuf[8192];
int res, res2;
- struct timeval tv;
- struct timeval tv_tmp;
- long error_sec, error_usec;
- long delay;
+ struct timeval tv, tv_tmp;
- tv_tmp.tv_sec = 0;
- tv_tmp.tv_usec = 0;
tv.tv_sec = 0;
tv.tv_usec = 0;
- error_sec = 0;
- error_usec = 0;
for(;/* ever */;) {
/* Spawn mp3 player if it's not there */
if (class->srcfd < 0) {
/* Pause some amount of time */
res = read(class->pseudofd, buf, sizeof(buf));
} else {
+ long delta;
/* Reliable sleep */
- if (gettimeofday(&tv_tmp, NULL) < 0) {
- ast_log(LOG_NOTICE, "gettimeofday() failed!\n");
- return NULL;
- }
- if (((unsigned long)(tv.tv_sec) > 0)&&((unsigned long)(tv.tv_usec) > 0)) {
- if ((unsigned long)(tv_tmp.tv_usec) < (unsigned long)(tv.tv_usec)) {
- tv_tmp.tv_usec += 1000000;
- tv_tmp.tv_sec -= 1;
- }
- error_sec = (unsigned long)(tv_tmp.tv_sec) - (unsigned long)(tv.tv_sec);
- error_usec = (unsigned long)(tv_tmp.tv_usec) - (unsigned long)(tv.tv_usec);
- } else {
- error_sec = 0;
- error_usec = 0;
- }
- if (error_sec * 1000 + error_usec / 1000 < MOH_MS_INTERVAL) {
- tv.tv_sec = tv_tmp.tv_sec + (MOH_MS_INTERVAL/1000 - error_sec);
- tv.tv_usec = tv_tmp.tv_usec + ((MOH_MS_INTERVAL % 1000) * 1000 - error_usec);
- delay = (MOH_MS_INTERVAL/1000 - error_sec) * 1000 +
- ((MOH_MS_INTERVAL % 1000) * 1000 - error_usec) / 1000;
+ tv_tmp = ast_tvnow();
+ if (ast_tvzero(tv))
+ tv = tv_tmp;
+ delta = ast_tvdiff_ms(tv_tmp, tv);
+ if (delta < MOH_MS_INTERVAL) { /* too early */
+ tv = ast_tvadd(tv, ast_samp2tv(MOH_MS_INTERVAL, 1000)); /* next deadline */
+ usleep(1000 * (MOH_MS_INTERVAL - delta));
} else {
ast_log(LOG_NOTICE, "Request to schedule in the past?!?!\n");
- tv.tv_sec = tv_tmp.tv_sec;
- tv.tv_usec = tv_tmp.tv_usec;
- delay = 0;
- }
- if (tv.tv_usec > 1000000) {
- tv.tv_sec++;
- tv.tv_usec-= 1000000;
+ tv = tv_tmp;
}
- if (delay > 0)
- usleep(delay * 1000);
- res = 800; /* 800 samples */
+ res = 8 * MOH_MS_INTERVAL; /* 8 samples per millisecond */
}
if (!class->members)
continue;
#include "asterisk/utils.h"
#include "asterisk/cli.h"
#include "asterisk/unaligned.h"
+#include "asterisk/utils.h"
#define MAX_TIMESTAMP_SKEW 640
static struct ast_frame *send_dtmf(struct ast_rtp *rtp)
{
- struct timeval tv;
static struct ast_frame null_frame = { AST_FRAME_NULL, };
char iabuf[INET_ADDRSTRLEN];
- gettimeofday(&tv, NULL);
- if ((tv.tv_sec < rtp->dtmfmute.tv_sec) ||
- ((tv.tv_sec == rtp->dtmfmute.tv_sec) && (tv.tv_usec < rtp->dtmfmute.tv_usec))) {
+
+ if (ast_tvcmp(ast_tvnow(), rtp->dtmfmute) < 0) {
if (option_debug)
ast_log(LOG_DEBUG, "Ignore potential DTMF echo from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr));
rtp->resp = 0;
static void calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int timestamp, int mark)
{
- if ((!rtp->rxcore.tv_sec && !rtp->rxcore.tv_usec) || mark) {
- gettimeofday(&rtp->rxcore, NULL);
- rtp->rxcore.tv_sec -= timestamp / 8000;
- rtp->rxcore.tv_usec -= (timestamp % 8000) * 125;
+ struct timeval ts = ast_samp2tv( timestamp, 8000);
+ if (ast_tvzero(rtp->rxcore) || mark) {
+ rtp->rxcore = ast_tvsub(ast_tvnow(), ts);
/* Round to 20ms for nice, pretty timestamps */
rtp->rxcore.tv_usec -= rtp->rxcore.tv_usec % 20000;
- if (rtp->rxcore.tv_usec < 0) {
- /* Adjust appropriately if necessary */
- rtp->rxcore.tv_usec += 1000000;
- rtp->rxcore.tv_sec -= 1;
- }
- }
- tv->tv_sec = rtp->rxcore.tv_sec + timestamp / 8000;
- tv->tv_usec = rtp->rxcore.tv_usec + (timestamp % 8000) * 125;
- if (tv->tv_usec >= 1000000) {
- tv->tv_usec -= 1000000;
- tv->tv_sec += 1;
}
+ *tv = ast_tvadd(rtp->rxcore, ts);
}
struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
{
- struct timeval now;
- unsigned int ms;
- if (!rtp->txcore.tv_sec && !rtp->txcore.tv_usec) {
- gettimeofday(&rtp->txcore, NULL);
+ struct timeval t;
+ long ms;
+ if (ast_tvzero(rtp->txcore)) {
+ rtp->txcore = ast_tvnow();
/* Round to 20ms for nice, pretty timestamps */
rtp->txcore.tv_usec -= rtp->txcore.tv_usec % 20000;
}
- if (delivery && (delivery->tv_sec || delivery->tv_usec)) {
- /* Use previous txcore */
- ms = (delivery->tv_sec - rtp->txcore.tv_sec) * 1000;
- ms += (1000000 + delivery->tv_usec - rtp->txcore.tv_usec) / 1000 - 1000;
- rtp->txcore.tv_sec = delivery->tv_sec;
- rtp->txcore.tv_usec = delivery->tv_usec;
- } else {
- gettimeofday(&now, NULL);
- ms = (now.tv_sec - rtp->txcore.tv_sec) * 1000;
- ms += (1000000 + now.tv_usec - rtp->txcore.tv_usec) / 1000 - 1000;
- /* Use what we just got for next time */
- rtp->txcore.tv_sec = now.tv_sec;
- rtp->txcore.tv_usec = now.tv_usec;
- }
- return ms;
+ /* Use previous txcore if available */
+ t = (delivery && !ast_tvzero(*delivery)) ? *delivery : ast_tvnow();
+ ms = ast_tvdiff_ms(t, rtp->txcore);
+ /* Use what we just got for next time */
+ rtp->txcore = t;
+ return (unsigned int) ms;
}
int ast_rtp_senddigit(struct ast_rtp *rtp, char digit)
if (!rtp->them.sin_addr.s_addr)
return 0;
- gettimeofday(&rtp->dtmfmute, NULL);
- rtp->dtmfmute.tv_usec += (500 * 1000);
- if (rtp->dtmfmute.tv_usec > 1000000) {
- rtp->dtmfmute.tv_usec -= 1000000;
- rtp->dtmfmute.tv_sec += 1;
- }
+ rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
/* Get a pointer to the header */
rtpheader = (unsigned int *)data;
if (!rtp->them.sin_addr.s_addr)
return 0;
- gettimeofday(&rtp->dtmfmute, NULL);
- rtp->dtmfmute.tv_usec += (500 * 1000);
- if (rtp->dtmfmute.tv_usec > 1000000) {
- rtp->dtmfmute.tv_usec -= 1000000;
- rtp->dtmfmute.tv_sec += 1;
- }
-
+ rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
+
/* Get a pointer to the header */
rtpheader = (unsigned int *)data;
rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno++));
/* Re-calculate last TS */
rtp->lastts = rtp->lastts + ms * 8;
- if (!f->delivery.tv_sec && !f->delivery.tv_usec) {
+ if (ast_tvzero(f->delivery)) {
/* If this isn't an absolute delivery time, Check if it is close to our prediction,
and if so, go with our prediction */
if (abs(rtp->lastts - pred) < MAX_TIMESTAMP_SKEW)
/* Re-calculate last TS */
rtp->lastts = rtp->lastts + ms * 90;
/* If it's close to our prediction, go for it */
- if (!f->delivery.tv_sec && !f->delivery.tv_usec) {
+ if (ast_tvzero(f->delivery)) {
if (abs(rtp->lastts - pred) < 7200) {
rtp->lastts = pred;
rtp->lastovidtimestamp += f->samples;
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/lock.h"
+#include "asterisk/utils.h"
/* Determine if a is sooner than b */
#define SOONER(a,b) (((b).tv_sec > (a).tv_sec) || \
* Return the number of milliseconds
* until the next scheduled event
*/
- struct timeval tv;
int ms;
DEBUG(ast_log(LOG_DEBUG, "ast_sched_wait()\n"));
ast_mutex_lock(&con->lock);
if (!con->schedq) {
ms = -1;
- } else if (gettimeofday(&tv, NULL) < 0) {
- /* This should never happen */
- ms = 0;
} else {
- ms = (con->schedq->when.tv_sec - tv.tv_sec) * 1000;
- ms += (con->schedq->when.tv_usec - tv.tv_usec) / 1000;
+ ms = ast_tvdiff_ms(con->schedq->when, ast_tvnow());
if (ms < 0)
ms = 0;
}
con->schedcnt++;
}
-static inline int sched_settime(struct timeval *tv, int when)
+/*
+ * given the last event *tv and the offset in milliseconds 'when',
+ * computes the next value,
+ */
+static int sched_settime(struct timeval *tv, int when)
{
- struct timeval tv_tmp;
- long error_sec, error_usec;
+ struct timeval now = ast_tvnow();
- if (gettimeofday(&tv_tmp, NULL) < 0) {
- /* This shouldn't ever happen, but let's be sure */
- ast_log(LOG_NOTICE, "gettimeofday() failed!\n");
- return -1;
- }
/*ast_log(LOG_DEBUG, "TV -> %lu,%lu\n", tv->tv_sec, tv->tv_usec);*/
- if (((unsigned long)(tv->tv_sec) > 0)||((unsigned long)(tv->tv_usec) > 0)) {
- if ((unsigned long)(tv_tmp.tv_usec) < (unsigned long)(tv->tv_usec)) {
- tv_tmp.tv_usec += 1000000;
- tv_tmp.tv_sec -= 1;
- }
- error_sec = (unsigned long)(tv_tmp.tv_sec) - (unsigned long)(tv->tv_sec);
- error_usec = (unsigned long)(tv_tmp.tv_usec) - (unsigned long)(tv->tv_usec);
- } else {
- /*ast_log(LOG_DEBUG, "Initializing error\n");*/
- error_sec = 0;
- error_usec = 0;
- }
- /*ast_log(LOG_DEBUG, "ERROR -> %lu,%lu\n", error_sec, error_usec);*/
- if (error_sec * 1000 + error_usec / 1000 < when) {
- tv->tv_sec = tv_tmp.tv_sec + (when/1000 - error_sec);
- tv->tv_usec = tv_tmp.tv_usec + ((when % 1000) * 1000 - error_usec);
- } else {
+ if (ast_tvzero(*tv)) /* not supplied, default to now */
+ *tv = now;
+ *tv = ast_tvadd(*tv, ast_samp2tv(when, 1000));
+ if (ast_tvcmp(*tv, now) < 0) {
ast_log(LOG_DEBUG, "Request to schedule in the past?!?!\n");
- tv->tv_sec = tv_tmp.tv_sec;
- tv->tv_usec = tv_tmp.tv_usec;
- }
- if (tv->tv_usec > 1000000) {
- tv->tv_sec++;
- tv->tv_usec-= 1000000;
+ *tv = now;
}
return 0;
}
tmp->callback = callback;
tmp->data = data;
tmp->resched = when;
- tmp->when.tv_sec = 0;
- tmp->when.tv_usec = 0;
+ tmp->when = ast_tv(0, 0);
if (sched_settime(&tmp->when, when)) {
sched_release(con, tmp);
} else {
* stderr
*/
struct sched *q;
- struct timeval tv;
- time_t s, ms;
- gettimeofday(&tv, NULL);
+ struct timeval tv = ast_tvnow();
#ifdef SCHED_MAX_CACHE
ast_log(LOG_DEBUG, "Asterisk Schedule Dump (%d in Q, %d Total, %d Cache)\n", con->schedcnt, con->eventcnt - 1, con->schedccnt);
#else
ast_log(LOG_DEBUG, "=============================================================\n");
ast_log(LOG_DEBUG, "|ID Callback Data Time (sec:ms) |\n");
ast_log(LOG_DEBUG, "+-----+-----------------+-----------------+-----------------+\n");
- q = con->schedq;
- while(q) {
- s = q->when.tv_sec - tv.tv_sec;
- ms = q->when.tv_usec - tv.tv_usec;
- if (ms < 0) {
- ms += 1000000;
- s--;
- }
+ for (q = con->schedq; q; q = q->next) {
+ struct timeval delta = ast_tvsub(q->when, tv);
+
ast_log(LOG_DEBUG, "|%.4d | %-15p | %-15p | %.6ld : %.6ld |\n",
- q->id,
- q->callback,
- q->data,
- (long)s,
- (long)ms);
- q=q->next;
+ q->id,
+ q->callback,
+ q->data,
+ delta.tv_sec,
+ delta.tv_usec);
}
ast_log(LOG_DEBUG, "=============================================================\n");
for(;;) {
if (!con->schedq)
break;
- if (gettimeofday(&tv, NULL)) {
- /* This should never happen */
- ast_log(LOG_NOTICE, "gettimeofday() failed!\n");
- break;
- }
- /* We only care about millisecond accuracy anyway, so this will
- help us get more than one event at one time if they are very
- close together. */
- tv.tv_usec += 1000;
+
+ /* schedule all events which are going to expire within 1ms.
+ * We only care about millisecond accuracy anyway, so this will
+ * help us get more than one event at one time if they are very
+ * close together.
+ */
+ tv = ast_tvadd(ast_tvnow(), ast_tv(0, 1000));
if (SOONER(con->schedq->when, tv)) {
current = con->schedq;
con->schedq = con->schedq->next;
{
struct sched *s;
long secs;
- struct timeval now;
DEBUG(ast_log(LOG_DEBUG, "ast_sched_when()\n"));
ast_mutex_lock(&con->lock);
}
secs=-1;
if (s!=NULL) {
- if (gettimeofday(&now, NULL)) {
- ast_log(LOG_NOTICE, "gettimeofday() failed!\n");
- } else {
- secs=s->when.tv_sec-now.tv_sec;
- }
+ struct timeval now = ast_tvnow();
+ secs=s->when.tv_sec-now.tv_sec;
}
ast_mutex_unlock(&con->lock);
return secs;
if (tmp) {
tmp->next = NULL;
- tmp->nextin.tv_sec = 0;
- tmp->nextin.tv_usec = 0;
- tmp->nextout.tv_sec = 0;
- tmp->nextout.tv_usec = 0;
+ tmp->nextin = tmp->nextout = ast_tv( 0, 0 );
tmp->step = tr_matrix[source][dest].step;
tmp->state = tmp->step->newpvt();
if (!tmp->state) {
p = path;
/* Feed the first frame into the first translator */
p->step->framein(p->state, f);
- if (f->delivery.tv_sec || f->delivery.tv_usec) {
- if (path->nextin.tv_sec || path->nextin.tv_usec) {
+ if (!ast_tvzero(f->delivery)) {
+ if (!ast_tvzero(path->nextin)) {
/* Make sure this is in line with what we were expecting */
- if ((path->nextin.tv_sec != f->delivery.tv_sec) ||
- (path->nextin.tv_usec != f->delivery.tv_usec)) {
+ if (!ast_tveq(path->nextin, f->delivery)) {
/* The time has changed between what we expected and this
most recent time on the new packet. Adjust our output
time appropriately */
- long sdiff;
- long udiff;
- sdiff = f->delivery.tv_sec - path->nextin.tv_sec;
- udiff = f->delivery.tv_usec - path->nextin.tv_usec;
- path->nextin.tv_sec = f->delivery.tv_sec;
- path->nextin.tv_usec = f->delivery.tv_usec;
- path->nextout.tv_sec += sdiff;
- path->nextout.tv_usec += udiff;
- if (path->nextout.tv_usec < 0) {
- path->nextout.tv_usec += 1000000;
- path->nextout.tv_sec--;
- } else if (path->nextout.tv_usec >= 1000000) {
- path->nextout.tv_usec -= 1000000;
- path->nextout.tv_sec++;
- }
+ path->nextout = ast_tvadd(path->nextout,
+ ast_tvsub(f->delivery, path->nextin));
+ path->nextin = f->delivery;
}
} else {
/* This is our first pass. Make sure the timing looks good */
- path->nextin.tv_sec = f->delivery.tv_sec;
- path->nextin.tv_usec = f->delivery.tv_usec;
- path->nextout.tv_sec = f->delivery.tv_sec;
- path->nextout.tv_usec = f->delivery.tv_usec;
+ path->nextin = f->delivery;
+ path->nextout = f->delivery;
}
/* Predict next incoming sample */
- path->nextin.tv_sec += (f->samples / 8000);
- path->nextin.tv_usec += ((f->samples % 8000) * 125);
- if (path->nextin.tv_usec >= 1000000) {
- path->nextin.tv_usec -= 1000000;
- path->nextin.tv_sec++;
- }
+ path->nextin = ast_tvadd(path->nextin, ast_samp2tv(f->samples, 8000));
}
- delivery.tv_sec = f->delivery.tv_sec;
- delivery.tv_usec = f->delivery.tv_usec;
+ delivery = f->delivery;
if (consume)
ast_frfree(f);
while(p) {
if (p->next)
p->next->step->framein(p->next->state, out);
else {
- if (delivery.tv_sec || delivery.tv_usec) {
+ if (!ast_tvzero(delivery)) {
/* Use next predicted outgoing timestamp */
- out->delivery.tv_sec = path->nextout.tv_sec;
- out->delivery.tv_usec = path->nextout.tv_usec;
+ out->delivery = path->nextout;
/* Predict next outgoing timestamp from samples in this
frame. */
- path->nextout.tv_sec += (out->samples / 8000);
- path->nextout.tv_usec += ((out->samples % 8000) * 125);
- if (path->nextout.tv_usec >= 1000000) {
- path->nextout.tv_sec++;
- path->nextout.tv_usec -= 1000000;
- }
+ path->nextout = ast_tvadd(path->nextout, ast_samp2tv( out->samples, 8000));
} else {
- out->delivery.tv_sec = 0;
- out->delivery.tv_usec = 0;
+ out->delivery = ast_tv(0, 0);
}
return out;
}
int sofar=0;
struct ast_translator_pvt *pvt;
struct ast_frame *f, *out;
- struct timeval start, finish;
+ struct timeval start;
int cost;
if(!samples)
samples = 1;
t->cost = 99999;
return;
}
- gettimeofday(&start, NULL);
+ start = ast_tvnow();
/* Call the encoder until we've processed one second of time */
while(sofar < samples * 8000) {
f = t->sample();
ast_frfree(out);
}
}
- gettimeofday(&finish, NULL);
+ cost = ast_tvdiff_ms(ast_tvnow(), start);
t->destroy(pvt);
- cost = (finish.tv_sec - start.tv_sec) * 1000 + (finish.tv_usec - start.tv_usec) / 1000;
t->cost = cost / samples;
if (!t->cost)
t->cost = 1;
return 0;
}
+#define ONE_MILLION 1000000
+/*
+ * put timeval in a valid range. usec is 0..999999
+ * negative values are not allowed and truncated.
+ */
+static struct timeval tvfix(struct timeval a)
+{
+ if (a.tv_usec >= ONE_MILLION) {
+ ast_log(LOG_ERROR, "warning too large timestamp %ld.%ld\n",
+ a.tv_sec, a.tv_usec);
+ a.tv_sec += a.tv_usec % ONE_MILLION;
+ a.tv_usec %= ONE_MILLION;
+ } else if (a.tv_usec < 0) {
+ ast_log(LOG_ERROR, "warning negative timestamp %ld.%ld\n",
+ a.tv_sec, a.tv_usec);
+ a.tv_usec = 0;
+ }
+ return a;
+}
+
+struct timeval ast_tvadd(struct timeval a, struct timeval b)
+{
+ /* consistency checks to guarantee usec in 0..999999 */
+ a = tvfix(a);
+ b = tvfix(b);
+ a.tv_sec += b.tv_sec;
+ a.tv_usec += b.tv_usec;
+ if (a.tv_usec >= ONE_MILLION) {
+ a.tv_sec++;
+ a.tv_usec -= ONE_MILLION;
+ }
+ return a;
+}
+
+struct timeval ast_tvsub(struct timeval a, struct timeval b)
+{
+ /* consistency checks to guarantee usec in 0..999999 */
+ a = tvfix(a);
+ b = tvfix(b);
+ a.tv_sec -= b.tv_sec;
+ a.tv_usec -= b.tv_usec;
+ if (a.tv_usec < 0) {
+ a.tv_sec-- ;
+ a.tv_usec += ONE_MILLION;
+ }
+ return a;
+}
+#undef ONE_MILLION
+
#ifndef HAVE_STRCASESTR
static char *upper(const char *orig, char *buf, int bufsize)
{