F´ Flight Software - C/C++ Documentation
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, FwSizeType bufferSize)
35  {
36  FW_ASSERT(buffer);
37  for(FwSizeType index = 0; index < bufferSize; index++) {
38  this->m_computed = static_cast<U32>(update_crc_32(this->m_computed, static_cast<char>(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::StringBase& 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 FwSizeType 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 
168  const FwSizeType capacity = buffer.getBuffCapacity();
169  FW_ASSERT(
170  capacity >= readLen,
171  static_cast<FwAssertArgType>(capacity),
172  static_cast<FwAssertArgType>(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(
182  fileStatus
183  );
184  status = false;
185  }
186 
187  if (status and readLen != Sequence::Header::SERIALIZED_SIZE) {
188  this->m_events.fileInvalid(
190  static_cast<I32>(readLen)
191  );
192  status = false;
193  }
194 
195  if (status) {
196  const Fw::SerializeStatus serializeStatus =
197  buffer.setBuffLen(static_cast<Fw::Serializable::SizeType>(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()
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(
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(
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(
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(
251  serializeStatus
252  );
253  return false;
254  }
255  return true;
256  }
257 
258  bool CmdSequencerComponentImpl::FPrimeSequence ::
259  readRecordsAndCRC()
260  {
261  Os::File& file = this->m_sequenceFile;
262  const FwSizeType size = this->m_header.m_fileSize;
263  Fw::SerializeBufferBase& buffer = this->m_buffer;
264 
265  FwSizeType 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(
274  fileStatus
275  );
276  return false;
277  }
278  // check read size
279  if (size != static_cast<FwSizeType>(readLen)) {
280  this->m_events.fileInvalid(
282  static_cast<I32>(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()
295  {
296  Fw::SerializeBufferBase& buffer = this->m_buffer;
297  U32& crc = this->m_crc.m_stored;
298 
299  // Compute the data size
300  const FwSizeType buffSize = buffer.getBuffLength();
301  const FwSizeType crcSize = sizeof(crc);
302  U8 *const buffAddr = buffer.getBuffAddr();
303  if (buffSize < crcSize) {
304  this->m_events.fileInvalid(
306  static_cast<I32>(buffSize)
307  );
308  return false;
309  }
310  FW_ASSERT(buffSize >= crcSize, static_cast<FwAssertArgType>(buffSize), crcSize);
311  const FwSizeType 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 
359  Fw::SerializeStatus status = buffer.deserialize(descEntry);
360  if (status != Fw::FW_SERIALIZE_OK) {
361  return status;
362  }
363 
364  if (descEntry > Sequence::Record::END_OF_SEQUENCE) {
366  }
367 
368  descriptor = static_cast<Record::Descriptor>(descEntry);
369  return Fw::FW_SERIALIZE_OK;
370  }
371 
372  Fw::SerializeStatus CmdSequencerComponentImpl::FPrimeSequence ::
373  deserializeTimeTag(Fw::Time& timeTag)
374  {
375  Fw::SerializeBufferBase& buffer = this->m_buffer;
376  U32 seconds, useconds;
377  Fw::SerializeStatus status = buffer.deserialize(seconds);
378  if (status == Fw::FW_SERIALIZE_OK) {
379  status = buffer.deserialize(useconds);
380  }
381  if (status == Fw::FW_SERIALIZE_OK) {
382  timeTag.set(seconds,useconds);
383  }
384  return status;
385  }
386 
387  Fw::SerializeStatus CmdSequencerComponentImpl::FPrimeSequence ::
388  deserializeRecordSize(U32& recordSize)
389  {
390  Fw::SerializeBufferBase& buffer = this->m_buffer;
391  Fw::SerializeStatus status = buffer.deserialize(recordSize);
392  if (status == Fw::FW_SERIALIZE_OK and recordSize > buffer.getBuffLeft()) {
393  // Not enough data left
395  }
396  if (
397  status == Fw::FW_SERIALIZE_OK and
399  ) {
400  // Record size is too big for com buffer
402  }
403  return status;
404  }
405 
406  Fw::SerializeStatus CmdSequencerComponentImpl::FPrimeSequence ::
407  copyCommand(Fw::ComBuffer& comBuffer, const U32 recordSize)
408  {
409  Fw::SerializeBufferBase& buffer = this->m_buffer;
410  comBuffer.resetSer();
411  FwSizeType size = recordSize;
412  Fw::SerializeStatus status = comBuffer.setBuffLen(recordSize);
413  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
414  status = buffer.deserialize(comBuffer.getBuffAddr(), size, true);
415  return status;
416  }
417 
418  bool CmdSequencerComponentImpl::FPrimeSequence ::
419  validateRecords()
420  {
421  Fw::SerializeBufferBase& buffer = this->m_buffer;
422  const U32 numRecords = this->m_header.m_numRecords;
423  Sequence::Record record;
424 
425  if (numRecords == 0)
426  {
427  this->m_events.noRecords();
428  return false;
429  }
430 
431  // Deserialize all records
432  for (U32 recordNumber = 0; recordNumber < numRecords; recordNumber++) {
433  Fw::SerializeStatus status = this->deserializeRecord(record);
434  if (status != Fw::FW_SERIALIZE_OK) {
435  this->m_events.recordInvalid(recordNumber, status);
436  return false;
437  }
438  }
439  // Check there is no data left
440  const FwSizeType buffLeftSize = buffer.getBuffLeft();
441  if (buffLeftSize > 0) {
442  this->m_events.recordMismatch(numRecords, static_cast<U32>(buffLeftSize));
443  return false;
444  }
445  // Rewind deserialization
446  buffer.resetDeser();
447 
448  return true;
449  }
450 
451 }
452 
Serialization/Deserialization operation was successful.
Definition: Time.hpp:9
PlatformSizeType FwSizeType
void resetSer()
reset to beginning of buffer to reuse for serialization
bool loadFile(const Fw::StringBase &fileName)
Deserialization data had incorrect values (unexpected data types)
SerializeStatus
forward declaration for string
unsigned long update_crc_32(unsigned long crc, char c)
Definition: lib_crc.c:271
Serializable::SizeType getBuffLength() const
returns current buffer size
Serializable::SizeType getBuffLeft() const
returns how much deserialization buffer is left
void set(U32 seconds, U32 useconds)
Definition: Time.cpp:25
A sequence with unspecified binary format.
File doesn&#39;t exist (for read)
Definition: File.hpp:31
void update(const BYTE *buffer, FwSizeType bufferSize)
Update computed CRC.
Data was left in the buffer, but not enough to deserialize.
External serialize buffer with no copy semantics.
U8 * getBuffAddr()
gets buffer address for data filling
Definition: ComBuffer.cpp:40
void resetDeser()
reset deserialization to beginning
FPrimeSequence(CmdSequencerComponentImpl &component)
Construct an FPrimeSequence.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:56
Status read(U8 *buffer, FwSizeType &size)
read data from this file into supplied buffer bounded by size
Definition: File.cpp:168
virtual Serializable::SizeType getBuffCapacity() const =0
returns capacity, not current size, of buffer
Operation was successful.
Definition: File.hpp:30
U32 FwPacketDescriptorType
The type of a com packet descriptor.
SerializeStatus deserialize(U8 &val)
deserialize 8-bit unsigned int
Open file for reading.
Definition: File.hpp:21
RateGroupDivider component implementation.
U8 BYTE
byte type
Definition: BasicTypes.h:59
U16 FwTimeBaseStoreType
The type used to serialize a time base value.
virtual U8 * getBuffAddr()=0
gets buffer address for data filling
TimeBase
Definition: FpConfig.h:29
#define FW_ASSERT(...)
Definition: Assert.hpp:14
SerializeStatus setBuffLen(Serializable::SizeType length)
sets buffer length manually after filling with data