F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
DpWriter.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title DpWriter.cpp
3 // \author bocchino
4 // \brief cpp file for DpWriter component implementation class
5 // ======================================================================
6 
7 #include "Fw/Com/ComPacket.hpp"
10 #include "Os/File.hpp"
12 #include "Utils/Hash/Hash.hpp"
13 #include "config/DpCfg.hpp"
14 #include "config/FpConfig.hpp"
15 
16 namespace Svc {
17 
18 // ----------------------------------------------------------------------
19 // Construction, initialization, and destruction
20 // ----------------------------------------------------------------------
21 
22 DpWriter::DpWriter(const char* const compName) : DpWriterComponentBase(compName), m_dpFileNamePrefix() {}
23 
25 
26 void DpWriter::configure(const Fw::StringBase& dpFileNamePrefix) {
27  this->m_dpFileNamePrefix = dpFileNamePrefix;
28 }
29 
30 // ----------------------------------------------------------------------
31 // Handler implementations for user-defined typed input ports
32 // ----------------------------------------------------------------------
33 
34 void DpWriter::bufferSendIn_handler(const NATIVE_INT_TYPE portNum, Fw::Buffer& buffer) {
36  // portNum is unused
37  (void)portNum;
38  // Update num buffers received
39  ++this->m_numBuffersReceived;
40  // Check that the buffer is valid
41  if (!buffer.isValid()) {
43  status = Fw::Success::FAILURE;
44  }
45  // Check that the buffer is large enough to hold a data product packet
46  const FwSizeType bufferSize = buffer.getSize();
47  if (status == Fw::Success::SUCCESS) {
48  if (bufferSize < Fw::DpContainer::MIN_PACKET_SIZE) {
50  static_cast<U32>(bufferSize),
52 
53  status = Fw::Success::FAILURE;
54  }
55  }
56  // Set up the container and check that the header hash is valid
57  Fw::DpContainer container;
58  if (status == Fw::Success::SUCCESS) {
59  container.setBuffer(buffer);
60  Utils::HashBuffer storedHash;
61  Utils::HashBuffer computedHash;
62  status = container.checkHeaderHash(storedHash, computedHash);
63  if (status != Fw::Success::SUCCESS) {
65  static_cast<U32>(bufferSize),
66  storedHash.asBigEndianU32(),
67  computedHash.asBigEndianU32());
68  }
69  }
70  // Deserialize the packet header
71  if (status == Fw::Success::SUCCESS) {
72  status = this->deserializePacketHeader(buffer, container);
73  }
74  // Check that the packet size fits in the buffer
75  if (status == Fw::Success::SUCCESS) {
76  const FwSizeType packetSize = container.getPacketSize();
77  if (bufferSize < packetSize) {
79  static_cast<U32>(bufferSize),
80  static_cast<U32>(packetSize));
81  status = Fw::Success::FAILURE;
82  }
83  }
84  // Perform the requested processing
85  if (status == Fw::Success::SUCCESS) {
86  this->performProcessing(container);
87  }
88  // Construct the file name
89  Fw::FileNameString fileName;
90  if (status == Fw::Success::SUCCESS) {
91  const FwDpIdType containerId = container.getId();
92  const Fw::Time timeTag = container.getTimeTag();
93  fileName.format(DP_FILENAME_FORMAT, this->m_dpFileNamePrefix.toChar(), containerId, timeTag.getSeconds(),
94  timeTag.getUSeconds());
95  }
96  FwSizeType fileSize = 0;
97  // Write the file
98  if (status == Fw::Success::SUCCESS) {
99  status = this->writeFile(container, fileName, fileSize);
100  }
101  // Send the DpWritten notification
102  if (status == Fw::Success::SUCCESS) {
103  this->sendNotification(container, fileName, fileSize);
104  }
105  // Deallocate the buffer
106  if (buffer.isValid()) {
107  this->deallocBufferSendOut_out(0, buffer);
108  }
109  // Update the error count
110  if (status != Fw::Success::SUCCESS) {
111  this->m_numErrors++;
112  }
113 }
114 
115 void DpWriter::schedIn_handler(const NATIVE_INT_TYPE portNum, U32 context) {
116  // portNum and context are not used
117  (void)portNum;
118  (void)context;
119  // Write telemetry
120  this->tlmWrite_NumBuffersReceived(this->m_numBuffersReceived);
121  this->tlmWrite_NumBytesWritten(this->m_numBytesWritten);
122  this->tlmWrite_NumSuccessfulWrites(this->m_numSuccessfulWrites);
123  this->tlmWrite_NumFailedWrites(this->m_numFailedWrites);
124  this->tlmWrite_NumErrors(this->m_numErrors);
125 }
126 
127 // ----------------------------------------------------------------------
128 // Handler implementations for commands
129 // ----------------------------------------------------------------------
130 
131 void DpWriter::CLEAR_EVENT_THROTTLE_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
132  // opCode and cmdSeq are not used
133  (void)opCode;
134  (void)cmdSeq;
135  // Clear throttling
143  // Return command response
144  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
145 }
146 
147 // ----------------------------------------------------------------------
148 // Private helper functions
149 // ----------------------------------------------------------------------
150 
151 Fw::Success::T DpWriter::deserializePacketHeader(Fw::Buffer& buffer, Fw::DpContainer& container) {
153  container.setBuffer(buffer);
154  const Fw::SerializeStatus serialStatus = container.deserializeHeader();
155  if (serialStatus != Fw::FW_SERIALIZE_OK) {
156  this->log_WARNING_HI_InvalidHeader(static_cast<U32>(buffer.getSize()), static_cast<U32>(serialStatus));
157  status = Fw::Success::FAILURE;
158  }
159  return status;
160 }
161 
162 void DpWriter::performProcessing(const Fw::DpContainer& container) {
163  // Get the buffer
164  Fw::Buffer buffer = container.getBuffer();
165  // Get the bit mask for the processing types
166  const Fw::DpCfg::ProcType::SerialType procTypes = container.getProcTypes();
167  // Do the processing
168  for (FwIndexType portNum = 0; portNum < NUM_PROCBUFFERSENDOUT_OUTPUT_PORTS; ++portNum) {
169  if ((procTypes & (1 << portNum)) != 0) {
170  this->procBufferSendOut_out(portNum, buffer);
171  }
172  }
173 }
174 
175 Fw::Success::T DpWriter::writeFile(const Fw::DpContainer& container,
176  const Fw::FileNameString& fileName,
177  FwSizeType& fileSize) {
179  // Get the buffer
180  Fw::Buffer buffer = container.getBuffer();
181  // Get the file size
182  fileSize = container.getPacketSize();
183  // Open the file
184  Os::File file;
185  Os::File::Status fileStatus = file.open(fileName.toChar(), Os::File::OPEN_CREATE);
186  if (fileStatus != Os::File::OP_OK) {
187  this->log_WARNING_HI_FileOpenError(static_cast<U32>(fileStatus), fileName);
188  status = Fw::Success::FAILURE;
189  }
190  // Write the file
191  if (status == Fw::Success::SUCCESS) {
192  // Set write size to file size
193  // On entry to the write call, this is the number of bytes to write
194  // On return from the write call, this is the number of bytes written
195  FwSignedSizeType writeSize = static_cast<FwSignedSizeType>(fileSize);
196  fileStatus = file.write(buffer.getData(), writeSize);
197  // If a successful write occurred, then update the number of bytes written
198  if (fileStatus == Os::File::OP_OK) {
199  this->m_numBytesWritten += static_cast<U64>(writeSize);
200  }
201  if ((fileStatus == Os::File::OP_OK) and (writeSize == static_cast<FwSignedSizeType>(fileSize))) {
202  // If the write status is success, and the number of bytes written
203  // is the expected number, then record the success
205  static_cast<U32>(writeSize),
206  fileName);
207  } else {
208  // Otherwise record the failure
209  this->log_WARNING_HI_FileWriteError(static_cast<U32>(fileStatus), static_cast<U32>(writeSize),
210  static_cast<U32>(fileSize), fileName);
211  status = Fw::Success::FAILURE;
212  }
213  }
214  // Update the count of successful or failed writes
215  if (status == Fw::Success::SUCCESS) {
216  this->m_numSuccessfulWrites++;
217  } else {
218  this->m_numFailedWrites++;
219  }
220  // Return the status
221  return status;
222 }
223 
224 void DpWriter::sendNotification(const Fw::DpContainer& container,
225  const Fw::FileNameString& fileName,
226  FwSizeType fileSize) {
228  // Get the priority
229  const FwDpPriorityType priority = container.getPriority();
230  this->dpWrittenOut_out(0, fileName, priority, fileSize);
231  }
232 }
233 
234 } // end namespace Svc
PlatformIntType NATIVE_INT_TYPE
Definition: BasicTypes.h:51
constexpr const char * DP_FILENAME_FORMAT
Definition: DpCfg.hpp:20
U32 FwDpPriorityType
Definition: FpConfig.h:106
PlatformSignedSizeType FwSignedSizeType
Definition: FpConfig.h:25
U32 FwDpIdType
Definition: FpConfig.h:102
U32 FwOpcodeType
Definition: FpConfig.h:78
PlatformSizeType FwSizeType
Definition: FpConfig.h:30
PlatformIndexType FwIndexType
Definition: FpConfig.h:20
C++-compatible configuration header for fprime configuration.
U8 * getData() const
Definition: Buffer.cpp:68
bool isValid() const
Definition: Buffer.cpp:64
U32 getSize() const
Definition: Buffer.cpp:72
@ OK
Command successfully executed.
U8 SerialType
The serial representation type.
A data product Container.
Definition: DpContainer.hpp:21
Fw::Time getTimeTag() const
DpCfg::ProcType::SerialType getProcTypes() const
FwDpIdType getId() const
Definition: DpContainer.hpp:91
static constexpr FwSizeType MIN_PACKET_SIZE
Definition: DpContainer.hpp:58
FwDpPriorityType getPriority() const
Fw::Buffer getBuffer() const
Definition: DpContainer.hpp:99
Fw::SerializeStatus deserializeHeader()
Definition: DpContainer.cpp:38
Success::T checkHeaderHash(Utils::HashBuffer &storedHash, Utils::HashBuffer &computedHash) const
Check the header hash.
FwSizeType getPacketSize() const
Get the packet size corresponding to the data size.
void setBuffer(const Buffer &buffer)
Set the packet buffer.
const char * toChar() const
void format(const CHAR *formatString,...)
write formatted string to buffer
Definition: StringBase.cpp:56
T
The raw enum type.
@ FAILURE
Representing failure.
@ SUCCESS
Representing success.
Definition: Time.hpp:9
U32 getUSeconds() const
Definition: Time.cpp:139
U32 getSeconds() const
Definition: Time.cpp:135
Os::FileInterface::Status open(const char *path, Mode mode)
open file with supplied path and mode
Definition: File.cpp:45
Status write(const U8 *buffer, FwSignedSizeType &size)
write data to this file from the supplied buffer bounded by size
Definition: File.cpp:162
@ OP_OK
Operation was successful.
Definition: File.hpp:30
@ OPEN_CREATE
Open file for writing and truncates file if it exists, ie same flags as creat()
Definition: File.hpp:22
Auto-generated base for DpWriter component.
void deallocBufferSendOut_out(FwIndexType portNum, Fw::Buffer &fwBuffer)
Invoke output port deallocBufferSendOut.
void log_WARNING_HI_BufferTooSmallForData(U32 bufferSize, U32 minSize)
void dpWrittenOut_out(FwIndexType portNum, const Fw::StringBase &fileName, FwDpPriorityType priority, FwSizeType size)
Invoke output port dpWrittenOut.
void log_WARNING_HI_InvalidHeader_ThrottleClear()
Reset throttle value for InvalidHeader.
void log_WARNING_HI_FileOpenError(U32 status, const Fw::StringBase &file)
void log_WARNING_HI_FileWriteError(U32 status, U32 bytesWritten, U32 bytesToWrite, const Fw::StringBase &file)
void log_WARNING_HI_InvalidBuffer_ThrottleClear()
Reset throttle value for InvalidBuffer.
void tlmWrite_NumSuccessfulWrites(U32 arg, Fw::Time _tlmTime=Fw::Time())
void log_WARNING_HI_BufferTooSmallForPacket_ThrottleClear()
Reset throttle value for BufferTooSmallForPacket.
void log_WARNING_HI_InvalidHeaderHash_ThrottleClear()
Reset throttle value for InvalidHeaderHash.
void log_WARNING_HI_FileWriteError_ThrottleClear()
Reset throttle value for FileWriteError.
void tlmWrite_NumBuffersReceived(U32 arg, Fw::Time _tlmTime=Fw::Time())
void log_ACTIVITY_LO_FileWritten(U32 bytes, const Fw::StringBase &file)
void procBufferSendOut_out(FwIndexType portNum, Fw::Buffer &fwBuffer)
Invoke output port procBufferSendOut.
void tlmWrite_NumBytesWritten(U64 arg, Fw::Time _tlmTime=Fw::Time())
void cmdResponse_out(FwOpcodeType opCode, U32 cmdSeq, Fw::CmdResponse response)
Emit command response.
void log_WARNING_HI_BufferTooSmallForPacket(U32 bufferSize, U32 minSize)
void log_WARNING_HI_InvalidHeader(U32 bufferSize, U32 errorCode)
bool isConnected_dpWrittenOut_OutputPort(FwIndexType portNum)
void log_WARNING_HI_FileOpenError_ThrottleClear()
Reset throttle value for FileOpenError.
void tlmWrite_NumErrors(U32 arg, Fw::Time _tlmTime=Fw::Time())
void tlmWrite_NumFailedWrites(U32 arg, Fw::Time _tlmTime=Fw::Time())
void log_WARNING_HI_BufferTooSmallForData_ThrottleClear()
Reset throttle value for BufferTooSmallForData.
void log_WARNING_HI_InvalidHeaderHash(U32 bufferSize, U32 storedHash, U32 computedHash)
void configure(const Fw::StringBase &dpFileNamePrefix)
Configure writer.
Definition: DpWriter.cpp:26
DpWriter(const char *const compName)
Definition: DpWriter.cpp:22
A container class for holding a hash buffer.
Definition: HashBuffer.hpp:26
U32 asBigEndianU32() const
Convert bytes 0 through 3 of the hash data to a big-Endian U32 value.
SerializeStatus
forward declaration for string
@ FW_SERIALIZE_OK
Serialization/Deserialization operation was successful.
#define U64(C)
Definition: sha.h:176