summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2013-10-14 10:39:34 +0200
committerHarald Welte <laforge@gnumonks.org>2013-10-14 10:39:34 +0200
commitc77a9b3342af3f15142162655268d1e55ca598f1 (patch)
treee60dbbf02b324e599f94093d433eb2294f0a9b00
parentcb65bc53489a3881783e8213e3c4b2a5cc507337 (diff)
downloadgpsdate-c77a9b3342af3f15142162655268d1e55ca598f1.tar.gz
gpsdate-c77a9b3342af3f15142162655268d1e55ca598f1.tar.bz2
gpsdate-c77a9b3342af3f15142162655268d1e55ca598f1.tar.xz
gpsdate-c77a9b3342af3f15142162655268d1e55ca598f1.zip
reconnect to gpsd if it disappears while we wait for fix/time
In some cases, gpsd might die while we are waiting to receive a valid fix/time information. In that case, we have to reconnect to gpsd again and again, until a valid time has been received (and set as system clock).
-rw-r--r--gpsdate.c57
1 files changed, 50 insertions, 7 deletions
diff --git a/gpsdate.c b/gpsdate.c
index 6b4f303..22ec29a 100644
--- a/gpsdate.c
+++ b/gpsdate.c
@@ -143,39 +143,82 @@ static int my_gps_mainloop(struct gps_data_t *gdata,
return 0;
}
+static int attempt_reconnect(const char *host, const char *port,
+ struct gps_data_t *gpsdata)
+{
+ int rc;
+
+ rc = gps_open(host, port, gpsdata);
+ if (rc)
+ return -1;
+
+ syslog(LOG_INFO, "(re)connected to gpsd\n");
+
+ gps_stream(gpsdata, WATCH_ENABLE|WATCH_JSON, NULL);
+
+ return 0;
+}
+
+enum state {
+ S_CONNECTED,
+ S_RECONNECT,
+};
+
int main(int argc, char **argv)
{
char *host = "localhost";
int i, rc;
+ enum state state;
openlog("gpsdate", LOG_PERROR, LOG_CRON);
if (argc > 1)
host = argv[1];
+ /* attempt up to NUM_RETRIES times to connect to gpsd while we are
+ * still running in foreground. The idea is that we will block the
+ * boot process (init scripts) until we have a connection */
for (i = 1; i <= NUM_RETRIES; i++) {
printf("Attempt #%d to connect to gpsd at %s...\n", i, host);
- rc = gps_open(host, DEFAULT_GPSD_PORT, &gpsdata);
- if (!rc)
+ rc = attempt_reconnect(host, DEFAULT_GPSD_PORT, &gpsdata);
+ if (rc >= 0)
break;
sleep(RETRY_SLEEP);
}
- if (rc) {
+ if (rc < 0) {
syslog(LOG_ERR, "no gpsd running or network error: %d, %s\n",
errno, gps_errstr(errno));
closelog();
exit(EXIT_FAILURE);
}
+ state = S_CONNECTED;
osmo_daemonize();
- gps_stream(&gpsdata, WATCH_ENABLE|WATCH_JSON, NULL);
-
/* We run in an endless loop. The only reasonable way to exit is after
* a correct GPS timestamp has been received in callback() */
- while (1)
- my_gps_mainloop(&gpsdata, INT_MAX, callback);
+ while (1) {
+ switch (state) {
+ case S_CONNECTED:
+ rc = my_gps_mainloop(&gpsdata, INT_MAX, callback);
+ if (rc < 1) {
+ syslog(LOG_ERR, "connection to gpsd was "
+ "closed: %d, reconnecting\n", rc);
+ gps_close(&gpsdata);
+ state = S_RECONNECT;
+ }
+ break;
+ case S_RECONNECT:
+ rc = attempt_reconnect(host, DEFAULT_GPSD_PORT,
+ &gpsdata);
+ if (rc < 0)
+ sleep(RETRY_SLEEP);
+ else
+ state = S_CONNECTED;
+ break;
+ }
+ }
gps_close(&gpsdata);