F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
ComStub.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title ComStub.cpp
3 // \author mstarch
4 // \brief cpp file for ComStub component implementation class
5 // ======================================================================
6 
7 #include <Fw/Logger/Logger.hpp>
9 #include "Fw/Types/Assert.hpp"
10 #include "Fw/Types/BasicTypes.hpp"
11 
12 namespace Svc {
13 
14 // ----------------------------------------------------------------------
15 // Construction, initialization, and destruction
16 // ----------------------------------------------------------------------
17 
18 ComStub::ComStub(const char* const compName) : ComStubComponentBase(compName), m_reinitialize(true), m_retry_count(0) {}
19 
21 
22 // ----------------------------------------------------------------------
23 // Handler implementations for user-defined typed input ports
24 // ----------------------------------------------------------------------
25 
26 void ComStub::dataIn_handler(const FwIndexType portNum, Fw::Buffer& sendBuffer, const ComCfg::FrameContext& context) {
27  // A message should never get here if we need to reinitialize
28  FW_ASSERT(!this->m_reinitialize || !this->isConnected_comStatusOut_OutputPort(0));
29  if (this->isConnected_drvSendOut_OutputPort(0)) {
30  this->handleSynchronousSend(sendBuffer, context);
31  } else if (this->isConnected_drvAsyncSendOut_OutputPort(0)) {
32  this->handleAsynchronousSend(sendBuffer, context);
33  } else {
34  FW_ASSERT(0); // Neither send port is connected, this should never happen
35  }
36 }
37 
38 void ComStub::drvConnected_handler(const FwIndexType portNum) {
39  if (this->isConnected_comStatusOut_OutputPort(0) && m_reinitialize) {
40  Fw::Success radioSuccess = Fw::Success::SUCCESS;
41  this->m_reinitialize = false;
42  this->comStatusOut_out(0, radioSuccess);
43  }
44 }
45 
46 void ComStub::drvReceiveIn_handler(const FwIndexType portNum,
47  Fw::Buffer& recvBuffer,
48  const Drv::ByteStreamStatus& recvStatus) {
49  if (recvStatus != Drv::ByteStreamStatus::OP_OK) {
50  // Receive failed - return buffer without processing
51  this->drvReceiveReturnOut_out(0, recvBuffer);
52  } else {
53  // Receive successful - forward data with empty context
54  ComCfg::FrameContext emptyContext; // ComStub knows nothing about the received bytes, empty context
55  this->dataOut_out(0, recvBuffer, emptyContext);
56  }
57 }
58 
59 void ComStub::drvAsyncSendReturnIn_handler(FwIndexType portNum,
60  Fw::Buffer& fwBuffer,
61  const Drv::ByteStreamStatus& sendStatus) {
62  // This should never be called if the drvAsyncSendOut port is not connected
64  if (sendStatus == Drv::ByteStreamStatus::SEND_RETRY) {
65  // Driver indicates we should retry
66  this->handleAsyncRetry(fwBuffer);
67  } else {
68  // Return buffer ownership and send status
69  this->dataReturnOut_out(0, fwBuffer, this->m_storedContext);
70  this->m_reinitialize = (sendStatus.e != Drv::ByteStreamStatus::OP_OK);
71  this->m_retry_count = 0; // Reset retry count
72  // Send Com status
73  Fw::Success comSuccess =
75  this->comStatusOut_out(0, comSuccess);
76  }
77 }
78 
79 void ComStub ::dataReturnIn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer, const ComCfg::FrameContext& context) {
80  this->drvReceiveReturnOut_out(0, fwBuffer);
81 }
82 
83 // ----------------------------------------------------------------------
84 // Helper method implementations
85 // ----------------------------------------------------------------------
86 
87 void ComStub::handleSynchronousSend(Fw::Buffer& sendBuffer, const ComCfg::FrameContext& context) {
89  Fw::Success comSuccess = Fw::Success::FAILURE;
90 
91  // Send to driver (and retry up to the retry limit)
92  for (FwIndexType i = 0; sendStatus == Drv::ByteStreamStatus::SEND_RETRY && i < RETRY_LIMIT; i++) {
93  sendStatus = this->drvSendOut_out(0, sendBuffer);
94  }
95 
96  // Handle the send status
97  if (sendStatus == Drv::ByteStreamStatus::OP_OK) {
98  comSuccess = Fw::Success::SUCCESS;
99  } else if (sendStatus == Drv::ByteStreamStatus::SEND_RETRY) {
100  Fw::Logger::log("ComStub RETRY_LIMIT exceeded, skipped sending data");
101  } else {
102  // Other error - need to reinitialize
103  this->m_reinitialize = true;
104  }
105 
106  // Return buffer and send status
107  this->dataReturnOut_out(0, sendBuffer, context);
108  this->comStatusOut_out(0, comSuccess);
109 }
110 
111 void ComStub::handleAsynchronousSend(Fw::Buffer& sendBuffer, const ComCfg::FrameContext& context) {
112  this->m_storedContext = context; // Store the context for async callback
113  this->drvAsyncSendOut_out(0, sendBuffer);
114 }
115 
116 void ComStub::handleAsyncRetry(Fw::Buffer& fwBuffer) {
117  if (this->m_retry_count < this->RETRY_LIMIT) {
118  // Attempt retry if under the limit
119  this->m_retry_count++;
120  this->drvAsyncSendOut_out(0, fwBuffer);
121  } else {
122  // Exceeded retry limit - return buffer and notify failure
123  this->dataReturnOut_out(0, fwBuffer, this->m_storedContext);
124  Fw::Success comStatus = Fw::Success::FAILURE;
125  this->comStatusOut_out(0, comStatus);
126  Fw::Logger::log("ComStub RETRY_LIMIT exceeded, skipped sending data");
127  this->m_retry_count = 0; // Reset retry count
128  }
129 }
130 
131 } // end namespace Svc
bool isConnected_drvAsyncSendOut_OutputPort(FwIndexType portNum)
void dataReturnOut_out(FwIndexType portNum, Fw::Buffer &data, const ComCfg::FrameContext &context)
Invoke output port dataReturnOut.
Representing success.
ComStub(const char *const compName)
Definition: ComStub.cpp:18
void dataOut_out(FwIndexType portNum, Fw::Buffer &data, const ComCfg::FrameContext &context)
Invoke output port dataOut.
Drv::ByteStreamStatus drvSendOut_out(FwIndexType portNum, Fw::Buffer &sendBuffer)
Invoke output port drvSendOut.
static void log(const char *format,...)
log a formated string with supplied arguments
Definition: Logger.cpp:21
Auto-generated base for ComStub component.
void drvReceiveReturnOut_out(FwIndexType portNum, Fw::Buffer &fwBuffer)
Invoke output port drvReceiveReturnOut.
void drvAsyncSendOut_out(FwIndexType portNum, Fw::Buffer &fwBuffer)
Invoke output port drvAsyncSendOut.
bool isConnected_comStatusOut_OutputPort(FwIndexType portNum)
Status returned by the send call.
Operation worked as expected.
bool isConnected_drvSendOut_OutputPort(FwIndexType portNum)
Representing failure.
const FwIndexType RETRY_LIMIT
Definition: ComStub.hpp:19
~ComStub() override
Definition: ComStub.cpp:20
PlatformIndexType FwIndexType
C++ header for working with basic fprime types.
Type used to pass context info between components during framing/deframing.
RateGroupDivider component implementation.
void comStatusOut_out(FwIndexType portNum, Fw::Success &condition)
Invoke output port comStatusOut.
#define FW_ASSERT(...)
Definition: Assert.hpp:14
Success/Failure.