F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
Loading...
Searching...
No Matches
ComLogger.cpp
Go to the documentation of this file.
1// ----------------------------------------------------------------------
2//
3// ComLogger.cpp
4//
5// ----------------------------------------------------------------------
6
8#include <FpConfig.hpp>
11#include <Os/ValidateFile.hpp>
12#include <cstdio>
13
14namespace Svc {
15
16 // ----------------------------------------------------------------------
17 // Construction, initialization, and destruction
18 // ----------------------------------------------------------------------
19
20 ComLogger ::
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
34 ComLogger ::
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
60 FW_ASSERT(Fw::StringUtils::string_length(incomingFilePrefix, static_cast<FwSizeType>(sizeof(this->m_filePrefix))) < sizeof(this->m_filePrefix),
61 static_cast<FwAssertArgType>(Fw::StringUtils::string_length(incomingFilePrefix, static_cast<FwSizeType>(sizeof(this->m_filePrefix)))),
62 static_cast<FwAssertArgType>(sizeof(this->m_filePrefix))); // ensure that file prefix is not too big
63
64 (void)Fw::StringUtils::string_copy(this->m_filePrefix, incomingFilePrefix, static_cast<FwSizeType>(sizeof(this->m_filePrefix)));
65
66 this->m_initialized = true;
67 }
68
69
70 ComLogger ::
71 ~ComLogger()
72 {
73 // Close file:
74 // this->closeFile();
75 // NOTE: the above did not work because we don't want to issue an event
76 // in the destructor. This can cause "virtual method called" segmentation
77 // faults.
78 // So I am copying part of that function here.
79 if( OPEN == this->m_fileMode ) {
80 // Close file:
81 this->m_file.close();
82
83 // Write out the hash file to disk:
84 this->writeHashFile();
85
86 // Update mode:
87 this->m_fileMode = CLOSED;
88
89 // Send event:
90 //Fw::LogStringArg logStringArg((char*) fileName);
91 //this->log_DIAGNOSTIC_FileClosed(logStringArg);
92 }
93 }
94
95 // ----------------------------------------------------------------------
96 // Handler implementations
97 // ----------------------------------------------------------------------
98
99 void ComLogger ::
100 comIn_handler(
101 NATIVE_INT_TYPE portNum,
102 Fw::ComBuffer &data,
103 U32 context
104 )
105 {
106 FW_ASSERT(portNum == 0);
107
108 // Get length of buffer:
109 U32 size32 = data.getBuffLength();
110 // ComLogger only writes 16-bit sizes to save space
111 // on disk:
112 FW_ASSERT(size32 < 65536, static_cast<FwAssertArgType>(size32));
113 U16 size = size32 & 0xFFFF;
114
115 // Close the file if it will be too big:
116 if( OPEN == this->m_fileMode ) {
117 U32 projectedByteCount = this->m_byteCount + size;
118 if( this->m_storeBufferLength ) {
119 projectedByteCount += static_cast<U32>(sizeof(size));
120 }
121 if( projectedByteCount > this->m_maxFileSize ) {
122 this->closeFile();
123 }
124 }
125
126 // Open the file if it there is not one open:
127 if( CLOSED == this->m_fileMode ){
128 this->openFile();
129 }
130
131 // Write to the file if it is open:
132 if( OPEN == this->m_fileMode ) {
133 this->writeComBufferToFile(data, size);
134 }
135 }
136
137 void ComLogger ::
138 CloseFile_cmdHandler(
139 FwOpcodeType opCode,
140 U32 cmdSeq
141 )
142 {
143 this->closeFile();
144 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
145 }
146
147 void ComLogger ::
148 pingIn_handler(
149 const NATIVE_INT_TYPE portNum,
150 U32 key
151 )
152 {
153 // return key
154 this->pingOut_out(0,key);
155 }
156
157 void ComLogger ::
158 openFile(
159 )
160 {
161 FW_ASSERT( CLOSED == this->m_fileMode );
162
163 if( !this->m_initialized ){
164 this->log_WARNING_LO_FileNotInitialized();
165 return;
166 }
167
168 U32 bytesCopied;
169
170 // Create filename:
171 Fw::Time timestamp = getTime();
172 memset(this->m_fileName, 0, sizeof(this->m_fileName));
173 bytesCopied = static_cast<U32>(snprintf(
174 this->m_fileName,
175 sizeof(this->m_fileName),
176 "%s_%" PRI_FwTimeBaseStoreType "_%" PRIu32 "_%06" PRIu32 ".com",
177 this->m_filePrefix,
178 static_cast<FwTimeBaseStoreType>(timestamp.getTimeBase()),
179 timestamp.getSeconds(),
180 timestamp.getUSeconds()));
181
182 // "A return value of size or more means that the output was truncated"
183 // See here: http://linux.die.net/man/3/snprintf
184 FW_ASSERT( bytesCopied < sizeof(this->m_fileName) );
185
186 // Create sha filename:
187 bytesCopied = static_cast<U32>(snprintf(
188 this->m_hashFileName,
189 sizeof(this->m_hashFileName),
190 "%s_%" PRI_FwTimeBaseStoreType "_%" PRIu32 "_%06" PRIu32 ".com%s",
191 this->m_filePrefix,
192 static_cast<FwTimeBaseStoreType>(timestamp.getTimeBase()),
193 timestamp.getSeconds(),
194 timestamp.getUSeconds(),
196 FW_ASSERT( bytesCopied < sizeof(this->m_hashFileName) );
197
198 Os::File::Status ret = m_file.open(this->m_fileName, Os::File::OPEN_WRITE);
199 if( Os::File::OP_OK != ret ) {
200 if( !this->m_openErrorOccurred ) { // throttle this event, otherwise a positive
201 // feedback event loop can occur!
202 Fw::LogStringArg logStringArg(this->m_fileName);
203 this->log_WARNING_HI_FileOpenError(ret, logStringArg);
204 }
205 this->m_openErrorOccurred = true;
206 } else {
207 // Reset event throttle:
208 this->m_openErrorOccurred = false;
209
210 // Reset byte count:
211 this->m_byteCount = 0;
212
213 // Set mode:
214 this->m_fileMode = OPEN;
215 }
216 }
217
218 void ComLogger ::
219 closeFile(
220 )
221 {
222 if( OPEN == this->m_fileMode ) {
223 // Close file:
224 this->m_file.close();
225
226 // Write out the hash file to disk:
227 this->writeHashFile();
228
229 // Update mode:
230 this->m_fileMode = CLOSED;
231
232 // Send event:
233 Fw::LogStringArg logStringArg(this->m_fileName);
234 this->log_DIAGNOSTIC_FileClosed(logStringArg);
235 }
236 }
237
238 void ComLogger ::
239 writeComBufferToFile(
240 Fw::ComBuffer &data,
241 U16 size
242 )
243 {
244 if( this->m_storeBufferLength ) {
245 U8 buffer[sizeof(size)];
246 Fw::SerialBuffer serialLength(&buffer[0], sizeof(size));
247 serialLength.serialize(size);
248 if(this->writeToFile(serialLength.getBuffAddr(),
249 static_cast<U16>(serialLength.getBuffLength()))) {
250 this->m_byteCount += serialLength.getBuffLength();
251 }
252 else {
253 return;
254 }
255 }
256
257 // Write buffer to file:
258 if(this->writeToFile(data.getBuffAddr(), size)) {
259 this->m_byteCount += size;
260 }
261 }
262
263 bool ComLogger ::
264 writeToFile(
265 void* data,
266 U16 length
267 )
268 {
269 FwSignedSizeType size = length;
270 Os::File::Status ret = m_file.write(reinterpret_cast<const U8*>(data), size);
271 if( Os::File::OP_OK != ret || size != static_cast<NATIVE_INT_TYPE>(length) ) {
272 if( !this->m_writeErrorOccurred ) { // throttle this event, otherwise a positive
273 // feedback event loop can occur!
274 Fw::LogStringArg logStringArg(this->m_fileName);
275 this->log_WARNING_HI_FileWriteError(ret, static_cast<U32>(size), length, logStringArg);
276 }
277 this->m_writeErrorOccurred = true;
278 return false;
279 }
280
281 this->m_writeErrorOccurred = false;
282 return true;
283 }
284
285 void ComLogger ::
286 writeHashFile(
287 )
288 {
289 Os::ValidateFile::Status validateStatus;
290 validateStatus = Os::ValidateFile::createValidation(this->m_fileName, this->m_hashFileName);
291 if( Os::ValidateFile::VALIDATION_OK != validateStatus ) {
292 Fw::LogStringArg logStringArg1(this->m_fileName);
293 Fw::LogStringArg logStringArg2(this->m_hashFileName);
294 this->log_WARNING_LO_FileValidationError(logStringArg1, logStringArg2, validateStatus);
295 }
296 }
297}
#define FW_ASSERT(...)
Definition Assert.hpp:14
PlatformIntType NATIVE_INT_TYPE
Definition BasicTypes.h:55
uint8_t U8
8-bit unsigned integer
Definition BasicTypes.h:30
PlatformAssertArgType FwAssertArgType
Definition FpConfig.h:39
PlatformSignedSizeType FwSignedSizeType
Definition FpConfig.h:30
U16 FwTimeBaseStoreType
Definition FpConfig.h:79
U32 FwOpcodeType
Definition FpConfig.h:91
PlatformSizeType FwSizeType
Definition FpConfig.h:35
#define PRI_FwTimeBaseStoreType
Definition FpConfig.h:80
C++-compatible configuration header for fprime configuration.
Defines a file class to validate files or generate a file validator file.
@ OK
Command successfully executed.
U8 * getBuffAddr()
gets buffer address for data filling
Definition ComBuffer.cpp:40
A variable-length serializable buffer.
Serializable::SizeType getBuffLength() const
returns current buffer size
U32 getUSeconds() const
Definition Time.cpp:139
TimeBase getTimeBase() const
Definition Time.cpp:143
U32 getSeconds() const
Definition Time.cpp:135
@ OP_OK
Operation was successful.
Definition File.hpp:30
@ OPEN_WRITE
Open file for writing.
Definition File.hpp:23
Auto-generated base for ComLogger component.
void init_log_file(const char *filePrefix, U32 maxFileSize, bool storeBufferLength=true)
Definition ComLogger.cpp:51
static const char * getFileExtensionString()
Definition HashCommon.cpp:6
FwSizeType string_length(const CHAR *source, FwSizeType buffer_size)
get the length of the source string
char * string_copy(char *destination, const char *source, FwSizeType num)
copy string with null-termination guaranteed
@ VALIDATION_OK
The validation of the file passed.
Status createValidation(const char *fileName, const char *hash, Utils::HashBuffer &hashBuffer)