blob: 1efe54d7c50e0bc101b96756f7896a5ca5e2d225 [file] [log] [blame]
Brad Bishop6e9cfdb2017-06-08 11:59:58 -04001#pragma once
2
3#include <sdbusplus/bus.hpp>
4#include <sdbusplus/message.hpp>
5#include <sdbusplus/bus/match.hpp>
6#include <phosphor-logging/log.hpp>
7#include <phosphor-logging/elog.hpp>
8#include <phosphor-logging/elog-errors.hpp>
9#include <xyz/openbmc_project/Common/error.hpp>
10
11namespace phosphor
12{
13namespace fan
14{
15namespace util
16{
17namespace detail
18{
19namespace errors = sdbusplus::xyz::openbmc_project::Common::Error;
20} // namespace detail
21
Brad Bishop1e4922a2017-07-12 22:56:49 -040022/** @brief Alias for PropertiesChanged signal callbacks. */
23template <typename ...T>
24using Properties = std::map<std::string, sdbusplus::message::variant<T...>>;
25
Brad Bishop6e9cfdb2017-06-08 11:59:58 -040026/** @class SDBusPlus
27 * @brief DBus access delegate implementation for sdbusplus.
28 */
29class SDBusPlus
30{
31
32 public:
33 /** @brief Get the bus connection. */
34 static auto& getBus() __attribute__((pure))
35 {
36 static auto bus = sdbusplus::bus::new_default();
37 return bus;
38 }
39
40 /** @brief Invoke a method. */
41 template <typename ...Args>
42 static auto callMethod(
Brad Bishopf2238ae2017-07-30 13:32:23 -040043 sdbusplus::bus::bus& bus,
Brad Bishop6e9cfdb2017-06-08 11:59:58 -040044 const std::string& busName,
45 const std::string& path,
46 const std::string& interface,
47 const std::string& method,
48 Args&& ... args)
49 {
Brad Bishopf2238ae2017-07-30 13:32:23 -040050 auto reqMsg = bus.new_method_call(
Brad Bishope67b41b2017-07-30 13:20:37 -040051 busName.c_str(),
52 path.c_str(),
53 interface.c_str(),
54 method.c_str());
Brad Bishop6e9cfdb2017-06-08 11:59:58 -040055 reqMsg.append(std::forward<Args>(args)...);
Brad Bishopf2238ae2017-07-30 13:32:23 -040056 auto respMsg = bus.call(reqMsg);
Brad Bishop6e9cfdb2017-06-08 11:59:58 -040057
58 if (respMsg.is_method_error())
59 {
60 phosphor::logging::log<phosphor::logging::level::INFO>(
61 "Failed to invoke DBus method.",
62 phosphor::logging::entry("PATH=%s", path.c_str()),
63 phosphor::logging::entry(
Brad Bishope67b41b2017-07-30 13:20:37 -040064 "INTERFACE=%s", interface.c_str()),
Brad Bishop6e9cfdb2017-06-08 11:59:58 -040065 phosphor::logging::entry("METHOD=%s", method.c_str()));
66 phosphor::logging::elog<detail::errors::InternalFailure>();
67 }
68
69 return respMsg;
70 }
71
Brad Bishopf2238ae2017-07-30 13:32:23 -040072 /** @brief Invoke a method. */
73 template <typename ...Args>
74 static auto callMethod(
75 const std::string& busName,
76 const std::string& path,
77 const std::string& interface,
78 const std::string& method,
79 Args&& ... args)
80 {
81 return callMethod(
82 getBus(),
83 busName,
84 path,
85 interface,
86 method,
87 std::forward<Args>(args)...);
88 }
89
Brad Bishop6e9cfdb2017-06-08 11:59:58 -040090 /** @brief Invoke a method and read the response. */
91 template <typename Ret, typename ...Args>
92 static auto callMethodAndRead(
Brad Bishopf2238ae2017-07-30 13:32:23 -040093 sdbusplus::bus::bus& bus,
Brad Bishop6e9cfdb2017-06-08 11:59:58 -040094 const std::string& busName,
95 const std::string& path,
96 const std::string& interface,
97 const std::string& method,
98 Args&& ... args)
99 {
100 sdbusplus::message::message respMsg =
Brad Bishope67b41b2017-07-30 13:20:37 -0400101 callMethod<Args...>(
Brad Bishopf2238ae2017-07-30 13:32:23 -0400102 bus,
Brad Bishope67b41b2017-07-30 13:20:37 -0400103 busName,
104 path,
105 interface,
106 method,
107 std::forward<Args>(args)...);
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400108 Ret resp;
109 respMsg.read(resp);
110 return resp;
111 }
112
Brad Bishopf2238ae2017-07-30 13:32:23 -0400113 /** @brief Invoke a method and read the response. */
114 template <typename Ret, typename ...Args>
115 static auto callMethodAndRead(
116 const std::string& busName,
117 const std::string& path,
118 const std::string& interface,
119 const std::string& method,
120 Args&& ... args)
121 {
122 return callMethodAndRead<Ret>(
123 getBus(),
124 busName,
125 path,
126 interface,
127 method,
128 std::forward<Args>(args)...);
129 }
130
131
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400132 /** @brief Get service from the mapper. */
133 static auto getService(
Brad Bishopf2238ae2017-07-30 13:32:23 -0400134 sdbusplus::bus::bus& bus,
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400135 const std::string& path,
136 const std::string& interface)
137 {
138 using namespace std::literals::string_literals;
139 using GetObject = std::map<std::string, std::vector<std::string>>;
140
141 auto mapperResp = callMethodAndRead<GetObject>(
Brad Bishopf2238ae2017-07-30 13:32:23 -0400142 bus,
Brad Bishope67b41b2017-07-30 13:20:37 -0400143 "xyz.openbmc_project.ObjectMapper"s,
144 "/xyz/openbmc_project/object_mapper"s,
145 "xyz.openbmc_project.ObjectMapper"s,
146 "GetObject"s,
147 path,
148 GetObject::mapped_type{interface});
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400149
150 if (mapperResp.empty())
151 {
152 phosphor::logging::log<phosphor::logging::level::INFO>(
153 "Object not found.",
154 phosphor::logging::entry("PATH=%s", path.c_str()),
155 phosphor::logging::entry(
Brad Bishope67b41b2017-07-30 13:20:37 -0400156 "INTERFACE=%s", interface.c_str()));
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400157 phosphor::logging::elog<detail::errors::InternalFailure>();
158 }
159 return mapperResp.begin()->first;
160 }
161
Brad Bishopf2238ae2017-07-30 13:32:23 -0400162 /** @brief Get service from the mapper. */
163 static auto getService(
164 const std::string& path,
165 const std::string& interface)
166 {
167 return getService(
168 getBus(),
169 path,
170 interface);
171 }
172
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400173 /** @brief Get a property with mapper lookup. */
174 template <typename Property>
175 static auto getProperty(
Brad Bishopf2238ae2017-07-30 13:32:23 -0400176 sdbusplus::bus::bus& bus,
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400177 const std::string& path,
178 const std::string& interface,
179 const std::string& property)
180 {
181 using namespace std::literals::string_literals;
182
183 auto msg = callMethod(
Brad Bishopf2238ae2017-07-30 13:32:23 -0400184 bus,
185 getService(bus, path, interface),
Brad Bishope67b41b2017-07-30 13:20:37 -0400186 path,
187 "org.freedesktop.DBus.Properties"s,
188 "Get"s,
189 interface,
190 property);
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400191 sdbusplus::message::variant<Property> value;
192 msg.read(value);
193 return value.template get<Property>();
194 }
195
Brad Bishopf2238ae2017-07-30 13:32:23 -0400196 /** @brief Get a property with mapper lookup. */
197 template <typename Property>
198 static auto getProperty(
199 const std::string& path,
200 const std::string& interface,
201 const std::string& property)
202 {
203 return getProperty<Property>(
204 getBus(),
205 path,
206 interface,
207 property);
208 }
209
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400210 /** @brief Set a property with mapper lookup. */
211 template <typename Property>
212 static void setProperty(
Brad Bishopf2238ae2017-07-30 13:32:23 -0400213 sdbusplus::bus::bus& bus,
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400214 const std::string& path,
215 const std::string& interface,
216 const std::string& property,
217 Property&& value)
218 {
219 using namespace std::literals::string_literals;
220
221 sdbusplus::message::variant<Property> varValue(
Brad Bishope67b41b2017-07-30 13:20:37 -0400222 std::forward<Property>(value));
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400223
224 callMethod(
Brad Bishopf2238ae2017-07-30 13:32:23 -0400225 bus,
226 getService(bus, path, interface),
Brad Bishope67b41b2017-07-30 13:20:37 -0400227 path,
228 "org.freedesktop.DBus.Properties"s,
229 "Set"s,
230 interface,
231 property,
232 varValue);
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400233 }
234
Brad Bishopf2238ae2017-07-30 13:32:23 -0400235 /** @brief Set a property with mapper lookup. */
236 template <typename Property>
237 static void setProperty(
238 const std::string& path,
239 const std::string& interface,
240 const std::string& property,
241 Property&& value)
242 {
243 return setProperty(
244 getBus(),
245 path,
246 interface,
247 property,
248 std::forward<Property>(value));
249 }
250
251 /** @brief Invoke method with mapper lookup. */
252 template <typename ...Args>
253 static auto lookupAndCallMethod(
254 sdbusplus::bus::bus& bus,
255 const std::string& path,
256 const std::string& interface,
257 const std::string& method,
258 Args&& ... args)
259 {
260 return callMethod(
261 bus,
262 getService(bus, path, interface),
263 path,
264 interface,
265 method,
266 std::forward<Args>(args)...);
267 }
268
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400269 /** @brief Invoke method with mapper lookup. */
270 template <typename ...Args>
271 static auto lookupAndCallMethod(
272 const std::string& path,
273 const std::string& interface,
274 const std::string& method,
275 Args&& ... args)
276 {
Brad Bishopf2238ae2017-07-30 13:32:23 -0400277 return lookupAndCallMethod(
278 getBus(),
279 path,
280 interface,
281 method,
282 std::forward<Args>(args)...);
283 }
284
285 /** @brief Invoke method and read with mapper lookup. */
286 template <typename Ret, typename ...Args>
287 static auto lookupCallMethodAndRead(
288 sdbusplus::bus::bus& bus,
289 const std::string& path,
290 const std::string& interface,
291 const std::string& method,
292 Args&& ... args)
293 {
294 return callMethodAndRead(
295 bus,
296 getService(bus, path, interface),
Brad Bishope67b41b2017-07-30 13:20:37 -0400297 path,
298 interface,
299 method,
300 std::forward<Args>(args)...);
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400301 }
302
303 /** @brief Invoke method and read with mapper lookup. */
304 template <typename Ret, typename ...Args>
305 static auto lookupCallMethodAndRead(
306 const std::string& path,
307 const std::string& interface,
308 const std::string& method,
309 Args&& ... args)
310 {
Brad Bishopf2238ae2017-07-30 13:32:23 -0400311 return lookupCallMethodAndRead<Ret>(
312 getBus(),
Brad Bishope67b41b2017-07-30 13:20:37 -0400313 path,
314 interface,
315 method,
316 std::forward<Args>(args)...);
Brad Bishop6e9cfdb2017-06-08 11:59:58 -0400317 }
318};
319
320} // namespace util
321} // namespace fan
322} // namespace phosphor