15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* gps.h -- interface of the libgps library */
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This file is Copyright (c) 2010 by the GPSD project
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * BSD terms apply: see the file COPYING in the distribution root for details.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef _GPSD_GPS_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _GPSD_GPS_H_
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __cplusplus
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" {
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Macro for declaring function arguments unused. */
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__GNUC__)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define UNUSED __attribute__((unused)) /* Flag variable as unused */
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else /* not __GNUC__ */
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define UNUSED
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h>
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/time.h>
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdbool.h>
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <inttypes.h>	/* stdint.h would be smaller but not all have it */
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits.h>
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <time.h>
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <signal.h>
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef S_SPLINT_S
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <pthread.h>	/* pacifies OpenBSD's compiler */
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4.1 - Base version for initial JSON protocol (Dec 2009, release 2.90)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4.2 - AIS application IDs split into DAC and FID (July 2010, release 2.95)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5.0 - MAXCHANNELS bumped from 20 to 32 for GLONASS (Mar 2011, release 2.96)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *       gps_open() becomes reentrant, what gps_open_r() used to be.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *       gps_poll() removed in favor of gps_read().  The raw hook is gone.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GPSD_API_MAJOR_VERSION	5	/* bump on incompatible changes */
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GPSD_API_MINOR_VERSION	0	/* bump on compatible changes */
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAXTAGLEN	8	/* maximum length of sentence tag name */
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAXCHANNELS	72	/* must be > 12 GPS + 12 GLONASS + 2 WAAS */
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GPS_PRNMAX	32	/* above this number are SBAS satellites */
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GPS_PATH_MAX	64	/* dev files usually have short names */
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAXUSERDEVS	4	/* max devices per user */
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The structure describing an uncertainty volume in kinematic space.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is what GPSes are meant to produce; all the other info is
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * technical impedimenta.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All double values use NAN to indicate data not available.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Usually all the information in this structure was considered valid
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * by the GPS at the time of update.  This will be so if you are using
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a GPS chipset that speaks SiRF binary, Garmin binary, or Zodiac binary.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This covers over 80% of GPS products in early 2005.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If you are using a chipset that speaks NMEA, this structure is updated
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in bits by GPRMC (lat/lon, track, speed), GPGGA (alt, climb), GPGLL
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (lat/lon), and GPGSA (eph, epv).  Most NMEA GPSes take a single fix
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * at the beginning of a 1-second cycle and report the same timestamp in
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * GPRMC, GPGGA, and GPGLL; for these, all info is guaranteed correctly
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * synced to the time member, but you'll get different stages of the same
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * update depending on where in the cycle you poll.  A very few GPSes,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * like the Garmin 48, take a new fix before more than one of of
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * GPRMC/GPGGA/GPGLL during a single cycle; thus, they may have different
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * timestamps and some data in this structure can be up to 1 cycle (usually
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1 second) older than the fix time.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Error estimates are at 95% confidence.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef double timestamp_t;	/* Unix time in seconds with fractional part */
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct gps_fix_t {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    timestamp_t time;	/* Time of update */
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int    mode;	/* Mode of fix */
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MODE_NOT_SEEN	0	/* mode update not seen yet */
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MODE_NO_FIX	1	/* none */
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MODE_2D  	2	/* good for latitude/longitude */
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MODE_3D  	3	/* good for altitude/climb too */
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double ept;		/* Expected time uncertainty */
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double latitude;	/* Latitude in degrees (valid if mode >= 2) */
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double epy;  	/* Latitude position uncertainty, meters */
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double longitude;	/* Longitude in degrees (valid if mode >= 2) */
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double epx;  	/* Longitude position uncertainty, meters */
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double altitude;	/* Altitude in meters (valid if mode == 3) */
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double epv;  	/* Vertical position uncertainty, meters */
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double track;	/* Course made good (relative to true north) */
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double epd;		/* Track uncertainty, degrees */
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double speed;	/* Speed over ground, meters/sec */
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double eps;		/* Speed uncertainty, meters/sec */
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double climb;       /* Vertical speed, meters/sec */
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double epc;		/* Vertical speed uncertainty */
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The structure describing the pseudorange errors (GPGST)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct gst_t {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double utctime;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double rms_deviation;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double smajor_deviation;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double sminor_deviation;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double smajor_orientation;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double lat_err_deviation;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double lon_err_deviation;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double alt_err_deviation;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * From the RCTM104 2.x standard:
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "The 30 bit words (as opposed to 32 bit words) coupled with a 50 Hz
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * transmission rate provides a convenient timing capability where the
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * times of word boundaries are a rational multiple of 0.6 seconds."
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "Each frame is N+2 words long, where N is the number of message data
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * words. For example, a filler message (type 6 or 34) with no message
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * data will have N=0, and will consist only of two header words. The
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * maximum number of data words allowed by the format is 31, so that
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the longest possible message will have a total of 33 words."
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RTCM2_WORDS_MAX	33
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAXCORRECTIONS	18	/* max correction count in type 1 or 9 */
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAXSTATIONS	10	/* maximum stations in almanac, type 5 */
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* RTCM104 doesn't specify this, so give it the largest reasonable value */
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAXHEALTH	(RTCM2_WORDS_MAX-2)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef S_SPLINT_S
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A nominally 30-bit word (24 bits of data, 6 bits of parity)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * used both in the GPS downlink protocol described in IS-GPS-200
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and in the format for DGPS corrections used in RTCM-104v2.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef /*@unsignedintegraltype@*/ uint32_t isgps30bits_t;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* S_SPLINT_S */
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Values for "system" fields.  Note, the encoding logic is senstive to the
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * actual values of these; it's not sufficient that they're distinct.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NAVSYSTEM_GPS   	0
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NAVSYSTEM_GLONASS	1
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NAVSYSTEM_GALILEO	2
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NAVSYSTEM_UNKNOWN	3
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct rtcm2_t {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* header contents */
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned type;	/* RTCM message type */
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned length;	/* length (words) */
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double   zcount;	/* time within hour: GPS time, no leap secs */
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned refstaid;	/* reference station ID */
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned seqnum;	/* message sequence number (modulo 8) */
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned stathlth;	/* station health */
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* message data in decoded form */
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    union {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int nentries;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct gps_rangesat_t {	/* data from messages 1 & 9 */
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned ident;		/* satellite ID */
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned udre;		/* user diff. range error */
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned iod;		/* issue of data */
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		double prc;		/* range error */
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		double rrc;		/* range error rate */
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } sat[MAXCORRECTIONS];
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} gps_ranges;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {		/* data for type 3 messages */
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool valid;		/* is message well-formed? */
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double x, y, z;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} ecef;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {		/* data from type 4 messages */
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool valid;		/* is message well-formed? */
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int system;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int sense;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SENSE_INVALID	0
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SENSE_GLOBAL	1
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SENSE_LOCAL   	2
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char datum[6];
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double dx, dy, dz;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} reference;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {		/* data from type 5 messages */
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int nentries;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct consat_t {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned ident;		/* satellite ID */
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		bool iodl;		/* issue of data */
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned int health;	/* is satellite healthy? */
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HEALTH_NORMAL		(0)	/* Radiobeacon operation normal */
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HEALTH_UNMONITORED	(1)	/* No integrity monitor operating */
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HEALTH_NOINFO		(2)	/* No information available */
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HEALTH_DONOTUSE		(3)	/* Do not use this radiobeacon */
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       int snr;			/* signal-to-noise ratio, dB */
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SNR_BAD	-1			/* not reported */
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		bool health_en; 	/* health enabled */
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		bool new_data;		/* new data? */
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		bool los_warning;	/* line-of-sight warning */
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned int tou;	/* time to unhealth, seconds */
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } sat[MAXHEALTH];
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} conhealth;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {		/* data from type 7 messages */
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int nentries;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct station_t {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		double latitude, longitude;	/* location */
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned int range;		/* range in km */
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		double frequency;		/* broadcast freq */
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned int health;		/* station health */
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned int station_id;	/* of the transmitter */
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned int bitrate;		/* of station transmissions */
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } station[MAXSTATIONS];
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} almanac;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {		/* data for type 13 messages */
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool status;		/* expect a text message */
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool rangeflag;		/* station range altered? */
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double lat, lon;		/* station longitude/latitude */
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int range;		/* transmission range in km */
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} xmitter;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {		/* data from type 14 messages */
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int week;			/* GPS week (0-1023) */
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int hour;			/* Hour in week (0-167) */
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int leapsecs;		/* Leap seconds (0-63) */
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} gpstime;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int nentries;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct glonass_rangesat_t {		/* data from message type 31 */
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned ident;		/* satellite ID */
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned udre;		/* user diff. range error */
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned tod;		/* issue of data */
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		bool change;		/* ephemeris change bit */
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		double prc;		/* range error */
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		double rrc;		/* range error rate */
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } sat[MAXCORRECTIONS];
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} glonass_ranges;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* data from type 16 messages */
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	char message[(RTCM2_WORDS_MAX-2) * sizeof(isgps30bits_t)];
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* data from messages of unknown type */
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	isgps30bits_t	words[RTCM2_WORDS_MAX-2];
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* RTCM3 report structures begin here */
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RTCM3_MAX_SATELLITES	64
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RTCM3_MAX_DESCRIPTOR	31
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RTCM3_MAX_ANNOUNCEMENTS	32
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct rtcm3_rtk_hdr {		/* header data from 1001, 1002, 1003, 1004 */
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Used for both GPS and GLONASS, but their timebases differ */
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int station_id;	/* Reference Station ID */
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    time_t tow;			/* GPS Epoch Time (TOW) in ms,
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   or GLONASS Epoch Time in ms */
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool sync;			/* Synchronous GNSS Message Flag */
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned short satcount;	/* # Satellite Signals Processed */
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool smoothing;		/* Divergence-free Smoothing Indicator */
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned short interval;	/* Smoothing Interval */
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct rtcm3_basic_rtk {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char indicator;	/* Indicator */
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    short channel;		/* Satellite Frequency Channel Number
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   (GLONASS only) */
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double pseudorange;		/* Pseudorange */
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double rangediff;		/* PhaseRange – Pseudorange in meters */
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char locktime;	/* Lock time Indicator */
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct rtcm3_extended_rtk {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char indicator;	/* Indicator */
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    short channel;		/* Satellite Frequency Channel Number
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   (GLONASS only) */
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double pseudorange;		/* Pseudorange */
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double rangediff;		/* PhaseRange – L1 Pseudorange */
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char locktime;	/* Lock time Indicator */
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char ambiguity;	/* Integer Pseudorange
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					   Modulus Ambiguity */
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double CNR;			/* Carrier-to-Noise Ratio */
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct rtcm3_network_rtk_header {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int network_id;	/* Network ID */
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int subnetwork_id;	/* Subnetwork ID */
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    time_t time;		/* GPS Epoch Time (TOW) in ms */
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool multimesg;		/* GPS Multiple Message Indicator */
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned master_id;		/* Master Reference Station ID */
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned aux_id;		/* Auxilary Reference Station ID */
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char satcount;	/* count of GPS satellites */
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct rtcm3_correction_diff {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char ident;	/* satellite ID */
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    enum {reserved, correct, widelane, uncertain} ambiguity;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char nonsync;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double geometric_diff;	/* Geometric Carrier Phase
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   Correction Difference (1016, 1017) */
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char iode;		/* GPS IODE (1016, 1017) */
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double ionospheric_diff;	/* Ionospheric Carrier Phase
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   Correction Difference (1015, 1017) */
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct rtcm3_t {
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* header contents */
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned type;	/* RTCM 3.x message type */
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned length;	/* payload length, inclusive of checksum */
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    union {
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* 1001-1013 were present in the 3.0 version */
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct rtcm3_rtk_hdr	header;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct rtcm3_1001_t {
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned ident;			/* Satellite ID */
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct rtcm3_basic_rtk L1;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } rtk_data[RTCM3_MAX_SATELLITES];
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1001;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1002_t {
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct rtcm3_rtk_hdr	header;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned ident;			/* Satellite ID */
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct rtcm3_extended_rtk L1;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } rtk_data[RTCM3_MAX_SATELLITES];
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1002;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1003_t {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct rtcm3_rtk_hdr	header;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned ident;			/* Satellite ID */
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct rtcm3_basic_rtk L1;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct rtcm3_basic_rtk L2;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } rtk_data[RTCM3_MAX_SATELLITES];
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1003;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1004_t {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct rtcm3_rtk_hdr	header;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned ident;			/* Satellite ID */
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct rtcm3_extended_rtk L1;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct rtcm3_extended_rtk L2;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } rtk_data[RTCM3_MAX_SATELLITES];
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1004;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1005_t {
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int station_id;		/* Reference Station ID */
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int system;				/* Which system is it? */
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool reference_station;		/* Reference-station indicator */
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool single_receiver;		/* Single Receiver Oscillator */
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double ecef_x, ecef_y, ecef_z;	/* ECEF antenna location */
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1005;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1006_t {
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int station_id;		/* Reference Station ID */
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int system;				/* Which system is it? */
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool reference_station;		/* Reference-station indicator */
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool single_receiver;		/* Single Receiver Oscillator */
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double ecef_x, ecef_y, ecef_z;	/* ECEF antenna location */
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double height;			/* Antenna height */
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1006;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1007_t {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int station_id;			/* Reference Station ID */
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char descriptor[RTCM3_MAX_DESCRIPTOR+1];	/* Description string */
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned char setup_id;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1007;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1008_t {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int station_id;			/* Reference Station ID */
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char descriptor[RTCM3_MAX_DESCRIPTOR+1];	/* Description string */
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned char setup_id;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char serial[RTCM3_MAX_DESCRIPTOR+1];	/* Serial # string */
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1008;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1009_t {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct rtcm3_rtk_hdr	header;
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned ident;		/* Satellite ID */
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct rtcm3_basic_rtk L1;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } rtk_data[RTCM3_MAX_SATELLITES];
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1009;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1010_t {
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct rtcm3_rtk_hdr	header;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned ident;		/* Satellite ID */
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct rtcm3_extended_rtk L1;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } rtk_data[RTCM3_MAX_SATELLITES];
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1010;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1011_t {
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct rtcm3_rtk_hdr	header;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct {
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned ident;			/* Satellite ID */
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct rtcm3_extended_rtk L1;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct rtcm3_extended_rtk L2;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } rtk_data[RTCM3_MAX_SATELLITES];
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1011;
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1012_t {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct rtcm3_rtk_hdr	header;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct {
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned ident;			/* Satellite ID */
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct rtcm3_extended_rtk L1;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct rtcm3_extended_rtk L2;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } rtk_data[RTCM3_MAX_SATELLITES];
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1012;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1013_t {
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int station_id;	/* Reference Station ID */
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned short mjd;		/* Modified Julian Day (MJD) Number */
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int sod;		/* Seconds of Day (UTC) */
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned char leapsecs;	/* Leap Seconds, GPS-UTC */
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned char ncount;	/* Count of announcements to follow */
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned short id;		/* message type ID */
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		bool sync;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned short interval;	/* interval in 0.1sec units */
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } announcements[RTCM3_MAX_ANNOUNCEMENTS];
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1013;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* 1014-1017 were added in the 3.1 version */
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1014_t {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int network_id;	/* Network ID */
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int subnetwork_id;	/* Subnetwork ID */
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned char stationcount;	/* # auxiliary stations transmitted */
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int master_id;	/* Master Reference Station ID */
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int aux_id;	/* Auxilary Reference Station ID */
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_lat, d_lon, d_alt;	/* Aux-master location delta */
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1014;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1015_t {
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct rtcm3_network_rtk_header	header;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct rtcm3_correction_diff corrections[RTCM3_MAX_SATELLITES];
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1015;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1016_t {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct rtcm3_network_rtk_header	header;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct rtcm3_correction_diff corrections[RTCM3_MAX_SATELLITES];
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1016;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1017_t {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct rtcm3_network_rtk_header	header;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct rtcm3_correction_diff corrections[RTCM3_MAX_SATELLITES];
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1017;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* 1018-1029 were in the 3.0 version */
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1019_t {
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int ident;		/* Satellite ID */
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int week;		/* GPS Week Number */
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned char sv_accuracy;	/* GPS SV ACCURACY */
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    enum {reserved_code, p, ca, l2c} code;
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double idot;
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned char iode;
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* ephemeris fields, not scaled */
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int t_sub_oc;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int a_sub_f2;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int a_sub_f1;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int a_sub_f0;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int iodc;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int C_sub_rs;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int delta_sub_n;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int M_sub_0;
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int C_sub_uc;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int e;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int C_sub_us;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int sqrt_sub_A;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int t_sub_oe;
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int C_sub_ic;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int OMEGA_sub_0;
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int C_sub_is;
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int i_sub_0;
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int C_sub_rc;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int argument_of_perigee;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int omegadot;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int t_sub_GD;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned char sv_health;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool p_data;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool fit_interval;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1019;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1020_t {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int ident;		/* Satellite ID */
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned short channel;	/* Satellite Frequency Channel Number */
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* ephemeris fields, not scaled */
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool C_sub_n;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool health_avAilability_indicator;
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned char P1;
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned short t_sub_k;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool msb_of_B_sub_n;
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool P2;
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool t_sub_b;
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int x_sub_n_t_of_t_sub_b_prime;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int x_sub_n_t_of_t_sub_b;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int x_sub_n_t_of_t_sub_b_prime_prime;
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int y_sub_n_t_of_t_sub_b_prime;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int y_sub_n_t_of_t_sub_b;
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int y_sub_n_t_of_t_sub_b_prime_prime;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int z_sub_n_t_of_t_sub_b_prime;
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int z_sub_n_t_of_t_sub_b;
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int z_sub_n_t_of_t_sub_b_prime_prime;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool P3;
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int gamma_sub_n_of_t_sub_b;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned char MP;
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool Ml_n;
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int tau_n_of_t_sub_b;
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int M_delta_tau_sub_n;
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int E_sub_n;
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool MP4;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned char MF_sub_T;
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned char MN_sub_T;
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned char MM;
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool additioinal_data_availability;
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int N_sup_A;
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int tau_sub_c;
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int M_N_sub_4;
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed int M_tau_sub_GPS;
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool M_l_sub_n;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1020;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1029_t {
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int station_id;	/* Reference Station ID */
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned short mjd;		/* Modified Julian Day (MJD) Number */
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int sod;		/* Seconds of Day (UTC) */
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    size_t len;			/* # chars to follow */
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    size_t unicode_units;	/* # Unicode units in text */
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned char text[128];
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1029;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_1033_t {
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int station_id;			/* Reference Station ID */
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char descriptor[RTCM3_MAX_DESCRIPTOR+1];	/* Description string */
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned char setup_id;
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char serial[RTCM3_MAX_DESCRIPTOR+1];	/* Serial # string */
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char receiver[RTCM3_MAX_DESCRIPTOR+1];	/* Receiver string */
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char firmware[RTCM3_MAX_DESCRIPTOR+1];	/* Firmware string */
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} rtcm3_1033;
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	char data[1024];		/* Max RTCM3 msg length is 1023 bytes */
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } rtcmtypes;
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* RTCM3 scaling constants */
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GPS_AMBIGUITY_MODULUS		299792.458	/* 1004, DF014*/
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GLONASS_AMBIGUITY_MODULUS	599584.916	/* 1012, DF044 */
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MESSAGE_INTERVAL_UNITS		0.1		/* 1013, DF047 */
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Raw IS_GPS subframe data
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* The almanac is a subset of the clock and ephemeris data, with reduced
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * precision. See IS-GPS-200E, Table 20-VI  */
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct almanac_t
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8_t sv;  /* The satellite this refers to */
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* toa, almanac reference time, 8 bits unsigned, seconds */
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8_t toa;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    long l_toa;
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* SV health data, 8 bit unsigned bit map */
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8_t svh;
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* deltai, correction to inclination, 16 bits signed, semi-circles */
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int16_t deltai;
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double d_deltai;
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* M0, Mean Anomaly at Reference Time, 24 bits signed, semi-circles */
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32_t M0;
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double d_M0;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Omega0, Longitude of Ascending Node of Orbit Plane at Weekly Epoch,
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * 24 bits signed, semi-circles */
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32_t Omega0;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double d_Omega0;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* omega, Argument of Perigee, 24 bits signed, semi-circles */
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32_t omega;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double d_omega;
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* af0, SV clock correction constant term
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * 11 bits signed, seconds */
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int16_t af0;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double d_af0;
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* af1, SV clock correction first order term
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * 11 bits signed, seconds/second */
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int16_t af1;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double d_af1;
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* eccentricity, 16 bits, unsigned, dimensionless */
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint16_t e;
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double d_eccentricity;
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* sqrt A, Square Root of the Semi-Major Axis
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * 24 bits unsigned, square_root(meters) */
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32_t sqrtA;
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double d_sqrtA;
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Omega dot, Rate of Right Ascension, 16 bits signed, semi-circles/sec */
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int16_t Omegad;
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double d_Omegad;
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct subframe_t {
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* subframe number, 3 bits, unsigned, 1 to 5 */
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8_t subframe_num;
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* data_id, denotes the NAV data structure of D(t), 2 bits, in
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * IS-GPS-200E always == 0x1 */
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8_t data_id;
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* SV/page id used for subframes 4 & 5, 6 bits */
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8_t pageid;
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* tSVID, SV ID of the sat that transmitted this frame, 6 bits unsigned */
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8_t tSVID;
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* TOW, Time of Week of NEXT message, 17 bits unsigned, scale 6, seconds */
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32_t TOW17;
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    long l_TOW17;
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* integrity, URA bounds flag, 1 bit */
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool integrity;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* alert, alert flag, SV URA and/or the SV User Differential Range
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Accuracy (UDRA) may be worse than indicated, 1 bit */
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool alert;
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* antispoof, A-S mode is ON in that SV, 1 bit */
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool antispoof;
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int is_almanac;
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    union {
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* subframe 1, part of ephemeris, see IS-GPS-200E, Table 20-II
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * and Table 20-I */
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* WN, Week Number, 10 bits unsigned, scale 1, weeks */
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint16_t WN;
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* IODC, Issue of Data, Clock, 10 bits, unsigned,
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * issued in 8 data ranges at the same time */
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint16_t IODC;
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* toc, clock data reference time, 16 bits, unsigned, seconds
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * scale 2**4, issued in 8 data ranges at the same time */
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint16_t toc;
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    long l_toc;
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* l2, code on L2, 2 bits, bit map */
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint8_t l2;
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* l2p, L2 P data flag, 1 bit */
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint8_t l2p;
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* ura, SV accuracy, 4 bits unsigned index */
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int ura;
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* hlth, SV health, 6 bits unsigned bitmap */
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int hlth;
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* af0, SV clock correction constant term
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * 22 bits signed, scale 2**-31, seconds */
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int32_t af0;
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_af0;
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* af1, SV clock correction first order term
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * 22 bits signed, scale 2**-43, seconds/second */
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int16_t af1;
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_af1;
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* af2, SV clock correction second order term
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * 8 bits signed, scale 2**-55, seconds/second**2 */
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int8_t af2;
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_af2;
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Tgd,  L1-L2 correction term, 8 bits signed,  scale 2**-31,
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * seconds */
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int8_t Tgd;
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_Tgd;
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} sub1;
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* subframe 2, part of ephemeris, see IS-GPS-200E, Table 20-II
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * and Table 20-III */
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Issue of Data (Ephemeris),
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * equal to the 8 LSBs of the 10 bit IODC of the same data set */
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint8_t IODE;
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Age of Data Offset for the NMCT, 6 bits, scale 900,
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * ignore if all ones, seconds */
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint8_t AODO;
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint16_t u_AODO;
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* fit, FIT interval flag, indicates a fit interval greater than
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * 4 hour, 1 bit */
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint8_t fit;
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* toe, Reference Time Ephemeris, 16 bits unsigned, scale 2**4,
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * seconds */
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint16_t toe;
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    long l_toe;
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Crs, Amplitude of the Sine Harmonic Correction Term to the
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Orbit Radius, 16 bits, scale 2**-5, signed, meters */
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int16_t Crs;
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_Crs;
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Cus, Amplitude of the Sine Harmonic Correction Term to the
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Argument of Latitude, 16 bits, signed, scale 2**-29, radians */
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int16_t Cus;
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_Cus;
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Cuc, Amplitude of the Cosine Harmonic Correction Term to the
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Argument of Latitude, 16 bits, signed, scale 2**-29, radians */
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int16_t Cuc;
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_Cuc;
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* deltan, Mean Motion Difference From Computed Value
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Mean Motion Difference From Computed Value
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * 16 bits, signed, scale 2**-43, semi-circles/sec */
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int16_t deltan;
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_deltan;
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* M0, Mean Anomaly at Reference Time, 32 bits signed,
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * scale 2**-31, semi-circles */
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int32_t M0;
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_M0;
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* eccentricity, 32 bits, unsigned, scale 2**-33, dimensionless */
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint32_t e;
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_eccentricity;
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* sqrt A, Square Root of the Semi-Major Axis
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * 32 bits unsigned, scale 2**-19, square_root(meters) */
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint32_t sqrtA;
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_sqrtA;
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} sub2;
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* subframe 3, part of ephemeris, see IS-GPS-200E, Table 20-II,
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * Table 20-III */
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Issue of Data (Ephemeris), 8 bits, unsigned
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * equal to the 8 LSBs of the 10 bit IODC of the same data set */
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint8_t IODE;
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Rate of Inclination Angle, 14 bits signed, scale2**-43,
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * semi-circles/sec */
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint16_t IDOT;
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_IDOT;
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Cic, Amplitude of the Cosine Harmonic Correction Term to the
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Angle of Inclination, 16 bits signed, scale 2**-29, radians*/
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint16_t Cic;
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_Cic;
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Cis, Amplitude of the Sine Harmonic Correction Term to the
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Angle of Inclination, 16 bits, unsigned, scale 2**-29, radians */
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int16_t Cis;
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_Cis;
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* Crc, Amplitude of the Cosine Harmonic Correction Term to the
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Orbit Radius, 16 bits signed, scale 2**-5, meters */
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int16_t Crc;
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_Crc;
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* i0, Inclination Angle at Reference Time, 32 bits, signed,
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * scale 2**-31, semi-circles */
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int32_t i0;
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_i0;
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Omega0, Longitude of Ascending Node of Orbit Plane at Weekly
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Epoch, 32 bits signed, semi-circles */
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int32_t Omega0;
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_Omega0;
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* omega, Argument of Perigee, 32 bits signed, scale 2**-31,
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * semi-circles */
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int32_t omega;
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_omega;
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Omega dot, Rate of Right Ascension, 24 bits signed,
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * scale 2**-43, semi-circles/sec */
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int32_t Omegad;
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_Omegad;
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} sub3;
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct almanac_t almanac;
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} sub4;
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* subframe 4, page 13 */
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* mapping ord ERD# to SV # is non trivial
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * leave it alone.  See IS-GPS-200E Section 20.3.3.5.1.9 */
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Estimated Range Deviation, 6 bits signed, meters */
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char ERD[33];
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* ai, Availability Indicator, 2bits, bit map */
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned char ai;
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} sub4_13;
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* subframe 4, page 17, system message, 23 chars, plus nul */
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char str[24];
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} sub4_17;
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* subframe 4, page 18 */
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* ionospheric and UTC data */
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* A0, Bias coefficient of GPS time scale relative to UTC time
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * scale, 32 bits signed, scale 2**-30, seconds */
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int32_t A0;
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_A0;
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* A1, Drift coefficient of GPS time scale relative to UTC time
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * scale, 24 bits signed, scale 2**-50, seconds/second */
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int32_t A1;
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_A1;
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* alphaX, the four coefficients of a cubic equation representing
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * the amplitude of the vertical delay */
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* alpha0, 8 bits signed, scale w**-30, seconds */
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int8_t alpha0;
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_alpha0;
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* alpha1, 8 bits signed, scale w**-27, seconds/semi-circle */
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int8_t alpha1;
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_alpha1;
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* alpha2, 8 bits signed, scale w**-24, seconds/semi-circle**2 */
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int8_t alpha2;
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_alpha2;
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* alpha3, 8 bits signed, scale w**-24, seconds/semi-circle**3 */
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int8_t alpha3;
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_alpha3;
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* betaX, the four coefficients of a cubic equation representing
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * the period of the model */
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* beta0, 8 bits signed, scale w**11, seconds */
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int8_t beta0;
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_beta0;
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* beta1, 8 bits signed, scale w**14, seconds/semi-circle */
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int8_t beta1;
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_beta1;
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* beta2, 8 bits signed, scale w**16, seconds/semi-circle**2 */
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int8_t beta2;
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_beta2;
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* beta3, 8 bits signed, scale w**16, seconds/semi-circle**3 */
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int8_t beta3;
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_beta3;
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* leap (delta t ls), current leap second, 8 bits signed,
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * scale 1, seconds */
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int8_t leap;
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* lsf (delta t lsf), future leap second, 8 bits signed,
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * scale 1, seconds */
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int8_t lsf;
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* tot, reference time for UTC data,
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * 8 bits unsigned, scale 2**12, seconds */
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint8_t tot;
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    double d_tot;
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* WNt, UTC reference week number, 8 bits unsigned, scale 1,
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * weeks */
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint8_t WNt;
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* WNlsf, Leap second reference Week Number,
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * 8 bits unsigned, scale 1, weeks */
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint8_t WNlsf;
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* DN, Leap second reference Day Number , 8 bits unsigned,
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * scale 1, days */
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint8_t DN;
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} sub4_18;
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* subframe 4, page 25 */
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* svf, A-S status and the configuration code of each SV
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * 4 bits unsigned, bitmap */
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned char svf[33];
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* svh, SV health data for SV 25 through 32
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * 6 bits unsigned bitmap */
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint8_t svhx[8];
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} sub4_25;
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct almanac_t almanac;
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} sub5;
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* toa, Almanac reference Time, 8 bits unsigned, scale 2**12,
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * seconds */
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint8_t toa;
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    long l_toa;
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* WNa, Week Number almanac, 8 bits, scale 2, GPS Week
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Number % 256 */
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint8_t WNa;
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* sv, SV health status, 6 bits, bitmap */
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    uint8_t sv[25];
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} sub5_25;
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef S_SPLINT_S
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef uint64_t gps_mask_t;
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef /*@unsignedintegraltype@*/ unsigned long long gps_mask_t;
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* S_SPLINT_S */
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Is an MMSI number that of an auxiliary associated with a mother ship?
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * We need to be able to test this for decoding AIS Type 24 messages.
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * According to <http://www.navcen.uscg.gov/marcomms/gmdss/mmsi.htm#format>,
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * auxiliary-craft MMSIs have the form 98MIDXXXX, where MID is a country
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * code and XXXX the vessel ID.
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_AUXILIARY_MMSI(n)	((n) / 10000000 == 98)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* N/A values and scaling constant for 25/24 bit lon/lat pairs */
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_LON3_NOT_AVAILABLE	181000
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_LAT3_NOT_AVAILABLE	91000
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_LATLON3_SCALE	60000.0
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* N/A values and scaling constant for 28/27 bit lon/lat pairs */
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_LON4_NOT_AVAILABLE	1810000
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_LAT4_NOT_AVAILABLE	910000
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_LATLON4_SCALE	600000.0
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct route_info {
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int linkage;	/* Message Linkage ID */
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int sender;	/* Sender Class */
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int rtype;		/* Route Type */
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int month;		/* Start month */
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int day;		/* Start day */
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int hour;		/* Start hour */
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int minute;	/* Start minute */
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int duration;	/* Duration */
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int waycount;		/* Waypoint count */
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct waypoint_t {
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	signed int lon;		/* Longitude */
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	signed int lat;		/* Latitude */
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } waypoints[16];
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ais_t
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int	type;		/* message type */
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int    	repeat;		/* Repeat indicator */
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int	mmsi;		/* MMSI */
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    union {
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Types 1-3 Common navigation info */
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int status;		/* navigation status */
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    signed turn;			/* rate of turn */
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_TURN_HARD_LEFT	-127
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_TURN_HARD_RIGHT	127
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_TURN_NOT_AVAILABLE	128
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int speed;			/* speed over ground in deciknots */
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_SPEED_NOT_AVAILABLE	1023
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_SPEED_FAST_MOVER	1022		/* >= 102.2 knots */
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool accuracy;			/* position accuracy */
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_LATLON_SCALE	600000.0
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int lon;				/* longitude */
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_LON_NOT_AVAILABLE	0x6791AC0
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int lat;				/* latitude */
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_LAT_NOT_AVAILABLE	0x3412140
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int course;		/* course over ground */
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_COURSE_NOT_AVAILABLE	3600
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int heading;		/* true heading */
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_HEADING_NOT_AVAILABLE	511
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int second;		/* seconds of UTC timestamp */
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_SEC_NOT_AVAILABLE	60
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_SEC_MANUAL		61
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_SEC_ESTIMATED	62
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_SEC_INOPERATIVE	63
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int maneuver;	/* maneuver indicator */
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare;	spare bits */
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool raim;			/* RAIM flag */
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int radio;		/* radio status bits */
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type1;
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 4 - Base Station Report & Type 11 - UTC and Date Response */
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int year;			/* UTC year */
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_YEAR_NOT_AVAILABLE	0
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int month;			/* UTC month */
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_MONTH_NOT_AVAILABLE	0
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int day;			/* UTC day */
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_DAY_NOT_AVAILABLE	0
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int hour;			/* UTC hour */
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_HOUR_NOT_AVAILABLE	24
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int minute;		/* UTC minute */
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_MINUTE_NOT_AVAILABLE	60
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int second;		/* UTC second */
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_SECOND_NOT_AVAILABLE	60
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool accuracy;		/* fix quality */
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int lon;			/* longitude */
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int lat;			/* latitude */
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int epfd;		/* type of position fix device */
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare;	spare bits */
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool raim;			/* RAIM flag */
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int radio;		/* radio status bits */
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type4;
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 5 - Ship static and voyage related data */
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int ais_version;	/* AIS version level */
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int imo;		/* IMO identification */
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char callsign[7+1];		/* callsign */
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_SHIPNAME_MAXLEN	20
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char shipname[AIS_SHIPNAME_MAXLEN+1];	/* vessel name */
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int shiptype;	/* ship type code */
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int to_bow;	/* dimension to bow */
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int to_stern;	/* dimension to stern */
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int to_port;	/* dimension to port */
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int to_starboard;	/* dimension to starboard */
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int epfd;		/* type of position fix deviuce */
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int month;		/* UTC month */
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int day;		/* UTC day */
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int hour;		/* UTC hour */
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int minute;	/* UTC minute */
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int draught;	/* draft in meters */
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char destination[20+1];	/* ship destination */
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int dte;		/* data terminal enable */
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare;	spare bits */
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type5;
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 6 - Addressed Binary Message */
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int seqno;		/* sequence number */
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int dest_mmsi;	/* destination MMSI */
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool retransmit;		/* retransmit flag */
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare;	spare bit(s) */
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int dac;           /* Application ID */
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int fid;           /* Functional ID */
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_TYPE6_BINARY_MAX	920	/* 920 bits */
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    size_t bitcount;		/* bit count of the data */
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    union {
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		char bitdata[(AIS_TYPE6_BINARY_MAX + 7) / 8];
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* IMO236 - Dangerous Cargo Indication */
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct {
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    char lastport[5+1];		/* Last Port Of Call */
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int lmonth;	/* ETA month */
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int lday;		/* ETA day */
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int lhour;		/* ETA hour */
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int lminute;	/* ETA minute */
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    char nextport[5+1];		/* Next Port Of Call */
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int nmonth;	/* ETA month */
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int nday;		/* ETA day */
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int nhour;		/* ETA hour */
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int nminute;	/* ETA minute */
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    char dangerous[20+1];	/* Main Dangerous Good */
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    char imdcat[4+1];		/* IMD Category */
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int unid;		/* UN Number */
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int amount;	/* Amount of Cargo */
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int unit;		/* Unit of Quantity */
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} dac1fid12;
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* IMO236 - Extended Ship Static and Voyage Related Data */
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct {
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int airdraught;	/* Air Draught */
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} dac1fid15;
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* IMO236 - Number of Persons on board */
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct {
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned persons;	/* number of persons */
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} dac1fid16;
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* IMO289 - Clearance Time To Enter Port */
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct {
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int linkage;	/* Message Linkage ID */
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int month;	/* Month (UTC) */
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int day;	/* Day (UTC) */
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int hour;	/* Hour (UTC) */
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int minute;	/* Minute (UTC) */
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    char portname[20+1];	/* Name of Port & Berth */
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    char destination[5+1];	/* Destination */
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    signed int lon;	/* Longitude */
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    signed int lat;	/* Latitude */
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} dac1fid18;
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* IMO289 - Berthing Data (addressed) */
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct {
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int linkage;	/* Message Linkage ID */
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int berth_length;	/* Berth length */
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int berth_depth;	/* Berth Water Depth */
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int position;	/* Mooring Position */
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int month;	/* Month (UTC) */
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int day;	/* Day (UTC) */
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int hour;	/* Hour (UTC) */
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int minute;	/* Minute (UTC) */
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int availability;	/* Services Availability */
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int agent;	/* Agent */
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int fuel;	/* Bunker/fuel */
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int chandler;	/* Chandler */
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int stevedore;	/* Stevedore */
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int electrical;	/* Electrical */
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int water;	/* Potable water */
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int customs;	/* Customs house */
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int cartage;	/* Cartage */
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int crane;	/* Crane(s) */
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int lift;	/* Lift(s) */
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int medical;	/* Medical facilities */
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int navrepair;	/* Navigation repair */
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int provisions;	/* Provisions */
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int shiprepair;	/* Ship repair */
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int surveyor;	/* Surveyor */
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int steam;	/* Steam */
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int tugs;	/* Tugs */
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int solidwaste;	/* Waste disposal (solid) */
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int liquidwaste;	/* Waste disposal (liquid) */
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int hazardouswaste;	/* Waste disposal (hazardous) */
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int ballast;	/* Reserved ballast exchange */
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int additional;	/* Additional services */
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int regional1;	/* Regional reserved 1 */
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int regional2;	/* Regional reserved 2 */
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int future1;	/* Reserved for future */
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int future2;	/* Reserved for future */
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    char berth_name[20+1];	/* Name of Berth */
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    signed int berth_lon;	/* Longitude */
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    signed int berth_lat;	/* Latitude */
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} dac1fid20;
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* IMO289 - Dangerous Cargo Indication */
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct {
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int unit;	/* Unit of Quantity */
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int amount;	/* Amount of Cargo */
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int ncargos;
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    struct cargo_t {
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			unsigned int code;	/* Cargo code */
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			unsigned int subtype;	/* Cargo subtype */
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } cargos[28];
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} dac1fid25;
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* IMO289 - Route info (addressed) */
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct route_info dac1fid28;
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* IMO289 - Text message (addressed) */
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct {
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int linkage;
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_DAC1FID30_TEXT_MAX	154	/* 920 bits of six-bit, plus NUL */
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    char text[AIS_DAC1FID30_TEXT_MAX];
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} dac1fid30;
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* IMO289 & IMO236 - Tidal Window */
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct {
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int type;	/* Message Type */
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int repeat;	/* Repeat Indicator */
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int mmsi;	/* Source MMSI */
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int seqno;	/* Sequence Number */
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int dest_mmsi;	/* Destination MMSI */
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    signed int retransmit;	/* Retransmit flag */
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int dac;	/* DAC */
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int fid;	/* FID */
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int month;	/* Month */
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int day;	/* Day */
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    signed int ntidals;
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    struct tidal_t {
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			signed int lon;	/* Longitude */
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			signed int lat;	/* Latitude */
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			unsigned int from_hour;	/* From UTC Hour */
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			unsigned int from_min;	/* From UTC Minute */
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			unsigned int to_hour;	/* To UTC Hour */
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			unsigned int to_min;	/* To UTC Minute */
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID32_CDIR_NOT_AVAILABLE		360
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			unsigned int cdir;	/* Current Dir. Predicted */
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID32_CSPEED_NOT_AVAILABLE		127
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			unsigned int cspeed;	/* Current Speed Predicted */
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } tidals[3];
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} dac1fid32;
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    };
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type6;
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 7 - Binary Acknowledge */
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int mmsi1;
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int mmsi2;
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int mmsi3;
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int mmsi4;
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* spares ignored, they're only padding here */
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type7;
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 8 - Broadcast Binary Message */
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare;	spare bit(s) */
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int dac;       	/* Designated Area Code */
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int fid;       	/* Functional ID */
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_TYPE8_BINARY_MAX	952	/* 952 bits */
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    size_t bitcount;		/* bit count of the data */
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    union {
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		char bitdata[(AIS_TYPE8_BINARY_MAX + 7) / 8];
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* IMO236 - Fairway Closed */
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct {
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    char reason[20+1];	/* Reason For Closing */
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    char closefrom[20+1];	/* Location Of Closing From */
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    char closeto[20+1];	/* Location of Closing To */
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int radius;	/* Radius extension */
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_DAC1FID13_RADIUS_NOT_AVAILABLE 10001
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int extunit;	/* Unit of extension */
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_DAC1FID13_EXTUNIT_NOT_AVAILABLE 0
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int fday;	/* From day (UTC) */
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int fmonth;	/* From month (UTC) */
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int fhour;	/* From hour (UTC) */
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int fminute;	/* From minute (UTC) */
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int tday;	/* To day (UTC) */
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int tmonth;	/* To month (UTC) */
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int thour;	/* To hour (UTC) */
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int tminute;	/* To minute (UTC) */
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} dac1fid13;
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        /* IMO236 - Extended ship and voyage data */
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct {
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int airdraught;	/* Air Draught */
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} dac1fid15;
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* IMO289 - VTS-generated/Synthetic Targets */
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct {
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    signed int ntargets;
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    struct target_t {
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID17_IDTYPE_MMSI		0
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID17_IDTYPE_IMO		1
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID17_IDTYPE_CALLSIGN	2
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID17_IDTYPE_OTHER		3
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			unsigned int idtype;	/* Identifier type */
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			union target_id {	/* Target identifier */
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    unsigned int mmsi;
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    unsigned int imo;
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID17_ID_LENGTH		7
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    char callsign[DAC1FID17_ID_LENGTH+1];
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    char other[DAC1FID17_ID_LENGTH+1];
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			} id;
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			signed int lat;		/* Latitude */
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			signed int lon;		/* Longitude */
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID17_COURSE_NOT_AVAILABLE		360
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			unsigned int course;	/* Course Over Ground */
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			unsigned int second;	/* Time Stamp */
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID17_SPEED_NOT_AVAILABLE		255
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			unsigned int speed;	/* Speed Over Ground */
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } targets[4];
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} dac1fid17;
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* IMO 289 - Marine Traffic Signal */
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct {
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int linkage;	/* Message Linkage ID */
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    char station[20+1];		/* Name of Signal Station */
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    signed int lon;		/* Longitude */
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    signed int lat;		/* Latitude */
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int status;	/* Status of Signal */
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int signal;	/* Signal In Service */
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int hour;		/* UTC hour */
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int minute;	/* UTC minute */
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int nextsignal;	/* Expected Next Signal */
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} dac1fid19;
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* IMO289 - Route info (broadcast) */
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct route_info dac1fid27;
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* IMO289 - Text message (broadcast) */
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct {
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int linkage;
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_DAC1FID29_TEXT_MAX	162	/* 920 bits of six-bit, plus NUL */
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    char text[AIS_DAC1FID29_TEXT_MAX];
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} dac1fid29;
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* IMO236 & IMO289 - Meteorological-Hydrological data */
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct {
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    bool accuracy;	/* position accuracy, <10m if true */
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_LATLON_SCALE	1000
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int lon;		/* longitude in minutes * .001 */
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_LON_NOT_AVAILABLE	(181*60*DAC1FID31_LATLON_SCALE)
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int lat;		/* longitude in minutes * .001 */
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_LAT_NOT_AVAILABLE	(91*60*DAC1FID31_LATLON_SCALE)
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int day;		/* UTC day */
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int hour;		/* UTC hour */
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int minute;	/* UTC minute */
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int wspeed;	/* average wind speed */
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int wgust;		/* wind gust */
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_WIND_HIGH			126
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_WIND_NOT_AVAILABLE		127
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int wdir;		/* wind direction */
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int wgustdir;	/* wind gust direction */
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_DIR_NOT_AVAILABLE		360
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int airtemp;		/* temperature, units 0.1C */
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_AIRTEMP_NOT_AVAILABLE		-1084
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int humidity;	/* relative humidity, % */
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_HUMIDITY_NOT_AVAILABLE	101
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int dewpoint;		/* dew point, units 0.1C */
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_DEWPOINT_NOT_AVAILABLE	501
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int pressure;	/* air pressure, hpa */
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_PRESSURE_NOT_AVAILABLE	511
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_PRESSURE_HIGH			402
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int pressuretend;	/* tendency */
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_PRESSURETREND_NOT_AVAILABLE	3
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    bool visgreater;            /* visibility greater than */
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int visibility;	/* units 0.1 nautical miles */
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_VISIBILITY_NOT_AVAILABLE	127
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int waterlevel;		/* decimeters or cm */
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID11_WATERLEVEL_NOT_AVAILABLE	4001
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_WATERLEVEL_NOT_AVAILABLE	40001
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int leveltrend;	/* water level trend code */
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_LEVELTREND_NOT_AVAILABLE	3
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int cspeed;	/* current speed in deciknots */
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_CSPEED_NOT_AVAILABLE		255
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int cdir;		/* current dir., degrees */
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int cspeed2;	/* current speed in deciknots */
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int cdir2;		/* current dir., degrees */
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int cdepth2;	/* measurement depth, 0.1m */
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_CDEPTH_NOT_AVAILABLE		301
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int cspeed3;	/* current speed in deciknots */
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int cdir3;		/* current dir., degrees */
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int cdepth3;	/* measurement depth, 0.1m */
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int waveheight;	/* in decimeters */
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_HEIGHT_NOT_AVAILABLE		31
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int waveperiod;	/* in seconds */
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_PERIOD_NOT_AVAILABLE		63
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int wavedir;	/* direction in degrees */
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int swellheight;	/* in decimeters */
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int swellperiod;	/* in seconds */
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int swelldir;	/* direction in degrees */
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int seastate;	/* Beaufort scale, 0-12 */
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_SEASTATE_NOT_AVAILABLE	15
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int watertemp;		/* units 0.1deg Celsius */
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_PRECIPTYPE_NOT_AVAILABLE	7
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int preciptype;	/* 0-7, enumerated */
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int salinity;	/* units of 0.1% */
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DAC1FID31_SALINITY_NOT_AVAILABLE	510
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    bool ice;			/* is there sea ice? */
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} dac1fid31;
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    };
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type8;
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 9 - Standard SAR Aircraft Position Report */
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int alt;		/* altitude in meters */
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_ALT_NOT_AVAILABLE	4095
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_ALT_HIGH    	4094	/* 4094 meters or higher */
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int speed;		/* speed over ground in deciknots */
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_SAR_SPEED_NOT_AVAILABLE	1023
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_SAR_FAST_MOVER  	1022
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool accuracy;		/* position accuracy */
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int lon;			/* longitude */
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int lat;			/* latitude */
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int course;	/* course over ground */
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int second;	/* seconds of UTC timestamp */
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int regional;	/* regional reserved */
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int dte;		/* data terminal enable */
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare;	spare bits */
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool assigned;		/* assigned-mode flag */
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool raim;			/* RAIM flag */
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int radio;		/* radio status bits */
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type9;
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 10 - UTC/Date Inquiry */
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare;
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int dest_mmsi;	/* destination MMSI */
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare2;
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type10;
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 12 - Safety-Related Message */
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int seqno;		/* sequence number */
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int dest_mmsi;	/* destination MMSI */
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool retransmit;		/* retransmit flag */
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare;	spare bit(s) */
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_TYPE12_TEXT_MAX	157	/* 936 bits of six-bit, plus NUL */
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char text[AIS_TYPE12_TEXT_MAX];
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type12;
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 14 - Safety-Related Broadcast Message */
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare;	spare bit(s) */
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_TYPE14_TEXT_MAX	161	/* 952 bits of six-bit, plus NUL */
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char text[AIS_TYPE14_TEXT_MAX];
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type14;
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 15 - Interrogation */
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare;	spare bit(s) */
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int mmsi1;
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int type1_1;
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int offset1_1;
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare2;	spare bit(s) */
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int type1_2;
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int offset1_2;
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare3;	spare bit(s) */
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int mmsi2;
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int type2_1;
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int offset2_1;
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare4;	spare bit(s) */
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type15;
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 16 - Assigned Mode Command */
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare;	spare bit(s) */
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int mmsi1;
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int offset1;
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int increment1;
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int mmsi2;
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int offset2;
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int increment2;
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type16;
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 17 - GNSS Broadcast Binary Message */
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare;	spare bit(s) */
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_GNSS_LATLON_SCALE	600.0
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int lon;			/* longitude */
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int lat;			/* latitude */
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare2;	spare bit(s) */
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_TYPE17_BINARY_MAX	736	/* 920 bits */
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    size_t bitcount;		/* bit count of the data */
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char bitdata[(AIS_TYPE17_BINARY_MAX + 7) / 8];
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type17;
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 18 - Standard Class B CS Position Report */
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int reserved;	/* altitude in meters */
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int speed;		/* speed over ground in deciknots */
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool accuracy;		/* position accuracy */
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int lon;			/* longitude */
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_GNS_LON_NOT_AVAILABLE	0x1a838
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int lat;			/* latitude */
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_GNS_LAT_NOT_AVAILABLE	0xd548
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int course;	/* course over ground */
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int heading;	/* true heading */
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int second;	/* seconds of UTC timestamp */
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int regional;	/* regional reserved */
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool cs;     		/* carrier sense unit flag */
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool display;		/* unit has attached display? */
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool dsc;   		/* unit attached to radio with DSC? */
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool band;   		/* unit can switch frequency bands? */
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool msg22;	        	/* can accept Message 22 management? */
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool assigned;		/* assigned-mode flag */
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool raim;			/* RAIM flag */
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int radio;		/* radio status bits */
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type18;
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 19 - Extended Class B CS Position Report */
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int reserved;	/* altitude in meters */
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int speed;		/* speed over ground in deciknots */
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool accuracy;		/* position accuracy */
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int lon;			/* longitude */
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int lat;			/* latitude */
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int course;	/* course over ground */
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int heading;	/* true heading */
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int second;	/* seconds of UTC timestamp */
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int regional;	/* regional reserved */
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char shipname[AIS_SHIPNAME_MAXLEN+1];		/* ship name */
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int shiptype;	/* ship type code */
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int to_bow;	/* dimension to bow */
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int to_stern;	/* dimension to stern */
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int to_port;	/* dimension to port */
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int to_starboard;	/* dimension to starboard */
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int epfd;		/* type of position fix deviuce */
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool raim;			/* RAIM flag */
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int dte;    	/* date terminal enable */
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool assigned;		/* assigned-mode flag */
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare;	spare bits */
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type19;
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 20 - Data Link Management Message */
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare;	spare bit(s) */
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int offset1;	/* TDMA slot offset */
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int number1;	/* number of xlots to allocate */
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int timeout1;	/* allocation timeout */
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int increment1;	/* repeat increment */
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int offset2;	/* TDMA slot offset */
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int number2;	/* number of xlots to allocate */
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int timeout2;	/* allocation timeout */
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int increment2;	/* repeat increment */
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int offset3;	/* TDMA slot offset */
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int number3;	/* number of xlots to allocate */
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int timeout3;	/* allocation timeout */
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int increment3;	/* repeat increment */
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int offset4;	/* TDMA slot offset */
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int number4;	/* number of xlots to allocate */
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int timeout4;	/* allocation timeout */
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int increment4;	/* repeat increment */
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type20;
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 21 - Aids to Navigation Report */
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int aid_type;	/* aid type */
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char name[35];		/* name of aid to navigation */
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool accuracy;		/* position accuracy */
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int lon;			/* longitude */
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int lat;			/* latitude */
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int to_bow;	/* dimension to bow */
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int to_stern;	/* dimension to stern */
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int to_port;	/* dimension to port */
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int to_starboard;	/* dimension to starboard */
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int epfd;		/* type of EPFD */
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int second;	/* second of UTC timestamp */
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool off_position;		/* off-position indicator */
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int regional;	/* regional reserved field */
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool raim;			/* RAIM flag */
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool virtual_aid;		/* is virtual station? */
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool assigned;		/* assigned-mode flag */
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare;	unused */
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type21;
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 22 - Channel Management */
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare;	spare bit(s) */
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int channel_a;	/* Channel A number */
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int channel_b;	/* Channel B number */
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int txrx;		/* transmit/receive mode */
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool power;			/* high-power flag */
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_CHANNEL_LATLON_SCALE	600.0
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    union {
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct {
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int ne_lon;		/* NE corner longitude */
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int ne_lat;		/* NE corner latitude */
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int sw_lon;		/* SW corner longitude */
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int sw_lat;		/* SW corner latitude */
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} area;
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct {
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int dest1;	/* addressed station MMSI 1 */
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int dest2;	/* addressed station MMSI 2 */
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} mmsi;
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    };
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool addressed;		/* addressed vs. broadast flag */
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool band_a;		/* fix 1.5kHz band for channel A */
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool band_b;		/* fix 1.5kHz band for channel B */
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int zonesize;	/* size of transitional zone */
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type22;
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 23 - Group Assignment Command */
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int ne_lon;			/* NE corner longitude */
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int ne_lat;			/* NE corner latitude */
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int sw_lon;			/* SW corner longitude */
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int sw_lat;			/* SW corner latitude */
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare;	spare bit(s) */
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int stationtype;	/* station type code */
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int shiptype;	/* ship type code */
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare2;	spare bit(s) */
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int txrx;		/* transmit-enable code */
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int interval;	/* report interval */
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int quiet;		/* quiet time */
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    //unsigned int spare3;	spare bit(s) */
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type23;
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 24 - Class B CS Static Data Report */
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char shipname[AIS_SHIPNAME_MAXLEN+1];	/* vessel name */
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int shiptype;	/* ship type code */
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char vendorid[8];		/* vendor ID */
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char callsign[8];		/* callsign */
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    union {
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		unsigned int mothership_mmsi;	/* MMSI of main vessel */
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		struct {
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int to_bow;	/* dimension to bow */
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int to_stern;	/* dimension to stern */
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int to_port;	/* dimension to port */
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    unsigned int to_starboard;	/* dimension to starboard */
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} dim;
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    };
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type24;
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 25 - Addressed Binary Message */
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool addressed;		/* addressed-vs.broadcast flag */
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool structured;		/* structured-binary flag */
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int dest_mmsi;	/* destination MMSI */
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int app_id;        /* Application ID */
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_TYPE25_BINARY_MAX	128	/* Up to 128 bits */
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    size_t bitcount;		/* bit count of the data */
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char bitdata[(AIS_TYPE25_BINARY_MAX + 7) / 8];
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type25;
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 26 - Addressed Binary Message */
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool addressed;		/* addressed-vs.broadcast flag */
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool structured;		/* structured-binary flag */
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int dest_mmsi;	/* destination MMSI */
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int app_id;        /* Application ID */
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_TYPE26_BINARY_MAX	1004	/* Up to 128 bits */
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    size_t bitcount;		/* bit count of the data */
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    char bitdata[(AIS_TYPE26_BINARY_MAX + 7) / 8];
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int radio;		/* radio status bits */
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type26;
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Type 27 - Long Range AIS Broadcast message */
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool accuracy;		/* position accuracy */
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool raim;			/* RAIM flag */
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int status;	/* navigation status */
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_LONGRANGE_LATLON_SCALE	600.0
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int lon;			/* longitude */
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_LONGRANGE_LON_NOT_AVAILABLE	0x1a838
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int lat;			/* latitude */
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_LONGRANGE_LAT_NOT_AVAILABLE	0xd548
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int speed;		/* speed over ground in deciknots */
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_LONGRANGE_SPEED_NOT_AVAILABLE 63
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    unsigned int course;	/* course over ground */
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_LONGRANGE_COURSE_NOT_AVAILABLE 511
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bool gnss;			/* are we reporting GNSS position? */
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} type27;
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct attitude_t {
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double heading;
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double pitch;
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double roll;
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double yaw;
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double dip;
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double mag_len; /* unitvector sqrt(x^2 + y^2 +z^2) */
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double mag_x;
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double mag_y;
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double mag_z;
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double acc_len; /* unitvector sqrt(x^2 + y^2 +z^2) */
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double acc_x;
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double acc_y;
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double acc_z;
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double gyro_x;
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double gyro_y;
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double temp;
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double depth;
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* compass status -- TrueNorth (and any similar) devices only */
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char mag_st;
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char pitch_st;
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char roll_st;
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char yaw_st;
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct dop_t {
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Dilution of precision factors */
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double xdop, ydop, pdop, hdop, vdop, tdop, gdop;
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct rawdata_t {
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* raw measurement data */
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double codephase[MAXCHANNELS];	/* meters */
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double carrierphase[MAXCHANNELS];	/* meters */
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double pseudorange[MAXCHANNELS];	/* meters */
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double deltarange[MAXCHANNELS];	/* meters/sec */
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double doppler[MAXCHANNELS];	/* Hz */
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double mtime[MAXCHANNELS];		/* sec */
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned satstat[MAXCHANNELS];	/* tracking status */
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SAT_ACQUIRED	0x01		/* satellite acquired */
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SAT_CODE_TRACK	0x02		/* code-tracking loop acquired */
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SAT_CARR_TRACK	0x04		/* carrier-tracking loop acquired */
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SAT_DATA_SYNC	0x08		/* data-bit synchronization done */
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SAT_FRAME_SYNC	0x10		/* frame synchronization done */
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SAT_EPHEMERIS	0x20		/* ephemeris collected */
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SAT_FIX_USED	0x40		/* used for position fix */
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct version_t {
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char release[64];			/* external version */
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char rev[64];			/* internal revision ID */
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int proto_major, proto_minor;	/* API major and minor versions */
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char remote[GPS_PATH_MAX];		/* could be from a remote device */
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct devconfig_t {
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char path[GPS_PATH_MAX];
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int flags;
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SEEN_GPS 	0x01
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SEEN_RTCM2	0x02
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SEEN_RTCM3	0x04
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SEEN_AIS 	0x08
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char driver[64];
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char subtype[64];
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double activated;
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int baudrate, stopbits;	/* RS232 link parameters */
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char parity;			/* 'N', 'O', or 'E' */
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double cycle, mincycle;     	/* refresh cycle time in seconds */
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int driver_mode;    		/* is driver in native mode or not? */
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct policy_t {
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool watcher;			/* is watcher mode on? */
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool json;				/* requesting JSON? */
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool nmea;				/* requesting dumping as NMEA? */
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int raw;				/* requesting raw data? */
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool scaled;			/* requesting report scaling? */
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool timing;			/* requesting timing info */
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int loglevel;			/* requested log level of messages */
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char devpath[GPS_PATH_MAX];		/* specific device to watch */
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char remote[GPS_PATH_MAX];		/* ...if this was passthrough */
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Someday we may support Windows, under which socket_t is a separate type.
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * In the meantime, having a typedef for this semantic kind is no bad thing,
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * as it makes clearer what some declarations are doing without breaking
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * binary compatibility.
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int socket_t;
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* mode flags for setting streaming policy */
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WATCH_ENABLE	0x000001u	/* enable streaming */
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WATCH_DISABLE	0x000002u	/* disable watching */
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WATCH_JSON	0x000010u	/* JSON output */
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WATCH_NMEA	0x000020u	/* output in NMEA */
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WATCH_RARE	0x000040u	/* output of packets in hex */
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WATCH_RAW	0x000080u	/* output of raw packets */
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WATCH_SCALED	0x000100u	/* scale output to floats */
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WATCH_TIMING	0x000200u	/* timing information */
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WATCH_DEVICE	0x000800u	/* watch specific device */
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WATCH_NEWSTYLE	0x010000u	/* force JSON streaming */
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WATCH_OLDSTYLE	0x020000u	/* force old-style streaming */
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Main structure that includes all previous substructures
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct gps_data_t {
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gps_mask_t set;	/* has field been set since this was last cleared? */
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ONLINE_SET	(1llu<<1)
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TIME_SET	(1llu<<2)
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TIMERR_SET	(1llu<<3)
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LATLON_SET	(1llu<<4)
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ALTITUDE_SET	(1llu<<5)
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SPEED_SET	(1llu<<6)
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TRACK_SET	(1llu<<7)
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CLIMB_SET	(1llu<<8)
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define STATUS_SET	(1llu<<9)
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MODE_SET	(1llu<<10)
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DOP_SET  	(1llu<<11)
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HERR_SET	(1llu<<12)
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VERR_SET	(1llu<<13)
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ATTITUDE_SET	(1llu<<14)
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SATELLITE_SET	(1llu<<15)
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SPEEDERR_SET	(1llu<<16)
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TRACKERR_SET	(1llu<<17)
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CLIMBERR_SET	(1llu<<18)
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEVICE_SET	(1llu<<19)
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEVICELIST_SET	(1llu<<20)
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEVICEID_SET	(1llu<<21)
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RTCM2_SET	(1llu<<22)
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RTCM3_SET	(1llu<<23)
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define AIS_SET 	(1llu<<24)
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PACKET_SET	(1llu<<25)
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SUBFRAME_SET	(1llu<<26)
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GST_SET 	(1llu<<27)
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VERSION_SET	(1llu<<28)
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define POLICY_SET	(1llu<<29)
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOGMESSAGE_SET	(1llu<<30)
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ERROR_SET	(1llu<<31)
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SET_HIGH_BIT	31
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    timestamp_t online;		/* NZ if GPS is on line, 0 if not.
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 *
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 * Note: gpsd clears this time when sentences
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 * fail to show up within the GPS's normal
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 * send cycle time. If the host-to-GPS
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 * link is lossy enough to drop entire
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 * sentences, this field will be
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 * prone to false zero values.
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 */
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef USE_QT
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socket_t gps_fd;		/* socket or file descriptor to GPS */
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void* gps_fd;
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct gps_fix_t	fix;	/* accumulated PVT data */
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double separation;		/* Geoidal separation, MSL - WGS84 (Meters) */
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* GPS status -- always valid */
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int    status;		/* Do we have a fix? */
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define STATUS_NO_FIX	0	/* no */
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define STATUS_FIX	1	/* yes, without DGPS */
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define STATUS_DGPS_FIX	2	/* yes, with DGPS */
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* precision of fix -- valid if satellites_used > 0 */
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int satellites_used;	/* Number of satellites used in solution */
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int used[MAXCHANNELS];	/* PRNs of satellites used in solution */
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct dop_t dop;
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* redundant with the estimate elements in the fix structure */
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double epe;  /* spherical position error, 95% confidence (meters)  */
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* satellite status -- valid when satellites_visible > 0 */
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    timestamp_t skyview_time;	/* skyview timestamp */
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int satellites_visible;	/* # of satellites in view */
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int PRN[MAXCHANNELS];	/* PRNs of satellite */
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int elevation[MAXCHANNELS];	/* elevation of satellite */
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int azimuth[MAXCHANNELS];	/* azimuth */
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double ss[MAXCHANNELS];	/* signal-to-noise ratio (dB) */
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct devconfig_t dev;	/* device that shipped last update */
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct policy_t policy;	/* our listening policy */
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* should be moved to privdata sometday */
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char tag[MAXTAGLEN+1];	/* tag of last sentence processed */
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* pack things never reported together to reduce structure size */
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define UNION_SET	(RTCM2_SET|RTCM3_SET|SUBFRAME_SET|AIS_SET|ATTITUDE_SET|VERSION_SET|DEVICELIST_SET|LOGMESSAGE_SET|ERROR_SET|GST_SET|VERSION_SET)
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    union {
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* unusual forms of sensor data that might come up the pipe */
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm2_t	rtcm2;
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rtcm3_t	rtcm3;
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct subframe_t subframe;
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct ais_t ais;
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct attitude_t attitude;
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct rawdata_t raw;
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct gst_t gst;
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* "artificial" structures for various protocol responses */
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct version_t version;
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct {
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    timestamp_t time;
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int ndevices;
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    struct devconfig_t list[MAXUSERDEVS];
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} devices;
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	char error[256];
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Private data - client code must not set this */
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void *privdata;
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int gps_open(/*@null@*/const char *, /*@null@*/const char *,
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      /*@out@*/struct gps_data_t *);
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int gps_close(struct gps_data_t *);
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int gps_send(struct gps_data_t *, const char *, ... );
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int gps_read(/*@out@*/struct gps_data_t *);
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int gps_unpack(char *, struct gps_data_t *);
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern bool gps_waiting(const struct gps_data_t *, int);
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int gps_stream(struct gps_data_t *, unsigned int, /*@null@*/void *);
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char /*@observer@*/ *gps_data(const struct gps_data_t *);
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char /*@observer@*/ *gps_errstr(const int);
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int gps_sock_open(/*@null@*/const char *, /*@null@*/const char *,
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      /*@out@*/struct gps_data_t *);
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int gps_sock_read(/*@out@*/struct gps_data_t *);
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int gps_sock_close(struct gps_data_t *);
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int gps_sock_send(struct gps_data_t *, const char *);
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int gps_shm_open(/*@out@*/struct gps_data_t *);
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int gps_shm_read(struct gps_data_t *);
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern bool gps_sock_waiting(const struct gps_data_t *, int);
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int gps_sock_stream(struct gps_data_t *, unsigned int, /*@null@*/void *);
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char /*@observer@*/ *gps_sock_data(const struct gps_data_t *);
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern void gps_shm_close(struct gps_data_t *);
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern void libgps_trace(int errlevel, const char *, ...);
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* dependencies on struct gpsdata_t end hrere */
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern void gps_clear_fix(/*@ out @*/struct gps_fix_t *);
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern void gps_clear_dop( /*@out@*/ struct dop_t *);
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern void gps_merge_fix(/*@ out @*/struct gps_fix_t *,
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  gps_mask_t,
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  /*@ in @*/struct gps_fix_t *);
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern void gps_enable_debug(int, FILE *);
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern /*@observer@*/const char *gps_maskdump(gps_mask_t);
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern double safe_atof(const char *);
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern time_t mkgmtime(register struct tm *);
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern timestamp_t timestamp(void);
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern timestamp_t iso8601_to_unix(char *);
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern /*@observer@*/char *unix_to_iso8601(timestamp_t t, /*@ out @*/char[], size_t len);
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern double earth_distance(double, double, double, double);
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern double earth_distance_and_bearings(double, double, double, double,
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					  /*@null@*//*@out@*/double *,
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					  /*@null@*//*@out@*/double *);
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern double wgs84_separation(double, double);
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* some multipliers for interpreting GPS output */
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define METERS_TO_FEET	3.2808399	/* Meters to U.S./British feet */
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define METERS_TO_MILES	0.00062137119	/* Meters to miles */
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define KNOTS_TO_MPH	1.1507794	/* Knots to miles per hour */
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define KNOTS_TO_KPH	1.852		/* Knots to kilometers per hour */
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define KNOTS_TO_MPS	0.51444444	/* Knots to meters per second */
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MPS_TO_KPH	3.6		/* Meters per second to klicks/hr */
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MPS_TO_MPH	2.2369363	/* Meters/second to miles per hour */
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MPS_TO_KNOTS	1.9438445	/* Meters per second to knots */
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* miles and knots are both the international standard versions of the units */
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* angle conversion multipliers */
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GPS_PI      	3.1415926535897932384626433832795029
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RAD_2_DEG	57.2957795130823208767981548141051703
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEG_2_RAD	0.0174532925199432957692369076848861271
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* geodetic constants */
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WGS84A 6378137		/* equatorial radius */
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WGS84F 298.257223563	/* flattening */
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WGS84B 6356752.3142	/* polar radius */
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* netlib_connectsock() errno return values */
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NL_NOSERVICE	-1	/* can't get service entry */
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NL_NOHOST	-2	/* can't get host entry */
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NL_NOPROTO	-3	/* can't get protocol entry */
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NL_NOSOCK	-4	/* can't create socket */
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NL_NOSOCKOPT	-5	/* error SETSOCKOPT SO_REUSEADDR */
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NL_NOCONNECT	-6	/* can't connect to host/socket pair */
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SHM_NOSHARED	-7	/* shared-memory segment not available */
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SHM_NOATTACH	-8	/* shared-memory attach failed */
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEFAULT_GPSD_PORT	"2947"	/* IANA assignment */
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEFAULT_RTCM_PORT	"2101"	/* IANA assignment */
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* special host values for non-socket exports */
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GPSD_SHARED_MEMORY	"shared memory"
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Platform-specific declarations
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _WIN32
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define strtok_r(s,d,p) strtok_s(s,d,p)
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Some libc's don't have strlcat/strlcpy. Local copies are provided */
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HAVE_STRLCAT
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t strlcat(/*@out@*/char *dst, /*@in@*/const char *src, size_t size);
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HAVE_STRLCPY
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t strlcpy(/*@out@*/char *dst, /*@in@*/const char *src, size_t size);
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __cplusplus
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  /* End of the 'extern "C"' block */
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* gps.h ends here */
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* _GPSD_GPS_H_ */
1810