summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Browet <cbro@semperpax.com>2010-03-31 04:35:58 -0400
committerEric S. Raymond <esr@thyrsus.com>2010-03-31 04:35:58 -0400
commitd8462cfb9ef84e1b0fbd7c794993318d56bd6dfc (patch)
tree4ef0f2990e1d5e63d89c8361a57e7231252153df
parent3202783122582a67b82ff40507550a17dffebb74 (diff)
downloadgpsd-d8462cfb9ef84e1b0fbd7c794993318d56bd6dfc.tar.gz
Internals of Qt support.
All regression tests pass. Note from esr: this feature cannot be announced yert, as it requires documentation in the INSTALL file. 1. What the target environments are (Linux? Windows? Both) 2. All build prerequisites (C++ compiler? Qt library? Other libraries?) 3. What the new files libQgpsmm_global.h and libQgpsmm.pro are for, and how the are used. We also need to know how to regression-test this code under Linux so we can verify that it's not broken as the client library evolves. Signed-off-by: Eric S. Raymond <esr@thyrsus.com>
-rw-r--r--configure.ac12
-rw-r--r--gps.h8
-rw-r--r--gps_json.h6
-rw-r--r--gpsd.h-tail6
-rw-r--r--gpsutils.c20
-rw-r--r--json.h6
-rw-r--r--libQgpsmm.pro64
-rw-r--r--libQgpsmm_global.h12
-rw-r--r--libgps_core.c55
-rw-r--r--libgpsmm.h5
10 files changed, 194 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index 082ea20c..e1c30fa3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -231,10 +231,22 @@ AC_SUBST(LIBPTHREAD)
AH_VERBATIM([_GNU_SOURCE],
[/* Some libc's don't have strlcat/strlcpy. Local copies are provided */
#ifndef HAVE_STRLCAT
+# ifdef __cplusplus
+extern "C" {
+# endif
size_t strlcat(/*@out@*/char *dst, /*@in@*/const char *src, size_t size);
+# ifdef __cplusplus
+}
+# endif
#endif
#ifndef HAVE_STRLCPY
+# ifdef __cplusplus
+extern "C" {
+# endif
size_t strlcpy(/*@out@*/char *dst, /*@in@*/const char *src, size_t size);
+# ifdef __cplusplus
+}
+# endif
#endif
#define GPSD_CONFIG_H])
diff --git a/gps.h b/gps.h
index 32dc34f2..b03034a7 100644
--- a/gps.h
+++ b/gps.h
@@ -7,6 +7,10 @@
/* gps.h -- interface of the libgps library */
+#ifdef _WIN32
+ #define strtok_r(s,d,p) strtok(s,d)
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -960,7 +964,11 @@ struct gps_data_t {
* prone to false zero values.
*/
+#ifndef USE_QT
socket_t gps_fd; /* socket or file descriptor to GPS */
+#else
+ void* gps_fd;
+#endif
struct gps_fix_t fix; /* accumulated PVT data */
double separation; /* Geoidal separation, MSL - WGS84 (Meters) */
diff --git a/gps_json.h b/gps_json.h
index 85061300..a00a31b4 100644
--- a/gps_json.h
+++ b/gps_json.h
@@ -10,6 +10,9 @@
#define GPS_JSON_COMMAND_MAX 80
#define GPS_JSON_RESPONSE_MAX 1024
+#ifdef __cplusplus
+extern "C" {
+#endif
char *json_stringify(/*@out@*/char *, size_t, /*@in@*/const char *);
void json_tpv_dump(const struct gps_data_t *, /*@out@*/char *, size_t);
void json_sky_dump(const struct gps_data_t *, /*@out@*/char *, size_t);
@@ -26,6 +29,9 @@ int json_ais_read(const char *, char *, size_t, struct ais_t *,
/*@null@*/const char **);
int libgps_json_unpack(const char *, struct gps_data_t *,
/*@null@*/const char **);
+#ifdef __cplusplus
+}
+#endif
/* these values don't matter in themselves, they just have to be out-of-band */
#define DEVDEFAULT_BPS 0
diff --git a/gpsd.h-tail b/gpsd.h-tail
index aa96f795..a56699a3 100644
--- a/gpsd.h-tail
+++ b/gpsd.h-tail
@@ -5,6 +5,10 @@
*/
#endif /* GPSD_CONFIG_H */
+#ifdef _WIN32
+typedef unsigned int speed_t;
+#endif
+
/* constants for the VERSION response */
#define GPSD_PROTO_MAJOR_VERSION 3 /* bump on incompatible changes */
#define GPSD_PROTO_MINOR_VERSION 2 /* bump on compatible changes */
@@ -232,7 +236,9 @@ struct gps_device_t {
struct gps_context_t *context;
bool is_serial;
double rtcmtime; /* timestamp of last RTCM104 correction to GPS */
+#ifndef _WIN32
struct termios ttyset, ttyset_old;
+#endif
unsigned int baudindex;
int saved_baud;
struct gps_packet_t packet;
diff --git a/gpsutils.c b/gpsutils.c
index 6c33f8c9..6b89ced5 100644
--- a/gpsutils.c
+++ b/gpsutils.c
@@ -16,6 +16,11 @@
#include "gpsd.h"
+#ifdef USE_QT
+#include <QDateTime>
+#include <QStringList>
+#endif
+
#define MONTHSPERYEAR 12 /* months per calendar year */
void gps_clear_fix(/*@out@*/struct gps_fix_t *fixp)
@@ -147,6 +152,7 @@ time_t mkgmtime(register struct tm *t)
double iso8601_to_unix(/*@in@*/char *isotime)
/* ISO8601 UTC to Unix UTC */
{
+#ifndef USE_QT
char *dp = NULL;
double usec;
struct tm tm;
@@ -157,6 +163,16 @@ double iso8601_to_unix(/*@in@*/char *isotime)
else
usec = 0;
return (double)mkgmtime(&tm) + usec;
+#else
+ double usec = 0;
+
+ QString t(isotime);
+ QDateTime d = QDateTime::fromString(isotime, Qt::ISODate);
+ QStringList sl = t.split(".");
+ if (sl.size() > 1)
+ usec = sl[1].toInt() / pow(10., (double)sl[1].size());
+ return d.toTime_t() + usec;
+#endif
}
/*@observer@*/char *unix_to_iso8601(double fixtime, /*@ out @*/char isotime[], size_t len)
@@ -539,9 +555,11 @@ gps_mask_t fill_dop(const struct gps_data_t *gpsdata, struct dop_t *dop)
}
#endif /* __UNUSED__ */
} else {
+#ifndef USE_QT
gpsd_report(LOG_DATA,
"LOS matrix is singular, can't calculate DOPs - source '%s'\n",
gpsdata->dev.path);
+#endif
return 0;
}
@@ -553,6 +571,7 @@ gps_mask_t fill_dop(const struct gps_data_t *gpsdata, struct dop_t *dop)
tdop = sqrt(inv[3][3]);
gdop = sqrt(inv[0][0] + inv[1][1] + inv[2][2] + inv[3][3]);
+#ifndef USE_QT
gpsd_report(LOG_DATA, "DOPS computed/reported: X=%f/%f, Y=%f/%f, H=%f/%f, V=%f/%f, P=%f/%f, T=%f/%f, G=%f/%f\n",
xdop, dop->xdop,
ydop, dop->ydop,
@@ -561,6 +580,7 @@ gps_mask_t fill_dop(const struct gps_data_t *gpsdata, struct dop_t *dop)
pdop, dop->pdop,
tdop, dop->tdop,
gdop, dop->gdop);
+#endif
/*@ -usedef @*/
if (isnan(dop->xdop)!=0) {
diff --git a/json.h b/json.h
index 1d928ee1..6e48cddb 100644
--- a/json.h
+++ b/json.h
@@ -65,6 +65,9 @@ struct json_attr_t {
#define JSON_ATTR_MAX 31 /* max chars in JSON attribute name */
#define JSON_VAL_MAX 120 /* max chars in JSON value part */
+#ifdef __cplusplus
+extern "C" {
+#endif
int json_read_object(const char *, const struct json_attr_t *,
/*@null@*/const char **);
int json_read_array(const char *, const struct json_array_t *,
@@ -72,6 +75,9 @@ int json_read_array(const char *, const struct json_array_t *,
const /*@observer@*/char *json_error_string(int);
void json_enable_debug(int, FILE *);
+#ifdef __cplusplus
+}
+#endif
#define JSON_ERR_OBSTART 1 /* non-WS when expecting object start */
#define JSON_ERR_ATTRSTART 2 /* non-WS when expecting attrib start */
diff --git a/libQgpsmm.pro b/libQgpsmm.pro
new file mode 100644
index 00000000..59044c7d
--- /dev/null
+++ b/libQgpsmm.pro
@@ -0,0 +1,64 @@
+# -------------------------------------------------
+# Project created by QtCreator 2010-03-26T10:37:44
+# -------------------------------------------------
+QT += network
+QT -= gui
+TARGET = Qgpsmm
+TEMPLATE = lib
+DEFINES += LIBQGPSMM_LIBRARY
+DEFINES += USE_QT
+#QMAKE_EXT_CPP += .c
+!win32: QMAKE_CFLAGS += -D_GNU_SOURCE
+INCLUDEPATH += $$PWD \
+ ..
+
+
+SOURCES += \
+ ../libgpsmm.cpp \
+ gpsutils.cpp \
+ ../libgps_json.c \
+ ../hex.c \
+ libgps_core.cpp \
+ ../gpsd_report.c \
+ ../strl.c \
+ ../shared_json.c \
+ ../rtcm2_json.c \
+ ../ais_json.c \
+ ../json.c
+HEADERS += libQgpsmm_global.h \
+ ../gps.h \
+ ../libgpsmm.h \
+ ../gps_json.h \
+ ../json.h
+
+unix {
+ # Prefix: base instalation directory
+ isEmpty( PREFIX ) {
+ PREFIX = /usr/local
+ }
+ target.path = $${PREFIX}/lib
+ INSTALLS += target
+
+ header.path = $${PREFIX}/include
+ header.files = ../libgpsmm.h ../gps.h
+ INSTALLS += header
+}
+
+gpsutilscpp.target = gpsutils.cpp
+win32:gpsutilscpp.commands = copy ..\gpsutils.c gpsutils.cpp
+else:gpsutilscpp.commands = cp ../gpsutils.c gpsutils.cpp
+gpsutilscpp.depends = FORCE
+
+libgps_corecpp.target = libgps_core.cpp
+win32:libgps_corecpp.commands = copy ..\libgps_core.c libgps_core.cpp
+else:libgps_corecpp.commands = cp ../libgps_core.c libgps_core.cpp
+libgps_corecpp.depends = FORCE
+
+gpsdhcreate.target = gpsd.h
+win32:gpsdhcreate.commands = "copy /Y /B ..\gpsd.h-head + mingw\gpsd_config.h + ..\gpsd.h-tail ..\gpsd.h" && "copy /Y mingw\gpsd_config.h .." && "copy /Y mingw\ais_json.i .."
+else:gpsdhcreate.commands = cat ../gpsd.h-head ../gpsd_config.h ../gpsd.h-tail > ../gpsd.h
+gpsdhcreate.depends = FORCE
+
+PRE_TARGETDEPS += gpsutils.cpp libgps_core.cpp gpsd.h
+QMAKE_EXTRA_TARGETS += gpsutilscpp libgps_corecpp gpsdhcreate
+
diff --git a/libQgpsmm_global.h b/libQgpsmm_global.h
new file mode 100644
index 00000000..450db5a9
--- /dev/null
+++ b/libQgpsmm_global.h
@@ -0,0 +1,12 @@
+#ifndef LIBQGPSMM_GLOBAL_H
+#define LIBQGPSMM_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+#if defined(LIBQGPSMM_LIBRARY)
+# define LIBQGPSMMSHARED_EXPORT Q_DECL_EXPORT
+#else
+# define LIBQGPSMMSHARED_EXPORT Q_DECL_IMPORT
+#endif
+
+#endif // LIBQGPSMM_GLOBAL_H
diff --git a/libgps_core.c b/libgps_core.c
index 8f40ba1b..98128781 100644
--- a/libgps_core.c
+++ b/libgps_core.c
@@ -21,6 +21,7 @@
#include "gpsd.h"
#include "gps_json.h"
+#ifndef USE_QT
#ifndef S_SPLINT_S
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
@@ -31,6 +32,9 @@
#if defined (HAVE_SYS_SELECT_H)
#include <sys/select.h>
#endif
+#else
+#include <QTcpSocket>
+#endif /* USE_QT */
#ifdef S_SPLINT_S
extern char *strtok_r(char *, const char *, char **);
@@ -57,7 +61,9 @@ void gps_enable_debug(int level, FILE *fp)
{
debuglevel = level;
debugfp = fp;
+#ifdef CLIENTDEBUG_ENABLE
json_enable_debug(level-2, fp);
+#endif
}
static void gps_trace(int errlevel, const char *fmt, ... )
@@ -95,10 +101,20 @@ int gps_open_r(const char *host, const char *port,
libgps_debug_trace((1, "gps_open_r(%s, %s)\n", host, port));
+#ifndef USE_QT
if ((gpsdata->gps_fd = netlib_connectsock(AF_UNSPEC, host, port, "tcp")) < 0) {
errno = gpsdata->gps_fd;
return -1;
}
+#else
+ QTcpSocket* sock = new QTcpSocket();
+ gpsdata->gps_fd = sock;
+ sock->connectToHost(host, QString(port).toInt());
+ if (!sock->waitForConnected())
+ qDebug() << "libgps::connect error: " << sock->errorString();
+ else
+ qDebug() << "libgps::connected!";
+#endif
gpsdata->set = 0;
gpsdata->status = STATUS_NO_FIX;
@@ -133,8 +149,15 @@ int gps_close(struct gps_data_t *gpsdata)
/* close a gpsd connection */
{
libgps_debug_trace((1, "gps_close()\n"));
+#ifndef USE_QT
free(PRIVATE(gpsdata));
gpsdata->gps_fd = -1;
+#else
+ QTcpSocket* sock = (QTcpSocket*)gpsdata->gps_fd;
+ sock->disconnectFromHost();
+ delete sock;
+ gpsdata->gps_fd = NULL;
+#endif
return 0;
}
@@ -153,8 +176,10 @@ static void libgps_dump_state(struct gps_data_t *collect, time_t now)
char *mode_values[] = {"", "NO_FIX", "MODE_2D", "MODE_3D"};
/* FIXME: We don't dump the entire state here yet */
+#ifndef USE_QT
(void)fprintf(debugfp, "flags: (0x%04x) %s\n",
collect->set, gpsd_maskdump(collect->set));
+#endif
if (collect->set & ONLINE_SET)
(void)fprintf(debugfp, "ONLINE: %lf\n", collect->online);
if (collect->set & TIME_SET)
@@ -602,7 +627,9 @@ int gps_unpack(char *buf, struct gps_data_t *gpsdata)
//libgps_debug_trace((stderr, "libgps: raw hook called on '%s'\n", buf));
gpsdata->raw_hook(gpsdata, buf, strlen(buf));
}
+#ifndef USE_QT
libgps_debug_trace((1, "final flags: (0x%04x) %s\n", gpsdata->set, gpsd_maskdump(gpsdata->set)));
+#endif
return 0;
}
/*@ +compdef @*/
@@ -611,6 +638,7 @@ int gps_unpack(char *buf, struct gps_data_t *gpsdata)
bool gps_waiting(struct gps_data_t *gpsdata)
/* is there input waiting from the GPS? */
{
+#ifndef USE_QT
fd_set rfds;
struct timeval tv;
@@ -623,6 +651,9 @@ bool gps_waiting(struct gps_data_t *gpsdata)
tv.tv_sec = 0; tv.tv_usec = 1;
/* all error conditions return "not waiting" -- crude but effective */
return (select(gpsdata->gps_fd+1, &rfds, NULL, NULL, &tv) == 1);
+#else
+ return ((QTcpSocket*)(gpsdata->gps_fd))->waitForReadyRead(250);
+#endif
}
int gps_poll(struct gps_data_t *gpsdata)
@@ -641,11 +672,16 @@ int gps_poll(struct gps_data_t *gpsdata)
eol = NULL;
if (eol == NULL) {
+#ifndef USE_QT
/* read data: return -1 if no data waiting or buffered, 0 otherwise */
status = (int)recv(gpsdata->gps_fd,
priv->buffer + priv->waiting,
sizeof(priv->buffer)-priv->waiting,
0);
+#else
+ status = ((QTcpSocket*)(gpsdata->gps_fd))->read(priv->buffer + priv->waiting, sizeof(priv->buffer)-priv->waiting);
+#endif
+
/* if we just received data from the socket, it's in the buffer */
if (status > -1)
priv->waiting += status;
@@ -657,9 +693,11 @@ int gps_poll(struct gps_data_t *gpsdata)
*/
if (status == 0)
return -1;
+#ifndef USE_QT
/* count transient errors as success, we'll retry later */
else if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
return 0;
+#endif
/* hard error return of -1, pass it along */
else
return -1;
@@ -701,10 +739,21 @@ int gps_send(struct gps_data_t *gpsdata, const char *fmt, ... )
va_end(ap);
if (buf[strlen(buf)-1] != '\n')
(void)strlcat(buf, "\n", BUFSIZ);
+#ifndef USE_QT
if (write(gpsdata->gps_fd, buf, strlen(buf)) == (ssize_t)strlen(buf))
return 0;
else
return -1;
+#else
+ QTcpSocket* sock = (QTcpSocket*)gpsdata->gps_fd;
+ sock->write(buf, strlen(buf));
+ if (sock->waitForBytesWritten())
+ return 0;
+ else {
+ qDebug() << "libgps::send error: " << sock->errorString();
+ return -1;
+ }
+#endif
}
int gps_stream(struct gps_data_t *gpsdata,
@@ -718,8 +767,10 @@ int gps_stream(struct gps_data_t *gpsdata,
flags |= WATCH_JSON;
}
+#ifndef USE_QT
if (flags & POLL_NONBLOCK)
(void)fcntl(gpsdata->gps_fd, F_SETFL, O_NONBLOCK);
+#endif
if ((flags & WATCH_DISABLE) != 0) {
if ((flags & WATCH_OLDSTYLE) != 0) {
(void)strlcpy(buf, "w-", sizeof(buf));
@@ -780,7 +831,11 @@ extern char /*@observer@*/ *gps_errstr(const int err)
* We might add our own error codes in the future, e.g for
* protocol compatibility checks
*/
+#ifndef USE_QT
return netlib_errstr(err);
+#else
+ return "";
+#endif
}
#ifdef TESTMAIN
diff --git a/libgpsmm.h b/libgpsmm.h
index f10b04e9..711e75c8 100644
--- a/libgpsmm.h
+++ b/libgpsmm.h
@@ -11,7 +11,12 @@
#include <sys/types.h>
#include "gps.h" //the C library we are going to wrap
+#ifndef USE_QT
class gpsmm {
+#else
+#include "libQgpsmm_global.h"
+class LIBQGPSMMSHARED_EXPORT gpsmm {
+#endif
public:
gpsmm();
virtual ~gpsmm();