GCC Code Coverage Report


Directory: ./
File: Svc/Ccsds/CfdpManager/Types/AckPdu.cpp
Date: 2026-09-03 21:13:48
Exec Total Coverage
Lines: 63 72 87.5%
Functions: 6 6 100.0%
Branches: 22 31 71.0%

Line Branch Exec Source
1 // ======================================================================
2 // \title AckPdu.cpp
3 // \author Brian Campuzano
4 // \brief cpp file for CFDP ACK (Acknowledge) PDU
5 // ======================================================================
6
7 #include <Fw/Types/Assert.hpp>
8 #include <Svc/Ccsds/CfdpManager/Types/AckPdu.hpp>
9
10 namespace Svc {
11 namespace Ccsds {
12 namespace Cfdp {
13
14 47 void AckPdu::initialize(PduDirection direction,
15 Cfdp::Class::T txmMode,
16 EntityId sourceEid,
17 TransactionSeq transactionSeq,
18 EntityId destEid,
19 FileDirective directiveCode,
20 U8 directiveSubtypeCode,
21 ConditionCode conditionCode,
22 AckTxnStatus transactionStatus) {
23 // Initialize header with PduTypeEnum::ACKNOWLEDGMENT type
24 47 this->m_header.initialize(PduTypeEnum::ACKNOWLEDGMENT, direction, txmMode, sourceEid, transactionSeq, destEid);
25
26 47 this->m_directiveCode = directiveCode;
27 47 this->m_directiveSubtypeCode = directiveSubtypeCode;
28 47 this->m_conditionCode = conditionCode;
29 47 this->m_transactionStatus = transactionStatus;
30 47 }
31
32 71 U32 AckPdu::getBufferSize() const {
33 71 U32 size = this->m_header.getBufferSize();
34
35 // Directive code: 1 byte (FileDirective::FILE_DIRECTIVE_ACK)
36 // Directive and subtype code (bit-packed): 1 byte
37 // Condition code and transaction status (bit-packed): 1 byte
38 71 size += static_cast<U32>(sizeof(U8) + sizeof(U8) + sizeof(U8));
39
40 71 return size;
41 }
42
43 46 Fw::SerializeStatus AckPdu::serializeTo(Fw::SerialBufferBase& buffer, Fw::Endianness mode) const {
44 46 return this->toSerialBuffer(buffer);
45 }
46
47 38 Fw::SerializeStatus AckPdu::deserializeFrom(Fw::SerialBufferBase& buffer, Fw::Endianness mode) {
48 // Deserialize header first
49
1/1
✓ Branch 4 taken 38 times.
38 Fw::SerializeStatus status = this->m_header.fromSerialBuffer(buffer);
50
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 37 times.
38 if (status != Fw::FW_SERIALIZE_OK) {
51 1 return status;
52 }
53
54 // Validate this is a directive PDU (not file data)
55
1/2
✗ Branch 5 not taken.
✓ Branch 6 taken 37 times.
37 if (this->m_header.m_pduType != PduType::PDU_TYPE_DIRECTIVE) {
56 return Fw::FW_DESERIALIZE_TYPE_MISMATCH;
57 }
58
59 // Validate directive code
60 37 U8 directiveCode;
61
1/1
✓ Branch 7 taken 37 times.
37 status = buffer.deserializeTo(directiveCode);
62
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
37 if (status != Fw::FW_SERIALIZE_OK) {
63 return status;
64 }
65
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
37 if (directiveCode != static_cast<U8>(FileDirective::FILE_DIRECTIVE_ACK)) {
66 return Fw::FW_DESERIALIZE_TYPE_MISMATCH;
67 }
68
69 // Now set the type to PduTypeEnum::ACKNOWLEDGMENT since we've validated it
70 37 this->m_header.m_type = PduTypeEnum::ACKNOWLEDGMENT;
71
72 // Deserialize the ACK body
73
1/1
✓ Branch 4 taken 37 times.
37 return this->fromSerialBuffer(buffer);
74 }
75
76 46 Fw::SerializeStatus AckPdu::toSerialBuffer(Fw::SerialBufferBase& serialBuffer) const {
77 46 FW_ASSERT(this->m_header.m_type == PduTypeEnum::ACKNOWLEDGMENT);
78
79 // Calculate PDU data length (everything after header)
80
2/2
✓ Branch 7 taken 46 times.
✓ Branch 15 taken 46 times.
46 U32 dataLength = this->getBufferSize() - this->m_header.getBufferSize();
81
82 // Update header with data length
83 46 PduHeader headerCopy = this->m_header;
84 46 headerCopy.setPduDataLength(static_cast<U16>(dataLength));
85
86 // Serialize header
87
1/1
✓ Branch 1 taken 46 times.
46 Fw::SerializeStatus status = headerCopy.toSerialBuffer(serialBuffer);
88
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (status != Fw::FW_SERIALIZE_OK) {
89 return status;
90 }
91
92 // Directive code (ACK = 6)
93 46 U8 directiveCodeByte = static_cast<U8>(FileDirective::FILE_DIRECTIVE_ACK);
94
1/1
✓ Branch 7 taken 46 times.
46 status = serialBuffer.serializeFrom(directiveCodeByte);
95
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (status != Fw::FW_SERIALIZE_OK) {
96 return status;
97 }
98
99 // Directive and subtype code (bit-packed into 1 byte)
100 // Bits 7-4: Directive code being acknowledged (4 bits)
101 // Bits 3-0: Directive subtype code (4 bits)
102 46 U8 directiveAndSubtype = 0;
103 46 directiveAndSubtype =
104 46 static_cast<U8>(directiveAndSubtype | static_cast<U8>((static_cast<U8>(this->m_directiveCode) & 0x0FU) << 4));
105 46 directiveAndSubtype = static_cast<U8>(directiveAndSubtype | (this->m_directiveSubtypeCode & 0x0FU));
106
107
1/1
✓ Branch 7 taken 46 times.
46 status = serialBuffer.serializeFrom(directiveAndSubtype);
108
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (status != Fw::FW_SERIALIZE_OK) {
109 return status;
110 }
111
112 // Condition code and transaction status (bit-packed into 1 byte)
113 // Bits 7-4: Condition code (4 bits)
114 // Bits 3-2: Spare (0)
115 // Bits 1-0: Transaction status (2 bits)
116 46 U8 ccAndStatus = 0;
117 46 ccAndStatus = static_cast<U8>(ccAndStatus | static_cast<U8>((static_cast<U8>(this->m_conditionCode) & 0x0FU) << 4));
118 46 ccAndStatus = static_cast<U8>(ccAndStatus | (static_cast<U8>(this->m_transactionStatus) & 0x03U));
119
120
1/1
✓ Branch 7 taken 46 times.
46 status = serialBuffer.serializeFrom(ccAndStatus);
121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (status != Fw::FW_SERIALIZE_OK) {
122 return status;
123 }
124
125 46 return Fw::FW_SERIALIZE_OK;
126 }
127
128 37 Fw::SerializeStatus AckPdu::fromSerialBuffer(Fw::SerialBufferBase& serialBuffer) {
129 37 FW_ASSERT(this->m_header.m_type == PduTypeEnum::ACKNOWLEDGMENT);
130
131 // Directive code already read by fromBuffer()
132
133 // Directive and subtype code (packed byte)
134 37 U8 directiveAndSubtype;
135
1/1
✓ Branch 7 taken 37 times.
37 Fw::SerializeStatus status = serialBuffer.deserializeTo(directiveAndSubtype);
136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
37 if (status != Fw::FW_SERIALIZE_OK) {
137 return status;
138 }
139
140 // Extract fields from directive and subtype byte:
141 // Bits 7-4: Directive code being acknowledged
142 // Bits 3-0: Directive subtype code
143 37 U8 directiveCodeVal = (directiveAndSubtype >> 4) & 0x0F;
144 37 U8 subtypeCodeVal = directiveAndSubtype & 0x0F;
145
146 37 this->m_directiveCode = static_cast<FileDirective>(directiveCodeVal);
147 37 this->m_directiveSubtypeCode = subtypeCodeVal;
148
149 // Condition code and transaction status (packed byte)
150 37 U8 ccAndStatus;
151
1/1
✓ Branch 7 taken 37 times.
37 status = serialBuffer.deserializeTo(ccAndStatus);
152
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
37 if (status != Fw::FW_SERIALIZE_OK) {
153 return status;
154 }
155
156 // Extract fields from condition code and transaction status byte:
157 // Bits 7-4: Condition code
158 // Bits 3-2: Spare
159 // Bits 1-0: Transaction status
160 37 U8 conditionCodeVal = (ccAndStatus >> 4) & 0x0F;
161 37 U8 transactionStatusVal = ccAndStatus & 0x03;
162
163 37 this->m_conditionCode = static_cast<ConditionCode>(conditionCodeVal);
164 37 this->m_transactionStatus = static_cast<AckTxnStatus>(transactionStatusVal);
165
166 37 return Fw::FW_SERIALIZE_OK;
167 }
168
169 } // namespace Cfdp
170 } // namespace Ccsds
171 } // namespace Svc
172