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