diff options
-rw-r--r-- | HACKING | 20 | ||||
-rw-r--r-- | garmin.c | 2 | ||||
-rw-r--r-- | geoid.c | 16 | ||||
-rw-r--r-- | gps.h | 5 | ||||
-rw-r--r-- | gpsd.c | 8 | ||||
-rw-r--r-- | gpsd.h | 2 | ||||
-rw-r--r-- | libgps.c | 27 | ||||
-rw-r--r-- | libgpsd_core.c | 22 | ||||
-rw-r--r-- | nmea_parse.c | 4 | ||||
-rw-r--r-- | sirf.c | 6 | ||||
-rw-r--r-- | zodiac.c | 2 |
11 files changed, 81 insertions, 33 deletions
@@ -3,6 +3,26 @@ doing Ctl-C Ctl-t and browsing through the outline headers. If you're looking for things to hack on, first see the TODO file. +** Contribution guidelines + +We prefer diff -u format, but diff -c is acceptable. Do not send +patches in the default (-e or ed) mode, as they are too brittle. + +If you are introducing a new feature, include a documentation patch. + +If you are contributing a driver for a new GPS, please also do the +following things: + +1) Send us a representative sample of the GPS output for future + regression-testing. + +2) Write a hardware entry describing the GPS for the hardware page at + <http://gpsd.berlios.de/hardware.html>. + +Before shipping a patch, it is a good idea to make sure the patched +code displays no warnings when you run 'make splint'. See +http://www.splint.org for a description of this tool. + ** The license on contributions The GPSD libraries are under the BSD license. Please do not send @@ -288,7 +288,7 @@ static gps_mask_t PrintPacket(struct gps_device_t *session, Packet_t *pkt) // geoid separation from WGS 84 // gpsd sign is opposite of garmin sign - session->gpsdata.fix.separation = -pvt->msl_hght; + session->gpsdata.separation = -pvt->msl_hght; // estimated position error in meters session->gpsdata.epe = pvt->epe; @@ -72,7 +72,7 @@ double wgs84_separation(double lat, double lon) } -void ecef_to_wgs84fix(struct gps_fix_t *fix, +void ecef_to_wgs84fix(struct gps_data_t *gpsdata, double x, double y, double z, double vx, double vy, double vz) /* fill in WGS84 position/velocity fields from ECEF coordinates */ @@ -92,20 +92,20 @@ void ecef_to_wgs84fix(struct gps_fix_t *fix, phi = atan2(z + e_2*b*pow(sin(theta),3),p - e2*a*pow(cos(theta),3)); n = a / sqrt(1.0 - e2*pow(sin(phi),2)); h = p / cos(phi) - n; - fix->latitude = phi * RAD_2_DEG; - fix->longitude = lambda * RAD_2_DEG; - fix->separation = wgs84_separation(fix->latitude, fix->longitude); - fix->altitude = h - fix->separation; + gpsdata->fix.latitude = phi * RAD_2_DEG; + gpsdata->fix.longitude = lambda * RAD_2_DEG; + gpsdata->separation = wgs84_separation(gpsdata->fix.latitude, gpsdata->fix.longitude); + gpsdata->fix.altitude = h - gpsdata->separation; /* velocity computation */ vnorth = -vx*sin(phi)*cos(lambda)-vy*sin(phi)*sin(lambda)+vz*cos(phi); veast = -vx*sin(lambda)+vy*cos(lambda); - fix->climb = vx*cos(phi)*cos(lambda)+vy*cos(phi)*sin(lambda)+vz*sin(phi); - fix->speed = sqrt(pow(vnorth,2) + pow(veast,2)); + gpsdata->fix.climb = vx*cos(phi)*cos(lambda)+vy*cos(phi)*sin(lambda)+vz*sin(phi); + gpsdata->fix.speed = sqrt(pow(vnorth,2) + pow(veast,2)); heading = atan2(veast,vnorth); /*@ +evalorder @*/ if (heading < 0) heading += 2 * PI; - fix->track = heading * RAD_2_DEG; + gpsdata->fix.track = heading * RAD_2_DEG; } #ifdef TESTMAIN @@ -69,8 +69,6 @@ struct gps_fix_t { double eps; /* Speed uncertainty, meters/sec */ double climb; /* Vertical speed, meters/sec */ double epc; /* Vertical speed uncertainty */ - double separation; /* Geoidal separation, MSL - WGS84 (Meters) */ -#define SEPARATION_NOT_VALID -99999.0 /* must be out of band */ }; typedef /*@unsignedintegraltype@*/ unsigned int gps_mask_t; @@ -113,6 +111,9 @@ struct gps_data_t { struct gps_fix_t fix; /* PVT data */ + double separation; /* Geoidal separation, MSL - WGS84 (Meters) */ +#define SEPARATION_NOT_VALID -99999.0 /* must be out of band */ + /* GPS status -- always valid */ int status; /* Do we have a fix? */ #define STATUS_NO_FIX 0 /* no */ @@ -135,7 +135,7 @@ void gpsd_report(int errlevel, const char *fmt, ... ) static void usage(void) { - printf("usage: gpsd [options] \n\ + (void)printf("usage: gpsd [options] \n\ Options include: \n\ -f string = set GPS device name \n\ -S integer (default %s) = set port for daemon \n\ @@ -511,11 +511,12 @@ static int handle_request(int cfd, char *buf, int buflen) (void)strcpy(phrase, ",E=?"); break; case 'F': + /*@ -branchstate @*/ if (*p == '=') { p = snarfline(++p, &stash); gpsd_report(1,"<= client(%d): switching to %s\n",cfd,stash); if ((newchan = find_device(stash))) { - whoami->device = *newchan; + /*@i@*/whoami->device = *newchan; whoami->tied = true; } free(stash); @@ -525,6 +526,7 @@ static int handle_request(int cfd, char *buf, int buflen) whoami->device->gpsdata.gps_device); else (void)strcpy(phrase, ",F=?"); + /*@ +branchstate @*/ break; case 'I': if (assign_channel(whoami)) @@ -889,6 +891,7 @@ static void handle_control(int sfd, char *buf) } } +/*@ -mustfreefresh @*/ int main(int argc, char *argv[]) { static char *pid_file = NULL; @@ -1260,3 +1263,4 @@ int main(int argc, char *argv[]) (void)unlink(control_socket); return 0; } +/*@ +mustfreefresh @*/ @@ -191,7 +191,7 @@ extern bool ntpshm_free(struct gps_context_t *context, int segment); extern int ntpshm_put(struct gps_device_t *, double); extern int ntpshm_pps(struct gps_device_t *,struct timeval *); -extern void ecef_to_wgs84fix(struct gps_fix_t *, +extern void ecef_to_wgs84fix(struct gps_data_t *, double, double, double, double, double, double); extern void dop(int, struct gps_data_t *); @@ -88,7 +88,6 @@ void gps_clear_fix(struct gps_fix_t *fixp) fixp->epd = UNCERTAINTY_NOT_VALID; fixp->eps = UNCERTAINTY_NOT_VALID; fixp->epc = UNCERTAINTY_NOT_VALID; - fixp->separation = SEPARATION_NOT_VALID; } struct gps_data_t *gps_open(const char *host, const char *port) @@ -96,6 +95,7 @@ struct gps_data_t *gps_open(const char *host, const char *port) { struct gps_data_t *gpsdata = (struct gps_data_t *)calloc(sizeof(struct gps_data_t), 1); + /*@ -branchstate @*/ if (!gpsdata) return NULL; if (!host) @@ -112,6 +112,7 @@ struct gps_data_t *gps_open(const char *host, const char *port) gpsdata->status = STATUS_NO_FIX; gps_clear_fix(&gpsdata->fix); return gpsdata; + /*@ +branchstate @*/ } int gps_close(struct gps_data_t *gpsdata) @@ -128,12 +129,12 @@ int gps_close(struct gps_data_t *gpsdata) if (gpsdata->devicelist) { int i; for (i = 0; i < gpsdata->ndevices; i++) - (void)free(gpsdata->devicelist[i]); + /*@i1@*/(void)free(gpsdata->devicelist[i]); (void)free(gpsdata->devicelist); gpsdata->devicelist = NULL; gpsdata->ndevices = -1; } - (void)free(gpsdata); + /*@i@*/(void)free(gpsdata); return retval; } @@ -143,6 +144,7 @@ void gps_set_raw_hook(struct gps_data_t *gpsdata, gpsdata->raw_hook = hook; } +/*@ -branchstate -usereleased @*/ static void gps_unpack(char *buf, struct gps_data_t *gpsdata) /* unpack a daemon response into a status structure */ { @@ -150,7 +152,7 @@ static void gps_unpack(char *buf, struct gps_data_t *gpsdata) int i; for (ns = buf; ns; ns = strstr(ns+1, "GPSD")) { - if (strncmp(ns, "GPSD", 4) == 0) { + if (/*@i1@*/strncmp(ns, "GPSD", 4) == 0) { for (sp = ns + 5; ; sp = tp) { tp = sp + strcspn(sp, ",\r\n"); if (*tp == '\0') break; @@ -198,6 +200,7 @@ static void gps_unpack(char *buf, struct gps_data_t *gpsdata) } break; case 'F': + /*@ -mustfreeonly */ if (sp[2] == '?') gpsdata->gps_device = NULL; else { @@ -206,8 +209,10 @@ static void gps_unpack(char *buf, struct gps_data_t *gpsdata) gpsdata->gps_device = strdup(sp+2); gpsdata->set |= DEVICE_SET; } + /*@ +mustfreeonly */ break; case 'I': + /*@ -mustfreeonly */ if (sp[2] == '?') gpsdata->gps_id = NULL; else { @@ -216,24 +221,29 @@ static void gps_unpack(char *buf, struct gps_data_t *gpsdata) gpsdata->gps_id = strdup(sp+2); gpsdata->set |= DEVICEID_SET; } + /*@ +mustfreeonly */ break; case 'K': if (gpsdata->devicelist) { for (i = 0; i < gpsdata->ndevices; i++) - (void)free(gpsdata->devicelist[i]); + /*@i1@*/(void)free(gpsdata->devicelist[i]); (void)free(gpsdata->devicelist); gpsdata->devicelist = NULL; gpsdata->ndevices = -1; gpsdata->set |= DEVICELIST_SET; } if (sp[2] != '?') { + /*@ -nullderef @*/ gpsdata->ndevices = (int)strtol(sp+2, &sp, 10); gpsdata->devicelist = (char **)calloc( (size_t)gpsdata->ndevices, sizeof(char **)); + /*@ -nullstate @*/ gpsdata->devicelist[i=0] = strtok_r(sp+2, " \r\n", &ns); while ((sp = strtok_r(NULL, " \r\n", &ns))) gpsdata->devicelist[++i] = strdup(sp); + /*@ +nullstate @*/ + /*@ +nullderef @*/ gpsdata->set |= DEVICELIST_SET; } break; @@ -421,11 +431,14 @@ static void gps_unpack(char *buf, struct gps_data_t *gpsdata) } } +/*@ -nullstate -compdef @*/ if (gpsdata->raw_hook) gpsdata->raw_hook(gpsdata, buf, (int)strlen(buf), 1); if (gpsdata->thread_hook) gpsdata->thread_hook(gpsdata, buf, (int)strlen(buf), 1); } +/*@ +nullstate +compdef @*/ +/*@ -branchstate +usereleased @*/ /* * return: 0, success @@ -473,8 +486,10 @@ static void *poll_gpsd(void *args) struct gps_data_t *gpsdata; /* set thread parameters */ + /*@ -compdef @*/ (void)pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,&oldstate); (void)pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&oldtype); /* we want to be canceled also when blocked on gps_poll() */ + /*@ +compdef @*/ gpsdata = (struct gps_data_t *) args; do { res = gps_poll(gpsdata); /* this is not actually polling */ @@ -504,7 +519,7 @@ int gps_del_callback(struct gps_data_t *gpsdata, pthread_t *handler) /* delete asynchronous callback and kill its thread */ { int res; - res = pthread_cancel(*handler); /* we cancel the whole thread */ + /*@i@*/res = pthread_cancel(*handler); /* we cancel the whole thread */ gpsdata->thread_hook = NULL; /* finally we cancel the callback */ if (res == 0) /* tell gpsd to stop sending data */ (void)gps_query(gpsdata,"w-\n"); /* disable watcher mode */ diff --git a/libgpsd_core.c b/libgpsd_core.c index 5e47a584..57330ef4 100644 --- a/libgpsd_core.c +++ b/libgpsd_core.c @@ -48,6 +48,7 @@ int gpsd_open_dgps(char *dgpsserver) int gpsd_switch_driver(struct gps_device_t *session, char* typename) { struct gps_type_t **dp; + /*@ -compmempass @*/ for (dp = gpsd_drivers; *dp; dp++) if (strcmp((*dp)->typename, typename) == 0) { gpsd_report(3, "Selecting %s driver...\n", (*dp)->typename); @@ -58,6 +59,7 @@ int gpsd_switch_driver(struct gps_device_t *session, char* typename) } gpsd_report(1, "invalid GPS type \"%s\".\n", typename); return 0; + /*@ +compmempass @*/ } struct gps_device_t *gpsd_init(struct gps_context_t *context, char *device) @@ -67,10 +69,14 @@ struct gps_device_t *gpsd_init(struct gps_context_t *context, char *device) if (!session) return NULL; + /*@ -mustfreeonly @*//* splint 3.1.1 can't deduce storage is zero */ session->gpsdata.gps_device = strdup(device); session->device_type = NULL; /* start by hunting packets */ session->dsock = -1; + /*@ -temptrans @*/ session->context = context; + /*@ +temptrans @*/ + /*@ +mustfreeonly @*/ session->gpsdata.hdop = DOP_NOT_VALID; session->gpsdata.vdop = DOP_NOT_VALID; session->gpsdata.pdop = DOP_NOT_VALID; @@ -120,7 +126,7 @@ static void *gpsd_ppsmonitor(void *arg) break; /*@ -ignoresigns */ - state = (state & TIOCM_CAR) != 0; + state = (int)((state & TIOCM_CAR) != 0); gpsd_report(5, "carrier-detect on %s changed to %d\n", session->gpsdata.gps_device, state); @@ -174,7 +180,7 @@ int gpsd_activate(struct gps_device_t *session) session->gpsdata.fix.track = TRACK_NOT_VALID; #ifdef BINARY_ENABLE session->mag_var = NO_MAG_VAR; - session->gpsdata.fix.separation = SEPARATION_NOT_VALID; + session->gpsdata.separation = SEPARATION_NOT_VALID; #endif /* BINARY_ENABLE */ #ifdef NTPSHM_ENABLE @@ -182,7 +188,7 @@ int gpsd_activate(struct gps_device_t *session) #if defined(PPS_ENABLE) && defined(TIOCMIWAIT) if (session->shmTime >= 0 && session->context->shmTimePPS) { if ((session->shmTimeP = ntpshm_alloc(session->context)) >= 0) - (void)pthread_create(&pt,NULL,gpsd_ppsmonitor,(void *)session); + /*@i1@*/(void)pthread_create(&pt,NULL,gpsd_ppsmonitor,(void *)session); } #endif /* defined(PPS_ENABLE) && defined(TIOCMIWAIT) */ #endif /* NTPSHM_ENABLE */ @@ -199,7 +205,7 @@ static int is_input_waiting(int fd) return count; } -static long handle_packet(struct gps_device_t *session) +static gps_mask_t handle_packet(struct gps_device_t *session) { session->packet_full = 0; session->gpsdata.sentence_time = 0; @@ -355,10 +361,12 @@ gps_mask_t gpsd_poll(struct gps_device_t *session) } if (packet_length) { + /*@ -nullstate @*/ if (session->gpsdata.raw_hook) session->gpsdata.raw_hook(&session->gpsdata, (char *)session->outbuffer, (int)packet_length, 2); + /*@ -nullstate @*/ return handle_packet(session); } else return ONLINE_SET; @@ -371,7 +379,7 @@ void gpsd_wrap(struct gps_device_t *session) gpsd_deactivate(session); if (session->gpsdata.gps_device) (void)free(session->gpsdata.gps_device); - (void)free(session); + /*@i@*/(void)free(session); } void gpsd_zero_satellites(/*@out@*/struct gps_data_t *out) @@ -435,11 +443,11 @@ void gpsd_binary_fix_dump(struct gps_device_t *session, char bufp[], int len) session->gpsdata.satellites_used, hdop_str, session->gpsdata.fix.altitude, 'M'); - if (session->gpsdata.fix.separation == SEPARATION_NOT_VALID) + if (session->gpsdata.separation == SEPARATION_NOT_VALID) (void)strcat(bufp, ",,"); else (void)snprintf(bufp+strlen(bufp), len-strlen(bufp), - "%.3f,M", session->gpsdata.fix.separation); + "%.3f,M", session->gpsdata.separation); if (session->mag_var == NO_MAG_VAR) (void)strcat(bufp, ",,"); else { diff --git a/nmea_parse.c b/nmea_parse.c index 58171701..4cea1a57 100644 --- a/nmea_parse.c +++ b/nmea_parse.c @@ -278,9 +278,9 @@ static gps_mask_t processGPGGA(int c UNUSED, char *field[], struct gps_data_t *o mask |= CLIMB_SET; } if (strlen(field[11]) > 0) { - out->fix.separation = atof(field[11]); + out->separation = atof(field[11]); } else { - out->fix.separation = wgs84_separation(out->fix.latitude,out->fix.longitude); + out->separation = wgs84_separation(out->fix.latitude,out->fix.longitude); } } return mask; @@ -171,7 +171,7 @@ gps_mask_t sirf_parse(struct gps_device_t *session, unsigned char *buf, int len) session->gpsdata.used[i] = (int)getbyte(29+i); if ((session->driverstate & (SIRF_GE_232 | UBLOX))==0) { /* position/velocity is bytes 1-18 */ - ecef_to_wgs84fix(&session->gpsdata.fix, + ecef_to_wgs84fix(&session->gpsdata, (double)getlong(1), (double)getlong(5), (double)getlong(9), (int)getword(13)/8.0, (int)getword(15)/8.0, (int)getword(17)/8.0); /* WGS 84 geodesy parameters */ @@ -607,8 +607,8 @@ gps_mask_t sirf_parse(struct gps_device_t *session, unsigned char *buf, int len) STATUS_SET | MODE_SET | HDOP_SET | VDOP_SET | PDOP_SET; session->gpsdata.fix.latitude = getlong(1) * RAD_2_DEG * 1e-8; session->gpsdata.fix.longitude = getlong(5) * RAD_2_DEG * 1e-8; - session->gpsdata.fix.separation = wgs84_separation(session->gpsdata.fix.latitude, session->gpsdata.fix.longitude); - session->gpsdata.fix.altitude = getlong(9) * 1e-3 - session->gpsdata.fix.separation; + session->gpsdata.separation = wgs84_separation(session->gpsdata.fix.latitude, session->gpsdata.fix.longitude); + session->gpsdata.fix.altitude = getlong(9) * 1e-3 - session->gpsdata.separation; session->gpsdata.fix.speed = getlong(13) * 1e-3; session->gpsdata.fix.climb = getlong(17) * 1e-3; session->gpsdata.fix.track = getlong(21) * RAD_2_DEG * 1e-8; @@ -176,7 +176,7 @@ static gps_mask_t handle1000(struct gps_device_t *session) session->gpsdata.fix.longitude = ((long)getlong(29)) * RAD_2_DEG * 1e-8; session->gpsdata.fix.altitude = ((long)getlong(31)) * 1e-2; /*@ +type @*/ - session->gpsdata.fix.separation = ((short)getword(33)) * 1e-2; + session->gpsdata.separation = ((short)getword(33)) * 1e-2; session->gpsdata.fix.speed = (int)getlong(34) * 1e-2; session->gpsdata.fix.track = (int)getword(36) * RAD_2_DEG * 1e-3; session->mag_var = ((short)getword(37)) * RAD_2_DEG * 1e-4; |