1 #pragma once
2 
3 #include <sdbusplus/bus.hpp>
4 #include <sdbusplus/message.hpp>
5 #include <sdbusplus/bus/match.hpp>
6 
7 struct Loop;
8 
9 namespace phosphor
10 {
11 namespace dbus
12 {
13 namespace monitoring
14 {
15 
16 /** @class SDBusPlus
17  *  @brief DBus access delegate implementation for sdbusplus.
18  */
19 class SDBusPlus
20 {
21     private:
22         static auto& getBus()
23         {
24             static auto bus = sdbusplus::bus::new_default();
25             return bus;
26         }
27 
28         static auto& getWatches()
29         {
30             static std::vector<sdbusplus::bus::match::match> watches;
31             return watches;
32         }
33 
34     public:
35         /** @brief Invoke a method; ignore reply. */
36         template <typename ...Args>
37         static void callMethodNoReply(
38             const std::string& busName,
39             const std::string& path,
40             const std::string& interface,
41             const std::string& method,
42             Args&& ... args)
43         {
44             auto reqMsg = getBus().new_method_call(
45                               busName.c_str(),
46                               path.c_str(),
47                               interface.c_str(),
48                               method.c_str());
49             reqMsg.append(std::forward<Args>(args)...);
50             getBus().call_noreply(reqMsg);
51 
52             // TODO: openbmc/openbmc#1719
53             // invoke these methods async, with a callback
54             // handler that checks for errors and logs.
55         }
56 
57         /** @brief Invoke a method. */
58         template <typename ...Args>
59         static auto callMethod(
60             const std::string& busName,
61             const std::string& path,
62             const std::string& interface,
63             const std::string& method,
64             Args&& ... args)
65         {
66             auto reqMsg = getBus().new_method_call(
67                               busName.c_str(),
68                               path.c_str(),
69                               interface.c_str(),
70                               method.c_str());
71             reqMsg.append(std::forward<Args>(args)...);
72             return getBus().call(reqMsg);
73         }
74 
75         /** @brief Invoke a method and read the response. */
76         template <typename Ret, typename ...Args>
77         static auto callMethodAndRead(
78             const std::string& busName,
79             const std::string& path,
80             const std::string& interface,
81             const std::string& method,
82             Args&& ... args)
83         {
84             Ret resp;
85             sdbusplus::message::message respMsg =
86                 callMethod<Args...>(
87                     busName,
88                     path,
89                     interface,
90                     method,
91                     std::forward<Args>(args)...);
92             respMsg.read(resp);
93             return resp;
94         }
95 
96         /** @brief Register a DBus signal callback. */
97         static auto addMatch(
98             const std::string& match,
99             const sdbusplus::bus::match::match::callback_t& callback)
100         {
101             getWatches().emplace_back(
102                     getBus(),
103                     match,
104                     callback);
105         }
106 
107         friend Loop;
108 };
109 
110 } // namespace monitoring
111 } // namespace dbus
112 } // namespace phosphor
113