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