1 /* gpsd.h -- fundamental types and structures for the gpsd library
2  *
3  * This file is Copyright (c) 2017 by the GPSD project
4  * SPDX-License-Identifier: BSD-2-clause
5  */
6 
7 #ifndef _GPSD_H_
8 #define _GPSD_H_
9 
10 #include "compiler.h"	/* Must be outside extern "C" for "atomic"
11                          * pulls in gpsd_config.h */
12 
13 # ifdef __cplusplus
14 extern "C" {
15 # endif
16 
17 #include <stdarg.h>
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include <stdio.h>
21 #include <termios.h>
22 #ifdef HAVE_WINSOCK2_H
23 #include <winsock2.h>      /* for fd_set */
24 #else /* !HAVE_WINSOCK2_H */
25 #include <sys/select.h>    /* for fd_set */
26 #endif /* !HAVE_WINSOCK2_H */
27 #include <time.h>    /* for time_t */
28 
29 #include "gps.h"
30 #include "os_compat.h"
31 #include "ppsthread.h"
32 #include "timespec.h"
33 
34 /*
35  * Constants for the VERSION response
36  * 3.1: Base JSON version
37  * 3.2: Added POLL command and response
38  * 3.3: AIS app_id split into DAC and FID
39  * 3.4: Timestamps change from seconds since Unix epoch to ISO8601.
40  * 3.5: POLL subobject name changes: fixes -> tpv, skyview -> sky.
41  *      DEVICE::activated becomes ISO8601 rather than real.
42  * 3.6  VERSION, WATCH, and DEVICES from slave gpsds get "remote" attribute.
43  * 3.7  PPS message added to repertoire. SDDBT water depth reported as
44  *      negative altitude with Mode 3 set.
45  * 3.8  AIS course member becomes float in scaled mode (bug fix).
46  * 3.9  split24 flag added. Controlled-vocabulary fields are now always
47  *      dumped in both numeric and string form, with the string being the
48  *      value of a synthesized additional attribute with "_text" appended.
49  *      (Thus, the 'scaled' flag no longer affects display of these fields.)
50  *      PPS drift message ships nsec rather than msec.
51  * 3.10 The obsolete tag field has been dropped from JSON.
52  * 3.11 A precision field, log2 of the time source jitter, has been added
53  *      to the PPS report.  See ntpshm.h for more details.
54  * 3.12 OSC message added to repertoire.
55  * 3.13 gnssid:svid added to SAT
56  *      time added to ATT
57  * 3.19 Added RAW message class.
58  *      Add cfg_stage and cfg_step, for initialization
59  *      Add oldfix2 for better oldfix
60  *      Make subtype longer
61  *      Add ubx.protver, ubx.last_msgid and more to gps_device_t.ubx
62  *      MAX_PACKET_LENGTH 516 -> 9216
63  *      Add stuff to gps_device_t.nmea for NMEA 4.1
64  * 3.20
65  *      Remove TIMEHINT_ENABLE.  It only worked when enabled.
66  *      Remove NTP_ENABLE and NTPSHM_ENABLE.  It only worked when enabled.
67  *      Change gps_type_t.min_cycle from double to timespec_t
68  *      Change gps_device_t.last_time from double to timespec_t
69  *      Change gps_lexer_t.start_time from timestamp_t to timespec_t
70  *      Change gps_context_t.gps_tow from double to timespec_t
71  *      Change gps_device_t.sor from timestamp_t to timespec_t
72  *      Change gps_device_t.this_frac_time, last_frac_time to timespec_t
73  *      Change nmea.subseconds from double to timespec_t
74  *      Remove gpsd_gpstime_resolve()
75  *      Changed order of gpsd_log() arguments.  Add GPSD_LOG().
76  *      Remove gps_device_t.back_to_nmea.
77  *      Add fixed_port_speed, fixed_port_framing to gps_context_t.
78  *      change tsip.superpkt from bool to int.
79  *      Add tsip  .machine_id, .hardware_code, .last_tow, last_chan_seen
80  *      Split gps_device_t.subtype into subtype and subtype1
81  */
82 /* Keep in sync with api_major_version and api_minor gps/__init__.py */
83 #define GPSD_PROTO_MAJOR_VERSION	3   /* bump on incompatible changes */
84 #define GPSD_PROTO_MINOR_VERSION	14  /* bump on compatible changes */
85 
86 #define JSON_DATE_MAX	24	/* ISO8601 timestamp with 2 decimal places */
87 
88 // be sure to change BUILD_LEAPSECONDS as needed.
89 #define BUILD_CENTURY 2000
90 #define BUILD_LEAPSECONDS 18
91 
92 #ifndef DEFAULT_GPSD_SOCKET
93 #define DEFAULT_GPSD_SOCKET	"/var/run/gpsd.sock"
94 #endif
95 
96 /* Some internal capabilities depend on which drivers we're compiling. */
97 #if !defined(AIVDM_ENABLE) && defined(NMEA2000_ENABLE)
98 #define AIVDM_ENABLE
99 #endif
100 #if !defined(NMEA0183_ENABLE) && (defined(ASHTECH_ENABLE) || defined(FV18_ENABLE) || defined(MTK3301_ENABLE) || defined(TNT_ENABLE) || defined(OCEANSERVER_ENABLE) || defined(GPSCLOCK_ENABLE) || defined(FURY_ENABLE) || defined(SKYTRAQ_ENABLE)   || defined(TRIPMATE_ENABLE))
101 #define NMEA0183_ENABLE
102 #endif
103 #ifdef EARTHMATE_ENABLE
104 #define ZODIAC_ENABLE
105 #endif
106 
107 #if defined(EVERMORE_ENABLE) || \
108      defined(GARMIN_ENABLE) || \
109      defined(GEOSTAR_ENABLE) || \
110      defined(GREIS_ENABLE) || \
111      defined(ITRAX_ENABLE) || \
112      defined(NAVCOM_ENABLE) || \
113      defined(NMEA2000_ENABLE) || \
114      defined(ONCORE_ENABLE) || \
115      defined(SIRF_ENABLE) || \
116      defined(SUPERSTAR2_ENABLE) || \
117      defined(TSIP_ENABLE) || \
118      defined(UBLOX_ENABLE) || \
119      defined(ZODIAC_ENABLE)
120 #define BINARY_ENABLE
121 #endif
122 
123 #if defined(TRIPMATE_ENABLE) || defined(BINARY_ENABLE)
124 #define NON_NMEA0183_ENABLE
125 #endif
126 #if defined(TNT_ENABLE) || defined(OCEANSERVER_ENABLE)
127 #define COMPASS_ENABLE
128 #endif
129 #ifdef ISYNC_ENABLE
130 #define STASH_ENABLE
131 #endif
132 
133 /* First, declarations for the packet layer... */
134 
135 /*
136  * NMEA 3.01, Section 5.3 says the max sentence length shall be
137  * 82 chars, including the leading $ and terminating \r\n.
138  *
139  * Some receivers (TN-200, GSW 2.3.2) emit oversized sentences.
140  * The Trimble BX-960 receiver emits a 91-character GGA message.
141  * The current hog champion is the Skytraq S2525F8 which emits
142  * a 100-character PSTI message.
143  */
144 #define NMEA_MAX	102	/* max length of NMEA sentence */
145 #define NMEA_BIG_BUF	(2*NMEA_MAX+1)	/* longer than longest NMEA sentence */
146 
147 /* a few bits of ISGPS magic */
148 enum isgpsstat_t {
149     ISGPS_NO_SYNC, ISGPS_SYNC, ISGPS_SKIP, ISGPS_MESSAGE,
150 };
151 
152 #define RTCM_MAX	(RTCM2_WORDS_MAX * sizeof(isgps30bits_t))
153 /* RTCM is more variable length than RTCM 2 */
154 #define RTCM3_MAX	512
155 
156 /*
157  * The packet buffers need to be as long than the longest packet we
158  * expect to see in any protocol, because we have to be able to hold
159  * an entire packet for checksumming...
160  * First we thought it had to be big enough for a SiRF Measured Tracker
161  * Data packet (188 bytes). Then it had to be big enough for a UBX SVINFO
162  * packet (206 bytes). Now it turns out that a couple of ITALK messages are
163  * over 512 bytes. I know we like verbose output, but this is ridiculous.
164  * Whoopie! The u-blox 8 UBX-RXM-RAWX packet is 8214 byte long!
165  */
166 #define MAX_PACKET_LENGTH	9216	/* 4 + 16 + (256 * 32) + 2 + fudge */
167 
168 /*
169  * UTC of second 0 of week 0 of the first rollover period of GPS time.
170  * Used to compute UTC from GPS time. Also, the threshold value
171  * under which system clock times are considered unreliable. Often,
172  * embedded systems come up thinking it's early 1970 and the system
173  * clock will report small positive values until the clock is set.  By
174  * choosing this as the cutoff, we'll never reject historical GPS logs
175  * that are actually valid.
176  */
177 #define GPS_EPOCH	((time_t)315964800)   /* 6 Jan 1980 00:00:00 UTC */
178 
179 /* time constant */
180 #define SECS_PER_DAY	((time_t)(60*60*24))  /* seconds per day */
181 #define SECS_PER_WEEK	(7*SECS_PER_DAY)        /* seconds per week */
182 #define GPS_ROLLOVER	(1024*SECS_PER_WEEK)    /* rollover period */
183 
184 struct gpsd_errout_t {
185     int debug;				/* lexer debug level */
186     void (*report)(const char *);	/* reporting hook for lexer errors */
187     char *label;
188 };
189 
190 struct gps_lexer_t {
191     /* packet-getter internals */
192     int	type;
193 #define BAD_PACKET      	-1
194 #define COMMENT_PACKET  	0
195 #define NMEA_PACKET     	1
196 #define AIVDM_PACKET    	2
197 #define GARMINTXT_PACKET	3
198 #define MAX_TEXTUAL_TYPE	3	/* increment this as necessary */
199 #define SIRF_PACKET     	4
200 #define ZODIAC_PACKET   	5
201 #define TSIP_PACKET     	6
202 #define EVERMORE_PACKET 	7
203 #define ITALK_PACKET    	8
204 #define GARMIN_PACKET   	9
205 #define NAVCOM_PACKET   	10
206 #define UBX_PACKET      	11
207 #define SUPERSTAR2_PACKET	12
208 #define ONCORE_PACKET   	13
209 #define GEOSTAR_PACKET   	14
210 #define NMEA2000_PACKET 	15
211 #define GREIS_PACKET		16
212 #define MAX_GPSPACKET_TYPE	16	/* increment this as necessary */
213 #define RTCM2_PACKET    	17
214 #define RTCM3_PACKET    	18
215 #define JSON_PACKET    	    	19
216 #define PACKET_TYPES		20	/* increment this as necessary */
217 #define SKY_PACKET     		21
218 #define TEXTUAL_PACKET_TYPE(n)	((((n)>=NMEA_PACKET) && ((n)<=MAX_TEXTUAL_TYPE)) || (n)==JSON_PACKET)
219 #define GPS_PACKET_TYPE(n)	(((n)>=NMEA_PACKET) && ((n)<=MAX_GPSPACKET_TYPE))
220 #define LOSSLESS_PACKET_TYPE(n)	(((n)>=RTCM2_PACKET) && ((n)<=RTCM3_PACKET))
221 #define PACKET_TYPEMASK(n)	(1 << (n))
222 #define GPS_TYPEMASK	(((2<<(MAX_GPSPACKET_TYPE+1))-1) &~ PACKET_TYPEMASK(COMMENT_PACKET))
223     unsigned int state;
224     size_t length;
225     unsigned char inbuffer[MAX_PACKET_LENGTH*2+1];
226     size_t inbuflen;
227     unsigned char *inbufptr;
228     /* outbuffer needs to be able to hold 4 GPGSV records at once */
229     unsigned char outbuffer[MAX_PACKET_LENGTH*2+1];
230     size_t outbuflen;
231     unsigned long char_counter;		/* count characters processed */
232     unsigned long retry_counter;	/* count sniff retries */
233     unsigned counter;			/* packets since last driver switch */
234     struct gpsd_errout_t errout;		/* how to report errors */
235     timespec_t start_time;		/* time of first input */
236     unsigned long start_char;		/* char counter at first input */
237     /*
238      * ISGPS200 decoding context.
239      *
240      * This is not conditionalized on RTCM104_ENABLE because we need to
241      * be able to build gpsdecode even when RTCM support is not
242      * configured in the daemon.
243      */
244     struct {
245 	bool            locked;
246 	int             curr_offset;
247 	isgps30bits_t   curr_word;
248 	unsigned int    bufindex;
249 	/*
250 	 * Only these should be referenced from elsewhere, and only when
251 	 * RTCM_MESSAGE has just been returned.
252 	 */
253 	isgps30bits_t   buf[RTCM2_WORDS_MAX];   /* packet data */
254 	size_t          buflen;                 /* packet length in bytes */
255     } isgps;
256 #ifdef PASSTHROUGH_ENABLE
257     unsigned int json_depth;
258     unsigned int json_after;
259 #endif /* PASSTHROUGH_ENABLE */
260 #ifdef STASH_ENABLE
261     unsigned char stashbuffer[MAX_PACKET_LENGTH];
262     size_t stashbuflen;
263 #endif /* STASH_ENABLE */
264 };
265 
266 extern void lexer_init(struct gps_lexer_t *);
267 extern void packet_reset(struct gps_lexer_t *);
268 extern void packet_pushback(struct gps_lexer_t *);
269 extern void packet_parse(struct gps_lexer_t *);
270 extern ssize_t packet_get(int, struct gps_lexer_t *);
271 extern int packet_sniff(struct gps_lexer_t *);
272 #define packet_buffered_input(lexer) ((lexer)->inbuffer + (lexer)->inbuflen - (lexer)->inbufptr)
273 
274 /* Next, declarations for the core library... */
275 
276 /* factors for converting among confidence interval units */
277 #define CEP50_SIGMA	1.18
278 #define DRMS_SIGMA	1.414
279 #define CEP95_SIGMA	2.45
280 
281 /* this is where we choose the confidence level to use in reports */
282 #define GPSD_CONFIDENCE	CEP95_SIGMA
283 
284 #define NTPSHMSEGS	(MAX_DEVICES * 2)	/* number of NTP SHM segments */
285 #define NTP_MIN_FIXES	3  /* # fixes to wait for before shipping NTP time */
286 
287 
288 #define AIVDM_CHANNELS	2		/* A, B */
289 
290 struct gps_device_t;
291 
292 struct gps_context_t {
293     int valid;				/* member validity flags */
294 #define LEAP_SECOND_VALID	0x01	/* we have or don't need correction */
295 #define GPS_TIME_VALID  	0x02	/* GPS week/tow is valid */
296 #define CENTURY_VALID		0x04	/* have received ZDA or 4-digit year */
297     struct gpsd_errout_t errout;		/* debug verbosity level and hook */
298     bool readonly;			/* if true, never write to device */
299     speed_t fixed_port_speed;           // Fixed port speed, if non-zero
300     char fixed_port_framing[4];         // Fixed port framing, if non-blank
301     /* DGPS status */
302     int fixcnt;				/* count of good fixes seen */
303     /* timekeeping */
304     time_t start_time;			/* local time of daemon startup */
305     int leap_seconds;			/* Unix seconds to UTC (GPS-UTC offset) */
306     unsigned short gps_week;            /* GPS week, usually 10 bits */
307     timespec_t gps_tow;                 /* GPS time of week */
308     int century;			/* for NMEA-only devices without ZDA */
309     int rollovers;			/* rollovers since start of run */
310     int leap_notify;			/* notification state from subframe */
311 #define LEAP_NOWARNING  0x0     /* normal, no leap second warning */
312 #define LEAP_ADDSECOND  0x1     /* last minute of day has 60 seconds */
313 #define LEAP_DELSECOND  0x2     /* last minute of day has 59 seconds */
314 #define LEAP_NOTINSYNC  0x3     /* overload, clock is free running */
315     /* we need the volatile here to tell the C compiler not to
316      * 'optimize' as 'dead code' the writes to SHM */
317     volatile struct shmTime *shmTime[NTPSHMSEGS];
318     bool shmTimeInuse[NTPSHMSEGS];
319     void (*pps_hook)(struct gps_device_t *, struct timedelta_t *);
320 #ifdef SHM_EXPORT_ENABLE
321     /* we don't want the compiler to treat writes to shmexport as dead code,
322      * and we don't want them reordered either */
323     volatile void *shmexport;
324     int shmid;				/* ID of SHM  (for later IPC_RMID) */
325 #endif
326     ssize_t (*serial_write)(struct gps_device_t *,
327 			    const char *buf, const size_t len);
328 };
329 
330 /* state for resolving interleaved Type 24 packets */
331 struct ais_type24a_t {
332     unsigned int mmsi;
333     char shipname[AIS_SHIPNAME_MAXLEN+1];
334 };
335 #define MAX_TYPE24_INTERLEAVE	8	/* max number of queued type 24s */
336 struct ais_type24_queue_t {
337     struct ais_type24a_t ships[MAX_TYPE24_INTERLEAVE];
338     int index;
339 };
340 
341 /* state for resolving AIVDM decodes */
342 struct aivdm_context_t {
343     /* hold context for decoding AIDVM packet sequences */
344     int decoded_frags;		/* for tracking AIDVM parts in a multipart sequence */
345     unsigned char bits[2048];
346     size_t bitlen; /* how many valid bits */
347     struct ais_type24_queue_t type24_queue;
348 };
349 
350 #define MODE_NMEA	0
351 #define MODE_BINARY	1
352 
353 typedef enum {ANY, GPS, RTCM2, RTCM3, AIS} gnss_type;
354 typedef enum {
355     event_wakeup,
356     event_triggermatch,
357     event_identified,
358     event_configure,
359     event_driver_switch,
360     event_deactivate,
361     event_reactivate,
362 } event_t;
363 
364 
365 #define INTERNAL_SET(n)	((gps_mask_t)(1llu<<(SET_HIGH_BIT+(n))))
366 #define RAW_IS  	INTERNAL_SET(1) 	/* raw pseudoranges available */
367 #define USED_IS 	INTERNAL_SET(2) 	/* sat-used count available */
368 #define DRIVER_IS	INTERNAL_SET(3) 	/* driver type identified */
369 #define CLEAR_IS	INTERNAL_SET(4) 	/* starts a reporting cycle */
370 #define REPORT_IS	INTERNAL_SET(5) 	/* ends a reporting cycle */
371 #define NODATA_IS	INTERNAL_SET(6) 	/* no data read from fd */
372 #define NTPTIME_IS	INTERNAL_SET(7) 	/* precision time is available */
373 #define PERR_IS 	INTERNAL_SET(8) 	/* PDOP set */
374 #define PASSTHROUGH_IS 	INTERNAL_SET(9) 	/* passthrough mode */
375 #define EOF_IS		INTERNAL_SET(10)	/* synthetic EOF */
376 #define GOODTIME_IS	INTERNAL_SET(11) 	/* time good even if no pos fix */
377 #define DATA_IS	~(ONLINE_SET|PACKET_SET|CLEAR_IS|REPORT_IS)
378 
379 typedef unsigned int driver_mask_t;
380 #define DRIVER_NOFLAGS	0x00000000u
381 #define DRIVER_STICKY	0x00000001u
382 
383 /*
384  * True if a device type is non-null and has control methods.
385  */
386 #define CONTROLLABLE(dp)	(((dp) != NULL) && \
387 				 ((dp)->speed_switcher != NULL		\
388 				  || (dp)->mode_switcher != NULL	\
389 				  || (dp)->rate_switcher != NULL))
390 
391 /*
392  * True if a driver selection of it should be sticky.
393  */
394 #define STICKY(dp)		((dp) != NULL && ((dp)->flags & DRIVER_STICKY) != 0)
395 
396 struct gps_type_t {
397 /* GPS method table, describes how to talk to a particular GPS type */
398     char *type_name;
399     int packet_type;
400     driver_mask_t flags;	/* reserved for expansion */
401     char *trigger;
402     int channels;
403     bool (*probe_detect)(struct gps_device_t *session);
404     ssize_t (*get_packet)(struct gps_device_t *session);
405     gps_mask_t (*parse_packet)(struct gps_device_t *session);
406     ssize_t (*rtcm_writer)(struct gps_device_t *session, const char *rtcmbuf, size_t rtcmbytes);
407     void (*init_query)(struct gps_device_t *session);
408     void (*event_hook)(struct gps_device_t *session, event_t event);
409 #ifdef RECONFIGURE_ENABLE
410     bool (*speed_switcher)(struct gps_device_t *session,
411 				     speed_t speed, char parity, int stopbits);
412     void (*mode_switcher)(struct gps_device_t *session, int mode);
413     bool (*rate_switcher)(struct gps_device_t *session, double rate);
414     timespec_t min_cycle;
415 #endif /* RECONFIGURE_ENABLE */
416 #ifdef CONTROLSEND_ENABLE
417     ssize_t (*control_send)(struct gps_device_t *session, char *buf, size_t buflen);
418 #endif /* CONTROLSEND_ENABLE */
419     double (*time_offset)(struct gps_device_t *session);
420 };
421 
422 /*
423  * Each input source has an associated type.  This is currently used in two
424  * ways:
425  *
426  * (1) To determine if we require that gpsd be the only process opening a
427  * device.  We make an exception for PTYs because the master side has to be
428  * opened by test code.
429  *
430  * (2) To determine whether it's safe to send wakeup strings.  These are
431  * required on some unusual RS-232 devices (such as the TNT compass and
432  * Thales/Ashtech GPSes) but should not be shipped to unidentified USB
433  * or Bluetooth devices as we don't even know in advance those are GPSes;
434  * they might not cope well.
435  *
436  * Where it says "case detected but not used" it means that we can identify
437  * a source type but no behavior is yet contingent on it.  A "discoverable"
438  * device is one for which there is discoverable metadata such as a
439  * vendor/product ID.
440  *
441  * We should never see a block device; that would indicate a serious error
442  * in command-line usage or the hotplug system.
443  */
444 typedef enum {source_unknown,
445 	      source_blockdev,	/* block devices can't be GPS sources */
446 	      source_rs232,	/* potential GPS source, not discoverable */
447 	      source_usb,	/* potential GPS source, discoverable */
448 	      source_bluetooth,	/* potential GPS source, discoverable */
449 	      source_can,	/* potential GPS source, fixed CAN format */
450 	      source_pty,	/* PTY: we don't require exclusive access */
451 	      source_tcp,	/* TCP/IP stream: case detected but not used */
452 	      source_udp,	/* UDP stream: case detected but not used */
453 	      source_gpsd,	/* Remote gpsd instance over TCP/IP */
454 	      source_pps,	/* PPS-only device, such as /dev/ppsN */
455 	      source_pipe,	/* Unix FIFO; don't use blocking I/O */
456 } sourcetype_t;
457 
458 /*
459  * Each input source also has an associated service type.
460  */
461 typedef enum {service_unknown,
462 	      service_sensor,
463 	      service_dgpsip,
464 	      service_ntrip,
465 } servicetype_t;
466 
467 /*
468  * Private state information about an NTRIP stream.
469  */
470 struct ntrip_stream_t
471 {
472     char mountpoint[101];
473     char credentials[128];
474     char authStr[128];
475     char url[256];
476     char port[32]; /* in my /etc/services 16 was the longest */
477     bool set; /* found and set */
478     enum
479     {
480 	fmt_rtcm2,
481 	fmt_rtcm2_0,
482 	fmt_rtcm2_1,
483 	fmt_rtcm2_2,
484 	fmt_rtcm2_3,
485 	fmt_rtcm3_0,
486 	fmt_rtcm3_1,
487 	fmt_rtcm3_2,
488 	fmt_rtcm3_3,
489 	fmt_unknown
490     } format;
491     int carrier;
492     double latitude;
493     double longitude;
494     int nmea;
495     enum
496     { cmp_enc_none, cmp_enc_unknown } compr_encryp;
497     enum
498     { auth_none, auth_basic, auth_digest, auth_unknown } authentication;
499     int fee;
500     int bitrate;
501 };
502 
503 struct gps_device_t {
504 /* session object, encapsulates all global state */
505     struct gps_data_t gpsdata;
506     const struct gps_type_t *device_type;
507     unsigned int driver_index;	      /* numeric index of current driver */
508     unsigned int drivers_identified;  /* bitmask; what drivers have we seen? */
509     unsigned int cfg_stage;	/* configuration stage counter */
510     unsigned int cfg_step;	/* configuration step counter */
511 #ifdef RECONFIGURE_ENABLE
512     const struct gps_type_t *last_controller;
513 #endif /* RECONFIGURE_ENABLE */
514     struct gps_context_t	*context;
515     sourcetype_t sourcetype;
516     servicetype_t servicetype;
517     int mode;
518     struct termios ttyset, ttyset_old;
519     unsigned int baudindex;
520     int saved_baud;
521     struct gps_lexer_t lexer;
522     int badcount;
523     int subframe_count;
524     /* firmware version or subtype ID, 96 too small for ZED-F9 */
525     char subtype[128];
526     char subtype1[128];
527     time_t opentime;
528     time_t releasetime;
529     bool zerokill;
530     time_t reawake;
531     timespec_t sor;	        /* time start of this reporting cycle */
532     unsigned long chars;	/* characters in the cycle */
533     bool ship_to_ntpd;
534     volatile struct shmTime *shm_clock;
535     volatile struct shmTime *shm_pps;
536     int chronyfd;			/* for talking to chrony */
537     volatile struct pps_thread_t pps_thread;
538     /*
539      * msgbuf needs to hold the hex decode of inbuffer
540      * so msgbuf must be 2x the size of inbuffer
541      */
542     char msgbuf[MAX_PACKET_LENGTH*4+1];	/* command message buffer for sends */
543     size_t msgbuflen;
544     int observed;			/* which packet type`s have we seen? */
545     bool cycle_end_reliable;		/* does driver signal REPORT_MASK */
546     int fixcnt;				/* count of fixes from this device */
547     struct gps_fix_t newdata;		/* where drivers put their data */
548     struct gps_fix_t lastfix;		/* not quite yet ready for oldfix */
549     struct gps_fix_t oldfix;		/* previous fix for error modeling */
550 #ifdef NMEA0183_ENABLE
551     struct {
552 	unsigned short sats_used[MAXCHANNELS];
553 	int part, await;		/* for tracking GSV parts */
554 	struct tm date;	                /* date part of last sentence time */
555 	timespec_t subseconds;		/* subsec part of last sentence time */
556 	char *field[NMEA_MAX];
557 	unsigned char fieldcopy[NMEA_MAX+1];
558 	/* detect receivers that ship GGA with non-advancing timestamp */
559 	bool latch_mode;
560 	char last_gga_timestamp[16];
561 	char last_gga_talker;
562         /* GSV stuff */
563 	bool seen_bdgsv;
564 	bool seen_gagsv;
565 	bool seen_glgsv;
566 	bool seen_gpgsv;
567 	bool seen_qzss;
568 	char last_gsv_talker;
569 	unsigned char last_gsv_sigid;           /* NMEA 4.1 */
570         /* GSA stuff */
571 	bool seen_glgsa;
572 	bool seen_gngsa;
573 	bool seen_bdgsa;
574 	bool seen_gagsa;
575 	char last_gsa_talker;
576 	/*
577 	 * State for the cycle-tracking machinery.
578 	 * The reason these timestamps are separate from the
579 	 * general sentence timestamps is that we can
580 	 * use the minutes and seconds part of a sentence
581 	 * with an incomplete timestamp (like GGA) for
582 	 * end-cycle recognition, even if we don't have a previous
583 	 * RMC or ZDA that lets us get full time from it.
584 	 */
585 	timespec_t this_frac_time, last_frac_time;
586 	bool latch_frac_time;
587 	int lasttag;              /* index into nmea_phrase[] */
588 	uint64_t cycle_enders;    /* bit map into nmea_phrase{} */
589 	bool cycle_continue;
590     } nmea;
591 #endif /* NMEA0183_ENABLE */
592     /*
593      * The rest of this structure is driver-specific private storage.
594      * Only put a driver's scratch storage in here if it is never
595      * implemented on the same device that supports any mode already
596      * in this union; otherwise bad things might happen after a device
597      * mode switch.
598      */
599     union {
600 #ifdef BINARY_ENABLE
601 #ifdef GEOSTAR_ENABLE
602 	struct {
603 	    unsigned int physical_port;
604 	} geostar;
605 #endif /* GEOSTAR_ENABLE */
606 #ifdef GREIS_ENABLE
607 	struct {
608 	    uint32_t rt_tod;		/* RT message time of day (modulo 1 day) */
609 	    bool seen_rt;		/* true if seen RT message */
610 	    bool seen_uo;		/* true if seen UO message */
611 	    bool seen_si;		/* true if seen SI message */
612 	    bool seen_az;		/* true if seen AZ message */
613 	    bool seen_ec;		/* true if seen EC message */
614 	    bool seen_el;		/* true if seen EL message */
615             /* true if seen a raw measurement message */
616 	    bool seen_raw;
617 	} greis;
618 #endif /* GREIS_ENABLE */
619 #ifdef SIRF_ENABLE
620 	struct {
621 	    unsigned int need_ack;	/* if NZ we're awaiting ACK */
622 	    unsigned int driverstate;	/* for private use */
623 #define SIRF_LT_231	0x01		/* SiRF at firmware rev < 231 */
624 #define SIRF_EQ_231     0x02            /* SiRF at firmware rev == 231 */
625 #define SIRF_GE_232     0x04            /* SiRF at firmware rev >= 232 */
626 #define UBLOX   	0x08		/* u-blox firmware with packet 0x62 */
627 	    unsigned long satcounter;
628 	    unsigned int time_seen;
629 	    unsigned char lastid;	/* ID with last timestamp seen */
630 #define TIME_SEEN_UTC_2	0x08	/* Seen UTC time variant 2? */
631 	    /* fields from Navigation Parameters message */
632 	    bool nav_parameters_seen;	/* have we seen one? */
633 	    unsigned char altitude_hold_mode;
634 	    unsigned char altitude_hold_source;
635 	    int16_t altitude_source_input;
636 	    unsigned char degraded_mode;
637 	    unsigned char degraded_timeout;
638 	    unsigned char dr_timeout;
639 	    unsigned char track_smooth_mode;
640 	    /* fields from DGPS Status */
641 	    unsigned int dgps_source;
642 #define SIRF_DGPS_SOURCE_NONE		0 /* No DGPS correction type have been selected */
643 #define SIRF_DGPS_SOURCE_SBAS		1 /* SBAS */
644 #define SIRF_DGPS_SOURCE_SERIAL		2 /* RTCM corrections */
645 #define SIRF_DGPS_SOURCE_BEACON		3 /* Beacon corrections */
646 #define SIRF_DGPS_SOURCE_SOFTWARE	4 /*  Software API corrections */
647 	} sirf;
648 #endif /* SIRF_ENABLE */
649 #ifdef SUPERSTAR2_ENABLE
650 	struct {
651 	    time_t last_iono;
652 	} superstar2;
653 #endif /* SUPERSTAR2_ENABLE */
654 #ifdef TSIP_ENABLE
655 	struct {
656 	    unsigned short sats_used[MAXCHANNELS];
657             /* Super Packet mode requested.
658              * 0 = None, 1 = old superpacket, 2 = new superpacket (SMT 360) */
659 	    uint8_t superpkt;
660 	    uint8_t machine_id;         // from 0x4b
661 	    uint16_t hardware_code;     // from 0x1c-83
662 	    time_t last_41;		/* Timestamps for packet requests */
663 	    time_t last_48;
664 	    time_t last_5c;
665 	    time_t last_6d;
666 	    time_t last_46;
667 	    time_t req_compact;
668 	    unsigned int stopbits; /* saved RS232 link parameter */
669 	    char parity;
670 	    int subtype;                // hardware ID, sort of
671 #define TSIP_UNKNOWN            0
672 #define TSIP_ACUTIME_GOLD       3001
673 #define TSIP_RESSMT360          3023
674 #define TSIP_ICMSMT360          3026
675 #define TSIP_RES36017x22        3031
676             uint8_t alt_is_msl;         // 0 if alt is HAE, 1 if MSL
677             timespec_t last_tow;        // used to find cycle start
678             int last_chan_seen;         // from 0x5c or 0x5d
679 	} tsip;
680 #endif /* TSIP_ENABLE */
681 #ifdef GARMIN_ENABLE	/* private housekeeping stuff for the Garmin driver */
682 	struct {
683 	    unsigned char Buffer[4096+12];	/* Garmin packet buffer */
684 	    size_t BufferLen;		/* current GarminBuffer Length */
685 	} garmin;
686 #endif /* GARMIN_ENABLE */
687 #ifdef ZODIAC_ENABLE	/* private housekeeping stuff for the Zodiac driver */
688 	struct {
689 	    unsigned short sn;		/* packet sequence number */
690 	    /*
691 	     * Zodiac chipset channel status from PRWIZCH. Keep it so
692 	     * raw-mode translation of Zodiac binary protocol can send
693 	     * it up to the client.
694 	     */
695 #define ZODIAC_CHANNELS	12
696 	    unsigned int Zs[ZODIAC_CHANNELS];	/* satellite PRNs */
697 	    unsigned int Zv[ZODIAC_CHANNELS];	/* signal values (0-7) */
698 	} zodiac;
699 #endif /* ZODIAC_ENABLE */
700 #ifdef UBLOX_ENABLE
701 	struct {
702 	    unsigned char port_id;
703 	    unsigned char sbas_in_use;
704 	    unsigned char protver;              /* u-blox protocol version */
705 	    unsigned int last_msgid;            /* last class/ID */
706             /* FIXME: last_time set but never used? */
707             timespec_t last_time;               /* time of last_msgid */
708 	    unsigned int end_msgid;             /* cycle ender class/ID */
709             /* iTOW, and last_iTOW, in ms, used for cycle end detect. */
710             int64_t iTOW;
711             int64_t last_iTOW;
712     	} ubx;
713 #endif /* UBLOX_ENABLE */
714 #ifdef NAVCOM_ENABLE
715 	struct {
716 	    uint8_t physical_port;
717 	    bool warned;
718 	} navcom;
719 #endif /* NAVCOM_ENABLE */
720 #ifdef ONCORE_ENABLE
721 	struct {
722 #define ONCORE_VISIBLE_CH 12
723 	    int visible;
724 	    int PRN[ONCORE_VISIBLE_CH];		/* PRNs of satellite */
725 	    int elevation[ONCORE_VISIBLE_CH];	/* elevation of satellite */
726 	    int azimuth[ONCORE_VISIBLE_CH];	/* azimuth */
727 	    int pps_offset_ns;
728 	} oncore;
729 #endif /* ONCORE_ENABLE */
730 #ifdef NMEA2000_ENABLE
731 	struct {
732 	    unsigned int can_msgcnt;
733 	    unsigned int can_net;
734 	    unsigned int unit;
735 	    bool unit_valid;
736 	    int mode;
737 	    unsigned int mode_valid;
738 	    unsigned int idx;
739 //	    size_t ptr;
740 	    size_t fast_packet_len;
741 	    int type;
742 	    void *workpgn;
743 	    void *pgnlist;
744 	    unsigned char sid[8];
745 	} nmea2000;
746 #endif /* NMEA2000_ENABLE */
747 	/*
748 	 * This is not conditionalized on RTCM104_ENABLE because we need to
749 	 * be able to build gpsdecode even when RTCM support is not
750 	 * configured in the daemon.  It doesn't take up extra space.
751 	 */
752 	struct {
753 	    /* ISGPS200 decoding */
754 	    bool            locked;
755 	    int             curr_offset;
756 	    isgps30bits_t   curr_word;
757 	    isgps30bits_t   buf[RTCM2_WORDS_MAX];
758 	    unsigned int    bufindex;
759 	} isgps;
760 #endif /* BINARY_ENABLE */
761 #ifdef AIVDM_ENABLE
762 	struct {
763 	    struct aivdm_context_t context[AIVDM_CHANNELS];
764 	    char ais_channel;
765 	} aivdm;
766 #endif /* AIVDM_ENABLE */
767     } driver;
768 
769     /*
770      * State of an NTRIP connection.  We don't want to zero this on every
771      * activation, otherwise the connection state will get lost.  Information
772      * in this substructure is only valid if servicetype is service_ntrip.
773      */
774     struct {
775 	/* state information about the stream */
776 	struct ntrip_stream_t stream;
777 
778 	/* state information about our response parsing */
779 	enum {
780 	    ntrip_conn_init,
781 	    ntrip_conn_sent_probe,
782 	    ntrip_conn_sent_get,
783 	    ntrip_conn_established,
784 	    ntrip_conn_err
785 	} conn_state; 	/* connection state for multi stage connect */
786 	bool works;		/* marks a working connection, so we try to reconnect once */
787 	bool sourcetable_parse;	/* have we read the sourcetable header? */
788     } ntrip;
789     /* State of a DGPSIP connection */
790     struct {
791 	bool reported;
792     } dgpsip;
793 };
794 
795 /*
796  * These are used where a file descriptor of 0 or greater indicates open device.
797  */
798 #define UNALLOCATED_FD	-1	/* this slot is available for reallocation */
799 #define PLACEHOLDING_FD	-2	/* this slot *not* available for reallocation */
800 
801 /* logging levels */
802 #define LOG_ERROR 	-1	/* errors, display always */
803 #define LOG_SHOUT	0	/* not an error but we should always see it */
804 #define LOG_WARN	1	/* not errors but may indicate a problem */
805 #define LOG_CLIENT	2	/* log JSON reports to clients */
806 #define LOG_INF 	3	/* key informative messages */
807 #define LOG_PROG	4	/* progress messages */
808 #define LOG_IO  	5	/* IO to and from devices */
809 #define LOG_DATA	6	/* log data management messages */
810 #define LOG_SPIN	7	/* logging for catching spin bugs */
811 #define LOG_RAW 	8	/* raw low-level I/O */
812 
813 #define ISGPS_ERRLEVEL_BASE	LOG_RAW
814 
815 #define IS_HIGHEST_BIT(v,m)	(v & ~((m<<1)-1))==0
816 
817 /* driver helper functions */
818 extern void isgps_init(struct gps_lexer_t *);
819 enum isgpsstat_t isgps_decode(struct gps_lexer_t *,
820 			      bool (*preamble_match)(isgps30bits_t *),
821 			      bool (*length_check)(struct gps_lexer_t *),
822 			      size_t,
823 			      unsigned int);
824 extern unsigned int isgps_parity(isgps30bits_t);
825 extern void isgps_output_magnavox(const isgps30bits_t *, unsigned int, FILE *);
826 
827 extern enum isgpsstat_t rtcm2_decode(struct gps_lexer_t *, unsigned int);
828 extern void json_rtcm2_dump(const struct rtcm2_t *,
829 			    const char *, char[], size_t);
830 extern void rtcm2_unpack(struct rtcm2_t *, char *);
831 extern void json_rtcm3_dump(const struct rtcm3_t *,
832 			    const char *, char[], size_t);
833 extern void rtcm3_unpack(const struct gps_context_t *,
834 			 struct rtcm3_t *, char *);
835 
836 /* here are the available GPS drivers */
837 extern const struct gps_type_t **gpsd_drivers;
838 
839 /* gpsd library internal prototypes */
840 extern gps_mask_t generic_parse_input(struct gps_device_t *);
841 extern ssize_t generic_get(struct gps_device_t *);
842 
843 extern gps_mask_t nmea_parse(char *, struct gps_device_t *);
844 extern ssize_t nmea_write(struct gps_device_t *, char *, size_t);
845 extern ssize_t nmea_send(struct gps_device_t *, const char *, ... );
846 extern void nmea_add_checksum(char *);
847 
848 extern gps_mask_t sirf_parse(struct gps_device_t *, unsigned char *, size_t);
849 extern gps_mask_t evermore_parse(struct gps_device_t *, unsigned char *, size_t);
850 extern gps_mask_t navcom_parse(struct gps_device_t *, unsigned char *, size_t);
851 extern gps_mask_t garmin_ser_parse(struct gps_device_t *);
852 extern gps_mask_t garmintxt_parse(struct gps_device_t *);
853 extern gps_mask_t aivdm_parse(struct gps_device_t *);
854 
855 extern bool netgnss_uri_check(char *);
856 extern int netgnss_uri_open(struct gps_device_t *, char *);
857 extern void netgnss_report(struct gps_context_t *,
858 			 struct gps_device_t *,
859 			 struct gps_device_t *);
860 extern void netgnss_autoconnect(struct gps_context_t *, double, double);
861 
862 extern int dgpsip_open(struct gps_device_t *, const char *);
863 extern void dgpsip_report(struct gps_context_t *,
864 			 struct gps_device_t *,
865 			 struct gps_device_t *);
866 extern void dgpsip_autoconnect(struct gps_context_t *,
867 			       double, double, const char *);
868 extern int ntrip_open(struct gps_device_t *, char *);
869 extern void ntrip_report(struct gps_context_t *,
870 			 struct gps_device_t *,
871 			 struct gps_device_t *);
872 
873 extern void gpsd_tty_init(struct gps_device_t *);
874 extern int gpsd_serial_open(struct gps_device_t *);
875 extern bool gpsd_set_raw(struct gps_device_t *);
876 extern ssize_t gpsd_serial_write(struct gps_device_t *,
877 				 const char *, const size_t);
878 extern bool gpsd_next_hunt_setting(struct gps_device_t *);
879 extern int gpsd_switch_driver(struct gps_device_t *, char *);
880 extern void gpsd_set_speed(struct gps_device_t *, speed_t, char, unsigned int);
881 extern speed_t gpsd_get_speed(const struct gps_device_t *);
882 extern speed_t gpsd_get_speed_old(const struct gps_device_t *);
883 extern int gpsd_get_stopbits(const struct gps_device_t *);
884 extern char gpsd_get_parity(const struct gps_device_t *);
885 extern void gpsd_assert_sync(struct gps_device_t *);
886 extern void gpsd_close(struct gps_device_t *);
887 
888 extern ssize_t gpsd_write(struct gps_device_t *, const char *, const size_t);
889 
890 extern void gpsd_time_init(struct gps_context_t *, time_t);
891 extern void gpsd_set_century(struct gps_device_t *);
892 extern timespec_t gpsd_gpstime_resolv(struct gps_device_t *,
893 			      const unsigned short, const timespec_t);
894 extern timespec_t gpsd_utc_resolve(struct gps_device_t *);
895 extern void gpsd_century_update(struct gps_device_t *, int);
896 
897 extern void gpsd_zero_satellites(struct gps_data_t *sp);
898 extern gps_mask_t gpsd_interpret_subframe(struct gps_device_t *, unsigned int,
899 				uint32_t[]);
900 extern gps_mask_t gpsd_interpret_subframe_raw(struct gps_device_t *,
901 				unsigned int, uint32_t[]);
902 extern const char *gpsd_hexdump(char *, size_t, char *, size_t);
903 extern const char *gpsd_packetdump(char *, size_t, char *, size_t);
904 extern const char *gpsd_prettydump(struct gps_device_t *);
905 # ifdef __cplusplus
906 extern "C" {
907 # endif
908 extern int gpsd_hexpack(const char *, char *, size_t);
909 # ifdef __cplusplus
910 }
911 # endif
912 extern ssize_t hex_escapes(char *, const char *);
913 extern void gpsd_position_fix_dump(struct gps_device_t *,
914 				   char[], size_t);
915 extern void gpsd_clear_data(struct gps_device_t *);
916 extern socket_t netlib_connectsock(int, const char *, const char *, const char *);
917 extern socket_t netlib_localsocket(const char *, int);
918 extern const char *netlib_errstr(const int);
919 extern char *netlib_sock2ip(socket_t);
920 
921 extern void nmea_tpv_dump(struct gps_device_t *, char[], size_t);
922 extern void nmea_sky_dump(struct gps_device_t *, char[], size_t);
923 extern void nmea_subframe_dump(struct gps_device_t *, char[], size_t);
924 extern void nmea_ais_dump(struct gps_device_t *, char[], size_t);
925 extern unsigned int ais_binary_encode(struct ais_t *ais, unsigned char *bits, int flag);
926 
927 extern void ntp_latch(struct gps_device_t *device,  struct timedelta_t *td);
928 extern void ntpshm_context_init(struct gps_context_t *);
929 extern void ntpshm_session_init(struct gps_device_t *);
930 extern int ntpshm_put(struct gps_device_t *, volatile struct shmTime *, struct timedelta_t *);
931 extern void ntpshm_link_deactivate(struct gps_device_t *);
932 extern void ntpshm_link_activate(struct gps_device_t *);
933 
934 extern void errout_reset(struct gpsd_errout_t *errout);
935 
936 extern void gpsd_acquire_reporting_lock(void);
937 extern void gpsd_release_reporting_lock(void);
938 
939 extern gps_mask_t ecef_to_wgs84fix(struct gps_fix_t *,
940                                    double, double, double,
941                                    double, double, double);
942 extern void clear_dop(struct dop_t *);
943 
944 /* shmexport.c */
945 #define GPSD_SHM_KEY	0x47505344	/* "GPSD" */
946 struct shmexport_t
947 {
948     int bookend1;
949     struct gps_data_t gpsdata;
950     int bookend2;
951 };
952 extern bool shm_acquire(struct gps_context_t *);
953 extern void shm_release(struct gps_context_t *);
954 extern void shm_update(struct gps_context_t *, struct gps_data_t *);
955 
956 /* dbusexport.c */
957 #if defined(DBUS_EXPORT_ENABLE)
958 int initialize_dbus_connection (void);
959 void send_dbus_fix (struct gps_device_t* channel);
960 #endif /* defined(DBUS_EXPORT_ENABLE) */
961 
962 /* srecord.c */
963 extern void hexdump(size_t, unsigned char *, unsigned char *);
964 extern unsigned char sr_sum(unsigned int, unsigned int, unsigned char *);
965 extern int bin2srec(unsigned int, unsigned int, unsigned int, unsigned char *, unsigned char *);
966 extern int srec_hdr(unsigned int, unsigned char *, unsigned char *);
967 extern int srec_fin(unsigned int, unsigned char *);
968 extern unsigned char hc(unsigned char);
969 
970 /* a BSD transplant */
971 int b64_ntop(unsigned char const *src, size_t srclength, char *target,
972     size_t targsize);
973 
974 /* application interface */
975 extern void gps_context_init(struct gps_context_t *context,
976 			     const char *label);
977 extern void gpsd_init(struct gps_device_t *,
978 		      struct gps_context_t *,
979 		      const char *);
980 extern void gpsd_clear(struct gps_device_t *);
981 extern int gpsd_open(struct gps_device_t *);
982 #define O_CONTINUE	0
983 #define O_PROBEONLY	1
984 #define O_OPTIMIZE	2
985 extern int gpsd_activate(struct gps_device_t *, const int);
986 extern void gpsd_deactivate(struct gps_device_t *);
987 
988 #define AWAIT_GOT_INPUT	1
989 #define AWAIT_NOT_READY	0
990 #define AWAIT_FAILED	-1
991 extern int gpsd_await_data(fd_set *,
992 			   fd_set *,
993 			    const int,
994 			    fd_set *,
995 			    struct gpsd_errout_t *errout);
996 extern gps_mask_t gpsd_poll(struct gps_device_t *);
997 #define DEVICE_EOF	-3
998 #define DEVICE_ERROR	-2
999 #define DEVICE_UNREADY	-1
1000 #define DEVICE_READY	1
1001 #define DEVICE_UNCHANGED	0
1002 extern int gpsd_multipoll(const bool,
1003 			  struct gps_device_t *,
1004 			  void (*)(struct gps_device_t *, gps_mask_t),
1005 			  float reawake_time);
1006 extern void gpsd_wrap(struct gps_device_t *);
1007 extern bool gpsd_add_device(const char *device_name, bool flag_nowait);
1008 extern const char *gpsd_maskdump(gps_mask_t);
1009 
1010 /* exceptional driver methods */
1011 extern bool ubx_write(struct gps_device_t *, unsigned int, unsigned int,
1012 		      unsigned char *, size_t);
1013 extern bool ais_binary_decode(const struct gpsd_errout_t *errout,
1014 			      struct ais_t *ais,
1015 			      const unsigned char *, size_t,
1016 			      struct ais_type24_queue_t *);
1017 
1018 void gpsd_labeled_report(const int, const int,
1019 			 const char *, const char *, va_list);
1020 
1021 // do not call gpsd_log() directly, use GPSD_LOG() to save a lot of cpu time
1022 PRINTF_FUNC(3, 4) void gpsd_log(const int, const struct gpsd_errout_t *,
1023                                 const char *, ...);
1024 
1025 /*
1026  * GPSD_LOG() is the new one debug logger to rule them all.
1027  *
1028  * The calling convention is not attractive:
1029  *     GPSD_LOG(debuglevel, (fmt, ...));
1030  *     GPSD_LOG(2, ("this will appear on stdout if debug >= %d\n", 2));
1031  *
1032  * This saves significant pushing, popping, hexification, etc. when
1033  * the debug level does not require it.
1034  */
1035 #define GPSD_LOG(lvl, eo, ...)           \
1036     do {                                 \
1037         if ((eo)->debug >= (lvl))        \
1038             gpsd_log(lvl, eo, __VA_ARGS__);   \
1039     } while (0)
1040 
1041 
1042 
1043 #define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
1044 
1045 /*
1046  * C99 requires NAN to be defined if the implementation supports quiet
1047  * NANs.  At one point, it seems Solaris did not define NAN; it is not
1048  * clear if this is still true.
1049  */
1050 #ifndef NAN
1051 #define NAN (0.0f/0.0f)
1052 #endif
1053 
1054 #if !defined(HAVE_CFMAKERAW)
1055 /*
1056  * POSIX does not specify cfmakeraw, but it is pretty common.  We
1057  * provide an implementation in serial.c for systems that lack it.
1058  */
1059 void cfmakeraw(struct termios *);
1060 #endif /* !defined(HAVE_CFMAKERAW) */
1061 
1062 #define DEVICEHOOKPATH "/" SYSCONFDIR "/gpsd/device-hook"
1063 
1064 # ifdef __cplusplus
1065 }
1066 # endif
1067 
1068 #endif /* _GPSD_H_ */
1069 // Local variables:
1070 // mode: c
1071 // end:
1072