blob: 086ef99eeced1932057c5bb882b8aca0ac444c13 [file] [log] [blame]
Brad Bishop6e9cfdb2017-06-08 11:59:58 -04001#pragma once
2
Brad Bishop6e9cfdb2017-06-08 11:59:58 -04003#include <phosphor-logging/elog-errors.hpp>
Matthew Barth9e80c872020-05-26 10:50:29 -05004#include <phosphor-logging/elog.hpp>
Anwaar Hadi32c4fef2025-04-02 16:08:27 +00005#include <phosphor-logging/lg2.hpp>
Matthew Barth9e80c872020-05-26 10:50:29 -05006#include <sdbusplus/bus.hpp>
7#include <sdbusplus/bus/match.hpp>
8#include <sdbusplus/message.hpp>
Brad Bishop6e9cfdb2017-06-08 11:59:58 -04009#include <xyz/openbmc_project/Common/error.hpp>
10
Patrick Williamsfbf47032023-07-17 12:27:34 -050011#include <format>
12
Brad Bishop6e9cfdb2017-06-08 11:59:58 -040013namespace phosphor
14{
15namespace fan
16{
17namespace util
18{
19namespace detail
20{
21namespace errors = sdbusplus::xyz::openbmc_project::Common::Error;
22} // namespace detail
23
Matt Spinlerba7b5fe2018-04-25 15:26:10 -050024/**
25 * @class DBusError
26 *
27 * The base class for the exceptions thrown on fails in the various
28 * SDBusPlus calls. Used so that a single catch statement can catch
29 * any type of these exceptions.
30 *
31 * None of these exceptions will log anything when they are created,
32 * it is up to the handler to do that if desired.
33 */
34class DBusError : public std::runtime_error
35{
Matthew Barth9e80c872020-05-26 10:50:29 -050036 public:
Patrick Williams61b73292023-05-10 07:50:12 -050037 explicit DBusError(const std::string& msg) : std::runtime_error(msg) {}
Matt Spinlerba7b5fe2018-04-25 15:26:10 -050038};
39
40/**
41 * @class DBusMethodError
42 *
43 * Thrown on a DBus Method call failure
44 */
45class DBusMethodError : public DBusError
46{
Matthew Barth9e80c872020-05-26 10:50:29 -050047 public:
48 DBusMethodError(const std::string& busName, const std::string& path,
49 const std::string& interface, const std::string& method) :
Patrick Williamsfbf47032023-07-17 12:27:34 -050050 DBusError(std::format("DBus method failed: {} {} {} {}", busName, path,
Matt Spinler23f87572021-01-20 14:20:30 -060051 interface, method)),
Matthew Barth9e80c872020-05-26 10:50:29 -050052 busName(busName), path(path), interface(interface), method(method)
53 {}
Matt Spinlerba7b5fe2018-04-25 15:26:10 -050054
Matthew Barth9e80c872020-05-26 10:50:29 -050055 const std::string busName;
56 const std::string path;
57 const std::string interface;
58 const std::string method;
Matt Spinlerba7b5fe2018-04-25 15:26:10 -050059};
60
61/**
62 * @class DBusServiceError
63 *
64 * Thrown when a service lookup fails. Usually this points to
65 * the object path not being present in D-Bus.
66 */
67class DBusServiceError : public DBusError
68{
Matthew Barth9e80c872020-05-26 10:50:29 -050069 public:
70 DBusServiceError(const std::string& path, const std::string& interface) :
Matt Spinler23f87572021-01-20 14:20:30 -060071 DBusError(
Patrick Williamsfbf47032023-07-17 12:27:34 -050072 std::format("DBus service lookup failed: {} {}", path, interface)),
Matt Spinler23f87572021-01-20 14:20:30 -060073 path(path), interface(interface)
Matthew Barth9e80c872020-05-26 10:50:29 -050074 {}
Matt Spinlerba7b5fe2018-04-25 15:26:10 -050075
Matthew Barth9e80c872020-05-26 10:50:29 -050076 const std::string path;
77 const std::string interface;
Matt Spinlerba7b5fe2018-04-25 15:26:10 -050078};
79
Matthew Barth88923a02018-05-11 10:14:44 -050080/**
81 * @class DBusPropertyError
82 *
83 * Thrown when a set/get property fails.
84 */
85class DBusPropertyError : public DBusError
86{
Matthew Barth9e80c872020-05-26 10:50:29 -050087 public:
Matt Spinler23f87572021-01-20 14:20:30 -060088 DBusPropertyError(const std::string& msg, const std::string& busName,
Matthew Barth9e80c872020-05-26 10:50:29 -050089 const std::string& path, const std::string& interface,
90 const std::string& property) :
Patrick Williamsfbf47032023-07-17 12:27:34 -050091 DBusError(msg + std::format(": {} {} {} {}", busName, path, interface,
Matt Spinler23f87572021-01-20 14:20:30 -060092 property)),
Matthew Barth9e80c872020-05-26 10:50:29 -050093 busName(busName), path(path), interface(interface), property(property)
94 {}
Matthew Barth88923a02018-05-11 10:14:44 -050095
Matthew Barth9e80c872020-05-26 10:50:29 -050096 const std::string busName;
97 const std::string path;
98 const std::string interface;
99 const std::string property;
Matthew Barth88923a02018-05-11 10:14:44 -0500100};
101
Brad Bishop1e4922a2017-07-12 22:56:49 -0400102/** @brief Alias for PropertiesChanged signal callbacks. */
Matthew Barth9e80c872020-05-26 10:50:29 -0500103template <typename... T>
Patrick Williamsc21d0b32020-05-13 17:55:14 -0500104using Properties = std::map<std::string, std::variant<T...>>;
Brad Bishop1e4922a2017-07-12 22:56:49 -0400105
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400106/** @class SDBusPlus
107 * @brief DBus access delegate implementation for sdbusplus.
108 */
109class SDBusPlus
110{
Matthew Barth9e80c872020-05-26 10:50:29 -0500111 public:
112 /** @brief Get the bus connection. */
113 static auto& getBus() __attribute__((pure))
114 {
115 static auto bus = sdbusplus::bus::new_default();
116 return bus;
117 }
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400118
Matthew Barth9e80c872020-05-26 10:50:29 -0500119 /** @brief Invoke a method. */
120 template <typename... Args>
Patrick Williamscb356d42022-07-22 19:26:53 -0500121 static auto callMethod(sdbusplus::bus_t& bus, const std::string& busName,
Matthew Barth9e80c872020-05-26 10:50:29 -0500122 const std::string& path,
123 const std::string& interface,
124 const std::string& method, Args&&... args)
125 {
126 auto reqMsg = bus.new_method_call(busName.c_str(), path.c_str(),
127 interface.c_str(), method.c_str());
128 reqMsg.append(std::forward<Args>(args)...);
129 try
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400130 {
Matthew Barth9e80c872020-05-26 10:50:29 -0500131 auto respMsg = bus.call(reqMsg);
132 if (respMsg.is_method_error())
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400133 {
Matt Spinlerba7b5fe2018-04-25 15:26:10 -0500134 throw DBusMethodError{busName, path, interface, method};
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400135 }
Matthew Barth7c48d102018-05-09 14:52:36 -0500136 return respMsg;
137 }
Patrick Williamscb356d42022-07-22 19:26:53 -0500138 catch (const sdbusplus::exception_t&)
Matthew Barth9e80c872020-05-26 10:50:29 -0500139 {
140 throw DBusMethodError{busName, path, interface, method};
141 }
142 }
143
144 /** @brief Invoke a method. */
145 template <typename... Args>
146 static auto callMethod(const std::string& busName, const std::string& path,
147 const std::string& interface,
148 const std::string& method, Args&&... args)
149 {
150 return callMethod(getBus(), busName, path, interface, method,
151 std::forward<Args>(args)...);
152 }
153
154 /** @brief Invoke a method and read the response. */
155 template <typename Ret, typename... Args>
Patrick Williams4fa67aa2025-02-03 14:28:47 -0500156 static auto callMethodAndRead(
157 sdbusplus::bus_t& bus, const std::string& busName,
158 const std::string& path, const std::string& interface,
159 const std::string& method, Args&&... args)
Matthew Barth9e80c872020-05-26 10:50:29 -0500160 {
Patrick Williamscb356d42022-07-22 19:26:53 -0500161 sdbusplus::message_t respMsg = callMethod<Args...>(
Matthew Barth9e80c872020-05-26 10:50:29 -0500162 bus, busName, path, interface, method, std::forward<Args>(args)...);
163 Ret resp;
164 respMsg.read(resp);
165 return resp;
166 }
167
168 /** @brief Invoke a method and read the response. */
169 template <typename Ret, typename... Args>
Patrick Williamsdfddd642024-08-16 15:21:51 -0400170 static auto callMethodAndRead(
171 const std::string& busName, const std::string& path,
172 const std::string& interface, const std::string& method, Args&&... args)
Matthew Barth9e80c872020-05-26 10:50:29 -0500173 {
174 return callMethodAndRead<Ret>(getBus(), busName, path, interface,
175 method, std::forward<Args>(args)...);
176 }
177
178 /** @brief Get subtree from the mapper without checking response. */
Patrick Williamscb356d42022-07-22 19:26:53 -0500179 static auto getSubTreeRaw(sdbusplus::bus_t& bus, const std::string& path,
Matthew Barth9e80c872020-05-26 10:50:29 -0500180 const std::string& interface, int32_t depth)
181 {
182 using namespace std::literals::string_literals;
183
184 using Path = std::string;
185 using Intf = std::string;
186 using Serv = std::string;
187 using Intfs = std::vector<Intf>;
188 using Objects = std::map<Path, std::map<Serv, Intfs>>;
189 Intfs intfs = {interface};
190
Patrick Williamsdfddd642024-08-16 15:21:51 -0400191 return callMethodAndRead<Objects>(
192 bus, "xyz.openbmc_project.ObjectMapper"s,
193 "/xyz/openbmc_project/object_mapper"s,
194 "xyz.openbmc_project.ObjectMapper"s, "GetSubTree"s, path, depth,
195 intfs);
Matthew Barth9e80c872020-05-26 10:50:29 -0500196 }
197
Mike Capps7a401a22021-07-12 13:59:31 -0400198 /** @brief Get subtree from the mapper without checking response,
199 * (multiple interfaces version). */
Patrick Williamscb356d42022-07-22 19:26:53 -0500200 static auto getSubTreeRaw(sdbusplus::bus_t& bus, const std::string& path,
Mike Capps7a401a22021-07-12 13:59:31 -0400201 const std::vector<std::string>& intfs,
202 int32_t depth)
203 {
204 using namespace std::literals::string_literals;
205
206 using Path = std::string;
207 using Intf = std::string;
208 using Serv = std::string;
209 using Intfs = std::vector<Intf>;
210 using Objects = std::map<Path, std::map<Serv, Intfs>>;
211
Patrick Williamsdfddd642024-08-16 15:21:51 -0400212 return callMethodAndRead<Objects>(
213 bus, "xyz.openbmc_project.ObjectMapper"s,
214 "/xyz/openbmc_project/object_mapper"s,
215 "xyz.openbmc_project.ObjectMapper"s, "GetSubTree"s, path, depth,
216 intfs);
Mike Capps7a401a22021-07-12 13:59:31 -0400217 }
218
Matthew Barth9e80c872020-05-26 10:50:29 -0500219 /** @brief Get subtree from the mapper. */
Patrick Williamscb356d42022-07-22 19:26:53 -0500220 static auto getSubTree(sdbusplus::bus_t& bus, const std::string& path,
Matthew Barth9e80c872020-05-26 10:50:29 -0500221 const std::string& interface, int32_t depth)
222 {
223 auto mapperResp = getSubTreeRaw(bus, path, interface, depth);
224 if (mapperResp.empty())
225 {
Anwaar Hadi32c4fef2025-04-02 16:08:27 +0000226 lg2::error(
227 "Empty response from mapper GetSubTree, SubTree={SUBTREE}, Interface={INTERFACE}, Depth={DEPTH}",
228 "SUBTREE", path, "INTERFACE", interface, "DEPTH", depth);
Matthew Barth9e80c872020-05-26 10:50:29 -0500229 phosphor::logging::elog<detail::errors::InternalFailure>();
230 }
231 return mapperResp;
232 }
233
Matthew Barthfcbdc0e2020-10-28 14:11:07 -0500234 /** @brief Get subtree paths from the mapper without checking response. */
Patrick Williamscb356d42022-07-22 19:26:53 -0500235 static auto getSubTreePathsRaw(sdbusplus::bus_t& bus,
Matthew Barthfcbdc0e2020-10-28 14:11:07 -0500236 const std::string& path,
237 const std::string& interface, int32_t depth)
238 {
239 using namespace std::literals::string_literals;
240
241 using Path = std::string;
242 using Intf = std::string;
243 using Intfs = std::vector<Intf>;
244 using ObjectPaths = std::vector<Path>;
245 Intfs intfs = {interface};
246
247 return callMethodAndRead<ObjectPaths>(
248 bus, "xyz.openbmc_project.ObjectMapper"s,
249 "/xyz/openbmc_project/object_mapper"s,
250 "xyz.openbmc_project.ObjectMapper"s, "GetSubTreePaths"s, path,
251 depth, intfs);
252 }
253
254 /** @brief Get subtree paths from the mapper. */
Patrick Williamscb356d42022-07-22 19:26:53 -0500255 static auto getSubTreePaths(sdbusplus::bus_t& bus, const std::string& path,
Matthew Barthfcbdc0e2020-10-28 14:11:07 -0500256 const std::string& interface, int32_t depth)
257 {
258 auto mapperResp = getSubTreePathsRaw(bus, path, interface, depth);
259 if (mapperResp.empty())
260 {
Anwaar Hadi32c4fef2025-04-02 16:08:27 +0000261 lg2::error(
262 "Empty response from mapper GetSubTreePaths, SubTree={SUBTREE}, Interface={INTERFACE}, Depth={DEPTH}",
263 "SUBTREE", path, "INTERFACE", interface, "DEPTH", depth);
Matthew Barthfcbdc0e2020-10-28 14:11:07 -0500264 phosphor::logging::elog<detail::errors::InternalFailure>();
265 }
266 return mapperResp;
267 }
268
Mike Cappsce6820a2021-05-26 10:40:19 -0400269 /** @brief Get service from the mapper without checking response. */
Patrick Williamscb356d42022-07-22 19:26:53 -0500270 static auto getServiceRaw(sdbusplus::bus_t& bus, const std::string& path,
Mike Cappsce6820a2021-05-26 10:40:19 -0400271 const std::string& interface)
Matthew Barth9e80c872020-05-26 10:50:29 -0500272 {
273 using namespace std::literals::string_literals;
274 using GetObject = std::map<std::string, std::vector<std::string>>;
275
Mike Cappsce6820a2021-05-26 10:40:19 -0400276 return callMethodAndRead<GetObject>(
277 bus, "xyz.openbmc_project.ObjectMapper"s,
278 "/xyz/openbmc_project/object_mapper"s,
279 "xyz.openbmc_project.ObjectMapper"s, "GetObject"s, path,
280 GetObject::mapped_type{interface});
281 }
282
283 /** @brief Get service from the mapper. */
Patrick Williamscb356d42022-07-22 19:26:53 -0500284 static auto getService(sdbusplus::bus_t& bus, const std::string& path,
Mike Cappsce6820a2021-05-26 10:40:19 -0400285 const std::string& interface)
286 {
Matthew Barth9e80c872020-05-26 10:50:29 -0500287 try
288 {
Mike Cappsce6820a2021-05-26 10:40:19 -0400289 auto mapperResp = getServiceRaw(bus, path, interface);
Matthew Barth9e80c872020-05-26 10:50:29 -0500290
291 if (mapperResp.empty())
292 {
293 // Should never happen. A missing object would fail
294 // in callMethodAndRead()
Anwaar Hadi32c4fef2025-04-02 16:08:27 +0000295 lg2::error("Empty mapper response on service lookup");
Matthew Barth9e80c872020-05-26 10:50:29 -0500296 throw DBusServiceError{path, interface};
297 }
298 return mapperResp.begin()->first;
299 }
Patrick Williamsddb773b2021-10-06 11:24:49 -0500300 catch (const DBusMethodError& e)
Matthew Barth9e80c872020-05-26 10:50:29 -0500301 {
302 throw DBusServiceError{path, interface};
303 }
304 }
305
306 /** @brief Get service from the mapper. */
307 static auto getService(const std::string& path,
308 const std::string& interface)
309 {
310 return getService(getBus(), path, interface);
311 }
312
Matthew Bartha3553632021-05-03 14:40:59 -0500313 /** @brief Get managed objects. */
314 template <typename Variant>
Patrick Williamscb356d42022-07-22 19:26:53 -0500315 static auto getManagedObjects(sdbusplus::bus_t& bus,
Matthew Bartha3553632021-05-03 14:40:59 -0500316 const std::string& service,
317 const std::string& path)
318 {
319 using namespace std::literals::string_literals;
320
321 using Path = sdbusplus::message::object_path;
322 using Intf = std::string;
323 using Prop = std::string;
324 using GetManagedObjects =
325 std::map<Path, std::map<Intf, std::map<Prop, Variant>>>;
326
327 return callMethodAndRead<GetManagedObjects>(
328 bus, service, path, "org.freedesktop.DBus.ObjectManager"s,
329 "GetManagedObjects"s);
330 }
331
Matthew Barth9e80c872020-05-26 10:50:29 -0500332 /** @brief Get a property with mapper lookup. */
333 template <typename Property>
Patrick Williamscb356d42022-07-22 19:26:53 -0500334 static auto getProperty(sdbusplus::bus_t& bus, const std::string& path,
Matthew Barth9e80c872020-05-26 10:50:29 -0500335 const std::string& interface,
336 const std::string& property)
337 {
338 using namespace std::literals::string_literals;
339
340 auto service = getService(bus, path, interface);
Patrick Williamsdfddd642024-08-16 15:21:51 -0400341 auto msg =
342 callMethod(bus, service, path, "org.freedesktop.DBus.Properties"s,
343 "Get"s, interface, property);
Matthew Barth9e80c872020-05-26 10:50:29 -0500344 if (msg.is_method_error())
345 {
346 throw DBusPropertyError{"DBus get property failed", service, path,
347 interface, property};
348 }
349 std::variant<Property> value;
350 msg.read(value);
351 return std::get<Property>(value);
352 }
353
354 /** @brief Get a property with mapper lookup. */
355 template <typename Property>
356 static auto getProperty(const std::string& path,
357 const std::string& interface,
358 const std::string& property)
359 {
360 return getProperty<Property>(getBus(), path, interface, property);
361 }
362
363 /** @brief Get a property variant with mapper lookup. */
364 template <typename Variant>
Patrick Williamsdfddd642024-08-16 15:21:51 -0400365 static auto getPropertyVariant(
366 sdbusplus::bus_t& bus, const std::string& path,
367 const std::string& interface, const std::string& property)
Matthew Barth9e80c872020-05-26 10:50:29 -0500368 {
369 using namespace std::literals::string_literals;
370
371 auto service = getService(bus, path, interface);
Patrick Williamsdfddd642024-08-16 15:21:51 -0400372 auto msg =
373 callMethod(bus, service, path, "org.freedesktop.DBus.Properties"s,
374 "Get"s, interface, property);
Matthew Barth9e80c872020-05-26 10:50:29 -0500375 if (msg.is_method_error())
376 {
377 throw DBusPropertyError{"DBus get property variant failed", service,
378 path, interface, property};
379 }
380 Variant value;
381 msg.read(value);
382 return value;
383 }
384
385 /** @brief Get a property variant with mapper lookup. */
386 template <typename Variant>
387 static auto getPropertyVariant(const std::string& path,
388 const std::string& interface,
389 const std::string& property)
390 {
391 return getPropertyVariant<Variant>(getBus(), path, interface, property);
392 }
393
Mike Capps808d7fe2022-06-13 10:12:16 -0400394 /** @brief Invoke a method and return without checking for error. */
395 template <typename... Args>
Patrick Williamsdfddd642024-08-16 15:21:51 -0400396 static auto callMethodAndReturn(
397 sdbusplus::bus_t& bus, const std::string& busName,
398 const std::string& path, const std::string& interface,
399 const std::string& method, Args&&... args)
Mike Capps808d7fe2022-06-13 10:12:16 -0400400 {
401 auto reqMsg = bus.new_method_call(busName.c_str(), path.c_str(),
402 interface.c_str(), method.c_str());
403 reqMsg.append(std::forward<Args>(args)...);
404 auto respMsg = bus.call(reqMsg);
405
406 return respMsg;
407 }
408
Matthew Barth9e80c872020-05-26 10:50:29 -0500409 /** @brief Get a property without mapper lookup. */
410 template <typename Property>
Patrick Williamscb356d42022-07-22 19:26:53 -0500411 static auto getProperty(sdbusplus::bus_t& bus, const std::string& service,
412 const std::string& path,
Matthew Barth9e80c872020-05-26 10:50:29 -0500413 const std::string& interface,
414 const std::string& property)
415 {
416 using namespace std::literals::string_literals;
417
418 auto msg = callMethodAndReturn(bus, service, path,
419 "org.freedesktop.DBus.Properties"s,
420 "Get"s, interface, property);
421 if (msg.is_method_error())
422 {
423 throw DBusPropertyError{"DBus get property failed", service, path,
424 interface, property};
425 }
426 std::variant<Property> value;
427 msg.read(value);
428 return std::get<Property>(value);
429 }
430
431 /** @brief Get a property without mapper lookup. */
432 template <typename Property>
433 static auto getProperty(const std::string& service, const std::string& path,
434 const std::string& interface,
435 const std::string& property)
436 {
437 return getProperty<Property>(getBus(), service, path, interface,
438 property);
439 }
440
441 /** @brief Get a property variant without mapper lookup. */
442 template <typename Variant>
Patrick Williamsdfddd642024-08-16 15:21:51 -0400443 static auto getPropertyVariant(
444 sdbusplus::bus_t& bus, const std::string& service,
445 const std::string& path, const std::string& interface,
446 const std::string& property)
Matthew Barth9e80c872020-05-26 10:50:29 -0500447 {
448 using namespace std::literals::string_literals;
449
450 auto msg = callMethodAndReturn(bus, service, path,
451 "org.freedesktop.DBus.Properties"s,
452 "Get"s, interface, property);
453 if (msg.is_method_error())
454 {
455 throw DBusPropertyError{"DBus get property variant failed", service,
456 path, interface, property};
457 }
458 Variant value;
459 msg.read(value);
460 return value;
461 }
462
463 /** @brief Get a property variant without mapper lookup. */
464 template <typename Variant>
Patrick Williamsdfddd642024-08-16 15:21:51 -0400465 static auto getPropertyVariant(
466 const std::string& service, const std::string& path,
467 const std::string& interface, const std::string& property)
Matthew Barth9e80c872020-05-26 10:50:29 -0500468 {
469 return getPropertyVariant<Variant>(getBus(), service, path, interface,
470 property);
471 }
472
473 /** @brief Set a property with mapper lookup. */
474 template <typename Property>
Patrick Williamscb356d42022-07-22 19:26:53 -0500475 static void setProperty(sdbusplus::bus_t& bus, const std::string& path,
Matthew Barth9e80c872020-05-26 10:50:29 -0500476 const std::string& interface,
477 const std::string& property, Property&& value)
478 {
479 using namespace std::literals::string_literals;
480
481 std::variant<Property> varValue(std::forward<Property>(value));
482
483 auto service = getService(bus, path, interface);
484 auto msg = callMethodAndReturn(bus, service, path,
485 "org.freedesktop.DBus.Properties"s,
486 "Set"s, interface, property, varValue);
487 if (msg.is_method_error())
488 {
489 throw DBusPropertyError{"DBus set property failed", service, path,
490 interface, property};
491 }
492 }
493
494 /** @brief Set a property with mapper lookup. */
495 template <typename Property>
496 static void setProperty(const std::string& path,
497 const std::string& interface,
498 const std::string& property, Property&& value)
499 {
500 return setProperty(getBus(), path, interface, property,
501 std::forward<Property>(value));
502 }
503
504 /** @brief Set a property without mapper lookup. */
505 template <typename Property>
Patrick Williamscb356d42022-07-22 19:26:53 -0500506 static void setProperty(sdbusplus::bus_t& bus, const std::string& service,
507 const std::string& path,
Matthew Barth9e80c872020-05-26 10:50:29 -0500508 const std::string& interface,
509 const std::string& property, Property&& value)
510 {
511 using namespace std::literals::string_literals;
512
513 std::variant<Property> varValue(std::forward<Property>(value));
514
515 auto msg = callMethodAndReturn(bus, service, path,
516 "org.freedesktop.DBus.Properties"s,
517 "Set"s, interface, property, varValue);
518 if (msg.is_method_error())
519 {
520 throw DBusPropertyError{"DBus set property failed", service, path,
521 interface, property};
522 }
523 }
524
525 /** @brief Set a property without mapper lookup. */
526 template <typename Property>
527 static void setProperty(const std::string& service, const std::string& path,
528 const std::string& interface,
529 const std::string& property, Property&& value)
530 {
531 return setProperty(getBus(), service, path, interface, property,
532 std::forward<Property>(value));
533 }
534
535 /** @brief Invoke method with mapper lookup. */
536 template <typename... Args>
Patrick Williamsdfddd642024-08-16 15:21:51 -0400537 static auto lookupAndCallMethod(
538 sdbusplus::bus_t& bus, const std::string& path,
539 const std::string& interface, const std::string& method, Args&&... args)
Matthew Barth9e80c872020-05-26 10:50:29 -0500540 {
541 return callMethod(bus, getService(bus, path, interface), path,
542 interface, method, std::forward<Args>(args)...);
543 }
544
545 /** @brief Invoke method with mapper lookup. */
546 template <typename... Args>
547 static auto lookupAndCallMethod(const std::string& path,
548 const std::string& interface,
549 const std::string& method, Args&&... args)
550 {
551 return lookupAndCallMethod(getBus(), path, interface, method,
552 std::forward<Args>(args)...);
553 }
554
555 /** @brief Invoke method and read with mapper lookup. */
556 template <typename Ret, typename... Args>
Patrick Williamsdfddd642024-08-16 15:21:51 -0400557 static auto lookupCallMethodAndRead(
558 sdbusplus::bus_t& bus, const std::string& path,
559 const std::string& interface, const std::string& method, Args&&... args)
Matthew Barth9e80c872020-05-26 10:50:29 -0500560 {
561 return callMethodAndRead(bus, getService(bus, path, interface), path,
562 interface, method,
563 std::forward<Args>(args)...);
564 }
565
566 /** @brief Invoke method and read with mapper lookup. */
567 template <typename Ret, typename... Args>
Patrick Williamsdfddd642024-08-16 15:21:51 -0400568 static auto lookupCallMethodAndRead(
569 const std::string& path, const std::string& interface,
570 const std::string& method, Args&&... args)
Matthew Barth9e80c872020-05-26 10:50:29 -0500571 {
572 return lookupCallMethodAndRead<Ret>(getBus(), path, interface, method,
573 std::forward<Args>(args)...);
574 }
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400575};
576
577} // namespace util
578} // namespace fan
579} // namespace phosphor