GCC Code Coverage Report


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