xref: /openbmc/bmcweb/src/dbus_utility.cpp (revision bb1c7d30d6799b4e0fcd0b3fc4f97be9a253e6c0)
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 
45 // gets the string N strings deep into a path
46 // i.e.  /0th/1st/2nd/3rd
getNthStringFromPath(const std::string & path,int index,std::string & result)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 
getAllProperties(const std::string & service,const std::string & objectPath,const std::string & interface,std::function<void (const boost::system::error_code &,const DBusPropertiesMap &)> && callback)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 
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)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 
checkDbusPathExists(const std::string & path,std::function<void (bool)> && callback)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 
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)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 
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)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 
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)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 
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)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 
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)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 
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)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 
getDbusObject(const std::string & path,std::span<const std::string_view> interfaces,std::function<void (const boost::system::error_code &,const MapperGetObject &)> && callback)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 
getAssociationEndPoints(const std::string & path,std::function<void (const boost::system::error_code &,const MapperEndPoints &)> && callback)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 
getManagedObjects(const std::string & service,const sdbusplus::message::object_path & path,std::function<void (const boost::system::error_code &,const ManagedObjectType &)> && callback)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