Browse Source

Imported Upstream version 3.15

master
Bernd Zeimetz 5 years ago
parent
commit
5a659e9e5a
100 changed files with 5622 additions and 4688 deletions
  1. +0
    -26
      .splintrc
  2. +1
    -1
      AUTHORS
  3. +1
    -1
      HACKING
  4. +209
    -9
      INSTALL
  5. +19
    -0
      NEWS
  6. +2
    -2
      Qgpsmm.pc.in
  7. +9
    -9
      README
  8. +309
    -341
      SConstruct
  9. +25
    -42
      TODO
  10. +2
    -36
      Tachometer.c
  11. +4
    -9
      ais_json.c
  12. +49
    -61
      ais_json.i
  13. +3
    -15
      bits.c
  14. +10
    -144
      bsd_base64.c
  15. +0
    -18
      bsd_base64.h
  16. +34
    -71
      build.txt
  17. +10
    -31
      cgps.c
  18. +47
    -0
      clock_gettime.c
  19. +68
    -1
      compiler.h
  20. +22
    -13
      contrib/README
  21. +3
    -2
      contrib/SConstruct
  22. +13
    -11
      contrib/motosend.c
  23. +164
    -0
      contrib/ntpshmviz
  24. +8
    -5
      contrib/ppscheck.c
  25. +78
    -10
      contrib/skyview.php
  26. +1
    -1
      contrib/webgps.py
  27. +3
    -3
      control.in
  28. +0
    -6
      daemon.c
  29. +2
    -2
      dbusexport.c
  30. +5
    -0
      devtools/README
  31. +10
    -1
      devtools/identify_failing_build_options.py
  32. +0
    -0
      devtools/test_json_validity.py
  33. +0
    -23
      doc/explan_gpsd.c.xml
  34. +6
    -5
      doc/explan_gpsd_log.c.xml
  35. +24
    -1
      doc/explan_libgpsd_core.c.xml
  36. +1
    -1
      doc/explan_ntpshm.c.xml
  37. +2
    -2
      doc/internals.xml
  38. +44
    -58
      driver_ais.c
  39. +49
    -66
      driver_evermore.c
  40. +237
    -251
      driver_garmin.c
  41. +29
    -35
      driver_garmin_txt.c
  42. +124
    -141
      driver_geostar.c
  43. +63
    -68
      driver_italk.c
  44. +212
    -251
      driver_navcom.c
  45. +364
    -218
      driver_nmea0183.c
  46. +281
    -218
      driver_nmea2000.c
  47. +44
    -60
      driver_oncore.c
  48. +29
    -33
      driver_proto.c
  49. +1
    -15
      driver_rtcm2.c
  50. +3
    -7
      driver_rtcm3.c
  51. +224
    -249
      driver_sirf.c
  52. +55
    -75
      driver_superstar2.c
  53. +152
    -188
      driver_tsip.c
  54. +237
    -143
      driver_ubx.c
  55. +1
    -0
      driver_ubx.h
  56. +36
    -44
      driver_zodiac.c
  57. +135
    -115
      drivers.c
  58. +0
    -4
      geoid.c
  59. +0
    -19
      getsid.c
  60. +1
    -1
      gps.1
  61. +62
    -45
      gps.h
  62. +27
    -27
      gps.xml
  63. +31
    -20
      gps/client.py
  64. +2
    -0
      gps/fake.py
  65. +4
    -0
      gps/gps.py
  66. +28
    -53
      gps2udp.c
  67. +20
    -20
      gps_json.h
  68. +3
    -2
      gps_maskdump.c
  69. +278
    -166
      gpscap.ini
  70. +11
    -11
      gpscap.py
  71. +3
    -3
      gpscat.xml
  72. +2
    -1
      gpsclient.c
  73. +156
    -185
      gpsctl.c
  74. +9
    -0
      gpsd.8
  75. +406
    -391
      gpsd.c
  76. +1
    -0
      gpsd.h-head
  77. +107
    -252
      gpsd.h-tail
  78. +2
    -2
      gpsd.hotplug
  79. +19
    -8
      gpsd.php
  80. +19
    -8
      gpsd.php.in
  81. +2
    -2
      gpsd.usermap
  82. +20
    -8
      gpsd.xml
  83. +318
    -0
      gpsd_config.h
  84. +168
    -36
      gpsd_json.5
  85. +44
    -63
      gpsd_json.c
  86. +156
    -33
      gpsd_json.xml
  87. +6
    -15
      gpsdclient.c
  88. +7
    -7
      gpsdclient.h
  89. +1
    -9
      gpsdctl.c
  90. +1
    -1
      gpsdctl.xml
  91. +1
    -9
      gpsdecode.c
  92. +5
    -5
      gpsdecode.xml
  93. +12
    -12
      gpsfake.xml
  94. +2
    -2
      gpsinit
  95. +2
    -2
      gpsinit.xml
  96. +10
    -1
      gpsmon.1
  97. +186
    -116
      gpsmon.c
  98. +6
    -0
      gpsmon.h
  99. +16
    -7
      gpsmon.xml
  100. +4
    -4
      gpspacket.c

+ 0
- 26
.splintrc View File

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

-Ddbus_uint32_t=uint
-Disgps30bits_t=uint
-DFD_SETSIZE=31
-DB57600=010001
-DB115200=0010011
-DCRTSCTS=0x00020000
-DONLCR=0x00000002
-D__gnuc_va_list=va_list
-D__signed__=signed
-D__pid_t=int
-D__size_t=size_t
-Dpps_handle_t=int


+ 1
- 1
AUTHORS View File

@@ -2,7 +2,7 @@ Remco Treffkorn <remco@rvt.com>
Derrick J. Brashear <shadow@dementia.org>
Russ Nelson <nelson@crynwyr.com>
Eric S. Raymond <esr@thyrsus.com>
Gary E. Miller <gem@rellim.com>
Gary E. Miller <gem@rellim.com>
Jeff Francis <jeff@gritch.org>
Amaury Jacquot <sxpert@esitcom.org>
Chris Kuethe <chris.kuethe@gmail.com>


+ 1
- 1
HACKING View File

@@ -3,7 +3,7 @@ this file is in the repository as:

www/hacking.html

If you only have www/hacking.html.in, run
If you only have www/hacking.html.in, run

scons www



+ 209
- 9
INSTALL View File

@@ -1,11 +1,20 @@
= GPSD Installation Instructions =
:title: GPSD Installation Instructions
:description: Here are the steps for installing GPSD and verifying its performance.
:keywords: GPSD, GPS, installation
:author: Eric S. Raymond <esr@thyrsus.com>
:robots:index,follow

Here are the steps for installing GPSD and verifying its performance.
They assume you have GPSD available as an installable binary package,
They assume you have GPSD available as an installable binary package,

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

Most of these installation instructions are generic to Linux (inc
There are some special notes on installation for OS X and the Raspberry Pi
near the end of this file.

== Check that your GPS is live and you can get data from it ==

Start by making sure you can get data from your GPS, otherwise the later
@@ -59,7 +68,7 @@ devices given to it on the command line by forcing their group read
and write permissions on.

On a Linux with udev, check the files in /etc/udev/permissions.d to
ensure that /dev/tty* devices are all created with the same group
ensure that /dev/tty* devices are all created with the same group
and with 0660 permissions.

When gpsd drops privileges, its default is to set uid to 'nobody' and
@@ -80,7 +89,7 @@ various additional features have additional prerequisites:

|==========================================================================
|pthreads library | support for PPS timekeeping on serial GPSes
|DBUS | gpsd will issue DBUS notifications
|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
@@ -96,7 +105,9 @@ 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.

== Install the package(s) ==
== Installing gpsd ==

=== Install your distributions package(s) ===

Up-to-date gpsd packages are generally available for Linux
distributions including Debian and derivatives (including Ubuntu and
@@ -112,9 +123,14 @@ 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.

=== Install from source code ===

Directions for installing from source are in the file build.txt found
in the source distribution.

== How to test the software ==

1. Start gpsd. You'll need to give it as an argument a path to
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:

@@ -139,12 +155,12 @@ lock.
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
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
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").

@@ -156,10 +172,194 @@ 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
package.) It should be manually copied to 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.

4. There are other non-essential scripts that may be useful; these
are in the contrib/ directory of the source. They may not be available
in the packages available from distributions.

For special instructions related to using GPSD for time service, see the
GPSD Time Service HOWTO in the distribution or on the web.

== Special Notes for OS X Installation ==

gpsd will build, install and run on OS X. The easiest way to do so is
to first install the MacPorts package. Follow their install procedure
at: http://www.macports.org/install.php

Then use their port command to install scons, and optionally git if you
want to access the develpment source.

--------------------------------------------------------------
# port install scons
# port install git
--------------------------------------------------------------

While runnning gpsd, or scons check, you may run out of shared memory
segments. If so, you will see this error message:

--------------------------------------------------------------
gpsd:ERROR: shmat failed: Too many open files
--------------------------------------------------------------

By default OS X allows a very small number of shared segments. You
can check your allowed maximum number of shared segments, then increase
the maximum number, with these commands:

--------------------------------------------------------------
# sysctl kern.sysv.shmseg=8
kern.sysv.shmseg: 32 -> 8
# sysctl -a | fgrep shmseg
kern.sysv.shmseg: 8
# sysctl kern.sysv.shmseg=16
kern.sysv.shmseg: 8 -> 16
# sysctl -a | fgrep shmseg
kern.sysv.shmseg: 16
--------------------------------------------------------------

If you are using a USB based GPS you will likely need the Prolific
PL2303 driver. You can find it here:
http://www.prolific.com.tw/US/ShowProduct.aspx?p_id=229&pcid=41

== Special Notes for Rasberry Pi Installation ==

gpsd will build, install and run on the Rasberry Pi (RasPi) and Pi 2
using Debian jessie. Other distributions based on
Debian (raspbian, etc) will work fine as well. The gpsd
package in Debian Wheezy is known to be flakey, be sure to update to a
new version of gpsd from source.

=== Raspbian ===
Before compiling gpsd from source, you will need to update your system
as root. Switching to the latest raspbian distribution (jessie)
is strongly recommended.

--------------------------------------------------------------
# apt-get update
# apt-get dist-upgrade
# rpi-update
# reboot
--------------------------------------------------------------

--------------------------------------------------------------
# apt-get install scons libncurses5-dev python-dev pps-tools
# apt-get install git-core
--------------------------------------------------------------

Git-core is only required to build from a git repository. pps-tools is for
testing PPS inputs.

The rest of the installation is just as for any other source based
install, as noted in the file *build.txt* .

=== Other Debian derivitives (including stock) ===
==== Jessie ====
--------------------------------------------------------------
# apt-get install scons libncurses5-dev python-dev pps-tools
# apt-get install git-core
--------------------------------------------------------------

Git-core is only required to build from a git repository. pps-tools is for
testing PPS inputs.

The rest of the installation is just as for any other source based
install, as noted in the file *build.txt* .


==== Wheezy ====
Wheezy, being older, requires updating the tools for compiling
and testing gpsd:

You need scons at 2.3.0 or higher to build.
If your scons is less than 2.3.0 you will need to get a newer scons
from wheezy-backport. Partial instructions are detailed here:
http://backports.debian.org/Instructions/

Basically you need to add this line to /etc/apt/sources.list:

--------------------------------------------------------------
deb http://http.debian.net/debian wheezy-backports main
--------------------------------------------------------------

Then do another update:

--------------------------------------------------------------
apt-get update
--------------------------------------------------------------

Which may lead you to this error if you lack a full set of debian keys:

--------------------------------------------------------------
W: GPG error: http://http.debian.net wheezy-backports Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 8B48AD6246925553
--------------------------------------------------------------

Partial but detailed instructions to fix that are here:

--------------------------------------------------------------
https://wiki.debian.org/SecureApt
--------------------------------------------------------------

Use either of the following code blocks. The first is more robust:

--------------------------------------------------------------
apt-get install debian-archive-keyring
--------------------------------------------------------------

--------------------------------------------------------------
gpg --keyserver pgpkeys.mit.edu --recv 8B48AD6246925553
gpg -a --export 46925553 | apt-key add -
apt-get update
--------------------------------------------------------------

You can now install scons from the wheezy-backports repository:

--------------------------------------------------------------
apt-get -t wheezy-backports install scons
--------------------------------------------------------------

and other tools:

--------------------------------------------------------------
# apt-get install scons libncurses5-dev python-dev pps-tools
# apt-get install git-core
--------------------------------------------------------------

Git-core is only required to build from a git repository. pps-tools is for
testing PPS inputs.

The rest of the installation is just as for any other source based
install, as noted in the file *build.txt* .

=== Other Raspberry Pi tips ===

Any USB connected GPS that is known to work with gpsd will work fine on
the RasPi. No special instructions apply.

A very popular option is to install the AdaFruit Ultimate GPS HAT. With
this GPS you also get a good 1PPS signal. This works as any other GPS
with gpsd, but there are two things to note. The GPS takes over the
serial console: /dev/ttyAMA0. The PPS signal will be on GPIO Pin #4.

Only two specific changes need to be made to make the HAT work. First
in the file /boot/cmdline.txt, remove this part "console=ttyAMA0,115200
kgdboc=ttyAMA0,115200)". That frees the serial port from console use so
the GPS can use it.

Second you need to tell the boot process to load the pps_gpio module
and attach /dev/pps0 to GPIO ping 4. Do that by adding this line
to the bottom of /boot/config.txt: dtoverlay=pps-gpio,gpiopin=4

Reboot and proceed as for any other operating system to use gpsd.

Warning, the pps_gpio driver in all linux kernels up to the current
3.19 only reports one edge. Be sure to validate that your PPS signal
is not offset by the pulse width.

Detailed instructions are available from their web site:
https://learn.adafruit.com/adafruit-ultimate-gps-hat-for-raspberry-pi/

You will need to dig deeper to make the PPS work, here is a good reference:
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html

+ 19
- 0
NEWS View File

@@ -1,5 +1,24 @@
GPSD project news

3.15: 2015-06-03 (Eric S. Raymond <esr@snark.thyrsus.com>)
Fix a rare crash bug related to devices becomin inaccessible while timed out.
Accept NMEA 4.1 GSV sententences with the trailing signal-ID field.
Fixed incorrect decode of south latitudes in AIS Type 17 messages.
splint has been retired; this removes almost 2KLOC of annotations.
chrpath is no longer a build dependency. Corrected Beidou/QZNSS display
in the Python clients so the graphics don't look like SBAS.

3.14: 2015-03-14 (Eric S. Raymond <esr@snark.thyrsus.com>)
The Pi Day release, 3.14 on 3/14 2015 at 9:26. Longer timeouts on test clients.
Skyview support for the Beidou and QZSS constellations in the NMEA0183 driver.
ntpmon rename to ntpshmmon - it doesn't actually monitor NTP itself.
New HOWTO on the website: "Introduction to Time Service".

3.13: 2015-02-26 (Eric S. Raymond <esr@snark.thyrsus.com>)
compiler.h inclusion removed for gps.h so it's standalone for /usr/include.
TOFF JSON report gives the offset between GPS top of second and clock time.
A new ntpmon tool supports capturing clock samples from NTP SHM segments.

3.12: 2015-02-22 (Eric S. Raymond <esr@snark.thyrsus.com>)
The daemon's power utilization has been reduced by changing from
non-blocking to blocking I/O; this may be significant on mobile devices.


+ 2
- 2
Qgpsmm.pc.in View File

@@ -7,7 +7,7 @@ qt_config=lex yacc warn_on uic resources qt release incremental link_prl def_fil
Name: Qgpsmm
Description: GPS Daemon communication library - QT binding
Version: @VERSION@
Libs: -L${libdir} -lQgpsmm
Libs.private: -L/usr/lib -lQtNetwork -lQtCore -lpthread
Libs: -L${libdir} -lQgpsmm
Libs.private: -L/usr/lib -lQtNetwork -lQtCore -lpthread
Cflags: -I${includedir}
Requires: QtNetwork

+ 9
- 9
README View File

@@ -45,7 +45,7 @@ into one package and autoconfiscated it.
Derrick J. Brashear <shadow@dementia.org> (KB3EGH) added code for the
EarthMate DeLorme. He also added "incredibly gross code to output
NMEA sentences" (his own words :-) He also did the first cut at
DGPS support (see http://www.wsrcc.com/wolfgang/gps/dgps-ip.html),
DGPS support (see http://www.wsrcc.com/wolfgang/gps/dgps-ip.html),
for the Earthmate.

Curt Mills <BowHunter@mail.com> (WE7U) furthered the dgps support,
@@ -65,27 +65,27 @@ 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
sentence from NMEA 3.0.
* Now parses both the NMEA 3.01 and pre-3.01 variants of the VTG sentence
correctly.
* 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
library, libgpsd(3).
library, libgpsd(3).
* C and Python libraries are available to encapsulate the client side of
querying gpsd, see libgps(3).
* Cleaned-up error reporting, we don't use syslog when running in foreground
but send all error and status messages to the tty instead.
* Added -n option to do batch monitoring of GPSes.
* xgpsspeed is working again; xgps has been seriously reworked and improved.
* RPMs which include installation of gpsd to start up at boot time
* RPMs which include installation of gpsd to start up at boot time
are available.
* New gpsprobe program probes the capabilities of GPSes and generates
error scattergrams from fixes. (Later this moved to gpsprof.)
* Autobauding, self-configuration, and hotplugging. gpsd can now get
its device from a hotplug script, and figures out itself which baud
its device from a hotplug script, and figures out itself which baud
rate to use and what the GPS's device type is.
* Support for SiRF binary mode.
* Support for RTCM104 and AIVDM.
@@ -93,7 +93,7 @@ included:
* Other test tools -- gpsfake, gpscat, gpsmon.

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
the 2.34 release, is our SiRF and low-level protocols expert, and does a
lot of general hacking and support. He has release authority.

Gary Miller <gem@rellim.com> wrote the driver for Garmin binary protocol
@@ -106,7 +106,7 @@ Ville Nuorvala <vnuorval@tcs.hut.fi> wrote the NTRIP support.

We are delighted to acknowlege the assistance of Carl Carter, a field
application engineer at SiRF. He assisted us with the correction and
tuning of the SiRF binary-protocol driver, shedding a good deal of
tuning of the SiRF binary-protocol driver, shedding a good deal of
light on murky aspects of the chip's behavior.

We are also delighted to acknowlege the assistance of Timo Ylhainen, VP of
@@ -116,6 +116,6 @@ 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
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.

+ 309
- 341
SConstruct
File diff suppressed because it is too large
View File


+ 25
- 42
TODO View File

@@ -1,5 +1,5 @@
This is the gpsd to-do list. If you're viewing it with Emacs, try
doing Ctl-C Ctl-t and browsing through the outline headers. Ctl-C Ctl-a
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
@@ -10,7 +10,7 @@ the "Upstream Bugs" page on the project website.

** Documentation **

We now have two different calibration procedures in the Tine Service
We now have two different calibration procedures in the Time Service
HOWTO. One was written by Gary and is based on peerstats; the other by
Sanjeev Gupta and is based on loopstats.

@@ -18,6 +18,16 @@ Can these be merged? How do we know which is appropriate to use when?
What could we build in the way of tools and visualization aids to make
the calibration process less annoying?

** Things to do when we can break compatibility **

In gps_data_t Make subtype longer. 128 chars long sounds good.

In gps_data_t, save PPS precision; this will require creating a pps struct.

In gps_fix_t, maybe change time away from float to timespec?

Add MMSI sequence number fields to type 7.

** Bugs in gpsd and its clients:

*** Tracker bugs
@@ -66,7 +76,7 @@ revision (all we have is revision 3).

The support for unpacking RTCM3 sentences in the client library is
limited to 1001, 1002, 1007, 1008, 1009, 1010, 1014, and 1033. There
are some design issues with the baby JSON parser that are going to
are some design issues with the baby JSON parser that are going to
make extending this set difficult.

**** Reporting code for specialized Type 6 and 8 AIS messages is incomplete.
@@ -86,15 +96,6 @@ Our goal is to be independent of the system clock.

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

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

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

*** Optionally use tag blocks in NMEA output

Ed W. writes:
@@ -131,37 +132,26 @@ However, Iván Sánchez Ortega notes:
>I, for one, would like to see the secs/msecs problem solved before GPSD
>embarks on the enterprise of writing TAGblocks.

*** Time offset debugging in gpsmon ***

Hall Murray:
> The gpsmon logging stuff should include time stamps.
>
> There should be some way for gpsmon to display the time offset that it would
> send to NTP via SHM. I don't see any obvious empty space on the screen. If
> nothing else, it could use the PPS space or alternate with the PPS info,
> perhaps via a keyboard command.
>
> Or perhaps a higher level keyboard command to switch into timekeeping
> debugging mode rather than position debugging mode.

Add PPS offset to each PPS bar.

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

Are not implemented. In theory they could be.
If someone is working on this, please see:
http://www.nmea.org/Assets/0183_errata_tag_block_final.pdf

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

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

**** Optional dump of GPS configuration using gpsctl.

Some setting, like antenna in use, dead-reckoning mode, would be
helpful to see.

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

We caw now *really* measure latency from GPS top of second when it has
1PPS. Add this capability to gpsprof and revise the "Where's the
Latency?" white paper.

*** Low-pwer autoconfiguration in the uBlox driver ***
*** Low-power autoconfiguration in the uBlox driver ***

Anthony Stirk <upuaut@gmail.com> writes on Wed May 21 06:09:00 2014:

@@ -195,9 +185,9 @@ The baud-rate switcher in the TNT driver needs to be tested.

gpsmon could support a number of TNT configuration commands, including
unit changes. See http://gpsd.googlecode.com/truenorth-reference.pdf
for possibilities.
for possibilities.

Jon Schlueter has one of these on a flock machine, so testing
Jon Schlueter has one of these on a flock machine, so testing
shouldn't be difficult.

*** Enable flocktest on the Debian server farm
@@ -225,13 +215,6 @@ These are used for the '?DEVICE' command. All work for 8N1.
SiRF, UBX, TSIP, and even Zodiac can support non-8N1 modes; these need
to be tested.

*** Command to ship RTCM corrections to a specified device

At the moment, if a GPS accepts RTCM corrections and they are
available, gpsd ships them to the serial device from which the GPS is
reporting fix data. Some GPSes have auxiliary ports for RTCM;
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,
@@ -243,7 +226,7 @@ some (but not all) of the things it tweaks in binary mode -- at the
moment, just the Navigation Parameters from message 0x13. With more
work, we should be able to do a full revert.

The TSIP driver changes its per-cycle sentence inventory and thus
The TSIP driver changes its per-cycle sentence inventory and thus
needs some state-restore logic. This can be done; the same packet 0x35
we use to configure it can be sent in a no-argument mode to query
the current sentence mix for later restore.
@@ -276,7 +259,7 @@ 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.
dumped in various standard formats.

Currently the RT-IGS format is looking like the favorite for
implementation; it's a fairly lightweight protocol, flexible enough to


+ 2
- 36
Tachometer.c View File

@@ -36,7 +36,6 @@ typedef struct
XPoint point_list[5];
} StringRec;

/*@ +charint @*/
/* Number character database - like an LED */
static DigitRec num_segment[] = {
{{1, 1, 1, 1, 1, 1, 0}},
@@ -61,7 +60,6 @@ static XSegment offset[] = {
{-10, 0, 10, 0}
};

/*@ -initallelements @*/
/* " X 10 %" character database */
static StringRec char_data[] = {
{2, /* "X" */
@@ -81,10 +79,7 @@ static StringRec char_data[] = {
{2, -5}}}
};

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

/*@ -nullderef -immediatetrans -type -nullassign @*/
#define offst(field) XtOffset(TachometerWidget, field)
static XtResource resources[] = {
{XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
@@ -114,7 +109,6 @@ static XtResource resources[] = {
,
};

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

static void Initialize(Widget request, Widget new),
Realize(Widget w, Mask * valueMask, XSetWindowAttributes * attributes),
@@ -122,7 +116,6 @@ 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 */
@@ -168,7 +161,6 @@ TachometerClassRec tachometerClassRec = {

};

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

/* Private procedures */
@@ -177,7 +169,6 @@ 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;

@@ -188,7 +179,6 @@ static void FastFillCircle(Display * d, Drawable w, GC gc,
(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,
@@ -203,7 +193,6 @@ static void DrawSingleNumber(TachometerWidget w, int which, Cardinal x,
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)
@@ -219,7 +208,6 @@ static void DrawSingleNumber(TachometerWidget w, int which, Cardinal x,

(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)
@@ -247,7 +235,6 @@ static void DrawLabelString(TachometerWidget w)

ry = (Cardinal) (radius_y * 0.35 + center_y);
gc = w->tachometer.scale_GC;
/*@ -compdef @*/
for (char_count = 0; char_count < 4; char_count++) {
for (data_count = 0; data_count < char_data[char_count].nofline;
data_count++) {
@@ -261,7 +248,6 @@ static void DrawLabelString(TachometerWidget w)
(void)XDrawLines(XtDisplay(w), XtWindow(w), gc, points,
char_data[char_count].nofline, CoordModeOrigin);
}
/*@ +compdef @*/
}

static void DrawGauge(TachometerWidget w)
@@ -272,7 +258,6 @@ static void DrawGauge(TachometerWidget w)
GC gc;
double step, jump = 1.0;

/*@ -type -unsignedcompare -compdef @*/
center_x = w->core.width / 2;
center_y = w->core.height / 2;
radius_x = center_x - w->tachometer.internal_border;
@@ -318,7 +303,6 @@ static void DrawGauge(TachometerWidget w)
in_gauge_y, out_gauge_x, out_gauge_y);
}
}
/*@ +type +unsignedcompare +compdef @*/

DrawLabelString(w);
}
@@ -329,7 +313,6 @@ static void DrawNeedle(TachometerWidget w, int load)
double cur_theta1, cur_theta2, cur_theta3, cur_theta4, cur_theta5;
Cardinal center_x, center_y, radius_x, radius_y;

/*@ -type -unsignedcompare -compdef @*/
center_x = w->core.width / 2;
center_y = w->core.height / 2;
radius_x = center_x - w->tachometer.internal_border;
@@ -354,21 +337,17 @@ static void DrawNeedle(TachometerWidget w, int load)
points[3].y = (short)(cos(cur_theta5) * radius_y * 0.1 + center_y);
points[4].x = (short)(sin(cur_theta3) * radius_x * 0.7 + center_x);
points[4].y = (short)(cos(cur_theta3) * radius_y * 0.7 + center_y);
/*@ -usedef @*/
points[5].x = points[0].x;
points[5].y = points[0].y;
/*@ +usedef @*/

(void)XDrawLines(XtDisplay(w), XtWindow(w),
w->tachometer.needle_GC, points, 6, CoordModeOrigin);
/*@ +type +unsignedcompare +compdef @*/
}

static void DrawTachometer(TachometerWidget w)
{
Cardinal center_x, center_y, radius_x, radius_y;

/*@ -type -unsignedcompare -compdef @*/
center_x = w->core.width / 2;
center_y = w->core.height / 2;
radius_x = center_x - w->tachometer.internal_border;
@@ -391,7 +370,6 @@ static void DrawTachometer(TachometerWidget w)
/* Draw the details */
DrawGauge(w);
DrawNeedle(w, w->tachometer.value);
/*@ +type +unsignedcompare +compdef @*/
}

static void MoveNeedle(TachometerWidget w, int new)
@@ -408,7 +386,6 @@ static void MoveNeedle(TachometerWidget w, int new)
else
step = (w->tachometer.speed ? -w->tachometer.speed : new - old);

/*@ -usedef @*/
if (old < new) {
for (loop = old; loop < new; loop += step)
DrawNeedle(w, loop);
@@ -423,7 +400,6 @@ static void MoveNeedle(TachometerWidget w, int new)

if (loop != new + step) /* The final needle wasn't printed */
DrawNeedle(w, new);
/*@ +usedef @*/

w->tachometer.value = new;
}
@@ -435,11 +411,9 @@ static void GetneedleGC(TachometerWidget ta)
values.background = ta->core.background_pixel;
values.foreground = ta->tachometer.needle ^ ta->core.background_pixel;
values.function = GXxor;
/*@ -type -compdef -mustfreeonly @*/
ta->tachometer.needle_GC = XtGetGC((Widget) ta,
(unsigned)GCFunction | GCBackground |
GCForeground, &values);
/*@ +type +compdef +mustfreeonly @*/
}

static void GetscaleGC(TachometerWidget ta)
@@ -448,11 +422,9 @@ static void GetscaleGC(TachometerWidget ta)

values.foreground = ta->tachometer.scale;
values.background = ta->core.background_pixel;
/*@ -type -compdef -mustfreeonly @*/
ta->tachometer.scale_GC = XtGetGC((Widget) ta,
(unsigned)GCForeground | GCBackground,
&values);
/*@ +type +compdef +mustfreeonly @*/
}

static void GetcircleGC(TachometerWidget ta)
@@ -461,11 +433,9 @@ static void GetcircleGC(TachometerWidget ta)

values.foreground = ta->tachometer.circle;
values.background = ta->core.background_pixel;
/*@ -type -compdef -mustfreeonly @*/
ta->tachometer.circle_GC = XtGetGC((Widget) ta,
(unsigned)GCForeground | GCBackground,
&values);
/*@ +type +compdef +mustfreeonly @*/
}

static void GetbackgroundGC(TachometerWidget ta)
@@ -474,11 +444,9 @@ static void GetbackgroundGC(TachometerWidget ta)

values.foreground = ta->core.background_pixel;
values.background = ta->core.background_pixel;
/*@ -type -compdef -mustfreeonly @*/
ta->tachometer.background_GC = XtGetGC((Widget) ta,
(unsigned)GCForeground |
GCBackground, &values);
/*@ +type +compdef +mustfreeonly @*/
}

static void Initialize(Widget request UNUSED, Widget new)
@@ -531,7 +499,6 @@ static void Resize(Widget w)
static Boolean SetValues(Widget current, Widget request UNUSED, Widget new)
/* Set specified arguments into widget */
{
/*@ -type -boolops -predboolothers @*/
Boolean back, changed = (Boolean) False;

TachometerWidget curta = (TachometerWidget) current;
@@ -562,7 +529,6 @@ static Boolean SetValues(Widget current, Widget request UNUSED, Widget new)
MoveNeedle(newta, newta->tachometer.value);
changed = True;
}
/*@ +type +boolops +predboolothers @*/

return (changed);
}
@@ -579,13 +545,13 @@ static void Destroy(Widget w)

/* Exported Procedures */

// cppcheck-suppress unusedFunction
// cppcheck-suppress unusedFunction
int TachometerGetValue(Widget w)
{
return (((TachometerWidget) w)->tachometer.value);
}

// cppcheck-suppress unusedFunction
// cppcheck-suppress unusedFunction
int TachometerSetValue(Widget w, int i)
{
int old;


+ 4
- 9
ais_json.c View File

@@ -14,6 +14,7 @@ representations to libgps structures.
#include <stdbool.h>
#include <stdlib.h>
#include <stddef.h>
#include <time.h>

#include "gpsd_config.h"
#include "gps.h"
@@ -22,11 +23,10 @@ representations to libgps structures.
#include "libgps.h"

/* kluge because we don't want to include gpsd.h here */
extern int gpsd_hexpack(/*@in@*/const char *, /*@out@*/char *, size_t);
extern int gpsd_hexpack(const char *, char *, size_t);

/*@ -mustdefine @*/
static void lenhex_unpack(const char *from,
size_t * plen, /*@out@*/ char *to, size_t maxlen)
size_t * plen, char *to, size_t maxlen)
{
char *colon = strchr(from, ':');

@@ -35,16 +35,13 @@ static void lenhex_unpack(const char *from,
(void)gpsd_hexpack(colon + 1, to, maxlen);
}

/*@ +mustdefine @*/

int json_ais_read(const char *buf,
char *path, size_t pathlen, struct ais_t *ais,
/*@null@*/ const char **endptr)
const char **endptr)
{
/* collected but not actually used yet */
bool scaled;
/*@-compdef@*//* splint is confused by storage declared in the .i file */
/*@-nullstate@*/

#define AIS_HEADER \
{"class", t_check, .dflt.check = "AIS"}, \
@@ -81,7 +78,6 @@ int json_ais_read(const char *buf,

memset(ais, '\0', sizeof(struct ais_t));

/*@-usedef@*/
if (strstr(buf, "\"type\":1,") != NULL
|| strstr(buf, "\"type\":2,") != NULL
|| strstr(buf, "\"type\":3,") != NULL) {
@@ -463,7 +459,6 @@ int json_ais_read(const char *buf,
return JSON_ERR_MISC;
}
return status;
/*@+compdef +usedef +nullstate@*/
}
#endif /* SOCKET_EXPORT_ENABLE */



+ 49
- 61
ais_json.i View File

@@ -33,7 +33,7 @@
.dflt.boolean = false},
{"radio", t_uinteger, .addr.uinteger = &ais->type1.radio,
.dflt.uinteger = 0},
{NULL}
{NULL}
};

char timestamp[JSON_VAL_MAX+1];
@@ -54,7 +54,7 @@
.dflt.boolean = false},
{"radio", t_uinteger, .addr.uinteger = &ais->type4.radio,
.dflt.uinteger = 0},
{NULL}
{NULL}
};

char eta[JSON_VAL_MAX+1];
@@ -90,7 +90,7 @@
.len = sizeof(ais->type5.destination)},
{"dte", t_uinteger, .addr.uinteger = &ais->type5.dte,
.dflt.uinteger = 1},
{NULL}
{NULL}
};

char data[JSON_VAL_MAX+1];
@@ -99,7 +99,7 @@
AIS_TYPE6
{"data", t_string, .addr.string = data,
.len = sizeof(data)},
{NULL}
{NULL}
};

const struct json_attr_t json_ais6_fid10[] = {
@@ -123,7 +123,7 @@
.dflt.uinteger = 0},
{"off_pos", t_boolean, .addr.boolean = &ais->type6.dac235fid10.off_pos,
.dflt.boolean = false},
{NULL}
{NULL}
};

char departure[JSON_VAL_MAX+1];
@@ -148,7 +148,7 @@
.dflt.uinteger = 0},
{"unit", t_uinteger, .addr.uinteger = &ais->type6.dac1fid12.unit,
.dflt.uinteger = 0},
{NULL}
{NULL}
};

const struct json_attr_t json_ais6_fid15[] = {
@@ -156,7 +156,7 @@
AIS_TYPE6
{"airdraught", t_uinteger, .addr.uinteger = &ais->type6.dac1fid15.airdraught,
.dflt.uinteger = 0},
{NULL}
{NULL}
};

const struct json_attr_t json_ais6_fid16[] = {
@@ -164,7 +164,7 @@
AIS_TYPE6
{"persons", t_uinteger, .addr.uinteger = &ais->type6.dac1fid16.persons,
.dflt.uinteger = 0},
{NULL}
{NULL}
};

char arrival[JSON_VAL_MAX+1];
@@ -183,7 +183,7 @@
.dflt.integer = AIS_LON3_NOT_AVAILABLE},
{"lat", t_integer, .addr.integer = &ais->type6.dac1fid18.lat,
.dflt.integer = AIS_LAT3_NOT_AVAILABLE},
{NULL}
{NULL}
};

char berth_name[JSON_VAL_MAX+1];
@@ -261,7 +261,7 @@
.dflt.integer = AIS_LON3_NOT_AVAILABLE},
{"berth_lat", t_integer, .addr.integer = &ais->type6.dac1fid20.berth_lat,
.dflt.integer = AIS_LAT3_NOT_AVAILABLE},
{NULL}
{NULL}
};

const struct json_attr_t json_ais6_fid21[] = {
@@ -283,7 +283,7 @@
.dflt.uinteger = 0},
{"airdraught", t_uinteger, .addr.uinteger = &ais->type6.dac200fid21.airdraught,
.dflt.uinteger = 0},
{NULL}
{NULL}
};

char rta[JSON_VAL_MAX+1];
@@ -304,7 +304,7 @@
.len = sizeof(rta)},
{"status", t_uinteger, .addr.uinteger = &ais->type6.dac200fid22.status,
.dflt.uinteger = DAC200FID22_STATUS_NOT_AVAILABLE},
{NULL}
{NULL}
};

const struct json_attr_t json_ais6_fid25_cargos_subtype[] = {
@@ -314,7 +314,6 @@
.dflt.uinteger = 0},
{NULL}
};
/*@-type@*//* STRUCTARRAY confuses splint */
const struct json_attr_t json_ais6_fid25[] = {
AIS_HEADER
AIS_TYPE6
@@ -323,9 +322,8 @@
{"amount", t_uinteger, .addr.uinteger = &ais->type6.dac1fid25.amount,
.dflt.uinteger = 0},
{"cargos", t_array, STRUCTARRAY(ais->type6.dac1fid25.cargos, json_ais6_fid25_cargos_subtype, &ais->type6.dac1fid25.ncargos)},
{NULL}
{NULL}
};
/*@+type@*/

char start[JSON_VAL_MAX+1];
const struct json_attr_t json_ais6_fid28_waypoints_subtype[] = {
@@ -335,7 +333,6 @@
.dflt.integer = AIS_LAT4_NOT_AVAILABLE},
{NULL}
};
/*@-type@*//* STRUCTARRAY confuses splint */
const struct json_attr_t json_ais6_fid28[] = {
AIS_HEADER
AIS_TYPE6
@@ -351,9 +348,8 @@
{"duration", t_uinteger, .addr.uinteger = &ais->type6.dac1fid28.duration,
.dflt.uinteger = 0},
{"waypoints", t_array, STRUCTARRAY(ais->type6.dac1fid28.waypoints, json_ais6_fid28_waypoints_subtype, &ais->type6.dac1fid28.waycount)},
{NULL}
{NULL}
};
/*@+type@*/

const struct json_attr_t json_ais6_fid30[] = {
AIS_HEADER
@@ -362,7 +358,7 @@
.dflt.uinteger = 0},
{"text", t_string, .addr.string = ais->type6.dac1fid30.text,
.len = sizeof(ais->type6.dac1fid30.text)},
{NULL}
{NULL}
};

const struct json_attr_t json_ais6_fid32_tidals_subtype[] = {
@@ -384,7 +380,6 @@
.dflt.uinteger = DAC1FID32_CSPEED_NOT_AVAILABLE},
{NULL}
};
/*@-type@*//* STRUCTARRAY confuses splint */
const struct json_attr_t json_ais6_fid32[] = {
AIS_HEADER
AIS_TYPE6
@@ -393,9 +388,8 @@
{"day", t_uinteger, .addr.uinteger = &ais->type6.dac1fid32.day,
.dflt.uinteger = AIS_DAY_NOT_AVAILABLE},
{"tidals", t_array, STRUCTARRAY(ais->type6.dac1fid32.tidals, json_ais6_fid32_tidals_subtype, &ais->type6.dac1fid32.ntidals)},
{NULL}
{NULL}
};
/*@+type@*/

const struct json_attr_t json_ais6_fid55[] = {
AIS_HEADER
@@ -406,7 +400,7 @@
.dflt.uinteger = DAC200FID55_COUNT_NOT_AVAILABLE},
{"personnel", t_uinteger, .addr.uinteger = &ais->type6.dac200fid55.personnel,
.dflt.uinteger = DAC200FID55_COUNT_NOT_AVAILABLE},
{NULL}
{NULL}
};

const struct json_attr_t json_ais7[] = {
@@ -419,7 +413,7 @@
.dflt.uinteger = 0},
{"mmsi4", t_uinteger, .addr.uinteger = &ais->type7.mmsi4,
.dflt.uinteger = 0},
{NULL}
{NULL}
};

const struct json_attr_t json_ais8[] = {
@@ -427,7 +421,7 @@
AIS_TYPE8
{"data", t_string, .addr.string = data,
.len = sizeof(data)},
{NULL}
{NULL}
};

const struct json_attr_t json_ais8_fid10[] = {
@@ -456,7 +450,7 @@
.dflt.boolean = false},
{"heading_q", t_boolean, .addr.boolean = &ais->type8.dac200fid10.heading_q,
.dflt.boolean = false},
{NULL}
{NULL}
};

const struct json_attr_t json_ais8_fid11[] = {
@@ -532,7 +526,7 @@
{"ice", t_uinteger, .addr.uinteger = &ais->type8.dac1fid11.ice,
.dflt.uinteger = DAC1FID11_ICE_NOT_AVAILABLE},
{"ice_text", t_ignore},
{NULL}
{NULL}
};

char closefrom[JSON_VAL_MAX+1];
@@ -566,7 +560,7 @@
.dflt.uinteger = AIS_HOUR_NOT_AVAILABLE},
{"tminute", t_uinteger, .addr.uinteger = &ais->type8.dac1fid13.tminute,
.dflt.uinteger = AIS_MINUTE_NOT_AVAILABLE},
{NULL}
{NULL}
};

const struct json_attr_t json_ais8_fid15[] = {
@@ -574,7 +568,7 @@
AIS_TYPE8
{"airdraught", t_uinteger, .addr.uinteger = &ais->type8.dac1fid15.airdraught,
.dflt.uinteger = 0},
{NULL}
{NULL}
};

const struct json_attr_t json_ais8_fid16[] = {
@@ -582,7 +576,7 @@
AIS_TYPE8
{"persons", t_uinteger, .addr.uinteger = &ais->type8.dac1fid16.persons,
.dflt.uinteger = 0},
{NULL}
{NULL}
};

const struct json_attr_t json_ais8_fid17_targets_subtype[] = {
@@ -608,14 +602,12 @@
.dflt.uinteger = DAC1FID17_SPEED_NOT_AVAILABLE},
{NULL}
};
/*@-type@*//* STRUCTARRAY confuses splint */
const struct json_attr_t json_ais8_fid17[] = {
AIS_HEADER
AIS_TYPE8
{"targets", t_array, STRUCTARRAY(ais->type8.dac1fid17.targets, json_ais8_fid17_targets_subtype, &ais->type8.dac1fid17.ntargets)},
{NULL}
{NULL}
};
/*@+type@*/

const struct json_attr_t json_ais8_fid19[] = {
AIS_HEADER
@@ -640,7 +632,7 @@
{"nextsignal", t_uinteger, .addr.uinteger = &ais->type8.dac1fid19.nextsignal,
.dflt.uinteger = 0},
{"nextsignal_type", t_ignore},
{NULL}
{NULL}
};

char end[JSON_VAL_MAX+1];
@@ -672,7 +664,7 @@
{"wind", t_uinteger, .addr.uinteger = &ais->type8.dac200fid23.wind,
.dflt.uinteger = DAC200FID23_WIND_UNKNOWN},
{"wind_text", t_ignore},
{NULL}
{NULL}
};

const struct json_attr_t json_ais8_fid24_gauges_subtype[] = {
@@ -682,16 +674,14 @@
.dflt.integer = DAC200FID24_GAUGE_LEVEL_UNKNOWN},
{NULL}
};
/*@-type@*//* STRUCTARRAY confuses splint */
const struct json_attr_t json_ais8_fid24[] = {
AIS_HEADER
AIS_TYPE8
{"country", t_string, .addr.string = ais->type8.dac200fid24.country,
.len = sizeof(ais->type8.dac200fid24.country)},
{"gauges", t_array, STRUCTARRAY(ais->type8.dac200fid24.gauges, json_ais8_fid24_gauges_subtype, &ais->type8.dac200fid24.ngauges)},
{NULL}
{NULL}
};
/*@+type@*/

const struct json_attr_t json_ais8_fid27_waypoints_subtype[] = {
{"lon", t_integer, STRUCTOBJECT(struct waypoint_t, lon),
@@ -700,7 +690,6 @@
.dflt.integer = AIS_LAT4_NOT_AVAILABLE},
{NULL}
};
/*@-type@*//* STRUCTARRAY confuses splint */
const struct json_attr_t json_ais8_fid27[] = {
AIS_HEADER
AIS_TYPE8
@@ -716,9 +705,8 @@
{"duration", t_uinteger, .addr.uinteger = &ais->type8.dac1fid27.duration,
.dflt.uinteger = 0},
{"waypoints", t_array, STRUCTARRAY(ais->type8.dac1fid27.waypoints, json_ais8_fid27_waypoints_subtype, &ais->type8.dac1fid27.waycount)},
{NULL}
{NULL}
};
/*@+type@*/

const struct json_attr_t json_ais8_fid29[] = {
AIS_HEADER
@@ -727,7 +715,7 @@
.dflt.uinteger = 0},
{"text", t_string, .addr.string = ais->type8.dac1fid29.text,
.len = sizeof(ais->type8.dac1fid29.text)},
{NULL}
{NULL}
};

const struct json_attr_t json_ais8_fid31[] = {
@@ -806,7 +794,7 @@
.dflt.uinteger = DAC1FID31_SALINITY_NOT_AVAILABLE},
{"ice", t_uinteger, .addr.uinteger = &ais->type8.dac1fid31.ice,
.dflt.uinteger = DAC1FID31_ICE_NOT_AVAILABLE},
{NULL}
{NULL}
};

const struct json_attr_t json_ais8_fid40[] = {
@@ -822,7 +810,7 @@
{"status", t_uinteger, .addr.uinteger = &ais->type8.dac200fid40.status,
.dflt.uinteger = DAC200FID40_STATUS_UNKNOWN},
{"status_text", t_ignore},
{NULL}
{NULL}
};

const struct json_attr_t json_ais9[] = {
@@ -849,14 +837,14 @@
.dflt.boolean = false},
{"radio", t_uinteger, .addr.uinteger = &ais->type9.radio,
.dflt.uinteger = 0},
{NULL}
{NULL}
};

const struct json_attr_t json_ais10[] = {
AIS_HEADER
{"dest_mmsi", t_uinteger, .addr.uinteger = &ais->type10.dest_mmsi,
.dflt.uinteger = 0},
{NULL}
{NULL}
};

const struct json_attr_t json_ais12[] = {
@@ -869,14 +857,14 @@
.dflt.boolean = 0},
{"text", t_string, .addr.string = ais->type12.text,
.len = sizeof(ais->type12.text)},
{NULL}
{NULL}
};

const struct json_attr_t json_ais14[] = {
AIS_HEADER
{"text", t_string, .addr.string = ais->type14.text,
.len = sizeof(ais->type14.text)},
{NULL}
{NULL}
};

const struct json_attr_t json_ais15[] = {
@@ -897,7 +885,7 @@
.dflt.uinteger = 0},
{"offset2_1", t_uinteger, .addr.uinteger = &ais->type15.offset2_1,
.dflt.uinteger = 0},
{NULL}
{NULL}
};

const struct json_attr_t json_ais16[] = {
@@ -914,7 +902,7 @@
.dflt.uinteger = 0},
{"increment2", t_uinteger, .addr.uinteger = &ais->type16.increment2,
.dflt.uinteger = 0},
{NULL}
{NULL}
};

const struct json_attr_t json_ais17[] = {
@@ -925,7 +913,7 @@
.dflt.integer = AIS_GNS_LAT_NOT_AVAILABLE},
{"data", t_string, .addr.string = data,
.len = sizeof(data)},
{NULL}
{NULL}
};

const struct json_attr_t json_ais18[] = {
@@ -962,7 +950,7 @@
.dflt.boolean = false},
{"radio", t_uinteger, .addr.uinteger = &ais->type18.radio,
.dflt.uinteger = 0},
{NULL}
{NULL}
};

const struct json_attr_t json_ais19[] = {
@@ -1007,7 +995,7 @@
.dflt.uinteger = 1},
{"assigned", t_boolean, .addr.boolean = &ais->type19.assigned,
.dflt.boolean = false},
{NULL}
{NULL}
};

const struct json_attr_t json_ais20[] = {
@@ -1044,7 +1032,7 @@
.dflt.uinteger = 0},
{"increment4", t_uinteger, .addr.uinteger = &ais->type20.increment4,
.dflt.uinteger = 0},
{NULL}
{NULL}
};

const struct json_attr_t json_ais21[] = {
@@ -1081,7 +1069,7 @@
.dflt.boolean = false},
{"virtual_aid", t_boolean, .addr.boolean = &ais->type21.virtual_aid,
.dflt.boolean = false},
{NULL}
{NULL}
};

const struct json_attr_t json_ais22[] = {
@@ -1114,7 +1102,7 @@
.dflt.boolean = false},
{"zonesize", t_uinteger, .addr.uinteger = &ais->type22.zonesize,
.dflt.uinteger = 0},
{NULL}
{NULL}
};

const struct json_attr_t json_ais23[] = {
@@ -1139,7 +1127,7 @@
.dflt.uinteger = 0},
{"quiet", t_uinteger, .addr.uinteger = &ais->type23.quiet,
.dflt.uinteger = 0},
{NULL}
{NULL}
};

const struct json_attr_t json_ais24[] = {
@@ -1167,7 +1155,7 @@
.dflt.uinteger = 0},
{"to_starboard", t_uinteger, .addr.uinteger = &ais->type24.dim.to_starboard,
.dflt.uinteger = 0},
{NULL}
{NULL}
};

const struct json_attr_t json_ais25[] = {
@@ -1182,7 +1170,7 @@
.dflt.uinteger = 0},
{"data", t_string, .addr.string = data,
.len = sizeof(data)},
{NULL}
{NULL}
};

const struct json_attr_t json_ais26[] = {
@@ -1199,7 +1187,7 @@
.len = sizeof(data)},
{"radio", t_uinteger, .addr.uinteger = &ais->type26.radio,
.dflt.uinteger = 0},
{NULL}
{NULL}
};

const struct json_attr_t json_ais27[] = {
@@ -1220,7 +1208,7 @@
.dflt.boolean = false},
{"gnss", t_boolean, .addr.boolean = &ais->type27.gnss,
.dflt.boolean = true},
{NULL}
{NULL}
};




+ 3
- 15
bits.c View File

@@ -25,21 +25,19 @@ uint64_t ubits(unsigned char buf[], unsigned int start, unsigned int width, bool
unsigned int i;
unsigned end;

/*@i1@*/ assert(width <= sizeof(uint64_t) * CHAR_BIT);
assert(width <= sizeof(uint64_t) * CHAR_BIT);
for (i = start / CHAR_BIT;
i < (start + width + CHAR_BIT - 1) / CHAR_BIT; i++) {
/*@i1@*/fld <<= CHAR_BIT;
fld <<= CHAR_BIT;
fld |= (unsigned char)buf[i];
}

end = (start + width) % CHAR_BIT;
if (end != 0) {
/*@i1@*/fld >>= (CHAR_BIT - end);
fld >>= (CHAR_BIT - end);
}

/*@ -shiftimplementation @*/
fld &= ~(-1LL << width);
/*@ +shiftimplementation @*/

/* was extraction as a little-endian requested? */
if (le)
@@ -69,14 +67,10 @@ int64_t sbits(signed char buf[], unsigned int start, unsigned int width, bool le
is undefined for width <= 0 */
assert(width > 0);

/*@ +relaxtypes */
if (fld & (1LL << (width - 1))) {
/*@ -shiftimplementation @*/
fld |= (-1LL << (width - 1));
/*@ +shiftimplementation @*/
}
return (int64_t)fld;
/*@ -relaxtypes */
}

union int_float {
@@ -126,15 +120,12 @@ void putbef32(char *buf, int off, float val)
union int_float i_f;

i_f.f = val;
/*@-shiftimplementation +ignoresigns@*/
putbe32(buf, off, i_f.i);
/*@+shiftimplementation -ignoresigns@*/
}


void shiftleft(unsigned char *data, int size, unsigned short left)
{
/*@+matchanyintegral +ignoresigns -type -shiftnegative@*/
unsigned char *byte;

if (left >= CHAR_BIT) {
@@ -153,7 +144,6 @@ void shiftleft(unsigned char *data, int size, unsigned short left)
*byte <<= left;
*byte |= bits;
}
/*@-matchanyintegral -ignoresigns +type +shiftnegative@*/
}

#ifdef __UNUSED__
@@ -162,10 +152,8 @@ void putbed64(char *buf, int off, double val)
union long_double l_d;

l_d.d = val;
/*@-shiftimplementation +ignoresigns@*/
putbe32(buf, (off), (l_d.l) >> 32);
putbe32(buf, (off)+4, (l_d.l));
/*@+shiftimplementation -ignoresigns@*/
}

u_int16_t swap_u16(u_int16_t i)


+ 10
- 144
bsd_base64.c View File

@@ -42,18 +42,14 @@
*/

#include <stdlib.h>
#include "gpsd_config.h"
#if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP)

#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "bsd_base64.h"

#define Assert(Cond) if (!(Cond)) abort()
#include "gpsd.h" /* we only need the prototype */

static const char Base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@@ -122,7 +118,6 @@ static const char Pad64 = '=';
characters followed by one "=" padding character.
*/

/*@ +matchanyintegral -type @*/
int
b64_ntop(unsigned char const *src, size_t srclength, char *target,
size_t targsize)
@@ -141,10 +136,10 @@ b64_ntop(unsigned char const *src, size_t srclength, char *target,
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
output[3] = input[2] & 0x3f;
Assert(output[0] < 64);
Assert(output[1] < 64);
Assert(output[2] < 64);
Assert(output[3] < 64);
assert(output[0] < 64);
assert(output[1] < 64);
assert(output[2] < 64);
assert(output[3] < 64);

if (datalength + 4 > targsize)
return (-1);
@@ -165,9 +160,9 @@ b64_ntop(unsigned char const *src, size_t srclength, char *target,
output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
Assert(output[0] < 64);
Assert(output[1] < 64);
Assert(output[2] < 64);
assert(output[0] < 64);
assert(output[1] < 64);
assert(output[2] < 64);

if (datalength + 4 > targsize)
return (-1);
@@ -185,133 +180,4 @@ b64_ntop(unsigned char const *src, size_t srclength, char *target,
return (datalength);
}

#ifdef __UNUSED__
/*@ -matchanyintegral +type @*/

/* skips all whitespace anywhere.
converts characters, four at a time, starting at (or after)
src from base - 64 numbers into three 8 bit bytes in the target area.
it returns the number of data bytes stored at the target, or -1 on error.
*/

/*@ +matchanyintegral +charint @*/
int b64_pton(char const *src, unsigned char *target, size_t targsize)
{
size_t tarindex;
int state, ch;
char *pos;

state = 0;
tarindex = 0;

while ((ch = *src++) != '\0') {
if (isspace(ch)) /* Skip whitespace anywhere. */
continue;

if (ch == Pad64)
break;

if ((pos = strchr(Base64, ch)) == NULL) /* A non-base64 character. */
return (-1);

switch (state) {
case 0:
if (target) {
if (tarindex >= targsize)
return (-1);
target[tarindex] = (pos - Base64) << 2;
}
state = 1;
break;
case 1:
if (target) {
if (tarindex + 1 >= targsize)
return (-1);
target[tarindex] |= (pos - Base64) >> 4;
target[tarindex + 1] = ((pos - Base64) & 0x0f)
<< 4;
}
tarindex++;
state = 2;
break;
case 2:
if (target) {
if (tarindex + 1 >= targsize)
return (-1);
target[tarindex] |= (pos - Base64) >> 2;
target[tarindex + 1] = ((pos - Base64) & 0x03)
<< 6;
}
tarindex++;
state = 3;
break;
case 3:
if (target) {
if (tarindex >= targsize)
return (-1);
target[tarindex] |= (pos - Base64);
}
tarindex++;
state = 0;
break;
}
}

/*
* We are done decoding Base-64 chars. Let's see if we ended
* on a byte boundary, and/or with erroneous trailing characters.
*/

if (ch == Pad64) { /* We got a pad char. */
ch = *src++; /* Skip it, get next. */
switch (state) {
case 0: /* Invalid = in first position */
case 1: /* Invalid = in second position */
return (-1);

case 2: /* Valid, means one byte of info */
/* Skip any number of spaces. */
for (; ch != '\0'; ch = *src++)
if (!isspace(ch))
break;
/* Make sure there is another trailing = sign. */
if (ch != Pad64)
return (-1);
ch = *src++; /* Skip the = */
/* Fall through to "single trailing =" case. */
/* FALLTHROUGH */
/*@ -casebreak @*/
case 3: /* Valid, means two bytes of info */
/*
* We know this char is an =. Is there anything but
* whitespace after it?
*/
for (; ch != '\0'; ch = *src++)
if (!isspace(ch))
return (-1);

/*
* Now make sure for cases 2 and 3 that the "extra"
* bits that slopped past the last full byte were
* zeros. If we don't check them, they become a
* subliminal channel.
*/
if (target != 0 && target[tarindex] != 0)
return (-1);
}
} else {
/*
* We ended by seeing the end of the string. Make sure we
* have no partial bytes lying around.
*/
if (state != 0)
return (-1);
}

return (tarindex);
}

/*@ +matchanyintegral -charint @*/
#endif /* __UNUSED__ */

#endif /* !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) */
/* end */

+ 0
- 18
bsd_base64.h View File

@@ -1,18 +0,0 @@
/*
* This file is Copyright (c)2010 by the GPSD project
* BSD terms apply: see the file COPYING in the distribution root for details.
*/
#ifndef _BSD_BASE64_H
#define _BSD_BASE64_H

#ifndef HAVE___B64_NTOP
# ifndef HAVE_B64_NTOP
int b64_ntop(unsigned char const *src, size_t srclength, char *target,
size_t targsize);
int b64_pton(char const *src, unsigned char *target, size_t targsize);
# endif /* !HAVE_B64_NTOP */
# define __b64_ntop b64_ntop
# define __b64_pton b64_pton
#endif /* HAVE___B64_NTOP */

#endif /* _BSD_BASE64_H */

+ 34
- 71
build.txt View File

@@ -31,9 +31,7 @@ We consider failure to build and function on any of these platforms
a serious bug; if you encounter it, please complain on the
development list.

Macintosh OS X has been dropped from the list of supported platforms
due to serial-layer flakiness that has persisted through 10.9 and
10.10.
Port difficulty to any system conforming to POSIX-2001.1 should be minimal.

A Cygwin port is in progress but not complete.

@@ -58,10 +56,17 @@ arrange this by putting symlink in a local directory on $PATH.
=== C compiler ===

C99 conformance is required in the compiler. The C code depends on one
non-C99 feature (supported by GCC, clang, and pretty much any C
compiler that also speaks C++): anonymous unions. We could eliminate
these, but the cost would be source-level interface breakage if we
have to move structure members in and out of unions.
C11 feature (supported by GCC, clang, and pretty much any C compiler
that also speaks C++): anonymous unions. We could eliminate these,
but the cost would be source-level interface breakage if we have to
move structure members in and out of unions.

Some portions of the code using shared-memory segments are improved by
the C11 stdatomic.h features for lockless concurrency. These are: the
SHM export mode in shmexport.c, the code for writing clock corrections
to NTP in ntpshmwrite.c, and the code for reading NTP corrections in
ntpshmread.c. These features have been supported in GCC since 4.7 and
clang since 3.1.

GPSD is normally built and tested with GCC. Do not compile with a version
older than 4.1.1; there are several known issues with older versions,
@@ -71,9 +76,7 @@ generation, (c) the option -Wno-missing-field-initializers is
unavailable, leading to a flood of warnings (this is due to generated
code and cannot be fixed).

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

=== Python ===

@@ -99,8 +102,7 @@ The xgps test client requires the following Python extensions:

=== 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.
You will need scons version 2.3.0 (from 2013-03-02) or later to build the code.

=== Optional build components ===

@@ -189,6 +191,12 @@ To build gpsd for your host platform from source, simply call 'scons'
in a working-directory copy. (Cross-build is described in a later
section.)

To clean the built files, call 'scons -c' . To clean scons' cache,
call 'scons sconsclean'. Doing both should return your working directory
to a near pristine state as far as building is concerned. Some user
created files may remain, and source code changes will not have been
reverted..

You can specify the installation prefix, as for an autotools build, by
running "scons prefix=<installation_root>". The default value is
"/usr/local". The environment variable DESTDIR also works in the
@@ -239,58 +247,6 @@ included with the distribution. To install it, copy the file
'gpsd.php' to your HTML document directory. Then see the
post-installation instructions in INSTALL for how to configure it.

=== Why you might need chrpath ===

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

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

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

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

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

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

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

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

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

chrpath is a tool for editing RPATH in object files.

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

== The leapseconds cache ==

Early in your build, the recipe will try to go over the Internet to
@@ -340,7 +296,7 @@ with pps=no. You'll lose support for updating the clock from PPS
pulses.

dbus_export=no: for systems using DBUS: gpsd includes support for
shipping fixes as DBUS notifications, compiled in by default. This
shipping fixes as DBUS notifications, compiled in by default. This
may lead to complaint messages during testing on systems that don't
support DBUS. Build with the option "dbus_export=no" to disable it

@@ -383,11 +339,18 @@ For instructions on how to live-test the software, see the file INSTALL.

== Reverting to a clean state ==

The scons equivalent of 'make clean' is 'scons -c'. This will revert
your source tree to a clean state nearly as though you had just cloned or
downloaded it; some scons housekeeping stuff is left in place. If you
interrupted a regression test, 'distclean' will remove generated test
programs.
The scons equivalent of 'make clean' is 'scons -c' or 'scons
--clean'. This will revert your source tree to a clean state nearly as
though you had just cloned or downloaded it; some scons housekeeping
stuff is left in place.

If you interrupted a regression test, 'scons testclean' will remove
generated test programs.

You can run 'scons sconsclean' to temove most of the configuration
state that scons keeps. Be aware, however, thatr doing this can
confuse scons; you may need to run 'scons --config=force' afterwards
to make your build succeed.

== Notes on Android:

@@ -408,7 +371,7 @@ Here are the scons switches I use:
scons wordsize=32 snapshot=off arch=arm sample=shell