From 1a77cd3c3629dc1008e550716f41c591656c9351 Mon Sep 17 00:00:00 2001 From: Patrik Flykt Date: Tue, 25 Sep 2012 13:28:02 +0300 Subject: ntp: Calculate transmit time from receive time and monotonic delta MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calculate transmit time used in NTP as the reception time minus the delta of the monotonic receive and transmit times. When calculated this way, it does not matter if the time happens to be set to something else between the sending and receiving of the NTP packet. On sending the added monotonic time and the previous transmit time are saved at the same point in time. On reception the monotonic time is evaluated after the packet has been received by ConnMan. This is in contrast to the actual reception wall clock time which is added by the kernel. The difference between the reception times on a normal system is about 100µs, which is neglible. --- src/ntp.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'src/ntp.c') diff --git a/src/ntp.c b/src/ntp.c index 2ef0cf2d..b588c99c 100644 --- a/src/ntp.c +++ b/src/ntp.c @@ -110,7 +110,7 @@ struct ntp_msg { #define NTP_PRECISION_NS -29 static guint channel_watch = 0; -static struct timeval transmit_timeval; +static struct timespec mtx_time; static int transmit_fd = 0; static char *timeserver = NULL; @@ -146,6 +146,7 @@ static void send_packet(int fd, const char *server) { struct ntp_msg msg; struct sockaddr_in addr; + struct timeval transmit_timeval; ssize_t len; /* @@ -166,6 +167,7 @@ static void send_packet(int fd, const char *server) addr.sin_addr.s_addr = inet_addr(server); gettimeofday(&transmit_timeval, NULL); + clock_gettime(CLOCK_MONOTONIC, &mtx_time); msg.xmttime.seconds = htonl(transmit_timeval.tv_sec + OFFSET_1900_1970); msg.xmttime.fraction = htonl(transmit_timeval.tv_usec * 1000); @@ -214,10 +216,11 @@ static void reset_timeout(void) retries = 0; } -static void decode_msg(void *base, size_t len, struct timeval *tv) +static void decode_msg(void *base, size_t len, struct timeval *tv, + struct timespec *mrx_time) { struct ntp_msg *msg = base; - double org, rec, xmt, dst; + double m_delta, org, rec, xmt, dst; double delay, offset; static guint transmit_delay; @@ -260,8 +263,10 @@ static void decode_msg(void *base, size_t len, struct timeval *tv) return; } - org = transmit_timeval.tv_sec + - (1.0e-6 * transmit_timeval.tv_usec) + OFFSET_1900_1970; + m_delta = mrx_time->tv_sec - mtx_time.tv_sec + + 1.0e-9 * (mrx_time->tv_nsec - mtx_time.tv_nsec); + + org = tv->tv_sec + (1.0e-6 * tv->tv_usec) - m_delta + OFFSET_1900_1970; rec = ntohl(msg->rectime.seconds) + ((double) ntohl(msg->rectime.fraction) / UINT_MAX); xmt = ntohl(msg->xmttime.seconds) + @@ -334,6 +339,7 @@ static gboolean received_data(GIOChannel *channel, GIOCondition condition, struct iovec iov; struct cmsghdr *cmsg; struct timeval *tv; + struct timespec mrx_time; char aux[128]; ssize_t len; int fd; @@ -360,6 +366,7 @@ static gboolean received_data(GIOChannel *channel, GIOCondition condition, return TRUE; tv = NULL; + clock_gettime(CLOCK_MONOTONIC, &mrx_time); for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level != SOL_SOCKET) @@ -372,7 +379,7 @@ static gboolean received_data(GIOChannel *channel, GIOCondition condition, } } - decode_msg(iov.iov_base, iov.iov_len, tv); + decode_msg(iov.iov_base, iov.iov_len, tv, &mrx_time); return TRUE; } -- cgit v1.2.3