summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--driver_sirf.c4
-rw-r--r--drivers.c6
-rw-r--r--gpsd.c9
-rw-r--r--gpsd.h-tail7
-rw-r--r--gpsd_json.c21
-rw-r--r--gpsdecode.c16
-rw-r--r--hex.c26
-rw-r--r--libgpsd_core.c16
-rw-r--r--packet.c23
-rw-r--r--serial.c7
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 */
diff --git a/drivers.c b/drivers.c
index 9c6eed26..4933004f 100644
--- a/drivers.c
+++ b/drivers.c
@@ -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 */
diff --git a/gpsd.c b/gpsd.c
index 2d18e268..aeb31a06 100644
--- a/gpsd.c
+++ b/gpsd.c
@@ -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;
diff --git a/hex.c b/hex.c
index c4130a66..95f4121d 100644
--- a/hex.c
+++ b/hex.c
@@ -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
diff --git a/packet.c b/packet.c
index 59702e63..bdbec125 100644
--- a/packet.c
+++ b/packet.c
@@ -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,
diff --git a/serial.c b/serial.c
index f3343870..7c515708 100644
--- a/serial.c
+++ b/serial.c
@@ -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;
}