F´ Flight Software - C/C++ Documentation  NASA-v2.0.1
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 
9 #include <Fw/Types/Assert.hpp>
11 
12 #include <Os/File.hpp>
13 
14 #include <cstring>
15 #include <stdio.h>
16 
17 namespace Svc {
18 
19  // anonymous namespace for buffer declaration
20  namespace {
21  class WorkingBuffer : public Fw::SerializeBufferBase {
22  public:
23 
24  NATIVE_UINT_TYPE getBuffCapacity(void) const {
25  return sizeof(m_buff);
26  }
27 
28  U8* getBuffAddr(void) {
29  return m_buff;
30  }
31 
32  const U8* getBuffAddr(void) const {
33  return m_buff;
34  }
35 
36  private:
37  // Set to max of parameter buffer + id
38  U8 m_buff[FW_PARAM_BUFFER_MAX_SIZE + sizeof(FwPrmIdType)];
39  };
40  }
41 
42  PrmDbImpl::PrmDbImpl(const char* name, const char* file) : PrmDbComponentBase(name) {
43  this->clearDb();
44  this->m_fileName = file;
45  }
46 
47  void PrmDbImpl::init(NATIVE_INT_TYPE queueDepth, NATIVE_INT_TYPE instance) {
48  PrmDbComponentBase::init(queueDepth,instance);
49  }
50 
51  void PrmDbImpl::clearDb(void) {
52  for (I32 entry = 0; entry < PRMDB_NUM_DB_ENTRIES; entry++) {
53  this->m_db[entry].used = false;
54  this->m_db[entry].id = 0;
55  }
56  }
57 
58  // If ports are no longer guarded, these accesses need to be protected from each other
59  // If there are a lot of accesses, perhaps an interrupt lock could be used instead of guarded ports
60 
61  Fw::ParamValid PrmDbImpl::getPrm_handler(NATIVE_INT_TYPE portNum, FwPrmIdType id, Fw::ParamBuffer &val) {
62  // search for entry
63  Fw::ParamValid stat = Fw::PARAM_INVALID;
64 
65  for (I32 entry = 0; entry < PRMDB_NUM_DB_ENTRIES; entry++) {
66  if (this->m_db[entry].used) {
67  if (this->m_db[entry].id == id) {
68  val = this->m_db[entry].val;
69  stat = Fw::PARAM_VALID;
70  break;
71  }
72  }
73  }
74 
75  // if unable to find parameter, send error message
76  if (Fw::PARAM_INVALID == stat) {
77  this->log_WARNING_LO_PrmIdNotFound(id);
78  }
79 
80  return stat;
81  }
82 
83  void PrmDbImpl::setPrm_handler(NATIVE_INT_TYPE portNum, FwPrmIdType id, Fw::ParamBuffer &val) {
84 
85  this->lock();
86 
87  // search for existing entry
88 
89  bool existingEntry = false;
90  bool noSlots = true;
91 
92  for (NATIVE_INT_TYPE entry = 0; entry < PRMDB_NUM_DB_ENTRIES; entry++) {
93  if ((this->m_db[entry].used) && (id == this->m_db[entry].id)) {
94  this->m_db[entry].val = val;
95  existingEntry = true;
96  break;
97  }
98  }
99 
100  // if there is no existing entry, add one
101  if (!existingEntry) {
102  for (I32 entry = 0; entry < PRMDB_NUM_DB_ENTRIES; entry++) {
103  if (!(this->m_db[entry].used)) {
104  this->m_db[entry].val = val;
105  this->m_db[entry].id = id;
106  this->m_db[entry].used = true;
107  noSlots = false;
108  break;
109  }
110  }
111  }
112 
113  this->unLock();
114 
115  if (existingEntry) {
116  this->log_ACTIVITY_HI_PrmIdUpdated(id);
117  } else if (noSlots) {
118  this->log_FATAL_PrmDbFull(id);
119  } else {
120  this->log_ACTIVITY_HI_PrmIdAdded(id);
121  }
122 
123  }
124 
125  void PrmDbImpl::PRM_SAVE_FILE_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
126 
127  Os::File paramFile;
128  WorkingBuffer buff;
129 
130  Os::File::Status stat = paramFile.open(this->m_fileName.toChar(),Os::File::OPEN_WRITE);
131  if (stat != Os::File::OP_OK) {
132  this->log_WARNING_HI_PrmFileWriteError(PRM_WRITE_OPEN,0,stat);
133  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_EXECUTION_ERROR);
134  return;
135  }
136 
137  this->lock();
138 
139  // Traverse the parameter list, saving each entry
140 
141  U32 numRecords = 0;
142 
143  for (NATIVE_UINT_TYPE entry = 0; entry < FW_NUM_ARRAY_ELEMENTS(this->m_db); entry++) {
144  if (this->m_db[entry].used) {
145  // write delimiter
146  static const U8 delim = PRMDB_ENTRY_DELIMITER;
147  NATIVE_INT_TYPE writeSize = sizeof(delim);
148  stat = paramFile.write(&delim,writeSize,true);
149  if (stat != Os::File::OP_OK) {
150  this->unLock();
151  this->log_WARNING_HI_PrmFileWriteError(PRM_WRITE_DELIMITER,numRecords,stat);
152  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_EXECUTION_ERROR);
153  return;
154  }
155  if (writeSize != sizeof(delim)) {
156  this->unLock();
157  this->log_WARNING_HI_PrmFileWriteError(PRM_WRITE_DELIMITER_SIZE,numRecords,writeSize);
158  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_EXECUTION_ERROR);
159  return;
160  }
161  // serialize record size = id field + data
162  U32 recordSize = sizeof(FwPrmIdType) + this->m_db[entry].val.getBuffLength();
163 
164  // reset buffer
165  buff.resetSer();
166  Fw::SerializeStatus serStat = buff.serialize(recordSize);
167  // should always work
168  FW_ASSERT(Fw::FW_SERIALIZE_OK == serStat,(NATIVE_INT_TYPE)serStat);
169 
170  // write record size
171  writeSize = buff.getBuffLength();
172  stat = paramFile.write(buff.getBuffAddr(),writeSize,true);
173  if (stat != Os::File::OP_OK) {
174  this->unLock();
175  this->log_WARNING_HI_PrmFileWriteError(PRM_WRITE_RECORD_SIZE,numRecords,stat);
176  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_EXECUTION_ERROR);
177  return;
178  }
179  if (writeSize != sizeof(writeSize)) {
180  this->unLock();
181  this->log_WARNING_HI_PrmFileWriteError(PRM_WRITE_RECORD_SIZE_SIZE,numRecords,writeSize);
182  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_EXECUTION_ERROR);
183  return;
184  }
185 
186  // reset buffer
187  buff.resetSer();
188 
189  // serialize parameter id
190 
191  serStat = buff.serialize(this->m_db[entry].id);
192  // should always work
193  FW_ASSERT(Fw::FW_SERIALIZE_OK == serStat,(NATIVE_INT_TYPE)serStat);
194 
195  // write parameter ID
196  writeSize = buff.getBuffLength();
197  stat = paramFile.write(buff.getBuffAddr(),writeSize,true);
198  if (stat != Os::File::OP_OK) {
199  this->unLock();
200  this->log_WARNING_HI_PrmFileWriteError(PRM_WRITE_PARAMETER_ID,numRecords,stat);
201  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_EXECUTION_ERROR);
202  return;
203  }
204  if (writeSize != (NATIVE_INT_TYPE)buff.getBuffLength()) {
205  this->unLock();
206  this->log_WARNING_HI_PrmFileWriteError(PRM_WRITE_PARAMETER_ID_SIZE,numRecords,writeSize);
207  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_EXECUTION_ERROR);
208  return;
209  }
210 
211  // write serialized parameter value
212 
213  writeSize = this->m_db[entry].val.getBuffLength();
214  stat = paramFile.write(this->m_db[entry].val.getBuffAddr(),writeSize,true);
215  if (stat != Os::File::OP_OK) {
216  this->unLock();
217  this->log_WARNING_HI_PrmFileWriteError(PRM_WRITE_PARAMETER_VALUE,numRecords,stat);
218  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_EXECUTION_ERROR);
219  return;
220  }
221  if (writeSize != (NATIVE_INT_TYPE)this->m_db[entry].val.getBuffLength()) {
222  this->unLock();
223  this->log_WARNING_HI_PrmFileWriteError(PRM_WRITE_PARAMETER_VALUE_SIZE,numRecords,writeSize);
224  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_EXECUTION_ERROR);
225  return;
226  }
227  numRecords++;
228  } // end if record in use
229  } // end for each record
230 
231  this->unLock();
232  this->log_ACTIVITY_HI_PrmFileSaveComplete(numRecords);
233  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_OK);
234 
235  }
236 
238  }
239 
241  // load file. FIXME: Put more robust file checking, such as a CRC.
242  Os::File paramFile;
243 
244  Os::File::Status stat = paramFile.open(this->m_fileName.toChar(),Os::File::OPEN_READ);
245  if (stat != Os::File::OP_OK) {
246  this->log_WARNING_HI_PrmFileReadError(PRM_READ_OPEN,0,stat);
247  return;
248  }
249 
250  WorkingBuffer buff;
251 
252  U32 recordNum = 0;
253 
254  this->clearDb();
255 
256  for (NATIVE_INT_TYPE entry = 0; entry < PRMDB_NUM_DB_ENTRIES; entry++) {
257 
258  U8 delimiter;
259  NATIVE_INT_TYPE readSize = sizeof(delimiter);
260 
261  // read delimiter
262  Os::File::Status fStat = paramFile.read(&delimiter,readSize,true);
263 
264  // check for end of file (read size 0)
265  if (0 == readSize) {
266  break;
267  }
268 
269  if (fStat != Os::File::OP_OK) {
270  this->log_WARNING_HI_PrmFileReadError(PRM_READ_DELIMITER,recordNum,fStat);
271  return;
272  }
273 
274  if (sizeof(delimiter) != readSize) {
275  this->log_WARNING_HI_PrmFileReadError(PRM_READ_DELIMITER_SIZE,recordNum,readSize);
276  return;
277  }
278 
279  if (PRMDB_ENTRY_DELIMITER != delimiter) {
280  this->log_WARNING_HI_PrmFileReadError(PRM_READ_DELIMITER_VALUE,recordNum,delimiter);
281  return;
282  }
283 
284  U32 recordSize = 0;
285  // read record size
286  readSize = sizeof(recordSize);
287 
288  fStat = paramFile.read(buff.getBuffAddr(),readSize,true);
289  if (fStat != Os::File::OP_OK) {
290  this->log_WARNING_HI_PrmFileReadError(PRM_READ_RECORD_SIZE,recordNum,fStat);
291  return;
292  }
293  if (sizeof(recordSize) != readSize) {
294  this->log_WARNING_HI_PrmFileReadError(PRM_READ_RECORD_SIZE_SIZE,recordNum,readSize);
295  return;
296  }
297  // set serialized size to read size
298  Fw::SerializeStatus desStat = buff.setBuffLen(readSize);
299  // should never fail
300  FW_ASSERT(Fw::FW_SERIALIZE_OK == desStat,(NATIVE_INT_TYPE)desStat);
301  // reset deserialization
302  buff.resetDeser();
303  // deserialize, since record size is serialized in file
304  FW_ASSERT(Fw::FW_SERIALIZE_OK == buff.deserialize(recordSize));
305 
306  // sanity check value. It can't be larger than the maximum parameter buffer size + id
307  // or smaller than the record id
308  if ((recordSize > FW_PARAM_BUFFER_MAX_SIZE + sizeof(U32)) or (recordSize < sizeof(U32))) {
309  this->log_WARNING_HI_PrmFileReadError(PRM_READ_RECORD_SIZE_VALUE,recordNum,recordSize);
310  return;
311  }
312 
313  // read the parameter ID
314  FwPrmIdType parameterId = 0;
315  readSize = sizeof(FwPrmIdType);
316 
317  fStat = paramFile.read(buff.getBuffAddr(),readSize,true);
318  if (fStat != Os::File::OP_OK) {
319  this->log_WARNING_HI_PrmFileReadError(PRM_READ_PARAMETER_ID,recordNum,fStat);
320  return;
321  }
322  if (sizeof(parameterId) != static_cast<NATIVE_INT_TYPE>(readSize)) {
323  this->log_WARNING_HI_PrmFileReadError(PRM_READ_PARAMETER_ID_SIZE,recordNum,readSize);
324  return;
325  }
326 
327  // set serialized size to read parameter ID
328  desStat = buff.setBuffLen(readSize);
329  // should never fail
330  FW_ASSERT(Fw::FW_SERIALIZE_OK == desStat,(NATIVE_INT_TYPE)desStat);
331  // reset deserialization
332  buff.resetDeser();
333  // deserialize, since parameter ID is serialized in file
334  FW_ASSERT(Fw::FW_SERIALIZE_OK == buff.deserialize(parameterId));
335 
336  // copy parameter
337  this->m_db[entry].used = true;
338  this->m_db[entry].id = parameterId;
339  readSize = recordSize-sizeof(parameterId);
340 
341  fStat = paramFile.read(this->m_db[entry].val.getBuffAddr(),readSize);
342 
343  if (fStat != Os::File::OP_OK) {
344  this->log_WARNING_HI_PrmFileReadError(PRM_READ_PARAMETER_VALUE,recordNum,fStat);
345  return;
346  }
347  if (static_cast<U32>(readSize) != recordSize-sizeof(parameterId)) {
348  this->log_WARNING_HI_PrmFileReadError(PRM_READ_PARAMETER_VALUE_SIZE,recordNum,readSize);
349  return;
350  }
351 
352  // set serialized size to read size
353  desStat = this->m_db[entry].val.setBuffLen(readSize);
354  // should never fail
355  FW_ASSERT(Fw::FW_SERIALIZE_OK == desStat,(NATIVE_INT_TYPE)desStat);
356  recordNum++;
357 
358  }
359 
360  this->log_ACTIVITY_HI_PrmFileLoadComplete(recordNum);
361  }
362 
363  void PrmDbImpl::pingIn_handler(NATIVE_INT_TYPE portNum, U32 key) {
364  // respond to ping
365  this->pingOut_out(0,key);
366  }
367 
368 
369 
370 }
Fw::EightyCharString::toChar
const char * toChar(void) const
gets char buffer
Definition: EightyCharString.cpp:34
Fw::SerializeBufferBase
Definition: Serializable.hpp:43
Fw::SerializeStatus
SerializeStatus
forward declaration for string
Definition: Serializable.hpp:14
FW_NUM_ARRAY_ELEMENTS
#define FW_NUM_ARRAY_ELEMENTS(a)
number of elements in an array
Definition: BasicTypes.hpp:103
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
Svc::PrmDbImpl::readParamFile
void readParamFile(void)
PrmDb file read function.
Definition: PrmDbImpl.cpp:240
Fw::ParamBuffer::getBuffAddr
U8 * getBuffAddr(void)
gets buffer address for data filling
Definition: PrmBuffer.cpp:36
Assert.hpp
Fw::FW_SERIALIZE_OK
@ FW_SERIALIZE_OK
Serialization/Deserialization operation was successful.
Definition: Serializable.hpp:15
Svc::PrmDbImpl::~PrmDbImpl
virtual ~PrmDbImpl()
PrmDb destructor.
Definition: PrmDbImpl.cpp:237
Os::File::write
Status write(const void *buffer, NATIVE_INT_TYPE &size, bool waitForDone=true)
write size; will return amount written or errno
Definition: File.cpp:33
EightyCharString.hpp
FW_PARAM_BUFFER_MAX_SIZE
#define FW_PARAM_BUFFER_MAX_SIZE
Definition: FpConfig.hpp:266
FwOpcodeType
#define FwOpcodeType
Type representation for a command opcode.
Definition: FpConfig.hpp:62
Os::File::OPEN_WRITE
@ OPEN_WRITE
Open file for writing.
Definition: File.hpp:17
NATIVE_UINT_TYPE
unsigned int NATIVE_UINT_TYPE
native unsigned integer type declaration
Definition: BasicTypes.hpp:30
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:9
Os::File::open
Status open(const char *fileName, Mode mode)
open file. Writing creates file if it doesn't exist
Definition: File.cpp:13
Fw::SerializeBufferBase::getBuffLength
NATIVE_UINT_TYPE getBuffLength() const
returns current buffer size
Definition: Serializable.cpp:587
Fw::ParamBuffer
Definition: PrmBuffer.hpp:22
Svc::PrmDbImpl::PrmDbImpl
PrmDbImpl(const char *name, const char *file)
PrmDb constructor.
Definition: PrmDbImpl.cpp:42
File.hpp
Svc
Definition: ActiveRateGroupImplCfg.hpp:18
Os::File::Status
Status
Definition: File.hpp:24
FwPrmIdType
#define FwPrmIdType
Type representation for a parameter id.
Definition: FpConfig.hpp:74
PrmDbImpl.hpp
Component for managing parameters.
Os::File::OP_OK
@ OP_OK
Operation was successful.
Definition: File.hpp:25
Svc::PrmDbImpl::init
void init(NATIVE_INT_TYPE queueDepth, NATIVE_INT_TYPE instance)
PrmDb initialization function.
Definition: PrmDbImpl.cpp:47
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
Os::File
Definition: File.hpp:11