1 /* gps.h -- interface of the libgps library */
2 /*
3  * This file is Copyright (c) 2010 by the GPSD project
4  * SPDX-License-Identifier: BSD-2-clause
5  */
6 #ifndef _GPSD_GPS_H_
7 #define _GPSD_GPS_H_
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 #include <inttypes.h>	/* stdint.h would be smaller but not all have it */
14 #include <limits.h>
15 #include <pthread.h>	/* pacifies OpenBSD's compiler */
16 #include <signal.h>
17 #include <stdbool.h>
18 #include <stdio.h>
19 #include <sys/time.h>   // for struct timespec
20 #include <sys/types.h>
21 #include <time.h>
22 
23 /*
24  * 4.1 - Base version for initial JSON protocol (Dec 2009, release 2.90)
25  * 4.2 - AIS application IDs split into DAC and FID (July 2010, release 2.95)
26  * 5.0 - MAXCHANNELS bumped from 20 to 32 for GLONASS (Mar 2011, release 2.96)
27  *       gps_open() becomes reentrant, what gps_open_r() used to be.
28  *       gps_poll() removed in favor of gps_read().  The raw hook is gone.
29  *       (Aug 2011, release 3.0)
30  * 5.1 - GPS_PATH_MAX uses system PATH_MAX; split24 flag added. New
31  *       model and serial members in part B of AIS type 24, conforming
32  *       with ITU-R 1371-4. New timedrift structure (Nov 2013, release 3.10).
33  * 6.0 - AIS type 6 and 8 get 'structured' flag; GPS_PATH_MAX
34  *       shortened because devices has moved out of the tail union. Sentence
35  *       tag fields dropped from emitted JSON. The shape of the skyview
36  *       structure has changed to make working with the satellites-used
37  *       bits less confusing. (January 2015, release 3.12).
38  * 6.1 - Add navdata_t for more (nmea2000) info.
39  * 7.0 - add gps_fix_t.ecef (February 2018)
40  *       changed prototype of gps_read() to add buffer parameters
41  *       increased length of devconfig_t.subtype
42  *       add gnssid:svid:sigid to satellite_t
43  *       add mtime to attitude_t
44  *       changed MAXCHANNELS
45  * 8.0 - Change shape of rawdata_t.
46  *       Added values for gps_data_t->status
47  *       Remove epe from gps_data_t, it duplicates gps_fix_t eph
48  *       Added sep (estimated spherical error, 3D)
49  *       Note: Some GPS call eph as epe, others call sep as epe
50  *       Add gps_fix_t datum string, and qErr
51  *       enlarge subtype to hold ZED-F9 string
52  *       MAXCHANNELS bumped from 120 to 140
53  *       Try to make PRN be NMEA 2.x-4.0 compliant, not 4.10 or u-blox
54  * 9.0   add NED and geoid_sep variables to gps_fix_t
55  *       add health variable to satellite_t
56  *       change satellite_t elevation and azimuth to double
57  *       satellite_t elevation, azimuth, and ss use NAN for unknown value.
58  *       add altMSL, and depth, to gps_fix_t
59  *       add altHAE to gps_fix_t
60  *       mark altitude in gps_fix_t as deprecated and undefined
61  *       Move mag_var from gps_device_t to magnetic_var gps_data_t.
62  *       add dgps_age and dgps_station, to gps_fix_t
63  *       Change gps_fix_t.time from timestamp_t to timespec_t
64  *       Change gps_data_t.skyview_time from timestamp_t to timespec_t
65  *       Change gps_data_t.online from timestamp_t to timespec_t
66  *       Change gpst_t.utctime from double to timespec_t
67  *       Change devices.time from timestamp_t to timespec_t
68  *       Change sub4_18.d_tot from timestamp_t to time_t t_tot
69  *       Change devconfig_t.activated, cycle & mincycle to timespec_t
70  *       Remove unused timestamp() and unix_to_iso8601().
71  *       Remove unused iso8601_to_unix().
72  *       Remove unused struct timestamp_t entirely
73  *       Add DEG_NORM()
74  *       Move toff and pps out of gps_data_t.union.
75  *       Move gps_fix_t.qErr to gps_data_t.
76  *       Split devconfig_t.subtype into subtype and subtype1
77  */
78 #define GPSD_API_MAJOR_VERSION	9	/* bump on incompatible changes */
79 #define GPSD_API_MINOR_VERSION	0	/* bump on compatible changes */
80 
81 #define MAXCHANNELS	140	/* u-blox 9 tracks 140 signals */
82 #define MAXUSERDEVS	4	/* max devices per user */
83 #define GPS_PATH_MAX	128	/* for names like /dev/serial/by-id/... */
84 
85 // normalize degrees to 0 to 359
86 #define DEG_NORM(deg) \
87     if (0 > (deg)) {(deg) += 360;} else if (360 <= (deg)) {(deg) -= 360;};
88 
89 /*
90  * The structure describing an uncertainty volume in kinematic space.
91  * This is what GPSes are meant to produce; all the other info is
92  * technical impedimenta.
93  *
94  * All double values use NAN to indicate data not available.
95  *
96  * All the information in this structure was considered valid
97  * by the GPS at the time of update.
98  *
99  * Error estimates are at 95% confidence.
100  */
101 /* WARNING!  loss of precision telling time as a double.
102  * A double is 53 significant bits.
103  * UNIX time to nanoSec precision is 62 significant bits
104  * UNIX time to nanoSec precision after 2038 is 63 bits
105  * UNIX time as a double is only microSec precision
106  * UNIX time as a double and PPS do not play well together
107  */
108 
109 /* we want cm accuracy and 0.0000001 degrees is 1.11 cm at the equator
110  * the equator is best case for longitude. At 45lat cut that in half.
111  * at 85lat make it 0.00000001
112  *
113  * this easily fits in a C double which has 15.95 digits of precision
114  * printf() format %f defaults to %.6f, which will truncate the result.
115  * so print with %.7f if you have a survey grade GPS.
116  *
117  * ref: https://en.wikipedia.org/wiki/Decimal_degrees
118  */
119 typedef struct timespec timespec_t;	/* Unix time as sec, nsec */
120 
121 /* GPS error estimates are all over the map, and often unspecified.
122  * try for 1-sigma if we can... */
123 struct gps_fix_t {
124     timespec_t time;	/* Time of update */
125     int    mode;	/* Mode of fix */
126 #define MODE_NOT_SEEN	0	/* mode update not seen yet */
127 #define MODE_NO_FIX	1	/* none */
128 #define MODE_2D  	2	/* good for latitude/longitude */
129 #define MODE_3D  	3	/* good for altitude/climb too */
130     double ept;		/* Expected time uncertainty, seconds */
131     double latitude;	/* Latitude in degrees (valid if mode >= 2) */
132     double epy;  	/* Latitude position uncertainty, meters */
133     double longitude;	/* Longitude in degrees (valid if mode >= 2) */
134     double epx;  	/* Longitude position uncertainty, meters */
135     double altitude;    // DEPRECATED, undefined.
136     double altHAE;	/* Altitude, height above ellipsoid.
137                          * in meters and probably WGS84
138                          * (valid if mode == 3)
139                          * MSL = altHAE - geoid_sep */
140     double altMSL;      /* Altitude MSL (maybe EGM2008) */
141     double epv;  	/* Vertical position uncertainty, meters */
142     double track;	/* Course made good (relative to true north) */
143     double epd;		/* Track uncertainty, degrees */
144     double speed;	/* Speed over ground, meters/sec */
145     double eps;		/* Speed uncertainty, meters/sec */
146     double climb;       /* Vertical speed, meters/sec */
147     double epc;		/* Vertical speed uncertainty */
148     /* estimated position error horizontal (2D). Meters, maybe 50%, maybe 95% */
149     /* aka estimated position error (epe) */
150     double eph;		/* estimated position error horizontal (2D) */
151     /* spherical error probability, 3D. Meters, maybe 50%, maybe 95% */
152     /* Garmin, not gpsd, calls this estimated position error (epe) */
153     double sep;
154     /* Geoid separation (ellipsoid separation)
155      * Height of MSL ellipsoid (geoid) above WGS84 ellipsoid.
156      * Postive is MSL above WGS84. In meters */
157     double geoid_sep;
158 
159     double magnetic_track;  /* Course (relative to Magnetic North) */
160     double magnetic_var;    /* magnetic variation in degrees */
161     double depth;           /* depth in meters, probably depth of water
162                              * under the keel */
163 
164     /* ECEF data, all data in meters, and meters/second, or NaN */
165     struct {
166 	double x, y, z; 	/* ECEF x, y, z */
167 	double pAcc;            /* 3D Position Accuracy Estimate, likely SEP */
168 	double vx, vy, vz;	/* ECEF x, y, z velocity */
169 	double vAcc;            /* Velocity Accuracy Estimate, probably SEP */
170     } ecef;
171     /* NED data, all data in meters, and meters/second, or NaN */
172     struct {
173         double relPosN, relPosE, relPosD;   /* NED relative positions */
174         double velN, velE, velD;            /* NED velocities */
175     } NED;
176     char datum[40];             /* map datum */
177     /* DGPS stuff, often from xxGGA, or xxGNS */
178     double dgps_age;            /* age of DGPS data in tenths of seconds,
179                                  * -1 invalid */
180     /* DGPS Station used, max size is a guess
181      * NMEA 2 says 0000-1023
182      * RTCM 3, station ID is 0 to 4095.
183      * u-blox UBX-NAV-DGPS is 16 bit integer */
184     int dgps_station;           /* DGPS station ID, -1 invalid */
185 };
186 
187 /*
188  * Other GNSS birds reuse GPS PRNs.
189  * It is an NMEA0183 convention to map them to pseudo-PRNs 65..437.
190  * Very dependent on NMEA version.
191  * (some other GPS receivers push them to 33 and above).
192  */
193 #define GLONASS_PRN_OFFSET	64
194 
195 /*
196  * The structure describing the pseudorange errors (GPGST)
197  */
198 struct gst_t {
199     timespec_t utctime;
200     double rms_deviation;
201     double smajor_deviation;
202     double sminor_deviation;
203     double smajor_orientation;
204     double lat_err_deviation;
205     double lon_err_deviation;
206     double alt_err_deviation;
207 };
208 
209 /*
210  * From the RCTM104 2.x standard:
211  *
212  * "The 30 bit words (as opposed to 32 bit words) coupled with a 50 Hz
213  * transmission rate provides a convenient timing capability where the
214  * times of word boundaries are a rational multiple of 0.6 seconds."
215  *
216  * "Each frame is N+2 words long, where N is the number of message data
217  * words. For example, a filler message (type 6 or 34) with no message
218  * data will have N=0, and will consist only of two header words. The
219  * maximum number of data words allowed by the format is 31, so that
220  * the longest possible message will have a total of 33 words."
221  */
222 #define RTCM2_WORDS_MAX	33
223 #define MAXCORRECTIONS	18	/* max correction count in type 1 or 9 */
224 #define MAXSTATIONS	10	/* maximum stations in almanac, type 5 */
225 /* RTCM104 doesn't specify this, so give it the largest reasonable value */
226 #define MAXHEALTH	(RTCM2_WORDS_MAX-2)
227 
228 /*
229  * A nominally 30-bit word (24 bits of data, 6 bits of parity)
230  * used both in the GPS downlink protocol described in IS-GPS-200
231  * and in the format for DGPS corrections used in RTCM-104v2.
232  */
233 typedef uint32_t isgps30bits_t;
234 
235 /*
236  * Values for "system" fields.  Note, the encoding logic is sensitive to the
237  * actual values of these; it's not sufficient that they're distinct.
238  */
239 #define NAVSYSTEM_GPS   	0
240 #define NAVSYSTEM_GLONASS	1
241 #define NAVSYSTEM_GALILEO	2
242 #define NAVSYSTEM_UNKNOWN	3
243 
244 struct rtcm2_t {
245     /* header contents */
246     unsigned type;	/* RTCM message type */
247     unsigned length;	/* length (words) */
248     double   zcount;	/* time within hour: GPS time, no leap secs */
249     unsigned refstaid;	/* reference station ID */
250     unsigned seqnum;	/* message sequence number (modulo 8) */
251     unsigned stathlth;	/* station health */
252 
253     /* message data in decoded form */
254     union {
255 	struct {
256 	    unsigned int nentries;
257 	    struct gps_rangesat_t {	/* data from messages 1 & 9 */
258 		unsigned ident;		/* satellite ID */
259 		unsigned udre;		/* user differential range error */
260 		unsigned iod;		/* issue of data */
261 		double prc;		/* range error */
262 		double rrc;		/* range error rate */
263 	    } sat[MAXCORRECTIONS];
264 	} gps_ranges;
265 	struct {		/* data for type 3 messages */
266 	    bool valid;		/* is message well-formed? */
267 	    double x, y, z;
268 	} ecef;
269 	struct {		/* data from type 4 messages */
270 	    bool valid;		/* is message well-formed? */
271 	    int system;
272 	    int sense;
273 #define SENSE_INVALID	0
274 #define SENSE_GLOBAL	1
275 #define SENSE_LOCAL   	2
276 	    char datum[6];
277 	    double dx, dy, dz;
278 	} reference;
279 	struct {		/* data from type 5 messages */
280 	    unsigned int nentries;
281 	    struct consat_t {
282 		unsigned ident;		/* satellite ID */
283 		bool iodl;		/* issue of data */
284 		unsigned int health;	/* is satellite healthy? */
285 #define HEALTH_NORMAL		(0)	/* Radiobeacon operation normal */
286 #define HEALTH_UNMONITORED	(1)	/* No integrity monitor operating */
287 #define HEALTH_NOINFO		(2)	/* No information available */
288 #define HEALTH_DONOTUSE		(3)	/* Do not use this radiobeacon */
289 	       int snr;			/* signal-to-noise ratio, dB */
290 #define SNR_BAD	-1			/* not reported */
291 		bool health_en; 	/* health enabled */
292 		bool new_data;		/* new data? */
293 		bool los_warning;	/* line-of-sight warning */
294 		unsigned int tou;	/* time to unhealth, seconds */
295 	    } sat[MAXHEALTH];
296 	} conhealth;
297 	struct {		/* data from type 7 messages */
298 	    unsigned int nentries;
299 	    struct station_t {
300 		double latitude, longitude;	/* location */
301 		unsigned int range;		/* range in km */
302 		double frequency;		/* broadcast freq */
303 		unsigned int health;		/* station health */
304 		unsigned int station_id;	/* of the transmitter */
305 		unsigned int bitrate;		/* of station transmissions */
306 	    } station[MAXSTATIONS];
307 	} almanac;
308 	struct {		/* data for type 13 messages */
309 	    bool status;		/* expect a text message */
310 	    bool rangeflag;		/* station range altered? */
311 	    double lat, lon;		/* station longitude/latitude */
312 	    unsigned int range;		/* transmission range in km */
313 	} xmitter;
314 	struct {		/* data from type 14 messages */
315 	    unsigned int week;			/* GPS week (0-1023) */
316 	    unsigned int hour;			/* Hour in week (0-167) */
317 	    unsigned int leapsecs;		/* Leap seconds (0-63) */
318 	} gpstime;
319 	struct {
320 	    unsigned int nentries;
321 	    struct glonass_rangesat_t {		/* data from message type 31 */
322 		unsigned ident;		/* satellite ID */
323 		unsigned udre;		/* user differential range error */
324 		unsigned tod;		/* issue of data */
325 		bool change;		/* ephemeris change bit */
326 		double prc;		/* range error */
327 		double rrc;		/* range error rate */
328 	    } sat[MAXCORRECTIONS];
329 	} glonass_ranges;
330 	/* data from type 16 messages */
331 	char message[(RTCM2_WORDS_MAX-2) * sizeof(isgps30bits_t)];
332 	/* data from messages of unknown type */
333 	isgps30bits_t	words[RTCM2_WORDS_MAX-2];
334     };
335 };
336 
337 /* RTCM3 report structures begin here */
338 
339 #define RTCM3_MAX_SATELLITES	64
340 #define RTCM3_MAX_DESCRIPTOR	31
341 #define RTCM3_MAX_ANNOUNCEMENTS	32
342 
343 struct rtcm3_rtk_hdr {		/* header data from 1001, 1002, 1003, 1004 */
344     /* Used for both GPS and GLONASS, but their timebases differ */
345     unsigned int station_id;	/* Reference Station ID */
346     time_t tow;			/* GPS Epoch Time (TOW) in ms,
347 				   or GLONASS Epoch Time in ms */
348     bool sync;			/* Synchronous GNSS Message Flag */
349     unsigned short satcount;	/* # Satellite Signals Processed */
350     bool smoothing;		/* Divergence-free Smoothing Indicator */
351     unsigned int interval;	/* Smoothing Interval */
352 };
353 
354 struct rtcm3_basic_rtk {
355     unsigned char indicator;	/* Indicator */
356     unsigned int channel;	/* Satellite Frequency Channel Number
357 				   (GLONASS only) */
358     double pseudorange;		/* Pseudorange */
359     double rangediff;		/* PhaseRange - Pseudorange in meters */
360     unsigned char locktime;	/* Lock time Indicator */
361 };
362 
363 struct rtcm3_extended_rtk {
364     unsigned char indicator;	/* Indicator */
365     unsigned int channel;	/* Satellite Frequency Channel Number
366 				   (GLONASS only) */
367     double pseudorange;		/* Pseudorange */
368     double rangediff;		/* PhaseRange - L1 Pseudorange */
369     unsigned char locktime;	/* Lock time Indicator */
370     unsigned char ambiguity;	/* Integer Pseudorange
371 					   Modulus Ambiguity */
372     double CNR;			/* Carrier-to-Noise Ratio */
373 };
374 
375 struct rtcm3_network_rtk_header {
376     unsigned int network_id;	/* Network ID */
377     unsigned int subnetwork_id;	/* Subnetwork ID */
378     time_t time;		/* GPS Epoch Time (TOW) in ms */
379     bool multimesg;		/* GPS Multiple Message Indicator */
380     unsigned master_id;		/* Master Reference Station ID */
381     unsigned aux_id;		/* Auxiliary Reference Station ID */
382     unsigned char satcount;	/* count of GPS satellites */
383 };
384 
385 struct rtcm3_correction_diff {
386     unsigned char ident;	/* satellite ID */
387     enum {reserved, correct, widelane, uncertain} ambiguity;
388     unsigned char nonsync;
389     double geometric_diff;	/* Geometric Carrier Phase
390 				   Correction Difference (1016, 1017) */
391     unsigned char iode;		/* GPS IODE (1016, 1017) */
392     double ionospheric_diff;	/* Ionospheric Carrier Phase
393 				   Correction Difference (1015, 1017) */
394 };
395 
396 struct rtcm3_t {
397     /* header contents */
398     unsigned type;	/* RTCM 3.x message type */
399     unsigned length;	/* payload length, inclusive of checksum */
400 
401     union {
402 	/* 1001-1013 were present in the 3.0 version */
403 	struct {
404 	    struct rtcm3_rtk_hdr	header;
405 	    struct rtcm3_1001_t {
406 		unsigned ident;			/* Satellite ID */
407 		struct rtcm3_basic_rtk L1;
408 	    } rtk_data[RTCM3_MAX_SATELLITES];
409 	} rtcm3_1001;
410 	struct {
411 	    struct rtcm3_rtk_hdr	header;
412 	    struct rtcm3_1002_t {
413 		unsigned ident;			/* Satellite ID */
414 		struct rtcm3_extended_rtk L1;
415 	    } rtk_data[RTCM3_MAX_SATELLITES];
416 	} rtcm3_1002;
417 	struct rtcm3_1003_t {
418 	    struct rtcm3_rtk_hdr	header;
419 	    struct {
420 		unsigned ident;			/* Satellite ID */
421 		struct rtcm3_basic_rtk L1;
422 		struct rtcm3_basic_rtk L2;
423 	    } rtk_data[RTCM3_MAX_SATELLITES];
424 	} rtcm3_1003;
425 	struct rtcm3_1004_t {
426 	    struct rtcm3_rtk_hdr	header;
427 	    struct {
428 		unsigned ident;			/* Satellite ID */
429 		struct rtcm3_extended_rtk L1;
430 		struct rtcm3_extended_rtk L2;
431 	    } rtk_data[RTCM3_MAX_SATELLITES];
432 	} rtcm3_1004;
433 	struct rtcm3_1005_t {
434 	    unsigned int station_id;		/* Reference Station ID */
435 	    int system;				/* Which system is it? */
436 	    bool reference_station;		/* Reference-station indicator */
437 	    bool single_receiver;		/* Single Receiver Oscillator */
438 	    double ecef_x, ecef_y, ecef_z;	/* ECEF antenna location */
439 	} rtcm3_1005;
440 	struct rtcm3_1006_t {
441 	    unsigned int station_id;		/* Reference Station ID */
442 	    int system;				/* Which system is it? */
443 	    bool reference_station;		/* Reference-station indicator */
444 	    bool single_receiver;		/* Single Receiver Oscillator */
445 	    double ecef_x, ecef_y, ecef_z;	/* ECEF antenna location */
446 	    double height;			/* Antenna height */
447 	} rtcm3_1006;
448 	struct {
449 	    unsigned int station_id;			/* Reference Station ID */
450 	    char descriptor[RTCM3_MAX_DESCRIPTOR+1];	/* Description string */
451 	    unsigned int setup_id;
452 	} rtcm3_1007;
453 	struct {
454 	    unsigned int station_id;			/* Reference Station ID */
455 	    char descriptor[RTCM3_MAX_DESCRIPTOR+1];	/* Description string */
456 	    unsigned int setup_id;
457 	    char serial[RTCM3_MAX_DESCRIPTOR+1];	/* Serial # string */
458 	} rtcm3_1008;
459 	struct {
460 	    struct rtcm3_rtk_hdr	header;
461 	    struct rtcm3_1009_t {
462 		unsigned ident;		/* Satellite ID */
463 		struct rtcm3_basic_rtk L1;
464 	    } rtk_data[RTCM3_MAX_SATELLITES];
465 	} rtcm3_1009;
466 	struct {
467 	    struct rtcm3_rtk_hdr	header;
468 	    struct rtcm3_1010_t {
469 		unsigned ident;		/* Satellite ID */
470 		struct rtcm3_extended_rtk L1;
471 	    } rtk_data[RTCM3_MAX_SATELLITES];
472 	} rtcm3_1010;
473 	struct {
474 	    struct rtcm3_rtk_hdr	header;
475 	    struct rtcm3_1011_t {
476 		unsigned ident;			/* Satellite ID */
477 		struct rtcm3_extended_rtk L1;
478 		struct rtcm3_extended_rtk L2;
479 	    } rtk_data[RTCM3_MAX_SATELLITES];
480 	} rtcm3_1011;
481 	struct {
482 	    struct rtcm3_rtk_hdr	header;
483 	    struct rtcm3_1012_t {
484 		unsigned ident;			/* Satellite ID */
485 		struct rtcm3_extended_rtk L1;
486 		struct rtcm3_extended_rtk L2;
487 	    } rtk_data[RTCM3_MAX_SATELLITES];
488 	} rtcm3_1012;
489 	struct {
490 	    unsigned int station_id;	/* Reference Station ID */
491 	    unsigned short mjd;		/* Modified Julian Day (MJD) Number */
492 	    unsigned int sod;		/* Seconds of Day (UTC) */
493 	    unsigned char leapsecs;	/* Leap Seconds, GPS-UTC */
494 	    unsigned char ncount;	/* Count of announcements to follow */
495 	    struct rtcm3_1013_t {
496 		unsigned short id;		/* message type ID */
497 		bool sync;
498 		unsigned short interval;	/* interval in 0.1sec units */
499 	    } announcements[RTCM3_MAX_ANNOUNCEMENTS];
500 	} rtcm3_1013;
501 	/* 1014-1017 were added in the 3.1 version */
502 	struct rtcm3_1014_t {
503 	    unsigned int network_id;	/* Network ID */
504 	    unsigned int subnetwork_id;	/* Subnetwork ID */
505 	    unsigned int stationcount;	/* # auxiliary stations transmitted */
506 	    unsigned int master_id;	/* Master Reference Station ID */
507 	    unsigned int aux_id;	/* Auxiliary Reference Station ID */
508 	    double d_lat, d_lon, d_alt;	/* Aux-master location delta */
509 	} rtcm3_1014;
510 	struct rtcm3_1015_t {
511 	    struct rtcm3_network_rtk_header	header;
512 	    struct rtcm3_correction_diff corrections[RTCM3_MAX_SATELLITES];
513 	} rtcm3_1015;
514 	struct rtcm3_1016_t {
515 	    struct rtcm3_network_rtk_header	header;
516 	    struct rtcm3_correction_diff corrections[RTCM3_MAX_SATELLITES];
517 	} rtcm3_1016;
518 	struct rtcm3_1017_t {
519 	    struct rtcm3_network_rtk_header	header;
520 	    struct rtcm3_correction_diff corrections[RTCM3_MAX_SATELLITES];
521 	} rtcm3_1017;
522 	/* 1018-1029 were in the 3.0 version */
523 	struct rtcm3_1019_t {
524 	    unsigned int ident;		/* Satellite ID */
525 	    unsigned int week;		/* GPS Week Number */
526 	    unsigned char sv_accuracy;	/* GPS SV ACCURACY */
527 	    enum {reserved_code, p, ca, l2c} code;
528 	    double idot;
529 	    unsigned char iode;
530 	    /* ephemeris fields, not scaled */
531 	    unsigned int t_sub_oc;
532 	    signed int a_sub_f2;
533 	    signed int a_sub_f1;
534 	    signed int a_sub_f0;
535 	    unsigned int iodc;
536 	    signed int C_sub_rs;
537 	    signed int delta_sub_n;
538 	    signed int M_sub_0;
539 	    signed int C_sub_uc;
540 	    unsigned int e;
541 	    signed int C_sub_us;
542 	    unsigned int sqrt_sub_A;
543 	    unsigned int t_sub_oe;
544 	    signed int C_sub_ic;
545 	    signed int OMEGA_sub_0;
546 	    signed int C_sub_is;
547 	    signed int i_sub_0;
548 	    signed int C_sub_rc;
549 	    signed int argument_of_perigee;
550 	    signed int omegadot;
551 	    signed int t_sub_GD;
552 	    unsigned char sv_health;
553 	    bool p_data;
554 	    bool fit_interval;
555 	} rtcm3_1019;
556 	struct rtcm3_1020_t {
557 	    unsigned int ident;		/* Satellite ID */
558 	    unsigned short channel;	/* Satellite Frequency Channel Number */
559 	    /* ephemeris fields, not scaled */
560 	    bool C_sub_n;
561 	    bool health_avAilability_indicator;
562 	    unsigned char P1;
563 	    unsigned short t_sub_k;
564 	    bool msb_of_B_sub_n;
565 	    bool P2;
566 	    bool t_sub_b;
567 	    signed int x_sub_n_t_of_t_sub_b_prime;
568 	    signed int x_sub_n_t_of_t_sub_b;
569 	    signed int x_sub_n_t_of_t_sub_b_prime_prime;
570 	    signed int y_sub_n_t_of_t_sub_b_prime;
571 	    signed int y_sub_n_t_of_t_sub_b;
572 	    signed int y_sub_n_t_of_t_sub_b_prime_prime;
573 	    signed int z_sub_n_t_of_t_sub_b_prime;
574 	    signed int z_sub_n_t_of_t_sub_b;
575 	    signed int z_sub_n_t_of_t_sub_b_prime_prime;
576 	    bool P3;
577 	    signed int gamma_sub_n_of_t_sub_b;
578 	    unsigned char MP;
579 	    bool Ml_n;
580 	    signed int tau_n_of_t_sub_b;
581 	    signed int M_delta_tau_sub_n;
582 	    unsigned int E_sub_n;
583 	    bool MP4;
584 	    unsigned char MF_sub_T;
585 	    unsigned char MN_sub_T;
586 	    unsigned char MM;
587 	    bool additioinal_data_availability;
588 	    unsigned int N_sup_A;
589 	    unsigned int tau_sub_c;
590 	    unsigned int M_N_sub_4;
591 	    signed int M_tau_sub_GPS;
592 	    bool M_l_sub_n;
593 	} rtcm3_1020;
594 	struct rtcm3_1029_t {
595 	    unsigned int station_id;	/* Reference Station ID */
596 	    unsigned short mjd;		/* Modified Julian Day (MJD) Number */
597 	    unsigned int sod;		/* Seconds of Day (UTC) */
598 	    size_t len;			/* # chars to follow */
599 	    size_t unicode_units;	/* # Unicode units in text */
600 	    unsigned char text[128];
601 	} rtcm3_1029;
602 	struct rtcm3_1033_t {
603 	    unsigned int station_id;			/* Reference Station ID */
604 	    char descriptor[RTCM3_MAX_DESCRIPTOR+1];	/* Description string */
605 	    unsigned int setup_id;
606 	    char serial[RTCM3_MAX_DESCRIPTOR+1];	/* Serial # string */
607 	    char receiver[RTCM3_MAX_DESCRIPTOR+1];	/* Receiver string */
608 	    char firmware[RTCM3_MAX_DESCRIPTOR+1];	/* Firmware string */
609 	} rtcm3_1033;
610 	unsigned char data[1024];	/* Max RTCM3 msg length is 1023 bytes */
611     } rtcmtypes;
612 };
613 
614 /* RTCM3 scaling constants */
615 #define GPS_AMBIGUITY_MODULUS		299792.458	/* 1004, DF014*/
616 #define GLONASS_AMBIGUITY_MODULUS	599584.916	/* 1012, DF044 */
617 #define MESSAGE_INTERVAL_UNITS		0.1		/* 1013, DF047 */
618 
619 /*
620  * Raw IS_GPS subframe data
621  */
622 
623 /* The almanac is a subset of the clock and ephemeris data, with reduced
624  * precision. See IS-GPS-200E, Table 20-VI  */
625 struct almanac_t
626 {
627     uint8_t sv;  /* The satellite this refers to */
628     /* toa, almanac reference time, 8 bits unsigned, seconds */
629     uint8_t toa;
630     long l_toa;
631     /* SV health data, 8 bit unsigned bit map */
632     uint8_t svh;
633     /* deltai, correction to inclination, 16 bits signed, semi-circles */
634     int16_t deltai;
635     double d_deltai;
636     /* M0, Mean Anomaly at Reference Time, 24 bits signed, semi-circles */
637     int32_t M0;
638     double d_M0;
639     /* Omega0, Longitude of Ascending Node of Orbit Plane at Weekly Epoch,
640      * 24 bits signed, semi-circles */
641     int32_t Omega0;
642     double d_Omega0;
643     /* omega, Argument of Perigee, 24 bits signed, semi-circles */
644     int32_t omega;
645     double d_omega;
646     /* af0, SV clock correction constant term
647      * 11 bits signed, seconds */
648     int16_t af0;
649     double d_af0;
650     /* af1, SV clock correction first order term
651      * 11 bits signed, seconds/second */
652     int16_t af1;
653     double d_af1;
654     /* eccentricity, 16 bits, unsigned, dimensionless */
655     uint16_t e;
656     double d_eccentricity;
657     /* sqrt A, Square Root of the Semi-Major Axis
658      * 24 bits unsigned, square_root(meters) */
659     uint32_t sqrtA;
660     double d_sqrtA;
661     /* Omega dot, Rate of Right Ascension, 16 bits signed, semi-circles/sec */
662     int16_t Omegad;
663     double d_Omegad;
664 };
665 
666 struct subframe_t {
667     /* subframe number, 3 bits, unsigned, 1 to 5 */
668     uint8_t subframe_num;
669     /* data_id, denotes the NAV data structure of D(t), 2 bits, in
670      * IS-GPS-200E always == 0x1 */
671     uint8_t data_id;
672     /* SV/page id used for subframes 4 & 5, 6 bits */
673     uint8_t pageid;
674     /* tSVID, SV ID of the sat that transmitted this frame, 6 bits unsigned */
675     uint8_t tSVID;
676     /* TOW, Time of Week of NEXT message, 17 bits unsigned, scale 6, seconds */
677     uint32_t TOW17;
678     long l_TOW17;
679     /* integrity, URA bounds flag, 1 bit */
680     bool integrity;
681     /* alert, alert flag, SV URA and/or the SV User Differential Range
682      * Accuracy (UDRA) may be worse than indicated, 1 bit */
683     bool alert;
684     /* antispoof, A-S mode is ON in that SV, 1 bit */
685     bool antispoof;
686     int is_almanac;
687     union {
688         /* subframe 1, part of ephemeris, see IS-GPS-200E, Table 20-II
689 	 * and Table 20-I */
690 	struct {
691 	    /* WN, Week Number, 10 bits unsigned, scale 1, weeks */
692 	    uint16_t WN;
693 	    /* IODC, Issue of Data, Clock, 10 bits, unsigned,
694 	     * issued in 8 data ranges at the same time */
695 	    uint16_t IODC;
696 	    /* toc, clock data reference time, 16 bits, unsigned, seconds
697 	     * scale 2**4, issued in 8 data ranges at the same time */
698 	    uint16_t toc;
699 	    long l_toc;
700 	    /* l2, code on L2, 2 bits, bit map */
701 	    uint8_t l2;
702 	    /* l2p, L2 P data flag, 1 bit */
703 	    uint8_t l2p;
704 	    /* ura, SV accuracy, 4 bits unsigned index */
705 	    unsigned int ura;
706 	    /* hlth, SV health, 6 bits unsigned bitmap */
707 	    unsigned int hlth;
708 	    /* af0, SV clock correction constant term
709 	     * 22 bits signed, scale 2**-31, seconds */
710 	    int32_t af0;
711 	    double d_af0;
712 	    /* af1, SV clock correction first order term
713 	     * 22 bits signed, scale 2**-43, seconds/second */
714 	    int16_t af1;
715 	    double d_af1;
716 	    /* af2, SV clock correction second order term
717 	     * 8 bits signed, scale 2**-55, seconds/second**2 */
718 	    int8_t af2;
719 	    double d_af2;
720 	    /* Tgd,  L1-L2 correction term, 8 bits signed,  scale 2**-31,
721 	     * seconds */
722 	    int8_t Tgd;
723 	    double d_Tgd;
724 	} sub1;
725         /* subframe 2, part of ephemeris, see IS-GPS-200E, Table 20-II
726 	 * and Table 20-III */
727 	struct {
728 	    /* Issue of Data (Ephemeris),
729 	     * equal to the 8 LSBs of the 10 bit IODC of the same data set */
730 	    uint8_t IODE;
731 	    /* Age of Data Offset for the NMCT, 6 bits, scale 900,
732 	     * ignore if all ones, seconds */
733 	    uint8_t AODO;
734 	    uint16_t u_AODO;
735 	    /* fit, FIT interval flag, indicates a fit interval greater than
736 	     * 4 hour, 1 bit */
737 	    uint8_t fit;
738 	    /* toe, Reference Time Ephemeris, 16 bits unsigned, scale 2**4,
739 	     * seconds */
740 	    uint16_t toe;
741 	    long l_toe;
742 	    /* Crs, Amplitude of the Sine Harmonic Correction Term to the
743 	     * Orbit Radius, 16 bits, scale 2**-5, signed, meters */
744 	    int16_t Crs;
745 	    double d_Crs;
746 	    /* Cus, Amplitude of the Sine Harmonic Correction Term to the
747 	     * Argument of Latitude, 16 bits, signed, scale 2**-29, radians */
748 	    int16_t Cus;
749 	    double d_Cus;
750 	    /* Cuc, Amplitude of the Cosine Harmonic Correction Term to the
751 	     * Argument of Latitude, 16 bits, signed, scale 2**-29, radians */
752 	    int16_t Cuc;
753 	    double d_Cuc;
754 	    /* deltan, Mean Motion Difference From Computed Value
755 	     * Mean Motion Difference From Computed Value
756 	     * 16 bits, signed, scale 2**-43, semi-circles/sec */
757 	    int16_t deltan;
758 	    double d_deltan;
759 	    /* M0, Mean Anomaly at Reference Time, 32 bits signed,
760 	     * scale 2**-31, semi-circles */
761 	    int32_t M0;
762 	    double d_M0;
763 	    /* eccentricity, 32 bits, unsigned, scale 2**-33, dimensionless */
764 	    uint32_t e;
765 	    double d_eccentricity;
766 	    /* sqrt A, Square Root of the Semi-Major Axis
767 	     * 32 bits unsigned, scale 2**-19, square_root(meters) */
768 	    uint32_t sqrtA;
769 	    double d_sqrtA;
770 	} sub2;
771         /* subframe 3, part of ephemeris, see IS-GPS-200E, Table 20-II,
772 	 * Table 20-III */
773 	struct {
774 	    /* Issue of Data (Ephemeris), 8 bits, unsigned
775 	     * equal to the 8 LSBs of the 10 bit IODC of the same data set */
776 	    uint8_t IODE;
777 	    /* Rate of Inclination Angle, 14 bits signed, scale2**-43,
778 	     * semi-circles/sec */
779 	    int16_t IDOT;
780 	    double d_IDOT;
781 	    /* Cic, Amplitude of the Cosine Harmonic Correction Term to the
782 	     * Angle of Inclination, 16 bits signed, scale 2**-29, radians*/
783 	    int16_t Cic;
784 	    double d_Cic;
785 	    /* Cis, Amplitude of the Sine Harmonic Correction Term to the
786 	     * Angle of Inclination, 16 bits, unsigned, scale 2**-29, radians */
787 	    int16_t Cis;
788 	    double d_Cis;
789             /* Crc, Amplitude of the Cosine Harmonic Correction Term to the
790 	     * Orbit Radius, 16 bits signed, scale 2**-5, meters */
791 	    int16_t Crc;
792 	    double d_Crc;
793 	    /* i0, Inclination Angle at Reference Time, 32 bits, signed,
794 	     * scale 2**-31, semi-circles */
795 	    int32_t i0;
796 	    double d_i0;
797 	    /* Omega0, Longitude of Ascending Node of Orbit Plane at Weekly
798 	     * Epoch, 32 bits signed, semi-circles */
799 	    int32_t Omega0;
800 	    double d_Omega0;
801 	    /* omega, Argument of Perigee, 32 bits signed, scale 2**-31,
802 	     * semi-circles */
803 	    int32_t omega;
804 	    double d_omega;
805 	    /* Omega dot, Rate of Right Ascension, 24 bits signed,
806 	     * scale 2**-43, semi-circles/sec */
807 	    int32_t Omegad;
808 	    double d_Omegad;
809 	} sub3;
810 	struct {
811 	    struct almanac_t almanac;
812 	} sub4;
813 	/* subframe 4, page 13 */
814 	struct {
815 	    /* mapping ord ERD# to SV # is non trivial
816 	     * leave it alone.  See IS-GPS-200E Section 20.3.3.5.1.9 */
817 	    /* Estimated Range Deviation, 6 bits signed, meters */
818 	    char ERD[33];
819 	    /* ai, Availability Indicator, 2bits, bit map */
820 	    unsigned char ai;
821 	} sub4_13;
822 	/* subframe 4, page 17, system message, 23 chars, plus nul */
823 	struct {
824 	    char str[24];
825 	} sub4_17;
826 	/* subframe 4, page 18 */
827 	struct {
828 	    /* ionospheric and UTC data */
829 	    /* A0, Bias coefficient of GPS time scale relative to UTC time
830 	     * scale, 32 bits signed, scale 2**-30, seconds */
831 	    int32_t A0;
832 	    double d_A0;
833 	    /* A1, Drift coefficient of GPS time scale relative to UTC time
834 	     * scale, 24 bits signed, scale 2**-50, seconds/second */
835 	    int32_t A1;
836 	    double d_A1;
837 
838 	    /* alphaX, the four coefficients of a cubic equation representing
839 	     * the amplitude of the vertical delay */
840 
841 	    /* alpha0, 8 bits signed, scale w**-30, seconds */
842 	    int8_t alpha0;
843 	    double d_alpha0;
844 	    /* alpha1, 8 bits signed, scale w**-27, seconds/semi-circle */
845 	    int8_t alpha1;
846 	    double d_alpha1;
847 	    /* alpha2, 8 bits signed, scale w**-24, seconds/semi-circle**2 */
848 	    int8_t alpha2;
849 	    double d_alpha2;
850 	    /* alpha3, 8 bits signed, scale w**-24, seconds/semi-circle**3 */
851 	    int8_t alpha3;
852 	    double d_alpha3;
853 
854 	    /* betaX, the four coefficients of a cubic equation representing
855 	     * the period of the model */
856 
857 	    /* beta0, 8 bits signed, scale w**11, seconds */
858 	    int8_t beta0;
859 	    double d_beta0;
860 	    /* beta1, 8 bits signed, scale w**14, seconds/semi-circle */
861 	    int8_t beta1;
862 	    double d_beta1;
863 	    /* beta2, 8 bits signed, scale w**16, seconds/semi-circle**2 */
864 	    int8_t beta2;
865 	    double d_beta2;
866 	    /* beta3, 8 bits signed, scale w**16, seconds/semi-circle**3 */
867 	    int8_t beta3;
868 	    double d_beta3;
869 
870 	    /* leap (delta t ls), current leap second, 8 bits signed,
871 	     * scale 1, seconds */
872 	    int8_t leap;
873 	    /* lsf (delta t lsf), future leap second, 8 bits signed,
874 	     * scale 1, seconds */
875 	    int8_t lsf;
876 
877 	    /* tot, reference time for UTC data,
878 	     * 8 bits unsigned, scale 2**12, seconds */
879 	    uint8_t tot;
880 	    time_t t_tot;
881 
882 	    /* WNt, UTC reference week number, 8 bits unsigned, scale 1,
883 	     * weeks */
884 	    uint8_t WNt;
885 	    /* WNlsf, Leap second reference Week Number,
886 	     * 8 bits unsigned, scale 1, weeks */
887 	    uint8_t WNlsf;
888 	    /* DN, Leap second reference Day Number , 8 bits unsigned,
889 	     * scale 1, days */
890 	    uint8_t DN;
891 	} sub4_18;
892 	/* subframe 4, page 25 */
893 	struct {
894 	    /* svf, A-S status and the configuration code of each SV
895 	     * 4 bits unsigned, bitmap */
896 	    unsigned char svf[33];
897 	    /* svh, SV health data for SV 25 through 32
898 	     * 6 bits unsigned bitmap */
899 	    uint8_t svhx[8];
900 	} sub4_25;
901 	struct {
902 	    struct almanac_t almanac;
903 	} sub5;
904 	struct {
905 	    /* toa, Almanac reference Time, 8 bits unsigned, scale 2**12,
906 	     * seconds */
907 	    uint8_t toa;
908 	    long l_toa;
909 	    /* WNa, Week Number almanac, 8 bits, scale 2, GPS Week
910 	     * Number % 256 */
911 	    uint8_t WNa;
912 	    /* sv, SV health status, 6 bits, bitmap */
913 	    uint8_t sv[25];
914 	} sub5_25;
915     };
916 };
917 
918 typedef uint64_t gps_mask_t;
919 
920 /*
921  * Is an MMSI number that of an auxiliary associated with a mother ship?
922  * We need to be able to test this for decoding AIS Type 24 messages.
923  * According to <http://www.navcen.uscg.gov/marcomms/gmdss/mmsi.htm#format>,
924  * auxiliary-craft MMSIs have the form 98MIDXXXX, where MID is a country
925  * code and XXXX the vessel ID.
926  */
927 #define AIS_AUXILIARY_MMSI(n)	((n) / 10000000 == 98)
928 
929 /* N/A values and scaling constant for 25/24 bit lon/lat pairs */
930 #define AIS_LON3_NOT_AVAILABLE	181000
931 #define AIS_LAT3_NOT_AVAILABLE	91000
932 #define AIS_LATLON3_DIV	60000.0
933 
934 /* N/A values and scaling constant for 28/27 bit lon/lat pairs */
935 #define AIS_LON4_NOT_AVAILABLE	1810000
936 #define AIS_LAT4_NOT_AVAILABLE	910000
937 #define AIS_LATLON4_DIV	600000.0
938 
939 struct route_info {
940     unsigned int linkage;	/* Message Linkage ID */
941     unsigned int sender;	/* Sender Class */
942     unsigned int rtype;		/* Route Type */
943     unsigned int month;		/* Start month */
944     unsigned int day;		/* Start day */
945     unsigned int hour;		/* Start hour */
946     unsigned int minute;	/* Start minute */
947     unsigned int duration;	/* Duration */
948     int waycount;		/* Waypoint count */
949     struct waypoint_t {
950 	signed int lon;		/* Longitude */
951 	signed int lat;		/* Latitude */
952     } waypoints[16];
953 };
954 
955 struct ais_t
956 {
957     unsigned int	type;		/* message type */
958     unsigned int    	repeat;		/* Repeat indicator */
959     unsigned int	mmsi;		/* MMSI */
960     union {
961 	/* Types 1-3 Common navigation info */
962 	struct {
963 	    unsigned int status;		/* navigation status */
964 	    signed turn;			/* rate of turn */
965 #define AIS_TURN_HARD_LEFT	-127
966 #define AIS_TURN_HARD_RIGHT	127
967 #define AIS_TURN_NOT_AVAILABLE	128
968 	    unsigned int speed;		/* speed over ground in deciknots */
969 #define AIS_SPEED_NOT_AVAILABLE	1023
970 #define AIS_SPEED_FAST_MOVER	1022		/* >= 102.2 knots */
971 	    bool accuracy;			/* position accuracy */
972 #define AIS_LATLON_DIV	600000.0
973 	    int lon;				/* longitude */
974 #define AIS_LON_NOT_AVAILABLE	0x6791AC0
975 	    int lat;				/* latitude */
976 #define AIS_LAT_NOT_AVAILABLE	0x3412140
977 	    unsigned int course;		/* course over ground */
978 #define AIS_COURSE_NOT_AVAILABLE	3600
979 	    unsigned int heading;		/* true heading */
980 #define AIS_HEADING_NOT_AVAILABLE	511
981             /* seconds of UTC time, 0 to 59.
982              * 60 == N/A, 61 == manual, 62 == dead reckoning,
983              * 63 == inoperative */
984 	    unsigned int second;
985 #define AIS_SEC_NOT_AVAILABLE	60
986 #define AIS_SEC_MANUAL		61
987 #define AIS_SEC_ESTIMATED	62
988 #define AIS_SEC_INOPERATIVE	63
989 	    unsigned int maneuver;	/* maneuver indicator */
990 	    //unsigned int spare;	spare bits */
991 	    bool raim;			/* RAIM flag */
992 	    unsigned int radio;		/* radio status bits */
993 	} type1;
994 	/* Type 4 - Base Station Report & Type 11 - UTC and Date Response */
995 	struct {
996 	    unsigned int year;			/* UTC year */
997 #define AIS_YEAR_NOT_AVAILABLE	0
998 	    unsigned int month;			/* UTC month */
999 #define AIS_MONTH_NOT_AVAILABLE	0
1000 	    unsigned int day;			/* UTC day */
1001 #define AIS_DAY_NOT_AVAILABLE	0
1002 	    unsigned int hour;			/* UTC hour */
1003 #define AIS_HOUR_NOT_AVAILABLE	24
1004 	    unsigned int minute;		/* UTC minute */
1005 #define AIS_MINUTE_NOT_AVAILABLE	60
1006 	    unsigned int second;		/* UTC second */
1007 #define AIS_SECOND_NOT_AVAILABLE	60
1008 	    bool accuracy;		/* fix quality */
1009 	    int lon;			/* longitude */
1010 	    int lat;			/* latitude */
1011 	    unsigned int epfd;		/* type of position fix device */
1012 	    //unsigned int spare;	spare bits */
1013 	    bool raim;			/* RAIM flag */
1014 	    unsigned int radio;		/* radio status bits */
1015 	} type4;
1016 	/* Type 5 - Ship static and voyage related data */
1017 	struct {
1018 	    unsigned int ais_version;	/* AIS version level */
1019 	    unsigned int imo;		/* IMO identification */
1020 	    // cppcheck-suppress arrayIndexOutOfBounds
1021 	    char callsign[7+1];		/* callsign */
1022 #define AIS_SHIPNAME_MAXLEN	20
1023 	    // cppcheck-suppress arrayIndexOutOfBounds
1024 	    char shipname[AIS_SHIPNAME_MAXLEN+1];	/* vessel name */
1025 	    unsigned int shiptype;	/* ship type code */
1026 	    unsigned int to_bow;	/* dimension to bow */
1027 	    unsigned int to_stern;	/* dimension to stern */
1028 	    unsigned int to_port;	/* dimension to port */
1029 	    unsigned int to_starboard;	/* dimension to starboard */
1030 	    unsigned int epfd;		/* type of position fix device */
1031 	    unsigned int month;		/* UTC month */
1032 	    unsigned int day;		/* UTC day */
1033 	    unsigned int hour;		/* UTC hour */
1034 	    unsigned int minute;	/* UTC minute */
1035 	    unsigned int draught;	/* draft in meters */
1036 	    char destination[20+1];	/* ship destination */
1037 	    unsigned int dte;		/* data terminal enable */
1038 	    //unsigned int spare;	spare bits */
1039 	} type5;
1040 	/* Type 6 - Addressed Binary Message */
1041 	struct {
1042 	    unsigned int seqno;		/* sequence number */
1043 	    unsigned int dest_mmsi;	/* destination MMSI */
1044 	    bool retransmit;		/* retransmit flag */
1045 	    //unsigned int spare;	spare bit(s) */
1046 	    unsigned int dac;           /* Application ID */
1047 	    unsigned int fid;           /* Functional ID */
1048 	    bool structured;		/* True match for DAC/FID? */
1049 #define AIS_TYPE6_BINARY_MAX	920	/* 920 bits */
1050 	    size_t bitcount;		/* bit count of the data */
1051 	    union {
1052 		// cppcheck-suppress arrayIndexOutOfBounds
1053 		char bitdata[(AIS_TYPE6_BINARY_MAX + 7) / 8];
1054 		/* Inland AIS - ETA at lock/bridge/terminal */
1055 		struct {
1056 		    char country[2+1];	/* UN Country Code */
1057 		    char locode[3+1];	/* UN/LOCODE */
1058 		    char section[5+1];	/* Fairway section */
1059 		    char terminal[5+1];	/* Terminal code */
1060 		    char hectometre[5+1];	/* Fairway hectometre */
1061 		    unsigned int month;	/* ETA month */
1062 		    unsigned int day;	/* ETA day */
1063 		    unsigned int hour;	/* ETA hour */
1064 		    unsigned int minute;	/* ETA minute */
1065 		    unsigned int tugs;	/* Assisting Tugs */
1066 		    unsigned int airdraught;	/* Air Draught */
1067 		} dac200fid21;
1068 		/* Inland AIS - ETA at lock/bridge/terminal */
1069 		struct {
1070 		    char country[2+1];	/* UN Country Code */
1071 		    char locode[3+1];	/* UN/LOCODE */
1072 		    char section[5+1];	/* Fairway section */
1073 		    char terminal[5+1];	/* Terminal code */
1074 		    char hectometre[5+1];	/* Fairway hectometre */
1075 		    unsigned int month;	/* RTA month */
1076 		    unsigned int day;	/* RTA day */
1077 		    unsigned int hour;	/* RTA hour */
1078 		    unsigned int minute;	/* RTA minute */
1079 		    unsigned int status;	/* Status */
1080 #define DAC200FID22_STATUS_OPERATIONAL	0
1081 #define DAC200FID22_STATUS_LIMITED	1
1082 #define DAC200FID22_STATUS_OUT_OF_ORDER	2
1083 #define DAC200FID22_STATUS_NOT_AVAILABLE	0
1084 		} dac200fid22;
1085 		/* Inland AIS - Number of persons on board */
1086 		struct {
1087 		    unsigned int crew;	/* # crew on board */
1088 		    unsigned int passengers;	/* # passengers on board */
1089 		    unsigned int personnel;	/* # personnel on board */
1090 #define DAC200FID55_COUNT_NOT_AVAILABLE	255
1091 		} dac200fid55;
1092 		/* GLA - AtoN monitoring data (UK/ROI) */
1093 		struct {
1094 		    unsigned int ana_int;       /* Analogue (internal) */
1095 		    unsigned int ana_ext1;      /* Analogue (external #1) */
1096 		    unsigned int ana_ext2;      /* Analogue (external #2) */
1097 		    unsigned int racon; /* RACON status */
1098 		    unsigned int light; /* Light status */
1099 		    bool alarm; /* Health alarm*/
1100 		    unsigned int stat_ext;      /* Status bits (external) */
1101 		    bool off_pos;    /* Off position status */
1102 		} dac235fid10;
1103 		/* IMO236 - Dangerous Cargo Indication */
1104 		struct {
1105 		    char lastport[5+1];		/* Last Port Of Call */
1106 		    unsigned int lmonth;	/* ETA month */
1107 		    unsigned int lday;		/* ETA day */
1108 		    unsigned int lhour;		/* ETA hour */
1109 		    unsigned int lminute;	/* ETA minute */
1110 		    char nextport[5+1];		/* Next Port Of Call */
1111 		    unsigned int nmonth;	/* ETA month */
1112 		    unsigned int nday;		/* ETA day */
1113 		    unsigned int nhour;		/* ETA hour */
1114 		    unsigned int nminute;	/* ETA minute */
1115 		    char dangerous[20+1];	/* Main Dangerous Good */
1116 		    char imdcat[4+1];		/* IMD Category */
1117 		    unsigned int unid;		/* UN Number */
1118 		    unsigned int amount;	/* Amount of Cargo */
1119 		    unsigned int unit;		/* Unit of Quantity */
1120 		} dac1fid12;
1121 		/* IMO236 - Extended Ship Static and Voyage Related Data */
1122 		struct {
1123 		    unsigned int airdraught;	/* Air Draught */
1124 		} dac1fid15;
1125 		/* IMO236 - Number of Persons on board */
1126 		struct {
1127 		    unsigned persons;	/* number of persons */
1128 		} dac1fid16;
1129 		/* IMO289 - Clearance Time To Enter Port */
1130 		struct {
1131 		    unsigned int linkage;	/* Message Linkage ID */
1132 		    unsigned int month;	/* Month (UTC) */
1133 		    unsigned int day;	/* Day (UTC) */
1134 		    unsigned int hour;	/* Hour (UTC) */
1135 		    unsigned int minute;	/* Minute (UTC) */
1136 		    char portname[20+1];	/* Name of Port & Berth */
1137 		    char destination[5+1];	/* Destination */
1138 		    signed int lon;	/* Longitude */
1139 		    signed int lat;	/* Latitude */
1140 		} dac1fid18;
1141 		/* IMO289 - Berthing Data (addressed) */
1142 		struct {
1143 		    unsigned int linkage;	/* Message Linkage ID */
1144 		    unsigned int berth_length;	/* Berth length */
1145 		    unsigned int berth_depth;	/* Berth Water Depth */
1146 		    unsigned int position;	/* Mooring Position */
1147 		    unsigned int month;	/* Month (UTC) */
1148 		    unsigned int day;	/* Day (UTC) */
1149 		    unsigned int hour;	/* Hour (UTC) */
1150 		    unsigned int minute;	/* Minute (UTC) */
1151 		    unsigned int availability;	/* Services Availability */
1152 		    unsigned int agent;	/* Agent */
1153 		    unsigned int fuel;	/* Bunker/fuel */
1154 		    unsigned int chandler;	/* Chandler */
1155 		    unsigned int stevedore;	/* Stevedore */
1156 		    unsigned int electrical;	/* Electrical */
1157 		    unsigned int water;	/* Potable water */
1158 		    unsigned int customs;	/* Customs house */
1159 		    unsigned int cartage;	/* Cartage */
1160 		    unsigned int crane;	/* Crane(s) */
1161 		    unsigned int lift;	/* Lift(s) */
1162 		    unsigned int medical;	/* Medical facilities */
1163 		    unsigned int navrepair;	/* Navigation repair */
1164 		    unsigned int provisions;	/* Provisions */
1165 		    unsigned int shiprepair;	/* Ship repair */
1166 		    unsigned int surveyor;	/* Surveyor */
1167 		    unsigned int steam;	/* Steam */
1168 		    unsigned int tugs;	/* Tugs */
1169 		    unsigned int solidwaste;	/* Waste disposal (solid) */
1170 		    unsigned int liquidwaste;	/* Waste disposal (liquid) */
1171 		    unsigned int hazardouswaste;  // Waste disposal (hazardous)
1172 		    unsigned int ballast;	/* Reserved ballast exchange */
1173 		    unsigned int additional;	/* Additional services */
1174 		    unsigned int regional1;	/* Regional reserved 1 */
1175 		    unsigned int regional2;	/* Regional reserved 2 */
1176 		    unsigned int future1;	/* Reserved for future */
1177 		    unsigned int future2;	/* Reserved for future */
1178 		    char berth_name[20+1];	/* Name of Berth */
1179 		    signed int berth_lon;	/* Longitude */
1180 		    signed int berth_lat;	/* Latitude */
1181 		} dac1fid20;
1182 		/* IMO289 - Weather observation report from ship */
1183 		/*** WORK IN PROGRESS - NOT YET DECODED ***/
1184 		struct {
1185 		    bool wmo;			/* true if WMO variant */
1186 		    union {
1187 			struct {
1188 			    char location[20+1];	/* Location */
1189 			    signed int lon;		/* Longitude */
1190 			    signed int lat;		/* Latitude */
1191 			    unsigned int day;		/* Report day */
1192 			    unsigned int hour;		/* Report hour */
1193 			    unsigned int minute;	/* Report minute */
1194 			    bool vislimit;		/* Max range? */
1195 			    unsigned int visibility;	/* Units of 0.1 nm */
1196 #define DAC1FID21_VISIBILITY_NOT_AVAILABLE	127
1197 #define DAC1FID21_VISIBILITY_SCALE		10.0
1198 			    unsigned humidity;		/* units of 1% */
1199 			    unsigned int wspeed;	/* average wind speed */
1200 			    unsigned int wgust;		/* wind gust */
1201 #define DAC1FID21_WSPEED_NOT_AVAILABLE		127
1202 			    unsigned int wdir;		/* wind direction */
1203 #define DAC1FID21_WDIR_NOT_AVAILABLE		360
1204 			    unsigned int pressure;	/* air pressure, hpa */
1205 #define DAC1FID21_NONWMO_PRESSURE_NOT_AVAILABLE	403
1206 #define DAC1FID21_NONWMO_PRESSURE_HIGH		402	/* > 1200hPa */
1207 #define DAC1FID21_NONWMO_PRESSURE_OFFSET		400	/* N/A */
1208 			    unsigned int pressuretend;	/* tendency */
1209 		    	    int airtemp;		/* temp, units 0.1C */
1210 #define DAC1FID21_AIRTEMP_NOT_AVAILABLE		-1024
1211 #define DAC1FID21_AIRTEMP_SCALE			10.0
1212 			    unsigned int watertemp;	/* units 0.1degC */
1213 #define DAC1FID21_WATERTEMP_NOT_AVAILABLE	501
1214 #define DAC1FID21_WATERTEMP_SCALE		10.0
1215 			    unsigned int waveperiod;	/* in seconds */
1216 #define DAC1FID21_WAVEPERIOD_NOT_AVAILABLE	63
1217 			    unsigned int wavedir;	/* direction in deg */
1218 #define DAC1FID21_WAVEDIR_NOT_AVAILABLE		360
1219 			    unsigned int swellheight;	/* in decimeters */
1220 			    unsigned int swellperiod;	/* in seconds */
1221 			    unsigned int swelldir;	/* direction in deg */
1222 			} nonwmo_obs;
1223 			struct {
1224 			    signed int lon;		/* Longitude */
1225 			    signed int lat;		/* Latitude */
1226 			    unsigned int month;		/* UTC month */
1227 			    unsigned int day;		/* Report day */
1228 			    unsigned int hour;		/* Report hour */
1229 			    unsigned int minute;	/* Report minute */
1230 			    unsigned int course;	/* course over ground */
1231 			    unsigned int speed;		/* speed, m/s */
1232 #define DAC1FID21_SOG_NOT_AVAILABLE		31
1233 #define DAC1FID21_SOG_HIGH_SPEED		30
1234 #define DAC1FID21_SOG_SCALE			2.0
1235 			    unsigned int heading;	/* true heading */
1236 #define DAC1FID21_HDG_NOT_AVAILABLE		127
1237 #define DAC1FID21_HDG_SCALE			5.0
1238 			    unsigned int pressure;	/* units of hPa * 0.1 */
1239 #define DAC1FID21_WMO_PRESSURE_SCALE		10
1240 #define DAC1FID21_WMO_PRESSURE_OFFSET		90.0
1241 			    unsigned int pdelta;	/* units of hPa * 0.1 */
1242 #define DAC1FID21_PDELTA_SCALE			10
1243 #define DAC1FID21_PDELTA_OFFSET			50.0
1244 			    unsigned int ptend;		/* enumerated */
1245 			    unsigned int twinddir;	/* in 5 degree steps */
1246 #define DAC1FID21_TWINDDIR_NOT_AVAILABLE	127
1247 			    unsigned int twindspeed;	/* meters per second */
1248 #define DAC1FID21_TWINDSPEED_SCALE		2
1249 #define DAC1FID21_RWINDSPEED_NOT_AVAILABLE	255
1250 			    unsigned int rwinddir;	/* in 5 degree steps */
1251 #define DAC1FID21_RWINDDIR_NOT_AVAILABLE	127
1252 			    unsigned int rwindspeed;	/* meters per second */
1253 #define DAC1FID21_RWINDSPEED_SCALE		2
1254 #define DAC1FID21_RWINDSPEED_NOT_AVAILABLE	255
1255 			    unsigned int mgustspeed;	/* meters per second */
1256 #define DAC1FID21_MGUSTSPEED_SCALE		2
1257 #define DAC1FID21_MGUSTSPEED_NOT_AVAILABLE	255
1258 			    unsigned int mgustdir;	/* in 5 degree steps */
1259 #define DAC1FID21_MGUSTDIR_NOT_AVAILABLE	127
1260 			    unsigned int airtemp;	/* degress K */
1261 #define DAC1FID21_AIRTEMP_OFFSET		223
1262 			    unsigned humidity;		/* units of 1% */
1263 #define DAC1FID21_HUMIDITY_NOT_VAILABLE		127
1264 			    /* some trailing fields are missing */
1265 			} wmo_obs;
1266 		    };
1267 	        } dac1fid21;
1268 		/*** WORK IN PROGRESS ENDS HERE ***/
1269 		/* IMO289 - Dangerous Cargo Indication */
1270 		struct {
1271 		    unsigned int unit;	/* Unit of Quantity */
1272 		    unsigned int amount;	/* Amount of Cargo */
1273 		    int ncargos;
1274 		    struct cargo_t {
1275 			unsigned int code;	/* Cargo code */
1276 			unsigned int subtype;	/* Cargo subtype */
1277 		    } cargos[28];
1278 		} dac1fid25;
1279 		/* IMO289 - Route info (addressed) */
1280 		struct route_info dac1fid28;
1281 		/* IMO289 - Text message (addressed) */
1282 		struct {
1283 		    unsigned int linkage;
1284 #define AIS_DAC1FID30_TEXT_MAX	154	/* 920 bits of six-bit, plus NUL */
1285 		    char text[AIS_DAC1FID30_TEXT_MAX];
1286 		} dac1fid30;
1287 		/* IMO289 & IMO236 - Tidal Window */
1288 		struct {
1289 		    unsigned int month;	/* Month */
1290 		    unsigned int day;	/* Day */
1291 		    signed int ntidals;
1292 		    struct tidal_t {
1293 			signed int lon;	/* Longitude */
1294 			signed int lat;	/* Latitude */
1295 			unsigned int from_hour;	/* From UTC Hour */
1296 			unsigned int from_min;	/* From UTC Minute */
1297 			unsigned int to_hour;	/* To UTC Hour */
1298 			unsigned int to_min;	/* To UTC Minute */
1299 #define DAC1FID32_CDIR_NOT_AVAILABLE		360
1300 			unsigned int cdir;	/* Current Dir. Predicted */
1301 #define DAC1FID32_CSPEED_NOT_AVAILABLE		127
1302 			unsigned int cspeed;	/* Current Speed Predicted */
1303 		    } tidals[3];
1304 		} dac1fid32;
1305 	    };
1306 	} type6;
1307 	/* Type 7 - Binary Acknowledge */
1308 	struct {
1309 	    unsigned int mmsi1;
1310 	    unsigned int seqno1;
1311 	    unsigned int mmsi2;
1312 	    unsigned int seqno2;
1313 	    unsigned int mmsi3;
1314 	    unsigned int seqno3;
1315 	    unsigned int mmsi4;
1316 	    unsigned int seqno4;
1317 	    /* spares ignored, they're only padding here */
1318 	} type7;
1319 	/* Type 8 - Broadcast Binary Message */
1320 	struct {
1321 	    unsigned int dac;       	/* Designated Area Code */
1322 	    unsigned int fid;       	/* Functional ID */
1323 #define AIS_TYPE8_BINARY_MAX	952	/* 952 bits */
1324 	    size_t bitcount;		/* bit count of the data */
1325 	    bool structured;		/* True match for DAC/FID? */
1326 	    union {
1327 		// cppcheck-suppress arrayIndexOutOfBounds
1328 		char bitdata[(AIS_TYPE8_BINARY_MAX + 7) / 8];
1329 		/* Inland static ship and voyage-related data */
1330 		struct {
1331 		    char vin[8+1];      	/* European Vessel ID */
1332 		    unsigned int length;	/* Length of ship */
1333 		    unsigned int beam;  	/* Beam of ship */
1334 		    unsigned int shiptype;	/* Ship/combination type */
1335 		    unsigned int hazard;	/* Hazardous cargo */
1336 #define DAC200FID10_HAZARD_MAX	5
1337 		    unsigned int draught;	/* Draught */
1338 		    unsigned int loaded;	/* Loaded/Unloaded */
1339 		    bool speed_q;	/* Speed inf. quality */
1340 		    bool course_q;	/* Course inf. quality */
1341 		    bool heading_q;	/* Heading inf. quality */
1342 		} dac200fid10;
1343 		/* Inland AIS EMMA Warning */
1344 		struct {
1345 		    unsigned int start_year;	/* Start Year */
1346 		    unsigned int start_month;	/* Start Month */
1347 		    unsigned int start_day;	/* Start Day */
1348 		    unsigned int end_year;	/* End Year */
1349 		    unsigned int end_month;	/* End Month */
1350 		    unsigned int end_day;	/* End Day */
1351 		    unsigned int start_hour;	/* Start Hour */
1352 		    unsigned int start_minute;	/* Start Minute */
1353 		    unsigned int end_hour;	/* End Hour */
1354 		    unsigned int end_minute;	/* End Minute */
1355 		    signed int start_lon;	/* Start Longitude */
1356 		    signed int start_lat;	/* Start Latitude */
1357 		    signed int end_lon;	/* End Longitude */
1358 		    signed int end_lat;	/* End Latitude */
1359 		    unsigned int type;	/* Type */
1360 #define DAC200FID23_TYPE_UNKNOWN		0
1361 		    signed int min;	/* Min value */
1362 #define DAC200FID23_MIN_UNKNOWN			255
1363 		    signed int max;	/* Max value */
1364 #define DAC200FID23_MAX_UNKNOWN			255
1365 		    unsigned int intensity;	/* Classification */
1366 #define DAC200FID23_CLASS_UNKNOWN		0
1367 		    unsigned int wind;	/* Wind Direction */
1368 #define DAC200FID23_WIND_UNKNOWN		0
1369 		} dac200fid23;
1370 		struct {
1371 		    char country[2+1];	/* UN Country Code */
1372 		    signed int ngauges;
1373 		    struct gauge_t {
1374 			unsigned int id;	/* Gauge ID */
1375 #define DAC200FID24_GAUGE_ID_UNKNOWN		0
1376 			signed int level;	/* Water Level */
1377 #define DAC200FID24_GAUGE_LEVEL_UNKNOWN		0
1378 		    } gauges[4];
1379 		} dac200fid24;
1380 		struct {
1381 		    signed int lon;	/* Signal Longitude */
1382 		    signed int lat;	/* Signal Latitude */
1383 		    unsigned int form;	/* Signal form */
1384 #define DAC200FID40_FORM_UNKNOWN		0
1385 		    unsigned int facing;	/* Signal orientation */
1386 #define DAC200FID40_FACING_UNKNOWN		0
1387 		    unsigned int direction;	/* Direction of impact */
1388 #define DAC200FID40_DIRECTION_UNKNOWN		0
1389 		    unsigned int status;	/* Light Status */
1390 #define DAC200FID40_STATUS_UNKNOWN		0
1391 		} dac200fid40;
1392 		/* IMO236  - Meteorological-Hydrological data
1393 		 * Trial message, not to be used after January 2013
1394 		 * Replaced by IMO289 (DAC 1, FID 31)
1395 		 */
1396 		struct {
1397 #define DAC1FID11_LATLON_SCALE			1000
1398 		    int lon;			/* longitude in minutes * .001 */
1399 #define DAC1FID11_LON_NOT_AVAILABLE		0xFFFFFF
1400 		    int lat;			/* latitude in minutes * .001 */
1401 #define DAC1FID11_LAT_NOT_AVAILABLE		0x7FFFFF
1402 		    unsigned int day;		/* UTC day */
1403 		    unsigned int hour;		/* UTC hour */
1404 		    unsigned int minute;	/* UTC minute */
1405 		    unsigned int wspeed;	/* average wind speed */
1406 		    unsigned int wgust;		/* wind gust */
1407 #define DAC1FID11_WSPEED_NOT_AVAILABLE		127
1408 		    unsigned int wdir;		/* wind direction */
1409 		    unsigned int wgustdir;	/* wind gust direction */
1410 #define DAC1FID11_WDIR_NOT_AVAILABLE		511
1411 		    unsigned int airtemp;	/* temperature, units 0.1C */
1412 #define DAC1FID11_AIRTEMP_NOT_AVAILABLE		2047
1413 #define DAC1FID11_AIRTEMP_OFFSET		600
1414 #define DAC1FID11_AIRTEMP_DIV			10.0
1415 		    unsigned int humidity;	/* relative humidity, % */
1416 #define DAC1FID11_HUMIDITY_NOT_AVAILABLE	127
1417 		    unsigned int dewpoint;	/* dew point, units 0.1C */
1418 #define DAC1FID11_DEWPOINT_NOT_AVAILABLE	1023
1419 #define DAC1FID11_DEWPOINT_OFFSET		200
1420 #define DAC1FID11_DEWPOINT_DIV		10.0
1421 		    unsigned int pressure;	/* air pressure, hpa */
1422 #define DAC1FID11_PRESSURE_NOT_AVAILABLE	511
1423 #define DAC1FID11_PRESSURE_OFFSET		-800
1424 		    unsigned int pressuretend;	/* tendency */
1425 #define DAC1FID11_PRESSURETREND_NOT_AVAILABLE	3
1426 		    unsigned int visibility;	/* units 0.1 nautical miles */
1427 #define DAC1FID11_VISIBILITY_NOT_AVAILABLE	255
1428 #define DAC1FID11_VISIBILITY_DIV		10.0
1429 		    int waterlevel;		/* decimeters */
1430 #define DAC1FID11_WATERLEVEL_NOT_AVAILABLE	511
1431 #define DAC1FID11_WATERLEVEL_OFFSET		100
1432 #define DAC1FID11_WATERLEVEL_DIV		10.0
1433 		    unsigned int leveltrend;	/* water level trend code */
1434 #define DAC1FID11_WATERLEVELTREND_NOT_AVAILABLE	3
1435 		    unsigned int cspeed;  // surface current speed in deciknots
1436 #define DAC1FID11_CSPEED_NOT_AVAILABLE		255
1437 #define DAC1FID11_CSPEED_DIV			10.0
1438 		    unsigned int cdir;	/* surface current dir., degrees */
1439 #define DAC1FID11_CDIR_NOT_AVAILABLE		511
1440 		    unsigned int cspeed2;	/* current speed in deciknots */
1441 		    unsigned int cdir2;		/* current dir., degrees */
1442 		    unsigned int cdepth2;	/* measurement depth, m */
1443 #define DAC1FID11_CDEPTH_NOT_AVAILABLE		31
1444 		    unsigned int cspeed3;	/* current speed in deciknots */
1445 		    unsigned int cdir3;		/* current dir., degrees */
1446 		    unsigned int cdepth3;	/* measurement depth, m */
1447 		    unsigned int waveheight;	/* in decimeters */
1448 #define DAC1FID11_WAVEHEIGHT_NOT_AVAILABLE	255
1449 #define DAC1FID11_WAVEHEIGHT_DIV		10.0
1450 		    unsigned int waveperiod;	/* in seconds */
1451 #define DAC1FID11_WAVEPERIOD_NOT_AVAILABLE	63
1452 		    unsigned int wavedir;	/* direction in degrees */
1453 #define DAC1FID11_WAVEDIR_NOT_AVAILABLE		511
1454 		    unsigned int swellheight;	/* in decimeters */
1455 		    unsigned int swellperiod;	/* in seconds */
1456 		    unsigned int swelldir;	/* direction in degrees */
1457 		    unsigned int seastate;	/* Beaufort scale, 0-12 */
1458 #define DAC1FID11_SEASTATE_NOT_AVAILABLE	15
1459 		    unsigned int watertemp;	/* units 0.1deg Celsius */
1460 #define DAC1FID11_WATERTEMP_NOT_AVAILABLE	1023
1461 #define DAC1FID11_WATERTEMP_OFFSET		100
1462 #define DAC1FID11_WATERTEMP_DIV		10.0
1463 		    unsigned int preciptype;	/* 0-7, enumerated */
1464 #define DAC1FID11_PRECIPTYPE_NOT_AVAILABLE	7
1465 		    unsigned int salinity;	/* units of 0.1ppt */
1466 #define DAC1FID11_SALINITY_NOT_AVAILABLE	511
1467 #define DAC1FID11_SALINITY_DIV		10.0
1468 		    unsigned int ice;		/* is there sea ice? */
1469 #define DAC1FID11_ICE_NOT_AVAILABLE		3
1470 		} dac1fid11;
1471 		/* IMO236 - Fairway Closed */
1472 		struct {
1473 		    char reason[20+1];		/* Reason For Closing */
1474 		    char closefrom[20+1];	/* Location Of Closing From */
1475 		    char closeto[20+1];		/* Location of Closing To */
1476 		    unsigned int radius;	/* Radius extension */
1477 #define AIS_DAC1FID13_RADIUS_NOT_AVAILABLE 10001
1478 		    unsigned int extunit;	/* Unit of extension */
1479 #define AIS_DAC1FID13_EXTUNIT_NOT_AVAILABLE 0
1480 		    unsigned int fday;		/* From day (UTC) */
1481 		    unsigned int fmonth;	/* From month (UTC) */
1482 		    unsigned int fhour;		/* From hour (UTC) */
1483 		    unsigned int fminute;	/* From minute (UTC) */
1484 		    unsigned int tday;		/* To day (UTC) */
1485 		    unsigned int tmonth;	/* To month (UTC) */
1486 		    unsigned int thour;		/* To hour (UTC) */
1487 		    unsigned int tminute;	/* To minute (UTC) */
1488 		} dac1fid13;
1489 	        /* IMO236 - Extended ship and voyage data */
1490 		struct {
1491 		    unsigned int airdraught;	/* Air Draught */
1492 		} dac1fid15;
1493 		/* IMO286 - Number of Persons on board */
1494 		struct {
1495 		    unsigned persons;	/* number of persons */
1496 		} dac1fid16;
1497 		/* IMO289 - VTS-generated/Synthetic Targets */
1498 		struct {
1499 		    signed int ntargets;
1500 		    struct target_t {
1501 #define DAC1FID17_IDTYPE_MMSI		0
1502 #define DAC1FID17_IDTYPE_IMO		1
1503 #define DAC1FID17_IDTYPE_CALLSIGN	2
1504 #define DAC1FID17_IDTYPE_OTHER		3
1505 			unsigned int idtype;	/* Identifier type */
1506 			union target_id {	/* Target identifier */
1507 			    unsigned int mmsi;
1508 			    unsigned int imo;
1509 #define DAC1FID17_ID_LENGTH		7
1510 			    // cppcheck-suppress arrayIndexOutOfBounds
1511 			    char callsign[DAC1FID17_ID_LENGTH+1];
1512 			    char other[DAC1FID17_ID_LENGTH+1];
1513 			} id;
1514 			signed int lat;		/* Latitude */
1515 			signed int lon;		/* Longitude */
1516 #define DAC1FID17_COURSE_NOT_AVAILABLE		360
1517 			unsigned int course;	/* Course Over Ground */
1518 			unsigned int second;	/* Time Stamp */
1519 #define DAC1FID17_SPEED_NOT_AVAILABLE		255
1520 			unsigned int speed;	/* Speed Over Ground */
1521 		    } targets[4];
1522 		} dac1fid17;
1523 		/* IMO 289 - Marine Traffic Signal */
1524 		struct {
1525 		    unsigned int linkage;	/* Message Linkage ID */
1526 		    char station[20+1];		/* Name of Signal Station */
1527 		    signed int lon;		/* Longitude */
1528 		    signed int lat;		/* Latitude */
1529 		    unsigned int status;	/* Status of Signal */
1530 		    unsigned int signal;	/* Signal In Service */
1531 		    unsigned int hour;		/* UTC hour */
1532 		    unsigned int minute;	/* UTC minute */
1533 		    unsigned int nextsignal;	/* Expected Next Signal */
1534 		} dac1fid19;
1535 		/* IMO289 - Route info (broadcast) */
1536 		struct route_info dac1fid27;
1537 		/* IMO289 - Text message (broadcast) */
1538 		struct {
1539 		    unsigned int linkage;
1540 #define AIS_DAC1FID29_TEXT_MAX	162	/* 920 bits of six-bit, plus NUL */
1541 		    char text[AIS_DAC1FID29_TEXT_MAX];
1542 		} dac1fid29;
1543 		/* IMO289 - Meteorological-Hydrological data */
1544 		struct {
1545 		    bool accuracy;	/* position accuracy, <10m if true */
1546 #define DAC1FID31_LATLON_SCALE	1000
1547 		    int lon;		/* longitude in minutes * .001 */
1548 #define DAC1FID31_LON_NOT_AVAILABLE	(181*60*DAC1FID31_LATLON_SCALE)
1549 		    int lat;		/* longitude in minutes * .001 */
1550 #define DAC1FID31_LAT_NOT_AVAILABLE	(91*60*DAC1FID31_LATLON_SCALE)
1551 		    unsigned int day;		/* UTC day */
1552 		    unsigned int hour;		/* UTC hour */
1553 		    unsigned int minute;	/* UTC minute */
1554 		    unsigned int wspeed;	/* average wind speed */
1555 		    unsigned int wgust;		/* wind gust */
1556 #define DAC1FID31_WIND_HIGH			126
1557 #define DAC1FID31_WIND_NOT_AVAILABLE		127
1558 		    unsigned int wdir;		/* wind direction */
1559 		    unsigned int wgustdir;	/* wind gust direction */
1560 #define DAC1FID31_DIR_NOT_AVAILABLE		360
1561 		    int airtemp;		/* temperature, units 0.1C */
1562 #define DAC1FID31_AIRTEMP_NOT_AVAILABLE		-1024
1563 #define DAC1FID31_AIRTEMP_DIV			10.0
1564 		    unsigned int humidity;	/* relative humidity, % */
1565 #define DAC1FID31_HUMIDITY_NOT_AVAILABLE	101
1566 		    int dewpoint;		/* dew point, units 0.1C */
1567 #define DAC1FID31_DEWPOINT_NOT_AVAILABLE	501
1568 #define DAC1FID31_DEWPOINT_DIV		10.0
1569 		    unsigned int pressure;	/* air pressure, hpa */
1570 #define DAC1FID31_PRESSURE_NOT_AVAILABLE	511
1571 #define DAC1FID31_PRESSURE_HIGH			402
1572 #define DAC1FID31_PRESSURE_OFFSET		-799
1573 		    unsigned int pressuretend;	/* tendency */
1574 #define DAC1FID31_PRESSURETEND_NOT_AVAILABLE	3
1575 		    bool visgreater;            /* visibility greater than */
1576 		    unsigned int visibility;	/* units 0.1 nautical miles */
1577 #define DAC1FID31_VISIBILITY_NOT_AVAILABLE	127
1578 #define DAC1FID31_VISIBILITY_DIV		10.0
1579 		    int waterlevel;		/* cm */
1580 #define DAC1FID31_WATERLEVEL_NOT_AVAILABLE	4001
1581 #define DAC1FID31_WATERLEVEL_OFFSET		1000
1582 #define DAC1FID31_WATERLEVEL_DIV		100.0
1583 		    unsigned int leveltrend;	/* water level trend code */
1584 #define DAC1FID31_WATERLEVELTREND_NOT_AVAILABLE	3
1585 		    unsigned int cspeed;	/* current speed in deciknots */
1586 #define DAC1FID31_CSPEED_NOT_AVAILABLE		255
1587 #define DAC1FID31_CSPEED_DIV			10.0
1588 		    unsigned int cdir;		/* current dir., degrees */
1589 		    unsigned int cspeed2;	/* current speed in deciknots */
1590 		    unsigned int cdir2;		/* current dir., degrees */
1591 		    unsigned int cdepth2;	/* measurement depth, 0.1m */
1592 #define DAC1FID31_CDEPTH_NOT_AVAILABLE		301
1593 #define DAC1FID31_CDEPTH_SCALE			10.0
1594 		    unsigned int cspeed3;	/* current speed in deciknots */
1595 		    unsigned int cdir3;		/* current dir., degrees */
1596 		    unsigned int cdepth3;	/* measurement depth, 0.1m */
1597 		    unsigned int waveheight;	/* in decimeters */
1598 #define DAC1FID31_HEIGHT_NOT_AVAILABLE		31
1599 #define DAC1FID31_HEIGHT_DIV			10.0
1600 		    unsigned int waveperiod;	/* in seconds */
1601 #define DAC1FID31_PERIOD_NOT_AVAILABLE		63
1602 		    unsigned int wavedir;	/* direction in degrees */
1603 		    unsigned int swellheight;	/* in decimeters */
1604 		    unsigned int swellperiod;	/* in seconds */
1605 		    unsigned int swelldir;	/* direction in degrees */
1606 		    unsigned int seastate;	/* Beaufort scale, 0-12 */
1607 #define DAC1FID31_SEASTATE_NOT_AVAILABLE	15
1608 		    int watertemp;		/* units 0.1deg Celsius */
1609 #define DAC1FID31_WATERTEMP_NOT_AVAILABLE	601
1610 #define DAC1FID31_WATERTEMP_DIV		10.0
1611 		    unsigned int preciptype;	/* 0-7, enumerated */
1612 #define DAC1FID31_PRECIPTYPE_NOT_AVAILABLE	7
1613 		    unsigned int salinity;   // units of 0.1 permil (ca. PSU)
1614 #define DAC1FID31_SALINITY_NOT_AVAILABLE	510
1615 #define DAC1FID31_SALINITY_DIV		10.0
1616 		    unsigned int ice;		/* is there sea ice? */
1617 #define DAC1FID31_ICE_NOT_AVAILABLE		3
1618 		} dac1fid31;
1619 	    };
1620 	} type8;
1621 	/* Type 9 - Standard SAR Aircraft Position Report */
1622 	struct {
1623 	    unsigned int alt;		/* altitude in meters */
1624 #define AIS_ALT_NOT_AVAILABLE	4095
1625 #define AIS_ALT_HIGH    	4094	/* 4094 meters or higher */
1626 	    unsigned int speed;		/* speed over ground in deciknots */
1627 #define AIS_SAR_SPEED_NOT_AVAILABLE	1023
1628 #define AIS_SAR_FAST_MOVER  	1022
1629 	    bool accuracy;		/* position accuracy */
1630 	    int lon;			/* longitude */
1631 	    int lat;			/* latitude */
1632 	    unsigned int course;	/* course over ground */
1633             /* seconds of UTC time, 0 to 59.
1634              * 60 == N/A, 61 == manual, 62 == dead reckoning,
1635              * 63 == inoperative */
1636 	    unsigned int second;	/* seconds of UTC time */
1637 	    unsigned int regional;	/* regional reserved */
1638 	    unsigned int dte;		/* data terminal enable */
1639 	    //unsigned int spare;	spare bits */
1640 	    bool assigned;		/* assigned-mode flag */
1641 	    bool raim;			/* RAIM flag */
1642 	    unsigned int radio;		/* radio status bits */
1643 	} type9;
1644 	/* Type 10 - UTC/Date Inquiry */
1645 	struct {
1646 	    //unsigned int spare;
1647 	    unsigned int dest_mmsi;	/* destination MMSI */
1648 	    //unsigned int spare2;
1649 	} type10;
1650 	/* Type 12 - Safety-Related Message */
1651 	struct {
1652 	    unsigned int seqno;		/* sequence number */
1653 	    unsigned int dest_mmsi;	/* destination MMSI */
1654 	    bool retransmit;		/* retransmit flag */
1655 	    //unsigned int spare;	spare bit(s) */
1656 #define AIS_TYPE12_TEXT_MAX	157	/* 936 bits of six-bit, plus NUL */
1657 	    char text[AIS_TYPE12_TEXT_MAX];
1658 	} type12;
1659 	/* Type 14 - Safety-Related Broadcast Message */
1660 	struct {
1661 	    //unsigned int spare;	spare bit(s) */
1662 #define AIS_TYPE14_TEXT_MAX	161	/* 952 bits of six-bit, plus NUL */
1663 	    char text[AIS_TYPE14_TEXT_MAX];
1664 	} type14;
1665 	/* Type 15 - Interrogation */
1666 	struct {
1667 	    //unsigned int spare;	spare bit(s) */
1668 	    unsigned int mmsi1;
1669 	    unsigned int type1_1;
1670 	    unsigned int offset1_1;
1671 	    //unsigned int spare2;	spare bit(s) */
1672 	    unsigned int type1_2;
1673 	    unsigned int offset1_2;
1674 	    //unsigned int spare3;	spare bit(s) */
1675 	    unsigned int mmsi2;
1676 	    unsigned int type2_1;
1677 	    unsigned int offset2_1;
1678 	    //unsigned int spare4;	spare bit(s) */
1679 	} type15;
1680 	/* Type 16 - Assigned Mode Command */
1681 	struct {
1682 	    //unsigned int spare;	spare bit(s) */
1683 	    unsigned int mmsi1;
1684 	    unsigned int offset1;
1685 	    unsigned int increment1;
1686 	    unsigned int mmsi2;
1687 	    unsigned int offset2;
1688 	    unsigned int increment2;
1689 	} type16;
1690 	/* Type 17 - GNSS Broadcast Binary Message */
1691 	struct {
1692 	    //unsigned int spare;	spare bit(s) */
1693 #define AIS_GNSS_LATLON_DIV	600.0
1694 	    int lon;			/* longitude */
1695 	    int lat;			/* latitude */
1696 	    //unsigned int spare2;	spare bit(s) */
1697 #define AIS_TYPE17_BINARY_MAX	736	/* 920 bits */
1698 	    size_t bitcount;		/* bit count of the data */
1699 	    char bitdata[(AIS_TYPE17_BINARY_MAX + 7) / 8];
1700 	} type17;
1701 	/* Type 18 - Standard Class B CS Position Report */
1702 	struct {
1703 	    unsigned int reserved;	/* altitude in meters */
1704 	    unsigned int speed;		/* speed over ground in deciknots */
1705 	    bool accuracy;		/* position accuracy */
1706 	    int lon;			/* longitude */
1707 #define AIS_GNS_LON_NOT_AVAILABLE	0x1a838
1708 	    int lat;			/* latitude */
1709 #define AIS_GNS_LAT_NOT_AVAILABLE	0xd548
1710 	    unsigned int course;	/* course over ground */
1711 	    unsigned int heading;	/* true heading */
1712             /* seconds of UTC time, 0 to 59.
1713              * 60 == N/A, 61 == manual, 62 == dead reckoning,
1714              * 63 == inoperative */
1715 	    unsigned int second;
1716 	    unsigned int regional;	/* regional reserved */
1717 	    bool cs;     		/* carrier sense unit flag */
1718 	    bool display;		/* unit has attached display? */
1719 	    bool dsc;   		/* unit attached to radio with DSC? */
1720 	    bool band;   		/* unit can switch frequency bands? */
1721 	    bool msg22;	        	/* can accept Message 22 management? */
1722 	    bool assigned;		/* assigned-mode flag */
1723 	    bool raim;			/* RAIM flag */
1724 	    unsigned int radio;		/* radio status bits */
1725 	} type18;
1726 	/* Type 19 - Extended Class B CS Position Report */
1727 	struct {
1728 	    unsigned int reserved;	/* altitude in meters */
1729 	    unsigned int speed;		/* speed over ground in deciknots */
1730 	    bool accuracy;		/* position accuracy */
1731 	    int lon;			/* longitude */
1732 	    int lat;			/* latitude */
1733 	    unsigned int course;	/* course over ground */
1734 	    unsigned int heading;	/* true heading */
1735             /* seconds of UTC time, 0 to 59.
1736              * 60 == N/A, 61 == manual, 62 == dead reckoning,
1737              * 63 == inoperative */
1738 	    unsigned int second;
1739 	    unsigned int regional;	/* regional reserved */
1740 	    // cppcheck-suppress arrayIndexOutOfBounds
1741 	    char shipname[AIS_SHIPNAME_MAXLEN+1];		/* ship name */
1742 	    unsigned int shiptype;	/* ship type code */
1743 	    unsigned int to_bow;	/* dimension to bow */
1744 	    unsigned int to_stern;	/* dimension to stern */
1745 	    unsigned int to_port;	/* dimension to port */
1746 	    unsigned int to_starboard;	/* dimension to starboard */
1747 	    unsigned int epfd;		/* type of position fix device */
1748 	    bool raim;			/* RAIM flag */
1749 	    unsigned int dte;    	/* date terminal enable */
1750 	    bool assigned;		/* assigned-mode flag */
1751 	    //unsigned int spare;	spare bits */
1752 	} type19;
1753 	/* Type 20 - Data Link Management Message */
1754 	struct {
1755 	    //unsigned int spare;	spare bit(s) */
1756 	    unsigned int offset1;	/* TDMA slot offset */
1757 	    unsigned int number1;	/* number of xlots to allocate */
1758 	    unsigned int timeout1;	/* allocation timeout */
1759 	    unsigned int increment1;	/* repeat increment */
1760 	    unsigned int offset2;	/* TDMA slot offset */
1761 	    unsigned int number2;	/* number of xlots to allocate */
1762 	    unsigned int timeout2;	/* allocation timeout */
1763 	    unsigned int increment2;	/* repeat increment */
1764 	    unsigned int offset3;	/* TDMA slot offset */
1765 	    unsigned int number3;	/* number of xlots to allocate */
1766 	    unsigned int timeout3;	/* allocation timeout */
1767 	    unsigned int increment3;	/* repeat increment */
1768 	    unsigned int offset4;	/* TDMA slot offset */
1769 	    unsigned int number4;	/* number of xlots to allocate */
1770 	    unsigned int timeout4;	/* allocation timeout */
1771 	    unsigned int increment4;	/* repeat increment */
1772 	} type20;
1773 	/* Type 21 - Aids to Navigation Report */
1774 	struct {
1775 	    unsigned int aid_type;	/* aid type */
1776 	    char name[35];		/* name of aid to navigation */
1777 	    bool accuracy;		/* position accuracy */
1778 	    int lon;			/* longitude */
1779 	    int lat;			/* latitude */
1780 	    unsigned int to_bow;	/* dimension to bow */
1781 	    unsigned int to_stern;	/* dimension to stern */
1782 	    unsigned int to_port;	/* dimension to port */
1783 	    unsigned int to_starboard;	/* dimension to starboard */
1784 	    unsigned int epfd;		/* type of EPFD */
1785             /* seconds of UTC time, 0 to 59.
1786              * 60 == N/A, 61 == manual, 62 == dead reckoning,
1787              * 63 == inoperative */
1788 	    unsigned int second;
1789 	    bool off_position;		/* off-position indicator */
1790 	    unsigned int regional;	/* regional reserved field */
1791 	    bool raim;			/* RAIM flag */
1792 	    bool virtual_aid;		/* is virtual station? */
1793 	    bool assigned;		/* assigned-mode flag */
1794 	    //unsigned int spare;	unused */
1795 	} type21;
1796 	/* Type 22 - Channel Management */
1797 	struct {
1798 	    //unsigned int spare;	spare bit(s) */
1799 	    unsigned int channel_a;	/* Channel A number */
1800 	    unsigned int channel_b;	/* Channel B number */
1801 	    unsigned int txrx;		/* transmit/receive mode */
1802 	    bool power;			/* high-power flag */
1803 #define AIS_CHANNEL_LATLON_DIV	600.0
1804 	    union {
1805 		struct {
1806 		    int ne_lon;		/* NE corner longitude */
1807 		    int ne_lat;		/* NE corner latitude */
1808 		    int sw_lon;		/* SW corner longitude */
1809 		    int sw_lat;		/* SW corner latitude */
1810 		} area;
1811 		struct {
1812 		    unsigned int dest1;	/* addressed station MMSI 1 */
1813 		    unsigned int dest2;	/* addressed station MMSI 2 */
1814 		} mmsi;
1815 	    };
1816 	    bool addressed;		/* addressed vs. broadcast flag */
1817 	    bool band_a;		/* fix 1.5kHz band for channel A */
1818 	    bool band_b;		/* fix 1.5kHz band for channel B */
1819 	    unsigned int zonesize;	/* size of transitional zone */
1820 	} type22;
1821 	/* Type 23 - Group Assignment Command */
1822 	struct {
1823 	    int ne_lon;			/* NE corner longitude */
1824 	    int ne_lat;			/* NE corner latitude */
1825 	    int sw_lon;			/* SW corner longitude */
1826 	    int sw_lat;			/* SW corner latitude */
1827 	    //unsigned int spare;	spare bit(s) */
1828 	    unsigned int stationtype;	/* station type code */
1829 	    unsigned int shiptype;	/* ship type code */
1830 	    //unsigned int spare2;	spare bit(s) */
1831 	    unsigned int txrx;		/* transmit-enable code */
1832 	    unsigned int interval;	/* report interval */
1833 	    unsigned int quiet;		/* quiet time */
1834 	    //unsigned int spare3;	spare bit(s) */
1835 	} type23;
1836 	/* Type 24 - Class B CS Static Data Report */
1837 	struct {
1838 	    char shipname[AIS_SHIPNAME_MAXLEN+1];	/* vessel name */
1839 	    enum {
1840 		both,
1841 		part_a,
1842 		part_b,
1843 	    } part;
1844 	    unsigned int shiptype;	/* ship type code */
1845 	    char vendorid[8];		/* vendor ID */
1846 	    unsigned int model;		/* unit model code */
1847 	    unsigned int serial;	/* serial number */
1848 	    char callsign[8];		/* callsign */
1849 	    union {
1850 		unsigned int mothership_mmsi;	/* MMSI of main vessel */
1851 		struct {
1852 		    unsigned int to_bow;	/* dimension to bow */
1853 		    unsigned int to_stern;	/* dimension to stern */
1854 		    unsigned int to_port;	/* dimension to port */
1855 		    unsigned int to_starboard;	/* dimension to starboard */
1856 		} dim;
1857 	    };
1858 	} type24;
1859 	/* Type 25 - Addressed Binary Message */
1860 	struct {
1861 	    bool addressed;		/* addressed-vs.broadcast flag */
1862 	    bool structured;		/* structured-binary flag */
1863 	    unsigned int dest_mmsi;	/* destination MMSI */
1864 	    unsigned int app_id;        /* Application ID */
1865 #define AIS_TYPE25_BINARY_MAX	128	/* Up to 128 bits */
1866 	    size_t bitcount;		/* bit count of the data */
1867 	    char bitdata[(AIS_TYPE25_BINARY_MAX + 7) / 8];
1868 	} type25;
1869 	/* Type 26 - Addressed Binary Message */
1870 	struct {
1871 	    bool addressed;		/* addressed-vs.broadcast flag */
1872 	    bool structured;		/* structured-binary flag */
1873 	    unsigned int dest_mmsi;	/* destination MMSI */
1874 	    unsigned int app_id;        /* Application ID */
1875 #define AIS_TYPE26_BINARY_MAX	1004	/* Up to 128 bits */
1876 	    size_t bitcount;		/* bit count of the data */
1877 	    char bitdata[(AIS_TYPE26_BINARY_MAX + 7) / 8];
1878 	    unsigned int radio;		/* radio status bits */
1879 	} type26;
1880 	/* Type 27 - Long Range AIS Broadcast message */
1881 	struct {
1882 	    bool accuracy;		/* position accuracy */
1883 	    bool raim;			/* RAIM flag */
1884 	    unsigned int status;	/* navigation status */
1885 #define AIS_LONGRANGE_LATLON_DIV	600.0
1886 	    int lon;			/* longitude */
1887 #define AIS_LONGRANGE_LON_NOT_AVAILABLE	0x1a838
1888 	    int lat;			/* latitude */
1889 #define AIS_LONGRANGE_LAT_NOT_AVAILABLE	0xd548
1890 	    unsigned int speed;		/* speed over ground in deciknots */
1891 #define AIS_LONGRANGE_SPEED_NOT_AVAILABLE 63
1892 	    unsigned int course;	/* course over ground */
1893 #define AIS_LONGRANGE_COURSE_NOT_AVAILABLE 511
1894 	    bool gnss;			/* are we reporting GNSS position? */
1895 	} type27;
1896     };
1897 };
1898 
1899 
1900 /* basic data, per PRN, from GPGSA and GPGSV, or GPS binary messages */
1901 /* FIXME: u-blox 9 no longer uses PRN */
1902 struct satellite_t {
1903     /* SNR. signal-to-noise ratio, 0 to 254 dB, u-blox can be 0 to 63.
1904      * -1 for n/a */
1905     double ss;
1906     bool used;		/* this satellite used in solution */
1907     /* PRN of this satellite, 1 to 437, 0 for n/a
1908      * sadly there is no standard, but many different implementations of
1909      * how to code PRN
1910      */
1911     short PRN;          /* PRN numbering per NMEA 2.x to 4.0, not 4.10 */
1912     double elevation;	/* elevation of satellite, -90 to 90 deg, NAN for n/a */
1913     double azimuth;	/* azimuth, 0 to 359 deg, NAN1 for n/a */
1914     /* gnssid:svid:sigid, as defined by u-blox 8/9:
1915      *  gnssid        svid (native PRN)
1916      *  0 = GPS       1-32
1917      *  1 = SBAS      120-158
1918      *  2 = Galileo   1-36
1919      *  3 - BeiDou    1-37
1920      *  4 = IMES      1-10
1921      *  5 = QZSS      1-5       Undocumented u-blox goes to 7
1922      *  6 = GLONASS   1-32, 255
1923      *  x = IRNSS    1-11       Not defined by u-blox:
1924      *
1925      * gnssid:svid:sigid, as defined by NMEA 4.10, NOT USED HERE!
1926      *  1 = GPS       1-32
1927      *  1 = SBAS      33-64, 152-158
1928      *  1 = QZSS      193-197  Undocuemtned u-blox goes to 199
1929      *  2 = GLONASS   1-32, nul
1930      *  3 = Galileo   1-36
1931      *  4 - BeiDou    1-37
1932      *  x = IMES                Not defined by NMEA 4.10
1933      *
1934      * Note: other GNSS receivers use different mappings!
1935      */
1936     unsigned char gnssid;
1937 /* defines for u-blox gnssId, as used in satellite_t */
1938 #define GNSSID_GPS 0
1939 #define GNSSID_SBAS 1
1940 #define GNSSID_GAL 2
1941 #define GNSSID_BD 3
1942 #define GNSSID_IMES 4
1943 #define GNSSID_QZSS 5
1944 #define GNSSID_GLO 6
1945 #define GNSSID_IRNSS 7            /* Not defined by u-blox */
1946 #define GNSSID_CNT 8              /* count for array size */
1947 
1948     /* ignore gnssid and sigid if svid is zero */
1949     unsigned char svid;
1950     /* sigid as defined by u-blox 9, and used here
1951      * GPS:      0 = L1C/A, 3 = L2 CL, 4 = L2 CM
1952      * SBAS:     0 = L1C/A, ? = L5I
1953      * Galileo:  0 = E1 C,  1 = E1 B,  5 = E5 bl, 6 = E5 bQ
1954      * BeiDou:   0 = B1I D1, 1 = B1I D2, 2 = B2I D1, 3 = B2I D2
1955      * QZSS:     0 = L1C/A, 4 = L2 CM, 5 = L2 CL
1956      * GLONASS:  0 = L1 OF, 2 = L2 OF
1957      *
1958      * sigid as defined by NMEA 4.10, NOT used here
1959      * GPS:      1 = L1C/A, 6 = L2 CL, 5 = L2 CM
1960      * Galileo:  7 = E1 C,  7 = E1 B,  2 = E5 bl, 2 = E5 bQ
1961      * BeiDou:   1 = B1|D1, 1 = B1|D2, 3 = B2|D1, 3 = B2|D2
1962      * QZSS:     not defined
1963      * GLONASS:  1 = L1 OF, 3 = L2 OF
1964      */
1965     unsigned char sigid;
1966     signed char freqid;         /* The GLONASS (Only) frequency, 0 - 13 */
1967     unsigned char health;       /* 0 = unknown, 1 = healthy, 2 = unhealthy */
1968 #define SAT_HEALTH_UNK 0
1969 #define SAT_HEALTH_OK 1
1970 #define SAT_HEALTH_BAD 2
1971 };
1972 
1973 struct attitude_t {
1974     timespec_t	mtime;  /* time of measurement */
1975     double acc_len; /* unitvector sqrt(x^2 + y^2 +z^2) */
1976     double acc_x;
1977     double acc_y;
1978     double acc_z;
1979     double depth;
1980     double dip;
1981     double gyro_x;
1982     double gyro_y;
1983     double heading;
1984     double mag_len; /* unitvector sqrt(x^2 + y^2 +z^2) */
1985     double mag_x;
1986     double mag_y;
1987     double mag_z;
1988     double pitch;
1989     double roll;
1990     double temp;
1991     double yaw;
1992     /* compass status -- TrueNorth (and any similar) devices only */
1993     char mag_st;
1994     char pitch_st;
1995     char roll_st;
1996     char yaw_st;
1997 };
1998 
1999 struct navdata_t {
2000     unsigned int version;
2001     double compass_heading;
2002     double compass_deviation;
2003     double compass_variation;
2004     double air_temp;
2005     double air_pressure;
2006     double water_temp;
2007     double depth;
2008     double depth_offset;
2009     double wind_speed;
2010     double wind_dir;
2011     double crosstrack_error;
2012     unsigned int compass_status;
2013     unsigned int log_cumulative;
2014     unsigned int log_trip;
2015     unsigned int crosstrack_status;
2016 };
2017 
2018 struct dop_t {
2019     /* Dilution of precision factors */
2020     double xdop, ydop, pdop, hdop, vdop, tdop, gdop;
2021 };
2022 
2023 struct rawdata_t {
2024     /* raw measurement data, suitable for RINEX 3 */
2025     timespec_t mtime;		/* time of measurement: sec, nsec
2026                                  * Note: GPS time, not UTC time */
2027     struct meas_t {
2028         /* gnssid see satellite_t for decode */
2029         unsigned char gnssid;
2030         /* svid see RINEX 3 for decode, not satellite_t */
2031         unsigned char svid;
2032         /* sigid see satellite_t for decode */
2033         unsigned char sigid;
2034         /* SNR.  0 to 100 dB-Hz.  u-blox can be 0 to 63. */
2035         unsigned char snr;
2036         unsigned char freqid;   /* The GLONASS (Only) frequency, 0 - 13 */
2037         unsigned char lli;      /* RINEX Loss of Lock Indicator
2038                                  * bit 0 - Lost Lock
2039                                  * bit 1 - half-cycle ambiguity/slip possible
2040                                  * bit 2 - GALILEO BOC-tracking of MBOC signal
2041                                  */
2042         char obs_code[4];       /* 3 char RINEX observation code */
2043         /* see RINEX documenetation
2044          * GPS: L1: L1C, L1S, L1L, L1X, L1P, L1W, L1N
2045          *      L2: L2C, L2D, L2S, L2L, L2X, L2P, L2W, L2N
2046          *      L5: L5I, L5Q
2047          * GLONASS: G1: L1C, L1P
2048          *          G2: L2C, L2P
2049          *          G3: L3I, L3Q, L3X
2050          * GALILEO: E1: L1B, L1C, L1X
2051          *          E5A: L5I, L5Ql L5X
2052          *          E5B: L7I, L7Q, L7X
2053          *          E5(A+B): L8I, L8Q, L8X
2054          *          E6: L6B, L6C, L6X
2055          * QZSS: L1: L1C, L1S, L1L, L1X, L1Z
2056          *       L2: L2S, L2L, L2X
2057          *       L5: L5I, L5Q, L5X
2058          *       LEX(6): L6S, L6L, L6X
2059          * BeiDou: B1: L2I, L2Q, L2X
2060          *         B2: L7I, L7Q, L7X
2061          *         B3: L6I, L6Q, L6X
2062          * IRNSS: L5: L5A, L5B, L5C, L5X
2063          *        S: L9A, L9B, L9C, L9X
2064          */
2065         double codephase;	/* meters */
2066         double carrierphase;	/* L1 C/A meters, RINEX L1C */
2067         double pseudorange;	/* L1 C/A meters, RINEX C1C */
2068         double deltarange;	/* L1 C/A meters/sec, RINEX D1C */
2069         double doppler;	        /* Hz */
2070 #define LOCKMAX         64500   /* locktime capped at 64500 */
2071         unsigned locktime;      /* Carrier Phase Locktime in ms.
2072                                  * max 64,500 ms */
2073         double l2c;		/* L2 C/A carrier phase meters, RINEX L2C */
2074         double c2c;	        /* L2 C/A pseudo-range meters, RINEX C2C */
2075         unsigned satstat;	/* tracking status */
2076 #define SAT_ACQUIRED	0x01	/* satellite acquired */
2077 #define SAT_CODE_TRACK	0x02	/* code-tracking loop acquired */
2078 #define SAT_CARR_TRACK	0x04	/* carrier-tracking loop acquired */
2079 #define SAT_DATA_SYNC	0x08	/* data-bit synchronization done */
2080 #define SAT_FRAME_SYNC	0x10	/* frame synchronization done */
2081 #define SAT_EPHEMERIS	0x20	/* ephemeris collected */
2082 #define SAT_FIX_USED	0x40	/* used for position fix */
2083     } meas[MAXCHANNELS];
2084 };
2085 
2086 struct version_t {
2087     char release[64];			/* external version */
2088     char rev[64];			/* internal revision ID */
2089     int proto_major, proto_minor;	/* API major and minor versions */
2090     char remote[GPS_PATH_MAX];		/* could be from a remote device */
2091 };
2092 
2093 #define HEXDATA_MAX 512                 /* hex encoded command buffer, max */
2094 struct devconfig_t {
2095     char path[GPS_PATH_MAX];
2096     int flags;
2097 #define SEEN_GPS 	0x01
2098 #define SEEN_RTCM2	0x02
2099 #define SEEN_RTCM3	0x04
2100 #define SEEN_AIS 	0x08
2101     char driver[64];
2102     /* 96 too small for ZED-F9 */
2103     char subtype[128];           // maybe hardware version
2104     char subtype1[128];          // maybe software version
2105     /* a buffer to hold data to output to GPS */
2106     char hexdata[HEXDATA_MAX];
2107     timespec_t activated;
2108     unsigned int baudrate, stopbits;	/* RS232 link parameters */
2109     char parity;			/* 'N', 'O', or 'E' */
2110     timespec_t cycle, mincycle;     	/* refresh cycle time in seconds */
2111     int driver_mode;    		/* is driver in native mode or not? */
2112 };
2113 
2114 struct gps_policy_t {
2115     bool watcher;			/* is watcher mode on? */
2116     bool json;				/* requesting JSON? */
2117     bool nmea;				/* requesting dumping as NMEA? */
2118     int raw;				/* requesting raw data? */
2119     bool scaled;			/* requesting report scaling? */
2120     bool timing;			/* requesting timing info */
2121     bool split24;			/* requesting split AIS Type 24s */
2122     bool pps;				/* requesting PPS in NMEA/raw modes */
2123     int loglevel;			/* requested log level of messages */
2124     char devpath[GPS_PATH_MAX];		/* specific device to watch */
2125     char remote[GPS_PATH_MAX];		/* ...if this was passthrough */
2126 };
2127 
2128 #ifndef TIMEDELTA_DEFINED
2129 #define TIMEDELTA_DEFINED
2130 
2131 struct timedelta_t {
2132     timespec_t	real;
2133     timespec_t	clock;
2134 };
2135 #endif /* TIMEDELTA_DEFINED */
2136 
2137 struct oscillator_t {
2138     bool running;			/* oscillator is running */
2139     bool reference;			/* PPS reference is available */
2140     bool disciplined;			/* oscillator is GPS-disciplined */
2141     int delta;				/* last observed PPS delta */
2142 };
2143 
2144 /*
2145  * Someday we may support Windows, under which socket_t is a separate type.
2146  * In the meantime, having a typedef for this semantic kind is no bad thing,
2147  * as it makes clearer what some declarations are doing without breaking
2148  * binary compatibility.
2149  */
2150 typedef int socket_t;
2151 #define BAD_SOCKET(s)	((s) == -1)
2152 #define INVALIDATE_SOCKET(s)	do { s = -1; } while (0)
2153 
2154 /* mode flags for setting streaming policy */
2155 #define WATCH_ENABLE	0x000001u	/* enable streaming */
2156 #define WATCH_DISABLE	0x000002u	/* disable watching */
2157 #define WATCH_JSON	0x000010u	/* JSON output */
2158 #define WATCH_NMEA	0x000020u	/* output in NMEA */
2159 #define WATCH_RARE	0x000040u	/* output of packets in hex */
2160 #define WATCH_RAW	0x000080u	/* output of raw packets */
2161 #define WATCH_SCALED	0x000100u	/* scale output to floats */
2162 #define WATCH_TIMING	0x000200u	/* timing information */
2163 #define WATCH_DEVICE	0x000800u	/* watch specific device */
2164 #define WATCH_SPLIT24	0x001000u	/* split AIS Type 24s */
2165 #define WATCH_PPS	0x002000u	/* enable PPS JSON */
2166 #define WATCH_NEWSTYLE	0x010000u	/* force JSON streaming */
2167 
2168 /*
2169  * Main structure that includes all previous substructures
2170  */
2171 
2172 struct gps_data_t {
2173     gps_mask_t set;	/* has field been set since this was last cleared? */
2174 #define ONLINE_SET	(1llu<<1)
2175 #define TIME_SET	(1llu<<2)
2176 #define TIMERR_SET	(1llu<<3)
2177 #define LATLON_SET	(1llu<<4)
2178 #define ALTITUDE_SET	(1llu<<5)
2179 #define SPEED_SET	(1llu<<6)
2180 #define TRACK_SET	(1llu<<7)
2181 #define CLIMB_SET	(1llu<<8)
2182 #define STATUS_SET	(1llu<<9)
2183 #define MODE_SET	(1llu<<10)
2184 #define DOP_SET  	(1llu<<11)
2185 #define HERR_SET	(1llu<<12)
2186 #define VERR_SET	(1llu<<13)
2187 #define ATTITUDE_SET	(1llu<<14)
2188 #define SATELLITE_SET	(1llu<<15)
2189 #define SPEEDERR_SET	(1llu<<16)
2190 #define TRACKERR_SET	(1llu<<17)
2191 #define CLIMBERR_SET	(1llu<<18)
2192 #define DEVICE_SET	(1llu<<19)
2193 #define DEVICELIST_SET	(1llu<<20)
2194 #define DEVICEID_SET	(1llu<<21)
2195 #define RTCM2_SET	(1llu<<22)
2196 #define RTCM3_SET	(1llu<<23)
2197 #define AIS_SET 	(1llu<<24)
2198 #define PACKET_SET	(1llu<<25)
2199 #define SUBFRAME_SET	(1llu<<26)
2200 #define GST_SET 	(1llu<<27)
2201 #define VERSION_SET	(1llu<<28)
2202 #define POLICY_SET	(1llu<<29)
2203 #define LOGMESSAGE_SET	(1llu<<30)
2204 #define ERROR_SET	(1llu<<31)
2205 #define TOFF_SET	(1llu<<32)	/* not yet used */
2206 #define PPS_SET 	(1llu<<33)
2207 #define NAVDATA_SET     (1llu<<34)
2208 #define OSCILLATOR_SET	(1llu<<35)
2209 #define ECEF_SET	(1llu<<36)
2210 #define VECEF_SET	(1llu<<37)
2211 #define MAGNETIC_TRACK_SET (1llu<<38)
2212 #define RAW_SET         (1llu<<39)
2213 #define NED_SET         (1llu<<40)
2214 #define VNED_SET        (1llu<<41)
2215 #define SET_HIGH_BIT	42
2216     timespec_t online;		/* NZ if GPS is on line, 0 if not.
2217 				 *
2218 				 * Note: gpsd clears this time when sentences
2219 				 * fail to show up within the GPS's normal
2220 				 * send cycle time. If the host-to-GPS
2221 				 * link is lossy enough to drop entire
2222 				 * sentences, this field will be
2223 				 * prone to false zero values.
2224 				 */
2225 
2226 #ifndef USE_QT
2227     socket_t gps_fd;		/* socket or file descriptor to GPS */
2228 #else
2229     void* gps_fd;
2230 #endif
2231     struct gps_fix_t	fix;	/* accumulated PVT data */
2232 
2233     /* GPS status -- always valid */
2234     int    status;		/* Do we have a fix? */
2235 #define STATUS_NO_FIX	0	/* no */
2236 /* yes, plain GPS (SPS Mode), without DGPS, PPS, RTK, DR, etc. */
2237 #define STATUS_FIX	1
2238 #define STATUS_DGPS_FIX	2	/* yes, with DGPS */
2239 #define STATUS_RTK_FIX	3	/* yes, with RTK Fixed */
2240 #define STATUS_RTK_FLT	4	/* yes, with RTK Float */
2241 #define STATUS_DR	5	/* yes, with dead reckoning */
2242 #define STATUS_GNSSDR	6	/* yes, with GNSS + dead reckoning */
2243 #define STATUS_TIME	7	/* yes, time only (surveyed in, manual) */
2244 #define STATUS_SIM	8	/* yes, simulated */
2245 /* yes, Precise Positioning Service (PPS)
2246  * Not to be confused with Pulse per Second (PPS)
2247  * PPS is the encrypted military P(Y)-code */
2248 #define STATUS_PPS_FIX	9
2249 
2250     /* precision of fix -- valid if satellites_used > 0 */
2251     int satellites_used;	/* Number of satellites used in solution */
2252     struct dop_t dop;
2253 
2254     /* satellite status -- valid when satellites_visible > 0 */
2255     timespec_t skyview_time;	/* skyview time */
2256     int satellites_visible;	/* # of satellites in view */
2257     struct satellite_t skyview[MAXCHANNELS];
2258 
2259     struct devconfig_t dev;	/* device that shipped last update */
2260 
2261     struct gps_policy_t policy;	/* our listening policy */
2262 
2263     struct {
2264 	timespec_t time;
2265 	int ndevices;
2266 	struct devconfig_t list[MAXUSERDEVS];
2267     } devices;
2268 
2269     /* pack things never reported together to reduce structure size */
2270 #define UNION_SET	(AIS_SET|ATTITUDE_SET|ERROR_SET|GST_SET| \
2271 			 LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
2272 			 RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
2273 
2274     union {
2275 	/* unusual forms of sensor data that might come up the pipe */
2276 	struct rtcm2_t	rtcm2;
2277 	struct rtcm3_t	rtcm3;
2278 	struct subframe_t subframe;
2279 	struct ais_t ais;
2280 	struct attitude_t attitude;
2281         struct navdata_t navdata;
2282 	struct rawdata_t raw;
2283 	struct gst_t gst;
2284 	struct oscillator_t osc;
2285 	/* "artificial" structures for various protocol responses */
2286 	struct version_t version;
2287 	char error[256];
2288     };
2289 
2290     /* time stuff */
2291     /* FIXME! next lib rev need to add a place to put PPS precision */
2292     struct timedelta_t toff;
2293     struct timedelta_t pps;
2294     /* quantization error adjustment to PPS. aka "sawtooth" correction */
2295     long qErr;                  /* offset in picoseconds (ps) */
2296     /* time of PPS pulse that qErr applies to */
2297     timespec_t qErr_time;
2298 
2299     /* Private data - client code must not set this */
2300     void *privdata;
2301 };
2302 
2303 extern int gps_open(const char *, const char *,
2304 		      struct gps_data_t *);
2305 extern int gps_close(struct gps_data_t *);
2306 extern int gps_send(struct gps_data_t *, const char *, ... );
2307 extern int gps_read(struct gps_data_t *, char *message, int message_len);
2308 extern int gps_unpack(char *, struct gps_data_t *);
2309 extern bool gps_waiting(const struct gps_data_t *, int);
2310 extern int gps_stream(struct gps_data_t *, unsigned int, void *);
2311 extern int gps_mainloop(struct gps_data_t *, int,
2312 			void (*)(struct gps_data_t *));
2313 extern const char *gps_data(const struct gps_data_t *);
2314 extern const char *gps_errstr(const int);
2315 
2316 int json_toff_read(const char *buf, struct gps_data_t *,
2317 		  const char **);
2318 int json_pps_read(const char *buf, struct gps_data_t *,
2319 		  const char **);
2320 int json_oscillator_read(const char *buf, struct gps_data_t *,
2321 			 const char **);
2322 
2323 /* dependencies on struct gpsdata_t end here */
2324 
2325 extern void libgps_trace(int errlevel, const char *, ...);
2326 
2327 extern void gps_clear_att(struct attitude_t *);
2328 extern void gps_clear_dop( struct dop_t *);
2329 extern void gps_clear_fix(struct gps_fix_t *);
2330 extern void gps_merge_fix(struct gps_fix_t *, gps_mask_t, struct gps_fix_t *);
2331 extern void gps_enable_debug(int, FILE *);
2332 extern const char *gps_maskdump(gps_mask_t);
2333 
2334 extern double safe_atof(const char *);
2335 extern time_t mkgmtime(struct tm *);
2336 extern timespec_t iso8601_to_timespec(char *);
2337 extern char *now_to_iso8601(char[], size_t len);
2338 extern char *timespec_to_iso8601(timespec_t t, char[], size_t len);
2339 extern double earth_distance(double, double, double, double);
2340 extern double earth_distance_and_bearings(double, double, double, double,
2341 					  double *,
2342 					  double *);
2343 extern double wgs84_separation(double, double);
2344 extern double mag_var(double, double);
2345 extern void datum_code_string(int code, char *buffer, size_t len);
2346 
2347 /* some multipliers for interpreting GPS output */
2348 #define METERS_TO_FEET	(1 / 0.3048)	/* Meters to International Foot */
2349 /* Note: not the same as the USA Survey Foot: (3937 / 1200)
2350  * Some states use the International Foot, not the USA Survey Foot */
2351 #define METERS_TO_MILES	0.00062137119	/* Meters to miles */
2352 #define METERS_TO_FATHOMS	0.54680665	/* Meters to fathoms */
2353 #define KNOTS_TO_MPH	1.1507794	/* Knots to miles per hour */
2354 #define KNOTS_TO_KPH	1.852		/* Knots to kilometers per hour */
2355 #define KNOTS_TO_MPS	0.51444444	/* Knots to meters per second */
2356 #define MPS_TO_KPH	3.6		/* Meters per second to klicks/hr */
2357 #define MPS_TO_MPH	2.2369363	/* Meters/second to miles per hour */
2358 #define MPS_TO_KNOTS	1.9438445	/* Meters per second to knots */
2359 /* miles and knots are both the international standard versions of the units */
2360 
2361 /* angle conversion multipliers */
2362 #define GPS_PI      	3.1415926535897932384626433832795029
2363 #define RAD_2_DEG	57.2957795130823208767981548141051703
2364 #define DEG_2_RAD	0.0174532925199432957692369076848861271
2365 
2366 /* other mathematical constants */
2367 #define GPS_LN2         0.693147180559945309417232121458176568
2368 
2369 
2370 /* WGS84(G1674) degining parameters */
2371 /* https://en.wikipedia.org/wiki/Geodetic_datum
2372  * Section #World_Geodetic_System_1984_(WGS_84)
2373  *
2374  * http://www.unoosa.org/pdf/icg/2012/template/WGS_84.pdf
2375  */
2376 #define WGS84A 6378137.0	     /* equatorial radius (semi-major axis) */
2377 #define WGS84F 298.257223563	        /* flattening */
2378 #define WGS84B 6356752.314245	        /* polar radius (semi-minor axis) */
2379 /* 1st eccentricity squared = (WGS84A ^ 2 + WGS84B ^ 2) / (WGS84A ^ 2)
2380  * precomputed so C does not recompute every time */
2381 #define WGS84E 0.006694379990197585	/* 1st eccentricity squared */
2382 /* 2nd eccentricity squared = ((WGS84A ^ 2 - WGS84B ^ 2) / (WGS84B ^ 2)
2383  * precomputed so C does not recompute every time */
2384 #define WGS84E2 0.006739496742333464    /* 2nd eccentricy squared */
2385 
2386 #define CLIGHT      299792458.0  /* speed of light (m/s) */
2387 
2388 /* netlib_connectsock() errno return values */
2389 #define NL_NOSERVICE	-1	/* can't get service entry */
2390 #define NL_NOHOST	-2	/* can't get host entry */
2391 #define NL_NOPROTO	-3	/* can't get protocol entry */
2392 #define NL_NOSOCK	-4	/* can't create socket */
2393 #define NL_NOSOCKOPT	-5	/* error SETSOCKOPT SO_REUSEADDR */
2394 #define NL_NOCONNECT	-6	/* can't connect to host/socket pair */
2395 #define SHM_NOSHARED	-7	/* shared-memory segment not available */
2396 #define SHM_NOATTACH	-8	/* shared-memory attach failed */
2397 #define DBUS_FAILURE	-9	/* DBUS initialization failure */
2398 
2399 #define DEFAULT_GPSD_PORT	"2947"	/* IANA assignment */
2400 #define DEFAULT_RTCM_PORT	"2101"	/* IANA assignment */
2401 
2402 /* special host values for non-socket exports */
2403 #define GPSD_SHARED_MEMORY	"shared memory"
2404 #define GPSD_DBUS_EXPORT	"DBUS export"
2405 
2406 #ifdef __cplusplus
2407 }  /* End of the 'extern "C"' block */
2408 #endif
2409 
2410 #endif /* _GPSD_GPS_H_ */
2411 /* gps.h ends here */
2412