F´ Flight Software - C/C++ Documentation  NASA-v2.1.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(NULL), m_in_ring(m_ring_buffer, sizeof(m_ring_buffer))
26 {}
27 
29  DeframerComponentBase::init(instance);
30 }
31 
33 
35  FW_ASSERT(m_protocol == NULL);
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 ::framedIn_handler(const NATIVE_INT_TYPE portNum,
46  Fw::Buffer& recvBuffer,
47  Drv::RecvStatus recvStatus) {
48  if (Drv::RECV_OK == recvStatus) {
49  processBuffer(recvBuffer);
50  }
51  framedDeallocate_out(0, recvBuffer);
52 }
53 
54 void DeframerComponentImpl ::schedIn_handler(const NATIVE_INT_TYPE portNum, NATIVE_UINT_TYPE context) {
55  Fw::Buffer buffer(m_poll_buffer, sizeof(m_poll_buffer));
56  // Call read poll if it is hooked up
57  if (isConnected_framedPoll_OutputPort(0)) {
58  Drv::PollStatus status = framedPoll_out(0, buffer);
59  if (status == Drv::POLL_OK) {
60  processBuffer(buffer);
61  }
62  }
63 }
64 
65 Fw::Buffer DeframerComponentImpl ::allocate(const U32 size) {
66  return bufferAllocate_out(0, size);
67 }
68 
69 void DeframerComponentImpl ::route(Fw::Buffer& data) {
70  // Read the packet type from the data buffer
71  I32 packet_type = static_cast<I32>(Fw::ComPacket::FW_PACKET_UNKNOWN);
73  serial.setBuffLen(data.getSize());
74  // Serialized packet type is explicitly an I32 (4 bytes)
75  Fw::SerializeStatus status = serial.deserialize(packet_type);
76  if (status != Fw::FW_SERIALIZE_OK) {
77  // In the case that the deserialize was unsuccessful we should deallocate the request
78  bufferDeallocate_out(0, data);
79  return;
80  }
81 
82  // Process variable type
83  switch (packet_type) {
85  Fw::ComBuffer com;
86  com.setBuff(data.getData(), data.getSize());
87  comOut_out(0, com, 0);
88  // Return buffer immediately as cmdDisp will not return buffers for us. Com buffers copy, so this is safe!
89  bufferDeallocate_out(0, data);
90  break;
91  }
93  // If file uplink is possible, handle files. Otherwise ignore.
94  if (isConnected_bufferOut_OutputPort(0)) {
95  // Shift the buffer to ignore the packet type
96  data.setData(data.getData() + sizeof(packet_type));
97  data.setSize(data.getSize() - sizeof(packet_type));
98  bufferOut_out(0, data);
99  }
100  break;
101  }
102  default:
103  // In the case that we do not know the packet type, we should deallocate the request
104  bufferDeallocate_out(0, data);
105  return;
106  }
107 }
108 
109 void DeframerComponentImpl ::processRing() {
110  FW_ASSERT(m_protocol != NULL);
111  // Maximum limit to the loop as at least one byte is process per iteration unless needed > remaining size
112  const U32 loop_limit = m_in_ring.get_capacity() + 1;
113 
114  // Inner-loop, process ring buffer looking for at least the header
115  U32 i = 0;
116  for (i = 0; (m_in_ring.get_remaining_size() > 0) and (i < loop_limit); i++) {
117  const U32 remaining = m_in_ring.get_remaining_size();
118  U32 needed = 0; // Needed is an out-only variable, and should be reset each loop
119  DeframingProtocol::DeframingStatus status = m_protocol->deframe(m_in_ring, needed);
120  FW_ASSERT(needed != 0); //Deframing protocol must always set needed to a non-zero value
121  FW_ASSERT(remaining == m_in_ring.get_remaining_size()); // Deframing protocol must not consume data only view it
122  // Successful deframing consumes messages
124  m_in_ring.rotate(needed);
125  }
126  // Break on the condition that more is needed
127  else if (status == DeframingProtocol::DEFRAMING_MORE_NEEDED) {
128  // Deframing protocol reported inconsistent "more is needed" and needed size
129  FW_ASSERT(needed > m_in_ring.get_remaining_size(), needed, m_in_ring.get_remaining_size());
130  break;
131  }
132  // Error statuses reset needed and rotate away 1 byte
133  else {
134  m_in_ring.rotate(1);
135  // Checksum errors get logged as it is unlikely to get to a checksum check on random data
137  Fw::Logger::logMsg("[ERROR] Deframing checksum validation failed\n");
138  }
139  }
140  }
141  // In every iteration of the loop above data is removed from the buffer, or we break from the loop due. Thus at
142  // worst case the loop should be called m_in_ring.get_capacity() times before exiting due an empty buffer. If it hits
143  // the limit, something went horribly wrong.
144  FW_ASSERT(i < loop_limit);
145 }
146 
147 void DeframerComponentImpl ::processBuffer(Fw::Buffer& buffer) {
148  U32 i = 0;
149  U32 buffer_offset = 0; // Max buffer size is U32
150  // Note: max iteration bounded by processing 1 byte per iteration
151  for (i = 0; (i < (buffer.getSize() + 1)) and (buffer_offset < buffer.getSize()); i++) {
152  U32 remaining = buffer.getSize() - buffer_offset;
153  NATIVE_UINT_TYPE ser_size = (remaining >= m_in_ring.get_remaining_size(true))
154  ? m_in_ring.get_remaining_size(true)
155  : static_cast<NATIVE_UINT_TYPE>(remaining);
156  m_in_ring.serialize(buffer.getData() + buffer_offset, ser_size);
157  buffer_offset = buffer_offset + ser_size;
158  processRing();
159  }
160  // Note: this assert can trip when the processRing function failed to process data
161  // or when the circular buffer is not large enough to hold a complete message. Both
162  // are hard-failures
163  FW_ASSERT(i <= buffer.getSize(), buffer.getSize());
164 }
165 
166 } // 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::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
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:604
NATIVE_UINT_TYPE
unsigned int NATIVE_UINT_TYPE
native unsigned integer type declaration
Definition: BasicTypes.hpp:30
Svc::DeframerComponentImpl::~DeframerComponentImpl
~DeframerComponentImpl(void)
Definition: DeframerComponentImpl.cpp:32
Types::CircularBuffer::rotate
Fw::SerializeStatus rotate(NATIVE_UINT_TYPE amount)
Definition: CircularBuffer.cpp:136
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:9
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:591
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
NULL
#define NULL
NULL.
Definition: BasicTypes.hpp:100
Svc::DeframingProtocol::deframe
virtual DeframingStatus deframe(Types::CircularBuffer &buffer, U32 &needed)=0
ComPacket.hpp
Logger.hpp