blob: bb9a6aa28057e583398a97f6a09a7b86a30d8d5d [file] [log] [blame]
Unive Tien7ad45b42025-08-18 06:04:53 +00001#include "firmware_inventory_manager.hpp"
2
3#include "common/types.hpp"
4#include "common/utils.hpp"
5
6#include <phosphor-logging/lg2.hpp>
7
8PHOSPHOR_LOG2_USING;
9
10namespace pldm::fw_update
11{
12
13void 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
rajeeranjan05d15a02025-06-30 12:10:08 +053023 // Determine the inventory board path for this EID. If Entity-Manager
24 // has provided a mapping, use it; otherwise fall back to a default
25 // placeholder path so that a software object can still be created.
26
27 std::optional<std::filesystem::path> boardPath;
28
Unive Tien7ad45b42025-08-18 06:04:53 +000029 auto& eid = softwareIdentifier.first;
30 const auto inventoryPath = getInventoryPath(eid);
rajeeranjan05d15a02025-06-30 12:10:08 +053031 if (inventoryPath)
Unive Tien7ad45b42025-08-18 06:04:53 +000032 {
rajeeranjan05d15a02025-06-30 12:10:08 +053033 boardPath = getBoardPath(*dbusHandler, *inventoryPath);
Unive Tien7ad45b42025-08-18 06:04:53 +000034 }
rajeeranjan05d15a02025-06-30 12:10:08 +053035 else
Unive Tien7ad45b42025-08-18 06:04:53 +000036 {
rajeeranjan05d15a02025-06-30 12:10:08 +053037 boardPath = "/xyz/openbmc_project/inventory/system/board/PLDM_Device";
Unive Tien7ad45b42025-08-18 06:04:53 +000038 }
39 const auto boardName = boardPath->filename().string();
40 const auto softwarePath =
41 std::format("/xyz/openbmc_project/software/{}_{}_{}", boardName,
42 softwareName, utils::generateSwId());
43
44 softwareMap.insert_or_assign(
45 softwareIdentifier, std::make_unique<FirmwareInventory>(
46 softwareIdentifier, softwarePath, activeVersion,
47 *boardPath, descriptors, componentInfo));
48}
49
50void FirmwareInventoryManager::deleteFirmwareEntry(const pldm::eid& eid)
51{
52 std::erase_if(softwareMap,
53 [&](const auto& pair) { return pair.first.first == eid; });
54}
55
56std::optional<std::filesystem::path> getBoardPath(
57 const pldm::utils::DBusHandler& handler, const InventoryPath& path)
58{
59 constexpr auto boardInterface = "xyz.openbmc_project.Inventory.Item.Board";
60 pldm::utils::GetAncestorsResponse response;
61
62 try
63 {
64 response = handler.getAncestors(path.c_str(), {boardInterface});
65 }
66 catch (const sdbusplus::exception_t& e)
67 {
68 error("Failed to get ancestors for path {PATH}: {ERROR}", "PATH", path,
69 "ERROR", e);
70 return std::nullopt;
71 }
72
73 if (response.empty())
74 {
75 error(
76 "Failed to get unique board path for Inventory path {PATH}, found: {SIZE}",
77 "PATH", path, "SIZE", response.size());
78 return std::nullopt;
79 }
80
81 return std::get<ObjectPath>(response.front());
82}
83
84std::optional<InventoryPath> FirmwareInventoryManager::getInventoryPath(
85 const pldm::eid& eid) const
86{
87 for (const auto& [configDbusPath, configMctpInfo] : configurations)
88 {
89 if (std::get<pldm::eid>(configMctpInfo) == eid)
90 {
91 return configDbusPath;
92 }
93 }
94 warning("No inventory path found for EID {EID}", "EID", eid);
95 return std::nullopt;
96}
97
98} // namespace pldm::fw_update