static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, char *, int, int);
static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, char *, int);
-static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts);
+static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct timeval *tv);
static int send_ping(void *data)
{
iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
} else if (fr->af.subclass == IAX_COMMAND_LAGRP) {
/* This is a reply we've been given, actually measure the difference */
- ts = calc_timestamp(iaxs[fr->callno], 0);
+ ts = calc_timestamp(iaxs[fr->callno], 0, NULL);
iaxs[fr->callno]->lag = ts - fr->ts;
}
} else {
IAX thread, with iaxsl lock held. */
ms = calc_rxstamp(iaxs[fr->callno]) - fr->ts;
+ 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;
+ if (fr->af.delivery.tv_usec >= 1000000) {
+ fr->af.delivery.tv_usec -= 1000000;
+ fr->af.delivery.tv_sec += 1;
+ }
+
if (ms > 32767) {
/* What likely happened here is that our counter has circled but we haven't
gotten the update from the main packet. We'll just pretend that we did, and
return ms + ts;
}
-static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts)
+static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct timeval *delivery)
{
struct timeval tv;
unsigned int ms;
/* If the timestamp is specified, just send it as is */
if (ts)
return ts;
- gettimeofday(&tv, NULL);
- ms = (tv.tv_sec - p->offset.tv_sec) * 1000 + (tv.tv_usec - p->offset.tv_usec) / 1000;
+ if (delivery && (delivery->tv_sec || delivery->tv_usec)) {
+ ms = (delivery->tv_sec - p->offset.tv_sec) * 1000 + (delivery->tv_usec - p->offset.tv_usec) / 1000;
+ } else {
+ gettimeofday(&tv, NULL);
+ ms = (tv.tv_sec - p->offset.tv_sec) * 1000 + (tv.tv_usec - p->offset.tv_usec) / 1000;
+ }
/* We never send the same timestamp twice, so fudge a little if we must */
if (ms <= p->lastsent)
ms = p->lastsent + 1;
lastsent = pvt->lastsent;
/* Calculate actual timestamp */
- fts = calc_timestamp(pvt, ts);
+ fts = calc_timestamp(pvt, ts, &f->delivery);
if ((pvt->trunk || ((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)))
/* High two bits are the same on timestamp, or sending on a trunk */ &&
forward_command(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr.ts, NULL, 0, -1);
} else {
/* Calculate ping time */
- iaxs[fr.callno]->pingtime = calc_timestamp(iaxs[fr.callno], 0) - fr.ts;
+ iaxs[fr.callno]->pingtime = calc_timestamp(iaxs[fr.callno], 0, NULL) - fr.ts;
}
#else
/* Calculate ping time */
- iaxs[fr.callno]->pingtime = calc_timestamp(iaxs[fr.callno], 0) - fr.ts;
+ iaxs[fr.callno]->pingtime = calc_timestamp(iaxs[fr.callno], 0, NULL) - fr.ts;
#endif
if (iaxs[fr.callno]->peerpoke) {
peer = iaxs[fr.callno]->peerpoke;