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