diff --git a/Svc/FrameAccumulator/FrameDetector/CCSDSFrameDetector.hpp b/Svc/FrameAccumulator/FrameDetector/CCSDSFrameDetector.hpp index a6ec26d2e1..5272c220c6 100644 --- a/Svc/FrameAccumulator/FrameDetector/CCSDSFrameDetector.hpp +++ b/Svc/FrameAccumulator/FrameDetector/CCSDSFrameDetector.hpp @@ -44,11 +44,16 @@ static_assert(CCSDS_SCID <= (std::numeric_limits::max() & TEN_BIT_MASK), "S //! - 1 bit of control command flag "0" //! - 2 bits of reserved "00" //! - 10 bits of configurable SCID -using CCSDSStartWord = StartToken(0 | (CCSDS_SCID & TEN_BIT_MASK))>; +using CCSDSStartWord = StartToken(0 | (CCSDS_SCID & TEN_BIT_MASK)), TEN_BIT_MASK>; //! CCSDS length is the last 10 bits of the 3rd and 4th octet using CCSDSLength = LengthToken; -//! CCSDS checksum is a 16bit CRC with data starting at the 6th octet and the crc following directly -using CCSDSChecksum = CRC; +//! CCSDS checksum is a 16bit CRC which is calculated from the first bit in the transfer frame up to (but not including) +//! the Frame Error Control field (aka the crc U16 itself) as per CCSDS 232.0-B-4 4.1.4.2 +//! When we perform the calculation during detection we do so by passing the length (found using the Length token) +//! The Frame Length is set as one fewer than the total octets in the Transfer Frame as per CCSDS 232.0-B-4 4.1.4.2 +//! Therefore if we're calculating a CRC check on a frame which itself includes a CRC check we need to offset by +//! another 1 fewer than what the frame length describes. +using CCSDSChecksum = CRC; //! CCSDS frame detector is a start/length/crc detector using the configured fprime tokens using CCSDSFrameDetector = StartLengthCrcDetector; diff --git a/Svc/FrameAccumulator/FrameDetector/StartLengthCrcDetector.hpp b/Svc/FrameAccumulator/FrameDetector/StartLengthCrcDetector.hpp index 45cbbf9466..685b1b2b09 100644 --- a/Svc/FrameAccumulator/FrameDetector/StartLengthCrcDetector.hpp +++ b/Svc/FrameAccumulator/FrameDetector/StartLengthCrcDetector.hpp @@ -133,6 +133,9 @@ class StartToken : public Token { } return status; } + TokenType getExpectedStart() { + return StartExpected & TokenMask; + } }; //! \breif token representing data length @@ -225,9 +228,10 @@ class CRC32 : public CRCWrapper { //! \tparam CRCFn: function for updating CRC with new byte template -class CRC : public Token::max(), BIG> { + FwNativeIntType RelativeTokenOffset = 0, + class CRCHandler = CRC32, + TokenType TokenMask = std::numeric_limits::max()> +class CRC : public Token { public: // Check CRC token and CRC handler match static_assert(std::is_base_of, CRCHandler>::value, "Invalid CRC wrapper supplied"); @@ -246,12 +250,12 @@ class CRC : public Token::max(), BIG> //! \return: FRAME_DETECTED, or MORE_DATA_NEEDED. FrameDetector::Status calculate(const Types::CircularBuffer& data, FwSizeType length, FwSizeType& size_out) { const FwSizeType checksum_length = DataOffset + length + RelativeTokenOffset; - size_out = checksum_length; CRCHandler crc; // Loop byte by byte - for (FwSizeType i = 0; i < checksum_length; i++) { + for (size_out = 0; size_out < checksum_length; size_out++) { U8 byte = 0; - Fw::SerializeStatus status = data.peek(byte, i); + Fw::SerializeStatus status = data.peek(byte, size_out); + if (status != Fw::SerializeStatus::FW_SERIALIZE_OK) { this->m_stored_offset = 0; return FrameDetector::Status::MORE_DATA_NEEDED; @@ -276,13 +280,15 @@ class CRC : public Token::max(), BIG> FW_ASSERT(this->m_stored_offset != 0); // Must have called calculate before calling read size_out = this->m_stored_offset; FrameDetector::Status status = - this->Token::max(), BIG>::read(data, size_out, size_out); + this->Token::read(data, size_out, size_out); if ((status == FrameDetector::FRAME_DETECTED) && (this->m_value != this->m_expected)) { status = FrameDetector::NO_FRAME_DETECTED; } return status; } - + TokenType getExpected() { + return m_expected; + } protected: FwSizeType m_stored_offset; TokenType m_expected;