F´ Flight Software - C/C++ Documentation  NASA-v2.0.1
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 
57  bool CmdSequencerComponentImpl::FPrimeSequence ::
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 
72  loadFile(const Fw::CmdStringArg& fileName)
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 
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 
140  bool CmdSequencerComponentImpl::FPrimeSequence ::
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 
160  bool CmdSequencerComponentImpl::FPrimeSequence ::
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 
210  bool CmdSequencerComponentImpl::FPrimeSequence ::
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 
261  bool CmdSequencerComponentImpl::FPrimeSequence ::
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 
296  bool CmdSequencerComponentImpl::FPrimeSequence ::
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 
328  Fw::SerializeStatus CmdSequencerComponentImpl::FPrimeSequence ::
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 
356  Fw::SerializeStatus CmdSequencerComponentImpl::FPrimeSequence ::
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 
376  Fw::SerializeStatus CmdSequencerComponentImpl::FPrimeSequence ::
377  deserializeTimeTag(Fw::Time& timeTag)
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 
391  Fw::SerializeStatus CmdSequencerComponentImpl::FPrimeSequence ::
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 
410  Fw::SerializeStatus CmdSequencerComponentImpl::FPrimeSequence ::
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 
422  bool CmdSequencerComponentImpl::FPrimeSequence ::
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::reset
void reset(void)
Definition: FPrimeSequence.cpp:103
Svc::CmdSequencerComponentImpl::Sequence::Header::SERIALIZED_SIZE
@ SERIALIZED_SIZE
Serialized size of header.
Definition: CmdSequencerImpl.hpp:168
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 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:323
Fw::CmdStringArg
Definition: CmdString.hpp:11
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: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:72
Svc::CmdSequencerComponentImpl::FPrimeSequence::hasMoreRecords
bool hasMoreRecords(void) const
Definition: FPrimeSequence.cpp:90
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: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:587
Svc::CmdSequencerComponentImpl::FPrimeSequence::FPrimeSequence
FPrimeSequence(CmdSequencerComponentImpl &component)
Construct an FPrimeSequence.
Definition: FPrimeSequence.cpp:51
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:332
lib_crc.h
Svc
Definition: ActiveRateGroupImplCfg.hpp:18
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:24
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
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: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