@@ -20,9 +20,9 @@ a short initial burst of binary garbage). If you don't see this, you | |||
may have OS-level problems with your serial support, but more likely | |||
have the wrong device. Look again. | |||
If you have trouble wuth the preceding step, check your cabling | |||
If you have trouble with the preceding step, check your cabling | |||
first. Verify that the device is connected and that its power LED | |||
(if iut has one) is lit. | |||
(if it has one) is lit. | |||
If you seem to have some sort of serial-device problem, check that | |||
your kernel properly supports the device you are using. For GPSes | |||
@@ -86,7 +86,7 @@ various additional features have additional prerequisites: | |||
|========================================================================== | |||
Some ncurses packages comntain the terminfo library; some break it out | |||
seperately as libtinfo5 or libtinfo. | |||
separately as libtinfo5 or libtinfo. | |||
The Python code in GPSD is actually compatible back to Python 2.4 except that | |||
you need either the json library module from 2.6 or the functionally | |||
@@ -1,4 +1,8 @@ | |||
* Wed Oct 29 2011 Eric S. Raymond <esr@snark.thyrsus.com> - 3.3 | |||
* Thu 12 Jan 2012 Eric S. Raymond <esr@snark.thyrsus.com> - 3.4 | |||
Don't barf when chrpath is not available, fall back to static linking; | |||
helps people not running Linux. | |||
* Sat Oct 29 2011 Eric S. Raymond <esr@snark.thyrsus.com> - 3.3 | |||
Improvements to build and release-procedure documentation. Make | |||
sirf=no build work again. Main reason for this release is to make | |||
chrpath a mandatory build depedency and explain why in the build | |||
@@ -0,0 +1,13 @@ | |||
prefix=@prefix@ | |||
exec_prefix=${prefix} | |||
libdir=${exec_prefix}@libdir@ | |||
includedir=${prefix}/include | |||
qt_config=lex yacc warn_on uic resources qt release incremental link_prl def_files_disabled exceptions no_mocdepend stl qt_no_framework create_pc create_prl moc thread dll | |||
Name: Qgpsmm | |||
Description: GPS Daemon communication library - QT binding | |||
Version: @VERSION@ | |||
Libs: -L${libdir} -lQgpsmm | |||
Libs.private: -L/usr/lib -lQtNetwork -lQtCore -lpthread | |||
Cflags: -I${includedir} | |||
Requires: QtNetwork |
@@ -17,15 +17,10 @@ SConstruct in this top-level directory. See that website for a list | |||
of GPS units known to be compatible. | |||
See the file INSTALL for installation instructions and some tips on | |||
how to troubleshoot your installation. The file build.txt | |||
has instructions for building from source. | |||
Distro integrators: An RPM spec file is included in the gpsd | |||
distribution. It wants to set up a hotplug script to notify gpsd | |||
when a potential GPS device goes active and should be polled. The | |||
goal is zero configuration; users should never have to tell gpsd how | |||
to configure itself. If you can't use RPM, use what you see in the | |||
specfile as a model. | |||
how to troubleshoot your installation. The file build.txt has | |||
instructions for building from source. The packaging/ directory | |||
contains resources and suggestions for packagers and distribution | |||
integrators. | |||
LICENSE | |||
======= | |||
@@ -16,15 +16,16 @@ | |||
# without changing the --prefix prefix. | |||
# Unfinished items: | |||
# * Qt binding (needs to build .pc, .prl files) | |||
# * Allow building for multiple python versions) | |||
# * Out-of-directory builds: see http://www.scons.org/wiki/UsingBuildDir | |||
# Release identification begins here | |||
gpsd_version = "3.3" | |||
libgps_major = 20 | |||
libgps_minor = 0 | |||
libgps_age = 0 | |||
gpsd_version = "3.4" | |||
# library version | |||
libgps_version_current = 20 | |||
libgps_version_revision = 0 | |||
libgps_version_age = 0 | |||
# Release identification ends here | |||
# Hosting information (mainly used for templating web pages) begins here | |||
@@ -49,13 +50,24 @@ formserver = "www@mainframe.cx" | |||
devmail = "gpsd-dev@lists.nongnu.org" | |||
# Hosting information ends here | |||
EnsureSConsVersion(1,2,0) | |||
EnsureSConsVersion(2,0,1) | |||
import copy, os, sys, commands, glob, re, platform, time | |||
import copy, os, sys, glob, re, platform, time | |||
from distutils import sysconfig | |||
from distutils.util import get_platform | |||
import SCons | |||
# replacement for functions from the commands module, which is deprecated. | |||
from subprocess import PIPE, STDOUT, Popen | |||
def _getstatusoutput(cmd, input=None, cwd=None, env=None): | |||
pipe = Popen(cmd, shell=True, cwd=cwd, env=env, stdout=PIPE, stderr=STDOUT) | |||
(output, errout) = pipe.communicate(input=input) | |||
status = pipe.returncode | |||
return (status, output) | |||
def _getoutput(cmd, input=None, cwd=None, env=None): | |||
return _getstatusoutput(cmd, input, cwd, env)[1] | |||
# | |||
# Build-control options | |||
# | |||
@@ -73,6 +85,12 @@ if sys.platform.startswith('linux'): | |||
if int(version) >= 13: | |||
# See https://fedoraproject.org/wiki/Features/ChangeInImplicitDSOLinking | |||
imloads = False | |||
elif os.path.exists("/etc/arch-release"): | |||
imloads = False | |||
# Does our platform has a working memory-barrier instruction? | |||
# The shared-memory export won't be reliable without it. | |||
mfence = (platform.machine() in ('x86_64',)) | |||
boolopts = ( | |||
# GPS protocols | |||
@@ -108,7 +126,7 @@ boolopts = ( | |||
# Export methods | |||
("socket_export", True, "data export over sockets"), | |||
("dbus_export", False, "enable DBUS export support"), | |||
("shm_export", True, "export via shared memory"), | |||
("shm_export", mfence,"export via shared memory"), | |||
# Communication | |||
('usb', True, "libusb support for USB devices"), | |||
("bluez", True, "BlueZ support for Bluetooth devices"), | |||
@@ -117,7 +135,7 @@ boolopts = ( | |||
("passthrough", True, "build support for passing through JSON"), | |||
# Other daemon options | |||
("force_global", False, "force daemon to listen on all addressses"), | |||
("timing", False, "latency timing support"), | |||
("timing", False, "latency timing support"), | |||
("control_socket",True, "control socket for hotplug notifications"), | |||
("systemd", systemd, "systemd socket activation"), | |||
# Client-side options | |||
@@ -157,13 +175,13 @@ for (name, default, help) in nonboolopts: | |||
opts.Add(name, help, default) | |||
pathopts = ( | |||
("sysconfdir", "/etc", "system configuration directory"), | |||
("bindir", "/bin", "application binaries directory"), | |||
("includedir", "/include", "header file directory"), | |||
("libdir", "/lib", "system libraries"), | |||
("sbindir", "/sbin", "system binaries directory"), | |||
("mandir", "/share/man", "manual pages directory"), | |||
("docdir", "/share/doc", "documents directory"), | |||
("sysconfdir", "etc", "system configuration directory"), | |||
("bindir", "bin", "application binaries directory"), | |||
("includedir", "include", "header file directory"), | |||
("libdir", "lib", "system libraries"), | |||
("sbindir", "sbin", "system binaries directory"), | |||
("mandir", "share/man", "manual pages directory"), | |||
("docdir", "share/doc", "documents directory"), | |||
("pkgconfig", "$libdir/pkgconfig", "pkgconfig file directory"), | |||
) | |||
for (name, default, help) in pathopts: | |||
@@ -202,8 +220,9 @@ env['PYTHON'] = sys.executable | |||
# explicitly quote them or (better yet) use the "=" form of GNU option | |||
# settings. | |||
env['STRIP'] = "strip" | |||
env['PKG_CONFIG'] = "pkg-config" | |||
env['CHRPATH'] = 'chrpath' | |||
for i in ["AR", "ARFLAGS", "CCFLAGS", "CFLAGS", "CC", "CXX", "CXXFLAGS", "STRIP", "CHRPATH", "LD", "TAR"]: | |||
for i in ["AR", "ARFLAGS", "CCFLAGS", "CFLAGS", "CC", "CXX", "CXXFLAGS", "STRIP", "PKG_CONFIG", "CHRPATH", "LD", "TAR"]: | |||
if os.environ.has_key(i): | |||
j = i | |||
if i == "LD": | |||
@@ -222,15 +241,8 @@ for flags in ["LDFLAGS", "LINKFLAGS", "SHLINKFLAGS", "CPPFLAGS"]: | |||
env['SRCDIR'] = '.' | |||
def announce(msg): | |||
# When we find out how to access the --quiet flag, we use that here | |||
print msg | |||
# define a helper function for pkg-config - we need to pass | |||
# --static for static linking, too. | |||
if env["shared"]: | |||
pkg_config = lambda pkg: ['!pkg-config --cflags --libs %s' %(pkg, )] | |||
else: | |||
pkg_config = lambda pkg: ['!pkg-config --cflags --libs --static %s' %(pkg, )] | |||
if not env.GetOption("silent"): | |||
print msg | |||
# GCC isn't always named gcc, alas. | |||
if env['CC'] == 'gcc' or (sys.platform.startswith('freebsd') and env['CC'] == 'cc'): | |||
@@ -248,14 +260,18 @@ if env['CC'] == 'gcc' or (sys.platform.startswith('freebsd') and env['CC'] == 'c | |||
# DESTDIR environment variable means user wants to prefix the installation root. | |||
DESTDIR = os.environ.get('DESTDIR', '') | |||
def installdir(dir): | |||
wrapped = DESTDIR + env['prefix'] + env[dir] | |||
def installdir(dir, add_destdir=True): | |||
# use os.path.join to handle absolute paths properly. | |||
wrapped = os.path.join(env['prefix'], env[dir]) | |||
if add_destdir: | |||
wrapped = os.path.normpath(DESTDIR + os.path.sep + wrapped) | |||
wrapped.replace("/usr/etc", "/etc") | |||
return wrapped | |||
# Honor the specified installation prefix in link paths. | |||
env.Prepend(LIBPATH=[installdir('libdir')]) | |||
env.Prepend(RPATH=[installdir('libdir')]) | |||
if env["shared"]: | |||
env.Prepend(RPATH=[installdir('libdir')]) | |||
# Give deheader a way to set compiler flags | |||
if 'MORECFLAGS' in os.environ: | |||
@@ -330,7 +346,7 @@ if "help" in ARGLIST: | |||
def CheckPKG(context, name): | |||
context.Message( 'Checking for %s... ' % name ) | |||
ret = context.TryAction('pkg-config --exists \'%s\'' % name)[0] | |||
ret = context.TryAction('%s --exists \'%s\'' % (env['PKG_CONFIG'], name))[0] | |||
context.Result( ret ) | |||
return ret | |||
@@ -373,18 +389,18 @@ config = Configure(env, custom_tests = { 'CheckPKG' : CheckPKG, | |||
'CheckExecutable' : CheckExecutable, | |||
'CheckXsltproc' : CheckXsltproc}) | |||
# The build is fragile when chrpath is not present, so we've made it mandatory. | |||
env.Prepend(LIBPATH=[os.path.realpath(os.curdir)]) | |||
if config.CheckExecutable('$CHRPATH -v', 'chrpath'): | |||
# Tell generated binaries to look in the current directory for | |||
# shared libraries so we can run 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. | |||
env.Prepend(LIBPATH=[os.path.realpath(os.curdir)]) | |||
env.Prepend(RPATH=[os.path.realpath(os.curdir)]) | |||
if env["shared"]: | |||
env.Prepend(RPATH=[os.path.realpath(os.curdir)]) | |||
else: | |||
print "The chrpath utility is required for GPSD to build." | |||
quit() | |||
print "chrpath is not available, forcing static linking." | |||
env["shared"] = False | |||
confdefs = ["/* gpsd_config.h. Generated by scons, do not hand-hack. */\n"] | |||
@@ -394,6 +410,13 @@ confdefs.append('#define GPSD_URL "%s"\n' % website) | |||
cxx = config.CheckCXX() | |||
# define a helper function for pkg-config - we need to pass | |||
# --static for static linking, too. | |||
if env["shared"]: | |||
pkg_config = lambda pkg: ['!%s --cflags --libs %s' %(env['PKG_CONFIG'], pkg, )] | |||
else: | |||
pkg_config = lambda pkg: ['!%s --cflags --libs --static %s' %(env['PKG_CONFIG'], pkg, )] | |||
# The actual distinction here is whether the platform has ncurses in the | |||
# base system or not. If it does, pkg-config is not likely to tell us | |||
# anything useful. FreeBSD does, Linux doesn't. Most likely other BSDs | |||
@@ -406,6 +429,8 @@ if env['ncurses']: | |||
ncurseslibs = ['!ncurses5-config --libs --cflags'] | |||
elif sys.platform.startswith('freebsd'): | |||
ncurseslibs= [ '-lncurses' ] | |||
elif sys.platform.startswith('openbsd'): | |||
ncurseslibs= [ '-lcurses' ] | |||
if env['usb']: | |||
# In FreeBSD except version 7, USB libraries are in the base system | |||
@@ -579,6 +604,9 @@ else: | |||
## Two shared libraries provide most of the code for the C programs | |||
libgps_version_soname = libgps_version_current - libgps_version_age | |||
libgps_version = "%d.%d.%d" %(libgps_version_soname, libgps_version_age, libgps_version_revision) | |||
libgps_sources = [ | |||
"ais_json.c", | |||
"daemon.c", | |||
@@ -641,7 +669,7 @@ libgpsd_sources = [ | |||
# Inspired by Richard Levitte's (slightly buggy) code at | |||
# http://markmail.org/message/spttz3o4xrsftofr | |||
def VersionedSharedLibrary(env, libname, libversion, lib_objs=[], parse_flags=[]): | |||
def VersionedSharedLibrary(env, libname, libgps_version, lib_objs=[], parse_flags=[]): | |||
platform = env.subst('$PLATFORM') | |||
shlib_pre_action = None | |||
shlib_suffix = env.subst('$SHLIBSUFFIX') | |||
@@ -649,8 +677,8 @@ def VersionedSharedLibrary(env, libname, libversion, lib_objs=[], parse_flags=[] | |||
shlink_flags = SCons.Util.CLVar(env.subst('$SHLINKFLAGS')) | |||
if platform == 'posix': | |||
ilib_suffix = shlib_suffix + '.' + libversion | |||
(major, age, revision) = libversion.split(".") | |||
ilib_suffix = shlib_suffix + '.' + libgps_version | |||
(major, age, revision) = libgps_version.split(".") | |||
soname = "lib" + libname + shlib_suffix + "." + major | |||
shlink_flags += [ '-Wl,-Bsymbolic', '-Wl,-soname=%s' % soname ] | |||
elif platform == 'cygwin': | |||
@@ -658,9 +686,9 @@ def VersionedSharedLibrary(env, libname, libversion, lib_objs=[], parse_flags=[] | |||
shlink_flags += [ '-Wl,-Bsymbolic', | |||
'-Wl,--out-implib,${TARGET.base}.a' ] | |||
elif platform == 'darwin': | |||
ilib_suffix = '.' + libversion + shlib_suffix | |||
shlink_flags += [ '-current_version', '%s' % libversion, | |||
'-compatibility_version', '%s' % libversion, | |||
ilib_suffix = '.' + libgps_version + shlib_suffix | |||
shlink_flags += [ '-current_version', '%s' % libgps_version, | |||
'-compatibility_version', '%s' % libgps_version, | |||
'-undefined', 'dynamic_lookup' ] | |||
ilib = env.SharedLibrary(libname,lib_objs, | |||
@@ -668,20 +696,20 @@ def VersionedSharedLibrary(env, libname, libversion, lib_objs=[], parse_flags=[] | |||
SHLINKFLAGS=shlink_flags, parse_flags=parse_flags) | |||
if platform == 'darwin': | |||
if libversion.count(".") != 2: | |||
if libgps_version.count(".") != 2: | |||
# We need a library name in libfoo.x.y.z.dylib form to proceed | |||
raise ValueError | |||
lib = 'lib' + libname + '.' + libversion + '.dylib' | |||
lib = 'lib' + libname + '.' + libgps_version + '.dylib' | |||
lib_no_ver = 'lib' + libname + '.dylib' | |||
# Link libfoo.x.y.z.dylib to libfoo.dylib | |||
env.AddPostAction(ilib, 'rm -f %s; ln -s %s %s' % ( | |||
lib_no_ver, lib, lib_no_ver)) | |||
env.Clean(lib, lib_no_ver) | |||
elif platform == 'posix': | |||
if libversion.count(".") != 2: | |||
if libgps_version.count(".") != 2: | |||
# We need a library name in libfoo.so.x.y.z form to proceed | |||
raise ValueError | |||
lib = "lib" + libname + ".so." + libversion | |||
lib = "lib" + libname + ".so." + libgps_version | |||
suffix_re = '%s\\.[0-9\\.]*$' % re.escape(shlib_suffix) | |||
# For libfoo.so.x.y.z, links libfoo.so libfoo.so.x.y libfoo.so.x | |||
major_name = shlib_suffix + "." + lib.split(".")[2] | |||
@@ -721,7 +749,7 @@ else: | |||
def Library(env, target, sources, version, parse_flags=[]): | |||
return VersionedSharedLibrary(env=env, | |||
libname=target, | |||
libversion=version, | |||
libgps_version=version, | |||
lib_objs=sources, | |||
parse_flags=parse_flags) | |||
LibraryInstall = lambda env, libdir, sources: \ | |||
@@ -729,20 +757,17 @@ else: | |||
# Klugery to handle sonames ends | |||
# Must be MAJOR.AGE.REVISION | |||
libversion = "%d.%d.%d" % (libgps_major, libgps_minor, libgps_age) | |||
compiled_gpslib = Library(env=env, | |||
target="gps", | |||
sources=libgps_sources, | |||
version=libversion, | |||
version=libgps_version, | |||
parse_flags= ["-lm"] + dbus_libs) | |||
env.Clean(compiled_gpslib, "gps_maskdump.c") | |||
compiled_gpsdlib = Library(env=env, | |||
target="gpsd", | |||
sources=libgpsd_sources, | |||
version=libversion, | |||
version=libgps_version, | |||
parse_flags=usblibs + rtlibs + bluezlibs) | |||
libraries = [compiled_gpslib, compiled_gpsdlib] | |||
@@ -768,7 +793,7 @@ if qt_env: | |||
CC=compile_with, | |||
CFLAGS=compile_flags, | |||
parse_flags=dbus_libs)) | |||
compiled_qgpsmmlib = Library(qt_env, "Qgpsmm", qtobjects, libversion) | |||
compiled_qgpsmmlib = Library(qt_env, "Qgpsmm", qtobjects, libgps_version) | |||
libraries.append(compiled_qgpsmmlib) | |||
# The libraries have dependencies on system libraries | |||
@@ -802,7 +827,8 @@ gpsmon_sources = [ | |||
# know how to force it when linking staticly. | |||
# | |||
# It turns out there are two cases where we need to force this. Some | |||
# distributions don't do implicit linking by design: | |||
# distributions don't do implicit linking by design. See the test | |||
# code for implicit_link. | |||
# | |||
if not env['shared'] or not env["implicit_link"]: | |||
env.MergeFlags("-lm") | |||
@@ -913,7 +939,13 @@ else: | |||
for ext, sources in python_extensions.iteritems(): | |||
python_objects[ext] = [] | |||
for src in sources: | |||
python_objects[ext].append(python_env.SharedObject(src.split(".")[0] + '-py', src)) | |||
python_objects[ext].append( | |||
python_env.NoCache( | |||
python_env.SharedObject( | |||
src.split(".")[0] + '-py_' + '_'.join(['%s' %(x) for x in sys.version_info]) + so_ext, src | |||
) | |||
) | |||
) | |||
python_compiled_libs[ext] = python_env.SharedLibrary(ext, python_objects[ext]) | |||
python_built_extensions = python_compiled_libs.values() | |||
@@ -957,12 +989,15 @@ env.Command(target="ais_json.i", source="jsongen.py", action='''\ | |||
chmod a-w $TARGET''') | |||
# generate revision.h | |||
(st, rev) = commands.getstatusoutput('git describe') | |||
if st != 0: | |||
from datetime import datetime | |||
rev = datetime.now().isoformat()[:-4] | |||
if 'dev' in gpsd_version: | |||
(st, rev) = _getstatusoutput('git describe') | |||
if st != 0: | |||
from datetime import datetime | |||
rev = datetime.now().isoformat()[:-4] | |||
else: | |||
rev = gpsd_version | |||
revision='#define REVISION "%s"\n' %(rev.strip(),) | |||
env.NoClean(env.Textfile(target="revision.h", source=[revision])) | |||
env.Textfile(target="revision.h", source=[revision]) | |||
# generate pps_pin.h | |||
pps_pin = env['pps_pin'] | |||
@@ -981,12 +1016,13 @@ generated_sources = ['packet_names.h', 'timebase.h', 'gpsd.h', "ais_json.i", | |||
# build without Internet access. | |||
from leapsecond import save_leapseconds | |||
leapseconds_cache_rebuild = lambda target, source, env: save_leapseconds(target[0].abspath) | |||
leapseconds_cache = env.Command(target="leapseconds.cache", | |||
if 'dev' in gpsd_version or not os.path.exists('leapseconds.cache'): | |||
leapseconds_cache = env.Command(target="leapseconds.cache", | |||
source="leapsecond.py", | |||
action=leapseconds_cache_rebuild) | |||
env.Clean(leapseconds_cache, "leapsecond.pyc") | |||
env.NoClean(leapseconds_cache) | |||
env.Precious(leapseconds_cache) | |||
env.Clean(leapseconds_cache, "leapsecond.pyc") | |||
env.NoClean(leapseconds_cache) | |||
env.Precious(leapseconds_cache) | |||
# Instantiate some file templates. We'd like to use the Substfile builtin | |||
# but it doesn't seem to work in scons 1.20 | |||
@@ -1014,6 +1050,7 @@ def substituter(target, source, env): | |||
('@WEBFORM@', webform), | |||
('@FORMSERVER@', formserver), | |||
('@DEVMAIL@', devmail), | |||
('@LIBGPSVERSION@', libgps_version), | |||
) | |||
with open(str(source[0])) as sfp: | |||
content = sfp.read() | |||
@@ -1102,7 +1139,10 @@ binaryinstall.append(LibraryInstall(env, installdir('libdir'), compiled_gpsdlib) | |||
if qt_env: | |||
binaryinstall.append(LibraryInstall(qt_env, installdir('libdir'), compiled_qgpsmmlib)) | |||
env.AddPostAction(binaryinstall, '$CHRPATH -r "%s" "$TARGET"' % installdir('libdir')) | |||
# We don't use installdir here in order to avoid having DESTDIR affect the rpath | |||
if env["shared"]: | |||
env.AddPostAction(binaryinstall, '$CHRPATH -r "%s" "$TARGET"' \ | |||
% (installdir('libdir', False), )) | |||
if not env['debug'] and not env['profiling'] and env['strip']: | |||
env.AddPostAction(binaryinstall, '$STRIP $TARGET') | |||
@@ -1130,6 +1170,10 @@ else: | |||
python_egg_info_install] | |||
pc_install = [ env.Install(installdir('pkgconfig'), x) for x in ("libgps.pc", "libgpsd.pc") ] | |||
if qt_env: | |||
pc_install.append(qt_env.Install(installdir('pkgconfig'), 'Qgpsmm.pc')) | |||
pc_install.append(qt_env.Install(installdir('libdir'), 'libQgpsmm.prl')) | |||
maninstall = [] | |||
if manbuilder: | |||
@@ -1474,9 +1518,10 @@ if env['python']: | |||
# is plugged in. | |||
Utility('udev-install', '', [ | |||
'cp $SRCDIR/gpsd.rules /lib/udev/rules.d/25-gpsd.rules', | |||
'cp $SRCDIR/gpsd.hotplug /lib/udev/', | |||
'chmod a+x /lib/udev/gpsd.hotplug', | |||
'mkdir -p ' + DESTDIR + '/lib/udev/rules.d', | |||
'cp $SRCDIR/gpsd.rules ' + DESTDIR + '/lib/udev/rules.d/25-gpsd.rules', | |||
'cp $SRCDIR/gpsd.hotplug ' + DESTDIR + '/lib/udev/', | |||
'chmod a+x ' + DESTDIR + '/lib/udev/gpsd.hotplug', | |||
]) | |||
Utility('udev-uninstall', '', [ | |||
@@ -1494,7 +1539,7 @@ Utility('udev-test', '', [ | |||
# for these productions to work. | |||
if os.path.exists("gpsd.c") and os.path.exists(".gitignore"): | |||
distfiles = commands.getoutput(r"git ls-files | grep -v '^www/'").split() | |||
distfiles = _getoutput(r"git ls-files | grep -v '^www/'").split() | |||
if ".gitignore" in distfiles: | |||
distfiles.remove(".gitignore") | |||
distfiles += generated_sources | |||
@@ -1540,6 +1585,7 @@ if os.path.exists("gpsd.c") and os.path.exists(".gitignore"): | |||
tag_release = Utility('tag-release', [], [ | |||
'git tag -s -m "Tagged for external release ${VERSION}" release-${VERSION}' | |||
]) | |||
upload_tags = Utility('upload-tags', [], ['git push --tags']) | |||
# Local release preparation. This production will require Internet access, | |||
# but it doesn't do any uploads or public repo mods. | |||
@@ -1548,7 +1594,6 @@ if os.path.exists("gpsd.c") and os.path.exists(".gitignore"): | |||
# won't be right when revision.h is generated for the tarball. | |||
releaseprep = env.Alias("releaseprep", | |||
[Utility("distclean", [], ["rm -f revision.h"]), | |||
leapseconds_cache, | |||
tag_release, | |||
tarball]) | |||
# Undo local release preparation | |||
@@ -1558,7 +1603,7 @@ if os.path.exists("gpsd.c") and os.path.exists(".gitignore"): | |||
# All a buildup to this. | |||
env.Alias("release", [releaseprep, | |||
upload_release, | |||
'git push --tags', | |||
upload_tags, | |||
upload_web]) | |||
# The following sets edit modes for GNU EMACS | |||
@@ -10,6 +10,12 @@ the "Upstream Bugs" page on the project website. | |||
** Bugs in gpsd and its clients: | |||
*** Old Earthmate support is currently broken | |||
Support for the the pre-2003 version of the Earthmate using Zodiac | |||
binary protocol is currently broken. Sometime after 2.96 the code | |||
for dealing with the EARTHA handshake came unstuck. | |||
*** Tracker bugs | |||
See the GPSD bug tracker on the project website, but don't be | |||
@@ -16,6 +16,8 @@ Necessary components for any build: | |||
|chrpath | needed with scons for RPATH setting | |||
|============================================================================== | |||
=== C compiler === | |||
C99 conformance is required in the compiler. The C code depends on one | |||
non-C99 feature: anonymous unions. We could eliminate these, but the | |||
cost would be source-level interface breakage if we have to move | |||
@@ -28,22 +30,43 @@ passes all regression tests. If -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. | |||
You will need scons version 1.2.0 or later to build the code. The | |||
autotools build from 2.96 and earlier versions has been dropped. | |||
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. | |||
While Python is required to build GPSD from source (the build uses | |||
some code generators in Python), it is not required to run the service | |||
daemon. In particular, you can cross-compile onto an embedded system | |||
without having to take Python with you. | |||
without having to take Python with you. | |||
=== Scons === | |||
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. | |||
Yes, you will need chrpath. libtool is a messy pile of crocks, and | |||
throwing it out of our build chain was a good thing, but it had | |||
consguences. Whatever its other flawes, 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. | |||
libtool is a messy pile of crocks, and throwing it out of our build | |||
chain was a good thing, but it had consguences. Whatever its other | |||
flawes, 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. | |||
(We previously tried to make chrpath optional. This turned out to be | |||
too tricky to get right to be worth it. So install chrpath. Now.) | |||
Ubuntu users can do 'apt-get install chrpath' | |||
CentOS users can do 'yum install chrpath' from extras. | |||
If you do not have chrpath available, GPSD binaries will be built | |||
statically. | |||
=== Optional build components === | |||
Having the following optional components on your system will enable | |||
various additional capabilities and extensions: | |||
@@ -73,6 +96,11 @@ Under Ubuntu, the ncurses package you want is libncurses5-dev. | |||
Depending on how your distribution packages ncurses you may | |||
also require libtinfo5, a separate terminfo library. | |||
On some recent versions of Ubuntu (notably 11.10) there is a packaging | |||
defect that may cause your build to blow up in SCons. It's a missing | |||
package info file for the tinfo library. To fix this, install the file | |||
packaging/tinfo.pc in /usr/lib/pkgconfig/tinfo.pc. | |||
For building from the source tree, or if you change the man page | |||
source, xslt and docbook xsl style files are used to generate nroff | |||
-man source from docbook xml. The following packages are used in this | |||
@@ -31,7 +31,7 @@ arch = x86_64 | |||
admin = esr@thyrsus.com | |||
login = gpsd | |||
devices = - | |||
status = up | |||
status = scons version is too old, must upgrade. | |||
[devel.recluse.de] | |||
os = Linux | |||
@@ -15,7 +15,7 @@ OLDPWD=`pwd` | |||
cd ${TMPDIR} | |||
getbuildlog gpsd last || true | |||
grep -- '--- ./test' * | sed 's,^gpsd_[^_]*_\([^.]*\).*\./test/\([^.]*\).*,\1 \2,' | sort -u | |||
grep -- '--- test' * | sed 's,^gpsd_[^_]*_\([^.]*\).*\./test/\([^.]*\).*,\1 \2,' | sort -u | |||
cd ${OLDPWD} | |||
rm -rf ${TMPDIR} | |||
@@ -314,8 +314,8 @@ bool aivdm_decode(const char *buf, size_t buflen, | |||
ais->type6.fid = UBITS(82, 6); | |||
ais->type6.bitcount = ais_context->bitlen - 88; | |||
imo = false; | |||
if (ais->type8.dac == 1) | |||
switch (ais->type8.fid) { | |||
if (ais->type6.dac == 1) | |||
switch (ais->type6.fid) { | |||
case 12: /* IMO236 - Dangerous cargo indication */ | |||
UCHARS(88, ais->type6.dac1fid12.lastport); | |||
ais->type6.dac1fid12.lmonth = UBITS(118, 4); | |||
@@ -41,7 +41,7 @@ | |||
#include <math.h> | |||
#include "gpsd.h" | |||
#if defined(NAVCOM_ENABLE) && defined(BINARY_ENABLE) | |||
#if defined(NAVCOM_ENABLE) | |||
#include "bits.h" | |||
/* Have data which is 24 bits long */ | |||
@@ -1306,4 +1306,4 @@ const struct gps_type_t navcom_binary = | |||
}; | |||
/* *INDENT-ON* */ | |||
#endif /* defined(NAVCOM_ENABLE) && defined(BINARY_ENABLE) */ | |||
#endif /* defined(NAVCOM_ENABLE) */ |
@@ -47,8 +47,82 @@ | |||
#define HI(n) ((n) >> 8) | |||
#define LO(n) ((n) & 0xff) | |||
#ifdef RECONFIGURE_ENABLE | |||
/*@ +charint @*/ | |||
/* Poll Software Version MID 132 */ | |||
static unsigned char versionprobe[] = { | |||
0xa0, 0xa2, 0x00, 0x02, | |||
0x84, /* MID 132 */ | |||
0x00, /* unused */ | |||
0x00, 0x00, 0xb0, 0xb3 | |||
}; | |||
/* Poll Navigation Parameters MID 152 | |||
* query for MID 19 */ | |||
static unsigned char navparams[] = { | |||
0xa0, 0xa2, 0x00, 0x02, | |||
0x98, /* MID 152 */ | |||
0x00, | |||
0x00, 0x00, 0xb0, 0xb3 | |||
}; | |||
#ifdef RECONFIGURE_ENABLE | |||
/* DGPS Source MID 133 */ | |||
static unsigned char dgpscontrol[] = { | |||
0xa0, 0xa2, 0x00, 0x07, | |||
0x85, /* MID 133 */ | |||
0x01, /* use SBAS */ | |||
0x00, 0x00, | |||
0x00, 0x00, 0x00, | |||
0x00, 0x00, 0xb0, 0xb3 | |||
}; | |||
/* Set SBAS Parameters MID 170 */ | |||
static unsigned char sbasparams[] = { | |||
0xa0, 0xa2, 0x00, 0x06, | |||
0xaa, /* MID 170 */ | |||
0x00, /* SBAS PRN */ | |||
0x01, /* SBAS Mode */ | |||
0x00, /* Auto PRN */ | |||
0x00, 0x00, | |||
0x00, 0x00, 0xb0, 0xb3 | |||
}; | |||
/* Set Message Rate MID 166 */ | |||
static unsigned char requestecef[] = { | |||
0xa0, 0xa2, 0x00, 0x08, | |||
0xa6, /* MID 166 */ | |||
0x00, /* enable 1 */ | |||
0x02, /* MID 2 */ | |||
0x01, /* once per Sec */ | |||
0x00, 0x00, /* unused */ | |||
0x00, 0x00, /* unused */ | |||
0x00, 0x00, 0xb0, 0xb3 | |||
}; | |||
/* Set Message Rate MID 166 */ | |||
static unsigned char requesttracker[] = { | |||
0xa0, 0xa2, 0x00, 0x08, | |||
0xa6, /* MID 166 */ | |||
0x00, /* enable 1 */ | |||
0x04, /* MID 4 */ | |||
0x03, /* every 3 sec */ | |||
0x00, 0x00, /* unused */ | |||
0x00, 0x00, /* unused */ | |||
0x00, 0x00, 0xb0, 0xb3 | |||
}; | |||
/* disable MID XX */ | |||
static unsigned char unsetmidXX[] = { | |||
0xa0, 0xa2, 0x00, 0x08, | |||
0xa6, /* MID 166 */ | |||
0x00, /* enable 1 */ | |||
0x00, /* MID 0xXX */ | |||
0x00, /* never */ | |||
0x00, 0x00, /* unused */ | |||
0x00, 0x00, /* unused */ | |||
0x00, 0x00, 0xb0, 0xb3 | |||
}; | |||
/* message to enable: | |||
* MID 7 Clock Status | |||
* MID 8 50Bps subframe data | |||
@@ -74,6 +148,7 @@ static unsigned char enablesubframe[] = { | |||
0x00, 0x00, 0xb0, 0xb3 | |||
}; | |||
/* disable subframe data */ | |||
static unsigned char disablesubframe[] = { | |||
0xa0, 0xa2, 0x00, 0x19, | |||
0x80, /* MID 128 initialize Data Source */ | |||
@@ -89,6 +164,7 @@ static unsigned char disablesubframe[] = { | |||
0x00, 0x00, 0xb0, 0xb3 | |||
}; | |||
/* mode control MID */ | |||
static unsigned char modecontrol[] = { | |||
0xa0, 0xa2, 0x00, 0x0e, | |||
0x88, /* MID 136 Mode Control */ | |||
@@ -116,9 +192,8 @@ static unsigned char enablemid52[] = { | |||
0x00, 0x00, 0x00, 0x00, /* unused, set to zero */ | |||
0x00, 0xdb, 0xb0, 0xb3 | |||
}; | |||
/*@ -charint @*/ | |||
#endif /* RECONFIGURE_ENABLE */ | |||
/*@ -charint @*/ | |||
static gps_mask_t sirf_msg_debug(unsigned char *, size_t); | |||
@@ -418,13 +493,6 @@ static gps_mask_t sirf_msg_swversion(struct gps_device_t *session, | |||
} else { | |||
session->driver.sirf.driverstate |= SIRF_GE_232; | |||
} | |||
#ifdef RECONFIGURE_ENABLE | |||
if (!session->context->readonly) { | |||
gpsd_report(LOG_PROG, "SiRF: Enabling PPS message...\n"); | |||
(void)sirf_write(session, enablemid52); | |||
} | |||
#endif /* RECONFIGURE_ENABLE */ | |||
if (strstr((char *)(buf + 1), "ES")) | |||
gpsd_report(LOG_INF, "SiRF: Firmware has XTrac capability\n"); | |||
gpsd_report(LOG_PROG, "SiRF: fv: %0.2f, Driver state flags are: %0x\n", | |||
@@ -432,13 +500,6 @@ static gps_mask_t sirf_msg_swversion(struct gps_device_t *session, | |||
#ifdef NTPSHM_ENABLE | |||
session->driver.sirf.time_seen = 0; | |||
#endif /* NTPSHM_ENABLE */ | |||
#ifdef RECONFIGURE_ENABLE | |||
if (!session->context->readonly && session->gpsdata.dev.baudrate >= 38400) { | |||
/* some USB devices are also too slow, no way to tell which ones */ | |||
gpsd_report(LOG_PROG, "SiRF: Enabling subframe transmission...\n"); | |||
(void)sirf_write(session, enablesubframe); | |||
} | |||
#endif /* RECONFIGURE_ENABLE */ | |||
gpsd_report(LOG_DATA, "SiRF: FV MID 0x06: subtype='%s' mask={DEVICEID}\n", | |||
session->subtype); | |||
return DEVICEID_SET; | |||
@@ -1191,122 +1252,73 @@ static void sirfbin_event_hook(struct gps_device_t *session, event_t event) | |||
(void)nmea_send(session, | |||
"$PSRF100,0,%d,8,1,0", | |||
session->gpsdata.dev.baudrate); | |||
(void)usleep(3330); /* guessed settling time */ | |||
} | |||
/* do this every time */ | |||
{ | |||
/*@ +charint @*/ | |||
/* Poll Navigation Parameters MID 152 | |||
* query for MID 19 */ | |||
static unsigned char navparams[] = { | |||
0xa0, 0xa2, 0x00, 0x02, | |||
0x98, /* MID 152 */ | |||
0x00, | |||
0x00, 0x00, 0xb0, 0xb3 | |||
}; | |||
/* DGPS Source MID 133 */ | |||
static unsigned char dgpscontrol[] = { | |||
0xa0, 0xa2, 0x00, 0x07, | |||
0x85, /* MID 133 */ | |||
0x01, /* use SBAS */ | |||
0x00, 0x00, | |||
0x00, 0x00, 0x00, | |||
0x00, 0x00, 0xb0, 0xb3 | |||
}; | |||
/* Set SBAS Parameters MID 170 */ | |||
static unsigned char sbasparams[] = { | |||
0xa0, 0xa2, 0x00, 0x06, | |||
0xaa, /* MID 170 */ | |||
0x00, /* SBAS PRN */ | |||
0x01, /* SBAS Mode */ | |||
0x00, /* Auto PRN */ | |||
0x00, 0x00, | |||
0x00, 0x00, 0xb0, 0xb3 | |||
}; | |||
/* Poll Software Version MID 132 */ | |||
static unsigned char versionprobe[] = { | |||
0xa0, 0xa2, 0x00, 0x02, | |||
0x84, /* MID 132 */ | |||
0x00, /* unused */ | |||
0x00, 0x00, 0xb0, 0xb3 | |||
}; | |||
/* Set Message Rate MID 166 */ | |||
static unsigned char requestecef[] = { | |||
0xa0, 0xa2, 0x00, 0x08, | |||
0xa6, /* MID 166 */ | |||
0x00, /* enable 1 */ | |||
0x02, /* MID 2 */ | |||
0x01, /* once per Sec */ | |||
0x00, 0x00, /* unused */ | |||
0x00, 0x00, /* unused */ | |||
0x00, 0x00, 0xb0, 0xb3 | |||
}; | |||
/* Set Message Rate MID 166 */ | |||
static unsigned char requesttracker[] = { | |||
0xa0, 0xa2, 0x00, 0x08, | |||
0xa6, /* MID 166 */ | |||
0x00, /* enable 1 */ | |||
0x04, /* MID 4 */ | |||
0x03, /* every 3 sec */ | |||
0x00, 0x00, /* unused */ | |||
0x00, 0x00, /* unused */ | |||
0x00, 0x00, 0xb0, 0xb3 | |||
}; | |||
/* unset MID 29 0x1d */ | |||
/* we do not decode it, so don't send it */ | |||
static unsigned char unsetmid29[] = { | |||
0xa0, 0xa2, 0x00, 0x08, | |||
0xa6, /* MID 166 */ | |||
0x00, /* enable 1 */ | |||
0x1d, /* MID 29 */ | |||
0x00, /* never */ | |||
0x00, 0x00, /* unused */ | |||
0x00, 0x00, /* unused */ | |||
0x00, 0x00, 0xb0, 0xb3 | |||
}; | |||
/* unset MID 30 0x1e */ | |||
/* we do not decode it, so don't send it */ | |||
static unsigned char unsetmid30[] = { | |||
0xa0, 0xa2, 0x00, 0x08, | |||
0xa6, /* MID 166 */ | |||
0x00, /* enable 1 */ | |||
0x1e, /* MID 30 */ | |||
0x00, /* never */ | |||
0x00, 0x00, /* unused */ | |||
0x00, 0x00, /* unused */ | |||
0x00, 0x00, 0xb0, 0xb3 | |||
}; | |||
/*@ -charint @*/ | |||
gpsd_report(LOG_PROG, "SiRF: baudrate: %d\n", | |||
session->gpsdata.dev.baudrate); | |||
(void)usleep(3330); /* guessed settling time */ | |||
gpsd_report(LOG_PROG, "SiRF: unset MID 30...\n"); | |||
(void)sirf_write(session, unsetmid30); | |||
(void)usleep(3330); /* guessed settling time */ | |||
gpsd_report(LOG_PROG, | |||
"SiRF: Requesting periodic ecef reports...\n"); | |||
(void)sirf_write(session, requestecef); | |||
gpsd_report(LOG_PROG, | |||
"SiRF: Requesting periodic tracker reports...\n"); | |||
(void)sirf_write(session, requesttracker); | |||
gpsd_report(LOG_PROG, | |||
"SiRF: Setting DGPS control to use SBAS...\n"); | |||
(void)sirf_write(session, dgpscontrol); | |||
gpsd_report(LOG_PROG, | |||
"SiRF: Setting SBAS to auto/integrity mode...\n"); | |||
(void)sirf_write(session, sbasparams); | |||
gpsd_report(LOG_PROG, "SiRF: Probing for firmware version...\n"); | |||
(void)sirf_write(session, versionprobe); | |||
(void)usleep(3330); /* guessed settling time */ | |||
gpsd_report(LOG_PROG, "SiRF: unset MID 29...\n"); | |||
(void)sirf_write(session, unsetmid29); | |||
gpsd_report(LOG_PROG, "SiRF: Requesting navigation parameters...\n"); | |||
(void)sirf_write(session, navparams); | |||
(void)usleep(3330); /* guessed settling time */ | |||
gpsd_report(LOG_PROG, "SiRF: Probing for firmware version...\n"); | |||
(void)sirf_write(session, versionprobe); | |||
gpsd_report(LOG_PROG, | |||
"SiRF: Requesting navigation parameters...\n"); | |||
(void)sirf_write(session, navparams); | |||
#ifdef RECONFIGURE_ENABLE | |||
gpsd_report(LOG_PROG, "SiRF: Requesting periodic ecef reports...\n"); | |||
(void)sirf_write(session, requestecef); | |||
(void)usleep(3330); /* guessed settling time */ | |||
gpsd_report(LOG_PROG, "SiRF: Requesting periodic tracker reports...\n"); | |||
(void)sirf_write(session, requesttracker); | |||
(void)usleep(3330); /* guessed settling time */ | |||
gpsd_report(LOG_PROG, "SiRF: Setting DGPS control to use SBAS...\n"); | |||
(void)sirf_write(session, dgpscontrol); | |||
(void)usleep(3330); /* guessed settling time */ | |||
gpsd_report(LOG_PROG, "SiRF: Setting SBAS to auto/integrity mode...\n"); | |||
(void)sirf_write(session, sbasparams); | |||
(void)usleep(3330); /* guessed settling time */ | |||
gpsd_report(LOG_PROG, "SiRF: Enabling PPS message...\n"); | |||
(void)sirf_write(session, enablemid52); | |||
(void)usleep(3330); /* guessed settling time */ | |||
if (session->gpsdata.dev.baudrate >= 38400) { | |||
/* some USB devices are also too slow, no way to tell which ones */ | |||
gpsd_report(LOG_PROG, "SiRF: Enabling subframe transmission...\n"); | |||
(void)sirf_write(session, enablesubframe); | |||
(void)usleep(3330); /* guessed settling time */ | |||
} | |||
/* disable some MIDs. we do not decode it, so don't send it */ | |||
gpsd_report(LOG_PROG, "SiRF: unset MID 7...\n"); | |||
putbyte(unsetmidXX, 6, 0x11); | |||
(void)sirf_write(session, unsetmidXX); | |||
(void)usleep(3330); /* guessed settling time */ | |||
gpsd_report(LOG_PROG, "SiRF: unset MID 28...\n"); | |||
putbyte(unsetmidXX, 6, 0x1c); | |||
(void)sirf_write(session, unsetmidXX); | |||
(void)usleep(3330); /* guessed settling time */ | |||
gpsd_report(LOG_PROG, "SiRF: unset MID 29...\n"); | |||
putbyte(unsetmidXX, 6, 0x1d); | |||
(void)sirf_write(session, unsetmidXX); | |||
(void)usleep(3330); /* guessed settling time */ | |||
gpsd_report(LOG_PROG, "SiRF: unset MID 30...\n"); | |||
putbyte(unsetmidXX, 6, 0x1e); | |||
(void)sirf_write(session, unsetmidXX); | |||
(void)usleep(3330); /* guessed settling time */ | |||
gpsd_report(LOG_PROG, "SiRF: unset MID 31...\n"); | |||
putbyte(unsetmidXX, 6, 0x1f); | |||
(void)sirf_write(session, unsetmidXX); | |||
(void)usleep(3330); /* guessed settling time */ | |||
#endif /* RECONFIGURE_ENABLE */ | |||
} | |||
if (event == event_deactivate) { | |||
/*@ +charint @*/ | |||
@@ -2070,6 +2070,29 @@ tested = 2.28 | |||
submitter = Romain Goyet <r.goyet@gmail.com> | |||
notes = Formerly sold under the corporate name "Bona CompuTech". | |||
[737A+ Bluetooth] | |||
type = device | |||
uses = MTK | |||
date = 2011-11-10 | |||
interfaces = Bluetooth | |||
location = Bend, Oregon 44N, 121W | |||
model = 737A+ Bluetooth | |||
nmea = 3.01 | |||
notes = USB ID: 0e8d:3329. Bluetooth (V1.2) and USB (V2) output. Linux sees | |||
the USB as a cell phone (/dev/ttyACM0). Seems a tad less | |||
sensitive than a SiRF III, but has 66 channels. Uses | |||
replaceable Lithium Ion battery that charges from the mini-USB | |||
connector. Small yet 32 hour runtime on a single charge. | |||
packaging = mouse | |||
rating = excellent | |||
sample_notes = Covered up with aluminum foil until lost lock, started capture, | |||
removed foil and logged until a good fix. | |||
submitter = Gary E. Miller <gem@rellim.com> | |||
techdoc = http://www.transystem.com.tw/product/53/737A+%20User%20Manual_v1.3.pdf | |||
tested = 3.2 | |||
logs = tr737A+.log | |||
vendor = Transystem | |||
#% Trimble | |||
[Trimble Lassen SK] | |||
@@ -657,7 +657,7 @@ GPSD presently fully recognizes only the 2\&.1 level of RTCM2 (message types 1, | |||
.PP | |||
The ISGPS used for RTCM2 and subframes decoder logic is sufficiently convoluted to confuse some compiler optimizers, notably in GCC 3\&.x at \-O2, into generating bad code\&. | |||
.PP | |||
Devices meant to to use PPS for high\-precision timekeeping may fail if they are specifed after startup by a control\-socket command, as opposed to on the daemon\*(Aqs original command line\&. (Root privileges are dropped early, and some Unix varients require them in order to set the PPS line discipline\&.) | |||
Devices meant to to use PPS for high\-precision timekeeping may fail if they are specified after startup by a control\-socket command, as opposed to on the daemon\*(Aqs original command line\&. (Root privileges are dropped early, and some Unix varients require them in order to set the PPS line discipline\&.) | |||
.SH "FILES" | |||
.PP | |||
/dev/ttyS0 | |||
@@ -855,7 +855,7 @@ static void handle_control(int sfd, char *buf) | |||
ignore_return(write(sfd, path, strlen(path))); | |||
ignore_return(write(sfd, "\n", 1)); | |||
} | |||
ignore_return(write(sfd, "OK\n", 6)); | |||
ignore_return(write(sfd, "OK\n", 3)); | |||
} else { | |||
/* unknown command */ | |||
ignore_return(write(sfd, "ERROR\n", 6)); | |||
@@ -1762,7 +1762,8 @@ int main(int argc, char *argv[]) | |||
static char *pid_file = NULL; | |||
struct gps_device_t *device; | |||
fd_set rfds; | |||
int i, option, msocks[2], dfd; | |||
int i, option, dfd; | |||
int msocks[2] = {-1, -1}; | |||
bool go_background = true; | |||
struct timeval tv; | |||
const struct gps_type_t **dp; | |||
@@ -39,7 +39,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(UBX_ENABLE) || defined(SUPERSTAR2_ENABLE) || defined(ONCORE_ENABLE) || defined(GEOSTAR_ENABLE) | |||
#if defined(ZODIAC_ENABLE) || defined(SIRF_ENABLE) || defined(GARMIN_ENABLE) || defined(TSIP_ENABLE) || defined(EVERMORE_ENABLE) || defined(ITRAX_ENABLE) || defined(UBX_ENABLE) || defined(SUPERSTAR2_ENABLE) || defined(ONCORE_ENABLE) || defined(GEOSTAR_ENABLE) || defined(NAVCOM_ENABLE) | |||
#define BINARY_ENABLE | |||
#endif | |||
#if defined(TRIPMATE_ENABLE) || defined(BINARY_ENABLE) | |||
@@ -804,11 +804,11 @@ void cfmakeraw(struct termios *); | |||
/* memory barriers */ | |||
static /*@unused@*/ inline void barrier(void) { | |||
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) | |||
#if defined(__GNUC__) && defined(__x86_64__) | |||
#ifndef S_SPLINT_S | |||
asm volatile("mfence"); | |||
#endif /* S_SPLINT_S */ | |||
#endif /* defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) */ | |||
#endif /* defined(__GNUC__) && defined(__x86_64__) */ | |||
} | |||
#endif /* _GPSD_H_ */ | |||
@@ -39,6 +39,8 @@ ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="gps%n", RUN+="/lib/ | |||
ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea71", SYMLINK="gps%n", RUN+="/lib/udev/gpsd.hotplug" | |||
# u-blox AG, u-blox 5 (tested with Navilock NL-402U) [linux module: cdc_acm] | |||
ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a5", SYMLINK="gps%n", RUN+="/lib/udev/gpsd.hotplug" | |||
# u-blox AG, u-blox 6 (tested with GNSS Evaluation Kit TCXO) [linux module: cdc_acm] | |||
ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a6", SYMLINK="gps%n", RUN+="/lib/udev/gpsd.hotplug" | |||
ACTION=="remove", RUN+="/lib/udev/gpsd.hotplug" | |||
@@ -806,7 +806,7 @@ sufficiently convoluted to confuse some compiler optimizers, notably | |||
in GCC 3.x at -O2, into generating bad code.</para> | |||
<para>Devices meant to to use PPS for high-precision timekeeping may | |||
fail if they are specifed after startup by a control-socket command, | |||
fail if they are specified after startup by a control-socket command, | |||
as opposed to on the daemon's original command line. (Root privileges | |||
are dropped early, and some Unix varients require them in order to set | |||
the PPS line discipline.)</para> | |||
@@ -28,7 +28,7 @@ | |||
.\" * MAIN CONTENT STARTS HERE * | |||
.\" ----------------------------------------------------------------- | |||
.SH "NAME" | |||
gpsdctl | |||
gpsdctl \- tool for sending commands to gpsd over its control socket | |||
.SH "SYNOPSIS" | |||
.HP \w'\fBgpdsctl\fR\ 'u | |||
\fBgpdsctl\fR \fIaction\fR \fIdevice\fR | |||
@@ -16,7 +16,7 @@ BSD terms apply: see the file COPYING in the distribution root for details. | |||
</refmeta> | |||
<refnamediv id='name'> | |||
<refname>gpsdctl</refname> | |||
<refpurpose></refpurpose> | |||
<refpurpose>tool for sending commands to gpsd over its control socket</refpurpose> | |||
</refnamediv> | |||
<refsynopsisdiv id='synopsis'> | |||
@@ -93,10 +93,6 @@ if __name__ == '__main__': | |||
print "gpsfake: " + str(msg) | |||
raise SystemExit, 1 | |||
if not arguments: | |||
print >>sys.stderr, "gpsfake: requires at least one logfile argument." | |||
raise SystemExit, 1 | |||
port = None | |||
progress = False | |||
cycle = 0 | |||
@@ -152,6 +148,10 @@ if __name__ == '__main__': | |||
sys.stderr.write("usage: gpsfake [-h] [-l] [-m monitor] [--D debug] [-o options] [-p] [-s speed] [-c cycle] [-b] logfile\n") | |||
raise SystemExit,0 | |||
if not arguments: | |||
print >>sys.stderr, "gpsfake: requires at least one logfile argument." | |||
raise SystemExit, 1 | |||
if progress: | |||
baton = Baton("Processing %s" % ",".join(arguments), "done") | |||
else: | |||
@@ -12,6 +12,7 @@ | |||
#include <errno.h> | |||
#include <libgen.h> | |||
#include <signal.h> | |||
#include <assert.h> | |||
#ifndef S_SPLINT_S | |||
#include <unistd.h> | |||
#endif /* S_SPLINT_S */ | |||
@@ -233,23 +234,35 @@ int main(int argc, char **argv) | |||
break; | |||
case 'f': /* Output file name. */ | |||
{ | |||
char fname[PATH_MAX]; | |||
/*@-usedef@*/ | |||
char *fname = NULL; | |||
time_t t; | |||
size_t s; | |||
size_t s = 0; | |||
size_t fnamesize = strlen(optarg); | |||
t = time(NULL); | |||
s = strftime(fname, sizeof(fname), optarg, localtime(&t)); | |||
if (s == 0) { | |||
syslog(LOG_ERR, | |||
"Bad template \"%s\", logging to stdout.", optarg); | |||
break; | |||
while (s == 0) { | |||
char *newfname = realloc(fname, fnamesize); | |||
if (newfname == NULL) { | |||
syslog(LOG_ERR, "realloc failed."); | |||
goto bailout; | |||
} else { | |||
fnamesize += 1024; | |||
fname = newfname; | |||
} | |||
s = strftime(fname, fnamesize-1, optarg, localtime(&t)); | |||
} | |||
assert(fname != NULL); /* pacify splint */ | |||
fname[s] = '\0';; | |||
logfile = fopen(fname, "w"); | |||
if (logfile == NULL) | |||
syslog(LOG_ERR, | |||
"Failed to open %s: %s, logging to stdout.", | |||
fname, strerror(errno)); | |||
syslog(LOG_ERR, | |||
"Failed to open %s: %s, logging to stdout.", | |||
fname, strerror(errno)); | |||
bailout: | |||
free(fname); | |||
break; | |||
/*@+usedef@*/ | |||
} | |||
case 'i': /* set polling interfal */ | |||
timeout = (time_t) atoi(optarg); | |||
@@ -138,10 +138,13 @@ def fetch_leapsecs(filename): | |||
return leapsecs | |||
def make_leapsecond_include(infile): | |||
leapsecs = fetch_leapsecs(infile) | |||
leapsecs.append(time.time()) # Add sentinel | |||
leapjumps = fetch_leapsecs(infile) | |||
year = time.strftime("%Y", time.localtime(time.time())) | |||
return ("#define CENTURY_BASE\t%s00\n" % year[:2]) + ("#define LEAPSECOND_NOW\t%d\n" % (len(leapsecs)-2)) | |||
leapsecs = 0 | |||
for leapjump in leapjumps: | |||
if leapjump < time.time(): | |||
leapsecs += 1 | |||
return ("#define CENTURY_BASE\t%s00\n" % year[:2]) + ("#define LEAPSECOND_NOW\t%d\n" % (leapsecs-1)) | |||
def leastsquares(tuples): | |||
"Generate coefficients for a least-squares fit to the specified data." | |||
@@ -14,3 +14,4 @@ | |||
915148800 | |||
1136073600 | |||
1230768000 | |||
1341100799 |
@@ -0,0 +1,5 @@ | |||
QMAKE_PRO_INPUT = libQgpsmm.pro | |||
QMAKE_PRL_TARGET = libQgpsmm.so.@LIBGPSVERSION@ | |||
QMAKE_PRL_CONFIG = include_source_dir lex yacc warn_on uic resources qt warn_on release incremental link_prl def_files_disabled exceptions no_mocdepend release stl qt_no_framework create_pc create_prl moc thread dll | |||
QMAKE_PRL_VERSION = @LIBGPSVERSION@ | |||
@@ -1,12 +0,0 @@ | |||
#ifndef LIBQGPSMM_GLOBAL_H | |||
#define LIBQGPSMM_GLOBAL_H | |||
#include <QtCore/qglobal.h> | |||
#if defined(LIBQGPSMM_LIBRARY) | |||
# define LIBQGPSMMSHARED_EXPORT Q_DECL_EXPORT | |||
#else | |||
# define LIBQGPSMMSHARED_EXPORT Q_DECL_IMPORT | |||
#endif | |||
#endif // LIBQGPSMM_GLOBAL_H |
@@ -246,7 +246,7 @@ The following is an excerpted and simplified version of the libgps interface cod | |||
.\} | |||
.SH "LIMITATIONS" | |||
.PP | |||
On some systems (those which do not support implicit linking in libaries) you may need to add \-lm to your link line when you link libgps\&. It is always safe to do this\&. | |||
On some systems (those which do not support implicit linking in libraries) you may need to add \-lm to your link line when you link libgps\&. It is always safe to do this\&. | |||
.PP | |||
In the C API, incautious use of | |||
\fBgps_send()\fR | |||
@@ -295,7 +295,7 @@ libgps interface code from | |||
<refsect1 id='limitations'><title>LIMITATIONS</title> | |||
<para>On some systems (those which do not support implicit linking in | |||
libaries) you may need to add -lm to your link line when you link libgps. | |||
libraries) you may need to add -lm to your link line when you link libgps. | |||
It is always safe to do this.</para> | |||
<para>In the C API, incautious use of <function>gps_send()</function> | |||
@@ -33,17 +33,29 @@ static void gpsd_run_device_hook(char *device_name, char *hook) | |||
gpsd_report(LOG_PROG, "no %s present, skipped running %s hook\n", | |||
DEVICEHOOKPATH, hook); | |||
else { | |||
char buf[PATH_MAX]; | |||
int status; | |||
(void)snprintf(buf, sizeof(buf), "%s %s %s", | |||
DEVICEHOOKPATH, device_name, hook); | |||
gpsd_report(LOG_INF, "running %s\n", buf); | |||
status = system(buf); | |||
if (status == -1) | |||
gpsd_report(LOG_ERROR, "error running %s\n", buf); | |||
/* | |||
* We make an exception to the no-malloc rule here because | |||
* the pointer will never persist outside this small scope | |||
* and can thus never cause a leak or stale-pointer problem. | |||
*/ | |||
size_t bufsize = strlen(DEVICEHOOKPATH) + 1 + strlen(device_name) + 1 + strlen(hook) + 1; | |||
char *buf = malloc(bufsize); | |||
if (buf == NULL) | |||
gpsd_report(LOG_ERROR, "error allocating run-hook buffer\n"); | |||
else | |||
gpsd_report(LOG_INF, "%s returned %d\n", DEVICEHOOKPATH, | |||
WEXITSTATUS(status)); | |||
{ | |||
int status; | |||
(void)snprintf(buf, bufsize, "%s %s %s", | |||
DEVICEHOOKPATH, device_name, hook); | |||
gpsd_report(LOG_INF, "running %s\n", buf); | |||
status = system(buf); | |||
if (status == -1) | |||
gpsd_report(LOG_ERROR, "error running %s\n", buf); | |||
else | |||
gpsd_report(LOG_INF, "%s returned %d\n", DEVICEHOOKPATH, | |||
WEXITSTATUS(status)); | |||
free(buf); | |||
} | |||
} | |||
} | |||
@@ -14,7 +14,15 @@ | |||
#ifndef USE_QT | |||
class gpsmm { | |||
#else | |||
#include "libQgpsmm_global.h" | |||
#include <QtCore/qglobal.h> | |||
#if defined(LIBQGPSMM_LIBRARY) | |||
# define LIBQGPSMMSHARED_EXPORT Q_DECL_EXPORT | |||
#else | |||
# define LIBQGPSMMSHARED_EXPORT Q_DECL_IMPORT | |||
#endif | |||
class LIBQGPSMMSHARED_EXPORT gpsmm { | |||
#endif | |||
public: | |||
@@ -178,6 +178,8 @@ static void garmin_bin_update(uint16_t pkt_id, uint32_t pkt_size UNUSED, unsigne | |||
display(mid51win, 5, 9, "%5.1f", hypot(pvt->lon_vel, pvt->lat_vel)); | |||
display(mid51win, 6, 9, "%5.1f", pvt->alt_vel); | |||
display(mid51win, 7, 8, "%d", (int)GPSD_LE16TOH(pvt->leap_sec)); | |||
if (GPSD_LE16TOH(pvt->fix) < 2) /* error value is very large when status no fix */ | |||
pvt->epe = pvt->eph = pvt->epv = NAN; | |||
display(mid51win, 8, 7, "%6.2f", pvt->epe); | |||
display(mid51win, 9, 7, "%6.2f", pvt->eph); | |||
display(mid51win, 10, 7, "%6.2f", pvt->epv); | |||
@@ -23,7 +23,6 @@ extern const struct gps_type_t sirf_binary; | |||
static WINDOW *mid2win, *mid4win, *mid6win, *mid7win, *mid9win, *mid13win; | |||
static WINDOW *mid19win, *mid27win; | |||
static bool dispmode = false, subframe_enabled = false, ppstime_enabled = false; | |||
static int nfix, fix[20]; | |||
static int leapseconds; | |||
/*@ -nullassign @*/ | |||
@@ -59,7 +58,7 @@ static char *dgpsvec[] = { | |||
#define display (void)mvwprintw | |||
#define MAXSATS 12 /* the most satellites we can dump data on */ | |||
#define SIRF_CHANNELS 12 /* max channels allowed in SiRF format */ | |||
static bool sirf_initialize(void) | |||
{ | |||
@@ -68,7 +67,7 @@ static bool sirf_initialize(void) | |||
/*@ -onlytrans @*/ | |||
mid2win = subwin(devicewin, 6, 80, 1, 0); | |||
mid4win = subwin(devicewin, MAXSATS + 3, 30, 7, 0); | |||
mid4win = subwin(devicewin, SIRF_CHANNELS + 3, 30, 7, 0); | |||
mid6win = subwin(devicewin, 3, 50, 7, 30); | |||
mid7win = subwin(devicewin, 4, 50, 13, 30); | |||
mid9win = subwin(devicewin, 3, 50, 10, 30); | |||
@@ -116,8 +115,8 @@ static bool sirf_initialize(void) | |||
(void)wborder(mid4win, 0, 0, 0, 0, 0, 0, 0, 0), | |||
(void)wattrset(mid4win, A_BOLD); | |||
display(mid4win, 1, 1, "Ch PRN Az El Stat C/N ? A"); | |||
for (i = 0; i < MAXSATS; i++) { | |||
display(mid4win, 1, 1, "Ch PRN Az El Stat C/N ? SF"); | |||
for (i = 0; i < SIRF_CHANNELS; i++) { | |||
display(mid4win, (int)(i + 2), 1, "%2d", i); | |||
} | |||
display(mid4win, 0, 1, " Measured Tracker "); | |||
@@ -272,7 +271,7 @@ static void decode_ecef(double x, double y, double z, | |||
/*@ -globstate */ | |||
static void sirf_update(void) | |||
{ | |||
int i, j, ch, off, cn; | |||
int i, j, ch, sv, off; | |||
unsigned char *buf; | |||
size_t len; | |||
uint8_t dgps; | |||
@@ -310,59 +309,46 @@ static void sirf_update(void) | |||
(void)wprintw(mid2win, "??"); | |||
(void)wattrset(mid2win, A_NORMAL); | |||
/* line 4 */ | |||
/* HDOP */ | |||
(void)wmove(mid2win, 4, 59); | |||
(void)wprintw(mid2win, "%4.1f", (double)getub(buf, 20) / 5); /* HDOP */ | |||
(void)wprintw(mid2win, "%4.1f", (double)getub(buf, 20) / 5); | |||
/* Mode 1 */ | |||
(void)wmove(mid2win, 4, 69); | |||
(void)wprintw(mid2win, "%02x", getub(buf, 19)); /* Mode 1 */ | |||
(void)wprintw(mid2win, "%02x", getub(buf, 19)); | |||
/* Mode 2 */ | |||
(void)wmove(mid2win, 4, 77); | |||
(void)wprintw(mid2win, "%02x", getub(buf, 21)); /* Mode 2 */ | |||
(void)wmove(mid2win, 4, 7); | |||
nfix = (int)getub(buf, 28); | |||
(void)wprintw(mid2win, "%d = ", nfix); /* SVs in fix */ | |||
for (i = 0; i < MAXSATS; i++) { /* SV list */ | |||
if (i < nfix) | |||
(void)wprintw(mid2win, "%3d", fix[i] = | |||
(int)getub(buf, 29 + i)); | |||
else | |||
(void)wprintw(mid2win, " "); | |||
} | |||
(void)wprintw(mid2win, "%02x", getub(buf, 21)); | |||
/* SVs in fix */ | |||
(void)wmove(mid2win, 4, 6); | |||
(void)wprintw(mid2win, "%2d = ", | |||
(int)getub(buf, 28)); | |||
/* SV list */ | |||
(void)wmove(mid2win, 4, 10); | |||
for (i = 0; i < (int)getub(buf, 28); i++) | |||
(void)wprintw(mid2win, " %2d", (int)getub(buf, 29 + i)); | |||
monitor_log("MND 0x02="); | |||
break; | |||
case 0x04: /* Measured Tracking Data */ | |||
ch = (int)getub(buf, 7); | |||
for (i = 0; i < ch; i++) { | |||
int sv, st; | |||
int az, el, state; | |||
double cn; | |||
off = 8 + 15 * i; | |||
(void)wmove(mid4win, i + 2, 3); | |||
sv = (int)getub(buf, off); | |||
(void)wprintw(mid4win, " %3d", sv); | |||
(void)wprintw(mid4win, " %3d%3d %04x", | |||
((int)getub(buf, off + 1) * 3) / 2, (int)getub(buf, | |||
off + | |||
2) / | |||
2, (int)getbes16(buf, off + 3)); | |||
st = ' '; | |||
if ((int)getbeu16(buf, off + 3) == 0xbf) | |||
st = 'T'; | |||
for (j = 0; j < nfix; j++) | |||
if (sv == fix[j]) { | |||
st = 'N'; | |||
break; | |||
} | |||
sv = (int)getub(buf, off); | |||
az = (int)getub(buf, off + 1) * 3 / 2; | |||
el = (int)getub(buf, off + 2) / 2; | |||
state = (int)getbeu16(buf, off + 3); | |||
cn = 0; | |||
for (j = 0; j < 10; j++) | |||
cn += (int)getub(buf, off + 5 + j); | |||
cn /= 10; | |||
(void)wprintw(mid4win, "%5.1f %c", (double)cn / 10, st); | |||
if (sv == 0) /* not tracking? */ | |||
(void)wprintw(mid4win, " "); /* clear other info */ | |||
(void)wprintw(mid4win, " %3d %3d %2d %04x %4.1f %c", | |||
sv, az, el, state, cn, state == 0xbf ? 'T' : ' '); | |||
} | |||
monitor_log("MTD 0x04="); | |||
break; | |||
@@ -403,7 +389,8 @@ static void sirf_update(void) | |||
case 0x08: /* 50 BPS data */ | |||
ch = (int)getub(buf, 1); | |||
display(mid4win, ch + 2, 27, "Y"); | |||
sv = (int)getub(buf, 2); | |||
display(mid4win, ch + 2, 27, "%2d", sv); | |||
subframe_enabled = true; | |||
monitor_log("50B 0x08="); | |||
break; | |||
@@ -428,10 +415,8 @@ static void sirf_update(void) | |||
display(mid13win, 1, 1, "%02d = ", | |||
getub(buf, 1)); | |||
(void)wmove(mid13win, 1, 5); | |||
for (i = 0; i < MAXSATS; i++) | |||
(void)wprintw(mid13win, " %2d", getub(buf, 2 + 5 * i)); | |||
if (MAXSATS < (int)getub(buf, 1)) | |||
(void)wprintw(mid13win, " ..."); | |||
for (i = 0; i < (int)getub(buf, 1); i++) | |||
(void)wprintw(mid13win, " %d", getub(buf, 2 + 5 * i)); | |||
monitor_log("VL 0x0d="); | |||
break; | |||
@@ -519,10 +504,10 @@ static void sirf_update(void) | |||
/*@ -type @*/ | |||
display(mid27win, 1, 1, "%8s = ", | |||
(CHECK_RANGE(dgpsvec, dgps) ? dgpsvec[dgps] : "???")); | |||
(void)wmove(mid27win, 1, 12); | |||
for (i = 0; i < MAXSATS; i++) | |||
if (getub(buf, 16 + 3 * i) != '\0') | |||
(void)wprintw(mid27win, " %2d", getub(buf, 16+3*i)); | |||
(void)wmove(mid27win, 1, 11); | |||
for (ch = 0; ch < SIRF_CHANNELS; ch++) | |||
if (getub(buf, 16 + 3 * ch) != '\0') | |||
(void)wprintw(mid27win, " %d", getub(buf, 16 + 3 * ch)); | |||
/*@ +type @*/ | |||
monitor_log("DST 0x1b="); | |||
break; | |||
@@ -581,6 +566,12 @@ static void sirf_update(void) | |||
} | |||
#endif /* CONTROLSEND_ENABLE */ | |||
/* clear the 50bps data field every 6 seconds */ | |||
if (subframe_enabled && (time(NULL) % 6 == 0)) { | |||
for (ch = 0; ch < SIRF_CHANNELS; ch++) | |||
display(mid4win, ch + 2, 27, " "); | |||
} | |||
/*@ -nullpass -nullderef @*/ | |||
if (dispmode) { | |||
(void)touchwin(mid19win); | |||
@@ -0,0 +1,16 @@ | |||
= Recommendations for distribution integrators = | |||
The X11 subdirectory contains icons and a project logo for use | |||
in desktop packaging. | |||
Usable deb and RPM specifications have their own subdirectories here. | |||
Our package files want to set up a hotplug script to notify gpsd | |||
when a potential GPS device goes active and should be polled. The | |||
goal is zero configuration; users should never have to tell gpsd how | |||
to configure itself. | |||
Bluetooth has a requirement to be able to write to the gpsd control | |||
socket from a userland device manager. Accordingly, you probably | |||
want to set up a gpsd privilege group and make sure the Bluetooth | |||
device manager is in it. | |||
@@ -1,7 +1,7 @@ | |||
%{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")} | |||
Name: gpsd | |||
Version: 3.3~dev | |||
Version: 3.4~dev | |||
Release: 1%{?dist} | |||
Summary: Service daemon for mediating access to a GPS | |||
@@ -0,0 +1,13 @@ | |||
prefix=/usr | |||
exec_prefix=${prefix} | |||
libdir=${exec_prefix}/lib | |||
includedir=${prefix}/include | |||
major_version=5 | |||
version=5.9.20110404 | |||
Name: tinfo | |||
Description: ncurses 5.9 add-on library | |||
Version: ${version} | |||
Requires: | |||
Libs: -ltinfo | |||
Cflags: |
@@ -1 +1 @@ | |||
#define REVISION "release-3.2-37-gcf863e4" | |||
#define REVISION "3.4" |
@@ -575,6 +575,7 @@ void gpsd_assert_sync(struct gps_device_t *session) | |||
void gpsd_close(struct gps_device_t *session) | |||
{ | |||
if (session->gpsdata.gps_fd != -1) { | |||
(void)ioctl(session->gpsdata.gps_fd, (unsigned long)TIOCNXCL); | |||
(void)tcdrain(session->gpsdata.gps_fd); | |||
if (isatty(session->gpsdata.gps_fd) != 0) { | |||
/* force hangup on close on systems that don't do HUPCL properly */ | |||
@@ -593,8 +594,13 @@ void gpsd_close(struct gps_device_t *session) | |||
* them the first time. Economical, and avoids tripping over an | |||
* obscure Linux 2.6 kernel bug that disables threaded | |||
* ioctl(TIOCMWAIT) on a device after tcsetattr() is called. | |||
* | |||
* Unfortunately the termios struct doesn't have c_ispeed/c_ospeed | |||
* on all architectures. Its missing on sparc, mips/mispel and hurd-i386 at least. | |||
*/ | |||
#if defined(_HAVE_STRUCT_TERMIOS_C_ISPEED) | |||
if (session->ttyset_old.c_ispeed != session->ttyset.c_ispeed || (session->ttyset_old.c_cflag & CSTOPB) != (session->ttyset.c_cflag & CSTOPB)) { | |||
#endif | |||
/*@ ignore @*/ | |||
(void)cfsetispeed(&session->ttyset_old, | |||
(speed_t) session->gpsdata.dev.baudrate); | |||
@@ -603,7 +609,9 @@ void gpsd_close(struct gps_device_t *session) | |||
/*@ end @*/ | |||
(void)tcsetattr(session->gpsdata.gps_fd, TCSANOW, | |||
&session->ttyset_old); | |||
#if defined(_HAVE_STRUCT_TERMIOS_C_ISPEED) | |||
} | |||
#endif | |||
gpsd_report(LOG_SPIN, "close(%d) in gpsd_close(%s)\n", | |||
session->gpsdata.gps_fd, session->gpsdata.dev.path); | |||
(void)close(session->gpsdata.gps_fd); | |||
@@ -0,0 +1,9 @@ | |||
[Unit] | |||
Description=GPS (Global Positioning System) Daemon | |||
Requires=gpsd.socket | |||
[Service] | |||
ExecStart=/usr/sbin/gpsd -N | |||
[Install] | |||
Also=gpsd.socket |
@@ -0,0 +1,9 @@ | |||
[Unit] | |||
Description=GPS (Global Positioning System) Daemon Sockets | |||
[Socket] | |||
ListenStream=/var/run/gpsd.sock | |||
ListenStream=127.0.0.1:2947 | |||
[Install] | |||
WantedBy=sockets.target |