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#include "FprimeProtocol.hpp"
13#include "FpConfig.hpp"
14#include "Utils/Hash/Hash.hpp"
15
16namespace Svc {
17
19
21
22void FprimeFraming::frame(const U8* const data, const U32 size, Fw::ComPacket::ComPacketType packet_type) {
23 FW_ASSERT(data != nullptr);
24 FW_ASSERT(m_interface != nullptr);
25 // Use of I32 size is explicit as ComPacketType will be specifically serialized as an I32
26 FpFrameHeader::TokenType real_data_size = size + ((packet_type != Fw::ComPacket::FW_PACKET_UNKNOWN) ? sizeof(I32) : 0);
28 Fw::Buffer buffer = m_interface->allocate(total);
29 Fw::SerializeBufferBase& serializer = buffer.getSerializeRepr();
31
32 // Serialize data
34 status = serializer.serialize(FpFrameHeader::START_WORD);
35 FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
36
37 status = serializer.serialize(real_data_size);
38 FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
39
40 // Serialize packet type if supplied, otherwise it *must* be present in the data
41 if (packet_type != Fw::ComPacket::FW_PACKET_UNKNOWN) {
42 status = serializer.serialize(static_cast<I32>(packet_type)); // I32 used for enum storage
43 FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
44 }
45
46 status = serializer.serialize(data, size, true); // Serialize without length
47 FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
48
49 // Calculate and add transmission hash
50 Utils::Hash::hash(buffer.getData(), total - HASH_DIGEST_LENGTH, hash);
51 status = serializer.serialize(hash.getBuffAddr(), HASH_DIGEST_LENGTH, true);
52 FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
53
54 buffer.setSize(total);
55
56 m_interface->send(buffer);
57}
58
60 Utils::Hash hash;
61 Utils::HashBuffer hashBuffer;
62 // Initialize the checksum and loop through all bytes calculating it
63 hash.init();
64 for (U32 i = 0; i < size; i++) {
65 char byte;
66 const Fw::SerializeStatus status = ring.peek(byte, i);
67 FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
68 hash.update(&byte, 1);
69 }
70 hash.final(hashBuffer);
71 // Now loop through the hash digest bytes and check for equality
72 for (U32 i = 0; i < HASH_DIGEST_LENGTH; i++) {
73 char calc = static_cast<char>(hashBuffer.getBuffAddr()[i]);
74 char sent = 0;
75 const Fw::SerializeStatus status = ring.peek(sent, size + i);
76 FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
77 if (calc != sent) {
78 return false;
79 }
80 }
81 return true;
82}
83
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 status = ring.peek(buffer.getData(), size, FpFrameHeader::SIZE);
130 FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
131 m_interface->route(buffer);
133}
134};
#define FW_ASSERT(...)
Definition Assert.hpp:7
uint8_t U8
8-bit unsigned integer
Definition BasicTypes.h:26
#define HASH_DIGEST_LENGTH
Definition CRC32.hpp:18
C++-compatible configuration header for fprime configuration.
U8 * getData() const
Definition Buffer.cpp:68
U32 getSize() const
Definition Buffer.cpp:72
void setSize(U32 size)
Definition Buffer.cpp:87
SerializeBufferBase & getSerializeRepr()
Definition Buffer.cpp:107
SerializeStatus serialize(U8 val)
serialize 8-bit unsigned int
Abstract base class representing a deframing protocol.
DeframingProtocolInterface * m_interface
DeframingStatus
Status of the deframing call.
virtual Fw::Buffer allocate(const U32 size)=0
called to allocate memory, typically delegating to an allocate port call
virtual void route(Fw::Buffer &data)=0
send deframed data into the system
FprimeDeframing()
Constructor.
bool validate(Types::CircularBuffer &buffer, U32 size)
DeframingStatus deframe(Types::CircularBuffer &buffer, U32 &needed) override
FprimeFraming()
Constructor.
void frame(const U8 *const data, const U32 size, Fw::ComPacket::ComPacketType packet_type) override
Implements the frame method.
abstract class representing a framing protocol
FramingProtocolInterface * m_interface
virtual void send(Fw::Buffer &outgoing)=0
send framed data out of the framer
virtual Fw::Buffer allocate(const U32 size)=0
allocation callback to allocate memory when framing
NATIVE_UINT_TYPE get_allocated_size() const
NATIVE_UINT_TYPE get_capacity() const
Fw::SerializeStatus peek(char &value, NATIVE_UINT_TYPE offset=0) const
A container class for holding a hash buffer.
A generic interface for creating and comparing hash values.
Definition Hash.hpp:24
static void hash(const void *data, const NATIVE_INT_TYPE len, HashBuffer &buffer)
Definition CRC32.cpp:29
void init()
Definition CRC32.cpp:47
void update(const void *const data, const NATIVE_INT_TYPE len)
Definition CRC32.cpp:53
void final(HashBuffer &buffer)
Definition CRC32.cpp:64
SerializeStatus
forward declaration for string
@ FW_SERIALIZE_OK
Serialization/Deserialization operation was successful.
U32 TokenType
Token type for F Prime frame header.
@ SIZE
Header size for F Prime frame header.
const TokenType START_WORD
The start word for F Prime framing.