F´ Flight Software - C/C++ Documentation  NASA-v1.5.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
FPrimeSequence.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title FPrimeSequence.cpp
3 // \author Bocchino/Canham
4 // \brief CmdSequencerComponentImpl::FPrimeSequence implementation
5 //
6 // \copyright
7 // Copyright (C) 2009-2018 California Institute of Technology.
8 // ALL RIGHTS RESERVED. United States Government Sponsorship
9 // acknowledged.
10 //
11 // ======================================================================
12 
13 #include "Fw/Types/Assert.hpp"
15 extern "C" {
17 }
18 
19 namespace Svc {
20 
22  CRC(void) :
23  m_computed(INITIAL_COMPUTED_VALUE),
24  m_stored(0)
25  {
26 
27  }
28 
30  init(void)
31  {
32  this->m_computed = INITIAL_COMPUTED_VALUE;
33  }
34 
36  update(const BYTE* buffer, NATIVE_UINT_TYPE bufferSize)
37  {
38  FW_ASSERT(buffer);
39  for(NATIVE_UINT_TYPE index = 0; index < bufferSize; index++) {
40  this->m_computed = update_crc_32(this->m_computed, buffer[index]);
41  }
42  }
43 
45  finalize(void)
46  {
47  this->m_computed = ~this->m_computed;
48  }
49 
52  Sequence(component)
53  {
54 
55  }
56 
58  validateCRC(void)
59  {
60  bool result = true;
61  if (this->m_crc.m_stored != this->m_crc.m_computed) {
62  this->m_events.fileCRCFailure(
63  this->m_crc.m_stored,
64  this->m_crc.m_computed
65  );
66  result = false;
67  }
68  return result;
69  }
70 
73  {
74 
75  // make sure there is a buffer allocated
76  FW_ASSERT(this->m_buffer.getBuffAddr());
77 
78  this->setFileName(fileName);
79 
80  const bool status = this->readFile()
81  and this->validateCRC()
82  and this->m_header.validateTime(this->m_component)
83  and this->validateRecords();
84 
85  return status;
86 
87  }
88 
90  hasMoreRecords(void) const
91  {
92  return this->m_buffer.getBuffLeft() > 0;
93  }
94 
96  nextRecord(Record& record)
97  {
98  Fw::SerializeStatus status = this->deserializeRecord(record);
99  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
100  }
101 
103  reset(void)
104  {
105  this->m_buffer.resetDeser();
106  }
107 
109  clear(void)
110  {
111  this->m_buffer.resetSer();
112  }
113 
114  bool CmdSequencerComponentImpl::FPrimeSequence ::
115  readFile(void)
116  {
117 
118  bool result;
119 
120  Os::File::Status status = this->m_sequenceFile.open(
121  this->m_fileName.toChar(),
123  );
124 
125  if (status == Os::File::OP_OK) {
126  result = this->readOpenFile();
127  } else if (status == Os::File::DOESNT_EXIST) {
128  this->m_events.fileNotFound();
129  result = false;
130  } else {
131  this->m_events.fileReadError();
132  result = false;
133  }
134 
135  this->m_sequenceFile.close();
136  return result;
137 
138  }
139 
141  readOpenFile(void)
142  {
143  U8 *const buffAddr = this->m_buffer.getBuffAddr();
144  this->m_crc.init();
145  bool status = this->readHeader();
146  if (status) {
147  this->m_crc.update(buffAddr, Sequence::Header::SERIALIZED_SIZE);
148  status = this->deserializeHeader()
149  and this->readRecordsAndCRC()
150  and this->extractCRC();
151  }
152  if (status) {
153  const NATIVE_UINT_TYPE buffLen = this->m_buffer.getBuffLength();
154  this->m_crc.update(buffAddr, buffLen);
155  this->m_crc.finalize();
156  }
157  return status;
158  }
159 
161  readHeader(void)
162  {
163 
164  Os::File& file = this->m_sequenceFile;
165  Fw::SerializeBufferBase& buffer = this->m_buffer;
166  bool status = true;
167 
169  FW_ASSERT(readLen >= 0, readLen);
170 
171  const NATIVE_UINT_TYPE capacity = buffer.getBuffCapacity();
172  FW_ASSERT(
173  capacity >= static_cast<NATIVE_UINT_TYPE>(readLen),
174  capacity,
175  readLen
176  );
177  Os::File::Status fileStatus = file.read(
178  buffer.getBuffAddr(),
179  readLen
180  );
181 
182  if (fileStatus != Os::File::OP_OK) {
183  this->m_events.fileInvalid(
184  Events::FileReadStage::READ_HEADER,
185  file.getLastError()
186  );
187  status = false;
188  }
189 
190  if (status and readLen != Sequence::Header::SERIALIZED_SIZE) {
191  this->m_events.fileInvalid(
192  Events::FileReadStage::READ_HEADER_SIZE,
193  readLen
194  );
195  status = false;
196  }
197 
198  if (status) {
199  const Fw::SerializeStatus serializeStatus =
200  buffer.setBuffLen(readLen);
201  FW_ASSERT(
202  serializeStatus == Fw::FW_SERIALIZE_OK,
203  serializeStatus
204  );
205  }
206 
207  return status;
208  }
209 
211  deserializeHeader(void)
212  {
213  Fw::SerializeBufferBase& buffer = this->m_buffer;
214  Header& header = this->m_header;
215 
216  // File size
217  Fw::SerializeStatus serializeStatus = buffer.deserialize(header.m_fileSize);
218  if (serializeStatus != Fw::FW_SERIALIZE_OK) {
219  this->m_events.fileInvalid(
220  Events::FileReadStage::DESER_SIZE,
221  serializeStatus
222  );
223  return false;
224  }
225  if (header.m_fileSize > buffer.getBuffCapacity()) {
226  this->m_events.fileSizeError(header.m_fileSize);
227  return false;
228  }
229  // Number of records
230  serializeStatus = buffer.deserialize(header.m_numRecords);
231  if (serializeStatus != Fw::FW_SERIALIZE_OK) {
232  this->m_events.fileInvalid(
233  Events::FileReadStage::DESER_NUM_RECORDS,
234  serializeStatus
235  );
236  return false;
237  }
238  // Time base
239  FwTimeBaseStoreType tbase;
240  serializeStatus = buffer.deserialize(tbase);
241  if (serializeStatus != Fw::FW_SERIALIZE_OK) {
242  this->m_events.fileInvalid(
243  Events::FileReadStage::DESER_TIME_BASE,
244  serializeStatus
245  );
246  return false;
247  }
248  header.m_timeBase = static_cast<TimeBase>(tbase);
249  // Time context
250  serializeStatus = buffer.deserialize(header.m_timeContext);
251  if (serializeStatus != Fw::FW_SERIALIZE_OK) {
252  this->m_events.fileInvalid(
253  Events::FileReadStage::DESER_TIME_CONTEXT,
254  serializeStatus
255  );
256  return false;
257  }
258  return true;
259  }
260 
262  readRecordsAndCRC(void)
263  {
264  Os::File& file = this->m_sequenceFile;
265  const NATIVE_UINT_TYPE size = this->m_header.m_fileSize;
266  Fw::SerializeBufferBase& buffer = this->m_buffer;
267 
268  NATIVE_INT_TYPE readLen = size;
269  Os::File::Status fileStatus = file.read(
270  buffer.getBuffAddr(),
271  readLen
272  );
273  // check read status
274  if (fileStatus != Os::File::OP_OK) {
275  this->m_events.fileInvalid(
276  Events::FileReadStage::READ_SEQ_DATA,
277  file.getLastError()
278  );
279  return false;
280  }
281  // check read size
282  if ((NATIVE_INT_TYPE) size != readLen) {
283  this->m_events.fileInvalid(
284  Events::FileReadStage::READ_SEQ_DATA_SIZE,
285  readLen
286  );
287  return false;
288  }
289  // set buffer size
290  Fw::SerializeStatus serializeStatus =
291  buffer.setBuffLen(size);
292  FW_ASSERT(serializeStatus == Fw::FW_SERIALIZE_OK, serializeStatus);
293  return true;
294  }
295 
297  extractCRC(void)
298  {
299  Fw::SerializeBufferBase& buffer = this->m_buffer;
300  U32& crc = this->m_crc.m_stored;
301 
302  // Compute the data size
303  const U32 buffSize = buffer.getBuffLength();
304  const U32 crcSize = sizeof(crc);
305  U8 *const buffAddr = buffer.getBuffAddr();
306  if (buffSize < crcSize) {
307  this->m_events.fileInvalid(
308  Events::FileReadStage::READ_SEQ_CRC,
309  buffSize
310  );
311  return false;
312  }
313  FW_ASSERT(buffSize >= crcSize, buffSize, crcSize);
314  const NATIVE_UINT_TYPE dataSize = buffSize - crcSize;
315  // Create a CRC buffer pointing at the CRC in the main buffer, after the data
316  Fw::ExternalSerializeBuffer crcBuff(&buffAddr[dataSize], crcSize);
317  Fw::SerializeStatus status = crcBuff.setBuffLen(crcSize);
318  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
319  // Deserialize the CRC from the CRC buffer
320  status = crcBuff.deserialize(crc);
321  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
322  // Set the main buffer size to the data size
323  status = buffer.setBuffLen(dataSize);
324  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
325  return true;
326  }
327 
329  deserializeRecord(Record& record)
330  {
331  U32 recordSize;
332 
333  Fw::SerializeStatus status =
334  this->deserializeDescriptor(record.m_descriptor);
335 
336  if (
337  status == Fw::FW_SERIALIZE_OK and
338  record.m_descriptor == Record::END_OF_SEQUENCE
339  ) {
340  return Fw::FW_SERIALIZE_OK;
341  }
342 
343  if (status == Fw::FW_SERIALIZE_OK) {
344  status = this->deserializeTimeTag(record.m_timeTag);
345  }
346  if (status == Fw::FW_SERIALIZE_OK) {
347  status = this->deserializeRecordSize(recordSize);
348  }
349  if (status == Fw::FW_SERIALIZE_OK) {
350  status = this->copyCommand(record.m_command, recordSize);
351  }
352 
353  return status;
354  }
355 
357  deserializeDescriptor(Record::Descriptor& descriptor)
358  {
359  Fw::SerializeBufferBase& buffer = this->m_buffer;
360  U8 descEntry;
361  Fw::SerializeStatus status = buffer.deserialize(descEntry);
362  if (status == Fw::FW_SERIALIZE_OK) {
363  switch (descEntry) {
364  case Sequence::Record::ABSOLUTE...Sequence::Record::END_OF_SEQUENCE:
365  break;
366  default:
368  }
369  }
370  if (status == Fw::FW_SERIALIZE_OK) {
371  descriptor = static_cast<Record::Descriptor>(descEntry);
372  }
373  return status;
374  }
375 
378  {
379  Fw::SerializeBufferBase& buffer = this->m_buffer;
380  U32 seconds, useconds;
381  Fw::SerializeStatus status = buffer.deserialize(seconds);
382  if (status == Fw::FW_SERIALIZE_OK) {
383  status = buffer.deserialize(useconds);
384  }
385  if (status == Fw::FW_SERIALIZE_OK) {
386  timeTag.set(seconds,useconds);
387  }
388  return status;
389  }
390 
392  deserializeRecordSize(U32& recordSize)
393  {
394  Fw::SerializeBufferBase& buffer = this->m_buffer;
395  Fw::SerializeStatus status = buffer.deserialize(recordSize);
396  if (status == Fw::FW_SERIALIZE_OK and recordSize > buffer.getBuffLeft()) {
397  // Not enough data left
399  }
400  if (
401  status == Fw::FW_SERIALIZE_OK and
403  ) {
404  // Record size is too big for com buffer
406  }
407  return status;
408  }
409 
411  copyCommand(Fw::ComBuffer& comBuffer, const U32 recordSize)
412  {
413  Fw::SerializeBufferBase& buffer = this->m_buffer;
414  comBuffer.resetSer();
415  NATIVE_UINT_TYPE size = recordSize;
416  Fw::SerializeStatus status = comBuffer.setBuffLen(recordSize);
417  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
418  status = buffer.deserialize(comBuffer.getBuffAddr(), size, true);
419  return status;
420  }
421 
423  validateRecords(void)
424  {
425  Fw::SerializeBufferBase& buffer = this->m_buffer;
426  const U32 numRecords = this->m_header.m_numRecords;
427  Sequence::Record record;
428 
429  // Deserialize all records
430  for (NATIVE_UINT_TYPE recordNumber = 0; recordNumber < numRecords; recordNumber++) {
431  Fw::SerializeStatus status = this->deserializeRecord(record);
432  if (status != Fw::FW_SERIALIZE_OK) {
433  this->m_events.recordInvalid(recordNumber, status);
434  return false;
435  }
436  }
437  // Check there is no data left
438  const U32 buffLeftSize = buffer.getBuffLeft();
439  if (buffLeftSize > 0) {
440  this->m_events.recordMismatch(numRecords, buffLeftSize);
441  return false;
442  }
443  // Rewind deserialization
444  buffer.resetDeser();
445 
446  return true;
447  }
448 
449 }
450 
Svc::CmdSequencerComponentImpl::FPrimeSequence::deserializeRecord
Fw::SerializeStatus deserializeRecord(Record &record)
Definition: FPrimeSequence.cpp:329
Svc::CmdSequencerComponentImpl::FPrimeSequence::reset
void reset(void)
Definition: FPrimeSequence.cpp:103
Svc::CmdSequencerComponentImpl::FPrimeSequence::deserializeTimeTag
Fw::SerializeStatus deserializeTimeTag(Fw::Time &timeTag)
Definition: FPrimeSequence.cpp:377
Svc::CmdSequencerComponentImpl::Sequence::Header::SERIALIZED_SIZE
@ SERIALIZED_SIZE
Serialized size of header.
Definition: CmdSequencerImpl.hpp:168
Svc::CmdSequencerComponentImpl::FPrimeSequence::readOpenFile
bool readOpenFile(void)
Definition: FPrimeSequence.cpp:141
Svc::CmdSequencerComponentImpl::Sequence::Record::m_descriptor
Descriptor m_descriptor
The descriptor.
Definition: CmdSequencerImpl.hpp:230
Fw::Time
Definition: Time.hpp:10
Fw::ComBuffer::SERIALIZED_SIZE
@ SERIALIZED_SIZE
Definition: ComBuffer.hpp:26
Fw::SerializeBufferBase
Definition: Serializable.hpp:43
Fw::SerializeStatus
SerializeStatus
forward declaration for string
Definition: Serializable.hpp:14
Fw::FW_DESERIALIZE_SIZE_MISMATCH
@ FW_DESERIALIZE_SIZE_MISMATCH
Data was left in in the buffer, but not enough to deserialize.
Definition: Serializable.hpp:20
Fw::SerializeBufferBase::resetDeser
void resetDeser(void)
reset deserialization to beginning
Definition: Serializable.cpp:575
Fw::ComBuffer::getBuffAddr
U8 * getBuffAddr(void)
gets buffer address for data filling
Definition: ComBuffer.cpp:36
FwPacketDescriptorType
#define FwPacketDescriptorType
Type representation for a packet descriptor.
Definition: FpConfig.hpp:58
Os::File::read
Status read(void *buffer, NATIVE_INT_TYPE &size, bool waitForFull=true)
waitForFull = true to wait for all bytes to be read
Definition: File.cpp:29
U8
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.hpp:76
Svc::CmdSequencerComponentImpl::FPrimeSequence::validateRecords
bool validateRecords(void)
Definition: FPrimeSequence.cpp:423
Fw::SerializeBufferBase::resetSer
void resetSer(void)
reset to beginning of buffer to reuse for serialization
Definition: Serializable.cpp:570
TimeBase
TimeBase
Definition: FpConfig.hpp:323
Fw::CmdStringArg
Definition: CmdString.hpp:11
Svc::CmdSequencerComponentImpl::FPrimeSequence::validateCRC
bool validateCRC(void)
Definition: FPrimeSequence.cpp:58
Svc::CmdSequencerComponentImpl::Sequence::Header::m_numRecords
U32 m_numRecords
The number of records in the sequence.
Definition: CmdSequencerImpl.hpp:194
Assert.hpp
Svc::CmdSequencerComponentImpl::Sequence::Record::ABSOLUTE
@ ABSOLUTE
Absolute time.
Definition: CmdSequencerImpl.hpp:213
Fw::FW_SERIALIZE_OK
@ FW_SERIALIZE_OK
Serialization/Deserialization operation was successful.
Definition: Serializable.hpp:15
Fw::SerializeBufferBase::getBuffLeft
NATIVE_UINT_TYPE getBuffLeft() const
returns how much deserialization buffer is left
Definition: Serializable.cpp:619
Fw::SerializeBufferBase::getBuffAddr
virtual U8 * getBuffAddr(void)=0
gets buffer address for data filling
Svc::CmdSequencerComponentImpl::FPrimeSequence::loadFile
bool loadFile(const Fw::CmdStringArg &fileName)
Definition: FPrimeSequence.cpp:72
Svc::CmdSequencerComponentImpl::Sequence::Header::m_timeContext
FwTimeContextStoreType m_timeContext
The context of the sequence.
Definition: CmdSequencerImpl.hpp:200
Svc::CmdSequencerComponentImpl::FPrimeSequence::hasMoreRecords
bool hasMoreRecords(void) const
Definition: FPrimeSequence.cpp:90
Os::File::DOESNT_EXIST
@ DOESNT_EXIST
File doesn't exist (for read)
Definition: File.hpp:26
Fw::Time::set
void set(U32 seconds, U32 useconds)
Definition: Time.cpp:24
Fw::SerializeBufferBase::getBuffCapacity
virtual NATIVE_UINT_TYPE getBuffCapacity(void) const =0
returns capacity, not current size, of buffer
BYTE
U8 BYTE
byte type
Definition: BasicTypes.hpp:77
Svc::CmdSequencerComponentImpl::FPrimeSequence::deserializeRecordSize
Fw::SerializeStatus deserializeRecordSize(U32 &recordSize)
Definition: FPrimeSequence.cpp:392
Svc::CmdSequencerComponentImpl::Sequence::Header::m_fileSize
U32 m_fileSize
The file size.
Definition: CmdSequencerImpl.hpp:191
Svc::CmdSequencerComponentImpl::FPrimeSequence::readRecordsAndCRC
bool readRecordsAndCRC(void)
Definition: FPrimeSequence.cpp:262
Fw::FW_DESERIALIZE_FORMAT_ERROR
@ FW_DESERIALIZE_FORMAT_ERROR
Deserialization data had incorrect values (unexpected data types)
Definition: Serializable.hpp:19
Svc::CmdSequencerComponentImpl::FPrimeSequence::deserializeDescriptor
Fw::SerializeStatus deserializeDescriptor(Record::Descriptor &descriptor)
Definition: FPrimeSequence.cpp:357
Svc::CmdSequencerComponentImpl::Sequence::Record::m_command
Fw::ComBuffer m_command
The command.
Definition: CmdSequencerImpl.hpp:236
Fw::SerializeBufferBase::setBuffLen
SerializeStatus setBuffLen(NATIVE_UINT_TYPE length)
sets buffer length manually after filling with data
Definition: Serializable.cpp:609
NATIVE_UINT_TYPE
unsigned int NATIVE_UINT_TYPE
native unsigned integer type declaration
Definition: BasicTypes.hpp:30
Svc::CmdSequencerComponentImpl::FPrimeSequence::readHeader
bool readHeader(void)
Definition: FPrimeSequence.cpp:161
Svc::CmdSequencerComponentImpl::FPrimeSequence::nextRecord
void nextRecord(Record &record)
Definition: FPrimeSequence.cpp:96
Svc::CmdSequencerComponentImpl::FPrimeSequence::CRC::CRC
CRC(void)
Construct a CRC.
Definition: FPrimeSequence.cpp:22
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:9
Fw::SerializeBufferBase::getBuffLength
NATIVE_UINT_TYPE getBuffLength() const
returns current buffer size
Definition: Serializable.cpp:592
Svc::CmdSequencerComponentImpl::FPrimeSequence::FPrimeSequence
FPrimeSequence(CmdSequencerComponentImpl &component)
Construct an FPrimeSequence.
Definition: FPrimeSequence.cpp:51
Fw::ExternalSerializeBuffer
Definition: Serializable.hpp:156
Svc::CmdSequencerComponentImpl::Sequence::Header
A sequence header.
Definition: CmdSequencerImpl.hpp:162
Svc::CmdSequencerComponentImpl::FPrimeSequence::copyCommand
Fw::SerializeStatus copyCommand(Fw::ComBuffer &comBuffer, const U32 recordSize)
Definition: FPrimeSequence.cpp:411
Fw::SerializeBufferBase::deserialize
SerializeStatus deserialize(U8 &val)
deserialize 8-bit unsigned int
Definition: Serializable.cpp:292
Svc::CmdSequencerComponentBase::fileName
PROTECTED U32 const Fw::CmdStringArg & fileName
Definition: CmdSequencerComponentAc.hpp:671
Svc::CmdSequencerComponentImpl::FPrimeSequence::deserializeHeader
bool deserializeHeader(void)
Definition: FPrimeSequence.cpp:211
FwTimeBaseStoreType
#define FwTimeBaseStoreType
Storage conversion for time base in scripts/ground interface.
Definition: FpConfig.hpp:332
lib_crc.h
Svc
Definition: ActiveLoggerComponentAc.cpp:22
Svc::CmdSequencerComponentImpl::FPrimeSequence::CRC::init
void init(void)
Initialize computed CRC.
Definition: FPrimeSequence.cpp:30
Svc::CmdSequencerComponentImpl::FPrimeSequence::CRC::finalize
void finalize(void)
Finalize computed CRC.
Definition: FPrimeSequence.cpp:45
Os::File::Status
Status
Definition: File.hpp:24
Svc::CmdSequencerComponentImpl
Definition: CmdSequencerImpl.hpp:26
Svc::CmdSequencerComponentImpl::Sequence::Header::m_timeBase
TimeBase m_timeBase
The time base of the sequence.
Definition: CmdSequencerImpl.hpp:197
CmdSequencerImpl.hpp
Os::File::OP_OK
@ OP_OK
Operation was successful.
Definition: File.hpp:25
Os::File::getLastError
NATIVE_INT_TYPE getLastError(void)
read back last error code (typically errno)
Definition: File.cpp:39
Svc::CmdSequencerComponentImpl::Sequence::Record
A sequence record.
Definition: CmdSequencerImpl.hpp:208
Svc::CmdSequencerComponentImpl::Sequence
A sequence with unspecified binary format.
Definition: CmdSequencerImpl.hpp:52
Svc::CmdSequencerComponentImpl::Sequence::Record::m_timeTag
Fw::Time m_timeTag
The time tag. NOTE: timeBase and context not filled in.
Definition: CmdSequencerImpl.hpp:233
NATIVE_INT_TYPE
int NATIVE_INT_TYPE
native integer type declaration
Definition: BasicTypes.hpp:29
Os::File::OPEN_READ
@ OPEN_READ
Open file for reading.
Definition: File.hpp:16
Fw::ComBuffer
Definition: ComBuffer.hpp:21
Svc::CmdSequencerComponentImpl::FPrimeSequence::extractCRC
bool extractCRC(void)
Definition: FPrimeSequence.cpp:297
Svc::CmdSequencerComponentImpl::FPrimeSequence::CRC::update
void update(const BYTE *buffer, NATIVE_UINT_TYPE bufferSize)
Update computed CRC.
Definition: FPrimeSequence.cpp:36
Svc::CmdSequencerComponentImpl::FPrimeSequence::clear
void clear(void)
Definition: FPrimeSequence.cpp:109
Os::File
Definition: File.hpp:11
update_crc_32
unsigned long update_crc_32(unsigned long crc, char c)
Definition: lib_crc.c:269