@@ -4,6 +4,7 @@ Repository head: | |||
A bug that prevented track interpolation has been fixed. | |||
We now get vertical error position and speed estimates from the | |||
u-blox driver rather than having to interpolate them. | |||
Some unusual AIS talker IDs (NMEA 4.0 station classes) are supported. | |||
chrpath is no longer a dependency for building and testing, and | |||
now defaults to 'no'. | |||
@@ -1190,6 +1190,7 @@ def substituter(target, source, env): | |||
('@VERSION@', gpsd_version), | |||
('@prefix@', env['prefix']), | |||
('@libdir@', env['libdir']), | |||
('@udevdir@', env['udevdir']), | |||
('@PYTHON@', sys.executable), | |||
('@DATE@', time.asctime()), | |||
('@MASTER@', 'DO NOT HAND_HACK! THIS FILE IS GENERATED'), | |||
@@ -1282,7 +1283,7 @@ if manbuilder: | |||
build = env.Alias('build', | |||
[libraries, binaries, python_targets, | |||
"gpsd.php", manpage_targets, | |||
"libgps.pc", "libgpsd.pc"]) | |||
"libgps.pc", "libgpsd.pc", "gpsd.rules"]) | |||
env.Default(*build) | |||
if qt_env: | |||
@@ -1760,6 +1761,9 @@ if env['python']: | |||
# another window, then run 'scons udev-test', then plug and unplug the | |||
# GPS ad libitum. All is well when you get fix reports each time a GPS | |||
# is plugged in. | |||
# | |||
# Note that a udev event can be triggered with an invocation like: | |||
# udevadm trigger --sysname-match=ttyUSB0 --action add | |||
Utility('udev-install', 'install', [ | |||
'mkdir -p ' + DESTDIR + env['udevdir'] + '/rules.d', | |||
@@ -73,6 +73,19 @@ The second 'n' is losing information that it shouldn't. | |||
Display update should not stop while this is going on. | |||
*** Time offset debugging in gpsmon *** | |||
Hall Murray: | |||
> The gpsmon logging stuff should include time stamps. | |||
> | |||
> There should be some way for gpsmon to display the time offset that it would | |||
> send to NTP via SHM. I don't see any obvious empty space on the screen. If | |||
> nothing else, it could use the PPS space or alternate with the PPS info, | |||
> perhaps via a keyboard command. | |||
> | |||
> Or perhaps a higher level keyboard command to switch into timekeeping | |||
> debugging mode rather than position debugging mode. | |||
**** Speed, mode and rate-changes in client-mode gpsmon. | |||
Are not implemented. In theory they could be. | |||
@@ -88,6 +101,28 @@ We caw now *really* measure latency from GPS top of second when it has | |||
1PPS. Add this capability to gpsprof and revise the "Where's the | |||
Latency?" white paper. | |||
*** Low-pwer autoconfiguration in the uBlox driver *** | |||
Anthony Stirk <upuaut@gmail.com> writes on Wed May 21 06:09:00 2014: | |||
The low power modes are really good on the ublox modules (especially the | |||
MAX7's) however a word of warning. | |||
We use the 1 sec cyclic mode on our balloon trackers but if the module | |||
looses satellites or is jammed out (cheap Chinese cameras do it) the ublox | |||
modules seem to hang and become unresponsive. To mitigate against this you | |||
need to put the module back in max performance mode as soon as the | |||
satellites drops below 4. | |||
I'm not sure for most applications the low power mode needs to be used at | |||
all on the newer ublox modules. The values for the MAX-7Q are 22mA (6Q | |||
50mA) under acquire, tracking (i.e locked and in max performance) current | |||
at is 17mA (39mA 6Q) and power saving reduces this to 5mA or less (15mA on | |||
the 6Q). We've observed the issue on the 6 and 7 series. | |||
A possibility: drop the chip to low-power mode when it can see > 4 | |||
sats, revert to normal otherwise. | |||
*** Dispatcher/network issues | |||
**** Reading AISHub data via UDP confuses xgps with short writes | |||
@@ -20,8 +20,8 @@ OLDPWD=`pwd` | |||
cd ${TMPDIR} | |||
getbuildlog gpsd $logs || true | |||
grep -c -- '--- test' * | grep -E ':0$' | sed 's,^gpsd_[^_]*_\([^.]*\)\.log:0,\1: no regressions,' | |||
grep -- '--- test' * | sed 's,^gpsd_[^_]*_\([^.]*\).*\./test/\([^.]*\).*,\1 \2,' | sort -u | |||
grep -c -E -- '--- (./)?test' * | grep -E ':0$' | sed 's,^gpsd_[^_]*_\([^.]*\)\.log:0,\1: no regressions,' | |||
grep -E -- '--- (./)?test' * | sed 's,\s2013.*,,;s,^gpsd_[^_]*_\([^.]*\)\.log:--- ,\1 ,' | sort -u | |||
cd ${OLDPWD} | |||
rm -rf ${TMPDIR} | |||
@@ -183,6 +183,8 @@ bool ais_binary_decode(const int debug, | |||
ais->type6.dac = UBITS(72, 10); | |||
ais->type6.fid = UBITS(82, 6); | |||
ais->type6.bitcount = bitlen - 88; | |||
/* not strictly required - helps stability in testing */ | |||
(void)memset(ais->type6.bitdata, '\0', sizeof(ais->type6.bitdata)); | |||
structured = false; | |||
/* Inland AIS */ | |||
if (ais->type6.dac == 200) { | |||
@@ -454,6 +456,8 @@ bool ais_binary_decode(const int debug, | |||
ais->type8.dac = UBITS(40, 10); | |||
ais->type8.fid = UBITS(50, 6); | |||
ais->type8.bitcount = bitlen - 56; | |||
/* not strictly required - helps stability in testing */ | |||
(void)memset(ais->type8.bitdata, '\0', sizeof(ais->type8.bitdata)); | |||
structured = false; | |||
if (ais->type8.dac == 1) | |||
switch (ais->type8.fid) { | |||
@@ -236,21 +236,20 @@ static bool sirf_write(struct gps_device_t *session, unsigned char *msg) | |||
unsigned int crc; | |||
size_t i, len; | |||
bool ok; | |||
unsigned int type = (unsigned int)msg[4]; | |||
/* | |||
* Control strings spaced too closely together confuse the SiRF | |||
* IV. This wasn't an issue on older SiRFs, but they've gone to a | |||
* lower-powered processor that apparently has trouble keeping up. | |||
* Now you have to wait for the ACK, otherwise chaos ensues. | |||
* Add instrumentation to reveal when this may happen. | |||
*/ | |||
if (time(NULL) - session->driver.sirf.last_send > SIRF_RETRY_TIME) | |||
session->driver.sirf.need_ack = false; | |||
/* can also be false because ACK was received after last send */ | |||
if (session->driver.sirf.need_ack) { | |||
if (session->driver.sirf.need_ack > 0) { | |||
gpsd_report(session->context->debug, LOG_WARN, | |||
"SiRF: write of control type %02x failed, awaiting ACK.\n", | |||
msg[4]); | |||
return false; | |||
"SiRF: warning, write of control type %02x while awaiting ACK for %02x.\n", | |||
type, session->driver.sirf.need_ack); | |||
} | |||
len = (size_t) ((msg[2] << 8) | msg[3]); | |||
@@ -266,11 +265,10 @@ static bool sirf_write(struct gps_device_t *session, unsigned char *msg) | |||
msg[len + 5] = (unsigned char)(crc & 0x00ff); | |||
gpsd_report(session->context->debug, LOG_PROG, | |||
"SiRF: Writing control type %02x:\n", msg[4]); | |||
"SiRF: Writing control type %02x:\n", type); | |||
ok = (gpsd_write(session, (const char *)msg, len+8) == (ssize_t) (len+8)); | |||
session->driver.sirf.need_ack = true; | |||
session->driver.sirf.last_send = time(NULL); | |||
session->driver.sirf.need_ack = type; | |||
return (ok); | |||
} | |||
@@ -939,13 +937,6 @@ static gps_mask_t sirf_msg_sysparam(struct gps_device_t *session, | |||
session->driver.sirf.degraded_timeout = (unsigned char)getub(buf, 10); | |||
session->driver.sirf.dr_timeout = (unsigned char)getub(buf, 11); | |||
session->driver.sirf.track_smooth_mode = (unsigned char)getub(buf, 12); | |||
#ifdef RECONFIGURE_ENABLE | |||
if (!session->context->readonly) { | |||
gpsd_report(session->context->debug, LOG_PROG, | |||
"SiRF: Setting Navigation Parameters\n"); | |||
(void)sirf_write(session, modecontrol); | |||
} | |||
#endif /* RECONFIGURE_ENABLE */ | |||
return 0; | |||
} | |||
@@ -1240,14 +1231,14 @@ gps_mask_t sirf_parse(struct gps_device_t * session, unsigned char *buf, | |||
case 0x0b: /* Command Acknowledgement MID 11 */ | |||
gpsd_report(session->context->debug, LOG_PROG, | |||
"SiRF: ACK 0x0b: %02x\n", getub(buf, 1)); | |||
session->driver.sirf.need_ack = false; | |||
session->driver.sirf.need_ack = 0; | |||
return 0; | |||
case 0x0c: /* Command NAcknowledgement MID 12 */ | |||
gpsd_report(session->context->debug, LOG_PROG, | |||
"SiRF: NAK 0x0c: %02x\n", getub(buf, 1)); | |||
/* ugh -- there's no alternative but silent failure here */ | |||
session->driver.sirf.need_ack = false; | |||
session->driver.sirf.need_ack = 0; | |||
return 0; | |||
case 0x0d: /* Visible List MID 13 */ | |||
@@ -1400,12 +1391,11 @@ static void sirfbin_event_hook(struct gps_device_t *session, event_t event) | |||
} | |||
if (event == event_configure) { | |||
#ifdef __UNUSED__ | |||
/* might not be time for the next init string yet */ | |||
if (time(NULL) - session->driver.sirf.last_send > SIRF_RETRY_TIME) | |||
session->driver.sirf.need_ack = false; | |||
/* can also be false because ACK was received after last send */ | |||
if (session->driver.sirf.need_ack) | |||
if (session->driver.sirf.need_ack > 0) | |||
return; | |||
#endif /* UNUSED */ | |||
switch (session->driver.sirf.cfg_stage++) { | |||
case 0: | |||
@@ -1419,12 +1409,6 @@ static void sirfbin_event_hook(struct gps_device_t *session, event_t event) | |||
break; | |||
case 2: | |||
gpsd_report(session->context->debug, LOG_PROG, | |||
"SiRF: Requesting navigation parameters...\n"); | |||
(void)sirf_write(session, navparams); | |||
break; | |||
case 3: | |||
#ifdef RECONFIGURE_ENABLE | |||
/* unset MID 64 first since there is a flood of them */ | |||
gpsd_report(session->context->debug, LOG_PROG, "SiRF: unset MID 64...\n"); | |||
@@ -1432,13 +1416,33 @@ static void sirfbin_event_hook(struct gps_device_t *session, event_t event) | |||
(void)sirf_write(session, unsetmidXX); | |||
break; | |||
case 3: | |||
/* | |||
* The response to this request will save the navigation | |||
* parameters so they can be reverted before close. | |||
*/ | |||
gpsd_report(session->context->debug, LOG_PROG, | |||
"SiRF: Requesting navigation parameters...\n"); | |||
(void)sirf_write(session, navparams); | |||
break; | |||
case 4: | |||
#ifdef RECONFIGURE_ENABLE | |||
if (!session->context->readonly) { | |||
gpsd_report(session->context->debug, LOG_PROG, | |||
"SiRF: Setting Navigation Parameters\n"); | |||
(void)sirf_write(session, modecontrol); | |||
} | |||
#endif /* RECONFIGURE_ENABLE */ | |||
break; | |||
case 5: | |||
gpsd_report(session->context->debug, LOG_PROG, | |||
"SiRF: Requesting periodic ecef reports...\n"); | |||
(void)sirf_write(session, requestecef); | |||
break; | |||
case 5: | |||
case 6: | |||
gpsd_report(session->context->debug, LOG_PROG, | |||
"SiRF: Requesting periodic tracker reports...\n"); | |||
(void)sirf_write(session, requesttracker); | |||
@@ -1460,7 +1464,9 @@ static void sirfbin_event_hook(struct gps_device_t *session, event_t event) | |||
gpsd_report(session->context->debug, LOG_PROG, | |||
"SiRF: Enabling PPS message...\n"); | |||
(void)sirf_write(session, enablemid52); | |||
break; | |||
case 10: | |||
/* SiRF recommends at least 57600 for SiRF IV nav data */ | |||
if (session->gpsdata.dev.baudrate >= 57600) { | |||
/* fast enough, turn on nav data */ | |||
@@ -1474,6 +1480,13 @@ static void sirfbin_event_hook(struct gps_device_t *session, event_t event) | |||
(void)sirf_write(session, disablesubframe); | |||
} | |||
break; | |||
case 11: | |||
gpsd_report(session->context->debug, LOG_PROG, "SiRF: disable MID 7, 28, 29, 30, 31...\n"); | |||
putbyte(unsetmidXX, 5, 0x05); | |||
(void)sirf_write(session, unsetmidXX); | |||
break; | |||
#endif /* RECONFIGURE_ENABLE */ | |||
default: | |||
/* initialization is done */ | |||
@@ -96,7 +96,7 @@ tested = 2.34 | |||
rating = good | |||
logs = ublox-sirf1.log | |||
notes = ublox-sirf1.log was made from a device with ublox firmware and | |||
may not be typical of SirF-1 chips. | |||
may not be typical of SiRF-1 chips. | |||
[SiRF-2] | |||
type = engine | |||
@@ -135,6 +135,7 @@ nmea = 3.01 | |||
uses = GenericSiRF | |||
rating = poor | |||
notes = Low power usage, but poor sensitivity and very long startup. | |||
Resets to 4800N1 every time it is unplugged. | |||
[MSB2122] | |||
type = engine | |||
@@ -783,7 +784,7 @@ logs = foretrex-201.log | |||
[Garmin GPS 10x] | |||
type = device | |||
chipset = SiRFstarIII | |||
uses = SiRF-3 | |||
date = 2010-07-18 | |||
model = GPS 10x | |||
nmea = 2.0 and 2.30 | |||
@@ -1034,7 +1035,7 @@ interfaces = USB | |||
submitter = Richard Allen <rsaxvc@gmail.com> | |||
vendor = Garmin | |||
techdoc = http://static.garmincdn.com/pumac/Montana_600_OM_EN.pdf | |||
chipset = STA2065 | |||
engine = STA2065 | |||
engine = unknown | |||
rating = good | |||
tested = 3.6 | |||
@@ -1129,6 +1130,20 @@ notes = This receiver does not support PPS timing output. Some versions of | |||
firmware do not support WAAS, though updates may be available for a | |||
fee from GlobalSat. | |||
[BU-355] | |||
type = device | |||
vendor = GlobalSat | |||
packaging = mouse | |||
uses = SiRF-3 | |||
interfaces = USB | |||
usbchip = pl2303 | |||
tested = 3.10 | |||
rating = good | |||
eval_unit = esr | |||
nmea = 2.3 | |||
notes = This receiver does not support PPS timing output. Does support | |||
WAAS/EGNOS, unlike some 353s. | |||
[BU-353-S4] | |||
type = device | |||
vendor = GlobalSat | |||
@@ -1139,7 +1154,7 @@ interfaces = USB | |||
usbchip = pl2303 | |||
tested = 3.7 | |||
rating = poor | |||
eval-unit = gary | |||
eval-unit = esr,gary | |||
nmea = 3.0 | |||
notes = This receiver does not support PPS timing output. Much like the | |||
BU-353 except for using a SiRFStar IV chip. Has poor | |||
@@ -1237,7 +1252,7 @@ tested = regression | |||
rating = excellent | |||
submitter = Pascal F. Martin <pascal.martin@cox.net> | |||
notes = Sometimes sold under the brand name "Rayming", but that vendor | |||
seems to have disappeared. Chipset said ton be SiRF 2 but the | |||
seems to have disappeared. Chipset said to be SiRF 2 but the | |||
output looks more like old Garmin GPSes. | |||
[ND100] | |||
@@ -1761,7 +1776,6 @@ logs = nl551e.log | |||
[BT-451] | |||
type = device | |||
chipset = ANTARIS ATR062x | |||
engine= ANTARIS4 | |||
date = 2009-12-09 | |||
location = Lithuania, 55.8N 23.6E | |||
@@ -1774,6 +1788,7 @@ techdoc = http://www.navilock.de/produkte/gruppen/28/Nicht_mehr_lieferbare_Artik | |||
tested = 2.39 | |||
vendor = NaviLock | |||
logs = bt451.log | |||
notes = Uses the ANTARIS4 ATR062x variant. | |||
#% NavMan | |||
@@ -149,6 +149,14 @@ static struct gps_context_t context; | |||
static int sd_socket_count = 0; | |||
#endif | |||
/* work around the unfinished ipv6 implementation on hurd */ | |||
#ifdef __GNU__ | |||
#ifndef IPV6_TCLASS | |||
#define IPV6_TCLASS 67 | |||
#endif | |||
#endif | |||
static volatile sig_atomic_t signalled; | |||
static void onsig(int sig) | |||
@@ -528,6 +536,7 @@ struct subscriber_t | |||
int fd; /* client file descriptor. -1 if unused */ | |||
timestamp_t active; /* when subscriber last polled for data */ | |||
struct policy_t policy; /* configurable bits */ | |||
pthread_mutex_t mutex; /* serialize access to fd */ | |||
}; | |||
#ifdef LIMITED_MAX_CLIENTS | |||
@@ -543,6 +552,16 @@ static struct subscriber_t subscribers[MAXSUBSCRIBERS]; /* indexed by client fil | |||
#define UNALLOCATED_FD -1 | |||
static void lock_subscriber(struct subscriber_t *sub) | |||
{ | |||
(void)pthread_mutex_lock(&sub->mutex); | |||
} | |||
static void unlock_subscriber(struct subscriber_t *sub) | |||
{ | |||
(void)pthread_mutex_unlock(&sub->mutex); | |||
} | |||
static /*@null@*//*@observer@ */ struct subscriber_t *allocate_client(void) | |||
/* return the address of a subscriber structure allocated for a new session */ | |||
{ | |||
@@ -564,8 +583,11 @@ static void detach_client(struct subscriber_t *sub) | |||
/* detach a client and terminate the session */ | |||
{ | |||
char *c_ip; | |||
if (sub->fd == UNALLOCATED_FD) | |||
lock_subscriber(sub); | |||
if (sub->fd == UNALLOCATED_FD) { | |||
unlock_subscriber(sub); | |||
return; | |||
} | |||
c_ip = netlib_sock2ip(sub->fd); | |||
(void)shutdown(sub->fd, SHUT_RDWR); | |||
gpsd_report(context.debug, LOG_SPIN, | |||
@@ -587,6 +609,7 @@ static void detach_client(struct subscriber_t *sub) | |||
sub->policy.split24 = false; | |||
sub->policy.devpath[0] = '\0'; | |||
sub->fd = UNALLOCATED_FD; | |||
unlock_subscriber(sub); | |||
/*@+mustfreeonly@*/ | |||
} | |||
@@ -2103,8 +2126,10 @@ int main(int argc, char *argv[]) | |||
"running with effective user ID %d\n", geteuid()); | |||
#ifdef SOCKET_EXPORT_ENABLE | |||
for (i = 0; i < NITEMS(subscribers); i++) | |||
for (i = 0; i < NITEMS(subscribers); i++) { | |||
subscribers[i].fd = UNALLOCATED_FD; | |||
(void)pthread_mutex_init(&subscribers[i].mutex, NULL); | |||
} | |||
#endif /* SOCKET_EXPORT_ENABLE*/ | |||
/*@-compdef -compdestroy@*/ | |||
@@ -2318,10 +2343,13 @@ int main(int argc, char *argv[]) | |||
if (sub->active == 0) | |||
continue; | |||
lock_subscriber(sub); | |||
if (FD_ISSET(sub->fd, &rfds)) { | |||
char buf[BUFSIZ]; | |||
int buflen; | |||
unlock_subscriber(sub); | |||
gpsd_report(context.debug, LOG_PROG, | |||
"checking client(%d)\n", | |||
sub_index(sub)); | |||
@@ -2346,6 +2374,8 @@ int main(int argc, char *argv[]) | |||
detach_client(sub); | |||
} | |||
} else { | |||
unlock_subscriber(sub); | |||
if (!sub->policy.watcher | |||
&& timestamp() - sub->active > COMMAND_TIMEOUT) { | |||
gpsd_report(context.debug, LOG_WARN, | |||
@@ -546,8 +546,7 @@ struct gps_device_t { | |||
#endif /* GEOSTAR_ENABLE */ | |||
#ifdef SIRF_ENABLE | |||
struct { | |||
bool need_ack; /* if NZ we're awaiting ACK */ | |||
time_t last_send; /* for tracking send timeouts */ | |||
unsigned int need_ack; /* if NZ we're awaiting ACK */ | |||
unsigned int cfg_stage; /* configuration stage counter */ | |||
unsigned int driverstate; /* for private use */ | |||
#define SIRF_LT_231 0x01 /* SiRF at firmware rev < 231 */ | |||
@@ -12,42 +12,42 @@ | |||
# | |||
# The following setup works on Debian and Ubuntu - something similar | |||
# will apply on other distributions: | |||
# | |||
# | |||
# /lib/udev/rules.d/25-gpsd.rules | |||
# /lib/udev/gpsd.hotplug | |||
# | |||
# | |||
# Setting the link in /lib/udev/rules.d activates the rule and determines | |||
# when to run it on boot (similar to init.d processing). | |||
SUBSYSTEM!="tty", GOTO="gpsd_rules_end" | |||
# Prolific Technology, Inc. PL2303 Serial Port [linux module: pl2303] | |||
ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", SYMLINK+="gps%n", RUN+="/lib/udev/gpsd.hotplug" | |||
ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug" | |||
# ATEN International Co., Ltd UC-232A Serial Port [linux module: pl2303] | |||
ATTRS{idVendor}=="0557", ATTRS{idProduct}=="2008", SYMLINK+="gps%n", RUN+="/lib/udev/gpsd.hotplug" | |||
ATTRS{idVendor}=="0557", ATTRS{idProduct}=="2008", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug" | |||
# PS-360 OEM (GPS sold with MS Street and Trips 2005) [linux module: pl2303] | |||
ATTRS{idVendor}=="067b", ATTRS{idProduct}=="aaa0", SYMLINK+="gps%n", RUN+="/lib/udev/gpsd.hotplug" | |||
ATTRS{idVendor}=="067b", ATTRS{idProduct}=="aaa0", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug" | |||
# FTDI 8U232AM / FT232 [linux module: ftdi_sio] | |||
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="gps%n", RUN+="/lib/udev/gpsd.hotplug" | |||
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug" | |||
# Cypress M8/CY7C64013 (Delorme uses these) [linux module: cypress_m8] | |||
ATTRS{idVendor}=="1163", ATTRS{idProduct}=="0100", SYMLINK+="gps%n", RUN+="/lib/udev/gpsd.hotplug" | |||
ATTRS{idVendor}=="1163", ATTRS{idProduct}=="0100", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug" | |||
# Cypress M8/CY7C64013 (DeLorme LT-40) | |||
ATTRS{idVendor}=="1163", ATTRS{idProduct}=="0200", SYMLINK+="gps%n", RUN+="/lib/udev/gpsd.hotplug" | |||
ATTRS{idVendor}=="1163", ATTRS{idProduct}=="0200", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug" | |||
# Garmin International GPSmap, various models (tested with Garmin GPS 18 USB) [linux module: garmin_gps] | |||
ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", SYMLINK+="gps%n", RUN+="/lib/udev/gpsd.hotplug" | |||
ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug" | |||
# Cygnal Integrated Products, Inc. CP210x Composite Device (Used by Holux m241 and Wintec grays2 wbt-201) [linux module: cp210x] | |||
ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="gps%n", RUN+="/lib/udev/gpsd.hotplug" | |||
ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug" | |||
# Cygnal Integrated Products, Inc. [linux module: cp210x] | |||
ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea71", SYMLINK="gps%n", RUN+="/lib/udev/gpsd.hotplug" | |||
ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea71", SYMLINK="gps%n", RUN+="@udevdir@/gpsd.hotplug" | |||
# u-blox AG, u-blox 5 (tested with Navilock NL-402U) [linux module: cdc_acm] | |||
ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a5", SYMLINK="gps%n", RUN+="/lib/udev/gpsd.hotplug" | |||
ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a5", SYMLINK="gps%n", RUN+="@udevdir@/gpsd.hotplug" | |||
# u-blox AG, u-blox 6 (tested with GNSS Evaluation Kit TCXO) [linux module: cdc_acm] | |||
ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a6", SYMLINK="gps%n", RUN+="/lib/udev/gpsd.hotplug" | |||
ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a6", SYMLINK="gps%n", RUN+="@udevdir@/gpsd.hotplug" | |||
# MediaTek (tested with HOLUX M-1200E) [linux module: cdc_acm] | |||
ATTRS{idVendor}=="0e8d", ATTRS{idProduct}=="3329", SYMLINK="gps%n", RUN+="/lib/udev/gpsd.hotplug" | |||
ATTRS{idVendor}=="0e8d", ATTRS{idProduct}=="3329", SYMLINK="gps%n", RUN+="@udevdir@/gpsd.hotplug" | |||
# Telit wireless solutions (tested with HE910G) [linux module: cdc_acm] | |||
ATTRS{interface}=="Telit Wireless Module Port", ATTRS{bInterfaceNumber}=="06", SYMLINK="gps%n", RUN+="/lib/udev/gpsd.hotplug" | |||
ATTRS{interface}=="Telit Wireless Module Port", ATTRS{bInterfaceNumber}=="06", SYMLINK="gps%n", RUN+="@udevdir@/gpsd.hotplug" | |||
ACTION=="remove", RUN+="/lib/udev/gpsd.hotplug" | |||
ACTION=="remove", RUN+="@udevdir@/gpsd.hotplug" | |||
LABEL="gpsd_rules_end" |
@@ -164,7 +164,7 @@ No | |||
T}:T{ | |||
numeric | |||
T}:T{ | |||
Latitude in degrees: +/\- signifies West/East\&. Present | |||
Latitude in degrees: +/\- signifies North/South\&. Present | |||
when mode is 2 or 3\&. | |||
T} | |||
T{ | |||
@@ -174,7 +174,7 @@ No | |||
T}:T{ | |||
numeric | |||
T}:T{ | |||
Longitude in degrees: +/\- signifies North/South\&. Present | |||
Longitude in degrees: +/\- signifies East/West\&. Present | |||
when mode is 2 or 3\&. | |||
T} | |||
T{ | |||
@@ -3019,11 +3019,11 @@ By default, certain scaling and conversion operations are performed for JSON out | |||
.PP | |||
Subframe support is always compiled into | |||
gpsd | |||
but many GPS do not output Subframe data or the | |||
but many GPSes do not output subframe data or the | |||
gpsd | |||
driver may not support Subframes\&. | |||
driver may not support subframes\&. | |||
.PP | |||
Subframe packets are dumped as JSON objects with class "SUBFRAME"\&. Each Subframe report object contains a "frame" field giving the subframe number, a "tSV" field for the transmitting satellite number, a "TOW17" field containing the 17 MSBs of the start of the next 12\-second message and a "scaled" field telling whether the remainder of the fields are dumped in scaled or unscaled form\&. It will also contain a "device" field naming the data source\&. Each SUBFRAME object will have a sub\-object specific to that subframe page type\&. Those sub\-object fields have names and types similar to those specified in the IS\-GPS\-200E document; each message field table may be directly interpreted as a specification for the members of the corresponding JSON object type\&. | |||
Subframe packets are dumped as JSON objects with class "SUBFRAME"\&. Each subframe report object contains a "frame" field giving the subframe number, a "tSV" field for the transmitting satellite number, a "TOW17" field containing the 17 MSBs of the start of the next 12\-second message and a "scaled" field telling whether the remainder of the fields are dumped in scaled or unscaled form\&. It will also contain a "device" field naming the data source\&. Each SUBFRAME object will have a sub\-object specific to that subframe page type\&. Those sub\-object fields have names and types similar to those specified in the IS\-GPS\-200E document; each message field table may be directly interpreted as a specification for the members of the corresponding JSON object type\&. | |||
.SH "SEE ALSO" | |||
.PP | |||
\fBgpsd\fR(8), | |||
@@ -3200,7 +3200,7 @@ void json_aivdm_dump(const struct ais_t *ais, | |||
"\"name\":\"%s\",\"lon\":%.4f," | |||
"\"lat\":%.4f,\"accuracy\":%s,\"to_bow\":%u," | |||
"\"to_stern\":%u,\"to_port\":%u,\"to_starboard\":%u," | |||
"\"epfd\"%u,\"epfd_text\":\"%s\"," | |||
"\"epfd\":%u,\"epfd_text\":\"%s\"," | |||
"\"second\":%u,\"regional\":%u," | |||
"\"off_position\":%s,\"raim\":%s," | |||
"\"virtual_aid\":%s}\r\n", | |||
@@ -144,14 +144,14 @@ Others may be reported or not depending on the fix quality.</para> | |||
<entry>lat</entry> | |||
<entry>No</entry> | |||
<entry>numeric</entry> | |||
<entry>Latitude in degrees: +/- signifies West/East. Present | |||
<entry>Latitude in degrees: +/- signifies North/South. Present | |||
when mode is 2 or 3.</entry> | |||
</row> | |||
<row> | |||
<entry>lon</entry> | |||
<entry>No</entry> | |||
<entry>numeric</entry> | |||
<entry>Longitude in degrees: +/- signifies North/South. Present | |||
<entry>Longitude in degrees: +/- signifies East/West. Present | |||
when mode is 2 or 3.</entry> | |||
</row> | |||
<row> | |||
@@ -2352,12 +2352,12 @@ decimeters. Various other scaling conversions are described in | |||
<refsect1 id='subframe'><title>SUBFRAME DUMP FORMATS</title> | |||
<para>Subframe support is always compiled into | |||
<application>gpsd</application> but many GPS do not output Subframe data | |||
or the <application>gpsd</application> driver may not support Subframes. | |||
<application>gpsd</application> but many GPSes do not output subframe data | |||
or the <application>gpsd</application> driver may not support subframes. | |||
</para> | |||
<para>Subframe packets are dumped as JSON objects with class "SUBFRAME". | |||
Each Subframe report object contains a "frame" field giving the subframe | |||
Each subframe report object contains a "frame" field giving the subframe | |||
number, a "tSV" field for the transmitting satellite number, a "TOW17" | |||
field containing the 17 MSBs of the start of the next 12-second message | |||
and a "scaled" field telling whether the remainder of the fields are | |||
@@ -94,7 +94,7 @@ static bool nmea_initialize(void) | |||
(void)mvwprintw(gpgsawin, 3, 1, "DOP: H= V= P="); | |||
(void)mvwprintw(gpgsawin, 4, 1, "PPS offset: "); | |||
#ifndef PPS_ENABLE | |||
(void)mvwaddstr(gpgsawin, 4, 13, "Not available"); | |||
(void)mvwaddstr(gpgsawin, 4, 13, "N/A"); | |||
#endif /* PPS_ENABLE */ | |||
(void)mvwprintw(gpgsawin, 5, 9, " GSA + PPS "); | |||
(void)wattrset(gpgsawin, A_NORMAL); | |||
@@ -151,7 +151,7 @@ static bool oncore_initialize(void) | |||
(void)wattrset(Aywin, A_BOLD); | |||
(void)mvwprintw(Aywin, 1, 1, "PPS offset:"); | |||
#ifndef PPS_ENABLE | |||
(void)mvwaddstr(Aywin, 1, 13, "Not available"); | |||
(void)mvwaddstr(Aywin, 1, 13, "N/A"); | |||
#endif /* PPS_ENABLE */ | |||
(void)mvwprintw(Aywin, 3, 4, " @@Ay "); | |||
(void)wattrset(Aywin, A_NORMAL); | |||
@@ -172,7 +172,7 @@ static bool sirf_initialize(void) | |||
display(mid7win, 2, 1, "Est. GPS Time: "); | |||
display(mid7win, 2, 27, "PPS offset: "); | |||
#ifndef PPS_ENABLE | |||
(void)mvwaddstr(mid7win, 2, 40, "Not available"); | |||
(void)mvwaddstr(mid7win, 2, 40, "N/A"); | |||
#endif /* PPS_ENABLE */ | |||
display(mid7win, 3, 8, " Packet type 7 (0x07) "); | |||
(void)wattrset(mid7win, A_NORMAL); | |||
@@ -76,7 +76,7 @@ static bool ubx_initialize(void) | |||
(void)wattrset(ppswin, A_BOLD); | |||
(void)mvwaddstr(ppswin, 1, 1, "PPS offset: "); | |||
#ifndef PPS_ENABLE | |||
(void)mvwaddstr(ppswin, 1, 13, "Not available"); | |||
(void)mvwaddstr(ppswin, 1, 13, "N/A"); | |||
#endif /* PPS_ENABLE */ | |||
display(ppswin, 2, 22, " PPS "); | |||
(void)wattrset(ppswin, A_NORMAL); | |||
@@ -90,18 +90,28 @@ PERMISSIONS | |||
* application, they'd just add complexity. | |||
* | |||
* The NMEA portion of the state machine allows the following talker IDs: | |||
* GP -- Global Positioning System. | |||
* GL -- GLONASS, according to IEIC 61162-1 | |||
* GN -- Mixed GPS and GLONASS data, according to IEIC 61162-1 | |||
* II -- Integrated Instrumentation (Raytheon's SeaTalk system). | |||
* IN -- Integrated Navigation (Garmin uses this). | |||
* WI -- Weather instrument (Airmar PB200, Radio Ocean ROWIND, Vaisala WXT520). | |||
* HC -- Heading/compass (Airmar PB200). | |||
* TI -- Turn indicator (Airmar PB200). | |||
* EC -- Electronic Chart Display & Information System (ECDIS) | |||
* SD -- Depth Sounder | |||
* P -- Vendor-specific sentence | |||
* $GP -- Global Positioning System. | |||
* $GL -- GLONASS, according to IEIC 61162-1 | |||
* $GN -- Mixed GPS and GLONASS data, according to IEIC 61162-1 | |||
* $II -- Integrated Instrumentation (Raytheon's SeaTalk system). | |||
* $IN -- Integrated Navigation (Garmin uses this). | |||
* $WI -- Weather instrument (Airmar PB200, Radio Ocean ROWIND, Vaisala WXT520). | |||
* $HC -- Heading/compass (Airmar PB200). | |||
* $TI -- Turn indicator (Airmar PB200). | |||
* $EC -- Electronic Chart Display & Information System (ECDIS) | |||
* $SD -- Depth Sounder | |||
* $P -- Vendor-specific sentence | |||
* | |||
* !AB -- NMEA 4.0 Base AIS station | |||
* !AD -- MMEA 4.0 Dependent AIS Base Station | |||
* !AI -- Mobile AIS station | |||
* !AN -- NMEA 4.0 Aid to Navigation AIS station | |||
* !AR -- NMEA 4.0 AIS Receiving Station | |||
* !AX -- NMEA 4.0 Repeater AIS station | |||
* !AS -- NMEA 4.0 Limited Base Station | |||
* !AT -- NMEA 4.0 AIS Transmitting Station | |||
* !BS -- Base AIS station (deprecated in NMEA 4.0) | |||
* !SA -- NMEA 4.0 Physical Shore AIS Station | |||
*/ | |||
enum | |||
@@ -415,11 +425,13 @@ static void nextstate(struct gps_packet_t *lexer, unsigned char c) | |||
lexer->state = AIS_LEAD_1; | |||
else if (c == 'B') | |||
lexer->state = AIS_LEAD_ALT1; | |||
else if (c == 'S') | |||
lexer->state = AIS_LEAD_ALT3; | |||
else | |||
lexer->state = GROUND_STATE; | |||
break; | |||
case AIS_LEAD_1: | |||
if (c == 'I') | |||
if (strchr("BDINRSTX", c) != NULL) | |||
lexer->state = AIS_LEAD_2; | |||
else | |||
lexer->state = GROUND_STATE; | |||
@@ -442,6 +454,18 @@ static void nextstate(struct gps_packet_t *lexer, unsigned char c) | |||
else | |||
lexer->state = GROUND_STATE; | |||
break; | |||
case AIS_LEAD_ALT3: | |||
if (c == 'A') | |||
lexer->state = AIS_LEAD_ALT4; | |||
else | |||
lexer->state = GROUND_STATE; | |||
break; | |||
case AIS_LEAD_ALT4: | |||
if (isalpha(c)) | |||
lexer->state = NMEA_LEADER_END; | |||
else | |||
lexer->state = GROUND_STATE; | |||
break; | |||
#if defined(TNT_ENABLE) || defined(GARMINTXT_ENABLE) || defined(ONCORE_ENABLE) | |||
case AT1_LEADER: | |||
switch (c) { | |||
@@ -21,10 +21,12 @@ | |||
"SIRF_ACK_LEAD_1", /* seen A of possible SiRF Ack */ | |||
"SIRF_ACK_LEAD_2", /* seen c of possible SiRF Ack */ | |||
"AIS_LEAD_1", /* seen A of possible marine AIS message */ | |||
"AIS_LEAD_2", /* seen I of possible marine AIS message */ | |||
"AIS_LEAD_ALT1", /* seen B of possible marine AIS message */ | |||
"AIS_LEAD_ALT2", /* seen S of possible marine AIS message */ | |||
"AIS_LEAD_1", /* seen initial A of possible AIS message */ | |||
"AIS_LEAD_2", /* seen second I/B/N/X of possible AIS message */ | |||
"AIS_LEAD_ALT1", /* seen initial B of possible AIS message */ | |||
"AIS_LEAD_ALT2", /* seen second S of possible AIS message */ | |||
"AIS_LEAD_ALT3", /* seen initial S of possible AIS message */ | |||
"AIS_LEAD_ALT4", /* seen second A of possible AIS message */ | |||
"SEATALK_LEAD_1", /* SeaTalk/Garmin packet leader 'I' */ | |||
"WEATHER_LEAD_1", /* Weather instrument packet leader 'W' */ | |||
@@ -21,10 +21,12 @@ | |||
SIRF_ACK_LEAD_1, /* seen A of possible SiRF Ack */ | |||
SIRF_ACK_LEAD_2, /* seen c of possible SiRF Ack */ | |||
AIS_LEAD_1, /* seen A of possible marine AIS message */ | |||
AIS_LEAD_2, /* seen I of possible marine AIS message */ | |||
AIS_LEAD_ALT1, /* seen B of possible marine AIS message */ | |||
AIS_LEAD_ALT2, /* seen S of possible marine AIS message */ | |||
AIS_LEAD_1, /* seen initial A of possible AIS message */ | |||
AIS_LEAD_2, /* seen second I/B/N/X of possible AIS message */ | |||
AIS_LEAD_ALT1, /* seen initial B of possible AIS message */ | |||
AIS_LEAD_ALT2, /* seen second S of possible AIS message */ | |||
AIS_LEAD_ALT3, /* seen initial S of possible AIS message */ | |||
AIS_LEAD_ALT4, /* seen second A of possible AIS message */ | |||
SEATALK_LEAD_1, /* SeaTalk/Garmin packet leader 'I' */ | |||
WEATHER_LEAD_1, /* Weather instrument packet leader 'W' */ | |||
@@ -1 +1 @@ | |||
#define REVISION "release-3.10-148-ga33bfd4" | |||
#define REVISION "release-3.10-180-g23b0752" |
@@ -44,7 +44,7 @@ | |||
{"class":"AIS","device":"stdin","type":19,"repeat":0,"mmsi":367059850,"scaled":true,"reserved":248,"speed":8.7,"accuracy":false,"lon":-88.8104,"lat":29.5437,"course":335.9,"heading":511,"second":46,"regional":4,"shipname":"CAPT.J.RIMES","shiptype":70,"shiptype_text":"Cargo - all ships of this type","to_bow":5,"to_stern":21,"to_port":4,"to_starboard":4,"epfd":1,"epfd_text":"GPS","raim":false,"dte":0,"assigned":false} | |||
{"class":"AIS","device":"stdin","type":20,"repeat":3,"mmsi":3669705,"scaled":true,"offset1":2182,"number1":5,"timeout1":7,"increment1":225,"offset2":0,"number2":0,"timeout2":0,"increment2":0,"offset3":0,"number3":0,"timeout3":0,"increment3":0,"offset4":0,"number4":0,"timeout4":0,"increment4":0} | |||
{"class":"AIS","device":"stdin","type":20,"repeat":0,"mmsi":3160097,"scaled":true,"offset1":47,"number1":1,"timeout1":7,"increment1":250,"offset2":2250,"number2":1,"timeout2":7,"increment2":1125,"offset3":856,"number3":5,"timeout3":7,"increment3":1125,"offset4":0,"number4":0,"timeout4":0,"increment4":0} | |||
{"class":"AIS","device":"stdin","type":21,"repeat":0,"mmsi":123456789,"scaled":true,"aid_type":20,"aid_type_text":"INVALID NAVAID TYPE","name":"CHINA ROSE MURPHY EXPRESS ALERT","lon":-122.6986,"lat":47.9206,"accuracy":false,"to_bow":5,"to_stern":5,"to_port":5,"to_starboard":5,"epfd"1,"epfd_text":"GPS","second":50,"regional":165,"off_position":false,"raim":false,"virtual_aid":false} | |||
{"class":"AIS","device":"stdin","type":21,"repeat":0,"mmsi":123456789,"scaled":true,"aid_type":20,"aid_type_text":"INVALID NAVAID TYPE","name":"CHINA ROSE MURPHY EXPRESS ALERT","lon":-122.6986,"lat":47.9206,"accuracy":false,"to_bow":5,"to_stern":5,"to_port":5,"to_starboard":5,"epfd":1,"epfd_text":"GPS","second":50,"regional":165,"off_position":false,"raim":false,"virtual_aid":false} | |||
{"class":"AIS","device":"stdin","type":22,"repeat":0,"mmsi":3160048,"scaled":true,"channel_a":2087,"channel_b":2088,"txrx":0,"power":false,"ne_lon":"-73.500000","ne_lat":"45.550000","sw_lon":"-80.166667","sw_lat":"42.333333","addressed":false,"band_a":false,"band_b":false,"zonesize":4} | |||
{"class":"AIS","device":"stdin","type":22,"repeat":1,"mmsi":17419965,"scaled":true,"channel_a":3584,"channel_b":8,"txrx":1,"power":true,"dest1":28144881,"dest2":268435519,"addressed":true,"band_a":false,"band_b":false,"zonesize":4} | |||
{"class":"AIS","device":"stdin","type":23,"repeat":0,"mmsi":2268120,"scaled":true,"ne_lon":"2.630000","ne_lat":"51.070000","sw_lon":"1.826667","sw_lat":"50.680000","stationtype":6,"stationtype_text":"Regional use and inland waterways","shiptype":0,"shiptype_text":"Not available","interval":9,"quiet":0} | |||
@@ -1,8 +1,8 @@ | |||
/* | |||
* Constants used for GPS time detection and rollover correction. | |||
* | |||
* Correct for week beginning 2014-01-16T00:00:00 | |||
* Correct for week beginning 2014-05-22T00:00:00 | |||
*/ | |||
#define CENTURY_BASE 201400 | |||
#define LEAPSECOND_NOW 16 | |||
#define GPS_WEEK_NOW 1776 | |||
#define GPS_WEEK_NOW 1793 |