blob: 1b54582ea9689808a89a2287be744c4fe800dc42 [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{
Brad Bishopd1eac882018-03-29 10:34:05 -040022 private:
23 static auto& getWatches()
24 {
25 static std::vector<sdbusplus::bus::match::match> watches;
26 return watches;
27 }
28
29 public:
30 static auto& getBus()
31 {
32 static auto bus = sdbusplus::bus::new_default();
33 return bus;
34 }
35
36 /** @brief Invoke a method; ignore reply. */
37 template <typename... Args>
38 static void callMethodNoReply(const std::string& busName,
39 const std::string& path,
40 const std::string& interface,
41 const std::string& method, Args&&... args)
42 {
43 auto reqMsg = getBus().new_method_call(
44 busName.c_str(), path.c_str(), interface.c_str(), method.c_str());
45 reqMsg.append(std::forward<Args>(args)...);
46 getBus().call_noreply(reqMsg);
47
48 // TODO: openbmc/openbmc#1719
49 // invoke these methods async, with a callback
50 // handler that checks for errors and logs.
51 }
52
53 /** @brief Invoke a method. */
54 template <typename... Args>
55 static auto callMethod(const std::string& busName, const std::string& path,
56 const std::string& interface,
57 const std::string& method, Args&&... args)
58 {
59 auto reqMsg = getBus().new_method_call(
60 busName.c_str(), path.c_str(), interface.c_str(), method.c_str());
61 reqMsg.append(std::forward<Args>(args)...);
62 return getBus().call(reqMsg);
63 }
64
65 /** @brief Invoke a method and read the response. */
66 template <typename Ret, typename... Args>
67 static auto callMethodAndRead(const std::string& busName,
68 const std::string& path,
69 const std::string& interface,
70 const std::string& method, Args&&... args)
71 {
72 Ret resp;
73 sdbusplus::message::message respMsg = callMethod<Args...>(
74 busName, path, interface, method, std::forward<Args>(args)...);
75 respMsg.read(resp);
76 return resp;
77 }
78
79 /** @brief Register a DBus signal callback. */
80 static auto
81 addMatch(const std::string& match,
82 const sdbusplus::bus::match::match::callback_t& callback)
83 {
84 getWatches().emplace_back(getBus(), match, callback);
85 }
86
87 /** @brief Look up the bus name for a path and interface */
88 static auto getBusName(const std::string& path,
89 const std::string& interface)
90 {
91 std::vector<std::string> interfaces{interface};
92
93 auto object = callMethodAndRead<GetObject>(
94 MAPPER_BUSNAME, MAPPER_PATH, MAPPER_INTERFACE, "GetObject", path,
95 interfaces);
96
97 std::string name;
98 if (!object.empty())
Brad Bishopfac1b102017-05-15 22:29:20 -040099 {
Brad Bishopd1eac882018-03-29 10:34:05 -0400100 name = object.begin()->first;
Brad Bishopfac1b102017-05-15 22:29:20 -0400101 }
Brad Bishopd1eac882018-03-29 10:34:05 -0400102 return name;
103 }
Brad Bishopfac1b102017-05-15 22:29:20 -0400104
Brad Bishopd1eac882018-03-29 10:34:05 -0400105 friend Loop;
Brad Bishopfac1b102017-05-15 22:29:20 -0400106};
107
108} // namespace monitoring
109} // namespace dbus
110} // namespace phosphor