GCC Code Coverage Report


Directory: ./
File: Types/FinPdu.cpp
Date: 2026-09-03 22:13:22
Exec Total Coverage
Lines: 0 65 0.0%
Functions: 0 6 0.0%
Branches: 0 31 0.0%

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