GCC Code Coverage Report


Directory: ./
File: Svc/Ccsds/SpacePacketDeframer/SpacePacketDeframer.cpp
Date: 2026-10-14 22:11:56
Exec Total Coverage
Lines: 38 59 64.4%
Functions: 5 5 100.0%
Branches: 24 60 40.0%

Line Branch Exec Source
1 // ======================================================================
2 // \title SpacePacketDeframer.cpp
3 // \author thomas-bc
4 // \brief cpp file for SpacePacketDeframer component implementation class
5 // ======================================================================
6
7 #include "Svc/Ccsds/SpacePacketDeframer/SpacePacketDeframer.hpp"
8 #include "Svc/Ccsds/Types/FppConstantsAc.hpp"
9 #include "Svc/Ccsds/Types/SpacePacketHeaderSerializableAc.hpp"
10
11 namespace Svc {
12
13 namespace Ccsds {
14
15 // ----------------------------------------------------------------------
16 // Component construction and destruction
17 // ----------------------------------------------------------------------
18
19 1 SpacePacketDeframer ::SpacePacketDeframer(const char* const compName) : SpacePacketDeframerComponentBase(compName) {}
20
21 2 SpacePacketDeframer ::~SpacePacketDeframer() {}
22
23 namespace {
24
25 151 bool isValidPacketVersionNumber(const SpacePacketHeader& header) {
26 151 const U16 packetIdentification = header.get_packetIdentification();
27 151 const U16 pvn = (packetIdentification & SpacePacketSubfields::PvnMask) >> SpacePacketSubfields::PvnOffset;
28 151 return pvn == static_cast<U16>(ComCfg::Pvn::SPACE_PACKET_PROTOCOL);
29 }
30
31 } // namespace
32
33 // ----------------------------------------------------------------------
34 // Handler implementations for typed input ports
35 // ----------------------------------------------------------------------
36
37 151 void SpacePacketDeframer ::dataIn_handler(FwIndexType portNum, Fw::Buffer& data, const ComCfg::FrameContext& context) {
38 // ################################
39 // CCSDS SpacePacket Format:
40 // 6 octets - Primary Header
41 // 0-65536 octets - Data Field (with optional secondary header)
42
43 // CCSDS SpacePacket Primary Header:
44 // 3b - 000 - (PVN) Packet Version Number
45 // 1b - 0/1 - (PT) Packet Type
46 // 1b - 0/1 - (SHF) Secondary Header Flag
47 // 11b - n/a - (APID) Application Process ID
48 // 2b - 00/01/10/11 - Sequence Flag
49 // 14b - n/a - Sequence Count
50 // 16b - n/a - Packet Data Length
51 // ################################
52
53 // Check size and drop packets that are too-small
54
2/3
✓ Branch 1 taken 151 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 151 times.
151 if (data.getSize() <= SpacePacketHeader::SERIALIZED_SIZE) {
55 ✗ this->log_WARNING_HI_InvalidPacket();
56 ✗ if (this->isConnected_errorNotify_OutputPort(0)) {
57 ✗ this->errorNotify_out(0, Svc::Ccsds::FrameError::SP_INVALID_PACKET);
58 }
59 ✗ this->dataReturnOut_out(0, data, context); // Drop the packet
60 ✗ return;
61 }
62
63
1/1
✓ Branch 1 taken 151 times.
151 SpacePacketHeader header;
64
2/2
✓ Branch 1 taken 151 times.
✓ Branch 4 taken 151 times.
151 Fw::SerializeStatus status = data.getDeserializer().deserializeTo(header);
65 // Deserialization can still fail if the buffer is malformed despite passing the size check
66
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 151 times.
151 if (status != Fw::FW_SERIALIZE_OK) {
67 ✗ this->log_WARNING_HI_InvalidPacket();
68 ✗ if (this->isConnected_errorNotify_OutputPort(0)) {
69 ✗ this->errorNotify_out(0, Svc::Ccsds::FrameError::SP_INVALID_PACKET);
70 }
71 ✗ this->dataReturnOut_out(0, data, context); // Drop the packet
72 ✗ return;
73 }
74
75
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 151 times.
151 if (!isValidPacketVersionNumber(header)) {
76 ✗ this->log_WARNING_HI_InvalidPacket();
77 ✗ if (this->isConnected_errorNotify_OutputPort(0)) {
78 ✗ this->errorNotify_out(0, Svc::Ccsds::FrameError::SP_INVALID_PACKET);
79 }
80 ✗ this->dataReturnOut_out(0, data, context); // Drop the packet
81 ✗ return;
82 }
83
84 // Widen to U32 before adding 1 to prevent U16 truncation to 0 when packetDataLength == 0xFFFF (max U16 value).
85 // This is a undefined behavior condition in C++.
86 151 const U32 pkt_length = static_cast<U32>(header.get_packetDataLength()) + 1U;
87
4/7
✓ Branch 1 taken 151 times.
✓ Branch 3 taken 151 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 151 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 151 times.
302 if ((pkt_length > data.getSize() - SpacePacketHeader::SERIALIZED_SIZE) ||
88 151 (pkt_length > std::numeric_limits<FwSizeType>::max())) {
89 ✗ FwSizeType maxDataAvailable = data.getSize() - SpacePacketHeader::SERIALIZED_SIZE;
90 ✗ this->log_WARNING_HI_InvalidLength(pkt_length, maxDataAvailable);
91 ✗ if (this->isConnected_errorNotify_OutputPort(0)) {
92 ✗ this->errorNotify_out(0, Svc::Ccsds::FrameError::SP_INVALID_LENGTH);
93 }
94 ✗ this->dataReturnOut_out(0, data, context); // Drop the packet
95 ✗ return;
96 }
97
98 151 U16 apidValue = header.get_packetIdentification() & SpacePacketSubfields::ApidMask;
99
2/3
✓ Branch 1 taken 151 times.
✓ Branch 3 taken 151 times.
✗ Branch 4 not taken.
151 ComCfg::Apid::T apid = ComCfg::Apid::isValid(apidValue) ? static_cast<ComCfg::Apid::T>(apidValue)
100 151 : ComCfg::Apid::INVALID_UNINITIALIZED;
101
1/1
✓ Branch 1 taken 151 times.
151 ComCfg::FrameContext contextCopy = context;
102
1/1
✓ Branch 1 taken 151 times.
151 contextCopy.set_apid(apid);
103
104 // Extract packet type
105 151 U8 pktType = static_cast<U8>((header.get_packetIdentification() & SpacePacketSubfields::PktTypeMask) >>
106 151 SpacePacketSubfields::PktTypeOffset);
107
1/1
✓ Branch 1 taken 151 times.
151 contextCopy.set_pktType(static_cast<ComCfg::SppPacketType::T>(pktType));
108
109 // Extract secondary header flag
110 151 bool hasSecHdr = (header.get_packetIdentification() & SpacePacketSubfields::SecHdrMask) != 0;
111
1/1
✓ Branch 1 taken 151 times.
151 contextCopy.set_hasSecHdr(hasSecHdr);
112
113 // Extract sequence flags
114 151 U8 sequenceFlags = static_cast<U8>((header.get_packetSequenceControl() & SpacePacketSubfields::SeqFlagsMask) >>
115 151 SpacePacketSubfields::SeqFlagsOffset);
116
1/1
✓ Branch 1 taken 151 times.
151 contextCopy.set_sequenceFlags(sequenceFlags);
117
118 // Validate with the ApidManager that the sequence count is correct
119 151 U16 receivedSequenceCount = header.get_packetSequenceControl() & SpacePacketSubfields::SeqCountMask;
120
2/2
✓ Branch 1 taken 151 times.
✓ Branch 4 taken 151 times.
151 (void)this->validateApidSeqCount_out(0, apid, receivedSequenceCount);
121
1/1
✓ Branch 1 taken 151 times.
151 contextCopy.set_sequenceCount(receivedSequenceCount);
122
123 // Set data buffer to be of the encapsulated data: HEADER (6 bytes) | PACKET DATA
124
1/1
✓ Branch 1 taken 151 times.
151 data.advance(SpacePacketHeader::SERIALIZED_SIZE);
125
1/1
✓ Branch 1 taken 151 times.
151 data.setSize(pkt_length);
126
127
1/1
✓ Branch 1 taken 151 times.
151 this->dataOut_out(0, data, contextCopy);
128 151 }
129
130 151 void SpacePacketDeframer ::dataReturnIn_handler(FwIndexType portNum,
131 Fw::Buffer& data,
132 const ComCfg::FrameContext& context) {
133 151 this->dataReturnOut_out(0, data, context);
134 151 }
135
136 } // namespace Ccsds
137 } // namespace Svc
138