Browse Source

Imported Upstream version 3.10+dev1~a33bfd44

master
Bernd Zeimetz 6 years ago
parent
commit
738eead7ea
80 changed files with 2157 additions and 1729 deletions
  1. +3
    -2
      INSTALL
  2. +8
    -1
      NEWS
  3. +81
    -107
      SConstruct
  4. +42
    -3
      TODO
  5. +5
    -0
      bits.c
  6. +60
    -52
      build.txt
  7. +5
    -2
      control.in
  8. +3
    -24
      driver_nmea0183.c
  9. +32
    -3
      driver_ubx.c
  10. +1
    -1
      driver_zodiac.c
  11. +5
    -3
      gps.h
  12. +2
    -5
      gps/client.py
  13. +11
    -2
      gps/fake.py
  14. +2
    -1
      gps/gps.py
  15. +6
    -6
      gps2udp.1
  16. +40
    -27
      gps2udp.c
  17. +6
    -7
      gps2udp.xml
  18. +1
    -0
      gps_maskdump.c
  19. +1
    -1
      gpscat.1
  20. +1
    -1
      gpscat.xml
  21. +5
    -1
      gpsctl.c
  22. +24
    -29
      gpsd.c
  23. +16
    -5
      gpsd.h-tail
  24. +2
    -0
      gpsd.php
  25. +2
    -0
      gpsd.php.in
  26. +2
    -0
      gpsd.rules
  27. +12
    -4
      gpsd_json.c
  28. +1
    -1
      gpsfake
  29. +25
    -6
      gpsmon.c
  30. +11
    -0
      gpspacket.c
  31. +1
    -1
      gpspipe.c
  32. +2
    -0
      jsongen.py.in
  33. +67
    -59
      leapsecond.py
  34. +17
    -17
      leapseconds.cache
  35. +24
    -6
      libgpsd_core.c
  36. +5
    -0
      libgpsmm.cpp
  37. +1
    -0
      libgpsmm.h
  38. +2
    -0
      maskaudit.py.in
  39. +5
    -1
      netlib.c
  40. +29
    -13
      ntpshm.c
  41. +1
    -1
      packaging/rpm/gpsd.spec
  42. +156
    -46
      ppsthread.c
  43. +10
    -2
      regress-driver
  44. +1
    -1
      revision.h
  45. +4
    -1
      serial.c
  46. +19
    -19
      test/daemon/bn-9015.log.chk
  47. +27
    -27
      test/daemon/bt-q818.log.chk
  48. +2
    -2
      test/daemon/bt451.log.chk
  49. +27
    -27
      test/daemon/bu303-climbing.log.chk
  50. +28
    -28
      test/daemon/bu303-moving.log.chk
  51. +10
    -10
      test/daemon/bu303-stillfix.log.chk
  52. +32
    -32
      test/daemon/ch-4711.log.chk
  53. +23
    -23
      test/daemon/garmin-10x.log.chk
  54. +222
    -222
      test/daemon/geos-1m.log.chk
  55. +54
    -54
      test/daemon/geostar-geos1m-binary.log.chk
  56. +52
    -52
      test/daemon/gps-360.log.chk
  57. +43
    -43
      test/daemon/gpslim236.log.chk
  58. +1
    -1
      test/daemon/gr601-w.log
  59. +67
    -67
      test/daemon/haicom-305N.log.chk
  60. +15
    -15
      test/daemon/iTrek.log.chk
  61. +26
    -26
      test/daemon/italk-binary.log.chk
  62. +3
    -3
      test/daemon/mtk-3301.log.chk
  63. +3
    -3
      test/daemon/mtk-3329.log.chk
  64. +34
    -34
      test/daemon/myguide-3100.log.chk
  65. +21
    -21
      test/daemon/navcom.log.chk
  66. +71
    -71
      test/daemon/nd-1005.log.chk
  67. +48
    -48
      test/daemon/nokia-ld-4w.log.chk
  68. +5
    -5
      test/daemon/oncore.log.chk
  69. +52
    -52
      test/daemon/pharos-360.log.chk
  70. +1
    -1
      test/daemon/rgm3800.log.chk
  71. +1
    -1
      test/daemon/sl869.log.chk
  72. +83
    -83
      test/daemon/superstar2.log.chk
  73. +3
    -3
      test/daemon/tomtom-mkII.log.chk
  74. +201
    -201
      test/daemon/tr737A+.log.chk
  75. +10
    -10
      test/daemon/ublox-aek-4t.log.chk
  76. +46
    -46
      test/daemon/ublox-lea-4t.log.chk
  77. +38
    -38
      test/daemon/ublox-sirf1.log.chk
  78. +140
    -18
      timebase.c
  79. +7
    -1
      timebase.h
  80. +2
    -0
      valgrind-audit.py.in

+ 3
- 2
INSTALL View File

@@ -47,8 +47,9 @@ prototypical device, typically /dev/ttyS0 under Linux or /dev/tty00
under *BSD. It does not actually matter what the owning group is, as
gpsd will look this up on startup. Alternatively, (3), you can set a
fallback group with the gpsd-group option in case the prototype is not
found: this should be the "dialout" group (or functional equivalent)
that has write access to serial devices.
found: this should be the group that has write access to serial
devices. On Debian and derivatives including Ubuntu this is "dialout";
on Gentoo/Fedora/openSuse it is "uucp".

Before dropping privileges, gpsd will ensure that it has access to
devices given to it on the command line by forcing their group read


+ 8
- 1
NEWS View File

@@ -1,6 +1,13 @@
GPSD project news

* Fri 22 Oct 2013 Eric S. Raymond <esr@snark.thyrsus.com> - 3.10
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.
chrpath is no longer a dependency for building and testing, and
now defaults to 'no'.

* Fri 22 Nov 2013 Eric S. Raymond <esr@snark.thyrsus.com> - 3.10
AIS: Adds gps2udp, an AIS data relay, split24 option supports
passing through Type 24 halves; support for Inland AIS; "scaled" no
longer controls dumping of controlled-vocabulary fields; instead,


+ 81
- 107
SConstruct View File

@@ -10,6 +10,7 @@
# check - run regression and unit tests.
# audit - run code-auditing tools
# testbuild - test-build the code from a tarball
# website - refresh the website
# release - ship a release
#
# clean - clean all normal build targets
@@ -23,7 +24,7 @@
# * Coveraging mode: gcc "-coverage" flag requires a hack for building the python bindings

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

# library version
libgps_version_current = 21
@@ -56,6 +57,9 @@ gitrepo = "git://git.savannah.nongnu.org/gpsd.git"
webform = "http://www.thyrsus.com/cgi-bin/gps_report.cgi"
formserver = "www@thyrsus.com"
devmail = "gpsd-dev@lists.nongnu.org"
usermail = "gpsd-users@lists.nongnu.org"
annmail = "gpsd-announce@nongnu.org"
ircchan = "irc://chat.freenode.net/#gpsd"
tiplink = "<a href='http://gittip.com/esr'>leave a tip at Gittip</a>"
tipwidget = "<script data-gittip-username='esr' \
data-gittip-widget='button' src='//gttp.co/v1.js'></script>"
@@ -63,7 +67,7 @@ tipwidget = "<script data-gittip-username='esr' \

EnsureSConsVersion(2,0,1)

import copy, os, sys, glob, re, platform, time, signal
import copy, os, sys, glob, re, platform, time
from distutils import sysconfig
from distutils.util import get_platform
import SCons
@@ -157,7 +161,7 @@ boolopts = (
("profiling", False, "build with profiling enabled"),
("coveraging", False, "build with code coveraging enabled"),
("strip", True, "build with stripping of binaries enabled"),
("chrpath", True, "use chrpath to edit library load paths"),
("chrpath", False, "use chrpath to edit library load paths"),
("manbuild", True, "build help in man and HTML formats"),
("leapfetch", True, "fetch up-to-date data on leap seconds."),
)
@@ -174,6 +178,8 @@ nonboolopts = (
("gpsd_user", "nobody", "privilege revocation user",),
("gpsd_group", def_group, "privilege revocation group"),
("prefix", "/usr/local", "installation directory prefix"),
("python_libdir", sysconfig.get_python_lib(plat_specific=1),
"Python module directory prefix"),
("limited_max_clients", 0, "maximum allowed clients"),
("limited_max_devices", 0, "maximum allowed devices"),
("fixed_port_speed", 0, "fixed serial port speed"),
@@ -221,6 +227,7 @@ for var in import_env:
if var in os.environ:
envs[var] = os.environ[var]
envs["GPSD_HOME"] = os.getcwd()
envs["LD_LIBRARY_PATH"] = os.getcwd()

env = Environment(tools=["default", "tar", "textfile"], options=opts, ENV=envs)
opts.Save('.scons-option-cache', env)
@@ -239,7 +246,7 @@ env['PYTHON'] = sys.executable
env['STRIP'] = "strip"
env['PKG_CONFIG'] = "pkg-config"
env['CHRPATH'] = 'chrpath'
for i in ["AR", "ARFLAGS", "CCFLAGS", "CFLAGS", "CC", "CXX", "CXXFLAGS", "STRIP", "PKG_CONFIG", "CHRPATH", "LD", "TAR"]:
for i in ["AR", "ARFLAGS", "CCFLAGS", "CFLAGS", "CC", "CXX", "CXXFLAGS", "LINKFLAGS", "STRIP", "PKG_CONFIG", "CHRPATH", "LD", "TAR"]:
if os.environ.has_key(i):
j = i
if i == "LD":
@@ -248,7 +255,7 @@ for i in ["AR", "ARFLAGS", "CCFLAGS", "CFLAGS", "CC", "CXX", "CXXFLAGS", "STRIP"
env.Replace(**{j: Split(os.getenv(i))})
else:
env.Replace(**{j: os.getenv(i)})
for flag in ["LDFLAGS", "LINKFLAGS", "SHLINKFLAGS", "CPPFLAGS"]:
for flag in ["LDFLAGS", "SHLINKFLAGS", "CPPFLAGS"]:
if os.environ.has_key(flag):
env.MergeFlags({flag : [os.getenv(flag)]})

@@ -287,8 +294,16 @@ def installdir(dir, add_destdir=True):
# Honor the specified installation prefix in link paths.
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.
if env["shared"]:
env.Prepend(RPATH=[installdir('libdir')])
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))
env.Prepend(RPATH=[installdir('libdir')])

# Give deheader a way to set compiler flags
if 'MORECFLAGS' in os.environ:
@@ -373,12 +388,6 @@ def CheckPKG(context, name):
context.Result( ret )
return ret

def CheckExecutable(context, testprogram, check_for):
context.Message( 'Checking for %s... ' %(check_for,))
ret = context.TryAction(testprogram)[0]
context.Result( ret )
return ret

# Stylesheet URLs for making HTML and man pages from DocBook XML.
docbook_url_stem = 'http://docbook.sourceforge.net/release/xsl/current/'
docbook_man_uri = docbook_url_stem + 'manpages/docbook.xsl'
@@ -450,12 +459,14 @@ def CheckCompilerDefines(context, define):
context.Result(ret)
return ret

def GetLoadPath(context):
context.Message("Getting system load path ...")

if env.GetOption("clean") or env.GetOption("help"):
dbus_libs = []
rtlibs = []
usblibs = []
bluezlibs = []
caplibs = []
ncurseslibs = []
confdefs = []
manbuilder = False
@@ -463,7 +474,6 @@ if env.GetOption("clean") or env.GetOption("help"):
qt_env = None
else:
config = Configure(env, custom_tests = { 'CheckPKG' : CheckPKG,
'CheckExecutable' : CheckExecutable,
'CheckXsltproc' : CheckXsltproc,
'CheckCompilerOption' : CheckCompilerOption,
'CheckCompilerDefines' : CheckCompilerDefines,
@@ -480,18 +490,20 @@ else:
'-Wstrict-prototypes', '-Wpointer-arith', '-Wreturn-type'):
config.CheckCompilerOption(option)


env.Prepend(LIBPATH=[os.path.realpath(os.curdir)])
if env["shared"]:
if env["chrpath"] and config.CheckExecutable('chrpath -v', 'chrpath'):
# Tell generated binaries to look in the current directory for
# shared libraries so we can run regression tests without
# hassle. Should be handled sanely by scons on all systems. Not
# good to use '.' or a relative path here; it's a security risk.
# At install time we use chrpath to edit this out of RPATH.
if env["shared"] and env["chrpath"]:
if WhereIs('chrpath'):
# Tell generated binaries to look in the current directory
# for shared libraries so we can run ad-hoc tests without
# hassle (the regression tests *don't* need this as
# they're run in a controlled environment where we can set
# LD_LIBRARY_PATH). Should be handled sanely by scons on
# all systems. Not good to use '.' or a relative path
# here; it's a security risk. At install time we use
# chrpath to edit this out of RPATH.
env.Prepend(RPATH=[os.path.realpath(os.curdir)])
else:
print "chrpath is not available or use of it has been disabled."
print "chrpath is not available; please build with chrpath=no."

confdefs = ["/* gpsd_config.h. Generated by scons, do not hand-hack. */\n"]

@@ -519,9 +531,9 @@ else:
if env['ncurses']:
if config.CheckPKG('ncurses'):
ncurseslibs = pkg_config('ncurses')
elif config.CheckExecutable('ncurses5-config --version', 'ncurses5-config'):
elif WhereIs('ncurses5-config'):
ncurseslibs = ['!ncurses5-config --libs --cflags']
elif config.CheckExecutable('ncursesw5-config --version', 'ncursesw5-config'):
elif WhereIs('ncursesw5-config'):
ncurseslibs = ['!ncursesw5-config --libs --cflags']
elif sys.platform.startswith('freebsd'):
ncurseslibs= [ '-lncurses' ]
@@ -558,14 +570,6 @@ else:
confdefs.append("/* #undef HAVE_LIBRT */\n")
rtlibs = []

if config.CheckLib('libcap'):
confdefs.append("#define HAVE_LIBCAP 1\n")
# System library - no special flags
caplibs = ["-lcap"]
else:
confdefs.append("/* #undef HAVE_LIBCAP */\n")
caplibs = []

if env['dbus_export'] and config.CheckPKG('dbus-1'):
confdefs.append("#define HAVE_DBUS 1\n")
dbus_libs = pkg_config('dbus-1')
@@ -582,15 +586,6 @@ else:
bluezlibs = []
env["bluez"] = False

# ntpshm is required for pps support
if env['pps'] and env['ntpshm'] and config.CheckHeader("sys/timepps.h"):
confdefs.append("#define HAVE_SYS_TIMEPPS_H 1\n")
announce("You have kernel PPS available.")
else:
confdefs.append("/* #undef HAVE_SYS_TIMEPPS_H */\n")
announce("You do not have kernel PPS available.")
# Don't turn off PPS here, we might be using the non-kernel version

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

if not config.CheckHeaderDefines("sys/ioctl.h", "TIOCMIWAIT"):
announce("Forcing pps=no (TIOCMIWAIT not available)")
if config.CheckHeader(["sys/time.h", "sys/timepps.h"]):
confdefs.append("#define HAVE_SYS_TIMEPPS_H 1\n")
kpps = True
else:
confdefs.append("/* #undef HAVE_SYS_TIMEPPS_H */\n")
kpps = False
tiocmiwait = config.CheckHeaderDefines("sys/ioctl.h", "TIOCMIWAIT")
if env["pps"] and not tiocmiwait and not kpps:
announce("Forcing pps=no (neither TIOCMIWAIT nor RFC2783 API is available)")
env["pps"] = False

confdefs.append('''\
@@ -957,27 +959,7 @@ if qt_env:
# The libraries have dependencies on system libraries

gpslibs = ["-lgps", "-lm"]
gpsdlibs = ["-lgpsd"] + usblibs + bluezlibs + gpslibs + caplibs


# We need to be able to make a static client library for ad-hoc testing.
# Without this, we can't run regression tests in the build directory
# without either (a) having installed the GPSD shared libraries in system
# space (which requires root) or (b) having either '.' or an absolute
# path in the shared library load path (which is a security hole).
#
# None of the normal targets relies on this library. You can use it
# with a build command like
#
# g++ --static streamtest.cpp libgps.a -lrt -o streamtest
#
# When you link with this library you will get warnings that look like this:
# warning: Using 'getprotobyname' in statically linked applications requires
# at runtime the shared libraries from the glibc version used for
# linking
# The final executable will build but not be portable.

env.StaticLibrary(target = 'libgps.a', source = libgps_sources)
gpsdlibs = ["-lgpsd"] + usblibs + bluezlibs + gpslibs

# Source groups

@@ -1145,14 +1127,15 @@ env.Command(target = "packet_names.h", source="packet_states.h", action="""
sed -e '/^ *\([A-Z][A-Z0-9_]*\),/s// \"\\1\",/' <$SOURCE >$TARGET &&\
chmod a-w $TARGET""")

# build timebase.h
# timebase.h - always built in order to include current GPS week
def timebase_h(target, source, env):
from leapsecond import make_leapsecond_include
f = open(target[0].abspath, 'w')
f.write(make_leapsecond_include(source[0].abspath))
f.close()
env.Command(target="timebase.h", source="leapseconds.cache",
action=timebase_h)
timebase = env.Command(target="timebase.h",
source=["leapseconds.cache"], action=timebase_h)
env.AlwaysBuild(timebase)

env.Textfile(target="gpsd_config.h", source=confdefs)
env.Textfile(target="gpsd.h", source=[File("gpsd.h-head"), File("gpsd_config.h"), File("gpsd.h-tail")])
@@ -1184,32 +1167,13 @@ generated_sources = ['packet_names.h', 'timebase.h', 'gpsd.h', "ais_json.i",
# leapseconds.cache is a local cache for information on leapseconds issued
# by the U.S. Naval observatory. It gets kept in the repository so we can
# build without Internet access.
from leapsecond import save_leapseconds
from leapsecond import conditional_leapsecond_fetch

def timed_save_leapseconds(outfile, env, timeout=15):
"Fetch leapsecond data with timeout, in case outside web access is blocked."
def leapseconds_cache_rebuild(target, source, env):
if not env["leapfetch"]:
sys.stdout.write("Leapsecond fetch suppressed by leapfetch=no.\n")
else:
def handler(signum, frame):
raise IOError
try:
signal.signal(signal.SIGALRM, handler)
except ValueError:
# Parallel builds trigger this - signal only works in main thread
sys.stdout.write("Signal set failed; try building with leapfetch=no.\n")
return
signal.alarm(timeout)
sys.stdout.write("attempting leap-second fetch...")
try:
save_leapseconds(outfile)
sys.stdout.write("succeeded.\n")
except IOError:
sys.stdout.write("failed; try building with leapfetch=no.\n")
signal.alarm(0)

def leapseconds_cache_rebuild(target, source, env):
timed_save_leapseconds(target[0].abspath, env)
elif not conditional_leapsecond_fetch(target[0].abspath, timeout=15):
sys.stdout.write("try building with leapfetch=no.\n")
if 'dev' in gpsd_version or not os.path.exists('leapseconds.cache'):
leapseconds_cache = env.Command(target="leapseconds.cache",
source="leapsecond.py",
@@ -1228,7 +1192,7 @@ def substituter(target, source, env):
('@libdir@', env['libdir']),
('@PYTHON@', sys.executable),
('@DATE@', time.asctime()),
('@MASTER', 'DO NOT HAND_HACK! THIS FILE IS GENERATED@'),
('@MASTER@', 'DO NOT HAND_HACK! THIS FILE IS GENERATED'),
('@SITENAME@', sitename),
('@SITESEARCH@', sitesearch),
('@WEBSITE@', website),
@@ -1245,7 +1209,10 @@ def substituter(target, source, env):
('@GITREPO@', gitrepo),
('@WEBFORM@', webform),
('@FORMSERVER@', formserver),
('@USERMAIL@', usermail),
('@DEVMAIL@', devmail),
('@ANNOUNCE@', annmail),
('@IRCCHAN@', ircchan),
('@LIBGPSVERSION@', libgps_version),
('@TIPLINK@', tiplink),
('@TIPWIDGET@', tipwidget),
@@ -1264,6 +1231,11 @@ def substituter(target, source, env):

templated = glob.glob("*.in") + glob.glob("*/*.in") + glob.glob("*/*/*.in")

# ignore files in subfolder called 'debian' - the Debian packaging
# tools will handle them.
templated = [ x for x in templated if not x.startswith('debian/') ]


for fn in templated:
builder = env.Command(source=fn, target=fn[:-3], action=substituter)
env.AddPostAction(builder, 'chmod -w $TARGET')
@@ -1349,7 +1321,7 @@ if not env['debug'] and not env['profiling'] and env['strip']:
if not env['python']:
python_install = []
else:
python_lib_dir = sysconfig.get_python_lib(plat_specific=1)
python_lib_dir = env['python_libdir']
python_module_dir = python_lib_dir + os.sep + 'gps'
python_extensions_install = python_env.Install( DESTDIR + python_module_dir,
python_built_extensions)
@@ -1461,7 +1433,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,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 --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'''])

# Check the documentation for bogons, too
Utility("xmllint", glob.glob("*.xml"),
@@ -1736,7 +1708,7 @@ def validation_list(target, source, env):
Utility("validation-list", [www], validation_list)

# How to update the website
upload_web = Utility("upload_web", [www],
upload_web = Utility("website", [www],
['rsync --exclude="*.in" -avz www/ ' + webupload,
'scp README TODO NEWS ' + webupload,
'chmod ug+w,a+x www/gps_report.cgi',
@@ -1790,10 +1762,10 @@ if env['python']:
# is plugged in.

Utility('udev-install', 'install', [
'mkdir -p ' + env['udevdir'],
'cp $SRCDIR/gpsd.rules ' + env['udevdir'] + '/rules.d/25-gpsd.rules',
'cp $SRCDIR/gpsd.hotplug ' + env['udevdir'],
'chmod a+x ' + env['udevdir'] + '/gpsd.hotplug',
'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',
])

Utility('udev-uninstall', '', [
@@ -1809,7 +1781,7 @@ Utility('udev-test', '', [

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

@@ -1819,6 +1791,13 @@ webclean = env.Clean(www, [])
# Clean up to a close approximation of a fresh repository pull
distclean = env.Alias('distclean', [clean, testclean, webclean])

# Tags for Emacs and vi
misc_sources = ['cgps.c', 'gpsctl.c', 'gpsdctl.c', 'gpspipe.c',
'gps2udp.c', 'gpsdecode.c', 'gpxlogger.c']
sources = libgpsd_sources + libgps_sources \
+ gpsd_sources + gpsmon_sources + misc_sources
env.Command('TAGS', sources, ['etags ' + " ".join(sources)])

# Release machinery begins here
#
# We need to be in the actual project repo (i.e. not doing a -Y build)
@@ -1900,13 +1879,8 @@ if os.path.exists("gpsd.c") and os.path.exists(".gitignore"):
upload_web])

# Experimental release mechanics using shipper
# This will ship a freecode metadata update
ship_release = Utility("ship_release",
[tarball],
['shipper -u --exclude "login.ibiblio.org:/public/html/catb/esr/" version=' + gpsd_version])
env.Alias("ship", [releaseprep,
ship_release,
upload_tags])
# This will ship a freecode metadata update
Utility("ship", [tarball, "control"], ['shipper version=%s | sh -e -x' % gpsd_version])

# The following sets edit modes for GNU EMACS
# Local Variables:


+ 42
- 3
TODO View File

@@ -16,11 +16,39 @@ See the GPSD bug tracker on the project website, but don't be
surprised if it's empty or very sparse. Our rate of new defects per
month is quite low.

*** Documentation

Consider merging the calibration draft into the Time Service HOWTO.

*** Time tracking

Our goal is to be independent of the system clock.

**** Compile the GPS week of the build into the build

The obvious place tp put this is in timebase.h. Not too expensive;
will typically cause extra work once per seven days. The benefit is that
we can compare received week to the compiled in week and if the latter
is less know that a rollover has occurred.

**** Maybe apply wraparound compensation ****

See <http://www.febo.com/pipermail/time-nuts/2013-August/079271.html>

**** Track gpsd's confidence in the GPS time it's seeing

This would increase when we see a leap-second offset or get GPZDA from
the device, decrease when we detect a rollover. Some devices that are
known to deliver high-quality time (notably u-blox GPSes) would peg the
confidence measure at a high level. We'd use the confidence level to
control (a) whether gpsd ships to NTP, and (b) how it sets time
uncertainty in output JSON.

*** Client bugs

**** In gpsmon's PPS Offset field

resently PPS Offset is displayed in direct mode for NMEA, SiRF, and
Presently PPS Offset is displayed in direct mode for NMEA, SiRF, and
UBX devices. Others should probably do likewise, notably the
Motorola Oncore and Garmin drivers.

@@ -45,15 +73,21 @@ The second 'n' is losing information that it shouldn't.

Display update should not stop while this is going on.

*** Speed, mode and rate-changes in client-mode gpsmon.
**** Speed, mode and rate-changes in client-mode gpsmon.

Are not implemented. In theory they could be.

*** Speed, mode and rate-changes in client-mode gpsctl.
**** Speed, mode and rate-changes in client-mode gpsctl.

Baud rate and mode changes work in direct mode but are not
reliable in client mode.

**** Integrate 1PPS into profiling ***

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.

*** Dispatcher/network issues

**** Reading AISHub data via UDP confuses xgps with short writes
@@ -89,6 +123,11 @@ We'd need machinery to shift a byte array 30 bits left...

** To do:

*** On next API bump ***

In struct gpsdata_t, move the device list out of the union and move
the tag field to private data.

*** Make subframe reports available in the C API.

gpsd now reports subframes when they're available, but the C client


+ 5
- 0
bits.c View File

@@ -63,6 +63,11 @@ int64_t sbits(signed char buf[], unsigned int start, unsigned int width, bool le
{
uint64_t fld = ubits((unsigned char *)buf, start, width, le);

/* ensure width > 0 as the result of
1LL << (width - 1)
is undefined for width <= 0 */
assert(width > 0);

/*@ +relaxtypes */
if (fld & (1LL << (width - 1))) {
/*@ -shiftimplementation @*/


+ 60
- 52
build.txt View File

@@ -1,4 +1,4 @@
= Building GPSD from source ==
= Building GPSD from source =

This is a guide to building GPSD from a bare source tree. It includes
guidance on how to cross-build the package.
@@ -24,7 +24,6 @@ Necessary components for any build:
|C compiler | gpsd and client library are written in C
|Python | some code is generated from python scripts
|scons | for executing the build recipe
|chrpath | needed with scons for RPATH setting
|============================================================================

=== C compiler ===
@@ -77,43 +76,6 @@ The xgps test client requires the following Python extensions:
You will need scons version 2.0.1 or later to build the code. The
autotools build from 2.96 and earlier versions has been dropped.

=== chrpath ===

chrpath is a tool for editing RPATH in object files.

libtool is a messy pile of crocks, and throwing it out of our build
chain was a good thing, but it had consequences. Whatever its other
flaws, libtool successfully hid some tricky problems related to
dynamic-linkage paths; to address these in the scons build, you need
chrpath present to edit those paths.

Ubuntu users can do 'apt-get install chrpath'
CentOS users can do 'yum install chrpath' from extras.

Some distribution makers have considered the use of chrpath to be a
wart on the build recipe.

Here's the problem. Ideally, we want to build build binaries that (a)
link dynamically, (b) can be tested in the build directory without
installing to system space (in particular, so we can run the regression
tests without disturbing a production installation) and (c) won't
carry a potential exploit into system space when the binaries are
installed.

The potential exploit is the remnant presence of the build directory in
the binary's internal list of places it will look for shared libraries.
We need that to be there for testing purposes, but we want it gone
in the version of the binary that's copied to /usr/lib. Otherwise
there are threat scenarios with a maliciously crafted library.

Without chrpath we can get any two of those three, but we can't get
all three. Choosing static linking we get (b) and (c), choosing
dynamic linking without chrpath we get (a) and (b).

If you configure with chrpath=no, you will suppress use of chrpath,
but this also means you will lose the ability to run regression tests
in the build directory

=== Optional build components ===

Having the following optional components on your system will enable
@@ -201,11 +163,6 @@ running "scons prefix=<installation_root>". The default value is
"/usr/local". The envoronment variable DESTDIR also works in the
usual way.

If your link fails with a message like "/usr/bin/ld: cannot find -lgps",
you need to install chrpath. Note that after you have done so, you
may need to run 'scons --config=force' to override the scons
configuration cache's belief that chrpath isn't there.

If your scons fails with the complaint "No tool named 'textfile'",
you need to upgrade it. This feature was introduced during the long
interval after the 1.2.0 release; 1.2.1 and later versions will have it.
@@ -237,10 +194,9 @@ DocBook on your machine so there will be a local copy of the
stylesheet where xmlto can find it.

After building, please run 'scons check' to test the correctness
of the build. It is not necessary to install first, but you do need
to have "." in your $PATH to run regressions uninstalled. Python is
of the build. It is not necessary to install first. Python is
required for regression tests. If any of the tests fail, you probably
have a toolchain issue. The most common such problem is issues with
have a toolchain issue. The most common such problem is failures of
strict C99 conformance in floating-point libraries.

Once you have verified that the code is working, "scons install"
@@ -258,6 +214,58 @@ included with the distribution. To install it, copy the file
'gpsd.php' to your HTML document directory. Then see the
post-installation instructions in INSTALL for how to configure it.

=== Why you might need chrpath ===

You can probably skip this section unless you are a developer working
on the GPSD source directly, with a need to run some of the GPSD
programs by hand in the test directory. You are likely to get a
message something like:

--------------------------------------------------------------------
./gpsd: error while loading shared libraries: libgpsd.so.XX: cannot open shared object file: No such file or directory
--------------------------------------------------------------------

If this happens, there are two different things you can do about it.
One is this:

--------------------------------------------------------------------
export LD_LIBRARY_PATH=${PWD}
--------------------------------------------------------------------

The other is to install the chrpath utility and do your builds with
chrpath=yes.

The reason one of these required is because of some details
about dynamic linking. The search path for dynamic linking that is
compiled into your binaries as you build them is set by the
environment variable RPATH, if it exists. At runtime, when a
dynamically-linked executable is called, that patch is extended
with $LD_LIBRARY_PATH

Ideally, during development, we want to build build binaries that (a)
link dynamically, (b) can be tested in the build directory without
installing to system space (in particular, so we can run ad-hoc
tests without disturbing a production installation) and (c) won't
carry a potential exploit into system space if the binaries are
installed.

The potential exploit is the remnant presence of the build directory in
the binary's internal list of places it will look for shared libraries.
We need that to be there for testing purposes, but we want it gone
in the version of the binary that's copied to /lib or /usr/lib. Otherwise
there are threat scenarios with a maliciously crafted library.

To get (b) without runtime tweaking of LD_LIBRARY_PATH, the
development directory needs to be in RPATH, opening the security hole.
Without editing RPATH at installation time we can get any two of those
three, but we can't get all three. Choosing static linking we get (b)
and (c), choosing dynamic linking without chrpath we get (a) and (b).

chrpath is a tool for editing RPATH in object files.

Ubuntu users can do 'apt-get install chrpath'
CentOS users can do 'yum install chrpath' from extras.

== The leapseconds cache ==

Early in your build, the recipe will try to go over the Internet to
@@ -265,9 +273,9 @@ one of several sources of current data on the leap-second offset in
order to ensure that the file leapseconds.cache is up to date. This,
in turn, is used to build a timebase.h include file.

This procedure may fail if you are building inside an intranet that
requires an authenticating web proxy. If that occurs, it will time
out with a warning and a suggestion to use the leapfetch=no build
This procedure may fail if you are building in a network that
requires an authenticating web proxy. If that occurs, the build will
time out with a warning and a suggestion to use the leapfetch=no build
option.

Building with leapfetch=no may, in unusual circumstances, result in
@@ -350,7 +358,7 @@ illustrating how to do that, with some routine messages suppressed and
replaced with [...], follows. The script assumes you're cloning from the
GPSD project site or a mirror. Notes and explanation follow the transcript.

===========================================================================
----
$ git clone [...]
Cloning into gpsd...
[...]
@@ -392,7 +400,7 @@ arm-indigo-linux-gnueabi-gcc -o gps_maskdump.os -c --sysroot=/work/buildroot/out
scons: done building targets.
$ file gpsd
gpsd: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.36, not stripped
===========================================================================
----

The author of this transcript notes:



control → control.in View File

@@ -15,12 +15,15 @@ Description: A monitoring daemon for GPSes, AIS radios, and other nav sensors.
distribution includes sample clients, application interface libraries,
and test/profiling tools.

XBS-Destinations: ~, savannah, freecode
XBS-Destinations: savannah, freecode, mailto:@ANNOUNCE@

XBS-Web-Directory: www

XBS-IRC-Channel: irc://chat.freenode.net/#gpsd
Homepage: @WEBSITE@

XBS-IRC-Channel: @IRCCHAN@

XBS-Project-Tag-List: Communications, Scientific/Engineering, Geographical

XBS-VC-Tag-Template: %(version)s


+ 3
- 24
driver_nmea0183.c View File

@@ -77,10 +77,8 @@ static void merge_ddmmyy(char *ddmmyy, struct gps_device_t *session)
int year;

/* check for century wrap */
if (session->driver.nmea.date.tm_year % 100 == 99 && yy == 0) {
session->context->century += 100;
gpsd_report(session->context->debug, LOG_WARN, "century rollover detected.\n");
}
if (session->driver.nmea.date.tm_year % 100 == 99 && yy == 0)
gpsd_century_update(session, session->context->century + 100);
year = (session->context->century + yy);

if ( (1 > mon ) || (12 < mon ) ) {
@@ -767,26 +765,7 @@ static gps_mask_t processGPZDA(int c UNUSED, char *field[],
gpsd_report(session->context->debug, LOG_WARN,
"malformed ZDA day: %s\n", field[2]);
} else {
if (century > session->context->century) {
/*
* This mismatch is almost certainly not due to a GPS week
* rollover, because that would throw the ZDA report backward
* into the last rollover period instead of forward. Almost
* certainly it means that a century mark has passed while
* gpsd was running, and we should trust the new ZDA year.
*/
gpsd_report(session->context->debug, LOG_WARN,
"century rollover detected.\n");
session->context->century = century;
} else if (session->context->start_time >= GPS_EPOCH && century < session->context->century) {
/*
* This looks like a GPS week-counter rollover.
*/
gpsd_report(session->context->debug, LOG_WARN,
"ZDA year %d less than clock year, "
"probable GPS week rollover lossage\n",
year);
}
gpsd_century_update(session, century);
session->driver.nmea.date.tm_year = year - 1900;
session->driver.nmea.date.tm_mon = mon - 1;
session->driver.nmea.date.tm_mday = mday;


+ 32
- 3
driver_ubx.c View File

@@ -68,7 +68,9 @@ static gps_mask_t ubx_msg_nav_svinfo(struct gps_device_t *session,
unsigned char *buf, size_t data_len);
static void ubx_msg_sbas(struct gps_device_t *session, unsigned char *buf);
static void ubx_msg_inf(unsigned char *buf, size_t data_len, const int debug);
#ifdef RECONFIGURE_ENABLE
static void ubx_mode(struct gps_device_t *session, int mode);
#endif /* RECONFIGURE_ENABLE */

/**
* Navigation solution message
@@ -105,10 +107,22 @@ ubx_msg_nav_sol(struct gps_device_t *session, unsigned char *buf,
ecef_to_wgs84fix(&session->newdata, &session->gpsdata.separation,
epx, epy, epz, evx, evy, evz);
mask |= LATLON_SET | ALTITUDE_SET | SPEED_SET | TRACK_SET | CLIMB_SET;
session->newdata.epx = session->newdata.epy =
(double)(getles32(buf, 24) / 100.0) / sqrt(2);

if (session->driver.ubx.last_herr > 0.0) {
session->newdata.epx = session->newdata.epy = session->driver.ubx.last_herr;
mask |= HERR_SET;
session->driver.ubx.last_herr = 0.0;
}

if (session->driver.ubx.last_verr > 0.0) {
session->newdata.epv = session->driver.ubx.last_verr;
mask |= VERR_SET;
session->driver.ubx.last_verr = 0.0;
}

session->newdata.eps = (double)(getles32(buf, 40) / 100.0);
mask |= HERR_SET | SPEEDERR_SET;
mask |= SPEEDERR_SET;
/* Better to have a single point of truth about DOPs */
//session->gpsdata.dop.pdop = (double)(getleu16(buf, 44)/100.0);
session->gpsdata.satellites_used = (int)getub(buf, 47);
@@ -149,6 +163,18 @@ ubx_msg_nav_sol(struct gps_device_t *session, unsigned char *buf,
return mask;
}

/**
* Geodetic position solution message
*/
static gps_mask_t
ubx_msg_nav_posllh(struct gps_device_t *session, unsigned char *buf,
size_t data_len UNUSED)
{
session->driver.ubx.last_herr = (double)(getleu32(buf, 20) / 1000.0);
session->driver.ubx.last_verr = (double)(getleu32(buf, 24) / 1000.0);
return 0;
}

/**
* Dilution of precision message
*/
@@ -362,6 +388,7 @@ gps_mask_t ubx_parse(struct gps_device_t * session, unsigned char *buf,
break;
case UBX_NAV_POSLLH:
gpsd_report(session->context->debug, LOG_DATA, "UBX_NAV_POSLLH\n");
mask = ubx_msg_nav_posllh(session, &buf[UBX_PREFIX_LEN], data_len);
break;
case UBX_NAV_STATUS:
gpsd_report(session->context->debug, LOG_DATA, "UBX_NAV_STATUS\n");
@@ -620,12 +647,14 @@ static void ubx_event_hook(struct gps_device_t *session, event_t event)
(void)ubx_write(session, UBX_CLASS_MON, 0x04, msg, 0);
/*@ +type @*/

#ifdef RECONFIGURE_ENABLE
/*
* Turn off NMEA output, turn on UBX on this port.
*/
if (session->mode == O_OPTIMIZE) {
ubx_mode(session, MODE_BINARY);
}
#endif /* RECONFIGURE_ENABLE */
} else if (event == event_deactivate) {
/*@ -type @*/
unsigned char msg[4] = {


+ 1
- 1
driver_zodiac.c View File

@@ -54,8 +54,8 @@ static ssize_t end_write(int fd, void *d, size_t len)
{
unsigned char buf[BUFSIZ];
short *data = (short *)d;
size_t n = (size_t)(len/2);

size_t n;
for (n = 0; n < (size_t)(len/2); n++)
putle16(buf, n*2, data[n]);
return write(fd, (char*)buf, len);


+ 5
- 3
gps.h View File

@@ -38,7 +38,7 @@ extern "C" {
* gps_poll() removed in favor of gps_read(). The raw hook is gone.
* 5.1 - GPS_PATH_MAX uses system PATH_MAX; split24 flag added. New
* model and serial members in part B of AIS type 24, conforming
* with ITU-R 1371-4. New timedrift structure.
* with ITU-R 1371-4. New timedrift structure (Nov 2013, release 3.10).
*/
#define GPSD_API_MAJOR_VERSION 5 /* bump on incompatible changes */
#define GPSD_API_MINOR_VERSION 1 /* bump on compatible changes */
@@ -1894,7 +1894,8 @@ struct timedrift_t {
};

/* difference between timespecs in nanoseconds */
#define timespec_diff_ns(x, y) (int)(((x).tv_sec-(y).tv_sec)*1e9+(x).tv_nsec-(y).tv_nsec)
/* int is too small, avoid floats */
#define timespec_diff_ns(x, y) (long)(((x).tv_sec-(y).tv_sec)*1000000000+(x).tv_nsec-(y).tv_nsec)

/*
* Someday we may support Windows, under which socket_t is a separate type.
@@ -1959,7 +1960,8 @@ struct gps_data_t {
#define LOGMESSAGE_SET (1llu<<30)
#define ERROR_SET (1llu<<31)
#define TIMEDRIFT_SET (1llu<<32)
#define SET_HIGH_BIT 33
#define EOF_SET (1llu<<33)
#define SET_HIGH_BIT 34
timestamp_t online; /* NZ if GPS is on line, 0 if not.
*
* Note: gpsd clears this time when sentences


+ 2
- 5
gps/client.py View File

@@ -17,7 +17,7 @@ class json_error(exceptions.Exception):
self.explanation = explanation

class gpscommon:
"Isolate socket handling and buffering from the protcol interpretation."
"Isolate socket handling and buffering from the protocol interpretation."
def __init__(self, host="127.0.0.1", port=GPSD_PORT, verbose=0):
self.sock = None # in case we blow up in connect
self.linebuffer = ""
@@ -133,11 +133,8 @@ WATCH_SPLIT24 = 0x001000 # split AIS Type 24s
WATCH_PPS = 0x002000 # enable PPS in raw/NMEA
WATCH_DEVICE = 0x000800 # watch specific device

class gpsjson(gpscommon):
class gpsjson:
"Basic JSON decoding."
def __init__(self):
gpscommon.__init__(self)

def __iter__(self):
return self



+ 11
- 2
gps/fake.py View File

@@ -626,13 +626,14 @@ class TestSession:
had_output = False
chosen = self.choose()
if isinstance(chosen, FakeGPS):
if chosen.exhausted and (time.time() - chosen.exhausted > CLOSE_DELAY):
if chosen.exhausted and (time.time() - chosen.exhausted > CLOSE_DELAY) and chosen.byname in self.fakegpslist:
self.gps_remove(chosen.byname)
self.progress("gpsfake: GPS %s removed\n" % chosen.byname)
self.progress("gpsfake: GPS %s removed (timeout)\n" % chosen.byname)
elif not chosen.go_predicate(chosen.index, chosen):
if chosen.exhausted == 0:
chosen.exhausted = time.time()
self.progress("gpsfake: GPS %s ran out of input\n" % chosen.byname)
chosen.write("# EOF\n")
else:
chosen.feed()
elif isinstance(chosen, gps.gps):
@@ -643,6 +644,14 @@ class TestSession:
chosen.read()
if chosen.valid & gps.PACKET_SET:
self.reporter(chosen.response)
# If we're lucky, this close notification reaches
# us before the device timeout. It would be nice
# if this were the only logic for device closing
# and we could get rid of CLOSE_DELAY, but this
# sometimes fails on binary logfiles.
if chosen.data["class"] == "DEVICE" and chosen.data["activated"] == 0 and chosen.data["path"] in self.fakegpslist:
self.gps_remove(chosen.data["path"])
self.progress("gpsfake: GPS %s removed (notification)\n" % chosen.data["path"])
had_output = True
else:
raise TestSessionError("test object of unknown type")


+ 2
- 1
gps/gps.py View File

@@ -53,7 +53,8 @@ POLICY_SET = (1<<29)
LOGMESSAGE_SET = (1<<30)
ERROR_SET = (1<<31)
TIMEDRIFT_SET = (1<<32)
SET_HIGH_BIT = 33
EOF_SET = (1<<33)
SET_HIGH_BIT = 34
UNION_SET = (RTCM2_SET|RTCM3_SET|SUBFRAME_SET|AIS_SET|VERSION_SET|DEVICELIST_SET|ERROR_SET|GST_SET)
STATUS_NO_FIX = 0
STATUS_FIX = 1


+ 6
- 6
gps2udp.1 View File

@@ -31,7 +31,7 @@
gps2udp \- feed the take from gpsd to one or more aggregation sites
.SH "SYNOPSIS"
.HP \w'\fBgps2udp\fR\ 'u
\fBgps2udp\fR [\-h] [\-n] [\-j] [\-a] [\-u\ \fIhostname:udpport\fR] [\-c\ \fIcount\fR] [\-d] [\-v] [\fIserver\fR [\fI:port\fR [\fI:device\fR]]]
\fBgps2udp\fR [\-h] [\-n] [\-j] [\-a] [\-u\ \fIhostname:udpport\fR] [\-c\ \fIcount\fR] [\-d\ \fI1|2\fR] [\-v] [\fIserver\fR [\fI:port\fR [\fI:device\fR]]]
.SH "DESCRIPTION"
.PP
gps2udp
@@ -80,11 +80,11 @@ print a usage message and exit\&.
gps2udp
to run as a daemon\&.
.PP
\-n [count] causes [count] sentences to be output\&.
\-c [count] causes [count] sentences to be output\&.
gps2udp
will then exit gracefully\&.
.PP
\-d prints sent packet on stdout\&.
\-d 1 prints sent packet on stdout\&.
.PP
\-v prints the version, then exits\&.
.SH "EXAMPLE"
@@ -92,11 +92,11 @@ will then exit gracefully\&.
With a running
gpsd accessible on the network
.PP
\fBgps2udp \-d \-n \-u data\&.aishub\&.net:2222 \fR
\fBgps2udp \-d 1 \-n \-u data\&.aishub\&.net:2222 \fR
will collect data from localhost:gpsd display them on stdout and send a copy to test aishub in NMEA format\&.
.PP
\fBgps2udp \-a \-n \-b \-u data\&.aishub\&.net 2222 \-u 5\&.9\&.207\&.224 5321 \-u 109\&.200\&.19\&.151 4001 vz\-fulup\&.vpn:2947\fR
will collect data from a remote gpsd located on vz\-fulup\&.vpn host, will filter AIS messages and send them to 3 destination (aishub, marinetraffic, shipfinder) in NMEA format, command is running in background mode
\fBgps2udp \-a \-n \-b \-u data\&.aishub\&.net:2222 \-u 5\&.9\&.207\&.224:5321 \-u 109\&.200\&.19\&.151:4001 fridu\&.net:2947\fR
will collect data from a remote gpsd located on fridu\&.net host, will filter AIS messages and send them to 3 destination (aishub, marinetraffic, shipfinder) in NMEA format, command is running in background mode
.SH "SEE ALSO"
.PP
\fBgpsd\fR(8),


+ 40
- 27
gps2udp.c View File

@@ -80,15 +80,15 @@ static bool aisonly = false;

static int send_udp (char *nmeastring, size_t ind)
{
char message[255];
char message [255];
char *buffer;
int channel;

/* if string length is unknown make a copy and compute it */
/* if string length is unknow make a copy and compute it */
if (ind == 0) {
/* compute message size and add 0x0a 0x0d */
for (ind=0; nmeastring [ind] != '\0'; ind ++) {
if (ind >= sizeof(message) - 3) {
if (ind >= sizeof(message)) {
fprintf(stderr, "gps2udp: too big [%s] \n", nmeastring);
return -1;
}
@@ -96,7 +96,7 @@ static int send_udp (char *nmeastring, size_t ind)
}
buffer = message;
} else {
/* use directly nmeastring but change termination */
/* use directly nmeastring but change terminition */
buffer = nmeastring;
ind = ind-1;
}
@@ -105,16 +105,20 @@ static int send_udp (char *nmeastring, size_t ind)
buffer[ind] = '\r'; ind++;
buffer[ind] = '\0';

if (!(flags & WATCH_JSON) && buffer[0] == '{') {
/* do not send JSON when not configured to do so */
return 0;
}

/* send message on udp channel */
/*@-type@*/
for (channel=0; channel < udpchannel; channel ++) {
ssize_t status;
status = sendto(sock[channel],
buffer,
ind,
0,
&remote[channel],
(int)sizeof(remote));
ssize_t status = sendto(sock[channel],
buffer,
ind,
0,
&remote[channel],
(int)sizeof(remote));
if (status < (ssize_t)ind) {
(void)fprintf(stderr, "gps2udp: failed to send [%s] \n", nmeastring);
return -1;
@@ -129,13 +133,16 @@ static int open_udp(char **hostport)
/* Open and bind udp socket to host */
{
int channel;
for (channel=0; channel < udpchannel; channel ++)

for (channel=0; channel <udpchannel; channel ++)
{
struct hostent *hp;
char *hostname = NULL;
char *portname = NULL;
char *endptr = '\0';
int portnum;
/* parse argument */
struct hostent *hp;

/* parse argument */
/*@-unrecog@*/
hostname = strsep(&hostport[channel], ":");
portname = strsep(&hostport[channel], ":");
@@ -145,8 +152,9 @@ static int open_udp(char **hostport)
return (-1);
}

portnum = atoi(portname);
if (errno != 0) {
errno = 0;
portnum = strtol(portname, &endptr, 10);
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);
}
@@ -184,6 +192,7 @@ static void usage(void)
"-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"
);
}

@@ -290,8 +299,10 @@ static ssize_t read_gpsd(char *message, size_t len)
connect2gpsd(true);
retry = 0;
}
/*@-sefparams@*/
if (debug > 0)
/*@i2@*/ignore_return(write (1, ".", 1));
ignore_return(write (1, ".", 1));
/*@+sefparams@*/
break;

default: /* we lost connection with gpsd */
@@ -299,7 +310,7 @@ static ssize_t read_gpsd(char *message, size_t len)
break;
}
}
message[ind-1] = '\0';
message[ind] = '\0';
(void)fprintf (stderr,"\n gps2udp: message too big [%s]\n", message);
return(-1);
}
@@ -336,7 +347,6 @@ static unsigned int AISGetInt(unsigned char *bitbytes, unsigned int sp, unsigned
for(i=0 ; i<len ; i++)
{
unsigned int cp, cx, c0;

acc = acc << 1;
cp = (s0p + i) / 6;
cx = (unsigned int)bitbytes[cp]; // what if cp >= byte_length?
@@ -356,11 +366,15 @@ int main(int argc, char **argv)
char *udphostport[MAX_UDP_DEST];

flags = WATCH_ENABLE;
while ((option = getopt(argc, argv, "?habnjcvl:u:d:")) != -1)
while ((option = getopt(argc, argv, "?habnjvc:l:u:d:")) != -1)
{
switch (option) {
case 'd':
debug = atoi(optarg);
if ((debug <1) || (debug > 2)) {
usage();
exit(1);
}
break;
case 'n':
if (debug >0)
@@ -393,12 +407,12 @@ int main(int argc, char **argv)
case 'v':
(void)fprintf(stderr, "%s: %s (revision %s)\n",
argv[0], VERSION, REVISION);
exit(EXIT_SUCCESS);
exit(0);
case '?':
case 'h':
default:
usage();
exit(EXIT_FAILURE);
exit(1);
}
}

@@ -416,8 +430,7 @@ int main(int argc, char **argv)
/* Open UDP port */
if (udpchannel > 0) {
int status = open_udp(udphostport);
if (status !=0)
exit(EXIT_FAILURE);
if (status !=0) exit (1);
}

/* Daemonize if the user requested it. */
@@ -484,8 +497,8 @@ int main(int argc, char **argv)
if (count-- == 0) {
/* completed count */
(void)fprintf(stderr,
"gpsd2udp: normal exit after %ld packets\n",count);
exit(EXIT_SUCCESS);
"gpsd2udp: normal exit after counted packets\n");
exit (0);
}
} // end count
} // end len > 3
@@ -494,7 +507,7 @@ int main(int argc, char **argv)
// This is an infinite loop, should never be here
/*@-unreachable@*/
fprintf (stderr, "gpsd2udp ERROR abnormal exit\n");
exit(EXIT_FAILURE);
exit (-1);
}
/*@=compdef =usedef@*/



+ 6
- 7
gps2udp.xml View File

@@ -28,7 +28,7 @@ BSD terms apply: see the file COPYING in the distribution root for details.
<arg choice='opt'>-a</arg>
<arg choice='opt'>-u <replaceable>hostname:udpport</replaceable></arg>
<arg choice='opt'>-c <replaceable>count</replaceable></arg>
<arg choice='opt'>-d</arg>
<arg choice='opt'>-d <replaceable>1|2</replaceable></arg>
<arg choice='opt'>-v</arg>
<group>
<replaceable>server</replaceable>
@@ -83,10 +83,10 @@ destinations).</para>

<para>-a output only AIS messages.</para>
<para>-b causes <application>gps2udp</application> to run as a daemon.</para>
<para>-n [count] causes [count] sentences to be output.
<para>-c [count] causes [count] sentences to be output.
<application>gps2udp</application> will then exit gracefully.</para>

<para>-d prints sent packet on stdout.</para>
<para>-d 1 prints sent packet on stdout.</para>
<para>-v prints the version, then exits.</para>
</refsect1>

@@ -94,13 +94,12 @@ destinations).</para>
<para>With a running <application>gpsd accessible on the
network</application> </para>

<para><command>gps2udp -d -n -u data.aishub.net:2222 </command> will
<para><command>gps2udp -d 1 -n -u data.aishub.net:2222 </command> will
collect data from localhost:gpsd display them on stdout and send a
copy to test aishub in NMEA format.</para>

<para><command>gps2udp -a -n -b -u data.aishub.net 2222 -u 5.9.207.224
5321 -u 109.200.19.151 4001 vz-fulup.vpn:2947</command> will collect
data from a remote gpsd located on vz-fulup.vpn host, will filter AIS
<para><command>gps2udp -a -n -b -u data.aishub.net:2222 -u 5.9.207.224:5321 -u 109.200.19.151:4001 fridu.net:2947</command> will collect
data from a remote gpsd located on fridu.net host, will filter AIS
messages and send them to 3 destination (aishub, marinetraffic,
shipfinder) in NMEA format, command is running in background
mode</para>


+ 1
- 0
gps_maskdump.c View File

@@ -49,6 +49,7 @@ const char *gps_maskdump(gps_mask_t set)
{LOGMESSAGE_SET, "LOGMESSAGE"},
{ERROR_SET, "ERROR"},
{TIMEDRIFT_SET, "TIMEDRIFT"},
{EOF_SET, "EOF"},
{RAW_IS, "RAW"},
{USED_IS, "USED"},
{DRIVER_IS, "DRIVER"},


+ 1
- 1
gpscat.1 View File

@@ -31,7 +31,7 @@
gpscat \- dump the output from a GPS
.SH "SYNOPSIS"
.HP \w'\fBgpscat\fR\ 'u
\fBgpscat\fR [\-s\ \fIspeed\fR] [\-p] [\-t] [\-D\ \fIdebuglevel\fR] \fIserial\-port\fR
\fBgpscat\fR [\-s\ \fIspeed\fR] [\-p] [\-t] [\-D\ \fIdebuglevel\fR] \fIfile\-or\-serial\-port\fR
.SH "DESCRIPTION"
.PP
gpscat


+ 1
- 1
gpscat.xml View File

@@ -26,7 +26,7 @@ BSD terms apply: see the file COPYING in the distribution root for details.
<arg choice='opt'>-p</arg>
<arg choice='opt'>-t</arg>
<arg choice='opt'>-D <replaceable>debuglevel</replaceable></arg>
<arg choice='plain'><replaceable>serial-port</replaceable></arg>
<arg choice='plain'><replaceable>file-or-serial-port</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>



+ 5
- 1
gpsctl.c View File

@@ -363,7 +363,7 @@ int main(int argc, char **argv)
if (gps_open(NULL, NULL, &gpsdata) != 0) {
gpsd_report(context.debug, LOG_ERROR,
"no gpsd running or network error: %s.\n",
netlib_errstr(errno));
gps_errstr(errno));
lowlevel = true;
}
}
@@ -688,6 +688,10 @@ int main(int argc, char **argv)
gpsd_report(context.debug, LOG_WARN,
"device error, bailing out.\n");
exit(EXIT_FAILURE);
case DEVICE_EOF:
gpsd_report(context.debug, LOG_WARN,
"device signed off, bailing out.\n");
exit(EXIT_SUCCESS);
default:
break;
}


+ 24
- 29
gpsd.c View File

@@ -44,11 +44,6 @@

#include "gpsd_config.h"

#if defined(HAVE_LIBCAP) && !defined(S_SPLINT_S)
#include <sys/capability.h>
#include <sys/prctl.h>
#endif /* HAVE_LIBCAP */

#include "gpsd.h"
#include "sockaddr.h"
#include "gps_json.h"
@@ -335,6 +330,10 @@ static void adjust_max_fd(int fd, bool on)
}

#ifdef SOCKET_EXPORT_ENABLE
#ifndef IPTOS_LOWDELAY
#define IPTOS_LOWDELAY 0x10
#endif

static socket_t passivesock_af(int af, char *service, char *tcp_or_udp, int qlen)
/* bind a passive command socket for the daemon */
{
@@ -352,7 +351,7 @@ static socket_t passivesock_af(int af, char *service, char *tcp_or_udp, int qlen
int type, proto, one = 1;
in_port_t port;
char *af_str = "";
const int dscp = IPTOS_LOWDELAY; /* Prioritize packet */
INVALIDATE_SOCKET(s);
if ((pse = getservbyname(service, tcp_or_udp)))
port = ntohs((in_port_t) pse->s_port);
@@ -391,6 +390,13 @@ static socket_t passivesock_af(int af, char *service, char *tcp_or_udp, int qlen
af_str = "IPv4";
/* see PF_INET6 case below */
s = socket(PF_INET, type, proto);
if (s > -1 ) {
/* Set packet priority */
if (setsockopt(s, IPPROTO_IP, IP_TOS, &dscp, sizeof(dscp)) == -1)
gpsd_report(context.debug, LOG_WARN,
"Warning: SETSOCKOPT TOS failed\n");
}

break;
#ifdef IPV6_ENABLE
case AF_INET6:
@@ -432,6 +438,10 @@ static socket_t passivesock_af(int af, char *service, char *tcp_or_udp, int qlen
(void)close(s);
return -1;
}
/* Set packet priority */
if (setsockopt(s, IPPROTO_IPV6, IPV6_TCLASS, &dscp, sizeof(dscp)) == -1)
gpsd_report(context.debug, LOG_WARN,
"Warning: SETSOCKOPT TOS failed\n");
}
#endif /* S_SPLINT_S */
break;
@@ -902,7 +912,7 @@ static void handle_control(int sfd, char *buf)
ignore_return(write(sfd, "ERROR\n", 6));
}
}
} else if (strcmp(buf, "?devices")==0) {
} else if (strstr(buf, "?devices")==buf) {
/* write back devices list followed by OK */
for (devp = devices; devp < devices + MAXDEVICES; devp++) {
char *path = devp->gpsdata.dev.path;
@@ -2039,13 +2049,6 @@ int main(int argc, char *argv[])
struct passwd *pw;
struct stat stb;

#if defined(HAVE_LIBCAP) && !defined(S_SPLINT_S)
/* set flag: keep privileges across setuid() call */
if (prctl(PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L) == -1)
gpsd_report(context.debug, LOG_ERR,
"prctl(PR_SET_KEEPCAPS, 1L ) failed\n");
#endif /* HAVE_LIBCAP */

/* make default devices accessible even after we drop privileges */
for (i = optind; i < argc; i++)
/* coverity[toctou] */
@@ -2059,6 +2062,12 @@ int main(int argc, char *argv[])
* of any compromises in the code. It requires that all GPS
* devices have their group read/write permissions set.
*/
/*@-nullpass@*/
if (setgroups(0, NULL) != 0)
gpsd_report(context.debug, LOG_ERROR,
"setgroups() failed, errno %s\n",
strerror(errno));
/*@+nullpass@*/
/*@-type@*/
#ifdef GPSD_GROUP
{
@@ -2087,21 +2096,6 @@ int main(int argc, char *argv[])
"setuid() failed, errno %s\n",
strerror(errno));
/*@+type@*/

#if defined(HAVE_LIBCAP) && !defined(S_SPLINT_S)
/* drop root capabilities, except CAP_SYS_TIME for 1PPS support */
{
cap_t caps = cap_from_text("cap_sys_time=pe");

if (!caps)
gpsd_report(context.debug, LOG_ERR, "cap_from_text() failed.\n");
else if (cap_set_proc(caps) == -1) {
gpsd_report(context.debug, LOG_ERR,
"cap_set_proc() failed to drop root privs\n");
cap_free(caps);
}
}
#endif /* HAVE_LIBCAP */
}
gpsd_report(context.debug, LOG_INF,
"running with effective group ID %d\n", getegid());
@@ -2297,6 +2291,7 @@ int main(int argc, char *argv[])
adjust_max_fd(device->gpsdata.gps_fd, false);
break;
case DEVICE_ERROR:
case DEVICE_EOF:
deactivate_device(device);
break;
default:


+ 16
- 5
gpsd.h-tail View File

@@ -77,7 +77,7 @@ typedef unsigned int speed_t;
#ifdef EARTHMATE_ENABLE
#define ZODIAC_ENABLE
#endif
#if defined(ZODIAC_ENABLE) || defined(SIRF_ENABLE) || defined(GARMIN_ENABLE) || defined(TSIP_ENABLE) || defined(EVERMORE_ENABLE) || defined(ITRAX_ENABLE) || defined(UBLOX_ENABLE) || defined(SUPERSTAR2_ENABLE) || defined(ONCORE_ENABLE) || defined(GEOSTAR_ENABLE) || defined(NAVCOM_ENABLE)
#if defined(ZODIAC_ENABLE) || defined(SIRF_ENABLE) || defined(GARMIN_ENABLE) || defined(TSIP_ENABLE) || defined(EVERMORE_ENABLE) || defined(ITRAX_ENABLE) || defined(UBLOX_ENABLE) || defined(SUPERSTAR2_ENABLE) || defined(ONCORE_ENABLE) || defined(GEOSTAR_ENABLE) || defined(NAVCOM_ENABLE) || defined(NMEA2000_ENABLE)
#define BINARY_ENABLE
#endif
#if defined(TRIPMATE_ENABLE) || defined(BINARY_ENABLE)
@@ -232,10 +232,11 @@ struct gps_device_t;

struct gps_context_t {
int valid; /* member validity flags */
int debug; /* dehug verbosity level */
bool readonly; /* if true, never write to device */
#define LEAP_SECOND_VALID 0x01 /* we have or don't need correction */
#define GPS_TIME_VALID 0x02 /* GPS week/tow is valid */
#define CENTURY_VALID 0x04 /* have received ZDA or 4-digit year */
int debug; /* dehug verbosity level */
bool readonly; /* if true, never write to device */
/* DGPS status */
int fixcnt; /* count of good fixes seen */
/* timekeeping */
@@ -474,7 +475,7 @@ struct gps_device_t {
int shmIndexPPS;
# endif /* PPS_ENABLE */
#endif /* NTPSHM_ENABLE */
timestamp_t last_fixtime; /* so updates happen once */
volatile timestamp_t last_fixtime; /* so updates happen once */
#ifdef PPS_ENABLE
#if defined(HAVE_SYS_TIMEPPS_H)
pps_handle_t kernelpps_handle;
@@ -618,6 +619,14 @@ struct gps_device_t {
struct {
unsigned char port_id;
unsigned char sbas_in_use;
/*
* NAV-* message order is not defined, thus we handle them isochronously
* and store the latest data into these variables rather than expect
* some messages to arrive in order. NAV-SOL handler picks up these values
* and inserts them into the fix structure in one go.
*/
double last_herr;
double last_verr;
} ubx;
#endif /* UBLOX_ENABLE */
#ifdef NAVCOM_ENABLE
@@ -794,8 +803,9 @@ extern void gpsd_set_century(struct gps_device_t *);
extern timestamp_t gpsd_gpstime_resolve(/*@in@ */ struct gps_device_t *,
const unsigned short, const double);
extern timestamp_t gpsd_utc_resolve(/*@in@*/struct gps_device_t *);
extern void gpsd_century_update(/*@in@*/struct gps_device_t *, int);

extern void gpsd_zero_satellites(/*@out@*/struct gps_data_t *sp)/*@modifies sp@*/;
extern void gpsd_zero_satellites(/*@out@*/struct gps_data_t *sp);
extern gps_mask_t gpsd_interpret_subframe(struct gps_device_t *, unsigned int,
uint32_t[]);
extern gps_mask_t gpsd_interpret_subframe_raw(struct gps_device_t *,
@@ -934,6 +944,7 @@ extern int gpsd_await_data(/*@out@*/fd_set *,
/*@in@*/fd_set *,
const int);
extern gps_mask_t gpsd_poll(struct gps_device_t *);
#define DEVICE_EOF -3
#define DEVICE_ERROR -2
#define DEVICE_UNREADY -1
#define DEVICE_READY 1


+ 2
- 0
gpsd.php View File

@@ -1,5 +1,7 @@
<?php

# DO NOT HAND_HACK! THIS FILE IS GENERATED

# Copyright (c) 2006,2010 Chris Kuethe <chris.kuethe@gmail.com>
#
# Permission to use, copy, modify, and distribute this software for any


+ 2
- 0
gpsd.php.in View File

@@ -1,5 +1,7 @@
<?php

# @MASTER@

# Copyright (c) 2006,2010 Chris Kuethe <chris.kuethe@gmail.com>
#
# Permission to use, copy, modify, and distribute this software for any


+ 2
- 0
gpsd.rules View File

@@ -45,6 +45,8 @@ ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a5", SYMLINK="gps%n", RUN+="/lib/u
ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a6", SYMLINK="gps%n", RUN+="/lib/udev/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"
# 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"

ACTION=="remove", RUN+="/lib/udev/gpsd.hotplug"



+ 12
- 4
gpsd_json.c View File

@@ -213,10 +213,17 @@ void json_tpv_dump(const struct gps_device_t *session,
replylen - strlen(reply),
"\"epc\":%.2f,", gpsdata->fix.epc);
#ifdef TIMING_ENABLE
if (policy->timing)
(void)snprintf(reply + strlen(reply),
replylen - strlen(reply),
"\"sor\":%f,\"chars\":%lu,\"sats\":%2d,\"rtime\":%f,\"week\":%u,\"tow\":%.3f,\"rollovers\":%d",
if (policy->timing) {
#ifdef PPS_ENABLE
/*@-type -formattype@*/ /* splint is confused about struct timespec */
if (session->ppscount)
(void)snprintf(reply + strlen(reply), replylen - strlen(reply),
"\"pps\":%.9f,",
session->ppslast.clock.tv_sec + session->ppslast.clock.tv_nsec / 1e9);
/*@+type +formattype@*/
#endif /* PPS_ENABLE */
(void)snprintf(reply + strlen(reply), replylen - strlen(reply),
"\"sor\":%.9f,\"chars\":%lu,\"sats\":%2d,\"rtime\":%.9f,\"week\":%u,\"tow\":%.3f,\"rollovers\":%d",
session->sor,
session->chars,
gpsdata->satellites_used,
@@ -224,6 +231,7 @@ void json_tpv_dump(const struct gps_device_t *session,
session->context->gps_week,
session->context->gps_tow,
session->context->rollovers);
}
#endif /* TIMING_ENABLE */
}
if (reply[strlen(reply) - 1] == ',')


+ 1
- 1
gpsfake View File

@@ -2,7 +2,7 @@
#
# gpsfake -- test harness for gpsd
#
# Simulates a GPS, playing back a logfile
# Simulates one or more GPSes, playing back logfiles.
# Most of the logic for this now lives in gps.fake,
# factored out so we can write other test programs with it.
#


+ 25
- 6
gpsmon.c View File

@@ -24,6 +24,7 @@
#endif /* S_SPLINT_S */

#include "gpsd.h"
#include "gps_json.h"
#include "gpsmon.h"
#include "revision.h"

@@ -35,7 +36,9 @@ extern struct monitor_object_t garmin_mmt, garmin_bin_ser_mmt;
extern struct monitor_object_t italk_mmt, ubx_mmt, superstar2_mmt;
extern struct monitor_object_t fv18_mmt, gpsclock_mmt, mtk3301_mmt;
extern struct monitor_object_t oncore_mmt, tnt_mmt, aivdm_mmt;
#ifdef NMEA_ENABLE
extern const struct gps_type_t driver_nmea0183;
#endif /* NMEA_ENABLE */

/* These are public */
struct gps_device_t session;
@@ -476,9 +479,11 @@ static void select_packet_monitor(struct gps_device_t *device)
*/
if (device->packet.type != last_type) {
const struct gps_type_t *active_type = device->device_type;
#ifdef NMEA_ENABLE
if (device->packet.type == NMEA_PACKET
&& ((device->device_type->flags & DRIVER_STICKY) != 0))
active_type = &driver_nmea0183;
#endif /* NMEA_ENABLE */
if (!switch_type(active_type))
longjmp(terminate, TERM_DRIVER_SWITCH);
else {
@@ -631,7 +636,9 @@ ssize_t gpsd_write(struct gps_device_t *session,
const size_t len)
/* pass low-level data to devices, echoing it to the log window */
{
#if defined(CONTROLSEND_ENABLE) || defined(RECONFIGURE_ENABLE)
monitor_dump_send((const char *)buf, len);
#endif /* defined(CONTROLSEND_ENABLE) || defined(RECONFIGURE_ENABLE) */
return gpsd_serial_write(session, buf, len);
}

@@ -652,12 +659,8 @@ bool monitor_control_send( /*@in@*/ unsigned char *buf, size_t len)

static bool monitor_raw_send( /*@in@*/ unsigned char *buf, size_t len)
{
if (!serial)
return false;
else {
ssize_t st = gpsd_write(&session, (char *)buf, len);
return (st > 0 && (size_t) st == len);
}
ssize_t st = gpsd_write(&session, (char *)buf, len);
return (st > 0 && (size_t) st == len);
}
#endif /* CONTROLSEND_ENABLE */

@@ -723,6 +726,17 @@ static void gpsmon_hook(struct gps_device_t *device, gps_mask_t changed UNUSED)
else
#endif /* PPS_ENABLE */
{
#ifdef __future__
if (!serial)
{
if (device->packet.type == JSON_PACKET)
{
const char *end = NULL;
libgps_json_unpack((char *)device->packet.outbuffer, &session.gpsdata, &end);
}
}
#endif /* __future__ */

if (curses_active)
select_packet_monitor(device);

@@ -815,7 +829,9 @@ static bool do_command(const char *line)
context.readonly = !context.readonly;
else
context.readonly = (atoi(line + 1) == 0);
#ifdef RECONFIGURE_ENABLE
announce_log("[probing %sabled]", context.readonly ? "dis" : "en");
#endif /* RECONFIGURE_ENABLE */
if (!context.readonly)
/* magic - forces a reconfigure */
session.packet.counter = 0;
@@ -1265,6 +1281,9 @@ int main(int argc, char **argv)
case DEVICE_ERROR:
longjmp(terminate, TERM_READ_ERROR);
break;
case DEVICE_EOF:
longjmp(terminate, TERM_QUIT);
break;
default:
break;
}


+ 11
- 0
gpspacket.c View File

@@ -273,4 +273,15 @@ initpacket(void)
PyModule_AddIntConstant(m, "RTCM2_PACKET", RTCM2_PACKET);
PyModule_AddIntConstant(m, "RTCM3_PACKET", RTCM3_PACKET);
PyModule_AddIntConstant(m, "JSON_PACKET", JSON_PACKET);

PyModule_AddIntConstant(m, "LOG_ERROR", LOG_ERROR);
PyModule_AddIntConstant(m, "LOG_SHOUT", LOG_SHOUT);
PyModule_AddIntConstant(m, "LOG_WARN", LOG_WARN);
PyModule_AddIntConstant(m, "LOG_CLIENT", LOG_CLIENT);
PyModule_AddIntConstant(m, "LOG_INF", LOG_INF);
PyModule_AddIntConstant(m, "LOG_PROG", LOG_PROG);
PyModule_AddIntConstant(m, "LOG_IO", LOG_IO);
PyModule_AddIntConstant(m, "LOG_DATA", LOG_DATA);
PyModule_AddIntConstant(m, "LOG_SPIN", LOG_SPIN);
PyModule_AddIntConstant(m, "LOG_RAW", LOG_RAW);
}

+ 1
- 1
gpspipe.c View File

@@ -283,7 +283,7 @@ int main(int argc, char **argv)
if (gps_open(source.server, source.port, &gpsdata) != 0) {
(void)fprintf(stderr,
"gpspipe: could not connect to gpsd %s:%s, %s(%d)\n",
source.server, source.port, strerror(errno), errno);
source.server, source.port, gps_errstr(errno), errno);
exit(EXIT_FAILURE);
}
/*@ +nullpass +onlytrans @*/


+ 2
- 0
jsongen.py.in View File

@@ -1,5 +1,7 @@
#!@PYTHON@
#
# @MASTER@
#
# This file is Copyright (c) 2010 by the GPSD project
# BSD terms apply: see the file COPYING in the distribution root for details.
#


+ 67
- 59
leapsecond.py View File

@@ -4,10 +4,6 @@
Usage: leapsecond.py [-v] { [-h] | [-f filename] | [-g filename] | [-H filename]
| [-I isodate] | [-O unixdate] | [-i rfcdate] | [-o unixdate] | [-n MMMYYYY] }

With no option, get the current leap-second value. This is the offset between
UTC and GPS time, which changes occasionally due to variations in the Earth's
rotation.

Options:

-I take a date in ISO8601 format and convert to Unix gmt time
@@ -20,7 +16,7 @@ Options:

-c generate a C initializer listing leap seconds in Unix time.

-f fetch USNO data and save to local cache file
-f fetch leap-second offset data and save to local cache file

-H make leapsecond include

@@ -29,7 +25,11 @@ Options:
-v be verbose

-g generate a plot of the leap-second trend over time. The command you
probably want is "leapsecond.py -g leapseconds.cache | gnuplot -persist".
probably want is something like (depending on if your gnuplot install
does or does not support X11.

leapsecond.py -g leapseconds.cache | gnuplot --persist
leapsecond.py -g leapseconds.cache | gnuplot -e 'set terminal svg' - | display

-n compute Unix gmt time for an IERS leap-second event given as a three-letter
English Gregorian month abbreviation followed by a 4-digit year.
@@ -37,8 +37,8 @@ Options:
Public urls and local cache file used:

http://hpiers.obspm.fr/iers/bul/bulc/bulletinc.dat
http://hpiers.obspm.fr/iers/bul/bulc/UTC-TAI.history
ftp://maia.usno.navy.mil/ser7/tai-utc.dat
file:///var/run/leapsecond
leapseconds.cache

This file is Copyright (c) 2013 by the GPSD project
@@ -46,7 +46,7 @@ BSD terms apply: see the file COPYING in the distribution root for details.

"""

import os, urllib, re, random, time, calendar, math, sys
import os, urllib, re, random, time, calendar, math, sys, signal

# Set a socket timeout for slow servers
import socket
@@ -74,10 +74,11 @@ __locations = [
),
]

# File containing cached offset data.
# Two fields: the offset, and the start of the current six-month span
# between times it might change, in seconds since Unix epoch GMT (1970-01-01T00:00:00).
__cachepath = "/var/run/leapsecond"
GPS_EPOCH = 315964800 # 6 Jan 1981 00:00:00
SECS_PER_WEEK = 60 * 60 * 24 * 7 # Seconds per GPS week

def gps_week(t):
return (t - GPS_EPOCH)/SECS_PER_WEEK

def isotime(s):
"Convert timestamps in ISO8661 format to and from Unix time including optional fractional seconds."
@@ -147,42 +148,6 @@ def last_insertion_time():
else:
return jan

def get():
"Fetch GPS offset, from local cache file if possible."
stale = False
offset = None
valid_from = None
last_insertion = last_insertion_time()
if not os.path.exists(__cachepath):
stale = True
else:
try:
cfp = open(__cachepath)
txt = cfp.read()
cfp.close()
(offset, valid_from) = map(int, txt.split())
if valid_from < last_insertion:
stale = True
except (IOError, OSError, ValueError):
if verbose:
print >>sys.stderr, "can't read %s" % __cachepath
stale = True
# We now know whether the cached data is stale
if not stale:
return (offset, valid_from)
else:
current_offset = retrieve()
# Try to cache this for later
if current_offset != None:
try:
cfp = open(__cachepath, "w")
cfp.write("%d %d\n" % (current_offset, last_insertion))
cfp.close()
except (IOError, OSError):
if verbose:
print >>sys.stderr, "can't write %s" % __cachepath