blob: a3e0ac9c4a2926c75f79e11f35bf71ef18e3337a [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,
Unive Tienee2bd8a2025-10-30 08:11:06 +000016 const Descriptors& /*descriptors*/, const ComponentInfo& /*componentInfo*/)
Unive Tien7ad45b42025-08-18 06:04:53 +000017{
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(
Unive Tienee2bd8a2025-10-30 08:11:06 +000045 softwareIdentifier,
46 std::make_unique<FirmwareInventory>(softwareIdentifier, softwarePath,
47 activeVersion, *boardPath));
Unive Tien7ad45b42025-08-18 06:04:53 +000048}
49
50void FirmwareInventoryManager::deleteFirmwareEntry(const pldm::eid& eid)
51{
52 std::erase_if(softwareMap,
53 [&](const auto& pair) { return pair.first.first == eid; });
Unive Tienee2bd8a2025-10-30 08:11:06 +000054 updateManager.eraseUpdateManagerIf(
55 [&](const SoftwareIdentifier& softwareIdentifier) {
56 return softwareIdentifier.first == eid;
57 });
Unive Tien7ad45b42025-08-18 06:04:53 +000058}
59
60std::optional<std::filesystem::path> getBoardPath(
61 const pldm::utils::DBusHandler& handler, const InventoryPath& path)
62{
63 constexpr auto boardInterface = "xyz.openbmc_project.Inventory.Item.Board";
64 pldm::utils::GetAncestorsResponse response;
65
66 try
67 {
68 response = handler.getAncestors(path.c_str(), {boardInterface});
69 }
70 catch (const sdbusplus::exception_t& e)
71 {
72 error("Failed to get ancestors for path {PATH}: {ERROR}", "PATH", path,
73 "ERROR", e);
74 return std::nullopt;
75 }
76
77 if (response.empty())
78 {
79 error(
80 "Failed to get unique board path for Inventory path {PATH}, found: {SIZE}",
81 "PATH", path, "SIZE", response.size());
82 return std::nullopt;
83 }
84
85 return std::get<ObjectPath>(response.front());
86}
87
88std::optional<InventoryPath> FirmwareInventoryManager::getInventoryPath(
89 const pldm::eid& eid) const
90{
91 for (const auto& [configDbusPath, configMctpInfo] : configurations)
92 {
93 if (std::get<pldm::eid>(configMctpInfo) == eid)
94 {
95 return configDbusPath;
96 }
97 }
98 warning("No inventory path found for EID {EID}", "EID", eid);
99 return std::nullopt;
100}
101
102} // namespace pldm::fw_update