Esempio n. 1
1
bool CCallsignList::LoadFromFile(const char *filename)
{
    bool ok = false;
    char sz[256];

    // and load
    std::ifstream file (filename);
    if ( file.is_open() )
    {
        Lock();

        // empty list
        clear();
        // fill with file content
        while ( file.getline(sz, sizeof(sz)).good()  )
        {
            // remove leading & trailing spaces
            char *szt = TrimWhiteSpaces(sz);
            // and load if not comment
            if ( (::strlen(szt) > 0) && (szt[0] != '#') )
            {
                push_back(CCallsignListItem(CCallsign(szt), CIp(), NULL));
            }
        }
        // close file
        file.close();

        // keep file path
        m_Filename = filename;

        // update time
        GetLastModTime(&m_LastModTime);

        // and done
        Unlock();
        ok = true;
        std::cout << "Gatekeeper loaded " << size() << " lines from " << filename <<  std::endl;
    }
    else
    {
        std::cout << "Gatekeeper cannot find " << filename <<  std::endl;
    }

    return ok;
}
Esempio n. 2
0
bool CDplusProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
{
    bool newstream = false;
    
    // find the stream
    CPacketStream *stream = GetStream(Header->GetStreamId());
    if ( stream == NULL )
    {
        // no stream open yet, open a new one
        CCallsign via(Header->GetRpt1Callsign());
        
        // first, check module is valid
        if ( g_Reflector.IsValidModule(Header->GetRpt1Module()) )
        {
            // find this client
            CClient *client = g_Reflector.GetClients()->FindClient(Ip, PROTOCOL_DPLUS);
            if ( client != NULL )
            {
                // now we know if it's a dextra dongle or a genuine dplus node
                if ( Header->GetRpt2Callsign().HasSameCallsignWithWildcard(CCallsign("XRF*"))  )
                {
                    client->SetDextraDongle();
                }
                // now we know its module, let's update it
                if ( !client->HasModule() )
                {
                    client->SetModule(Header->GetRpt1Module());
                }
                // get client callsign
                via = client->GetCallsign();
                // and try to open the stream
                if ( (stream = g_Reflector.OpenStream(Header, client)) != NULL )
                {
                    // keep the handle
                    m_Streams.push_back(stream);
                    newstream = true;
                }
            }
            // release
            g_Reflector.ReleaseClients();
            
            // update last heard
            g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), via, Header->GetRpt2Callsign());
            g_Reflector.ReleaseUsers();
        }
        else
        {
            std::cout << "DPlus node " << via << " link attempt on non-existing module" << std::endl;
        }
    }
    else
    {
        // stream already open
        // skip packet, but tickle the stream
        stream->Tickle();
        // and delete packet
        delete Header;
    }
    
    // done
    return newstream;
}
Esempio n. 3
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 );
}