F´ Flight Software - C/C++ Documentation  NASA-v1.6.0
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-2021, by the California Institute of Technology.
8 // ALL RIGHTS RESERVED. United States Government Sponsorship
9 // acknowledged.
10 //
11 // ======================================================================
12 
13 #include "FprimeProtocol.hpp"
14 #include "Utils/Hash/Hash.hpp"
15 
16 namespace Svc {
17 
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  FP_FRAME_TOKEN_TYPE 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(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  FP_FRAME_TOKEN_TYPE start = 0;
86  FP_FRAME_TOKEN_TYPE size = 0;
87  FW_ASSERT(m_interface != nullptr);
88  // Check for header or ask for more data
90  needed = FP_FRAME_HEADER_SIZE;
92  }
93  // Peek into the header and read out values
94  Fw::SerializeStatus status = ring.peek(start, 0);
95  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
96  status = ring.peek(size, sizeof(FP_FRAME_TOKEN_TYPE));
97  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
98  needed = (FP_FRAME_HEADER_SIZE + size + HASH_DIGEST_LENGTH);
99  // Check the header for correctness
100  if ((start != FprimeFraming::START_WORD) || (size >= (ring.get_capacity() - FP_FRAME_HEADER_SIZE - HASH_DIGEST_LENGTH))) {
102  }
103  // Check for enough data to deserialize everything otherwise break and wait for more.
104  else if (ring.get_remaining_size() < needed) {
106  }
107  // Check the checksum
108  if (not this->validate(ring, needed - HASH_DIGEST_LENGTH)) {
110  }
111  Fw::Buffer buffer = m_interface->allocate(size);
112  // some allocators may return buffers larger than requested
113  // that causes issues in routing. adjust size
114  FW_ASSERT(buffer.getSize() >= size);
115  buffer.setSize(size);
116  ring.peek(buffer.getData(), size, FP_FRAME_HEADER_SIZE);
117  m_interface->route(buffer);
119 }
120 };
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:67
Svc::FprimeDeframing::FprimeDeframing
FprimeDeframing()
Definition: FprimeProtocol.cpp:22
U8
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.hpp:76
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::FprimeDeframing::deframe
DeframingStatus deframe(Types::CircularBuffer &buffer, U32 &needed)
Definition: FprimeProtocol.cpp:84
Fw::Buffer
Definition: Buffer.hpp:43
Svc::DeframingProtocol::m_interface
DeframingProtocolInterface * m_interface
Definition: DeframingProtocol.hpp:62
Utils::HashBuffer
A container class for holding a hash buffer.
Definition: HashBuffer.hpp:26
Fw::FW_SERIALIZE_OK
@ FW_SERIALIZE_OK
Serialization/Deserialization operation was successful.
Definition: Serializable.hpp:15
Fw::Buffer::getSerializeRepr
SerializeBufferBase & getSerializeRepr()
Definition: Buffer.cpp:99
HASH_DIGEST_LENGTH
#define HASH_DIGEST_LENGTH
Definition: CRC32.hpp:18
Svc::FprimeFraming::START_WORD
static const FP_FRAME_TOKEN_TYPE START_WORD
Definition: FprimeProtocol.hpp:27
Svc::DeframingProtocol::DEFRAMING_STATUS_SUCCESS
@ DEFRAMING_STATUS_SUCCESS
Definition: DeframingProtocol.hpp:40
DeframingProtocolInterface::route
virtual void route(Fw::Buffer &data)=0
send deframed data into the system
Types::CircularBuffer::get_remaining_size
NATIVE_UINT_TYPE get_remaining_size(bool serialization=false)
Definition: CircularBuffer.cpp:33
Fw::Buffer::getSize
U32 getSize() const
Definition: Buffer.cpp:64
Hash.hpp
Fw::Buffer::setSize
void setSize(U32 size)
Definition: Buffer.cpp:79
DeframingProtocolInterface::allocate
virtual Fw::Buffer allocate(const U32 size)=0
called to allocate memory, typically delegating to an allocate port call
FramingProtocolInterface::send
virtual void send(Fw::Buffer &outgoing)=0
send framed data out of the framer
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:8
FprimeProtocol.hpp
Types::CircularBuffer::peek
Fw::SerializeStatus peek(char &value, NATIVE_UINT_TYPE offset=0)
Definition: CircularBuffer.cpp:76
Utils::Hash
A generic interface for creating and comparing hash values.
Definition: Hash.hpp:24
Svc::DeframingProtocol::DeframingStatus
DeframingStatus
Status of the deframing call.
Definition: DeframingProtocol.hpp:39
FramingProtocolInterface::allocate
virtual Fw::Buffer allocate(const U32 size)=0
allocation callback to allocate memory when framing
FP_FRAME_HEADER_SIZE
#define FP_FRAME_HEADER_SIZE
Definition: FprimeProtocol.hpp:19
Svc::FprimeFraming::FprimeFraming
FprimeFraming()
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: ActiveRateGroupImplCfg.hpp:18
Svc::DeframingProtocol
Abstract base class representing a deframing protocol.
Definition: DeframingProtocol.hpp:33
Svc::FprimeFraming::frame
void frame(const U8 *const data, const U32 size, Fw::ComPacket::ComPacketType packet_type)
frame a given set of bytes
Definition: FprimeProtocol.cpp:24
Types::CircularBuffer::get_capacity
NATIVE_UINT_TYPE get_capacity()
Definition: CircularBuffer.cpp:150
FP_FRAME_TOKEN_TYPE
#define FP_FRAME_TOKEN_TYPE
Definition: FprimeProtocol.hpp:18
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:31
Svc::DeframingProtocol::DEFRAMING_INVALID_SIZE
@ DEFRAMING_INVALID_SIZE
Definition: DeframingProtocol.hpp:41
Utils::Hash::hash
static void hash(const void *data, const NATIVE_INT_TYPE len, HashBuffer &buffer)
Definition: CRC32.cpp:29