blob: baaebcd4eee6096378dba0f4b93ef0c12f12dab6 [file] [log] [blame]
Brad Bishop0df00be2017-05-25 23:38:37 -04001#pragma once
2
Brad Bishop0df00be2017-05-25 23:38:37 -04003#include "callback.hpp"
4
George Liu13e3df62022-06-22 15:03:06 +08005#include <phosphor-logging/lg2.hpp>
George Liu3fe976c2022-06-21 09:37:04 +08006
7#include <experimental/tuple>
Andrew Geisslerae4c95c2020-05-16 13:58:53 -05008#include <string>
Patrick Williams26dc0bc2022-06-16 17:06:18 -05009#include <tuple>
Patrick Venture3d6d3182018-08-31 09:33:09 -070010
Brad Bishop0df00be2017-05-25 23:38:37 -040011namespace phosphor
12{
13namespace dbus
14{
15namespace monitoring
16{
17namespace detail
18{
19
20/** @class CallDBusMethod
21 * @brief Provide explicit call forwarding to
22 * DBusInterface::callMethodNoReply.
23 *
24 * @tparam DBusInterface - The DBus interface to use.
25 * @tparam MethodArgs - DBus method argument types.
26 */
Patrick Venture3d6d3182018-08-31 09:33:09 -070027template <typename DBusInterface, typename... MethodArgs>
28struct CallDBusMethod
Brad Bishop0df00be2017-05-25 23:38:37 -040029{
Brad Bishopd1eac882018-03-29 10:34:05 -040030 static void op(const std::string& bus, const std::string& path,
31 const std::string& iface, const std::string& method,
32 MethodArgs&&... args)
Brad Bishop0df00be2017-05-25 23:38:37 -040033 {
Alexander Soldatov12789e62018-11-23 10:40:40 +030034 try
35 {
36 DBusInterface::callMethodNoReply(bus, path, iface, method,
37 std::forward<MethodArgs>(args)...);
38 }
Patrick Williams413a4852022-07-22 19:26:52 -050039 catch (const sdbusplus::exception_t& e)
Alexander Soldatov12789e62018-11-23 10:40:40 +030040 {
George Liu13e3df62022-06-22 15:03:06 +080041 lg2::error(
42 "Unable to call DBus method: {ERROR}. {BUS}, {PATH}, {INTF}, {METHOD}",
43 "ERROR", e, "BUS", bus, "PATH", path, "INTF", iface, "METHOD",
44 method);
Alexander Soldatov12789e62018-11-23 10:40:40 +030045 }
Brad Bishop0df00be2017-05-25 23:38:37 -040046 }
47};
48} // namespace detail
49
50/** @class MethodBase
51 * @brief Invoke DBus method callback implementation.
52 *
53 * The method callback invokes the client supplied DBus method.
54 */
55class MethodBase : public Callback
56{
Brad Bishopd1eac882018-03-29 10:34:05 -040057 public:
58 MethodBase() = delete;
59 MethodBase(const MethodBase&) = delete;
60 MethodBase(MethodBase&&) = default;
61 MethodBase& operator=(const MethodBase&) = delete;
62 MethodBase& operator=(MethodBase&&) = default;
63 virtual ~MethodBase() = default;
64 MethodBase(const std::string& b, const std::string& p, const std::string& i,
65 const std::string& m) :
Patrick Williamseab4f8c2024-08-16 15:20:10 -040066 Callback(), bus(b), path(p), interface(i), method(m)
George Liu3fe976c2022-06-21 09:37:04 +080067 {}
Brad Bishop0df00be2017-05-25 23:38:37 -040068
Brad Bishopd1eac882018-03-29 10:34:05 -040069 /** @brief Callback interface implementation. */
70 void operator()(Context ctx) override = 0;
Brad Bishop0df00be2017-05-25 23:38:37 -040071
Brad Bishopd1eac882018-03-29 10:34:05 -040072 protected:
73 const std::string& bus;
74 const std::string& path;
75 const std::string& interface;
76 const std::string& method;
Brad Bishop0df00be2017-05-25 23:38:37 -040077};
78
79/** @class Method
80 * @brief C++ type specific logic for the method callback.
81 *
82 * @tparam DBusInterface - The DBus interface to use to call the method.
83 * @tparam MethodArgs - DBus method argument types.
84 */
Brad Bishopd1eac882018-03-29 10:34:05 -040085template <typename DBusInterface, typename... MethodArgs>
Brad Bishop0df00be2017-05-25 23:38:37 -040086class Method : public MethodBase
87{
Brad Bishopd1eac882018-03-29 10:34:05 -040088 public:
89 Method() = delete;
90 Method(const Method&) = default;
91 Method(Method&&) = default;
92 Method& operator=(const Method&) = default;
93 Method& operator=(Method&&) = default;
94 ~Method() = default;
95 Method(const std::string& bus, const std::string& path,
96 const std::string& iface, const std::string& method,
97 MethodArgs&&... arguments) :
98 MethodBase(bus, path, iface, method),
99 args(std::forward<MethodArgs>(arguments)...)
George Liu3fe976c2022-06-21 09:37:04 +0800100 {}
Brad Bishop0df00be2017-05-25 23:38:37 -0400101
Brad Bishopd1eac882018-03-29 10:34:05 -0400102 /** @brief Callback interface implementation. */
George Liu5e6b51d2022-06-21 16:59:39 +0800103 void operator()(Context /* ctx */) override
Brad Bishopd1eac882018-03-29 10:34:05 -0400104 {
Patrick Williams26dc0bc2022-06-16 17:06:18 -0500105 std::apply(detail::CallDBusMethod<DBusInterface, MethodArgs...>::op,
106 std::tuple_cat(std::make_tuple(bus), std::make_tuple(path),
107 std::make_tuple(interface),
108 std::make_tuple(method), args));
Brad Bishopd1eac882018-03-29 10:34:05 -0400109 }
Brad Bishop0df00be2017-05-25 23:38:37 -0400110
Brad Bishopd1eac882018-03-29 10:34:05 -0400111 private:
112 std::tuple<MethodArgs...> args;
Brad Bishop0df00be2017-05-25 23:38:37 -0400113};
114
115/** @brief Argument type deduction for constructing Method instances. */
Brad Bishopd1eac882018-03-29 10:34:05 -0400116template <typename DBusInterface, typename... MethodArgs>
117auto makeMethod(const std::string& bus, const std::string& path,
118 const std::string& iface, const std::string& method,
119 MethodArgs&&... arguments)
Brad Bishop0df00be2017-05-25 23:38:37 -0400120{
121 return std::make_unique<Method<DBusInterface, MethodArgs...>>(
Brad Bishopd1eac882018-03-29 10:34:05 -0400122 bus, path, iface, method, std::forward<MethodArgs>(arguments)...);
Brad Bishop0df00be2017-05-25 23:38:37 -0400123}
124
125} // namespace monitoring
126} // namespace dbus
127} // namespace phosphor