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