xref: /openbmc/phosphor-dbus-monitor/src/method.hpp (revision babf3b78deb58a2f40e405713f5ceb1485457529)
1 #pragma once
2 
3 #include <experimental/tuple>
4 #include "callback.hpp"
5 
6 namespace phosphor
7 {
8 namespace dbus
9 {
10 namespace monitoring
11 {
12 namespace detail
13 {
14 
15 /** @class CallDBusMethod
16  *  @brief Provide explicit call forwarding to
17  *     DBusInterface::callMethodNoReply.
18  *
19  *  @tparam DBusInterface - The DBus interface to use.
20  *  @tparam MethodArgs - DBus method argument types.
21  */
22 template <typename DBusInterface, typename ...MethodArgs>
23 struct CallDBusMethod
24 {
25     static void op(
26         const std::string& bus,
27         const std::string& path,
28         const std::string& iface,
29         const std::string& method,
30         MethodArgs&& ...args)
31     {
32         DBusInterface::callMethodNoReply(
33             bus,
34             path,
35             iface,
36             method,
37             std::forward<MethodArgs>(args)...);
38     }
39 };
40 } // namespace detail
41 
42 /** @class MethodBase
43  *  @brief Invoke DBus method callback implementation.
44  *
45  *  The method callback invokes the client supplied DBus method.
46  */
47 class MethodBase : public Callback
48 {
49     public:
50         MethodBase() = delete;
51         MethodBase(const MethodBase&) = delete;
52         MethodBase(MethodBase&&) = default;
53         MethodBase& operator=(const MethodBase&) = delete;
54         MethodBase& operator=(MethodBase&&) = default;
55         virtual ~MethodBase() = default;
56         MethodBase(
57             const std::string& b,
58             const std::string& p,
59             const std::string& i,
60             const std::string& m)
61             : Callback(),
62               bus(b),
63               path(p),
64               interface(i),
65                   method(m) {}
66 
67         /** @brief Callback interface implementation. */
68         void operator()() override = 0;
69 
70     protected:
71         const std::string& bus;
72         const std::string& path;
73         const std::string& interface;
74         const std::string& method;
75 };
76 
77 /** @class Method
78  *  @brief C++ type specific logic for the method callback.
79  *
80  *  @tparam DBusInterface - The DBus interface to use to call the method.
81  *  @tparam MethodArgs - DBus method argument types.
82  */
83 template <typename DBusInterface, typename ...MethodArgs>
84 class Method : public MethodBase
85 {
86     public:
87         Method() = delete;
88         Method(const Method&) = default;
89         Method(Method&&) = default;
90         Method& operator=(const Method&) = default;
91         Method& operator=(Method&&) = default;
92         ~Method() = default;
93         Method(
94             const std::string& bus,
95             const std::string& path,
96             const std::string& iface,
97             const std::string& method,
98             MethodArgs&& ... arguments)
99             : MethodBase(bus, path, iface, method),
100               args(std::forward<MethodArgs>(arguments)...) {}
101 
102         /** @brief Callback interface implementation. */
103         void operator()() override
104         {
105             std::experimental::apply(
106                 detail::CallDBusMethod<DBusInterface, MethodArgs...>::op,
107                 std::tuple_cat(
108                     std::make_tuple(bus),
109                     std::make_tuple(path),
110                     std::make_tuple(interface),
111                     std::make_tuple(method),
112                     args));
113         }
114 
115     private:
116         std::tuple<MethodArgs...> args;
117 };
118 
119 /** @brief Argument type deduction for constructing Method instances. */
120 template <typename DBusInterface, typename ...MethodArgs>
121 auto makeMethod(
122     const std::string& bus,
123     const std::string& path,
124     const std::string& iface,
125     const std::string& method,
126     MethodArgs&& ... arguments)
127 {
128     return std::make_unique<Method<DBusInterface, MethodArgs...>>(
129                bus,
130                path,
131                iface,
132                method,
133                std::forward<MethodArgs>(arguments)...);
134 }
135 
136 } // namespace monitoring
137 } // namespace dbus
138 } // namespace phosphor
139