diff options
author | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-09-24 17:47:20 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-10-09 08:35:59 +0000 |
commit | d4f7a35cfcc84b2c90785867e6246a6ec61a1479 (patch) | |
tree | 7e5292c66ba1eedf477aff48e3e6478f771b5319 /src | |
parent | 403112bdfafbfd1f90593c163e812b45a741a5d6 (diff) | |
download | qtlocation-d4f7a35cfcc84b2c90785867e6246a6ec61a1479.tar.gz |
Add qtserialport-based NMEA position plugin for Windows
GPS receivers typically come with USB-to-serial drivers for Windows.
This allows reading NMEA sentences via Qt Serial Port, thus providing
basic GPS positioning support for all desktop Windows versions.
Task-number: QTBUG-48082
Change-Id: Ie053dffaaf76bc08b2b6148104fd981b0f1ccc6b
Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
Diffstat (limited to 'src')
5 files changed, 201 insertions, 0 deletions
diff --git a/src/plugins/position/position.pro b/src/plugins/position/position.pro index 3886eb4d..f9492a79 100644 --- a/src/plugins/position/position.pro +++ b/src/plugins/position/position.pro @@ -6,6 +6,7 @@ qtHaveModule(simulator):SUBDIRS += simulator osx|ios:SUBDIRS += corelocation android:!android-no-sdk:SUBDIRS += android winrt:SUBDIRS += winrt +win32:qtHaveModule(serialport):SUBDIRS += serialnmea SUBDIRS += \ positionpoll diff --git a/src/plugins/position/serialnmea/plugin.json b/src/plugins/position/serialnmea/plugin.json new file mode 100644 index 00000000..826836c3 --- /dev/null +++ b/src/plugins/position/serialnmea/plugin.json @@ -0,0 +1,9 @@ +{ + "Keys": ["serialnmea"], + "Provider": "serialnmea", + "Position": true, + "Satellite": false, + "Monitor" : false, + "Priority": 1000, + "Testable": false +} diff --git a/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp b/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp new file mode 100644 index 00000000..2b6b3ce6 --- /dev/null +++ b/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtPositioning module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgeopositioninfosourcefactory_serialnmea.h" +#include <QtPositioning/qnmeapositioninfosource.h> +#include <QtSerialPort/qserialport.h> +#include <QtSerialPort/qserialportinfo.h> +#include <QtCore/qloggingcategory.h> + +Q_LOGGING_CATEGORY(lcSerial, "qt.positioning.serialnmea") + +class NmeaSource : public QNmeaPositionInfoSource +{ +public: + NmeaSource(QObject *parent); + bool isValid() const { return !m_port.isNull(); } + +private: + QScopedPointer<QSerialPort> m_port; +}; + +NmeaSource::NmeaSource(QObject *parent) + : QNmeaPositionInfoSource(RealTimeMode, parent), + m_port(new QSerialPort) +{ + QByteArray requestedPort = qgetenv("QT_NMEA_SERIAL_PORT"); + 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"); + m_port.reset(); + return; + } + + // Try to find a well-known device. + QString portName; + for (int i = 0; i < ports.count(); ++i) { + const QString candidatePortName = ports[i].portName(); + bool acceptThis = false; + + // GlobalSat (BU-353S4 and probably others) + acceptThis |= ports[i].hasVendorIdentifier() && ports[i].vendorIdentifier() == 0x67b; + + if (acceptThis) { + portName = candidatePortName; + break; + } + } + + if (portName.isEmpty()) { + qWarning("serialnmea: No known GPS device found. Specify the COM port via QT_NMEA_SERIAL_PORT."); + m_port.reset(); + return; + } + + m_port->setPortName(portName); + } else { + m_port->setPortName(QString::fromUtf8(requestedPort)); + } + + m_port->setBaudRate(4800); + + qCDebug(lcSerial) << "Opening serial port" << m_port->portName(); + + if (!m_port->open(QIODevice::ReadOnly)) { + qWarning("serialnmea: Failed to open %s", qPrintable(m_port->portName())); + m_port.reset(); + return; + } + + setDevice(m_port.data()); + + qCDebug(lcSerial) << "Opened successfully"; +} + +QGeoPositionInfoSource *QGeoPositionInfoSourceFactorySerialNmea::positionInfoSource(QObject *parent) +{ + QScopedPointer<NmeaSource> src(new NmeaSource(parent)); + return src->isValid() ? src.take() : Q_NULLPTR; +} + +QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactorySerialNmea::satelliteInfoSource(QObject *parent) +{ + Q_UNUSED(parent); + return Q_NULLPTR; +} + +QGeoAreaMonitorSource *QGeoPositionInfoSourceFactorySerialNmea::areaMonitor(QObject *parent) +{ + Q_UNUSED(parent); + return Q_NULLPTR; +} diff --git a/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.h b/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.h new file mode 100644 index 00000000..b28d9834 --- /dev/null +++ b/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.h @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtPositioning module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGEOPOSITIONINFOSOURCEFACTORY_SERIALNMEA_H +#define QGEOPOSITIONINFOSOURCEFACTORY_SERIALNMEA_H + +#include <QObject> +#include <qgeopositioninfosourcefactory.h> + +class QGeoPositionInfoSourceFactorySerialNmea : public QObject, public QGeoPositionInfoSourceFactory +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/5.0" + FILE "plugin.json") + Q_INTERFACES(QGeoPositionInfoSourceFactory) + +public: + QGeoPositionInfoSource *positionInfoSource(QObject *parent); + QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent); + QGeoAreaMonitorSource *areaMonitor(QObject *parent); +}; + +#endif diff --git a/src/plugins/position/serialnmea/serialnmea.pro b/src/plugins/position/serialnmea/serialnmea.pro new file mode 100644 index 00000000..81570837 --- /dev/null +++ b/src/plugins/position/serialnmea/serialnmea.pro @@ -0,0 +1,15 @@ +TARGET = qtposition_serialnmea +QT = core positioning serialport + +PLUGIN_TYPE = position +PLUGIN_CLASS_NAME = QGeoPositionInfoSourceFactorySerialNmea +load(qt_plugin) + +HEADERS += \ + qgeopositioninfosourcefactory_serialnmea.h + +SOURCES += \ + qgeopositioninfosourcefactory_serialnmea.cpp + +OTHER_FILES += \ + plugin.json |