GCC Code Coverage Report


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