Esempio n. 1
0
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;
  }
}
Esempio n. 2
0
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 );
}