1 #include "config.h"
2
3 #include "manager.hpp"
4
5 #include "constants.hpp"
6 #include "exceptions.hpp"
7 #include "logger.hpp"
8 #include "parser.hpp"
9 #include "parser_factory.hpp"
10 #include "parser_interface.hpp"
11 #include "single_fab.hpp"
12 #include "types.hpp"
13 #include "utility/dbus_utility.hpp"
14 #include "utility/json_utility.hpp"
15 #include "utility/vpd_specific_utility.hpp"
16
17 #include <boost/asio/steady_timer.hpp>
18 #include <sdbusplus/bus/match.hpp>
19 #include <sdbusplus/message.hpp>
20
21 namespace vpd
22 {
Manager(const std::shared_ptr<boost::asio::io_context> & ioCon,const std::shared_ptr<sdbusplus::asio::dbus_interface> & iFace,const std::shared_ptr<sdbusplus::asio::connection> & asioConnection)23 Manager::Manager(
24 const std::shared_ptr<boost::asio::io_context>& ioCon,
25 const std::shared_ptr<sdbusplus::asio::dbus_interface>& iFace,
26 const std::shared_ptr<sdbusplus::asio::connection>& asioConnection) :
27 m_ioContext(ioCon), m_interface(iFace), m_asioConnection(asioConnection)
28 {
29 #ifdef IBM_SYSTEM
30 if (!dbusUtility::isChassisPowerOn())
31 {
32 SingleFab l_singleFab;
33 const int& l_rc = l_singleFab.singleFabImOverride();
34
35 if (l_rc == constants::FAILURE)
36 {
37 throw std::runtime_error(
38 std::string(__FUNCTION__) +
39 " : Found an invalid system configuration. Needs manual intervention. BMC is being quiesced.");
40 }
41 }
42 #endif
43
44 try
45 {
46 // For backward compatibility. Should be depricated.
47 iFace->register_method(
48 "WriteKeyword",
49 [this](const sdbusplus::message::object_path i_path,
50 const std::string i_recordName, const std::string i_keyword,
51 const types::BinaryVector i_value) -> int {
52 return this->updateKeyword(
53 i_path, std::make_tuple(i_recordName, i_keyword, i_value));
54 });
55
56 // Register methods under com.ibm.VPD.Manager interface
57 iFace->register_method(
58 "UpdateKeyword",
59 [this](const types::Path i_vpdPath,
60 const types::WriteVpdParams i_paramsToWriteData) -> int {
61 return this->updateKeyword(i_vpdPath, i_paramsToWriteData);
62 });
63
64 iFace->register_method(
65 "WriteKeywordOnHardware",
66 [this](const types::Path i_fruPath,
67 const types::WriteVpdParams i_paramsToWriteData) -> int {
68 return this->updateKeywordOnHardware(i_fruPath,
69 i_paramsToWriteData);
70 });
71
72 iFace->register_method(
73 "ReadKeyword",
74 [this](const types::Path i_fruPath,
75 const types::ReadVpdParams i_paramsToReadData)
76 -> types::DbusVariantType {
77 return this->readKeyword(i_fruPath, i_paramsToReadData);
78 });
79
80 iFace->register_method(
81 "CollectFRUVPD",
82 [this](const sdbusplus::message::object_path& i_dbusObjPath) {
83 this->collectSingleFruVpd(i_dbusObjPath);
84 });
85
86 iFace->register_method(
87 "deleteFRUVPD",
88 [this](const sdbusplus::message::object_path& i_dbusObjPath) {
89 this->deleteSingleFruVpd(i_dbusObjPath);
90 });
91
92 iFace->register_method(
93 "GetExpandedLocationCode",
94 [this](const std::string& i_unexpandedLocationCode,
95 uint16_t& i_nodeNumber) -> std::string {
96 return this->getExpandedLocationCode(i_unexpandedLocationCode,
97 i_nodeNumber);
98 });
99
100 iFace->register_method("GetFRUsByExpandedLocationCode",
101 [this](const std::string& i_expandedLocationCode)
102 -> types::ListOfPaths {
103 return this->getFrusByExpandedLocationCode(
104 i_expandedLocationCode);
105 });
106
107 iFace->register_method(
108 "GetFRUsByUnexpandedLocationCode",
109 [this](const std::string& i_unexpandedLocationCode,
110 uint16_t& i_nodeNumber) -> types::ListOfPaths {
111 return this->getFrusByUnexpandedLocationCode(
112 i_unexpandedLocationCode, i_nodeNumber);
113 });
114
115 iFace->register_method(
116 "GetHardwarePath",
117 [this](const sdbusplus::message::object_path& i_dbusObjPath)
118 -> std::string { return this->getHwPath(i_dbusObjPath); });
119
120 iFace->register_method("PerformVPDRecollection", [this]() {
121 this->performVpdRecollection();
122 });
123
124 iFace->register_method("CollectAllFRUVPD", [this]() -> bool {
125 return this->collectAllFruVpd();
126 });
127
128 // Indicates FRU VPD collection for the system has not started.
129 iFace->register_property_rw<std::string>(
130 "CollectionStatus", sdbusplus::vtable::property_::emits_change,
131 [this](const std::string& l_currStatus, const auto&) {
132 if (m_vpdCollectionStatus != l_currStatus)
133 {
134 m_vpdCollectionStatus = l_currStatus;
135 m_interface->signal_property("CollectionStatus");
136 }
137 return true;
138 },
139 [this](const auto&) { return m_vpdCollectionStatus; });
140
141 // If required, instantiate OEM specific handler here.
142 #ifdef IBM_SYSTEM
143 m_ibmHandler = std::make_shared<IbmHandler>(
144 m_worker, m_backupAndRestoreObj, m_interface, m_ioContext,
145 m_asioConnection);
146 #else
147 m_worker = std::make_shared<Worker>(INVENTORY_JSON_DEFAULT);
148 m_interface->set_property("CollectionStatus", std::string("Completed"));
149 #endif
150 }
151 catch (const std::exception& e)
152 {
153 logging::logMessage(
154 "Manager class instantiation failed. " + std::string(e.what()));
155
156 vpd::EventLogger::createSyncPel(
157 vpd::EventLogger::getErrorType(e), vpd::types::SeverityType::Error,
158 __FILE__, __FUNCTION__, 0, vpd::EventLogger::getErrorMsg(e),
159 std::nullopt, std::nullopt, std::nullopt, std::nullopt);
160 }
161 }
162
updateKeyword(const types::Path i_vpdPath,const types::WriteVpdParams i_paramsToWriteData)163 int Manager::updateKeyword(const types::Path i_vpdPath,
164 const types::WriteVpdParams i_paramsToWriteData)
165 {
166 if (i_vpdPath.empty())
167 {
168 logging::logMessage("Given VPD path is empty.");
169 return -1;
170 }
171
172 types::Path l_fruPath;
173 nlohmann::json l_sysCfgJsonObj{};
174
175 if (m_worker.get() != nullptr)
176 {
177 l_sysCfgJsonObj = m_worker->getSysCfgJsonObj();
178
179 // Get the EEPROM path
180 if (!l_sysCfgJsonObj.empty())
181 {
182 l_fruPath =
183 jsonUtility::getFruPathFromJson(l_sysCfgJsonObj, i_vpdPath);
184 }
185 }
186
187 if (l_fruPath.empty())
188 {
189 l_fruPath = i_vpdPath;
190 }
191
192 try
193 {
194 std::shared_ptr<Parser> l_parserObj =
195 std::make_shared<Parser>(l_fruPath, l_sysCfgJsonObj);
196 auto l_rc = l_parserObj->updateVpdKeyword(i_paramsToWriteData);
197
198 if (l_rc != constants::FAILURE && m_backupAndRestoreObj)
199 {
200 if (m_backupAndRestoreObj->updateKeywordOnPrimaryOrBackupPath(
201 l_fruPath, i_paramsToWriteData) < constants::VALUE_0)
202 {
203 logging::logMessage(
204 "Write success, but backup and restore failed for file[" +
205 l_fruPath + "]");
206 }
207 }
208
209 // update keyword in inherited FRUs
210 if (l_rc != constants::FAILURE)
211 {
212 vpdSpecificUtility::updateKwdOnInheritedFrus(
213 l_fruPath, i_paramsToWriteData, l_sysCfgJsonObj);
214 }
215
216 // update common interface(s) properties
217 if (l_rc != constants::FAILURE)
218 {
219 vpdSpecificUtility::updateCiPropertyOfInheritedFrus(
220 l_fruPath, i_paramsToWriteData, l_sysCfgJsonObj);
221 }
222
223 return l_rc;
224 }
225 catch (const std::exception& l_exception)
226 {
227 // TODO:: error log needed
228 logging::logMessage("Update keyword failed for file[" + i_vpdPath +
229 "], reason: " + std::string(l_exception.what()));
230 return -1;
231 }
232 }
233
updateKeywordOnHardware(const types::Path i_fruPath,const types::WriteVpdParams i_paramsToWriteData)234 int Manager::updateKeywordOnHardware(
235 const types::Path i_fruPath,
236 const types::WriteVpdParams i_paramsToWriteData) noexcept
237 {
238 try
239 {
240 if (i_fruPath.empty())
241 {
242 throw std::runtime_error("Given FRU path is empty");
243 }
244
245 nlohmann::json l_sysCfgJsonObj{};
246
247 if (m_worker.get() != nullptr)
248 {
249 l_sysCfgJsonObj = m_worker->getSysCfgJsonObj();
250 }
251
252 std::shared_ptr<Parser> l_parserObj =
253 std::make_shared<Parser>(i_fruPath, l_sysCfgJsonObj);
254 return l_parserObj->updateVpdKeywordOnHardware(i_paramsToWriteData);
255 }
256 catch (const std::exception& l_exception)
257 {
258 EventLogger::createAsyncPel(
259 types::ErrorType::InvalidEeprom, types::SeverityType::Informational,
260 __FILE__, __FUNCTION__, 0,
261 "Update keyword on hardware failed for file[" + i_fruPath +
262 "], reason: " + std::string(l_exception.what()),
263 std::nullopt, std::nullopt, std::nullopt, std::nullopt);
264
265 return constants::FAILURE;
266 }
267 }
268
readKeyword(const types::Path i_fruPath,const types::ReadVpdParams i_paramsToReadData)269 types::DbusVariantType Manager::readKeyword(
270 const types::Path i_fruPath, const types::ReadVpdParams i_paramsToReadData)
271 {
272 try
273 {
274 nlohmann::json l_jsonObj{};
275
276 if (m_worker.get() != nullptr)
277 {
278 l_jsonObj = m_worker->getSysCfgJsonObj();
279 }
280
281 std::error_code ec;
282
283 // Check if given path is filesystem path
284 if (!std::filesystem::exists(i_fruPath, ec) && (ec))
285 {
286 throw std::runtime_error(
287 "Given file path " + i_fruPath + " not found.");
288 }
289
290 logging::logMessage("Performing VPD read on " + i_fruPath);
291
292 std::shared_ptr<vpd::Parser> l_parserObj =
293 std::make_shared<vpd::Parser>(i_fruPath, l_jsonObj);
294
295 std::shared_ptr<vpd::ParserInterface> l_vpdParserInstance =
296 l_parserObj->getVpdParserInstance();
297
298 return (
299 l_vpdParserInstance->readKeywordFromHardware(i_paramsToReadData));
300 }
301 catch (const std::exception& e)
302 {
303 logging::logMessage(
304 e.what() + std::string(". VPD manager read operation failed for ") +
305 i_fruPath);
306 throw types::DeviceError::ReadFailure();
307 }
308 }
309
collectSingleFruVpd(const sdbusplus::message::object_path & i_dbusObjPath)310 void Manager::collectSingleFruVpd(
311 const sdbusplus::message::object_path& i_dbusObjPath)
312 {
313 if (m_vpdCollectionStatus != "Completed")
314 {
315 logging::logMessage(
316 "Currently VPD CollectionStatus is not completed. Cannot perform single FRU VPD collection for " +
317 std::string(i_dbusObjPath));
318 return;
319 }
320
321 if (m_worker.get() != nullptr)
322 {
323 m_worker->collectSingleFruVpd(i_dbusObjPath);
324 }
325 }
326
deleteSingleFruVpd(const sdbusplus::message::object_path & i_dbusObjPath)327 void Manager::deleteSingleFruVpd(
328 const sdbusplus::message::object_path& i_dbusObjPath)
329 {
330 try
331 {
332 if (std::string(i_dbusObjPath).empty())
333 {
334 throw std::runtime_error(
335 "Given DBus object path is empty. Aborting FRU VPD deletion.");
336 }
337
338 if (m_worker.get() == nullptr)
339 {
340 throw std::runtime_error(
341 "Worker object not found, can't perform FRU VPD deletion for: " +
342 std::string(i_dbusObjPath));
343 }
344
345 m_worker->deleteFruVpd(std::string(i_dbusObjPath));
346 }
347 catch (const std::exception& l_ex)
348 {
349 // TODO: Log PEL
350 logging::logMessage(l_ex.what());
351 }
352 }
353
isValidUnexpandedLocationCode(const std::string & i_unexpandedLocationCode)354 bool Manager::isValidUnexpandedLocationCode(
355 const std::string& i_unexpandedLocationCode)
356 {
357 if ((i_unexpandedLocationCode.length() <
358 constants::UNEXP_LOCATION_CODE_MIN_LENGTH) ||
359 ((i_unexpandedLocationCode.compare(0, 4, "Ufcs") !=
360 constants::STR_CMP_SUCCESS) &&
361 (i_unexpandedLocationCode.compare(0, 4, "Umts") !=
362 constants::STR_CMP_SUCCESS)) ||
363 ((i_unexpandedLocationCode.length() >
364 constants::UNEXP_LOCATION_CODE_MIN_LENGTH) &&
365 (i_unexpandedLocationCode.find("-") != 4)))
366 {
367 return false;
368 }
369
370 return true;
371 }
372
getExpandedLocationCode(const std::string & i_unexpandedLocationCode,const uint16_t i_nodeNumber)373 std::string Manager::getExpandedLocationCode(
374 const std::string& i_unexpandedLocationCode,
375 [[maybe_unused]] const uint16_t i_nodeNumber)
376 {
377 if (!isValidUnexpandedLocationCode(i_unexpandedLocationCode))
378 {
379 phosphor::logging::elog<types::DbusInvalidArgument>(
380 types::InvalidArgument::ARGUMENT_NAME("LOCATIONCODE"),
381 types::InvalidArgument::ARGUMENT_VALUE(
382 i_unexpandedLocationCode.c_str()));
383 }
384
385 const nlohmann::json& l_sysCfgJsonObj = m_worker->getSysCfgJsonObj();
386 if (!l_sysCfgJsonObj.contains("frus"))
387 {
388 logging::logMessage("Missing frus tag in system config JSON");
389 }
390
391 const nlohmann::json& l_listOfFrus =
392 l_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();
393
394 for (const auto& l_frus : l_listOfFrus.items())
395 {
396 for (const auto& l_aFru : l_frus.value())
397 {
398 if (l_aFru["extraInterfaces"].contains(
399 constants::locationCodeInf) &&
400 l_aFru["extraInterfaces"][constants::locationCodeInf].value(
401 "LocationCode", "") == i_unexpandedLocationCode)
402 {
403 return std::get<std::string>(dbusUtility::readDbusProperty(
404 l_aFru["serviceName"], l_aFru["inventoryPath"],
405 constants::locationCodeInf, "LocationCode"));
406 }
407 }
408 }
409 phosphor::logging::elog<types::DbusInvalidArgument>(
410 types::InvalidArgument::ARGUMENT_NAME("LOCATIONCODE"),
411 types::InvalidArgument::ARGUMENT_VALUE(
412 i_unexpandedLocationCode.c_str()));
413 }
414
getFrusByUnexpandedLocationCode(const std::string & i_unexpandedLocationCode,const uint16_t i_nodeNumber)415 types::ListOfPaths Manager::getFrusByUnexpandedLocationCode(
416 const std::string& i_unexpandedLocationCode,
417 [[maybe_unused]] const uint16_t i_nodeNumber)
418 {
419 types::ListOfPaths l_inventoryPaths;
420
421 if (!isValidUnexpandedLocationCode(i_unexpandedLocationCode))
422 {
423 phosphor::logging::elog<types::DbusInvalidArgument>(
424 types::InvalidArgument::ARGUMENT_NAME("LOCATIONCODE"),
425 types::InvalidArgument::ARGUMENT_VALUE(
426 i_unexpandedLocationCode.c_str()));
427 }
428
429 const nlohmann::json& l_sysCfgJsonObj = m_worker->getSysCfgJsonObj();
430 if (!l_sysCfgJsonObj.contains("frus"))
431 {
432 logging::logMessage("Missing frus tag in system config JSON");
433 }
434
435 const nlohmann::json& l_listOfFrus =
436 l_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();
437
438 for (const auto& l_frus : l_listOfFrus.items())
439 {
440 for (const auto& l_aFru : l_frus.value())
441 {
442 if (l_aFru["extraInterfaces"].contains(
443 constants::locationCodeInf) &&
444 l_aFru["extraInterfaces"][constants::locationCodeInf].value(
445 "LocationCode", "") == i_unexpandedLocationCode)
446 {
447 l_inventoryPaths.push_back(
448 l_aFru.at("inventoryPath")
449 .get_ref<const nlohmann::json::string_t&>());
450 }
451 }
452 }
453
454 if (l_inventoryPaths.empty())
455 {
456 phosphor::logging::elog<types::DbusInvalidArgument>(
457 types::InvalidArgument::ARGUMENT_NAME("LOCATIONCODE"),
458 types::InvalidArgument::ARGUMENT_VALUE(
459 i_unexpandedLocationCode.c_str()));
460 }
461
462 return l_inventoryPaths;
463 }
464
getHwPath(const sdbusplus::message::object_path & i_dbusObjPath)465 std::string Manager::getHwPath(
466 const sdbusplus::message::object_path& i_dbusObjPath)
467 {
468 // Dummy code to supress unused variable warning. To be removed.
469 logging::logMessage(std::string(i_dbusObjPath));
470
471 return std::string{};
472 }
473
getUnexpandedLocationCode(const std::string & i_expandedLocationCode)474 std::tuple<std::string, uint16_t> Manager::getUnexpandedLocationCode(
475 const std::string& i_expandedLocationCode)
476 {
477 /**
478 * Location code should always start with U and fulfil minimum length
479 * criteria.
480 */
481 if (i_expandedLocationCode[0] != 'U' ||
482 i_expandedLocationCode.length() <
483 constants::EXP_LOCATION_CODE_MIN_LENGTH)
484 {
485 phosphor::logging::elog<types::DbusInvalidArgument>(
486 types::InvalidArgument::ARGUMENT_NAME("LOCATIONCODE"),
487 types::InvalidArgument::ARGUMENT_VALUE(
488 i_expandedLocationCode.c_str()));
489 }
490
491 std::string l_fcKwd;
492
493 auto l_fcKwdValue = dbusUtility::readDbusProperty(
494 "xyz.openbmc_project.Inventory.Manager",
495 "/xyz/openbmc_project/inventory/system/chassis/motherboard",
496 "com.ibm.ipzvpd.VCEN", "FC");
497
498 if (auto l_kwdValue = std::get_if<types::BinaryVector>(&l_fcKwdValue))
499 {
500 l_fcKwd.assign(l_kwdValue->begin(), l_kwdValue->end());
501 }
502
503 // Get the first part of expanded location code to check for FC or TM.
504 std::string l_firstKwd = i_expandedLocationCode.substr(1, 4);
505
506 std::string l_unexpandedLocationCode{};
507 uint16_t l_nodeNummber = constants::INVALID_NODE_NUMBER;
508
509 // Check if this value matches the value of FC keyword.
510 if (l_fcKwd.substr(0, 4) == l_firstKwd)
511 {
512 /**
513 * Period(.) should be there in expanded location code to seggregate
514 * FC, node number and SE values.
515 */
516 size_t l_nodeStartPos = i_expandedLocationCode.find('.');
517 if (l_nodeStartPos == std::string::npos)
518 {
519 phosphor::logging::elog<types::DbusInvalidArgument>(
520 types::InvalidArgument::ARGUMENT_NAME("LOCATIONCODE"),
521 types::InvalidArgument::ARGUMENT_VALUE(
522 i_expandedLocationCode.c_str()));
523 }
524
525 size_t l_nodeEndPos =
526 i_expandedLocationCode.find('.', l_nodeStartPos + 1);
527 if (l_nodeEndPos == std::string::npos)
528 {
529 phosphor::logging::elog<types::DbusInvalidArgument>(
530 types::InvalidArgument::ARGUMENT_NAME("LOCATIONCODE"),
531 types::InvalidArgument::ARGUMENT_VALUE(
532 i_expandedLocationCode.c_str()));
533 }
534
535 // Skip 3 bytes for '.ND'
536 l_nodeNummber = std::stoi(i_expandedLocationCode.substr(
537 l_nodeStartPos + 3, (l_nodeEndPos - l_nodeStartPos - 3)));
538
539 /**
540 * Confirm if there are other details apart FC, node number and SE
541 * in location code
542 */
543 if (i_expandedLocationCode.length() >
544 constants::EXP_LOCATION_CODE_MIN_LENGTH)
545 {
546 l_unexpandedLocationCode =
547 i_expandedLocationCode[0] + std::string("fcs") +
548 i_expandedLocationCode.substr(
549 l_nodeEndPos + 1 + constants::SE_KWD_LENGTH,
550 std::string::npos);
551 }
552 else
553 {
554 l_unexpandedLocationCode = "Ufcs";
555 }
556 }
557 else
558 {
559 std::string l_tmKwd;
560 // Read TM keyword value.
561 auto l_tmKwdValue = dbusUtility::readDbusProperty(
562 "xyz.openbmc_project.Inventory.Manager",
563 "/xyz/openbmc_project/inventory/system/chassis/motherboard",
564 "com.ibm.ipzvpd.VSYS", "TM");
565
566 if (auto l_kwdValue = std::get_if<types::BinaryVector>(&l_tmKwdValue))
567 {
568 l_tmKwd.assign(l_kwdValue->begin(), l_kwdValue->end());
569 }
570
571 // Check if the substr matches to TM keyword value.
572 if (l_tmKwd.substr(0, 4) == l_firstKwd)
573 {
574 /**
575 * System location code will not have node number and any other
576 * details.
577 */
578 l_unexpandedLocationCode = "Umts";
579 }
580 // The given location code is neither "fcs" or "mts".
581 else
582 {
583 phosphor::logging::elog<types::DbusInvalidArgument>(
584 types::InvalidArgument::ARGUMENT_NAME("LOCATIONCODE"),
585 types::InvalidArgument::ARGUMENT_VALUE(
586 i_expandedLocationCode.c_str()));
587 }
588 }
589
590 return std::make_tuple(l_unexpandedLocationCode, l_nodeNummber);
591 }
592
getFrusByExpandedLocationCode(const std::string & i_expandedLocationCode)593 types::ListOfPaths Manager::getFrusByExpandedLocationCode(
594 const std::string& i_expandedLocationCode)
595 {
596 std::tuple<std::string, uint16_t> l_locationAndNodePair =
597 getUnexpandedLocationCode(i_expandedLocationCode);
598
599 return getFrusByUnexpandedLocationCode(std::get<0>(l_locationAndNodePair),
600 std::get<1>(l_locationAndNodePair));
601 }
602
performVpdRecollection()603 void Manager::performVpdRecollection()
604 {
605 if (m_worker.get() != nullptr)
606 {
607 m_worker->performVpdRecollection();
608 }
609 }
610
collectAllFruVpd() const611 bool Manager::collectAllFruVpd() const noexcept
612 {
613 try
614 {
615 types::SeverityType l_severityType;
616 if (m_vpdCollectionStatus == "NotStarted")
617 {
618 l_severityType = types::SeverityType::Informational;
619 }
620 else if (m_vpdCollectionStatus == "Completed" ||
621 m_vpdCollectionStatus == "Failure")
622 {
623 l_severityType = types::SeverityType::Warning;
624 }
625 else
626 {
627 throw std::runtime_error(
628 "Invalid collection status " + m_vpdCollectionStatus +
629 ". Aborting all FRUs VPD collection.");
630 }
631
632 EventLogger::createSyncPel(
633 types::ErrorType::FirmwareError, l_severityType, __FILE__,
634 __FUNCTION__, 0, "Collect all FRUs VPD is requested.", std::nullopt,
635 std::nullopt, std::nullopt, std::nullopt);
636
637 if (m_ibmHandler.get() != nullptr)
638 {
639 m_ibmHandler->collectAllFruVpd();
640 return true;
641 }
642 else
643 {
644 throw std::runtime_error(
645 "Not found any OEM handler to collect all FRUs VPD.");
646 }
647 }
648 catch (const std::exception& l_ex)
649 {
650 EventLogger::createSyncPel(
651 EventLogger::getErrorType(l_ex), types::SeverityType::Warning,
652 __FILE__, __FUNCTION__, 0, std::string(l_ex.what()), std::nullopt,
653 std::nullopt, std::nullopt, std::nullopt);
654 }
655 return false;
656 }
657 } // namespace vpd
658