diff options
-rw-r--r-- | driver_sirf.c | 4 | ||||
-rw-r--r-- | drivers.c | 6 | ||||
-rw-r--r-- | gpsd.c | 9 | ||||
-rw-r--r-- | gpsd.h-tail | 7 | ||||
-rw-r--r-- | gpsd_json.c | 21 | ||||
-rw-r--r-- | gpsdecode.c | 16 | ||||
-rw-r--r-- | hex.c | 26 | ||||
-rw-r--r-- | libgpsd_core.c | 16 | ||||
-rw-r--r-- | packet.c | 23 | ||||
-rw-r--r-- | serial.c | 7 |
10 files changed, 91 insertions, 44 deletions
diff --git a/driver_sirf.c b/driver_sirf.c index 96d60fba..ba410199 100644 --- a/driver_sirf.c +++ b/driver_sirf.c @@ -270,7 +270,9 @@ static ssize_t sirfbin_visualize(struct gps_device_t *session, size_t len) { (void)snprintf(buf, len, "MID%d:", (int)buf[4]); - gpsd_packetdump(buf + strlen(buf), len - strlen(buf)); + (void)gpsd_packetdump(session->msgbuf, sizeof(session->msgbuf), + buf + strlen(buf), len - strlen(buf)); + return (ssize_t)strlen(buf); } #endif /* VISUALIZE_ENABLE */ @@ -971,7 +971,8 @@ static gps_mask_t rtcm104v2_analyze(struct gps_device_t *session) session->gpsdata.rtcm2.type, session->gpsdata.rtcm2.length + 2, session->packet.isgps.buflen, - gpsd_hexdump((char *)session->packet.isgps.buf, + gpsd_hexdump(session->msgbuf, sizeof(session->msgbuf), + (char *)session->packet.isgps.buf, (session->gpsdata.rtcm2.length + 2) * sizeof(isgps30bits_t))); session->cycle_end_reliable = true; @@ -1353,7 +1354,8 @@ static bool aivdm_decode(const char *buf, size_t buflen, gpsd_report(session->context->debug, LOG_INF, "AIVDM payload is %zd bits, %zd chars: %s\n", ais_context->bitlen, clen, - gpsd_hexdump((char *)ais_context->bits, clen)); + gpsd_hexdump(session->msgbuf, sizeof(session->msgbuf), + (char *)ais_context->bits, clen)); } /* clear waiting fragments count */ @@ -1384,13 +1384,10 @@ static void raw_report(struct subscriber_t *sub, struct gps_device_t *device) */ if (sub->policy.raw == 1) { const char *hd = - gpsd_hexdump((char *)device->packet.outbuffer, + gpsd_hexdump(device->msgbuf, sizeof(device->msgbuf), + (char *)device->packet.outbuffer, device->packet.outbuflen); - /* - * Ugh...depends on knowing the length of gpsd_hexdump's - * buffer. - */ - (void)strlcat((char *)hd, "\r\n", MAX_PACKET_LENGTH * 2 + 1); + (void)strlcat((char *)hd, "\r\n", sizeof(device->msgbuf)); (void)throttled_write(sub, (char *)hd, strlen(hd)); } #endif /* BINARY_ENABLE */ diff --git a/gpsd.h-tail b/gpsd.h-tail index 998f1b46..9252c1d8 100644 --- a/gpsd.h-tail +++ b/gpsd.h-tail @@ -755,8 +755,11 @@ extern gps_mask_t gpsd_interpret_subframe(struct gps_device_t *, unsigned int, uint32_t[]); extern gps_mask_t gpsd_interpret_subframe_raw(struct gps_device_t *, unsigned int, uint32_t[]); -extern /*@ observer @*/ const char *gpsd_hexdump(/*@null@*/char *, size_t); -extern /*@ observer @*/ const char *gpsd_packetdump(/*@null@*/char *, size_t); +extern /*@ observer @*/ const char *gpsd_hexdump(/*@out@*/char *, size_t, + /*@null@*/char *, size_t); +extern /*@ observer @*/ const char *gpsd_packetdump(/*@out@*/char *, size_t, + /*@null@*/char *, size_t); +extern /*@ observer @*/ const char *gpsd_prettydump(struct gps_device_t *); # ifdef __cplusplus extern "C" { # endif diff --git a/gpsd_json.c b/gpsd_json.c index e91dad6b..dbebcc5c 100644 --- a/gpsd_json.c +++ b/gpsd_json.c @@ -1369,6 +1369,7 @@ void json_aivdm_dump(const struct ais_t *ais, char buf2[JSON_VAL_MAX * 2 + 1]; char buf3[JSON_VAL_MAX * 2 + 1]; char buf4[JSON_VAL_MAX * 2 + 1]; + char scratchbuf[MAX_PACKET_LENGTH*2+1]; bool structured; int i; @@ -2205,8 +2206,9 @@ void json_aivdm_dump(const struct ais_t *ais, "\"data\":\"%zd:%s\"}\r\n", ais->type6.bitcount, json_stringify(buf1, sizeof(buf1), - gpsd_hexdump((char *)ais->type6.bitdata, - (ais->type6.bitcount + 7) / 8))); + gpsd_hexdump(scratchbuf, sizeof(scratchbuf), + (char *)ais->type6.bitdata, + (ais->type6.bitcount + 7) / 8))); break; case 7: /* Binary Acknowledge */ case 13: /* Safety Related Acknowledge */ @@ -2900,7 +2902,8 @@ void json_aivdm_dump(const struct ais_t *ais, "\"data\":\"%zd:%s\"}\r\n", ais->type8.bitcount, json_stringify(buf1, sizeof(buf1), - gpsd_hexdump((char *)ais->type8.bitdata, + gpsd_hexdump(scratchbuf, sizeof(scratchbuf), + (char *)ais->type8.bitdata, (ais->type8.bitcount + 7) / 8))); break; case 9: /* Standard SAR Aircraft Position Report */ @@ -3012,7 +3015,8 @@ void json_aivdm_dump(const struct ais_t *ais, ais->type17.lon / AIS_GNSS_LATLON_DIV, ais->type17.lat / AIS_GNSS_LATLON_DIV, ais->type17.bitcount, - gpsd_hexdump((char *)ais->type17.bitdata, + gpsd_hexdump(scratchbuf, sizeof(scratchbuf), + (char *)ais->type17.bitdata, (ais->type17.bitcount + 7) / 8)); } else { (void)snprintf(buf + strlen(buf), buflen - strlen(buf), @@ -3020,7 +3024,8 @@ void json_aivdm_dump(const struct ais_t *ais, ais->type17.lon, ais->type17.lat, ais->type17.bitcount, - gpsd_hexdump((char *)ais->type17.bitdata, + gpsd_hexdump(scratchbuf, sizeof(scratchbuf), + (char *)ais->type17.bitdata, (ais->type17.bitcount + 7) / 8)); } break; @@ -3346,7 +3351,8 @@ void json_aivdm_dump(const struct ais_t *ais, ais->type25.dest_mmsi, ais->type25.app_id, ais->type25.bitcount, - gpsd_hexdump((char *)ais->type25.bitdata, + gpsd_hexdump(scratchbuf, sizeof(scratchbuf), + (char *)ais->type25.bitdata, (ais->type25.bitcount + 7) / 8)); break; case 26: /* Binary Message, Multiple Slot */ @@ -3358,7 +3364,8 @@ void json_aivdm_dump(const struct ais_t *ais, ais->type26.dest_mmsi, ais->type26.app_id, ais->type26.bitcount, - gpsd_hexdump((char *)ais->type26.bitdata, + gpsd_hexdump(scratchbuf, sizeof(scratchbuf), + (char *)ais->type26.bitdata, (ais->type26.bitcount + 7) / 8), ais->type26.radio); break; diff --git a/gpsdecode.c b/gpsdecode.c index 61db9f74..35b5cc7f 100644 --- a/gpsdecode.c +++ b/gpsdecode.c @@ -49,6 +49,7 @@ void gpsd_report(const int debuglevel, const int errlevel, #ifdef AIVDM_ENABLE static void aivdm_csv_dump(struct ais_t *ais, char *buf, size_t buflen) { + char scratchbuf[MAX_PACKET_LENGTH*2+1]; bool imo = false; (void)snprintf(buf, buflen, "%u|%u|%09u|", ais->type, ais->repeat, ais->mmsi); @@ -139,7 +140,8 @@ static void aivdm_csv_dump(struct ais_t *ais, char *buf, size_t buflen) (void)snprintf(buf + strlen(buf), buflen - strlen(buf), "|%zd:%s", ais->type6.bitcount, - gpsd_hexdump(ais->type6.bitdata, + gpsd_hexdump(scratchbuf, sizeof(scratchbuf), + ais->type6.bitdata, (ais->type6.bitcount + 7) / 8)); break; case 7: /* Binary Acknowledge */ @@ -246,7 +248,8 @@ static void aivdm_csv_dump(struct ais_t *ais, char *buf, size_t buflen) (void)snprintf(buf + strlen(buf), buflen - strlen(buf), "|%zd:%s", ais->type8.bitcount, - gpsd_hexdump(ais->type8.bitdata, + gpsd_hexdump(scratchbuf, sizeof(scratchbuf), + ais->type8.bitdata, (ais->type8.bitcount + 7) / 8)); break; case 9: @@ -304,7 +307,8 @@ static void aivdm_csv_dump(struct ais_t *ais, char *buf, size_t buflen) ais->type17.lon, ais->type17.lat, ais->type17.bitcount, - gpsd_hexdump(ais->type17.bitdata, + gpsd_hexdump(scratchbuf, sizeof(scratchbuf), + ais->type17.bitdata, (ais->type17.bitcount + 7) / 8)); break; case 18: @@ -459,7 +463,8 @@ static void aivdm_csv_dump(struct ais_t *ais, char *buf, size_t buflen) ais->type25.dest_mmsi, ais->type25.app_id, ais->type25.bitcount, - gpsd_hexdump(ais->type25.bitdata, + gpsd_hexdump(scratchbuf, sizeof(scratchbuf), + ais->type25.bitdata, (ais->type25.bitcount + 7) / 8)); break; case 26: /* Binary Message, Multiple Slot */ @@ -470,7 +475,8 @@ static void aivdm_csv_dump(struct ais_t *ais, char *buf, size_t buflen) ais->type26.dest_mmsi, ais->type26.app_id, ais->type26.bitcount, - gpsd_hexdump(ais->type26.bitdata, + gpsd_hexdump(scratchbuf, sizeof(scratchbuf), + ais->type26.bitdata, (ais->type26.bitcount + 7) / 8), ais->type26.radio); break; @@ -8,7 +8,9 @@ #include "gpsd.h" -const char /*@ observer @*/ *gpsd_packetdump(char *binbuf, size_t binbuflen) +/*@-mustdefine@*/ +const char /*@ observer @*/ *gpsd_packetdump(char *scbuf, size_t scbuflen, + char *binbuf, size_t binbuflen) { char *cp; bool printable = true; @@ -20,13 +22,14 @@ const char /*@ observer @*/ *gpsd_packetdump(char *binbuf, size_t binbuflen) if (printable) return binbuf; else - return gpsd_hexdump(binbuf, binbuflen); + return gpsd_hexdump(scbuf, scbuflen, binbuf, binbuflen); } +/*@+mustdefine@*/ -const char /*@ observer @*/ *gpsd_hexdump(char *binbuf, size_t binbuflen) +/*@-mustdefine@*/ +const char /*@ observer @*/ *gpsd_hexdump(char *scbuf, size_t scbuflen, + char *binbuf, size_t binbuflen) { - /* FIXME: this isn't thead-safe! */ - static char hexbuf[MAX_PACKET_LENGTH * 2 + 1]; #ifndef SQUELCH_ENABLE size_t i, j = 0; size_t len = @@ -39,17 +42,18 @@ const char /*@ observer @*/ *gpsd_hexdump(char *binbuf, size_t binbuflen) return ""; /*@ -shiftimplementation @*/ - for (i = 0; i < len; i++) { - hexbuf[j++] = hexchar[(ibuf[i] & 0xf0) >> 4]; - hexbuf[j++] = hexchar[ibuf[i] & 0x0f]; + for (i = 0; i < len && i * 2 < scbuflen - 2; i++) { + scbuf[j++] = hexchar[(ibuf[i] & 0xf0) >> 4]; + scbuf[j++] = hexchar[ibuf[i] & 0x0f]; } /*@ +shiftimplementation @*/ - hexbuf[j] = '\0'; + scbuf[j] = '\0'; #else /* SQUELCH defined */ - hexbuf[0] = '\0'; + scbuf[0] = '\0'; #endif /* SQUELCH_ENABLE */ - return hexbuf; + return scbuf; } +/*@+mustdefine@*/ /*@ +charint -shiftimplementation @*/ static int hex2bin(const char *s) diff --git a/libgpsd_core.c b/libgpsd_core.c index 1c237589..37dbfe0e 100644 --- a/libgpsd_core.c +++ b/libgpsd_core.c @@ -59,6 +59,14 @@ static void visibilize(/*@out@*/char *buf2, size_t len, const char *buf) 0x00ff & (unsigned)*sp); } +const char *gpsd_prettydump(struct gps_device_t *session) +/* dump the current packet in a form optimised for eyeballs */ +{ + return gpsd_packetdump(session->msgbuf, sizeof(session->msgbuf), + (char *)session->packet.outbuffer, + session->packet.outbuflen); +} + void gpsd_labeled_report(const int debuglevel, const int errlevel, const char *label, const char *fmt, va_list ap) /* assemble command in printf(3) style, use stderr or syslog */ @@ -163,6 +171,7 @@ static void gpsd_run_device_hook(const int debuglevel, int gpsd_switch_driver(struct gps_device_t *session, char *type_name) { + /*@-mustfreeonly@*/ const struct gps_type_t **dp; bool first_sync = (session->device_type != NULL); @@ -197,6 +206,7 @@ int gpsd_switch_driver(struct gps_device_t *session, char *type_name) gpsd_report(session->context->debug, LOG_ERROR, "invalid GPS type \"%s\".\n", type_name); return 0; /*@ +compmempass @*/ + /*@+mustfreeonly@*/ } /*@-compdestroy@*/ @@ -1186,7 +1196,7 @@ gps_mask_t gpsd_poll(struct gps_device_t *session) if (session->packet.type == (*dp)->packet_type) { gpsd_report(session->context->debug, LOG_PROG, "switching to match packet type %d: %s\n", - session->packet.type, gpsd_packetdump((char *)session->packet.outbuffer, session->packet.outbuflen)); + session->packet.type, gpsd_prettydump(session)); (void)gpsd_switch_driver(session, (*dp)->type_name); break; } @@ -1273,7 +1283,7 @@ gps_mask_t gpsd_poll(struct gps_device_t *session) "raw packet of type %d, %zd:%s\n", session->packet.type, session->packet.outbuflen, - gpsd_packetdump((char *)session->packet.outbuffer, session->packet.outbuflen)); + gpsd_prettydump(session)); /* Get data from current packet into the fix structure */ if (session->packet.type != COMMENT_PACKET) @@ -1288,6 +1298,7 @@ gps_mask_t gpsd_poll(struct gps_device_t *session) * like AIVDM, but a driver with control methods had been active * before that, we keep the information about the control methods. */ + /*@-mustfreeonly@*/ if (!CONTROLLABLE(session->device_type) && session->last_controller != NULL) { @@ -1296,6 +1307,7 @@ gps_mask_t gpsd_poll(struct gps_device_t *session) "reverted to %s driver...\n", session->device_type->type_name); } + /*@+mustfreeonly@*/ #endif /* RECONFIGURE_ENABLE */ #ifdef TIMING_ENABLE @@ -1356,6 +1356,8 @@ static void packet_accept(struct gps_packet_t *lexer, int packet_type) /* packet grab succeeded, move to output buffer */ { size_t packetlen = lexer->inbufptr - lexer->inbuffer; + char scratchbuf[MAX_PACKET_LENGTH*2+1]; + if (packetlen < sizeof(lexer->outbuffer)) { memcpy(lexer->outbuffer, lexer->inbuffer, packetlen); lexer->outbuflen = packetlen; @@ -1365,7 +1367,8 @@ static void packet_accept(struct gps_packet_t *lexer, int packet_type) gpsd_report(lexer->debug, LOG_RAW+1, "Packet type %d accepted %zu = %s\n", packet_type, packetlen, - gpsd_packetdump((char *)lexer->outbuffer, + gpsd_packetdump(scratchbuf, sizeof(scratchbuf), + (char *)lexer->outbuffer, lexer->outbuflen)); } else { gpsd_report(lexer->debug, LOG_ERROR, @@ -1381,23 +1384,28 @@ static void packet_discard(struct gps_packet_t *lexer) size_t remaining = lexer->inbuflen - discard; lexer->inbufptr = memmove(lexer->inbuffer, lexer->inbufptr, remaining); lexer->inbuflen = remaining; - if (lexer->debug >= LOG_RAW+1) + if (lexer->debug >= LOG_RAW+1) { + char scratchbuf[MAX_PACKET_LENGTH*2+1]; gpsd_report(lexer->debug, LOG_RAW + 1, "Packet discard of %zu, chars remaining is %zu = %s\n", discard, remaining, - gpsd_packetdump((char *)lexer->inbuffer, lexer->inbuflen)); + gpsd_packetdump(scratchbuf, sizeof(scratchbuf), + (char *)lexer->inbuffer, lexer->inbuflen)); + } } static void character_discard(struct gps_packet_t *lexer) /* shift the input buffer to discard one character and reread data */ { + char scratchbuf[MAX_PACKET_LENGTH*2+1]; memmove(lexer->inbuffer, lexer->inbuffer + 1, (size_t)-- lexer->inbuflen); lexer->inbufptr = lexer->inbuffer; if (lexer->debug >= LOG_RAW+1) gpsd_report(lexer->debug, LOG_RAW + 1, "Character discarded, buffer %zu chars = %s\n", lexer->inbuflen, - gpsd_packetdump((char *)lexer->inbuffer, lexer->inbuflen)); + gpsd_packetdump(scratchbuf, sizeof(scratchbuf), + (char *)lexer->inbuffer, lexer->inbuflen)); } /* get 0-origin big-endian words relative to start of packet buffer */ @@ -2065,11 +2073,14 @@ ssize_t packet_get(int fd, struct gps_packet_t *lexer) return -1; } } else { - if (lexer->debug >= LOG_RAW+1) + if (lexer->debug >= LOG_RAW+1) { + char scratchbuf[MAX_PACKET_LENGTH*2+1]; gpsd_report(lexer->debug, LOG_RAW + 1, "Read %zd chars to buffer offset %zd (total %zd): %s\n", recvd, lexer->inbuflen, lexer->inbuflen + recvd, - gpsd_packetdump((char *)lexer->inbufptr, (size_t) recvd)); + gpsd_packetdump(scratchbuf, sizeof(scratchbuf), + (char *)lexer->inbufptr, (size_t) recvd)); + } lexer->inbuflen += recvd; } gpsd_report(lexer->debug, LOG_SPIN, @@ -558,10 +558,13 @@ ssize_t gpsd_serial_write(struct gps_device_t * session, ok = (status == (ssize_t) len); (void)tcdrain(session->gpsdata.gps_fd); /* extra guard prevents expensive hexdump calls */ - if (session->context->debug >= LOG_IO) + if (session->context->debug >= LOG_IO) { + char scratchbuf[MAX_PACKET_LENGTH*2+1]; gpsd_report(session->context->debug, LOG_IO, "=> GPS: %s%s\n", - gpsd_packetdump((char *)buf, len), ok ? "" : " FAILED"); + gpsd_packetdump(scratchbuf, sizeof(scratchbuf), + (char *)buf, len), ok ? "" : " FAILED"); + } return status; } |