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