blob: 68b3930ef72573b45c1ea81ae19d4f56d93ae19b [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 sdbusplus::message::unix_fd,
63 std::vector<uint32_t>,
64 std::vector<uint16_t>,
65 sdbusplus::message::object_path,
Krzysztof Grobelny479e8992021-06-17 13:37:57 +000066 std::tuple<uint64_t, std::vector<std::tuple<std::string, double, uint64_t>>>,
Szymon Dompkef19ab442022-03-07 14:28:06 +010067 std::vector<sdbusplus::message::object_path>,
Ed Tanousd1a64812021-12-13 12:14:05 -080068 std::vector<std::tuple<std::string, std::string>>,
69 std::vector<std::tuple<uint32_t, std::vector<uint32_t>>>,
70 std::vector<std::tuple<uint32_t, size_t>>,
Krzysztof Grobelny479e8992021-06-17 13:37:57 +000071 std::vector<std::tuple<
72 std::vector<std::tuple<sdbusplus::message::object_path, std::string>>,
73 std::string, std::string, uint64_t>>
Ed Tanousd1a64812021-12-13 12:14:05 -080074 >;
James Feist5b4aa862018-08-16 14:07:01 -070075
Ed Tanousd1a64812021-12-13 12:14:05 -080076// clang-format on
Ed Tanous711ac7a2021-12-20 09:34:41 -080077using DBusPropertiesMap = std::vector<std::pair<std::string, DbusVariantType>>;
Michael Shen80f79a42023-08-24 13:41:53 +000078using DBusInterfacesMap =
79 std::vector<std::pair<std::string, DBusPropertiesMap>>;
Zbigniew Kurzynski755a33c2020-02-28 14:06:37 +010080using ManagedObjectType =
Michael Shen80f79a42023-08-24 13:41:53 +000081 std::vector<std::pair<sdbusplus::message::object_path, DBusInterfacesMap>>;
James Feist5b4aa862018-08-16 14:07:01 -070082
Shantappa Teekappanavar5df6eda2022-01-18 12:29:28 -060083// Map of service name to list of interfaces
84using MapperServiceMap =
85 std::vector<std::pair<std::string, std::vector<std::string>>>;
86
87// Map of object paths to MapperServiceMaps
88using MapperGetSubTreeResponse =
89 std::vector<std::pair<std::string, MapperServiceMap>>;
90
Ed Tanousb9d36b42022-02-26 21:42:46 -080091using MapperGetObject =
92 std::vector<std::pair<std::string, std::vector<std::string>>>;
93
94using MapperGetAncestorsResponse = std::vector<
95 std::pair<std::string,
96 std::vector<std::pair<std::string, std::vector<std::string>>>>>;
97
98using MapperGetSubTreePathsResponse = std::vector<std::string>;
99
George Liua4eb7612023-02-11 15:49:46 +0800100using MapperEndPoints = std::vector<std::string>;
101
James Feist5b4aa862018-08-16 14:07:01 -0700102inline void escapePathForDbus(std::string& path)
103{
Ed Tanous4b242742023-05-11 09:51:51 -0700104 const static std::regex reg("[^A-Za-z0-9_/]");
James Feist5b4aa862018-08-16 14:07:01 -0700105 std::regex_replace(path.begin(), path.begin(), path.end(), reg, "_");
106}
107
Ed Tanous863c1c22022-02-21 21:33:06 -0800108inline void logError(const boost::system::error_code& ec)
109{
110 if (ec)
111 {
Ed Tanous62598e32023-07-17 17:06:25 -0700112 BMCWEB_LOG_ERROR("DBus error: {}, cannot call method", ec);
Ed Tanous863c1c22022-02-21 21:33:06 -0800113 }
114}
115
James Feist5b4aa862018-08-16 14:07:01 -0700116// gets the string N strings deep into a path
117// i.e. /0th/1st/2nd/3rd
118inline bool getNthStringFromPath(const std::string& path, int index,
119 std::string& result)
120{
Manojkiran Eda17a897d2020-09-12 15:31:58 +0530121 if (index < 0)
James Feist5b4aa862018-08-16 14:07:01 -0700122 {
Manojkiran Eda17a897d2020-09-12 15:31:58 +0530123 return false;
124 }
125
126 std::filesystem::path p1(path);
127 int count = -1;
Patrick Williams89492a12023-05-10 07:51:34 -0500128 for (const auto& element : p1)
Manojkiran Eda17a897d2020-09-12 15:31:58 +0530129 {
130 if (element.has_filename())
James Feist5b4aa862018-08-16 14:07:01 -0700131 {
Manojkiran Eda17a897d2020-09-12 15:31:58 +0530132 ++count;
James Feist5b4aa862018-08-16 14:07:01 -0700133 if (count == index)
134 {
Manojkiran Eda17a897d2020-09-12 15:31:58 +0530135 result = element.stem().string();
James Feist5b4aa862018-08-16 14:07:01 -0700136 break;
137 }
138 }
139 }
Ed Tanousdcf2ebc2022-01-25 10:07:45 -0800140 return count >= index;
James Feist5b4aa862018-08-16 14:07:01 -0700141}
142
Ed Tanousdeae6a72024-11-11 21:58:57 -0800143inline void
144 getAllProperties(const std::string& service, const std::string& objectPath,
145 const std::string& interface,
146 std::function<void(const boost::system::error_code&,
147 const DBusPropertiesMap&)>&& callback)
148{
149 sdbusplus::asio::getAllProperties(*crow::connections::systemBus, service,
150 objectPath, interface,
151 std::move(callback));
152}
153
154template <typename PropertyType>
155inline void getProperty(
156 const std::string& service, const std::string& objectPath,
157 const std::string& interface, const std::string& propertyName,
158 std::function<void(const boost::system::error_code&, const PropertyType&)>&&
159 callback)
160{
161 sdbusplus::asio::getProperty<PropertyType>(
162 *crow::connections::systemBus, service, objectPath, interface,
163 propertyName, std::move(callback));
164}
165
166template <typename PropertyType>
167inline void getProperty(
168 sdbusplus::asio::connection& /*conn*/, const std::string& service,
169 const std::string& objectPath, const std::string& interface,
170 const std::string& propertyName,
171 std::function<void(const boost::system::error_code&, const PropertyType&)>&&
172 callback)
173{
174 getProperty(service, objectPath, interface, propertyName,
175 std::move(callback));
176}
177
178inline void getAllProperties(
179 sdbusplus::asio::connection& /*conn*/, const std::string& service,
180 const std::string& objectPath, const std::string& interface,
181 std::function<void(const boost::system::error_code&,
182 const DBusPropertiesMap&)>&& callback)
183{
184 getAllProperties(service, objectPath, interface, std::move(callback));
185}
186
Ratan Gupta22c33712019-05-03 21:50:28 +0530187template <typename Callback>
188inline void checkDbusPathExists(const std::string& path, Callback&& callback)
189{
Ratan Gupta22c33712019-05-03 21:50:28 +0530190 crow::connections::systemBus->async_method_call(
Ed Tanous8cb2c022024-03-27 16:31:46 -0700191 [callback = std::forward<Callback>(callback)](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800192 const boost::system::error_code& ec,
Ed Tanousdeae6a72024-11-11 21:58:57 -0800193 const MapperGetObject& objectNames) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400194 callback(!ec && !objectNames.empty());
195 },
Ratan Gupta22c33712019-05-03 21:50:28 +0530196 "xyz.openbmc_project.ObjectMapper",
197 "/xyz/openbmc_project/object_mapper",
198 "xyz.openbmc_project.ObjectMapper", "GetObject", path,
199 std::array<std::string, 0>());
200}
201
George Liu21384832022-11-09 11:21:15 +0800202inline void
George Liue99073f2022-12-09 11:06:16 +0800203 getSubTree(const std::string& path, int32_t depth,
204 std::span<const std::string_view> interfaces,
George Liu21384832022-11-09 11:21:15 +0800205 std::function<void(const boost::system::error_code&,
206 const MapperGetSubTreeResponse&)>&& callback)
207{
208 crow::connections::systemBus->async_method_call(
209 [callback{std::move(callback)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800210 const boost::system::error_code& ec,
George Liu21384832022-11-09 11:21:15 +0800211 const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); },
212 "xyz.openbmc_project.ObjectMapper",
213 "/xyz/openbmc_project/object_mapper",
George Liue99073f2022-12-09 11:06:16 +0800214 "xyz.openbmc_project.ObjectMapper", "GetSubTree", path, depth,
215 interfaces);
George Liu21384832022-11-09 11:21:15 +0800216}
217
218inline void getSubTreePaths(
George Liu7a1dbc42022-12-07 16:03:22 +0800219 const std::string& path, int32_t depth,
220 std::span<const std::string_view> interfaces,
George Liu21384832022-11-09 11:21:15 +0800221 std::function<void(const boost::system::error_code&,
222 const MapperGetSubTreePathsResponse&)>&& callback)
223{
224 crow::connections::systemBus->async_method_call(
225 [callback{std::move(callback)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800226 const boost::system::error_code& ec,
George Liu21384832022-11-09 11:21:15 +0800227 const MapperGetSubTreePathsResponse& subtreePaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400228 callback(ec, subtreePaths);
229 },
George Liu21384832022-11-09 11:21:15 +0800230 "xyz.openbmc_project.ObjectMapper",
231 "/xyz/openbmc_project/object_mapper",
George Liu7a1dbc42022-12-07 16:03:22 +0800232 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", path, depth,
George Liu21384832022-11-09 11:21:15 +0800233 interfaces);
234}
235
Willy Tu8d018362023-04-14 09:14:16 -0700236inline void getAssociatedSubTree(
237 const sdbusplus::message::object_path& associatedPath,
238 const sdbusplus::message::object_path& path, int32_t depth,
239 std::span<const std::string_view> interfaces,
240 std::function<void(const boost::system::error_code&,
241 const MapperGetSubTreeResponse&)>&& callback)
242{
243 crow::connections::systemBus->async_method_call(
244 [callback{std::move(callback)}](
245 const boost::system::error_code& ec,
246 const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); },
247 "xyz.openbmc_project.ObjectMapper",
248 "/xyz/openbmc_project/object_mapper",
249 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTree",
250 associatedPath, path, depth, interfaces);
251}
252
253inline void getAssociatedSubTreePaths(
254 const sdbusplus::message::object_path& associatedPath,
255 const sdbusplus::message::object_path& path, int32_t depth,
256 std::span<const std::string_view> interfaces,
257 std::function<void(const boost::system::error_code&,
258 const MapperGetSubTreePathsResponse&)>&& callback)
259{
260 crow::connections::systemBus->async_method_call(
261 [callback{std::move(callback)}](
262 const boost::system::error_code& ec,
263 const MapperGetSubTreePathsResponse& subtreePaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400264 callback(ec, subtreePaths);
265 },
Willy Tu8d018362023-04-14 09:14:16 -0700266 "xyz.openbmc_project.ObjectMapper",
267 "/xyz/openbmc_project/object_mapper",
268 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreePaths",
269 associatedPath, path, depth, interfaces);
270}
271
Lakshmi Yadlapati64d8e802024-06-26 17:41:19 -0500272inline void getAssociatedSubTreeById(
273 const std::string& id, const std::string& path,
274 std::span<const std::string_view> subtreeInterfaces,
275 std::string_view association,
276 std::span<const std::string_view> endpointInterfaces,
277 std::function<void(const boost::system::error_code&,
278 const MapperGetSubTreeResponse&)>&& callback)
279{
280 crow::connections::systemBus->async_method_call(
281 [callback{std::move(callback)}](
282 const boost::system::error_code& ec,
283 const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); },
284 "xyz.openbmc_project.ObjectMapper",
285 "/xyz/openbmc_project/object_mapper",
286 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreeById", id,
287 path, subtreeInterfaces, association, endpointInterfaces);
288}
289
290inline void getAssociatedSubTreePathsById(
291 const std::string& id, const std::string& path,
292 std::span<const std::string_view> subtreeInterfaces,
293 std::string_view association,
294 std::span<const std::string_view> endpointInterfaces,
295 std::function<void(const boost::system::error_code&,
296 const MapperGetSubTreePathsResponse&)>&& callback)
297{
298 crow::connections::systemBus->async_method_call(
299 [callback{std::move(callback)}](
300 const boost::system::error_code& ec,
301 const MapperGetSubTreePathsResponse& subtreePaths) {
302 callback(ec, subtreePaths);
303 },
304 "xyz.openbmc_project.ObjectMapper",
305 "/xyz/openbmc_project/object_mapper",
306 "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreePathsById", id,
307 path, subtreeInterfaces, association, endpointInterfaces);
308}
309
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400310inline void getDbusObject(
311 const std::string& path, std::span<const std::string_view> interfaces,
312 std::function<void(const boost::system::error_code&,
313 const MapperGetObject&)>&& callback)
George Liu2b731192023-01-11 16:27:13 +0800314{
315 crow::connections::systemBus->async_method_call(
316 [callback{std::move(callback)}](const boost::system::error_code& ec,
317 const MapperGetObject& object) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400318 callback(ec, object);
319 },
George Liu2b731192023-01-11 16:27:13 +0800320 "xyz.openbmc_project.ObjectMapper",
321 "/xyz/openbmc_project/object_mapper",
322 "xyz.openbmc_project.ObjectMapper", "GetObject", path, interfaces);
323}
324
George Liua4eb7612023-02-11 15:49:46 +0800325inline void getAssociationEndPoints(
326 const std::string& path,
327 std::function<void(const boost::system::error_code&,
328 const MapperEndPoints&)>&& callback)
329{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800330 getProperty<MapperEndPoints>("xyz.openbmc_project.ObjectMapper", path,
331 "xyz.openbmc_project.Association", "endpoints",
332 std::move(callback));
George Liua4eb7612023-02-11 15:49:46 +0800333}
334
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400335inline void getManagedObjects(
336 const std::string& service, const sdbusplus::message::object_path& path,
337 std::function<void(const boost::system::error_code&,
338 const ManagedObjectType&)>&& callback)
George Liuf5892d02023-03-01 10:37:08 +0800339{
340 crow::connections::systemBus->async_method_call(
341 [callback{std::move(callback)}](const boost::system::error_code& ec,
342 const ManagedObjectType& objects) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400343 callback(ec, objects);
344 },
George Liuf5892d02023-03-01 10:37:08 +0800345 service, path, "org.freedesktop.DBus.ObjectManager",
346 "GetManagedObjects");
347}
348
James Feist5b4aa862018-08-16 14:07:01 -0700349} // namespace utility
350} // namespace dbus