summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgps.c2
-rw-r--r--gps.h6
-rw-r--r--gps_json.h2
-rw-r--r--libgps.xml8
-rw-r--r--libgps_core.c50
-rw-r--r--www/client-howto.txt4
6 files changed, 42 insertions, 30 deletions
diff --git a/cgps.c b/cgps.c
index 5d9200d6..6fac00cb 100644
--- a/cgps.c
+++ b/cgps.c
@@ -693,7 +693,7 @@ static void update_gps_panel(struct gps_data_t *gpsdata)
/* Be quiet if the user requests silence. */
if (!silent_flag && raw_flag) {
- (void)waddstr(messages, gpsdata->buffer);
+ (void)waddstr(messages, gps_data(gpsdata));
}
/* Reset the status_timer if the state has changed. */
diff --git a/gps.h b/gps.h
index b8f706d2..612b6ca8 100644
--- a/gps.h
+++ b/gps.h
@@ -49,7 +49,6 @@ extern "C" {
#define MAXCHANNELS 72 /* must be > 12 GPS + 12 GLONASS + 2 WAAS */
#define GPS_PRNMAX 32 /* above this number are SBAS satellites */
#define GPS_PATH_MAX 64 /* dev files usually have short names */
-#define GPS_BUFFER_MAX 3072 /* enough for two maximun-size JSON objects */
#define MAXUSERDEVS 4 /* max devices per user */
/*
@@ -1403,10 +1402,6 @@ struct gps_data_t {
char tag[MAXTAGLEN+1]; /* tag of last sentence processed */
- /* data buffered from the last read */
- ssize_t waiting;
- char buffer[GPS_BUFFER_MAX * 2];
-
/* pack things never reported together to reduce structure size */
#define UNION_SET (RTCM2_SET|RTCM3_SET|SUBFRAME_SET|AIS_SET|VERSION_SET|DEVICELIST_SET|LOGMESSAGE_SET|ERROR_SET|GST_SET)
union {
@@ -1439,6 +1434,7 @@ extern int gps_send(struct gps_data_t *, const char *, ... );
extern int gps_read(/*@out@*/struct gps_data_t *);
extern bool gps_waiting(struct gps_data_t *, int);
extern int gps_stream(struct gps_data_t *, unsigned int, /*@null@*/void *);
+extern const char /*@observer@*/ *gps_data(struct gps_data_t *);
extern const char /*@observer@*/ *gps_errstr(const int);
/* this only needs to be visible for the unit tests */
diff --git a/gps_json.h b/gps_json.h
index e5a82594..bf5150d2 100644
--- a/gps_json.h
+++ b/gps_json.h
@@ -8,7 +8,7 @@
#include "json.h"
#define GPS_JSON_COMMAND_MAX 80
-#define GPS_JSON_RESPONSE_MAX 1536
+#define GPS_JSON_RESPONSE_MAX 4096
#ifdef __cplusplus
extern "C" {
diff --git a/libgps.xml b/libgps.xml
index eccc66d1..b70f3a67 100644
--- a/libgps.xml
+++ b/libgps.xml
@@ -47,6 +47,10 @@ C:
<paramdef>int <parameter>timeout</parameter></paramdef>
</funcprototype>
<funcprototype>
+<funcdef>void <function>gps_data</function></funcdef>
+ <paramdef>struct gps_data_t *<parameter>gpsdata</parameter></paramdef>
+</funcprototype>
+<funcprototype>
<funcdef>void <function>gps_close</function></funcdef>
<paramdef>struct gps_data_t *<parameter>gpsdata</parameter></paramdef>
</funcprototype>
@@ -140,6 +144,10 @@ will not supply input often enough to prevent a spurious error indication.
For the typical 1-second cycle time of GPSes this implies a minimum 2-second
timeout.</para>
+<para><function>gps_data()</function> returns the contents of the
+client data buffer. Use with care; this may fail to be a NUL-terminated
+string if WATCH_RAW is enabled.</para>
+
<para><function>gps_stream()</function> asks
<application>gpsd</application> to stream the reports it has at you,
to be made available when you poll. It is preferable to the
diff --git a/libgps_core.c b/libgps_core.c
index d59f3839..23f3e999 100644
--- a/libgps_core.c
+++ b/libgps_core.c
@@ -44,6 +44,10 @@ extern char *strtok_r(char *, const char *, char **);
struct privdata_t
{
bool newstyle;
+ /* data buffered from the last read */
+ ssize_t waiting;
+ char buffer[GPS_JSON_RESPONSE_MAX * 2];
+
};
#define PRIVATE(gpsdata) ((struct privdata_t *)gpsdata->privdata)
@@ -129,9 +133,7 @@ int gps_open(/*@null@*/const char *host, /*@null@*/const char *port,
if (gpsdata->privdata == NULL)
return -1;
PRIVATE(gpsdata)->newstyle = false;
- gpsdata->waiting = 0;
- /*@i1@*/ gpsdata->buffer[0] = '\0';
-
+ PRIVATE(gpsdata)->waiting = 0;
return 0;
/*@ +branchstate @*/
}
@@ -507,7 +509,7 @@ bool gps_waiting(struct gps_data_t * gpsdata, int timeout)
struct timeval tv;
libgps_debug_trace((DEBUG_CALLS, "gps_waiting(%d): %d\n", timeout, waitcount++));
- if (gpsdata->waiting > 0)
+ if (PRIVATE(gpsdata)->waiting > 0)
return true;
/* we might want to check for EINTR if this returns false */
@@ -534,8 +536,8 @@ int gps_read(/*@out@*/struct gps_data_t *gpsdata)
int status = -1;
gpsdata->set &= ~PACKET_SET;
- for (eol = gpsdata->buffer;
- *eol != '\n' && eol < gpsdata->buffer + gpsdata->waiting; eol++)
+ for (eol = PRIVATE(gpsdata)->buffer;
+ *eol != '\n' && eol < PRIVATE(gpsdata)->buffer + PRIVATE(gpsdata)->waiting; eol++)
continue;
if (*eol != '\n')
eol = NULL;
@@ -546,21 +548,21 @@ int gps_read(/*@out@*/struct gps_data_t *gpsdata)
#ifndef USE_QT
/* read data: return -1 if no data waiting or buffered, 0 otherwise */
status = (int)recv(gpsdata->gps_fd,
- gpsdata->buffer + gpsdata->waiting,
- sizeof(gpsdata->buffer) - gpsdata->waiting, 0);
+ PRIVATE(gpsdata)->buffer + PRIVATE(gpsdata)->waiting,
+ sizeof(PRIVATE(gpsdata)->buffer) - PRIVATE(gpsdata)->waiting, 0);
#else
status =
- ((QTcpSocket *) (gpsdata->gps_fd))->read(gpsdata->buffer +
- gpsdata->waiting,
- sizeof(gpsdata->buffer) -
- gpsdata->waiting);
+ ((QTcpSocket *) (gpsdata->gps_fd))->read(PRIVATE(gpsdata)->buffer +
+ PRIVATE(gpsdata)->waiting,
+ sizeof(PRIVATE(gpsdata)->buffer) -
+ PRIVATE(gpsdata)->waiting);
#endif
/* if we just received data from the socket, it's in the buffer */
if (status > -1)
- gpsdata->waiting += status;
+ PRIVATE(gpsdata)->waiting += status;
/* buffer is empty - implies no data was read */
- if (gpsdata->waiting == 0) {
+ if (PRIVATE(gpsdata)->waiting == 0) {
/*
* If we received 0 bytes, other side of socket is closing.
* Return -1 as end-of-data indication.
@@ -578,8 +580,8 @@ int gps_read(/*@out@*/struct gps_data_t *gpsdata)
return -1;
}
/* there's buffered data waiting to be returned */
- for (eol = gpsdata->buffer;
- *eol != '\n' && eol < gpsdata->buffer + gpsdata->waiting; eol++)
+ for (eol = PRIVATE(gpsdata)->buffer;
+ *eol != '\n' && eol < PRIVATE(gpsdata)->buffer + PRIVATE(gpsdata)->waiting; eol++)
continue;
if (*eol != '\n')
eol = NULL;
@@ -589,20 +591,26 @@ int gps_read(/*@out@*/struct gps_data_t *gpsdata)
assert(eol != NULL);
*eol = '\0';
- response_length = eol - gpsdata->buffer + 1;
+ response_length = eol - PRIVATE(gpsdata)->buffer + 1;
received = gpsdata->online = timestamp();
- status = gps_unpack(gpsdata->buffer, gpsdata);
+ status = gps_unpack(PRIVATE(gpsdata)->buffer, gpsdata);
/*@+matchanyintegral@*/
- memmove(gpsdata->buffer,
- gpsdata->buffer + response_length, gpsdata->waiting - response_length);
+ memmove(PRIVATE(gpsdata)->buffer,
+ PRIVATE(gpsdata)->buffer + response_length, PRIVATE(gpsdata)->waiting - response_length);
/*@-matchanyintegral@*/
- gpsdata->waiting -= response_length;
+ PRIVATE(gpsdata)->waiting -= response_length;
gpsdata->set |= PACKET_SET;
return (status == 0) ? (int)response_length : status;
}
/*@+compdef -usedef +uniondef@*/
+const char /*@observer@*/ *gps_data(struct gps_data_t *gpsdata)
+/* return the contents of the client data buffer */
+{
+ return PRIVATE(gpsdata)->buffer;
+}
+
int gps_send(struct gps_data_t *gpsdata, const char *fmt, ...)
/* send a command to the gpsd instance */
{
diff --git a/www/client-howto.txt b/www/client-howto.txt
index 9d5a9ffc..3dbf341f 100644
--- a/www/client-howto.txt
+++ b/www/client-howto.txt
@@ -1,6 +1,6 @@
= GPSD Client HOWTO =
Eric S. Raymond <esr@thyrsus.com>
-v1.7, March 2011
+v1.8, March 2011
This document is mastered in asciidoc format. If you are reading it
in HTML, you can find the original at
@@ -507,7 +507,7 @@ In major versions before 5:
send messages to stderr. This requirement is now gone.
* There was a set_raw_hook() method in the C and Python bindings, now gone.
- Clients can simply look at the response buffer.
+ C clients should call gps_data(); the buffer is available directly in Python.
See http://gpsd.berlios.de/future.html#api_cleanup[Client API Cleanup]
for details.