QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
qgsgpsdetector.cpp
Go to the documentation of this file.
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 "qextserialenumerator.h"
20 #include "qgslogger.h"
21 #include "qgsgpsconnection.h"
22 #include "qgsnmeaconnection.h"
23 #include "qgsgpsdconnection.h"
24 
25 #if defined(HAVE_QT_MOBILITY_LOCATION ) || defined(QT_POSITIONING_LIB)
27 #endif
28 
29 #include <QStringList>
30 #include <QFileInfo>
31 #include <QTimer>
32 
34 {
36 
37  // try local QtLocation first
38 #if defined(HAVE_QT_MOBILITY_LOCATION ) || defined(QT_POSITIONING_LIB)
39  devs << QPair<QString, QString>( "internalGPS", tr( "internal GPS" ) );
40 #endif
41 
42  // try local gpsd first
43  devs << QPair<QString, QString>( "localhost:2947:", tr( "local gpsd" ) );
44 
45 #ifdef Q_OS_LINUX
46  // look for linux serial devices
47  Q_FOREACH ( const QString& linuxDev, QStringList() << "/dev/ttyS%1" << "/dev/ttyUSB%1" << "/dev/rfcomm%1" << "/dev/ttyACM%1" )
48  {
49  for ( int i = 0; i < 10; ++i )
50  {
51  if ( QFileInfo( linuxDev.arg( i ) ).exists() )
52  {
53  devs << QPair<QString, QString>( linuxDev.arg( i ), linuxDev.arg( i ) );
54  }
55  }
56  }
57 #endif
58 
59 #ifdef Q_OS_FREEBSD
60  // and freebsd devices (untested)
61  Q_FOREACH ( const QString& freebsdDev, QStringList() << "/dev/cuaa%1" << "/dev/ucom%1" )
62  {
63  for ( int i = 0; i < 10; ++i )
64  {
65  if ( QFileInfo( freebsdDev.arg( i ) ).exists() )
66  {
67  devs << QPair<QString, QString>( freebsdDev.arg( i ), freebsdDev.arg( i ) );
68  }
69  }
70  }
71 #endif
72 
73 #ifdef Q_OS_SOLARIS
74  // and solaris devices (also untested)
75  QString solarisDev( "/dev/cua/%1" );
76  for ( char i = 'a'; i < 'k'; ++i )
77  {
78  if ( QFileInfo( solarisDev.arg( i ) ).exists() )
79  {
80  devs << QPair<QString, QString>( solarisDev.arg( i ), solarisDev.arg( i ) );
81  }
82  }
83 #endif
84 
85 #if defined(Q_OS_WIN) || defined(Q_OS_MAC)
86  QList<QextPortInfo> ports = QextSerialEnumerator::getPorts();
87  Q_FOREACH ( QextPortInfo port, ports )
88  {
89  devs << QPair<QString, QString>( port.portName, port.friendName );
90  }
91 #endif
92 
93  // OpenBSD, NetBSD etc? Anyone?
94 
95  return devs;
96 }
97 
99 {
100  mConn = nullptr;
101  mBaudList << BAUD4800 << BAUD9600 << BAUD38400 << BAUD57600 << BAUD115200; //add 57600 for SXBlueII GPS unit
102 
103  if ( portName.isEmpty() )
104  {
105  mPortList = availablePorts();
106  }
107  else
108  {
109  mPortList << QPair<QString, QString>( portName, portName );
110  }
111 
112  mPortIndex = 0;
113  mBaudIndex = -1;
114 }
115 
117 {
118  if ( mConn )
119  delete mConn;
120 }
121 
123 {
124  if ( mConn )
125  {
126  delete mConn;
127  }
128 
129  mConn = nullptr;
130 
131  while ( !mConn )
132  {
133  mBaudIndex++;
134  if ( mBaudIndex == mBaudList.size() )
135  {
136  mBaudIndex = 0;
137  mPortIndex++;
138  }
139 
140  if ( mPortIndex == mPortList.size() )
141  {
142  emit detectionFailed();
143  deleteLater();
144  return;
145  }
146 
147  if ( mPortList.at( mPortIndex ).first.contains( ':' ) )
148  {
149  mBaudIndex = mBaudList.size() - 1;
150 
151  QStringList gpsParams = mPortList.at( mPortIndex ).first.split( ':' );
152 
153  Q_ASSERT( gpsParams.size() >= 3 );
154 
155  mConn = new QgsGpsdConnection( gpsParams[0], gpsParams[1].toShort(), gpsParams[2] );
156  }
157  else if ( mPortList.at( mPortIndex ).first.contains( "internalGPS" ) )
158  {
159 #if defined(HAVE_QT_MOBILITY_LOCATION ) || defined(QT_POSITIONING_LIB)
160  mConn = new QgsQtLocationConnection();
161 #else
162  qWarning( "QT_MOBILITY_LOCATION not found and mPortList matches internalGPS, this should never happen" );
163 #endif
164  }
165  else
166  {
167  QextSerialPort *serial = new QextSerialPort( mPortList.at( mPortIndex ).first, QextSerialPort::EventDriven );
168 
169  serial->setBaudRate( mBaudList[ mBaudIndex ] );
170  serial->setFlowControl( FLOW_OFF );
171  serial->setParity( PAR_NONE );
172  serial->setDataBits( DATA_8 );
173  serial->setStopBits( STOP_1 );
174 
175  if ( serial->open( QIODevice::ReadOnly | QIODevice::Unbuffered ) )
176  {
177  mConn = new QgsNMEAConnection( serial );
178  }
179  else
180  {
181  delete serial;
182  }
183  }
184  }
185 
186  connect( mConn, SIGNAL( stateChanged( const QgsGPSInformation & ) ), this, SLOT( detected( const QgsGPSInformation & ) ) );
187  connect( mConn, SIGNAL( destroyed( QObject * ) ), this, SLOT( connDestroyed( QObject * ) ) );
188 
189  // leave 2s to pickup a valid string
190  QTimer::singleShot( 2000, this, SLOT( advance() ) );
191 }
192 
194 {
195  Q_UNUSED( info );
196 
197  if ( !mConn )
198  {
199  // advance if connection was destroyed
200  advance();
201  }
202  else if ( mConn->status() == QgsGPSConnection::GPSDataReceived )
203  {
204  // signal detection
205  QgsGPSConnection *conn = mConn;
206  mConn = nullptr;
207  emit detected( conn );
208  deleteLater();
209  }
210 }
211 
213 {
214  if ( obj == mConn )
215  {
216  mConn = nullptr;
217  }
218 }
Evaluates NMEA sentences coming from gpsd.
const T & at(int i) const
void detectionFailed()
QString tr(const char *sourceText, const char *disambiguation, int n)
int size() const
Abstract base class for connection to a GPS device.
QgsGPSDetector(const QString &portName)
bool isEmpty() const
Evaluates NMEA sentences coming from a GPS device.
void deleteLater()
void connDestroyed(QObject *)
void detected(const QgsGPSInformation &)
static QList< QPair< QString, QString > > availablePorts()
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
Status status() const
Returns the status.
void destroyed(QObject *obj)