File indexing completed on 2024-04-28 03:50:07
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2009 Eckhart Wörner <ewoerner@kde.org> 0004 // SPDX-FileCopyrightText: 2011 Bastian Holst <bastianholst@gmx.de> 0005 // 0006 0007 #include "GpsdConnection.h" 0008 0009 #include "MarbleDebug.h" 0010 0011 #include <QTime> 0012 0013 #include <cerrno> 0014 #include <clocale> 0015 0016 using namespace Marble; 0017 /* TRANSLATOR Marble::GpsdConnection */ 0018 0019 const int gpsUpdateInterval = 1000; // ms 0020 const int gpsWaitTimeout = 200; // ms 0021 0022 GpsdConnection::GpsdConnection( QObject* parent ) 0023 : QObject( parent ), 0024 #if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION >= 5 ) 0025 m_gpsd( "localhost", DEFAULT_GPSD_PORT ), 0026 #endif 0027 m_timer( nullptr ) 0028 { 0029 m_oldLocale = setlocale( LC_NUMERIC, nullptr ); 0030 setlocale( LC_NUMERIC, "C" ); 0031 connect( &m_timer, SIGNAL(timeout()), this, SLOT(update()) ); 0032 } 0033 0034 GpsdConnection::~GpsdConnection() 0035 { 0036 setlocale( LC_NUMERIC, m_oldLocale ); 0037 } 0038 0039 void GpsdConnection::initialize() 0040 { 0041 m_timer.stop(); 0042 bool success = false; 0043 #if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION >= 5 ) 0044 success = true; 0045 #else 0046 gps_data_t* data = m_gpsd.open(); 0047 success = ( data != 0 ); 0048 #endif 0049 #if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION >= 3 ) && defined( WATCH_ENABLE ) 0050 if ( success ) { 0051 success = (m_gpsd.stream( WATCH_ENABLE ) != nullptr); 0052 } 0053 #endif 0054 if ( success ) { 0055 m_status = PositionProviderStatusAcquiring; 0056 emit statusChanged( m_status ); 0057 m_timer.start( gpsUpdateInterval ); 0058 } 0059 else { 0060 // There is also gps_errstr() for libgps version >= 2.90, 0061 // but it doesn't return a sensible error description 0062 switch ( errno ) { 0063 case NL_NOSERVICE: 0064 m_error = tr("Internal gpsd error (cannot get service entry)"); 0065 break; 0066 case NL_NOHOST: 0067 m_error = tr("Internal gpsd error (cannot get host entry)"); 0068 break; 0069 case NL_NOPROTO: 0070 m_error = tr("Internal gpsd error (cannot get protocol entry)"); 0071 break; 0072 case NL_NOSOCK: 0073 m_error = tr("Internal gpsd error (unable to create socket)"); 0074 break; 0075 case NL_NOSOCKOPT: 0076 m_error = tr("Internal gpsd error (unable to set socket option)"); 0077 break; 0078 case NL_NOCONNECT: 0079 m_error = tr("No GPS device found by gpsd."); 0080 break; 0081 default: 0082 m_error = tr("Unknown error when opening gpsd connection"); 0083 break; 0084 } 0085 0086 m_status = PositionProviderStatusError; 0087 emit statusChanged( m_status ); 0088 0089 mDebug() << "Connection to gpsd failed, no position info available: " << m_error; 0090 } 0091 } 0092 0093 void GpsdConnection::update() 0094 { 0095 #if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION >= 12 ) && defined( PACKET_SET ) 0096 gps_data_t* data = nullptr; 0097 0098 if ( m_gpsd.waiting(gpsUpdateInterval * 1000) ) 0099 { 0100 gps_data_t *currentData = m_gpsd.read(); 0101 0102 if( currentData && currentData->set & PACKET_SET ) { 0103 data = currentData; 0104 } 0105 } 0106 0107 if ( data ) { 0108 emit gpsdInfo( *data ); 0109 } 0110 #else 0111 #if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION >= 4 ) && defined( PACKET_SET ) 0112 gps_data_t *data = nullptr; 0113 0114 QTime watchdog; 0115 watchdog.start(); 0116 0117 #if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION >= 5 ) 0118 while ( m_gpsd.waiting( 0 ) && watchdog.elapsed() < gpsWaitTimeout ) { 0119 gps_data_t *currentData = m_gpsd.read(); 0120 #else 0121 while ( m_gpsd.waiting() && watchdog.elapsed() < gpsWaitTimeout ) { 0122 gps_data_t *currentData = m_gpsd.poll(); 0123 #endif 0124 0125 if( currentData && currentData->set & PACKET_SET ) { 0126 data = currentData; 0127 } 0128 } 0129 0130 if ( data ) { 0131 emit gpsdInfo( *data ); 0132 } 0133 #else 0134 #if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION == 3 ) && defined( PACKET_SET ) 0135 gps_data_t *data = m_gpsd.poll(); 0136 #else 0137 gps_data_t* data = m_gpsd.query( "o" ); 0138 #endif 0139 0140 if ( data ) { 0141 emit gpsdInfo( *data ); 0142 } 0143 else if ( m_status != PositionProviderStatusAcquiring ) { 0144 mDebug() << "Lost connection to gpsd, trying to re-open."; 0145 initialize(); 0146 } 0147 #endif 0148 #endif 0149 } 0150 0151 QString GpsdConnection::error() const 0152 { 0153 return m_error; 0154 } 0155 0156 #include "moc_GpsdConnection.cpp"