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