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