GCC Code Coverage Report


Directory: Svc/Ccsds/CfdpManager/Types/
File: AckPdu.cpp
Date: 2026-09-03 21:16:30
Exec Total Coverage
Lines: 62 72 86.1%
Functions: 6 6 100.0%
Branches: 21 31 67.7%

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 22 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 22 this->m_header.initialize(PduTypeEnum::ACKNOWLEDGMENT, direction, txmMode, sourceEid, transactionSeq, destEid);
25
26 22 this->m_directiveCode = directiveCode;
27 22 this->m_directiveSubtypeCode = directiveSubtypeCode;
28 22 this->m_conditionCode = conditionCode;
29 22 this->m_transactionStatus = transactionStatus;
30 22 }
31
32 22 U32 AckPdu::getBufferSize() const {
33 22 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 22 size += static_cast<U32>(sizeof(U8) + sizeof(U8) + sizeof(U8));
39
40 22 return size;
41 }
42
43 21 Fw::SerializeStatus AckPdu::serializeTo(Fw::SerialBufferBase& buffer, Fw::Endianness mode) const {
44 21 return this->toSerialBuffer(buffer);
45 }
46
47 21 Fw::SerializeStatus AckPdu::deserializeFrom(Fw::SerialBufferBase& buffer, Fw::Endianness mode) {
48 // Deserialize header first
49
1/1
✓ Branch 4 taken 21 times.
21 Fw::SerializeStatus status = this->m_header.fromSerialBuffer(buffer);
50
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (status != Fw::FW_SERIALIZE_OK) {
51 return status;
52 }
53
54 // Validate this is a directive PDU (not file data)
55
1/2
✗ Branch 5 not taken.
✓ Branch 6 taken 21 times.
21 if (this->m_header.m_pduType != PduType::PDU_TYPE_DIRECTIVE) {
56 return Fw::FW_DESERIALIZE_TYPE_MISMATCH;
57 }
58
59 // Validate directive code
60 21 U8 directiveCode;
61
1/1
✓ Branch 7 taken 21 times.
21 status = buffer.deserializeTo(directiveCode);
62
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (status != Fw::FW_SERIALIZE_OK) {
63 return status;
64 }
65
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 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 21 this->m_header.m_type = PduTypeEnum::ACKNOWLEDGMENT;
71
72 // Deserialize the ACK body
73
1/1
✓ Branch 4 taken 21 times.
21 return this->fromSerialBuffer(buffer);
74 }
75
76 21 Fw::SerializeStatus AckPdu::toSerialBuffer(Fw::SerialBufferBase& serialBuffer) const {
77 21 FW_ASSERT(this->m_header.m_type == PduTypeEnum::ACKNOWLEDGMENT);
78
79 // Calculate PDU data length (everything after header)
80
2/2
✓ Branch 7 taken 21 times.
✓ Branch 15 taken 21 times.
21 U32 dataLength = this->getBufferSize() - this->m_header.getBufferSize();
81
82 // Update header with data length
83 21 PduHeader headerCopy = this->m_header;
84 21 headerCopy.setPduDataLength(static_cast<U16>(dataLength));
85
86 // Serialize header
87
1/1
✓ Branch 1 taken 21 times.
21 Fw::SerializeStatus status = headerCopy.toSerialBuffer(serialBuffer);
88
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (status != Fw::FW_SERIALIZE_OK) {
89 return status;
90 }
91
92 // Directive code (ACK = 6)
93 21 U8 directiveCodeByte = static_cast<U8>(FileDirective::FILE_DIRECTIVE_ACK);
94
1/1
✓ Branch 7 taken 21 times.
21 status = serialBuffer.serializeFrom(directiveCodeByte);
95
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 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 21 U8 directiveAndSubtype = 0;
103 21 directiveAndSubtype =
104 21 static_cast<U8>(directiveAndSubtype | static_cast<U8>((static_cast<U8>(this->m_directiveCode) & 0x0FU) << 4));
105 21 directiveAndSubtype = static_cast<U8>(directiveAndSubtype | (this->m_directiveSubtypeCode & 0x0FU));
106
107
1/1
✓ Branch 7 taken 21 times.
21 status = serialBuffer.serializeFrom(directiveAndSubtype);
108
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 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 21 U8 ccAndStatus = 0;
117 21 ccAndStatus = static_cast<U8>(ccAndStatus | static_cast<U8>((static_cast<U8>(this->m_conditionCode) & 0x0FU) << 4));
118 21 ccAndStatus = static_cast<U8>(ccAndStatus | (static_cast<U8>(this->m_transactionStatus) & 0x03U));
119
120
1/1
✓ Branch 7 taken 21 times.
21 status = serialBuffer.serializeFrom(ccAndStatus);
121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (status != Fw::FW_SERIALIZE_OK) {
122 return status;
123 }
124
125 21 return Fw::FW_SERIALIZE_OK;
126 }
127
128 21 Fw::SerializeStatus AckPdu::fromSerialBuffer(Fw::SerialBufferBase& serialBuffer) {
129 21 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 21 U8 directiveAndSubtype;
135
1/1
✓ Branch 7 taken 21 times.
21 Fw::SerializeStatus status = serialBuffer.deserializeTo(directiveAndSubtype);
136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 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 21 U8 directiveCodeVal = (directiveAndSubtype >> 4) & 0x0F;
144 21 U8 subtypeCodeVal = directiveAndSubtype & 0x0F;
145
146 21 this->m_directiveCode = static_cast<FileDirective>(directiveCodeVal);
147 21 this->m_directiveSubtypeCode = subtypeCodeVal;
148
149 // Condition code and transaction status (packed byte)
150 21 U8 ccAndStatus;
151
1/1
✓ Branch 7 taken 21 times.
21 status = serialBuffer.deserializeTo(ccAndStatus);
152
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 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 21 U8 conditionCodeVal = (ccAndStatus >> 4) & 0x0F;
161 21 U8 transactionStatusVal = ccAndStatus & 0x03;
162
163 21 this->m_conditionCode = static_cast<ConditionCode>(conditionCodeVal);
164 21 this->m_transactionStatus = static_cast<AckTxnStatus>(transactionStatusVal);
165
166 21 return Fw::FW_SERIALIZE_OK;
167 }
168
169 } // namespace Cfdp
170 } // namespace Ccsds
171 } // namespace Svc
172