diff options
Diffstat (limited to 'src/plugins/position')
4 files changed, 720 insertions, 5 deletions
diff --git a/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp b/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp index bebf7230..d56f1d46 100644 --- a/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp +++ b/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp @@ -45,6 +45,7 @@ #include <QSet> #include "qiopipe_p.h" #include <QSharedPointer> +#include "qnmeasatelliteinfosource_p.h" Q_LOGGING_CATEGORY(lcSerial, "qt.positioning.serialnmea") @@ -172,6 +173,67 @@ NmeaSource::~NmeaSource() deviceContainer->releaseSerial(m_portName, m_port); } + + +class NmeaSatelliteSource : public QNmeaSatelliteInfoSource +{ +public: + NmeaSatelliteSource(QObject *parent, const QVariantMap ¶meters) + : QNmeaSatelliteInfoSource(parent) + { + QByteArray requestedPort; + if (parameters.contains(QStringLiteral("serialnmea.serial_port"))) + requestedPort = parameters.value(QStringLiteral("serialnmea.serial_port")).toString().toLatin1(); + else + requestedPort = qgetenv("QT_NMEA_SERIAL_PORT"); + QString portName; + if (requestedPort.isEmpty()) { + const QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts(); + qCDebug(lcSerial) << "Found" << ports.count() << "serial ports"; + if (ports.isEmpty()) { + qWarning("serialnmea: No serial ports found"); + return; + } + + // Try to find a well-known device. + QSet<int> supportedDevices; + supportedDevices << 0x67b; // GlobalSat (BU-353S4 and probably others) + supportedDevices << 0xe8d; // Qstarz MTK II + foreach (const QSerialPortInfo& port, ports) { + if (port.hasVendorIdentifier() && supportedDevices.contains(port.vendorIdentifier())) { + portName = port.portName(); + break; + } + } + + if (portName.isEmpty()) { + qWarning("serialnmea: No known GPS device found. Specify the COM port via QT_NMEA_SERIAL_PORT."); + return; + } + m_portName = portName; + } else { + m_portName = QString::fromUtf8(requestedPort); + } + + m_port = deviceContainer->serial(m_portName); + if (!m_port) + return; + + setDevice(m_port.data()); + } + + ~NmeaSatelliteSource() + { + deviceContainer->releaseSerial(m_portName, m_port); + } + + bool isValid() const { return !m_port.isNull(); } + +private: + QSharedPointer<QIOPipe> m_port; + QString m_portName; +}; + QGeoPositionInfoSource *QGeoPositionInfoSourceFactorySerialNmea::positionInfoSource(QObject *parent) { return positionInfoSourceWithParameters(parent, QVariantMap()); @@ -195,9 +257,8 @@ QGeoPositionInfoSource *QGeoPositionInfoSourceFactorySerialNmea::positionInfoSou QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactorySerialNmea::satelliteInfoSourceWithParameters(QObject *parent, const QVariantMap ¶meters) { - Q_UNUSED(parent); - Q_UNUSED(parameters) - return nullptr; + QScopedPointer<NmeaSatelliteSource> src(new NmeaSatelliteSource(parent, parameters)); + return src->isValid() ? src.take() : nullptr; } QGeoAreaMonitorSource *QGeoPositionInfoSourceFactorySerialNmea::areaMonitorWithParameters(QObject *parent, const QVariantMap ¶meters) diff --git a/src/plugins/position/serialnmea/qnmeasatelliteinfosource.cpp b/src/plugins/position/serialnmea/qnmeasatelliteinfosource.cpp new file mode 100644 index 00000000..d31106fc --- /dev/null +++ b/src/plugins/position/serialnmea/qnmeasatelliteinfosource.cpp @@ -0,0 +1,558 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtPositioning module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnmeasatelliteinfosource_p.h" +#include <QtPositioning/private/qgeosatelliteinfo_p.h> +#include <QtPositioning/private/qgeosatelliteinfosource_p.h> +#include <QtPositioning/private/qlocationutils_p.h> + +#include <QIODevice> +#include <QBasicTimer> +#include <QTimerEvent> +#include <QTimer> +#include <array> +#include <QDebug> +#include <QtCore/QtNumeric> + + +//QT_BEGIN_NAMESPACE + +#define USE_NMEA_PIMPL 1 + +#if USE_NMEA_PIMPL +class QGeoSatelliteInfoPrivateNmea : public QGeoSatelliteInfoPrivate +{ +public: + QGeoSatelliteInfoPrivateNmea(const QGeoSatelliteInfoPrivate &other); + QGeoSatelliteInfoPrivateNmea(const QGeoSatelliteInfoPrivateNmea &other); + virtual ~QGeoSatelliteInfoPrivateNmea(); + virtual QGeoSatelliteInfoPrivate *clone() const; + + QList<QByteArray> nmeaSentences; +}; + +QGeoSatelliteInfoPrivateNmea::QGeoSatelliteInfoPrivateNmea(const QGeoSatelliteInfoPrivate &other) +: QGeoSatelliteInfoPrivate(other) +{ +} + +QGeoSatelliteInfoPrivateNmea::QGeoSatelliteInfoPrivateNmea(const QGeoSatelliteInfoPrivateNmea &other) +: QGeoSatelliteInfoPrivate(other) +{ + nmeaSentences = other.nmeaSentences; +} + +QGeoSatelliteInfoPrivateNmea::~QGeoSatelliteInfoPrivateNmea() {} + +QGeoSatelliteInfoPrivate *QGeoSatelliteInfoPrivateNmea::clone() const +{ + return new QGeoSatelliteInfoPrivateNmea(*this); +} +#else +typedef QGeoSatelliteInfoPrivate QGeoSatelliteInfoPrivateNmea; +#endif + +class QNmeaSatelliteInfoSourcePrivate : public QObject, public QGeoSatelliteInfoSourcePrivate +{ + Q_OBJECT +public: + QNmeaSatelliteInfoSourcePrivate(QNmeaSatelliteInfoSource *parent); + ~QNmeaSatelliteInfoSourcePrivate(); + + void startUpdates(); + void stopUpdates(); + void requestUpdate(int msec); + void notifyNewUpdate(); + +public slots: + void readyRead(); + void emitPendingUpdate(); + void sourceDataClosed(); + void updateRequestTimeout(); + + +public: + QGeoSatelliteInfoSource *m_source = nullptr; + QGeoSatelliteInfoSource::Error m_satelliteError = QGeoSatelliteInfoSource::NoError; + QPointer<QIODevice> m_device; + struct Update { + QList<QGeoSatelliteInfo> m_satellitesInView; + QList<QGeoSatelliteInfo> m_satellitesInUse; + QList<int> m_inUse; // temp buffer for GSA received before GSV + bool m_validInView = false; + bool m_validInUse = false; + bool m_fresh = false; + bool m_updatingGsv = false; +#if USE_NMEA_PIMPL + QByteArray gsa; + QList<QByteArray> gsv; +#endif + void setSatellitesInView(const QList<QGeoSatelliteInfo> &inView) + { + m_updatingGsv = false; + m_satellitesInView = inView; + m_validInView = m_fresh = true; + if (m_inUse.size()) { + m_satellitesInUse.clear(); + m_validInUse = false; + bool corrupt = false; + for (const auto i: m_inUse) { + bool found = false; + for (const auto &s: m_satellitesInView) { + if (s.satelliteIdentifier() == i) { + m_satellitesInUse.append(s); + found = true; + } + } + if (!found) { // received a GSA before a GSV, but it was incorrect or something. Unrelated to this GSV at least. + m_satellitesInUse.clear(); + corrupt = true; + break; + } + } + m_validInUse = !corrupt; + m_inUse.clear(); + } + } + +// void setSatellitesInUse(const QList<QGeoSatelliteInfo> &inUse) +// { +// m_satellitesInUse = inUse; +// m_validInUse = true; +// m_inUse.clear(); +// } + + bool setSatellitesInUse(const QList<int> &inUse) + { + m_satellitesInUse.clear(); + m_validInUse = false; + m_inUse = inUse; + if (m_updatingGsv) { + m_satellitesInUse.clear(); + m_validInView = false; + return false; + } + for (const auto i: inUse) { + bool found = false; + for (const auto &s: m_satellitesInView) { + if (s.satelliteIdentifier() == i) { + m_satellitesInUse.append(s); + found = true; + } + } + if (!found) { // if satellites in use aren't in view, the related GSV is still to be received. + m_inUse = inUse; // So clear outdated data, buffer the info, and set it later. + m_satellitesInUse.clear(); + m_satellitesInView.clear(); + m_validInView = false; + return false; + } + } + m_validInUse = m_fresh = true; + return true; + } + + void consume() + { + m_fresh = false; + } + + bool isFresh() + { + return m_fresh; + } + + QSet<int> inUse() const + { + QSet<int> res; + for (const auto &s: m_satellitesInUse) + res.insert(s.satelliteIdentifier()); + return res; + } + + void clear() + { + m_satellitesInView.clear(); + m_satellitesInUse.clear(); + m_validInView = m_validInUse = false; + } + + bool isValid() + { + return m_validInView || m_validInUse; // GSV without GSA is valid. GSA with outdated but still matching GSV also valid. + } + } m_pendingUpdate, m_lastUpdate; + bool m_fresh = false; + bool m_invokedStart = false; + bool m_noUpdateLastInterval = false; + bool m_updateTimeoutSent = false; + bool m_connectedReadyRead = false; + int m_pushDelay = 20; + QBasicTimer *m_updateTimer = nullptr; // the timer used in startUpdates() + QTimer *m_requestTimer = nullptr; // the timer used in requestUpdate() + +protected: + void readAvailableData(); + bool openSourceDevice(); + bool initialize(); + void prepareSourceDevice(); + bool emitUpdated(Update &update); + void timerEvent(QTimerEvent *event) override; +}; + +QNmeaSatelliteInfoSourcePrivate::QNmeaSatelliteInfoSourcePrivate(QNmeaSatelliteInfoSource *parent) +: m_source(parent) +{ +} + +void QNmeaSatelliteInfoSourcePrivate::notifyNewUpdate() +{ + if (m_pendingUpdate.isValid() && m_pendingUpdate.isFresh()) { + if (m_requestTimer && m_requestTimer->isActive()) { // User called requestUpdate() + m_requestTimer->stop(); + emitUpdated(m_pendingUpdate); + } else if (m_invokedStart) { // user called startUpdates() + if (m_updateTimer && m_updateTimer->isActive()) { // update interval > 0 + // for periodic updates, only want the most recent update + if (m_noUpdateLastInterval) { + // if the update was invalid when timerEvent was last called, a valid update + // should be sent ASAP + emitPendingUpdate(); // m_noUpdateLastInterval handled in there. + } + } else { // update interval <= 0, send anything new ASAP + m_noUpdateLastInterval = !emitUpdated(m_pendingUpdate); + } + } + } +} + +QNmeaSatelliteInfoSourcePrivate::~QNmeaSatelliteInfoSourcePrivate() +{ + delete m_updateTimer; +} + +void QNmeaSatelliteInfoSourcePrivate::startUpdates() +{ + if (m_invokedStart) + return; + + m_invokedStart = true; + m_pendingUpdate.clear(); + m_noUpdateLastInterval = false; + + bool initialized = initialize(); + if (!initialized) + return; + + // Do not support simulation just yet +// if (m_updateMode == QNmeaPositionInfoSource::RealTimeMode) + { + // skip over any buffered data - we only want the newest data. + // Don't do this in requestUpdate. In that case bufferedData is good to have/use. + if (m_device->bytesAvailable()) { + if (m_device->isSequential()) + m_device->readAll(); + else + m_device->seek(m_device->bytesAvailable()); + } + } + + if (m_updateTimer) + m_updateTimer->stop(); + + if (m_source->updateInterval() > 0) { + if (!m_updateTimer) + m_updateTimer = new QBasicTimer; + m_updateTimer->start(m_source->updateInterval(), this); + } + + if (initialized) + prepareSourceDevice(); +} + +void QNmeaSatelliteInfoSourcePrivate::stopUpdates() +{ + m_invokedStart = false; + if (m_updateTimer) + m_updateTimer->stop(); + m_pendingUpdate.clear(); + m_noUpdateLastInterval = false; +} + +void QNmeaSatelliteInfoSourcePrivate::requestUpdate(int msec) +{ + if (m_requestTimer && m_requestTimer->isActive()) + return; + + if (msec <= 0 || msec < m_source->minimumUpdateInterval()) { + emit m_source->requestTimeout(); + return; + } + + if (!m_requestTimer) { + m_requestTimer = new QTimer(this); + connect(m_requestTimer, SIGNAL(timeout()), SLOT(updateRequestTimeout())); + } + + bool initialized = initialize(); + if (!initialized) { + emit m_source->requestTimeout(); + return; + } + + m_requestTimer->start(msec); + prepareSourceDevice(); +} + +void QNmeaSatelliteInfoSourcePrivate::readyRead() +{ + readAvailableData(); +} + +void QNmeaSatelliteInfoSourcePrivate::emitPendingUpdate() +{ + if (m_pendingUpdate.isValid() && m_pendingUpdate.isFresh()) { + m_updateTimeoutSent = false; + m_noUpdateLastInterval = false; + if (!emitUpdated(m_pendingUpdate)) + m_noUpdateLastInterval = true; +// m_pendingUpdate.clear(); // Do not clear, it will be incrementally updated + } else { // invalid or not fresh update + if (m_noUpdateLastInterval && !m_updateTimeoutSent) { + m_updateTimeoutSent = true; + emit m_source->requestTimeout(); + } + m_noUpdateLastInterval = true; + } +} + +void QNmeaSatelliteInfoSourcePrivate::sourceDataClosed() +{ + if (m_device && m_device->bytesAvailable()) + readAvailableData(); +} + +void QNmeaSatelliteInfoSourcePrivate::updateRequestTimeout() +{ + m_requestTimer->stop(); + emit m_source->requestTimeout(); +} + +void QNmeaSatelliteInfoSourcePrivate::readAvailableData() +{ + while (m_device->canReadLine()) { + char buf[1024]; + qint64 size = m_device->readLine(buf, sizeof(buf)); + QList<int> satInUse; + const bool satInUseParsed = QLocationUtils::getSatInUseFromNmea(buf, size, satInUse); + if (satInUseParsed) { + m_pendingUpdate.setSatellitesInUse(satInUse); +#if USE_NMEA_PIMPL + m_pendingUpdate.gsa = QByteArray(buf, size); + if (m_pendingUpdate.m_satellitesInUse.size()) { + for (auto &s: m_pendingUpdate.m_satellitesInUse) + static_cast<QGeoSatelliteInfoPrivateNmea *>(QGeoSatelliteInfoPrivate::get(s))->nmeaSentences.append(m_pendingUpdate.gsa); + for (auto &s: m_pendingUpdate.m_satellitesInView) + static_cast<QGeoSatelliteInfoPrivateNmea *>(QGeoSatelliteInfoPrivate::get(s))->nmeaSentences.append(m_pendingUpdate.gsa); + } +#endif + } else { + const QLocationUtils::GSVParseStatus parserStatus = QLocationUtils::getSatInfoFromNmea(buf, size, m_pendingUpdate.m_satellitesInView); + if (parserStatus == QLocationUtils::GSVPartiallyParsed) { + m_pendingUpdate.m_updatingGsv = true; +#if USE_NMEA_PIMPL + m_pendingUpdate.gsv.append(QByteArray(buf, size)); +#endif + } else if (parserStatus == QLocationUtils::GSVFullyParsed) { +#if USE_NMEA_PIMPL + m_pendingUpdate.gsv.append(QByteArray(buf, size)); + for (int i = 0; i < m_pendingUpdate.m_satellitesInView.size(); i++) { + const QGeoSatelliteInfo &s = m_pendingUpdate.m_satellitesInView.at(i); + QGeoSatelliteInfoPrivateNmea *pimpl = new QGeoSatelliteInfoPrivateNmea(*QGeoSatelliteInfoPrivate::get(s)); + pimpl->nmeaSentences.append(m_pendingUpdate.gsa); + pimpl->nmeaSentences.append(m_pendingUpdate.gsv); + m_pendingUpdate.m_satellitesInView.replace(i, QGeoSatelliteInfo(*pimpl)); + } + m_pendingUpdate.gsv.clear(); +#endif + m_pendingUpdate.setSatellitesInView(m_pendingUpdate.m_satellitesInView); + } + } + } + notifyNewUpdate(); +} + +bool QNmeaSatelliteInfoSourcePrivate::openSourceDevice() +{ + if (!m_device) { + qWarning("QNmeaSatelliteInfoSource: no QIODevice data source, call setDevice() first"); + return false; + } + + if (!m_device->isOpen() && !m_device->open(QIODevice::ReadOnly)) { + qWarning("QNmeaSatelliteInfoSource: cannot open QIODevice data source"); + return false; + } + + connect(m_device, SIGNAL(aboutToClose()), SLOT(sourceDataClosed())); + connect(m_device, SIGNAL(readChannelFinished()), SLOT(sourceDataClosed())); + connect(m_device, SIGNAL(destroyed()), SLOT(sourceDataClosed())); + + return true; +} + +bool QNmeaSatelliteInfoSourcePrivate::initialize() +{ + if (!openSourceDevice()) + return false; + + return true; +} + +void QNmeaSatelliteInfoSourcePrivate::prepareSourceDevice() +{ + if (!m_connectedReadyRead) { + connect(m_device, SIGNAL(readyRead()), SLOT(readyRead())); + m_connectedReadyRead = true; + } +} + +bool QNmeaSatelliteInfoSourcePrivate::emitUpdated(QNmeaSatelliteInfoSourcePrivate::Update &update) +{ + bool emitted = false; + if (!update.isFresh()) + return emitted; + + update.consume(); + const bool inUseUpdated = update.m_satellitesInUse != m_lastUpdate.m_satellitesInUse; + const bool inViewUpdated = update.m_satellitesInView != m_lastUpdate.m_satellitesInView; + + + m_lastUpdate = update; + if (update.m_validInUse && inUseUpdated) { + emit m_source->satellitesInUseUpdated(update.m_satellitesInUse); + emitted = true; + } + if (update.m_validInView && inViewUpdated) { + emit m_source->satellitesInViewUpdated(update.m_satellitesInView); + emitted = true; + } + return emitted; +} + +void QNmeaSatelliteInfoSourcePrivate::timerEvent(QTimerEvent * /*event*/) +{ + emitPendingUpdate(); +} + + +// currently supports only realtime +QNmeaSatelliteInfoSource::QNmeaSatelliteInfoSource(QObject *parent) +: QGeoSatelliteInfoSource(*new QNmeaSatelliteInfoSourcePrivate(this), parent) +{ + d = static_cast<QNmeaSatelliteInfoSourcePrivate *>(QGeoSatelliteInfoSourcePrivate::get(*this)); +} + +QNmeaSatelliteInfoSource::~QNmeaSatelliteInfoSource() +{ + // d deleted in superclass destructor +} + +void QNmeaSatelliteInfoSource::setDevice(QIODevice *device) +{ + if (device != d->m_device) { + if (!d->m_device) + d->m_device = device; + else + qWarning("QNmeaPositionInfoSource: source device has already been set"); + } +} + +QIODevice *QNmeaSatelliteInfoSource::device() const +{ + return d->m_device; +} + +void QNmeaSatelliteInfoSource::setUpdateInterval(int msec) +{ + int interval = msec; + if (interval != 0) + interval = qMax(msec, minimumUpdateInterval()); + QGeoSatelliteInfoSource::setUpdateInterval(interval); + if (d->m_invokedStart) { + d->stopUpdates(); + d->startUpdates(); + } +} + +int QNmeaSatelliteInfoSource::minimumUpdateInterval() const +{ + return 2; // Some chips are capable of over 100 updates per seconds. +} + +QGeoSatelliteInfoSource::Error QNmeaSatelliteInfoSource::error() const +{ + return d->m_satelliteError; +} + +void QNmeaSatelliteInfoSource::startUpdates() +{ + d->startUpdates(); +} + +void QNmeaSatelliteInfoSource::stopUpdates() +{ + d->stopUpdates(); +} + +void QNmeaSatelliteInfoSource::requestUpdate(int msec) +{ + d->requestUpdate(msec == 0 ? 60000 * 5 : msec); // 5min default timeout +} + +void QNmeaSatelliteInfoSource::setError(QGeoSatelliteInfoSource::Error satelliteError) +{ + d->m_satelliteError = satelliteError; + emit QGeoSatelliteInfoSource::error(satelliteError); +} + + +//QT_END_NAMESPACE + +#include "qnmeasatelliteinfosource.moc" diff --git a/src/plugins/position/serialnmea/qnmeasatelliteinfosource_p.h b/src/plugins/position/serialnmea/qnmeasatelliteinfosource_p.h new file mode 100644 index 00000000..2f7469c6 --- /dev/null +++ b/src/plugins/position/serialnmea/qnmeasatelliteinfosource_p.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtPositioning module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNMESATELLITEINFOSOURCE_P_H +#define QNMESATELLITEINFOSOURCE_P_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 <QtPositioning/private/qpositioningglobal_p.h> +#include <QtPositioning/qgeosatelliteinfosource.h> +#include <QtPositioning/qgeosatelliteinfo.h> + +#include <QObject> +#include <QQueue> +#include <QPointer> +#include <QtCore/qiodevice.h> +#include <QtCore/qtimer.h> + +//QT_BEGIN_NAMESPACE + +class QNmeaSatelliteInfoSourcePrivate; +class /*Q_POSITIONING_PRIVATE_EXPORT*/ QNmeaSatelliteInfoSource : public QGeoSatelliteInfoSource +{ + Q_OBJECT +public: + explicit QNmeaSatelliteInfoSource( QObject *parent = nullptr); + ~QNmeaSatelliteInfoSource() override; + + void setDevice(QIODevice *source); + QIODevice *device() const; + + void setUpdateInterval(int msec) override; + int minimumUpdateInterval() const override; + Error error() const override; + +public Q_SLOTS: + void startUpdates() override; + void stopUpdates() override; + void requestUpdate(int timeout = 0) override; + +protected: + QNmeaSatelliteInfoSourcePrivate *d; + void setError(QGeoSatelliteInfoSource::Error satelliteError); + + friend class QNmeaSatelliteInfoSourcePrivate; + Q_DISABLE_COPY(QNmeaSatelliteInfoSource) +}; + +//QT_END_NAMESPACE + +#endif diff --git a/src/plugins/position/serialnmea/serialnmea.pro b/src/plugins/position/serialnmea/serialnmea.pro index e5677e99..4e0088bb 100644 --- a/src/plugins/position/serialnmea/serialnmea.pro +++ b/src/plugins/position/serialnmea/serialnmea.pro @@ -3,10 +3,10 @@ TARGET = qtposition_serialnmea QT = core-private positioning-private serialport HEADERS += \ - qgeopositioninfosourcefactory_serialnmea.h qiopipe_p.h + qgeopositioninfosourcefactory_serialnmea.h qnmeasatelliteinfosource_p.h qiopipe_p.h SOURCES += \ - qgeopositioninfosourcefactory_serialnmea.cpp qiopipe.cpp + qgeopositioninfosourcefactory_serialnmea.cpp qnmeasatelliteinfosource.cpp qiopipe.cpp OTHER_FILES += \ plugin.json |