diff --git a/src/common/p25/data/DataHeader.cpp b/src/common/p25/data/DataHeader.cpp index 41ca2322..cb660010 100644 --- a/src/common/p25/data/DataHeader.cpp +++ b/src/common/p25/data/DataHeader.cpp @@ -37,6 +37,16 @@ using namespace p25; #include #include +// --------------------------------------------------------------------------- +// Static Class Members +// --------------------------------------------------------------------------- + +#if FORCE_TSBK_CRC_WARN +bool DataHeader::m_warnCRC = true; +#else +bool DataHeader::m_warnCRC = false; +#endif + // --------------------------------------------------------------------------- // Public Class Members // --------------------------------------------------------------------------- @@ -100,8 +110,25 @@ bool DataHeader::decode(const uint8_t* data, bool noTrellis) else { valid = m_trellis.decode12(data, m_data); } - if (valid) + + if (valid) { valid = edac::CRC::checkCCITT162(m_data, P25_PDU_HEADER_LENGTH_BYTES); + if (!valid) { + if (m_warnCRC) { + // if we're already warning instead of erroring CRC, don't announce invalid CRC in the + // case where no CRC is defined + if ((m_data[P25_PDU_HEADER_LENGTH_BYTES - 2U] != 0x00U) && (m_data[P25_PDU_HEADER_LENGTH_BYTES - 1U] != 0x00U)) { + LogWarning(LOG_P25, "DataHeader::decode(), failed CRC CCITT-162 check"); + } + + valid = true; // ignore CRC error + } + else { + LogError(LOG_P25, "DataHeader::decode(), failed CRC CCITT-162 check"); + } + } + } + if (!valid) { return false; } @@ -253,6 +280,8 @@ void DataHeader::encode(uint8_t* data, bool noTrellis) if (!noTrellis) { // encode 1/2 rate Trellis m_trellis.encode12(header, data); + } else { + ::memcpy(data, header, P25_PDU_HEADER_LENGTH_BYTES); } } diff --git a/src/common/p25/data/DataHeader.h b/src/common/p25/data/DataHeader.h index 09ffc577..6346c662 100644 --- a/src/common/p25/data/DataHeader.h +++ b/src/common/p25/data/DataHeader.h @@ -71,6 +71,9 @@ namespace p25 /// Gets the count of block padding. uint8_t getPadCount() const; + /// Sets the flag indicating CRC-errors should be warnings and not errors. + static void setWarnCRC(bool warnCRC) { m_warnCRC = warnCRC; } + public: /// Flag indicating if acknowledgement is needed. __PROPERTY(bool, ackNeeded, AckNeeded); @@ -124,6 +127,8 @@ namespace p25 uint32_t m_dataOctets; uint8_t* m_data; + + static bool m_warnCRC; }; } // namespace data } // namespace p25 diff --git a/src/common/p25/lc/TSBK.cpp b/src/common/p25/lc/TSBK.cpp index ab5b1b04..9192ab55 100644 --- a/src/common/p25/lc/TSBK.cpp +++ b/src/common/p25/lc/TSBK.cpp @@ -229,7 +229,12 @@ bool TSBK::decode(const uint8_t* data, uint8_t* payload, bool rawTSBK) bool ret = edac::CRC::checkCCITT162(tsbk, P25_TSBK_LENGTH_BYTES); if (!ret) { if (m_warnCRC) { - LogWarning(LOG_P25, "TSBK::decode(), failed CRC CCITT-162 check"); + // if we're already warning instead of erroring CRC, don't announce invalid CRC in the + // case where no CRC is defined + if ((tsbk[P25_TSBK_LENGTH_BYTES - 2U] != 0x00U) && (tsbk[P25_TSBK_LENGTH_BYTES - 1U] != 0x00U)) { + LogWarning(LOG_P25, "TSBK::decode(), failed CRC CCITT-162 check"); + } + ret = true; // ignore CRC error } else { diff --git a/src/common/p25/lc/tsbk/OSP_RFSS_STS_BCAST.cpp b/src/common/p25/lc/tsbk/OSP_RFSS_STS_BCAST.cpp index fd5900f2..c294a07a 100644 --- a/src/common/p25/lc/tsbk/OSP_RFSS_STS_BCAST.cpp +++ b/src/common/p25/lc/tsbk/OSP_RFSS_STS_BCAST.cpp @@ -42,7 +42,8 @@ using namespace p25; /// /// Initializes a new instance of the OSP_RFSS_STS_BCAST class. /// -OSP_RFSS_STS_BCAST::OSP_RFSS_STS_BCAST() : TSBK() +OSP_RFSS_STS_BCAST::OSP_RFSS_STS_BCAST() : TSBK(), + m_roamerReaccess(false) { m_lco = TSBK_OSP_RFSS_STS_BCAST; } @@ -76,7 +77,8 @@ void OSP_RFSS_STS_BCAST::encode(uint8_t* data, bool rawTSBK, bool noTrellis) tsbkValue = m_siteData.lra(); // Location Registration Area tsbkValue = (tsbkValue << 4) + - (m_siteData.netActive()) ? P25_CFVA_NETWORK : 0U; // CFVA + (m_roamerReaccess) ? 0x02U : 0x00U + // Roamer Reaccess Method + (m_siteData.netActive()) ? 0x01U : 0x00U; // Network Active tsbkValue = (tsbkValue << 12) + m_siteData.sysId(); // System ID tsbkValue = (tsbkValue << 8) + m_siteData.rfssId(); // RF Sub-System ID tsbkValue = (tsbkValue << 8) + m_siteData.siteId(); // Site ID diff --git a/src/common/p25/lc/tsbk/OSP_RFSS_STS_BCAST.h b/src/common/p25/lc/tsbk/OSP_RFSS_STS_BCAST.h index 38c7d207..d9becc98 100644 --- a/src/common/p25/lc/tsbk/OSP_RFSS_STS_BCAST.h +++ b/src/common/p25/lc/tsbk/OSP_RFSS_STS_BCAST.h @@ -52,6 +52,10 @@ namespace p25 /// Returns a string that represents the current TSBK. virtual std::string toString(bool isp = false) override; + + public: + /// Roamer Reaccess Method. + __PROPERTY(bool, roamerReaccess, RoamerReaccess); }; } // namespace tsbk } // namespace lc diff --git a/src/common/p25/lc/tsbk/TSBKFactory.cpp b/src/common/p25/lc/tsbk/TSBKFactory.cpp index 5129a7a8..5babd777 100644 --- a/src/common/p25/lc/tsbk/TSBKFactory.cpp +++ b/src/common/p25/lc/tsbk/TSBKFactory.cpp @@ -86,11 +86,16 @@ std::unique_ptr TSBKFactory::createTSBK(const uint8_t* data, bool rawTSBK) bool ret = edac::CRC::checkCCITT162(tsbk, P25_TSBK_LENGTH_BYTES); if (!ret) { if (m_warnCRC) { - LogWarning(LOG_P25, "TSBK::decode(), failed CRC CCITT-162 check"); + // if we're already warning instead of erroring CRC, don't announce invalid CRC in the + // case where no CRC is defined + if ((tsbk[P25_TSBK_LENGTH_BYTES - 2U] != 0x00U) && (tsbk[P25_TSBK_LENGTH_BYTES - 1U] != 0x00U)) { + LogWarning(LOG_P25, "TSBKFactory::createTSBK(), failed CRC CCITT-162 check"); + } + ret = true; // ignore CRC error } else { - LogError(LOG_P25, "TSBK::decode(), failed CRC CCITT-162 check"); + LogError(LOG_P25, "TSBKFactory::createTSBK(), failed CRC CCITT-162 check"); } } } @@ -103,18 +108,18 @@ std::unique_ptr TSBKFactory::createTSBK(const uint8_t* data, bool rawTSBK) try { bool ret = trellis.decode12(raw, tsbk); if (!ret) { - LogError(LOG_P25, "TSBK::decode(), failed to decode Trellis 1/2 rate coding"); + LogError(LOG_P25, "TSBKFactory::createTSBK(), failed to decode Trellis 1/2 rate coding"); } if (ret) { ret = edac::CRC::checkCCITT162(tsbk, P25_TSBK_LENGTH_BYTES); if (!ret) { if (m_warnCRC) { - LogWarning(LOG_P25, "TSBK::decode(), failed CRC CCITT-162 check"); + LogWarning(LOG_P25, "TSBKFactory::createTSBK(), failed CRC CCITT-162 check"); ret = true; // ignore CRC error } else { - LogError(LOG_P25, "TSBK::decode(), failed CRC CCITT-162 check"); + LogError(LOG_P25, "TSBKFactory::createTSBK(), failed CRC CCITT-162 check"); } } } @@ -155,7 +160,7 @@ std::unique_ptr TSBKFactory::createTSBK(const uint8_t* data, bool rawTSBK) mfId = P25_MFG_STANDARD; break; default: - LogError(LOG_P25, "TSBK::decode(), unknown TSBK LCO value, mfId = $%02X, lco = $%02X", mfId, lco); + LogError(LOG_P25, "TSBKFactory::createTSBK(), unknown TSBK LCO value, mfId = $%02X, lco = $%02X", mfId, lco); break; }