void CDeviceDetailView::enableContent() { if( poOverlayObject ) { pqPushButtonEdit->setEnabled( true ); pqPushButtonDelete->setEnabled( true ); pqPushButtonStop->setEnabled( true ); pqPushButtonPause->setEnabled( true ); pqPushButtonStart->setEnabled( true ); QObject::connect( (CDevice*)poOverlayObject, SIGNAL( signalOperatingMode(CDevice::EOperatingMode) ), this, SLOT( slotOperatingMode(CDevice::EOperatingMode) ) ); QObject::connect( (CDevice*)poOverlayObject, SIGNAL( signalActivity() ), this, SLOT( slotActivity() ) ); bIgnoreUpdate = false; } }
void CDeviceTcpSbs1::slotProcessData() { // NOTE: SBS-1 protocol: http://www.homepages.mcb.net/bones/SBS/Article/Barebones42_Socket_Data.htm // NOTE: as per QT documentation: "[...] within a slot connected to the readyRead() signal, readyRead() will not be reemitted" static const QRegExp __qRegExpYMD( "^(197\\d|19[89]\\d|[2-9]\\d\\d\\d)/(0?[1-9]|1[12])/(0?[1-9]|[12]\\d|3[01])$" ); static const QRegExp __qRegExpHMS( "^(0?\\d|1\\d|2[0-3]):(0?\\d|[1-5]\\d):(0?\\d|[1-5]\\d(\\.\\d+)?)$" ); //qDebug( "DEBUG[%s]: Begin", Q_FUNC_INFO ); QMutex* __pqMutexDataChange = QVCTRuntime::useMutexDataChange(); __pqMutexDataChange->lock(); do // data-processing loop { // Check data availability if( !pqTcpSocket->canReadLine() ) break; //qDebug( "DEBUG[%s]: SBS-1 data are waiting to be read", Q_FUNC_INFO ); // Retrieve data QString __qsDataLine = QString::fromAscii( pqTcpSocket->readLine().trimmed() ); //qDebug( "DEBUG[%s]: SBS-1 data successfully read; data=%s", Q_FUNC_INFO, qPrintable( __qsDataLine ) ); // Do not process data if paused if( bPaused ) continue; // Check data status if( __qsDataLine.isEmpty() ) continue; // We need a non-empty string emit signalActivity(); // Check SBS-1 data status int __iMSG; QStringList __qDataFields = __qsDataLine.split( "," ); if( __qDataFields.at( 0 ) != "MSG" ) continue; // We process only SBS-1's "MSG" message type if( __qDataFields.size() != 22 ) continue; // "MSG" message type ought to be 22-fields long if( ( __iMSG = __qDataFields.at( 1 ).toInt() ) > 4 ) continue; // Transmission types greater than "4" are useless to us if( __qDataFields.at( 21 ).toInt() < 0 && !bGroundTraffic ) continue; // Ignore ground traffic if( __qDataFields.at( 4 ).isEmpty() ) continue; // We need a valid "HexIdent" QString __qsSource = __qDataFields.at( 4 ); //qDebug( "DEBUG[%s]: SBS-1 data are available from source %s", Q_FUNC_INFO, qPrintable( __qsSource ) ); // Callsign lookup if( bCallsignLookup ) { QString __qsCallsign; double __fdTimestamp = microtime(); // Dictionary cleanup (every 300 seconds) if( __fdTimestamp - fdCallsignCleanupTimestamp > (double)300.0 ) { fdCallsignCleanupTimestamp = __fdTimestamp; QList<QString> __qListSource = qHashCallsign.keys(); for( QList<QString>::const_iterator __iqsSource = __qListSource.begin(); __iqsSource != __qListSource.end(); ++__iqsSource ) // Cleanup stale entries (older than 900 seconds) if( __fdTimestamp - qHashCallsign[ *__iqsSource ].fdTimestamp > (double)900.0 ) qHashCallsign.remove( *__iqsSource ); } // Actual lookup if( !__qDataFields.at( 10 ).isEmpty() ) { __qsCallsign = __qDataFields.at( 10 ).trimmed(); if( qHashCallsign.contains( __qsSource ) ) qHashCallsign[ __qsSource ].update( __qsCallsign, __fdTimestamp ); else qHashCallsign.insert( __qsSource, CCallsign( __qsCallsign, __fdTimestamp ) ); } else { if( !qHashCallsign.contains( __qsSource ) ) continue; __qsCallsign = qHashCallsign[ __qsSource ].get( __fdTimestamp ); } // Use looked-up callsign __qsSource = __qsCallsign; } if( __iMSG == 1 ) continue; // Parse SBS-1 data CDeviceDataFix __oDeviceDataFix( __qsSource ); __oDeviceDataFix.setSourceType( CDeviceDataSource::SBS ); __oDeviceDataFix.setCourseFromPosition( false ); bool __bDataAvailable = false; // ... time if( !__qDataFields.at( 6 ).isEmpty() && !__qDataFields.at( 7 ).isEmpty() && __qRegExpYMD.exactMatch( __qDataFields.at( 6 ) ) && __qRegExpHMS.exactMatch( __qDataFields.at( 7 ) ) ) { QDateTime __qDateTime; __qDateTime.setTimeSpec( eTimeZone == CUnitTimeZone::UTC ? Qt::UTC : Qt::LocalTime ); __qDateTime.setDate( QDate( __qRegExpYMD.cap(1).toInt(), __qRegExpYMD.cap(2).toInt(), __qRegExpYMD.cap(3).toInt() ) ); __qDateTime.setTime( QTime( __qRegExpHMS.cap(1).toInt(), __qRegExpHMS.cap(2).toInt(), __qRegExpHMS.cap(3).toInt(), !__qRegExpHMS.cap(4).isEmpty() ? 1000*__qRegExpHMS.cap(4).toDouble() : 0 ) ); __oDeviceDataFix.setTime( (double)__qDateTime.toTime_t() ); } else { // Let's default to use current system time (some SBS-1 devices do not set the date/time fields) __oDeviceDataFix.setTime( (double)QDateTime::currentDateTime().toTime_t() ); } // ... position / elevation // SBS-1 elevation: feet if( !__qDataFields.at( 14 ).isEmpty() && !__qDataFields.at( 15 ).isEmpty() ) { if( !__qDataFields.at( 11 ).isEmpty() ) { __oDeviceDataFix.setPosition( __qDataFields.at( 15 ).toDouble(), __qDataFields.at( 14 ).toDouble(), __qDataFields.at( 11 ).toDouble() * 0.3048 ); __oDeviceDataFix.setType( CDeviceDataFix::FIX_3D ); } else { __oDeviceDataFix.setPosition( __qDataFields.at( 15 ).toDouble(), __qDataFields.at( 14 ).toDouble() ); __oDeviceDataFix.setType( CDeviceDataFix::FIX_2D ); } __bDataAvailable = true; } // ... course if( !__qDataFields.at( 13 ).isEmpty() ) { __oDeviceDataFix.setBearing( __qDataFields.at( 13 ).toDouble() ); __bDataAvailable = true; } // ... speed // SBS-1 (horizontal) speed: knots // SBS-1 vertical speed: feet/minute if( !__qDataFields.at( 12 ).isEmpty() ) { if( !__qDataFields.at( 16 ).isEmpty() ) { __oDeviceDataFix.setSpeed( __qDataFields.at( 12 ).toDouble() / 1.94384449244, __qDataFields.at( 16 ).toDouble() / 196.8503937 ); } else { __oDeviceDataFix.setSpeed( __qDataFields.at( 12 ).toDouble() / 1.94384449244 ); } __bDataAvailable = true; } // ... hexident/callsign if( bCallsignLookup || !__qDataFields.at( 10 ).isEmpty() ) { __oDeviceDataFix.setText( bCallsignLookup ? "HEX:"+__qDataFields.at( 4 ) : "C/S:"+__qDataFields.at( 10 ) ); __bDataAvailable = true; } // [end] if( __bDataAvailable ) { emit signalDataFix( __oDeviceDataFix ); } } while( true ); // data-processing loop __pqMutexDataChange->unlock(); //qDebug( "DEBUG[%s]: End", Q_FUNC_INFO ); }