GCC Code Coverage Report


Directory: Svc/PrmDb/
File: PrmDbImpl.cpp
Date: 2026-09-03 21:18:19
Exec Total Coverage
Lines: 333 358 93.0%
Functions: 19 20 95.0%
Branches: 345 394 87.6%

Line Branch Exec Source
1 /*
2 * PrmDbImpl.cpp
3 *
4 * Created on: March 9, 2015
5 * Author: Timothy Canham
6 */
7
8 #include <Fw/Types/Assert.hpp>
9 #include <Svc/PrmDb/PrmDbImpl.hpp>
10
11 #include <Os/File.hpp>
12 #include <Os/SandboxedFile.hpp>
13 #include <Utils/Hash/Hash.hpp>
14
15 #include <cstdio>
16 #include <cstring>
17
18 static_assert(std::numeric_limits<FwSizeType>::max() >= PRMDB_NUM_DB_ENTRIES,
19 "PRMDB_NUM_DB_ENTRIES must fit within range of FwSizeType");
20
21 namespace Svc {
22
23 // anonymous namespace for buffer declaration
24 namespace {
25 class WorkingBuffer : public Fw::LinearBufferBase {
26 public:
27 46 WorkingBuffer() : Fw::LinearBufferBase(m_buff, sizeof(m_buff)) {}
28
29 private:
30 // Set to max of parameter buffer + id
31 U8 m_buff[FW_PARAM_BUFFER_MAX_SIZE + sizeof(FwPrmIdType)];
32 static_assert(sizeof(m_buff) >= sizeof(U32), "Size of parameter buffer storage must be >= sizeof(U32)");
33 };
34 } // namespace
35
36 //! ----------------------------------------------------------------------
37 //! Construction, initialization, and destruction
38 //! ----------------------------------------------------------------------
39
5/5
✓ Branch 10 taken 14 times.
✓ Branch 16 taken 14 times.
✓ Branch 22 taken 14 times.
✓ Branch 28 taken 14 times.
✓ Branch 34 taken 14 times.
14 PrmDbImpl::PrmDbImpl(const char* name) : PrmDbComponentBase(name), m_state(PrmDbFileLoadState::IDLE) {
40 14 this->m_activeDb = &this->m_dbStore1;
41 14 this->m_stagingDb = &this->m_dbStore2;
42
43
2/2
✓ Branch 5 taken 14 times.
✓ Branch 8 taken 14 times.
14 this->clearDb(PrmDbType::DB_ACTIVE);
44
2/2
✓ Branch 5 taken 14 times.
✓ Branch 8 taken 14 times.
14 this->clearDb(PrmDbType::DB_STAGING);
45 14 }
46
47 28 PrmDbImpl::~PrmDbImpl() {}
48
49 14 void PrmDbImpl::configure(const char* file) {
50 14 FW_ASSERT(file != nullptr);
51 14 this->m_fileName = file;
52 14 }
53
54 1 void PrmDbImpl::configureLoadSandbox(const char* directory) {
55 1 FW_ASSERT(directory != nullptr);
56 1 this->m_sandboxDir = directory;
57 1 }
58
59 23 void PrmDbImpl::readParamFile() {
60 // Assumed to run at initialization time
61 // State should be IDLE upon entry
62 23 FW_ASSERT(static_cast<FwAssertArgType>(m_state == PrmDbFileLoadState::IDLE));
63
64 // Clear databases
65
2/2
✓ Branch 5 taken 23 times.
✓ Branch 8 taken 23 times.
23 this->clearDb(PrmDbType::DB_ACTIVE);
66
2/2
✓ Branch 5 taken 23 times.
✓ Branch 8 taken 23 times.
23 this->clearDb(PrmDbType::DB_STAGING);
67
68 // Read parameter file to active database
69
2/2
✓ Branch 5 taken 23 times.
✓ Branch 11 taken 23 times.
23 (void)readParamFileImpl(this->m_fileName, PrmDbType::DB_ACTIVE);
70 23 }
71
72 //! ----------------------------------------------------------------------
73 //! Port & Command Handlers
74 //! ----------------------------------------------------------------------
75
76 // If ports are no longer guarded, these accesses need to be protected from each other
77 // If there are a lot of accesses, perhaps an interrupt lock could be used instead of guarded ports
78
79 31 Fw::ParamValid PrmDbImpl::getPrm_handler(FwIndexType portNum, FwPrmIdType id, Fw::ParamBuffer& val) {
80 // search for entry
81
1/1
✓ Branch 7 taken 31 times.
31 auto success = this->m_activeDb->find(id, val);
82
83
3/5
✗ Branch 2 not taken.
✓ Branch 3 taken 31 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 28 times.
✗ Branch 6 not taken.
31 switch (success.e) {
84 3 case Fw::Success::FAILURE:
85 // if unable to find parameter, send error message
86
1/1
✓ Branch 5 taken 3 times.
3 this->log_WARNING_LO_PrmIdNotFound(id);
87
1/1
✓ Branch 1 taken 3 times.
3 return Fw::ParamValid::INVALID;
88 28 case Fw::Success::SUCCESS:
89
1/1
✓ Branch 1 taken 28 times.
28 return Fw::ParamValid::VALID;
90 default:
91 FW_ASSERT(false, success.e);
92 return Fw::ParamValid::INVALID;
93 }
94 31 }
95
96 59 void PrmDbImpl::setPrm_handler(FwIndexType portNum, FwPrmIdType id, Fw::ParamBuffer& val) {
97 // Reject parameter updates during non-idle file load states
98
2/2
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 57 times.
59 if (m_state != PrmDbFileLoadState::IDLE) {
99
2/2
✓ Branch 6 taken 2 times.
✓ Branch 13 taken 2 times.
2 this->log_WARNING_LO_PrmDbFileLoadInvalidAction(m_state, PrmDb_PrmLoadAction::SET_PARAMETER);
100 2 return;
101 }
102
103 // Update the parameter in the active database
104
2/2
✓ Branch 5 taken 57 times.
✓ Branch 8 taken 57 times.
57 PrmUpdateType update_status = updateAddPrmImpl(id, val, PrmDbType::DB_ACTIVE);
105
106 // Issue relevant EVR
107
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 49 times.
57 if (update_status == PARAM_UPDATED) {
108 8 this->log_ACTIVITY_HI_PrmIdUpdated(id);
109
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 48 times.
49 } else if (update_status == NO_SLOTS) {
110 1 this->log_WARNING_HI_PrmDbFull(id);
111 } else {
112 48 this->log_ACTIVITY_HI_PrmIdAdded(id);
113 }
114 }
115
116 void PrmDbImpl::pingIn_handler(FwIndexType portNum, U32 key) {
117 // respond to ping
118 this->pingOut_out(0, key);
119 }
120
121 24 void PrmDbImpl::PRM_SAVE_FILE_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
122 // Reject PRM_SAVE_FILE command during non-idle file load states
123
2/2
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 22 times.
24 if (m_state != PrmDbFileLoadState::IDLE) {
124
2/2
✓ Branch 6 taken 2 times.
✓ Branch 13 taken 2 times.
2 this->log_WARNING_LO_PrmDbFileLoadInvalidAction(m_state, PrmDb_PrmLoadAction::SAVE_FILE_COMMAND);
125
2/2
✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
2 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::BUSY);
126 2 return;
127 }
128
129 22 FW_ASSERT(this->m_fileName.length() > 0);
130
131
1/1
✓ Branch 2 taken 22 times.
22 Os::File paramFile;
132
1/1
✓ Branch 2 taken 22 times.
22 WorkingBuffer buff;
133
134
1/1
✓ Branch 8 taken 22 times.
22 Os::File::Status stat = paramFile.open(this->m_fileName.toChar(), Os::File::OPEN_WRITE, Os::File::OVERWRITE);
135
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 21 times.
22 if (stat != Os::File::OP_OK) {
136
2/2
✓ Branch 6 taken 1 times.
✓ Branch 10 taken 1 times.
1 this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::OPEN, 0, stat);
137
2/2
✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
1 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
138 1 return;
139 }
140
141 // write placeholder for the CRC
142
1/1
✓ Branch 2 taken 21 times.
21 Utils::Hash crc;
143 21 U32 crcInitial = 0xFFFFFFFF;
144
1/1
✓ Branch 2 taken 21 times.
21 buff.resetSer();
145
1/1
✓ Branch 2 taken 21 times.
21 Fw::SerializeStatus serStat = buff.serializeFrom(crcInitial);
146 21 FW_ASSERT(Fw::FW_SERIALIZE_OK == serStat, static_cast<FwAssertArgType>(serStat));
147
1/1
✓ Branch 3 taken 21 times.
21 FwSizeType writeSize = static_cast<FwSizeType>(buff.getSize());
148
1/1
✓ Branch 4 taken 21 times.
21 stat = paramFile.write(buff.getBuffAddr(), writeSize, Os::File::WaitType::WAIT);
149
150
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 19 times.
21 if (stat != Os::File::OP_OK) {
151
2/2
✓ Branch 6 taken 2 times.
✓ Branch 10 taken 2 times.
2 this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::CRC_PLACE, 0, stat);
152
2/2
✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
2 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
153 2 return;
154 }
155
156
1/1
✓ Branch 5 taken 19 times.
19 this->lock();
157
2/2
✓ Branch 5 taken 19 times.
✓ Branch 8 taken 19 times.
19 auto db = getDbPtr(PrmDbType::DB_ACTIVE);
158 19 FW_ASSERT(db != nullptr);
159
160 // Traverse the parameter list, saving each entry
161
162 19 U32 numRecords = 0;
163
164
6/6
✓ Branch 3 taken 19 times.
✓ Branch 7 taken 19 times.
✓ Branch 10 taken 26 times.
✓ Branch 14 taken 33 times.
✓ Branch 16 taken 26 times.
✓ Branch 17 taken 7 times.
33 for (const auto& entry : *db) {
165 // write delimiter
166 static const U8 delim = PRMDB_ENTRY_DELIMITER;
167 26 writeSize = static_cast<FwSizeType>(sizeof(delim));
168
1/1
✓ Branch 2 taken 26 times.
26 stat = paramFile.write(&delim, writeSize, Os::File::WaitType::WAIT);
169
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 24 times.
26 if (stat != Os::File::OP_OK) {
170
1/1
✓ Branch 5 taken 2 times.
2 this->unLock();
171
2/2
✓ Branch 6 taken 2 times.
✓ Branch 10 taken 2 times.
2 this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::DELIMITER, static_cast<I32>(numRecords), stat);
172
2/2
✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
2 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
173 2 return;
174 }
175
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 23 times.
24 if (writeSize != sizeof(delim)) {
176
1/1
✓ Branch 5 taken 1 times.
1 this->unLock();
177
2/2
✓ Branch 6 taken 1 times.
✓ Branch 10 taken 1 times.
1 this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::DELIMITER_SIZE, static_cast<I32>(numRecords),
178 static_cast<I32>(writeSize));
179
2/2
✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
1 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
180 1 return;
181 }
182
183 // add delimiter to CRC
184
1/1
✓ Branch 1 taken 23 times.
23 crc.update(&delim, sizeof(delim));
185
186 // serialize record size = id field + data
187
2/2
✓ Branch 7 taken 23 times.
✓ Branch 14 taken 23 times.
23 U32 recordSize = static_cast<U32>(sizeof(FwPrmIdType) + entry.getValue().getSize());
188
189 // reset buffer
190
1/1
✓ Branch 2 taken 23 times.
23 buff.resetSer();
191
1/1
✓ Branch 2 taken 23 times.
23 serStat = buff.serializeFrom(recordSize);
192 // should always work
193 23 FW_ASSERT(Fw::FW_SERIALIZE_OK == serStat, static_cast<FwAssertArgType>(serStat));
194
195 // write record size
196
1/1
✓ Branch 2 taken 23 times.
23 writeSize = static_cast<FwSizeType>(buff.getSize());
197
1/1
✓ Branch 4 taken 23 times.
23 stat = paramFile.write(buff.getBuffAddr(), writeSize, Os::File::WaitType::WAIT);
198
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 21 times.
23 if (stat != Os::File::OP_OK) {
199
1/1
✓ Branch 5 taken 2 times.
2 this->unLock();
200
2/2
✓ Branch 6 taken 2 times.
✓ Branch 10 taken 2 times.
2 this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::RECORD_SIZE, static_cast<I32>(numRecords), stat);
201
2/2
✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
2 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
202 2 return;
203 }
204
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 20 times.
21 if (writeSize != sizeof(recordSize)) {
205
1/1
✓ Branch 5 taken 1 times.
1 this->unLock();
206
2/2
✓ Branch 6 taken 1 times.
✓ Branch 10 taken 1 times.
1 this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::RECORD_SIZE_SIZE, static_cast<I32>(numRecords),
207 static_cast<I32>(writeSize));
208
2/2
✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
1 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
209 1 return;
210 }
211
212 // add recordSize to CRC
213
3/6
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
20 if (buff.getBuffAddr() != nullptr && writeSize != 0) {
214
1/1
✓ Branch 3 taken 20 times.
20 crc.update(buff.getBuffAddr(), writeSize);
215 }
216
217 // reset buffer
218
1/1
✓ Branch 2 taken 20 times.
20 buff.resetSer();
219
220 // serialize parameter id
221
222
2/2
✓ Branch 8 taken 20 times.
✓ Branch 12 taken 20 times.
20 serStat = buff.serializeFrom(entry.getKey());
223 // should always work
224 20 FW_ASSERT(Fw::FW_SERIALIZE_OK == serStat, static_cast<FwAssertArgType>(serStat));
225
226 // write parameter ID
227
1/1
✓ Branch 2 taken 20 times.
20 writeSize = static_cast<FwSizeType>(buff.getSize());
228
1/1
✓ Branch 4 taken 20 times.
20 stat = paramFile.write(buff.getBuffAddr(), writeSize, Os::File::WaitType::WAIT);
229
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 18 times.
20 if (stat != Os::File::OP_OK) {
230
1/1
✓ Branch 5 taken 2 times.
2 this->unLock();
231
2/2
✓ Branch 6 taken 2 times.
✓ Branch 10 taken 2 times.
2 this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::PARAMETER_ID, static_cast<I32>(numRecords), stat);
232
2/2
✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
2 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
233 2 return;
234 }
235
3/3
✓ Branch 2 taken 18 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 17 times.
18 if (writeSize != static_cast<FwSizeType>(buff.getSize())) {
236
1/1
✓ Branch 5 taken 1 times.
1 this->unLock();
237
2/2
✓ Branch 6 taken 1 times.
✓ Branch 10 taken 1 times.
1 this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::PARAMETER_ID_SIZE, static_cast<I32>(numRecords),
238 static_cast<I32>(writeSize));
239
2/2
✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
1 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
240 1 return;
241 }
242
243 // add parameter ID to CRC
244
3/6
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 17 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 17 times.
✗ Branch 7 not taken.
17 if (buff.getBuffAddr() != nullptr && writeSize != 0) {
245
1/1
✓ Branch 3 taken 17 times.
17 crc.update(buff.getBuffAddr(), writeSize);
246 }
247
248 // write serialized parameter value
249
250
2/2
✓ Branch 7 taken 17 times.
✓ Branch 14 taken 17 times.
17 writeSize = static_cast<FwSizeType>(entry.getValue().getSize());
251
2/2
✓ Branch 8 taken 17 times.
✓ Branch 16 taken 17 times.
17 stat = paramFile.write(entry.getValue().getBuffAddr(), writeSize, Os::File::WaitType::WAIT);
252
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 15 times.
17 if (stat != Os::File::OP_OK) {
253
1/1
✓ Branch 5 taken 2 times.
2 this->unLock();
254
2/2
✓ Branch 6 taken 2 times.
✓ Branch 10 taken 2 times.
2 this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::PARAMETER_VALUE, static_cast<I32>(numRecords), stat);
255
2/2
✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
2 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
256 2 return;
257 }
258
4/4
✓ Branch 7 taken 15 times.
✓ Branch 14 taken 15 times.
✓ Branch 16 taken 1 times.
✓ Branch 17 taken 14 times.
15 if (writeSize != static_cast<FwSizeType>(entry.getValue().getSize())) {
259
1/1
✓ Branch 5 taken 1 times.
1 this->unLock();
260
2/2
✓ Branch 6 taken 1 times.
✓ Branch 10 taken 1 times.
1 this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::PARAMETER_VALUE_SIZE, static_cast<I32>(numRecords),
261 static_cast<I32>(writeSize));
262
2/2
✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
1 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
263 1 return;
264 }
265
266 // add serialized parameter value to crc
267
4/7
✓ Branch 7 taken 14 times.
✓ Branch 14 taken 14 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 14 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 14 times.
✗ Branch 19 not taken.
14 if (entry.getValue().getBuffAddr() != nullptr && writeSize != 0) {
268
2/2
✓ Branch 7 taken 14 times.
✓ Branch 15 taken 14 times.
14 crc.update(entry.getValue().getBuffAddr(), writeSize);
269 }
270
271
1/1
✓ Branch 1 taken 14 times.
14 numRecords++;
272 31 }
273
274
1/1
✓ Branch 5 taken 7 times.
7 this->unLock();
275
276 // save current location of pointer in paramFile
277 7 FwSizeType currPosInParamFile;
278
279
1/1
✓ Branch 2 taken 7 times.
7 stat = paramFile.position(currPosInParamFile);
280
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (stat != Os::File::OP_OK) {
281 this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::CURR_POSITION, 0, stat);
282 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
283 return;
284 }
285
286 // seek to beginning and write CRC value
287
1/1
✓ Branch 2 taken 7 times.
7 stat = paramFile.seek(0, Os::File::SeekType::ABSOLUTE);
288
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (stat != Os::File::OP_OK) {
289 this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::SEEK_ZERO, 0, stat);
290 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
291 return;
292 }
293
1/1
✓ Branch 2 taken 7 times.
7 buff.resetSer();
294 7 U32 crcFinal = 0;
295
1/1
✓ Branch 1 taken 7 times.
7 crc.finalize(crcFinal);
296 7 crcFinal = ~crcFinal;
297
1/1
✓ Branch 2 taken 7 times.
7 serStat = buff.serializeFrom(crcFinal);
298
299 7 FW_ASSERT(Fw::FW_SERIALIZE_OK == serStat, static_cast<FwAssertArgType>(serStat));
300
1/1
✓ Branch 2 taken 7 times.
7 writeSize = static_cast<FwSizeType>(buff.getSize());
301
302
1/1
✓ Branch 4 taken 7 times.
7 stat = paramFile.write(buff.getBuffAddr(), writeSize, Os::File::WaitType::WAIT);
303
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (stat != Os::File::OP_OK) {
304 this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::CRC_REAL, 0, stat);
305 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
306 return;
307 }
308
309 // Restore pointer to previously saved location
310
1/1
✓ Branch 2 taken 7 times.
7 stat = paramFile.seek(static_cast<FwSignedSizeType>(currPosInParamFile), Os::File::SeekType::ABSOLUTE);
311
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (stat != Os::File::OP_OK) {
312 this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::SEEK_POSITION, 0, stat);
313 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
314 return;
315 }
316
317
1/1
✓ Branch 5 taken 7 times.
7 this->log_ACTIVITY_HI_PrmFileSaveComplete(numRecords);
318
2/2
✓ Branch 6 taken 7 times.
✓ Branch 9 taken 7 times.
7 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
319 51 }
320
321 6 void PrmDbImpl::PRM_LOAD_FILE_cmdHandler(FwOpcodeType opCode,
322 U32 cmdSeq,
323 const Fw::CmdStringArg& fileName,
324 const PrmDb_Merge& merge) {
325 // Reject PRM_LOAD_FILE command during non-idle file load states
326
2/2
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 4 times.
6 if (m_state != PrmDbFileLoadState::IDLE) {
327
2/2
✓ Branch 6 taken 2 times.
✓ Branch 13 taken 2 times.
2 this->log_WARNING_LO_PrmDbFileLoadInvalidAction(m_state, PrmDb_PrmLoadAction::LOAD_FILE_COMMAND);
328
2/2
✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
2 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::BUSY);
329 2 return;
330 }
331
332 // Set state to loading
333 4 m_state = PrmDbFileLoadState::LOADING_FILE_UPDATES;
334
335 // If reset is true, clear the staging database first
336
2/2
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
4 if (merge == PrmDb_Merge::MERGE) {
337 // Copy active to staging for merging
338
3/3
✓ Branch 5 taken 2 times.
✓ Branch 9 taken 2 times.
✓ Branch 12 taken 2 times.
2 dbCopy(PrmDbType::DB_STAGING, PrmDbType::DB_ACTIVE);
339 } else {
340 // reset staging db, all file contents will be loaded but no old parameters will be retained
341
2/2
✓ Branch 5 taken 2 times.
✓ Branch 8 taken 2 times.
2 this->clearDb(PrmDbType::DB_STAGING);
342 }
343
344 // Load the file into staging database
345 // The readParamFileImpl will emit the relevant EVR if the file load fails
346 // and also if it succeeds will emit EVRs with the number of records
347
2/2
✓ Branch 5 taken 4 times.
✓ Branch 11 taken 4 times.
4 PrmDbImpl::PrmLoadStatus success = PrmDbImpl::readParamFileImpl(fileName, PrmDbType::DB_STAGING);
348
349
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (success == PrmLoadStatus::SUCCESS) {
350
2/2
✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
1 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
351 1 m_state = PrmDbFileLoadState::FILE_UPDATES_STAGED;
352 } else {
353 3 this->log_WARNING_HI_PrmDbFileLoadFailed();
354 // clear the staging DB and reset to an IDLE state in case of issues
355
2/2
✓ Branch 5 taken 3 times.
✓ Branch 8 taken 3 times.
3 this->clearDb(PrmDbType::DB_STAGING);
356 3 m_state = PrmDbFileLoadState::IDLE;
357
2/2
✓ Branch 6 taken 3 times.
✓ Branch 9 taken 3 times.
3 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
358 }
359 }
360
361 5 void PrmDbImpl::PRM_COMMIT_STAGED_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
362 // Verify we are in the correct state
363
2/2
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 2 times.
5 if (m_state != PrmDbFileLoadState::FILE_UPDATES_STAGED) {
364
2/2
✓ Branch 6 taken 3 times.
✓ Branch 13 taken 3 times.
3 this->log_WARNING_LO_PrmDbFileLoadInvalidAction(m_state, PrmDb_PrmLoadAction::COMMIT_STAGED_COMMAND);
365
2/2
✓ Branch 6 taken 3 times.
✓ Branch 9 taken 3 times.
3 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR);
366 3 return;
367 }
368
369 // Swap active and staging databases, safely w.r.t. prmGet
370 2 this->lock();
371 2 PrmDbStore* temp = this->m_activeDb;
372 2 this->m_activeDb = this->m_stagingDb;
373 2 this->unLock();
374 2 this->m_stagingDb = temp;
375
376 // Clear the new staging database
377
2/2
✓ Branch 5 taken 2 times.
✓ Branch 8 taken 2 times.
2 this->clearDb(PrmDbType::DB_STAGING);
378
379 // Set file load state to idle
380 2 m_state = PrmDbFileLoadState::IDLE;
381
382 2 this->log_ACTIVITY_HI_PrmDbCommitComplete();
383
2/2
✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
2 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
384 }
385
386 //! ----------------------------------------------------------------------
387 //! Helpers for construction/destruction, init, & handlers
388 //! ----------------------------------------------------------------------
389
390 27 PrmDbImpl::PrmLoadStatus PrmDbImpl::readParamFileImpl(const Fw::StringBase& fileName, PrmDbType dbType) {
391 27 FW_ASSERT(dbType == PrmDbType::DB_ACTIVE or dbType == PrmDbType::DB_STAGING);
392 27 FW_ASSERT(fileName.length() > 0);
393
394 // Commanded loads (staging) may carry a ground-supplied path; restrict them
395 // to the configured sandbox directory to prevent path traversal
396
7/7
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 23 times.
✓ Branch 11 taken 4 times.
✓ Branch 13 taken 2 times.
✓ Branch 14 taken 2 times.
✓ Branch 15 taken 2 times.
✓ Branch 16 taken 25 times.
27 if ((dbType == PrmDbType::DB_STAGING) && (this->m_sandboxDir.length() > 0)) {
397
1/1
✓ Branch 2 taken 2 times.
2 Os::SandboxedFile paramFile;
398
1/1
✓ Branch 7 taken 2 times.
2 paramFile.configure(this->m_sandboxDir.toChar());
399
2/2
✓ Branch 5 taken 2 times.
✓ Branch 8 taken 2 times.
2 return this->readParamFileWork(paramFile, fileName, dbType);
400 2 }
401
1/1
✓ Branch 2 taken 25 times.
25 Os::File paramFile;
402
2/2
✓ Branch 5 taken 25 times.
✓ Branch 8 taken 25 times.
25 return this->readParamFileWork(paramFile, fileName, dbType);
403 25 }
404
405 template <typename FileType>
406 54 PrmDbImpl::PrmLoadStatus PrmDbImpl::readParamFileWork(FileType& paramFile,
407 const Fw::StringBase& fileName,
408 PrmDbType dbType) {
409
2/2
✓ Branch 3 taken 27 times.
✓ Branch 6 taken 27 times.
54 Fw::String dbString = getDbString(dbType);
410
411
3/3
✓ Branch 12 taken 2 times.
✓ Branch 14 taken 25 times.
✓ Branch 17 taken 25 times.
54 Os::File::Status stat = paramFile.open(fileName.toChar(), Os::File::OPEN_READ);
412
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 24 times.
54 if (stat != Os::File::OP_OK) {
413
2/2
✓ Branch 6 taken 3 times.
✓ Branch 10 taken 3 times.
6 this->log_WARNING_HI_PrmFileReadError(PrmReadError::OPEN, 0, stat);
414 6 return PrmLoadStatus::ERROR;
415 }
416 //===========================================================================
417 // read CRC from beginning of file
418
1/1
✓ Branch 2 taken 24 times.
48 WorkingBuffer buff;
419 48 U32 fileCrc;
420 48 FwSizeType readSize = static_cast<FwSizeType>(sizeof(fileCrc));
421
422 // Read raw CRC bytes from file
423
1/2
✗ Branch 4 not taken.
✓ Branch 6 taken 24 times.
48 stat = paramFile.read(buff.getBuffAddr(), readSize);
424
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 22 times.
48 if (stat != Os::File::OP_OK) {
425
2/2
✓ Branch 6 taken 2 times.
✓ Branch 10 taken 2 times.
4 this->log_WARNING_HI_PrmFileReadError(PrmReadError::CRC, static_cast<I32>(0), stat);
426 4 return PrmLoadStatus::ERROR;
427 }
428
429
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 21 times.
44 if (readSize != sizeof(fileCrc)) {
430
2/2
✓ Branch 6 taken 1 times.
✓ Branch 10 taken 1 times.
2 this->log_WARNING_HI_PrmFileReadError(PrmReadError::CRC_SIZE, static_cast<I32>(0), static_cast<I32>(readSize));
431 2 return PrmLoadStatus::ERROR;
432 }
433
434 // Deserialize the CRC in a portable way
435
1/1
✓ Branch 2 taken 21 times.
42 Fw::SerializeStatus serStat = buff.setBuffLen(readSize);
436 42 FW_ASSERT(Fw::FW_SERIALIZE_OK == serStat, static_cast<FwAssertArgType>(serStat));
437
1/1
✓ Branch 2 taken 21 times.
42 buff.resetDeser();
438
1/1
✓ Branch 2 taken 21 times.
42 serStat = buff.deserializeTo(fileCrc);
439 42 FW_ASSERT(Fw::FW_SERIALIZE_OK == serStat, static_cast<FwAssertArgType>(serStat));
440
441 42 U32 crc = 0xFFFFFFFF;
442 // read into CRC buffer for checking
443
444
1/2
✗ Branch 2 not taken.
✓ Branch 4 taken 21 times.
42 Os::File::Status status = paramFile.calculateCrc(crc);
445
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 19 times.
42 if (status != Os::File::OP_OK) {
446
2/2
✓ Branch 6 taken 2 times.
✓ Branch 10 taken 2 times.
4 this->log_WARNING_HI_PrmFileReadError(PrmReadError::CRC_BUFFER, static_cast<I32>(0), status);
447 4 return PrmLoadStatus::ERROR;
448 }
449
450
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 18 times.
38 if (fileCrc != crc) {
451
1/1
✓ Branch 5 taken 1 times.
2 this->log_WARNING_HI_PrmFileBadCrc(fileCrc, crc);
452 2 return PrmLoadStatus::ERROR;
453 }
454
455 // seek back to just after CRC
456
1/2
✗ Branch 2 not taken.
✓ Branch 4 taken 18 times.
36 stat = paramFile.seek(sizeof(fileCrc), Os::File::SeekType::ABSOLUTE);
457
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
36 if (stat != Os::File::OP_OK) {
458 this->log_WARNING_HI_PrmFileReadError(PrmReadError::SEEK_ZERO, 0, stat);
459 return PrmLoadStatus::ERROR;
460 }
461 //===========================================================================
462
463 36 U32 recordNumTotal = 0;
464 36 U32 recordNumAdded = 0;
465 36 U32 recordNumUpdated = 0;
466 36 U32 recordNumDropped = 0;
467
468
3/4
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 25 times.
✗ Branch 5 not taken.
70 for (FwSizeType entry = 0; entry < PRMDB_NUM_DB_ENTRIES; entry++) {
469 50 U8 delimiter;
470 50 readSize = static_cast<FwSizeType>(sizeof(delimiter));
471
472 // read delimiter
473
1/2
✗ Branch 2 not taken.
✓ Branch 4 taken 25 times.
50 Os::File::Status fStat = paramFile.read(&delimiter, readSize, Os::File::WaitType::WAIT);
474
475 // check for end of file (successful read of size 0); a failed read can
476 // also yield size 0 and must not be mistaken for a clean EOF
477
4/4
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 19 times.
50 if ((Os::File::OP_OK == fStat) && (0 == readSize)) {
478 8 break;
479 }
480
481
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 19 times.
42 if (fStat != Os::File::OP_OK) {
482
2/2
✓ Branch 6 taken 2 times.
✓ Branch 10 taken 2 times.
4 this->log_WARNING_HI_PrmFileReadError(PrmReadError::DELIMITER, static_cast<I32>(recordNumTotal), fStat);
483 4 return PrmLoadStatus::ERROR;
484 }
485
486
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 18 times.
38 if (sizeof(delimiter) != readSize) {
487
2/2
✓ Branch 6 taken 1 times.
✓ Branch 10 taken 1 times.
2 this->log_WARNING_HI_PrmFileReadError(PrmReadError::DELIMITER_SIZE, static_cast<I32>(recordNumTotal),
488 static_cast<I32>(readSize));
489 2 return PrmLoadStatus::ERROR;
490 }
491
492
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 17 times.
36 if (PRMDB_ENTRY_DELIMITER != delimiter) {
493
2/2
✓ Branch 6 taken 1 times.
✓ Branch 10 taken 1 times.
2 this->log_WARNING_HI_PrmFileReadError(PrmReadError::DELIMITER_VALUE, static_cast<I32>(recordNumTotal),
494 delimiter);
495 2 return PrmLoadStatus::ERROR;
496 }
497
498 34 U32 recordSize = 0;
499
500 // read record size
501 34 readSize = sizeof(recordSize);
502
503
1/2
✗ Branch 4 not taken.
✓ Branch 6 taken 17 times.
34 fStat = paramFile.read(buff.getBuffAddr(), readSize, Os::File::WaitType::WAIT);
504
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 15 times.
34 if (fStat != Os::File::OP_OK) {
505
2/2
✓ Branch 6 taken 2 times.
✓ Branch 10 taken 2 times.
4 this->log_WARNING_HI_PrmFileReadError(PrmReadError::RECORD_SIZE, static_cast<I32>(recordNumTotal), fStat);
506 4 return PrmLoadStatus::ERROR;
507 }
508
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 14 times.
30 if (sizeof(recordSize) != readSize) {
509
2/2
✓ Branch 6 taken 1 times.
✓ Branch 10 taken 1 times.
2 this->log_WARNING_HI_PrmFileReadError(PrmReadError::RECORD_SIZE_SIZE, static_cast<I32>(recordNumTotal),
510 static_cast<I32>(readSize));
511 2 return PrmLoadStatus::ERROR;
512 }
513 // set serialized size to read size
514
1/1
✓ Branch 2 taken 14 times.
28 Fw::SerializeStatus desStat = buff.setBuffLen(static_cast<Fw::Serializable::SizeType>(readSize));
515 // should never fail
516 28 FW_ASSERT(Fw::FW_SERIALIZE_OK == desStat, static_cast<FwAssertArgType>(desStat));
517 // reset deserialization
518
1/1
✓ Branch 2 taken 14 times.
28 buff.resetDeser();
519 // deserialize, since record size is serialized in file
520
1/1
✓ Branch 2 taken 14 times.
28 desStat = buff.deserializeTo(recordSize);
521 28 FW_ASSERT(Fw::FW_SERIALIZE_OK == desStat);
522
523 // sanity check value. It can't be larger than the maximum parameter buffer size + id
524 // or smaller than the record id
525
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
28 if ((recordSize > FW_PARAM_BUFFER_MAX_SIZE + sizeof(FwPrmIdType)) or (recordSize < sizeof(FwPrmIdType))) {
526
2/2
✓ Branch 6 taken 1 times.
✓ Branch 10 taken 1 times.
2 this->log_WARNING_HI_PrmFileReadError(PrmReadError::RECORD_SIZE_VALUE, static_cast<I32>(recordNumTotal),
527 static_cast<I32>(recordSize));
528 2 return PrmLoadStatus::ERROR;
529 }
530
531 // read the parameter ID
532 26 FwPrmIdType parameterId = 0;
533 26 readSize = static_cast<FwSizeType>(sizeof(FwPrmIdType));
534
535
1/2
✗ Branch 4 not taken.
✓ Branch 6 taken 13 times.
26 fStat = paramFile.read(buff.getBuffAddr(), readSize, Os::File::WaitType::WAIT);
536
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 11 times.
26 if (fStat != Os::File::OP_OK) {
537
2/2
✓ Branch 6 taken 2 times.
✓ Branch 10 taken 2 times.
4 this->log_WARNING_HI_PrmFileReadError(PrmReadError::PARAMETER_ID, static_cast<I32>(recordNumTotal), fStat);
538 4 return PrmLoadStatus::ERROR;
539 }
540
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 10 times.
22 if (sizeof(parameterId) != static_cast<FwSizeType>(readSize)) {
541
2/2
✓ Branch 6 taken 1 times.
✓ Branch 10 taken 1 times.
2 this->log_WARNING_HI_PrmFileReadError(PrmReadError::PARAMETER_ID_SIZE, static_cast<I32>(recordNumTotal),
542 static_cast<I32>(readSize));
543 2 return PrmLoadStatus::ERROR;
544 }
545
546 // set serialized size to read parameter ID
547
1/1
✓ Branch 2 taken 10 times.
20 desStat = buff.setBuffLen(static_cast<Fw::Serializable::SizeType>(readSize));
548 // should never fail
549 20 FW_ASSERT(Fw::FW_SERIALIZE_OK == desStat, static_cast<FwAssertArgType>(desStat));
550 // reset deserialization
551
1/1
✓ Branch 2 taken 10 times.
20 buff.resetDeser();
552 // deserialize, since parameter ID is serialized in file
553
1/1
✓ Branch 2 taken 10 times.
20 desStat = buff.deserializeTo(parameterId);
554 20 FW_ASSERT(Fw::FW_SERIALIZE_OK == desStat);
555
556 // copy parameter value from file into a temporary buffer
557
1/1
✓ Branch 2 taken 10 times.
20 Fw::ParamBuffer tmpParamBuffer; // temporary param buffer to read parameter value from file
558 20 readSize = recordSize - sizeof(parameterId);
559
1/1
✓ Branch 2 taken 10 times.
20 desStat = tmpParamBuffer.setBuffLen(static_cast<Fw::Serializable::SizeType>(readSize));
560 20 FW_ASSERT(Fw::FW_SERIALIZE_OK == desStat, static_cast<FwAssertArgType>(desStat)); // should never fail
561
1/2
✗ Branch 4 not taken.
✓ Branch 6 taken 10 times.
20 fStat = paramFile.read(tmpParamBuffer.getBuffAddr(), readSize);
562
563
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
20 if (fStat != Os::File::OP_OK) {
564
2/2
✓ Branch 6 taken 2 times.
✓ Branch 10 taken 2 times.
4 this->log_WARNING_HI_PrmFileReadError(PrmReadError::PARAMETER_VALUE, static_cast<I32>(recordNumTotal),
565 fStat);
566 4 return PrmLoadStatus::ERROR;
567 }
568
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
16 if (static_cast<U32>(readSize) != recordSize - sizeof(parameterId)) {
569
2/2
✓ Branch 6 taken 1 times.
✓ Branch 10 taken 1 times.
2 this->log_WARNING_HI_PrmFileReadError(PrmReadError::PARAMETER_VALUE_SIZE, static_cast<I32>(recordNumTotal),
570 static_cast<I32>(readSize));
571 2 return PrmLoadStatus::ERROR;
572 }
573
574 // Actually update or add parameter
575
2/2
✓ Branch 5 taken 7 times.
✓ Branch 8 taken 7 times.
14 PrmUpdateType updateStatus = updateAddPrmImpl(parameterId, tmpParamBuffer, dbType);
576
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
14 if (updateStatus == PARAM_ADDED) {
577 12 recordNumAdded++;
578
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 } else if (updateStatus == PARAM_UPDATED) {
579 2 recordNumUpdated++;
580 }
581
582
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
14 if (updateStatus == NO_SLOTS) {
583 this->log_WARNING_HI_PrmDbFull(parameterId);
584 recordNumDropped++;
585 }
586 14 recordNumTotal++;
587 }
588
589 // Dropped records mean the database does not reflect the file: report an error
590
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
8 if (recordNumDropped > 0) {
591 return PrmLoadStatus::ERROR;
592 }
593
594
1/1
✓ Branch 5 taken 4 times.
8 this->log_ACTIVITY_HI_PrmFileLoadComplete(dbString, recordNumTotal, recordNumAdded, recordNumUpdated);
595 8 return PrmLoadStatus::SUCCESS;
596 54 }
597
598 81 PrmDbImpl::PrmUpdateType PrmDbImpl::updateAddPrmImpl(FwPrmIdType id, Fw::ParamBuffer& val, PrmDbType prmDbType) {
599
2/2
✓ Branch 5 taken 81 times.
✓ Branch 8 taken 81 times.
81 auto* db = getDbPtr(prmDbType);
600
601 81 PrmUpdateType updateStatus = NO_SLOTS;
602
603 81 this->lock();
604
605 81 auto prevSize = db->getSize();
606
3/4
✓ Branch 3 taken 81 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 80 times.
✗ Branch 14 not taken.
81 switch (db->insert(id, val)) {
607 1 case Fw::Success::FAILURE:
608 1 updateStatus = NO_SLOTS;
609 1 break;
610 80 case Fw::Success::SUCCESS:
611
2/2
✓ Branch 4 taken 69 times.
✓ Branch 5 taken 11 times.
80 if (prevSize < db->getSize()) {
612 69 updateStatus = PARAM_ADDED;
613 } else {
614 11 FW_ASSERT(prevSize == db->getSize(), static_cast<FwAssertArgType>(prevSize),
615 static_cast<FwAssertArgType>(db->getSize()));
616 11 updateStatus = PARAM_UPDATED;
617 }
618 80 break;
619 default:
620 FW_ASSERT(false);
621 }
622
623 81 this->unLock();
624 81 return updateStatus;
625 }
626
627 //! ----------------------------------------------------------------------
628 //! Helpers for database management
629 //! ----------------------------------------------------------------------
630
631 106 void PrmDbImpl::clearDb(PrmDbType prmDbType) {
632
3/3
✓ Branch 5 taken 106 times.
✓ Branch 8 taken 106 times.
✓ Branch 14 taken 106 times.
106 getDbPtr(prmDbType)->clear();
633 106 }
634
635 3 void PrmDbImpl::dbCopy(PrmDbType dest, PrmDbType src) {
636
5/5
✓ Branch 5 taken 3 times.
✓ Branch 8 taken 3 times.
✓ Branch 16 taken 3 times.
✓ Branch 19 taken 3 times.
✓ Branch 25 taken 3 times.
3 *getDbPtr(dest) = *getDbPtr(src);
637
5/5
✓ Branch 7 taken 3 times.
✓ Branch 10 taken 3 times.
✓ Branch 16 taken 3 times.
✓ Branch 19 taken 3 times.
✓ Branch 23 taken 3 times.
3 this->log_ACTIVITY_HI_PrmDbCopyAllComplete(getDbString(src), getDbString(dest));
638 3 }
639
640 228 PrmDbImpl::PrmDbStore* PrmDbImpl::getDbPtr(PrmDbType dbType) {
641 228 FW_ASSERT(dbType == PrmDbType::DB_ACTIVE or dbType == PrmDbType::DB_STAGING);
642
2/2
✓ Branch 3 taken 158 times.
✓ Branch 4 taken 70 times.
228 if (dbType == PrmDbType::DB_ACTIVE) {
643 158 return m_activeDb;
644 }
645 70 return m_stagingDb;
646 }
647
648 49 Fw::String PrmDbImpl::getDbString(PrmDbType dbType) {
649 49 FW_ASSERT(dbType == PrmDbType::DB_ACTIVE or dbType == PrmDbType::DB_STAGING);
650
2/2
✓ Branch 3 taken 34 times.
✓ Branch 4 taken 15 times.
49 if (dbType == PrmDbType::DB_ACTIVE) {
651 34 return Fw::String("ACTIVE");
652 }
653 15 return Fw::String("STAGING");
654 }
655
656 } // namespace Svc
657