F´ Flight Software - C/C++ Documentation NASA-v1.6.0
A framework for building embedded system applications to NASA flight quality standards.
Loading...
Searching...
No Matches
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:60
U32 getSize() const
Definition Buffer.cpp:64
void setSize(U32 size)
Definition Buffer.cpp:79
SerializeBufferBase & getSerializeRepr()
Definition Buffer.cpp:99
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.