F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
CcsdsTcFrameDetector.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title CcsdsTcFrameDetector.hpp
3 // \author thomas-bc
4 // \brief hpp file for fprime frame detector definitions
5 // ======================================================================
6 
8 #include <cstdio>
13 #include "Utils/Hash/Hash.hpp"
15 
16 namespace Svc {
17 namespace FrameDetectors {
18 
22  return Status::MORE_DATA_NEEDED;
23  }
24 
25  // ---------------- Frame Header ----------------
26  // Copy CircularBuffer data into linear buffer, for serialization into FrameHeader object
28  Fw::SerializeStatus status = data.peek(header_data, Ccsds::TCHeader::SERIALIZED_SIZE, 0);
29  if (status != Fw::FW_SERIALIZE_OK) {
30  return Status::NO_FRAME_DETECTED;
31  }
32  Fw::ExternalSerializeBuffer header_ser_buffer(header_data, Ccsds::TCHeader::SERIALIZED_SIZE);
33  status = header_ser_buffer.setBuffLen(Ccsds::TCHeader::SERIALIZED_SIZE);
34  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
35  // Attempt to deserialize data into the FrameHeader object
36  Ccsds::TCHeader header;
37  status = header.deserializeFrom(header_ser_buffer);
38  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
39 
40  if (header.get_flagsAndScId() != this->m_expectedFlagsAndScIdToken) {
41  // If the flags and SC ID do not match the expected token, we don't have a valid frame
42  return Status::NO_FRAME_DETECTED;
43  }
44  // TC protocol defines the Frame Length as number of bytes minus 1, so we add 1 back to get length in bytes
45  const FwSizeType expected_frame_length =
47 
48  // If the full frame is not yet available, report that more data is needed
49  if (data.get_allocated_size() < expected_frame_length) {
50  size_out = expected_frame_length;
51  return Status::MORE_DATA_NEEDED;
52  }
53  // Validate minimum frame size BEFORE computing data_to_crc_length.
54  // If expected_frame_length < TRAILER_SIZE the subtraction below would underflow to a
55  // near-maximum value, causing the CRC loop to read far beyond the valid frame data.
57  return Status::NO_FRAME_DETECTED;
58  }
59  // Safe: the guard above guarantees expected_frame_length >= TRAILER_SIZE, so this
60  // subtraction cannot underflow. Type is FwSizeType (not U16) to avoid silent truncation
61  // if expected_frame_length ever exceeds 65535.
62  const FwSizeType data_to_crc_length = expected_frame_length - Ccsds::TCTrailer::SERIALIZED_SIZE;
63 
64  // ---------------- Frame Trailer ----------------
65  // Compute CRC on the received data
67  for (FwSizeType i = 0; i < data_to_crc_length; ++i) {
68  U8 byte = 0;
69  status = data.peek(byte, i);
70  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
71  crc.update(byte);
72  }
73  U16 computed_fecf = crc.finalize();
74  // Retrieve CRC field from the trailer
76  status = data.peek(trailer_data, Ccsds::TCTrailer::SERIALIZED_SIZE, data_to_crc_length);
77  if (status != Fw::FW_SERIALIZE_OK) {
78  return Status::NO_FRAME_DETECTED;
79  }
80  Fw::ExternalSerializeBuffer trailer_ser_buffer(trailer_data, Ccsds::TCTrailer::SERIALIZED_SIZE);
81  status = trailer_ser_buffer.setBuffLen(Ccsds::TCTrailer::SERIALIZED_SIZE);
82  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
83  // Attempt to deserialize data into the FrameTrailer object
84  Ccsds::TCTrailer trailer;
85  status = trailer.deserializeFrom(trailer_ser_buffer);
86  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
87  U16 transmitted_fecf = trailer.get_fecf();
88  if (transmitted_fecf != computed_fecf) {
89  // If the computed CRC does not match the transmitted CRC, we don't have a valid frame
90  return Status::NO_FRAME_DETECTED;
91  }
92  // At this point, we have validated the header and CRC - we report a valid frame detected
93  size_out = expected_frame_length;
94  return Status::FRAME_DETECTED;
95 }
96 
97 } // namespace FrameDetectors
98 } // namespace Svc
Serialization/Deserialization operation was successful.
PlatformSizeType FwSizeType
CRC16 CCITT implementation.
Definition: CRC16.hpp:18
U16 finalize()
finalize and return CRC value
Definition: CRC16.hpp:31
SerializeStatus
forward declaration for string
Describes the frame trailer format for a Telecommand (TC) Transfer Frame.
Status detect(const Types::CircularBuffer &data, FwSizeType &size_out) const override
detect if a frame is available within the circular buffer
Fw::SerializeStatus deserializeFrom(Fw::SerialBufferBase &buffer, Fw::Endianness mode=Fw::Endianness::BIG)
Deserialization.
Status
status returned from the detection step
U16 get_flagsAndScId() const
Get member flagsAndScId.
const U16 m_expectedFlagsAndScIdToken
expected flags and spacecraft ID token for a valid CCSDS TC frame
U16 get_fecf() const
Get member fecf.
External serialize buffer with no copy semantics.
Describes the frame header format for a Telecommand (TC) Transfer Frame.
U16 get_vcIdAndLength() const
Get member vcIdAndLength.
FwSizeType get_allocated_size() const
Fw::SerializeStatus deserializeFrom(Fw::SerialBufferBase &buffer, Fw::Endianness mode=Fw::Endianness::BIG)
Deserialization.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:53
The size of the serial representation.
Fw::SerializeStatus peek(char &value, FwSizeType offset=0) const
void update(U8 new_byte)
update CRC with one new byte
Definition: CRC16.hpp:28
RateGroupDivider component implementation.
SerializeStatus setBuffLen(Serializable::SizeType length) override
Set buffer length manually.
The size of the serial representation.
#define FW_ASSERT(...)
Definition: Assert.hpp:14