/* Feature configuration switches end here * * This file is Copyright (c) 2010 by the GPSD project * BSD terms apply: see the file COPYING in the distribution root for details. */ #endif /* GPSD_CONFIG_H */ #ifdef HAVE_TERMIOS_H #include #endif #ifdef HAVE_SYS_TERMIOS_H #include #endif #include "gps.h" #ifdef _WIN32 typedef unsigned int speed_t; #endif /* * Constants for the VERSION response * 3.1: Base JSON version * 3.2: Added POLL command and response * 3.3: AIS app_id split into DAC and FID */ #define GPSD_PROTO_MAJOR_VERSION 3 /* bump on incompatible changes */ #define GPSD_PROTO_MINOR_VERSION 3 /* bump on compatible changes */ /* Some internal capabilities depend on which drivers we're compiling. */ #ifdef EARTHMATE_ENABLE #define ZODIAC_ENABLE #endif #if defined(ZODIAC_ENABLE) || defined(SIRF_ENABLE) || defined(GARMIN_ENABLE) || defined(TSIP_ENABLE) || defined(EVERMORE_ENABLE) || defined(ITRAX_ENABLE) || defined(UBX_ENABLE) || defined(SUPERSTAR2_ENABLE) || defined(ONCORE_ENABLE) #define BINARY_ENABLE #endif #if defined(TRIPMATE_ENABLE) || defined(BINARY_ENABLE) #define NON_NMEA_ENABLE #endif #if defined(TNT_ENABLE) || defined(OCEANSERVER_ENABLE) #define COMPASS_ENABLE #endif /* First, declarations for the packet layer... */ /* * For NMEA-conforming receivers this is supposed to be 82, but * some receivers (TN-200, GSW 2.3.2) emit oversized sentences. * The current hog champion is the Trimble BX-960 receiver, which * emits a 91-character GGA message. */ #define NMEA_MAX 91 /* max length of NMEA sentence */ #define NMEA_BIG_BUF (2*NMEA_MAX+1) /* longer than longest NMEA sentence */ /* a few bits of ISGPS magic */ enum isgpsstat_t { ISGPS_NO_SYNC, ISGPS_SYNC, ISGPS_SKIP, ISGPS_MESSAGE, }; #define ISGPS_ERRLEVEL_BASE 5 #define RTCM_MAX (RTCM2_WORDS_MAX * sizeof(isgps30bits_t)) /* * The packet buffers need to be as long than the longest packet we * expect to see in any protocol, because we have to be able to hold * an entire packet for checksumming... * First we thought it had to be big enough for a SiRF Measured Tracker * Data packet (188 bytes). Then it had to be big enough for a UBX SVINFO * packet (206 bytes). Now it turns out that a couple of ITALK messages are * over 512 bytes. I know we like verbose output, but this is ridiculous. */ #define MAX_PACKET_LENGTH 516 /* 7 + 506 + 3 */ struct gps_packet_t { /* packet-getter internals */ int type; #define BAD_PACKET -1 #define COMMENT_PACKET 0 #define NMEA_PACKET 1 #define AIVDM_PACKET 2 #define GARMINTXT_PACKET 3 #define MAX_TEXTUAL_TYPE 3 /* increment this as necessary */ #define SIRF_PACKET 4 #define ZODIAC_PACKET 5 #define TSIP_PACKET 6 #define EVERMORE_PACKET 7 #define ITALK_PACKET 8 #define GARMIN_PACKET 9 #define NAVCOM_PACKET 10 #define UBX_PACKET 11 #define SUPERSTAR2_PACKET 12 #define ONCORE_PACKET 13 #define MAX_PACKET_TYPE 13 /* increment this as necessary */ #define RTCM2_PACKET 14 #define RTCM3_PACKET 15 #define TEXTUAL_PACKET_TYPE(n) (((n)>=NMEA_PACKET) && ((n)<=MAX_TEXTUAL_TYPE)) #define GPS_PACKET_TYPE(n) (((n)>=NMEA_PACKET) && ((n)<=MAX_PACKET_TYPE)) #define LOSSLESS_PACKET_TYPE(n) (((n)>=RTCM2_PACKET) && ((n)<=RTCM3_PACKET)) #define PACKET_TYPEMASK(n) (1 << (n)) #define GPS_TYPEMASK (((2<<(MAX_PACKET_TYPE+1))-1) &~ PACKET_TYPEMASK(COMMENT_PACKET)) unsigned int state; size_t length; unsigned char inbuffer[MAX_PACKET_LENGTH*2+1]; size_t inbuflen; unsigned /*@observer@*/char *inbufptr; /* outbuffer needs to be able to hold 4 GPGSV records at once */ unsigned char outbuffer[MAX_PACKET_LENGTH*2+1]; size_t outbuflen; unsigned long char_counter; /* count characters processed */ unsigned long retry_counter; /* count sniff retries */ unsigned counter; /* packets since last driver switch */ /* * This is not conditionalized on RTCM104_ENABLE because we need to * be able to build gpsdecode even when RTCM support is not * configured in the daemon. */ struct { /* ISGPS200 decoding */ bool locked; int curr_offset; isgps30bits_t curr_word; isgps30bits_t buf[RTCM2_WORDS_MAX]; unsigned int bufindex; } isgps; }; extern void packet_init(/*@out@*/struct gps_packet_t *); extern void packet_reset(/*@out@*/struct gps_packet_t *); extern void packet_pushback(struct gps_packet_t *); extern void packet_parse(struct gps_packet_t *); extern ssize_t packet_get(int, struct gps_packet_t *); extern int packet_sniff(struct gps_packet_t *); #define packet_buffered_input(lexer) ((lexer)->inbuffer + (lexer)->inbuflen - (lexer)->inbufptr) extern void isgps_init(/*@out@*/struct gps_packet_t *); enum isgpsstat_t isgps_decode(struct gps_packet_t *, bool (*preamble_match)(isgps30bits_t *), bool (*length_check)(struct gps_packet_t *), size_t, unsigned int); extern unsigned int isgps_parity(isgps30bits_t); extern void isgps_output_magnavox(const isgps30bits_t *, unsigned int, FILE *); extern enum isgpsstat_t rtcm2_decode(struct gps_packet_t *, unsigned int); extern void rtcm2_sager_dump(const struct rtcm2_t *, /*@out@*/char[], size_t); extern void rtcm2_json_dump(const struct rtcm2_t *, /*@out@*/char[], size_t); extern int rtcm2_undump(/*@out@*/struct rtcm2_t *, char *); extern void rtcm2_unpack(/*@out@*/struct rtcm2_t *, char *); extern void rtcm3_unpack(/*@out@*/struct rtcm3_t *, char *); extern void rtcm3_dump(struct rtcm3_t *rtcm, FILE *); extern size_t oncore_payload_cksum_length(unsigned char id1,unsigned char id2); /* Next, declarations for the core library... */ /* factors for converting among confidence interval units */ #define CEP50_SIGMA 1.18 #define DRMS_SIGMA 1.414 #define CEP95_SIGMA 2.45 /* this is where we choose the confidence level to use in reports */ #define GPSD_CONFIDENCE CEP95_SIGMA #define NTPSHMSEGS 4 /* number of NTP SHM segments */ #define AIVDM_CHANNELS 2 /* A, B */ struct gps_context_t { int valid; /* member validity flags */ bool readonly; /* if true, never write to device */ #define LEAP_SECOND_VALID 0x01 /* we have or don't need correction */ /* DGPSIP status */ bool sentdgps; /* have we sent a DGPS report? */ enum { netgnss_none, netgnss_dgpsip, netgnss_ntrip} netgnss_service; /* type of GNSS service */ int fixcnt; /* count of good fixes seen */ socket_t dsock; /* socket to DGPSIP server/Ntrip caster */ void *netgnss_privdata; /* DGNSS service specific data */ size_t rtcmbytes; /* byte count of last RTCM104 report */ char rtcmbuf[RTCM_MAX]; /* last RTCM104 report */ double rtcmtime; /* timestamp of last RTCM104 report */ /* timekeeping */ int leap_seconds; /* Unix seconds to UTC */ unsigned short gps_week; /* GPS week, actually 10 bits */ double gps_tow; /* GPS time of week, actually 19 bits */ int century; /* for NMEA-only devices without ZDA */ #ifdef NTPSHM_ENABLE bool enable_ntpshm; /*@reldef@*/struct shmTime *shmTime[NTPSHMSEGS]; bool shmTimeInuse[NTPSHMSEGS]; # ifdef PPS_ENABLE bool shmTimePPS; # endif /* PPS_ENABLE */ #endif /* NTPSHM_ENABLE */ }; struct aivdm_context_t { /* hold context for decoding AIDVM packet sequences */ int decoded_frags; /* for tracking AIDVM parts in a multipart sequence */ unsigned char bits[2048]; size_t bitlen; /* how many valid bits */ unsigned int mmsi24; /* type 24 specific */ char shipname24[AIS_SHIPNAME_MAXLEN+1]; /* type 24 specific */ }; struct gps_device_t; #if defined (HAVE_SYS_TERMIOS_H) #include #else #if defined (HAVE_TERMIOS_H) #include #endif #endif #define MODE_NMEA 0 #define MODE_BINARY 1 typedef enum {ANY, GPS, RTCM2, RTCM3, AIS} gnss_type; typedef enum { event_wakeup, event_triggermatch, event_identified, event_configure, event_driver_switch, event_deactivate, event_reactivate, } event_t; #define ONLINE_IS 0x00000001u #define TIME_IS 0x00000002u #define TIMERR_IS 0x00000004u #define LATLON_IS 0x00000008u #define ALTITUDE_IS 0x00000010u #define SPEED_IS 0x00000020u #define TRACK_IS 0x00000040u #define CLIMB_IS 0x00000080u #define STATUS_IS 0x00000100u #define MODE_IS 0x00000200u #define DOP_IS 0x00000400u #define HERR_IS 0x00000800u #define VERR_IS 0x00001000u #define PERR_IS 0x00002000u #define SATELLITE_IS 0x00004000u #define RAW_IS 0x00008000u #define USED_IS 0x00010000u #define SPEEDERR_IS 0x00020000u #define DRIVER_IS 0x00040000u #define DEVICEID_IS 0x00100000u #define ERROR_IS 0x00200000u #define RTCM2_IS 0x00400000u #define RTCM3_IS 0x00800000u #define AIS_IS 0x01000000u #define ATT_IS 0x02000000u #define PACKET_IS 0x04000000u #define CLEAR_IS 0x08000000u /* sentence starts a reporting cycle */ #define REPORT_IS 0x10000000u /* sentence ends a reporting cycle */ #define NODATA_IS 0x20000000u /* no data read from fd */ #define DATA_IS ~(ONLINE_IS|PACKET_IS|CLEAR_IS|REPORT_IS) struct gps_type_t { /* GPS method table, describes how to talk to a particular GPS type */ /*@observer@*/char *type_name; int packet_type; /*@observer@*//*@null@*/char *trigger; int channels; /*@null@*/bool (*probe_detect)(struct gps_device_t *session); /*@null@*/ssize_t (*get_packet)(struct gps_device_t *session); /*@null@*/gps_mask_t (*parse_packet)(struct gps_device_t *session); /*@null@*/ssize_t (*rtcm_writer)(struct gps_device_t *session, char *rtcmbuf, size_t rtcmbytes); /*@null@*/void (*event_hook)(struct gps_device_t *session, event_t event); #ifdef ALLOW_RECONFIGURE /*@null@*/bool (*speed_switcher)(struct gps_device_t *session, speed_t speed, char parity, int stopbits); /*@null@*/void (*mode_switcher)(struct gps_device_t *session, int mode); /*@null@*/bool (*rate_switcher)(struct gps_device_t *session, double rate); double min_cycle; #endif /* ALLOW_RECONFIGURE */ #ifdef ALLOW_CONTROLSEND /*@null@*/ssize_t (*control_send)(struct gps_device_t *session, char *buf, size_t buflen); #endif /* ALLOW_CONTROLSEND */ #ifdef NTPSHM_ENABLE /*@null@*/double (*ntp_offset)(struct gps_device_t *session); #endif /* NTPSHM_ENABLE */ }; typedef enum {source_unknown, source_blockdev, source_rs232, source_usb, source_bluetooth, source_pty, source_tcp, source_udp} sourcetype_t; struct gps_device_t { /* session object, encapsulates all global state */ struct gps_data_t gpsdata; /*@relnull@*/const struct gps_type_t *device_type; struct gps_context_t *context; bool is_serial; sourcetype_t sourcetype; double rtcmtime; /* timestamp of last RTCM104 correction to GPS */ #ifndef _WIN32 struct termios ttyset, ttyset_old; #endif unsigned int baudindex; int saved_baud; struct gps_packet_t packet; int getcount; char subtype[64]; /* firmware version or subtype ID */ double opentime; double releasetime; bool zerokill; double reawake; #ifdef NTPSHM_ENABLE int shmindex; double last_fixtime; /* so updates happen once */ # ifdef PPS_ENABLE int shmTimeP; # endif /* PPS_ENABLE */ #endif /* NTPSHM_ENABLE */ double mag_var; /* magnetic variation in degrees */ bool back_to_nmea; /* back to NMEA on revert? */ char msgbuf[MAX_PACKET_LENGTH*2+1]; /* command message buffer for sends */ size_t msgbuflen; int observed; /* which packet type`s have we seen? */ bool cycle_end_reliable; /* does driver signal REPORT_MASK */ bool notify_clients; /* ship DEVICE notification on poll? */ struct gps_fix_t newdata; /* where clients put their data */ struct gps_fix_t oldfix; /* previous fix for error modeling */ /* * The rest of this structure is driver-specific private storage. * Because the Garmin driver uses a long buffer, you can have * up to 4096+12 bytes of private storage in your own union member * without making this structure larger or changing the API at all. */ union { #ifdef NMEA_ENABLE struct { int part, await; /* for tracking GSV parts */ struct tm date; /* date part of last sentence time */ double subseconds; /* subsec part of last sentence time */ char *field[NMEA_MAX]; unsigned char fieldcopy[NMEA_MAX+1]; /* * State for the cycle-tracking machinery. * The reason these timestamps are separate from the * general sentence timestamps is that we can * use the minutes and seconds part of a sentence * with an incomplete timestasmp (like GGA) for * end-cycle recognition, even if we don't have a previous * RMC or ZDA that lets us get full time from it. */ double this_frac_time, last_frac_time; bool latch_frac_time; unsigned int lasttag; unsigned int cycle_enders; #ifdef GPSCLOCK_ENABLE bool ignore_trailing_edge; #endif /* GPSCLOCK_ENABLE */ } nmea; #endif /* NMEA_ENABLE */ #ifdef GARMINTXT_ENABLE struct { struct tm date; /* date part of last sentence time */ double subseconds; /* subsec part of last sentence time */ } garmintxt; #endif /* NMEA_ENABLE */ #ifdef BINARY_ENABLE #ifdef SIRF_ENABLE struct { unsigned int driverstate; /* for private use */ #define SIRF_LT_231 0x01 /* SiRF at firmware rev < 231 */ #define SIRF_EQ_231 0x02 /* SiRF at firmware rev == 231 */ #define SIRF_GE_232 0x04 /* SiRF at firmware rev >= 232 */ #define UBLOX 0x08 /* uBlox firmware with packet 0x62 */ unsigned long satcounter; unsigned int time_seen; #define TIME_SEEN_GPS_1 0x01 /* Seen GPS time variant 1? */ #define TIME_SEEN_GPS_2 0x02 /* Seen GPS time variant 2? */ #define TIME_SEEN_UTC_1 0x04 /* Seen UTC time variant 1? */ #define TIME_SEEN_UTC_2 0x08 /* Seen UTC time variant 2? */ /* fields from Navigation Parameters message */ bool nav_parameters_seen; /* have we seen one? */ unsigned char altitude_hold_mode; unsigned char altitude_hold_source; int16_t altitude_source_input; unsigned char degraded_mode; unsigned char degraded_timeout; unsigned char dr_timeout; unsigned char track_smooth_mode; } sirf; #endif /* SIRF_ENABLE */ #ifdef SUPERSTAR2_ENABLE struct { time_t last_iono; } superstar2; #endif /* SUPERSTAR2_ENABLE */ #ifdef TSIP_ENABLE struct { bool superpkt; /* Super Packet mode requested */ time_t last_41; /* Timestamps for packet requests */ time_t last_48; time_t last_5c; time_t last_6d; time_t last_46; time_t req_compact; unsigned int stopbits; /* saved RS232 link parameter */ char parity; } tsip; #endif /* TSIP_ENABLE */ #ifdef GARMIN_ENABLE /* private housekeeping stuff for the Garmin driver */ struct { unsigned char Buffer[4096+12]; /* Garmin packet buffer */ size_t BufferLen; /* current GarminBuffer Length */ } garmin; #endif /* GARMIN_ENABLE */ #ifdef ZODIAC_ENABLE /* private housekeeping stuff for the Zodiac driver */ struct { unsigned short sn; /* packet sequence number */ /* * Zodiac chipset channel status from PRWIZCH. Keep it so * raw-mode translation of Zodiac binary protocol can send * it up to the client. */ #define ZODIAC_CHANNELS 12 unsigned int Zs[ZODIAC_CHANNELS]; /* satellite PRNs */ unsigned int Zv[ZODIAC_CHANNELS]; /* signal values (0-7) */ } zodiac; #endif /* ZODIAC_ENABLE */ #ifdef UBX_ENABLE struct { bool have_port_configuration; unsigned char original_port_settings[20]; unsigned char sbas_in_use; } ubx; #endif /* UBX_ENABLE */ #ifdef NAVCOM_ENABLE struct { uint8_t physical_port; bool warned; } navcom; #endif /* NAVCOM_ENABLE */ #ifdef ONCORE_ENABLE struct { #define ONCORE_VISIBLE_CH 12 int visible; int PRN[ONCORE_VISIBLE_CH]; /* PRNs of satellite */ int elevation[ONCORE_VISIBLE_CH]; /* elevation of satellite */ int azimuth[ONCORE_VISIBLE_CH]; /* azimuth */ double pps_delay; } oncore; #endif /* ONCORE_ENABLE */ /* * This is not conditionalized on RTCM104_ENABLE because we need to * be able to build gpsdecode even when RTCM support is not * configured in the daemon. It doesn't take up extra space. */ struct { /* ISGPS200 decoding */ bool locked; int curr_offset; isgps30bits_t curr_word; isgps30bits_t buf[RTCM2_WORDS_MAX]; unsigned int bufindex; } isgps; #endif /* BINARY_ENABLE */ } driver; /* * Auxiliary structures for parsing data that can be interleaved with * GPS sentences. Can't be in the driver union or it will get stepped on. * So far the only case of this is AIS reports, which in marine navigation * systems may come over the same wire with GPS NMEA sentences. */ #ifdef AIVDM_ENABLE struct aivdm_context_t aivdm[AIVDM_CHANNELS]; #endif /* AIVDM_ENABLE */ #ifdef TIMING_ENABLE /* profiling data for last sentence */ char tag[MAXTAGLEN+1]; /* tag of last sentence processed */ double d_xmit_time; /* beginning of sentence transmission */ double d_recv_time; /* daemon receipt time (-> E1+T1) */ double d_decode_time; /* daemon end-of-decode time (-> D1) */ double emit_time; /* emission time (-> E2) */ #endif /* TIMING_ENABLE */ }; /* logging levels */ #define LOG_ERROR 0 /* errors, display always */ #define LOG_SHOUT 0 /* not an error but we should always see it */ #define LOG_WARN 1 /* not errors but may indicate a problem */ #define LOG_INF 2 /* key informative messages */ #define LOG_DATA 3 /* log data management messages */ #define LOG_PROG 4 /* progress messages */ #define LOG_IO 5 /* IO to and from devices */ #define LOG_SPIN 6 /* logging for catching spin bugs */ #define LOG_RAW 7 /* raw low-level I/O */ #define IS_HIGHEST_BIT(v,m) (v & ~((m<<1)-1))==0 /* here are the available GPS drivers */ extern const struct gps_type_t **gpsd_drivers; /* gpsd library internal prototypes */ extern gps_mask_t nmea_parse_input(struct gps_device_t *); extern gps_mask_t nmea_parse(char *, struct gps_device_t *); extern ssize_t nmea_write(struct gps_device_t *session, char *buf, size_t len); extern ssize_t nmea_send(struct gps_device_t *session, const char *, ... ); extern void nmea_add_checksum(char *); ssize_t generic_get(struct gps_device_t *); ssize_t pass_rtcm(struct gps_device_t *, char *, size_t); extern gps_mask_t sirf_parse(struct gps_device_t *, unsigned char *, size_t); extern gps_mask_t evermore_parse(struct gps_device_t *, unsigned char *, size_t); extern gps_mask_t navcom_parse(struct gps_device_t *, unsigned char *, size_t); extern gps_mask_t garmin_ser_parse(struct gps_device_t *); extern gps_mask_t garmintxt_parse(struct gps_device_t *); extern gps_mask_t aivdm_parse(struct gps_device_t *); extern bool netgnss_uri_check(char *); extern int netgnss_uri_open(struct gps_context_t *, char *); extern int netgnss_poll(struct gps_context_t *); extern void netgnss_report(struct gps_device_t *); extern void netgnss_autoconnect(struct gps_context_t *, double, double); extern void rtcm_relay(struct gps_device_t *); extern void rtcm2_output_mag(isgps30bits_t *, FILE *); extern int dgpsip_open(struct gps_context_t *, const char *); extern void dgpsip_report(struct gps_device_t *); extern void dgpsip_autoconnect(struct gps_context_t *, double, double, const char *); extern int ntrip_open(struct gps_context_t *, char *); extern void ntrip_report(struct gps_device_t *); extern void gpsd_tty_init(struct gps_device_t *); extern int gpsd_open(struct gps_device_t *); extern bool gpsd_set_raw(struct gps_device_t *); extern ssize_t gpsd_write(struct gps_device_t *, void const *, size_t); extern bool gpsd_next_hunt_setting(struct gps_device_t *); extern int gpsd_switch_driver(struct gps_device_t *, char *); extern void gpsd_set_speed(struct gps_device_t *, speed_t, char, unsigned int); extern speed_t gpsd_get_speed(const struct termios *); extern void gpsd_assert_sync(struct gps_device_t *); extern void gpsd_close(struct gps_device_t *); extern void gpsd_zero_satellites(/*@out@*/struct gps_data_t *sp)/*@modifies sp@*/; extern void gpsd_interpret_subframe(struct gps_device_t *, unsigned int[]); extern int gpsd_interpret_subframe_raw(struct gps_device_t *, unsigned int[]); extern int gpsd_hexdump_level; extern /*@ observer @*/ char *gpsd_hexdump(/*@null@*/const void *, size_t); extern /*@ observer @*/ char *gpsd_hexdump_wrapper(/*@null@*/const void *, size_t, int); extern int gpsd_hexpack(/*@in@*/const char *, /*@out@*/char *, size_t); extern int hex2bin(const char *); extern ssize_t hex_escapes(/*@out@*/char *cooked, const char *raw); extern void ntpd_link_activate(struct gps_device_t *session); extern char /*@observer@*/ *gpsd_id(/*@in@*/struct gps_device_t *); extern void gpsd_position_fix_dump(struct gps_device_t *, /*@out@*/char[], size_t); extern void gpsd_clear_data(struct gps_device_t *); extern socket_t netlib_connectsock(int, const char *, const char *, const char *); extern char /*@observer@*/ *netlib_errstr(const int); extern char /*@observer@*/ *netlib_sock2ip(int); extern void nmea_tpv_dump(struct gps_device_t *, /*@out@*/char[], size_t); extern void nmea_sky_dump(struct gps_device_t *, /*@out@*/char[], size_t); extern void ntpshm_init(struct gps_context_t *, bool); extern int ntpshm_alloc(struct gps_context_t *); extern bool ntpshm_free(struct gps_context_t *, int); extern int ntpshm_put(struct gps_device_t *, double, double); extern int ntpshm_pps(struct gps_device_t *,struct timeval *); extern void ecef_to_wgs84fix(/*@out@*/struct gps_fix_t *, /*@out@*/double *, double, double, double, double, double, double); extern void clear_dop(/*@out@*/struct dop_t *); extern gps_mask_t fill_dop(/*@in@*/const struct gps_data_t *gpsdata, struct dop_t *dop); /* srecord.c */ extern void hexdump(size_t, unsigned char *, unsigned char *); extern unsigned char sr_sum(unsigned int, unsigned int, unsigned char *); extern int bin2srec(unsigned int, unsigned int, unsigned int, unsigned char *, unsigned char *); extern int srec_hdr(unsigned int, unsigned char *, unsigned char *); extern int srec_fin(unsigned int, unsigned char *); extern unsigned char hc(unsigned char); /* application interface */ extern void gpsd_init(struct gps_device_t *, struct gps_context_t *, /*@null@*/char *); extern int gpsd_activate(struct gps_device_t *); extern void gpsd_deactivate(struct gps_device_t *); extern gps_mask_t gpsd_poll(struct gps_device_t *); extern void gpsd_wrap(struct gps_device_t *); /* exceptional driver methods */ #ifdef UBX_ENABLE extern bool ubx_write(struct gps_device_t *, unsigned int, unsigned int, /*@null@*/unsigned char *, unsigned short); #endif /* UBX_ENABLE */ #ifdef AIVDM_ENABLE extern bool aivdm_decode(const char *, size_t, struct aivdm_context_t [], struct ais_t *); extern void aivdm_json_dump(const struct ais_t *, bool, /*@out@*/char *, size_t); #endif /* AIVDM_ENABLE */ #ifdef MTK3301_ENABLE extern gps_mask_t processMTK3301(int c UNUSED, char *field[], struct gps_device_t *session); #endif /* MTK3301_ENABLE */ /* caller should supply this */ # if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) __attribute__((__format__(__printf__, 2, 3))) void gpsd_report(int, const char *, ...); # else /* not a new enough GCC, use the unprotected prototype */ void gpsd_report(int, const char *, ...); #endif extern /*@observer@*/const char *gpsd_maskdump(gps_mask_t); #ifdef S_SPLINT_S extern bool finite(double); extern struct protoent *getprotobyname(const char *); extern /*@observer@*/char *strptime(const char *,const char *tp,/*@out@*/struct tm *)/*@modifies tp@*/; extern struct tm *gmtime_r(const time_t *,/*@out@*/struct tm *tp)/*@modifies tp@*/; extern struct tm *localtime_r(const time_t *,/*@out@*/struct tm *tp)/*@modifies tp@*/; extern float roundf(float x); #endif /* S_SPLINT_S */ /* * How to mix together epx and epy to get a horizontal circular error * eph when reporting requires it. Most devices don't report these; * NMEA 3.x devices reporting $GPGBS are the exception. */ #define EMIX(x, y) (((x) > (y)) ? (x) : (y)) /* some OSes don't have round(). fake it if need be */ #ifndef HAVE_ROUND #define round(x) ((double)rint(x)) #define roundf(x) ((float)rintf((double)x)) #endif /* !HAVE_ROUND */ #define NITEMS(x) (int)(sizeof(x)/sizeof(x[0])) /* OpenBSD and FreeBSD and Cygwin don't seem to have NAN, NetBSD does, others? */ /* FIX-ME: test for this in configure? */ #if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__CYGWIN__) #ifndef NAN #define NAN (0.0/0.0) #endif /* !NAN */ #endif /* list of Operating Systems */ /* Cygwin, in addition to NAN, doesn't have cfmakeraw */ #if defined(__CYGWIN__) void cfmakeraw(struct termios *); #endif /* defined(__CYGWIN__) */ #endif /* _GPSD_H_ */ // Local variables: // mode: c // end: