GCC Code Coverage Report


Directory: ./
File: Svc/FprimeRouter/FprimeRouter.cpp
Date: 2026-09-03 21:13:48
Exec Total Coverage
Lines: 55 57 96.5%
Functions: 7 7 100.0%
Branches: 46 56 82.1%

Line Branch Exec Source
1 // ======================================================================
2 // \title FprimeRouter.cpp
3 // \author thomas-bc
4 // \brief cpp file for FprimeRouter component implementation class
5 // ======================================================================
6
7 #include "Svc/FprimeRouter/FprimeRouter.hpp"
8 #include "Fw/Com/ComPacket.hpp"
9 #include "Fw/FPrimeBasicTypes.hpp"
10 #include "Fw/Logger/Logger.hpp"
11 #include "config/ApidEnumAc.hpp"
12
13 namespace Svc {
14
15 // ----------------------------------------------------------------------
16 // Component construction and destruction
17 // ----------------------------------------------------------------------
18
19
3/9
✓ Branch 10 taken 500 times.
✓ Branch 13 taken 500 times.
✓ Branch 14 taken 10 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
510 FprimeRouter ::FprimeRouter(const char* const compName) : FprimeRouterComponentBase(compName) {
20 // Mark every table entry unused
21
2/2
✓ Branch 1 taken 500 times.
✓ Branch 2 taken 10 times.
510 for (FwSizeType i = 0; i < FW_NUM_ARRAY_ELEMENTS(this->m_bufferContextTable); i++) {
22
1/1
✓ Branch 6 taken 500 times.
500 this->m_bufferContextTable[i].state = Fw::Active::INACTIVE;
23 }
24 10 }
25
26
3/4
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 11 taken 500 times.
✓ Branch 12 taken 10 times.
1020 FprimeRouter ::~FprimeRouter() {}
27
28 // ----------------------------------------------------------------------
29 // Handler implementations for user-defined typed input ports
30 // ----------------------------------------------------------------------
31
32 109 void FprimeRouter ::dataIn_handler(FwIndexType portNum, Fw::Buffer& packetBuffer, const ComCfg::FrameContext& context) {
33 Fw::SerializeStatus status;
34 109 Fw::ComPacketType packetType = context.get_apid();
35 // Route based on received APID (packet type)
36
3/3
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 55 times.
✓ Branch 2 taken 53 times.
109 switch (packetType) {
37 // Handle a command packet
38 1 case Fw::ComPacketType::FW_PACKET_COMMAND: {
39 // Allocate a com buffer on the stack
40
1/1
✓ Branch 2 taken 1 times.
1 Fw::ComBuffer com;
41 // Copy the contents of the packet buffer into the com buffer
42
3/3
✓ Branch 5 taken 1 times.
✓ Branch 11 taken 1 times.
✓ Branch 14 taken 1 times.
1 status = com.setBuff(packetBuffer.getData(), packetBuffer.getSize());
43
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (status == Fw::FW_SERIALIZE_OK) {
44 // Send the com buffer - critical functionality so it is considered an error not to
45 // have the port connected. This is why we don't check isConnected() before sending.
46
1/1
✓ Branch 5 taken 1 times.
1 this->commandOut_out(0, com, 0);
47 } else {
48 this->log_WARNING_HI_SerializationError(status);
49 }
50 // The command buffer was copied into the com buffer above, so ownership of the
51 // incoming packetBuffer is returned immediately with the context it was received with.
52
1/1
✓ Branch 5 taken 1 times.
1 this->dataReturnOut_out(0, packetBuffer, context);
53 1 break;
54 1 }
55 // Handle a file packet
56 55 case Fw::ComPacketType::FW_PACKET_FILE: {
57 // If the file uplink output port is connected, send the file packet directly.
58 // Ownership is passed to the receiver and will come back on fileBufferReturnIn,
59 // at which point we return it to the deframer via dataReturnOut. fileOut carries
60 // only Fw::Buffer, so remember the context here to restore it on return.
61
1/2
✓ Branch 5 taken 55 times.
✗ Branch 6 not taken.
55 if (this->isConnected_fileOut_OutputPort(0)) {
62
3/3
✓ Branch 3 taken 55 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 54 times.
55 if (this->insertContext(packetBuffer, context) == Fw::Success::FAILURE) {
63 1 this->log_WARNING_HI_FileOutContextTableFull();
64 }
65 55 this->fileOut_out(0, packetBuffer);
66 } else {
67 // Port not connected, return the buffer immediately with its context
68 this->dataReturnOut_out(0, packetBuffer, context);
69 }
70 55 break;
71 }
72 53 default: {
73 // Packet type is not known to the F Prime protocol. If the unknownDataOut port is
74 // connected, forward packet and context for further processing.
75 // Ownership is passed to the receiver and will come back on fileBufferReturnIn,
76 // at which point we return it to the deframer via dataReturnOut. The return path
77 // (fileBufferReturnIn) carries no context, so remember it here to restore on return.
78
2/2
✓ Branch 5 taken 52 times.
✓ Branch 6 taken 1 times.
53 if (this->isConnected_unknownDataOut_OutputPort(0)) {
79
3/3
✓ Branch 3 taken 52 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 51 times.
52 if (this->insertContext(packetBuffer, context) == Fw::Success::FAILURE) {
80 1 this->log_WARNING_HI_UnknownDataOutContextTableFull();
81 }
82 52 this->unknownDataOut_out(0, packetBuffer, context);
83 } else {
84 // Port not connected, return the buffer immediately with its context
85 1 this->dataReturnOut_out(0, packetBuffer, context);
86 }
87 53 break;
88 }
89 }
90 109 }
91
92 1 void FprimeRouter ::cmdResponseIn_handler(FwIndexType portNum,
93 FwOpcodeType opcode,
94 U32 cmdSeq,
95 const Fw::CmdResponse& response) {
96 // Nothing to do
97 1 }
98
99 6 void FprimeRouter ::fileBufferReturnIn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) {
100 // Restore the context that was saved when this buffer was handed off on
101 // fileOut/unknownDataOut
102
1/1
✓ Branch 2 taken 6 times.
6 ComCfg::FrameContext context;
103
3/3
✓ Branch 3 taken 6 times.
✓ Branch 12 taken 3 times.
✓ Branch 13 taken 3 times.
6 if (this->takeContext(fwBuffer, context) == Fw::Success::FAILURE) {
104 // Buffer not found in the table: return with an empty context (already default)
105
1/1
✓ Branch 5 taken 3 times.
3 this->log_WARNING_HI_BufferContextNotFound();
106 }
107
1/1
✓ Branch 5 taken 6 times.
6 this->dataReturnOut_out(0, fwBuffer, context);
108 12 }
109
110 // ----------------------------------------------------------------------
111 // Buffer-to-context association table helpers
112 // ----------------------------------------------------------------------
113
114 107 Fw::Success FprimeRouter ::insertContext(const Fw::Buffer& buffer, const ComCfg::FrameContext& context) {
115 107 const U8* key = buffer.getData();
116
2/2
✓ Branch 1 taken 2656 times.
✓ Branch 2 taken 2 times.
2658 for (FwSizeType i = 0; i < FW_NUM_ARRAY_ELEMENTS(this->m_bufferContextTable); i++) {
117
2/2
✓ Branch 6 taken 105 times.
✓ Branch 7 taken 2551 times.
2656 if (this->m_bufferContextTable[i].state == Fw::Active::INACTIVE) {
118 105 this->m_bufferContextTable[i].state = Fw::Active::ACTIVE;
119 105 this->m_bufferContextTable[i].key = key;
120 105 this->m_bufferContextTable[i].context = context;
121 105 return Fw::Success::SUCCESS;
122 }
123 }
124 // Table full
125 2 return Fw::Success::FAILURE;
126 }
127
128 6 Fw::Success FprimeRouter ::takeContext(const Fw::Buffer& buffer, ComCfg::FrameContext& context) {
129 6 const U8* key = buffer.getData();
130
2/2
✓ Branch 1 taken 154 times.
✓ Branch 2 taken 3 times.
157 for (FwSizeType i = 0; i < FW_NUM_ARRAY_ELEMENTS(this->m_bufferContextTable); i++) {
131
6/6
✓ Branch 6 taken 104 times.
✓ Branch 7 taken 50 times.
✓ Branch 12 taken 3 times.
✓ Branch 13 taken 101 times.
✓ Branch 14 taken 3 times.
✓ Branch 15 taken 151 times.
154 if (this->m_bufferContextTable[i].state == Fw::Active::ACTIVE && this->m_bufferContextTable[i].key == key) {
132 3 context = this->m_bufferContextTable[i].context;
133 3 this->m_bufferContextTable[i].state = Fw::Active::INACTIVE;
134 3 return Fw::Success::SUCCESS;
135 }
136 }
137 // Not found
138 3 return Fw::Success::FAILURE;
139 }
140
141 } // namespace Svc
142