F´ Flight Software - C/C++ Documentation  NASA-v1.6.0
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 
13 #include <limits>
14 
15 #include "FprimeProtocol.hpp"
16 #include "Utils/Hash/Hash.hpp"
17 
18 namespace Svc {
19 
21 
23 
24 void FprimeFraming::frame(const U8* const data, const U32 size, Fw::ComPacket::ComPacketType packet_type) {
25  FW_ASSERT(data != nullptr);
26  FW_ASSERT(m_interface != nullptr);
27  // Use of I32 size is explicit as ComPacketType will be specifically serialized as an I32
28  FpFrameHeader::TokenType real_data_size = size + ((packet_type != Fw::ComPacket::FW_PACKET_UNKNOWN) ? sizeof(I32) : 0);
30  Fw::Buffer buffer = m_interface->allocate(total);
31  Fw::SerializeBufferBase& serializer = buffer.getSerializeRepr();
32  Utils::HashBuffer hash;
33 
34  // Serialize data
35  Fw::SerializeStatus status;
36  status = serializer.serialize(FpFrameHeader::START_WORD);
37  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
38 
39  status = serializer.serialize(real_data_size);
40  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
41 
42  // Serialize packet type if supplied, otherwise it *must* be present in the data
43  if (packet_type != Fw::ComPacket::FW_PACKET_UNKNOWN) {
44  status = serializer.serialize(static_cast<I32>(packet_type)); // I32 used for enum storage
45  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
46  }
47 
48  status = serializer.serialize(data, size, true); // Serialize without length
49  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
50 
51  // Calculate and add transmission hash
52  Utils::Hash::hash(buffer.getData(), total - HASH_DIGEST_LENGTH, hash);
53  status = serializer.serialize(hash.getBuffAddr(), HASH_DIGEST_LENGTH, true);
54  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
55 
56  buffer.setSize(total);
57 
58  m_interface->send(buffer);
59 }
60 
62  Utils::Hash hash;
63  Utils::HashBuffer hashBuffer;
64  // Initialize the checksum and loop through all bytes calculating it
65  hash.init();
66  for (U32 i = 0; i < size; i++) {
67  char byte;
68  ring.peek(byte, i);
69  hash.update(&byte, 1);
70  }
71  hash.final(hashBuffer);
72  // Now loop through the hash digest bytes and check for equality
73  for (U32 i = 0; i < HASH_DIGEST_LENGTH; i++) {
74  char calc = static_cast<char>(hashBuffer.getBuffAddr()[i]);
75  char sent = 0;
76  ring.peek(sent, size + i);
77  if (calc != sent) {
78  return false;
79  }
80  }
81  return true;
82 }
83 
85  FpFrameHeader::TokenType start = 0;
86  FpFrameHeader::TokenType size = 0;
87  FW_ASSERT(m_interface != nullptr);
88  // Check for header or ask for more data
90  needed = FpFrameHeader::SIZE;
92  }
93  // Read start value from header
94  Fw::SerializeStatus status = ring.peek(start, 0);
95  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
96  if (start != FpFrameHeader::START_WORD) {
97  // Start word must be valid
99  }
100  // Read size from header
101  status = ring.peek(size, sizeof(FpFrameHeader::TokenType));
102  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
103  const U32 maxU32 = std::numeric_limits<U32>::max();
104  if (size > maxU32 - (FpFrameHeader::SIZE + HASH_DIGEST_LENGTH)) {
105  // Size is too large to process: needed would overflow
107  }
108  needed = (FpFrameHeader::SIZE + size + HASH_DIGEST_LENGTH);
109  // Check frame size
110  const U32 frameSize = size + FpFrameHeader::SIZE + HASH_DIGEST_LENGTH;
111  if (frameSize > ring.get_capacity()) {
112  // Frame size is too large for ring buffer
114  }
115  // Check for enough data to deserialize everything;
116  // otherwise break and wait for more.
117  else if (ring.get_allocated_size() < needed) {
119  }
120  // Check the checksum
121  if (not this->validate(ring, needed - HASH_DIGEST_LENGTH)) {
123  }
124  Fw::Buffer buffer = m_interface->allocate(size);
125  // Some allocators may return buffers larger than requested.
126  // That causes issues in routing; adjust size.
127  FW_ASSERT(buffer.getSize() >= size);
128  buffer.setSize(size);
129  ring.peek(buffer.getData(), size, FpFrameHeader::SIZE);
130  m_interface->route(buffer);
132 }
133 };
Svc::DeframingProtocolInterface::route
virtual void route(Fw::Buffer &data)=0
send deframed data into the system
Svc::FpFrameHeader::START_WORD
const TokenType START_WORD
The start word for F Prime framing.
Definition: FprimeProtocol.hpp:33
Svc::DeframingProtocol::DEFRAMING_MORE_NEEDED
@ DEFRAMING_MORE_NEEDED
Definition: DeframingProtocol.hpp:43
Fw::SerializeBufferBase
Definition: Serializable.hpp:43
Fw::SerializeStatus
SerializeStatus
forward declaration for string
Definition: Serializable.hpp:14
Fw::ComPacket::FW_PACKET_UNKNOWN
@ FW_PACKET_UNKNOWN
Definition: ComPacket.hpp:28
Svc::FramingProtocol::m_interface
FramingProtocolInterface * m_interface
Definition: FramingProtocol.hpp:49
Fw::Buffer::getData
U8 * getData() const
Definition: Buffer.cpp:60
Fw::SerializeBufferBase::serialize
SerializeStatus serialize(U8 val)
serialize 8-bit unsigned int
Definition: Serializable.cpp:69
Svc::FprimeDeframing::FprimeDeframing
FprimeDeframing()
Constructor.
Definition: FprimeProtocol.cpp:22
U8
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.hpp:73
Utils::Hash::init
void init()
Definition: CRC32.cpp:47
Svc::DeframingProtocol::DEFRAMING_INVALID_CHECKSUM
@ DEFRAMING_INVALID_CHECKSUM
Definition: DeframingProtocol.hpp:42
Utils::Hash::final
void final(HashBuffer &buffer)
Definition: CRC32.cpp:64
Svc::FramingProtocolInterface::send
virtual void send(Fw::Buffer &outgoing)=0
send framed data out of the framer
Fw::Buffer
Definition: Buffer.hpp:43
Svc::FpFrameHeader::SIZE
@ SIZE
Header size for F Prime frame header.
Definition: FprimeProtocol.hpp:29
Svc::FprimeDeframing::deframe
DeframingStatus deframe(Types::CircularBuffer &buffer, U32 &needed) override
Definition: FprimeProtocol.cpp:84
Svc::DeframingProtocol::m_interface
DeframingProtocolInterface * m_interface
Definition: DeframingProtocol.hpp:63
Utils::HashBuffer
A container class for holding a hash buffer.
Definition: HashBuffer.hpp:26
Fw::Buffer::getSerializeRepr
SerializeBufferBase & getSerializeRepr()
Definition: Buffer.cpp:99
HASH_DIGEST_LENGTH
#define HASH_DIGEST_LENGTH
Definition: CRC32.hpp:18
Types::CircularBuffer::get_allocated_size
NATIVE_UINT_TYPE get_allocated_size() const
Definition: CircularBuffer.cpp:34
Svc::DeframingProtocol::DEFRAMING_STATUS_SUCCESS
@ DEFRAMING_STATUS_SUCCESS
Definition: DeframingProtocol.hpp:40
Fw::Buffer::getSize
U32 getSize() const
Definition: Buffer.cpp:64
Svc::FpFrameHeader::TokenType
U32 TokenType
Token type for F Prime frame header.
Definition: FprimeProtocol.hpp:25
Hash.hpp
Types::CircularBuffer::get_capacity
NATIVE_UINT_TYPE get_capacity() const
Definition: CircularBuffer.cpp:124
Svc::FramingProtocolInterface::allocate
virtual Fw::Buffer allocate(const U32 size)=0
allocation callback to allocate memory when framing
Fw::Buffer::setSize
void setSize(U32 size)
Definition: Buffer.cpp:79
Types::CircularBuffer::peek
Fw::SerializeStatus peek(char &value, NATIVE_UINT_TYPE offset=0) const
Definition: CircularBuffer.cpp:66
FprimeProtocol.hpp
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:9
Utils::Hash
A generic interface for creating and comparing hash values.
Definition: Hash.hpp:24
Svc::DeframingProtocolInterface::allocate
virtual Fw::Buffer allocate(const U32 size)=0
called to allocate memory, typically delegating to an allocate port call
Svc::DeframingProtocol::DeframingStatus
DeframingStatus
Status of the deframing call.
Definition: DeframingProtocol.hpp:39
Svc::FprimeFraming::FprimeFraming
FprimeFraming()
Constructor.
Definition: FprimeProtocol.cpp:20
Svc::FramingProtocol
abstract class representing a framing protocol
Definition: FramingProtocol.hpp:31
Utils::HashBuffer::getBuffAddr
U8 * getBuffAddr()
Definition: HashBufferCommon.cpp:44
Utils::Hash::update
void update(const void *const data, const NATIVE_INT_TYPE len)
Definition: CRC32.cpp:53
Svc
Definition: ActiveRateGroupCfg.hpp:18
Svc::DeframingProtocol
Abstract base class representing a deframing protocol.
Definition: DeframingProtocol.hpp:33
Fw::ComPacket::ComPacketType
ComPacketType
Definition: ComPacket.hpp:21
Svc::FprimeDeframing::validate
bool validate(Types::CircularBuffer &buffer, U32 size)
Definition: FprimeProtocol.cpp:61
Types::CircularBuffer
Definition: CircularBuffer.hpp:28
Svc::DeframingProtocol::DEFRAMING_INVALID_SIZE
@ DEFRAMING_INVALID_SIZE
Definition: DeframingProtocol.hpp:41
Svc::DeframingProtocol::DEFRAMING_INVALID_FORMAT
@ DEFRAMING_INVALID_FORMAT
Definition: DeframingProtocol.hpp:44
Utils::Hash::hash
static void hash(const void *data, const NATIVE_INT_TYPE len, HashBuffer &buffer)
Definition: CRC32.cpp:29
Fw::FW_SERIALIZE_OK
@ FW_SERIALIZE_OK
Serialization/Deserialization operation was successful.
Definition: Serializable.hpp:15
Svc::FprimeFraming::frame
void frame(const U8 *const data, const U32 size, Fw::ComPacket::ComPacketType packet_type) override
Implements the frame method.
Definition: FprimeProtocol.cpp:24