F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
FinPdu.cpp
Go to the documentation of this file.
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>
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  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 
47  return this->toSerialBuffer(buffer);
48 }
49 
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) {
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)) {
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
Serialization/Deserialization operation was successful.
U32 EntityId
Entity id size.
Fw::SerializeStatus toSerialBuffer(Fw::SerialBufferBase &serialBuffer) const
Definition: Tlv.cpp:219
U32 getBufferSize() const override
Compute the buffer size needed.
Definition: FinPdu.cpp:33
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 serializeTo(Fw::SerialBufferBase &buffer, Fw::Endianness mode=Fw::Endianness::BIG) const override
Fw::Serializable interface - serialize to buffer.
Definition: FinPdu.cpp:46
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.
U32 TransactionSeq
transaction sequence number size
Fw::SerializeStatus fromSerialBuffer(Fw::SerialBufferBase &serialBuffer)
Definition: Tlv.cpp:233
Fw::SerializeStatus deserializeFrom(Fw::SerialBufferBase &buffer, Fw::Endianness mode=Fw::Endianness::BIG) override
Fw::Serializable interface - deserialize from buffer.
Definition: FinPdu.cpp:50
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
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:54
void initialize(PduDirection direction, Cfdp::Class::T txmMode, EntityId sourceEid, TransactionSeq transactionSeq, EntityId destEid, ConditionCode conditionCode, FinDeliveryCode deliveryCode, FinFileStatus fileStatus)
Initialize a Finished PDU.
Definition: FinPdu.cpp:14
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.
Endianness
T
The raw enum type.
Definition: ClassEnumAc.hpp:42
U32 getEncodedSize() const
Definition: Tlv.cpp:211
#define FW_ASSERT(...)
Definition: Assert.hpp:14