F´ Flight Software - C/C++ Documentation  NASA-v2.0.1
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 
110 void DeframerComponentImpl ::processRing() {
111  FW_ASSERT(m_protocol != NULL);
112  // Inner-loop, process ring buffer looking for at least the header
113  U32 i = 0;
114  U32 needed = 0;
115  for (i = 0; (i < (m_in_ring.get_capacity() + 1)) and (m_in_ring.get_remaining_size() >= needed); i++) {
116  DeframingProtocol::DeframingStatus status = m_protocol->deframe(m_in_ring, needed);
117  // Successful deframing consumes messages
119  m_in_ring.rotate(needed);
120  }
121  // Error statuses reset needed and rotate away 1 byte
122  else if (status != DeframingProtocol::DEFRAMING_MORE_NEEDED) {
123  m_in_ring.rotate(1);
124  needed = 0;
125  // Checksum errors get logged as it is unlikely to get to a checksum check on random data
127  Fw::Logger::logMsg("[ERROR] Deframing checksum validation failed\n");
128  }
129  }
130  }
131  // Note: this assert can trip when "more is needed" from the circular buffer and the circular buffer
132  // reports that it has enough for what is needed. This would constitute a hard failure
133  FW_ASSERT(i <= m_in_ring.get_capacity(), m_in_ring.get_capacity());
134 }
135 
136 void DeframerComponentImpl ::processBuffer(Fw::Buffer& buffer) {
137  U32 i = 0;
138  U32 buffer_offset = 0; // Max buffer size is U32
139  // Note: max iteration bounded by processing 1 byte per iteration
140  for (i = 0; (i < (buffer.getSize() + 1)) and (buffer_offset < buffer.getSize()); i++) {
141  U32 remaining = buffer.getSize() - buffer_offset;
142  NATIVE_UINT_TYPE ser_size = (remaining >= m_in_ring.get_remaining_size(true))
143  ? m_in_ring.get_remaining_size(true)
144  : static_cast<NATIVE_UINT_TYPE>(remaining);
145  m_in_ring.serialize(buffer.getData() + buffer_offset, ser_size);
146  buffer_offset = buffer_offset + ser_size;
147  processRing();
148  }
149  // Note: this assert can trip when the processRing function failed to process data
150  // or when the circular buffer is not large enough to hold a complete message. Both
151  // are hard-failures
152  FW_ASSERT(i <= buffer.getSize(), buffer.getSize());
153 }
154 
155 } // end namespace Svc
DeframerComponentImpl.hpp
Svc::DeframingProtocol::DEFRAMING_MORE_NEEDED
@ DEFRAMING_MORE_NEEDED
Definition: DeframingProtocol.hpp:42
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:56
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:68
Svc::DeframingProtocol::DEFRAMING_INVALID_CHECKSUM
@ DEFRAMING_INVALID_CHECKSUM
Definition: DeframingProtocol.hpp:41
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:95
Svc::DeframingProtocol::DEFRAMING_STATUS_SUCCESS
@ DEFRAMING_STATUS_SUCCESS
Definition: DeframingProtocol.hpp:39
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:60
Fw::Buffer::setSize
void setSize(U32 size)
Definition: Buffer.cpp:75
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:38
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