GCC Code Coverage Report


Directory: Svc/ComStub/
File: ComStub.cpp
Date: 2026-09-03 21:16:53
Exec Total Coverage
Lines: 69 70 98.6%
Functions: 10 10 100.0%
Branches: 46 54 85.2%

Line Branch Exec Source
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>
8 #include <Svc/ComStub/ComStub.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
1/1
✓ Branch 19 taken 10 times.
10 ComStub::ComStub(const char* const compName) : ComStubComponentBase(compName), m_reinitialize(true), m_retry_count(0) {}
19
20 20 ComStub::~ComStub() {}
21
22 // ----------------------------------------------------------------------
23 // Handler implementations for user-defined typed input ports
24 // ----------------------------------------------------------------------
25
26 7 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 7 FW_ASSERT(!this->m_reinitialize || !this->isConnected_comStatusOut_OutputPort(0));
29
2/2
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 2 times.
7 if (this->isConnected_drvSendOut_OutputPort(0)) {
30 5 this->handleSynchronousSend(sendBuffer, context);
31
1/2
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
2 } else if (this->isConnected_drvAsyncSendOut_OutputPort(0)) {
32 2 this->handleAsynchronousSend(sendBuffer, context);
33 } else {
34 FW_ASSERT(false); // Neither send port is connected, this should never happen
35 }
36 7 }
37
38 9 void ComStub::drvConnected_handler(const FwIndexType portNum) {
39
4/8
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 9 times.
✓ Branch 12 taken 9 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 9 times.
✗ Branch 15 not taken.
9 if (this->isConnected_comStatusOut_OutputPort(0) && m_reinitialize) {
40
1/1
✓ Branch 2 taken 9 times.
9 Fw::Success radioSuccess = Fw::Success::SUCCESS;
41 9 this->m_reinitialize = false;
42
1/1
✓ Branch 5 taken 9 times.
9 this->comStatusOut_out(0, radioSuccess);
43 9 }
44 9 }
45
46 4 void ComStub::drvReceiveIn_handler(const FwIndexType portNum,
47 Fw::Buffer& recvBuffer,
48 const Drv::ByteStreamStatus& recvStatus) {
49
2/2
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
4 if (recvStatus != Drv::ByteStreamStatus::OP_OK) {
50 // Receive failed - return buffer without processing
51 2 this->drvReceiveReturnOut_out(0, recvBuffer);
52 } else {
53 // Receive successful - forward data with empty context
54
1/1
✓ Branch 2 taken 2 times.
2 ComCfg::FrameContext emptyContext; // ComStub knows nothing about the received bytes, empty context
55
1/1
✓ Branch 5 taken 2 times.
2 this->dataOut_out(0, recvBuffer, emptyContext);
56 2 }
57 4 }
58
59 32 void ComStub::drvAsyncSendReturnIn_handler(FwIndexType portNum, //!< The port number
60 Fw::Buffer& fwBuffer, //!< The buffer
61 const Drv::ByteStreamStatus& sendStatus) {
62 // This should never be called if the drvAsyncSendOut port is not connected
63 32 FW_ASSERT(this->isConnected_drvAsyncSendOut_OutputPort(0));
64
2/2
✓ Branch 4 taken 31 times.
✓ Branch 5 taken 1 times.
32 if (sendStatus == Drv::ByteStreamStatus::SEND_RETRY) {
65 // Driver indicates we should retry
66 31 this->handleAsyncRetry(fwBuffer);
67 } else {
68 // Return buffer ownership and send status
69
1/1
✓ Branch 8 taken 1 times.
1 this->dataReturnOut_out(0, fwBuffer, this->m_storedContext);
70
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 this->m_reinitialize = (sendStatus.e != Drv::ByteStreamStatus::OP_OK);
71 1 this->m_retry_count = 0; // Reset retry count
72 // Send Com status
73 1 Fw::Success comSuccess =
74
3/5
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
1 (sendStatus.e == Drv::ByteStreamStatus::OP_OK) ? Fw::Success::SUCCESS : Fw::Success::FAILURE;
75
1/1
✓ Branch 5 taken 1 times.
1 this->comStatusOut_out(0, comSuccess);
76 1 }
77 32 }
78
79 1 void ComStub ::dataReturnIn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer, const ComCfg::FrameContext& context) {
80 1 this->drvReceiveReturnOut_out(0, fwBuffer);
81 1 }
82
83 // ----------------------------------------------------------------------
84 // Helper method implementations
85 // ----------------------------------------------------------------------
86
87 5 void ComStub::handleSynchronousSend(Fw::Buffer& sendBuffer, const ComCfg::FrameContext& context) {
88
1/1
✓ Branch 2 taken 5 times.
5 Drv::ByteStreamStatus sendStatus = Drv::ByteStreamStatus::SEND_RETRY;
89
1/1
✓ Branch 2 taken 5 times.
5 Fw::Success comSuccess = Fw::Success::FAILURE;
90
91 // Send to driver (and retry up to the retry limit)
92
6/6
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 4 times.
✓ Branch 8 taken 23 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 23 times.
✓ Branch 11 taken 5 times.
28 for (FwIndexType i = 0; sendStatus == Drv::ByteStreamStatus::SEND_RETRY && i < RETRY_LIMIT; i++) {
93
2/2
✓ Branch 3 taken 23 times.
✓ Branch 8 taken 23 times.
23 sendStatus = this->drvSendOut_out(0, sendBuffer);
94 }
95
96 // Handle the send status
97
2/2
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 2 times.
5 if (sendStatus == Drv::ByteStreamStatus::OP_OK) {
98
1/1
✓ Branch 2 taken 3 times.
3 comSuccess = Fw::Success::SUCCESS;
99
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
2 } else if (sendStatus == Drv::ByteStreamStatus::SEND_RETRY) {
100 // Retry exhaustion requires a driver reconnect to emit the recovery SUCCESS
101 1 this->m_reinitialize = true;
102
1/1
✓ Branch 1 taken 1 times.
1 Fw::Logger::log("ComStub RETRY_LIMIT exceeded, skipped sending data");
103 } else {
104 // Other error - need to reinitialize
105 1 this->m_reinitialize = true;
106 }
107
108 // Return buffer and send status
109
1/1
✓ Branch 5 taken 5 times.
5 this->dataReturnOut_out(0, sendBuffer, context);
110
1/1
✓ Branch 5 taken 5 times.
5 this->comStatusOut_out(0, comSuccess);
111 10 }
112
113 2 void ComStub::handleAsynchronousSend(Fw::Buffer& sendBuffer, const ComCfg::FrameContext& context) {
114 2 this->m_storedContext = context; // Store the context for async callback
115 2 this->drvAsyncSendOut_out(0, sendBuffer);
116 2 }
117
118 31 void ComStub::handleAsyncRetry(Fw::Buffer& fwBuffer) {
119 31 FW_ASSERT(this->m_retry_count <= this->RETRY_LIMIT, static_cast<FwAssertArgType>(this->m_retry_count));
120
2/2
✓ Branch 8 taken 30 times.
✓ Branch 9 taken 1 times.
31 if (this->m_retry_count < this->RETRY_LIMIT) {
121 // Attempt retry if under the limit
122 30 this->m_retry_count++;
123 30 this->drvAsyncSendOut_out(0, fwBuffer);
124 } else {
125 // Exceeded retry limit - return buffer and notify failure
126 // Retry exhaustion requires a driver reconnect to emit the recovery SUCCESS
127 1 this->m_reinitialize = true;
128
1/1
✓ Branch 8 taken 1 times.
1 this->dataReturnOut_out(0, fwBuffer, this->m_storedContext);
129
1/1
✓ Branch 2 taken 1 times.
1 Fw::Success comStatus = Fw::Success::FAILURE;
130
1/1
✓ Branch 5 taken 1 times.
1 this->comStatusOut_out(0, comStatus);
131
1/1
✓ Branch 1 taken 1 times.
1 Fw::Logger::log("ComStub RETRY_LIMIT exceeded, skipped sending data");
132 1 this->m_retry_count = 0; // Reset retry count
133 1 }
134 31 }
135
136 } // end namespace Svc
137