1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors 3 4 #include "dbus_utility.hpp" 5 6 #include "boost_formatters.hpp" 7 #include "dbus_singleton.hpp" 8 #include "logging.hpp" 9 10 #include <boost/system/error_code.hpp> 11 #include <sdbusplus/asio/connection.hpp> 12 #include <sdbusplus/asio/property.hpp> 13 #include <sdbusplus/message/native_types.hpp> 14 15 #include <array> 16 #include <cstdint> 17 #include <filesystem> 18 #include <functional> 19 #include <regex> 20 #include <span> 21 #include <string> 22 #include <string_view> 23 #include <utility> 24 25 namespace dbus 26 { 27 28 namespace utility 29 { 30 31 void escapePathForDbus(std::string& path) 32 { 33 const static std::regex reg("[^A-Za-z0-9_/]"); 34 std::regex_replace(path.begin(), path.begin(), path.end(), reg, "_"); 35 } 36 37 void logError(const boost::system::error_code& ec) 38 { 39 if (ec) 40 { 41 BMCWEB_LOG_ERROR("DBus error: {}, cannot call method", ec); 42 } 43 } 44 45 void getAllProperties(const std::string& service, const std::string& objectPath, 46 const std::string& interface, 47 std::function<void(const boost::system::error_code&, 48 const DBusPropertiesMap&)>&& callback) 49 { 50 sdbusplus::asio::getAllProperties(*crow::connections::systemBus, service, 51 objectPath, interface, 52 std::move(callback)); 53 } 54 55 void getAllProperties(sdbusplus::asio::connection& /*conn*/, 56 const std::string& service, const std::string& objectPath, 57 const std::string& interface, 58 std::function<void(const boost::system::error_code&, 59 const DBusPropertiesMap&)>&& callback) 60 { 61 getAllProperties(service, objectPath, interface, std::move(callback)); 62 } 63 64 void checkDbusPathExists(const std::string& path, 65 std::function<void(bool)>&& callback) 66 { 67 dbus::utility::async_method_call( 68 [callback = std::move(callback)](const boost::system::error_code& ec, 69 const MapperGetObject& objectNames) { 70 callback(!ec && !objectNames.empty()); 71 }, 72 "xyz.openbmc_project.ObjectMapper", 73 "/xyz/openbmc_project/object_mapper", 74 "xyz.openbmc_project.ObjectMapper", "GetObject", path, 75 std::array<std::string, 0>()); 76 } 77 78 void getSubTree(const std::string& path, int32_t depth, 79 std::span<const std::string_view> interfaces, 80 std::function<void(const boost::system::error_code&, 81 const MapperGetSubTreeResponse&)>&& callback) 82 { 83 dbus::utility::async_method_call( 84 [callback = std::move(callback)]( 85 const boost::system::error_code& ec, 86 const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); }, 87 "xyz.openbmc_project.ObjectMapper", 88 "/xyz/openbmc_project/object_mapper", 89 "xyz.openbmc_project.ObjectMapper", "GetSubTree", path, depth, 90 interfaces); 91 } 92 93 void getSubTreePaths( 94 const std::string& path, int32_t depth, 95 std::span<const std::string_view> interfaces, 96 std::function<void(const boost::system::error_code&, 97 const MapperGetSubTreePathsResponse&)>&& callback) 98 { 99 dbus::utility::async_method_call( 100 [callback = std::move(callback)]( 101 const boost::system::error_code& ec, 102 const MapperGetSubTreePathsResponse& subtreePaths) { 103 callback(ec, subtreePaths); 104 }, 105 "xyz.openbmc_project.ObjectMapper", 106 "/xyz/openbmc_project/object_mapper", 107 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", path, depth, 108 interfaces); 109 } 110 111 void getAssociatedSubTree( 112 const sdbusplus::message::object_path& associatedPath, 113 const sdbusplus::message::object_path& path, int32_t depth, 114 std::span<const std::string_view> interfaces, 115 std::function<void(const boost::system::error_code&, 116 const MapperGetSubTreeResponse&)>&& callback) 117 { 118 dbus::utility::async_method_call( 119 [callback = std::move(callback)]( 120 const boost::system::error_code& ec, 121 const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); }, 122 "xyz.openbmc_project.ObjectMapper", 123 "/xyz/openbmc_project/object_mapper", 124 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTree", 125 associatedPath, path, depth, interfaces); 126 } 127 128 void getAssociatedSubTreePaths( 129 const sdbusplus::message::object_path& associatedPath, 130 const sdbusplus::message::object_path& path, int32_t depth, 131 std::span<const std::string_view> interfaces, 132 std::function<void(const boost::system::error_code&, 133 const MapperGetSubTreePathsResponse&)>&& callback) 134 { 135 dbus::utility::async_method_call( 136 [callback = std::move(callback)]( 137 const boost::system::error_code& ec, 138 const MapperGetSubTreePathsResponse& subtreePaths) { 139 callback(ec, subtreePaths); 140 }, 141 "xyz.openbmc_project.ObjectMapper", 142 "/xyz/openbmc_project/object_mapper", 143 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreePaths", 144 associatedPath, path, depth, interfaces); 145 } 146 147 void getAssociatedSubTreeById( 148 const std::string& id, const std::string& path, 149 std::span<const std::string_view> subtreeInterfaces, 150 std::string_view association, 151 std::span<const std::string_view> endpointInterfaces, 152 std::function<void(const boost::system::error_code&, 153 const MapperGetSubTreeResponse&)>&& callback) 154 { 155 dbus::utility::async_method_call( 156 [callback = std::move(callback)]( 157 const boost::system::error_code& ec, 158 const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); }, 159 "xyz.openbmc_project.ObjectMapper", 160 "/xyz/openbmc_project/object_mapper", 161 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreeById", id, 162 path, subtreeInterfaces, association, endpointInterfaces); 163 } 164 165 void getAssociatedSubTreePathsById( 166 const std::string& id, const std::string& path, 167 std::span<const std::string_view> subtreeInterfaces, 168 std::string_view association, 169 std::span<const std::string_view> endpointInterfaces, 170 std::function<void(const boost::system::error_code&, 171 const MapperGetSubTreePathsResponse&)>&& callback) 172 { 173 dbus::utility::async_method_call( 174 [callback = std::move(callback)]( 175 const boost::system::error_code& ec, 176 const MapperGetSubTreePathsResponse& subtreePaths) { 177 callback(ec, subtreePaths); 178 }, 179 "xyz.openbmc_project.ObjectMapper", 180 "/xyz/openbmc_project/object_mapper", 181 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreePathsById", id, 182 path, subtreeInterfaces, association, endpointInterfaces); 183 } 184 185 void getDbusObject(const std::string& path, 186 std::span<const std::string_view> interfaces, 187 std::function<void(const boost::system::error_code&, 188 const MapperGetObject&)>&& callback) 189 { 190 dbus::utility::async_method_call( 191 [callback = std::move(callback)](const boost::system::error_code& ec, 192 const MapperGetObject& object) { 193 callback(ec, object); 194 }, 195 "xyz.openbmc_project.ObjectMapper", 196 "/xyz/openbmc_project/object_mapper", 197 "xyz.openbmc_project.ObjectMapper", "GetObject", path, interfaces); 198 } 199 200 void getAssociationEndPoints( 201 const std::string& path, 202 std::function<void(const boost::system::error_code&, 203 const MapperEndPoints&)>&& callback) 204 { 205 getProperty<MapperEndPoints>("xyz.openbmc_project.ObjectMapper", path, 206 "xyz.openbmc_project.Association", "endpoints", 207 std::move(callback)); 208 } 209 210 void getManagedObjects(const std::string& service, 211 const sdbusplus::message::object_path& path, 212 std::function<void(const boost::system::error_code&, 213 const ManagedObjectType&)>&& callback) 214 { 215 dbus::utility::async_method_call( 216 [callback = std::move(callback)](const boost::system::error_code& ec, 217 const ManagedObjectType& objects) { 218 callback(ec, objects); 219 }, 220 service, path, "org.freedesktop.DBus.ObjectManager", 221 "GetManagedObjects"); 222 } 223 224 } // namespace utility 225 } // namespace dbus 226