F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
NakPdu.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title NakPdu.cpp
3 // \author Brian Campuzano
4 // \brief cpp file for CFDP NAK (Negative Acknowledge) PDU
5 // ======================================================================
6 
7 #include <Fw/Types/Assert.hpp>
9 
10 namespace Svc {
11 namespace Ccsds {
12 namespace Cfdp {
13 
15  Cfdp::Class::T txmMode,
16  EntityId sourceEid,
17  TransactionSeq transactionSeq,
18  EntityId destEid,
19  FileSize scopeStart,
20  FileSize scopeEnd) {
21  // Initialize header with PduTypeEnum::NEGATIVE_ACK type
22  this->m_header.initialize(PduTypeEnum::NEGATIVE_ACK, direction, txmMode, sourceEid, transactionSeq, destEid);
23 
24  this->m_scopeStart = scopeStart;
25  this->m_scopeEnd = scopeEnd;
26  this->m_numSegments = 0;
27 }
28 
29 bool NakPdu::addSegment(FileSize offsetStart, FileSize offsetEnd) {
30  if (this->m_numSegments >= NakMaxSegments) {
31  return false;
32  }
33  this->m_segments[this->m_numSegments].offsetStart = offsetStart;
34  this->m_segments[this->m_numSegments].offsetEnd = offsetEnd;
35  this->m_numSegments++;
36  return true;
37 }
38 
40  this->m_numSegments = 0;
41 }
42 
43 U32 NakPdu::getBufferSize() const {
44  U32 size = this->m_header.getBufferSize();
45 
46  // Directive code: 1 byte (FileDirective::FILE_DIRECTIVE_NAK)
47  // Scope start: sizeof(FileSize) bytes
48  // Scope end: sizeof(FileSize) bytes
49  // Segment requests: m_numSegments * (2 * sizeof(FileSize)) bytes
50  size += static_cast<U32>(sizeof(U8) + sizeof(FileSize) + sizeof(FileSize));
51  size += static_cast<U32>(this->m_numSegments * (sizeof(FileSize) + sizeof(FileSize)));
52 
53  return size;
54 }
55 
57  return this->toSerialBuffer(buffer);
58 }
59 
61  // Deserialize header first
62  Fw::SerializeStatus status = this->m_header.fromSerialBuffer(buffer);
63  if (status != Fw::FW_SERIALIZE_OK) {
64  return status;
65  }
66 
67  // Validate this is a directive PDU (not file data)
68  if (this->m_header.m_pduType != PduType::PDU_TYPE_DIRECTIVE) {
70  }
71 
72  // Validate directive code
73  U8 directiveCode;
74  status = buffer.deserializeTo(directiveCode);
75  if (status != Fw::FW_SERIALIZE_OK) {
76  return status;
77  }
78  if (directiveCode != static_cast<U8>(FileDirective::FILE_DIRECTIVE_NAK)) {
80  }
81 
82  // Now set the type to PduTypeEnum::NEGATIVE_ACK since we've validated it
83  this->m_header.m_type = PduTypeEnum::NEGATIVE_ACK;
84 
85  // Deserialize the NAK body
86  return this->fromSerialBuffer(buffer);
87 }
88 
89 Fw::SerializeStatus NakPdu::toSerialBuffer(Fw::SerialBufferBase& serialBuffer) const {
91 
92  // Calculate PDU data length (everything after header)
93  U32 dataLength = this->getBufferSize() - this->m_header.getBufferSize();
94 
95  // Update header with data length
96  PduHeader headerCopy = this->m_header;
97  headerCopy.setPduDataLength(static_cast<U16>(dataLength));
98 
99  // Serialize header
100  Fw::SerializeStatus status = headerCopy.toSerialBuffer(serialBuffer);
101  if (status != Fw::FW_SERIALIZE_OK) {
102  return status;
103  }
104 
105  // Directive code (NAK = 8)
106  U8 directiveCodeByte = static_cast<U8>(FileDirective::FILE_DIRECTIVE_NAK);
107  status = serialBuffer.serializeFrom(directiveCodeByte);
108  if (status != Fw::FW_SERIALIZE_OK) {
109  return status;
110  }
111 
112  // Scope start (file offset)
113  status = serialBuffer.serializeFrom(this->m_scopeStart);
114  if (status != Fw::FW_SERIALIZE_OK) {
115  return status;
116  }
117 
118  // Scope end (file offset)
119  status = serialBuffer.serializeFrom(this->m_scopeEnd);
120  if (status != Fw::FW_SERIALIZE_OK) {
121  return status;
122  }
123 
124  // Serialize segment requests
125  for (U8 i = 0; i < this->m_numSegments; i++) {
126  // Segment start offset
127  status = serialBuffer.serializeFrom(this->m_segments[i].offsetStart);
128  if (status != Fw::FW_SERIALIZE_OK) {
129  return status;
130  }
131 
132  // Segment end offset
133  status = serialBuffer.serializeFrom(this->m_segments[i].offsetEnd);
134  if (status != Fw::FW_SERIALIZE_OK) {
135  return status;
136  }
137  }
138 
139  return Fw::FW_SERIALIZE_OK;
140 }
141 
142 Fw::SerializeStatus NakPdu::fromSerialBuffer(Fw::SerialBufferBase& serialBuffer) {
144 
145  // Directive code already read by fromBuffer()
146 
147  // Scope start (file offset)
148  Fw::SerializeStatus status = serialBuffer.deserializeTo(this->m_scopeStart);
149  if (status != Fw::FW_SERIALIZE_OK) {
150  return status;
151  }
152 
153  // Scope end (file offset)
154  status = serialBuffer.deserializeTo(this->m_scopeEnd);
155  if (status != Fw::FW_SERIALIZE_OK) {
156  return status;
157  }
158 
159  // Calculate number of segment requests from remaining buffer size
160  // Each segment is 2 * sizeof(FileSize) bytes
161  Fw::Serializable::SizeType remainingBytes = serialBuffer.getDeserializeSizeLeft();
162  U32 segmentSize = static_cast<U32>(sizeof(FileSize) + sizeof(FileSize));
163  U32 numSegsCalculated = static_cast<U32>(remainingBytes / segmentSize);
164  this->m_numSegments = static_cast<U8>(numSegsCalculated);
165 
166  // Limit to max segments
167  if (this->m_numSegments > NakMaxSegments) {
168  this->m_numSegments = NakMaxSegments;
169  }
170 
171  // Deserialize segment requests
172  for (U8 i = 0; i < this->m_numSegments; i++) {
173  // Segment start offset
174  status = serialBuffer.deserializeTo(this->m_segments[i].offsetStart);
175  if (status != Fw::FW_SERIALIZE_OK) {
176  return status;
177  }
178 
179  // Segment end offset
180  status = serialBuffer.deserializeTo(this->m_segments[i].offsetEnd);
181  if (status != Fw::FW_SERIALIZE_OK) {
182  return status;
183  }
184  }
185 
186  return Fw::FW_SERIALIZE_OK;
187 }
188 
189 } // namespace Cfdp
190 } // namespace Ccsds
191 } // namespace Svc
Serialization/Deserialization operation was successful.
U32 EntityId
Entity id size.
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
virtual SerializeStatus serializeFrom(U8 val, Endianness mode=Endianness::BIG)=0
Serialize an 8-bit unsigned integer value.
Fw::SerializeStatus fromSerialBuffer(Fw::SerialBufferBase &serialBuffer)
Initialize this Header from a SerialBufferBase.
Definition: PduHeader.cpp:163
SerializeStatus
forward declaration for string
virtual SerializeStatus deserializeTo(U8 &val, Endianness mode=Endianness::BIG)=0
Deserialize an 8-bit unsigned integer value.
Fw::SerializeStatus serializeTo(Fw::SerialBufferBase &buffer, Fw::Endianness mode=Fw::Endianness::BIG) const override
Fw::Serializable interface - serialize to buffer.
Definition: NakPdu.cpp:56
U32 TransactionSeq
transaction sequence number size
FileSize offsetEnd
End offset of missing data.
Definition: NakPdu.hpp:20
FwSizeType SizeType
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
void initialize(PduDirection direction, Cfdp::Class::T txmMode, EntityId sourceEid, TransactionSeq transactionSeq, EntityId destEid, FileSize scopeStart, FileSize scopeEnd)
Initialize a NAK PDU.
Definition: NakPdu.cpp:14
bool addSegment(FileSize offsetStart, FileSize offsetEnd)
Definition: NakPdu.cpp:29
U32 FileSize
File size and offset type.
virtual Serializable::SizeType getDeserializeSizeLeft() const =0
Get remaining deserialization buffer size.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:54
FileSize offsetStart
Start offset of missing data.
Definition: NakPdu.hpp:19
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
void clearSegments()
Clear all segment requests.
Definition: NakPdu.cpp:39
RateGroupDivider component implementation.
Endianness
Fw::SerializeStatus deserializeFrom(Fw::SerialBufferBase &buffer, Fw::Endianness mode=Fw::Endianness::BIG) override
Fw::Serializable interface - deserialize from buffer.
Definition: NakPdu.cpp:60
T
The raw enum type.
Definition: ClassEnumAc.hpp:42
U32 getBufferSize() const override
Compute the buffer size needed.
Definition: NakPdu.cpp:43
#define FW_ASSERT(...)
Definition: Assert.hpp:14