blob: 0788fcb87034c5255df826c5ec13ee573f3bfa83 [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>
Alexander Hansene4faeec2025-11-18 12:06:06 +01007#include <xyz/openbmc_project/Inventory/Item/Board/common.hpp>
8#include <xyz/openbmc_project/Software/Version/common.hpp>
9
10using InventoryItemBoard =
11 sdbusplus::common::xyz::openbmc_project::inventory::item::Board;
12using SoftwareVersion =
13 sdbusplus::common::xyz::openbmc_project::software::Version;
Unive Tien7ad45b42025-08-18 06:04:53 +000014
15PHOSPHOR_LOG2_USING;
16
17namespace pldm::fw_update
18{
19
20void FirmwareInventoryManager::createFirmwareEntry(
21 const SoftwareIdentifier& softwareIdentifier,
22 const SoftwareName& softwareName, const std::string& activeVersion,
Unive Tienee2bd8a2025-10-30 08:11:06 +000023 const Descriptors& /*descriptors*/, const ComponentInfo& /*componentInfo*/)
Unive Tien7ad45b42025-08-18 06:04:53 +000024{
25 struct timespec ts;
26 clock_gettime(CLOCK_REALTIME, &ts);
27 unsigned seed = ts.tv_nsec ^ getpid();
28 srandom(seed);
29
rajeeranjan05d15a02025-06-30 12:10:08 +053030 // Determine the inventory board path for this EID. If Entity-Manager
31 // has provided a mapping, use it; otherwise fall back to a default
32 // placeholder path so that a software object can still be created.
33
34 std::optional<std::filesystem::path> boardPath;
35
Unive Tien7ad45b42025-08-18 06:04:53 +000036 auto& eid = softwareIdentifier.first;
37 const auto inventoryPath = getInventoryPath(eid);
rajeeranjan05d15a02025-06-30 12:10:08 +053038 if (inventoryPath)
Unive Tien7ad45b42025-08-18 06:04:53 +000039 {
rajeeranjan05d15a02025-06-30 12:10:08 +053040 boardPath = getBoardPath(*dbusHandler, *inventoryPath);
Unive Tien7ad45b42025-08-18 06:04:53 +000041 }
rajeeranjan05d15a02025-06-30 12:10:08 +053042 else
Unive Tien7ad45b42025-08-18 06:04:53 +000043 {
rajeeranjan05d15a02025-06-30 12:10:08 +053044 boardPath = "/xyz/openbmc_project/inventory/system/board/PLDM_Device";
Unive Tien7ad45b42025-08-18 06:04:53 +000045 }
46 const auto boardName = boardPath->filename().string();
47 const auto softwarePath =
Alexander Hansene4faeec2025-11-18 12:06:06 +010048 std::format("{}/{}_{}_{}", SoftwareVersion::namespace_path, boardName,
Unive Tien7ad45b42025-08-18 06:04:53 +000049 softwareName, utils::generateSwId());
50
51 softwareMap.insert_or_assign(
Unive Tienee2bd8a2025-10-30 08:11:06 +000052 softwareIdentifier,
53 std::make_unique<FirmwareInventory>(softwareIdentifier, softwarePath,
54 activeVersion, *boardPath));
Unive Tien7ad45b42025-08-18 06:04:53 +000055}
56
57void FirmwareInventoryManager::deleteFirmwareEntry(const pldm::eid& eid)
58{
59 std::erase_if(softwareMap,
60 [&](const auto& pair) { return pair.first.first == eid; });
Unive Tienee2bd8a2025-10-30 08:11:06 +000061 updateManager.eraseUpdateManagerIf(
62 [&](const SoftwareIdentifier& softwareIdentifier) {
63 return softwareIdentifier.first == eid;
64 });
Unive Tien7ad45b42025-08-18 06:04:53 +000065}
66
67std::optional<std::filesystem::path> getBoardPath(
68 const pldm::utils::DBusHandler& handler, const InventoryPath& path)
69{
Unive Tien7ad45b42025-08-18 06:04:53 +000070 pldm::utils::GetAncestorsResponse response;
71
72 try
73 {
Alexander Hansene4faeec2025-11-18 12:06:06 +010074 response =
75 handler.getAncestors(path.c_str(), {InventoryItemBoard::interface});
Unive Tien7ad45b42025-08-18 06:04:53 +000076 }
77 catch (const sdbusplus::exception_t& e)
78 {
79 error("Failed to get ancestors for path {PATH}: {ERROR}", "PATH", path,
80 "ERROR", e);
81 return std::nullopt;
82 }
83
84 if (response.empty())
85 {
86 error(
87 "Failed to get unique board path for Inventory path {PATH}, found: {SIZE}",
88 "PATH", path, "SIZE", response.size());
89 return std::nullopt;
90 }
91
92 return std::get<ObjectPath>(response.front());
93}
94
95std::optional<InventoryPath> FirmwareInventoryManager::getInventoryPath(
96 const pldm::eid& eid) const
97{
98 for (const auto& [configDbusPath, configMctpInfo] : configurations)
99 {
100 if (std::get<pldm::eid>(configMctpInfo) == eid)
101 {
102 return configDbusPath;
103 }
104 }
105 warning("No inventory path found for EID {EID}", "EID", eid);
106 return std::nullopt;
107}
108
109} // namespace pldm::fw_update