GCC Code Coverage Report


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