summaryrefslogtreecommitdiff
path: root/libgpsd_core.c
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2011-01-15 01:08:07 -0500
committerEric S. Raymond <esr@thyrsus.com>2011-01-15 01:34:23 -0500
commit42eba3edc67243742fe3a514bed292f3fac559e0 (patch)
tree11e54b697ab3f1357c9f543792dd01b25125d0c9 /libgpsd_core.c
parent6cccec33ae4151b70f978695fd5ab475afc4781c (diff)
downloadgpsd-42eba3edc67243742fe3a514bed292f3fac559e0.tar.gz
Detect week-counter overruns using the leap second.
Diffstat (limited to 'libgpsd_core.c')
-rw-r--r--libgpsd_core.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/libgpsd_core.c b/libgpsd_core.c
index 73e12bdd..a4e45521 100644
--- a/libgpsd_core.c
+++ b/libgpsd_core.c
@@ -835,19 +835,43 @@ char /*@observer@*/ *gpsd_id( /*@in@ */ struct gps_device_t *session)
return (buf);
}
-void gpsd_rollover_check(/*@in@ */ struct gps_device_t *session, const double unixtime)
+void gpsd_rollover_check(/*@in@*/struct gps_device_t *session,
+ const double unixtime)
{
/*
+ * If the system clock is zero or has a small-integer value,
+ * no sanity-checking is possible.
+ */
+ if (session->context->start_time < GPS_EPOCH)
+ return;
+
+ /*
+ * Check the time passed in against the leap-second offset the satellites
+ * are reporting. After a rollover, the receiver will probably report a
+ * time far enough in the past that it won't be consistent with the
+ * leap-second value.
+ */
+ if (gpsd_check_leapsecond(session->context->leap_seconds, unixtime) == 0) {
+ char scr[128];
+ (void)unix_to_iso8601(unixtime, scr, sizeof(scr));
+ gpsd_report(LOG_WARN, "leap-second %d is impossible at time %s (%f)\n",
+ session->context->leap_seconds, scr, unixtime);
+ }
+
+ /*
+ * If the GPS is reporting a time from before the daemon started, we've
+ * had a rollover event while the daemon was running.
+ *
* The reason for the 12-hour slop is that our recorded start time is local,
* but GPSes deliver time as though in UTC. This test could be exact if we
* counted on knowing our timezone at startup, but since we can't count on
* knowing location...
*/
- if (session->context->start_time >= GPS_EPOCH && unixtime + (12*60*60) < (double)session->context->start_time) {
- char scr[128];
- (void)unix_to_iso8601(unixtime, scr, sizeof(scr));
- gpsd_report(LOG_WARN, "GPS week rollover makes time %s (%f) invalid\n",
- scr, unixtime);
+ if (unixtime + (12*60*60) < (double)session->context->start_time) {
+ char scr[128];
+ (void)unix_to_iso8601(unixtime, scr, sizeof(scr));
+ gpsd_report(LOG_WARN, "GPS week rollover makes time %s (%f) invalid\n",
+ scr, unixtime);
}
}