summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers.c2
-rw-r--r--gps.h8
-rw-r--r--gpsd.c12
-rw-r--r--gpsd.h2
-rw-r--r--gpsd.spec.in4
-rw-r--r--gpsd.xml21
-rw-r--r--libgps.c8
-rw-r--r--libgpsd.xml5
-rw-r--r--libgpsd_core.c14
-rw-r--r--libgpsmm.cpp2
-rw-r--r--libgpsmm.h2
-rw-r--r--packet.c2
-rw-r--r--sirf.c14
-rw-r--r--xgps.c4
-rw-r--r--xgpsspeed.c3
-rw-r--r--zodiac.c10
16 files changed, 72 insertions, 41 deletions
diff --git a/drivers.c b/drivers.c
index 34b578ce..c58491cc 100644
--- a/drivers.c
+++ b/drivers.c
@@ -48,7 +48,7 @@ static int nmea_parse_input(struct gps_device_t *session)
#endif /* NTPSHM_ENABLE */
/* also copy the sentence up to clients in raw mode */
- gpsd_raw_hook(session, session->outbuffer);
+ gpsd_raw_hook(session, session->outbuffer, 1);
return st;
} else
return 0;
diff --git a/gps.h b/gps.h
index ff134026..ef86f681 100644
--- a/gps.h
+++ b/gps.h
@@ -159,8 +159,8 @@ struct gps_data_t {
/* these members are private */
int gps_fd; /* socket or file descriptor to GPS */
- void (*raw_hook)(struct gps_data_t *, char *);/* Raw-mode hook for GPS data. */
- void (*thread_hook)(struct gps_data_t *, char *);/* Thread-callback hook for GPS data. */
+ void (*raw_hook)(struct gps_data_t *, char *, int level);/* Raw-mode hook for GPS data. */
+ void (*thread_hook)(struct gps_data_t *, char *, int level);/* Thread-callback hook for GPS data. */
int seen_sentences; /* track which sentences have been seen */
#define GPRMC 0x01
#define GPGGA 0x02
@@ -179,8 +179,8 @@ extern struct gps_data_t *gps_open(const char *host, const char *port);
int gps_close(struct gps_data_t *);
int gps_query(struct gps_data_t *gpsdata, const char *requests);
int gps_poll(struct gps_data_t *gpsdata);
-void gps_set_raw_hook(struct gps_data_t *gpsdata, void (*hook)(struct gps_data_t *sentence, char *buf));
-int gps_set_callback(struct gps_data_t *gpsdata, void (*callback)(struct gps_data_t *sentence, char *buf), pthread_t *handler);
+void gps_set_raw_hook(struct gps_data_t *gpsdata, void (*hook)(struct gps_data_t *sentence, char *buf, int level));
+int gps_set_callback(struct gps_data_t *gpsdata, void (*callback)(struct gps_data_t *sentence, char *buf, int level), pthread_t *handler);
int gps_del_callback(struct gps_data_t *gpsdata, pthread_t *handler);
/* some multipliers for interpreting GPS output */
diff --git a/gpsd.c b/gpsd.c
index df7ec7c0..5a8899e6 100644
--- a/gpsd.c
+++ b/gpsd.c
@@ -285,14 +285,14 @@ static void notify_watchers(struct gps_device_t *device, char *sentence, ...)
throttled_write(cfd, buf, strlen(buf));
}
-static void raw_hook(struct gps_data_t *ud UNUSED, char *sentence)
+static void raw_hook(struct gps_data_t *ud UNUSED, char *sentence, int level)
/* hook to be executed on each incoming packet */
{
int cfd;
for (cfd = 0; cfd < FD_SETSIZE; cfd++) {
/* copy raw NMEA sentences from GPS to clients in raw mode */
- if (subscribers[cfd].raw && !strcmp(ud->gps_device, (subscribers[cfd].device->gpsdata.gps_device)))
+ if (subscribers[cfd].raw >= level && !strcmp(ud->gps_device, (subscribers[cfd].device->gpsdata.gps_device)))
throttled_write(cfd, sentence, strlen(sentence));
}
}
@@ -604,7 +604,13 @@ static int handle_request(int cfd, char *buf, int buflen)
break;
case 'R':
if (*p == '=') ++p;
- if (*p == '1' || *p == '+') {
+ if (*p == '2') {
+ assign_channel(whoami);
+ subscribers[cfd].raw = 2;
+ gpsd_report(3, "%d turned on super-raw mode\n", cfd);
+ sprintf(phrase, ",R=2");
+ p++;
+ } else if (*p == '1' || *p == '+') {
assign_channel(whoami);
subscribers[cfd].raw = 1;
gpsd_report(3, "%d turned on raw mode\n", cfd);
diff --git a/gpsd.h b/gpsd.h
index c72ec708..f86c3109 100644
--- a/gpsd.h
+++ b/gpsd.h
@@ -166,7 +166,7 @@ extern void gpsd_set_speed(struct gps_device_t *, unsigned int, unsigned int, un
extern int gpsd_get_speed(struct termios *);
extern void gpsd_close(struct gps_device_t *);
-extern void gpsd_raw_hook(struct gps_device_t *, char *);
+extern void gpsd_raw_hook(struct gps_device_t *, char *, int level);
extern void gpsd_zero_satellites(struct gps_data_t *);
extern void gpsd_binary_fix_dump(struct gps_device_t *, char *);
extern void gpsd_binary_satellite_dump(struct gps_device_t *, char *);
diff --git a/gpsd.spec.in b/gpsd.spec.in
index ad6272e3..7e3c811b 100644
--- a/gpsd.spec.in
+++ b/gpsd.spec.in
@@ -127,7 +127,9 @@ cp gps.py "$RPM_BUILD_ROOT"%{_libdir}/python${PYVERSION}/site-packages
Ensure longitude has a leading zero when <100, for compatibility with
gpsdrive. Synchronous and thread hooks are now separate in the client
library. Packet-sniffing on a new device no longer holds up incoming
- data on already-connected ones.
+ data on already-connected ones. There is now a super-raw mode (R=2)
+ that dumps a hex-encoding of every binary packet received to the
+ client.
* Sat May 21 2005 Eric S. Raymond <esr@snark.thyrsus.com> - 2.25-1
- Various signedness and scaling fixes and an OpenBSD port patch for the
diff --git a/gpsd.xml b/gpsd.xml
index 97252dab..7f1e3557 100644
--- a/gpsd.xml
+++ b/gpsd.xml
@@ -398,13 +398,20 @@ only the first three DOP numbers, omitting time DOP and total DOP.</para>
<varlistentry>
<term>r</term>
-<listitem><para>Sets or toggles 'raw' mode. Return "R=0" or "R=1". In
-raw mode you read the NMEA data stream from the GPS. (Non-NMEA GPSes
-get their communication format translated to NMEA on the fly.) The
-command 'r' immediately followed by the digit '1' or the plus sign '+'
-sets raw mode. The command 'r' followed by the digit '0' or the minus
-sign '-' clears raw mode. The command 'r' with neither suffix toggles
-raw mode.</para></listitem>
+<listitem><para>Sets or toggles 'raw' mode. Return "R=0" or "R=1" or
+"R=2". In raw mode you read the NMEA data stream from the
+GPS. (Non-NMEA GPSes get their communication format translated to NMEA
+on the fly.) The command 'r' immediately followed by the digit '1' or
+the plus sign '+' sets raw mode. The command 'r' immediately followed
+by the digit '2' sets super-raw mode; for non-NMEA (binary) GPSes this
+dumps '=', followed by a hex encoding of the raw binary packet, then
+dumps translated NMEA. The command 'r' followed by the digit '0' or
+the minus sign '-' clears raw mode. The command 'r' with neither
+suffix toggles raw mode.</para>
+
+<para>Note: older versions of <application>gpsd</application> did not
+support super-raw mode.</para>
+</listitem>
</varlistentry>
<varlistentry>
diff --git a/libgps.c b/libgps.c
index 411f74af..f60ed979 100644
--- a/libgps.c
+++ b/libgps.c
@@ -131,7 +131,7 @@ int gps_close(struct gps_data_t *gpsdata)
return retval;
}
-void gps_set_raw_hook(struct gps_data_t *gpsdata, void (*hook)(struct gps_data_t *, char *))
+void gps_set_raw_hook(struct gps_data_t *gpsdata, void (*hook)(struct gps_data_t *, char *, int level))
{
gpsdata->raw_hook = hook;
}
@@ -425,9 +425,9 @@ static void gps_unpack(char *buf, struct gps_data_t *gpsdata)
}
if (gpsdata->raw_hook)
- gpsdata->raw_hook(gpsdata, buf);
+ gpsdata->raw_hook(gpsdata, buf, 1);
if (gpsdata->thread_hook)
- gpsdata->thread_hook(gpsdata, buf);
+ gpsdata->thread_hook(gpsdata, buf, 1);
}
/*
@@ -488,7 +488,7 @@ static void *poll_gpsd(void *args)
}
int gps_set_callback(struct gps_data_t *gpsdata,
- void (*callback)(struct gps_data_t *sentence, char *buf),
+ void (*callback)(struct gps_data_t *sentence, char *buf, int level),
pthread_t *handler)
/* set an asynchronous callback and launch a thread for it */
{
diff --git a/libgpsd.xml b/libgpsd.xml
index 44ba3064..4452ccf6 100644
--- a/libgpsd.xml
+++ b/libgpsd.xml
@@ -113,9 +113,10 @@ designate a speed to be tried at the front of the hunt queue</para>
<term><structfield>raw_hook</structfield></term>
<listitem>
<para>A hook function to be executed on each NMEA
-sentence as it is read from the GPS. The data from non-NMEA GPSes like
+sentence or as it is read from the GPS. The data from non-NMEA GPSes like
the EarthMate will be translated to an NMEA sentence before being
-passed to the hook.</para>
+passed to the hook. Parameters are a pointer to a gps_data structure
+full of parsed data, the sentence, and a rawness level.</para>
</listitem>
</varlistentry>
</variablelist>
diff --git a/libgpsd_core.c b/libgpsd_core.c
index 7adca7bb..fa4ac838 100644
--- a/libgpsd_core.c
+++ b/libgpsd_core.c
@@ -372,10 +372,10 @@ void gpsd_zero_satellites(struct gps_data_t *out)
out->satellites = 0;
}
-void gpsd_raw_hook(struct gps_device_t *session, char *sentence)
+void gpsd_raw_hook(struct gps_device_t *session, char *sentence, int level)
{
if (session->gpsdata.raw_hook) {
- session->gpsdata.raw_hook(&session->gpsdata, sentence);
+ session->gpsdata.raw_hook(&session->gpsdata, sentence, level);
}
}
@@ -436,7 +436,7 @@ void gpsd_binary_fix_dump(struct gps_device_t *session, char *bufp)
strcat(bufp, (session->mag_var > 0) ? "E": "W");
}
nmea_add_checksum(bufp);
- gpsd_raw_hook(session, bufp);
+ gpsd_raw_hook(session, bufp, 1);
bufp += strlen(bufp);
}
sprintf(bufp,
@@ -455,7 +455,7 @@ void gpsd_binary_fix_dump(struct gps_device_t *session, char *bufp)
tm.tm_mon + 1,
tm.tm_year % 100);
nmea_add_checksum(bufp);
- gpsd_raw_hook(session, bufp);
+ gpsd_raw_hook(session, bufp, 1);
}
void gpsd_binary_satellite_dump(struct gps_device_t *session, char *bufp)
@@ -482,7 +482,7 @@ void gpsd_binary_satellite_dump(struct gps_device_t *session, char *bufp)
session->gpsdata.ss[i]);
if (i % 4 == 3 || i == session->gpsdata.satellites-1) {
nmea_add_checksum(bufp2);
- gpsd_raw_hook(session, bufp2);
+ gpsd_raw_hook(session, bufp2, 1);
}
}
}
@@ -511,7 +511,7 @@ void gpsd_binary_quality_dump(struct gps_device_t *session, char *bufp)
session->gpsdata.hdop,
session->gpsdata.vdop);
nmea_add_checksum(bufp2);
- gpsd_raw_hook(session, bufp2);
+ gpsd_raw_hook(session, bufp2, 1);
bufp += strlen(bufp);
if ((session->gpsdata.fix.eph || session->gpsdata.fix.epv)
&& finite(session->gpsdata.fix.eph)
@@ -525,7 +525,7 @@ void gpsd_binary_quality_dump(struct gps_device_t *session, char *bufp)
session->gpsdata.fix.epv,
session->gpsdata.epe);
nmea_add_checksum(bufp);
- gpsd_raw_hook(session, bufp);
+ gpsd_raw_hook(session, bufp, 1);
session->gpsdata.seen_sentences |= PGRME;
}
}
diff --git a/libgpsmm.cpp b/libgpsmm.cpp
index 908d49c5..b63a12b6 100644
--- a/libgpsmm.cpp
+++ b/libgpsmm.cpp
@@ -38,7 +38,7 @@ struct gps_data_t* gpsmm::poll(void) {
}
}
-int gpsmm::set_callback(void (*hook)(struct gps_data_t *sentence, char *buf)) {
+int gpsmm::set_callback(void (*hook)(struct gps_data_t *sentence, char *buf, int level)) {
handler = new pthread_t;
return gps_set_callback(gps_data,hook,handler);
}
diff --git a/libgpsmm.h b/libgpsmm.h
index d41404b8..d3853407 100644
--- a/libgpsmm.h
+++ b/libgpsmm.h
@@ -28,7 +28,7 @@ class gpsmm {
struct gps_data_t* open(void); //open() with default values
struct gps_data_t* query(const char *request); //put a command to gpsd and return the updated struct
struct gps_data_t* poll(void); //block until gpsd returns new data, then return the updated struct
- int set_callback(void (*hook)(struct gps_data_t *sentence, char *buf)); //set a callback funcition, called each time new data arrives
+ int set_callback(void (*hook)(struct gps_data_t *sentence, char *buf, int level)); //set a callback funcition, called each time new data arrives
int del_callback(void); //delete the callback function
void clear_fix(void);
diff --git a/packet.c b/packet.c
index 9dffa7bc..cf8c95c9 100644
--- a/packet.c
+++ b/packet.c
@@ -437,7 +437,7 @@ static char *buffer_dump(unsigned char *base, unsigned char *end)
static void packet_accept(struct gps_device_t *session)
/* packet grab succeeded, move to output buffer */
{
- int packetlen = session->inbufptr-session->inbuffer;
+ unsigned int packetlen = session->inbufptr-session->inbuffer;
if (packetlen < sizeof(session->outbuffer)) {
memcpy(session->outbuffer, session->inbuffer, packetlen);
session->outbuffer[session->outbuflen = packetlen] = '\0';
diff --git a/sirf.c b/sirf.c
index 6ed1a39b..9aceca89 100644
--- a/sirf.c
+++ b/sirf.c
@@ -115,7 +115,7 @@ static void sirfbin_mode(struct gps_device_t *session, int mode)
int sirf_parse(struct gps_device_t *session, unsigned char *buf, int len)
{
int st, i, j, cn, navtype, mask;
- char buf2[MAX_PACKET_LENGTH*3];
+ char buf2[MAX_PACKET_LENGTH*3+2];
double fv;
u_int8_t enablesubframe[] = {0xa0, 0xa2, 0x00, 0x19,
0x80, 0x00, 0x00, 0x00,
@@ -139,10 +139,18 @@ int sirf_parse(struct gps_device_t *session, unsigned char *buf, int len)
if (len < 0)
return 0;
- buf2[0] = '\0';
+ buf2[0] = '=';
+ buf2[1] = '\0';
for (i = 0; i < len; i++)
sprintf(buf2+strlen(buf2), "%02x", buf[i]);
+ strcat(buf2, "\n");
+ if (session->gpsdata.raw_hook)
+ session->gpsdata.raw_hook(&session->gpsdata, buf2, 2);
gpsd_report(5, "Raw SiRF packet type 0x%02x length %d: %s\n", buf[0],len,buf2);
+ buf += 4;
+ len -= 8;
+
+
if (buf[0] != 0xff)
snprintf(session->gpsdata.tag,sizeof(session->gpsdata.tag),"MID%d",buf[0]);
@@ -665,7 +673,7 @@ static int sirfbin_parse_input(struct gps_device_t *session)
int st;
if (session->packet_type == SIRF_PACKET){
- st = sirf_parse(session, session->outbuffer+4, session->outbuflen-8);
+ st = sirf_parse(session, session->outbuffer, session->outbuflen);
session->gpsdata.driver_mode = 1;
return st;
} else if (session->packet_type == NMEA_PACKET) {
diff --git a/xgps.c b/xgps.c
index f3c73153..412b237d 100644
--- a/xgps.c
+++ b/xgps.c
@@ -235,7 +235,9 @@ static void handle_input(XtPointer client_data UNUSED, int *source UNUSED,
}
}
-static void update_panel(struct gps_data_t *gpsdata, char *message)
+static void update_panel(struct gps_data_t *gpsdata,
+ char *message,
+ int level UNUSED)
/* runs on each sentence */
{
unsigned int i;
diff --git a/xgpsspeed.c b/xgpsspeed.c
index aa9a5251..6e7a2213 100644
--- a/xgpsspeed.c
+++ b/xgpsspeed.c
@@ -29,7 +29,8 @@ static Widget tacho;
static double speedfactor;
static Widget toplevel;
-static void update_display(struct gps_data_t *gpsdata, char *buf UNUSED)
+static void update_display(struct gps_data_t *gpsdata,
+ char *buf UNUSED, int level UNUSED)
{
TachometerSetValue(tacho, rint(gpsdata->fix.speed * speedfactor));
}
diff --git a/zodiac.c b/zodiac.c
index 32b0a487..7216d33e 100644
--- a/zodiac.c
+++ b/zodiac.c
@@ -323,7 +323,7 @@ static void handle1108(struct gps_device_t *session)
static int zodiac_analyze(struct gps_device_t *session)
{
char buf[BUFSIZ];
- char buf2[MAX_PACKET_LENGTH*3];
+ char buf2[MAX_PACKET_LENGTH*3+2];
int i, mask = 0;
unsigned int id = (session->outbuffer[3] << 8) | session->outbuffer[2];
@@ -332,9 +332,13 @@ static int zodiac_analyze(struct gps_device_t *session)
return 0;
}
- buf2[0] = '\0';
+ buf2[0] = '=';
+ buf2[1] = '\0';
for (i = 0; i < session->outbuflen; i++)
sprintf(buf2+strlen(buf2), "%02x", session->outbuffer[i]);
+ strcat(buf2, "\n");
+ if (session->gpsdata.raw_hook)
+ session->gpsdata.raw_hook(&session->gpsdata, buf2, 2);
gpsd_report(5, "Raw Zodiac packet type %d length %d: %s\n",id,session->outbuflen,buf2);
if (session->outbuflen < 10)
@@ -356,7 +360,7 @@ static int zodiac_analyze(struct gps_device_t *session)
}
strcat(buf, "*");
nmea_add_checksum(buf);
- gpsd_raw_hook(session, buf);
+ gpsd_raw_hook(session, buf, 1);
gpsd_binary_quality_dump(session, buf+strlen(buf));
gpsd_report(3, "<= GPS: %s", buf);
break;