blob: 89cda891a8b3f542df92832e24c306c3c934e375 [file] [log] [blame]
James Feist5b4aa862018-08-16 14:07:01 -07001/*
Ed Tanous6be832e2024-09-10 11:44:48 -07002Copyright (c) 2018 Intel Corporation
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
James Feist5b4aa862018-08-16 14:07:01 -070015 */
16#pragma once
17
Ed Tanous95c63072024-03-26 13:19:52 -070018#include "boost_formatters.hpp"
Nan Zhou80d37e72022-06-21 17:46:14 +000019#include "dbus_singleton.hpp"
Ed Tanous863c1c22022-02-21 21:33:06 -080020#include "logging.hpp"
Nan Zhou80d37e72022-06-21 17:46:14 +000021
Ed Tanous478b7ad2024-07-15 19:11:54 -070022#include <boost/system/error_code.hpp>
George Liua4eb7612023-02-11 15:49:46 +080023#include <sdbusplus/asio/property.hpp>
Nan Zhoud5c80ad2022-07-11 01:16:31 +000024#include <sdbusplus/message/native_types.hpp>
James Feist5b4aa862018-08-16 14:07:01 -070025
Nan Zhou80d37e72022-06-21 17:46:14 +000026#include <array>
Nan Zhoud5c80ad2022-07-11 01:16:31 +000027#include <cstddef>
28#include <cstdint>
Manojkiran Eda17a897d2020-09-12 15:31:58 +053029#include <filesystem>
George Liu21384832022-11-09 11:21:15 +080030#include <functional>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050031#include <regex>
George Liu21384832022-11-09 11:21:15 +080032#include <span>
Nan Zhoud5c80ad2022-07-11 01:16:31 +000033#include <sstream>
Nan Zhou80d37e72022-06-21 17:46:14 +000034#include <string>
George Liu7a1dbc42022-12-07 16:03:22 +080035#include <string_view>
Nan Zhou80d37e72022-06-21 17:46:14 +000036#include <tuple>
Nan Zhoud5c80ad2022-07-11 01:16:31 +000037#include <utility>
Ed Tanous40681292022-02-22 10:11:43 -080038#include <variant>
Nan Zhou80d37e72022-06-21 17:46:14 +000039#include <vector>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050040
James Feist5b4aa862018-08-16 14:07:01 -070041namespace dbus
42{
43
44namespace utility
45{
46
Ed Tanousd1a64812021-12-13 12:14:05 -080047// clang-format off
Ed Tanous40681292022-02-22 10:11:43 -080048using DbusVariantType = std::variant<
Ed Tanousd1a64812021-12-13 12:14:05 -080049 std::vector<std::tuple<std::string, std::string, std::string>>,
50 std::vector<std::string>,
51 std::vector<double>,
52 std::string,
53 int64_t,
54 uint64_t,
55 double,
56 int32_t,
57 uint32_t,
58 int16_t,
59 uint16_t,
60 uint8_t,
61 bool,
Ed Tanousd1a64812021-12-13 12:14:05 -080062 std::vector<uint32_t>,
63 std::vector<uint16_t>,
64 sdbusplus::message::object_path,
Krzysztof Grobelny479e8992021-06-17 13:37:57 +000065 std::tuple<uint64_t, std::vector<std::tuple<std::string, double, uint64_t>>>,
Szymon Dompkef19ab442022-03-07 14:28:06 +010066 std::vector<sdbusplus::message::object_path>,
Ed Tanousd1a64812021-12-13 12:14:05 -080067 std::vector<std::tuple<std::string, std::string>>,
68 std::vector<std::tuple<uint32_t, std::vector<uint32_t>>>,
69 std::vector<std::tuple<uint32_t, size_t>>,
Krzysztof Grobelny479e8992021-06-17 13:37:57 +000070 std::vector<std::tuple<
71 std::vector<std::tuple<sdbusplus::message::object_path, std::string>>,
Ed Tanouse3648032024-10-16 18:06:39 -070072 std::string, std::string, uint64_t>>,
73 std::vector<std::pair<sdbusplus::message::object_path, std::string>>,
Ed Tanous58c71482024-10-19 14:35:07 -070074 std::vector<std::tuple<std::string, uint64_t, std::string, double>>,
75 std::vector<std::tuple<std::string, std::string, uint64_t, std::string>>
Ed Tanousd1a64812021-12-13 12:14:05 -080076 >;
James Feist5b4aa862018-08-16 14:07:01 -070077
Ed Tanousd1a64812021-12-13 12:14:05 -080078// clang-format on
Ed Tanous711ac7a2021-12-20 09:34:41 -080079using DBusPropertiesMap = std::vector<std::pair<std::string, DbusVariantType>>;
Michael Shen80f79a42023-08-24 13:41:53 +000080using DBusInterfacesMap =
81 std::vector<std::pair<std::string, DBusPropertiesMap>>;
Zbigniew Kurzynski755a33c2020-02-28 14:06:37 +010082using ManagedObjectType =
Michael Shen80f79a42023-08-24 13:41:53 +000083 std::vector<std::pair<sdbusplus::message::object_path, DBusInterfacesMap>>;
James Feist5b4aa862018-08-16 14:07:01 -070084
Shantappa Teekappanavar5df6eda2022-01-18 12:29:28 -060085// Map of service name to list of interfaces
86using MapperServiceMap =
87 std::vector<std::pair<std::string, std::vector<std::string>>>;
88
89// Map of object paths to MapperServiceMaps
90using MapperGetSubTreeResponse =
91 std::vector<std::pair<std::string, MapperServiceMap>>;
92
Ed Tanousb9d36b42022-02-26 21:42:46 -080093using MapperGetObject =
94 std::vector<std::pair<std::string, std::vector<std::string>>>;
95
96using MapperGetAncestorsResponse = std::vector<
97 std::pair<std::string,
98 std::vector<std::pair<std::string, std::vector<std::string>>>>>;
99
100using MapperGetSubTreePathsResponse = std::vector<std::string>;
101
George Liua4eb7612023-02-11 15:49:46 +0800102using MapperEndPoints = std::vector<std::string>;
103
James Feist5b4aa862018-08-16 14:07:01 -0700104inline void escapePathForDbus(std::string& path)
105{
Ed Tanous4b242742023-05-11 09:51:51 -0700106 const static std::regex reg("[^A-Za-z0-9_/]");
James Feist5b4aa862018-08-16 14:07:01 -0700107 std::regex_replace(path.begin(), path.begin(), path.end(), reg, "_");
108}
109
Ed Tanous863c1c22022-02-21 21:33:06 -0800110inline void logError(const boost::system::error_code& ec)
111{
112 if (ec)
113 {
Ed Tanous62598e32023-07-17 17:06:25 -0700114 BMCWEB_LOG_ERROR("DBus error: {}, cannot call method", ec);
Ed Tanous863c1c22022-02-21 21:33:06 -0800115 }
116}
117
James Feist5b4aa862018-08-16 14:07:01 -0700118// gets the string N strings deep into a path
119// i.e. /0th/1st/2nd/3rd
120inline bool getNthStringFromPath(const std::string& path, int index,
121 std::string& result)
122{
Manojkiran Eda17a897d2020-09-12 15:31:58 +0530123 if (index < 0)
James Feist5b4aa862018-08-16 14:07:01 -0700124 {
Manojkiran Eda17a897d2020-09-12 15:31:58 +0530125 return false;
126 }
127
128 std::filesystem::path p1(path);
129 int count = -1;
Patrick Williams89492a12023-05-10 07:51:34 -0500130 for (const auto& element : p1)
Manojkiran Eda17a897d2020-09-12 15:31:58 +0530131 {
132 if (element.has_filename())
James Feist5b4aa862018-08-16 14:07:01 -0700133 {
Manojkiran Eda17a897d2020-09-12 15:31:58 +0530134 ++count;
James Feist5b4aa862018-08-16 14:07:01 -0700135 if (count == index)
136 {
Manojkiran Eda17a897d2020-09-12 15:31:58 +0530137 result = element.stem().string();
James Feist5b4aa862018-08-16 14:07:01 -0700138 break;
139 }
140 }
141 }
Ed Tanousdcf2ebc2022-01-25 10:07:45 -0800142 return count >= index;
James Feist5b4aa862018-08-16 14:07:01 -0700143}
144
Ed Tanousdeae6a72024-11-11 21:58:57 -0800145inline void
146 getAllProperties(const std::string& service, const std::string& objectPath,
147 const std::string& interface,
148 std::function<void(const boost::system::error_code&,
149 const DBusPropertiesMap&)>&& callback)
150{
151 sdbusplus::asio::getAllProperties(*crow::connections::systemBus, service,
152 objectPath, interface,
153 std::move(callback));
154}
155
156template <typename PropertyType>
157inline void getProperty(
158 const std::string& service, const std::string& objectPath,
159 const std::string& interface, const std::string& propertyName,
160 std::function<void(const boost::system::error_code&, const PropertyType&)>&&
161 callback)
162{
163 sdbusplus::asio::getProperty<PropertyType>(
164 *crow::connections::systemBus, service, objectPath, interface,
165 propertyName, std::move(callback));
166}
167
168template <typename PropertyType>
169inline void getProperty(
170 sdbusplus::asio::connection& /*conn*/, const std::string& service,
171 const std::string& objectPath, const std::string& interface,
172 const std::string& propertyName,
173 std::function<void(const boost::system::error_code&, const PropertyType&)>&&
174 callback)
175{
176 getProperty(service, objectPath, interface, propertyName,
177 std::move(callback));
178}
179
180inline void getAllProperties(
181 sdbusplus::asio::connection& /*conn*/, const std::string& service,
182 const std::string& objectPath, const std::string& interface,
183 std::function<void(const boost::system::error_code&,
184 const DBusPropertiesMap&)>&& callback)
185{
186 getAllProperties(service, objectPath, interface, std::move(callback));
187}
188
Ratan Gupta22c33712019-05-03 21:50:28 +0530189template <typename Callback>
190inline void checkDbusPathExists(const std::string& path, Callback&& callback)
191{
Ratan Gupta22c33712019-05-03 21:50:28 +0530192 crow::connections::systemBus->async_method_call(
Ed Tanous8cb2c022024-03-27 16:31:46 -0700193 [callback = std::forward<Callback>(callback)](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800194 const boost::system::error_code& ec,
Ed Tanousdeae6a72024-11-11 21:58:57 -0800195 const MapperGetObject& objectNames) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400196 callback(!ec && !objectNames.empty());
197 },
Ratan Gupta22c33712019-05-03 21:50:28 +0530198 "xyz.openbmc_project.ObjectMapper",
199 "/xyz/openbmc_project/object_mapper",
200 "xyz.openbmc_project.ObjectMapper", "GetObject", path,
201 std::array<std::string, 0>());
202}
203
George Liu21384832022-11-09 11:21:15 +0800204inline void
George Liue99073f2022-12-09 11:06:16 +0800205 getSubTree(const std::string& path, int32_t depth,
206 std::span<const std::string_view> interfaces,
George Liu21384832022-11-09 11:21:15 +0800207 std::function<void(const boost::system::error_code&,
208 const MapperGetSubTreeResponse&)>&& callback)
209{
210 crow::connections::systemBus->async_method_call(
211 [callback{std::move(callback)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800212 const boost::system::error_code& ec,
George Liu21384832022-11-09 11:21:15 +0800213 const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); },
214 "xyz.openbmc_project.ObjectMapper",
215 "/xyz/openbmc_project/object_mapper",
George Liue99073f2022-12-09 11:06:16 +0800216 "xyz.openbmc_project.ObjectMapper", "GetSubTree", path, depth,
217 interfaces);
George Liu21384832022-11-09 11:21:15 +0800218}
219
220inline void getSubTreePaths(
George Liu7a1dbc42022-12-07 16:03:22 +0800221 const std::string& path, int32_t depth,
222 std::span<const std::string_view> interfaces,
George Liu21384832022-11-09 11:21:15 +0800223 std::function<void(const boost::system::error_code&,
224 const MapperGetSubTreePathsResponse&)>&& callback)
225{
226 crow::connections::systemBus->async_method_call(
227 [callback{std::move(callback)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800228 const boost::system::error_code& ec,
George Liu21384832022-11-09 11:21:15 +0800229 const MapperGetSubTreePathsResponse& subtreePaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400230 callback(ec, subtreePaths);
231 },
George Liu21384832022-11-09 11:21:15 +0800232 "xyz.openbmc_project.ObjectMapper",
233 "/xyz/openbmc_project/object_mapper",
George Liu7a1dbc42022-12-07 16:03:22 +0800234 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", path, depth,
George Liu21384832022-11-09 11:21:15 +0800235 interfaces);
236}
237
Willy Tu8d018362023-04-14 09:14:16 -0700238inline void getAssociatedSubTree(
239 const sdbusplus::message::object_path& associatedPath,
240 const sdbusplus::message::object_path& path, int32_t depth,
241 std::span<const std::string_view> interfaces,
242 std::function<void(const boost::system::error_code&,
243 const MapperGetSubTreeResponse&)>&& callback)
244{
245 crow::connections::systemBus->async_method_call(
246 [callback{std::move(callback)}](
247 const boost::system::error_code& ec,
248 const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); },
249 "xyz.openbmc_project.ObjectMapper",
250 "/xyz/openbmc_project/object_mapper",
251 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTree",
252 associatedPath, path, depth, interfaces);
253}
254
255inline void getAssociatedSubTreePaths(
256 const sdbusplus::message::object_path& associatedPath,
257 const sdbusplus::message::object_path& path, int32_t depth,
258 std::span<const std::string_view> interfaces,
259 std::function<void(const boost::system::error_code&,
260 const MapperGetSubTreePathsResponse&)>&& callback)
261{
262 crow::connections::systemBus->async_method_call(
263 [callback{std::move(callback)}](
264 const boost::system::error_code& ec,
265 const MapperGetSubTreePathsResponse& subtreePaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400266 callback(ec, subtreePaths);
267 },
Willy Tu8d018362023-04-14 09:14:16 -0700268 "xyz.openbmc_project.ObjectMapper",
269 "/xyz/openbmc_project/object_mapper",
270 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreePaths",
271 associatedPath, path, depth, interfaces);
272}
273
Lakshmi Yadlapati64d8e802024-06-26 17:41:19 -0500274inline void getAssociatedSubTreeById(
275 const std::string& id, const std::string& path,
276 std::span<const std::string_view> subtreeInterfaces,
277 std::string_view association,
278 std::span<const std::string_view> endpointInterfaces,
279 std::function<void(const boost::system::error_code&,
280 const MapperGetSubTreeResponse&)>&& callback)
281{
282 crow::connections::systemBus->async_method_call(
283 [callback{std::move(callback)}](
284 const boost::system::error_code& ec,
285 const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); },
286 "xyz.openbmc_project.ObjectMapper",
287 "/xyz/openbmc_project/object_mapper",
288 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreeById", id,
289 path, subtreeInterfaces, association, endpointInterfaces);
290}
291
292inline void getAssociatedSubTreePathsById(
293 const std::string& id, const std::string& path,
294 std::span<const std::string_view> subtreeInterfaces,
295 std::string_view association,
296 std::span<const std::string_view> endpointInterfaces,
297 std::function<void(const boost::system::error_code&,
298 const MapperGetSubTreePathsResponse&)>&& callback)
299{
300 crow::connections::systemBus->async_method_call(
301 [callback{std::move(callback)}](
302 const boost::system::error_code& ec,
303 const MapperGetSubTreePathsResponse& subtreePaths) {
304 callback(ec, subtreePaths);
305 },
306 "xyz.openbmc_project.ObjectMapper",
307 "/xyz/openbmc_project/object_mapper",
308 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreePathsById", id,
309 path, subtreeInterfaces, association, endpointInterfaces);
310}
311
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400312inline void getDbusObject(
313 const std::string& path, std::span<const std::string_view> interfaces,
314 std::function<void(const boost::system::error_code&,
315 const MapperGetObject&)>&& callback)
George Liu2b731192023-01-11 16:27:13 +0800316{
317 crow::connections::systemBus->async_method_call(
318 [callback{std::move(callback)}](const boost::system::error_code& ec,
319 const MapperGetObject& object) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400320 callback(ec, object);
321 },
George Liu2b731192023-01-11 16:27:13 +0800322 "xyz.openbmc_project.ObjectMapper",
323 "/xyz/openbmc_project/object_mapper",
324 "xyz.openbmc_project.ObjectMapper", "GetObject", path, interfaces);
325}
326
George Liua4eb7612023-02-11 15:49:46 +0800327inline void getAssociationEndPoints(
328 const std::string& path,
329 std::function<void(const boost::system::error_code&,
330 const MapperEndPoints&)>&& callback)
331{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800332 getProperty<MapperEndPoints>("xyz.openbmc_project.ObjectMapper", path,
333 "xyz.openbmc_project.Association", "endpoints",
334 std::move(callback));
George Liua4eb7612023-02-11 15:49:46 +0800335}
336
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400337inline void getManagedObjects(
338 const std::string& service, const sdbusplus::message::object_path& path,
339 std::function<void(const boost::system::error_code&,
340 const ManagedObjectType&)>&& callback)
George Liuf5892d02023-03-01 10:37:08 +0800341{
342 crow::connections::systemBus->async_method_call(
343 [callback{std::move(callback)}](const boost::system::error_code& ec,
344 const ManagedObjectType& objects) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400345 callback(ec, objects);
346 },
George Liuf5892d02023-03-01 10:37:08 +0800347 service, path, "org.freedesktop.DBus.ObjectManager",
348 "GetManagedObjects");
349}
350
James Feist5b4aa862018-08-16 14:07:01 -0700351} // namespace utility
352} // namespace dbus