blob: 9627e400f6e92bac202b6e53d4d836c681270a0a [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>
5#include <phosphor-logging/log.hpp>
6#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>
156 static auto
Patrick Williamscb356d42022-07-22 19:26:53 -0500157 callMethodAndRead(sdbusplus::bus_t& bus, const std::string& busName,
Matthew Barth9e80c872020-05-26 10:50:29 -0500158 const std::string& path, const std::string& interface,
159 const std::string& method, Args&&... args)
160 {
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>
170 static auto callMethodAndRead(const std::string& busName,
171 const std::string& path,
172 const std::string& interface,
173 const std::string& method, Args&&... args)
174 {
175 return callMethodAndRead<Ret>(getBus(), busName, path, interface,
176 method, std::forward<Args>(args)...);
177 }
178
179 /** @brief Get subtree from the mapper without checking response. */
Patrick Williamscb356d42022-07-22 19:26:53 -0500180 static auto getSubTreeRaw(sdbusplus::bus_t& bus, const std::string& path,
Matthew Barth9e80c872020-05-26 10:50:29 -0500181 const std::string& interface, int32_t depth)
182 {
183 using namespace std::literals::string_literals;
184
185 using Path = std::string;
186 using Intf = std::string;
187 using Serv = std::string;
188 using Intfs = std::vector<Intf>;
189 using Objects = std::map<Path, std::map<Serv, Intfs>>;
190 Intfs intfs = {interface};
191
192 return callMethodAndRead<Objects>(bus,
193 "xyz.openbmc_project.ObjectMapper"s,
194 "/xyz/openbmc_project/object_mapper"s,
195 "xyz.openbmc_project.ObjectMapper"s,
196 "GetSubTree"s, path, depth, intfs);
197 }
198
Mike Capps7a401a22021-07-12 13:59:31 -0400199 /** @brief Get subtree from the mapper without checking response,
200 * (multiple interfaces version). */
Patrick Williamscb356d42022-07-22 19:26:53 -0500201 static auto getSubTreeRaw(sdbusplus::bus_t& bus, const std::string& path,
Mike Capps7a401a22021-07-12 13:59:31 -0400202 const std::vector<std::string>& intfs,
203 int32_t depth)
204 {
205 using namespace std::literals::string_literals;
206
207 using Path = std::string;
208 using Intf = std::string;
209 using Serv = std::string;
210 using Intfs = std::vector<Intf>;
211 using Objects = std::map<Path, std::map<Serv, Intfs>>;
212
213 return callMethodAndRead<Objects>(bus,
214 "xyz.openbmc_project.ObjectMapper"s,
215 "/xyz/openbmc_project/object_mapper"s,
216 "xyz.openbmc_project.ObjectMapper"s,
217 "GetSubTree"s, path, depth, intfs);
218 }
219
Matthew Barth9e80c872020-05-26 10:50:29 -0500220 /** @brief Get subtree from the mapper. */
Patrick Williamscb356d42022-07-22 19:26:53 -0500221 static auto getSubTree(sdbusplus::bus_t& bus, const std::string& path,
Matthew Barth9e80c872020-05-26 10:50:29 -0500222 const std::string& interface, int32_t depth)
223 {
224 auto mapperResp = getSubTreeRaw(bus, path, interface, depth);
225 if (mapperResp.empty())
226 {
227 phosphor::logging::log<phosphor::logging::level::ERR>(
228 "Empty response from mapper GetSubTree",
229 phosphor::logging::entry("SUBTREE=%s", path.c_str()),
230 phosphor::logging::entry("INTERFACE=%s", interface.c_str()),
231 phosphor::logging::entry("DEPTH=%u", depth));
232 phosphor::logging::elog<detail::errors::InternalFailure>();
233 }
234 return mapperResp;
235 }
236
Matthew Barthfcbdc0e2020-10-28 14:11:07 -0500237 /** @brief Get subtree paths from the mapper without checking response. */
Patrick Williamscb356d42022-07-22 19:26:53 -0500238 static auto getSubTreePathsRaw(sdbusplus::bus_t& bus,
Matthew Barthfcbdc0e2020-10-28 14:11:07 -0500239 const std::string& path,
240 const std::string& interface, int32_t depth)
241 {
242 using namespace std::literals::string_literals;
243
244 using Path = std::string;
245 using Intf = std::string;
246 using Intfs = std::vector<Intf>;
247 using ObjectPaths = std::vector<Path>;
248 Intfs intfs = {interface};
249
250 return callMethodAndRead<ObjectPaths>(
251 bus, "xyz.openbmc_project.ObjectMapper"s,
252 "/xyz/openbmc_project/object_mapper"s,
253 "xyz.openbmc_project.ObjectMapper"s, "GetSubTreePaths"s, path,
254 depth, intfs);
255 }
256
257 /** @brief Get subtree paths from the mapper. */
Patrick Williamscb356d42022-07-22 19:26:53 -0500258 static auto getSubTreePaths(sdbusplus::bus_t& bus, const std::string& path,
Matthew Barthfcbdc0e2020-10-28 14:11:07 -0500259 const std::string& interface, int32_t depth)
260 {
261 auto mapperResp = getSubTreePathsRaw(bus, path, interface, depth);
262 if (mapperResp.empty())
263 {
264 phosphor::logging::log<phosphor::logging::level::ERR>(
265 "Empty response from mapper GetSubTreePaths",
266 phosphor::logging::entry("SUBTREE=%s", path.c_str()),
267 phosphor::logging::entry("INTERFACE=%s", interface.c_str()),
268 phosphor::logging::entry("DEPTH=%u", depth));
269 phosphor::logging::elog<detail::errors::InternalFailure>();
270 }
271 return mapperResp;
272 }
273
Mike Cappsce6820a2021-05-26 10:40:19 -0400274 /** @brief Get service from the mapper without checking response. */
Patrick Williamscb356d42022-07-22 19:26:53 -0500275 static auto getServiceRaw(sdbusplus::bus_t& bus, const std::string& path,
Mike Cappsce6820a2021-05-26 10:40:19 -0400276 const std::string& interface)
Matthew Barth9e80c872020-05-26 10:50:29 -0500277 {
278 using namespace std::literals::string_literals;
279 using GetObject = std::map<std::string, std::vector<std::string>>;
280
Mike Cappsce6820a2021-05-26 10:40:19 -0400281 return callMethodAndRead<GetObject>(
282 bus, "xyz.openbmc_project.ObjectMapper"s,
283 "/xyz/openbmc_project/object_mapper"s,
284 "xyz.openbmc_project.ObjectMapper"s, "GetObject"s, path,
285 GetObject::mapped_type{interface});
286 }
287
288 /** @brief Get service from the mapper. */
Patrick Williamscb356d42022-07-22 19:26:53 -0500289 static auto getService(sdbusplus::bus_t& bus, const std::string& path,
Mike Cappsce6820a2021-05-26 10:40:19 -0400290 const std::string& interface)
291 {
Matthew Barth9e80c872020-05-26 10:50:29 -0500292 try
293 {
Mike Cappsce6820a2021-05-26 10:40:19 -0400294 auto mapperResp = getServiceRaw(bus, path, interface);
Matthew Barth9e80c872020-05-26 10:50:29 -0500295
296 if (mapperResp.empty())
297 {
298 // Should never happen. A missing object would fail
299 // in callMethodAndRead()
300 phosphor::logging::log<phosphor::logging::level::ERR>(
301 "Empty mapper response on service lookup");
302 throw DBusServiceError{path, interface};
303 }
304 return mapperResp.begin()->first;
305 }
Patrick Williamsddb773b2021-10-06 11:24:49 -0500306 catch (const DBusMethodError& e)
Matthew Barth9e80c872020-05-26 10:50:29 -0500307 {
308 throw DBusServiceError{path, interface};
309 }
310 }
311
312 /** @brief Get service from the mapper. */
313 static auto getService(const std::string& path,
314 const std::string& interface)
315 {
316 return getService(getBus(), path, interface);
317 }
318
Matthew Bartha3553632021-05-03 14:40:59 -0500319 /** @brief Get managed objects. */
320 template <typename Variant>
Patrick Williamscb356d42022-07-22 19:26:53 -0500321 static auto getManagedObjects(sdbusplus::bus_t& bus,
Matthew Bartha3553632021-05-03 14:40:59 -0500322 const std::string& service,
323 const std::string& path)
324 {
325 using namespace std::literals::string_literals;
326
327 using Path = sdbusplus::message::object_path;
328 using Intf = std::string;
329 using Prop = std::string;
330 using GetManagedObjects =
331 std::map<Path, std::map<Intf, std::map<Prop, Variant>>>;
332
333 return callMethodAndRead<GetManagedObjects>(
334 bus, service, path, "org.freedesktop.DBus.ObjectManager"s,
335 "GetManagedObjects"s);
336 }
337
Matthew Barth9e80c872020-05-26 10:50:29 -0500338 /** @brief Get a property with mapper lookup. */
339 template <typename Property>
Patrick Williamscb356d42022-07-22 19:26:53 -0500340 static auto getProperty(sdbusplus::bus_t& bus, const std::string& path,
Matthew Barth9e80c872020-05-26 10:50:29 -0500341 const std::string& interface,
342 const std::string& property)
343 {
344 using namespace std::literals::string_literals;
345
346 auto service = getService(bus, path, interface);
Patrick Williams61b73292023-05-10 07:50:12 -0500347 auto msg = callMethod(bus, service, path,
348 "org.freedesktop.DBus.Properties"s, "Get"s,
349 interface, property);
Matthew Barth9e80c872020-05-26 10:50:29 -0500350 if (msg.is_method_error())
351 {
352 throw DBusPropertyError{"DBus get property failed", service, path,
353 interface, property};
354 }
355 std::variant<Property> value;
356 msg.read(value);
357 return std::get<Property>(value);
358 }
359
360 /** @brief Get a property with mapper lookup. */
361 template <typename Property>
362 static auto getProperty(const std::string& path,
363 const std::string& interface,
364 const std::string& property)
365 {
366 return getProperty<Property>(getBus(), path, interface, property);
367 }
368
369 /** @brief Get a property variant with mapper lookup. */
370 template <typename Variant>
Patrick Williamscb356d42022-07-22 19:26:53 -0500371 static auto getPropertyVariant(sdbusplus::bus_t& bus,
Matthew Barth9e80c872020-05-26 10:50:29 -0500372 const std::string& path,
373 const std::string& interface,
374 const std::string& property)
375 {
376 using namespace std::literals::string_literals;
377
378 auto service = getService(bus, path, interface);
Patrick Williams61b73292023-05-10 07:50:12 -0500379 auto msg = callMethod(bus, service, path,
380 "org.freedesktop.DBus.Properties"s, "Get"s,
381 interface, property);
Matthew Barth9e80c872020-05-26 10:50:29 -0500382 if (msg.is_method_error())
383 {
384 throw DBusPropertyError{"DBus get property variant failed", service,
385 path, interface, property};
386 }
387 Variant value;
388 msg.read(value);
389 return value;
390 }
391
392 /** @brief Get a property variant with mapper lookup. */
393 template <typename Variant>
394 static auto getPropertyVariant(const std::string& path,
395 const std::string& interface,
396 const std::string& property)
397 {
398 return getPropertyVariant<Variant>(getBus(), path, interface, property);
399 }
400
Mike Capps808d7fe2022-06-13 10:12:16 -0400401 /** @brief Invoke a method and return without checking for error. */
402 template <typename... Args>
Patrick Williamscb356d42022-07-22 19:26:53 -0500403 static auto callMethodAndReturn(sdbusplus::bus_t& bus,
Mike Capps808d7fe2022-06-13 10:12:16 -0400404 const std::string& busName,
405 const std::string& path,
406 const std::string& interface,
407 const std::string& method, Args&&... args)
408 {
409 auto reqMsg = bus.new_method_call(busName.c_str(), path.c_str(),
410 interface.c_str(), method.c_str());
411 reqMsg.append(std::forward<Args>(args)...);
412 auto respMsg = bus.call(reqMsg);
413
414 return respMsg;
415 }
416
Matthew Barth9e80c872020-05-26 10:50:29 -0500417 /** @brief Get a property without mapper lookup. */
418 template <typename Property>
Patrick Williamscb356d42022-07-22 19:26:53 -0500419 static auto getProperty(sdbusplus::bus_t& bus, const std::string& service,
420 const std::string& path,
Matthew Barth9e80c872020-05-26 10:50:29 -0500421 const std::string& interface,
422 const std::string& property)
423 {
424 using namespace std::literals::string_literals;
425
426 auto msg = callMethodAndReturn(bus, service, path,
427 "org.freedesktop.DBus.Properties"s,
428 "Get"s, interface, property);
429 if (msg.is_method_error())
430 {
431 throw DBusPropertyError{"DBus get property failed", service, path,
432 interface, property};
433 }
434 std::variant<Property> value;
435 msg.read(value);
436 return std::get<Property>(value);
437 }
438
439 /** @brief Get a property without mapper lookup. */
440 template <typename Property>
441 static auto getProperty(const std::string& service, const std::string& path,
442 const std::string& interface,
443 const std::string& property)
444 {
445 return getProperty<Property>(getBus(), service, path, interface,
446 property);
447 }
448
449 /** @brief Get a property variant without mapper lookup. */
450 template <typename Variant>
Patrick Williamscb356d42022-07-22 19:26:53 -0500451 static auto getPropertyVariant(sdbusplus::bus_t& bus,
Matthew Barth9e80c872020-05-26 10:50:29 -0500452 const std::string& service,
453 const std::string& path,
454 const std::string& interface,
455 const std::string& property)
456 {
457 using namespace std::literals::string_literals;
458
459 auto msg = callMethodAndReturn(bus, service, path,
460 "org.freedesktop.DBus.Properties"s,
461 "Get"s, interface, property);
462 if (msg.is_method_error())
463 {
464 throw DBusPropertyError{"DBus get property variant failed", service,
465 path, interface, property};
466 }
467 Variant value;
468 msg.read(value);
469 return value;
470 }
471
472 /** @brief Get a property variant without mapper lookup. */
473 template <typename Variant>
474 static auto getPropertyVariant(const std::string& service,
475 const std::string& path,
476 const std::string& interface,
477 const std::string& property)
478 {
479 return getPropertyVariant<Variant>(getBus(), service, path, interface,
480 property);
481 }
482
483 /** @brief Set a property with mapper lookup. */
484 template <typename Property>
Patrick Williamscb356d42022-07-22 19:26:53 -0500485 static void setProperty(sdbusplus::bus_t& bus, const std::string& path,
Matthew Barth9e80c872020-05-26 10:50:29 -0500486 const std::string& interface,
487 const std::string& property, Property&& value)
488 {
489 using namespace std::literals::string_literals;
490
491 std::variant<Property> varValue(std::forward<Property>(value));
492
493 auto service = getService(bus, path, interface);
494 auto msg = callMethodAndReturn(bus, service, path,
495 "org.freedesktop.DBus.Properties"s,
496 "Set"s, interface, property, varValue);
497 if (msg.is_method_error())
498 {
499 throw DBusPropertyError{"DBus set property failed", service, path,
500 interface, property};
501 }
502 }
503
504 /** @brief Set a property with mapper lookup. */
505 template <typename Property>
506 static void setProperty(const std::string& path,
507 const std::string& interface,
508 const std::string& property, Property&& value)
509 {
510 return setProperty(getBus(), path, interface, property,
511 std::forward<Property>(value));
512 }
513
514 /** @brief Set a property without mapper lookup. */
515 template <typename Property>
Patrick Williamscb356d42022-07-22 19:26:53 -0500516 static void setProperty(sdbusplus::bus_t& bus, const std::string& service,
517 const std::string& path,
Matthew Barth9e80c872020-05-26 10:50:29 -0500518 const std::string& interface,
519 const std::string& property, Property&& value)
520 {
521 using namespace std::literals::string_literals;
522
523 std::variant<Property> varValue(std::forward<Property>(value));
524
525 auto msg = callMethodAndReturn(bus, service, path,
526 "org.freedesktop.DBus.Properties"s,
527 "Set"s, interface, property, varValue);
528 if (msg.is_method_error())
529 {
530 throw DBusPropertyError{"DBus set property failed", service, path,
531 interface, property};
532 }
533 }
534
535 /** @brief Set a property without mapper lookup. */
536 template <typename Property>
537 static void setProperty(const std::string& service, const std::string& path,
538 const std::string& interface,
539 const std::string& property, Property&& value)
540 {
541 return setProperty(getBus(), service, path, interface, property,
542 std::forward<Property>(value));
543 }
544
545 /** @brief Invoke method with mapper lookup. */
546 template <typename... Args>
Patrick Williamscb356d42022-07-22 19:26:53 -0500547 static auto lookupAndCallMethod(sdbusplus::bus_t& bus,
Matthew Barth9e80c872020-05-26 10:50:29 -0500548 const std::string& path,
549 const std::string& interface,
550 const std::string& method, Args&&... args)
551 {
552 return callMethod(bus, getService(bus, path, interface), path,
553 interface, method, std::forward<Args>(args)...);
554 }
555
556 /** @brief Invoke method with mapper lookup. */
557 template <typename... Args>
558 static auto lookupAndCallMethod(const std::string& path,
559 const std::string& interface,
560 const std::string& method, Args&&... args)
561 {
562 return lookupAndCallMethod(getBus(), path, 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 Williamscb356d42022-07-22 19:26:53 -0500568 static auto
569 lookupCallMethodAndRead(sdbusplus::bus_t& bus, const std::string& path,
570 const std::string& interface,
571 const std::string& method, Args&&... args)
Matthew Barth9e80c872020-05-26 10:50:29 -0500572 {
573 return callMethodAndRead(bus, getService(bus, path, interface), path,
574 interface, method,
575 std::forward<Args>(args)...);
576 }
577
578 /** @brief Invoke method and read with mapper lookup. */
579 template <typename Ret, typename... Args>
580 static auto lookupCallMethodAndRead(const std::string& path,
581 const std::string& interface,
582 const std::string& method,
583 Args&&... args)
584 {
585 return lookupCallMethodAndRead<Ret>(getBus(), path, interface, method,
586 std::forward<Args>(args)...);
587 }
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400588};
589
590} // namespace util
591} // namespace fan
592} // namespace phosphor