F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
AckPdu.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title AckPdu.cpp
3 // \author Brian Campuzano
4 // \brief cpp file for CFDP ACK (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  FileDirective directiveCode,
20  U8 directiveSubtypeCode,
21  ConditionCode conditionCode,
22  AckTxnStatus transactionStatus) {
23  // Initialize header with PduTypeEnum::ACKNOWLEDGMENT type
24  this->m_header.initialize(PduTypeEnum::ACKNOWLEDGMENT, direction, txmMode, sourceEid, transactionSeq, destEid);
25 
26  this->m_directiveCode = directiveCode;
27  this->m_directiveSubtypeCode = directiveSubtypeCode;
28  this->m_conditionCode = conditionCode;
29  this->m_transactionStatus = transactionStatus;
30 }
31 
32 U32 AckPdu::getBufferSize() const {
33  U32 size = this->m_header.getBufferSize();
34 
35  // Directive code: 1 byte (FileDirective::FILE_DIRECTIVE_ACK)
36  // Directive and subtype code (bit-packed): 1 byte
37  // Condition code and transaction status (bit-packed): 1 byte
38  size += static_cast<U32>(sizeof(U8) + sizeof(U8) + sizeof(U8));
39 
40  return size;
41 }
42 
44  return this->toSerialBuffer(buffer);
45 }
46 
48  // Deserialize header first
49  Fw::SerializeStatus status = this->m_header.fromSerialBuffer(buffer);
50  if (status != Fw::FW_SERIALIZE_OK) {
51  return status;
52  }
53 
54  // Validate this is a directive PDU (not file data)
55  if (this->m_header.m_pduType != PduType::PDU_TYPE_DIRECTIVE) {
57  }
58 
59  // Validate directive code
60  U8 directiveCode;
61  status = buffer.deserializeTo(directiveCode);
62  if (status != Fw::FW_SERIALIZE_OK) {
63  return status;
64  }
65  if (directiveCode != static_cast<U8>(FileDirective::FILE_DIRECTIVE_ACK)) {
67  }
68 
69  // Now set the type to PduTypeEnum::ACKNOWLEDGMENT since we've validated it
71 
72  // Deserialize the ACK body
73  return this->fromSerialBuffer(buffer);
74 }
75 
76 Fw::SerializeStatus AckPdu::toSerialBuffer(Fw::SerialBufferBase& serialBuffer) const {
78 
79  // Calculate PDU data length (everything after header)
80  U32 dataLength = this->getBufferSize() - this->m_header.getBufferSize();
81 
82  // Update header with data length
83  PduHeader headerCopy = this->m_header;
84  headerCopy.setPduDataLength(static_cast<U16>(dataLength));
85 
86  // Serialize header
87  Fw::SerializeStatus status = headerCopy.toSerialBuffer(serialBuffer);
88  if (status != Fw::FW_SERIALIZE_OK) {
89  return status;
90  }
91 
92  // Directive code (ACK = 6)
93  U8 directiveCodeByte = static_cast<U8>(FileDirective::FILE_DIRECTIVE_ACK);
94  status = serialBuffer.serializeFrom(directiveCodeByte);
95  if (status != Fw::FW_SERIALIZE_OK) {
96  return status;
97  }
98 
99  // Directive and subtype code (bit-packed into 1 byte)
100  // Bits 7-4: Directive code being acknowledged (4 bits)
101  // Bits 3-0: Directive subtype code (4 bits)
102  U8 directiveAndSubtype = 0;
103  directiveAndSubtype =
104  static_cast<U8>(directiveAndSubtype | static_cast<U8>((static_cast<U8>(this->m_directiveCode) & 0x0FU) << 4));
105  directiveAndSubtype = static_cast<U8>(directiveAndSubtype | (this->m_directiveSubtypeCode & 0x0FU));
106 
107  status = serialBuffer.serializeFrom(directiveAndSubtype);
108  if (status != Fw::FW_SERIALIZE_OK) {
109  return status;
110  }
111 
112  // Condition code and transaction status (bit-packed into 1 byte)
113  // Bits 7-4: Condition code (4 bits)
114  // Bits 3-2: Spare (0)
115  // Bits 1-0: Transaction status (2 bits)
116  U8 ccAndStatus = 0;
117  ccAndStatus = static_cast<U8>(ccAndStatus | static_cast<U8>((static_cast<U8>(this->m_conditionCode) & 0x0FU) << 4));
118  ccAndStatus = static_cast<U8>(ccAndStatus | (static_cast<U8>(this->m_transactionStatus) & 0x03U));
119 
120  status = serialBuffer.serializeFrom(ccAndStatus);
121  if (status != Fw::FW_SERIALIZE_OK) {
122  return status;
123  }
124 
125  return Fw::FW_SERIALIZE_OK;
126 }
127 
128 Fw::SerializeStatus AckPdu::fromSerialBuffer(Fw::SerialBufferBase& serialBuffer) {
130 
131  // Directive code already read by fromBuffer()
132 
133  // Directive and subtype code (packed byte)
134  U8 directiveAndSubtype;
135  Fw::SerializeStatus status = serialBuffer.deserializeTo(directiveAndSubtype);
136  if (status != Fw::FW_SERIALIZE_OK) {
137  return status;
138  }
139 
140  // Extract fields from directive and subtype byte:
141  // Bits 7-4: Directive code being acknowledged
142  // Bits 3-0: Directive subtype code
143  U8 directiveCodeVal = (directiveAndSubtype >> 4) & 0x0F;
144  U8 subtypeCodeVal = directiveAndSubtype & 0x0F;
145 
146  this->m_directiveCode = static_cast<FileDirective>(directiveCodeVal);
147  this->m_directiveSubtypeCode = subtypeCodeVal;
148 
149  // Condition code and transaction status (packed byte)
150  U8 ccAndStatus;
151  status = serialBuffer.deserializeTo(ccAndStatus);
152  if (status != Fw::FW_SERIALIZE_OK) {
153  return status;
154  }
155 
156  // Extract fields from condition code and transaction status byte:
157  // Bits 7-4: Condition code
158  // Bits 3-2: Spare
159  // Bits 1-0: Transaction status
160  U8 conditionCodeVal = (ccAndStatus >> 4) & 0x0F;
161  U8 transactionStatusVal = ccAndStatus & 0x03;
162 
163  this->m_conditionCode = static_cast<ConditionCode>(conditionCodeVal);
164  this->m_transactionStatus = static_cast<AckTxnStatus>(transactionStatusVal);
165 
166  return Fw::FW_SERIALIZE_OK;
167 }
168 
169 } // namespace Cfdp
170 } // namespace Ccsds
171 } // namespace Svc
Serialization/Deserialization operation was successful.
U32 getBufferSize() const override
Compute the buffer size needed.
Definition: AckPdu.cpp:32
U32 EntityId
Entity id size.
void initialize(PduDirection direction, Cfdp::Class::T txmMode, EntityId sourceEid, TransactionSeq transactionSeq, EntityId destEid, FileDirective directiveCode, U8 directiveSubtypeCode, ConditionCode conditionCode, AckTxnStatus transactionStatus)
Initialize an ACK PDU.
Definition: AckPdu.cpp:14
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.
U32 TransactionSeq
transaction sequence number size
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 setPduDataLength(U16 length)
Set PDU data length (used during encoding)
Definition: PduHeader.hpp:136
Fw::SerializeStatus deserializeFrom(Fw::SerialBufferBase &buffer, Fw::Endianness mode=Fw::Endianness::BIG) override
Fw::Serializable interface - deserialize from buffer.
Definition: AckPdu.cpp:47
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
Fw::SerializeStatus serializeTo(Fw::SerialBufferBase &buffer, Fw::Endianness mode=Fw::Endianness::BIG) const override
Fw::Serializable interface - serialize to buffer.
Definition: AckPdu.cpp:43
#define FW_ASSERT(...)
Definition: Assert.hpp:14