util: add conversion between intervals and NTP 64-bit format

This will be needed to save PTP correction in NTP timestamp format.
This commit is contained in:
Miroslav Lichvar 2023-09-21 14:02:11 +02:00
parent e08a0ee668
commit bf616eafa1
3 changed files with 72 additions and 0 deletions

View file

@ -253,6 +253,47 @@ test_unit(void)
TEST_CHECK(UTI_IsEqualAnyNtp64(&ntp_ts, NULL, NULL, &ntp_ts)); TEST_CHECK(UTI_IsEqualAnyNtp64(&ntp_ts, NULL, NULL, &ntp_ts));
TEST_CHECK(!UTI_IsEqualAnyNtp64(&ntp_ts, &ntp_fuzz, &ntp_fuzz, &ntp_fuzz)); TEST_CHECK(!UTI_IsEqualAnyNtp64(&ntp_ts, &ntp_fuzz, &ntp_fuzz, &ntp_fuzz));
ntp_ts.hi = htonl(0);
ntp_ts.lo = htonl(0);
x = UTI_Ntp64ToDouble(&ntp_ts);
TEST_CHECK(fabs(x) < 1e-10);
UTI_DoubleToNtp64(x, &ntp_ts2);
TEST_CHECK(UTI_CompareNtp64(&ntp_ts, &ntp_ts2) == 0);
ntp_ts.hi = htonl(0);
ntp_ts.lo = htonl(0xffffffff);
x = UTI_Ntp64ToDouble(&ntp_ts);
TEST_CHECK(fabs(x - 1.0 + 0.23e-9) < 1e-10);
UTI_DoubleToNtp64(x, &ntp_ts2);
TEST_CHECK(fabs(UTI_DiffNtp64ToDouble(&ntp_ts, &ntp_ts2)) < 0.3e-9);
ntp_ts.hi = htonl(0xffffffff);
ntp_ts.lo = htonl(0xffffffff);
x = UTI_Ntp64ToDouble(&ntp_ts);
TEST_CHECK(fabs(x + 0.23e-9) < 1e-10);
UTI_DoubleToNtp64(x, &ntp_ts2);
TEST_CHECK(fabs(UTI_DiffNtp64ToDouble(&ntp_ts, &ntp_ts2)) < 0.3e-9);
ntp_ts.hi = htonl(0x80000000);
ntp_ts.lo = htonl(0);
x = UTI_Ntp64ToDouble(&ntp_ts);
TEST_CHECK(fabs(x + 0x80000000) < 1e-10);
UTI_DoubleToNtp64(x, &ntp_ts2);
TEST_CHECK(fabs(UTI_DiffNtp64ToDouble(&ntp_ts, &ntp_ts2)) < 0.3e-9);
ntp_ts.hi = htonl(0x7fffffff);
ntp_ts.lo = htonl(0xffffffff);
x = UTI_Ntp64ToDouble(&ntp_ts);
TEST_CHECK(fabs(x - 2147483648) < 1.0);
ntp_ts.lo = htonl(0);
ntp_ts.hi = htonl(0x7fffffff);
UTI_DoubleToNtp64(0x7fffffff + 0.1, &ntp_ts2);
TEST_CHECK(UTI_CompareNtp64(&ntp_ts, &ntp_ts2) == 0);
ntp_ts.hi = htonl(0x80000000);
UTI_DoubleToNtp64(0x80000000 - 0.1, &ntp_ts);
TEST_CHECK(UTI_CompareNtp64(&ntp_ts, &ntp_ts2) == 0);
ts.tv_sec = 1; ts.tv_sec = 1;
ts.tv_nsec = 2; ts.tv_nsec = 2;
ts2.tv_sec = 1; ts2.tv_sec = 1;

27
util.c
View file

@ -818,6 +818,33 @@ UTI_DiffNtp64ToDouble(const NTP_int64 *a, const NTP_int64 *b)
/* ================================================== */ /* ================================================== */
double
UTI_Ntp64ToDouble(NTP_int64 *src)
{
NTP_int64 zero;
UTI_ZeroNtp64(&zero);
return UTI_DiffNtp64ToDouble(src, &zero);
}
/* ================================================== */
void
UTI_DoubleToNtp64(double src, NTP_int64 *dest)
{
int32_t hi;
src = CLAMP(INT32_MIN, src, INT32_MAX);
hi = round(src);
if (hi > src)
hi -= 1;
dest->hi = htonl(hi);
dest->lo = htonl((src - hi) * (1.0e9 * NSEC_PER_NTP64));
}
/* ================================================== */
/* Maximum offset between two sane times */ /* Maximum offset between two sane times */
#define MAX_OFFSET 4294967296.0 #define MAX_OFFSET 4294967296.0

4
util.h
View file

@ -163,6 +163,10 @@ extern void UTI_Ntp64ToTimespec(const NTP_int64 *src, struct timespec *dest);
/* Calculate a - b in any epoch */ /* Calculate a - b in any epoch */
extern double UTI_DiffNtp64ToDouble(const NTP_int64 *a, const NTP_int64 *b); extern double UTI_DiffNtp64ToDouble(const NTP_int64 *a, const NTP_int64 *b);
/* Convert a difference in double (not a timestamp) from and to NTP format */
extern double UTI_Ntp64ToDouble(NTP_int64 *src);
extern void UTI_DoubleToNtp64(double src, NTP_int64 *dest);
/* Check if time + offset is sane */ /* Check if time + offset is sane */
extern int UTI_IsTimeOffsetSane(const struct timespec *ts, double offset); extern int UTI_IsTimeOffsetSane(const struct timespec *ts, double offset);