Browse Source

Imported Upstream version 3.3

master
Bernd Zeimetz 9 years ago
parent
commit
8e0670df59
100 changed files with 11586 additions and 41320 deletions
  1. +20
    -0
      .splintrc
  2. +4
    -0
      HACKING
  3. +112
    -169
      INSTALL
  4. +0
    -939
      Makefile.am
  5. +0
    -2398
      Makefile.in
  6. +82
    -3
      NEWS
  7. +36
    -30
      README
  8. +1567
    -0
      SConstruct
  9. +59
    -111
      TODO
  10. +595
    -0
      Tachometer.c
  11. +0
    -9790
      aclocal.m4
  12. +212
    -20
      ais_json.c
  13. +468
    -35
      ais_json.i
  14. +0
    -140
      autogen.sh
  15. +19
    -19
      bits.c
  16. +25
    -29
      bits.h
  17. +1
    -1
      bsd_base64.c
  18. +0
    -0
      bsd_base64.h
  19. +264
    -0
      build.txt
  20. +124
    -204
      cgps.c
  21. +0
    -1533
      config.guess
  22. +0
    -1693
      config.sub
  23. +0
    -21815
      configure
  24. +0
    -1120
      configure.ac
  25. +5
    -0
      contrib/.gitignore
  26. +43
    -0
      contrib/README
  27. +12
    -0
      contrib/SConstruct
  28. +175
    -0
      contrib/ashctl.c
  29. +85
    -0
      contrib/binlog.c
  30. +170
    -0
      contrib/binreplay.c
  31. +105
    -0
      contrib/lla2ecef.c
  32. +41
    -0
      contrib/maxsats.pl
  33. +211
    -0
      contrib/motosend.c
  34. +264
    -0
      contrib/skyview.php
  35. +327
    -0
      contrib/webgps.py
  36. +2
    -0
      crc24q.c
  37. +53
    -0
      daemon.c
  38. +5
    -7
      dbusexport.c
  39. +0
    -630
      depcomp
  40. +93
    -0
      devtools/README
  41. +1083
    -0
      devtools/ais.py
  42. +34
    -0
      devtools/aivdmtable
  43. +15
    -0
      devtools/client-projects
  44. +281
    -0
      devtools/cycle_analyzer
  45. +27
    -0
      devtools/dchroot-exec
  46. +52
    -0
      devtools/editcomment
  47. +23
    -0
      devtools/fakecompare
  48. +52
    -0
      devtools/flock-instructions
  49. +340
    -0
      devtools/flocktest
  50. +69
    -0
      devtools/flocktest.ini
  51. +21
    -0
      devtools/gpsd-debian-regressions.sh
  52. +50
    -0
      devtools/gpsdfake
  53. +9
    -0
      devtools/logextract
  54. +190
    -0
      devtools/regress-builder
  55. +47
    -0
      devtools/regressdiff
  56. +26
    -0
      devtools/reindent
  57. +78
    -0
      devtools/sizes
  58. +28
    -0
      devtools/striplog
  59. +518
    -0
      devtools/tablegen.py
  60. +0
    -3
      do-tests
  61. +2
    -0
      doc/Makefile
  62. +1
    -0
      doc/README
  63. +28
    -0
      doc/explan_bits.h.xml
  64. +33
    -0
      doc/explan_dbusexport.c.xml
  65. +208
    -0
      doc/explan_driver_nmea.c.xml
  66. +22
    -0
      doc/explan_driver_proto.c.xml
  67. +54
    -0
      doc/explan_driver_rtcm2.c.xml
  68. +53
    -0
      doc/explan_drivers.c.xml
  69. +48
    -0
      doc/explan_geoid.c.xml
  70. +39
    -0
      doc/explan_gps.h.xml
  71. +325
    -0
      doc/explan_gpsd.c.xml
  72. +44
    -0
      doc/explan_gpsd.h.xml
  73. +34
    -0
      doc/explan_gpsd_report.c.xml
  74. +33
    -0
      doc/explan_gpsdclient.c.xml
  75. +75
    -0
      doc/explan_gpsutils.c.xml
  76. +67
    -0
      doc/explan_isgps.c.xml
  77. +107
    -0
      doc/explan_libgps_core.c.xml
  78. +130
    -0
      doc/explan_libgpsd_core.c.xml
  79. +22
    -0
      doc/explan_libgpsmm.cpp.xml
  80. +22
    -0
      doc/explan_libgpsmm.h.xml
  81. +61
    -0
      doc/explan_net_dgnss_dispatch.c.xml
  82. +53
    -0
      doc/explan_net_dgpsip.c.xml
  83. +74
    -0
      doc/explan_net_ntrip.c.xml
  84. +41
    -0
      doc/explan_netlib.c.xml
  85. +71
    -0
      doc/explan_ntpshm.c.xml
  86. +91
    -0
      doc/explan_packet.c.xml
  87. +27
    -0
      doc/explan_packet_names.h.xml
  88. +25
    -0
      doc/explan_packet_states.h.xml
  89. +55
    -0
      doc/explan_pseudonmea.c.xml
  90. +105
    -0
      doc/explan_serial.c.xml
  91. +29
    -0
      doc/explan_subframe.c.xml
  92. +39
    -0
      doc/explan_timebase.h.xml
  93. +7
    -0
      doc/explan_wrapup.xml
  94. +118
    -0
      doc/explanation.xml
  95. +427
    -152
      driver_aivdm.c
  96. +78
    -90
      driver_evermore.c
  97. +116
    -169
      driver_garmin.c
  98. +19
    -39
      driver_garmin_txt.c
  99. +596
    -0
      driver_geostar.c
  100. +85
    -181
      driver_italk.c

+ 20
- 0
.splintrc View File

@@ -0,0 +1,20 @@
-I.
+unixlib
+charindex
+charintliteral
-realcompare
-exitarg
-booltype bool
-paramuse
-predboolint
-nestedextern
-abstract

-Ddbus_uint32_t=uint
-Disgps30bits_t=uint
-DFD_SETSIZE=31
-DB57600=010001
-DB115200=0010011
-DCRTSCTS=0x00020000
-DONLCR=0x00000002
-D__gnuc_va_list=va_list

+ 4
- 0
HACKING View File

@@ -0,0 +1,4 @@
For the gpsd project, the information that was traditionally placed in
this file is in the repository as:

www/hacking.html

+ 112
- 169
INSTALL View File

@@ -1,70 +1,14 @@
Here are the steps for installing gpsd and verifying its performance:
= GPSD Installation Instructions =

0. gpsd has a core set of prerequisites that are required for any
configuration of the package, and then additional features and tests
have additional prerequisites.
Here are the steps for installing GPSD and verifying its performance.
They assume you have GPSD available as an installable binary package,

Necessary components for any build:
Instructions for building GPSD from source (including cross-building)
are in the file "build.txt" in the source distribution.

C compiler -> gpsd and client library are written in C
Python -> some code is generated from python scripts
Python GTK-2 binding -> the main test client, xgps, needs this
== Check that your GPS is live and you can get data from it ==

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 structure members in and out of unions.

You will need Python 2.6 or 2.4+ & simplejson. The Python code in
GPSD is 2.4-compatible except that you need either the json library
module from 2.6 or the functionally equivalent simplejson backport.
Note that while Python is required to *build* GPSD (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 embeddeed system
without having to take Python with you.

Having the following optional components on your system will enable
various additional capabilities and extensions:

C++ compiler -> libgpsmm C++ wrapper for the library
pthreads library -> support for PPS timekeeping on serial GPSes
DBUS -> gpsd will issue DBUS notifications
ncurses -> a test client and the GPS monitor depend on this
libusb-1.0.x or later -> better USB device discovery
Qt + qmake -> libQgpsmm depends on this

If you have libusb-1.0.0 or later, the GPSD build will autodetect
this and use it to discover Garmin USB GPSes, rather than groveling
through /proc/bus/usb/devices (which has been deprecated by the
Linux kernel team).

For working with DBUS, you'll need the DBUS development
headers and libraries installed. Under Debian/Ubuntu these
are the packages ibdbus-1-dev and libdbus-glib-1-dev.

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
process:

libxslt -> xsltproc is used to build man pages from xml
docbook-xsl -> style file for xml to man translation

The build degrades gracefully in the absence of any of these. You should
be able to tell from configure messages which extensions you will get.

Under Ubuntu and most other Debian-derived, an easy way to pick up
the prerequisites is: "apt-get build-dep gpsd"

If you are going to modify the build, you will need these:

autoconf 2.61 or later
automake 1.10 or later
libtool 2.26 or later
pkg-config

Once you have fetched the software prerequisites:

1. Start by making sure you can get data from your GPS, otherwise the later
Start by making sure you can get data from your GPS, otherwise the later
steps will be very frustrating. In this command

stty -F /dev/ttyXXX ispeed 4800 && cat </dev/ttyXXX
@@ -76,18 +20,34 @@ 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.

2. Ensure that device permissions will enable gpsd to read from and
write to GPS devices even after it drops root privileges. If you are
running Fedora Core or Ubuntu you can skip this step, as the stock
configuration has the right properties.
If you have trouble wuth 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 you seem to have some sort of serial-device problem, check that
your kernel properly supports the device you are using. For GPSes
using an RS-232 port (which is no longer common) you will need
serial-port support compiled into your kernel. Various USB-to-serial
adapter chips found in GPSes require specific drivers.

Under a stock Linux kernel these will all be loaded on demand when
the USB system sees the appropriate vendor/product ID combinations.
See build.txt for instructions relating to custom kernels.

== Check that your system configuration will allow GPSD to work ==

Ensure that device permissions will enable gpsd to read from and write
to GPS devices even after it drops root privileges. If you are
running Fedora Core, Ubuntu, or stock Debian you can skip this step,
as the stock configuration has the right properties.

gpsd requires two things: (1) that GPS devices have group read and
write enabled, and (2) all of them are have the same group ID as a
write enabled, and (2) all of them are have the same group ID as a
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 enable-gpsd-group in case the prototype
is not found: this should be the "dialout" group (or functional equivalent)
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.

Before dropping privileges, gpsd will ensure that it has access to
@@ -100,7 +60,7 @@ and with 0660 permissions.

When gpsd drops privileges, its default is to set uid to 'nobody' and
group to the owning group of the prototype device (the configure
option --enable-gpsd-user=foo will cause gpsd to change to 'foo'
option gpsd-user=foo will cause gpsd to change to 'foo'
instead).

If your system has the Linux hotplug facility installed you can skip
@@ -108,115 +68,98 @@ the permission-setting part; the hotplug scripts will force the
permissions for you. You still have to make sure all the tty devices
are in the same group.

3. Install prerequisites
== Check your installation prerequisites ==

A minimum build of GPSD can run pretty close to the metal; all it
absolutely needs is the C runtime support. The test clients and
various additional features have additional prerequisites:

|==========================================================================
|pthreads library | support for PPS timekeeping on serial GPSes
|DBUS | gpsd will issue DBUS notifications
|ncurses | a test client and the GPS monitor depend on this
|libtinfo5 | shared low-level terminfo library (see below)
|libusb-1.0.x or later | better USB device discovery
|Qt + qmake | libQgpsmm depends on this
|python2.6+ | required for various clients and utilities
|pgtk-2/cairo bindings | the main test client, xgps, needs this
|==========================================================================

Some ncurses packages comntain the terminfo library; some break it out
seperately as libtinfo5 or libtinfo.

Under Debian and Ubuntu ou can get all the build prerequisites
installed with "apt-get build-dep gpsd".
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
equivalent simplejson backport.

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

4. Build gpsd from source (skip this step if you have installed GPSD
from a binary package). As usual, the sequence is:
Up-to-date gpsd packages are generally available for Linux
distributions including Debian and derivatives (including Ubuntu and
Mint), Fedora and derivatives (including CentOS), openSUSE, PCLinuxOS,
Mageia, and Slackware. In the embedded space, CeroWRT carries
GPSD. The GPSD package in the FreeBSD ports tree is also reliably up
to date. Even if your distribution is not on this list, it is quite
likely GPSD has already been packaged for it.

./configure && make
Whatever distribution you are running, the name of the core GPSD
package containing the service daemon is almost certainly "gpsd".
However, many distributions break up GPSD into separate installable
packages for the core daemon and clients; you should search your
repository index for anything with gpsd as a prefix.

Mac OS X users may need to do "./configure --x-includes=/usr/X11R6/include"
== How to test the software ==

5. Start gpsd. You'll need to give it as an argument a path to
a serial or USB port with a GPS attached to it.
1. Start gpsd. You'll need to give it as an argument a path to
a serial or USB port with a GPS attached to it. Your test command
should look something like this:

6. Once gpsd is running, telnet to port 2947. You should see a
gpsd -D 5 -N -n /dev/ttyUSB0

2. Once gpsd is running, telnet to port 2947. You should see a
greeting line that's a JSON object describing GPSD's version.
Now plug in your GPS (or AIS receiver, or RTCM2 receiver).

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

8. Start the xgps client. Calling it with no arguments should do the right
thing. You should see a GUI panel with position/velocity-time information,
and a satellite display. The displays won't look very interesting until
the GPS acquires satellite lock.

9. Now that you've verified that the code is working, "make install"
will install it it in the system directories. "make uninstall" will
undo this.

(You won't need to "make install" if you installed from a binary package.)

10. To enable hotplugging of USB GPSes under Linux, do a 'make udev-install' or
equivalent to put the appropriate udev rules and wrapper files in place.

11. Check out the list of supported hardware at

http://gpsd.berlios.de/hardware.html

If your GPS isn't on the list, please send us information to add a new
line to the table. Directions are included on that page.

We can also use updates of the latest version number known to work with
hardware already supported.

12. Note for small embedded systems and those without threading. It is
possible to build gpsd without thread support if you configure with
--disable-pps. You'll lose support for updating the clock from PPS pulses.

13. Note for systems using DBUS: gpsd includes support for shipping fixes
as DBUS notifications, but it is not compiled in by default. Configure
with the option "--enable-dbus" to get it working.

14. The distribution includes a PHP script that you can use to
generate a PHP status page for your GPS. You will need php and php-gd
installed. To install it, copy the file 'gpsd.php' to your HTTP
document directory. The first time it's invoked, it will generate a
file called 'gpsd_config.inc' containing configuration information;
edit to taste. Note that for the Google Maps feature work you need
to set a valid Google API key in your config file.

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

You can build libQgpsmm if you have qmake and Qt (specifically the
(specifically QtCore and QtNetwork modules) version 4.5.3 or higher.
You will also need a C++ compiler supported by Qt (tested on GCC
4.4.0/mingw on Windows and GCC 4.1.2 on linux).

Building is done through a standard Qt .pro project file:
- Go to the libQgpsmm subdirectory of gpsd and execute "qmake"
to create the Makefiles
- execute "make" to build the library
- execute "make install" or equivalent to copy libgpsmm.h and the library
to the appropriate location for your platform.

Specifically for linux: You can specify the installation prefix by
running "qmake PREFIX=<installation_root>". Default value is
"/usr/local".

Please refer to Qt's documentation at
http://qt.nokia.com/doc/4.6/platform-specific.html for platform specific
building documentation

16. There are regression tests to verify proper operation of gpsd, and
it can be useful to run these to verify that all is well. To run the
regression tests, first build gpsd from sources, and then run "make
check". It is not necessary to install first, but you do need
to have "." in your $PATH to run regressions uninstalled. Python is
required for regression tests.

17. If you installed from a .deb under Debian or a Debian-derived
JSON objects representing reports from your GPS; these are reports
in GPSD protocol.

4. Start the xgps or cgps client. Calling it with no arguments should
do the right thing. You should see a display panel with
position/velocity-time information, and a satellite display. The
displays won't look very interesting until the GPS acquires satellite
lock.

5. Have patience. If you are cold-starting a new GPS, it may take
15-20 minutes after it gets a skyview for it to download an ephemeris
and begin delivering fixes.

6. A FAQ and troubleshooting instructions can be found at the GPSD
project site.

== Once you have verified correct operation ==

1. If you installed from a .deb under Debian or a Debian-derived
system, you may need to `dpkg-reconfigure -plow gpsd' to enable the
hotplug magic ("Start gpsd automatically").

18. Note for people using gpsd as time source for ntpd: In case you're
2. Check out the list of supported hardware at the Hardware page on
the GPSD project's website. If your GPS isn't on the list, please send
us information to add a new line to the table. Directions are
included on that page. We can also use updates of the latest version
number known to work with hardware already supported.

3. GPSD includes a PHP script that you can use to generate a PHP
status page for your GPS if you wish. (It may not be in the core
package.) It will be installed in your HTTP document directory. The
first time it's invoked, it will generate a file called
'gpsd_config.inc' in that directory containing configuration
information; edit to taste. Note that for the Google Maps feature
work you need to set a valid Google API key in gpsd_config.inc.

4. Note for people using gpsd as time source for ntpd: In case you're
using dhcp3-client to configure your system, make sure you disable
/etc/dhcp3/dhclient-exit-hooks.d/ntp as dhclient would restart
/etc/dhcp3/dhclient-exit-hooks.d/ntp, as dhclient would restart
ntpd with an automatically created ntp.conf otherwise - and gpsd
would not be ablt to talk with ntpd anymore.
would not be able to talk with ntpd anymore.

+ 0
- 939
Makefile.am View File

@@ -1,939 +0,0 @@
# Automake description for gpsd
#
# This file is Copyright (c) 2010 by the GPSD project
# BSD terms apply: see the file COPYING in the distribution root for details.
#

CLEANFILES =

# For a detailed explanation of what this ugly code is doing, see
# http://www.gnu.org/software/automake/manual/automake.html#Multiple-Outputs
MULTIOUT_RECOVER_DELETED = \
if test -f '$@'; then :; else \
trap "rm -rf '$$WITNESS.lock' '$$WITNESS'" HUP INT PIPE TERM; \
if mkdir "$$WITNESS.lock" 2>/dev/null; then \
rm -f "$$WITNESS"; \
$(MAKE) $(AM_MAKEFLAGS) "$$WITNESS"; \
result=$$?; rm -rf "$$WITNESS.lock"; exit $$result; \
else \
while test -d "$$WITNESS.lock"; do sleep 1; done; \
test -f "$$WITNESS"; \
fi; \
fi

#SUBDIRS = contrib

XMLTO = xmlto

#
# Conditionally add programs depending on libraries that may or may not be present.
#
if HAVE_NCURSES
CURSESPROGS = cgps gpsmon
endif

# Conditional includes.
INCLUDES = $(LIBUSB_CFLAGS)
if HAVE_DBUS
INCLUDES += $(DBUS_CFLAGS) $(DBUS_GLIB_CFLAGS) -DDBUS_API_SUBJECT_TO_CHANGE=1
endif
if HAVE_BLUEZ
INCLUDES += $(BLUEZ_CFLAGS)
endif

RTCM104PAGES_DIST = gpsdecode.1
if HAVE_RTCM104V2
if HAVE_RTCM104V3
if HAVE_AIVDM
RTCM104PROGS = gpsdecode
RTCM104PAGES = $(RTCM104PAGES_DIST)
endif
endif
endif

bin_PROGRAMS = $(XAW_PROGS) $(RTCM104PROGS) $(CURSESPROGS) gpsctl gpspipe gpxlogger lcdgps
sbin_PROGRAMS = gpsd

# \todo Add programs to TESTS if not already. used.
check_PROGRAMS = test_float test_trig test_bits test_packet test_mkgmtime test_geoid test_json
if LIBGPSMM_ENABLE
check_PROGRAMS += test_gpsmm
endif
if LIB_Q_GPSMM_ENABLE
check_PROGRAMS += test_qgpsmm
endif

# List of Python scripts and modules, which are handled by setup.py.
# Required to ensure that the extensions/modules/scripts are rebuilt via
# setup.py in case they changed.
# Also used to specify which files to include during make dist.
PYTHONSCRIPTS_DIST = gpscat gpsfake gpsprof xgps xgpsspeed
PYTHONMODULES_DIST = gps/__init__.py gps/misc.py gps/fake.py gps/gps.py gps/client.py

PYTHONPAGES_DIST = gpsprof.1 gpsfake.1 gpscat.1 xgpsspeed.1 xgps.1
if HAVE_PYTHON
python_PYTHON = gpscap.py
PYTHONPAGES = $(PYTHONPAGES_DIST)
endif


#
# Build cgps
#
cgps_SOURCES = cgps.c
cgps_LDADD = $(LIBM) $(LIBC) $(LIBNSL) $(LIBSOCKET) $(NCURSES_LIBS) libgps.la -lm $(LIBPTHREAD)

#
# Build gpxlogger
#
gpxlogger_SOURCES = gpxlogger.c
gpxlogger_LDADD = $(DBUS_GLIB_LIBS) libgps.la -lm

#
# Build gpsd
#
gpsd_c_sources = gpsd_dbus.c gpsd.c
gpsd_SOURCES = $(gpsd_c_sources) gpsd_dbus.h
gpsd_LDADD = $(DBUS_LIBS) $(LIBM) libgpsd.la libgps.la -lm $(LIBPTHREAD) $(LIBUSB_LIBS)

#
# Build gpsctl
#
gpsctl_SOURCES = gpsctl.c
gpsctl_LDADD = $(LIBM) libgpsd.la libgps.la -lm $(LIBPTHREAD) $(LIBUSB_LIBS)

#
# Build gpspipe
#
gpspipe_SOURCES = gpspipe.c
gpspipe_LDADD = $(DBUS_LIBS) $(LIBM) libgps.la -lm

#
# Build lcdgps
#
lcdgps_SOURCES = lcdgps.c
lcdgps_LDADD = $(LIBM) libgps.la -lm

#
# Build gpsmon
#
gpsmon_SOURCES = gpsmon.c monitor_nmea.c monitor_sirf.c \
monitor_italk.c monitor_ubx.c monitor_superstar2.c \
monitor_oncore.c monitor_tnt.c
gpsmon_LDADD = $(LIBM) $(NCURSES_LIBS) libgpsd.la libgps.la -lm $(LIBPTHREAD) $(LIBUSB_LIBS)

#
# Build gpsdecode
#
gpsdecode_SOURCES = gpsdecode.c
gpsdecode_LDADD = $(LIBM) libgpsd.la libgps.la -lm $(LIBPTHREAD) $(LIBUSB_LIBS)

#
# Build shared libraries
#
# As we need to retrieve the version from qmake to build the Qt library,
# we provide targets to print the necessary informations.
libgps_VERSION_CURRENT = 19
libgps_VERSION__REVISION = 0
libgps_VERSION_AGE = 0
libgps_VERSION_NUMBER = $(libgps_VERSION_AGE):$(libgps_VERSION__REVISION):$(libgps_VERSION_AGE)
libgps_la_LDFLAGS = -version-number $(libgps_VERSION_CURRENT):$(libgps_VERSION__REVISION):$(libgps_VERSION_AGE)
lib_LTLIBRARIES = libgps.la libgpsd.la

libgps_SONAME = $(shell expr $(libgps_VERSION_CURRENT) - $(libgps_VERSION_AGE))
libgps_VERSION = $(libgps_SONAME).$(libgps_VERSION_AGE).$(libgps_VERSION__REVISION)
print_libgps_VERSION_CURRENT:
echo $(libgps_VERSION_CURRENT)
print_libgps_VERSION__REVISION:
echo $(libgps_VERSION__REVISION)
print_libgps_VERSION_AGE:
echo $(libgps_VERSION_AGE)
print_libgps_SONAME:
echo $(libgps_SONAME)
print_libgps_VERSION:
echo $(libgps_VERSION)

libgps_c_sources = \
ais_json.c \
gpsd_report.c \
gpsutils.c \
geoid.c \
gpsdclient.c \
gps_maskdump.c \
hex.c \
json.c \
libgps_core.c \
libgps_json.c \
netlib.c \
rtcm2_json.c \
shared_json.c \
strl.c

libgpsd_c_sources = \
bits.c \
bsd-base64.c \
crc24q.c \
gpsd_json.c \
isgps.c \
gpsd_maskdump.c \
libgpsd_core.c \
net_dgpsip.c \
net_gnss_dispatch.c \
net_ntrip.c \
ntpshm.c \
packet.c \
pseudonmea.c \
serial.c \
srecord.c \
subframe.c \
drivers.c \
driver_aivdm.c \
driver_evermore.c \
driver_garmin.c \
driver_garmin_txt.c \
driver_italk.c \
driver_navcom.c \
driver_nmea.c \
driver_oncore.c \
driver_rtcm2.c \
driver_rtcm3.c \
driver_sirf.c \
driver_superstar2.c \
driver_tsip.c \
driver_ubx.c \
driver_zodiac.c

libgpsd_h_sources = \
sockaddr.h \
bsd-base64.h \
timebase.h \
bits.h \
crc24q.h

BUILT_SOURCES = packet_names.h gpsd.h revision.h ais_json.i gps_maskdump.c gpsd_maskdump.c

packet_names.h: packet_states.h
rm -f packet_names.h && \
sed -e '/^ *\([A-Z][A-Z0-9_]*\),/s// "\1",/' -e '/_states/s//_names/' < `test -f 'packet_states.h' || echo '$(srcdir)/'`packet_states.h > packet_names.h && \
chmod a-w packet_names.h

gpsd.h: gpsd.h-head gpsd.h-tail gpsd_config.h
rm -f gpsd.h && \
echo "/* This file is generated. Do not hand-hack it! */" >gpsd.h && \
cat $(srcdir)/gpsd.h-head >>gpsd.h && \
cat $(srcdir)/gpsd_config.h >>gpsd.h && \
cat $(srcdir)/gpsd.h-tail >>gpsd.h && \
chmod a-w gpsd.h

ais_json.i: jsongen.py
rm -f ais_json.i && \
$(PYTHON) jsongen.py --ais --target=parser >ais_json.i && \
chmod a-w ais_json.i

revision.h: Makefile
@rm -f revision.h && \
echo '#define' REVISION '"'`date -u +%Y-%m-%dT%H:%M:%S`'"' >revision.h && \
chmod a-w revision.h

gps_maskdump.c: gps.h maskaudit.py
rm -f gps_maskdump.c && \
$(PYTHON) maskaudit.py -c >gps_maskdump.c && \
chmod a-w gps_maskdump.c

gpsd_maskdump.c: gpsd.h maskaudit.py
rm -f gpsd_maskdump.c && \
$(PYTHON) maskaudit.py -d >gpsd_maskdump.c && \
chmod a-w gpsd_maskdump.c

libgps_la_SOURCES = $(libgps_c_sources)

libgpsd_la_SOURCES = $(libgpsd_c_sources) $(libgpsd_h_sources) \
driver_rtcm2.h packet_states.h

# Warning: This overrides autoconf's normal link-line generation process
if LIBGPSMM_ENABLE
libgps_la_SOURCES += libgpsmm.cpp
libgps_la_LINK = /bin/sh ./libtool --tag=CXX --mode=link g++ $(libgps_la_LDFLAGS) -o $@
else
libgps_la_LINK = /bin/sh ./libtool --tag=CC --mode=link gcc $(libgps_la_LDFLAGS) -o $@
endif

nodist_libgpsd_la_SOURCES = packet_names.h ais_json.i
libgps_la_LIBADD = $(LIBM) $(LIBC) $(LIBNSL) $(LIBSOCKET) $(LIBPTHREAD)
libgpsd_la_LIBADD = $(LIBM) $(LIBC) $(LIBNSL) $(LIBSOCKET) $(LIBPTHREAD) $(BLUEZ_LIBS) libgps.la

noinst_SCRIPTS =

# Build Python binding
#
if HAVE_PYTHON
PYEXTENSIONS = gpspacket.so gpslib.so
noinst_SCRIPTS += stamp-python setup.py

# Multiple-outputs hack. See
# http://www.gnu.org/software/automake/manual/automake.html#Multiple-Outputs
$(PYEXTENSIONS): stamp-python
+@WITNESS=stamp-python; $(MULTIOUT_RECOVER_DELETED)
# TODO: Should the dependency on libgps.la be enforced inside
# setup.py? (See the variable 'needed_files' in setup.py.)
stamp-python: gpspacket.c gpsclient.c libgps.la setup.py $(PYTHONMODULES_DIST) $(PYTHONSCRIPTS_DIST)
# Build Python modules and scripts using distutils via setup.py.
# We define build-lib and build-scripts as distutils might have been
# configured to use different directories, but we want to use the
# produced files within the regress-driver script - therefore we
# need to build them in directories we know about.
# See configure.ac for the definition of PYTHON_DISTUTILS_LIBDIR
# and PYTHON_DISTUTILS_SCRIPTDIR.
@rm -f '$@' '$@.tmp'
@echo 'timestamp for $@' > '$@.tmp'
(cd '$(srcdir)' && \
env abs_builddir='$(abs_builddir)' \
MAKE='$(MAKE)' \
$(PYTHON) setup.py build \
--build-lib '$(srcdir)/$(PYTHON_DISTUTILS_LIBDIR)' \
--build-scripts '$(srcdir)/$(PYTHON_DISTUTILS_SCRIPTDIR)' \
--mangenerator '$(XMLPROC)') && \
(cd '$(srcdir)/gps' && \
rm -f *.so && \
ln -s ../$(PYTHON_DISTUTILS_LIBDIR)/gps/*.so . ) && \
mv -f '$@.tmp' '$@'
CLEANFILES += stamp-python stamp-python.tmp
endif

QTLIB_DIST = libQgpsmm/libQgpsmm.pro \
libQgpsmm/gpsutils.cpp \
libQgpsmm/libgps_core.cpp \
libQgpsmm/libQgpsmm_global.h

QTLIB_DIST_MINGW = libQgpsmm/mingw/gpsd_config.h \
libQgpsmm/mingw/test_qgpsmm.pro

if LIB_Q_GPSMM_ENABLE
noinst_SCRIPTS += stamp-qt
QTLIBS = libQgpsmm/binaries/libQgpsmm.so \
libQgpsmm/binaries/libQgpsmm.so.$(libgps_SONAME) \
libQgpsmm/binaries/libQgpsmm.so.$(libgps_SONAME).$(libgps_VERSION_AGE) \
libQgpsmm/binaries/libQgpsmm.so.$(libgps_VERSION)

QTLIB_sources = gpsutils.c \
libgps_core.c \
libgpsmm.cpp \
libgps_json.c \
hex.c \
gpsd_report.c \
strl.c \
shared_json.c \
rtcm2_json.c \
ais_json.c \
json.c \
gps.h \
libgpsmm.h \
gps_json.h \
json.h \
ais_json.i \
gpsd.h \
$(QTLIB_DIST)

QMAKE_OPTS = "PREFIX=${prefix}" \
"MAKE=$(MAKE)" \
"QMAKE_CXX=$(CXX)" \
"QMAKE_CC=$(CC)" \
"QMAKE_CFLAGS+=$(CFLAGS)" \
"QMAKE_LFLAGS+=$(LDFLAGS)" \
"VERSION=$(libgps_VERSION)" \
"TARGET_LIBDIR=${libdir}" \
"TARGET_INCLUDEDIR=${includedir}"

libQgpsmm/Makefile: libQgpsmm/libQgpsmm.pro gpsd.h ais_json.i
cd $(srcdir)/libQgpsmm && $(QMAKE) $(QMAKE_OPTS)
# Yet another multiple-outputs hack:
$(QTLIBS): stamp-qt
+@WITNESS=stamp-qt; $(MULTIOUT_RECOVER_DELETED)
stamp-qt: $(QTLIB_sources) libQgpsmm/Makefile
$(MAKE) -C $(srcdir)/libQgpsmm
touch $@
CLEANFILES += stamp-qt
endif

# Clean up after Python and QT
clean-local:
if HAVE_PYTHON
rm -rf build gps/*.so
endif
if LIB_Q_GPSMM_ENABLE
if test -r $(srcdir)/libQgpsmm/Makefile; then \
$(MAKE) -C $(srcdir)/libQgpsmm distclean || true; \
fi
rm -rf $(srcdir)/libQgpsmm/binaries
rm -f $(srcdir)/libQgpsmm/*.o $(srcdir)/libQgpsmm/Makefile
endif

# Install Python modules and QT library
install-exec-local:
if HAVE_PYTHON
# Make sure we do not use --root as option to setup.py install
# when DESTDIR is not defined as distutils would use the current
# working directory as root directory and not install to ${prefix}.
if test -z "$(DESTDIR)"; then \
$(PYTHON) setup.py install --prefix=${prefix} ;\
else \
$(PYTHON) setup.py install --prefix=${prefix} --root=$(DESTDIR) ;\
fi
endif
if LIB_Q_GPSMM_ENABLE
$(MAKE) -C libQgpsmm install INSTALL_ROOT=$(DESTDIR)
endif

#
# Build test_float
#
test_float_SOURCES = test_float.c
test_float_LDADD = $(LIBC) -lm

#
# Build test_trig
#
test_trig_SOURCES = test_trig.c
test_trig_LDADD = $(LIBC) -lm

if LIBGPSMM_ENABLE
#
# Build test_gpsmm
#
test_gpsmm_SOURCES = test_gpsmm.cpp
test_gpsmm_LDADD = $(LIBC) libgps.la -lm $(LIBUSB_LIBS)
endif

if LIB_Q_GPSMM_ENABLE
#
# Build test_qgpsmm
#
test_qgpsmm_SOURCES = test_gpsmm.cpp
test_qgpsmm_LDFLAGS = -Wl,-rpath,$(srcdir)/libQgpsmm/binaries
test_qgpsmm_LDADD = $(LIBC) $(LIBUSB) $(QtNetwork_LIBS) -LlibQgpsmm/binaries -lQgpsmm
test_qgpsmm_DEPENDENCIES = libQgpsmm/binaries/libQgpsmm.so
endif

#
# Build test_bits tester
#
test_bits_SOURCES = test_bits.c
test_bits_LDADD = $(LIBC) libgpsd.la libgps.la $(LIBUSB_LIBS)

#
# Build packets tester
#
test_packet_SOURCES = test_packet.c
test_packet_LDADD = $(LIBC) libgpsd.la libgps.la -lm $(LIBUSB_LIBS)

#
# Build geoid model tester
#
test_geoid_SOURCES = test_geoid.c
test_geoid_LDADD = $(LIBC) libgps.la -lm

#
# Build time functions tester
#
test_mkgmtime_SOURCES = test_mkgmtime.c
test_mkgmtime_LDADD = $(LIBC) libgps.la -lm

#
# Build JSON parse tester
test_json_SOURCES = test_json.c
test_json_LDADD = $(LIBC) libgps.la -lm

MANPAGES_BASE = \
gpsd.8 \
gps.1 \
cgps.1 \
lcdgps.1 \
libgps.3 \
libgpsmm.3 \
libgpsd.3 \
gpsmon.1 \
gpsctl.1 \
gpspipe.1 \
rtcm-104.5 \
srec.5

if HAVE_XSLT_PROCESSOR
MANPAGES_DIST = \
$(MANPAGES_BASE) \
$(RTCM104PAGES_DIST) \
$(PYTHONPAGES_DIST)

man_MANS = \
$(MANPAGES_BASE) \
$(RTCM104PAGES) \
$(PYTHONPAGES)

#
# Create Manpages
#
BUILT_MANPAGES = $(MANPAGES_DIST)

.xml.1:
$(XMLPROC) $(XMLPROCFLAGS) $(MANTARGET) $<

.xml.3:
$(XMLPROC) $(XMLPROCFLAGS) $(MANTARGET) $<

.xml.5:
$(XMLPROC) $(XMLPROCFLAGS) $(MANTARGET) $<

.xml.8:
$(XMLPROC) $(XMLPROCFLAGS) $(MANTARGET) $<

# Another instance of the multiple-outputs hack.
gps.1 xgps.1 xgpsspeed.1 cgps.1 lcdgps.1: stamp-gps-manpages
+@WITNESS=stamp-gps-manpages; $(MULTIOUT_RECOVER_DELETED)
stamp-gps-manpages: gps.xml
@rm -f '$@' '$@.tmp'
echo 'timestamp for $@' > '$@.tmp' && \
$(XMLPROC) $(XMLPROCFLAGS) $(MANTARGET) '$(srcdir)/gps.xml' && \
mv -f '$@.tmp' '$@'
CLEANFILES += stamp-gps-manpages stamp-gps-manpages.tmp
endif

noinst_HEADERS = gpsd_config.h \
driver_italk.h driver_rtcm2.h driver_superstar2.h \
driver_ubx.h gpsmon.h gpsdclient.h json.h gps_json.h \
revision.h TachometerP.h Tachometer.h
nodist_include_HEADERS = gpsd.h

if LIBGPSMM_ENABLE
include_HEADERS = gps.h libgpsmm.h
else
include_HEADERS = gps.h
endif

XML = \
gpsd.xml \
gps.xml \
libgps.xml \
libgpsmm.xml \
libgpsd.xml \
gpsmon.xml \
gpsdecode.xml \
gpsprof.xml \
gpsfake.xml \
gpsctl.xml \
gpscat.xml \
gpspipe.xml \
rtcm-104.xml \
srec.xml

# Note: packaging/rpm/gpsd.spec is generated, but it needs to be in the
# tarball in order for 'make dist-rpm' to work. The BUILT_SOURCES
# files are here in order to minimize build dependencies for package
# builders who never alter anything, especially the Python dependency.
# Also note that the test and gps directories are here rather than
# being the contents of a SUBDIRS variable so that autconf won't
# go looking for makefiles in them.
EXTRA_DIST = \
revision.h \
autogen.sh \
README \
INSTALL \
COPYING \
TODO \
NEWS \
AUTHORS \
jsongen.py.in \
maskaudit.py.in \
dgpsip-servers \
test_float.c \
test_trig.c \
gpsd.php \
gpsd.xml \
gpsd.h-head \
gpsd.h-tail \
$(XML) \
$(BUILT_SOURCES) \
$(MANPAGES_DIST) \
gpsd.rules \
gpsd.hotplug \
gpsd.hotplug.wrapper \
gpsd.usermap \
valgrind-audit \
valgrind-suppressions \
gpspacket.c \
gpsclient.c \
driver_proto.c \
monitor_proto.c \
setup.py \
packet_states.h \
libgps.pc.in \
libgpsd.pc.in \
gpscap.ini \
packaging/deb/etc_default_gpsd \
packaging/deb/etc_init.d_gpsd \
packaging/rpm/gpsd.spec \
packaging/rpm/gpsd.init \
packaging/rpm/gpsd.sysconfig \
packaging/X11/xgps.desktop \
packaging/X11/xgpsspeed.desktop \
packaging/X11/gpsd-logo.png \
do-tests \
regress-driver \
$(PYTHONSCRIPTS_DIST) \
$(PYTHONMODULES_DIST) \
$(QTLIB_DIST) \
$(QTLIB_DIST_MINGW) \
test


# Prepare necessary files to build the mingw-port of libQgpsmm
# while creating the dist tarball.
dist-hook: ais_json.i gpsd_config.h
$(MKDIR_P) '$(distdir)/libQgpsmm/mingw'
cp -p ais_json.i $(distdir)/libQgpsmm/mingw
grep "#define VERSION" gpsd_config.h > $(distdir)/libQgpsmm/mingw/version.h
echo "VERSION=$(libgps_VERSION)" > $(distdir)/libQgpsmm/mingw/version.pri
distclean-local:
rm -f $(distdir)/libQgpsmm/mingw/version.* $(distdir)/libQgpsmm/mingw/ais_json.i


CLEANFILES += $(BUILT_SOURCES) *.core $(PYEXTENSIONS) $(BUILT_MANPAGES)

pkgconfig_DATA = libgps.pc libgpsd.pc
pkgconfigdir = $(libdir)/pkgconfig

# These are not distributed
libgps: libgps_core.c gps.h .libs/libgps.a
$(CC) $(CFLAGS) -o libgps -lm -DTESTMAIN $(LIBPTHREAD) -g libgps_core.c .libs/libgps.a

# Report splint warnings
SPLINTOPTS = -I/usr/include/dbus-1.0/ $(LIBUSB_CFLAGS) +quiet
splint: gpsd.h packet_names.h
@echo "Running splint on daemon and libraries..."
-splint $(SPLINTOPTS) -exportlocal -redef $(gpsd_c_sources) $(libgpsd_c_sources) $(libgps_c_sources)
@echo "Running splint on cgps..."
-splint $(SPLINTOPTS) -exportlocal $(cgps_SOURCES)
@echo "Running splint on gpsctl..."
-splint $(SPLINTOPTS) $(gpsctl_SOURCES)
@echo "Running splint on gpsmon..."
-splint $(SPLINTOPTS) -exportlocal $(gpsmon_SOURCES)
@echo "Running splint on gpspipe..."
-splint $(SPLINTOPTS) $(gpspipe_SOURCES)
@echo "Running splint on gpsdecode..."
-splint $(SPLINTOPTS) $(gpsdecode_SOURCES)
@echo "Running splint on gpxlogger..."
-splint $(SPLINTOPTS) $(gpxlogger_SOURCES)
@echo "Running splint on test_bits test harness..."
-splint $(SPLINTOPTS) $(test_bits_SOURCES)
@echo "Running splint on test_packet test harness..."
-splint $(SPLINTOPTS) $(test_packet_SOURCES)
@echo "Running splint on test_mkgmtime test harness..."
-splint $(SPLINTOPTS) $(test_mkgmtime_SOURCES)
@echo "Running splint on test_geoid test harness..."
-splint $(SPLINTOPTS) $(test_geoid_SOURCES)
@echo "Running splint on test_json test harness..."
-splint $(SPLINTOPTS) $(test_json_SOURCES)

# Report cppcheck warnings. Requires 1.40 or later.
cppcheck: gpsd.h packet_names.h
cppcheck --template gcc --all --force .

# Check the documentation for bogons, too
xmllint: $(XML)
for xml in $(XML); do xmllint --nonet --noout --valid $$xml; done

# Re-indent the codebase in a uniform style for readability.
INDENT_FILES = $(gpsd_c_sources) $(libgpsd_c_sources) $(libgps_c_sources) \
$(cgps_SOURCES) $(gpsmon_SOURCES) $(gpspipe_SOURCES) \
$(gpxlogger_SOURCES) $(gpsdecode_SOURCES) \
$(test_bits_SOURCES) $(test_packet_SOURCES) \
$(test_mkgmtime_SOURCES) $(test_geoid_SOURCES) $(test_json_SOURCES)
INDENT_OPTIONS = --indent-level4 \
--honour-newlines \
--dont-break-procedure-type \
--cuddle-else \
--braces-on-if-line \
--case-brace-indentation0 \
--brace-indent0 \
--no-space-after-casts \
--no-space-after-function-call-names \
--start-left-side-of-comments \
--dont-format-comments
indent:
chmod u+w *maskdump.c
indent $(INDENT_OPTIONS) $(INDENT_FILES)
for f in $(INDENT_FILES); \
do \
sed <$${f} >/tmp/reindent$$$$ -e 's/@ \*/@*/' ; \
mv /tmp/reindent$$$$ $${f} ; \
done
chmod u-w *maskdump.c
@echo "Diff lines:" `git diff | wc -l`

version:
@echo $(VERSION)

#
# Regression tests begin here
#
# Note that the *-makeregress targets re-create the *.log.chk source
# files from the *.log source files.
#
# These require gcc4; use of the math coprocessor's on-board trig functions
# apparently increases the accuracy of computation in a way that affects
# the low-order digits of the track field in the O response.

# Our regression tests are make targets, while automake expects
# programs. Thus, our approach is to construct the test
# infrastructure our way, with make targets, and to have one TEST from
# automake's viewpoint: a trivial shell script to invoke make with our
# top-level regression target.

# One might think that using TESTS_ENVIRONMENT=$(MAKE) would work
# around this, but because the generated rule (check-TESTS) both
# depends on each TEST as well as invokes it (with TESTS_ENVIRONMENT)
# the entire list of tests is run twice.

# Use make REGRESSOPTS=-u to force running with UDP rather than pty devices

run_regress_driver = PYTHON=$(PYTHON) $(srcdir)/regress-driver $(REGRESSOPTS)

# Regression-test the daemon
gps-regress: gpsd stamp-python
$(run_regress_driver) $(srcdir)/test/daemon/*.log

# Test that super-raw mode works. Compare each logfile against itself
# dumped through the daemon running in R=2 mode. (This test is not
# included in the normal regressions.)
raw-regress: stamp-python
$(run_regress_driver) -r $(srcdir)/test/daemon/*.log

# Build the regression tests for the daemon.
gps-makeregress: gpsd stamp-python
$(run_regress_driver) -b $(srcdir)/test/daemon/*.log

# To build an individual test for a load named foo.log, put it in
# test/daemon and do this:
# regress-driver -b test/daemon/foo.log

# Regression-test the RTCM decoder.
rtcm-regress: gpsdecode
@echo "Testing RTCM decoding..."
@mkdir -p test
@for f in $(srcdir)/test/*.rtcm2; do \
echo "Testing $${f}..."; \
$(srcdir)/gpsdecode <$${f} >/tmp/test-$$$$.chk; \
diff -ub $${f}.chk /tmp/test-$$$$.chk; \
done;
@echo "Testing idempotency of JSON dump/decode for RTCM2"
@$(srcdir)/gpsdecode -e -j <test/synthetic-rtcm2.json >/tmp/test-$$$$.chk; \
grep -v '^#' test/synthetic-rtcm2.json | diff -ub - /tmp/test-$$$$.chk; \
rm /tmp/test-$$$$.chk

# Rebuild the RTCM regression tests.
rtcm-makeregress: gpsdecode
@for f in $(srcdir)/test/*.rtcm2; do \
$(srcdir)/gpsdecode -j < $${f} > $${f}.chk; \
done

# Regression-test the AIVDM decoder.
aivdm-regress: gpsdecode
echo "Testing AIVDM decoding..."
@mkdir -p $(srcdir)/test
@for f in $(srcdir)/test/*.aivdm; do \
echo "Testing $${f}..."; \
$(srcdir)/gpsdecode -u -c <$${f} >/tmp/test-$$$$.chk; \
diff -ub $${f}.chk /tmp/test-$$$$.chk; \
done;
@echo "Testing idempotency of JSON dump/decode for AIS"
@$(srcdir)/gpsdecode -e -j <$(srcdir)/test/synthetic-ais.json >/tmp/test-$$$$.chk; \
grep -v '^#' $(srcdir)/test/synthetic-ais.json | diff -ub - /tmp/test-$$$$.chk; \
rm /tmp/test-$$$$.chk

# Rebuild the AIVDM regression tests.
aivdm-makeregress: gpsdecode
@for f in $(srcdir)/test/*.aivdm; do \
$(srcdir)/gpsdecode -u -c <$${f} > $${f}.chk; \
done

# Regression-test the packet getter.
packet-regress: test_packet
@echo "Testing detection of invalid packets..."
@$(srcdir)/test_packet | diff -u $(srcdir)/test/packet.test.chk -

# Rebuild the packet-getter regression test
packet-makeregress: test_packet
@mkdir -p $(srcdir)/test
$(srcdir)/test_packet >$(srcdir)/test/packet.test.chk

# Regression-test the geoid tester.
geoid-regress: test_geoid
@echo "Testing the geoid model..."
@$(srcdir)/test_geoid 37.371192 122.014965 | diff -u $(srcdir)/test/geoid.test.chk -

# Rebuild the packet-getter regression test
geoid-makeregress: test_geoid
@mkdir -p $(srcdir)/test
$(srcdir)/test_geoid 37.371192 122.014965 >$(srcdir)/test/geoid.test.chk

# Regression-test the calendar functions
time-regress: test_mkgmtime
$(srcdir)/test_mkgmtime

# Regression test the unpacking code in libgps
unpack-regress: libgps
@echo "Testing the client-library sentence decoder..."
$(run_regress_driver) -c $(srcdir)/test/clientlib/*.log

# Build the regression test for the sentence unpacker
unpack-makeregress: libgps
@echo "Rebuilding the client sentence-unpacker tests..."
$(run_regress_driver) -c -b $(srcdir)/test/clientlib/*.log

# Unit-test the JSON parsing
json-regress: test_json
$(srcdir)/test_json

# Unit-test the bitfield extractor - not in normal tests
bits-regress: test_bits
$(srcdir)/test_bits

# Do all normal regression tests.
testregress: gps-regress rtcm-regress aivdm-regress packet-regress time-regress unpack-regress json-regress
@echo "Regressions complete."

# do-tests is a shell script that invokes make with target testregress.
# This works around automake's lack of support for make targets as tests.
TESTS_ENVIRONMENT = MAKE=$(MAKE) PYTHON=$(PYTHON)
TESTS = do-tests

# The website directory
#
# None of these productions are fired by 'make all'.

if XMLTOSTDOUT
www/%.html: %.xml
$(XMLPROC) $(XMLPROCFLAGS) $(HTMLTARGET) $< >$(<:.xml=.html) ; cp $(<:.xml=.html) $@
else
www/%.html: %.xml
$(XMLPROC) $(XMLPROCFLAGS) $(HTMLTARGET) $<; cp $(<:.xml=.html) $@
endif

website: www/gpscat.html www/gpsctl.html www/gpsdecode.html \
www/gpsd.html www/gpsfake.html www/gpsmon.html \
www/gpspipe.html www/gpsprof.html www/gps.html \
www/libgpsd.html www/libgpsmm.html www/libgps.html \
www/rtcm-104.html www/srec.html \
www/AIVDM.html www/NMEA.html \
www/protocol-evolution.html www/protocol-transition.html \
www/client-howto.html www/writing-a-driver.html \
www/index.html www/hardware.html \
www/performance/performance.html \
www/internals.html

www/AIVDM.html: www/AIVDM.txt
asciidoc -a toc -o www/AIVDM.html www/AIVDM.txt

www/NMEA.html: www/NMEA.txt
asciidoc -a toc -o www/NMEA.html www/NMEA.txt

www/protocol-evolution.html: www/protocol-evolution.txt
asciidoc -a toc -o www/protocol-evolution.html www/protocol-evolution.txt

www/protocol-transition.html: www/protocol-transition.txt
asciidoc -a toc -o www/protocol-transition.html www/protocol-transition.txt

www/client-howto.html: www/client-howto.txt
asciidoc -a toc -o www/client-howto.html www/client-howto.txt

www/writing-a-driver.html: www/writing-a-driver.xml
xmlto xhtml-nochunks www/writing-a-driver.xml; mv writing-a-driver.html www

www/index.html: www/index.html.in
sed -e "/@DATE@/s//`date '+%B %d, %Y'`/" <www/index.html.in >www/index.html

www/hardware.html: www/hardware-head.html gpscap.ini www/hardware-tail.html
(cat www/hardware-head.html; python gpscap.py; cat www/hardware-tail.html) >www/hardware.html

www/performance/performance.html: www/performance/performance.xml
(cd www/performance; xmlto xhtml-nochunks performance.xml)

www/internals.html: $(shell ls doc/*.xml)
cd doc; xmlto xhtml-nochunks explanation.xml; cp explanation.html ../www/internals.html

if HAVE_PYTHON
# Experimenting with pydoc. Not yet fired by any other productions.

pydoc: www/pydoc/index.html

# We need to run epydoc with the Python version we built the modules for.
# So we define our on epydoc instead of using /usr/bin/epydoc
EPYDOC = $(PYTHON) -c 'from epydoc.cli import cli; cli()'

# We have pre-compiled python scripts in the script directory, so we exclude
# all files ending on c here. Needs a better solution as soon as we have a
# script ending with c.
EPYDOCSCRIPTS = $(shell find $(PYTHON_DISTUTILS_SCRIPTDIR) -name '*c' -o -type f -print)
EPYDOCMODULES = $(PYTHON_DISTUTILS_LIBDIR)/gps

www/pydoc/index.html: gps gpsfake gpscat gpsprof stamp-python
mkdir -p www/pydoc
$(EPYDOC) -v --html --graph all -n GPSD $(EPYDOCSCRIPTS) $(EPYDOCMODULES) -o www/pydoc

endif

# Productions for setting up and performing udev tests.
#
# Requires root. Do "udev-install", then "tail -f /var/run/syslog" in
# another window, then run 'make udev-test', then plug and unplug the
# GPS ad libitum. All is well when you get fix reports each time a GPS
# is plugged in.

udev-install:
cp $(srcdir)/gpsd.rules /lib/udev/rules.d/025_gpsd.rules
cp $(srcdir)/gpsd.hotplug $(srcdir)/gpsd.hotplug.wrapper /lib/udev/
chmod a+x /lib/udev/gpsd.hotplug /lib/udev/gpsd.hotplug.wrapper

udev-uninstall:
rm -f /lib/udev/{gpsd.hotplug,gpsd.hotplug.wrapper}
rm -f /lib/udev/rules.d/025_gpsd.rules

udev-test:
$(srcdir)/gpsd -N -F /var/run/gpsd.sock -D 4

# Release machinery begins here
#

# Make RPM from the specfile in packaging
dist-rpm: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
rpmbuild -ta $(distdir).tar.gz
$(am__remove_distdir)

# This is how to ship a release to Berlios incoming.
# It requires developer access verified via ssh.
#
upload-ftp: dist
shasum gpsd-$(VERSION).tar.gz >gpsd.sum
lftp -c "open ftp://ftp.berlios.de/incoming; mput gpsd-$(VERSION).tar.gz gpsd.sum"

#
# This is how to tag a release.
# It requires developer access verified via ssh.
#
release-tag:
git tag -s -m "Tagged for external release $(VERSION)" release-$(VERSION)
git push --tags

#
# Ship a release, providing all regression tests pass.
# The clean is necessary so that dist will remake revision.h
# with the current revision level in it.
#
ship: testregress clean dist upload-ftp release-tag


.PHONY: print_libgps_VERSION_CURRENT \
print_libgps_VERSION__REVISION \
print_libgps_VERSION_AGE \
print_libgps_SONAME \
print_libgps_VERSION \
pydoc

+ 0
- 2398
Makefile.in
File diff suppressed because it is too large
View File


+ 82
- 3
NEWS View File

@@ -1,3 +1,82 @@
* Wed 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
documentation.

* Wed Oct 25 2011 Eric S. Raymond <esr@snark.thyrsus.com> - 3.2
In the build recipe, (1) set pkgconfig properly for 64-bit Fedora
systems, (2) clean up various derived files including *.pyc on scons
-c, (3) add an option to disable stripping of binaries (strip=no),
(4) for embedded targets, add an option to disable building Python
support (python=no), (5) make the help for gpsd_group and gpsd_user
a little clearer, (6) add a force_global option to build gpsd to
listen to all addresses (rather than just loopback). The packet
sniffer now accepts NMEA packets with the ECDIS packet leader 'EC'.
SBAS satellites are now properly use-flagged in SiRF and UBX
skyviews. The -G option now works under IPv6. Cross-build is now
officially supported and instructions included. gpsprof works again
and does whole-cycle profiling. gpsd.php has Open Street Map
support. The pp-on-cts option is replaced by a pps_pin option that
lets you specify the pin; the default is still DCD. New supported
device; the Jackson Labs Fury. The chrpath utility has become a
build prerequisite.

* Sun Aug 28 2011 Eric S. Raymond <esr@snark.thyrsus.com> - 3.1
The Irene release, rocking you like a hurricane and brought to you
from the storm shelter in my basement. This is a snap release mainly
to get some scons recipe cleanups out the door. Parallelized builds
now work. Small but fatal problems with reconfigure=no, netfeed=no
and sock_export=no builds have been fixed. Build recipe ported for
Fedora, Darwin, FreeBSD and OpenBSD. libgps now brings -lm with it
on systems with implicit linking. One old bug fixed (code was
previously present but broken): Under Linux, gpsd will refrain from
opening serial or USB devices that another process has open,
avoiding potential problems with class 0xFF USB devices opened by
other programs. One new bug fix: we now use an atof()
implementation that ignores locale, avoiding problems where decimal
point is a comma. One new feature: Change -N semantics so it only
suppresses backgrounding; privileges are now dropped as in normal
background operation.

* Fri Aug 19 2011 Eric S. Raymond <esr@snark.thyrsus.com> - 3.0
POLL subobject name changes: fixes -> tpv, skyview -> sky.
Fix a timestamp-clobbering bug in the C library revealed by an
obscure car-nav device, the MyGuide 3100. The DEVICE 'activated'
attribute becomes an ISO8601 string; the client libraries will
still backward-compatibly read a float value. gps_unpack() is
now a documented part of the library API. There is now a
shared-memory export from the daemon that can be accessed through
the C and C++ client libraries. xgps and cgps may now display
the Maidenhead grid locator for current lat/lon. xgps displays
GST noise statistics if they are available. Codebase now has
an scons build recipe. Direct support for activation of gpsd from
Mac OS/X systemd. gpsdecode can now filter reports by RTCM2, RTCM3,
or AIS message type. NMEA HEHDT is implemented. Remote gpsd instances
can now be used as data sources via a gpsd:// URL. There is a client
for live-feeding GPSD data to Google Earth. The hotplug sequence no
longer requires Python.

* Mon Mar 21 2011 Eric S. Raymond <esr@snark.thyrsus.com> - 2.96
Bumped maximum channel count to 32 to accommodate GPS+GLONASS devices.
API version bumped to 5, redesign finished (changes are documented
in the Client HOWTO). cgps now handles resize signals. Code can now
link with uClibc for embedded use. Various bugs in the C++ binding
have been fixed. gpxlogger can now daemonize and write to a specified
log file. A gpsd client can now set any locale it likes, and JSON
will still be parsed using the C locale matching the daemon's. Clients
are no longer required to define a gpsd_report() hook. gpsd no longer
emits probe strings to unidentified USB devices at startup.
JSON timestamps in TPV and SKY are now ISO8601 rather than seconds since
the Unix epoch; the library handles the older style backward-compatibly.
GPGST sentences are now parsed for noise statistics when a device emits them.
AIS and RTCM2 JSON dumps have device fields. JSON reports now include 50bps
subframe data if the device allows access to it. gpsdecode can now dump NMEA
GPS binary, and subframe data to JSON. The RTCM2 code now understands and
analyzes RTCM2.3 messages 13, 14, and 31, and has been checked against another
analyzer. The ancient Sager dump format for RTCM2 is abolished in favor of
a JSON profile.

* Tue Jul 13 2010 Eric S. Raymond <esr@snark.thyrsus.com> - 2.95
The autonomous robot submarine total world domination release!
Rationalize clearing and generation of DOPs, this makes epx/epy much
@@ -16,7 +95,7 @@
libraries. We now ship a Qt binding for the client library. Note
a GCC 4.2.1 optimizer bug. gpsdcode now uses | as a field separator
in -c mode, as string fields can contain commas. Corrected error
or reporting of AIS rate-of-turn fields.
in reporting of AIS rate-of-turn fields.

* Tue Apr 20 2010 Eric S. Raymond <esr@snark.thyrsus.com> - 2.94
Error-checking in the 50bps subframe code has been greatly improved.
@@ -116,7 +195,7 @@
and returns, 'rtcm104v2' rather than 'rtcm104'; this is design forward
for when RTCM104v3 is fully working.

* Sun Feb 17 2008 Chris Kuethe <ckuethe@mail.berlios.de> - 2.37
* Sun Feb 17 2008 Chris Kuethe <ckuethe@mainframe.cx> - 2.37
The C++ bindings, Garmin USB support, and multiple instances of ntp
pps thread starting were fixed. Handling of odd PPS signals was
improved. The eye candy in the PHP visualizers was fixed.
@@ -194,7 +273,7 @@

* Wed Jul 6 2005 Eric S. Raymond <esr@snark.thyrsus.com> - 2.28-1
The 2.27 source tarball somehow got truncated on upload.
Due to procedural mechanics at berlios.de, shipping a new release
Due to procedural mechanics at Berlios, shipping a new release
seems to be the least painful way to recover. This release is
identical to 2.27 except the roadmap stuff has been added to TODO.



+ 36
- 30
README View File

@@ -1,14 +1,8 @@
COPYRIGHT
=========

This software (gpsd) released under the terms and conditions of the BSD
License, a copy of which is included in the file COPYING.

GENERAL
=======

gpsd is a userland daemon acting as a translator between GPS or
Loran-C receivers and clients. gpsd listens on port 2947 for clients
gpsd is a userland daemon acting as a translator between GPS and
AIS receivers and their clients. gpsd listens on port 2947 for clients
requesting position/time/velocity information. The receivers are
expected to generate position information in a well-known format -- as
NMEA-0183 sentences, SiRF binary, Rockwell binary, Garmin binary
@@ -17,12 +11,14 @@ information from the GPS and translates it into something uniform and
easier to understand for clients. The distribution includes sample
clients, application interface libraries, and test/profiling tools.

There is a project site for gpsd at <http://gpsd.berlios.de/>.
Look there for updates, news, and project mailing lists. See that
website for a list of GPS units known to be compatible.
There is a website for GPSD where you can find updates, news, and
project mailing lists; look for that URL in the scons recipe, the file
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.
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
@@ -31,6 +27,12 @@ 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.

LICENSE
=======

This software (gpsd) is released under the terms and conditions of the BSD
License, a copy of which is included in the file COPYING.

1.X CREDITS
===========

@@ -54,29 +56,25 @@ for the Earthmate.
Curt Mills <BowHunter@mail.com> (WE7U) furthered the dgps support,
writing the portion for other GPS receivers.

None of these people are active in 2.X, through Remco de-lurks on the
mailing list occasionally.
None of these people have been active in 2.X and later versions; gpsd
has evolved out of recognition from the 1.X codebase.

2.X CREDITS
===========

Eric S. Raymond drastically rewrote this code to clean it up and extend it.
The 2.X architecture has become significantly different and far more
modularized. His new features include:
Eric S. Raymond drastically rewrote this code in late 2004/early 2005
to clean it up and extend it. The 2.X architecture has become
significantly different and far more modularized. His new features
included:

* Documentation (what a concept!)
* Cleaned up, simplified command-line options.
* Now understands the GLL (Geographic position - Latitude, Longitude)
sentence from NMEA 3.0.
* Now parses both the NMEA 3.01 and pre-3.01 variants of the VTG sentence
correctly.
* New 'y' command supports satellite location -- it should no longer ever
be necessary for clients to go to raw mode unless they want to monitor and
and log the NMEA stream itself.
* New 'w' command toggles 'watcher' mode. In watcher mode gpsd ships
a gpsd-style response for each incoming sentence as if the client
had just sent all commands that asked for data contained in the sentence.
* New 'x' command allows the client to query whether or not the GPS
is on-line.
* New commands including 'y', 'w', and 'x', since obsolesced by a
JSON-based protocol.
* Massive refactoring -- one main loop now calls a self-contained
driver object for each type.
* The GPS-bashing code the daemon uses can now be directly linked as a
@@ -94,17 +92,18 @@ modularized. His new features include:
* Autobauding, self-configuration, and hotplugging. gpsd can now get
its device from a hotplug script, and figures out itself which baud
rate to use and what the GPS's device type is.
* More new commands: 'I', 'U', 'E', 'B', 'Z'. See the docs.
* Support for SiRF binary mode.
* Support for RTCM104 and AIVDM.
* Support for multiple devices.
* Other test tools -- gpsfake, gpscat.
* Other test tools -- gpsfake, gpscat, gpsmon.

Chris Kuethe <ckuethe@mail.berlios.de> maintains the OpenBSD port, shipped
Chris Kuethe <ckuethe@mainframe.cx> maintains the OpenBSD port, shipped
the 2.34 release, is our SiRF and low-level protocols expert, and does a
lot of general hacking and support.
lot of general hacking and support. He has release authority.

Gary Miller <gem@rellim.com> wrote the driver for Garmin binary protocol.
Gary Miller <gem@rellim.com> wrote the driver for Garmin binary protocol
and most of the support for PPS handling on serial devices. He has release
authority.

Amaury Jacquot <sxpert@esitcom.org> added DBUS support.

@@ -118,3 +117,10 @@ light on murky aspects of the chip's behavior.
We are also delighted to acknowlege the assistance of Timo Ylhainen, VP of
Software Operations at Fastrax. He clarified a number of points about
the iTalk protocol, helping to further development of iTalk support.

3.X CREDITS
===========

The main feature of the 3.x versions is a stabilized and finalized
version of the JSON command/response protocol. This was designed and mainly
implemented by ESR. Gary Miller wrote the subframe support.

+ 1567
- 0
SConstruct
File diff suppressed because it is too large
View File


+ 59
- 111
TODO View File

@@ -3,25 +3,46 @@ doing Ctl-C Ctl-t and browsing through the outline headers. Ctl-C Ctl-a
will unfold them again.

For contribution guidelines and internals documentation, please see
<http://gpsd.berlios.de/hacking.html>.
the "Hacking Guide" on the project website.

The list of bugs exposed by gpsd in other software has moved to
<http://gpsd.berlios.de/upstream-bugs.html>.
the "Upstream Bugs" page on the project website.

** Bugs in gpsd and its clients:

*** Tracker bugs

See the GPSD bug tracker at https://developer.berlios.de/bugs/?group_id=2116
but don't be surprised if it's empty or very sparse. Our rate of new defects
per month is quite low.
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.

** Dispatcher/network issues

**** Reading AISHub data via UDP confuses xgps with short writes

To reproduce, "gpsd -D 5 -N -n udp://192.168.1.3:12346" (only
works inside thyrsus.com) and run xgps. Probably some kind of
packet aggregation issue.

*** Driver issues

**** gpsctl -b should work on UBX, but does not.

Presently this means there's no way to kick a UBX into returning
binary data.
binary data. Chris Kuethe is supposed to fix this one.

**** RTCM3 analysis is incomplete

We can presently decode RTCM3 messages of type 1004, 1005, 1006, 1008, 1012,
1013, and 1029. This is not the complete set. We need more test data with
different types in them, and a copy of the RTCM3 standard at latest revision
(all we have is revision 3).

**** Reporting code for specialized Type 6 and 8 AIS messages is incomplete.

This one is mine and Kurt Schwehr's. Support is currently nearly
complete; the only missing cases are a handful of IMO 236 and IMO 289
message 6 and 8 subtypes.

** Ports

@@ -31,11 +52,11 @@ Partially complete. David Ludlow <dave@adsllc.com> is working on it.

** To do:

*** Bump MAXCHANNELS to support GPS/GLONASS devices
*** Make subframe reports available in the C API.

This will require a major soname bump. Probably goes with the API
changes on the Future page. Here's a test log for a GPS/GLONASS device,
the Geostar Geos 1M: <http://old.nabble.com/new-gps-report-to29115582.html>.
gpsd now reports subframes when they're available, but the C client
library doesn't yet parse them. A sample program to dump the SUBFRAME
data would also be useful. Gary Miller has this in his queue.

*** Write advanced features for TNT Revolution device

@@ -48,6 +69,11 @@ for possibilities.
Jon Schlueter has one of these on a flock machine, so testing
shouldn't be difficult.

*** Enable flocktest on the Debian server farm

Debian server farm boxes have a screwy chrooted envoronment setup.
flocktest needs to be modified to deal with it.

*** Finish gpssim

It's blocked on skyview computation.
@@ -78,7 +104,7 @@ there should be a (privileged) command to redirect RTCM connections.
*** Per-driver restore of changed config settings on exit.

This is a solved problem for generic NMEA, EverMore, TripMate,
EarthMate, TNTC, Zodiac, and RTCM104 drivers (if only because they
EarthMate, TNT, Zodiac, and RTCM104 drivers (if only because they
don't configure any device settings).

The SiRF driver now restores NMEA when necessary. It also restores
@@ -104,119 +130,41 @@ checking to see if it's already on, and stops navigation methods on
wrapup. It also forces the set of sentences issued. There doesn't
seem to be any way to query these settings.

** Future features (?)

*** Industry-standard format dumping of raw satellite data

It would be useful to be able to extract RINEX (or some other standard)
format data from any GPS device that can report pseudoranges etc. This
belongs in the daemon because the device drivers are already doing the
packet-cracking needed to get the data off the chips.
It would be useful to be able to report raw GPS data (pseudoranges,
clock, doppler carrier) from any GPS device that can report
pseudoranges etc. This belongs in the daemon because the device
drivers are already doing the packet-cracking needed to get the data
off the chips.

Several commodity chipsets (ANTARIS, iTrax3, SiRF and Trimble) readily
output enough data to make this a chore, rather than a hard problem.
Probably the best way to do this would be to add support for unscaled
output of pseudoranges in SKY and add clock and doppler carrier
phase. This JSON could then be interpreted by a client program and
dunmped in various standard formats.

It has been suggested one way to do this is to have a generic structure
in memory and corresponding output message with clock, doppler carrier
phase and pseudoranges. This message is then reformatted by a client
program. There are numerous formats for this information, and it would
be easier to adapt to new formats if the formatting and use was handled
by something other than the gpsd daemon. Currently the RT-IGS format is
looking like the favorite for implementation; it's a fairly lightweight
protocol, flexible enough to handle all the quantities required, and it
is actually in use in production reference networks. RT-IGS is also a
packet-oriented format, rather than a file-oriented format like RINEX.

*** RTCM3 support.

Previous plans for more RTCM2 support seem to have been overtaken by
events, e.g. the world moving to RTCM3. We have support for analyzing
RTCM3 messages, but it's entirely theoretical - written from the
standard. We need to find a pair of files consisting of a
representative set of RTCM3 sentences and some sort of ASCII dump of
them so we can test whether our analyzer gets all the bitfield
boundaries right.
Currently the RT-IGS format is looking like the favorite for
implementation; it's a fairly lightweight protocol, flexible enough to
handle all the quantities required, and it is actually in use in
production reference networks. RT-IGS is also a packet-oriented
format, rather than a file-oriented format like RINEX.

** Future features (?)
*** NOFLOAT build

We want to be able to build a minimalist version that doesn't require
floating-point arithmetic, for deployment on low-power ARM devices
without FPU.

*** Support for more survey / professional / up-scale receivers.

Devices such as the Javad JNSCore, Hemisphere Crescent, Septentrio
AsteRx and PolaRx, NovAtel Superstar2 and OEMV, Thales (Magellan
Professional) AC12 and DG14 would all be welcome. Of course, these
are not $50 usb mice...

*** Audio cues in the client when the fix status changes

Calum writes:
>Is it possible to add functionality (with a switch to enable it to
>avoid annoying those that don't want it) so that beeps indicate NO
>FIX, FIX, and OFFLINE status changes?
>
>For example - I run cgps and my laptop battery doesn't always supply
>my PS2 port-powered GPS device with enough power, and it goes into
>OFFLINE mode. As I can't drive, and check my laptop all the time, if
>it emitted 5 1 second beeps when it went OFFLINE, it would be a handy alert.
>
>Similarly, a PCMCIA "eject" 2 beeps for NO FIX, and a PCMCIA "happy" 2
>beeps when it gets a fix again?
>
>Or something like that.

This is a good idea for supporting hands-free operation, e.g. while driving.

It would be an easy first project for somebody who wants to get into
the client code.

*** Set the system time zone from latitude/longitude

If we're going to give gpsd the capability to set system time via
ntpd, why not let it set timezone as well? A good thing for hackers
travelling with laptops!

The major issue here is that I have not yet found code, or a
database, that would allow mapping from lon/lat to timezone.
And the rules change from year to year.

Actually this should be built as a specialized client, as some
people won't want it.

From <http://www.linuxsa.org.au/tips/time.html>:

The timezone under Linux is set by a symbolic link from
/etc/localtime[1] to a file in the /usr/share/zoneinfo[2] directory
that corresponds with what timezone you are in. For example, since I'm
in South Australia, /etc/localtime is a symlink to
/usr/share/zoneinfo/Australia/South. To set this link, type:

ln -sf ../usr/share/zoneinfo/your/zone /etc/localtime

Replace your/zone with something like Australia/NSW or
Australia/Perth. Have a look in the directories under
/usr/share/zoneinfo to see what timezones are available.

[1] This assumes that /usr/share/zoneinfo is linked to /etc/localtime as it is under Red Hat Linux.

[2] On older systems, you'll find that /usr/lib/zoneinfo is used
instead of /usr/share/zoneinfo.

Changing the hardlink will, of course, update the system timezone for
all users. If I were designing this feature, I'd ensure that the
system timezone can be overridden by a user-set TZ, but I don't know
if it actually works that way.

If I'm reading the tea leaves correctly, this functionality is actually
embedded in the GCC library version of tzset(), so the same method will
work on any system that uses that.

Problem: system daemons use the timezone set when they start up. You
can't get them to grok a new one short of rebooting.

Sources:

Sources for Time Zone and Daylight Saving Time Data
http://www.twinsun.com/tz/tz-link.htm

Free time-zone maps of the U.S.
http://www.manifold.net/download/freemaps.html
are not $50 USB mice...

Local variables:
mode: outline


+ 595
- 0
Tachometer.c View File

@@ -0,0 +1,595 @@
/*
* Tachometer Widget Implementation
*
* Author: Kazuhiko Shutoh, 1989.
* Revised by Shinji Sumimoto, 1989/9 (xtachos)
* Modifications : ilham@mit.edu (July 10 '90)
* Cleaned up and simplified by Eric S. Raymond, December 2004.
*
* This file is Copyright (c) 2010 by the GPSD project
* BSD terms apply: see the file COPYING in the distribution root for details.
*/
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <TachometerP.h>
#include <math.h>

#include "gpsd_config.h"
#include "gps.h"

#define D2R 0.0174532925199432957692369076848861271 /* radians = pi/180 */

/****************************************************************
*
* Full class record constant
*
****************************************************************/

typedef struct
{
unsigned char digit[7];
} DigitRec;

typedef struct
{
int nofline;
XPoint point_list[5];
} StringRec;

/*@ +charint @*/
/* Number character database - like an LED */
static DigitRec num_segment[] = {
{{1, 1, 1, 1, 1, 1, 0}},
{{0, 1, 1, 0, 0, 0, 0}},
{{1, 1, 0, 1, 1, 0, 1}},
{{1, 1, 1, 1, 0, 0, 1}},
{{0, 1, 1, 0, 0, 1, 1}},
{{1, 0, 1, 1, 0, 1, 1}},
{{1, 0, 1, 1, 1, 1, 1}},
{{1, 1, 1, 0, 0, 0, 0}},
{{1, 1, 1, 1, 1, 1, 1}},
{{1, 1, 1, 1, 0, 1, 1}}
};

static XSegment offset[] = {
{-10, -10, 10, -10},
{10, -10, 10, 0},
{10, 0, 10, 10},
{10, 10, -10, 10},
{-10, 10, -10, 0},
{-10, 0, -10, -10},
{-10, 0, 10, 0}
};

/*@ -initallelements @*/
/* " X 10 %" character database */
static StringRec char_data[] = {
{2, /* "X" */
{{-17, -5},
{-7, 5}}},
{2,
{{-7, -5},
{-17, 5}}},
{2, /* "1" */
{{-2, -5},
{-2, 5}}},
{5, /* "0" */
{{2, -5},
{12, -5},
{12, 5},
{2, 5},
{2, -5}}}
};

/*@ -initallelements @*/
/*@ -charint @*/

/*@ -nullderef -immediatetrans -type -nullassign @*/
#define offst(field) XtOffset(TachometerWidget, field)
static XtResource resources[] = {
{XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
offst(tachometer.scale), XtRString, "XtDefaultForeground"}
,
{XtNtachometerCircleColor, XtCBorderColor, XtRPixel, sizeof(Pixel),
offst(tachometer.circle), XtRString, "XtDefaultForeground"}
,
{XtNtachometerNeedleColor, XtCBorderColor, XtRPixel, sizeof(Pixel),
offst(tachometer.needle), XtRString, "XtDefaultForeground"}
,
{XtNtachometerNeedleSpeed, XtCtachometerNeedleSpeed, XtRInt,
sizeof(int), offst(tachometer.speed), XtRImmediate, (caddr_t) 1},
{XtNvalue, XtCValue, XtRInt, sizeof(int),
offst(tachometer.value), XtRImmediate, (caddr_t) 0},
{XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
offst(core.height), XtRImmediate, (caddr_t) 100}
,
{XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
offst(core.width), XtRImmediate, (caddr_t) 100}
,
{XtNborderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),
offst(core.border_width), XtRImmediate, (caddr_t) 0}
,
{XtNinternalBorderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),
offst(tachometer.internal_border), XtRImmediate, (caddr_t) 0}
,
};

/*@ -nullderef -immediatetrans +type +nullassign @*/

static void Initialize(Widget request, Widget new),
Realize(Widget w, Mask * valueMask, XSetWindowAttributes * attributes),
Resize(Widget w), Redisplay(Widget w, XEvent * event, Region region),
Destroy(Widget w);
static Boolean SetValues(Widget current, Widget request UNUSED, Widget new);

/*@ -fullinitblock @*/
TachometerClassRec tachometerClassRec = {
{
/* core_class fields */
#define superclass (&simpleClassRec)
/* superclass */ (WidgetClass) superclass,
/* class_name */ "Tachometer",
/* widget_size */ sizeof(TachometerRec),
/* class_initialize */ NULL,
/* class_part_initialize */ NULL,
/* class_inited */ FALSE,
/* initialize */ (XtInitProc) Initialize,
/* initialize_hook */ NULL,
/* realize */ Realize,
/* actions */ NULL,
/* num_actions */ 0,
/* resources */ resources,
/* num_resources */ XtNumber(resources),
/* xrm_class */ NULLQUARK,
/* compress_motion */ TRUE,
/* compress_exposure */ TRUE,
/* compress_enterleave */ TRUE,
/* visible_interest */ FALSE,
/* destroy */ Destroy,
/* resize */ Resize,
/* expose */ Redisplay,
/* set_values */ (XtSetValuesFunc) SetValues,
/* set_values_hook */ NULL,
/* set_values_almost */ XtInheritSetValuesAlmost,
/* get_values_hook */ NULL,
/* accept_focus */ NULL,
/* version */ XtVersion,
/* callback_private */ NULL,
/* tm_table */ NULL,
/* query_geometry */ NULL,
/* display_accelerator */ XtInheritDisplayAccelerator,
/* extension */ NULL
}
,
/* Simple class fields initialization */
{
/* change_sensitive */ XtInheritChangeSensitive
}

};

/*@ +fullinitblock @*/
WidgetClass tachometerWidgetClass = (WidgetClass) & tachometerClassRec;

/* Private procedures */

static void FastFillCircle(Display * d, Drawable w, GC gc,
Cardinal center_x, Cardinal center_y,
Cardinal radius_x, Cardinal radius_y)
{
/*@ -compdef @*/
XPoint points[360];
Cardinal angle;

for (angle = 0; angle < 360; angle++) {
points[angle].x = (short)(sin((double)angle * D2R) *
(double)radius_x + (double)center_x);
points[angle].y = (short)(cos((double)angle * D2R) *
(double)radius_y + (double)center_y);
}
(void)XFillPolygon(d, w, gc, points, 360, Complex, CoordModeOrigin);
/*@ +compdef @*/
}

static void DrawSingleNumber(TachometerWidget w, int which, Cardinal x,
Cardinal y)
{
XSegment segments[7];
Cardinal nsegments, width, height, count;

width = (Cardinal) ((w->core.width / 2) - w->tachometer.internal_border);
height =
(Cardinal) ((w->core.height / 2) - w->tachometer.internal_border);
if ((width == 0) || (height == 0))
return;

/*@ +charint -compdef */
for (count = 0, nsegments = 0; count < 7; count++)
if (num_segment[which].digit[count] == 1) {
segments[nsegments].x1 = (short)
(x + ((double)offset[count].x1 * ((double)width / 200.0)));
segments[nsegments].y1 = (short)
(y + ((double)offset[count].y1 * ((double)height / 200.0)));
segments[nsegments].x2 = (short)
(x + ((double)offset[count].x2 * ((double)width / 200.0)));
segments[nsegments].y2 = (short)
(y + ((double)offset[count].y2 * ((double)height / 200.0)));
nsegments++;
}

(void)XDrawSegments(XtDisplay(w), XtWindow(w),
w->tachometer.scale_GC, segments, (int)nsegments);
/*@ -charint +compdef */
}

static void DrawNumbers(TachometerWidget w, int which, Cardinal x, Cardinal y)
{
if (which == 10) {
DrawSingleNumber(w, 1, (Cardinal) ((double)x * 0.9), y);
DrawSingleNumber(w, 0, x, y);
} else
DrawSingleNumber(w, which, x, y);
}