F´ Flight Software - C/C++ Documentation NASA-v1.6.0
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 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 > 0, maxFileSize); // must be a positive integer
35 }
36 FW_ASSERT(Fw::StringUtils::string_length(incomingFilePrefix, sizeof(this->filePrefix)) < sizeof(this->filePrefix),
37 Fw::StringUtils::string_length(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 ::
44 init(
45 NATIVE_INT_TYPE queueDepth,
46 NATIVE_INT_TYPE instance
47 )
48 {
49 ComLoggerComponentBase::init(queueDepth, instance);
50 }
51
52 ComLogger ::
53 ~ComLogger()
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_%" PRI_FwTimeBaseStoreType "_%" PRIu32 "_%06" PRIu32 ".com",
151 this->filePrefix, static_cast<FwTimeBaseStoreType>(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_%" PRI_FwTimeBaseStoreType "_%" PRIu32 "_%06" PRIu32 ".com%s",
159 this->filePrefix, static_cast<FwTimeBaseStoreType>(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};
#define FW_ASSERT(...)
Definition Assert.hpp:7
PlatformIntType NATIVE_INT_TYPE
Definition BasicTypes.h:51
uint8_t U8
8-bit unsigned integer
Definition BasicTypes.h:26
U16 FwTimeBaseStoreType
Definition FpConfig.h:47
U32 FwOpcodeType
Definition FpConfig.h:56
#define PRI_FwTimeBaseStoreType
Definition FpConfig.h:48
C++-compatible configuration header for fprime configuration.
Defines a file class to validate files or generate a file validator file.
U8 * getBuffAddr()
gets buffer address for data filling
Definition ComBuffer.cpp:40
A variable-length serializable buffer.
NATIVE_UINT_TYPE 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:24
@ OPEN_WRITE
Open file for writing.
Definition File.hpp:16
static const char * getFileExtensionString()
Definition HashCommon.cpp:6
char * string_copy(char *destination, const char *source, U32 num)
copy string with null-termination guaranteed
U32 string_length(const CHAR *source, U32 max_len)
get the length of the source string or max_len if the string is longer than max_len.
@ VALIDATION_OK
The validation of the file passed.
Status createValidation(const char *fileName, const char *hash, Utils::HashBuffer &hashBuffer)