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 using JsonVariantType = 18 std::variant<std::vector<std::string>, std::vector<double>, std::string, 19 int64_t, uint64_t, double, int32_t, uint32_t, int16_t, 20 uint16_t, uint8_t, bool>; 21 22 class EMDBusInterface 23 { 24 public: 25 EMDBusInterface(boost::asio::io_context& io, 26 sdbusplus::asio::object_server& objServer); 27 28 std::shared_ptr<sdbusplus::asio::dbus_interface> createInterface( 29 const std::string& path, const std::string& interface, 30 const std::string& parent, bool checkNull = false); 31 32 std::vector<std::weak_ptr<sdbusplus::asio::dbus_interface>>& 33 getDeviceInterfaces(const nlohmann::json& device); 34 35 void createAddObjectMethod(const std::string& jsonPointerPath, 36 const std::string& path, 37 nlohmann::json& systemConfiguration, 38 const std::string& board); 39 40 void populateInterfaceFromJson( 41 nlohmann::json& systemConfiguration, const std::string& jsonPointerPath, 42 std::shared_ptr<sdbusplus::asio::dbus_interface>& iface, 43 nlohmann::json& dict, 44 sdbusplus::asio::PropertyPermission permission = 45 sdbusplus::asio::PropertyPermission::readOnly); 46 47 void createDeleteObjectMethod( 48 const std::string& jsonPointerPath, 49 const std::shared_ptr<sdbusplus::asio::dbus_interface>& iface, 50 nlohmann::json& systemConfiguration); 51 52 private: 53 void addObject( 54 const std::flat_map<std::string, JsonVariantType, std::less<>>& data, 55 nlohmann::json& systemConfiguration, const std::string& jsonPointerPath, 56 const std::string& path, const std::string& board); 57 58 // @brief: same as 'addObject', but operates on json 59 void addObjectJson(nlohmann::json& newData, 60 nlohmann::json& systemConfiguration, 61 const std::string& jsonPointerPath, 62 const std::string& path, const std::string& board); 63 64 boost::asio::io_context& io; 65 sdbusplus::asio::object_server& objServer; 66 67 boost::container::flat_map< 68 std::string, 69 std::vector<std::weak_ptr<sdbusplus::asio::dbus_interface>>> 70 inventory; 71 }; 72 73 void tryIfaceInitialize( 74 std::shared_ptr<sdbusplus::asio::dbus_interface>& iface); 75 76 template <typename PropertyType> 77 void addArrayToDbus(const std::string& name, const nlohmann::json& array, 78 sdbusplus::asio::dbus_interface* iface, 79 sdbusplus::asio::PropertyPermission permission, 80 nlohmann::json& systemConfiguration, 81 const std::string& jsonPointerString) 82 { 83 std::vector<PropertyType> values; 84 for (const auto& property : array) 85 { 86 auto ptr = property.get_ptr<const PropertyType*>(); 87 if (ptr != nullptr) 88 { 89 values.emplace_back(*ptr); 90 } 91 } 92 93 if (permission == sdbusplus::asio::PropertyPermission::readOnly) 94 { 95 iface->register_property(name, values); 96 } 97 else 98 { 99 iface->register_property( 100 name, values, 101 [&systemConfiguration, 102 jsonPointerString{std::string(jsonPointerString)}]( 103 const std::vector<PropertyType>& newVal, 104 std::vector<PropertyType>& val) { 105 val = newVal; 106 if (!setJsonFromPointer(jsonPointerString, val, 107 systemConfiguration)) 108 { 109 lg2::error("error setting json field"); 110 return -1; 111 } 112 if (!writeJsonFiles(systemConfiguration)) 113 { 114 lg2::error("error setting json file"); 115 return -1; 116 } 117 return 1; 118 }); 119 } 120 } 121 122 template <typename PropertyType> 123 void addProperty(const std::string& name, const PropertyType& value, 124 sdbusplus::asio::dbus_interface* iface, 125 nlohmann::json& systemConfiguration, 126 const std::string& jsonPointerString, 127 sdbusplus::asio::PropertyPermission permission) 128 { 129 if (permission == sdbusplus::asio::PropertyPermission::readOnly) 130 { 131 iface->register_property(name, value); 132 return; 133 } 134 iface->register_property( 135 name, value, 136 [&systemConfiguration, 137 jsonPointerString{std::string(jsonPointerString)}]( 138 const PropertyType& newVal, PropertyType& val) { 139 val = newVal; 140 if (!setJsonFromPointer(jsonPointerString, val, 141 systemConfiguration)) 142 { 143 lg2::error("error setting json field"); 144 return -1; 145 } 146 if (!writeJsonFiles(systemConfiguration)) 147 { 148 lg2::error("error setting json file"); 149 return -1; 150 } 151 return 1; 152 }); 153 } 154 155 template <typename PropertyType> 156 void addValueToDBus(const std::string& key, const nlohmann::json& value, 157 sdbusplus::asio::dbus_interface& iface, 158 sdbusplus::asio::PropertyPermission permission, 159 nlohmann::json& systemConfiguration, 160 const std::string& path) 161 { 162 if (value.is_array()) 163 { 164 addArrayToDbus<PropertyType>(key, value, &iface, permission, 165 systemConfiguration, path); 166 } 167 else 168 { 169 addProperty(key, value.get<PropertyType>(), &iface, systemConfiguration, 170 path, sdbusplus::asio::PropertyPermission::readOnly); 171 } 172 } 173 174 } // namespace dbus_interface 175