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