F´ Flight Software - C/C++ Documentation  NASA-v1.6.0
A framework for building embedded system applications to NASA flight quality standards.
DeframerComponentImpl.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title DeframerComponentImpl.cpp
3 // \author mstarch
4 // \brief cpp file for Deframer component implementation class
5 //
6 // \copyright
7 // Copyright 2009-2015, by the California Institute of Technology.
8 // ALL RIGHTS RESERVED. United States Government Sponsorship
9 // acknowledged.
10 //
11 // ======================================================================
12 
14 #include "Fw/Types/BasicTypes.hpp"
15 #include <Fw/Com/ComPacket.hpp>
16 #include <Fw/Logger/Logger.hpp>
17 
18 namespace Svc {
19 
20 // ----------------------------------------------------------------------
21 // Construction, initialization, and destruction
22 // ----------------------------------------------------------------------
23 
24 DeframerComponentImpl ::DeframerComponentImpl(const char* const compName) : DeframerComponentBase(compName), DeframingProtocolInterface(),
25  m_protocol(nullptr), m_in_ring(m_ring_buffer, sizeof(m_ring_buffer))
26 {}
27 
29  DeframerComponentBase::init(instance);
30 }
31 
33 
35  FW_ASSERT(m_protocol == nullptr);
36  m_protocol = &protocol;
37  protocol.setup(*this);
38 }
39 
40 
41 // ----------------------------------------------------------------------
42 // Handler implementations for user-defined typed input ports
43 // ----------------------------------------------------------------------
44 
45 void DeframerComponentImpl ::cmdResponseIn_handler(NATIVE_INT_TYPE portNum,
46  FwOpcodeType opcode,
47  U32 cmdSeq,
48  const Fw::CmdResponse& response) {
49  // Nothing to do
50 }
51 
52 void DeframerComponentImpl ::framedIn_handler(const NATIVE_INT_TYPE portNum,
53  Fw::Buffer& recvBuffer,
54  const Drv::RecvStatus& recvStatus) {
55  if (Drv::RecvStatus::RECV_OK == recvStatus.e) {
56  processBuffer(recvBuffer);
57  }
58  framedDeallocate_out(0, recvBuffer);
59 }
60 
61 void DeframerComponentImpl ::schedIn_handler(const NATIVE_INT_TYPE portNum, NATIVE_UINT_TYPE context) {
62  Fw::Buffer buffer(m_poll_buffer, sizeof(m_poll_buffer));
63  // Call read poll if it is hooked up
64  if (isConnected_framedPoll_OutputPort(0)) {
65  Drv::PollStatus status = framedPoll_out(0, buffer);
66  if (status == Drv::PollStatus::POLL_OK) {
67  processBuffer(buffer);
68  }
69  }
70 }
71 
72 Fw::Buffer DeframerComponentImpl ::allocate(const U32 size) {
73  return bufferAllocate_out(0, size);
74 }
75 
76 void DeframerComponentImpl ::route(Fw::Buffer& data) {
77  // Read the packet type from the data buffer
78  I32 packet_type = static_cast<I32>(Fw::ComPacket::FW_PACKET_UNKNOWN);
80  serial.setBuffLen(data.getSize());
81  // Serialized packet type is explicitly an I32 (4 bytes)
82  Fw::SerializeStatus status = serial.deserialize(packet_type);
83  if (status != Fw::FW_SERIALIZE_OK) {
84  // In the case that the deserialize was unsuccessful we should deallocate the request
85  bufferDeallocate_out(0, data);
86  return;
87  }
88 
89  // Process variable type
90  switch (packet_type) {
92  Fw::ComBuffer com;
93  com.setBuff(data.getData(), data.getSize());
94  comOut_out(0, com, 0);
95  // Return buffer immediately as cmdDisp will not return buffers for us. Com buffers copy, so this is safe!
96  bufferDeallocate_out(0, data);
97  break;
98  }
100  // If file uplink is possible, handle files. Otherwise ignore.
101  if (isConnected_bufferOut_OutputPort(0)) {
102  // Shift the buffer to ignore the packet type
103  data.setData(data.getData() + sizeof(packet_type));
104  data.setSize(data.getSize() - sizeof(packet_type));
105  bufferOut_out(0, data);
106  }
107  break;
108  }
109  default:
110  // In the case that we do not know the packet type, we should deallocate the request
111  bufferDeallocate_out(0, data);
112  return;
113  }
114 }
115 
116 void DeframerComponentImpl ::processRing() {
117  FW_ASSERT(m_protocol != nullptr);
118  // Maximum limit to the loop as at least one byte is process per iteration unless needed > remaining size
119  const U32 loop_limit = m_in_ring.get_capacity() + 1;
120 
121  // Inner-loop, process ring buffer looking for at least the header
122  U32 i = 0;
123  for (i = 0; (m_in_ring.get_remaining_size() > 0) and (i < loop_limit); i++) {
124  const U32 remaining = m_in_ring.get_remaining_size();
125  U32 needed = 0; // Needed is an out-only variable, and should be reset each loop
126  DeframingProtocol::DeframingStatus status = m_protocol->deframe(m_in_ring, needed);
127  FW_ASSERT(needed != 0); //Deframing protocol must always set needed to a non-zero value
128  FW_ASSERT(remaining == m_in_ring.get_remaining_size()); // Deframing protocol must not consume data only view it
129  // Successful deframing consumes messages
131  m_in_ring.rotate(needed);
132  }
133  // Break on the condition that more is needed
134  else if (status == DeframingProtocol::DEFRAMING_MORE_NEEDED) {
135  // Deframing protocol reported inconsistent "more is needed" and needed size
136  FW_ASSERT(needed > m_in_ring.get_remaining_size(), needed, m_in_ring.get_remaining_size());
137  break;
138  }
139  // Error statuses reset needed and rotate away 1 byte
140  else {
141  m_in_ring.rotate(1);
142  // Checksum errors get logged as it is unlikely to get to a checksum check on random data
144  Fw::Logger::logMsg("[ERROR] Deframing checksum validation failed\n");
145  }
146  }
147  }
148  // In every iteration of the loop above data is removed from the buffer, or we break from the loop due. Thus at
149  // worst case the loop should be called m_in_ring.get_capacity() times before exiting due an empty buffer. If it hits
150  // the limit, something went horribly wrong.
151  FW_ASSERT(i < loop_limit);
152 }
153 
154 void DeframerComponentImpl ::processBuffer(Fw::Buffer& buffer) {
155  U32 i = 0;
156  U32 buffer_offset = 0; // Max buffer size is U32
157  // Note: max iteration bounded by processing 1 byte per iteration
158  for (i = 0; (i < (buffer.getSize() + 1)) and (buffer_offset < buffer.getSize()); i++) {
159  U32 remaining = buffer.getSize() - buffer_offset;
160  NATIVE_UINT_TYPE ser_size = (remaining >= m_in_ring.get_remaining_size(true))
161  ? m_in_ring.get_remaining_size(true)
162  : static_cast<NATIVE_UINT_TYPE>(remaining);
163  m_in_ring.serialize(buffer.getData() + buffer_offset, ser_size);
164  buffer_offset = buffer_offset + ser_size;
165  processRing();
166  }
167  // Note: this assert can trip when the processRing function failed to process data
168  // or when the circular buffer is not large enough to hold a complete message. Both
169  // are hard-failures
170  FW_ASSERT(i <= buffer.getSize(), buffer.getSize());
171 }
172 
173 } // end namespace Svc
DeframerComponentImpl.hpp
Svc::DeframingProtocol::DEFRAMING_MORE_NEEDED
@ DEFRAMING_MORE_NEEDED
Definition: DeframingProtocol.hpp:43
Types::CircularBuffer::serialize
Fw::SerializeStatus serialize(const U8 *const buffer, const NATIVE_UINT_TYPE size)
Definition: CircularBuffer.cpp:54
Svc::DeframerComponentImpl::~DeframerComponentImpl
~DeframerComponentImpl()
Definition: DeframerComponentImpl.cpp:32
Svc::DeframerComponentImpl::setup
void setup(DeframingProtocol &protocol)
Definition: DeframerComponentImpl.cpp:34
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
Fw::Buffer::getData
U8 * getData() const
Definition: Buffer.cpp:60
Svc::DeframerComponentImpl::init
void init(const NATIVE_INT_TYPE instance=0)
Definition: DeframerComponentImpl.cpp:28
Svc::DeframerComponentImpl::DeframerComponentImpl
DeframerComponentImpl(const char *const compName)
Definition: DeframerComponentImpl.cpp:24
Fw::ComPacket::FW_PACKET_FILE
@ FW_PACKET_FILE
Definition: ComPacket.hpp:25
DeframingProtocolInterface
interface supplied to the deframing protocol
Definition: DeframingProtocolInterface.hpp:26
Fw::Buffer::setData
void setData(U8 *data)
Definition: Buffer.cpp:72
Svc::DeframingProtocol::DEFRAMING_INVALID_CHECKSUM
@ DEFRAMING_INVALID_CHECKSUM
Definition: DeframingProtocol.hpp:42
Fw::ComPacket::FW_PACKET_COMMAND
@ FW_PACKET_COMMAND
Definition: ComPacket.hpp:22
Fw::Buffer
Definition: Buffer.hpp:43
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
Svc::DeframingProtocol::DEFRAMING_STATUS_SUCCESS
@ DEFRAMING_STATUS_SUCCESS
Definition: DeframingProtocol.hpp:40
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
FwOpcodeType
#define FwOpcodeType
Type representation for a command opcode.
Definition: FpConfig.hpp:58
Fw::Buffer::setSize
void setSize(U32 size)
Definition: Buffer.cpp:79
Fw::SerializeBufferBase::setBuffLen
SerializeStatus setBuffLen(NATIVE_UINT_TYPE length)
sets buffer length manually after filling with data
Definition: Serializable.cpp:608
NATIVE_UINT_TYPE
unsigned int NATIVE_UINT_TYPE
native unsigned integer type declaration
Definition: BasicTypes.hpp:30
Types::CircularBuffer::rotate
Fw::SerializeStatus rotate(NATIVE_UINT_TYPE amount)
Definition: CircularBuffer.cpp:136
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:8
Fw::SerializeBufferBase::deserialize
SerializeStatus deserialize(U8 &val)
deserialize 8-bit unsigned int
Definition: Serializable.cpp:290
Fw::SerializeBufferBase::setBuff
SerializeStatus setBuff(const U8 *src, NATIVE_UINT_TYPE length)
sets buffer contents and size
Definition: Serializable.cpp:595
Fw::Logger::logMsg
static void logMsg(const char *fmt, POINTER_CAST a0=0, POINTER_CAST a1=0, POINTER_CAST a2=0, POINTER_CAST a3=0, POINTER_CAST a4=0, POINTER_CAST a5=0, POINTER_CAST a6=0, POINTER_CAST a7=0, POINTER_CAST a8=0, POINTER_CAST a9=0)
Definition: Logger.cpp:18
Svc::DeframingProtocol::setup
void setup(DeframingProtocolInterface &interface)
Definition: DeframingProtocol.cpp:21
Svc::DeframingProtocol::DeframingStatus
DeframingStatus
Status of the deframing call.
Definition: DeframingProtocol.hpp:39
Svc
Definition: ActiveRateGroupImplCfg.hpp:18
Svc::DeframingProtocol
Abstract base class representing a deframing protocol.
Definition: DeframingProtocol.hpp:33
Types::CircularBuffer::get_capacity
NATIVE_UINT_TYPE get_capacity()
Definition: CircularBuffer.cpp:150
BasicTypes.hpp
Declares ISF basic types.
NATIVE_INT_TYPE
int NATIVE_INT_TYPE
native integer type declaration
Definition: BasicTypes.hpp:29
Fw::ComBuffer
Definition: ComBuffer.hpp:21
Svc::DeframingProtocol::deframe
virtual DeframingStatus deframe(Types::CircularBuffer &buffer, U32 &needed)=0
ComPacket.hpp
Logger.hpp