1 #pragma once
2
3 #include "callback.hpp"
4
5 #include <phosphor-logging/lg2.hpp>
6
7 #include <experimental/tuple>
8 #include <string>
9 #include <tuple>
10
11 namespace phosphor
12 {
13 namespace dbus
14 {
15 namespace monitoring
16 {
17 namespace 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 */
27 template <typename DBusInterface, typename... MethodArgs>
28 struct CallDBusMethod
29 {
opphosphor::dbus::monitoring::detail::CallDBusMethod30 static void op(const std::string& bus, const std::string& path,
31 const std::string& iface, const std::string& method,
32 MethodArgs&&... args)
33 {
34 try
35 {
36 DBusInterface::callMethodNoReply(bus, path, iface, method,
37 std::forward<MethodArgs>(args)...);
38 }
39 catch (const sdbusplus::exception_t& e)
40 {
41 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);
45 }
46 }
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 */
55 class MethodBase : public Callback
56 {
57 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;
MethodBase(const std::string & b,const std::string & p,const std::string & i,const std::string & m)64 MethodBase(const std::string& b, const std::string& p, const std::string& i,
65 const std::string& m) :
66 Callback(), bus(b), path(p), interface(i), method(m)
67 {}
68
69 /** @brief Callback interface implementation. */
70 void operator()(Context ctx) override = 0;
71
72 protected:
73 const std::string& bus;
74 const std::string& path;
75 const std::string& interface;
76 const std::string& method;
77 };
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 */
85 template <typename DBusInterface, typename... MethodArgs>
86 class Method : public MethodBase
87 {
88 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;
Method(const std::string & bus,const std::string & path,const std::string & iface,const std::string & method,MethodArgs &&...arguments)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)...)
100 {}
101
102 /** @brief Callback interface implementation. */
operator ()(Context)103 void operator()(Context /* ctx */) override
104 {
105 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));
109 }
110
111 private:
112 std::tuple<MethodArgs...> args;
113 };
114
115 /** @brief Argument type deduction for constructing Method instances. */
116 template <typename DBusInterface, typename... MethodArgs>
makeMethod(const std::string & bus,const std::string & path,const std::string & iface,const std::string & method,MethodArgs &&...arguments)117 auto makeMethod(const std::string& bus, const std::string& path,
118 const std::string& iface, const std::string& method,
119 MethodArgs&&... arguments)
120 {
121 return std::make_unique<Method<DBusInterface, MethodArgs...>>(
122 bus, path, iface, method, std::forward<MethodArgs>(arguments)...);
123 }
124
125 } // namespace monitoring
126 } // namespace dbus
127 } // namespace phosphor
128