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
escapePathForDbus(std::string & path)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
logError(const boost::system::error_code & ec)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
getAllProperties(const std::string & service,const std::string & objectPath,const std::string & interface,std::function<void (const boost::system::error_code &,const DBusPropertiesMap &)> && callback)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
getAllProperties(sdbusplus::asio::connection &,const std::string & service,const std::string & objectPath,const std::string & interface,std::function<void (const boost::system::error_code &,const DBusPropertiesMap &)> && callback)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
checkDbusPathExists(const std::string & path,std::function<void (bool)> && callback)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
getSubTree(const std::string & path,int32_t depth,std::span<const std::string_view> interfaces,std::function<void (const boost::system::error_code &,const MapperGetSubTreeResponse &)> && callback)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
getSubTreePaths(const std::string & path,int32_t depth,std::span<const std::string_view> interfaces,std::function<void (const boost::system::error_code &,const MapperGetSubTreePathsResponse &)> && callback)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
getAssociatedSubTree(const sdbusplus::message::object_path & associatedPath,const sdbusplus::message::object_path & path,int32_t depth,std::span<const std::string_view> interfaces,std::function<void (const boost::system::error_code &,const MapperGetSubTreeResponse &)> && callback)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
getAssociatedSubTreePaths(const sdbusplus::message::object_path & associatedPath,const sdbusplus::message::object_path & path,int32_t depth,std::span<const std::string_view> interfaces,std::function<void (const boost::system::error_code &,const MapperGetSubTreePathsResponse &)> && callback)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
getAssociatedSubTreeById(const std::string & id,const std::string & path,std::span<const std::string_view> subtreeInterfaces,std::string_view association,std::span<const std::string_view> endpointInterfaces,std::function<void (const boost::system::error_code &,const MapperGetSubTreeResponse &)> && callback)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
getAssociatedSubTreePathsById(const std::string & id,const std::string & path,std::span<const std::string_view> subtreeInterfaces,std::string_view association,std::span<const std::string_view> endpointInterfaces,std::function<void (const boost::system::error_code &,const MapperGetSubTreePathsResponse &)> && callback)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
getDbusObject(const std::string & path,std::span<const std::string_view> interfaces,std::function<void (const boost::system::error_code &,const MapperGetObject &)> && callback)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
getAssociationEndPoints(const std::string & path,std::function<void (const boost::system::error_code &,const MapperEndPoints &)> && callback)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
getManagedObjects(const std::string & service,const sdbusplus::message::object_path & path,std::function<void (const boost::system::error_code &,const ManagedObjectType &)> && callback)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