summaryrefslogtreecommitdiff
path: root/src/imports/positioning
diff options
context:
space:
mode:
authorAlbin Olsson <albin.olsson@cybercom.com>2013-08-30 12:56:31 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-03 13:18:53 +0200
commit5611ad387a9ff1f6383773d6108f257a1338e921 (patch)
treec8439056199bebc94f535c8293c072d048c29132 /src/imports/positioning
parentd26ab7e17cebbdf0ad3fe7ea5208dec8ac8dcef8 (diff)
downloadqtlocation-5611ad387a9ff1f6383773d6108f257a1338e921.tar.gz
Implement socket NMEA source.
nmeaSource property of PositionSource is limited to log files. This change adds possibility of using a TCP socket instead. This is a lot more useful when testing because it can be used with a simulator. Change-Id: Ie6fb2b5344aae2702a8cf53d0146780d6ea1e0f9 Reviewed-by: Albin Olsson <albin.olsson@cybercom.com> Reviewed-by: Alex Blasche <alexander.blasche@digia.com>
Diffstat (limited to 'src/imports/positioning')
-rw-r--r--src/imports/positioning/qdeclarativepositionsource.cpp176
-rw-r--r--src/imports/positioning/qdeclarativepositionsource_p.h8
2 files changed, 136 insertions, 48 deletions
diff --git a/src/imports/positioning/qdeclarativepositionsource.cpp b/src/imports/positioning/qdeclarativepositionsource.cpp
index 97ad1bbc..00775010 100644
--- a/src/imports/positioning/qdeclarativepositionsource.cpp
+++ b/src/imports/positioning/qdeclarativepositionsource.cpp
@@ -47,6 +47,7 @@
#include <QtQml/qqml.h>
#include <qnmeapositioninfosource.h>
#include <QFile>
+#include <QTcpSocket>
#include <QTimer>
QT_BEGIN_NAMESPACE
@@ -116,13 +117,15 @@ QT_BEGIN_NAMESPACE
QDeclarativePositionSource::QDeclarativePositionSource()
: m_positionSource(0), m_preferredPositioningMethods(NoPositioningMethod), m_nmeaFile(0),
- m_active(false), m_singleUpdate(false), m_updateInterval(0), m_sourceError(UnknownSourceError)
+ m_nmeaSocket(0), m_active(false), m_singleUpdate(false), m_updateInterval(0),
+ m_sourceError(UnknownSourceError)
{
}
QDeclarativePositionSource::~QDeclarativePositionSource()
{
delete m_nmeaFile;
+ delete m_nmeaSocket;
delete m_positionSource;
}
@@ -218,67 +221,145 @@ bool QDeclarativePositionSource::isValid() const
*/
void QDeclarativePositionSource::setNmeaSource(const QUrl &nmeaSource)
{
- // Strip the filename. This is clumsy but the file may be prefixed in several
- // ways: "file:///", "qrc:///", "/", "" in platform dependant manner.
- QString localFileName = nmeaSource.toString();
- if (!QFile::exists(localFileName)) {
- if (localFileName.startsWith("qrc:///")) {
- localFileName.remove(0, 7);
- } else if (localFileName.startsWith("file:///")) {
- localFileName.remove(0, 7);
+ if (nmeaSource.scheme() == QLatin1String("socket")) {
+ if (m_nmeaSocket
+ && nmeaSource.host() == m_nmeaSocket->peerName()
+ && nmeaSource.port() == m_nmeaSocket->peerPort()) {
+ return;
}
- if (!QFile::exists(localFileName) && localFileName.startsWith("/")) {
- localFileName.remove(0,1);
+
+ delete m_nmeaSocket;
+ m_nmeaSocket = new QTcpSocket();
+
+ connect(m_nmeaSocket, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)> (&QAbstractSocket::error),
+ this, &QDeclarativePositionSource::socketError);
+ connect(m_nmeaSocket, &QTcpSocket::connected,
+ this, &QDeclarativePositionSource::socketConnected);
+
+ m_nmeaSocket->connectToHost(nmeaSource.host(), nmeaSource.port(), QTcpSocket::ReadOnly);
+ } else {
+ // Strip the filename. This is clumsy but the file may be prefixed in several
+ // ways: "file:///", "qrc:///", "/", "" in platform dependent manner.
+ QString localFileName = nmeaSource.toString();
+ if (!QFile::exists(localFileName)) {
+ if (localFileName.startsWith("qrc:///")) {
+ localFileName.remove(0, 7);
+ } else if (localFileName.startsWith("file:///")) {
+ localFileName.remove(0, 7);
+ }
+ if (!QFile::exists(localFileName) && localFileName.startsWith("/")) {
+ localFileName.remove(0,1);
+ }
+ }
+ if (m_nmeaFileName == localFileName)
+ return;
+ m_nmeaFileName = localFileName;
+
+ PositioningMethods previousPositioningMethods = supportedPositioningMethods();
+
+ // The current position source needs to be deleted
+ // because QNmeaPositionInfoSource can be bound only to a one file.
+ delete m_nmeaSocket;
+ m_nmeaSocket = 0;
+ delete m_positionSource;
+ m_positionSource = 0;
+ // Create the NMEA source based on the given data. QML has automatically set QUrl
+ // type to point to correct path. If the file is not found, check if the file actually
+ // was an embedded resource file.
+ delete m_nmeaFile;
+ m_nmeaFile = new QFile(localFileName);
+ if (!m_nmeaFile->exists()) {
+ localFileName.prepend(":");
+ m_nmeaFile->setFileName(localFileName);
+ }
+ if (m_nmeaFile->exists()) {
+#ifdef QDECLARATIVE_POSITION_DEBUG
+ qDebug() << "QDeclarativePositionSource NMEA File was found: " << localFileName;
+#endif
+ m_positionSource = new QNmeaPositionInfoSource(QNmeaPositionInfoSource::SimulationMode);
+ (qobject_cast<QNmeaPositionInfoSource *>(m_positionSource))->setDevice(m_nmeaFile);
+ connect(m_positionSource, SIGNAL(positionUpdated(QGeoPositionInfo)),
+ this, SLOT(positionUpdateReceived(QGeoPositionInfo)));
+ if (m_active && !m_singleUpdate) {
+ // Keep on updating even though source changed
+ QTimer::singleShot(0, this, SLOT(start()));
+ }
+ } else {
+ qmlInfo(this) << QCoreApplication::translate(CONTEXT_NAME, MISSED_NMEA_FILE) << localFileName;
+#ifdef QDECLARATIVE_POSITION_DEBUG
+ qDebug() << "QDeclarativePositionSource NMEA File was not found: " << localFileName;
+#endif
+ if (m_active) {
+ m_active = false;
+ m_singleUpdate = false;
+ emit activeChanged();
+ }
}
+
+ if (previousPositioningMethods != supportedPositioningMethods())
+ emit supportedPositioningMethodsChanged();
}
- if (m_nmeaFileName == localFileName)
- return;
- m_nmeaFileName = localFileName;
+
m_nmeaSource = nmeaSource;
+ emit nmeaSourceChanged();
+}
+/*!
+ \internal
+*/
+void QDeclarativePositionSource::socketConnected()
+{
+#ifdef QDECLARATIVE_POSITION_DEBUG
+ qDebug() << "Socket connected: " << m_nmeaSocket->peerName();
+#endif
PositioningMethods previousPositioningMethods = supportedPositioningMethods();
// The current position source needs to be deleted
// because QNmeaPositionInfoSource can be bound only to a one file.
- delete m_positionSource;
- m_positionSource = 0;
- // Create the NMEA source based on the given data. QML has automatically set QUrl
- // type to point to correct path. If the file is not found, check if the file actually
- // was an embedded resource file.
delete m_nmeaFile;
- m_nmeaFile = new QFile(localFileName);
- if (!m_nmeaFile->exists()) {
- localFileName.prepend(":");
- m_nmeaFile->setFileName(localFileName);
- }
- if (m_nmeaFile->exists()) {
-#ifdef QDECLARATIVE_POSITION_DEBUG
- qDebug() << "QDeclarativePositionSource NMEA File was found: " << localFileName;
-#endif
- m_positionSource = new QNmeaPositionInfoSource(QNmeaPositionInfoSource::SimulationMode);
- (qobject_cast<QNmeaPositionInfoSource *>(m_positionSource))->setDevice(m_nmeaFile);
- connect(m_positionSource, SIGNAL(positionUpdated(QGeoPositionInfo)),
- this, SLOT(positionUpdateReceived(QGeoPositionInfo)));
- if (m_active && !m_singleUpdate) {
- // Keep on updating even though source changed
- QTimer::singleShot(0, this, SLOT(start()));
- }
- } else {
- qmlInfo(this) << QCoreApplication::translate(CONTEXT_NAME, MISSED_NMEA_FILE) << localFileName;
-#ifdef QDECLARATIVE_POSITION_DEBUG
- qDebug() << "QDeclarativePositionSource NMEA File was not found: " << localFileName;
-#endif
- if (m_active) {
- m_active = false;
- m_singleUpdate = false;
- emit activeChanged();
- }
+ m_nmeaFile = 0;
+ delete m_positionSource;
+
+ m_positionSource = new QNmeaPositionInfoSource(QNmeaPositionInfoSource::RealTimeMode);
+ (qobject_cast<QNmeaPositionInfoSource *>(m_positionSource))->setDevice(m_nmeaSocket);
+
+ connect(m_positionSource, &QNmeaPositionInfoSource::positionUpdated,
+ this, &QDeclarativePositionSource::positionUpdateReceived);
+
+ if (m_active && !m_singleUpdate) {
+ // Keep on updating even though source changed
+ QTimer::singleShot(0, this, SLOT(start()));
}
if (previousPositioningMethods != supportedPositioningMethods())
emit supportedPositioningMethodsChanged();
+}
- emit nmeaSourceChanged();
+/*!
+ \internal
+*/
+void QDeclarativePositionSource::socketError(QAbstractSocket::SocketError error)
+{
+ delete m_nmeaSocket;
+ m_nmeaSocket = 0;
+
+ switch (error) {
+ case QAbstractSocket::UnknownSocketError:
+ m_sourceError = QDeclarativePositionSource::UnknownSourceError;
+ break;
+ case QAbstractSocket::SocketAccessError:
+ m_sourceError = QDeclarativePositionSource::AccessError;
+ break;
+ case QAbstractSocket::RemoteHostClosedError:
+ m_sourceError = QDeclarativePositionSource::ClosedError;
+ break;
+ default:
+ qWarning() << "Connection failed! QAbstractSocket::SocketError" << error;
+ m_sourceError = QDeclarativePositionSource::SocketError;
+ break;
+ }
+
+ emit sourceErrorChanged();
}
/*!
@@ -578,6 +659,7 @@ void QDeclarativePositionSource::positionUpdateReceived(const QGeoPositionInfo &
the user is switching location services to off. This object becomes invalid and should be deleted.
A new source can be declared later on to check whether the positioning backend is up again.
\li PositionSource.UnknownSourceError - An unidentified error occurred.
+ \li PositionSource.SocketError - An error occurred while connecting to an nmea source using a socket.
\endlist
*/
diff --git a/src/imports/positioning/qdeclarativepositionsource_p.h b/src/imports/positioning/qdeclarativepositionsource_p.h
index 70506c00..fc720301 100644
--- a/src/imports/positioning/qdeclarativepositionsource_p.h
+++ b/src/imports/positioning/qdeclarativepositionsource_p.h
@@ -45,12 +45,14 @@
#include "qdeclarativeposition_p.h"
#include <QtCore/QObject>
+#include <QtNetwork/QAbstractSocket>
#include <QtQml/QQmlParserStatus>
#include <QtPositioning/QGeoPositionInfoSource>
QT_BEGIN_NAMESPACE
class QFile;
+class QTcpSocket;
class QDeclarativePositionSource : public QObject, public QQmlParserStatus
{
@@ -83,7 +85,8 @@ public:
enum SourceError {
AccessError = QGeoPositionInfoSource::AccessError,
ClosedError = QGeoPositionInfoSource::ClosedError,
- UnknownSourceError = QGeoPositionInfoSource::UnknownSourceError
+ UnknownSourceError = QGeoPositionInfoSource::UnknownSourceError,
+ SocketError
};
Q_ENUMS(SourceError)
@@ -130,11 +133,14 @@ Q_SIGNALS:
private Q_SLOTS:
void positionUpdateReceived(const QGeoPositionInfo &update);
void sourceErrorReceived(const QGeoPositionInfoSource::Error error);
+ void socketConnected();
+ void socketError(QAbstractSocket::SocketError error);
private:
QGeoPositionInfoSource *m_positionSource;
QDeclarativePosition m_position;
PositioningMethods m_preferredPositioningMethods;
QFile *m_nmeaFile;
+ QTcpSocket *m_nmeaSocket;
QString m_nmeaFileName;
QUrl m_nmeaSource;
bool m_active;