blob: 4b09b4f8eb4a384be0269337b112fbf7192c3ae0 [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
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
48void FirmwareInventoryManager::deleteFirmwareEntry(const pldm::eid& eid)
49{
50 std::erase_if(softwareMap,
51 [&](const auto& pair) { return pair.first.first == eid; });
52}
53
54std::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
82std::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