1 /** 2 * @file ntp.c NTP Routines 3 * 4 * Copyright (C) 2010 Creytiv.com 5 */ 6 #ifdef HAVE_SYS_TIME_H 7 #include <sys/time.h> 8 #else 9 #include <time.h> 10 #endif 11 #include <re_types.h> 12 #include <re_fmt.h> 13 #include <re_list.h> 14 #include <re_sa.h> 15 #include <re_rtp.h> 16 #include "rtcp.h" 17 18 19 /* 20 * Unix time: seconds relative to 0h January 1, 1970 21 * NTP time: seconds relative to 0h UTC on 1 January 1900 22 */ 23 24 25 /* Number of seconds from 1900 to 1970 */ 26 #define UNIX_NTP_OFFSET 0x83aa7e80 27 28 29 /** 30 * Convert from Unix time to NTP time 31 * 32 * @param ntp NTP time to convert to (output) 33 * @param tv Unix time to convert from (input) 34 */ unix2ntp(struct ntp_time * ntp,const struct timeval * tv)35void unix2ntp(struct ntp_time *ntp, const struct timeval *tv) 36 { 37 ntp->hi = (uint32_t)(tv->tv_sec + UNIX_NTP_OFFSET); 38 ntp->lo = (uint32_t)((double)tv->tv_usec*(double)(1LL<<32)*1.0e-6); 39 } 40 41 42 /** 43 * Convert from NTP time to Unix time 44 * 45 * @param tv Unix time to convert to (output) 46 * @param ntp NTP time to convert from (input) 47 */ ntp2unix(struct timeval * tv,const struct ntp_time * ntp)48void ntp2unix(struct timeval *tv, const struct ntp_time *ntp) 49 { 50 tv->tv_sec = ntp->hi - UNIX_NTP_OFFSET; 51 tv->tv_usec = (uint32_t)(1.0e6 * (double) ntp->lo / (1LL<<32)); 52 } 53 54 ntp_time_get(struct ntp_time * ntp)55int ntp_time_get(struct ntp_time *ntp) 56 { 57 struct timeval tv; 58 #ifdef WIN32 59 union { 60 long long ns100; 61 FILETIME ft; 62 } now; 63 64 GetSystemTimeAsFileTime(&now.ft); 65 tv.tv_usec = (long) ((now.ns100 / 10LL) % 1000000LL); 66 tv.tv_sec = (long) ((now.ns100 - 116444736000000000LL) / 10000000LL); 67 #else 68 if (gettimeofday(&tv, NULL) != 0) 69 return errno; 70 #endif 71 unix2ntp(ntp, &tv); 72 73 return 0; 74 } 75 76 77 /** 78 * Convert NTP time to middle 32-bits (compact representation) 79 * 80 * @param ntp NTP time 81 * 82 * @return NTP time in compact representation 83 */ ntp_compact(const struct ntp_time * ntp)84uint32_t ntp_compact(const struct ntp_time *ntp) 85 { 86 return ntp ? ((ntp->hi & 0xffff) << 16 | (ntp->lo >> 16)) : 0; 87 } 88 89 90 /** 91 * Convert NTP compact representation to microseconds 92 * 93 * @param ntpc NTP time in compact representation 94 * 95 * @return NTP time in microseconds 96 */ ntp_compact2us(uint32_t ntpc)97uint64_t ntp_compact2us(uint32_t ntpc) 98 { 99 const uint32_t hi = (ntpc >> 16) & 0xffff; 100 const uint32_t lo = (ntpc & 0xffff) << 16; 101 102 return (1000000ULL * hi) + ((1000000ULL * lo) >> 32); 103 } 104