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