F´ Flight Software - C/C++ Documentation  NASA-v2.0.1
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 <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