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