F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
Loading...
Searching...
No Matches
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
10#include "Os/File.hpp"
12#include "Utils/Hash/Hash.hpp"
13#include "config/DpCfg.hpp"
14#include "config/FpConfig.hpp"
15
16namespace Svc {
17
18// ----------------------------------------------------------------------
19// Construction, initialization, and destruction
20// ----------------------------------------------------------------------
21
22DpWriter::DpWriter(const char* const compName) : DpWriterComponentBase(compName), m_dpFileNamePrefix() {}
23
25
26void 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
34void 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
115void 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
131void 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
151Fw::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
162void 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
175Fw::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
224void 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:21
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.
Fw::Time getTimeTag() const
DpCfg::ProcType::SerialType getProcTypes() const
FwDpIdType getId() const
static constexpr FwSizeType MIN_PACKET_SIZE
FwDpPriorityType getPriority() const
Fw::Buffer getBuffer() const
Fw::SerializeStatus deserializeHeader()
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
T
The raw enum type.
@ FAILURE
Representing failure.
@ SUCCESS
Representing success.
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 log_ACTIVITY_LO_FileWritten(U32 bytes, const Fw::StringBase &file) const
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 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.
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