F´ Flight Software - C/C++ Documentation  NASA-v1.6.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 
11 #include "Fw/Types/Assert.hpp"
13 extern "C" {
15 }
16 
17 namespace Svc {
18 
20  CRC() :
21  m_computed(INITIAL_COMPUTED_VALUE),
22  m_stored(0)
23  {
24 
25  }
26 
29  {
30  this->m_computed = INITIAL_COMPUTED_VALUE;
31  }
32 
34  update(const BYTE* buffer, NATIVE_UINT_TYPE bufferSize)
35  {
36  FW_ASSERT(buffer);
37  for(NATIVE_UINT_TYPE index = 0; index < bufferSize; index++) {
38  this->m_computed = update_crc_32(this->m_computed, buffer[index]);
39  }
40  }
41 
44  {
45  this->m_computed = ~this->m_computed;
46  }
47 
50  Sequence(component)
51  {
52 
53  }
54 
55  bool CmdSequencerComponentImpl::FPrimeSequence ::
56  validateCRC()
57  {
58  bool result = true;
59  if (this->m_crc.m_stored != this->m_crc.m_computed) {
60  this->m_events.fileCRCFailure(
61  this->m_crc.m_stored,
62  this->m_crc.m_computed
63  );
64  result = false;
65  }
66  return result;
67  }
68 
70  loadFile(const Fw::CmdStringArg& fileName)
71  {
72 
73  // make sure there is a buffer allocated
74  FW_ASSERT(this->m_buffer.getBuffAddr());
75 
76  this->setFileName(fileName);
77 
78  const bool status = this->readFile()
79  and this->validateCRC()
80  and this->m_header.validateTime(this->m_component)
81  and this->validateRecords();
82 
83  return status;
84 
85  }
86 
89  {
90  return this->m_buffer.getBuffLeft() > 0;
91  }
92 
95  {
96  Fw::SerializeStatus status = this->deserializeRecord(record);
97  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
98  }
99 
102  {
103  this->m_buffer.resetDeser();
104  }
105 
108  {
109  this->m_buffer.resetSer();
110  }
111 
112  bool CmdSequencerComponentImpl::FPrimeSequence ::
113  readFile()
114  {
115 
116  bool result;
117 
118  Os::File::Status status = this->m_sequenceFile.open(
119  this->m_fileName.toChar(),
121  );
122 
123  if (status == Os::File::OP_OK) {
124  result = this->readOpenFile();
125  } else if (status == Os::File::DOESNT_EXIST) {
126  this->m_events.fileNotFound();
127  result = false;
128  } else {
129  this->m_events.fileReadError();
130  result = false;
131  }
132 
133  this->m_sequenceFile.close();
134  return result;
135 
136  }
137 
138  bool CmdSequencerComponentImpl::FPrimeSequence ::
139  readOpenFile()
140  {
141  U8 *const buffAddr = this->m_buffer.getBuffAddr();
142  this->m_crc.init();
143  bool status = this->readHeader();
144  if (status) {
145  this->m_crc.update(buffAddr, Sequence::Header::SERIALIZED_SIZE);
146  status = this->deserializeHeader()
147  and this->readRecordsAndCRC()
148  and this->extractCRC();
149  }
150  if (status) {
151  const NATIVE_UINT_TYPE buffLen = this->m_buffer.getBuffLength();
152  this->m_crc.update(buffAddr, buffLen);
153  this->m_crc.finalize();
154  }
155  return status;
156  }
157 
158  bool CmdSequencerComponentImpl::FPrimeSequence ::
159  readHeader()
160  {
161 
162  Os::File& file = this->m_sequenceFile;
163  Fw::SerializeBufferBase& buffer = this->m_buffer;
164  bool status = true;
165 
167  FW_ASSERT(readLen >= 0, readLen);
168 
169  const NATIVE_UINT_TYPE capacity = buffer.getBuffCapacity();
170  FW_ASSERT(
171  capacity >= static_cast<NATIVE_UINT_TYPE>(readLen),
172  capacity,
173  readLen
174  );
175  Os::File::Status fileStatus = file.read(
176  buffer.getBuffAddr(),
177  readLen
178  );
179 
180  if (fileStatus != Os::File::OP_OK) {
181  this->m_events.fileInvalid(
182  CmdSequencer_FileReadStage::READ_HEADER,
183  file.getLastError()
184  );
185  status = false;
186  }
187 
188  if (status and readLen != Sequence::Header::SERIALIZED_SIZE) {
189  this->m_events.fileInvalid(
190  CmdSequencer_FileReadStage::READ_HEADER_SIZE,
191  readLen
192  );
193  status = false;
194  }
195 
196  if (status) {
197  const Fw::SerializeStatus serializeStatus =
198  buffer.setBuffLen(readLen);
199  FW_ASSERT(
200  serializeStatus == Fw::FW_SERIALIZE_OK,
201  serializeStatus
202  );
203  }
204 
205  return status;
206  }
207 
208  bool CmdSequencerComponentImpl::FPrimeSequence ::
209  deserializeHeader()
210  {
211  Fw::SerializeBufferBase& buffer = this->m_buffer;
212  Header& header = this->m_header;
213 
214  // File size
215  Fw::SerializeStatus serializeStatus = buffer.deserialize(header.m_fileSize);
216  if (serializeStatus != Fw::FW_SERIALIZE_OK) {
217  this->m_events.fileInvalid(
218  CmdSequencer_FileReadStage::DESER_SIZE,
219  serializeStatus
220  );
221  return false;
222  }
223  if (header.m_fileSize > buffer.getBuffCapacity()) {
224  this->m_events.fileSizeError(header.m_fileSize);
225  return false;
226  }
227  // Number of records
228  serializeStatus = buffer.deserialize(header.m_numRecords);
229  if (serializeStatus != Fw::FW_SERIALIZE_OK) {
230  this->m_events.fileInvalid(
231  CmdSequencer_FileReadStage::DESER_NUM_RECORDS,
232  serializeStatus
233  );
234  return false;
235  }
236  // Time base
237  FwTimeBaseStoreType tbase;
238  serializeStatus = buffer.deserialize(tbase);
239  if (serializeStatus != Fw::FW_SERIALIZE_OK) {
240  this->m_events.fileInvalid(
241  CmdSequencer_FileReadStage::DESER_TIME_BASE,
242  serializeStatus
243  );
244  return false;
245  }
246  header.m_timeBase = static_cast<TimeBase>(tbase);
247  // Time context
248  serializeStatus = buffer.deserialize(header.m_timeContext);
249  if (serializeStatus != Fw::FW_SERIALIZE_OK) {
250  this->m_events.fileInvalid(
251  CmdSequencer_FileReadStage::DESER_TIME_CONTEXT,
252  serializeStatus
253  );
254  return false;
255  }
256  return true;
257  }
258 
259  bool CmdSequencerComponentImpl::FPrimeSequence ::
260  readRecordsAndCRC()
261  {
262  Os::File& file = this->m_sequenceFile;
263  const NATIVE_UINT_TYPE size = this->m_header.m_fileSize;
264  Fw::SerializeBufferBase& buffer = this->m_buffer;
265 
266  NATIVE_INT_TYPE readLen = size;
267  Os::File::Status fileStatus = file.read(
268  buffer.getBuffAddr(),
269  readLen
270  );
271  // check read status
272  if (fileStatus != Os::File::OP_OK) {
273  this->m_events.fileInvalid(
274  CmdSequencer_FileReadStage::READ_SEQ_DATA,
275  file.getLastError()
276  );
277  return false;
278  }
279  // check read size
280  if (static_cast<NATIVE_INT_TYPE>(size) != readLen) {
281  this->m_events.fileInvalid(
282  CmdSequencer_FileReadStage::READ_SEQ_DATA_SIZE,
283  readLen
284  );
285  return false;
286  }
287  // set buffer size
288  Fw::SerializeStatus serializeStatus =
289  buffer.setBuffLen(size);
290  FW_ASSERT(serializeStatus == Fw::FW_SERIALIZE_OK, serializeStatus);
291  return true;
292  }
293 
294  bool CmdSequencerComponentImpl::FPrimeSequence ::
295  extractCRC()
296  {
297  Fw::SerializeBufferBase& buffer = this->m_buffer;
298  U32& crc = this->m_crc.m_stored;
299 
300  // Compute the data size
301  const U32 buffSize = buffer.getBuffLength();
302  const U32 crcSize = sizeof(crc);
303  U8 *const buffAddr = buffer.getBuffAddr();
304  if (buffSize < crcSize) {
305  this->m_events.fileInvalid(
306  CmdSequencer_FileReadStage::READ_SEQ_CRC,
307  buffSize
308  );
309  return false;
310  }
311  FW_ASSERT(buffSize >= crcSize, buffSize, crcSize);
312  const NATIVE_UINT_TYPE dataSize = buffSize - crcSize;
313  // Create a CRC buffer pointing at the CRC in the main buffer, after the data
314  Fw::ExternalSerializeBuffer crcBuff(&buffAddr[dataSize], crcSize);
315  Fw::SerializeStatus status = crcBuff.setBuffLen(crcSize);
316  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
317  // Deserialize the CRC from the CRC buffer
318  status = crcBuff.deserialize(crc);
319  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
320  // Set the main buffer size to the data size
321  status = buffer.setBuffLen(dataSize);
322  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
323  return true;
324  }
325 
326  Fw::SerializeStatus CmdSequencerComponentImpl::FPrimeSequence ::
327  deserializeRecord(Record& record)
328  {
329  U32 recordSize;
330 
331  Fw::SerializeStatus status =
332  this->deserializeDescriptor(record.m_descriptor);
333 
334  if (
335  status == Fw::FW_SERIALIZE_OK and
336  record.m_descriptor == Record::END_OF_SEQUENCE
337  ) {
338  return Fw::FW_SERIALIZE_OK;
339  }
340 
341  if (status == Fw::FW_SERIALIZE_OK) {
342  status = this->deserializeTimeTag(record.m_timeTag);
343  }
344  if (status == Fw::FW_SERIALIZE_OK) {
345  status = this->deserializeRecordSize(recordSize);
346  }
347  if (status == Fw::FW_SERIALIZE_OK) {
348  status = this->copyCommand(record.m_command, recordSize);
349  }
350 
351  return status;
352  }
353 
354  Fw::SerializeStatus CmdSequencerComponentImpl::FPrimeSequence ::
355  deserializeDescriptor(Record::Descriptor& descriptor)
356  {
357  Fw::SerializeBufferBase& buffer = this->m_buffer;
358  U8 descEntry;
359 
360  Fw::SerializeStatus status = buffer.deserialize(descEntry);
361  if (status != Fw::FW_SERIALIZE_OK) {
362  return status;
363  }
364 
365  if (descEntry > Sequence::Record::END_OF_SEQUENCE) {
367  }
368 
369  descriptor = static_cast<Record::Descriptor>(descEntry);
370  return Fw::FW_SERIALIZE_OK;
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()
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 
Fw::ComBuffer::SERIALIZED_SIZE
@ SERIALIZED_SIZE
Definition: ComBuffer.hpp:26
Svc::CmdSequencerComponentImpl::FPrimeSequence::hasMoreRecords
bool hasMoreRecords() const
Definition: FPrimeSequence.cpp:88
Svc::CmdSequencerComponentImpl::FPrimeSequence::clear
void clear()
Definition: FPrimeSequence.cpp:107
Svc::CmdSequencerComponentImpl::Sequence::Header::SERIALIZED_SIZE
@ SERIALIZED_SIZE
Serialized size of header.
Definition: CmdSequencerImpl.hpp:141
Fw::Time
Definition: Time.hpp:10
FwPacketDescriptorType
#define FwPacketDescriptorType
Type representation for a packet descriptor.
Definition: FpConfig.hpp:58
Fw::SerializeBufferBase
Definition: Serializable.hpp:43
Fw::SerializeStatus
SerializeStatus
forward declaration for string
Definition: Serializable.hpp:14
Fw::SerializeBufferBase::resetDeser
void resetDeser(void)
reset deserialization to beginning
Definition: Serializable.cpp:577
FwTimeBaseStoreType
#define FwTimeBaseStoreType
Storage conversion for time base in scripts/ground interface.
Definition: FpConfig.hpp:324
Svc::CmdSequencerComponentImpl::FPrimeSequence::CRC::init
void init()
Initialize computed CRC.
Definition: FPrimeSequence.cpp:28
Fw::FW_DESERIALIZE_FORMAT_ERROR
@ FW_DESERIALIZE_FORMAT_ERROR
Deserialization data had incorrect values (unexpected data types)
Definition: Serializable.hpp:19
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
Svc::CmdSequencerComponentImpl::Sequence::Record::END_OF_SEQUENCE
@ END_OF_SEQUENCE
end of sequence
Definition: CmdSequencerImpl.hpp:188
U8
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.hpp:73
NATIVE_UINT_TYPE
unsigned int NATIVE_UINT_TYPE
native unsigned integer type declaration
Definition: BasicTypes.hpp:28
TimeBase
TimeBase
Definition: FpConfig.hpp:315
Fw::SerializeBufferBase::resetSer
void resetSer(void)
reset to beginning of buffer to reuse for serialization
Definition: Serializable.cpp:572
Fw::CmdStringArg
Definition: CmdString.hpp:11
Fw::ComBuffer::getBuffAddr
U8 * getBuffAddr()
gets buffer address for data filling
Definition: ComBuffer.cpp:36
Fw::SerializeBufferBase::getBuffLeft
NATIVE_UINT_TYPE getBuffLeft() const
returns how much deserialization buffer is left
Definition: Serializable.cpp:621
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:70
Os::File::DOESNT_EXIST
@ DOESNT_EXIST
File doesn't exist (for read)
Definition: File.hpp:26
NATIVE_INT_TYPE
int NATIVE_INT_TYPE
native integer type declaration
Definition: BasicTypes.hpp:27
Fw::Time::set
void set(U32 seconds, U32 useconds)
Definition: Time.cpp:25
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:74
Fw::SerializeBufferBase::setBuffLen
SerializeStatus setBuffLen(NATIVE_UINT_TYPE length)
sets buffer length manually after filling with data
Definition: Serializable.cpp:611
Svc::CmdSequencerComponentImpl::FPrimeSequence::nextRecord
void nextRecord(Record &record)
Definition: FPrimeSequence.cpp:94
Svc::CmdSequencerComponentImpl::FPrimeSequence::reset
void reset()
Definition: FPrimeSequence.cpp:101
Fw::SerializeBufferBase::getBuffLength
NATIVE_UINT_TYPE getBuffLength() const
returns current buffer size
Definition: Serializable.cpp:594
Svc::CmdSequencerComponentImpl::FPrimeSequence::CRC::CRC
CRC()
Construct a CRC.
Definition: FPrimeSequence.cpp:20
Svc::CmdSequencerComponentImpl::FPrimeSequence::FPrimeSequence
FPrimeSequence(CmdSequencerComponentImpl &component)
Construct an FPrimeSequence.
Definition: FPrimeSequence.cpp:49
Fw::ExternalSerializeBuffer
Definition: Serializable.hpp:153
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:9
Fw::SerializeBufferBase::deserialize
SerializeStatus deserialize(U8 &val)
deserialize 8-bit unsigned int
Definition: Serializable.cpp:294
Svc::CmdSequencerComponentImpl::FPrimeSequence::CRC::finalize
void finalize()
Finalize computed CRC.
Definition: FPrimeSequence.cpp:43
lib_crc.h
Svc
Definition: ActiveRateGroupCfg.hpp:18
Os::File::getLastError
NATIVE_INT_TYPE getLastError()
read back last error code (typically errno)
Definition: File.cpp:39
Os::File::Status
Status
Definition: File.hpp:24
Svc::CmdSequencerComponentImpl
Definition: CmdSequencerImpl.hpp:22
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
CmdSequencerImpl.hpp
Os::File::OP_OK
@ OP_OK
Operation was successful.
Definition: File.hpp:25
Svc::CmdSequencerComponentImpl::Sequence::Record
A sequence record.
Definition: CmdSequencerImpl.hpp:181
Svc::CmdSequencerComponentImpl::Sequence
A sequence with unspecified binary format.
Definition: CmdSequencerImpl.hpp:50
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:34
Os::File
Definition: File.hpp:11
Fw::FW_SERIALIZE_OK
@ FW_SERIALIZE_OK
Serialization/Deserialization operation was successful.
Definition: Serializable.hpp:15
update_crc_32
unsigned long update_crc_32(unsigned long crc, char c)
Definition: lib_crc.c:269