F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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:55
constexpr const char * DP_FILENAME_FORMAT
Definition: DpCfg.hpp:20
U32 FwDpPriorityType
Definition: FpConfig.h:119
PlatformSignedSizeType FwSignedSizeType
Definition: FpConfig.h:30
U32 FwDpIdType
Definition: FpConfig.h:115
U32 FwOpcodeType
Definition: FpConfig.h:91
PlatformSizeType FwSizeType
Definition: FpConfig.h:35
PlatformIndexType FwIndexType
Definition: FpConfig.h:25
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:163
@ 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