diff options
author | Chris Browet <cbro@semperpax.com> | 2010-03-31 04:35:58 -0400 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2010-03-31 04:35:58 -0400 |
commit | d8462cfb9ef84e1b0fbd7c794993318d56bd6dfc (patch) | |
tree | 4ef0f2990e1d5e63d89c8361a57e7231252153df | |
parent | 3202783122582a67b82ff40507550a17dffebb74 (diff) | |
download | gpsd-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.ac | 12 | ||||
-rw-r--r-- | gps.h | 8 | ||||
-rw-r--r-- | gps_json.h | 6 | ||||
-rw-r--r-- | gpsd.h-tail | 6 | ||||
-rw-r--r-- | gpsutils.c | 20 | ||||
-rw-r--r-- | json.h | 6 | ||||
-rw-r--r-- | libQgpsmm.pro | 64 | ||||
-rw-r--r-- | libQgpsmm_global.h | 12 | ||||
-rw-r--r-- | libgps_core.c | 55 | ||||
-rw-r--r-- | libgpsmm.h | 5 |
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]) @@ -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) */ @@ -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; @@ -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) { @@ -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 @@ -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(); |