F´ Flight Software - C/C++ Documentation  NASA-v2.1.0
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 <stdio.h>
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((NATIVE_UINT_TYPE)strnlen(incomingFilePrefix, sizeof(this->filePrefix)) < sizeof(this->filePrefix),
37  (NATIVE_UINT_TYPE) strnlen(incomingFilePrefix, sizeof(this->filePrefix)), (NATIVE_UINT_TYPE) sizeof(this->filePrefix)); // ensure that file prefix is not too big
38 
39  // Set the file prefix:
40  Fw::StringUtils::string_copy((char*) 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::COMMAND_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((char*) this->fileName, sizeof(this->fileName), "%s_%d_%d_%06d.com",
151  this->filePrefix, (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((char*) this->hashFileName, sizeof(this->hashFileName), "%s_%d_%d_%06d.com%s",
159  this->filePrefix, (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((char*) 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((char*) 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((char*) 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 != (NATIVE_INT_TYPE) length ) {
236  if( !this->writeErrorOccurred ) { // throttle this event, otherwise a positive
237  // feedback event loop can occur!
238  Fw::LogStringArg logStringArg((char*) 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((char*) this->fileName, (char*)this->hashFileName);
255  if( Os::ValidateFile::VALIDATION_OK != validateStatus ) {
256  Fw::LogStringArg logStringArg1((char*) this->fileName);
257  Fw::LogStringArg logStringArg2((char*) 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::getTimeBase
TimeBase getTimeBase(void) const
Definition: Time.cpp:142
Os::File::close
void close(void)
close file
Definition: File.cpp:37
Fw::ComBuffer::getBuffAddr
U8 * getBuffAddr(void)
gets buffer address for data filling
Definition: ComBuffer.cpp:36
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(void) 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
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
Utils::Hash::getFileExtensionString
static const char * getFileExtensionString(void)
Definition: HashCommon.cpp:6
FwOpcodeType
#define FwOpcodeType
Type representation for a command opcode.
Definition: FpConfig.hpp:62
Os::File::OPEN_WRITE
@ OPEN_WRITE
Open file for writing.
Definition: File.hpp:17
NATIVE_UINT_TYPE
unsigned int NATIVE_UINT_TYPE
native unsigned integer type declaration
Definition: BasicTypes.hpp:30
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:9
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:587
Fw::Time::getSeconds
U32 getSeconds(void) const
Definition: Time.cpp:134
Svc
Definition: ActiveRateGroupImplCfg.hpp:18
Os::File::Status
Status
Definition: File.hpp:24
Svc::ComLogger::~ComLogger
~ComLogger(void)
Definition: ComLogger.cpp:53
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