From 16fd3128b8312d4ff7b5a3391f718dec41a72028 Mon Sep 17 00:00:00 2001 From: Jon Beniston <jon@beniston.com> Date: Fri, 26 Aug 2022 13:47:36 +0100 Subject: [PATCH] Check ICAO in sink worker, so CRC can be checked. Fix warnings --- plugins/channelrx/demodadsb/adsbdemodgui.cpp | 12 +++---- plugins/channelrx/demodadsb/adsbdemodgui.h | 2 +- .../demodadsb/adsbdemodsinkworker.cpp | 34 ++++++++++++++----- .../channelrx/demodadsb/adsbdemodsinkworker.h | 1 + 4 files changed, 33 insertions(+), 16 deletions(-) diff --git a/plugins/channelrx/demodadsb/adsbdemodgui.cpp b/plugins/channelrx/demodadsb/adsbdemodgui.cpp index 9a0b8ddb1..898119544 100644 --- a/plugins/channelrx/demodadsb/adsbdemodgui.cpp +++ b/plugins/channelrx/demodadsb/adsbdemodgui.cpp @@ -1557,7 +1557,7 @@ void ADSBDemodGUI::handleADSB( else if (tc == 29) { // Target state and status - bool selAltitudeType = (data[5] >> 7) & 0x1; + //bool selAltitudeType = (data[5] >> 7) & 0x1; int selAltitudeFix = ((data[5] & 0x7f) << 4) | ((data[6] >> 4) & 0xf); if (selAltitudeFix != 0) { @@ -1665,11 +1665,11 @@ void ADSBDemodGUI::handleADSB( } else if ((df == 4) || (df == 5)) { - decodeModeS(data, dateTime, df, aircraft); + decodeModeS(data, df, aircraft); } else if ((df == 20) || (df == 21)) { - decodeModeS(data, dateTime, df, aircraft); + decodeModeS(data, df, aircraft); decodeCommB(data, dateTime, df, aircraft, updatedCallsign); } @@ -1682,7 +1682,7 @@ void ADSBDemodGUI::handleADSB( } } -void ADSBDemodGUI::decodeModeS(const QByteArray data, const QDateTime dateTime, int df, Aircraft *aircraft) +void ADSBDemodGUI::decodeModeS(const QByteArray data, int df, Aircraft *aircraft) { bool wasOnSurface = aircraft->m_onSurface; bool takenOff = false; @@ -2060,7 +2060,7 @@ void ADSBDemodGUI::decodeCommB(const QByteArray data, const QDateTime dateTime, bool hazardWindShearInconsistent = !hazardWindShearStatus && (hazardWindShear != 0); bool hazardMicroburstStatus = (data[4] >> 1) & 0x1; - int hazardMicroburst = ((data[4] & 0x1) << 1) || ((data[5] >> 7) & 0x1); + int hazardMicroburst = ((data[4] & 0x1) << 1) | ((data[5] >> 7) & 0x1); bool hazardMicroburstInconsistent = !hazardMicroburstStatus && (hazardMicroburst != 0); bool hazardIcingStatus = (data[5] >> 6) & 0x1; @@ -2201,7 +2201,7 @@ void ADSBDemodGUI::decodeCommB(const QByteArray data, const QDateTime dateTime, int arAltitudeRate = arAltitudeRateFix * 64; // Ft/min bool arAltitudeRateInconsistent = (abs(arAltitudeRate) > 6000) || (!arAltitudeRateStatus && (arAltitudeRateFix != 0)); - bool bds_5_3 = !arMagHeadingInconsistent && !arIndicatedAirspeedInconsistent && !arMachInconsistent && !arTrueAirspeedInconsistent; + bool bds_5_3 = !arMagHeadingInconsistent && !arIndicatedAirspeedInconsistent && !arMachInconsistent && !arTrueAirspeedInconsistent && !arAltitudeRateInconsistent; // BDS 6,0 - Heading and speed report - EHS diff --git a/plugins/channelrx/demodadsb/adsbdemodgui.h b/plugins/channelrx/demodadsb/adsbdemodgui.h index e7bbd9b00..8bf57accf 100644 --- a/plugins/channelrx/demodadsb/adsbdemodgui.h +++ b/plugins/channelrx/demodadsb/adsbdemodgui.h @@ -969,7 +969,7 @@ private: float correlationOnes, unsigned crc, bool updateModel); - void decodeModeS(const QByteArray data, const QDateTime dateTime, int df, Aircraft *aircraft); + void decodeModeS(const QByteArray data, int df, Aircraft *aircraft); void decodeCommB(const QByteArray data, const QDateTime dateTime, int df, Aircraft *aircraft, bool &updatedCallsign); QList<SWGSDRangel::SWGMapAnimation *> *animate(QDateTime dateTime, Aircraft *aircraft); SWGSDRangel::SWGMapAnimation *gearAnimation(QDateTime startDateTime, bool up); diff --git a/plugins/channelrx/demodadsb/adsbdemodsinkworker.cpp b/plugins/channelrx/demodadsb/adsbdemodsinkworker.cpp index f3bf5f09e..bd48e4db8 100644 --- a/plugins/channelrx/demodadsb/adsbdemodsinkworker.cpp +++ b/plugins/channelrx/demodadsb/adsbdemodsinkworker.cpp @@ -195,6 +195,9 @@ void ADSBDemodSinkWorker::run() { // Got a valid frame m_demodStats.m_adsbFrames++; + // Get 24-bit ICAO and save in hash of ICAOs that have been seen + unsigned icao = ((data[1] & 0xff) << 16) | ((data[2] & 0xff) << 8) | (data[3] & 0xff); + m_icaos.insert(icao, true); // Don't try to re-demodulate the same frame // We could possibly allow a partial overlap here readIdx += (ADS_B_ES_BITS+ADS_B_PREAMBLE_BITS)*ADS_B_CHIPS_PER_BIT*samplesPerChip - 1; @@ -228,26 +231,39 @@ void ADSBDemodSinkWorker::run() { int bytes; - m_crc.init(); - if ((df == 0) || (df == 4) || (df == 5) || (df == 11)) + // Determine number of bytes in frame depending on downlink format + if ((df == 0) || (df == 4) || (df == 5) || (df == 11)) { bytes = 56/8; - else if ((df == 16) || (df == 20) || (df == 21) || (df >= 24)) + } else if ((df == 16) || (df == 20) || (df == 21) || (df >= 24)) { bytes = 112/8; - else + } else { bytes = 0; + } if (bytes > 0) { + // Extract received parity int parity = (data[bytes-3] << 16) | (data[bytes-2] << 8) | data[bytes-1]; + // Calculate CRC on received frame + m_crc.init(); m_crc.calculate(data, bytes-3); int crc = m_crc.get(); + // DF4 / DF5 / DF20 / DF21 have ICAO address XORed in to parity. + // Extract ICAO from parity and see if it matches an aircraft we've already + // received an ADS-B frame from + if ((df == 4) || (df == 5) || (df == 20) || (df == 21)) + { + unsigned icao = (parity ^ crc) & 0xffffff; + if (m_icaos.contains(icao)) { + crc ^= icao; + } + } // For DF11, the last 7 bits may have an address/interogration indentifier (II) // XORed in, so we ignore those bits - // DF4 / DF5 / DF20 / DF21 have full address XORed in to parity. GUI will check if valid - if ((parity == crc) || ((df == 11) && (parity & 0xffff80) == (crc & 0xffff80)) || (df == 4) || (df == 5) || (df == 20) || (df == 21)) + if ((parity == crc) || ((df == 11) && ((parity & 0xffff80) == (crc & 0xffff80)))) { m_demodStats.m_modesFrames++; - // Pass to GUI - if (m_sink->getMessageQueueToGUI()) + // Pass to GUI (only pass formats it can decode) + if (m_sink->getMessageQueueToGUI() && ((df == 4) || (df == 5) || (df == 20) || (df == 21))) { ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create( QByteArray((char*)data, sizeof(data)), @@ -258,7 +274,7 @@ void ADSBDemodSinkWorker::run() m_sink->getMessageQueueToGUI()->push(msg); } // Pass to worker to feed to other servers - if (m_sink->getMessageQueueToWorker() && (parity == crc)) + if (m_sink->getMessageQueueToWorker()) { ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create( QByteArray((char*)data, sizeof(data)), diff --git a/plugins/channelrx/demodadsb/adsbdemodsinkworker.h b/plugins/channelrx/demodadsb/adsbdemodsinkworker.h index fe9a295e8..db60e57b8 100644 --- a/plugins/channelrx/demodadsb/adsbdemodsinkworker.h +++ b/plugins/channelrx/demodadsb/adsbdemodsinkworker.h @@ -76,6 +76,7 @@ private: Real m_correlationThresholdLinear; Real m_correlationScale; crcadsb m_crc; //!< Have as member to avoid recomputing LUT + QHash<int, bool> m_icaos; //!< ICAO addresses that have been received QDateTime rxDateTime(int firstIdx, int readBuffer) const;