Browse Source

Imported Upstream version 3.11

master
Bernd Zeimetz 6 years ago
parent
commit
8d0eb37525
55 changed files with 631 additions and 317 deletions
  1. +1
    -1
      INSTALL
  2. +4
    -2
      NEWS
  3. +81
    -21
      SConstruct
  4. +15
    -0
      TODO
  5. +1
    -1
      ais_json.c
  6. +2
    -2
      ais_json.i
  7. +8
    -17
      build.txt
  8. +41
    -73
      driver_ais.c
  9. +2
    -0
      driver_geostar.c
  10. +5
    -10
      driver_nmea2000.c
  11. +29
    -22
      driver_sirf.c
  12. +2
    -0
      driver_tsip.c
  13. +10
    -1
      driver_zodiac.c
  14. +19
    -0
      getsid.c
  15. +3
    -3
      gps.h
  16. +1
    -1
      gps/client.py
  17. +7
    -8
      gps/fake.py
  18. +5
    -5
      gps/gps.py
  19. +1
    -1
      gps/misc.py
  20. +10
    -8
      gps2udp.c
  21. +16
    -1
      gpscap.ini
  22. +9
    -0
      gpsctl.c
  23. +1
    -1
      gpsd.8
  24. +25
    -30
      gpsd.c
  25. +4
    -0
      gpsd.h-head
  26. +9
    -1
      gpsd.h-tail
  27. +14
    -14
      gpsd.rules.in
  28. +1
    -1
      gpsd.xml
  29. +1
    -1
      gpsd_json.5
  30. +26
    -10
      gpsd_json.c
  31. +1
    -1
      gpsd_json.xml
  32. +22
    -2
      gpsmon.1
  33. +48
    -17
      gpsmon.c
  34. +25
    -2
      gpsmon.xml
  35. +3
    -2
      gpspipe.c
  36. +4
    -4
      jsongen.py.in
  37. +11
    -12
      leapsecond.py
  38. +4
    -2
      libgps_shm.c
  39. +1
    -0
      libgps_sock.c
  40. +58
    -4
      libgpsd_core.c
  41. +1
    -0
      libgpsmm.cpp
  42. +7
    -7
      maskaudit.py.in
  43. +1
    -1
      netlib.c
  44. +13
    -10
      ppsthread.c
  45. +1
    -1
      revision.h
  46. +4
    -2
      shmexport.c
  47. +3
    -1
      systemd/gpsd.service
  48. +1
    -0
      systemd/gpsd.socket
  49. +13
    -0
      systemd/gpsdctl@.service
  50. +36
    -0
      test/sample.aivdm
  51. +2
    -0
      test/sample.aivdm.chk
  52. +2
    -0
      test/sample.aivdm.js.chk
  53. +2
    -0
      test/sample.aivdm.ju.chk
  54. +2
    -2
      timebase.h
  55. +13
    -12
      xgps

+ 1
- 1
INSTALL View File

@@ -121,7 +121,7 @@ should look something like this:
greeting line that's a JSON object describing GPSD's version.
Now plug in your GPS (or AIS receiver, or RTCM2 receiver).

3. Type '?WATCH={"enable":true,"json"};' to start raw and
3. Type '?WATCH={"enable":true,"json":true};' to start raw and
watcher modes. You should see lines beginning with '{' that are
JSON objects representing reports from your GPS; these are reports
in GPSD protocol.


+ 4
- 2
NEWS View File

@@ -1,12 +1,14 @@
GPSD project news

Repository head:
* Sat 23 Aug 2014 Eric S. Raymond <esr@snark.thyrsus.com> - 3.11
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'.
now defaults to 'no'. Full systemd support. Fixes for handling
large PPS offsets. Improved recovery from device flakeouts,
gpsmon argument parsing.

* Fri 22 Nov 2013 Eric S. Raymond <esr@snark.thyrsus.com> - 3.10
AIS: Adds gps2udp, an AIS data relay, split24 option supports


+ 81
- 21
SConstruct View File

@@ -24,7 +24,7 @@
# * Coveraging mode: gcc "-coverage" flag requires a hack for building the python bindings

# Release identification begins here
gpsd_version = "3.11~dev"
gpsd_version = "3.11"

# library version
libgps_version_current = 21
@@ -90,7 +90,8 @@ def _getoutput(cmd, input=None, cwd=None, env=None):
# Start by reading configuration variables from the cache
opts = Variables('.scons-option-cache')

systemd = os.path.exists("/usr/share/systemd/system")
systemd_dir = '/lib/systemd/system'
systemd = os.path.exists(systemd_dir)

# Set distribution-specific defaults here
imloads = True
@@ -146,7 +147,8 @@ boolopts = (
("clientdebug", True, "client debugging support"),
("oldstyle", True, "oldstyle (pre-JSON) protocol support"),
("libgpsmm", True, "build C++ bindings"),
("libQgpsmm", True, "build QT bindings"),
("libQgpsmm", True, "build QT bindings (deprecated alias)"),
("qt", True, "build QT bindings"),
# Daemon options
("reconfigure", True, "allow gpsd to change device settings"),
("controlsend", True, "allow gpsctl/gpsmon to change device settings"),
@@ -289,6 +291,7 @@ def installdir(dir, add_destdir=True):
if add_destdir:
wrapped = os.path.normpath(DESTDIR + os.path.sep + wrapped)
wrapped.replace("/usr/etc", "/etc")
wrapped.replace("/usr/lib/systemd", "/lib/systemd")
return wrapped

# Honor the specified installation prefix in link paths.
@@ -296,13 +299,9 @@ if env["sysroot"]:
env.Prepend(LIBPATH=[env["sysroot"] + installdir('libdir', add_destdir=False)])

# Don't hack RPATH unless libdir points somewhere that is not on the
# system default load path. /lib and /usr/lib should always be on
# this; listing them explicitly is a fail-safe against this ldconfig
# invocation not doing what we expect.
# minimum default load path.
if env["shared"]:
sysrpath = Split(_getoutput("ldconfig -v -N -X 2>/dev/null | sed -n -e '/^\//s/://p'"))
if env["libdir"] not in ["/usr/lib", "/lib"] + sysrpath:
announce("Prepending %s to RPATH." % installdir('libdir', False))
if env["libdir"] not in ["/usr/lib", "/lib"]:
env.Prepend(RPATH=[installdir('libdir')])

# Give deheader a way to set compiler flags
@@ -586,6 +585,18 @@ else:
bluezlibs = []
env["bluez"] = False

#in_port_t is not defined on Android
if not config.CheckType("in_port_t","#include <netinet/in.h>"):
announce("Did not find in_port_t typedef, assuming unsigned short int")
confdefs.append("typedef unsigned short int in_port_t;\n")

#SUN_LEN is not defined on Android
if not config.CheckDeclaration("SUN_LEN", "#include <sys/un.h>") and not config.CheckDeclaration("SUN_LEN", "#include <linux/un.h>"):
announce("SUN_LEN is not system-defined, using local definition")
confdefs.append("#ifndef SUN_LEN\n")
confdefs.append("#define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) + strlen((ptr)->sun_path))\n")
confdefs.append("#endif /* SUN_LEN */\n")

if config.CheckHeader(["bits/sockaddr.h", "linux/can.h"]):
confdefs.append("#define HAVE_LINUX_CAN_H 1\n")
announce("You have kernel CANbus available.")
@@ -626,7 +637,7 @@ else:

# check function after libraries, because some function require library
# for example clock_gettime() require librt on Linux
for f in ("daemon", "strlcpy", "strlcat", "clock_gettime"):
for f in ("daemon", "strlcpy", "strlcat", "clock_gettime","getsid"):
if config.CheckFunc(f):
confdefs.append("#define HAVE_%s 1\n" % f.upper())
else:
@@ -685,6 +696,7 @@ else:
# ifdef __cplusplus
extern "C" {
# endif
#include <string.h>
size_t strlcat(/*@out@*/char *dst, /*@in@*/const char *src, size_t size);
# ifdef __cplusplus
}
@@ -694,11 +706,23 @@ size_t strlcat(/*@out@*/char *dst, /*@in@*/const char *src, size_t size);
# ifdef __cplusplus
extern "C" {
# endif
#include <string.h>
size_t strlcpy(/*@out@*/char *dst, /*@in@*/const char *src, size_t size);
# ifdef __cplusplus
}
# endif
#endif
#ifndef HAVE_GETSID
# ifdef __cplusplus
extern "C" {
# endif
#include <unistd.h>
pid_t getsid(pid_t pid);
# ifdef __cplusplus
}
# endif
#endif


#define GPSD_CONFIG_H
''')
@@ -725,7 +749,7 @@ size_t strlcpy(/*@out@*/char *dst, /*@in@*/const char *src, size_t size);
env['BUILDERS']["HTML"] = Builder(action=htmlbuilder,
src_suffix=".xml", suffix=".html")

qt_network = env['libQgpsmm'] and config.CheckPKG('QtNetwork')
qt_network = env['qt'] and env['libQgpsmm'] and config.CheckPKG('QtNetwork')

env = config.Finish()

@@ -783,6 +807,7 @@ libgps_sources = [
"rtcm3_json.c",
"shared_json.c",
"strl.c",
"getsid.c",
]

if env['libgpsmm']:
@@ -1017,7 +1042,7 @@ cgps = env.Program('cgps', ['cgps.c'], parse_flags=gpslibs + ncurseslibs)
env.Depends(cgps, compiled_gpslib)

binaries = [gpsd, gpsdecode, gpsctl, gpsdctl, gpspipe, gps2udp, gpxlogger, lcdgps]
if ncurseslibs:
if env["ncurses"]:
binaries += [cgps, gpsmon]

# Test programs
@@ -1183,6 +1208,12 @@ if 'dev' in gpsd_version or not os.path.exists('leapseconds.cache'):
env.Precious(leapseconds_cache)
env.AlwaysBuild(leapseconds_cache)

if env['systemd']:
udevcommand = 'TAG+="systemd", ENV{SYSTEMD_WANTS}="gpsdctl@%k.service"'
else:
udevcommand = 'RUN+="%s/gpsd.hotplug"' %(env['udevdir'], )


# Instantiate some file templates. We'd like to use the Substfile builtin
# but it doesn't seem to work in scons 1.20
def substituter(target, source, env):
@@ -1190,7 +1221,7 @@ def substituter(target, source, env):
('@VERSION@', gpsd_version),
('@prefix@', env['prefix']),
('@libdir@', env['libdir']),
('@udevdir@', env['udevdir']),
('@udevcommand@', udevcommand),
('@PYTHON@', sys.executable),
('@DATE@', time.asctime()),
('@MASTER@', 'DO NOT HAND_HACK! THIS FILE IS GENERATED'),
@@ -1305,7 +1336,7 @@ headerinstall = [ env.Install(installdir('includedir'), x) for x in ("libgpsmm.h
binaryinstall = []
binaryinstall.append(env.Install(installdir('sbindir'), [gpsd, gpsdctl]))
binaryinstall.append(env.Install(installdir('bindir'), [gpsdecode, gpsctl, gpspipe, gps2udp, gpxlogger, lcdgps]))
if ncurseslibs:
if env["ncurses"]:
binaryinstall.append(env.Install(installdir('bindir'), [cgps, gpsmon]))
binaryinstall.append(LibraryInstall(env, installdir('libdir'), compiled_gpslib))
binaryinstall.append(LibraryInstall(env, installdir('libdir'), compiled_gpsdlib))
@@ -1347,6 +1378,7 @@ if qt_env:
pc_install.append(qt_env.Install(installdir('libdir'), 'libQgpsmm.prl'))



maninstall = []
for manpage in base_manpages.keys() + python_manpages.keys():
if not manbuilder and not os.path.exists(manpage):
@@ -1426,7 +1458,7 @@ for (target,sources,description,params) in splint_table:
# Putting in all these -U flags speeds up cppcheck and allows it to look
# at configurations we actually care about.
Utility("cppcheck", ["gpsd.h", "packet_names.h"],
"cppcheck -U__UNUSED__ -US_SPLINT_S -U__COVERITY__ -U__future__ -ULIMITED_MAX_CLIENTS -ULIMITED_MAX_DEVICES -UAF_UNSPEC -UINADDR_ANY -UFIXED_PORT_SPEED -UFIXED_STOP_BITS -U_WIN32 -U__CYGWIN__ -UPATH_MAX -UHAVE_STRLCAT -UHAVE_STRLCPY --template gcc --enable=all --inline-suppr --suppress='*:driver_proto.c' --force $SRCDIR")
"cppcheck -U__UNUSED__ -UUSE_QT -US_SPLINT_S -U__COVERITY__ -U__future__ -ULIMITED_MAX_CLIENTS -ULIMITED_MAX_DEVICES -UAF_UNSPEC -UINADDR_ANY -UFIXED_PORT_SPEED -UFIXED_STOP_BITS -U_WIN32 -U__CYGWIN__ -UPATH_MAX -UHAVE_STRLCAT -UHAVE_STRLCPY -UIPTOS_LOWDELAY -UIPV6_TCLASS -UTCP_NODELAY -UTIOCMIWAIT --template gcc --enable=all --inline-suppr --suppress='*:driver_proto.c' --force $SRCDIR")

# Experimental check with clang analyzer
Utility("scan-build", ["gpsd.h", "packet_names.h"],
@@ -1434,7 +1466,7 @@ Utility("scan-build", ["gpsd.h", "packet_names.h"],

# Sanity-check Python code.
pylint = Utility("pylint", ["jsongen.py", "maskaudit.py", python_built_extensions],
['''pylint --output-format=parseable --reports=n --include-ids=y --disable=F0001,C0103,C0111,C0301,C0302,C0322,C0324,C0323,C0321,R0201,R0801,R0902,R0903,R0904,R0911,R0912,R0913,R0914,R0915,R0924,W0201,W0232,W0401,W0403,W0141,W0142,W0603,W0614,W0621,E1101,E1102,F0401 jsongen.py leapsecond.py maskaudit.py gpsprof.py gpscat.py gpsfake.py gegps.py gps/*.py xgps'''])
['''pylint --rcfile=/dev/null --dummy-variables-rgx='^_' --msg-template="{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}" --reports=n --disable=F0001,C0103,C0111,C1001,C0301,C0302,C0322,C0324,C0323,C0321,R0201,R0801,R0902,R0903,R0904,R0911,R0912,R0913,R0914,R0915,W0110,W0201,W0121,W0232,W0234,W0401,W0403,W0141,W0142,W0603,W0614,W0621,E1101,E1102,F0401 jsongen.py leapsecond.py maskaudit.py gpsprof.py gpscat.py gpsfake.py gegps.py gps/*.py xgps'''])

# Check the documentation for bogons, too
Utility("xmllint", glob.glob("*.xml"),
@@ -1762,15 +1794,43 @@ if env['python']:
# GPS ad libitum. All is well when you get fix reports each time a GPS
# is plugged in.
#
# In case you are a systemd user you might also need to watch the
# journalctl output. Instead of the hotplug script the gpsdctl@.service
# unit will handle hotplugging together with the udev rules.
#
# Note that a udev event can be triggered with an invocation like:
# udevadm trigger --sysname-match=ttyUSB0 --action add

Utility('udev-install', 'install', [
if env['systemd']:
systemdinstall_target = [ env.Install(DESTDIR + systemd_dir, "systemd/%s" %(x,)) for x in ("gpsdctl@.service", "gpsd.service", "gpsd.socket") ]
systemd_install = env.Alias('systemd_install', systemdinstall_target)
systemd_uninstall = env.Command('systemd_uninstall', '', Flatten(Uninstall(Alias("systemd_install"))) or "")

env.AlwaysBuild(systemd_uninstall)
env.Precious(systemd_uninstall)


if env['systemd']:
hotplug_wrapper_install = []
else:
hotplug_wrapper_install = [
'cp $SRCDIR/gpsd.hotplug ' + DESTDIR + env['udevdir'],
'chmod a+x ' + DESTDIR + env['udevdir'] + '/gpsd.hotplug'
]

udev_install = Utility('udev-install', 'install', [
'mkdir -p ' + DESTDIR + env['udevdir'] + '/rules.d',
'cp $SRCDIR/gpsd.rules ' + DESTDIR + env['udevdir'] + '/rules.d/25-gpsd.rules',
'cp $SRCDIR/gpsd.hotplug ' + DESTDIR + env['udevdir'],
'chmod a+x ' + DESTDIR + env['udevdir'] + '/gpsd.hotplug',
])
] + hotplug_wrapper_install)

if env['systemd']:
systemctl_daemon_reload = Utility('systemctl-daemon-reload', '', [ 'systemctl daemon-reload || true'])
env.AlwaysBuild(systemctl_daemon_reload)
env.Precious(systemctl_daemon_reload)
env.Requires(udev_install, systemd_install)
env.Requires(systemctl_daemon_reload, systemd_install)
env.Requires(udev_install, systemctl_daemon_reload)


Utility('udev-uninstall', '', [
'rm -f %s/gpsd.hotplug' % env['udevdir'],
@@ -1785,7 +1845,7 @@ Utility('udev-test', '', [

# Ordinary cleanup
clean = env.Clean(build,
map(glob.glob,("*.[oa]", "*.os", "*.os.*", "*.gcno", "*.pyc", "gps/*.pyc", "TAGS")) + \
map(glob.glob,("*.[oa]", "*.[1358]", "*.os", "*.os.*", "*.gcno", "*.pyc", "gps/*.pyc", "TAGS")) + testprogs + \
generated_sources + base_manpages.keys() + \
map(lambda f: f[:-3], templated))



+ 15
- 0
TODO View File

@@ -156,6 +156,21 @@ message 6 and 8 subtypes - specifically, 6/23, 8/21, 8/22, 8/24, and

We'd need machinery to shift a byte array 30 bits left...

**** AIS struct needs a 'structured' bit detected by the driver ****

Turns out that dispatching JSON dump on Types 6 and 8 by DAC/FID
isn't reliable, because sometimes unstructured Type 8s can
false-match with a structured type. Observed in the wild with
an unstructured Type 8 misconstrued as an Inland AIS Type 10.
To fix this, the driver needs to store the 'structured' bit in
the AIS structure. Will require a library bump, but afterwards
some code can be removed from the JSON dumper.

When this happens, also dump AIS text fields unconditionally (not on
"scaled"). xgps may need changes.

Also, in gps.h, move the tag field to privdata.

** To do:

*** On next API bump ***


+ 1
- 1
ais_json.c View File

@@ -397,7 +397,7 @@ int json_ais_read(const char *buf,
structured = true;
}
}
else if (strstr(buf, "\"dac\":200,") != NULL) {
else if (strstr(buf, "\"dac\":200,") != NULL && strstr(buf,"data")==NULL) {
if (strstr(buf, "\"fid\":10,") != NULL) {
status = json_read_object(buf, json_ais8_fid10, endptr);
structured = true;


+ 2
- 2
ais_json.i View File

@@ -439,9 +439,9 @@
.dflt.uinteger = 0},
{"beam", t_uinteger, .addr.uinteger = &ais->type8.dac200fid10.beam,
.dflt.uinteger = 0},
{"type", t_uinteger, .addr.uinteger = &ais->type8.dac200fid10.type,
{"shiptype", t_uinteger, .addr.uinteger = &ais->type8.dac200fid10.shiptype,
.dflt.uinteger = 0},
{"type_text", t_ignore},
{"shiptype_text", t_ignore},
{"hazard", t_uinteger, .addr.uinteger = &ais->type8.dac200fid10.hazard,
.dflt.uinteger = 0},
{"hazard_text", t_ignore},


+ 8
- 17
build.txt View File

@@ -34,21 +34,18 @@ compiler that also speaks C++): anonymous unions. We could eliminate
these, but the cost would be source-level interface breakage if we
have to move structure members in and out of unions.

GPSD is normally built and tested with GCC. If the option
-Wmissing-field-initializers or its non-gcc equivalent is set you will
get a lot of warnings; this is due to generated code and cannot be
fixed.
GPSD is normally built and tested with GCC. Do not compile with a version
older than 4.1.1; there are several known issues with older versions,
including (a) non-standards-conformant floating-point generation that
messes up regression testing, (b) a compiler bug affecting RTCM2 code
generation, (c) the option -Wno-missing-field-initializers is
unavailable, leading to a flood of warnings (this is due to generated
code and cannot be fixed).

The shared-memory interface relies on one GCCism, but the code is
otherwise pretty compiler-agnostic. It is reported that clang
produces a gpsd that passes all regression tests.

Older versions of gcc don't recognize Wno-missing-field-initializers;
this has been reported from GCC 3.4.6. We don't recommend building
with GCC versions prior to 4.1.1, as these had some floating-point
non-conformances that confused our regression testing and might have
real-world consequences.

=== Python ===

You will need Python 2.5 or later for the build.
@@ -173,12 +170,6 @@ need to build with implicit_link=no. If this happens, please report
your platform, ideally along with a way of identifying it from Python,
to the GPSD maintainers.

If you are going to use the RTCM-104 support, you should compile with
gcc4; if you don't have it installed as your default compiler, do this
by specifying CC=gcc4 before the build command. The rtcm2.c file
confuses the gcc-3.4.[23] optimizer at -O2 level, making it generate
incorrect code.

If, while building, you see a complaint that looks like this:

--------------------------------------------------------------------
@@ -318,7 +309,7 @@ dbus=no: for systems using DBUS: gpsd includes support for shipping
fixes as DBUS notifications, but it is not compiled in by default.
Build with the option "dbus=yes" to get it working.

libQgpsmm=yes: libQgpsmm is a Qt version of the libgps/libgpsmm
qt=yes: libQgpsmm is a Qt version of the libgps/libgpsmm
pair. Thanks to the multi-platform approach of Qt, it allows the gpsd
client library to be available on all the Qt supported platforms.
Please see http://qt.nokia.com/doc/4.6/supported-platforms.html for a


+ 41
- 73
driver_ais.c View File

@@ -95,6 +95,14 @@ bool ais_binary_decode(const int debug,
"AIVDM message type %d size > %d bits (%zd).\n", \
ais->type, correct, bitlen); \
}
#define RANGE_CHECK(min, max) \
if (bitlen < min || bitlen > max) { \
gpsd_report(debug, LOG_ERROR, \
"AIVDM message type %d size is out of range (%zd).\n", \
ais->type, bitlen); \
return false; \
}

/*
* Something about the shape of this switch statement confuses
* GNU indent so badly that there is no point in trying to be
@@ -170,12 +178,7 @@ bool ais_binary_decode(const int debug,
//ais->type5.spare = UBITS(423, 1);
break;
case 6: /* Addressed Binary Message */
if (bitlen < 88 || bitlen > 1008) {
gpsd_report(debug, LOG_WARN,
"AIVDM message type 6 size is out of range (%zd).\n",
bitlen);
return false;
}
RANGE_CHECK(88, 1008);
ais->type6.seqno = UBITS(38, 2);
ais->type6.dest_mmsi = UBITS(40, 30);
ais->type6.retransmit = UBITS(70, 1)!=0;
@@ -190,6 +193,8 @@ bool ais_binary_decode(const int debug,
if (ais->type6.dac == 200) {
switch (ais->type6.fid) {
case 21: /* ETA at lock/bridge/terminal */
if (bitlen != 248)
break;
UCHARS(88, ais->type6.dac200fid21.country);
UCHARS(100, ais->type6.dac200fid21.locode);
UCHARS(118, ais->type6.dac200fid21.section);
@@ -205,6 +210,8 @@ bool ais_binary_decode(const int debug,
structured = true;
break;
case 22: /* RTA at lock/bridge/terminal */
if (bitlen != 232)
break;
UCHARS(88, ais->type6.dac200fid22.country);
UCHARS(100, ais->type6.dac200fid22.locode);
UCHARS(118, ais->type6.dac200fid22.section);
@@ -219,6 +226,8 @@ bool ais_binary_decode(const int debug,
structured = true;
break;
case 55: /* Number of Persons On Board */
if (bitlen != 168)
break;
ais->type6.dac200fid55.crew = UBITS(88, 8);
ais->type6.dac200fid55.passengers = UBITS(96, 13);
ais->type6.dac200fid55.personnel = UBITS(109, 8);
@@ -232,6 +241,8 @@ bool ais_binary_decode(const int debug,
else if (ais->type6.dac == 235 || ais->type6.dac == 250) {
switch (ais->type6.fid) {
case 10: /* GLA - AtoN monitoring data */
if (bitlen != 136)
break;
ais->type6.dac235fid10.ana_int = UBITS(88, 10);
ais->type6.dac235fid10.ana_ext1 = UBITS(98, 10);
ais->type6.dac235fid10.ana_ext2 = UBITS(108, 10);
@@ -425,13 +436,7 @@ bool ais_binary_decode(const int debug,
case 13: /* Safety Related Acknowledge */
{
unsigned int mmsi[4];
if (bitlen < 72 || bitlen > 158) {
gpsd_report(debug, LOG_WARN,
"AIVDM message type %d size is out of range (%zd).\n",
ais->type,
bitlen);
return false;
}
RANGE_CHECK(72, 158);
for (u = 0; u < sizeof(mmsi)/sizeof(mmsi[0]); u++)
if (bitlen > 40 + 32*u)
mmsi[u] = UBITS(40 + 32*u, 30);
@@ -446,12 +451,7 @@ bool ais_binary_decode(const int debug,
break;
}
case 8: /* Binary Broadcast Message */
if (bitlen < 56 || bitlen > 1008) {
gpsd_report(debug, LOG_WARN,
"AIVDM message type 8 size is out of range (%zd).\n",
bitlen);
return false;
}
RANGE_CHECK(56, 1008);
//ais->type8.spare = UBITS(38, 2);
ais->type8.dac = UBITS(40, 10);
ais->type8.fid = UBITS(50, 6);
@@ -654,11 +654,13 @@ bool ais_binary_decode(const int debug,
}
else if (ais->type8.dac == 200) {
switch (ais->type8.fid) {
case 21: /* Inland ship static and voyage related data */
case 10: /* Inland ship static and voyage related data */
if (bitlen != 168)
break;
UCHARS(56, ais->type8.dac200fid10.vin);
ais->type8.dac200fid10.length = UBITS(104, 13);
ais->type8.dac200fid10.beam = UBITS(117, 10);
ais->type8.dac200fid10.type = UBITS(127, 14);
ais->type8.dac200fid10.shiptype = UBITS(127, 14);
ais->type8.dac200fid10.hazard = UBITS(141, 3);
ais->type8.dac200fid10.draught = UBITS(144, 11);
ais->type8.dac200fid10.loaded = UBITS(155, 2);
@@ -668,7 +670,9 @@ bool ais_binary_decode(const int debug,
/* skip 8 bits */
structured = true;
break;
case 23:
case 23: /* EMMA warning */
if (bitlen != 256)
break;
ais->type8.dac200fid23.start_year = UBITS(56, 8);
ais->type8.dac200fid23.start_month = UBITS(64, 4);
ais->type8.dac200fid23.start_day = UBITS(68, 5);
@@ -691,7 +695,9 @@ bool ais_binary_decode(const int debug,
/* skip 6 bits */
structured = true;
break;
case 24:
case 24: /* Water level */
if (bitlen != 168)
break;
UCHARS(56, ais->type8.dac200fid24.country);
#define ARRAY_BASE 68
#define ELEMENT_SIZE 25
@@ -706,7 +712,9 @@ bool ais_binary_decode(const int debug,
/* skip 6 bits */
structured = true;
break;
case 40:
case 40: /* Signal status */
if (bitlen != 168)
break;
ais->type8.dac200fid40.lon = SBITS(56, 28);
ais->type8.dac200fid40.lat = SBITS(84, 27);
ais->type8.dac200fid40.form = UBITS(111, 4);
@@ -747,12 +755,7 @@ bool ais_binary_decode(const int debug,
//ais->type10.spare2 = UBITS(70, 2);
break;
case 12: /* Safety Related Message */
if (bitlen < 72 || bitlen > 1008) {
gpsd_report(debug, LOG_WARN,
"AIVDM message type 12 size is out of range (%zd).\n",
bitlen);
return false;
}
RANGE_CHECK(72, 1008);
ais->type12.seqno = UBITS(38, 2);
ais->type12.dest_mmsi = UBITS(40, 30);
ais->type12.retransmit = (bool)UBITS(70, 1);
@@ -760,22 +763,12 @@ bool ais_binary_decode(const int debug,
ENDCHARS(72, ais->type12.text);
break;
case 14: /* Safety Related Broadcast Message */
if (bitlen < 40 || bitlen > 1008) {
gpsd_report(debug, LOG_WARN,
"AIVDM message type 14 size is out of range (%zd).\n",
bitlen);
return false;
}
RANGE_CHECK(40, 1008);
//ais->type14.spare = UBITS(38, 2);
ENDCHARS(40, ais->type14.text);
break;
case 15: /* Interrogation */
if (bitlen < 88 || bitlen > 168) {
gpsd_report(debug, LOG_WARN,
"AIVDM message type 15 size is out of range (%zd).\n",
bitlen);
return false;
}
RANGE_CHECK(88, 168);
(void)memset(&ais->type15, '\0', sizeof(ais->type15));
//ais->type14.spare = UBITS(38, 2);
ais->type15.mmsi1 = UBITS(40, 30);
@@ -796,12 +789,7 @@ bool ais_binary_decode(const int debug,
}
break;
case 16: /* Assigned Mode Command */
if (bitlen != 96 && bitlen != 144) {
gpsd_report(debug, LOG_WARN,
"AIVDM message type 16 size is out of range (%zd).\n",
bitlen);
return false;
}
RANGE_CHECK(96, 144);
ais->type16.mmsi1 = UBITS(40, 30);
ais->type16.offset1 = UBITS(70, 12);
ais->type16.increment1 = UBITS(82, 10);
@@ -814,12 +802,7 @@ bool ais_binary_decode(const int debug,
}
break;
case 17: /* GNSS Broadcast Binary Message */
if (bitlen < 80 || bitlen > 816) {
gpsd_report(debug, LOG_WARN,
"AIVDM message type 17 size is out of range (%zd).\n",
bitlen);
return false;
}
RANGE_CHECK(80, 816);
//ais->type17.spare = UBITS(38, 2);
ais->type17.lon = UBITS(40, 18);
ais->type17.lat = UBITS(58, 17);
@@ -873,12 +856,7 @@ bool ais_binary_decode(const int debug,
//ais->type19.spare = UBITS(308, 4);
break;
case 20: /* Data Link Management Message */
if (bitlen < 72 || bitlen > 160) {
gpsd_report(debug, LOG_WARN,
"AIVDM message type 20 size is out of range (%zd).\n",
bitlen);
return false;
}
RANGE_CHECK(72, 160);
//ais->type20.spare = UBITS(38, 2);
ais->type20.offset1 = UBITS(40, 12);
ais->type20.number1 = UBITS(52, 4);
@@ -898,12 +876,7 @@ bool ais_binary_decode(const int debug,
ais->type20.increment4 = UBITS(149, 11);
break;
case 21: /* Aid-to-Navigation Report */
if (bitlen < 272 || bitlen > 360) {
gpsd_report(debug, LOG_WARN,
"AIVDM message type 21 size is out of range (%zd).\n",
bitlen);
return false;
}
RANGE_CHECK(272, 360);
ais->type21.aid_type = UBITS(38, 5);
from_sixbit((unsigned char *)bits,
43, 20, ais->type21.name);
@@ -960,7 +933,7 @@ bool ais_binary_decode(const int debug,
case 24: /* Class B CS Static Data Report */
switch (UBITS(38, 2)) {
case 0:
PERMISSIVE_LENGTH_CHECK(160)
RANGE_CHECK(160, 168);
/* save incoming 24A shipname/MMSI pairs in a circular queue */
{
struct ais_type24a_t *saveptr = &type24_queue->ships[type24_queue->index];
@@ -1066,12 +1039,7 @@ bool ais_binary_decode(const int debug,
(ais->type25.bitcount + 7) / 8);
break;
case 26: /* Binary Message, Multiple Slot */
if (bitlen < 60 || bitlen > 1004) {
gpsd_report(debug, LOG_WARN,
"AIVDM message type 26 size is out of range (%zd).\n",
bitlen);
return false;
}
RANGE_CHECK(60, 1004);
ais->type26.addressed = (bool)UBITS(38, 1);
ais->type26.structured = (bool)UBITS(39, 1);
if ((signed)bitlen < 40 + 16*ais->type26.structured + 30*ais->type26.addressed + 20) {


+ 2
- 0
driver_geostar.c View File

@@ -19,6 +19,8 @@
#include "gpsd.h"
#include "bits.h"

#include <sys/select.h>

#ifdef GEOSTAR_ENABLE
#define GEOSTAR_CHANNELS 24



+ 5
- 10
driver_nmea2000.c View File

@@ -854,10 +854,6 @@ static gps_mask_t hnd_129810(unsigned char *bu, int len, PGN *pgn, struct gps_de
beam = getleu16(bu, 22);
to_starboard = getleu16(bu, 24);
to_bow = getleu16(bu, 26);
ais->type24.dim.to_bow = (unsigned int) (to_bow/10);
ais->type24.dim.to_stern = (unsigned int) ((length-to_bow)/10);
ais->type24.dim.to_port = (unsigned int) ((beam-to_starboard)/10);
ais->type24.dim.to_starboard = (unsigned int) (to_starboard/10);
if ((length == 0xffff) || (to_bow == 0xffff)) {
length = 0;
to_bow = 0;
@@ -866,6 +862,10 @@ static gps_mask_t hnd_129810(unsigned char *bu, int len, PGN *pgn, struct gps_de
beam = 0;
to_starboard = 0;
}
ais->type24.dim.to_bow = (unsigned int) (to_bow/10);
ais->type24.dim.to_stern = (unsigned int) ((length-to_bow)/10);
ais->type24.dim.to_port = (unsigned int) ((beam-to_starboard)/10);
ais->type24.dim.to_starboard = (unsigned int) (to_starboard/10);
}

for (i = 0; i < MAX_TYPE24_INTERLEAVE; i++) {
@@ -1485,19 +1485,14 @@ static ssize_t nmea2000_get(struct gps_device_t *session)
struct can_frame frame;
ssize_t status;

// printf("NMEA2000 get: enter\n");
session->packet.outbuflen = 0;
status = read(session->gpsdata.gps_fd, &frame, sizeof(frame));
if (status == (ssize_t)sizeof(frame)) {
session->packet.type = NMEA2000_PACKET;
find_pgn(&frame, session);
// printf("NMEA2000 get: exit(%d)\n", status);
if (session->driver.nmea2000.workpgn == NULL) {
status = 0;
}

return frame.can_dlc & 0x0f;
}
// printf("NMEA2000 get: exit(EXIT_SUCCESS)\n");
return 0;
}



+ 29
- 22
driver_sirf.c View File

@@ -1404,14 +1404,14 @@ static void sirfbin_event_hook(struct gps_device_t *session, event_t event)

case 1:
gpsd_report(session->context->debug, LOG_PROG,
"SiRF: Probing for firmware version...\n");
"SiRF: Probing for firmware version.\n");
(void)sirf_write(session, versionprobe);
break;

case 2:
#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");
/* unset MID 0x40 = 64 first since there is a flood of them */
gpsd_report(session->context->debug, LOG_PROG, "SiRF: unset MID 64.\n");
putbyte(unsetmidXX, 6, 0x40);
(void)sirf_write(session, unsetmidXX);
break;
@@ -1422,67 +1422,74 @@ static void sirfbin_event_hook(struct gps_device_t *session, event_t event)
* parameters so they can be reverted before close.
*/
gpsd_report(session->context->debug, LOG_PROG,
"SiRF: Requesting navigation parameters...\n");
"SiRF: Requesting navigation parameters.\n");
(void)sirf_write(session, navparams);
break;

case 4:
#ifdef RECONFIGURE_ENABLE
/* unset GND (0x29 = 41), it's not reliable on SiRF II */
gpsd_report(session->context->debug, LOG_PROG, "SiRF: unset MID 64.\n");
putbyte(unsetmidXX, 6, 0x29);
(void)sirf_write(session, unsetmidXX);
break;

case 5:
if (!session->context->readonly) {
gpsd_report(session->context->debug, LOG_PROG,
"SiRF: Setting Navigation Parameters\n");
"SiRF: Setting Navigation Parameters.\n");
(void)sirf_write(session, modecontrol);
}
#endif /* RECONFIGURE_ENABLE */
break;

case 5:
case 6:
gpsd_report(session->context->debug, LOG_PROG,
"SiRF: Requesting periodic ecef reports...\n");
"SiRF: Requesting periodic ecef reports.\n");
(void)sirf_write(session, requestecef);
break;

case 6:
case 7:
gpsd_report(session->context->debug, LOG_PROG,
"SiRF: Requesting periodic tracker reports...\n");
"SiRF: Requesting periodic tracker reports.\n");
(void)sirf_write(session, requesttracker);
break;

case 7:
case 8:
gpsd_report(session->context->debug, LOG_PROG,
"SiRF: Setting DGPS control to use SBAS...\n");
"SiRF: Setting DGPS control to use SBAS.\n");
(void)sirf_write(session, dgpscontrol);
break;

case 8:
case 9:
gpsd_report(session->context->debug, LOG_PROG,
"SiRF: Setting SBAS to auto/integrity mode...\n");
"SiRF: Setting SBAS to auto/integrity mode.\n");
(void)sirf_write(session, sbasparams);
break;

case 9:
case 10:
gpsd_report(session->context->debug, LOG_PROG,
"SiRF: Enabling PPS message...\n");
"SiRF: Enabling PPS message.\n");
(void)sirf_write(session, enablemid52);
break;

case 10:
case 11:
/* SiRF recommends at least 57600 for SiRF IV nav data */
if (session->gpsdata.dev.baudrate >= 57600) {
/* fast enough, turn on nav data */
gpsd_report(session->context->debug, LOG_PROG,
"SiRF: Enabling subframe transmission...\n");
"SiRF: Enabling subframe transmission.\n");
(void)sirf_write(session, enablesubframe);
} else {
/* too slow, turn off nav data */
gpsd_report(session->context->debug, LOG_PROG,
"SiRF: Disabling subframe transmission...\n");
"SiRF: Disabling subframe transmission.\n");
(void)sirf_write(session, disablesubframe);
}
break;

case 11:
gpsd_report(session->context->debug, LOG_PROG, "SiRF: disable MID 7, 28, 29, 30, 31...\n");
case 12:
/* disable navigation debug messages (the value 5 is magic) */
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;


+ 2
- 0
driver_tsip.c View File

@@ -24,6 +24,8 @@
#include "gpsd.h"
#include "bits.h"

#include <sys/select.h>

#define USE_SUPERPACKET 1 /* use Super Packet mode? */

#define SEMI_2_DEG (180.0 / 2147483647) /* 2^-31 semicircle to deg */


+ 10
- 1
driver_zodiac.c View File

@@ -396,11 +396,20 @@ static gps_mask_t zodiac_analyze(struct gps_device_t *session)
static ssize_t zodiac_control_send(struct gps_device_t *session,
char *msg, size_t len)
{
unsigned short *shortwords = (unsigned short *)msg;
/*@-usedef -compdef@*/
unsigned short shortwords[256];

#define min(x,y) ((x) < (y) ? x : y)
/*
* We used to just cast msg to an unsigned short pointer.
* This can fail on word-oriented achitectures like a SPARC.
*/
memcpy((char *)shortwords, msg, min(sizeof(shortwords), len));

/* and if len isn't even, it's your own fault */
return zodiac_spew(session, shortwords[0], shortwords + 1,
(int)(len / 2 - 1));
/*@+usedef +compdef@*/
}
#endif /* CONTROLSEND_ENABLE */



+ 19
- 0
getsid.c View File

@@ -0,0 +1,19 @@
/*
* This file plugs a hole in Bionic, a derivation of the BSD standard C library
* code that was originally developed by Google for Android.
*
* This file is Copyright (c) 2010 by the GPSD project
* BSD terms apply: see the file COPYING in the distribution root for details.
*/
#include "gpsd_config.h"

#ifndef HAVE_GETSID
#include <unistd.h>
#include <sys/syscall.h>

/* This implementation is required for Android */

pid_t getsid(pid_t pid) {
return syscall(__NR_getsid, pid);
}
#endif /* HAVE_GETSID */

+ 3
- 3
gps.h View File

@@ -1250,10 +1250,10 @@ struct ais_t
char bitdata[(AIS_TYPE8_BINARY_MAX + 7) / 8];
/* Inland static ship and voyage-related data */
struct {
char vin[8+1]; /* European Vessel ID */
char vin[8+1]; /* European Vessel ID */
unsigned int length; /* Length of ship */
unsigned int beam; /* Beam of ship */
unsigned int type; /* Ship/combination type */
unsigned int beam; /* Beam of ship */
unsigned int shiptype; /* Ship/combination type */
unsigned int hazard; /* Hazardous cargo */
unsigned int draught; /* Draught */
unsigned int loaded; /* Loaded/Unloaded */


+ 1
- 1
gps/client.py View File

@@ -127,7 +127,7 @@ WATCH_JSON = 0x000010 # JSON output
WATCH_NMEA = 0x000020 # output in NMEA
WATCH_RARE = 0x000040 # output of packets in hex
WATCH_RAW = 0x000080 # output of raw packets
WATCH_SCALED = 0x000100 # scale output to floats
WATCH_SCALED = 0x000100 # scale output to floats
WATCH_TIMING = 0x000200 # timing information
WATCH_SPLIT24 = 0x001000 # split AIS Type 24s
WATCH_PPS = 0x002000 # enable PPS in raw/NMEA


+ 7
- 8
gps/fake.py View File

@@ -132,7 +132,7 @@ class TestLoad:
def __init__(self, logfp, predump=False):
self.sentences = [] # This is the interesting part
if type(logfp) == type(""):
logfp = open(logfp, "r")
logfp = open(logfp, "r")
self.name = logfp.name
self.logfp = logfp
self.predump = predump
@@ -176,7 +176,7 @@ class TestLoad:
raise ValueError
except (ValueError, IndexError):
raise TestLoadError("bad serial-parameter spec in %s"%\
self.name)
self.name)
self.serial = (baud, databits, parity, stopbits)
elif "Transport: UDP" in packet:
self.sourcetype = "UDP"
@@ -199,7 +199,7 @@ class TestLoad:
print repr(packet)
if not packet:
raise TestLoadError("zero-length packet from %s"%\
self.name)
self.name)
self.sentences.append(packet)
# Look at the first packet to grok the GPS type
self.textual = (type_latch == sniffer.NMEA_PACKET)
@@ -559,7 +559,7 @@ class TestSession:
progress=self.progress)
self.baseport += 1
else:
newgps = FakePTY(testload, speed=speed,
newgps = FakePTY(testload, speed=speed,
progress=self.progress)
if pred:
newgps.go_predicate = pred
@@ -582,11 +582,11 @@ class TestSession:
self.progress("gpsfake: client_add()\n")
newclient = gps.gps(port=self.port, verbose=self.verbose)
self.append(newclient)
newclient.id = self.client_id + 1
newclient.id = self.client_id + 1
self.client_id += 1
self.progress("gpsfake: client %d has %s\n" % (self.client_id,newclient.device))
if commands:
self.initialize(newclient, commands)
self.initialize(newclient, commands)
return self.client_id
def client_remove(self, cid):
"Terminate a client session."
@@ -595,8 +595,7 @@ class TestSession:
if isinstance(obj, gps.gps) and obj.id == cid:
self.remove(obj)
return True
else:
return False
return False
def wait(self, seconds):
"Wait, doing nothing."
self.progress("gpsfake: wait(%d)\n" % seconds)


+ 5
- 5
gps/gps.py View File

@@ -112,7 +112,7 @@ class gpsdata:
)

def __init__(self):
# Initialize all data members
# Initialize all data members
self.online = 0 # NZ if GPS on, zero if not

self.valid = 0
@@ -261,8 +261,8 @@ class gps(gpscommon, gpsdata, gpsjson):
self.valid = ONLINE_SET | DEVICE_SET
self.path = self.data["path"]
self.activated = default("activated", None)
driver = default("driver", None, DEVICEID_SET)
subtype = default("subtype", None, DEVICEID_SET)
driver = default("driver", None, DEVICEID_SET)
subtype = default("subtype", None, DEVICEID_SET)
self.gps_id = driver
if subtype:
self.gps_id += " " + subtype
@@ -298,7 +298,7 @@ class gps(gpscommon, gpsdata, gpsjson):
for attrp in ("x", "y", "v", "h", "p", "g"):
setattr(self, attrp+"dop", default(attrp+"dop", NaN, DOP_SET))
if "satellites" in self.data.keys():
self.satellites = []
self.satellites = []
for sat in self.data['satellites']:
self.satellites.append(gps.satellite(PRN=sat['PRN'], elevation=sat['el'], azimuth=sat['az'], ss=sat['ss'], used=sat['used']))
self.satellites_used = 0
@@ -345,7 +345,7 @@ class gps(gpscommon, gpsdata, gpsjson):
else: # flags & WATCH_ENABLE:
if flags & WATCH_OLDSTYLE:
arg = 'w+'
if (flags & WATCH_NMEA):
if flags & WATCH_NMEA:
arg += 'r+'
return self.send(arg)
else:


+ 1
- 1
gps/misc.py View File

@@ -93,7 +93,7 @@ def isotime(s):
else:
date = s
msec = "0"
# Note: no leap-second correction!
# Note: no leap-second correction!
return calendar.timegm(time.strptime(date, "%Y-%m-%dT%H:%M:%S")) + float("0." + msec)
else:
raise TypeError


+ 10
- 8
gps2udp.c View File

@@ -11,8 +11,6 @@
* BSD terms apply: see the file COPYING in the distribution root for details.
*
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
@@ -22,8 +20,11 @@
#include <fcntl.h>
#include <termios.h>
#include <time.h>
#include <sys/time.h>
#include <assert.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>

#ifndef S_SPLINT_S
#include <unistd.h>
@@ -105,7 +106,7 @@ static int send_udp (char *nmeastring, size_t ind)
buffer[ind] = '\r'; ind++;
buffer[ind] = '\0';

if (!(flags & WATCH_JSON) && buffer[0] == '{') {
if ((flags & WATCH_JSON)==0 && buffer[0] == '{') {
/* do not send JSON when not configured to do so */
return 0;
}
@@ -138,7 +139,7 @@ static int open_udp(char **hostport)
{
char *hostname = NULL;
char *portname = NULL;
char *endptr = '\0';
char *endptr = NULL;
int portnum;
struct hostent *hp;

@@ -153,11 +154,13 @@ static int open_udp(char **hostport)
}

errno = 0;
portnum = strtol(portname, &endptr, 10);
portnum = (int)strtol(portname, &endptr, 10);
/*@+charint@*/
if (1 > portnum || 65535 < portnum || '\0' != *endptr || 0 != errno) {
(void)fprintf(stderr, "gps2udp: syntax is [-u hostname:port] [%s] is not a valid port number\n",portname);
return (-1);
}
/*@-charint@*/

sock[channel]= socket(AF_INET, SOCK_DGRAM, 0);
if (sock[channel] < 0) {
@@ -168,7 +171,7 @@ static int open_udp(char **hostport)
remote[channel].sin_family = (sa_family_t)AF_INET;
hp = gethostbyname(hostname);
if (hp==NULL) {
fprintf(stderr, "gps2udp: syntaxe is [-u hostname:port] [%s] is not a valid hostnamer\n",hostname);
fprintf(stderr, "gps2udp: syntax is [-u hostname:port] [%s] is not a valid hostname\n",hostname);
return (-1);
}

@@ -191,7 +194,6 @@ static void usage(void)
"-b Run in background as a daemon.\n"
"-d [0-2] 1 display sent packets, 2 ignored packets.\n"
"-v Print version and exit.\n\n"
"You must specify one, or more, of -r, -R, or -w\n"
"example: gps2udp -a -n -c 2 -d 1 -u data.aishub.net:2222 fridu.net\n"
);
}


+ 16
- 1
gpscap.ini View File

@@ -1036,10 +1036,25 @@ submitter = Richard Allen <rsaxvc@gmail.com>
vendor = Garmin
techdoc = http://static.garmincdn.com/pumac/Montana_600_OM_EN.pdf
engine = STA2065
engine = unknown
rating = good
tested = 3.6

[GPS 152]
type = device
submitter = Erkki Laasonen <erkki.laasonen@gmail.com>
vendor = Garmin
techdoc = http://www.manualrepubliccdn.com/pdf/garmin/396-m-gps-152-manual-owner-s-manual.pdf
packaging = handheld
engine = unknown
firmware = 3.60
nmea = 2.3
interfaces = FTDI
tested = 3.6
rating = broken
location = Uusikaupunki, FI, 61N 21E
date = 2014-06-30
sample_notes: Log was taken on my moored boat.

#% Geostar Navigation

[GeoS-1M]


+ 9
- 0
gpsctl.c View File

@@ -14,6 +14,7 @@
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/select.h>
#ifndef S_SPLINT_S
#include <unistd.h>
#endif /* S_SPLINT_S */
@@ -664,11 +665,19 @@ int main(int argc, char **argv)
/* grab packets until we time out, get sync, or fail sync */
for (hunting = true; hunting; )
{
#ifdef EFDS
fd_set efds;
#endif /* EFDS */
switch(gpsd_await_data(&rfds, maxfd, &all_fds, context.debug))
{
case AWAIT_GOT_INPUT:
break;
case AWAIT_NOT_READY:
#ifdef EFDS
/* no recovery from bad fd is possible */
if (FD_ISSET(session.gpsdata.gps_fd, &efds))
exit(EXIT_FAILURE);
#endif /* EFDS */
continue;
case AWAIT_FAILED:
exit(EXIT_FAILURE);


+ 1
- 1
gpsd.8 View File

@@ -100,7 +100,7 @@ may differ depending on how it was compiled; general\-purpose versions support m
gpsd
effectively hides the differences among the GPS types it supports\&. It also knows about and uses commands that tune these GPSes for lower latency\&. By using
gpsd
as an intermediary applications avoid contention for serial devices\&.
as an intermediary, applications avoid contention for serial devices\&.
.PP
gpsd
can use differential\-GPS corrections from a DGPS radio or over the net, from a ground station running a DGPSIP server or a Ntrip broadcaster that reports RTCM\-104 data; this will shrink position errors by roughly a factor of four\&. When


+ 25
- 30
gpsd.c View File

@@ -248,10 +248,13 @@ static void usage(void)
-S integer (default %s) = set port for daemon \n\
-h = help message \n\
-V = emit version and exit.\n\
A device may be a local serial device for GPS input, or a URL of the form:\n\
A device may be a local serial device for GPS input, or a URL in one \n\
of the following forms:\n\
tcp://host[:port]\n\
udp://host[:port]\n\
{dgpsip|ntrip}://[user:passwd@]host[:port][/stream]\n\
gpsd://host[:port][/device][?protocol]\n\
in which case it specifies an input source for GPSD, DGPS or ntrip data.\n\
in which case it specifies an input source for device, DGPS or ntrip data.\n\
\n\
The following driver types are compiled into this gpsd instance:\n",
DEFAULT_GPSD_PORT);
@@ -399,11 +402,13 @@ static socket_t passivesock_af(int af, char *service, char *tcp_or_udp, int qlen
/* see PF_INET6 case below */
s = socket(PF_INET, type, proto);
if (s > -1 ) {
/*@-unrecog@*/
/* Set packet priority */
if (setsockopt(s, IPPROTO_IP, IP_TOS, &dscp, sizeof(dscp)) == -1)
if (setsockopt(s, IPPROTO_IP, IP_TOS, &dscp, sizeof(dscp)) == -1)
gpsd_report(context.debug, LOG_WARN,
"Warning: SETSOCKOPT TOS failed\n");
}
/*@+unrecog@*/

break;
#ifdef IPV6_ENABLE
@@ -1557,38 +1562,16 @@ static void all_reports(struct gps_device_t *device, gps_mask_t changed)
//gpsd_report(context.debug, LOG_PROG, "NTP: No time this packet\n");
} else if (isnan(device->newdata.time)) {
//gpsd_report(context.debug, LOG_PROG, "NTP: bad new time\n");
} else if (device->newdata.time == device->last_fixtime) {
} else if (device->newdata.time == device->last_fixtime.real) {
//gpsd_report(context.debug, LOG_PROG, "NTP: Not a new time\n");
} else if (!device->ship_to_ntpd) {
//gpsd_report(context.debug, LOG_PROG, "NTP: No precision time report\n");
} else {
double fix_time, integral, fractional;
struct timedrift_t td;

#ifdef HAVE_CLOCK_GETTIME
/*@i2@*/(void)clock_gettime(CLOCK_REALTIME, &td.clock);
#else
struct timeval clock_tv;
(void)gettimeofday(&clock_tv, NULL);
TVTOTS(&td.clock, &clock_tv);
#endif /* HAVE_CLOCK_GETTIME */
fix_time = device->newdata.time;
/* assume zero when there's no offset method */
if (device->device_type == NULL
|| device->device_type->time_offset == NULL)
fix_time += 0.0;
else
fix_time += device->device_type->time_offset(device);
/* it's ugly but timestamp_t is double */
fractional = modf(fix_time, &integral);
/*@-type@*/ /* splint is confused about struct timespec */
td.real.tv_sec = (time_t)integral;
td.real.tv_nsec = (long)(fractional * 1e+9);
/*@+type@*/
/*@-compdef@*/
struct timedrift_t td;
ntpshm_latch(device, &td);
(void)ntpshm_put(device, device->shmIndex, &td);
/*@+compdef@*/
device->last_fixtime = device->newdata.time;
}
#endif /* NTPSHM_ENABLE */

@@ -1847,7 +1830,7 @@ int main(int argc, char *argv[])
int i, option;
int msocks[2] = {-1, -1};
bool go_background = true;
bool in_restart;
volatile bool in_restart;

context.debug = 0;
gps_context_init(&context);
@@ -1912,7 +1895,7 @@ int main(int argc, char *argv[])

#ifdef SYSTEMD_ENABLE
sd_socket_count = sd_get_socket_count();
if (sd_socket_count > 0 && control_socket) {
if (sd_socket_count > 0 && control_socket != NULL) {
gpsd_report(context.debug, LOG_WARN,
"control socket passed on command line ignored\n");
control_socket = NULL;
@@ -2128,7 +2111,9 @@ int main(int argc, char *argv[])
#ifdef SOCKET_EXPORT_ENABLE
for (i = 0; i < NITEMS(subscribers); i++) {
subscribers[i].fd = UNALLOCATED_FD;
#ifndef S_SPLINT_S
(void)pthread_mutex_init(&subscribers[i].mutex, NULL);
#endif /* S_SPLINT_S */
}
#endif /* SOCKET_EXPORT_ENABLE*/

@@ -2191,11 +2176,21 @@ int main(int argc, char *argv[])
}

while (0 == signalled) {
#ifdef EFDS
fd_set efds;
#endif /* EFDS */
switch(gpsd_await_data(&rfds, maxfd, &all_fds, context.debug))
{
case AWAIT_GOT_INPUT:
break;
case AWAIT_NOT_READY:
#ifdef EFDS
for (device = devices; device < devices + MAXDEVICES; device++)
if (FD_ISSET(device->gpsdata.gps_fd, &efds)) {
deactivate_device(device);
free_device(device);
}
#endif /* EFDS*/
continue;
case AWAIT_FAILED:
exit(EXIT_FAILURE);


+ 4
- 0
gpsd.h-head View File

@@ -7,6 +7,10 @@
#ifndef _GPSD_H_
#define _GPSD_H_

# ifdef __cplusplus
extern "C" {
# endif

#include <stdbool.h>
#include <stdio.h>



+ 9
- 1
gpsd.h-tail View File

@@ -475,7 +475,10 @@ struct gps_device_t {
int shmIndexPPS;
# endif /* PPS_ENABLE */
#endif /* NTPSHM_ENABLE */
volatile timestamp_t last_fixtime; /* so updates happen once */
volatile struct {
timestamp_t real;
timestamp_t clock;
} last_fixtime; /* so updates happen once */
#ifdef PPS_ENABLE
#if defined(HAVE_SYS_TIMEPPS_H)
pps_handle_t kernelpps_handle;
@@ -839,6 +842,7 @@ extern unsigned int ais_binary_encode(struct ais_t *ais, /*@out@*/unsigned char
extern void ntpshm_context_init(struct gps_context_t *);
extern void ntpshm_session_init(struct gps_device_t *);
extern int ntpshm_put(struct gps_device_t *, int, struct timedrift_t *);
extern void ntpshm_latch(struct gps_device_t *device, /*@out@*/struct timedrift_t *td);
extern void ntpshm_link_deactivate(struct gps_device_t *);
extern void ntpshm_link_activate(struct gps_device_t *);

@@ -1028,6 +1032,10 @@ static /*@unused@*/ inline void memory_barrier(void)
#endif /* S_SPLINT_S */
}

# ifdef __cplusplus
}
# endif

#endif /* _GPSD_H_ */
// Local variables:
// mode: c


+ 14
- 14
gpsd.rules.in View File

@@ -22,32 +22,32 @@
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+="@udevdir@/gpsd.hotplug"
ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", SYMLINK+="gps%n", @udevcommand@
# ATEN International Co., Ltd UC-232A Serial Port [linux module: pl2303]
ATTRS{idVendor}=="0557", ATTRS{idProduct}=="2008", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug"
ATTRS{idVendor}=="0557", ATTRS{idProduct}=="2008", SYMLINK+="gps%n", @udevcommand@
# PS-360 OEM (GPS sold with MS Street and Trips 2005) [linux module: pl2303]
ATTRS{idVendor}=="067b", ATTRS{idProduct}=="aaa0", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug"
ATTRS{idVendor}=="067b", ATTRS{idProduct}=="aaa0", SYMLINK+="gps%n", @udevcommand@
# FTDI 8U232AM / FT232 [linux module: ftdi_sio]
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug"
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="gps%n", @udevcommand@
# Cypress M8/CY7C64013 (Delorme uses these) [linux module: cypress_m8]
ATTRS{idVendor}=="1163", ATTRS{idProduct}=="0100", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug"
ATTRS{idVendor}=="1163", ATTRS{idProduct}=="0100", SYMLINK+="gps%n", @udevcommand@
# Cypress M8/CY7C64013 (DeLorme LT-40)
ATTRS{idVendor}=="1163", ATTRS{idProduct}=="0200", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug"
ATTRS{idVendor}=="1163", ATTRS{idProduct}=="0200", SYMLINK+="gps%n", @udevcommand@
# 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+="@udevdir@/gpsd.hotplug"
ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", SYMLINK+="gps%n", @udevcommand@
# 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+="@udevdir@/gpsd.hotplug"
ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="gps%n", @udevcommand@
# Cygnal Integrated Products, Inc. [linux module: cp210x]
ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea71", SYMLINK="gps%n", RUN+="@udevdir@/gpsd.hotplug"
ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea71", SYMLINK+="gps%n", @udevcommand@
# 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+="@udevdir@/gpsd.hotplug"
ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a5", SYMLINK+="gps%n", @udevcommand@
# 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+="@udevdir@/gpsd.hotplug"
ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a6", SYMLINK+="gps%n", @udevcommand@
# MediaTek (tested with HOLUX M-1200E) [linux module: cdc_acm]
ATTRS{idVendor}=="0e8d", ATTRS{idProduct}=="3329", SYMLINK="gps%n", RUN+="@udevdir@/gpsd.hotplug"
ATTRS{idVendor}=="0e8d", ATTRS{idProduct}=="3329", SYMLINK+="gps%n", @udevcommand@
# Telit wireless solutions (tested with HE910G) [linux module: cdc_acm]
ATTRS{interface}=="Telit Wireless Module Port", ATTRS{bInterfaceNumber}=="06", SYMLINK="gps%n", RUN+="@udevdir@/gpsd.hotplug"
ATTRS{interface}=="Telit Wireless Module Port", ATTRS{bInterfaceNumber}=="06", SYMLINK+="gps%n", @udevcommand@

ACTION=="remove", RUN+="@udevdir@/gpsd.hotplug"
ACTION=="remove", @udevcommand@

LABEL="gpsd_rules_end"

+ 1
- 1
gpsd.xml View File

@@ -116,7 +116,7 @@ instance, see the output of <command>gpsd -l</command></para>
<para><application>gpsd</application> effectively hides the
differences among the GPS types it supports. It also knows about and
uses commands that tune these GPSes for lower latency. By using
<application>gpsd</application> as an intermediary applications
<application>gpsd</application> as an intermediary, applications
avoid contention for serial devices.</para>

<para><application>gpsd</application> can use differential-GPS


+ 1
- 1
gpsd_json.5 View File

@@ -1373,7 +1373,7 @@ No
T}:T{
boolean
T}:T{
If true, emit a PPS bar when the device issues
If true, emit a PPS JSON message when the device issues
1PPS\&. Intended to be used with the "nmea" and "raw" modes\&.
Default is false\&. \fBNote: this is an
unstable experimental feature which may change or be removed


+ 26
- 10
gpsd_json.c View File

@@ -2810,25 +2810,35 @@ void json_aivdm_dump(const struct ais_t *ais,
};
#define STATUS_DISPLAY(n) (((n) < (unsigned int)NITEMS(status_vocabulary)) ? status_vocabulary[n] : "INVALID STATUS")

structured = false;
switch (ais->type8.fid) {
case 10: /* Inland ship static and voyage-related data */
for (cp = shiptypes; cp < shiptypes + NITEMS(shiptypes); cp++)
if (cp->code == ais->type8.dac200fid10.type
|| cp->ais == ais->type8.dac200fid10.type)
if (cp->code == ais->type8.dac200fid10.shiptype
|| cp->ais == ais->type8.dac200fid10.shiptype
|| cp->code == 0)
break;
/*
* FIXME: AIS struct should have "structured" bit set by driver
* This is a kluge.
*/
if (cp->code == 0
|| (int)ais->type8.dac200fid10.hazard >= NITEMS(hazard_types)
|| !isascii((int)ais->type8.dac200fid10.vin[0]))
break;
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
"\"vin\":\"%s\",\"length\":%u,\"beam\":%u,"
"\"type\":%u,\"type_text\":\"%s\","
"\"shiptype\":%u,\"shiptype_text\":\"%s\","
"\"hazard\":%u,\"hazard_text\":\"%s\","
"\"draught\":%u,"
"\"loaded\":%u,\"loaded_text\":\"%s\","
"\"speed_q\":\"%s\","
"\"course_q\":\"%s\","
"\"heading_q\":\"%s\"}",
"\"speed_q\":%s,"
"\"course_q\":%s,"
"\"heading_q\":%s}\r\n",
ais->type8.dac200fid10.vin,
ais->type8.dac200fid10.length,
ais->type8.dac200fid10.beam,
ais->type8.dac200fid10.type,
ais->type8.dac200fid10.shiptype,
cp->legend,
ais->type8.dac200fid10.hazard,
HTYPE_DISPLAY(ais->type8.dac200fid10.hazard),
@@ -2841,6 +2851,12 @@ void json_aivdm_dump(const struct ais_t *ais,
structured = true;
break;
case 23: /* EMMA warning */
/*
* FIXME: AIS struct should have "structured" bit set by driver
* This is a kluge.
*/
if ((int)ais->type8.dac200fid23.type >= NITEMS(emma_types))
break;
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
"\"start\":\"%4u-%02u-%02uT%02u:%02u\","
"\"end\":\"%4u-%02u-%02uT%02u:%02u\",",
@@ -2869,7 +2885,7 @@ void json_aivdm_dump(const struct ais_t *ais,
ais->type8.dac200fid23.end_lon,
ais->type8.dac200fid23.end_lat);
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
"\"type\":%u,\"type_text\":\"%s\",\"min\":%d,\"max\":%d,\"class\":%u,\"class_text\":\"%s\",\"wind\":%u,\"wind_text\":\"%s\"}",
"\"type\":%u,\"type_text\":\"%s\",\"min\":%d,\"max\":%d,\"class\":%u,\"class_text\":\"%s\",\"wind\":%u,\"wind_text\":\"%s\"}\r\n",

ais->type8.dac200fid23.type,
EMMA_TYPE_DISPLAY(ais->type8.dac200fid23.type),
@@ -2893,7 +2909,7 @@ void json_aivdm_dump(const struct ais_t *ais,
}
if (buf[strlen(buf)-1] == ',')
buf[strlen(buf)-1] = '\0';
(void)strlcat(buf, "]}", buflen - strlen(buf));
(void)strlcat(buf, "]}\r\n", buflen - strlen(buf));
structured = true;
break;
case 40: /* Inland AIS Signal Strength */
@@ -2908,7 +2924,7 @@ void json_aivdm_dump(const struct ais_t *ais,
ais->type8.dac200fid40.lon,
ais->type8.dac200fid40.lat);
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
"\"form\":%u,\"facing\":%u,\"direction\":%u,\"direction_text\":\"%s\",\"status\":%u,\"status_text\":\"%s\"}",
"\"form\":%u,\"facing\":%u,\"direction\":%u,\"direction_text\":\"%s\",\"status\":%u,\"status_text\":\"%s\"}\r\n",
ais->type8.dac200fid40.form,
ais->type8.dac200fid40.facing,
ais->type8.dac200fid40.direction,


+ 1
- 1
gpsd_json.xml View File

@@ -1014,7 +1014,7 @@ object.</para>
<entry>pps</entry>
<entry>No</entry>
<entry>boolean</entry>
<entry>If true, emit a PPS bar when the device issues
<entry>If true, emit a PPS JSON message when the device issues
1PPS. Intended to be used with the "nmea" and "raw" modes.
Default is false. <emphasis role="bold">Note: this is an
unstable experimental feature which may change or be removed


+ 22
- 2
gpsmon.1 View File

@@ -48,9 +48,29 @@ accepts an \-h option that displays a usage message, or a \-V option to dump the
.PP
This program may be run in either of two modes, as a client for the
gpsd
daemon (and its associated control socket) or directly connected to a specified serial device\&. When run with no argument, it attempts to connect to the daemon\&. If the argument looks like a server:port specification it will also attempt to connect to the daemon\&. If the argument looks like a bare server name it will attempt to connect to a daemon running on the default gpsd port on that server\&. Only if the device argument contains slashes but no colons will it be treated as a serial device for direct connection\&. In direct\-connect mode
daemon (and its associated control socket) or directly connected to a specified serial device\&. When run with no argument, it attempts to connect to the daemon\&. If the argument begins with a server:port specification it will also attempt to connect to the daemon\&. If the argument looks like a bare server name it will attempt to connect to a daemon running on the default gpsd port on that server\&. Only if the device argument contains slashes but no colons will it be treated as a serial device for direct connection\&. In direct\-connect mode
gpsmon
will hunt for a correct baud rate and lock on to it automatically\&.
will hunt for a correct baud rate and lock on to it automatically\&. Possible cases look like this:
.PP
localhost:/dev/ttyS1
.RS 4
Look at the default port of localhost, trying both IPv4 and IPv6 and watching output from serial device 1\&.
.RE
.PP
example\&.com:2317
.RS 4
Look at port 2317 on example\&.com, trying both IPv4 and IPv6\&.
.RE
.PP
71\&.162\&.241\&.5:2317:/dev/ttyS3
.RS 4
Look at port 2317 at the specified IPv4 address, collecting data from attached serial device 3\&.
.RE
.PP
[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:2317:/dev/ttyS5
.RS 4
Look at port 2317 at the specified IPv6 address, collecting data from attached serial device 5\&.
.RE
.PP
Unlike
gpsd,


+ 48
- 17
gpsmon.c View File

@@ -18,6 +18,7 @@
#include <sys/time.h> /* expected to declare select(2) a la SuS */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <fcntl.h>
#ifndef S_SPLINT_S
#include <unistd.h>
@@ -26,6 +27,7 @@
#include "gpsd.h"
#include "gps_json.h"
#include "gpsmon.h"
#include "gpsdclient.h"
#include "revision.h"

#define BUFLEN 2048
@@ -54,6 +56,7 @@ static WINDOW *statwin, *cmdwin;
static char *type_name;
static size_t promptlen = 0;
struct termios cooked, rare;
struct fixsource_t source;

#ifdef PASSTHROUGH_ENABLE
/* no methods, it's all device window */
@@ -340,8 +343,13 @@ static /*@observer@*/ const char *promptgen(void)
9 - session.gpsdata.dev.stopbits,
session.gpsdata.dev.parity,
session.gpsdata.dev.stopbits);
else
else {
(void)strlcpy(buf, session.gpsdata.dev.path, sizeof(buf));
if (source.device != NULL) {
(void) strlcat(buf, ":", sizeof(buf));
(void) strlcat(buf, source.device, sizeof(buf));
}
}
return buf;
}

@@ -690,6 +698,7 @@ static void gpsmon_hook(struct gps_device_t *device, gps_mask_t changed UNUSED)
/* per-packet hook */
{
char buf[BUFSIZ];
struct timedrift_t td;

#ifdef PPS_ENABLE
if (!serial && strncmp((char*)device->packet.outbuffer, "{\"class\":\"PPS\",", 13) == 0)
@@ -770,7 +779,7 @@ static void gpsmon_hook(struct gps_device_t *device, gps_mask_t changed UNUSED)
report_unlock();

/* Update the last fix time seen for PPS. FIXME: do this here? */
device->last_fixtime = device->newdata.time;
ntpshm_latch(device, &td);
}
/*@+observertrans +nullpass +globstate +compdef +uniondef@*/

@@ -1069,7 +1078,7 @@ static const char *cmdline;
int main(int argc, char **argv)
{
int option;
char *explanation, *devicename;
char *explanation;
int bailout = 0, matches = 0;
bool nmea = false;
fd_set all_fds;
@@ -1179,19 +1188,32 @@ int main(int argc, char **argv)
gpsd_time_init(&context, time(NULL));
gpsd_init(&session, &context, NULL);

if (optind >= argc)
devicename = "gpsd://localhost:" DEFAULT_GPSD_PORT;
else
devicename = argv[optind];
/* Grok the server, port, and device. */
if (optind < argc) {
serial = (strncmp(argv[optind], "/dev", 4) == 0);
gpsd_source_spec(argv[optind], &source);
} else {
serial = false;
gpsd_source_spec(NULL, &source);
}

/* backward compatibilty: accept a bare server name */
if (strchr(devicename, ':') == NULL && devicename[0] != '/')
if (serial) {
assert(source.device != NULL); /* clue to splint */
(void) strlcpy(session.gpsdata.dev.path,
"tcp://", sizeof(session.gpsdata.dev.path));
else
session.gpsdata.dev.path[0] = '\0';
(void)strlcat(session.gpsdata.dev.path, devicename,
sizeof(session.gpsdata.dev.path));
source.device,
sizeof(session.gpsdata.dev.path));
} else {
assert(source.server != NULL); /* clue to splint */
if (strstr(source.server, "//") == 0)
(void) strlcpy(session.gpsdata.dev.path,
"tcp://",
sizeof(session.gpsdata.dev.path));
else
session.gpsdata.dev.path[0] = '\0';
(void)snprintf(session.gpsdata.dev.path + strlen(session.gpsdata.dev.path),
sizeof(session.gpsdata.dev.path) - strlen(session.gpsdata.dev.path),
"%s:%s", source.server, source.port);
}

if (gpsd_activate(&session, O_PROBEONLY) == -1) {
(void)fprintf(stderr,
@@ -1200,7 +1222,6 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE);
}

serial = (strncmp(devicename, "/dev", 4) == 0);

if (serial) {
#ifdef PPS_ENABLE
@@ -1209,8 +1230,10 @@ int main(int argc, char **argv)
#endif /* PPS_ENABLE */
}
else {
/* FIXME: Also use WATCH*DEVICE here someday */
(void)gps_send(&session.gpsdata, nmea ? WATCHNMEA : WATCHRAW);
if (source.device != NULL)
(void)gps_send(&session.gpsdata, nmea ? WATCHNMEADEVICE : WATCHRAWDEVICE, source.device);
else
(void)gps_send(&session.gpsdata, nmea ? WATCHNMEA : WATCHRAW);
}

/*
@@ -1258,11 +1281,19 @@ int main(int argc, char **argv)

for (;;)
{
#ifdef EFDS
fd_set efds;
#endif /* EFDS */
switch(gpsd_await_data(&rfds, maxfd, &all_fds, context.debug))
{
case AWAIT_GOT_INPUT:
break;
case AWAIT_NOT_READY:
#ifdef EFDS
/* no recovery from bad fd is possible */
if (FD_ISSET(session.gpsdata.gps_fd, &efds))
longjmp(terminate, TERM_SELECT_FAILED);
#endif /* EFDS */
continue;
case AWAIT_FAILED:
longjmp(terminate, TERM_SELECT_FAILED);


+ 25
- 2
gpsmon.xml View File

@@ -76,14 +76,37 @@ version and exit.</para>
the <application>gpsd</application> daemon (and its associated control
socket) or directly connected to a specified serial device. When run
with no argument, it attempts to connect to the daemon. If the
argument looks like a server:port specification it will also attempt
argument begins with a server:port specification it will also attempt
to connect to the daemon. If the argument looks like a bare server
name it will attempt to connect to a daemon running on the default
gpsd port on that server. Only if the device argument contains
slashes but no colons will it be treated as a serial device for direct
connection. In direct-connect mode <application>gpsmon</application>
will hunt for a correct baud rate and lock on to it
automatically.</para>
automatically. Possible cases look like this:</para>

<variablelist>
<varlistentry>
<term>localhost:/dev/ttyS1</term>
<listitem><para>Look at the default port of localhost, trying both
IPv4 and IPv6 and watching output from serial device 1.</para></listitem>
</varlistentry>
<varlistentry>
<term>example.com:2317</term>
<listitem><para>Look at port 2317 on example.com, trying both
IPv4 and IPv6.</para></listitem>
</varlistentry>
<varlistentry>
<term>71.162.241.5:2317:/dev/ttyS3</term>
<listitem><para>Look at port 2317 at the specified IPv4
address, collecting data from attached serial device 3.</para></listitem>
</varlistentry>
<varlistentry>
<term>[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:2317:/dev/ttyS5</term>
<listitem><para>Look at port 2317 at the specified IPv6
address, collecting data from attached serial device 5.</para></listitem>
</varlistentry>
</variablelist>

<para>Unlike <application>gpsd</application>,
<application>gpsmon</application> run in direct mode does not do its


+ 3
- 2
gpspipe.c View File

@@ -23,8 +23,6 @@
*
*/

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
@@ -35,6 +33,9 @@
#include <termios.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#ifndef S_SPLINT_S
#include <unistd.h>
#endif /* S_SPLINT_S */


+ 4
- 4
jsongen.py.in View File

@@ -355,8 +355,8 @@ ais_specs = (
('vin', 'string', None),
('length', 'uinteger', '0'),
('beam', 'uinteger', '0'),
('type', 'uinteger', '0'),
('type_text', 'ignore', None),
('shiptype', 'uinteger', '0'),
('shiptype_text', 'ignore', None),
('hazard', 'uinteger', '0'),
('hazard_text','ignore', None),
('draught', 'uinteger', '0'),
@@ -660,7 +660,7 @@ ais_specs = (
('text', 'string', None),
),
},
# Message type 13 duplicates 7
# Message type 13 duplicates 7
{
"initname" : "json_ais14",
"headers": ("AIS_HEADER",),
@@ -939,7 +939,7 @@ def generate(spec):
elif attr not in outboard:
report += " char %s[JSON_VAL_MAX+1];\n" % attr
outboard.append(attr)
structname = spec["structname"]
# If there are structarrays describing array subobjects, we need
# to make a separate parse control initializer for each one. The


+ 11
- 12
leapsecond.py View File

@@ -121,8 +121,7 @@ def retrieve():
except IOError:
if verbose:
print >>sys.stderr, "IOError: %s" % url
else:
return None
return None

def last_insertion_time():
"Give last potential insertion time for a leap second."
@@ -352,32 +351,32 @@ if __name__ == '__main__':
import getopt
(options, arguments) = getopt.getopt(sys.argv[1:], "hvf:g:H:i:n:o:I:O:")
for (switch, val) in options:
if (switch == '-h'): # help, get usage only
if switch == '-h': # help, get usage only
usage()
if (switch == '-v'): # be verbose
elif switch == '-v': # be verbose
verbose=1
if (switch == '-f'): # Fetch USNO data to cache locally
elif switch == '-f': # Fetch USNO data to cache locally
save_leapseconds(val)
raise SystemExit, 0
elif (switch == '-g'): # Graph the leap_second history
elif switch == '-g': # Graph the leap_second history
graph_history(val)
raise SystemExit, 0
elif (switch == '-H'): # make leapsecond include
elif switch == '-H': # make leapsecond include
sys.stdout.write(make_leapsecond_include(val))
raise SystemExit, 0
elif (switch == '-i'): # Compute Unix time from RFC822 date
elif switch == '-i': # Compute Unix time from RFC822 date
print rfc822_to_unix(val)
raise SystemExit, 0
elif (switch == '-n'): # Compute possible next leapsecond
elif switch == '-n': # Compute possible next leapsecond
printnext(val)
raise SystemExit, 0
elif (switch == '-o'): # Compute RFC822 date from Unix time
elif switch == '-o': # Compute RFC822 date from Unix time
print unix_to_rfc822(float(val))
raise SystemExit, 0
elif (switch == '-I'): # Compute Unix time from ISO8601 date
elif switch == '-I': # Compute Unix time from ISO8601 date
print isotime(val)
raise SystemExit, 0