GCC Code Coverage Report


Directory: ./
File: Types/FileDataPdu.cpp
Date: 2026-09-23 22:12:37
Exec Total Coverage
Lines: 0 84 0.0%
Functions: 0 9 0.0%
Branches: 0 54 0.0%

Line Branch Exec Source
1 // ======================================================================
2 // \title FileDataPdu.cpp
3 // \author Brian Campuzano
4 // \brief cpp file for CFDP File Data PDU
5 // ======================================================================
6
7 #include <Fw/Types/Assert.hpp>
8 #include <Svc/Ccsds/CfdpManager/Types/FileDataPdu.hpp>
9 #include <config/CfdpCfg.hpp>
10
11 namespace Svc {
12 namespace Ccsds {
13 namespace Cfdp {
14
15 ✗ void FileDataPdu::initialize(PduDirection direction,
16 Cfdp::Class::T txmMode,
17 EntityId sourceEid,
18 TransactionSeq transactionSeq,
19 EntityId destEid,
20 FileSize offset,
21 U16 dataSize,
22 const U8* data) {
23 // Initialize header with PduTypeEnum::FILE_DATA type
24 ✗ this->m_header.initialize(PduTypeEnum::FILE_DATA, direction, txmMode, sourceEid, transactionSeq, destEid);
25
26 ✗ this->m_offset = offset;
27 ✗ this->m_dataSize = dataSize;
28 ✗ this->m_data = data;
29 ✗ }
30
31 ✗ U32 FileDataPdu::getBufferSize() const {
32 ✗ U32 size = this->m_header.getBufferSize();
33
34 // Offset field size depends on large file flag
35 ✗ if (this->m_header.m_largeFileFlag == LargeFileFlag::LARGE_FILE_64_BIT) {
36 ✗ size += static_cast<U32>(sizeof(U64)); // 8-byte offset
37 } else {
38 ✗ size += static_cast<U32>(sizeof(U32)); // 4-byte offset
39 }
40
41 ✗ size += this->m_dataSize; // actual data
42 ✗ return size;
43 }
44
45 ✗ U32 FileDataPdu::getMaxFileDataSize() {
46 ✗ U32 size = this->m_header.getBufferSize();
47
48 // Offset field size depends on large file flag
49 ✗ if (this->m_header.m_largeFileFlag == LargeFileFlag::LARGE_FILE_64_BIT) {
50 ✗ size += static_cast<U32>(sizeof(U64)); // 8-byte offset
51 } else {
52 ✗ size += static_cast<U32>(sizeof(U32)); // 4-byte offset
53 }
54
55 ✗ return MaxPduSize - size;
56 }
57
58 ✗ Fw::SerializeStatus FileDataPdu::toBuffer(Fw::Buffer& buffer) const {
59 ✗ Fw::SerialBuffer serialBuffer(buffer.getData(), buffer.getSize());
60 ✗ Fw::SerializeStatus status = this->toSerialBuffer(serialBuffer);
61 ✗ if (status == Fw::FW_SERIALIZE_OK) {
62 ✗ buffer.setSize(serialBuffer.getSize());
63 }
64 ✗ return status;
65 ✗ }
66
67 ✗ Fw::SerializeStatus FileDataPdu::fromBuffer(const Fw::Buffer& buffer) {
68 // Create SerialBuffer from Buffer
69 ✗ Fw::SerialBuffer serialBuffer(const_cast<Fw::Buffer&>(buffer).getData(), const_cast<Fw::Buffer&>(buffer).getSize());
70 ✗ serialBuffer.fill();
71
72 // Deserialize header first
73 ✗ Fw::SerializeStatus status = this->m_header.fromSerialBuffer(serialBuffer);
74 ✗ if (status != Fw::FW_SERIALIZE_OK) {
75 ✗ return status;
76 }
77
78 // Validate this is a file data PDU
79 ✗ if (this->m_header.m_pduType != PduType::PDU_TYPE_FILE_DATA) {
80 ✗ return Fw::FW_DESERIALIZE_TYPE_MISMATCH;
81 }
82
83 // Set the type to PduTypeEnum::FILE_DATA since we've validated it
84 ✗ this->m_header.m_type = PduTypeEnum::FILE_DATA;
85
86 // Deserialize the file data body
87 ✗ return this->fromSerialBuffer(serialBuffer);
88 ✗ }
89
90 ✗ Fw::SerializeStatus FileDataPdu::toSerialBuffer(Fw::SerialBuffer& serialBuffer) const {
91 ✗ FW_ASSERT(this->m_header.m_type == PduTypeEnum::FILE_DATA);
92
93 // Calculate PDU data length (everything after header)
94 ✗ U32 dataLength = this->getBufferSize() - this->m_header.getBufferSize();
95
96 // Update header with data length
97 ✗ PduHeader headerCopy = this->m_header;
98 ✗ headerCopy.setPduDataLength(static_cast<U16>(dataLength));
99
100 // Serialize header
101 ✗ Fw::SerializeStatus status = headerCopy.toSerialBuffer(serialBuffer);
102 ✗ if (status != Fw::FW_SERIALIZE_OK) {
103 ✗ return status;
104 }
105
106 // Serialize offset - size depends on large file flag
107 ✗ if (this->m_header.m_largeFileFlag == LargeFileFlag::LARGE_FILE_64_BIT) {
108 // Serialize as 8 bytes (64-bit)
109 ✗ U64 offset64 = this->m_offset;
110 ✗ status = serialBuffer.serializeFrom(offset64);
111 } else {
112 // Serialize as 4 bytes (32-bit)
113 ✗ U32 offset32 = static_cast<U32>(this->m_offset);
114 ✗ status = serialBuffer.serializeFrom(offset32);
115 }
116 ✗ if (status != Fw::FW_SERIALIZE_OK) {
117 ✗ return status;
118 }
119
120 // Serialize file data (only if there is data to serialize)
121 ✗ if (this->m_dataSize > 0) {
122 ✗ status = serialBuffer.pushBytes(this->m_data, this->m_dataSize);
123 ✗ if (status != Fw::FW_SERIALIZE_OK) {
124 ✗ return status;
125 }
126 }
127
128 ✗ return Fw::FW_SERIALIZE_OK;
129 }
130
131 ✗ Fw::SerializeStatus FileDataPdu::fromSerialBuffer(Fw::SerialBuffer& serialBuffer) {
132 ✗ FW_ASSERT(this->m_header.m_type == PduTypeEnum::FILE_DATA);
133
134 // Deserialize offset - size depends on large file flag
135 Fw::SerializeStatus status;
136 U8 offsetSize;
137 ✗ status = serialBuffer.deserializeTo(this->m_offset);
138 ✗ if (status != Fw::FW_SERIALIZE_OK) {
139 ✗ return status;
140 }
141 ✗ offsetSize = sizeof(this->m_offset);
142
143 // Calculate remaining data size based on header's PDU data length
144 ✗ U16 pduDataLength = this->m_header.getPduDataLength();
145
146 // Defensive check: prevent unsigned integer underflow
147 ✗ if (pduDataLength < offsetSize) {
148 ✗ return Fw::FW_DESERIALIZE_SIZE_MISMATCH;
149 }
150
151 ✗ this->m_dataSize = static_cast<U16>(pduDataLength - offsetSize); // minus offset size
152
153 // Point to the data in the buffer (zero-copy)
154 ✗ this->m_data = serialBuffer.getBuffAddrLeft();
155
156 // Validate we have enough bytes
157 ✗ if (serialBuffer.getDeserializeSizeLeft() < this->m_dataSize) {
158 ✗ return Fw::FW_DESERIALIZE_SIZE_MISMATCH;
159 }
160
161 // Advance the buffer pointer
162 U8 tempBuf[1]; // Dummy buffer for validation
163 ✗ for (U16 i = 0; i < this->m_dataSize; ++i) {
164 ✗ status = serialBuffer.popBytes(tempBuf, 1);
165 ✗ if (status != Fw::FW_SERIALIZE_OK) {
166 ✗ return status;
167 }
168 }
169
170 ✗ return Fw::FW_SERIALIZE_OK;
171 }
172
173 ✗ Fw::SerializeStatus FileDataPdu::serializeTo(Fw::SerialBufferBase& buffer, Fw::Endianness mode) const {
174 // Caller contract guarantees a SerialBuffer.
175 ✗ Fw::SerialBuffer* serialBuffer = static_cast<Fw::SerialBuffer*>(&buffer);
176 ✗ return this->toSerialBuffer(*serialBuffer);
177 }
178
179 ✗ Fw::SerializeStatus FileDataPdu::deserializeFrom(Fw::SerialBufferBase& buffer, Fw::Endianness mode) {
180 // Caller contract guarantees a SerialBuffer.
181 ✗ Fw::SerialBuffer* serialBuffer = static_cast<Fw::SerialBuffer*>(&buffer);
182
183 // Deserialize header first
184 ✗ Fw::SerializeStatus status = this->m_header.fromSerialBuffer(*serialBuffer);
185 ✗ if (status != Fw::FW_SERIALIZE_OK) {
186 ✗ return status;
187 }
188
189 // Deserialize the file data body
190 ✗ return this->fromSerialBuffer(*serialBuffer);
191 }
192
193 } // namespace Cfdp
194 } // namespace Ccsds
195 } // namespace Svc
196