29#include "moc_qgsgpsdetector.cpp"
31using namespace Qt::StringLiterals;
33#if defined( QT_POSITIONING_LIB )
41#if defined( HAVE_QTSERIALPORT )
42#include <QSerialPortInfo>
56 QList< QPair<QString, QString> > devs;
59#if defined( QT_POSITIONING_LIB )
60 devs << QPair<QString, QString>( u
"internalGPS"_s, tr(
"internal GPS" ) );
64 devs << QPair<QString, QString>( u
"localhost:2947:"_s, tr(
"local gpsd" ) );
67#if defined( HAVE_QTSERIALPORT )
68 for (
const QSerialPortInfo &p : QSerialPortInfo::availablePorts() )
70 devs << QPair<QString, QString>( p.portName(), tr(
"%1: %2" ).arg( p.portName(), p.description() ) );
78 : mUseUnsafeSignals( useUnsafeSignals )
80#if defined( HAVE_QTSERIALPORT )
81 mBaudList << QSerialPort::Baud4800 << QSerialPort::Baud9600 << QSerialPort::Baud38400 << QSerialPort::Baud57600 << QSerialPort::Baud115200;
84 if ( portName.isEmpty() )
86 QgsDebugMsgLevel( u
"Attempting to autodetect GPS connection"_s, 2 );
87 mPortList = availablePorts();
91 QgsDebugMsgLevel( u
"Attempting GPS connection for %1"_s.arg( portName ), 2 );
92 mPortList << QPair<QString, QString>( portName, portName );
95 mTimeoutTimer =
new QTimer(
this );
96 mTimeoutTimer->setSingleShot(
true );
97 connect( mTimeoutTimer, &QTimer::timeout,
this, &QgsGpsDetector::connectionTimeout );
107 if ( mUseUnsafeSignals )
109 QgsDebugError( u
"QgsGpsDetector::takeConnection() incorrectly called when useUnsafeSignals option is in effect"_s );
117 mConn->disconnect(
this );
123 QgsDebugMsgLevel( u
"Detected GPS connection is being taken by caller"_s, 2 );
127 QgsDebugError( u
"Something is trying to take the GPS connection, but it doesn't exist!"_s );
131 return mConn.release();
138 QgsDebugMsgLevel( u
"Destroying existing connection to attempt next configuration combination"_s, 2 );
147 if ( mBaudIndex == mBaudList.size() )
153 if ( mPortIndex == mPortList.size() )
161 QgsDebugMsgLevel( u
"Attempting connection to device %1 @ %2"_s.arg( mPortIndex ).arg( mBaudIndex ), 2 );
163 if ( mPortList.at( mPortIndex ).first.contains(
':' ) )
165 mBaudIndex = mBaudList.size() - 1;
167 QStringList gpsParams = mPortList.at( mPortIndex ).first.split(
':' );
168 if ( gpsParams.size() < 3 )
170 QgsDebugError( u
"If the port name contains a colon, then it should have more than one colon (e.g., host:port:device). Port name: %1"_s.arg( mPortList.at( mPortIndex ).first ) );
176 QgsDebugMsgLevel( u
"Connecting to GPSD device %1"_s.arg( gpsParams.join(
',' ) ), 2 );
178 mConn = std::make_unique< QgsGpsdConnection >( gpsParams[0], gpsParams[1].toShort(), gpsParams[2] );
180 else if ( mPortList.at( mPortIndex ).first.contains(
"internalGPS"_L1 ) )
182#if defined( QT_POSITIONING_LIB )
184 mConn = std::make_unique< QgsQtLocationConnection >();
186 QgsDebugError( u
"QT_POSITIONING_LIB not found and mPortList matches internalGPS, this should never happen"_s );
187 qWarning(
"QT_POSITIONING_LIB not found and mPortList matches internalGPS, this should never happen" );
192#if defined( HAVE_QTSERIALPORT )
193 auto serial = std::make_unique< QSerialPort >( mPortList.at( mPortIndex ).first );
195 serial->setBaudRate( mBaudList[mBaudIndex] );
197 serial->setFlowControl( QgsGpsDetector::settingsGpsFlowControl->value() );
198 serial->setParity( QgsGpsDetector::settingsGpsParity->value() );
199 serial->setDataBits( QgsGpsDetector::settingsGpsDataBits->value() );
200 serial->setStopBits( QgsGpsDetector::settingsGpsStopBits->value() );
202 QgsDebugMsgLevel( u
"Connecting to serial GPS device %1 (@ %2)"_s.arg( mPortList.at( mPortIndex ).first ).arg( mBaudList[mBaudIndex] ), 2 );
204 if ( serial->open( QIODevice::ReadOnly ) )
206 QgsDebugMsgLevel( u
"Successfully opened, have a port connection ready"_s, 2 );
207 mConn = std::make_unique< QgsNmeaConnection >( serial.release() );
214 QgsDebugError( u
"QTSERIALPORT not found and mPortList matches serial port, this should never happen"_s );
215 qWarning(
"QTSERIALPORT not found and mPortList matches serial port, this should never happen" );
221 QgsDebugError( u
"Got to end of connection handling loop, but have no connection!"_s );
228 if ( mUseUnsafeSignals )
234 mTimeoutTimer->start( 2000 );
243 mTimeoutTimer->stop();
246 QgsDebugError( u
"Got information, but CONNECTION WAS DESTROYED EXTERNALLY!"_s );
251 mTimeoutTimer->stop();
259 if ( mUseUnsafeSignals )
276 QgsDebugMsgLevel( u
"Connection status is NOT GPSDataReceived. It is %1"_s.arg( mConn->status() ), 2 );
280void QgsGpsDetector::connectionTimeout()
291 if ( obj == mConn.get() )
Abstract base class for connections to a GPS device.
void stateChanged(const QgsGpsInformation &info)
Emitted whenever the GPS state is changed.
~QgsGpsDetector() override
void connDestroyed(QObject *)
void detected(const QgsGpsInformation &)
static QList< QPair< QString, QString > > availablePorts()
QgsGpsConnection * takeConnection()
Returns the detected GPS connection, and removes it from the detector.
void connectionDetected()
Emitted when a GPS connection is successfully detected.
QgsGpsDetector(const QString &portName=QString(), bool useUnsafeSignals=true)
Constructor for QgsGpsDetector.
void detectionFailed()
Emitted when the detector could not find a valid GPS connection.
A template class for enum and flag settings entry.
static QgsSettingsTreeNode * sTreeGps
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)