1 #include "firmware_inventory_manager.hpp" 2 3 #include "common/types.hpp" 4 #include "common/utils.hpp" 5 6 #include <phosphor-logging/lg2.hpp> 7 8 PHOSPHOR_LOG2_USING; 9 10 namespace pldm::fw_update 11 { 12 13 void FirmwareInventoryManager::createFirmwareEntry( 14 const SoftwareIdentifier& softwareIdentifier, 15 const SoftwareName& softwareName, const std::string& activeVersion, 16 const Descriptors& descriptors, const ComponentInfo& componentInfo) 17 { 18 struct timespec ts; 19 clock_gettime(CLOCK_REALTIME, &ts); 20 unsigned seed = ts.tv_nsec ^ getpid(); 21 srandom(seed); 22 23 auto& eid = softwareIdentifier.first; 24 const auto inventoryPath = getInventoryPath(eid); 25 if (!inventoryPath) 26 { 27 error("No inventory path found for EID {EID}", "EID", eid); 28 return; 29 } 30 auto boardPath = getBoardPath(*dbusHandler, *inventoryPath); 31 32 if (!boardPath) 33 { 34 error("Failed to get board path for EID {EID}", "EID", eid); 35 return; 36 } 37 const auto boardName = boardPath->filename().string(); 38 const auto softwarePath = 39 std::format("/xyz/openbmc_project/software/{}_{}_{}", boardName, 40 softwareName, utils::generateSwId()); 41 42 softwareMap.insert_or_assign( 43 softwareIdentifier, std::make_unique<FirmwareInventory>( 44 softwareIdentifier, softwarePath, activeVersion, 45 *boardPath, descriptors, componentInfo)); 46 } 47 48 void FirmwareInventoryManager::deleteFirmwareEntry(const pldm::eid& eid) 49 { 50 std::erase_if(softwareMap, 51 [&](const auto& pair) { return pair.first.first == eid; }); 52 } 53 54 std::optional<std::filesystem::path> getBoardPath( 55 const pldm::utils::DBusHandler& handler, const InventoryPath& path) 56 { 57 constexpr auto boardInterface = "xyz.openbmc_project.Inventory.Item.Board"; 58 pldm::utils::GetAncestorsResponse response; 59 60 try 61 { 62 response = handler.getAncestors(path.c_str(), {boardInterface}); 63 } 64 catch (const sdbusplus::exception_t& e) 65 { 66 error("Failed to get ancestors for path {PATH}: {ERROR}", "PATH", path, 67 "ERROR", e); 68 return std::nullopt; 69 } 70 71 if (response.empty()) 72 { 73 error( 74 "Failed to get unique board path for Inventory path {PATH}, found: {SIZE}", 75 "PATH", path, "SIZE", response.size()); 76 return std::nullopt; 77 } 78 79 return std::get<ObjectPath>(response.front()); 80 } 81 82 std::optional<InventoryPath> FirmwareInventoryManager::getInventoryPath( 83 const pldm::eid& eid) const 84 { 85 for (const auto& [configDbusPath, configMctpInfo] : configurations) 86 { 87 if (std::get<pldm::eid>(configMctpInfo) == eid) 88 { 89 return configDbusPath; 90 } 91 } 92 warning("No inventory path found for EID {EID}", "EID", eid); 93 return std::nullopt; 94 } 95 96 } // namespace pldm::fw_update 97