|
QGIS API Documentation
master-28efcda
|
00001 /*************************************************************************** 00002 qgsgpsdetector.cpp - description 00003 -------------------- 00004 begin : January 13th, 2009 00005 copyright : (C) 2009 by Juergen E. Fischer 00006 email : jef at norbit dot de 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This program is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU General Public License as published by * 00013 * the Free Software Foundation; either version 2 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 ***************************************************************************/ 00017 00018 #include "qgsgpsdetector.h" 00019 #include "qextserialenumerator.h" 00020 #include "qgslogger.h" 00021 #include "qgsgpsconnection.h" 00022 #include "qgsnmeaconnection.h" 00023 #include "qgsgpsdconnection.h" 00024 00025 #ifdef HAVE_QT_MOBILITY_LOCATION 00026 #include "qgsqtlocationconnection.h" 00027 #endif 00028 00029 #include <QStringList> 00030 #include <QFileInfo> 00031 #include <QTimer> 00032 00033 QList< QPair<QString, QString> > QgsGPSDetector::availablePorts() 00034 { 00035 QList< QPair<QString, QString> > devs; 00036 00037 // try local QtLocation first 00038 #ifdef HAVE_QT_MOBILITY_LOCATION 00039 devs << QPair<QString, QString>( "internalGPS", tr( "internal GPS" ) ); 00040 #endif 00041 // try local gpsd first 00042 devs << QPair<QString, QString>( "localhost:2947:", tr( "local gpsd" ) ); 00043 00044 #ifdef linux 00045 // look for linux serial devices 00046 foreach ( QString linuxDev, QStringList() << "/dev/ttyS%1" << "/dev/ttyUSB%1" << "/dev/rfcomm%1" << "/dev/ttyACM%1" ) 00047 { 00048 for ( int i = 0; i < 10; ++i ) 00049 { 00050 if ( QFileInfo( linuxDev.arg( i ) ).exists() ) 00051 { 00052 devs << QPair<QString, QString>( linuxDev.arg( i ), linuxDev.arg( i ) ); 00053 } 00054 } 00055 } 00056 #endif 00057 00058 #ifdef __FreeBSD__ // freebsd 00059 // and freebsd devices (untested) 00060 foreach ( QString freebsdDev, QStringList() << "/dev/cuaa%1" << "/dev/ucom%1" ) 00061 { 00062 for ( int i = 0; i < 10; ++i ) 00063 { 00064 if ( QFileInfo( freebsdDev.arg( i ) ).exists() ) 00065 { 00066 devs << QPair<QString, QString>( freebsdDev.arg( i ), freebsdDev.arg( i ) ); 00067 } 00068 } 00069 } 00070 #endif 00071 00072 #ifdef sparc 00073 // and solaris devices (also untested) 00074 QString solarisDev( "/dev/cua/%1" ); 00075 for ( char i = 'a'; i < 'k'; ++i ) 00076 { 00077 if ( QFileInfo( solarisDev.arg( i ) ).exists() ) 00078 { 00079 devs << QPair<QString, QString>( solarisDev.arg( i ), solarisDev.arg( i ) ); 00080 } 00081 } 00082 #endif 00083 00084 #if defined(Q_WS_WIN) || defined(Q_WS_MAC) 00085 QList<QextPortInfo> ports = QextSerialEnumerator::getPorts(); 00086 foreach ( QextPortInfo port, ports ) 00087 { 00088 devs << QPair<QString, QString>( port.portName, port.friendName ); 00089 } 00090 #endif 00091 00092 // OpenBSD, NetBSD etc? Anyone? 00093 00094 return devs; 00095 } 00096 00097 QgsGPSDetector::QgsGPSDetector( QString portName ) 00098 { 00099 mConn = 0; 00100 mBaudList << BAUD4800 << BAUD9600 << BAUD38400 << BAUD57600 << BAUD115200; //add 57600 for SXBlueII GPS unit 00101 00102 if ( portName.isEmpty() ) 00103 { 00104 mPortList = availablePorts(); 00105 } 00106 else 00107 { 00108 mPortList << QPair<QString, QString>( portName, portName ); 00109 } 00110 00111 mPortIndex = 0; 00112 mBaudIndex = -1; 00113 } 00114 00115 QgsGPSDetector::~QgsGPSDetector() 00116 { 00117 if ( mConn ) 00118 delete mConn; 00119 } 00120 00121 void QgsGPSDetector::advance() 00122 { 00123 if ( mConn ) 00124 { 00125 delete mConn; 00126 } 00127 00128 mConn = 0; 00129 00130 while ( !mConn ) 00131 { 00132 mBaudIndex++; 00133 if ( mBaudIndex == mBaudList.size() ) 00134 { 00135 mBaudIndex = 0; 00136 mPortIndex++; 00137 } 00138 00139 if ( mPortIndex == mPortList.size() ) 00140 { 00141 emit detectionFailed(); 00142 deleteLater(); 00143 return; 00144 } 00145 00146 if ( mPortList[ mPortIndex ].first.contains( ":" ) ) 00147 { 00148 mBaudIndex = mBaudList.size() - 1; 00149 00150 QStringList gpsParams = mPortList[ mPortIndex ].first.split( ":" ); 00151 00152 Q_ASSERT( gpsParams.size() >= 3 ); 00153 00154 mConn = new QgsGpsdConnection( gpsParams[0], gpsParams[1].toShort(), gpsParams[2] ); 00155 } 00156 else if ( mPortList[ mPortIndex ].first.contains( "internalGPS" ) ) 00157 { 00158 #ifdef HAVE_QT_MOBILITY_LOCATION 00159 mConn = new QgsQtLocationConnection(); 00160 #else 00161 qWarning( "QT_MOBILITY_LOCATION not found and mPortList matches internalGPS, this should never happen" ); 00162 #endif 00163 } 00164 00165 else 00166 { 00167 QextSerialPort *serial = new QextSerialPort( mPortList[ mPortIndex ].first, QextSerialPort::EventDriven ); 00168 00169 serial->setBaudRate( mBaudList[ mBaudIndex ] ); 00170 serial->setFlowControl( FLOW_OFF ); 00171 serial->setParity( PAR_NONE ); 00172 serial->setDataBits( DATA_8 ); 00173 serial->setStopBits( STOP_1 ); 00174 00175 if ( serial->open( QIODevice::ReadOnly | QIODevice::Unbuffered ) ) 00176 { 00177 mConn = new QgsNMEAConnection( serial ); 00178 } 00179 else 00180 { 00181 delete serial; 00182 } 00183 } 00184 } 00185 00186 connect( mConn, SIGNAL( stateChanged( const QgsGPSInformation & ) ), this, SLOT( detected( const QgsGPSInformation & ) ) ); 00187 connect( mConn, SIGNAL( destroyed( QObject * ) ), this, SLOT( connDestroyed( QObject * ) ) ); 00188 00189 // leave 2s to pickup a valid string 00190 QTimer::singleShot( 2000, this, SLOT( advance() ) ); 00191 } 00192 00193 void QgsGPSDetector::detected( const QgsGPSInformation& info ) 00194 { 00195 Q_UNUSED( info ); 00196 00197 if ( !mConn ) 00198 { 00199 // advance if connection was destroyed 00200 advance(); 00201 } 00202 else if ( mConn->status() == QgsGPSConnection::GPSDataReceived ) 00203 { 00204 // signal detection 00205 QgsGPSConnection *conn = mConn; 00206 mConn = 0; 00207 emit detected( conn ); 00208 deleteLater(); 00209 } 00210 } 00211 00212 void QgsGPSDetector::connDestroyed( QObject *obj ) 00213 { 00214 if ( obj == mConn ) 00215 { 00216 mConn = 0; 00217 } 00218 }