QGIS API Documentation  master-3f58142
src/core/gps/qgsgpsdetector.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines