F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
FprimeFrameDetector.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title FprimeFrameDetector.hpp
3 // \author thomas-bc
4 // \brief hpp file for fprime frame detector definitions
5 // ======================================================================
6 
8 
9 namespace Svc {
10 namespace FrameDetectors {
11 
13  // If not enough data for header + trailer, report MORE_DATA_NEEDED
14  if (data.get_allocated_size() <
17  return Status::MORE_DATA_NEEDED;
18  }
19 
20  // NOTE: it is understood and accepted that the following code is not as efficient as it could technically be
21  // We are leveraging the FPP autocoded types to do the deserialization for us.
22  // In its current implementation, CircularBuffer is not a SerializeBufferBase, which prevents us from deserializing
23  // directly from the CircularBuffer into FrameHeader/FrameTrailer. Instead, we have to copy the data into
24  // a temporary SerializeBuffer, and then deserialize from that buffer into the FrameHeader/FrameTrailer objects.
25  // A better implementation would be to have CircularBuffer implement a shared interface with SerializeBufferBase,
26  // and then we could pass the CircularBuffer directly into the FrameHeader/FrameTrailer deserializers. This is left
27  // as a TODO for future improvement as it is a significant refactor
28 
31 
32  // ---------------- Frame Header ----------------
33  // Copy CircularBuffer data into linear buffer, for serialization into FrameHeader object
36  if (status != Fw::FW_SERIALIZE_OK) {
37  return Status::NO_FRAME_DETECTED;
38  }
40  status = header_ser_buffer.setBuffLen(FprimeProtocol::FrameHeader::SERIALIZED_SIZE);
41  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
42  // Attempt to deserialize data into the FrameHeader object
43  status = header.deserialize(header_ser_buffer);
44  if (status != Fw::FW_SERIALIZE_OK) {
45  return Status::NO_FRAME_DETECTED;
46  }
47  // Check that deserialized start_word token matches expected value (default start_word value in the FPP object)
48  FprimeProtocol::FrameHeader default_value;
49  if (header.getstartWord() != default_value.getstartWord()) {
50  return Status::NO_FRAME_DETECTED;
51  }
52  // We expect the frame size to be size of header + body (of size specified in header) + trailer
53  const FwSizeType expected_frame_size = FprimeProtocol::FrameHeader::SERIALIZED_SIZE + header.getlengthField() +
55  // If the current allocated size can't hold the expected_frame_size -> MORE_DATA_NEEDED
56  if (data.get_allocated_size() < expected_frame_size) {
57  size_out = expected_frame_size;
58  return Status::MORE_DATA_NEEDED;
59  }
60 
61  // ---------------- Frame Trailer ----------------
64  status = data.peek(trailer_data, FprimeProtocol::FrameTrailer::SERIALIZED_SIZE,
66  if (status != Fw::FW_SERIALIZE_OK) {
67  return Status::NO_FRAME_DETECTED;
68  }
69  status = trailer_ser_buffer.setBuffLen(FprimeProtocol::FrameTrailer::SERIALIZED_SIZE);
70  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
71  // Deserialize trailer from circular buffer (peeked data) into trailer object
72  status = trailer.deserialize(trailer_ser_buffer);
73  if (status != Fw::FW_SERIALIZE_OK) {
74  return Status::NO_FRAME_DETECTED;
75  }
76 
77  Utils::Hash hash;
78  Utils::HashBuffer hashBuffer;
79  // Compute CRC over the transmitted data (header + body)
81  hash.init();
82  for (U32 i = 0; i < hash_field_size; i++) {
83  U8 byte = 0;
84  status = data.peek(byte, i);
85  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
86  hash.update(&byte, 1);
87  }
88  hash.final(hashBuffer);
89 
90  // Compare the transmitted CRC with the computed one
91  if (trailer.getcrcField() != hashBuffer.asBigEndianU32()) {
92  // CRC mismatch - there likely was data corruption. The F Prime protocol
93  // being very simple, we don't have a way to recover from this.
94  // So we report NO_FRAME_DETECTED and drop the frame
95  return Status::NO_FRAME_DETECTED;
96  }
97  // All checks passed - we have detected a frame of size expected_frame_size
98  size_out = expected_frame_size;
99  return Status::FRAME_DETECTED;
100 }
101 
102 } // namespace FrameDetectors
103 } // namespace Svc
void update(const void *const data, const FwSizeType len)
Definition: CRC32.cpp:56
Serialization/Deserialization operation was successful.
PlatformSizeType FwSizeType
Svc::FprimeProtocol::TokenType getstartWord() const
Get member startWord.
U32 getcrcField() const
Get member crcField.
Status detect(const Types::CircularBuffer &data, FwSizeType &size_out) const override
detect if a frame is available within the circular buffer
void init()
Definition: CRC32.cpp:50
Describes the frame header format for the F Prime communications protocol.
SerializeStatus
forward declaration for string
void final(HashBuffer &buffer)
Definition: CRC32.cpp:67
Status
status returned from the detection step
Svc::FprimeProtocol::TokenType getlengthField() const
Get member lengthField.
External serialize buffer with no copy semantics.
Fw::SerializeStatus deserialize(Fw::SerializeBufferBase &buffer)
Deserialization.
A generic interface for creating and comparing hash values.
Definition: Hash.hpp:24
FwSizeType get_allocated_size() const
Describes the frame trailer format for the F Prime communications protocol.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:56
Fw::SerializeStatus peek(char &value, FwSizeType offset=0) const
U32 asBigEndianU32() const
Convert bytes 0 through 3 of the hash data to a big-Endian U32 value.
A container class for holding a hash buffer.
Definition: HashBuffer.hpp:26
Fw::SerializeStatus deserialize(Fw::SerializeBufferBase &buffer)
Deserialization.
RateGroupDivider component implementation.
#define FW_ASSERT(...)
Definition: Assert.hpp:14
SerializeStatus setBuffLen(Serializable::SizeType length)
sets buffer length manually after filling with data