From d59eb51be6e47f019f3c80d9eaf40aa5cb2e6be8 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sat, 17 Aug 2019 12:54:24 +0200 Subject: [PATCH] gpsdate: Discard gpsd reports when no fix or no satellites used We've observed several times that GPS receivers would report a wrong time/date directly after boot, probably assuming that their RTC is correct. Let's wait until the receiver reports it has a fix and reports actual satellites were used to compute it. --- gpsdate.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/gpsdate.c b/gpsdate.c index 513ca77..375c517 100644 --- a/gpsdate.c +++ b/gpsdate.c @@ -1,5 +1,5 @@ /* gpsdate - small utility to set system RTC based on gpsd time - * (C) 2013-2015 by sysmocom - s.f.m.c. GmbH, Author: Harald Welte + * (C) 2013-2019 by sysmocom - s.f.m.c. GmbH, Author: Harald Welte * All Rights Reserved * * This program is free software; you can redistribute it and/or modify @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -52,6 +53,7 @@ static void callback(struct gps_data_t *gpsdata) { struct timeval tv; time_t time; + char *timestr, *lf; int rc; if (!(gpsdata->set & TIME_SET)) @@ -62,12 +64,34 @@ static void callback(struct gps_data_t *gpsdata) tv.tv_usec = 0; time = tv.tv_sec; + timestr = ctime(&time); + if (!timestr) { + syslog(LOG_ERR, "ctime failed"); + timestr = ""; + } + /* god knows why ctime insists on including a LF at the end */ + lf = strchr(timestr, '\n'); + if (lf) + *lf = '\0'; + + syslog(LOG_DEBUG, "%s: gpsdate->set=0x%08"PRIu64"x status=%u sats_used=%u\n", + timestr, gpsdata->set, gpsdata->status, gpsdata->satellites_used); + + if (gpsdata->status == 0) { + syslog(LOG_INFO, "%s: discarding; no fix yet\n", timestr); + return; + } + + if (gpsdata->satellites_used == 0) { + syslog(LOG_INFO, "%s: discarding; 0 satellites used\n", timestr); + return; + } rc = settimeofday(&tv, NULL); gps_close(gpsdata); if (rc == 0) { syslog(LOG_NOTICE, "Successfully set RTC time to GPSD time:" - " %s", ctime(&time)); + " %s\n", timestr); closelog(); exit(EXIT_SUCCESS); } else {