blob: 50d75c5477d5c1b1e7392c21a073e81cfa3bb4f2 [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>>,
74
75 // TODO This needs looked at. It's used in the trigger system, but a
76 // variant of a variant seems really odd
77 std::variant<
78 std::vector<std::tuple<std::string, uint64_t, std::string, double>>,
79 std::vector<std::tuple<std::string, std::string, uint64_t, std::string>>
80 >
Ed Tanousd1a64812021-12-13 12:14:05 -080081 >;
James Feist5b4aa862018-08-16 14:07:01 -070082
Ed Tanousd1a64812021-12-13 12:14:05 -080083// clang-format on
Ed Tanous711ac7a2021-12-20 09:34:41 -080084using DBusPropertiesMap = std::vector<std::pair<std::string, DbusVariantType>>;
Michael Shen80f79a42023-08-24 13:41:53 +000085using DBusInterfacesMap =
86 std::vector<std::pair<std::string, DBusPropertiesMap>>;
Zbigniew Kurzynski755a33c2020-02-28 14:06:37 +010087using ManagedObjectType =
Michael Shen80f79a42023-08-24 13:41:53 +000088 std::vector<std::pair<sdbusplus::message::object_path, DBusInterfacesMap>>;
James Feist5b4aa862018-08-16 14:07:01 -070089
Shantappa Teekappanavar5df6eda2022-01-18 12:29:28 -060090// Map of service name to list of interfaces
91using MapperServiceMap =
92 std::vector<std::pair<std::string, std::vector<std::string>>>;
93
94// Map of object paths to MapperServiceMaps
95using MapperGetSubTreeResponse =
96 std::vector<std::pair<std::string, MapperServiceMap>>;
97
Ed Tanousb9d36b42022-02-26 21:42:46 -080098using MapperGetObject =
99 std::vector<std::pair<std::string, std::vector<std::string>>>;
100
101using MapperGetAncestorsResponse = std::vector<
102 std::pair<std::string,
103 std::vector<std::pair<std::string, std::vector<std::string>>>>>;
104
105using MapperGetSubTreePathsResponse = std::vector<std::string>;
106
George Liua4eb7612023-02-11 15:49:46 +0800107using MapperEndPoints = std::vector<std::string>;
108
James Feist5b4aa862018-08-16 14:07:01 -0700109inline void escapePathForDbus(std::string& path)
110{
Ed Tanous4b242742023-05-11 09:51:51 -0700111 const static std::regex reg("[^A-Za-z0-9_/]");
James Feist5b4aa862018-08-16 14:07:01 -0700112 std::regex_replace(path.begin(), path.begin(), path.end(), reg, "_");
113}
114
Ed Tanous863c1c22022-02-21 21:33:06 -0800115inline void logError(const boost::system::error_code& ec)
116{
117 if (ec)
118 {
Ed Tanous62598e32023-07-17 17:06:25 -0700119 BMCWEB_LOG_ERROR("DBus error: {}, cannot call method", ec);
Ed Tanous863c1c22022-02-21 21:33:06 -0800120 }
121}
122
James Feist5b4aa862018-08-16 14:07:01 -0700123// gets the string N strings deep into a path
124// i.e. /0th/1st/2nd/3rd
125inline bool getNthStringFromPath(const std::string& path, int index,
126 std::string& result)
127{
Manojkiran Eda17a897d2020-09-12 15:31:58 +0530128 if (index < 0)
James Feist5b4aa862018-08-16 14:07:01 -0700129 {
Manojkiran Eda17a897d2020-09-12 15:31:58 +0530130 return false;
131 }
132
133 std::filesystem::path p1(path);
134 int count = -1;
Patrick Williams89492a12023-05-10 07:51:34 -0500135 for (const auto& element : p1)
Manojkiran Eda17a897d2020-09-12 15:31:58 +0530136 {
137 if (element.has_filename())
James Feist5b4aa862018-08-16 14:07:01 -0700138 {
Manojkiran Eda17a897d2020-09-12 15:31:58 +0530139 ++count;
James Feist5b4aa862018-08-16 14:07:01 -0700140 if (count == index)
141 {
Manojkiran Eda17a897d2020-09-12 15:31:58 +0530142 result = element.stem().string();
James Feist5b4aa862018-08-16 14:07:01 -0700143 break;
144 }
145 }
146 }
Ed Tanousdcf2ebc2022-01-25 10:07:45 -0800147 return count >= index;
James Feist5b4aa862018-08-16 14:07:01 -0700148}
149
Ed Tanousdeae6a72024-11-11 21:58:57 -0800150inline void
151 getAllProperties(const std::string& service, const std::string& objectPath,
152 const std::string& interface,
153 std::function<void(const boost::system::error_code&,
154 const DBusPropertiesMap&)>&& callback)
155{
156 sdbusplus::asio::getAllProperties(*crow::connections::systemBus, service,
157 objectPath, interface,
158 std::move(callback));
159}
160
161template <typename PropertyType>
162inline void getProperty(
163 const std::string& service, const std::string& objectPath,
164 const std::string& interface, const std::string& propertyName,
165 std::function<void(const boost::system::error_code&, const PropertyType&)>&&
166 callback)
167{
168 sdbusplus::asio::getProperty<PropertyType>(
169 *crow::connections::systemBus, service, objectPath, interface,
170 propertyName, std::move(callback));
171}
172
173template <typename PropertyType>
174inline void getProperty(
175 sdbusplus::asio::connection& /*conn*/, const std::string& service,
176 const std::string& objectPath, const std::string& interface,
177 const std::string& propertyName,
178 std::function<void(const boost::system::error_code&, const PropertyType&)>&&
179 callback)
180{
181 getProperty(service, objectPath, interface, propertyName,
182 std::move(callback));
183}
184
185inline void getAllProperties(
186 sdbusplus::asio::connection& /*conn*/, const std::string& service,
187 const std::string& objectPath, const std::string& interface,
188 std::function<void(const boost::system::error_code&,
189 const DBusPropertiesMap&)>&& callback)
190{
191 getAllProperties(service, objectPath, interface, std::move(callback));
192}
193
Ratan Gupta22c33712019-05-03 21:50:28 +0530194template <typename Callback>
195inline void checkDbusPathExists(const std::string& path, Callback&& callback)
196{
Ratan Gupta22c33712019-05-03 21:50:28 +0530197 crow::connections::systemBus->async_method_call(
Ed Tanous8cb2c022024-03-27 16:31:46 -0700198 [callback = std::forward<Callback>(callback)](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800199 const boost::system::error_code& ec,
Ed Tanousdeae6a72024-11-11 21:58:57 -0800200 const MapperGetObject& objectNames) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400201 callback(!ec && !objectNames.empty());
202 },
Ratan Gupta22c33712019-05-03 21:50:28 +0530203 "xyz.openbmc_project.ObjectMapper",
204 "/xyz/openbmc_project/object_mapper",
205 "xyz.openbmc_project.ObjectMapper", "GetObject", path,
206 std::array<std::string, 0>());
207}
208
George Liu21384832022-11-09 11:21:15 +0800209inline void
George Liue99073f2022-12-09 11:06:16 +0800210 getSubTree(const std::string& path, int32_t depth,
211 std::span<const std::string_view> interfaces,
George Liu21384832022-11-09 11:21:15 +0800212 std::function<void(const boost::system::error_code&,
213 const MapperGetSubTreeResponse&)>&& callback)
214{
215 crow::connections::systemBus->async_method_call(
216 [callback{std::move(callback)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800217 const boost::system::error_code& ec,
George Liu21384832022-11-09 11:21:15 +0800218 const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); },
219 "xyz.openbmc_project.ObjectMapper",
220 "/xyz/openbmc_project/object_mapper",
George Liue99073f2022-12-09 11:06:16 +0800221 "xyz.openbmc_project.ObjectMapper", "GetSubTree", path, depth,
222 interfaces);
George Liu21384832022-11-09 11:21:15 +0800223}
224
225inline void getSubTreePaths(
George Liu7a1dbc42022-12-07 16:03:22 +0800226 const std::string& path, int32_t depth,
227 std::span<const std::string_view> interfaces,
George Liu21384832022-11-09 11:21:15 +0800228 std::function<void(const boost::system::error_code&,
229 const MapperGetSubTreePathsResponse&)>&& callback)
230{
231 crow::connections::systemBus->async_method_call(
232 [callback{std::move(callback)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800233 const boost::system::error_code& ec,
George Liu21384832022-11-09 11:21:15 +0800234 const MapperGetSubTreePathsResponse& subtreePaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400235 callback(ec, subtreePaths);
236 },
George Liu21384832022-11-09 11:21:15 +0800237 "xyz.openbmc_project.ObjectMapper",
238 "/xyz/openbmc_project/object_mapper",
George Liu7a1dbc42022-12-07 16:03:22 +0800239 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", path, depth,
George Liu21384832022-11-09 11:21:15 +0800240 interfaces);
241}
242
Willy Tu8d018362023-04-14 09:14:16 -0700243inline void getAssociatedSubTree(
244 const sdbusplus::message::object_path& associatedPath,
245 const sdbusplus::message::object_path& path, int32_t depth,
246 std::span<const std::string_view> interfaces,
247 std::function<void(const boost::system::error_code&,
248 const MapperGetSubTreeResponse&)>&& callback)
249{
250 crow::connections::systemBus->async_method_call(
251 [callback{std::move(callback)}](
252 const boost::system::error_code& ec,
253 const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); },
254 "xyz.openbmc_project.ObjectMapper",
255 "/xyz/openbmc_project/object_mapper",
256 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTree",
257 associatedPath, path, depth, interfaces);
258}
259
260inline void getAssociatedSubTreePaths(
261 const sdbusplus::message::object_path& associatedPath,
262 const sdbusplus::message::object_path& path, int32_t depth,
263 std::span<const std::string_view> interfaces,
264 std::function<void(const boost::system::error_code&,
265 const MapperGetSubTreePathsResponse&)>&& callback)
266{
267 crow::connections::systemBus->async_method_call(
268 [callback{std::move(callback)}](
269 const boost::system::error_code& ec,
270 const MapperGetSubTreePathsResponse& subtreePaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400271 callback(ec, subtreePaths);
272 },
Willy Tu8d018362023-04-14 09:14:16 -0700273 "xyz.openbmc_project.ObjectMapper",
274 "/xyz/openbmc_project/object_mapper",
275 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreePaths",
276 associatedPath, path, depth, interfaces);
277}
278
Lakshmi Yadlapati64d8e802024-06-26 17:41:19 -0500279inline void getAssociatedSubTreeById(
280 const std::string& id, const std::string& path,
281 std::span<const std::string_view> subtreeInterfaces,
282 std::string_view association,
283 std::span<const std::string_view> endpointInterfaces,
284 std::function<void(const boost::system::error_code&,
285 const MapperGetSubTreeResponse&)>&& callback)
286{
287 crow::connections::systemBus->async_method_call(
288 [callback{std::move(callback)}](
289 const boost::system::error_code& ec,
290 const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); },
291 "xyz.openbmc_project.ObjectMapper",
292 "/xyz/openbmc_project/object_mapper",
293 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreeById", id,
294 path, subtreeInterfaces, association, endpointInterfaces);
295}
296
297inline void getAssociatedSubTreePathsById(
298 const std::string& id, const std::string& path,
299 std::span<const std::string_view> subtreeInterfaces,
300 std::string_view association,
301 std::span<const std::string_view> endpointInterfaces,
302 std::function<void(const boost::system::error_code&,
303 const MapperGetSubTreePathsResponse&)>&& callback)
304{
305 crow::connections::systemBus->async_method_call(
306 [callback{std::move(callback)}](
307 const boost::system::error_code& ec,
308 const MapperGetSubTreePathsResponse& subtreePaths) {
309 callback(ec, subtreePaths);
310 },
311 "xyz.openbmc_project.ObjectMapper",
312 "/xyz/openbmc_project/object_mapper",
313 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreePathsById", id,
314 path, subtreeInterfaces, association, endpointInterfaces);
315}
316
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400317inline void getDbusObject(
318 const std::string& path, std::span<const std::string_view> interfaces,
319 std::function<void(const boost::system::error_code&,
320 const MapperGetObject&)>&& callback)
George Liu2b731192023-01-11 16:27:13 +0800321{
322 crow::connections::systemBus->async_method_call(
323 [callback{std::move(callback)}](const boost::system::error_code& ec,
324 const MapperGetObject& object) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400325 callback(ec, object);
326 },
George Liu2b731192023-01-11 16:27:13 +0800327 "xyz.openbmc_project.ObjectMapper",
328 "/xyz/openbmc_project/object_mapper",
329 "xyz.openbmc_project.ObjectMapper", "GetObject", path, interfaces);
330}
331
George Liua4eb7612023-02-11 15:49:46 +0800332inline void getAssociationEndPoints(
333 const std::string& path,
334 std::function<void(const boost::system::error_code&,
335 const MapperEndPoints&)>&& callback)
336{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800337 getProperty<MapperEndPoints>("xyz.openbmc_project.ObjectMapper", path,
338 "xyz.openbmc_project.Association", "endpoints",
339 std::move(callback));
George Liua4eb7612023-02-11 15:49:46 +0800340}
341
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400342inline void getManagedObjects(
343 const std::string& service, const sdbusplus::message::object_path& path,
344 std::function<void(const boost::system::error_code&,
345 const ManagedObjectType&)>&& callback)
George Liuf5892d02023-03-01 10:37:08 +0800346{
347 crow::connections::systemBus->async_method_call(
348 [callback{std::move(callback)}](const boost::system::error_code& ec,
349 const ManagedObjectType& objects) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400350 callback(ec, objects);
351 },
George Liuf5892d02023-03-01 10:37:08 +0800352 service, path, "org.freedesktop.DBus.ObjectManager",
353 "GetManagedObjects");
354}
355
James Feist5b4aa862018-08-16 14:07:01 -0700356} // namespace utility
357} // namespace dbus