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 boost::asio::io_context& io; 59 sdbusplus::asio::object_server& objServer; 60 61 boost::container::flat_map< 62 std::string, 63 std::vector<std::weak_ptr<sdbusplus::asio::dbus_interface>>> 64 inventory; 65 }; 66 67 void tryIfaceInitialize( 68 std::shared_ptr<sdbusplus::asio::dbus_interface>& iface); 69 70 template <typename PropertyType> 71 void addArrayToDbus(const std::string& name, const nlohmann::json& array, 72 sdbusplus::asio::dbus_interface* iface, 73 sdbusplus::asio::PropertyPermission permission, 74 nlohmann::json& systemConfiguration, 75 const std::string& jsonPointerString) 76 { 77 std::vector<PropertyType> values; 78 for (const auto& property : array) 79 { 80 auto ptr = property.get_ptr<const PropertyType*>(); 81 if (ptr != nullptr) 82 { 83 values.emplace_back(*ptr); 84 } 85 } 86 87 if (permission == sdbusplus::asio::PropertyPermission::readOnly) 88 { 89 iface->register_property(name, values); 90 } 91 else 92 { 93 iface->register_property( 94 name, values, 95 [&systemConfiguration, 96 jsonPointerString{std::string(jsonPointerString)}]( 97 const std::vector<PropertyType>& newVal, 98 std::vector<PropertyType>& val) { 99 val = newVal; 100 if (!setJsonFromPointer(jsonPointerString, val, 101 systemConfiguration)) 102 { 103 lg2::error("error setting json field"); 104 return -1; 105 } 106 if (!writeJsonFiles(systemConfiguration)) 107 { 108 lg2::error("error setting json file"); 109 return -1; 110 } 111 return 1; 112 }); 113 } 114 } 115 116 template <typename PropertyType> 117 void addProperty(const std::string& name, const PropertyType& value, 118 sdbusplus::asio::dbus_interface* iface, 119 nlohmann::json& systemConfiguration, 120 const std::string& jsonPointerString, 121 sdbusplus::asio::PropertyPermission permission) 122 { 123 if (permission == sdbusplus::asio::PropertyPermission::readOnly) 124 { 125 iface->register_property(name, value); 126 return; 127 } 128 iface->register_property( 129 name, value, 130 [&systemConfiguration, 131 jsonPointerString{std::string(jsonPointerString)}]( 132 const PropertyType& newVal, PropertyType& val) { 133 val = newVal; 134 if (!setJsonFromPointer(jsonPointerString, val, 135 systemConfiguration)) 136 { 137 lg2::error("error setting json field"); 138 return -1; 139 } 140 if (!writeJsonFiles(systemConfiguration)) 141 { 142 lg2::error("error setting json file"); 143 return -1; 144 } 145 return 1; 146 }); 147 } 148 149 template <typename PropertyType> 150 void addValueToDBus(const std::string& key, const nlohmann::json& value, 151 sdbusplus::asio::dbus_interface& iface, 152 sdbusplus::asio::PropertyPermission permission, 153 nlohmann::json& systemConfiguration, 154 const std::string& path) 155 { 156 if (value.is_array()) 157 { 158 addArrayToDbus<PropertyType>(key, value, &iface, permission, 159 systemConfiguration, path); 160 } 161 else 162 { 163 addProperty(key, value.get<PropertyType>(), &iface, systemConfiguration, 164 path, sdbusplus::asio::PropertyPermission::readOnly); 165 } 166 } 167 168 } // namespace dbus_interface 169