summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2005-06-29 20:38:44 +0000
committerEric S. Raymond <esr@thyrsus.com>2005-06-29 20:38:44 +0000
commit7034fb6917d6afc9851dc79518fa1ce83a767e67 (patch)
treea4b8e41bbc8edd029c93b45210d9e71154fb3eac
parentcba6b916920d78ef3e002061f1229d6c4debecac (diff)
downloadgpsd-7034fb6917d6afc9851dc79518fa1ce83a767e67.tar.gz
Experimental code to hunt for a DGPSIP server.
-rw-r--r--dgpsip.c47
-rw-r--r--gps.h2
-rw-r--r--gpsd.c33
-rw-r--r--gpsd.h2
-rw-r--r--gpsd.spec.in5
-rw-r--r--gpsd.xml24
-rw-r--r--gpsutils.c4
7 files changed, 96 insertions, 21 deletions
diff --git a/dgpsip.c b/dgpsip.c
index 96b7771d..77615b4d 100644
--- a/dgpsip.c
+++ b/dgpsip.c
@@ -31,7 +31,8 @@ int dgpsip_open(struct gps_context_t *context, const char *dgpsserver)
(void)gethostname(hn, sizeof(hn));
(void)snprintf(buf,sizeof(buf), "HELO %s gpsd %s\r\nR\r\n",hn,VERSION);
(void)write(context->dsock, buf, strlen(buf));
- }
+ } else
+ gpsd_report(1, "Can't connect to DGPS server, netlib error %d\n", context->dsock);
opts = fcntl(context->dsock, F_GETFL);
if (opts >= 0)
@@ -89,3 +90,47 @@ void dgpsip_report(struct gps_device_t *session)
}
}
+/* maximum distance from DGPS server for it to be useful (meters) */
+#define DGPS_THRESHOLD 1600000
+
+void dgpsip_autoconnect(struct gps_context_t *context,
+ double lat, double lon,
+ const char *serverlist)
+/* tell the library to talk to the nearest DGPSIP server */
+{
+ char buf[BUFSIZ];
+ struct dgps_server_t {
+ double lat, lon;
+ char server[255];
+ double dist;
+ } keep, hold;
+ FILE *sfp = fopen(serverlist, "r");
+
+ if (sfp == NULL) {
+ gpsd_report(1, "no DGPS server list found.\n");
+ context->dsock = -2; /* don't try this again */
+ return;
+ }
+
+ keep.dist = DGPS_THRESHOLD;
+ keep.server[0] = '\0';
+ while (fgets(buf, (int)sizeof(buf), sfp)) {
+ char *cp = strchr(buf, '#');
+ if (cp)
+ *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);
+ if (hold.dist < keep.dist)
+ memcpy(&keep, &hold, sizeof(struct dgps_server_t));
+ }
+ }
+ (void)fclose(sfp);
+
+ if (keep.server[0] == '\0') {
+ gpsd_report(1, "no DGPS server within %d m\n", DGPS_THRESHOLD);
+ context->dsock = -2; /* don't try this again */
+ return;
+ }
+
+ (void)dgpsip_open(context, keep.server);
+}
diff --git a/gps.h b/gps.h
index 5223bc75..263affcb 100644
--- a/gps.h
+++ b/gps.h
@@ -195,7 +195,7 @@ extern double timestamp(void);
extern double iso8601_to_unix(char *);
extern /*@observer@*/char *unix_to_iso8601(double t, /*@ out @*/char[], int len);
extern double gpstime_to_unix(int, double);
-/* extern double earth_distance(double, double, double, double); */
+extern double earth_distance(double, double, double, double);
extern double wgs84_separation(double lat, double lon);
extern int gpsd_units(void);
diff --git a/gpsd.c b/gpsd.c
index b794fe32..c4482891 100644
--- a/gpsd.c
+++ b/gpsd.c
@@ -48,6 +48,10 @@
#define QLEN 5
+/* Where to find the list of DGPS correction servers, if there is one */
+#define DGPS_SERVER_LIST "/usr/share/gpsd/dgpsip-servers"
+
+
/*
* The name of a tty device from which to pick up whatever the local
* owning group for tty devices is. Used when we drop privileges.
@@ -60,7 +64,7 @@ static bool in_background = false;
static jmp_buf restartbuf;
/*@ -initallelements -nullassign -nullderef @*/
static struct gps_context_t context = {0,
- false, 0, 0, 0, {'\0'}, 0,
+ false, 0, -1, 0, {'\0'}, 0,
LEAP_SECONDS, CENTURY_BASE,
#ifdef NTPSHM_ENABLE
{0},
@@ -138,13 +142,13 @@ void gpsd_report(int errlevel, const char *fmt, ... )
static void usage(void)
{
- (void)printf("usage: gpsd [options] \n\
+ (void)printf("usage: gpsd [-d dgpsip-server] [-D n] [-F sockfile] [-P pidfile] [-S port] [-h] device...\n\
Options include: \n\
- -f string = set GPS device name \n\
- -S integer (default %s) = set port for daemon \n\
-d host[:port] = set DGPS server \n\
+ -F sockfile = specift control socket location\n\
-P pidfile = set file to record process ID \n\
-D integer (default 0) = set debug level \n\
+ -S integer (default %s) = set port for daemon \n\
-h = help message \n",
DEFAULT_GPSD_PORT);
}
@@ -1037,10 +1041,8 @@ int main(int argc, char *argv[])
if (dgpsserver) {
int dsock = dgpsip_open(&context, dgpsserver);
- if (dsock >= 0) {
+ if (dsock >= 0)
FD_SET(dsock, &all_fds);
- } else
- gpsd_report(1, "Can't connect to DGPS server, netlib error %d\n", dsock);
}
#ifdef NTPSHM_ENABLE
@@ -1192,9 +1194,8 @@ int main(int argc, char *argv[])
}
/* be ready for DGPSIP reports */
- if (FD_ISSET(context.dsock, &rfds)) {
+ if (context.dsock >= 0 && FD_ISSET(context.dsock, &rfds))
dgpsip_poll(&context);
- }
/* read any commands that came in over control sockets */
for (cfd = 0; cfd < FD_SETSIZE; cfd++)
@@ -1212,7 +1213,6 @@ int main(int argc, char *argv[])
/* poll all active devices */
for (channel = channels; channel < channels + MAXDEVICES; channel++) {
-
if (!allocated_channel(channel))
continue;
@@ -1270,6 +1270,19 @@ int main(int argc, char *argv[])
#endif
}
+ /* may be time to hunt up a DGPSIP server */
+ if (context.fixcnt > 0 && context.dsock == -1) {
+ for (channel=channels; channel < channels+MAXDEVICES; channel++) {
+ if (channel->gpsdata.fix.mode < MODE_NO_FIX) {
+ dgpsip_autoconnect(&context,
+ channel->gpsdata.fix.latitude,
+ channel->gpsdata.fix.longitude,
+ DGPS_SERVER_LIST);
+ break;
+ }
+ }
+ }
+
/* accept and execute commands for all clients */
for (cfd = 0; cfd < FD_SETSIZE; cfd++) {
if (subscribers[cfd].active && FD_ISSET(cfd, &rfds)) {
diff --git a/gpsd.h b/gpsd.h
index 15e7179a..75096a3e 100644
--- a/gpsd.h
+++ b/gpsd.h
@@ -177,6 +177,8 @@ extern int dgpsip_open(struct gps_context_t *, const char *);
extern void dgpsip_poll(struct gps_context_t *);
extern void dgpsip_relay(struct gps_device_t *);
extern void dgpsip_report(struct gps_device_t *);
+extern void dgpsip_autoconnect(struct gps_context_t *,
+ double, double, const char *);
extern int gpsd_open(struct gps_device_t *);
extern bool gpsd_next_hunt_setting(struct gps_device_t *);
diff --git a/gpsd.spec.in b/gpsd.spec.in
index e5434d18..ed494109 100644
--- a/gpsd.spec.in
+++ b/gpsd.spec.in
@@ -72,6 +72,7 @@ cp xgpsspeed.ad "$RPM_BUILD_ROOT"%{_libdir}/X11/app-defaults/xgpsspeed
mkdir -p "$RPM_BUILD_ROOT"%{_sysconfdir}/hotplug/usb
cp gpsd.hotplug gpsd.usermap "$RPM_BUILD_ROOT"%{_sysconfdir}/hotplug/usb/
# additional gpsd-devel files
+mkdir -p "$RPM_BUILD_ROOT"%{_datadir}/gpsd
PYVERSION=`python -c "import sys; print sys.version[:3]"`
mkdir -p "$RPM_BUILD_ROOT"%{_libdir}/python${PYVERSION}/site-packages
cp gps.py gpsfake.py "$RPM_BUILD_ROOT"%{_libdir}/python${PYVERSION}/site-packages
@@ -99,6 +100,7 @@ cp gps.py gpsfake.py "$RPM_BUILD_ROOT"%{_libdir}/python${PYVERSION}/site-package
%{_mandir}/man1/sirfmon.1*
%{_sysconfdir}/hotplug/usb/gpsd.hotplug
%{_sysconfdir}/hotplug/usb/gpsd.usermap
+%{_datadir}/gpsd/dgps-servers
%{_libdir}/python*/site-packages/gps.py*
%files -n gpsd-devel
@@ -134,7 +136,8 @@ cp gps.py gpsfake.py "$RPM_BUILD_ROOT"%{_libdir}/python${PYVERSION}/site-package
and (3) a subtle error in the channel-assignment logic that only
showed up with multiple sessions active. In fact, the daemon code
no longer uses dynamic-memory allocation at all. Also, the code
- no longer relies on FIONREAD working.
+ no longer relies on FIONREAD working. The daemon now hunts for a
+ DGPSIP server within 1600000m if the user didn't specify one.
* Wed Jun 22 2005 Eric S. Raymond <esr@snark.thyrsus.com> - 2.26
- Time DOP and total DOP are now passed on from GPSes that report
diff --git a/gpsd.xml b/gpsd.xml
index 5bc3bb5f..77531a71 100644
--- a/gpsd.xml
+++ b/gpsd.xml
@@ -21,7 +21,7 @@
<arg choice='opt'>-f <replaceable>GPS-devicename</replaceable></arg>
<arg choice='opt'>-F <replaceable>control-socket</replaceable></arg>
<arg choice='opt'>-S <replaceable>listener-port</replaceable></arg>
- <arg choice='opt'>-d <replaceable>DGPS-server</replaceable></arg>
+ <arg choice='opt'>-d <replaceable>DGPSIP-server</replaceable></arg>
<arg choice='opt'>-n </arg>
<arg choice='opt'>-N </arg>
<arg choice='opt'>-h </arg>
@@ -56,10 +56,12 @@ protocol used by the USB version of the Garmin 18 and other Garmin USB
GPSes. <application>gpsd</application> effectively hides the
differences among these.</para>
-<para>Optionally, <application>gpsd</application> may get
-differential-GPS corrections from a ground station running a RTCM-S104
-server; this will improve user error by roughly a factor of four.
-See <xref linkend='accuracy'/> for discussion.</para>
+<para><application>gpsd</application> can use differential-GPS
+corrections from a ground station running a DGPSIP server that reports
+RTCM-S104 data; this will improve user error by roughly a factor of
+four. If no server is specified, <application>gpsd</application> will
+hunt for one. See <xref linkend='accuracy'/> and <xref
+linkend='files'/> for discussion.</para>
<para>The program accepts the following options:</para>
<variablelist remap='TP'>
@@ -781,6 +783,18 @@ device if no GPS device was specified on the command line does not
exist.</para>
</listitem>
</varlistentry>
+<varlistentry>
+<term><filename>/usr/share/gpsd/dgpsip-servers</filename></term>
+<listitem>
+<para>A text file listing DGPSIP servers worldwide. If no DGPSIP
+server is specified at startup (via the -d option)
+<application>gpsd</application> will look here to find the
+nearest one. Each line has three space-separated fields:
+latitude (decimal degrees), longitude (decimal degrees) and
+a server name (optionally followed by a colon and a port number).
+Text following # on a line is ignored. Blank lines are ignored.</para>
+</listitem>
+</varlistentry>
</variablelist>
</refsect1>
diff --git a/gpsutils.c b/gpsutils.c
index dc9e68d1..2cc081ac 100644
--- a/gpsutils.c
+++ b/gpsutils.c
@@ -165,7 +165,6 @@ double gpstime_to_unix(int week, double tow)
#define Deg2Rad(n) ((n) * DEG_2_RAD)
-#ifdef __UNUSED__
static double CalcRad(double lat)
/* earth's radius of curvature in meters at specified latitude.*/
{
@@ -206,13 +205,12 @@ double earth_distance(double lat1, double lon1, double lat2, double lon2)
// a very small amount due to rounding errors in the preceding
// calculations (this is prone to happen when the argument points
// are very close together). Thus we constrain it here.
- if (abs(a) > 1)
+ if (fabs(a) > 1)
a = 1;
else if (a < -1)
a = -1;
return CalcRad((lat1+lat2) / 2) * acos(a);
}
-#endif /* __UNUSED__ */
/*****************************************************************************