blob: db37d24e2371b3202b44811011974804c47bf5b9 [file] [log] [blame]
Brad Bishop0df00be2017-05-25 23:38:37 -04001#pragma once
2
Brad Bishop0df00be2017-05-25 23:38:37 -04003#include "callback.hpp"
4
Alexander Soldatov12789e62018-11-23 10:40:40 +03005#include <phosphor-logging/log.hpp>
George Liu3fe976c2022-06-21 09:37:04 +08006
7#include <experimental/tuple>
Andrew Geisslerae4c95c2020-05-16 13:58:53 -05008#include <string>
Patrick Williams26dc0bc2022-06-16 17:06:18 -05009#include <tuple>
Patrick Venture3d6d3182018-08-31 09:33:09 -070010
Brad Bishop0df00be2017-05-25 23:38:37 -040011namespace phosphor
12{
13namespace dbus
14{
15namespace monitoring
16{
17namespace detail
18{
19
Alexander Soldatov12789e62018-11-23 10:40:40 +030020using namespace phosphor::logging;
21
Brad Bishop0df00be2017-05-25 23:38:37 -040022/** @class CallDBusMethod
23 * @brief Provide explicit call forwarding to
24 * DBusInterface::callMethodNoReply.
25 *
26 * @tparam DBusInterface - The DBus interface to use.
27 * @tparam MethodArgs - DBus method argument types.
28 */
Patrick Venture3d6d3182018-08-31 09:33:09 -070029template <typename DBusInterface, typename... MethodArgs>
30struct CallDBusMethod
Brad Bishop0df00be2017-05-25 23:38:37 -040031{
Brad Bishopd1eac882018-03-29 10:34:05 -040032 static void op(const std::string& bus, const std::string& path,
33 const std::string& iface, const std::string& method,
34 MethodArgs&&... args)
Brad Bishop0df00be2017-05-25 23:38:37 -040035 {
Alexander Soldatov12789e62018-11-23 10:40:40 +030036 try
37 {
38 DBusInterface::callMethodNoReply(bus, path, iface, method,
39 std::forward<MethodArgs>(args)...);
40 }
Patrick Williams764adb52021-09-02 09:36:47 -050041 catch (const sdbusplus::exception::exception& e)
Alexander Soldatov12789e62018-11-23 10:40:40 +030042 {
43 // clang-format off
44 log<level::ERR>("Unable to call DBus method",
45 entry("BUS=%s", bus.c_str(),
46 "PATH=%s", path.c_str(),
47 "IFACE=%s", iface.c_str(),
48 "METHOD=%s", method.c_str(),
49 "ERROR=%s", e.what()));
50 // clang-format on
51 }
Brad Bishop0df00be2017-05-25 23:38:37 -040052 }
53};
54} // namespace detail
55
56/** @class MethodBase
57 * @brief Invoke DBus method callback implementation.
58 *
59 * The method callback invokes the client supplied DBus method.
60 */
61class MethodBase : public Callback
62{
Brad Bishopd1eac882018-03-29 10:34:05 -040063 public:
64 MethodBase() = delete;
65 MethodBase(const MethodBase&) = delete;
66 MethodBase(MethodBase&&) = default;
67 MethodBase& operator=(const MethodBase&) = delete;
68 MethodBase& operator=(MethodBase&&) = default;
69 virtual ~MethodBase() = default;
70 MethodBase(const std::string& b, const std::string& p, const std::string& i,
71 const std::string& m) :
72 Callback(),
73 bus(b), path(p), interface(i), method(m)
George Liu3fe976c2022-06-21 09:37:04 +080074 {}
Brad Bishop0df00be2017-05-25 23:38:37 -040075
Brad Bishopd1eac882018-03-29 10:34:05 -040076 /** @brief Callback interface implementation. */
77 void operator()(Context ctx) override = 0;
Brad Bishop0df00be2017-05-25 23:38:37 -040078
Brad Bishopd1eac882018-03-29 10:34:05 -040079 protected:
80 const std::string& bus;
81 const std::string& path;
82 const std::string& interface;
83 const std::string& method;
Brad Bishop0df00be2017-05-25 23:38:37 -040084};
85
86/** @class Method
87 * @brief C++ type specific logic for the method callback.
88 *
89 * @tparam DBusInterface - The DBus interface to use to call the method.
90 * @tparam MethodArgs - DBus method argument types.
91 */
Brad Bishopd1eac882018-03-29 10:34:05 -040092template <typename DBusInterface, typename... MethodArgs>
Brad Bishop0df00be2017-05-25 23:38:37 -040093class Method : public MethodBase
94{
Brad Bishopd1eac882018-03-29 10:34:05 -040095 public:
96 Method() = delete;
97 Method(const Method&) = default;
98 Method(Method&&) = default;
99 Method& operator=(const Method&) = default;
100 Method& operator=(Method&&) = default;
101 ~Method() = default;
102 Method(const std::string& bus, const std::string& path,
103 const std::string& iface, const std::string& method,
104 MethodArgs&&... arguments) :
105 MethodBase(bus, path, iface, method),
106 args(std::forward<MethodArgs>(arguments)...)
George Liu3fe976c2022-06-21 09:37:04 +0800107 {}
Brad Bishop0df00be2017-05-25 23:38:37 -0400108
Brad Bishopd1eac882018-03-29 10:34:05 -0400109 /** @brief Callback interface implementation. */
George Liu5e6b51d2022-06-21 16:59:39 +0800110 void operator()(Context /* ctx */) override
Brad Bishopd1eac882018-03-29 10:34:05 -0400111 {
Patrick Williams26dc0bc2022-06-16 17:06:18 -0500112 std::apply(detail::CallDBusMethod<DBusInterface, MethodArgs...>::op,
113 std::tuple_cat(std::make_tuple(bus), std::make_tuple(path),
114 std::make_tuple(interface),
115 std::make_tuple(method), args));
Brad Bishopd1eac882018-03-29 10:34:05 -0400116 }
Brad Bishop0df00be2017-05-25 23:38:37 -0400117
Brad Bishopd1eac882018-03-29 10:34:05 -0400118 private:
119 std::tuple<MethodArgs...> args;
Brad Bishop0df00be2017-05-25 23:38:37 -0400120};
121
122/** @brief Argument type deduction for constructing Method instances. */
Brad Bishopd1eac882018-03-29 10:34:05 -0400123template <typename DBusInterface, typename... MethodArgs>
124auto makeMethod(const std::string& bus, const std::string& path,
125 const std::string& iface, const std::string& method,
126 MethodArgs&&... arguments)
Brad Bishop0df00be2017-05-25 23:38:37 -0400127{
128 return std::make_unique<Method<DBusInterface, MethodArgs...>>(
Brad Bishopd1eac882018-03-29 10:34:05 -0400129 bus, path, iface, method, std::forward<MethodArgs>(arguments)...);
Brad Bishop0df00be2017-05-25 23:38:37 -0400130}
131
132} // namespace monitoring
133} // namespace dbus
134} // namespace phosphor