blob: 759f907ab9011478ff1fe33d22ef38d501f92ffb [file] [log] [blame]
Brad Bishop6e9cfdb2017-06-08 11:59:58 -04001#pragma once
2
Matt Spinler23f87572021-01-20 14:20:30 -06003#include <fmt/format.h>
4
Brad Bishop6e9cfdb2017-06-08 11:59:58 -04005#include <phosphor-logging/elog-errors.hpp>
Matthew Barth9e80c872020-05-26 10:50:29 -05006#include <phosphor-logging/elog.hpp>
7#include <phosphor-logging/log.hpp>
8#include <sdbusplus/bus.hpp>
9#include <sdbusplus/bus/match.hpp>
10#include <sdbusplus/message.hpp>
Brad Bishop6e9cfdb2017-06-08 11:59:58 -040011#include <xyz/openbmc_project/Common/error.hpp>
12
13namespace 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:
Matt Spinler23f87572021-01-20 14:20:30 -060037 explicit DBusError(const std::string& msg) : std::runtime_error(msg)
Matthew Barth9e80c872020-05-26 10:50:29 -050038 {}
Matt Spinlerba7b5fe2018-04-25 15:26:10 -050039};
40
41/**
42 * @class DBusMethodError
43 *
44 * Thrown on a DBus Method call failure
45 */
46class DBusMethodError : public DBusError
47{
Matthew Barth9e80c872020-05-26 10:50:29 -050048 public:
49 DBusMethodError(const std::string& busName, const std::string& path,
50 const std::string& interface, const std::string& method) :
Matt Spinler23f87572021-01-20 14:20:30 -060051 DBusError(fmt::format("DBus method failed: {} {} {} {}", busName, path,
52 interface, method)),
Matthew Barth9e80c872020-05-26 10:50:29 -050053 busName(busName), path(path), interface(interface), method(method)
54 {}
Matt Spinlerba7b5fe2018-04-25 15:26:10 -050055
Matthew Barth9e80c872020-05-26 10:50:29 -050056 const std::string busName;
57 const std::string path;
58 const std::string interface;
59 const std::string method;
Matt Spinlerba7b5fe2018-04-25 15:26:10 -050060};
61
62/**
63 * @class DBusServiceError
64 *
65 * Thrown when a service lookup fails. Usually this points to
66 * the object path not being present in D-Bus.
67 */
68class DBusServiceError : public DBusError
69{
Matthew Barth9e80c872020-05-26 10:50:29 -050070 public:
71 DBusServiceError(const std::string& path, const std::string& interface) :
Matt Spinler23f87572021-01-20 14:20:30 -060072 DBusError(
73 fmt::format("DBus service lookup failed: {} {}", path, interface)),
74 path(path), interface(interface)
Matthew Barth9e80c872020-05-26 10:50:29 -050075 {}
Matt Spinlerba7b5fe2018-04-25 15:26:10 -050076
Matthew Barth9e80c872020-05-26 10:50:29 -050077 const std::string path;
78 const std::string interface;
Matt Spinlerba7b5fe2018-04-25 15:26:10 -050079};
80
Matthew Barth88923a02018-05-11 10:14:44 -050081/**
82 * @class DBusPropertyError
83 *
84 * Thrown when a set/get property fails.
85 */
86class DBusPropertyError : public DBusError
87{
Matthew Barth9e80c872020-05-26 10:50:29 -050088 public:
Matt Spinler23f87572021-01-20 14:20:30 -060089 DBusPropertyError(const std::string& msg, const std::string& busName,
Matthew Barth9e80c872020-05-26 10:50:29 -050090 const std::string& path, const std::string& interface,
91 const std::string& property) :
Matt Spinler23f87572021-01-20 14:20:30 -060092 DBusError(msg + fmt::format(": {} {} {} {}", busName, path, interface,
93 property)),
Matthew Barth9e80c872020-05-26 10:50:29 -050094 busName(busName), path(path), interface(interface), property(property)
95 {}
Matthew Barth88923a02018-05-11 10:14:44 -050096
Matthew Barth9e80c872020-05-26 10:50:29 -050097 const std::string busName;
98 const std::string path;
99 const std::string interface;
100 const std::string property;
Matthew Barth88923a02018-05-11 10:14:44 -0500101};
102
Brad Bishop1e4922a2017-07-12 22:56:49 -0400103/** @brief Alias for PropertiesChanged signal callbacks. */
Matthew Barth9e80c872020-05-26 10:50:29 -0500104template <typename... T>
Patrick Williamsc21d0b32020-05-13 17:55:14 -0500105using Properties = std::map<std::string, std::variant<T...>>;
Brad Bishop1e4922a2017-07-12 22:56:49 -0400106
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400107/** @class SDBusPlus
108 * @brief DBus access delegate implementation for sdbusplus.
109 */
110class SDBusPlus
111{
112
Matthew Barth9e80c872020-05-26 10:50:29 -0500113 public:
114 /** @brief Get the bus connection. */
115 static auto& getBus() __attribute__((pure))
116 {
117 static auto bus = sdbusplus::bus::new_default();
118 return bus;
119 }
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400120
Matthew Barth9e80c872020-05-26 10:50:29 -0500121 /** @brief Invoke a method. */
122 template <typename... Args>
Patrick Williamscb356d42022-07-22 19:26:53 -0500123 static auto callMethod(sdbusplus::bus_t& bus, const std::string& busName,
Matthew Barth9e80c872020-05-26 10:50:29 -0500124 const std::string& path,
125 const std::string& interface,
126 const std::string& method, Args&&... args)
127 {
128 auto reqMsg = bus.new_method_call(busName.c_str(), path.c_str(),
129 interface.c_str(), method.c_str());
130 reqMsg.append(std::forward<Args>(args)...);
131 try
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400132 {
Matthew Barth9e80c872020-05-26 10:50:29 -0500133 auto respMsg = bus.call(reqMsg);
134 if (respMsg.is_method_error())
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400135 {
Matt Spinlerba7b5fe2018-04-25 15:26:10 -0500136 throw DBusMethodError{busName, path, interface, method};
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400137 }
Matthew Barth7c48d102018-05-09 14:52:36 -0500138 return respMsg;
139 }
Patrick Williamscb356d42022-07-22 19:26:53 -0500140 catch (const sdbusplus::exception_t&)
Matthew Barth9e80c872020-05-26 10:50:29 -0500141 {
142 throw DBusMethodError{busName, path, interface, method};
143 }
144 }
145
146 /** @brief Invoke a method. */
147 template <typename... Args>
148 static auto callMethod(const std::string& busName, const std::string& path,
149 const std::string& interface,
150 const std::string& method, Args&&... args)
151 {
152 return callMethod(getBus(), busName, path, interface, method,
153 std::forward<Args>(args)...);
154 }
155
156 /** @brief Invoke a method and read the response. */
157 template <typename Ret, typename... Args>
158 static auto
Patrick Williamscb356d42022-07-22 19:26:53 -0500159 callMethodAndRead(sdbusplus::bus_t& bus, const std::string& busName,
Matthew Barth9e80c872020-05-26 10:50:29 -0500160 const std::string& path, const std::string& interface,
161 const std::string& method, Args&&... args)
162 {
Patrick Williamscb356d42022-07-22 19:26:53 -0500163 sdbusplus::message_t respMsg = callMethod<Args...>(
Matthew Barth9e80c872020-05-26 10:50:29 -0500164 bus, busName, path, interface, method, std::forward<Args>(args)...);
165 Ret resp;
166 respMsg.read(resp);
167 return resp;
168 }
169
170 /** @brief Invoke a method and read the response. */
171 template <typename Ret, typename... Args>
172 static auto callMethodAndRead(const std::string& busName,
173 const std::string& path,
174 const std::string& interface,
175 const std::string& method, Args&&... args)
176 {
177 return callMethodAndRead<Ret>(getBus(), busName, path, interface,
178 method, std::forward<Args>(args)...);
179 }
180
181 /** @brief Get subtree from the mapper without checking response. */
Patrick Williamscb356d42022-07-22 19:26:53 -0500182 static auto getSubTreeRaw(sdbusplus::bus_t& bus, const std::string& path,
Matthew Barth9e80c872020-05-26 10:50:29 -0500183 const std::string& interface, int32_t depth)
184 {
185 using namespace std::literals::string_literals;
186
187 using Path = std::string;
188 using Intf = std::string;
189 using Serv = std::string;
190 using Intfs = std::vector<Intf>;
191 using Objects = std::map<Path, std::map<Serv, Intfs>>;
192 Intfs intfs = {interface};
193
194 return callMethodAndRead<Objects>(bus,
195 "xyz.openbmc_project.ObjectMapper"s,
196 "/xyz/openbmc_project/object_mapper"s,
197 "xyz.openbmc_project.ObjectMapper"s,
198 "GetSubTree"s, path, depth, intfs);
199 }
200
Mike Capps7a401a22021-07-12 13:59:31 -0400201 /** @brief Get subtree from the mapper without checking response,
202 * (multiple interfaces version). */
Patrick Williamscb356d42022-07-22 19:26:53 -0500203 static auto getSubTreeRaw(sdbusplus::bus_t& bus, const std::string& path,
Mike Capps7a401a22021-07-12 13:59:31 -0400204 const std::vector<std::string>& intfs,
205 int32_t depth)
206 {
207 using namespace std::literals::string_literals;
208
209 using Path = std::string;
210 using Intf = std::string;
211 using Serv = std::string;
212 using Intfs = std::vector<Intf>;
213 using Objects = std::map<Path, std::map<Serv, Intfs>>;
214
215 return callMethodAndRead<Objects>(bus,
216 "xyz.openbmc_project.ObjectMapper"s,
217 "/xyz/openbmc_project/object_mapper"s,
218 "xyz.openbmc_project.ObjectMapper"s,
219 "GetSubTree"s, path, depth, intfs);
220 }
221
Matthew Barth9e80c872020-05-26 10:50:29 -0500222 /** @brief Get subtree from the mapper. */
Patrick Williamscb356d42022-07-22 19:26:53 -0500223 static auto getSubTree(sdbusplus::bus_t& bus, const std::string& path,
Matthew Barth9e80c872020-05-26 10:50:29 -0500224 const std::string& interface, int32_t depth)
225 {
226 auto mapperResp = getSubTreeRaw(bus, path, interface, depth);
227 if (mapperResp.empty())
228 {
229 phosphor::logging::log<phosphor::logging::level::ERR>(
230 "Empty response from mapper GetSubTree",
231 phosphor::logging::entry("SUBTREE=%s", path.c_str()),
232 phosphor::logging::entry("INTERFACE=%s", interface.c_str()),
233 phosphor::logging::entry("DEPTH=%u", depth));
234 phosphor::logging::elog<detail::errors::InternalFailure>();
235 }
236 return mapperResp;
237 }
238
Matthew Barthfcbdc0e2020-10-28 14:11:07 -0500239 /** @brief Get subtree paths from the mapper without checking response. */
Patrick Williamscb356d42022-07-22 19:26:53 -0500240 static auto getSubTreePathsRaw(sdbusplus::bus_t& bus,
Matthew Barthfcbdc0e2020-10-28 14:11:07 -0500241 const std::string& path,
242 const std::string& interface, int32_t depth)
243 {
244 using namespace std::literals::string_literals;
245
246 using Path = std::string;
247 using Intf = std::string;
248 using Intfs = std::vector<Intf>;
249 using ObjectPaths = std::vector<Path>;
250 Intfs intfs = {interface};
251
252 return callMethodAndRead<ObjectPaths>(
253 bus, "xyz.openbmc_project.ObjectMapper"s,
254 "/xyz/openbmc_project/object_mapper"s,
255 "xyz.openbmc_project.ObjectMapper"s, "GetSubTreePaths"s, path,
256 depth, intfs);
257 }
258
259 /** @brief Get subtree paths from the mapper. */
Patrick Williamscb356d42022-07-22 19:26:53 -0500260 static auto getSubTreePaths(sdbusplus::bus_t& bus, const std::string& path,
Matthew Barthfcbdc0e2020-10-28 14:11:07 -0500261 const std::string& interface, int32_t depth)
262 {
263 auto mapperResp = getSubTreePathsRaw(bus, path, interface, depth);
264 if (mapperResp.empty())
265 {
266 phosphor::logging::log<phosphor::logging::level::ERR>(
267 "Empty response from mapper GetSubTreePaths",
268 phosphor::logging::entry("SUBTREE=%s", path.c_str()),
269 phosphor::logging::entry("INTERFACE=%s", interface.c_str()),
270 phosphor::logging::entry("DEPTH=%u", depth));
271 phosphor::logging::elog<detail::errors::InternalFailure>();
272 }
273 return mapperResp;
274 }
275
Mike Cappsce6820a2021-05-26 10:40:19 -0400276 /** @brief Get service from the mapper without checking response. */
Patrick Williamscb356d42022-07-22 19:26:53 -0500277 static auto getServiceRaw(sdbusplus::bus_t& bus, const std::string& path,
Mike Cappsce6820a2021-05-26 10:40:19 -0400278 const std::string& interface)
Matthew Barth9e80c872020-05-26 10:50:29 -0500279 {
280 using namespace std::literals::string_literals;
281 using GetObject = std::map<std::string, std::vector<std::string>>;
282
Mike Cappsce6820a2021-05-26 10:40:19 -0400283 return callMethodAndRead<GetObject>(
284 bus, "xyz.openbmc_project.ObjectMapper"s,
285 "/xyz/openbmc_project/object_mapper"s,
286 "xyz.openbmc_project.ObjectMapper"s, "GetObject"s, path,
287 GetObject::mapped_type{interface});
288 }
289
290 /** @brief Get service from the mapper. */
Patrick Williamscb356d42022-07-22 19:26:53 -0500291 static auto getService(sdbusplus::bus_t& bus, const std::string& path,
Mike Cappsce6820a2021-05-26 10:40:19 -0400292 const std::string& interface)
293 {
Matthew Barth9e80c872020-05-26 10:50:29 -0500294 try
295 {
Mike Cappsce6820a2021-05-26 10:40:19 -0400296 auto mapperResp = getServiceRaw(bus, path, interface);
Matthew Barth9e80c872020-05-26 10:50:29 -0500297
298 if (mapperResp.empty())
299 {
300 // Should never happen. A missing object would fail
301 // in callMethodAndRead()
302 phosphor::logging::log<phosphor::logging::level::ERR>(
303 "Empty mapper response on service lookup");
304 throw DBusServiceError{path, interface};
305 }
306 return mapperResp.begin()->first;
307 }
Patrick Williamsddb773b2021-10-06 11:24:49 -0500308 catch (const DBusMethodError& e)
Matthew Barth9e80c872020-05-26 10:50:29 -0500309 {
310 throw DBusServiceError{path, interface};
311 }
312 }
313
314 /** @brief Get service from the mapper. */
315 static auto getService(const std::string& path,
316 const std::string& interface)
317 {
318 return getService(getBus(), path, interface);
319 }
320
Matthew Bartha3553632021-05-03 14:40:59 -0500321 /** @brief Get managed objects. */
322 template <typename Variant>
Patrick Williamscb356d42022-07-22 19:26:53 -0500323 static auto getManagedObjects(sdbusplus::bus_t& bus,
Matthew Bartha3553632021-05-03 14:40:59 -0500324 const std::string& service,
325 const std::string& path)
326 {
327 using namespace std::literals::string_literals;
328
329 using Path = sdbusplus::message::object_path;
330 using Intf = std::string;
331 using Prop = std::string;
332 using GetManagedObjects =
333 std::map<Path, std::map<Intf, std::map<Prop, Variant>>>;
334
335 return callMethodAndRead<GetManagedObjects>(
336 bus, service, path, "org.freedesktop.DBus.ObjectManager"s,
337 "GetManagedObjects"s);
338 }
339
Matthew Barth9e80c872020-05-26 10:50:29 -0500340 /** @brief Get a property with mapper lookup. */
341 template <typename Property>
Patrick Williamscb356d42022-07-22 19:26:53 -0500342 static auto getProperty(sdbusplus::bus_t& bus, const std::string& path,
Matthew Barth9e80c872020-05-26 10:50:29 -0500343 const std::string& interface,
344 const std::string& property)
345 {
346 using namespace std::literals::string_literals;
347
348 auto service = getService(bus, path, interface);
349 auto msg =
350 callMethod(bus, service, path, "org.freedesktop.DBus.Properties"s,
351 "Get"s, interface, property);
352 if (msg.is_method_error())
353 {
354 throw DBusPropertyError{"DBus get property failed", service, path,
355 interface, property};
356 }
357 std::variant<Property> value;
358 msg.read(value);
359 return std::get<Property>(value);
360 }
361
362 /** @brief Get a property with mapper lookup. */
363 template <typename Property>
364 static auto getProperty(const std::string& path,
365 const std::string& interface,
366 const std::string& property)
367 {
368 return getProperty<Property>(getBus(), path, interface, property);
369 }
370
371 /** @brief Get a property variant with mapper lookup. */
372 template <typename Variant>
Patrick Williamscb356d42022-07-22 19:26:53 -0500373 static auto getPropertyVariant(sdbusplus::bus_t& bus,
Matthew Barth9e80c872020-05-26 10:50:29 -0500374 const std::string& path,
375 const std::string& interface,
376 const std::string& property)
377 {
378 using namespace std::literals::string_literals;
379
380 auto service = getService(bus, path, interface);
381 auto msg =
382 callMethod(bus, service, path, "org.freedesktop.DBus.Properties"s,
383 "Get"s, interface, property);
384 if (msg.is_method_error())
385 {
386 throw DBusPropertyError{"DBus get property variant failed", service,
387 path, interface, property};
388 }
389 Variant value;
390 msg.read(value);
391 return value;
392 }
393
394 /** @brief Get a property variant with mapper lookup. */
395 template <typename Variant>
396 static auto getPropertyVariant(const std::string& path,
397 const std::string& interface,
398 const std::string& property)
399 {
400 return getPropertyVariant<Variant>(getBus(), path, interface, property);
401 }
402
Mike Capps808d7fe2022-06-13 10:12:16 -0400403 /** @brief Invoke a method and return without checking for error. */
404 template <typename... Args>
Patrick Williamscb356d42022-07-22 19:26:53 -0500405 static auto callMethodAndReturn(sdbusplus::bus_t& bus,
Mike Capps808d7fe2022-06-13 10:12:16 -0400406 const std::string& busName,
407 const std::string& path,
408 const std::string& interface,
409 const std::string& method, Args&&... args)
410 {
411 auto reqMsg = bus.new_method_call(busName.c_str(), path.c_str(),
412 interface.c_str(), method.c_str());
413 reqMsg.append(std::forward<Args>(args)...);
414 auto respMsg = bus.call(reqMsg);
415
416 return respMsg;
417 }
418
Matthew Barth9e80c872020-05-26 10:50:29 -0500419 /** @brief Get a property without mapper lookup. */
420 template <typename Property>
Patrick Williamscb356d42022-07-22 19:26:53 -0500421 static auto getProperty(sdbusplus::bus_t& bus, const std::string& service,
422 const std::string& path,
Matthew Barth9e80c872020-05-26 10:50:29 -0500423 const std::string& interface,
424 const std::string& property)
425 {
426 using namespace std::literals::string_literals;
427
428 auto msg = callMethodAndReturn(bus, service, path,
429 "org.freedesktop.DBus.Properties"s,
430 "Get"s, interface, property);
431 if (msg.is_method_error())
432 {
433 throw DBusPropertyError{"DBus get property failed", service, path,
434 interface, property};
435 }
436 std::variant<Property> value;
437 msg.read(value);
438 return std::get<Property>(value);
439 }
440
441 /** @brief Get a property without mapper lookup. */
442 template <typename Property>
443 static auto getProperty(const std::string& service, const std::string& path,
444 const std::string& interface,
445 const std::string& property)
446 {
447 return getProperty<Property>(getBus(), service, path, interface,
448 property);
449 }
450
451 /** @brief Get a property variant without mapper lookup. */
452 template <typename Variant>
Patrick Williamscb356d42022-07-22 19:26:53 -0500453 static auto getPropertyVariant(sdbusplus::bus_t& bus,
Matthew Barth9e80c872020-05-26 10:50:29 -0500454 const std::string& service,
455 const std::string& path,
456 const std::string& interface,
457 const std::string& property)
458 {
459 using namespace std::literals::string_literals;
460
461 auto msg = callMethodAndReturn(bus, service, path,
462 "org.freedesktop.DBus.Properties"s,
463 "Get"s, interface, property);
464 if (msg.is_method_error())
465 {
466 throw DBusPropertyError{"DBus get property variant failed", service,
467 path, interface, property};
468 }
469 Variant value;
470 msg.read(value);
471 return value;
472 }
473
474 /** @brief Get a property variant without mapper lookup. */
475 template <typename Variant>
476 static auto getPropertyVariant(const std::string& service,
477 const std::string& path,
478 const std::string& interface,
479 const std::string& property)
480 {
481 return getPropertyVariant<Variant>(getBus(), service, path, interface,
482 property);
483 }
484
485 /** @brief Set a property with mapper lookup. */
486 template <typename Property>
Patrick Williamscb356d42022-07-22 19:26:53 -0500487 static void setProperty(sdbusplus::bus_t& bus, const std::string& path,
Matthew Barth9e80c872020-05-26 10:50:29 -0500488 const std::string& interface,
489 const std::string& property, Property&& value)
490 {
491 using namespace std::literals::string_literals;
492
493 std::variant<Property> varValue(std::forward<Property>(value));
494
495 auto service = getService(bus, path, interface);
496 auto msg = callMethodAndReturn(bus, service, path,
497 "org.freedesktop.DBus.Properties"s,
498 "Set"s, interface, property, varValue);
499 if (msg.is_method_error())
500 {
501 throw DBusPropertyError{"DBus set property failed", service, path,
502 interface, property};
503 }
504 }
505
506 /** @brief Set a property with mapper lookup. */
507 template <typename Property>
508 static void setProperty(const std::string& path,
509 const std::string& interface,
510 const std::string& property, Property&& value)
511 {
512 return setProperty(getBus(), path, interface, property,
513 std::forward<Property>(value));
514 }
515
516 /** @brief Set a property without mapper lookup. */
517 template <typename Property>
Patrick Williamscb356d42022-07-22 19:26:53 -0500518 static void setProperty(sdbusplus::bus_t& bus, const std::string& service,
519 const std::string& path,
Matthew Barth9e80c872020-05-26 10:50:29 -0500520 const std::string& interface,
521 const std::string& property, Property&& value)
522 {
523 using namespace std::literals::string_literals;
524
525 std::variant<Property> varValue(std::forward<Property>(value));
526
527 auto msg = callMethodAndReturn(bus, service, path,
528 "org.freedesktop.DBus.Properties"s,
529 "Set"s, interface, property, varValue);
530 if (msg.is_method_error())
531 {
532 throw DBusPropertyError{"DBus set property failed", service, path,
533 interface, property};
534 }
535 }
536
537 /** @brief Set a property without mapper lookup. */
538 template <typename Property>
539 static void setProperty(const std::string& service, const std::string& path,
540 const std::string& interface,
541 const std::string& property, Property&& value)
542 {
543 return setProperty(getBus(), service, path, interface, property,
544 std::forward<Property>(value));
545 }
546
547 /** @brief Invoke method with mapper lookup. */
548 template <typename... Args>
Patrick Williamscb356d42022-07-22 19:26:53 -0500549 static auto lookupAndCallMethod(sdbusplus::bus_t& bus,
Matthew Barth9e80c872020-05-26 10:50:29 -0500550 const std::string& path,
551 const std::string& interface,
552 const std::string& method, Args&&... args)
553 {
554 return callMethod(bus, getService(bus, path, interface), path,
555 interface, method, std::forward<Args>(args)...);
556 }
557
558 /** @brief Invoke method with mapper lookup. */
559 template <typename... Args>
560 static auto lookupAndCallMethod(const std::string& path,
561 const std::string& interface,
562 const std::string& method, Args&&... args)
563 {
564 return lookupAndCallMethod(getBus(), path, interface, method,
565 std::forward<Args>(args)...);
566 }
567
568 /** @brief Invoke method and read with mapper lookup. */
569 template <typename Ret, typename... Args>
Patrick Williamscb356d42022-07-22 19:26:53 -0500570 static auto
571 lookupCallMethodAndRead(sdbusplus::bus_t& bus, const std::string& path,
572 const std::string& interface,
573 const std::string& method, Args&&... args)
Matthew Barth9e80c872020-05-26 10:50:29 -0500574 {
575 return callMethodAndRead(bus, getService(bus, path, interface), path,
576 interface, method,
577 std::forward<Args>(args)...);
578 }
579
580 /** @brief Invoke method and read with mapper lookup. */
581 template <typename Ret, typename... Args>
582 static auto lookupCallMethodAndRead(const std::string& path,
583 const std::string& interface,
584 const std::string& method,
585 Args&&... args)
586 {
587 return lookupCallMethodAndRead<Ret>(getBus(), path, interface, method,
588 std::forward<Args>(args)...);
589 }
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400590};
591
592} // namespace util
593} // namespace fan
594} // namespace phosphor