summaryrefslogtreecommitdiff
path: root/gpsd.h
blob: 0d7113c8242d68fa7f659588a4a1b962e87546d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/* gpsd.h -- fundamental types and structures for the GPS daemon */

#include "config.h"
#include "gps.h"
#include <setjmp.h>

/* Some internal capabilities depend on which drivers we're compiling. */
#define ZODIAC_ENABLE	EARTHMATE_ENABLE
#define BINARY_ENABLE	(ZODIAC_ENABLE || SIRF_ENABLE || GARMIN_ENABLE)
#define NON_NMEA_ENABLE	(TRIPMATE_ENABLE || BINARY_ENABLE)

#define NMEA_MAX	82		/* max length of NMEA sentence */
#define NMEA_BIG_BUF	(2*NMEA_MAX+1)	/* longer than longest NMEA sentence */

/*
 * User Equivalent Range Error
 * UERE is the square root of the sum of the squares of individual
 * errors.  We compute based on the following error budget for
 * satellite range measurements.  Note: this is only used if the
 * GPS doesn't report estimated position error itself.
 *
 * From R.B Langley's 1997 "The GPS error budget". 
 * GPS World , Vol. 8, No. 3, pp. 51-56
 *
 * Atmospheric error -- ionosphere                 7.0m
 * Atmospheric error -- troposphere                0.7m
 * Clock and ephemeris error                       3.6m
 * Receiver noise                                  1.5m
 * Multipath effect                                1.2m
 *
 * From Hoffmann-Wellenhof et al. (1997), "GPS: Theory and Practice", 4th
 * Ed., Springer.
 *
 * Code range noise (C/A)                          0.3m
 * Code range noise (P-code)                       0.03m
 * Phase range                                     0.005m
 *
 * Taking the square root of the sum of aa squares...
 * UERE=sqrt(7.0^2 + 0.7^2 + 3.6^2 + 1.5^2 + 1.2^2 + 0.3^2 + 0.03^2 + 0.005^2)
 *
 * See http://www.seismo.berkeley.edu/~battag/GAMITwrkshp/lecturenotes/unit1/
 * for discussion.
 *
 * DGPS corrects for atmospheric distortion, ephemeris error, and satellite/
 * receiver clock error.  Thus:
 * UERE =  sqrt(1.5^2 + 1.2^2 + 0.3^2 + 0.03^2 + 0.005^2)
 */
#define UERE_NO_DGPS	8.1382
#define UERE_WITH_DGPS	1.9444
#define UERE(session)	((session->dsock==-1) ? UERE_NO_DGPS : UERE_WITH_DGPS)

struct gps_session_t;

struct gps_type_t {
/* GPS method table, describes how to talk to a particular GPS type */
    char *typename, *trigger;
    int (*probe)(struct gps_session_t *session);
    void (*initializer)(struct gps_session_t *session);
    void (*handle_input)(struct gps_session_t *session);
    int (*rtcm_writer)(struct gps_session_t *session, char *rtcmbuf, int rtcmbytes);
    int (*speed_switcher)(struct gps_session_t *session, int speed);
    void (*wrapup)(struct gps_session_t *session);
    int cycle;
};

#if defined (HAVE_SYS_TERMIOS_H)
#include <sys/termios.h>
#else
#if defined (HAVE_TERMIOS_H)
#include <termios.h>
#endif
#endif

/*
 * 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.  Thus, in particular, they need
 * to be as long as a SiRF MID 4 packet, 188 bytes payload plus eight bytes 
 * of header/length/checksum/trailer.  But making this longer also 
 * slows down the autobauding.
 */
#define MAX_PACKET_LENGTH	193	/* 188 + 8 + 1 */

struct gps_session_t {
/* session object, encapsulates all global state */
    struct gps_data_t gNMEAdata;
    struct gps_type_t *device_type;
    char *gpsd_device;	/* where to find the GPS */
    int dsock;		/* socket to DGPS server */
    int sentdgps;	/* have we sent a DGPS correction? */
    int fixcnt;		/* count of good fixes seen */
    struct termios ttyset, ttyset_old;
    /* packet-getter internals */
    int	packet_type;
#define BAD_PACKET	-1
#define NMEA_PACKET	0
#define SIRF_PACKET	1
#define ZODIAC_PACKET	2
    unsigned char inbuffer[MAX_PACKET_LENGTH+1];
    unsigned short inbuflen;
    unsigned char *inbufptr;
    unsigned char outbuffer[MAX_PACKET_LENGTH+1];
    unsigned short outbuflen;
    jmp_buf packet_error;
    double poll_times[__FD_SETSIZE];	/* last daemon poll time */
#ifdef BINARY_ENABLE
#ifdef GARMIN_ENABLE	/* private housekeeping stuff for the Garmin driver */
    unsigned char GarminBuffer[4096 + 12]; /* Garmin packet buffer */
    long GarminBufferLen;                  /* current GarminBuffer Length */
#endif /* GARMIN_ENABLE */
    double separation;		/* Geoidal separation */
#define NO_SEPARATION	-99999	/* must be out of band */
    int year, month, day;
    int hours, minutes; 
    double seconds;
    unsigned int driverstate;	/* for private use */
#define SIRF_LT_231	0x01		/* SiRF at firmware rev < 231 */
#ifdef ZODIAC_ENABLE	/* private housekeeping stuff for the Zodiac driver */
    unsigned short sn;		/* packet sequence number */
    double mag_var;		/* Magnetic variation in degrees */  
    /*
     * Zodiac chipset channel status from PRWIZCH. Keep it so raw-mode 
     * translation of Zodiac binary protocol can send it up to the client.
     */
    int Zs[MAXCHANNELS];	/* satellite PRNs */
    int Zv[MAXCHANNELS];	/* signal values (0-7) */
#endif /* ZODIAC_ENABLE */
#endif /* BINARY_ENABLE */
};

#define PREFIX(pref, sentence)	!strncmp(pref, sentence, sizeof(pref)-1)
#define TIME2DOUBLE(tv)	(tv.tv_sec + tv.tv_usec/1e6)

/* here are the available GPS drivers */
extern struct gps_type_t **gpsd_drivers;

/* GPS library internal prototypes */
extern int nmea_parse(char *, struct gps_data_t *);
extern int nmea_send(int, const char *, ... );
extern int nmea_sane_satellites(struct gps_data_t *);
extern void nmea_add_checksum(char *);

extern int packet_sniff(struct gps_session_t *);
extern int packet_get_nmea(struct gps_session_t *);
extern int packet_get_sirf(struct gps_session_t *);
extern void packet_accept(struct gps_session_t *);

extern int gpsd_open(struct gps_session_t *);
extern int gpsd_switch_driver(struct gps_session_t *, char *);
extern int gpsd_set_speed(struct gps_session_t *, unsigned int, unsigned int);
extern int gpsd_get_speed(struct termios *);
extern void gpsd_close(struct gps_session_t *);

extern void gpsd_zero_satellites(struct gps_data_t *);
extern void gpsd_binary_fix_dump(struct gps_session_t *, char *);
extern void gpsd_binary_satellite_dump(struct gps_session_t *, char *);
extern void gpsd_binary_quality_dump(struct gps_session_t *, char *);

extern int netlib_connectsock(const char *, const char *, const char *);

/* External interface */
extern struct gps_session_t * gpsd_init(char *);
extern int gpsd_activate(struct gps_session_t *);
extern void gpsd_deactivate(struct gps_session_t *);
extern int gpsd_poll(struct gps_session_t *);
extern void gpsd_wrap(struct gps_session_t *);

/* caller should supply this */
void gpsd_report(int, const char *, ...);

#define DEFAULT_DEVICE_NAME	"/dev/gps"