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