[Git][NTPsec/ntpsec][master] Pry some device-independent code loose from the NMEA driver.
Eric S. Raymond
gitlab at mg.gitlab.com
Sat Jun 22 16:05:56 UTC 2019
Eric S. Raymond pushed to branch master at NTPsec / ntpsec
Commits:
f50f7172 by Eric S. Raymond at 2019-06-22T16:02:50Z
Pry some device-independent code loose from the NMEA driver.
This logic for resolving GPS time and wrapped calendar dates
should be used by other GPS drivers as well.
- - - - -
4 changed files:
- + include/ntp_wrapdate.h
- + ntpd/ntp_wrapdate.c
- ntpd/refclock_nmea.c
- ntpd/wscript
Changes:
=====================================
include/ntp_wrapdate.h
=====================================
@@ -0,0 +1,23 @@
+/* calendar / date helpers for GPS devices */
+
+/*
+ * NMEA gps week/time information
+ * This record contains the number of weeks since 1980-01-06 modulo
+ * 1024, the seconds elapsed since start of the week, and the number of
+ * leap seconds that are the difference between GPS and UTC time scale.
+ */
+typedef struct {
+ uint32_t wt_time; /* seconds since weekstart */
+ unsigned short wt_week; /* week number */
+ short wt_leap; /* leap seconds */
+} gps_weektm;
+
+
+void wrapdate_init (void);
+bool unfold_day (struct calendar * jd, uint32_t rec_ui);
+bool unfold_century (struct calendar * jd, uint32_t rec_ui);
+bool gpsfix_century (struct calendar * jd, const gps_weektm * wd,
+ unsigned short * ccentury);
+l_fp eval_gps_time (const char *, const struct calendar * gpst,
+ const struct timespec * gpso, bool trustl, short *epoch_wrap, const l_fp * xrecv);
+// end
=====================================
ntpd/ntp_wrapdate.c
=====================================
@@ -0,0 +1,319 @@
+/*
+ * Calendar-oriented stuff -- perhaps a bit hard to grok.
+ *
+ * Used for interpreting GPS sentences and resolving wrap issies
+ * around 2-digit years. Formerly part of refclock_nmea.c,
+ * dissected out so it can be used by other drivers.
+ */
+
+#include "config.h"
+#include "ntp_types.h"
+
+#include "ntp.h"
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_stdlib.h"
+#include "ntp_calendar.h"
+#include "ntp_wrapdate.h"
+#include "timespecops.h"
+
+static int32_t g_gpsMinBase;
+static int32_t g_gpsMinYear;
+
+/*
+ * The GPS week time scale starts on Sunday, 1980-01-06. We need the
+ * rata die number of this day.
+ */
+#ifndef DAY_GPS_STARTS
+#define DAY_GPS_STARTS 722820
+#endif
+
+/*
+ * -------------------------------------------------------------------
+ * nmea_init - initialise data
+ *
+ * calculates a few runtime constants that cannot be made compile time
+ * constants.
+ * -------------------------------------------------------------------
+ */
+void
+wrapdate_init(void)
+{
+ struct calendar date;
+
+ /* - calculate min. base value for GPS epoch & century unfolding
+ * This assumes that the build system was roughly in sync with
+ * the world, and that really synchronising to a time before the
+ * program was created would be unsafe or insane. If the build
+ * date cannot be stablished, at least use the start of GPS
+ * (1980-01-06) as minimum, because GPS can surely NOT
+ * synchronise beyond it's own big bang. We add a little safety
+ * margin for the fuzziness of the build date, which is in an
+ * undefined time zone. */
+ if (ntpcal_get_build_date(&date))
+ g_gpsMinBase = ntpcal_date_to_rd(&date) - 2;
+ else
+ g_gpsMinBase = 0;
+
+ if (g_gpsMinBase < DAY_GPS_STARTS)
+ g_gpsMinBase = DAY_GPS_STARTS;
+
+ ntpcal_rd_to_date(&date, g_gpsMinBase);
+ g_gpsMinYear = date.year;
+ g_gpsMinBase -= DAY_NTP_STARTS;
+}
+
+/*
+ * -------------------------------------------------------------------
+ *
+ * Unfold a time-of-day (seconds since midnight) around the current
+ * system time in a manner that guarantees an absolute difference of
+ * less than 12hrs.
+ *
+ * This function is used for NMEA sentences that contain no date
+ * information. This requires the system clock to be in +/-12hrs
+ * around the true time, or the clock will synchronize the system 1day
+ * off if not augmented with a time sources that also provide the
+ * necessary date information.
+ *
+ * The function updates the calendar structure it also uses as
+ * input to fetch the time from.
+ *
+ * returns true on success, false on failure
+ * -------------------------------------------------------------------
+ */
+bool
+unfold_day(
+ struct calendar * jd,
+ uint32_t rec_ui
+ )
+{
+ time64_t rec_qw;
+ ntpcal_split rec_ds;
+
+ /*
+ * basically this is the peridiodic extension of the receive
+ * time - 12hrs to the time-of-day with a period of 1 day.
+ * But we would have to execute this in 64bit arithmetic, and we
+ * cannot assume we can do this; therefore this is done
+ * in split representation.
+ */
+ rec_qw = ntpcal_ntp_to_ntp(rec_ui - SECSPERDAY/2, time(NULL));
+ rec_ds = ntpcal_daysplit(rec_qw);
+ rec_ds.lo = ntpcal_periodic_extend(rec_ds.lo,
+ ntpcal_date_to_daysec(jd),
+ SECSPERDAY);
+ rec_ds.hi += ntpcal_daysec_to_date(jd, rec_ds.lo);
+ /* -1 return means calculation overflowed */
+ return (ntpcal_rd_to_date(jd, rec_ds.hi + DAY_NTP_STARTS) >= 0);
+}
+
+/*
+ * -------------------------------------------------------------------
+ * A 2-digit year is expanded into full year spec around the year found
+ * in 'jd->year'. This should be in +79/-19 years around the system time,
+ * or the result will be off by 100 years. The asymmetric behaviour was
+ * chosen to enable initial sync for systems that do not have a
+ * battery-backup clock and start with a date that is typically years in
+ * the past.
+ *
+ * Since the GPS epoch starts at 1980-01-06, the resulting year will be
+ * not be before 1980 in any case.
+ *
+ * returns true on success, false on failure
+ * -------------------------------------------------------------------
+ */
+bool
+unfold_century(
+ struct calendar * jd,
+ uint32_t rec_ui
+ )
+{
+ struct calendar rec;
+ int32_t baseyear;
+
+ ntpcal_ntp_to_date(&rec, rec_ui, time(NULL));
+ baseyear = rec.year - 20;
+ if (baseyear < g_gpsMinYear)
+ baseyear = g_gpsMinYear;
+ jd->year = (unsigned short)ntpcal_periodic_extend(baseyear, jd->year,
+ 100);
+
+ return ((baseyear <= jd->year) && (baseyear + 100 > jd->year));
+}
+
+/*
+ * -------------------------------------------------------------------
+ * A 2-digit year is expanded into a full year spec by correlation with
+ * a GPS week number and the current leap second count.
+ *
+ * The GPS week time scale counts weeks since Sunday, 1980-01-06, modulo
+ * 1024 and seconds since start of the week. The GPS time scale is based
+ * on international atomic time (TAI), so the leap second difference to
+ * UTC is also needed for a proper conversion.
+ *
+ * A brute-force analysis (that is, test for every date) shows that a
+ * wrong assignment of the century can not happen between the years 1900
+ * to 2399 when comparing the week signatures for different
+ * centuries. (I *think* that will not happen for 400*1024 years, but I
+ * have no valid proof. -*-perlinger at ntp.org-*-)
+ *
+ * This function is bound to work between years 1980 and 2399
+ * (inclusive), which should suffice for now ;-)
+ *
+ * Note: This function needs a full date&time spec on input due to the
+ * necessary leap second corrections!
+ *
+ * returns true on success, false on failure
+ * -------------------------------------------------------------------
+ */
+bool
+gpsfix_century(
+ struct calendar * jd,
+ const gps_weektm * wd,
+ unsigned short * century
+ )
+{
+ int32_t days;
+ int32_t doff;
+ unsigned short week;
+ unsigned short year;
+ int loop;
+
+ /* Get day offset. Assumes that the input time is in range and
+ * that the leap seconds do not shift more than +/-1 day.
+ */
+ doff = ntpcal_date_to_daysec(jd) + wd->wt_leap;
+ doff = (doff >= SECSPERDAY) - (doff < 0);
+
+ /*
+ * Loop over centuries to get a match, starting with the last
+ * successful one. (Or with the 19th century if the cached value
+ * is out of range...)
+ */
+ year = jd->year % 100;
+ for (loop = 5; loop > 0; loop--,(*century)++) {
+ if (*century < 19 || *century >= 24)
+ *century = 19;
+ /* Get days and week in GPS epoch */
+ jd->year = year + *century * 100;
+ days = ntpcal_date_to_rd(jd) - DAY_GPS_STARTS + doff;
+ week = (days / 7) % 1024;
+ if (days >= 0 && wd->wt_week == week)
+ return true; /* matched... */
+ }
+
+ jd->year = year;
+ return false; /* match failed... */
+}
+
+/*
+ * -------------------------------------------------------------------
+ * And now the final execise: Considering the fact that many (most?)
+ * GPS receivers cannot handle a GPS epoch wrap well, we try to
+ * compensate for that problem by unwrapping a GPS epoch around the
+ * receive stamp. Another execise in periodic unfolding, of course,
+ * but with enough points to take care of.
+ *
+ * Note: The integral part of 'tofs' is intended to handle small(!)
+ * systematic offsets, as -1 for handling $GPZDG, which gives the
+ * following second. (sigh...) The absolute value shall be less than a
+ * day (86400 seconds).
+ * -------------------------------------------------------------------
+ */
+l_fp
+eval_gps_time(
+ const char * refclock_name, /* ffor logging */
+ const struct calendar * gpst, /* GPS time stamp */
+ const struct timespec * tofs, /* GPS frac second & offset */
+ const bool trusted, /* do we fully trust dates from this GPS? */
+ short *epoch_warp, /* for logging */
+ const l_fp * xrecv /* receive time stamp */
+ )
+{
+
+ l_fp retv;
+
+ /* components of calculation */
+ int32_t rcv_sec, rcv_day; /* receive ToD and day */
+ int32_t gps_sec, gps_day; /* GPS ToD and day in NTP epoch */
+ int32_t adj_day, weeks; /* adjusted GPS day and week shift */
+
+ /* some temporaries to shuffle data */
+ time64_t vi64;
+ ntpcal_split rs64;
+
+ /* evaluate time stamp from receiver. */
+ gps_sec = ntpcal_date_to_daysec(gpst);
+ gps_day = ntpcal_date_to_rd(gpst) - DAY_NTP_STARTS;
+
+ /* merge in fractional offset */
+ retv = tspec_intv_to_lfp(*tofs);
+ gps_sec += lfpsint(retv);
+
+ /* If we fully trust the GPS receiver, just combine days and
+ * seconds and be done. */
+ if (trusted) {
+ setlfpuint(retv, time64lo(ntpcal_dayjoin(gps_day, gps_sec)));
+ return retv;
+ }
+
+ /* So we do not trust the GPS receiver to deliver a correct date
+ * due to the GPS epoch changes. We map the date from the
+ * receiver into the +/-512 week interval around the receive
+ * time in that case. This would be a tad easier with 64bit
+ * calculations, but again, we restrict the code to 32bit ops
+ * when possible. */
+
+ /* - make sure the GPS fractional day is normalised
+ * Applying the offset value might have put us slightly over the
+ * edge of the allowed range for seconds-of-day. Doing a full
+ * division with floor correction is overkill here; a simple
+ * addition or subtraction step is sufficient. Using WHILE loops
+ * gives the right result even if the offset exceeds one day,
+ * which is NOT what it's intended for! */
+ while (gps_sec >= SECSPERDAY) {
+ gps_sec -= SECSPERDAY;
+ gps_day += 1;
+ }
+ while (gps_sec < 0) {
+ gps_sec += SECSPERDAY;
+ gps_day -= 1;
+ }
+
+ /* - get unfold base: day of full recv time - 512 weeks */
+ vi64 = ntpcal_ntp_to_ntp(lfpuint(*xrecv), time(NULL));
+ rs64 = ntpcal_daysplit(vi64);
+ rcv_sec = rs64.lo;
+ rcv_day = rs64.hi - 512 * 7;
+
+ /* - take the fractional days into account
+ * If the fractional day of the GPS time is smaller than the
+ * fractional day of the receive time, we shift the base day for
+ * the unfold by 1. */
+ if ( gps_sec < rcv_sec
+ || (gps_sec == rcv_sec && lfpfrac(retv) < lfpfrac(*xrecv)))
+ rcv_day += 1;
+
+ /* - don't warp ahead of GPS invention! */
+ if (rcv_day < g_gpsMinBase)
+ rcv_day = g_gpsMinBase;
+
+ /* - let the magic happen: */
+ adj_day = ntpcal_periodic_extend(rcv_day, gps_day, 1024*7);
+
+ /* - check if we should log a GPS epoch warp */
+ weeks = (adj_day - gps_day) / 7;
+ if (weeks != *epoch_warp) {
+ *epoch_warp = (short)weeks;
+ LOGIF(CLOCKINFO, (LOG_INFO,
+ "%s Changed GPS epoch warp to %d weeks",
+ refclock_name, weeks));
+ }
+
+ /* - build result and be done */
+ setlfpuint(retv, time64lo(ntpcal_dayjoin(adj_day, gps_sec)));
+ return retv;
+}
+
+// end
=====================================
ntpd/refclock_nmea.c
=====================================
@@ -31,6 +31,7 @@
#include "ntp_refclock.h"
#include "ntp_stdlib.h"
#include "ntp_calendar.h"
+#include "ntp_wrapdate.h"
#include "timespecops.h"
#ifdef HAVE_PPSAPI
@@ -247,18 +248,6 @@ typedef struct {
int cidx; /* current field index */
} nmea_data;
-/*
- * NMEA gps week/time information
- * This record contains the number of weeks since 1980-01-06 modulo
- * 1024, the seconds elapsed since start of the week, and the number of
- * leap seconds that are the difference between GPS and UTC time scale.
- */
-typedef struct {
- uint32_t wt_time; /* seconds since weekstart */
- unsigned short wt_week; /* week number */
- short wt_leap; /* leap seconds */
-} gps_weektm;
-
/*
* The GPS week time scale starts on Sunday, 1980-01-06. We need the
* rata die number of this day.
@@ -296,13 +285,6 @@ static bool parse_date (struct calendar *jd, nmea_data*,
int idx, enum date_fmt fmt);
static bool parse_weekdata (gps_weektm *, nmea_data *,
int weekidx, int timeidx, int leapidx);
-/* calendar / date helpers */
-static bool unfold_day (struct calendar * jd, uint32_t rec_ui);
-static bool unfold_century (struct calendar * jd, uint32_t rec_ui);
-static bool gpsfix_century (struct calendar * jd, const gps_weektm * wd,
- unsigned short * ccentury);
-static l_fp eval_gps_time (struct peer * peer, const struct calendar * gpst,
- const struct timespec * gpso, const l_fp * xrecv);
static void save_ltc (struct refclockproc * const, const char * const,
size_t);
@@ -315,9 +297,6 @@ static void save_ltc (struct refclockproc * const, const char * const
static void gps_send(int, const char *, struct peer *);
#endif /* NMEA_WRITE_SUPPORT */
-static int32_t g_gpsMinBase;
-static int32_t g_gpsMinYear;
-
/*
* -------------------------------------------------------------------
* Transfer vector
@@ -344,28 +323,7 @@ struct refclock refclock_nmea = {
static void
nmea_init(void)
{
- struct calendar date;
-
- /* - calculate min. base value for GPS epoch & century unfolding
- * This assumes that the build system was roughly in sync with
- * the world, and that really synchronising to a time before the
- * program was created would be unsafe or insane. If the build
- * date cannot be stablished, at least use the start of GPS
- * (1980-01-06) as minimum, because GPS can surely NOT
- * synchronise beyond it's own big bang. We add a little safety
- * margin for the fuzziness of the build date, which is in an
- * undefined time zone. */
- if (ntpcal_get_build_date(&date))
- g_gpsMinBase = ntpcal_date_to_rd(&date) - 2;
- else
- g_gpsMinBase = 0;
-
- if (g_gpsMinBase < DAY_GPS_STARTS)
- g_gpsMinBase = DAY_GPS_STARTS;
-
- ntpcal_rd_to_date(&date, g_gpsMinBase);
- g_gpsMinYear = date.year;
- g_gpsMinBase -= DAY_NTP_STARTS;
+ wrapdate_init();
}
/*
@@ -1049,7 +1007,8 @@ nmea_receive(
* timecode timestamp, but only if the PPS is not in control.
* Discard sentence if reference time did not change.
*/
- rd_reftime = eval_gps_time(peer, &date, &tofs, &rd_timestamp);
+ rd_reftime = eval_gps_time(refclock_name(peer), &date, &tofs,
+ (peer->cfg.mode & NMEA_DATETRUST_MASK), &up->epoch_warp, &rd_timestamp);
if (up->last_reftime == rd_reftime) {
/* Do not touch pp->a_lastcode on purpose! */
up->tally.filtered++;
@@ -1649,259 +1608,4 @@ parse_weekdata(
return true;
}
-/*
- * -------------------------------------------------------------------
- * funny calendar-oriented stuff -- perhaps a bit hard to grok.
- * -------------------------------------------------------------------
- *
- * Unfold a time-of-day (seconds since midnight) around the current
- * system time in a manner that guarantees an absolute difference of
- * less than 12hrs.
- *
- * This function is used for NMEA sentences that contain no date
- * information. This requires the system clock to be in +/-12hrs
- * around the true time, or the clock will synchronize the system 1day
- * off if not augmented with a time sources that also provide the
- * necessary date information.
- *
- * The function updates the calendar structure it also uses as
- * input to fetch the time from.
- *
- * returns true on success, false on failure
- * -------------------------------------------------------------------
- */
-static bool
-unfold_day(
- struct calendar * jd,
- uint32_t rec_ui
- )
-{
- time64_t rec_qw;
- ntpcal_split rec_ds;
-
- /*
- * basically this is the peridiodic extension of the receive
- * time - 12hrs to the time-of-day with a period of 1 day.
- * But we would have to execute this in 64bit arithmetic, and we
- * cannot assume we can do this; therefore this is done
- * in split representation.
- */
- rec_qw = ntpcal_ntp_to_ntp(rec_ui - SECSPERDAY/2, time(NULL));
- rec_ds = ntpcal_daysplit(rec_qw);
- rec_ds.lo = ntpcal_periodic_extend(rec_ds.lo,
- ntpcal_date_to_daysec(jd),
- SECSPERDAY);
- rec_ds.hi += ntpcal_daysec_to_date(jd, rec_ds.lo);
- /* -1 return means calculation overflowed */
- return (ntpcal_rd_to_date(jd, rec_ds.hi + DAY_NTP_STARTS) >= 0);
-}
-
-/*
- * -------------------------------------------------------------------
- * A 2-digit year is expanded into full year spec around the year found
- * in 'jd->year'. This should be in +79/-19 years around the system time,
- * or the result will be off by 100 years. The asymmetric behaviour was
- * chosen to enable initial sync for systems that do not have a
- * battery-backup clock and start with a date that is typically years in
- * the past.
- *
- * Since the GPS epoch starts at 1980-01-06, the resulting year will be
- * not be before 1980 in any case.
- *
- * returns true on success, false on failure
- * -------------------------------------------------------------------
- */
-static bool
-unfold_century(
- struct calendar * jd,
- uint32_t rec_ui
- )
-{
- struct calendar rec;
- int32_t baseyear;
-
- ntpcal_ntp_to_date(&rec, rec_ui, time(NULL));
- baseyear = rec.year - 20;
- if (baseyear < g_gpsMinYear)
- baseyear = g_gpsMinYear;
- jd->year = (unsigned short)ntpcal_periodic_extend(baseyear, jd->year,
- 100);
-
- return ((baseyear <= jd->year) && (baseyear + 100 > jd->year));
-}
-
-/*
- * -------------------------------------------------------------------
- * A 2-digit year is expanded into a full year spec by correlation with
- * a GPS week number and the current leap second count.
- *
- * The GPS week time scale counts weeks since Sunday, 1980-01-06, modulo
- * 1024 and seconds since start of the week. The GPS time scale is based
- * on international atomic time (TAI), so the leap second difference to
- * UTC is also needed for a proper conversion.
- *
- * A brute-force analysis (that is, test for every date) shows that a
- * wrong assignment of the century can not happen between the years 1900
- * to 2399 when comparing the week signatures for different
- * centuries. (I *think* that will not happen for 400*1024 years, but I
- * have no valid proof. -*-perlinger at ntp.org-*-)
- *
- * This function is bound to work between years 1980 and 2399
- * (inclusive), which should suffice for now ;-)
- *
- * Note: This function needs a full date&time spec on input due to the
- * necessary leap second corrections!
- *
- * returns true on success, false on failure
- * -------------------------------------------------------------------
- */
-static bool
-gpsfix_century(
- struct calendar * jd,
- const gps_weektm * wd,
- unsigned short * century
- )
-{
- int32_t days;
- int32_t doff;
- unsigned short week;
- unsigned short year;
- int loop;
-
- /* Get day offset. Assumes that the input time is in range and
- * that the leap seconds do not shift more than +/-1 day.
- */
- doff = ntpcal_date_to_daysec(jd) + wd->wt_leap;
- doff = (doff >= SECSPERDAY) - (doff < 0);
-
- /*
- * Loop over centuries to get a match, starting with the last
- * successful one. (Or with the 19th century if the cached value
- * is out of range...)
- */
- year = jd->year % 100;
- for (loop = 5; loop > 0; loop--,(*century)++) {
- if (*century < 19 || *century >= 24)
- *century = 19;
- /* Get days and week in GPS epoch */
- jd->year = year + *century * 100;
- days = ntpcal_date_to_rd(jd) - DAY_GPS_STARTS + doff;
- week = (days / 7) % 1024;
- if (days >= 0 && wd->wt_week == week)
- return true; /* matched... */
- }
-
- jd->year = year;
- return false; /* match failed... */
-}
-
-/*
- * -------------------------------------------------------------------
- * And now the final execise: Considering the fact that many (most?)
- * GPS receivers cannot handle a GPS epoch wrap well, we try to
- * compensate for that problem by unwrapping a GPS epoch around the
- * receive stamp. Another execise in periodic unfolding, of course,
- * but with enough points to take care of.
- *
- * Note: The integral part of 'tofs' is intended to handle small(!)
- * systematic offsets, as -1 for handling $GPZDG, which gives the
- * following second. (sigh...) The absolute value shall be less than a
- * day (86400 seconds).
- * -------------------------------------------------------------------
- */
-static l_fp
-eval_gps_time(
- struct peer * peer, /* for logging etc */
- const struct calendar * gpst, /* GPS time stamp */
- const struct timespec * tofs, /* GPS frac second & offset */
- const l_fp * xrecv /* receive time stamp */
- )
-{
- struct refclockproc * const pp = peer->procptr;
- nmea_unit * const up = (nmea_unit *)pp->unitptr;
-
- l_fp retv;
-
- /* components of calculation */
- int32_t rcv_sec, rcv_day; /* receive ToD and day */
- int32_t gps_sec, gps_day; /* GPS ToD and day in NTP epoch */
- int32_t adj_day, weeks; /* adjusted GPS day and week shift */
-
- /* some temporaries to shuffle data */
- time64_t vi64;
- ntpcal_split rs64;
-
- /* evaluate time stamp from receiver. */
- gps_sec = ntpcal_date_to_daysec(gpst);
- gps_day = ntpcal_date_to_rd(gpst) - DAY_NTP_STARTS;
-
- /* merge in fractional offset */
- retv = tspec_intv_to_lfp(*tofs);
- gps_sec += lfpsint(retv);
-
- /* If we fully trust the GPS receiver, just combine days and
- * seconds and be done. */
- if (peer->cfg.mode & NMEA_DATETRUST_MASK) {
- setlfpuint(retv, time64lo(ntpcal_dayjoin(gps_day, gps_sec)));
- return retv;
- }
-
- /* So we do not trust the GPS receiver to deliver a correct date
- * due to the GPS epoch changes. We map the date from the
- * receiver into the +/-512 week interval around the receive
- * time in that case. This would be a tad easier with 64bit
- * calculations, but again, we restrict the code to 32bit ops
- * when possible. */
-
- /* - make sure the GPS fractional day is normalised
- * Applying the offset value might have put us slightly over the
- * edge of the allowed range for seconds-of-day. Doing a full
- * division with floor correction is overkill here; a simple
- * addition or subtraction step is sufficient. Using WHILE loops
- * gives the right result even if the offset exceeds one day,
- * which is NOT what it's intended for! */
- while (gps_sec >= SECSPERDAY) {
- gps_sec -= SECSPERDAY;
- gps_day += 1;
- }
- while (gps_sec < 0) {
- gps_sec += SECSPERDAY;
- gps_day -= 1;
- }
-
- /* - get unfold base: day of full recv time - 512 weeks */
- vi64 = ntpcal_ntp_to_ntp(lfpuint(*xrecv), time(NULL));
- rs64 = ntpcal_daysplit(vi64);
- rcv_sec = rs64.lo;
- rcv_day = rs64.hi - 512 * 7;
-
- /* - take the fractional days into account
- * If the fractional day of the GPS time is smaller than the
- * fractional day of the receive time, we shift the base day for
- * the unfold by 1. */
- if ( gps_sec < rcv_sec
- || (gps_sec == rcv_sec && lfpfrac(retv) < lfpfrac(*xrecv)))
- rcv_day += 1;
-
- /* - don't warp ahead of GPS invention! */
- if (rcv_day < g_gpsMinBase)
- rcv_day = g_gpsMinBase;
-
- /* - let the magic happen: */
- adj_day = ntpcal_periodic_extend(rcv_day, gps_day, 1024*7);
-
- /* - check if we should log a GPS epoch warp */
- weeks = (adj_day - gps_day) / 7;
- if (weeks != up->epoch_warp) {
- up->epoch_warp = (short)weeks;
- LOGIF(CLOCKINFO, (LOG_INFO,
- "%s Changed GPS epoch warp to %d weeks",
- refclock_name(peer), weeks));
- }
-
- /* - build result and be done */
- setlfpuint(retv, time64lo(ntpcal_dayjoin(adj_day, gps_sec)));
- return retv;
-}
-
// end
=====================================
ntpd/wscript
=====================================
@@ -77,6 +77,7 @@ def build(ctx):
if ctx.env.REFCLOCK_ENABLE:
refclock_source = ["ntp_refclock.c",
+ "ntp_wrapdate.c",
"refclock_conf.c"
]
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/f50f717226a34f8e53acd5791488781fe114fa26
--
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/f50f717226a34f8e53acd5791488781fe114fa26
You're receiving this email because of your account on gitlab.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20190622/21f065de/attachment-0001.htm>
More information about the vc
mailing list