diff options
Diffstat (limited to 'gpsd.c')
-rw-r--r-- | gpsd.c | 91 |
1 files changed, 82 insertions, 9 deletions
@@ -588,9 +588,6 @@ static void deactivate_device(struct gps_device_t *device) if (device->gpsdata.gps_fd != -1) { FD_CLR(device->gpsdata.gps_fd, &all_fds); adjust_max_fd(device->gpsdata.gps_fd, false); - if (context.dsock == device->gpsdata.gps_fd) { - context.dsock = -1; - } gpsd_deactivate(device); } } @@ -1294,9 +1291,6 @@ static void consume_packets(struct gps_device_t *device) device->driver.ntrip.conn_state = ntrip_conn_init; deactivate_device(device); } else { - if (device->driver.ntrip.conn_state == ntrip_conn_established) { - device->context->dsock = device->gpsdata.gps_fd; - } FD_SET(device->gpsdata.gps_fd, &all_fds); } return; @@ -1504,6 +1498,84 @@ static int handle_gpsd_request(struct subscriber_t *sub, const char *buf) return (int)throttled_write(sub, reply, strlen(reply)); } +#ifdef AUTOCONNECT_UNUSED +#define DGPS_THRESHOLD 1600000 /* max. useful dist. from DGPS server (m) */ +#define SERVER_SAMPLE 12 /* # of servers within threshold to check */ + +struct dgps_server_t +{ + double lat, lon; + char server[257]; + double dist; +}; + +static int srvcmp(const void *s, const void *t) +{ + return (int)(((const struct dgps_server_t *)s)->dist - ((const struct dgps_server_t *)t)->dist); /* fixes: warning: cast discards qualifiers from pointer target type */ +} + +static void netgnss_autoconnect(struct gps_context_t *context, + double lat, double lon, const char *serverlist) +/* tell the library to talk to the nearest DGPSIP server */ +{ + struct dgps_server_t keep[SERVER_SAMPLE], hold, *sp, *tp; + char buf[BUFSIZ]; + FILE *sfp = fopen(serverlist, "r"); + + if (sfp == NULL) { + gpsd_report(LOG_ERROR, "no DGPS server list found.\n"); + return; + } + + for (sp = keep; sp < keep + SERVER_SAMPLE; sp++) { + sp->dist = DGPS_THRESHOLD; + sp->server[0] = '\0'; + } + /*@ -usedef @*/ + while (fgets(buf, (int)sizeof(buf), sfp)) { + char *cp = strchr(buf, '#'); + if (cp != NULL) + *cp = '\0'; + if (sscanf(buf, "%lf %lf %256s", &hold.lat, &hold.lon, hold.server) == + 3) { + hold.dist = earth_distance(lat, lon, hold.lat, hold.lon); + tp = NULL; + /* + * The idea here is to look for a server in the sample array + * that is (a) closer than the one we're checking, and (b) + * furtherest away of all those that are closer. Replace it. + * In this way we end up with the closest possible set. + */ + for (sp = keep; sp < keep + SERVER_SAMPLE; sp++) + if (hold.dist < sp->dist + && (tp == NULL || hold.dist > tp->dist)) + tp = sp; + if (tp != NULL) + memcpy(tp, &hold, sizeof(struct dgps_server_t)); + } + } + (void)fclose(sfp); + + if (keep[0].server[0] == '\0') { + gpsd_report(LOG_ERROR, "no DGPS servers within %dm.\n", + (int)(DGPS_THRESHOLD / 1000)); + return; + } + /*@ +usedef @*/ + + /* sort them and try the closest first */ + qsort((void *)keep, SERVER_SAMPLE, sizeof(struct dgps_server_t), srvcmp); + for (sp = keep; sp < keep + SERVER_SAMPLE; sp++) { + if (sp->server[0] != '\0') { + gpsd_report(LOG_INF, "%s is %dkm away.\n", sp->server, + (int)(sp->dist / 1000)); + if (dgpsip_open(context, sp->server) >= 0) + break; + } + } +} +#endif /* AUTOCONNECT_UNUSED */ + /*@ -mustfreefresh @*/ int main(int argc, char *argv[]) { @@ -1911,18 +1983,19 @@ int main(int argc, char *argv[]) } } /* devices */ -#ifdef NOT_FIXED - if (context.fixcnt > 0 && context.dsock == -1) { +#ifdef AUTOCONNECT_UNUSED + if (context.fixcnt > 0 && !context.autconnect) { for (device = devices; device < devices + MAXDEVICES; device++) { if (device->gpsdata.fix.mode > MODE_NO_FIX) { netgnss_autoconnect(&context, device->gpsdata.fix.latitude, device->gpsdata.fix.longitude); + context.autconnect = True; break; } } } -#endif +#endif /* AUTOCONNECT_UNUSED */ /* accept and execute commands for all clients */ for (sub = subscribers; sub < subscribers + MAXSUBSCRIBERS; sub++) { |