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