blob: 581cd1babdb915f9a80322a8db40f73286d246d6 [file] [log] [blame]
Jagpal Singh Gill15dde862024-10-16 09:42:54 -07001#include "EntityManagerInterface.hpp"
2
3#include "Utils.hpp"
4
5#include <phosphor-logging/lg2.hpp>
6#include <sdbusplus/async.hpp>
7#include <sdbusplus/message/native_types.hpp>
8#include <xyz/openbmc_project/Inventory/Item/client.hpp>
9
10#include <algorithm>
11#include <utility>
12
13namespace entity_manager
14{
15
16PHOSPHOR_LOG2_USING;
17
18namespace rules_intf = sdbusplus::bus::match::rules;
19
20EntityManagerInterface::EntityManagerInterface(
21 sdbusplus::async::context& ctx, const interface_list_t& interfaceNames,
22 Callback_t addedCallback, Callback_t removedCallback) :
23 ctx(ctx), interfaceNames(interfaceNames),
24 addedCallback(std::move(addedCallback)),
25 removedCallback(std::move(removedCallback))
26{
27 ctx.spawn(handleInventoryAdded());
28 ctx.spawn(handleInventoryRemoved());
29}
30
31auto EntityManagerInterface::handleInventoryGet() -> sdbusplus::async::task<>
32{
33 if (!addedCallback)
34 {
35 error("addedCallback is not set");
36 co_return;
37 }
38
39 using InventoryIntf =
40 sdbusplus::client::xyz::openbmc_project::inventory::Item<>;
41
42 constexpr auto entityManager =
43 sdbusplus::async::proxy()
44 .service(serviceName)
45 .path(InventoryIntf::namespace_path)
46 .interface("org.freedesktop.DBus.ObjectManager");
47
48 for (const auto& [objectPath, detectorConfig] :
49 co_await entityManager.call<ManagedObjectType>(ctx,
50 "GetManagedObjects"))
51 {
52 for (const auto& interfaceName : interfaceNames)
53 {
54 if (detectorConfig.contains(interfaceName))
55 {
56 addedCallback(objectPath, interfaceName);
57 }
58 }
59 }
60
61 co_return;
62}
63
64auto EntityManagerInterface::handleInventoryAdded() -> sdbusplus::async::task<>
65{
66 if (!addedCallback)
67 {
68 error("addedCallback is not set");
69 co_return;
70 }
71
72 auto addedMatch = sdbusplus::async::match(
73 ctx, rules_intf::interfacesAdded() + rules_intf::sender(serviceName));
74
75 while (!ctx.stop_requested())
76 {
77 auto [objectPath, inventoryData] =
78 co_await addedMatch
79 .next<sdbusplus::message::object_path, SensorData>();
80
81 for (const auto& interfaceName : interfaceNames)
82 {
83 if (inventoryData.contains(interfaceName))
84 {
85 addedCallback(objectPath, interfaceName);
86 }
87 }
88 }
89
90 co_return;
91}
92
93auto EntityManagerInterface::handleInventoryRemoved()
94 -> sdbusplus::async::task<>
95{
96 if (!removedCallback)
97 {
98 error("removedCallback is not set");
99 co_return;
100 }
101
102 auto removedMatch = sdbusplus::async::match(
103 ctx, rules_intf::interfacesRemoved() + rules_intf::sender(serviceName));
104
105 while (!ctx.stop_requested())
106 {
107 auto [objectPath, interfaces] =
108 co_await removedMatch
109 .next<sdbusplus::message::object_path, interface_list_t>();
110
111 for (const auto& interfaceName : interfaceNames)
112 {
113 if (std::ranges::find(interfaces, interfaceName) !=
114 interfaces.end())
115 {
116 removedCallback(objectPath, interfaceName);
117 }
118 }
119 }
120
121 co_return;
122}
123
124} // namespace entity_manager