F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
ComLogger.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------
2 //
3 // ComLogger.cpp
4 //
5 // ----------------------------------------------------------------------
6 
10 #include <Fw/Types/StringUtils.hpp>
11 #include <Os/ValidateFile.hpp>
12 #include <cstdio>
13 
14 namespace Svc {
15  static_assert(std::numeric_limits<U16>::max() <= std::numeric_limits<FwSizeType>::max(),
16  "U16 must fit in the positive range of FwSizeType");
17  // ----------------------------------------------------------------------
18  // Construction, initialization, and destruction
19  // ----------------------------------------------------------------------
20 
22  ComLogger(const char* compName, const char* incomingFilePrefix, U32 maxFileSize, bool storeBufferLength) :
23  ComLoggerComponentBase(compName),
24  m_maxFileSize(maxFileSize),
25  m_fileMode(CLOSED),
26  m_byteCount(0),
27  m_writeErrorOccurred(false),
28  m_openErrorOccurred(false),
29  m_storeBufferLength(storeBufferLength),
30  m_initialized(true)
31  {
32  this->init_log_file(incomingFilePrefix, maxFileSize, storeBufferLength);
33  }
34 
36  ComLogger(const char* compName) :
37  ComLoggerComponentBase(compName),
38  m_filePrefix(),
39  m_maxFileSize(0),
40  m_fileMode(CLOSED),
41  m_fileName(),
42  m_hashFileName(),
43  m_byteCount(0),
44  m_writeErrorOccurred(false),
45  m_openErrorOccurred(false),
46  m_storeBufferLength(),
47  m_initialized(false)
48  {
49  }
50 
51  void ComLogger ::
52  init_log_file(const char* incomingFilePrefix, U32 maxFileSize, bool storeBufferLength)
53  {
54  FW_ASSERT(incomingFilePrefix != nullptr);
55  this->m_maxFileSize = maxFileSize;
56  this->m_storeBufferLength = storeBufferLength;
57  if( this->m_storeBufferLength ) {
58  FW_ASSERT(maxFileSize > sizeof(U16), static_cast<FwAssertArgType>(maxFileSize));
59  }
60  // Assign the prefix checking if it is too big
61  Fw::FormatStatus formatStatus = this->m_filePrefix.format("%s", incomingFilePrefix);
62  FW_ASSERT(formatStatus == Fw::FormatStatus::SUCCESS);
63  this->m_initialized = true;
64  }
65 
66 
69  {
70  // Close file:
71  // this->closeFile();
72  // NOTE: the above did not work because we don't want to issue an event
73  // in the destructor. This can cause "virtual method called" segmentation
74  // faults.
75  // So I am copying part of that function here.
76  if( OPEN == this->m_fileMode ) {
77  // Close file:
78  this->m_file.close();
79 
80  // Write out the hash file to disk:
81  this->writeHashFile();
82 
83  // Update mode:
84  this->m_fileMode = CLOSED;
85 
86  // Send event:
87  //Fw::LogStringArg logStringArg((char*) fileName);
88  //this->log_DIAGNOSTIC_FileClosed(logStringArg);
89  }
90  }
91 
92  // ----------------------------------------------------------------------
93  // Handler implementations
94  // ----------------------------------------------------------------------
95 
96  void ComLogger ::
97  comIn_handler(
98  FwIndexType portNum,
99  Fw::ComBuffer &data,
100  U32 context
101  )
102  {
103  FW_ASSERT(portNum == 0);
104 
105  // Get length of buffer:
106  FwSizeType sizeNative = data.getBuffLength();
107  // ComLogger only writes 16-bit sizes to save space
108  // on disk:
109  FW_ASSERT(sizeNative < 65536, static_cast<FwAssertArgType>(sizeNative));
110  U16 size = sizeNative & 0xFFFF;
111 
112  // Close the file if it will be too big:
113  if( OPEN == this->m_fileMode ) {
114  U32 projectedByteCount = this->m_byteCount + size;
115  if( this->m_storeBufferLength ) {
116  projectedByteCount += static_cast<U32>(sizeof(size));
117  }
118  if( projectedByteCount > this->m_maxFileSize ) {
119  this->closeFile();
120  }
121  }
122 
123  // Open the file if it there is not one open:
124  if( CLOSED == this->m_fileMode ){
125  this->openFile();
126  }
127 
128  // Write to the file if it is open:
129  if( OPEN == this->m_fileMode ) {
130  this->writeComBufferToFile(data, size);
131  }
132  }
133 
134  void ComLogger ::
135  CloseFile_cmdHandler(
136  FwOpcodeType opCode,
137  U32 cmdSeq
138  )
139  {
140  this->closeFile();
141  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
142  }
143 
144  void ComLogger ::
145  pingIn_handler(
146  const FwIndexType portNum,
147  U32 key
148  )
149  {
150  // return key
151  this->pingOut_out(0,key);
152  }
153 
154  void ComLogger ::
155  openFile(
156  )
157  {
158  FW_ASSERT( CLOSED == this->m_fileMode );
159 
160  if( !this->m_initialized ){
162  return;
163  }
164 
165  // Create filename:
166  Fw::Time timestamp = getTime();
167  Fw::FormatStatus formatStatus = this->m_fileName.format(
168  "%s_%" PRI_FwTimeBaseStoreType "_%" PRIu32 "_%06" PRIu32 ".com",
169  this->m_filePrefix.toChar(),
170  static_cast<FwTimeBaseStoreType>(timestamp.getTimeBase()),
171  timestamp.getSeconds(),
172  timestamp.getUSeconds());
173  FW_ASSERT(formatStatus == Fw::FormatStatus::SUCCESS);
174  this->m_hashFileName.format("%s%s", this->m_fileName.toChar(), Utils::Hash::getFileExtensionString());
175  FW_ASSERT(formatStatus == Fw::FormatStatus::SUCCESS);
176 
177  Os::File::Status ret = m_file.open(this->m_fileName.toChar(), Os::File::OPEN_WRITE);
178  if( Os::File::OP_OK != ret ) {
179  if( !this->m_openErrorOccurred ) { // throttle this event, otherwise a positive
180  // feedback event loop can occur!
181  this->log_WARNING_HI_FileOpenError(ret, this->m_fileName);
182  }
183  this->m_openErrorOccurred = true;
184  } else {
185  // Reset event throttle:
186  this->m_openErrorOccurred = false;
187 
188  // Reset byte count:
189  this->m_byteCount = 0;
190 
191  // Set mode:
192  this->m_fileMode = OPEN;
193  }
194  }
195 
196  void ComLogger ::
197  closeFile(
198  )
199  {
200  if( OPEN == this->m_fileMode ) {
201  // Close file:
202  this->m_file.close();
203 
204  // Write out the hash file to disk:
205  this->writeHashFile();
206 
207  // Update mode:
208  this->m_fileMode = CLOSED;
209 
210  // Send event:
211  this->log_DIAGNOSTIC_FileClosed(this->m_fileName);
212  }
213  }
214 
215  void ComLogger ::
216  writeComBufferToFile(
217  Fw::ComBuffer &data,
218  U16 size
219  )
220  {
221  if( this->m_storeBufferLength ) {
222  U8 buffer[sizeof(size)];
223  Fw::SerialBuffer serialLength(&buffer[0], sizeof(size));
224  serialLength.serialize(size);
225  if(this->writeToFile(serialLength.getBuffAddr(),
226  static_cast<U16>(serialLength.getBuffLength()))) {
227  this->m_byteCount += static_cast<U32>(serialLength.getBuffLength());
228  }
229  else {
230  return;
231  }
232  }
233 
234  // Write buffer to file:
235  if(this->writeToFile(data.getBuffAddr(), size)) {
236  this->m_byteCount += size;
237  }
238  }
239 
240  bool ComLogger ::
241  writeToFile(
242  void* data,
243  U16 length
244  )
245  {
246  FwSizeType size = length;
247  Os::File::Status ret = m_file.write(reinterpret_cast<const U8*>(data), size);
248  if((Os::File::OP_OK != ret) || (size != length)) {
249  if( !this->m_writeErrorOccurred ) { // throttle this event, otherwise a positive
250  // feedback event loop can occur!
251  this->log_WARNING_HI_FileWriteError(ret, static_cast<U32>(size), length, this->m_fileName);
252  }
253  this->m_writeErrorOccurred = true;
254  return false;
255  }
256 
257  this->m_writeErrorOccurred = false;
258  return true;
259  }
260 
261  void ComLogger ::
262  writeHashFile(
263  )
264  {
265  Os::ValidateFile::Status validateStatus;
266  validateStatus = Os::ValidateFile::createValidation(this->m_fileName.toChar(), this->m_hashFileName.toChar());
267  if( Os::ValidateFile::VALIDATION_OK != validateStatus ) {
268  this->log_WARNING_LO_FileValidationError(this->m_fileName, this->m_hashFileName, validateStatus);
269  }
270  }
271 }
Definition: Time.hpp:9
A variable-length serializable buffer.
PlatformSizeType FwSizeType
void log_WARNING_LO_FileNotInitialized()
Log event FileNotInitialized.
void log_DIAGNOSTIC_FileClosed(const Fw::StringBase &file) const
Open file for writing.
Definition: File.hpp:23
TimeBase getTimeBase() const
Definition: Time.cpp:143
Os::FileInterface::Status open(const char *path, Mode mode)
open file with supplied path and mode
void init_log_file(const char *filePrefix, U32 maxFileSize, bool storeBufferLength=true)
Definition: ComLogger.cpp:52
void pingOut_out(FwIndexType portNum, U32 key)
Invoke output port pingOut.
The validation of the file passed.
Serializable::SizeType getBuffLength() const
returns current buffer size
U32 FwOpcodeType
The type of a command opcode.
const char * toChar() const
void log_WARNING_HI_FileOpenError(U32 errornum, const Fw::StringBase &file) const
U32 getSeconds() const
Definition: Time.cpp:135
void cmdResponse_out(FwOpcodeType opCode, U32 cmdSeq, Fw::CmdResponse response)
Emit command response.
U8 * getBuffAddr()
gets buffer address for data filling
Definition: ComBuffer.cpp:40
void log_WARNING_HI_FileWriteError(U32 errornum, U32 bytesWritten, U32 bytesToWrite, const Fw::StringBase &file) const
void close() override
close the file, if not opened then do nothing
Definition: File.cpp:70
Status write(const U8 *buffer, FwSizeType &size)
write data to this file from the supplied buffer bounded by size
Definition: File.cpp:187
static const char * getFileExtensionString()
Definition: HashCommon.cpp:6
#define PRI_FwTimeBaseStoreType
FormatStatus format(const CHAR *formatString,...)
write formatted string to buffer
Definition: StringBase.cpp:55
Command successfully executed.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:56
Status createValidation(const char *fileName, const char *hash, Utils::HashBuffer &hashBuffer)
void log_WARNING_LO_FileValidationError(const Fw::StringBase &validationFile, const Fw::StringBase &file, U32 status) const
Operation was successful.
Definition: File.hpp:30
U32 getUSeconds() const
Definition: Time.cpp:139
Defines a file class to validate files or generate a file validator file.
PlatformIndexType FwIndexType
RateGroupDivider component implementation.
U16 FwTimeBaseStoreType
The type used to serialize a time base value.
ComLogger(const char *compName, const char *filePrefix, U32 maxFileSize, bool storeBufferLength=true)
Definition: ComLogger.cpp:22
#define FW_ASSERT(...)
Definition: Assert.hpp:14
Auto-generated base for ComLogger component.
FormatStatus
status of string format calls
Definition: format.hpp:18