F´ Flight Software - C/C++ Documentation  NASA-v2.1.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 (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