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> struct CallDBusMethod 23 { 24 static void op(const std::string& bus, const std::string& path, 25 const std::string& iface, const std::string& method, 26 MethodArgs&&... args) 27 { 28 DBusInterface::callMethodNoReply(bus, path, iface, method, 29 std::forward<MethodArgs>(args)...); 30 } 31 }; 32 } // namespace detail 33 34 /** @class MethodBase 35 * @brief Invoke DBus method callback implementation. 36 * 37 * The method callback invokes the client supplied DBus method. 38 */ 39 class MethodBase : public Callback 40 { 41 public: 42 MethodBase() = delete; 43 MethodBase(const MethodBase&) = delete; 44 MethodBase(MethodBase&&) = default; 45 MethodBase& operator=(const MethodBase&) = delete; 46 MethodBase& operator=(MethodBase&&) = default; 47 virtual ~MethodBase() = default; 48 MethodBase(const std::string& b, const std::string& p, const std::string& i, 49 const std::string& m) : 50 Callback(), 51 bus(b), path(p), interface(i), method(m) 52 { 53 } 54 55 /** @brief Callback interface implementation. */ 56 void operator()(Context ctx) override = 0; 57 58 protected: 59 const std::string& bus; 60 const std::string& path; 61 const std::string& interface; 62 const std::string& method; 63 }; 64 65 /** @class Method 66 * @brief C++ type specific logic for the method callback. 67 * 68 * @tparam DBusInterface - The DBus interface to use to call the method. 69 * @tparam MethodArgs - DBus method argument types. 70 */ 71 template <typename DBusInterface, typename... MethodArgs> 72 class Method : public MethodBase 73 { 74 public: 75 Method() = delete; 76 Method(const Method&) = default; 77 Method(Method&&) = default; 78 Method& operator=(const Method&) = default; 79 Method& operator=(Method&&) = default; 80 ~Method() = default; 81 Method(const std::string& bus, const std::string& path, 82 const std::string& iface, const std::string& method, 83 MethodArgs&&... arguments) : 84 MethodBase(bus, path, iface, method), 85 args(std::forward<MethodArgs>(arguments)...) 86 { 87 } 88 89 /** @brief Callback interface implementation. */ 90 void operator()(Context ctx) override 91 { 92 std::experimental::apply( 93 detail::CallDBusMethod<DBusInterface, MethodArgs...>::op, 94 std::tuple_cat(std::make_tuple(bus), std::make_tuple(path), 95 std::make_tuple(interface), std::make_tuple(method), 96 args)); 97 } 98 99 private: 100 std::tuple<MethodArgs...> args; 101 }; 102 103 /** @brief Argument type deduction for constructing Method instances. */ 104 template <typename DBusInterface, typename... MethodArgs> 105 auto makeMethod(const std::string& bus, const std::string& path, 106 const std::string& iface, const std::string& method, 107 MethodArgs&&... arguments) 108 { 109 return std::make_unique<Method<DBusInterface, MethodArgs...>>( 110 bus, path, iface, method, std::forward<MethodArgs>(arguments)...); 111 } 112 113 } // namespace monitoring 114 } // namespace dbus 115 } // namespace phosphor 116