Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsgpsdetector.cpp - description 3 : : -------------------- 4 : : begin : January 13th, 2009 5 : : copyright : (C) 2009 by Juergen E. Fischer 6 : : email : jef at norbit dot de 7 : : ***************************************************************************/ 8 : : 9 : : /*************************************************************************** 10 : : * * 11 : : * This program is free software; you can redistribute it and/or modify * 12 : : * it under the terms of the GNU General Public License as published by * 13 : : * the Free Software Foundation; either version 2 of the License, or * 14 : : * (at your option) any later version. * 15 : : * * 16 : : ***************************************************************************/ 17 : : 18 : : #include "qgsgpsdetector.h" 19 : : #include "qgslogger.h" 20 : : #include "qgsgpsconnection.h" 21 : : #include "qgsnmeaconnection.h" 22 : : #include "qgsgpsdconnection.h" 23 : : #include "qgssettings.h" 24 : : 25 : : #if defined(HAVE_QT_MOBILITY_LOCATION ) || defined(QT_POSITIONING_LIB) 26 : : #include "qgsqtlocationconnection.h" 27 : : #endif 28 : : 29 : : #include <QStringList> 30 : : #include <QFileInfo> 31 : : #include <QTimer> 32 : : 33 : : #if defined( HAVE_QT5SERIALPORT ) 34 : : #include <QSerialPortInfo> 35 : : #include <QSerialPort> 36 : : #endif 37 : : 38 : 0 : QList< QPair<QString, QString> > QgsGpsDetector::availablePorts() 39 : : { 40 : 0 : QList< QPair<QString, QString> > devs; 41 : : 42 : : // try local QtLocation first 43 : : #if defined(HAVE_QT_MOBILITY_LOCATION ) || defined(QT_POSITIONING_LIB) 44 : 0 : devs << QPair<QString, QString>( QStringLiteral( "internalGPS" ), tr( "internal GPS" ) ); 45 : : #endif 46 : : 47 : : // try local gpsd first 48 : 0 : devs << QPair<QString, QString>( QStringLiteral( "localhost:2947:" ), tr( "local gpsd" ) ); 49 : : 50 : : // try serial ports 51 : : #if defined( HAVE_QT5SERIALPORT ) 52 : 0 : for ( auto p : QSerialPortInfo::availablePorts() ) 53 : : { 54 : 0 : devs << QPair<QString, QString>( p.portName(), tr( "%1: %2" ).arg( p.portName(), p.description() ) ); 55 : 0 : } 56 : : #endif 57 : : 58 : 0 : return devs; 59 : 0 : } 60 : : 61 : 0 : QgsGpsDetector::QgsGpsDetector( const QString &portName ) 62 : 0 : { 63 : 0 : #if defined( HAVE_QT5SERIALPORT ) 64 : 0 : mBaudList << QSerialPort::Baud4800 << QSerialPort::Baud9600 << QSerialPort::Baud38400 << QSerialPort::Baud57600 << QSerialPort::Baud115200; //add 57600 for SXBlueII GPS unit 65 : : #endif 66 : : 67 : 0 : if ( portName.isEmpty() ) 68 : : { 69 : 0 : mPortList = availablePorts(); 70 : 0 : } 71 : : else 72 : : { 73 : 0 : mPortList << QPair<QString, QString>( portName, portName ); 74 : : } 75 : 0 : } 76 : : 77 : 0 : QgsGpsDetector::~QgsGpsDetector() = default; 78 : : 79 : 0 : void QgsGpsDetector::advance() 80 : : { 81 : 0 : mConn.reset(); 82 : : 83 : 0 : QgsSettings settings; 84 : : 85 : 0 : while ( !mConn ) 86 : : { 87 : 0 : mBaudIndex++; 88 : 0 : if ( mBaudIndex == mBaudList.size() ) 89 : : { 90 : 0 : mBaudIndex = 0; 91 : 0 : mPortIndex++; 92 : 0 : } 93 : : 94 : 0 : if ( mPortIndex == mPortList.size() ) 95 : : { 96 : 0 : emit detectionFailed(); 97 : 0 : deleteLater(); 98 : 0 : return; 99 : : } 100 : : 101 : 0 : if ( mPortList.at( mPortIndex ).first.contains( ':' ) ) 102 : : { 103 : 0 : mBaudIndex = mBaudList.size() - 1; 104 : : 105 : 0 : QStringList gpsParams = mPortList.at( mPortIndex ).first.split( ':' ); 106 : : 107 : : Q_ASSERT( gpsParams.size() >= 3 ); 108 : : 109 : 0 : mConn = std::make_unique< QgsGpsdConnection >( gpsParams[0], gpsParams[1].toShort(), gpsParams[2] ); 110 : 0 : } 111 : 0 : else if ( mPortList.at( mPortIndex ).first.contains( QLatin1String( "internalGPS" ) ) ) 112 : : { 113 : : #if defined(HAVE_QT_MOBILITY_LOCATION ) || defined(QT_POSITIONING_LIB) 114 : 0 : mConn = std::make_unique< QgsQtLocationConnection >(); 115 : : #else 116 : : qWarning( "QT_MOBILITY_LOCATION not found and mPortList matches internalGPS, this should never happen" ); 117 : : #endif 118 : 0 : } 119 : : else 120 : : { 121 : : #if defined( HAVE_QT5SERIALPORT ) 122 : 0 : std::unique_ptr< QSerialPort > serial = std::make_unique< QSerialPort >( mPortList.at( mPortIndex ).first ); 123 : : 124 : 0 : serial->setBaudRate( mBaudList[ mBaudIndex ] ); 125 : : 126 : 0 : serial->setFlowControl( settings.enumValue( QStringLiteral( "gps/flow_control" ), QSerialPort::NoFlowControl, QgsSettings::Core ) ); 127 : 0 : serial->setParity( settings.enumValue( QStringLiteral( "gps/parity" ), QSerialPort::NoParity, QgsSettings::Core ) ); 128 : 0 : serial->setDataBits( settings.enumValue( QStringLiteral( "gps/data_bits" ), QSerialPort::Data8, QgsSettings::Core ) ); 129 : 0 : serial->setStopBits( settings.enumValue( QStringLiteral( "gps/stop_bits" ), QSerialPort::OneStop, QgsSettings::Core ) ); 130 : : 131 : 0 : if ( serial->open( QIODevice::ReadOnly ) ) 132 : : { 133 : 0 : mConn = std::make_unique< QgsNmeaConnection >( serial.release() ); 134 : 0 : } 135 : : #else 136 : : qWarning( "QT5SERIALPORT not found and mPortList matches serial port, this should never happen" ); 137 : : #endif 138 : 0 : } 139 : : } 140 : : 141 : 0 : connect( mConn.get(), &QgsGpsConnection::stateChanged, this, static_cast < void ( QgsGpsDetector::* )( const QgsGpsInformation & ) >( &QgsGpsDetector::detected ) ); 142 : 0 : connect( mConn.get(), &QObject::destroyed, this, &QgsGpsDetector::connDestroyed ); 143 : : 144 : : // leave 2s to pickup a valid string 145 : 0 : QTimer::singleShot( 2000, this, &QgsGpsDetector::advance ); 146 : 0 : } 147 : : 148 : 0 : void QgsGpsDetector::detected( const QgsGpsInformation &info ) 149 : : { 150 : 0 : Q_UNUSED( info ) 151 : : 152 : 0 : if ( !mConn ) 153 : : { 154 : : // advance if connection was destroyed 155 : 0 : advance(); 156 : 0 : } 157 : 0 : else if ( mConn->status() == QgsGpsConnection::GPSDataReceived ) 158 : : { 159 : : // signal detected 160 : : 161 : : // let's hope there's a single, unique connection to this signal... otherwise... boom 162 : 0 : emit detected( mConn.release() ); 163 : : 164 : 0 : deleteLater(); 165 : 0 : } 166 : 0 : } 167 : : 168 : 0 : void QgsGpsDetector::connDestroyed( QObject *obj ) 169 : : { 170 : : // WTF? This whole class needs re-writing... 171 : 0 : if ( obj == mConn.get() ) 172 : : { 173 : 0 : mConn.release(); 174 : 0 : } 175 : 0 : }