10df00be0SBrad Bishop #pragma once
20df00be0SBrad Bishop
30df00be0SBrad Bishop #include "callback.hpp"
40df00be0SBrad Bishop
513e3df60SGeorge Liu #include <phosphor-logging/lg2.hpp>
63fe976ccSGeorge Liu
73fe976ccSGeorge Liu #include <experimental/tuple>
8ae4c95c6SAndrew Geissler #include <string>
926dc0bcbSPatrick Williams #include <tuple>
103d6d3182SPatrick Venture
110df00be0SBrad Bishop namespace phosphor
120df00be0SBrad Bishop {
130df00be0SBrad Bishop namespace dbus
140df00be0SBrad Bishop {
150df00be0SBrad Bishop namespace monitoring
160df00be0SBrad Bishop {
170df00be0SBrad Bishop namespace detail
180df00be0SBrad Bishop {
190df00be0SBrad Bishop
200df00be0SBrad Bishop /** @class CallDBusMethod
210df00be0SBrad Bishop * @brief Provide explicit call forwarding to
220df00be0SBrad Bishop * DBusInterface::callMethodNoReply.
230df00be0SBrad Bishop *
240df00be0SBrad Bishop * @tparam DBusInterface - The DBus interface to use.
250df00be0SBrad Bishop * @tparam MethodArgs - DBus method argument types.
260df00be0SBrad Bishop */
273d6d3182SPatrick Venture template <typename DBusInterface, typename... MethodArgs>
283d6d3182SPatrick Venture struct CallDBusMethod
290df00be0SBrad Bishop {
opphosphor::dbus::monitoring::detail::CallDBusMethod30d1eac88dSBrad Bishop static void op(const std::string& bus, const std::string& path,
31d1eac88dSBrad Bishop const std::string& iface, const std::string& method,
320df00be0SBrad Bishop MethodArgs&&... args)
330df00be0SBrad Bishop {
3412789e6cSAlexander Soldatov try
3512789e6cSAlexander Soldatov {
36d1eac88dSBrad Bishop DBusInterface::callMethodNoReply(bus, path, iface, method,
370df00be0SBrad Bishop std::forward<MethodArgs>(args)...);
380df00be0SBrad Bishop }
39413a4857SPatrick Williams catch (const sdbusplus::exception_t& e)
4012789e6cSAlexander Soldatov {
4113e3df60SGeorge Liu lg2::error(
4213e3df60SGeorge Liu "Unable to call DBus method: {ERROR}. {BUS}, {PATH}, {INTF}, {METHOD}",
4313e3df60SGeorge Liu "ERROR", e, "BUS", bus, "PATH", path, "INTF", iface, "METHOD",
4413e3df60SGeorge Liu method);
4512789e6cSAlexander Soldatov }
4612789e6cSAlexander Soldatov }
470df00be0SBrad Bishop };
480df00be0SBrad Bishop } // namespace detail
490df00be0SBrad Bishop
500df00be0SBrad Bishop /** @class MethodBase
510df00be0SBrad Bishop * @brief Invoke DBus method callback implementation.
520df00be0SBrad Bishop *
530df00be0SBrad Bishop * The method callback invokes the client supplied DBus method.
540df00be0SBrad Bishop */
550df00be0SBrad Bishop class MethodBase : public Callback
560df00be0SBrad Bishop {
570df00be0SBrad Bishop public:
580df00be0SBrad Bishop MethodBase() = delete;
590df00be0SBrad Bishop MethodBase(const MethodBase&) = delete;
600df00be0SBrad Bishop MethodBase(MethodBase&&) = default;
610df00be0SBrad Bishop MethodBase& operator=(const MethodBase&) = delete;
620df00be0SBrad Bishop MethodBase& operator=(MethodBase&&) = default;
630df00be0SBrad Bishop virtual ~MethodBase() = default;
MethodBase(const std::string & b,const std::string & p,const std::string & i,const std::string & m)64d1eac88dSBrad Bishop MethodBase(const std::string& b, const std::string& p, const std::string& i,
65d1eac88dSBrad Bishop const std::string& m) :
66*eab4f8c0SPatrick Williams Callback(), bus(b), path(p), interface(i), method(m)
673fe976ccSGeorge Liu {}
680df00be0SBrad Bishop
690df00be0SBrad Bishop /** @brief Callback interface implementation. */
70a45e086dSRatan Gupta void operator()(Context ctx) override = 0;
710df00be0SBrad Bishop
720df00be0SBrad Bishop protected:
730df00be0SBrad Bishop const std::string& bus;
740df00be0SBrad Bishop const std::string& path;
750df00be0SBrad Bishop const std::string& interface;
760df00be0SBrad Bishop const std::string& method;
770df00be0SBrad Bishop };
780df00be0SBrad Bishop
790df00be0SBrad Bishop /** @class Method
800df00be0SBrad Bishop * @brief C++ type specific logic for the method callback.
810df00be0SBrad Bishop *
820df00be0SBrad Bishop * @tparam DBusInterface - The DBus interface to use to call the method.
830df00be0SBrad Bishop * @tparam MethodArgs - DBus method argument types.
840df00be0SBrad Bishop */
850df00be0SBrad Bishop template <typename DBusInterface, typename... MethodArgs>
860df00be0SBrad Bishop class Method : public MethodBase
870df00be0SBrad Bishop {
880df00be0SBrad Bishop public:
890df00be0SBrad Bishop Method() = delete;
900df00be0SBrad Bishop Method(const Method&) = default;
910df00be0SBrad Bishop Method(Method&&) = default;
920df00be0SBrad Bishop Method& operator=(const Method&) = default;
930df00be0SBrad Bishop Method& operator=(Method&&) = default;
940df00be0SBrad Bishop ~Method() = default;
Method(const std::string & bus,const std::string & path,const std::string & iface,const std::string & method,MethodArgs &&...arguments)95d1eac88dSBrad Bishop Method(const std::string& bus, const std::string& path,
96d1eac88dSBrad Bishop const std::string& iface, const std::string& method,
97d1eac88dSBrad Bishop MethodArgs&&... arguments) :
98d1eac88dSBrad Bishop MethodBase(bus, path, iface, method),
99d1eac88dSBrad Bishop args(std::forward<MethodArgs>(arguments)...)
1003fe976ccSGeorge Liu {}
1010df00be0SBrad Bishop
1020df00be0SBrad Bishop /** @brief Callback interface implementation. */
operator ()(Context)1035e6b51d7SGeorge Liu void operator()(Context /* ctx */) override
1040df00be0SBrad Bishop {
10526dc0bcbSPatrick Williams std::apply(detail::CallDBusMethod<DBusInterface, MethodArgs...>::op,
106d1eac88dSBrad Bishop std::tuple_cat(std::make_tuple(bus), std::make_tuple(path),
10726dc0bcbSPatrick Williams std::make_tuple(interface),
10826dc0bcbSPatrick Williams std::make_tuple(method), args));
1090df00be0SBrad Bishop }
1100df00be0SBrad Bishop
1110df00be0SBrad Bishop private:
1120df00be0SBrad Bishop std::tuple<MethodArgs...> args;
1130df00be0SBrad Bishop };
1140df00be0SBrad Bishop
1150df00be0SBrad Bishop /** @brief Argument type deduction for constructing Method instances. */
1160df00be0SBrad Bishop template <typename DBusInterface, typename... MethodArgs>
makeMethod(const std::string & bus,const std::string & path,const std::string & iface,const std::string & method,MethodArgs &&...arguments)117d1eac88dSBrad Bishop auto makeMethod(const std::string& bus, const std::string& path,
118d1eac88dSBrad Bishop const std::string& iface, const std::string& method,
1190df00be0SBrad Bishop MethodArgs&&... arguments)
1200df00be0SBrad Bishop {
1210df00be0SBrad Bishop return std::make_unique<Method<DBusInterface, MethodArgs...>>(
122d1eac88dSBrad Bishop bus, path, iface, method, std::forward<MethodArgs>(arguments)...);
1230df00be0SBrad Bishop }
1240df00be0SBrad Bishop
1250df00be0SBrad Bishop } // namespace monitoring
1260df00be0SBrad Bishop } // namespace dbus
1270df00be0SBrad Bishop } // namespace phosphor
128