F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
PrmDbImpl.cpp
Go to the documentation of this file.
1 /*
2  * PrmDbImpl.cpp
3  *
4  * Created on: March 9, 2015
5  * Author: Timothy Canham
6  */
7 
8 #include <Fw/Types/Assert.hpp>
10 
11 #include <Os/File.hpp>
12 #include <Utils/Hash/Hash.hpp>
13 
14 #include <cstdio>
15 #include <cstring>
16 
17 static_assert(std::numeric_limits<FwSizeType>::max() >= PRMDB_NUM_DB_ENTRIES,
18  "PRMDB_NUM_DB_ENTRIES must fit within range of FwSizeType");
19 
20 namespace Svc {
21 
22 // anonymous namespace for buffer declaration
23 namespace {
24 class WorkingBuffer : public Fw::LinearBufferBase {
25  public:
26  FwSizeType getCapacity() const { return sizeof(m_buff); }
27 
28  U8* getBuffAddr() { return m_buff; }
29 
30  const U8* getBuffAddr() const { return m_buff; }
31 
32  private:
33  // Set to max of parameter buffer + id
34  U8 m_buff[FW_PARAM_BUFFER_MAX_SIZE + sizeof(FwPrmIdType)];
35  static_assert(sizeof(m_buff) >= sizeof(U32), "Size of parameter buffer storage must be >= sizeof(U32)");
36 };
37 } // namespace
38 
42 PrmDbImpl::PrmDbImpl(const char* name) : PrmDbComponentBase(name), m_state(PrmDbFileLoadState::IDLE) {
43  this->m_activeDb = &this->m_dbStore1;
44  this->m_stagingDb = &this->m_dbStore2;
45 
46  this->clearDb(PrmDbType::DB_ACTIVE);
47  this->clearDb(PrmDbType::DB_STAGING);
48 }
49 
51 
52 void PrmDbImpl::configure(const char* file) {
53  FW_ASSERT(file != nullptr);
54  this->m_fileName = file;
55 }
56 
58  // Assumed to run at initialization time
59  // State should be IDLE upon entry
60  FW_ASSERT(static_cast<FwAssertArgType>(m_state == PrmDbFileLoadState::IDLE));
61 
62  // Clear databases
63  this->clearDb(PrmDbType::DB_ACTIVE);
64  this->clearDb(PrmDbType::DB_STAGING);
65 
66  // Read parameter file to active database
67  (void)readParamFileImpl(this->m_fileName, PrmDbType::DB_ACTIVE);
68 }
69 
73 
74 // If ports are no longer guarded, these accesses need to be protected from each other
75 // If there are a lot of accesses, perhaps an interrupt lock could be used instead of guarded ports
76 
77 Fw::ParamValid PrmDbImpl::getPrm_handler(FwIndexType portNum, FwPrmIdType id, Fw::ParamBuffer& val) {
78  // search for entry
79  auto success = this->m_activeDb->find(id, val);
80 
81  switch (success.e) {
83  // if unable to find parameter, send error message
87  return Fw::ParamValid::VALID;
88  default:
89  FW_ASSERT(0, success.e);
91  }
92 }
93 
94 void PrmDbImpl::setPrm_handler(FwIndexType portNum, FwPrmIdType id, Fw::ParamBuffer& val) {
95  // Reject parameter updates during non-idle file load states
96  if (m_state != PrmDbFileLoadState::IDLE) {
98  return;
99  }
100 
101  // Update the parameter in the active database
102  PrmUpdateType update_status = updateAddPrmImpl(id, val, PrmDbType::DB_ACTIVE);
103 
104  // Issue relevant EVR
105  if (update_status == PARAM_UPDATED) {
107  } else if (update_status == NO_SLOTS) {
108  this->log_WARNING_HI_PrmDbFull(id);
109  } else {
110  this->log_ACTIVITY_HI_PrmIdAdded(id);
111  }
112 }
113 
114 void PrmDbImpl::pingIn_handler(FwIndexType portNum, U32 key) {
115  // respond to ping
116  this->pingOut_out(0, key);
117 }
118 
119 void PrmDbImpl::PRM_SAVE_FILE_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
120  // Reject PRM_SAVE_FILE command during non-idle file load states
121  if (m_state != PrmDbFileLoadState::IDLE) {
123  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::BUSY);
124  return;
125  }
126 
127  FW_ASSERT(this->m_fileName.length() > 0);
128 
129  Os::File paramFile;
130  WorkingBuffer buff;
131 
132  Os::File::Status stat = paramFile.open(this->m_fileName.toChar(), Os::File::OPEN_WRITE, Os::File::OVERWRITE);
133  if (stat != Os::File::OP_OK) {
135  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
136  return;
137  }
138 
139  // write placeholder for the CRC
140  Utils::Hash crc;
141  U32 crcInitial = 0xFFFFFFFF;
142  buff.resetSer();
143  Fw::SerializeStatus serStat = buff.serializeFrom(crcInitial);
144  FW_ASSERT(Fw::FW_SERIALIZE_OK == serStat, static_cast<FwAssertArgType>(serStat));
145  FwSizeType writeSize = static_cast<FwSizeType>(buff.getSize());
146  stat = paramFile.write(buff.getBuffAddr(), writeSize, Os::File::WaitType::WAIT);
147 
148  if (stat != Os::File::OP_OK) {
150  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
151  return;
152  }
153 
154  this->lock();
155  auto db = getDbPtr(PrmDbType::DB_ACTIVE);
156  FW_ASSERT(db != nullptr);
157 
158  // Traverse the parameter list, saving each entry
159 
160  U32 numRecords = 0;
161 
162  for (const auto& entry : *db) {
163  // write delimiter
164  static const U8 delim = PRMDB_ENTRY_DELIMITER;
165  writeSize = static_cast<FwSizeType>(sizeof(delim));
166  stat = paramFile.write(&delim, writeSize, Os::File::WaitType::WAIT);
167  if (stat != Os::File::OP_OK) {
168  this->unLock();
169  this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::DELIMITER, static_cast<I32>(numRecords), stat);
170  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
171  return;
172  }
173  if (writeSize != sizeof(delim)) {
174  this->unLock();
175  this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::DELIMITER_SIZE, static_cast<I32>(numRecords),
176  static_cast<I32>(writeSize));
177  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
178  return;
179  }
180 
181  // add delimiter to CRC
182  crc.update(&delim, sizeof(delim));
183 
184  // serialize record size = id field + data
185  U32 recordSize = static_cast<U32>(sizeof(FwPrmIdType) + entry.getValue().getSize());
186 
187  // reset buffer
188  buff.resetSer();
189  serStat = buff.serializeFrom(recordSize);
190  // should always work
191  FW_ASSERT(Fw::FW_SERIALIZE_OK == serStat, static_cast<FwAssertArgType>(serStat));
192 
193  // write record size
194  writeSize = static_cast<FwSizeType>(buff.getSize());
195  stat = paramFile.write(buff.getBuffAddr(), writeSize, Os::File::WaitType::WAIT);
196  if (stat != Os::File::OP_OK) {
197  this->unLock();
198  this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::RECORD_SIZE, static_cast<I32>(numRecords), stat);
199  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
200  return;
201  }
202  if (writeSize != sizeof(recordSize)) {
203  this->unLock();
204  this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::RECORD_SIZE_SIZE, static_cast<I32>(numRecords),
205  static_cast<I32>(writeSize));
206  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
207  return;
208  }
209 
210  // add recordSize to CRC
211  if (buff.getBuffAddr() != nullptr && writeSize != 0) {
212  crc.update(buff.getBuffAddr(), writeSize);
213  }
214 
215  // reset buffer
216  buff.resetSer();
217 
218  // serialize parameter id
219 
220  serStat = buff.serializeFrom(entry.getKey());
221  // should always work
222  FW_ASSERT(Fw::FW_SERIALIZE_OK == serStat, static_cast<FwAssertArgType>(serStat));
223 
224  // write parameter ID
225  writeSize = static_cast<FwSizeType>(buff.getSize());
226  stat = paramFile.write(buff.getBuffAddr(), writeSize, Os::File::WaitType::WAIT);
227  if (stat != Os::File::OP_OK) {
228  this->unLock();
229  this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::PARAMETER_ID, static_cast<I32>(numRecords), stat);
230  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
231  return;
232  }
233  if (writeSize != static_cast<FwSizeType>(buff.getSize())) {
234  this->unLock();
235  this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::PARAMETER_ID_SIZE, static_cast<I32>(numRecords),
236  static_cast<I32>(writeSize));
237  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
238  return;
239  }
240 
241  // add parameter ID to CRC
242  if (buff.getBuffAddr() != nullptr && writeSize != 0) {
243  crc.update(buff.getBuffAddr(), writeSize);
244  }
245 
246  // write serialized parameter value
247 
248  writeSize = static_cast<FwSizeType>(entry.getValue().getSize());
249  stat = paramFile.write(entry.getValue().getBuffAddr(), writeSize, Os::File::WaitType::WAIT);
250  if (stat != Os::File::OP_OK) {
251  this->unLock();
252  this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::PARAMETER_VALUE, static_cast<I32>(numRecords), stat);
253  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
254  return;
255  }
256  if (writeSize != static_cast<FwSizeType>(entry.getValue().getSize())) {
257  this->unLock();
258  this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::PARAMETER_VALUE_SIZE, static_cast<I32>(numRecords),
259  static_cast<I32>(writeSize));
260  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
261  return;
262  }
263 
264  // add serialized parameter value to crc
265  if (entry.getValue().getBuffAddr() != nullptr && writeSize != 0) {
266  crc.update(entry.getValue().getBuffAddr(), writeSize);
267  }
268 
269  numRecords++;
270  }
271 
272  this->unLock();
273 
274  // save current location of pointer in paramFile
275  FwSizeType currPosInParamFile;
276 
277  stat = paramFile.position(currPosInParamFile);
278  if (stat != Os::File::OP_OK) {
280  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
281  return;
282  }
283 
284  // seek to beginning and write CRC value
285  stat = paramFile.seek(0, Os::File::SeekType::ABSOLUTE);
286  if (stat != Os::File::OP_OK) {
288  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
289  return;
290  }
291  buff.resetSer();
292  U32 crcFinal = 0;
293  crc.finalize(crcFinal);
294  crcFinal = ~crcFinal;
295  serStat = buff.serializeFrom(crcFinal);
296 
297  FW_ASSERT(Fw::FW_SERIALIZE_OK == serStat, static_cast<FwAssertArgType>(serStat));
298  writeSize = static_cast<FwSizeType>(buff.getSize());
299 
300  stat = paramFile.write(buff.getBuffAddr(), writeSize, Os::File::WaitType::WAIT);
301  if (stat != Os::File::OP_OK) {
303  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
304  return;
305  }
306 
307  // Restore pointer to previously saved location
308  stat = paramFile.seek(static_cast<FwSignedSizeType>(currPosInParamFile), Os::File::SeekType::ABSOLUTE);
309  if (stat != Os::File::OP_OK) {
311  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
312  return;
313  }
314 
315  this->log_ACTIVITY_HI_PrmFileSaveComplete(numRecords);
316  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
317 }
318 
319 void PrmDbImpl::PRM_LOAD_FILE_cmdHandler(FwOpcodeType opCode,
320  U32 cmdSeq,
321  const Fw::CmdStringArg& fileName,
322  PrmDb_Merge merge) {
323  // Reject PRM_LOAD_FILE command during non-idle file load states
324  if (m_state != PrmDbFileLoadState::IDLE) {
326  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::BUSY);
327  return;
328  }
329 
330  // Set state to loading
332 
333  // If reset is true, clear the staging database first
334  if (merge == PrmDb_Merge::MERGE) {
335  // Copy active to staging for merging
337  } else {
338  // reset staging db, all file contents will be loaded but no old parameters will be retained
339  this->clearDb(PrmDbType::DB_STAGING);
340  }
341 
342  // Load the file into staging database
343  // The readParamFileImpl will emit the relevant EVR if the file load fails
344  // and also if it succeeds will emit EVRs with the number of records
345  PrmDbImpl::PrmLoadStatus success = PrmDbImpl::readParamFileImpl(fileName, PrmDbType::DB_STAGING);
346 
347  if (success == PrmLoadStatus::SUCCESS) {
348  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
350  } else {
352  // clear the staging DB and reset to an IDLE state in case of issues
353  this->clearDb(PrmDbType::DB_STAGING);
354  m_state = PrmDbFileLoadState::IDLE;
355  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
356  }
357 }
358 
359 void PrmDbImpl::PRM_COMMIT_STAGED_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
360  // Verify we are in the correct state
363  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR);
364  return;
365  }
366 
367  // Swap active and staging databases, safely w.r.t. prmGet
368  this->lock();
369  PrmDbStore* temp = this->m_activeDb;
370  this->m_activeDb = this->m_stagingDb;
371  this->unLock();
372  this->m_stagingDb = temp;
373 
374  // Clear the new staging database
375  this->clearDb(PrmDbType::DB_STAGING);
376 
377  // Set file load state to idle
378  m_state = PrmDbFileLoadState::IDLE;
379 
381  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
382 }
383 
387 
388 PrmDbImpl::PrmLoadStatus PrmDbImpl::readParamFileImpl(const Fw::StringBase& fileName, PrmDbType dbType) {
389  FW_ASSERT(dbType == PrmDbType::DB_ACTIVE or dbType == PrmDbType::DB_STAGING);
390  FW_ASSERT(fileName.length() > 0);
391 
392  Fw::String dbString = getDbString(dbType);
393 
394  // load file. FIXME: Put more robust file checking, such as a CRC.
395  Os::File paramFile;
396 
397  Os::File::Status stat = paramFile.open(fileName.toChar(), Os::File::OPEN_READ);
398  if (stat != Os::File::OP_OK) {
400  return PrmLoadStatus::ERROR;
401  }
402  //===========================================================================
403  // read CRC from beginning of file
404  WorkingBuffer buff;
405  U32 fileCrc;
406  FwSizeType readSize = static_cast<FwSizeType>(sizeof(fileCrc));
407 
408  // Read raw CRC bytes from file
409  stat = paramFile.read(buff.getBuffAddr(), readSize);
410  if (stat != Os::File::OP_OK) {
411  this->log_WARNING_HI_PrmFileReadError(PrmReadError::CRC, static_cast<I32>(0), stat);
412  return PrmLoadStatus::ERROR;
413  }
414 
415  if (readSize != sizeof(fileCrc)) {
416  this->log_WARNING_HI_PrmFileReadError(PrmReadError::CRC_SIZE, static_cast<I32>(0), static_cast<I32>(readSize));
417  return PrmLoadStatus::ERROR;
418  }
419 
420  // Deserialize the CRC in a portable way
421  Fw::SerializeStatus serStat = buff.setBuffLen(readSize);
422  FW_ASSERT(Fw::FW_SERIALIZE_OK == serStat, static_cast<FwAssertArgType>(serStat));
423  buff.resetDeser();
424  serStat = buff.deserializeTo(fileCrc);
425  FW_ASSERT(Fw::FW_SERIALIZE_OK == serStat, static_cast<FwAssertArgType>(serStat));
426 
427  U32 crc = 0xFFFFFFFF;
428  // read into CRC buffer for checking
429 
430  Os::File::Status status = paramFile.calculateCrc(crc);
431  if (status != Os::File::OP_OK) {
432  this->log_WARNING_HI_PrmFileReadError(PrmReadError::CRC_BUFFER, static_cast<I32>(0), status);
433  return PrmLoadStatus::ERROR;
434  }
435 
436  if (fileCrc != crc) {
437  this->log_WARNING_HI_PrmFileBadCrc(fileCrc, crc);
438  return PrmLoadStatus::ERROR;
439  }
440 
441  // seek back to just after CRC
442  stat = paramFile.seek(sizeof(fileCrc), Os::File::SeekType::ABSOLUTE);
443  if (stat != Os::File::OP_OK) {
445  return PrmLoadStatus::ERROR;
446  }
447  //===========================================================================
448 
449  U32 recordNumTotal = 0;
450  U32 recordNumAdded = 0;
451  U32 recordNumUpdated = 0;
452 
453  for (FwSizeType entry = 0; entry < PRMDB_NUM_DB_ENTRIES; entry++) {
454  U8 delimiter;
455  readSize = static_cast<FwSizeType>(sizeof(delimiter));
456 
457  // read delimiter
458  Os::File::Status fStat = paramFile.read(&delimiter, readSize, Os::File::WaitType::WAIT);
459 
460  // check for end of file (read size 0)
461  if (0 == readSize) {
462  break;
463  }
464 
465  if (fStat != Os::File::OP_OK) {
466  this->log_WARNING_HI_PrmFileReadError(PrmReadError::DELIMITER, static_cast<I32>(recordNumTotal), fStat);
467  return PrmLoadStatus::ERROR;
468  }
469 
470  if (sizeof(delimiter) != readSize) {
471  this->log_WARNING_HI_PrmFileReadError(PrmReadError::DELIMITER_SIZE, static_cast<I32>(recordNumTotal),
472  static_cast<I32>(readSize));
473  return PrmLoadStatus::ERROR;
474  }
475 
476  if (PRMDB_ENTRY_DELIMITER != delimiter) {
477  this->log_WARNING_HI_PrmFileReadError(PrmReadError::DELIMITER_VALUE, static_cast<I32>(recordNumTotal),
478  delimiter);
479  return PrmLoadStatus::ERROR;
480  }
481 
482  U32 recordSize = 0;
483 
484  // read record size
485  readSize = sizeof(recordSize);
486 
487  fStat = paramFile.read(buff.getBuffAddr(), readSize, Os::File::WaitType::WAIT);
488  if (fStat != Os::File::OP_OK) {
489  this->log_WARNING_HI_PrmFileReadError(PrmReadError::RECORD_SIZE, static_cast<I32>(recordNumTotal), fStat);
490  return PrmLoadStatus::ERROR;
491  }
492  if (sizeof(recordSize) != readSize) {
493  this->log_WARNING_HI_PrmFileReadError(PrmReadError::RECORD_SIZE_SIZE, static_cast<I32>(recordNumTotal),
494  static_cast<I32>(readSize));
495  return PrmLoadStatus::ERROR;
496  }
497  // set serialized size to read size
498  Fw::SerializeStatus desStat = buff.setBuffLen(static_cast<Fw::Serializable::SizeType>(readSize));
499  // should never fail
500  FW_ASSERT(Fw::FW_SERIALIZE_OK == desStat, static_cast<FwAssertArgType>(desStat));
501  // reset deserialization
502  buff.resetDeser();
503  // deserialize, since record size is serialized in file
504  desStat = buff.deserializeTo(recordSize);
505  FW_ASSERT(Fw::FW_SERIALIZE_OK == desStat);
506 
507  // sanity check value. It can't be larger than the maximum parameter buffer size + id
508  // or smaller than the record id
509  if ((recordSize > FW_PARAM_BUFFER_MAX_SIZE + sizeof(U32)) or (recordSize < sizeof(U32))) {
510  this->log_WARNING_HI_PrmFileReadError(PrmReadError::RECORD_SIZE_VALUE, static_cast<I32>(recordNumTotal),
511  static_cast<I32>(recordSize));
512  return PrmLoadStatus::ERROR;
513  }
514 
515  // read the parameter ID
516  FwPrmIdType parameterId = 0;
517  readSize = static_cast<FwSizeType>(sizeof(FwPrmIdType));
518 
519  fStat = paramFile.read(buff.getBuffAddr(), readSize, Os::File::WaitType::WAIT);
520  if (fStat != Os::File::OP_OK) {
521  this->log_WARNING_HI_PrmFileReadError(PrmReadError::PARAMETER_ID, static_cast<I32>(recordNumTotal), fStat);
522  return PrmLoadStatus::ERROR;
523  }
524  if (sizeof(parameterId) != static_cast<FwSizeType>(readSize)) {
525  this->log_WARNING_HI_PrmFileReadError(PrmReadError::PARAMETER_ID_SIZE, static_cast<I32>(recordNumTotal),
526  static_cast<I32>(readSize));
527  return PrmLoadStatus::ERROR;
528  }
529 
530  // set serialized size to read parameter ID
531  desStat = buff.setBuffLen(static_cast<Fw::Serializable::SizeType>(readSize));
532  // should never fail
533  FW_ASSERT(Fw::FW_SERIALIZE_OK == desStat, static_cast<FwAssertArgType>(desStat));
534  // reset deserialization
535  buff.resetDeser();
536  // deserialize, since parameter ID is serialized in file
537  desStat = buff.deserializeTo(parameterId);
538  FW_ASSERT(Fw::FW_SERIALIZE_OK == desStat);
539 
540  // copy parameter value from file into a temporary buffer
541  Fw::ParamBuffer tmpParamBuffer; // temporary param buffer to read parameter value from file
542  readSize = recordSize - sizeof(parameterId);
543  desStat = tmpParamBuffer.setBuffLen(static_cast<Fw::Serializable::SizeType>(readSize));
544  FW_ASSERT(Fw::FW_SERIALIZE_OK == desStat, static_cast<FwAssertArgType>(desStat)); // should never fail
545  fStat = paramFile.read(tmpParamBuffer.getBuffAddr(), readSize);
546 
547  if (fStat != Os::File::OP_OK) {
548  this->log_WARNING_HI_PrmFileReadError(PrmReadError::PARAMETER_VALUE, static_cast<I32>(recordNumTotal),
549  fStat);
550  return PrmLoadStatus::ERROR;
551  }
552  if (static_cast<U32>(readSize) != recordSize - sizeof(parameterId)) {
553  this->log_WARNING_HI_PrmFileReadError(PrmReadError::PARAMETER_VALUE_SIZE, static_cast<I32>(recordNumTotal),
554  static_cast<I32>(readSize));
555  return PrmLoadStatus::ERROR;
556  }
557 
558  // Actually update or add parameter
559  PrmUpdateType updateStatus = updateAddPrmImpl(parameterId, tmpParamBuffer, dbType);
560  if (updateStatus == PARAM_ADDED) {
561  recordNumAdded++;
562  } else if (updateStatus == PARAM_UPDATED) {
563  recordNumUpdated++;
564  }
565 
566  if (updateStatus == NO_SLOTS) {
567  this->log_WARNING_HI_PrmDbFull(parameterId);
568  }
569  recordNumTotal++;
570  }
571 
572  this->log_ACTIVITY_HI_PrmFileLoadComplete(dbString, recordNumTotal, recordNumAdded, recordNumUpdated);
573  return PrmLoadStatus::SUCCESS;
574 }
575 
576 PrmDbImpl::PrmUpdateType PrmDbImpl::updateAddPrmImpl(FwPrmIdType id, Fw::ParamBuffer& val, PrmDbType prmDbType) {
577  auto* db = getDbPtr(prmDbType);
578 
579  PrmUpdateType updateStatus = NO_SLOTS;
580 
581  this->lock();
582 
583  auto prevSize = db->getSize();
584  switch (db->insert(id, val)) {
586  updateStatus = NO_SLOTS;
587  break;
589  if (prevSize < db->getSize()) {
590  updateStatus = PARAM_ADDED;
591  } else {
592  FW_ASSERT(prevSize == db->getSize(), static_cast<FwAssertArgType>(prevSize),
593  static_cast<FwAssertArgType>(db->getSize()));
594  updateStatus = PARAM_UPDATED;
595  }
596  break;
597  default:
598  FW_ASSERT(false);
599  }
600 
601  this->unLock();
602  return updateStatus;
603 }
604 
608 
609 void PrmDbImpl::clearDb(PrmDbType prmDbType) {
610  getDbPtr(prmDbType)->clear();
611 }
612 
613 void PrmDbImpl::dbCopy(PrmDbType dest, PrmDbType src) {
614  *getDbPtr(dest) = *getDbPtr(src);
615  this->log_ACTIVITY_HI_PrmDbCopyAllComplete(getDbString(src), getDbString(dest));
616 }
617 
618 PrmDbImpl::PrmDbStore* PrmDbImpl::getDbPtr(PrmDbType dbType) {
619  FW_ASSERT(dbType == PrmDbType::DB_ACTIVE or dbType == PrmDbType::DB_STAGING);
620  if (dbType == PrmDbType::DB_ACTIVE) {
621  return m_activeDb;
622  }
623  return m_stagingDb;
624 }
625 
626 Fw::String PrmDbImpl::getDbString(PrmDbType dbType) {
627  FW_ASSERT(dbType == PrmDbType::DB_ACTIVE or dbType == PrmDbType::DB_STAGING);
628  if (dbType == PrmDbType::DB_ACTIVE) {
629  return Fw::String("ACTIVE");
630  }
631  return Fw::String("STAGING");
632 }
633 
634 } // namespace Svc
void update(const void *const data, const FwSizeType len)
Definition: HashImpl.cpp:34
Serialization/Deserialization operation was successful.
Parameter already in database, updated parameter.
Definition: PrmDbImpl.hpp:75
State of parameter DB file load operations.
U8 * getBuffAddr()
Get buffer address for data filling (non-const version)
Definition: PrmBuffer.cpp:42
FwIdType FwOpcodeType
The type of a command opcode.
Status calculateCrc(U32 &crc)
calculate the CRC32 of the entire file
Definition: File.cpp:230
Representing success.
void pingOut_out(FwIndexType portNum, U32 key) const
Invoke output port pingOut.
PlatformSizeType FwSizeType
Operation failed.
Definition: Os.hpp:28
void log_ACTIVITY_HI_PrmIdUpdated(FwPrmIdType Id) const
void readParamFile()
PrmDb file read function.
Definition: PrmDbImpl.cpp:57
StringTemplate< FW_FIXED_LENGTH_STRING_SIZE > String
Definition: String.hpp:14
FwIdType FwPrmIdType
The type of a parameter identifier.
void log_ACTIVITY_HI_PrmFileSaveComplete(U32 records) const
virtual const CHAR * toChar() const =0
Convert to a C-style char*.
Overwrite file when it exists and creation was requested.
Definition: File.hpp:59
Open file for writing.
Definition: File.hpp:35
PrmDbImpl(const char *name)
PrmDb constructor.
Definition: PrmDbImpl.cpp:42
PrmDb_PrmDbType PrmDbType
Definition: PrmDbImpl.hpp:29
void log_WARNING_HI_PrmFileWriteError(Svc::PrmDb_PrmWriteError stage, I32 record, I32 error) const
Parameter added to database.
Definition: PrmDbImpl.hpp:74
void log_ACTIVITY_HI_PrmFileLoadComplete(const Fw::StringBase &databaseString, U32 recordsTotal, U32 recordsAdded, U32 recordsUpdated) const
SerializeStatus
forward declaration for string
virtual void lock()
Lock the guarded mutex.
void log_WARNING_HI_PrmFileReadError(Svc::PrmDb_PrmReadError stage, I32 record, I32 error) const
Os::FileInterface::Status open(const char *path, Mode mode)
open file with supplied path and mode
Definition: File.cpp:43
void log_ACTIVITY_HI_PrmDbCommitComplete() const
void clear() override
Clear the map.
Definition: ArrayMap.hpp:73
void log_WARNING_LO_PrmDbFileLoadInvalidAction(Svc::PrmDb_PrmDbFileLoadState currentState, Svc::PrmDb_PrmLoadAction attemptedAction) const
Status seek(FwSignedSizeType offset, SeekType seekType) override
seek the file pointer to the given offset
Definition: File.cpp:135
virtual void unLock()
Unlock the guarded mutex.
void log_ACTIVITY_HI_PrmIdAdded(FwPrmIdType Id) const
A generic interface for creating and comparing hash values.
Definition: Hash.hpp:24
void log_ACTIVITY_HI_PrmDbCopyAllComplete(const Fw::StringBase &databaseStringSrc, const Fw::StringBase &databaseStringDest) const
const char * toChar() const
Convert to a C-style char*.
void configure(const char *file)
PrmDb configure method.
Definition: PrmDbImpl.cpp:52
Representing failure.
Command successfully executed.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:53
void log_WARNING_HI_PrmDbFull(FwPrmIdType Id) const
Status read(U8 *buffer, FwSizeType &size)
read data from this file into supplied buffer bounded by size
Definition: File.cpp:187
Auto-generated base for PrmDb component.
Command had execution error.
void log_WARNING_LO_PrmIdNotFound(FwPrmIdType Id)
Operation was successful.
Definition: File.hpp:42
Success find(const K &key, V &value) const override
Definition: ArrayMap.hpp:81
PlatformIndexType FwIndexType
Open file for reading.
Definition: File.hpp:33
void cmdResponse_out(FwOpcodeType opCode, U32 cmdSeq, Fw::CmdResponse response)
Emit command response.
Command failed validation.
RateGroupDivider component implementation.
virtual SizeType length() const
Get the length of the string.
Enum representing parameter validity.
SerializeStatus setBuffLen(Serializable::SizeType length) override
Set buffer length manually.
No slots available to add new parameter.
Definition: PrmDbImpl.hpp:73
void finalize(HashBuffer &buffer) const
Definition: HashImpl.cpp:40
virtual ~PrmDbImpl()
PrmDb destructor.
Definition: PrmDbImpl.cpp:50
#define FW_ASSERT(...)
Definition: Assert.hpp:14
Component for managing parameters.
void log_WARNING_HI_PrmFileBadCrc(U32 readCrc, U32 compCrc) const
PlatformAssertArgType FwAssertArgType
The type of arguments to assert functions.
void log_WARNING_HI_PrmDbFileLoadFailed() const