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