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