F´ Flight Software - C/C++ Documentation  NASA-v2.1.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(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