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 // gets the string N strings deep into a path 46 // i.e. /0th/1st/2nd/3rd 47 bool getNthStringFromPath(const std::string& path, int index, 48 std::string& result) 49 { 50 if (index < 0) 51 { 52 return false; 53 } 54 55 std::filesystem::path p1(path); 56 int count = -1; 57 for (const auto& element : p1) 58 { 59 if (element.has_filename()) 60 { 61 ++count; 62 if (count == index) 63 { 64 result = element.stem().string(); 65 break; 66 } 67 } 68 } 69 return count >= index; 70 } 71 72 void getAllProperties(const std::string& service, const std::string& objectPath, 73 const std::string& interface, 74 std::function<void(const boost::system::error_code&, 75 const DBusPropertiesMap&)>&& callback) 76 { 77 sdbusplus::asio::getAllProperties(*crow::connections::systemBus, service, 78 objectPath, interface, 79 std::move(callback)); 80 } 81 82 void getAllProperties(sdbusplus::asio::connection& /*conn*/, 83 const std::string& service, const std::string& objectPath, 84 const std::string& interface, 85 std::function<void(const boost::system::error_code&, 86 const DBusPropertiesMap&)>&& callback) 87 { 88 getAllProperties(service, objectPath, interface, std::move(callback)); 89 } 90 91 void checkDbusPathExists(const std::string& path, 92 std::function<void(bool)>&& callback) 93 { 94 crow::connections::systemBus->async_method_call( 95 [callback = std::move(callback)](const boost::system::error_code& ec, 96 const MapperGetObject& objectNames) { 97 callback(!ec && !objectNames.empty()); 98 }, 99 "xyz.openbmc_project.ObjectMapper", 100 "/xyz/openbmc_project/object_mapper", 101 "xyz.openbmc_project.ObjectMapper", "GetObject", path, 102 std::array<std::string, 0>()); 103 } 104 105 void getSubTree(const std::string& path, int32_t depth, 106 std::span<const std::string_view> interfaces, 107 std::function<void(const boost::system::error_code&, 108 const MapperGetSubTreeResponse&)>&& callback) 109 { 110 crow::connections::systemBus->async_method_call( 111 [callback{std::move(callback)}]( 112 const boost::system::error_code& ec, 113 const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); }, 114 "xyz.openbmc_project.ObjectMapper", 115 "/xyz/openbmc_project/object_mapper", 116 "xyz.openbmc_project.ObjectMapper", "GetSubTree", path, depth, 117 interfaces); 118 } 119 120 void getSubTreePaths( 121 const std::string& path, int32_t depth, 122 std::span<const std::string_view> interfaces, 123 std::function<void(const boost::system::error_code&, 124 const MapperGetSubTreePathsResponse&)>&& callback) 125 { 126 crow::connections::systemBus->async_method_call( 127 [callback{std::move(callback)}]( 128 const boost::system::error_code& ec, 129 const MapperGetSubTreePathsResponse& subtreePaths) { 130 callback(ec, subtreePaths); 131 }, 132 "xyz.openbmc_project.ObjectMapper", 133 "/xyz/openbmc_project/object_mapper", 134 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", path, depth, 135 interfaces); 136 } 137 138 void getAssociatedSubTree( 139 const sdbusplus::message::object_path& associatedPath, 140 const sdbusplus::message::object_path& path, int32_t depth, 141 std::span<const std::string_view> interfaces, 142 std::function<void(const boost::system::error_code&, 143 const MapperGetSubTreeResponse&)>&& callback) 144 { 145 crow::connections::systemBus->async_method_call( 146 [callback{std::move(callback)}]( 147 const boost::system::error_code& ec, 148 const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); }, 149 "xyz.openbmc_project.ObjectMapper", 150 "/xyz/openbmc_project/object_mapper", 151 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTree", 152 associatedPath, path, depth, interfaces); 153 } 154 155 void getAssociatedSubTreePaths( 156 const sdbusplus::message::object_path& associatedPath, 157 const sdbusplus::message::object_path& path, int32_t depth, 158 std::span<const std::string_view> interfaces, 159 std::function<void(const boost::system::error_code&, 160 const MapperGetSubTreePathsResponse&)>&& callback) 161 { 162 crow::connections::systemBus->async_method_call( 163 [callback{std::move(callback)}]( 164 const boost::system::error_code& ec, 165 const MapperGetSubTreePathsResponse& subtreePaths) { 166 callback(ec, subtreePaths); 167 }, 168 "xyz.openbmc_project.ObjectMapper", 169 "/xyz/openbmc_project/object_mapper", 170 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreePaths", 171 associatedPath, path, depth, interfaces); 172 } 173 174 void getAssociatedSubTreeById( 175 const std::string& id, const std::string& path, 176 std::span<const std::string_view> subtreeInterfaces, 177 std::string_view association, 178 std::span<const std::string_view> endpointInterfaces, 179 std::function<void(const boost::system::error_code&, 180 const MapperGetSubTreeResponse&)>&& callback) 181 { 182 crow::connections::systemBus->async_method_call( 183 [callback{std::move(callback)}]( 184 const boost::system::error_code& ec, 185 const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); }, 186 "xyz.openbmc_project.ObjectMapper", 187 "/xyz/openbmc_project/object_mapper", 188 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreeById", id, 189 path, subtreeInterfaces, association, endpointInterfaces); 190 } 191 192 void getAssociatedSubTreePathsById( 193 const std::string& id, const std::string& path, 194 std::span<const std::string_view> subtreeInterfaces, 195 std::string_view association, 196 std::span<const std::string_view> endpointInterfaces, 197 std::function<void(const boost::system::error_code&, 198 const MapperGetSubTreePathsResponse&)>&& callback) 199 { 200 crow::connections::systemBus->async_method_call( 201 [callback{std::move(callback)}]( 202 const boost::system::error_code& ec, 203 const MapperGetSubTreePathsResponse& subtreePaths) { 204 callback(ec, subtreePaths); 205 }, 206 "xyz.openbmc_project.ObjectMapper", 207 "/xyz/openbmc_project/object_mapper", 208 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreePathsById", id, 209 path, subtreeInterfaces, association, endpointInterfaces); 210 } 211 212 void getDbusObject(const std::string& path, 213 std::span<const std::string_view> interfaces, 214 std::function<void(const boost::system::error_code&, 215 const MapperGetObject&)>&& callback) 216 { 217 crow::connections::systemBus->async_method_call( 218 [callback{std::move(callback)}](const boost::system::error_code& ec, 219 const MapperGetObject& object) { 220 callback(ec, object); 221 }, 222 "xyz.openbmc_project.ObjectMapper", 223 "/xyz/openbmc_project/object_mapper", 224 "xyz.openbmc_project.ObjectMapper", "GetObject", path, interfaces); 225 } 226 227 void getAssociationEndPoints( 228 const std::string& path, 229 std::function<void(const boost::system::error_code&, 230 const MapperEndPoints&)>&& callback) 231 { 232 getProperty<MapperEndPoints>("xyz.openbmc_project.ObjectMapper", path, 233 "xyz.openbmc_project.Association", "endpoints", 234 std::move(callback)); 235 } 236 237 void getManagedObjects(const std::string& service, 238 const sdbusplus::message::object_path& path, 239 std::function<void(const boost::system::error_code&, 240 const ManagedObjectType&)>&& callback) 241 { 242 crow::connections::systemBus->async_method_call( 243 [callback{std::move(callback)}](const boost::system::error_code& ec, 244 const ManagedObjectType& objects) { 245 callback(ec, objects); 246 }, 247 service, path, "org.freedesktop.DBus.ObjectManager", 248 "GetManagedObjects"); 249 } 250 251 } // namespace utility 252 } // namespace dbus 253