F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
FprimeProtocol.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title FprimeProtocol.cpp
3 // \author mstarch
4 // \brief cpp file for FprimeProtocol class
5 //
6 // \copyright
7 // Copyright 2009-2022, by the California Institute of Technology.
8 // ALL RIGHTS RESERVED. United States Government Sponsorship
9 // acknowledged.
10 //
11 // ======================================================================
12 #include "FprimeProtocol.hpp"
13 #include "Fw/FPrimeBasicTypes.hpp"
14 #include "Utils/Hash/Hash.hpp"
15 
16 namespace Svc {
17 
19 
21 
22 void FprimeFraming::frame(const U8* const data, const U32 size, Fw::ComPacket::ComPacketType packet_type) {
23  // NOTE: packet_type is not used in this implementation
24 
25  FW_ASSERT(data != nullptr);
26  FW_ASSERT(m_interface != nullptr);
27 
29  Fw::Buffer buffer = m_interface->allocate(totalSize);
30  auto serializer = buffer.getSerializer();
31  Utils::HashBuffer hash;
32 
33  // Serialize start word
34  Fw::SerializeStatus status;
35  status = serializer.serialize(FpFrameHeader::START_WORD);
36  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
37 
38  // Serialize data size
39  status = serializer.serialize(size);
40  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
41 
42  // Serialize data
43  status = serializer.serialize(data, size, true); // Serialize without length
44  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
45 
46  // Calculate and add transmission hash
47  Utils::Hash::hash(buffer.getData(), static_cast<FwSizeType>(totalSize - HASH_DIGEST_LENGTH), hash);
48  status = serializer.serialize(hash.getBuffAddr(), HASH_DIGEST_LENGTH, true);
49  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
50 
51  buffer.setSize(totalSize);
52 
53  m_interface->send(buffer);
54 }
55 
57  Utils::Hash hash;
58  Utils::HashBuffer hashBuffer;
59  // Initialize the checksum and loop through all bytes calculating it
60  hash.init();
61  for (U32 i = 0; i < size; i++) {
62  U8 byte;
63  const Fw::SerializeStatus status = ring.peek(byte, i);
64  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
65  hash.update(&byte, 1);
66  }
67  hash.final(hashBuffer);
68  // Now loop through the hash digest bytes and check for equality
69  for (U32 i = 0; i < HASH_DIGEST_LENGTH; i++) {
70  U8 calc = static_cast<U8>(hashBuffer.getBuffAddr()[i]);
71  U8 sent = 0;
72  const Fw::SerializeStatus status = ring.peek(sent, size + i);
73  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
74  if (calc != sent) {
75  return false;
76  }
77  }
78  return true;
79 }
80 
82  FpFrameHeader::TokenType start = 0;
83  FpFrameHeader::TokenType size = 0;
84  FW_ASSERT(m_interface != nullptr);
85  // Check for header or ask for more data
87  needed = FpFrameHeader::SIZE;
89  }
90  // Read start value from header
91  Fw::SerializeStatus status = ring.peek(start, 0);
92  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
93  if (start != FpFrameHeader::START_WORD) {
94  // Start word must be valid
96  }
97  // Read size from header
98  status = ring.peek(size, sizeof(FpFrameHeader::TokenType));
99  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
100  const U32 maxU32 = std::numeric_limits<U32>::max();
101  if (size > maxU32 - (FpFrameHeader::SIZE + HASH_DIGEST_LENGTH)) {
102  // Size is too large to process: needed would overflow
104  }
105  needed = (FpFrameHeader::SIZE + size + HASH_DIGEST_LENGTH);
106  // Check frame size
107  const U32 frameSize = size + FpFrameHeader::SIZE + HASH_DIGEST_LENGTH;
108  if (frameSize > ring.get_capacity()) {
109  // Frame size is too large for ring buffer
111  }
112  // Check for enough data to deserialize everything;
113  // otherwise break and wait for more.
114  else if (ring.get_allocated_size() < needed) {
116  }
117  // Check the checksum
118  if (not this->validate(ring, needed - HASH_DIGEST_LENGTH)) {
120  }
121  Fw::Buffer buffer = m_interface->allocate(size);
122  // Some allocators may return buffers larger than requested.
123  // That causes issues in routing; adjust size.
124  FW_ASSERT(buffer.getSize() >= size);
125  buffer.setSize(size);
126  status = ring.peek(buffer.getData(), size, FpFrameHeader::SIZE);
127  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
128  m_interface->route(buffer);
130 }
131 }
void update(const void *const data, const FwSizeType len)
Definition: CRC32.cpp:56
U32 TokenType
Token type for F Prime frame header.
Serialization/Deserialization operation was successful.
abstract class representing a framing protocol
#define HASH_DIGEST_LENGTH
Definition: CRC32.hpp:18
virtual void route(Fw::Buffer &data)=0
send deframed data into the system
PlatformSizeType FwSizeType
DeframingProtocolInterface * m_interface
SerializeStatus serialize(U8 val)
serialize 8-bit unsigned int
void setSize(SizeType size)
Definition: Buffer.cpp:87
U8 * getData() const
Definition: Buffer.cpp:68
void init()
Definition: CRC32.cpp:50
SerializeStatus
forward declaration for string
void final(HashBuffer &buffer)
Definition: CRC32.cpp:67
void frame(const U8 *const data, const U32 size, Fw::ComPacket::ComPacketType packet_type) override
Implements the frame method.
Header size for F Prime frame header.
Abstract base class representing a deframing protocol.
const TokenType START_WORD
The start word for F Prime framing.
FprimeDeframing()
Constructor.
FprimeFraming()
Constructor.
A generic interface for creating and comparing hash values.
Definition: Hash.hpp:24
DeframingStatus deframe(Types::CircularBuffer &buffer, U32 &needed) override
FwSizeType get_allocated_size() const
virtual Fw::Buffer allocate(const U32 size)=0
called to allocate memory, typically delegating to an allocate port call
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:56
FwSizeType get_capacity() const
virtual void send(Fw::Buffer &outgoing)=0
send framed data out of the framer
DeframingStatus
Status of the deframing call.
static void hash(const void *data, const FwSizeType len, HashBuffer &buffer)
Definition: CRC32.cpp:32
FramingProtocolInterface * m_interface
Fw::SerializeStatus peek(char &value, FwSizeType offset=0) const
A container class for holding a hash buffer.
Definition: HashBuffer.hpp:26
RateGroupDivider component implementation.
SizeType getSize() const
Definition: Buffer.cpp:72
ExternalSerializeBufferWithMemberCopy getSerializer()
Definition: Buffer.cpp:107
#define FW_ASSERT(...)
Definition: Assert.hpp:14
virtual Fw::Buffer allocate(const U32 size)=0
allocation callback to allocate memory when framing
bool validate(Types::CircularBuffer &buffer, U32 size)