F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
FprimeRouter.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title FprimeRouter.cpp
3 // \author thomas-bc
4 // \brief cpp file for FprimeRouter component implementation class
5 // ======================================================================
6 
8 #include "Fw/Com/ComPacket.hpp"
10 #include "Fw/Logger/Logger.hpp"
11 #include "config/ApidEnumAc.hpp"
12 
13 namespace Svc {
14 
15 // ----------------------------------------------------------------------
16 // Component construction and destruction
17 // ----------------------------------------------------------------------
18 
19 FprimeRouter ::FprimeRouter(const char* const compName) : FprimeRouterComponentBase(compName) {
20  // Mark every table entry unused
21  for (FwSizeType i = 0; i < FW_NUM_ARRAY_ELEMENTS(this->m_bufferContextTable); i++) {
22  this->m_bufferContextTable[i].state = Fw::Active::INACTIVE;
23  }
24 }
25 
27 
28 // ----------------------------------------------------------------------
29 // Handler implementations for user-defined typed input ports
30 // ----------------------------------------------------------------------
31 
32 void FprimeRouter ::dataIn_handler(FwIndexType portNum, Fw::Buffer& packetBuffer, const ComCfg::FrameContext& context) {
33  Fw::SerializeStatus status;
34  Fw::ComPacketType packetType = context.get_apid();
35  // Route based on received APID (packet type)
36  switch (packetType) {
37  // Handle a command packet
38  case Fw::ComPacketType::FW_PACKET_COMMAND: {
39  // Allocate a com buffer on the stack
40  Fw::ComBuffer com;
41  // Copy the contents of the packet buffer into the com buffer
42  status = com.setBuff(packetBuffer.getData(), packetBuffer.getSize());
43  if (status == Fw::FW_SERIALIZE_OK) {
44  // Send the com buffer - critical functionality so it is considered an error not to
45  // have the port connected. This is why we don't check isConnected() before sending.
46  this->commandOut_out(0, com, 0);
47  } else {
49  }
50  // The command buffer was copied into the com buffer above, so ownership of the
51  // incoming packetBuffer is returned immediately with the context it was received with.
52  this->dataReturnOut_out(0, packetBuffer, context);
53  break;
54  }
55  // Handle a file packet
56  case Fw::ComPacketType::FW_PACKET_FILE: {
57  // If the file uplink output port is connected, send the file packet directly.
58  // Ownership is passed to the receiver and will come back on fileBufferReturnIn,
59  // at which point we return it to the deframer via dataReturnOut. fileOut carries
60  // only Fw::Buffer, so remember the context here to restore it on return.
61  if (this->isConnected_fileOut_OutputPort(0)) {
62  if (this->insertContext(packetBuffer, context) == Fw::Success::FAILURE) {
64  }
65  this->fileOut_out(0, packetBuffer);
66  } else {
67  // Port not connected, return the buffer immediately with its context
68  this->dataReturnOut_out(0, packetBuffer, context);
69  }
70  break;
71  }
72  default: {
73  // Packet type is not known to the F Prime protocol. If the unknownDataOut port is
74  // connected, forward packet and context for further processing.
75  // Ownership is passed to the receiver and will come back on fileBufferReturnIn,
76  // at which point we return it to the deframer via dataReturnOut. The return path
77  // (fileBufferReturnIn) carries no context, so remember it here to restore on return.
79  if (this->insertContext(packetBuffer, context) == Fw::Success::FAILURE) {
81  }
82  this->unknownDataOut_out(0, packetBuffer, context);
83  } else {
84  // Port not connected, return the buffer immediately with its context
85  this->dataReturnOut_out(0, packetBuffer, context);
86  }
87  break;
88  }
89  }
90 }
91 
92 void FprimeRouter ::cmdResponseIn_handler(FwIndexType portNum,
93  FwOpcodeType opcode,
94  U32 cmdSeq,
95  const Fw::CmdResponse& response) {
96  // Nothing to do
97 }
98 
99 void FprimeRouter ::fileBufferReturnIn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) {
100  // Restore the context that was saved when this buffer was handed off on
101  // fileOut/unknownDataOut
102  ComCfg::FrameContext context;
103  if (this->takeContext(fwBuffer, context) == Fw::Success::FAILURE) {
104  // Buffer not found in the table: return with an empty context (already default)
106  }
107  this->dataReturnOut_out(0, fwBuffer, context);
108 }
109 
110 // ----------------------------------------------------------------------
111 // Buffer-to-context association table helpers
112 // ----------------------------------------------------------------------
113 
114 Fw::Success FprimeRouter ::insertContext(const Fw::Buffer& buffer, const ComCfg::FrameContext& context) {
115  const U8* key = buffer.getData();
116  for (FwSizeType i = 0; i < FW_NUM_ARRAY_ELEMENTS(this->m_bufferContextTable); i++) {
117  if (this->m_bufferContextTable[i].state == Fw::Active::INACTIVE) {
118  this->m_bufferContextTable[i].state = Fw::Active::ACTIVE;
119  this->m_bufferContextTable[i].key = key;
120  this->m_bufferContextTable[i].context = context;
121  return Fw::Success::SUCCESS;
122  }
123  }
124  // Table full
125  return Fw::Success::FAILURE;
126 }
127 
128 Fw::Success FprimeRouter ::takeContext(const Fw::Buffer& buffer, ComCfg::FrameContext& context) {
129  const U8* key = buffer.getData();
130  for (FwSizeType i = 0; i < FW_NUM_ARRAY_ELEMENTS(this->m_bufferContextTable); i++) {
131  if (this->m_bufferContextTable[i].state == Fw::Active::ACTIVE && this->m_bufferContextTable[i].key == key) {
132  context = this->m_bufferContextTable[i].context;
133  this->m_bufferContextTable[i].state = Fw::Active::INACTIVE;
134  return Fw::Success::SUCCESS;
135  }
136  }
137  // Not found
138  return Fw::Success::FAILURE;
139 }
140 
141 } // namespace Svc
Serialization/Deserialization operation was successful.
FwIdType FwOpcodeType
The type of a command opcode.
SerializeStatus setBuff(const U8 *src, Serializable::SizeType length) override
Set buffer contents from external source.
Representing success.
PlatformSizeType FwSizeType
void unknownDataOut_out(FwIndexType portNum, Fw::Buffer &data, const ComCfg::FrameContext &context) const
Invoke output port unknownDataOut.
ComCfg::Apid::T get_apid() const
Get member apid.
Active state.
U8 * getData() const
Definition: Buffer.cpp:82
void fileOut_out(FwIndexType portNum, Fw::Buffer &fwBuffer) const
Invoke output port fileOut.
Enum representing a command response.
void commandOut_out(FwIndexType portNum, Fw::ComBuffer &data, U32 context) const
Invoke output port commandOut.
SerializeStatus
forward declaration for string
FprimeRouter(const char *const compName)
Construct FprimeRouter object.
T
The raw enum type.
Definition: ApidEnumAc.hpp:32
Inactive state.
~FprimeRouter()
Destroy FprimeRouter object.
Auto-generated base for FprimeRouter component.
Representing failure.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:54
FwSizeType getSize() const
Definition: Buffer.cpp:90
void dataReturnOut_out(FwIndexType portNum, Fw::Buffer &data, const ComCfg::FrameContext &context) const
Invoke output port dataReturnOut.
bool isConnected_unknownDataOut_OutputPort(FwIndexType portNum) const
PlatformIndexType FwIndexType
#define FW_NUM_ARRAY_ELEMENTS(a)
number of elements in an array
Definition: BasicTypes.h:94
void log_WARNING_HI_SerializationError(U32 status) const
Type used to pass context info between components during framing/deframing.
bool isConnected_fileOut_OutputPort(FwIndexType portNum) const
RateGroupDivider component implementation.
Success/Failure.