26#if defined(QT_POSITIONING_LIB)
34#if defined( HAVE_QTSERIALPORT )
35#include <QSerialPortInfo>
46 QList< QPair<QString, QString> > devs;
49#if defined(QT_POSITIONING_LIB)
50 devs << QPair<QString, QString>( QStringLiteral(
"internalGPS" ), tr(
"internal GPS" ) );
54 devs << QPair<QString, QString>( QStringLiteral(
"localhost:2947:" ), tr(
"local gpsd" ) );
57#if defined( HAVE_QTSERIALPORT )
58 for (
const QSerialPortInfo &p : QSerialPortInfo::availablePorts() )
60 devs << QPair<QString, QString>( p.portName(), tr(
"%1: %2" ).arg( p.portName(), p.description() ) );
68 : mUseUnsafeSignals( useUnsafeSignals )
70#if defined( HAVE_QTSERIALPORT )
71 mBaudList << QSerialPort::Baud4800 << QSerialPort::Baud9600 << QSerialPort::Baud38400 << QSerialPort::Baud57600 << QSerialPort::Baud115200;
74 if ( portName.isEmpty() )
76 QgsDebugMsgLevel( QStringLiteral(
"Attempting to autodetect GPS connection" ), 2 );
81 QgsDebugMsgLevel( QStringLiteral(
"Attempting GPS connection for %1" ).arg( portName ), 2 );
82 mPortList << QPair<QString, QString>( portName, portName );
85 mTimeoutTimer =
new QTimer(
this );
86 mTimeoutTimer->setSingleShot(
true );
87 connect( mTimeoutTimer, &QTimer::timeout,
this, &QgsGpsDetector::connectionTimeout );
97 if ( mUseUnsafeSignals )
99 QgsDebugError( QStringLiteral(
"QgsGpsDetector::takeConnection() incorrectly called when useUnsafeSignals option is in effect" ) );
107 mConn->disconnect(
this );
113 QgsDebugMsgLevel( QStringLiteral(
"Detected GPS connection is being taken by caller" ), 2 );
117 QgsDebugError( QStringLiteral(
"Something is trying to take the GPS connection, but it doesn't exist!" ) );
121 return mConn.release();
128 QgsDebugMsgLevel( QStringLiteral(
"Destroying existing connection to attempt next configuration combination" ), 2 );
137 if ( mBaudIndex == mBaudList.size() )
143 if ( mPortIndex == mPortList.size() )
145 QgsDebugError( QStringLiteral(
"No more devices to try!" ) );
151 QgsDebugMsgLevel( QStringLiteral(
"Attempting connection to device %1 @ %2" ).arg( mPortIndex ).arg( mBaudIndex ), 2 );
153 if ( mPortList.at( mPortIndex ).first.contains(
':' ) )
155 mBaudIndex = mBaudList.size() - 1;
157 QStringList gpsParams = mPortList.at( mPortIndex ).first.split(
':' );
159 Q_ASSERT( gpsParams.size() >= 3 );
160 QgsDebugMsgLevel( QStringLiteral(
"Connecting to GPSD device %1" ).arg( gpsParams.join(
',' ) ), 2 );
162 mConn = std::make_unique< QgsGpsdConnection >( gpsParams[0], gpsParams[1].toShort(), gpsParams[2] );
164 else if ( mPortList.at( mPortIndex ).first.contains( QLatin1String(
"internalGPS" ) ) )
166#if defined(QT_POSITIONING_LIB)
167 QgsDebugMsgLevel( QStringLiteral(
"Connecting to QtLocation service device" ), 2 );
168 mConn = std::make_unique< QgsQtLocationConnection >();
170 QgsDebugError( QStringLiteral(
"QT_POSITIONING_LIB not found and mPortList matches internalGPS, this should never happen" ) );
171 qWarning(
"QT_POSITIONING_LIB not found and mPortList matches internalGPS, this should never happen" );
176#if defined( HAVE_QTSERIALPORT )
177 std::unique_ptr< QSerialPort > serial = std::make_unique< QSerialPort >( mPortList.at( mPortIndex ).first );
179 serial->setBaudRate( mBaudList[ mBaudIndex ] );
181 serial->setFlowControl( QgsGpsDetector::settingsGpsFlowControl->value() );
182 serial->setParity( QgsGpsDetector::settingsGpsParity->value() );
183 serial->setDataBits( QgsGpsDetector::settingsGpsDataBits->value() );
184 serial->setStopBits( QgsGpsDetector::settingsGpsStopBits->value() );
186 QgsDebugMsgLevel( QStringLiteral(
"Connecting to serial GPS device %1 (@ %2)" ).arg( mPortList.at( mPortIndex ).first ).arg( mBaudList[ mBaudIndex ] ), 2 );
188 if ( serial->open( QIODevice::ReadOnly ) )
190 QgsDebugMsgLevel( QStringLiteral(
"Successfully opened, have a port connection ready" ), 2 );
191 mConn = std::make_unique< QgsNmeaConnection >( serial.release() );
195 QgsDebugError( QStringLiteral(
"Serial port could NOT be opened" ) );
198 QgsDebugError( QStringLiteral(
"QT5SERIALPORT not found and mPortList matches serial port, this should never happen" ) );
199 qWarning(
"QT5SERIALPORT not found and mPortList matches serial port, this should never happen" );
205 QgsDebugError( QStringLiteral(
"Got to end of connection handling loop, but have no connection!" ) );
209 QgsDebugMsgLevel( QStringLiteral(
"Have a connection, now listening for messages" ), 2 );
212 if ( mUseUnsafeSignals )
218 mTimeoutTimer->start( 2000 );
227 mTimeoutTimer->stop();
230 QgsDebugError( QStringLiteral(
"Got information, but CONNECTION WAS DESTROYED EXTERNALLY!" ) );
235 mTimeoutTimer->stop();
241 QgsDebugMsgLevel( QStringLiteral(
"Connection status IS GPSDataReceived" ), 2 );
243 if ( mUseUnsafeSignals )
260 QgsDebugMsgLevel( QStringLiteral(
"Connection status is NOT GPSDataReceived. It is %1" ).arg( mConn->status() ), 2 );
264void QgsGpsDetector::connectionTimeout()
266 QgsDebugMsgLevel( QStringLiteral(
"No data received within max listening time" ), 2 );
272 QgsDebugError( QStringLiteral(
"CONNECTION WAS DESTROYED EXTERNALLY!" ) );
275 if ( obj == mConn.get() )
Abstract base class for connection 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)