F´ Flight Software - C/C++ Documentation  NASA-v1.6.0
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 
16  // ----------------------------------------------------------------------
17  // Construction, initialization, and destruction
18  // ----------------------------------------------------------------------
19 
21  ComLogger(const char* compName, const char* incomingFilePrefix, U32 maxFileSize, bool storeBufferLength) :
22  ComLoggerComponentBase(compName),
23  maxFileSize(maxFileSize),
24  fileMode(CLOSED),
25  byteCount(0),
26  writeErrorOccurred(false),
27  openErrorOccurred(false),
28  storeBufferLength(storeBufferLength)
29  {
30  if( this->storeBufferLength ) {
31  FW_ASSERT(maxFileSize > sizeof(U16), maxFileSize); // must be a positive integer greater than buffer length size
32  }
33  else {
34  FW_ASSERT(maxFileSize > sizeof(0), maxFileSize); // must be a positive integer
35  }
36  FW_ASSERT(strnlen(incomingFilePrefix, sizeof(this->filePrefix)) < sizeof(this->filePrefix),
37  strnlen(incomingFilePrefix, sizeof(this->filePrefix)), sizeof(this->filePrefix)); // ensure that file prefix is not too big
38 
39  // Set the file prefix:
40  Fw::StringUtils::string_copy(this->filePrefix, incomingFilePrefix, sizeof(this->filePrefix));
41  }
42 
43  void ComLogger ::
45  NATIVE_INT_TYPE queueDepth,
46  NATIVE_INT_TYPE instance
47  )
48  {
49  ComLoggerComponentBase::init(queueDepth, instance);
50  }
51 
54  {
55  // Close file:
56  // this->closeFile();
57  // NOTE: the above did not work because we don't want to issue an event
58  // in the destructor. This can cause "virtual method called" segmentation
59  // faults.
60  // So I am copying part of that function here.
61  if( OPEN == this->fileMode ) {
62  // Close file:
63  this->file.close();
64 
65  // Write out the hash file to disk:
66  this->writeHashFile();
67 
68  // Update mode:
69  this->fileMode = CLOSED;
70 
71  // Send event:
72  //Fw::LogStringArg logStringArg((char*) fileName);
73  //this->log_DIAGNOSTIC_FileClosed(logStringArg);
74  }
75  }
76 
77  // ----------------------------------------------------------------------
78  // Handler implementations
79  // ----------------------------------------------------------------------
80 
81  void ComLogger ::
82  comIn_handler(
83  NATIVE_INT_TYPE portNum,
84  Fw::ComBuffer &data,
85  U32 context
86  )
87  {
88  FW_ASSERT(portNum == 0);
89 
90  // Get length of buffer:
91  U32 size32 = data.getBuffLength();
92  // ComLogger only writes 16-bit sizes to save space
93  // on disk:
94  FW_ASSERT(size32 < 65536, size32);
95  U16 size = size32 & 0xFFFF;
96 
97  // Close the file if it will be too big:
98  if( OPEN == this->fileMode ) {
99  U32 projectedByteCount = this->byteCount + size;
100  if( this->storeBufferLength ) {
101  projectedByteCount += sizeof(size);
102  }
103  if( projectedByteCount > this->maxFileSize ) {
104  this->closeFile();
105  }
106  }
107 
108  // Open the file if it there is not one open:
109  if( CLOSED == this->fileMode ){
110  this->openFile();
111  }
112 
113  // Write to the file if it is open:
114  if( OPEN == this->fileMode ) {
115  this->writeComBufferToFile(data, size);
116  }
117  }
118 
119  void ComLogger ::
120  CloseFile_cmdHandler(
121  FwOpcodeType opCode,
122  U32 cmdSeq
123  )
124  {
125  this->closeFile();
126  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
127  }
128 
129  void ComLogger ::
130  pingIn_handler(
131  const NATIVE_INT_TYPE portNum,
132  U32 key
133  )
134  {
135  // return key
136  this->pingOut_out(0,key);
137  }
138 
139  void ComLogger ::
140  openFile(
141  )
142  {
143  FW_ASSERT( CLOSED == this->fileMode );
144 
145  U32 bytesCopied;
146 
147  // Create filename:
148  Fw::Time timestamp = getTime();
149  memset(this->fileName, 0, sizeof(this->fileName));
150  bytesCopied = snprintf(this->fileName, sizeof(this->fileName), "%s_%d_%d_%06d.com",
151  this->filePrefix, static_cast<U32>(timestamp.getTimeBase()), timestamp.getSeconds(), timestamp.getUSeconds());
152 
153  // "A return value of size or more means that the output was truncated"
154  // See here: http://linux.die.net/man/3/snprintf
155  FW_ASSERT( bytesCopied < sizeof(this->fileName) );
156 
157  // Create sha filename:
158  bytesCopied = snprintf(this->hashFileName, sizeof(this->hashFileName), "%s_%d_%d_%06d.com%s",
159  this->filePrefix, static_cast<U32>(timestamp.getTimeBase()), timestamp.getSeconds(), timestamp.getUSeconds(), Utils::Hash::getFileExtensionString());
160  FW_ASSERT( bytesCopied < sizeof(this->hashFileName) );
161 
162  Os::File::Status ret = file.open(this->fileName, Os::File::OPEN_WRITE);
163  if( Os::File::OP_OK != ret ) {
164  if( !this->openErrorOccurred ) { // throttle this event, otherwise a positive
165  // feedback event loop can occur!
166  Fw::LogStringArg logStringArg(this->fileName);
167  this->log_WARNING_HI_FileOpenError(ret, logStringArg);
168  }
169  this->openErrorOccurred = true;
170  } else {
171  // Reset event throttle:
172  this->openErrorOccurred = false;
173 
174  // Reset byte count:
175  this->byteCount = 0;
176 
177  // Set mode:
178  this->fileMode = OPEN;
179  }
180  }
181 
182  void ComLogger ::
183  closeFile(
184  )
185  {
186  if( OPEN == this->fileMode ) {
187  // Close file:
188  this->file.close();
189 
190  // Write out the hash file to disk:
191  this->writeHashFile();
192 
193  // Update mode:
194  this->fileMode = CLOSED;
195 
196  // Send event:
197  Fw::LogStringArg logStringArg(this->fileName);
198  this->log_DIAGNOSTIC_FileClosed(logStringArg);
199  }
200  }
201 
202  void ComLogger ::
203  writeComBufferToFile(
204  Fw::ComBuffer &data,
205  U16 size
206  )
207  {
208  if( this->storeBufferLength ) {
209  U8 buffer[sizeof(size)];
210  Fw::SerialBuffer serialLength(&buffer[0], sizeof(size));
211  serialLength.serialize(size);
212  if(this->writeToFile(serialLength.getBuffAddr(),
213  static_cast<U16>(serialLength.getBuffLength()))) {
214  this->byteCount += serialLength.getBuffLength();
215  }
216  else {
217  return;
218  }
219  }
220 
221  // Write buffer to file:
222  if(this->writeToFile(data.getBuffAddr(), size)) {
223  this->byteCount += size;
224  }
225  }
226 
227  bool ComLogger ::
228  writeToFile(
229  void* data,
230  U16 length
231  )
232  {
233  NATIVE_INT_TYPE size = length;
234  Os::File::Status ret = file.write(data, size);
235  if( Os::File::OP_OK != ret || size != static_cast<NATIVE_INT_TYPE>(length) ) {
236  if( !this->writeErrorOccurred ) { // throttle this event, otherwise a positive
237  // feedback event loop can occur!
238  Fw::LogStringArg logStringArg(this->fileName);
239  this->log_WARNING_HI_FileWriteError(ret, size, length, logStringArg);
240  }
241  this->writeErrorOccurred = true;
242  return false;
243  }
244 
245  this->writeErrorOccurred = false;
246  return true;
247  }
248 
249  void ComLogger ::
250  writeHashFile(
251  )
252  {
253  Os::ValidateFile::Status validateStatus;
254  validateStatus = Os::ValidateFile::createValidation(this->fileName, this->hashFileName);
255  if( Os::ValidateFile::VALIDATION_OK != validateStatus ) {
256  Fw::LogStringArg logStringArg1(this->fileName);
257  Fw::LogStringArg logStringArg2(this->hashFileName);
258  this->log_WARNING_LO_FileValidationError(logStringArg1, logStringArg2, validateStatus);
259  }
260  }
261 };
Svc::ComLogger::ComLogger
ComLogger(const char *compName, const char *filePrefix, U32 maxFileSize, bool storeBufferLength=true)
Definition: ComLogger.cpp:21
Fw::SerialBuffer
A variable-length serializable buffer.
Definition: SerialBuffer.hpp:24
Fw::Time
Definition: Time.hpp:10
Os::ValidateFile::VALIDATION_OK
@ VALIDATION_OK
The validation of the file passed.
Definition: ValidateFile.hpp:29
Fw::Time::getSeconds
U32 getSeconds() const
Definition: Time.cpp:134
Svc::ComLogger::~ComLogger
~ComLogger()
Definition: ComLogger.cpp:53
Os::File::close
void close()
close file
Definition: File.cpp:37
Os::ValidateFile::Status
Status
Definition: ValidateFile.hpp:27
Fw::LogStringArg
Definition: LogString.hpp:11
U8
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.hpp:76
Fw::Time::getUSeconds
U32 getUSeconds() const
Definition: Time.cpp:138
Os::ValidateFile::createValidation
Status createValidation(const char *fileName, const char *hash, Utils::HashBuffer &hashBuffer)
Definition: ValidateFileCommon.cpp:205
ValidateFile.hpp
Defines a file class to validate files or generate a file validator file.
StringUtils.hpp
Fw::ComBuffer::getBuffAddr
U8 * getBuffAddr()
gets buffer address for data filling
Definition: ComBuffer.cpp:36
Os::File::write
Status write(const void *buffer, NATIVE_INT_TYPE &size, bool waitForDone=true)
write size; will return amount written or errno
Definition: File.cpp:33
ComLogger.hpp
SerialBuffer.hpp
Fw::StringUtils::string_copy
char * string_copy(char *destination, const char *source, U32 num)
copy string with null-termination guaranteed
Definition: StringUtils.cpp:5
FwOpcodeType
#define FwOpcodeType
Type representation for a command opcode.
Definition: FpConfig.hpp:58
Os::File::OPEN_WRITE
@ OPEN_WRITE
Open file for writing.
Definition: File.hpp:17
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:8
Os::File::open
Status open(const char *fileName, Mode mode)
open file. Writing creates file if it doesn't exist
Definition: File.cpp:13
Svc::ComLogger::init
void init(NATIVE_INT_TYPE queueDepth, NATIVE_INT_TYPE instance)
Definition: ComLogger.cpp:44
Fw::SerializeBufferBase::getBuffLength
NATIVE_UINT_TYPE getBuffLength() const
returns current buffer size
Definition: Serializable.cpp:591
OK
@ OK
Definition: StandardTypes.hpp:14
Utils::Hash::getFileExtensionString
static const char * getFileExtensionString()
Definition: HashCommon.cpp:6
Fw::Time::getTimeBase
TimeBase getTimeBase() const
Definition: Time.cpp:142
Svc
Definition: ActiveRateGroupImplCfg.hpp:18
Os::File::Status
Status
Definition: File.hpp:24
BasicTypes.hpp
Declares ISF basic types.
Os::File::OP_OK
@ OP_OK
Operation was successful.
Definition: File.hpp:25
NATIVE_INT_TYPE
int NATIVE_INT_TYPE
native integer type declaration
Definition: BasicTypes.hpp:29
Fw::ComBuffer
Definition: ComBuffer.hpp:21