F´ Flight Software - C/C++ Documentation NASA-v1.6.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
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)