GCC Code Coverage Report


Directory: ./
File: Svc/ComAggregator/ComAggregator.cpp
Date: 2026-09-03 22:12:29
Exec Total Coverage
Lines: 67 70 95.7%
Functions: 15 16 93.8%
Branches: 24 25 96.0%

Line Branch Exec Source
1 // ======================================================================
2 // \title ComAggregator.cpp
3 // \author lestarch
4 // \brief cpp file for ComAggregator component implementation class
5 // ======================================================================
6
7 #include "Svc/ComAggregator/ComAggregator.hpp"
8
9 namespace Svc {
10
11 // ----------------------------------------------------------------------
12 // Component construction and destruction
13 // ----------------------------------------------------------------------
14
15 1 ComAggregator ::ComAggregator(const char* const compName)
16 : ComAggregatorComponentBase(compName),
17 1 m_bufferState(Fw::Buffer::OwnershipState::OWNED),
18
1/1
✓ Branch 1 taken 1 times.
1 m_frameBuffer(m_frameBufferStore, sizeof(m_frameBufferStore)),
19
1/1
✓ Branch 1 taken 1 times.
1 m_frameSerializer(m_frameBuffer.getSerializer()),
20
2/2
✓ Branch 3 taken 1 times.
✓ Branch 6 taken 1 times.
2 m_allow_timeout(false) {}
21
22 2 ComAggregator ::~ComAggregator() {}
23
24 1 void ComAggregator ::preamble() {
25
1/1
✓ Branch 1 taken 1 times.
1 Fw::Success good = Fw::Success::SUCCESS;
26
1/1
✓ Branch 1 taken 1 times.
1 this->comStatusOut_out(0, good);
27 1 }
28
29 // ----------------------------------------------------------------------
30 // Handler implementations for typed input ports
31 // ----------------------------------------------------------------------
32
33 230 void ComAggregator ::comStatusIn_handler(FwIndexType portNum, Fw::Success& condition) {
34 230 this->aggregationMachine_sendSignal_status(condition);
35 230 }
36
37 668 void ComAggregator ::dataIn_handler(FwIndexType portNum, Fw::Buffer& data, const ComCfg::FrameContext& context) {
38
1/1
✓ Branch 1 taken 668 times.
668 Svc::ComDataContextPair pair(data, context);
39
1/1
✓ Branch 1 taken 668 times.
668 this->aggregationMachine_sendSignal_fill(pair);
40 668 }
41
42 229 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 229 const Fw::Buffer::OwnershipState previousState = this->m_bufferState.exchange(Fw::Buffer::OwnershipState::OWNED);
45 229 FW_ASSERT(previousState == Fw::Buffer::OwnershipState::NOT_OWNED, static_cast<FwAssertArgType>(previousState));
46 229 }
47
48 235 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
2/2
✓ Branch 1 taken 233 times.
✓ Branch 2 taken 2 times.
235 if (this->m_allow_timeout) {
60 233 this->aggregationMachine_sendSignal_timeout();
61 }
62 235 }
63
64 // ----------------------------------------------------------------------
65 // Implementations for internal state machine actions
66 // ----------------------------------------------------------------------
67
68 230 void ComAggregator ::Svc_AggregationMachine_action_doClear(SmId smId, Svc_AggregationMachine::Signal signal) {
69 230 this->m_allow_timeout = true; // Allow timeout messages in FILL state
70 230 this->m_frameSerializer.resetSer();
71 230 this->m_frameBuffer.setSize(sizeof(this->m_frameBufferStore));
72
2/2
✓ Branch 1 taken 230 times.
✓ Branch 4 taken 230 times.
230 this->m_lastContext = ComCfg::FrameContext();
73
2/2
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 214 times.
230 if (this->m_held.get_data().isValid()) {
74 // Fill the held data
75 16 this->Svc_AggregationMachine_action_doFill(smId, signal, this->m_held);
76
2/2
✓ Branch 1 taken 16 times.
✓ Branch 4 taken 16 times.
16 this->m_held = Svc::ComDataContextPair();
77 }
78 230 }
79
80 668 void ComAggregator ::Svc_AggregationMachine_action_doFill(SmId smId,
81 Svc_AggregationMachine::Signal signal,
82 const Svc::ComDataContextPair& value) {
83
1/1
✓ Branch 1 taken 668 times.
668 Fw::SerializeStatus status = this->m_frameSerializer.serializeFrom(
84
2/2
✓ Branch 3 taken 668 times.
✓ Branch 6 taken 668 times.
1336 value.get_data().getData(), value.get_data().getSize(), Fw::Serialization::OMIT_LENGTH);
85 668 FW_ASSERT(status == Fw::SerializeStatus::FW_SERIALIZE_OK);
86
1/1
✓ Branch 2 taken 668 times.
668 this->m_lastContext = value.get_context();
87
1/1
✓ Branch 1 taken 668 times.
668 Fw::Success good = Fw::Success::SUCCESS;
88 // Return port does not alter data and thus const-cast is safe
89
1/1
✓ Branch 3 taken 668 times.
668 this->dataReturnOut_out(0, const_cast<Fw::Buffer&>(value.get_data()), value.get_context());
90
1/1
✓ Branch 1 taken 668 times.
668 this->comStatusOut_out(0, good);
91 668 }
92
93 229 void ComAggregator ::Svc_AggregationMachine_action_doSend(SmId smId, Svc_AggregationMachine::Signal signal) {
94 // Send only when the buffer will be valid
95
1/2
✓ Branch 1 taken 229 times.
✗ Branch 2 not taken.
229 if (this->m_frameSerializer.getSize() > 0) {
96 const Fw::Buffer::OwnershipState previousState =
97 229 this->m_bufferState.exchange(Fw::Buffer::OwnershipState::NOT_OWNED);
98 229 FW_ASSERT(previousState == Fw::Buffer::OwnershipState::OWNED, static_cast<FwAssertArgType>(previousState));
99 229 this->m_frameBuffer.setSize(this->m_frameSerializer.getSize());
100 229 this->m_allow_timeout = false; // Timeout messages should be discarded in WAIT_STATUS state
101 229 this->dataOut_out(0, this->m_frameBuffer, this->m_lastContext);
102 }
103 229 }
104
105 16 void ComAggregator ::Svc_AggregationMachine_action_doHold(SmId smId,
106 Svc_AggregationMachine::Signal signal,
107 const Svc::ComDataContextPair& value) {
108 16 FW_ASSERT(not this->m_held.get_data().isValid());
109 16 this->m_held = value;
110 16 }
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 654 bool ComAggregator ::Svc_AggregationMachine_guard_isFull(SmId smId,
122 Svc_AggregationMachine::Signal signal,
123 const Svc::ComDataContextPair& value) const {
124 654 FW_ASSERT(value.get_data().getSize() <= ComCfg::AggregationSize);
125 654 const FwSizeType remaining = this->m_frameSerializer.getCapacity() - this->m_frameSerializer.getSize();
126 654 return (remaining < value.get_data().getSize());
127 }
128
129 652 bool ComAggregator ::Svc_AggregationMachine_guard_willFill(SmId smId,
130 Svc_AggregationMachine::Signal signal,
131 const Svc::ComDataContextPair& value) const {
132 652 FW_ASSERT(value.get_data().getSize() <= ComCfg::AggregationSize);
133 652 const FwSizeType remaining = this->m_frameSerializer.getCapacity() - this->m_frameSerializer.getSize();
134 652 return (remaining == value.get_data().getSize());
135 }
136
137 233 bool ComAggregator ::Svc_AggregationMachine_guard_isNotEmpty(SmId smId, Svc_AggregationMachine::Signal signal) const {
138 233 return this->m_frameSerializer.getSize() > 0;
139 }
140
141 230 bool ComAggregator ::Svc_AggregationMachine_guard_isGood(SmId smId,
142 Svc_AggregationMachine::Signal signal,
143 const Fw::Success& value) const {
144 230 return value == Fw::Success::SUCCESS;
145 }
146
147 } // namespace Svc
148