xref: /openbmc/entity-manager/src/entity_manager/dbus_interface.hpp (revision dbf95b2c54c5a40d1ea44d650eb6aab2a4c34ba5)
1 #pragma once
2 
3 #include "configuration.hpp"
4 
5 #include <boost/container/flat_map.hpp>
6 #include <nlohmann/json.hpp>
7 #include <phosphor-logging/lg2.hpp>
8 #include <sdbusplus/asio/connection.hpp>
9 #include <sdbusplus/asio/object_server.hpp>
10 
11 #include <flat_map>
12 #include <vector>
13 
14 namespace dbus_interface
15 {
16 
17 class EMDBusInterface
18 {
19   public:
20     EMDBusInterface(boost::asio::io_context& io,
21                     sdbusplus::asio::object_server& objServer);
22 
23     std::shared_ptr<sdbusplus::asio::dbus_interface> createInterface(
24         const std::string& path, const std::string& interface,
25         const std::string& parent, bool checkNull = false);
26 
27     std::vector<std::weak_ptr<sdbusplus::asio::dbus_interface>>&
28         getDeviceInterfaces(const nlohmann::json& device);
29 
30     void createAddObjectMethod(const std::string& jsonPointerPath,
31                                const std::string& path,
32                                nlohmann::json& systemConfiguration,
33                                const std::string& board);
34 
35     void populateInterfaceFromJson(
36         nlohmann::json& systemConfiguration, const std::string& jsonPointerPath,
37         std::shared_ptr<sdbusplus::asio::dbus_interface>& iface,
38         nlohmann::json& dict,
39         sdbusplus::asio::PropertyPermission permission =
40             sdbusplus::asio::PropertyPermission::readOnly);
41 
42     void createDeleteObjectMethod(
43         const std::string& jsonPointerPath,
44         const std::shared_ptr<sdbusplus::asio::dbus_interface>& iface,
45         nlohmann::json& systemConfiguration);
46 
47   private:
48     boost::asio::io_context& io;
49     sdbusplus::asio::object_server& objServer;
50 
51     boost::container::flat_map<
52         std::string,
53         std::vector<std::weak_ptr<sdbusplus::asio::dbus_interface>>>
54         inventory;
55 };
56 
57 void tryIfaceInitialize(
58     std::shared_ptr<sdbusplus::asio::dbus_interface>& iface);
59 
60 template <typename PropertyType>
61 void addArrayToDbus(const std::string& name, const nlohmann::json& array,
62                     sdbusplus::asio::dbus_interface* iface,
63                     sdbusplus::asio::PropertyPermission permission,
64                     nlohmann::json& systemConfiguration,
65                     const std::string& jsonPointerString)
66 {
67     std::vector<PropertyType> values;
68     for (const auto& property : array)
69     {
70         auto ptr = property.get_ptr<const PropertyType*>();
71         if (ptr != nullptr)
72         {
73             values.emplace_back(*ptr);
74         }
75     }
76 
77     if (permission == sdbusplus::asio::PropertyPermission::readOnly)
78     {
79         iface->register_property(name, values);
80     }
81     else
82     {
83         iface->register_property(
84             name, values,
85             [&systemConfiguration,
86              jsonPointerString{std::string(jsonPointerString)}](
87                 const std::vector<PropertyType>& newVal,
88                 std::vector<PropertyType>& val) {
89                 val = newVal;
90                 if (!setJsonFromPointer(jsonPointerString, val,
91                                         systemConfiguration))
92                 {
93                     lg2::error("error setting json field");
94                     return -1;
95                 }
96                 if (!writeJsonFiles(systemConfiguration))
97                 {
98                     lg2::error("error setting json file");
99                     return -1;
100                 }
101                 return 1;
102             });
103     }
104 }
105 
106 template <typename PropertyType>
107 void addProperty(const std::string& name, const PropertyType& value,
108                  sdbusplus::asio::dbus_interface* iface,
109                  nlohmann::json& systemConfiguration,
110                  const std::string& jsonPointerString,
111                  sdbusplus::asio::PropertyPermission permission)
112 {
113     if (permission == sdbusplus::asio::PropertyPermission::readOnly)
114     {
115         iface->register_property(name, value);
116         return;
117     }
118     iface->register_property(
119         name, value,
120         [&systemConfiguration,
121          jsonPointerString{std::string(jsonPointerString)}](
122             const PropertyType& newVal, PropertyType& val) {
123             val = newVal;
124             if (!setJsonFromPointer(jsonPointerString, val,
125                                     systemConfiguration))
126             {
127                 lg2::error("error setting json field");
128                 return -1;
129             }
130             if (!writeJsonFiles(systemConfiguration))
131             {
132                 lg2::error("error setting json file");
133                 return -1;
134             }
135             return 1;
136         });
137 }
138 
139 template <typename PropertyType>
140 void addValueToDBus(const std::string& key, const nlohmann::json& value,
141                     sdbusplus::asio::dbus_interface& iface,
142                     sdbusplus::asio::PropertyPermission permission,
143                     nlohmann::json& systemConfiguration,
144                     const std::string& path)
145 {
146     if (value.is_array())
147     {
148         addArrayToDbus<PropertyType>(key, value, &iface, permission,
149                                      systemConfiguration, path);
150     }
151     else
152     {
153         addProperty(key, value.get<PropertyType>(), &iface, systemConfiguration,
154                     path, sdbusplus::asio::PropertyPermission::readOnly);
155     }
156 }
157 
158 } // namespace dbus_interface
159