summaryrefslogtreecommitdiff
path: root/gpsd.c
diff options
context:
space:
mode:
Diffstat (limited to 'gpsd.c')
-rw-r--r--gpsd.c91
1 files changed, 82 insertions, 9 deletions
diff --git a/gpsd.c b/gpsd.c
index d972ed36..28b56170 100644
--- a/gpsd.c
+++ b/gpsd.c
@@ -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++) {