[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