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
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