F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
FileDataPdu.cpp
Go to the documentation of this file.
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>
9 #include <config/CfdpCfg.hpp>
10 
11 namespace Svc {
12 namespace Ccsds {
13 namespace Cfdp {
14 
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 
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 
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 
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 
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) {
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) {
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) {
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 
174  // Caller contract guarantees a SerialBuffer.
175  Fw::SerialBuffer* serialBuffer = static_cast<Fw::SerialBuffer*>(&buffer);
176  return this->toSerialBuffer(*serialBuffer);
177 }
178 
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
Fw::SerializeStatus toBuffer(Fw::Buffer &buffer) const
Convert this FileDataPdu to a Buffer.
Definition: FileDataPdu.cpp:58
U32 getBufferSize() const override
Compute the buffer size needed.
Definition: FileDataPdu.cpp:31
Serialization/Deserialization operation was successful.
A variable-length serializable buffer.
SerializeStatus serializeFrom(U8 val, Endianness mode=Endianness::BIG) override
Serialize an 8-bit unsigned integer value.
void setSize(FwSizeType size)
Definition: Buffer.cpp:75
Fw::SerializeStatus deserializeFrom(Fw::SerialBufferBase &buffer, Fw::Endianness mode=Fw::Endianness::BIG) override
Fw::Serializable interface - deserialize from buffer.
const U8 * getBuffAddrLeft() const
Get address of remaining non-deserialized data.
U32 EntityId
Entity id size.
void fill()
Fill the buffer to capacity with preexisting data.
U8 * getData() const
Definition: Buffer.cpp:56
U16 getPduDataLength() const
Get PDU data length.
Definition: PduHeader.hpp:133
void initialize(PduTypeEnum::T type, PduDirection direction, Cfdp::Class::T txmMode, EntityId sourceEid, TransactionSeq transactionSeq, EntityId destEid)
Initialize a PDU header.
Definition: PduHeader.cpp:16
Fw::SerializeStatus fromSerialBuffer(Fw::SerialBufferBase &serialBuffer)
Initialize this Header from a SerialBufferBase.
Definition: PduHeader.cpp:163
SerializeStatus
forward declaration for string
U32 TransactionSeq
transaction sequence number size
SerializeStatus popBytes(U8 *const addr, FwSizeType n)
Pop n bytes off the buffer.
Data was left in the buffer, but not enough to deserialize.
Serializable::SizeType getDeserializeSizeLeft() const override
Get remaining deserialization buffer size.
Fw::SerializeStatus fromBuffer(const Fw::Buffer &buffer)
Initialize this FileDataPdu from a Buffer.
Definition: FileDataPdu.cpp:67
SerializeStatus pushBytes(const U8 *const addr, const FwSizeType n)
Push n bytes onto the buffer.
U32 getBufferSize() const
Compute the buffer size needed to hold this Header.
Definition: PduHeader.cpp:80
Deserialized type ID didn&#39;t match.
PduHeader m_header
The PDU header (common to all PDUs)
Definition: PduBase.hpp:27
U32 FileSize
File size and offset type.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:54
Fw::SerializeStatus serializeTo(Fw::SerialBufferBase &buffer, Fw::Endianness mode=Fw::Endianness::BIG) const override
Fw::Serializable interface - serialize to buffer.
const U8 * getData() const
Get the data pointer.
Definition: FileDataPdu.hpp:71
FwSizeType getSize() const
Definition: Buffer.cpp:60
void setPduDataLength(U16 length)
Set PDU data length (used during encoding)
Definition: PduHeader.hpp:136
The type of a PDU header (common to all PDUs)
Definition: PduHeader.hpp:47
Fw::SerializeStatus toSerialBuffer(Fw::SerialBufferBase &serialBuffer) const
Write this Header to a SerialBufferBase.
Definition: PduHeader.cpp:95
RateGroupDivider component implementation.
SerializeStatus deserializeTo(U8 &val, Endianness mode=Endianness::BIG) override
Deserialize an 8-bit unsigned integer value.
Endianness
T
The raw enum type.
Definition: ClassEnumAc.hpp:42
void initialize(PduDirection direction, Cfdp::Class::T txmMode, EntityId sourceEid, TransactionSeq transactionSeq, EntityId destEid, FileSize offset, U16 dataSize, const U8 *data)
Initialize a File Data PDU.
Definition: FileDataPdu.cpp:15
#define FW_ASSERT(...)
Definition: Assert.hpp:14
#define U64(C)
Definition: sha.h:181