Browse Source

Imported Upstream version 3.15

master upstream/3.15
Bernd Zeimetz 9 years ago
parent
commit
5a659e9e5a
  1. 26
      .splintrc
  2. 2
      AUTHORS
  3. 2
      HACKING
  4. 218
      INSTALL
  5. 19
      NEWS
  6. 4
      Qgpsmm.pc.in
  7. 18
      README
  8. 650
      SConstruct
  9. 67
      TODO
  10. 38
      Tachometer.c
  11. 13
      ais_json.c
  12. 110
      ais_json.i
  13. 18
      bits.c
  14. 154
      bsd_base64.c
  15. 18
      bsd_base64.h
  16. 105
      build.txt
  17. 41
      cgps.c
  18. 47
      clock_gettime.c
  19. 69
      compiler.h
  20. 35
      contrib/README
  21. 5
      contrib/SConstruct
  22. 24
      contrib/motosend.c
  23. 164
      contrib/ntpshmviz
  24. 13
      contrib/ppscheck.c
  25. 88
      contrib/skyview.php
  26. 2
      contrib/webgps.py
  27. 6
      control.in
  28. 6
      daemon.c
  29. 4
      dbusexport.c
  30. 5
      devtools/README
  31. 11
      devtools/identify_failing_build_options.py
  32. 0
      devtools/test_json_validity.py
  33. 23
      doc/explan_gpsd.c.xml
  34. 11
      doc/explan_gpsd_log.c.xml
  35. 25
      doc/explan_libgpsd_core.c.xml
  36. 2
      doc/explan_ntpshm.c.xml
  37. 4
      doc/internals.xml
  38. 102
      driver_ais.c
  39. 115
      driver_evermore.c
  40. 488
      driver_garmin.c
  41. 64
      driver_garmin_txt.c
  42. 265
      driver_geostar.c
  43. 131
      driver_italk.c
  44. 463
      driver_navcom.c
  45. 582
      driver_nmea0183.c
  46. 499
      driver_nmea2000.c
  47. 104
      driver_oncore.c
  48. 62
      driver_proto.c
  49. 16
      driver_rtcm2.c
  50. 10
      driver_rtcm3.c
  51. 473
      driver_sirf.c
  52. 130
      driver_superstar2.c
  53. 340
      driver_tsip.c
  54. 380
      driver_ubx.c
  55. 1
      driver_ubx.h
  56. 80
      driver_zodiac.c
  57. 250
      drivers.c
  58. 4
      geoid.c
  59. 19
      getsid.c
  60. 2
      gps.1
  61. 107
      gps.h
  62. 54
      gps.xml
  63. 51
      gps/client.py
  64. 2
      gps/fake.py
  65. 4
      gps/gps.py
  66. 81
      gps2udp.c
  67. 40
      gps_json.h
  68. 5
      gps_maskdump.c
  69. 444
      gpscap.ini
  70. 22
      gpscap.py
  71. 6
      gpscat.xml
  72. 3
      gpsclient.c
  73. 341
      gpsctl.c
  74. 9
      gpsd.8
  75. 797
      gpsd.c
  76. 1
      gpsd.h-head
  77. 359
      gpsd.h-tail
  78. 4
      gpsd.hotplug
  79. 27
      gpsd.php
  80. 27
      gpsd.php.in
  81. 4
      gpsd.usermap
  82. 28
      gpsd.xml
  83. 318
      gpsd_config.h
  84. 204
      gpsd_json.5
  85. 107
      gpsd_json.c
  86. 189
      gpsd_json.xml
  87. 21
      gpsdclient.c
  88. 14
      gpsdclient.h
  89. 10
      gpsdctl.c
  90. 2
      gpsdctl.xml
  91. 10
      gpsdecode.c
  92. 10
      gpsdecode.xml
  93. 24
      gpsfake.xml
  94. 4
      gpsinit
  95. 4
      gpsinit.xml
  96. 11
      gpsmon.1
  97. 302
      gpsmon.c
  98. 6
      gpsmon.h
  99. 23
      gpsmon.xml
  100. 8
      gpspacket.c

26
.splintrc

@ -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

2
AUTHORS

@ -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>

2
HACKING

@ -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

218
INSTALL

@ -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
NEWS

@ -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.

4
Qgpsmm.pc.in

@ -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

18
README

@ -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.

650
SConstruct

File diff suppressed because it is too large

67
TODO

@ -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

38
Tachometer.c

@ -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;

13
ais_json.c

@ -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 */

110
ais_json.i

@ -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}
};

18
bits.c

@ -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;