blob: d62a5d4ec442b56ed404633371f937d124b7f699 [file] [log] [blame]
Brad Bishopfac1b102017-05-15 22:29:20 -04001#pragma once
2
3#include <sdbusplus/bus.hpp>
4#include <sdbusplus/message.hpp>
5#include <sdbusplus/bus/match.hpp>
Matt Spinlerdf1b7cf2017-10-31 14:17:23 -05006#include "data_types.hpp"
Brad Bishopfac1b102017-05-15 22:29:20 -04007
Brad Bishopd9c1fab2017-06-04 22:32:12 -04008struct Loop;
9
Brad Bishopfac1b102017-05-15 22:29:20 -040010namespace phosphor
11{
12namespace dbus
13{
14namespace monitoring
15{
16
17/** @class SDBusPlus
18 * @brief DBus access delegate implementation for sdbusplus.
19 */
20class SDBusPlus
21{
22 private:
23 static auto& getBus()
24 {
25 static auto bus = sdbusplus::bus::new_default();
26 return bus;
27 }
28
29 static auto& getWatches()
30 {
31 static std::vector<sdbusplus::bus::match::match> watches;
32 return watches;
33 }
34
35 public:
Brad Bishop0df00be2017-05-25 23:38:37 -040036 /** @brief Invoke a method; ignore reply. */
37 template <typename ...Args>
38 static void callMethodNoReply(
39 const std::string& busName,
40 const std::string& path,
41 const std::string& interface,
42 const std::string& method,
43 Args&& ... args)
44 {
45 auto reqMsg = getBus().new_method_call(
46 busName.c_str(),
47 path.c_str(),
48 interface.c_str(),
49 method.c_str());
50 reqMsg.append(std::forward<Args>(args)...);
51 getBus().call_noreply(reqMsg);
52
53 // TODO: openbmc/openbmc#1719
54 // invoke these methods async, with a callback
55 // handler that checks for errors and logs.
56 }
57
Brad Bishopfac1b102017-05-15 22:29:20 -040058 /** @brief Invoke a method. */
59 template <typename ...Args>
60 static auto callMethod(
61 const std::string& busName,
62 const std::string& path,
63 const std::string& interface,
64 const std::string& method,
65 Args&& ... args)
66 {
67 auto reqMsg = getBus().new_method_call(
68 busName.c_str(),
69 path.c_str(),
70 interface.c_str(),
71 method.c_str());
72 reqMsg.append(std::forward<Args>(args)...);
73 return getBus().call(reqMsg);
74 }
75
76 /** @brief Invoke a method and read the response. */
77 template <typename Ret, typename ...Args>
78 static auto callMethodAndRead(
79 const std::string& busName,
80 const std::string& path,
81 const std::string& interface,
82 const std::string& method,
83 Args&& ... args)
84 {
85 Ret resp;
86 sdbusplus::message::message respMsg =
87 callMethod<Args...>(
88 busName,
89 path,
90 interface,
91 method,
92 std::forward<Args>(args)...);
93 respMsg.read(resp);
94 return resp;
95 }
96
97 /** @brief Register a DBus signal callback. */
98 static auto addMatch(
99 const std::string& match,
100 const sdbusplus::bus::match::match::callback_t& callback)
101 {
102 getWatches().emplace_back(
103 getBus(),
104 match,
105 callback);
106 }
Brad Bishopd9c1fab2017-06-04 22:32:12 -0400107
Matt Spinlerdf1b7cf2017-10-31 14:17:23 -0500108 /** @brief Look up the bus name for a path and interface */
109 static auto getBusName(
110 const std::string& path,
111 const std::string& interface)
112 {
113 std::vector<std::string> interfaces{interface};
114
115 auto object = callMethodAndRead<GetObject>(
116 MAPPER_BUSNAME,
117 MAPPER_PATH,
118 MAPPER_INTERFACE,
119 "GetObject",
120 path,
121 interfaces);
122
123 std::string name;
124 if (!object.empty())
125 {
126 name = object.begin()->first;
127 }
128 return name;
129 }
130
Brad Bishopd9c1fab2017-06-04 22:32:12 -0400131 friend Loop;
Brad Bishopfac1b102017-05-15 22:29:20 -0400132};
133
134} // namespace monitoring
135} // namespace dbus
136} // namespace phosphor