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