summaryrefslogtreecommitdiffstats
path: root/src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.cpp
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2021-10-21 17:27:08 +0200
committerIvan Solovev <ivan.solovev@qt.io>2021-11-02 09:46:33 +0200
commit6db775f6d9d72cf8ee9d66333b8424e74be1e352 (patch)
tree0a293756b61619a91970d9368a0449b7bf922728 /src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.cpp
parent5a1f44c3d41febca8480c077bd4c34e5a3332cdc (diff)
Remove QtPositioning module from qtlocation.git6.2.46.2.36.2.26.2
Turns out that our CI does not support repos without any tests. This is treated like an error and leads to integration failure. This patch fixes it by disabling tests in coin/module_config.yaml. This config should be fixed when QtLocation tests are enabled Task-number: QTBUG-97084 Change-Id: Ib06e865fe2836806bbbee34345f06b471dd48660 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Alex Blasche <alexander.blasche@qt.io> (cherry picked from commit 23f32792ad53e23bbafbff6d7667f0bb0f69fc53)
Diffstat (limited to 'src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.cpp')
-rw-r--r--src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.cpp505
1 files changed, 0 insertions, 505 deletions
diff --git a/src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.cpp b/src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.cpp
deleted file mode 100644
index 15460062..00000000
--- a/src/plugins/position/nmea/qgeopositioninfosourcefactory_nmea.cpp
+++ /dev/null
@@ -1,505 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qgeopositioninfosourcefactory_nmea.h"
-#include <QtPositioning/QNmeaPositionInfoSource>
-#include <QtPositioning/QNmeaSatelliteInfoSource>
-#include <QtSerialPort/QSerialPort>
-#include <QtSerialPort/QSerialPortInfo>
-#include <QtNetwork/QTcpSocket>
-#include <QLoggingCategory>
-#include <QSet>
-#include <QUrl>
-#include <QFile>
-#include <QSharedPointer>
-#include "qiopipe_p.h"
-
-Q_LOGGING_CATEGORY(lcNmea, "qt.positioning.nmea")
-
-QT_BEGIN_NAMESPACE
-
-static const auto sourceParameterName = QStringLiteral("nmea.source");
-static const auto socketScheme = QStringLiteral("socket:");
-static const auto serialScheme = QStringLiteral("serial:");
-
-// This class is used only for SerialPort devices, because we can't open the
-// same serial port twice.
-// In case of files and sockets it's easier to explicitly create a QIODevice for
-// each new instance of Nmea*InfoSource.
-// Also QFile can't be directly used with QIOPipe, because QFile is not a
-// sequential device.
-// TcpSocket could be used with QIOPipe, but it complicates error handling
-// dramatically, as we would need to somehow forward socket errors through
-// QIOPipes to the clients.
-class IODeviceContainer
-{
-public:
- IODeviceContainer() {}
- IODeviceContainer(IODeviceContainer const&) = delete;
- void operator=(IODeviceContainer const&) = delete;
-
- QSharedPointer<QIOPipe> serial(const QString &portName)
- {
- if (m_serialPorts.contains(portName)) {
- m_serialPorts[portName].refs++;
- QIOPipe *endPipe = new QIOPipe(m_serialPorts[portName].proxy);
- m_serialPorts[portName].proxy->addChildPipe(endPipe);
- return QSharedPointer<QIOPipe>(endPipe);
- }
- IODevice device;
- QSerialPort *port = new QSerialPort(portName);
- port->setBaudRate(4800);
- qCDebug(lcNmea) << "Opening serial port" << portName;
- if (!port->open(QIODevice::ReadOnly)) {
- qWarning("nmea: Failed to open %s", qPrintable(portName));
- delete port;
- return {};
- }
- qCDebug(lcNmea) << "Opened successfully";
- device.device = port;
- device.refs = 1;
- device.proxy = new QIOPipe(port, QIOPipe::ProxyPipe);
- m_serialPorts[portName] = device;
- QIOPipe *endPipe = new QIOPipe(device.proxy);
- device.proxy->addChildPipe(endPipe);
- return QSharedPointer<QIOPipe>(endPipe);
- }
-
- void releaseSerial(const QString &portName, QSharedPointer<QIOPipe> &pipe)
- {
- if (!m_serialPorts.contains(portName))
- return;
-
- pipe.clear(); // make sure to release the pipe returned by getSerial, or else, if there are still refs, data will be leaked through it
- IODevice &device = m_serialPorts[portName];
- if (device.refs > 1) {
- device.refs--;
- return;
- }
-
- IODevice taken = m_serialPorts.take(portName);
- taken.device->deleteLater();
- }
-
-private:
-
- struct IODevice {
- QIODevice *device = nullptr;
- QIOPipe *proxy = nullptr; // adding client pipes as children of proxy
- // allows to dynamically add clients to one device.
- unsigned int refs = 1;
- };
-
- QMap<QString, IODevice> m_serialPorts;
-};
-
-Q_GLOBAL_STATIC(IODeviceContainer, deviceContainer)
-
-// We use a string prefix to distinguish between the different data sources.
-// "socket:" means that we use a socket connection
-// "serial:" means that we use a serial port connection
-// "file:///", "qrc:///" and just plain strings mean that we try to use local
-// file.
-// Note: if we do not specify anything, or specify "serial:" without specifying
-// the port name, then we will try to search for a well-known serial port
-// device.
-class NmeaSource : public QNmeaPositionInfoSource
-{
- Q_OBJECT
-public:
- NmeaSource(QObject *parent, const QVariantMap &parameters);
- NmeaSource(QObject *parent, const QString &fileName);
- ~NmeaSource() override;
- bool isValid() const
- {
- return !m_dataSource.isNull() || !m_fileSource.isNull() || !m_socket.isNull();
- }
-
-private slots:
- void onSocketError(QAbstractSocket::SocketError error);
-
-private:
- void parseSourceParameter(const QString &source);
- void addSerialDevice(const QString &requestedPort);
- void setFileName(const QString &fileName);
- void connectSocket(const QString &source);
-
- QSharedPointer<QIOPipe> m_dataSource;
- QScopedPointer<QFile> m_fileSource;
- QScopedPointer<QTcpSocket> m_socket;
- QString m_sourceName;
-};
-
-NmeaSource::NmeaSource(QObject *parent, const QVariantMap &parameters)
- : QNmeaPositionInfoSource(RealTimeMode, parent)
-{
- const QString source = parameters.value(sourceParameterName).toString();
- parseSourceParameter(source);
-}
-
-NmeaSource::NmeaSource(QObject *parent, const QString &fileName)
- : QNmeaPositionInfoSource(SimulationMode, parent)
-{
- setFileName(fileName);
-}
-
-NmeaSource::~NmeaSource()
-{
- deviceContainer->releaseSerial(m_sourceName, m_dataSource);
-}
-
-void NmeaSource::onSocketError(QAbstractSocket::SocketError error)
-{
- m_socket->close();
-
- switch (error) {
- case QAbstractSocket::UnknownSocketError:
- setError(QGeoPositionInfoSource::UnknownSourceError);
- break;
- case QAbstractSocket::SocketAccessError:
- setError(QGeoPositionInfoSource::AccessError);
- break;
- case QAbstractSocket::RemoteHostClosedError:
- setError(QGeoPositionInfoSource::ClosedError);
- break;
- default:
- qWarning() << "Connection failed! QAbstractSocket::SocketError" << error;
- // TODO - introduce new type of error. TransportError?
- setError(QGeoPositionInfoSource::UnknownSourceError);
- break;
- }
-}
-
-void NmeaSource::parseSourceParameter(const QString &source)
-{
- if (source.startsWith(socketScheme)) {
- // This is a socket
- connectSocket(source);
- } else {
- // Last chance - this can be serial device.
- // Note: File is handled in a separate case.
- addSerialDevice(source);
- }
-}
-
-static QString tryFindSerialDevice(const QString &requestedPort)
-{
- QString portName;
- if (requestedPort.isEmpty()) {
- const QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts();
- qCDebug(lcNmea) << "Found" << ports.count() << "serial ports";
- if (ports.isEmpty()) {
- qWarning("nmea: No serial ports found");
- return portName;
- }
-
- // Try to find a well-known device.
- QSet<int> supportedDevices;
- supportedDevices << 0x67b; // GlobalSat (BU-353S4 and probably others)
- supportedDevices << 0xe8d; // Qstarz MTK II
- for (const QSerialPortInfo& port : ports) {
- if (port.hasVendorIdentifier() && supportedDevices.contains(port.vendorIdentifier())) {
- portName = port.portName();
- break;
- }
- }
-
- if (portName.isEmpty()) {
- qWarning("nmea: No known GPS device found.");
- }
- } else {
- portName = requestedPort;
- if (portName.startsWith(serialScheme))
- portName.remove(0, 7);
- }
- return portName;
-}
-
-void NmeaSource::addSerialDevice(const QString &requestedPort)
-{
- m_sourceName = tryFindSerialDevice(requestedPort);
- if (m_sourceName.isEmpty())
- return;
-
- m_dataSource = deviceContainer->serial(m_sourceName);
- if (!m_dataSource)
- return;
-
- setDevice(m_dataSource.data());
-}
-
-void NmeaSource::setFileName(const QString &fileName)
-{
- m_sourceName = fileName;
-
- m_fileSource.reset(new QFile(fileName));
- qCDebug(lcNmea) << "Opening file" << fileName;
- if (!m_fileSource->open(QIODevice::ReadOnly)) {
- qWarning("nmea: failed to open file %s", qPrintable(fileName));
- m_fileSource.reset();
- }
-
- if (!m_fileSource)
- return;
-
- qCDebug(lcNmea) << "Opened successfully";
-
- setDevice(m_fileSource.data());
-}
-
-void NmeaSource::connectSocket(const QString &source)
-{
- const QUrl url(source);
- const QString host = url.host();
- const int port = url.port();
- if (!host.isEmpty() && (port > 0)) {
- m_socket.reset(new QTcpSocket);
- // no need to explicitly connect to connected() signal
- connect(m_socket.get(), &QTcpSocket::errorOccurred, this, &NmeaSource::onSocketError);
- m_socket->connectToHost(host, port, QTcpSocket::ReadOnly);
- m_sourceName = source;
-
- setDevice(m_socket.data());
- } else {
- qWarning("nmea: incorrect socket parameters %s:%d", qPrintable(host), port);
- }
-}
-
-class NmeaSatelliteSource : public QNmeaSatelliteInfoSource
-{
- Q_OBJECT
-public:
- NmeaSatelliteSource(QObject *parent, const QVariantMap &parameters);
- NmeaSatelliteSource(QObject *parent, const QString &fileName, const QVariantMap &parameters);
- ~NmeaSatelliteSource();
-
- bool isValid() const { return !m_port.isNull() || !m_file.isNull() || !m_socket.isNull(); }
-
-private slots:
- void onSocketError(QAbstractSocket::SocketError error);
-
-private:
- void parseRealtimeSource(const QString &source);
- void parseSimulationSource(const QString &localFileName);
-
- QSharedPointer<QIOPipe> m_port;
- QScopedPointer<QFile> m_file;
- QScopedPointer<QTcpSocket> m_socket;
- QString m_sourceName;
-};
-
-NmeaSatelliteSource::NmeaSatelliteSource(QObject *parent, const QVariantMap &parameters)
- : QNmeaSatelliteInfoSource(QNmeaSatelliteInfoSource::UpdateMode::RealTimeMode, parent)
-{
- const QString source = parameters.value(sourceParameterName).toString();
- parseRealtimeSource(source);
-}
-
-// We can use a QNmeaSatelliteInfoSource::SimulationUpdateInterval parameter to
-// set the file read frequency in simulation mode. We use setBackendProperty()
-// for it. The value can't be smaller than minimumUpdateInterval().
-// This check is done on the QNmeaSatelliteInfoSource level
-NmeaSatelliteSource::NmeaSatelliteSource(QObject *parent, const QString &fileName,
- const QVariantMap &parameters)
- : QNmeaSatelliteInfoSource(QNmeaSatelliteInfoSource::UpdateMode::SimulationMode, parent)
-{
- bool ok = false;
- const int interval =
- parameters.value(QNmeaSatelliteInfoSource::SimulationUpdateInterval).toInt(&ok);
- if (ok)
- setBackendProperty(QNmeaSatelliteInfoSource::SimulationUpdateInterval, interval);
- parseSimulationSource(fileName);
-}
-
-NmeaSatelliteSource::~NmeaSatelliteSource()
-{
- deviceContainer->releaseSerial(m_sourceName, m_port);
-}
-
-void NmeaSatelliteSource::onSocketError(QAbstractSocket::SocketError error)
-{
- m_socket->close();
-
- switch (error) {
- case QAbstractSocket::UnknownSocketError:
- setError(QGeoSatelliteInfoSource::UnknownSourceError);
- break;
- case QAbstractSocket::SocketAccessError:
- setError(QGeoSatelliteInfoSource::AccessError);
- break;
- case QAbstractSocket::RemoteHostClosedError:
- setError(QGeoSatelliteInfoSource::ClosedError);
- break;
- default:
- qWarning() << "Connection failed! QAbstractSocket::SocketError" << error;
- // TODO - introduce new type of error. TransportError?
- setError(QGeoSatelliteInfoSource::UnknownSourceError);
- break;
- }
-}
-
-void NmeaSatelliteSource::parseRealtimeSource(const QString &source)
-{
- if (source.startsWith(socketScheme)) {
- // This is a socket.
- const QUrl url(source);
- const QString host = url.host();
- const int port = url.port();
- if (!host.isEmpty() && (port > 0)) {
- m_socket.reset(new QTcpSocket);
- // no need to explicitly connect to connected() signal
- connect(m_socket.get(), &QTcpSocket::errorOccurred,
- this, &NmeaSatelliteSource::onSocketError);
- m_socket->connectToHost(host, port, QTcpSocket::ReadOnly);
- m_sourceName = source;
-
- setDevice(m_socket.data());
- } else {
- qWarning("nmea: incorrect socket parameters %s:%d", qPrintable(host), port);
- }
- } else {
- // Last chance - this can be serial device.
- m_sourceName = tryFindSerialDevice(source);
- if (m_sourceName.isEmpty())
- return;
-
- m_port = deviceContainer->serial(m_sourceName);
- if (!m_port)
- return;
-
- setDevice(m_port.data());
- }
-}
-
-void NmeaSatelliteSource::parseSimulationSource(const QString &localFileName)
-{
- // This is a text file.
- m_sourceName = localFileName;
-
- qCDebug(lcNmea) << "Opening file" << localFileName;
- m_file.reset(new QFile(localFileName));
- if (!m_file->open(QIODevice::ReadOnly)) {
- qWarning("nmea: failed to open file %s", qPrintable(localFileName));
- m_file.reset();
- return;
- }
- qCDebug(lcNmea) << "Opened successfully";
-
- setDevice(m_file.data());
-}
-
-/*!
- \internal
- Returns a local file name if \a source represents it.
- The returned value can be different from \a source, as the method tries to
- modify the path
-*/
-static QString checkSourceIsFile(const QString &source)
-{
- if (source.isEmpty())
- return QString();
-
- QString localFileName = source;
-
- if (!QFile::exists(localFileName)) {
- if (localFileName.startsWith(QStringLiteral("qrc:///")))
- localFileName.remove(0, 7);
- else if (localFileName.startsWith(QStringLiteral("file:///")))
- localFileName.remove(0, 7);
- else if (localFileName.startsWith(QStringLiteral("qrc:/")))
- localFileName.remove(0, 5);
-
- if (!QFile::exists(localFileName) && localFileName.startsWith(QLatin1Char('/')))
- localFileName.remove(0, 1);
- }
- if (!QFile::exists(localFileName))
- localFileName.prepend(QLatin1Char(':'));
-
- const bool isLocalFile = QFile::exists(localFileName);
- return isLocalFile ? localFileName : QString();
-}
-
-/*!
- \internal
- Returns a local file name if file exists, or an empty string otherwise
-*/
-static QString extractLocalFileName(const QVariantMap &parameters)
-{
- QString localFileName = parameters.value(sourceParameterName).toString();
- return checkSourceIsFile(localFileName);
-}
-
-QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryNmea::positionInfoSource(QObject *parent, const QVariantMap &parameters)
-{
- std::unique_ptr<NmeaSource> src = nullptr;
-
- const QString localFileName = extractLocalFileName(parameters);
- if (localFileName.isEmpty())
- src = std::make_unique<NmeaSource>(parent, parameters); // use RealTimeMode
- else
- src = std::make_unique<NmeaSource>(parent, localFileName); // use SimulationMode
-
- return (src && src->isValid()) ? src.release() : nullptr;
-}
-
-QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryNmea::satelliteInfoSource(QObject *parent, const QVariantMap &parameters)
-{
- std::unique_ptr<NmeaSatelliteSource> src = nullptr;
-
- const QString localFileName = extractLocalFileName(parameters);
- if (localFileName.isEmpty()) {
- // use RealTimeMode
- src = std::make_unique<NmeaSatelliteSource>(parent, parameters);
- } else {
- // use SimulationMode
- src = std::make_unique<NmeaSatelliteSource>(parent, localFileName, parameters);
- }
- return (src && src->isValid()) ? src.release() : nullptr;
-}
-
-QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryNmea::areaMonitor(QObject *parent, const QVariantMap &parameters)
-{
- Q_UNUSED(parent);
- Q_UNUSED(parameters);
- return nullptr;
-}
-
-QT_END_NAMESPACE
-
-#include "qgeopositioninfosourcefactory_nmea.moc"