summaryrefslogtreecommitdiff
path: root/src/location
diff options
context:
space:
mode:
Diffstat (limited to 'src/location')
-rw-r--r--src/location/location.pro11
-rw-r--r--src/location/qgeopositioninfosource.cpp8
-rw-r--r--src/location/qgeopositioninfosource_npe_backend.cpp334
-rw-r--r--src/location/qgeopositioninfosource_npe_backend_p.h105
4 files changed, 458 insertions, 0 deletions
diff --git a/src/location/location.pro b/src/location/location.pro
index 2012769d..df4b9937 100644
--- a/src/location/location.pro
+++ b/src/location/location.pro
@@ -122,6 +122,17 @@ meego {
}
}
+contains(config_test_jsondb, yes): contains(config_test_mtcore, yes) {
+ DEFINES += NPE_BACKEND
+ QT += jsondb-private
+ SOURCES += qgeopositioninfosource_npe_backend.cpp
+ PRIVATE_HEADERS += qgeopositioninfosource_npe_backend_p.h
+ unix{
+ CONFIG += link_pkgconfig
+ PKGCONFIG += mtcore
+ }
+}
+
HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS
SOURCES += \
diff --git a/src/location/qgeopositioninfosource.cpp b/src/location/qgeopositioninfosource.cpp
index e159085d..29517c81 100644
--- a/src/location/qgeopositioninfosource.cpp
+++ b/src/location/qgeopositioninfosource.cpp
@@ -57,6 +57,8 @@
# include "qgeopositioninfosource_maemo_p.h"
#elif defined(Q_WS_MAEMO_5)
# include "qgeopositioninfosource_maemo5_p.h"
+#elif defined (NPE_BACKEND)
+# include "qgeopositioninfosource_npe_backend_p.h"
#endif
#if defined (Q_WS_MEEGO)
@@ -421,6 +423,12 @@ QGeoPositionInfoSource *QGeoPositionInfoSource::createDefaultSource(QObject *par
return geoclueSource;
delete geoclueSource;
#endif // GEOCLUE_MASTER_AVAILABLE
+#elif defined(NPE_BACKEND)
+ QGeoPositionInfoSourceNpeBackend* npeBackendSource = new QGeoPositionInfoSourceNpeBackend(parent);
+ if (npeBackendSource->init())
+ return npeBackendSource;
+ else
+ delete npeBackendSource;
#endif
// no good platform source, try plugins
foreach (QGeoPositionInfoSourceFactory *f, QGeoPositionInfoSourcePrivate::pluginsSorted()) {
diff --git a/src/location/qgeopositioninfosource_npe_backend.cpp b/src/location/qgeopositioninfosource_npe_backend.cpp
new file mode 100644
index 00000000..a052ff26
--- /dev/null
+++ b/src/location/qgeopositioninfosource_npe_backend.cpp
@@ -0,0 +1,334 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgeopositioninfosource_npe_backend_p.h"
+#include <QtDebug>
+#include <sys/stat.h>
+
+
+// API for socket communication towards nld
+const QString kstartUpdates = QLatin1String("startUpdates");
+const QString krequestUpdate = QLatin1String("requestUpdate");
+const QString kstopUpdates = QLatin1String("stopUpdates");
+const QString ksetUpdateInterval = QLatin1String("setUpdateInterval");
+const QString ksetPreferredMethod = QLatin1String("setPreferredMethod");
+const QString kgetMinimumUpdateInterval = QLatin1String("getMinimumUpdateInterval"); // Request
+const QString kgetMinimumUpdateIntervalReply = QLatin1String("getMinimumUpdateIntervalReply"); // Response
+const QString kgetSupportedMethods = QLatin1String("getSupportedMethods");
+const QString kgetSupportedMethodsReply = QLatin1String("getSupportedMethodsReply");
+const QString kgetLastKnownPosition = QLatin1String("getLastKnownPosition");
+const QString kgetLastKnownPositionReply = QLatin1String("getLastKnownPositionReply");
+const QString kpositionUpdate = QLatin1String("positionUpdate"); // Notification
+const QString ksatelliteInfoUpdate = QLatin1String("satelliteInfoUpdate"); // Notification
+const QString knmeaUpdate = QLatin1String("nmeaUpdate"); // Notification
+
+// Attributes for socket communication towards nld
+const QString kinterval = QLatin1String("interval");
+const QString ksatelliteOnly = QLatin1String("satelliteOnly");
+const QString klatitude = QLatin1String("latitude");
+const QString klongitude = QLatin1String("longitude");
+const QString khorizontalAccuracy = QLatin1String("horizontalAccuracy");
+const QString kaltitude = QLatin1String("altitude");
+const QString kverticalAccuracy = QLatin1String("verticalAccuracy");
+const QString kgroundSpeed = QLatin1String("groundSpeed");
+const QString kverticalSpeed = QLatin1String("verticalSpeed");
+const QString kbearing = QLatin1String("bearing");
+const QString kmagneticVariation = QLatin1String("magneticVariation");
+const QString ktimestamp = QLatin1String("timestamp");
+const QString kmethod = QLatin1String("method");
+const QString kvalid = QLatin1String("valid");
+
+
+
+QGeoPositionInfoSourceNpeBackend::QGeoPositionInfoSourceNpeBackend(QObject *parent): QGeoPositionInfoSource(parent)
+{
+ requestTimer = new QTimer(this);
+ QObject::connect(requestTimer, SIGNAL(timeout()), this, SLOT(requestTimerExpired()));
+ locationOngoing = false;
+}
+
+
+bool QGeoPositionInfoSourceNpeBackend::init()
+{
+ struct stat buf;
+ if (stat("/var/run/nld/nld.socket", &buf) == 0) {
+ mSocket = new QLocalSocket(this);
+ if (mSocket) {
+ connect(mSocket, SIGNAL(connected()), this, SLOT(onSocketConnected()));
+ connect(mSocket, SIGNAL(disconnected()), this, SLOT(onSocketDisconnected()));
+ mStream = new VariantStream(mSocket);
+ if (mStream) {
+ connect(mStream, SIGNAL(receive(const QVariantMap&)), this, SLOT(onStreamReceived(const QVariantMap&)), Qt::QueuedConnection);
+ }
+ mSocket->connectToServer("/var/run/nld/nld.socket");
+ return(mSocket->waitForConnected(500)); // wait up to 0.5 seconds to get connected, otherwise return false
+ }
+ }
+ else
+ qDebug() << "stat fails for nld.socket";
+ return(false);
+}
+
+
+QGeoPositionInfo QGeoPositionInfoSourceNpeBackend::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const
+{
+ // todo: test failed as nld does not respond yet; QEventloop forever....
+ QEventLoop loop; // loop to wait for response from nld (asynchronous socket connection)
+ connect( this, SIGNAL(lastKnownPositionReceived()), &loop, SLOT(quit()));
+ QVariantMap action;
+ QVariantMap object;
+ action.insert(JsonDbString::kActionStr, kgetLastKnownPosition);
+ object.insert(ksatelliteOnly, fromSatellitePositioningMethodsOnly);
+ action.insert(JsonDbString::kDataStr, object);
+ mStream->send(action);
+ loop.exec(); // wait for signal lastKnownPositionReceived()sent by slot onStreamReceived
+ return(lastPosition);
+}
+
+
+QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSourceNpeBackend::supportedPositioningMethods() const
+{
+ QEventLoop loop; // loop to wait for response from nld (asynchronous socket connection)
+ connect( this, SIGNAL(supportedPositioningMethodsReceived()), &loop, SLOT(quit()));
+ QVariantMap action;
+ action.insert(JsonDbString::kActionStr, kgetSupportedMethods);
+ mStream->send(action);
+ loop.exec(); // wait for supportedPositioningMethodsReceived() signal sent by slot onStreamReceived
+ switch (supportedMethods){
+ case QGeoPositionInfoSource::SatellitePositioningMethods:
+ return(QGeoPositionInfoSource::SatellitePositioningMethods);
+ case QGeoPositionInfoSource::NonSatellitePositioningMethods:
+ return(NonSatellitePositioningMethods);
+ case QGeoPositionInfoSource::AllPositioningMethods:
+ return(QGeoPositionInfoSource::AllPositioningMethods);
+ default:
+ qDebug() << "unsupported Method received from nld";
+ }
+}
+
+
+void QGeoPositionInfoSourceNpeBackend::setUpdateInterval(int msec)
+{
+ QVariantMap action;
+ QEventLoop loop; // loop to wait for response from nld (asynchronous socket connection)
+ connect( this, SIGNAL(minimumUpdateIntervalReceived()), &loop, SLOT(quit()));
+ action.insert(JsonDbString::kActionStr, kgetMinimumUpdateInterval);
+ mStream->send(action);
+ loop.exec(); // wait for minimumUpdateIntervalReceived() signal sent by slot onStreamReceived
+ if (msec < minInterval)
+ msec = minInterval;
+ QVariantMap actionUpdate;
+ QVariantMap object;
+ actionUpdate.insert(JsonDbString::kActionStr, ksetUpdateInterval);
+ object.insert(kinterval, msec);
+ actionUpdate.insert(JsonDbString::kDataStr, object);
+ mStream->send(actionUpdate);
+ QGeoPositionInfoSource::setUpdateInterval(msec);
+}
+
+
+void QGeoPositionInfoSourceNpeBackend::setPreferredPositioningMethods(PositioningMethods sources)
+{
+ QGeoPositionInfoSource::setPreferredPositioningMethods(sources);
+ QVariantMap action;
+ QVariantMap object;
+ action.insert(JsonDbString::kActionStr, ksetPreferredMethod);
+ object.insert(kmethod, (uint)sources);
+ action.insert(JsonDbString::kDataStr, object);
+ mStream->send(action);
+}
+
+
+int QGeoPositionInfoSourceNpeBackend::minimumUpdateInterval() const
+{
+ QVariantMap action;
+ QEventLoop loop; // loop to wait for response from nld (asynchronous socket connection)
+ connect( this, SIGNAL(minimumUpdateIntervalReceived()), &loop, SLOT(quit()));
+ action.insert(JsonDbString::kActionStr, kgetMinimumUpdateInterval);
+ mStream->send(action);
+ loop.exec(); // wait for minimumUpdateIntervalReceived() signal sent by slot onStreamReceived
+ return(minInterval);
+}
+
+
+void QGeoPositionInfoSourceNpeBackend::startUpdates()
+{
+ locationOngoing = true;
+ QVariantMap action;
+ action.insert(JsonDbString::kActionStr, kstartUpdates);
+ mStream->send(action);
+}
+
+
+void QGeoPositionInfoSourceNpeBackend::stopUpdates()
+{
+ if ( !requestTimer->isActive() ) {
+ locationOngoing = false;
+ QVariantMap action;
+ action.insert(JsonDbString::kActionStr, kstopUpdates);
+ mStream->send(action);
+ }
+}
+
+
+void QGeoPositionInfoSourceNpeBackend::requestUpdate(int timeout)
+{
+ int minimumInterval = minimumUpdateInterval();
+ // set reasonable timeout for the source if timeout is 0
+ if (timeout == 0)
+ timeout = 5*minimumInterval;
+ // do not start request if timeout can not be fullfilled by the source
+ if (timeout < minimumInterval) {
+ emit updateTimeout();
+ return;
+ }
+ // get position as accurate and fast as possible
+ if ( QGeoPositionInfoSource::updateInterval() != minimumInterval) {
+ QVariantMap actionUpdate;
+ QVariantMap object;
+ actionUpdate.insert(JsonDbString::kActionStr, ksetUpdateInterval);
+ object.insert(kinterval, minimumInterval);
+ actionUpdate.insert(JsonDbString::kDataStr, object);
+ mStream->send(actionUpdate);
+ }
+ if ( !QGeoPositionInfoSource::preferredPositioningMethods().testFlag(QGeoPositionInfoSource::AllPositioningMethods) )
+ setPreferredPositioningMethods(QGeoPositionInfoSource::AllPositioningMethods);
+ // request the update only if no other regular session request is ongoing
+ if ( !locationOngoing ) {
+ QVariantMap action;
+ action.insert(JsonDbString::kActionStr, krequestUpdate);
+ mStream->send(action);
+ }
+ requestTimer->start(timeout);
+}
+
+
+void QGeoPositionInfoSourceNpeBackend::requestTimerExpired()
+{
+ emit updateTimeout();
+ shutdownRequestSession();
+}
+
+
+
+void QGeoPositionInfoSourceNpeBackend::shutdownRequestSession()
+{
+ requestTimer->stop();
+ // Restore updateInterval and preferedPositioningMethods from before Request Session
+ int minimumInterval = minimumUpdateInterval();
+ if ( QGeoPositionInfoSource::updateInterval() != minimumInterval)
+ setUpdateInterval(QGeoPositionInfoSource::updateInterval());
+ if ( !QGeoPositionInfoSource::preferredPositioningMethods().testFlag(QGeoPositionInfoSource::AllPositioningMethods) )
+ setPreferredPositioningMethods(QGeoPositionInfoSource::preferredPositioningMethods());
+}
+
+
+void QGeoPositionInfoSourceNpeBackend::onStreamReceived(const QVariantMap& map)
+{
+ // this slot handles the communication received from nld socket
+ if (map.contains(JsonDbString::kActionStr)) {
+ QString action = map.value(JsonDbString::kActionStr).toString();
+
+ if (action == kgetMinimumUpdateIntervalReply) {
+ QVariantMap tmp = map.value(JsonDbString::kDataStr).toMap();
+ minInterval = tmp.value(kinterval).toInt();
+ emit minimumUpdateIntervalReceived();
+ }
+
+ else if (action == kgetSupportedMethodsReply) {
+ QVariantMap tmp = map.value(JsonDbString::kDataStr).toMap();
+ supportedMethods = tmp.value(kmethod).toUInt();
+ emit supportedPositioningMethodsReceived();
+ }
+
+ else if (action == kgetLastKnownPositionReply) {
+ QVariantMap tmp = map.value(JsonDbString::kDataStr).toMap();
+ bool valid = tmp.value(kvalid).toBool();
+ if (valid) {
+ QGeoCoordinate coordinate;
+ coordinate.setLatitude(tmp.value(klatitude).toDouble());
+ coordinate.setLongitude(tmp.value(klongitude).toDouble());
+ lastPosition.setCoordinate(coordinate);
+ lastPosition.setTimestamp(tmp.value(ktimestamp).toDateTime());
+ emit lastKnownPositionReceived();
+ }
+ else
+ qDebug() << "invalid lastKnownPosition received from nld";
+ }
+
+ else if (action == kpositionUpdate) {
+ QVariantMap tmp = map.value(JsonDbString::kDataStr).toMap();
+ QGeoPositionInfo update;
+ QGeoCoordinate coordinate;
+ coordinate.setLatitude(tmp.value(klatitude).toDouble());
+ coordinate.setLongitude(tmp.value(klongitude).toDouble());
+ coordinate.setAltitude(tmp.value(kaltitude).toDouble());
+ if (coordinate.isValid()) {
+ update.setCoordinate(coordinate);
+ update.setAttribute(QGeoPositionInfo::HorizontalAccuracy, tmp.value(khorizontalAccuracy).toReal());
+ update.setAttribute(QGeoPositionInfo::VerticalAccuracy, tmp.value(kverticalAccuracy).toReal());
+ update.setAttribute(QGeoPositionInfo::GroundSpeed, tmp.value(kgroundSpeed).toReal());
+ update.setAttribute(QGeoPositionInfo::VerticalSpeed, tmp.value(kverticalSpeed).toReal());
+ update.setAttribute(QGeoPositionInfo::MagneticVariation, tmp.value(kmagneticVariation).toReal());
+ update.setAttribute(QGeoPositionInfo::Direction, tmp.value(kbearing).toReal());
+ QDateTime timestamp = tmp.value(ktimestamp).toDateTime();
+ update.setTimestamp(timestamp);
+ emit positionUpdated(update);
+ if ( requestTimer->isActive() )
+ shutdownRequestSession();
+ } else {
+ qDebug() << "invalid position received from nld";
+ }
+ }
+ }
+}
+
+
+void QGeoPositionInfoSourceNpeBackend::onSocketConnected()
+{
+ qDebug("Socket Connected!");
+}
+
+
+void QGeoPositionInfoSourceNpeBackend::onSocketDisconnected()
+{
+ qDebug("Socket Disconnected!");
+}
diff --git a/src/location/qgeopositioninfosource_npe_backend_p.h b/src/location/qgeopositioninfosource_npe_backend_p.h
new file mode 100644
index 00000000..ff518796
--- /dev/null
+++ b/src/location/qgeopositioninfosource_npe_backend_p.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGEOPOSITIONINFOSOURCE_NPE_BACKEND_H
+#define QGEOPOSITIONINFOSOURCE_NPE_BACKEND_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qgeopositioninfosource.h>
+#include <mtcore/variantstream.h>
+#include <private/jsondb-strings_p.h>
+#include <qlocalsocket.h>
+#include <qeventloop.h>
+#include <qtimer.h>
+
+Q_USE_JSONDB_NAMESPACE
+
+class QGeoPositionInfoSourceNpeBackend : public QGeoPositionInfoSource
+{
+ Q_OBJECT
+
+public:
+ QGeoPositionInfoSourceNpeBackend(QObject *parent = 0);
+ bool init();
+ void setUpdateInterval(int interval);
+ void setPreferredPositioningMethods(PositioningMethods sources);
+ QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const;
+ PositioningMethods supportedPositioningMethods() const;
+ int minimumUpdateInterval() const;
+
+public Q_SLOTS:
+ void startUpdates();
+ void stopUpdates();
+ void requestUpdate(int timeout = 5000);
+
+private:
+ QLocalSocket* mSocket;
+ VariantStream* mStream;
+ int minInterval;
+ uint supportedMethods;
+ QGeoPositionInfo lastPosition;
+ bool locationOngoing;
+ QTimer* requestTimer;
+ void shutdownRequestSession();
+
+Q_SIGNALS:
+ void minimumUpdateIntervalReceived();
+ void supportedPositioningMethodsReceived();
+ void lastKnownPositionReceived();
+
+private Q_SLOTS:
+ void onStreamReceived(const QVariantMap& map);
+ void onSocketConnected();
+ void onSocketDisconnected();
+ void requestTimerExpired();
+};
+
+#endif // QGEOPOSITIONINFOSOURCE_NPE_BACKEND_H