| #include "EntityManagerInterface.hpp" |
| |
| #include "Utils.hpp" |
| |
| #include <phosphor-logging/lg2.hpp> |
| #include <sdbusplus/async.hpp> |
| #include <sdbusplus/message/native_types.hpp> |
| #include <xyz/openbmc_project/Inventory/Item/client.hpp> |
| |
| #include <algorithm> |
| #include <utility> |
| |
| namespace entity_manager |
| { |
| |
| PHOSPHOR_LOG2_USING; |
| |
| namespace rules_intf = sdbusplus::bus::match::rules; |
| |
| EntityManagerInterface::EntityManagerInterface( |
| sdbusplus::async::context& ctx, const interface_list_t& interfaceNames, |
| Callback_t addedCallback, Callback_t removedCallback) : |
| ctx(ctx), interfaceNames(interfaceNames), |
| addedCallback(std::move(addedCallback)), |
| removedCallback(std::move(removedCallback)) |
| { |
| ctx.spawn(handleInventoryAdded()); |
| ctx.spawn(handleInventoryRemoved()); |
| } |
| |
| auto EntityManagerInterface::handleInventoryGet() -> sdbusplus::async::task<> |
| { |
| if (!addedCallback) |
| { |
| error("addedCallback is not set"); |
| co_return; |
| } |
| |
| using InventoryIntf = |
| sdbusplus::client::xyz::openbmc_project::inventory::Item<>; |
| |
| constexpr auto entityManager = |
| sdbusplus::async::proxy() |
| .service(serviceName) |
| .path(InventoryIntf::namespace_path) |
| .interface("org.freedesktop.DBus.ObjectManager"); |
| |
| for (const auto& [objectPath, detectorConfig] : |
| co_await entityManager.call<ManagedObjectType>(ctx, |
| "GetManagedObjects")) |
| { |
| for (const auto& interfaceName : interfaceNames) |
| { |
| if (detectorConfig.contains(interfaceName)) |
| { |
| addedCallback(objectPath, interfaceName); |
| } |
| } |
| } |
| |
| co_return; |
| } |
| |
| auto EntityManagerInterface::handleInventoryAdded() -> sdbusplus::async::task<> |
| { |
| if (!addedCallback) |
| { |
| error("addedCallback is not set"); |
| co_return; |
| } |
| |
| auto addedMatch = sdbusplus::async::match( |
| ctx, rules_intf::interfacesAdded() + rules_intf::sender(serviceName)); |
| |
| while (!ctx.stop_requested()) |
| { |
| auto [objectPath, inventoryData] = |
| co_await addedMatch |
| .next<sdbusplus::message::object_path, SensorData>(); |
| |
| for (const auto& interfaceName : interfaceNames) |
| { |
| if (inventoryData.contains(interfaceName)) |
| { |
| addedCallback(objectPath, interfaceName); |
| } |
| } |
| } |
| |
| co_return; |
| } |
| |
| auto EntityManagerInterface::handleInventoryRemoved() |
| -> sdbusplus::async::task<> |
| { |
| if (!removedCallback) |
| { |
| error("removedCallback is not set"); |
| co_return; |
| } |
| |
| auto removedMatch = sdbusplus::async::match( |
| ctx, rules_intf::interfacesRemoved() + rules_intf::sender(serviceName)); |
| |
| while (!ctx.stop_requested()) |
| { |
| auto [objectPath, interfaces] = |
| co_await removedMatch |
| .next<sdbusplus::message::object_path, interface_list_t>(); |
| |
| for (const auto& interfaceName : interfaceNames) |
| { |
| if (std::ranges::find(interfaces, interfaceName) != |
| interfaces.end()) |
| { |
| removedCallback(objectPath, interfaceName); |
| } |
| } |
| } |
| |
| co_return; |
| } |
| |
| } // namespace entity_manager |