forked from sysmocom/gpsdate
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).
This commit is contained in:
parent
cb65bc5348
commit
c77a9b3342
57
gpsdate.c
57
gpsdate.c
|
@ -143,39 +143,82 @@ static int my_gps_mainloop(struct gps_data_t *gdata,
|
||||||
return 0;
|
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)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char *host = "localhost";
|
char *host = "localhost";
|
||||||
int i, rc;
|
int i, rc;
|
||||||
|
enum state state;
|
||||||
|
|
||||||
openlog("gpsdate", LOG_PERROR, LOG_CRON);
|
openlog("gpsdate", LOG_PERROR, LOG_CRON);
|
||||||
|
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
host = argv[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++) {
|
for (i = 1; i <= NUM_RETRIES; i++) {
|
||||||
printf("Attempt #%d to connect to gpsd at %s...\n", i, host);
|
printf("Attempt #%d to connect to gpsd at %s...\n", i, host);
|
||||||
rc = gps_open(host, DEFAULT_GPSD_PORT, &gpsdata);
|
rc = attempt_reconnect(host, DEFAULT_GPSD_PORT, &gpsdata);
|
||||||
if (!rc)
|
if (rc >= 0)
|
||||||
break;
|
break;
|
||||||
sleep(RETRY_SLEEP);
|
sleep(RETRY_SLEEP);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc) {
|
if (rc < 0) {
|
||||||
syslog(LOG_ERR, "no gpsd running or network error: %d, %s\n",
|
syslog(LOG_ERR, "no gpsd running or network error: %d, %s\n",
|
||||||
errno, gps_errstr(errno));
|
errno, gps_errstr(errno));
|
||||||
closelog();
|
closelog();
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
state = S_CONNECTED;
|
||||||
|
|
||||||
osmo_daemonize();
|
osmo_daemonize();
|
||||||
|
|
||||||
gps_stream(&gpsdata, WATCH_ENABLE|WATCH_JSON, NULL);
|
|
||||||
|
|
||||||
/* We run in an endless loop. The only reasonable way to exit is after
|
/* We run in an endless loop. The only reasonable way to exit is after
|
||||||
* a correct GPS timestamp has been received in callback() */
|
* a correct GPS timestamp has been received in callback() */
|
||||||
while (1)
|
while (1) {
|
||||||
my_gps_mainloop(&gpsdata, INT_MAX, callback);
|
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);
|
gps_close(&gpsdata);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue