F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
ComAggregator.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title ComAggregator.cpp
3 // \author lestarch
4 // \brief cpp file for ComAggregator component implementation class
5 // ======================================================================
6 
8 
9 namespace Svc {
10 
11 // ----------------------------------------------------------------------
12 // Component construction and destruction
13 // ----------------------------------------------------------------------
14 
15 ComAggregator ::ComAggregator(const char* const compName)
16  : ComAggregatorComponentBase(compName),
17  m_bufferState(Fw::Buffer::OwnershipState::OWNED),
18  m_frameBuffer(m_frameBufferStore, sizeof(m_frameBufferStore)),
19  m_frameSerializer(m_frameBuffer.getSerializer()),
20  m_allow_timeout(false) {}
21 
23 
26  this->comStatusOut_out(0, good);
27 }
28 
29 // ----------------------------------------------------------------------
30 // Handler implementations for typed input ports
31 // ----------------------------------------------------------------------
32 
33 void ComAggregator ::comStatusIn_handler(FwIndexType portNum, Fw::Success& condition) {
34  this->aggregationMachine_sendSignal_status(condition);
35 }
36 
37 void ComAggregator ::dataIn_handler(FwIndexType portNum, Fw::Buffer& data, const ComCfg::FrameContext& context) {
38  Svc::ComDataContextPair pair(data, context);
40 }
41 
42 void ComAggregator ::dataReturnIn_handler(FwIndexType portNum, Fw::Buffer& data, const ComCfg::FrameContext& context) {
43  // This handler runs on the returning caller's thread: take ownership atomically
44  const Fw::Buffer::OwnershipState previousState = this->m_bufferState.exchange(Fw::Buffer::OwnershipState::OWNED);
45  FW_ASSERT(previousState == Fw::Buffer::OwnershipState::NOT_OWNED, static_cast<FwAssertArgType>(previousState));
46 }
47 
48 void ComAggregator ::timeout_handler(FwIndexType portNum, U32 context) {
49  // Timeout is ignored in WAIT_STATUS state. However, the queue may not process timeout messages until the wait
50  // status is returned because the port chain may be synchronous and downstream components (radio, retry, etc) may
51  // take a long time to complete the transmission of data. This can cause the queue to overflow with messages that
52  // will soon be discarded.
53  //
54  // Therefore, to fix the risk of queue overflow we only queue timeout messages when they would be processed by the
55  // state machine (i.e. in the FILL state). Otherwise, these messages are not queued.
56  //
57  // Behaviorally, this solution will work exactly like the naive implementation with an infinite queue depth, but
58  // prevents queue overflow when using finite queues.
59  if (this->m_allow_timeout) {
61  }
62 }
63 
64 // ----------------------------------------------------------------------
65 // Implementations for internal state machine actions
66 // ----------------------------------------------------------------------
67 
68 void ComAggregator ::Svc_AggregationMachine_action_doClear(SmId smId, Svc_AggregationMachine::Signal signal) {
69  this->m_allow_timeout = true; // Allow timeout messages in FILL state
70  this->m_frameSerializer.resetSer();
71  this->m_frameBuffer.setSize(sizeof(this->m_frameBufferStore));
72  this->m_lastContext = ComCfg::FrameContext();
73  if (this->m_held.get_data().isValid()) {
74  // Fill the held data
75  this->Svc_AggregationMachine_action_doFill(smId, signal, this->m_held);
76  this->m_held = Svc::ComDataContextPair();
77  }
78 }
79 
80 void ComAggregator ::Svc_AggregationMachine_action_doFill(SmId smId,
82  const Svc::ComDataContextPair& value) {
83  Fw::SerializeStatus status = this->m_frameSerializer.serializeFrom(
86  this->m_lastContext = value.get_context();
88  // Return port does not alter data and thus const-cast is safe
89  this->dataReturnOut_out(0, const_cast<Fw::Buffer&>(value.get_data()), value.get_context());
90  this->comStatusOut_out(0, good);
91 }
92 
93 void ComAggregator ::Svc_AggregationMachine_action_doSend(SmId smId, Svc_AggregationMachine::Signal signal) {
94  // Send only when the buffer will be valid
95  if (this->m_frameSerializer.getSize() > 0) {
96  const Fw::Buffer::OwnershipState previousState =
97  this->m_bufferState.exchange(Fw::Buffer::OwnershipState::NOT_OWNED);
98  FW_ASSERT(previousState == Fw::Buffer::OwnershipState::OWNED, static_cast<FwAssertArgType>(previousState));
99  this->m_frameBuffer.setSize(this->m_frameSerializer.getSize());
100  this->m_allow_timeout = false; // Timeout messages should be discarded in WAIT_STATUS state
101  this->dataOut_out(0, this->m_frameBuffer, this->m_lastContext);
102  }
103 }
104 
105 void ComAggregator ::Svc_AggregationMachine_action_doHold(SmId smId,
107  const Svc::ComDataContextPair& value) {
108  FW_ASSERT(not this->m_held.get_data().isValid());
109  this->m_held = value;
110 }
111 
112 void ComAggregator ::Svc_AggregationMachine_action_assertNoStatus(SmId smId, Svc_AggregationMachine::Signal signal) {
113  // Status is not possible in this state, confirm by assertion
114  FW_ASSERT(false);
115 }
116 
117 // ----------------------------------------------------------------------
118 // Implementations for internal state machine guards
119 // ----------------------------------------------------------------------
120 
121 bool ComAggregator ::Svc_AggregationMachine_guard_isFull(SmId smId,
123  const Svc::ComDataContextPair& value) const {
125  const FwSizeType remaining = this->m_frameSerializer.getCapacity() - this->m_frameSerializer.getSize();
126  return (remaining < value.get_data().getSize());
127 }
128 
129 bool ComAggregator ::Svc_AggregationMachine_guard_willFill(SmId smId,
131  const Svc::ComDataContextPair& value) const {
133  const FwSizeType remaining = this->m_frameSerializer.getCapacity() - this->m_frameSerializer.getSize();
134  return (remaining == value.get_data().getSize());
135 }
136 
137 bool ComAggregator ::Svc_AggregationMachine_guard_isNotEmpty(SmId smId, Svc_AggregationMachine::Signal signal) const {
138  return this->m_frameSerializer.getSize() > 0;
139 }
140 
141 bool ComAggregator ::Svc_AggregationMachine_guard_isGood(SmId smId,
143  const Fw::Success& value) const {
144  return value == Fw::Success::SUCCESS;
145 }
146 
147 } // namespace Svc
Serialization/Deserialization operation was successful.
Representing success.
PlatformSizeType FwSizeType
void setSize(FwSizeType size)
Definition: Buffer.cpp:131
Serializable::SizeType getSize() const override
Get current buffer size.
void dataReturnOut_out(FwIndexType portNum, Fw::Buffer &data, const ComCfg::FrameContext &context) const
Invoke output port dataReturnOut.
void aggregationMachine_sendSignal_status(const Fw::Success &value)
Send signal status to state machine aggregationMachine.
U8 * getData() const
Definition: Buffer.cpp:82
SerializeStatus serializeFrom(U8 val, Endianness mode=Endianness::BIG) override
Serialize an 8-bit unsigned integer value.
Serializable::SizeType getCapacity() const override
Get buffer capacity.
The buffer is currently not owned.
SerializeStatus
forward declaration for string
~ComAggregator()
Destroy ComAggregator object.
void preamble() override
A function that will be called before the event loop is entered.
Omit length from serialization.
bool isValid() const
Definition: Buffer.cpp:78
void resetSer() override
Reset serialization pointer to beginning of buffer.
ComCfg::FrameContext & get_context()
Get member context.
FwSizeType getSize() const
Definition: Buffer.cpp:90
Auto-generated base for ComAggregator component.
void aggregationMachine_sendSignal_timeout()
Send signal timeout to state machine aggregationMachine.
Fw::Buffer & get_data()
Get member data.
ComAggregator(const char *const compName)
Construct ComAggregator object.
PlatformIndexType FwIndexType
void comStatusOut_out(FwIndexType portNum, Fw::Success &condition) const
Invoke output port comStatusOut.
OwnershipState
Definition: Buffer.hpp:60
Type used to pass context info between components during framing/deframing.
RateGroupDivider component implementation.
The buffer is currently owned.
Implementation of malloc based allocator.
void dataOut_out(FwIndexType portNum, Fw::Buffer &data, const ComCfg::FrameContext &context) const
Invoke output port dataOut.
FpySequencer_SequencerStateMachineStateMachineBase::Signal Signal
#define FW_ASSERT(...)
Definition: Assert.hpp:14
void aggregationMachine_sendSignal_fill(const Svc::ComDataContextPair &value)
Send signal fill to state machine aggregationMachine.
Success/Failure.