diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2011-01-15 01:08:07 -0500 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2011-01-15 01:34:23 -0500 |
commit | 42eba3edc67243742fe3a514bed292f3fac559e0 (patch) | |
tree | 11e54b697ab3f1357c9f543792dd01b25125d0c9 /libgpsd_core.c | |
parent | 6cccec33ae4151b70f978695fd5ab475afc4781c (diff) | |
download | gpsd-42eba3edc67243742fe3a514bed292f3fac559e0.tar.gz |
Detect week-counter overruns using the leap second.
Diffstat (limited to 'libgpsd_core.c')
-rw-r--r-- | libgpsd_core.c | 36 |
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); } } |