xref: /openbmc/phosphor-dbus-monitor/src/method.hpp (revision eab4f8c0a047e1aaedf74d6144d83132d1b003de)
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