blob: 0a8e715a9ee818b8513b88dac1c01fbd6a866043 [file] [log] [blame]
Brad Bishopfac1b102017-05-15 22:29:20 -04001#pragma once
2
Adriana Kobylak0049c982018-06-06 15:33:22 -05003#include <phosphor-logging/log.hpp>
Brad Bishopfac1b102017-05-15 22:29:20 -04004#include <sdbusplus/bus.hpp>
Adriana Kobylak0049c982018-06-06 15:33:22 -05005#include <sdbusplus/exception.hpp>
Brad Bishopfac1b102017-05-15 22:29:20 -04006#include <sdbusplus/message.hpp>
7#include <sdbusplus/bus/match.hpp>
Matt Spinlerdf1b7cf2017-10-31 14:17:23 -05008#include "data_types.hpp"
Brad Bishopfac1b102017-05-15 22:29:20 -04009
Brad Bishopd9c1fab2017-06-04 22:32:12 -040010struct Loop;
11
Brad Bishopfac1b102017-05-15 22:29:20 -040012namespace phosphor
13{
14namespace dbus
15{
16namespace monitoring
17{
18
Adriana Kobylak0049c982018-06-06 15:33:22 -050019using namespace phosphor::logging;
20using sdbusplus::exception::SdBusError;
21
Brad Bishopfac1b102017-05-15 22:29:20 -040022/** @class SDBusPlus
23 * @brief DBus access delegate implementation for sdbusplus.
24 */
25class SDBusPlus
26{
Brad Bishopd1eac882018-03-29 10:34:05 -040027 private:
28 static auto& getWatches()
29 {
30 static std::vector<sdbusplus::bus::match::match> watches;
31 return watches;
32 }
33
34 public:
35 static auto& getBus()
36 {
37 static auto bus = sdbusplus::bus::new_default();
38 return bus;
39 }
40
41 /** @brief Invoke a method; ignore reply. */
42 template <typename... Args>
43 static void callMethodNoReply(const std::string& busName,
44 const std::string& path,
45 const std::string& interface,
46 const std::string& method, Args&&... args)
47 {
48 auto reqMsg = getBus().new_method_call(
49 busName.c_str(), path.c_str(), interface.c_str(), 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
58 /** @brief Invoke a method. */
59 template <typename... Args>
60 static auto callMethod(const std::string& busName, const std::string& path,
61 const std::string& interface,
62 const std::string& method, Args&&... args)
63 {
64 auto reqMsg = getBus().new_method_call(
65 busName.c_str(), path.c_str(), interface.c_str(), method.c_str());
66 reqMsg.append(std::forward<Args>(args)...);
67 return getBus().call(reqMsg);
68 }
69
70 /** @brief Invoke a method and read the response. */
71 template <typename Ret, typename... Args>
72 static auto callMethodAndRead(const std::string& busName,
73 const std::string& path,
74 const std::string& interface,
75 const std::string& method, Args&&... args)
76 {
77 Ret resp;
78 sdbusplus::message::message respMsg = callMethod<Args...>(
79 busName, path, interface, method, std::forward<Args>(args)...);
Adriana Kobylak0049c982018-06-06 15:33:22 -050080 try
81 {
82 respMsg.read(resp);
83 }
84 catch (const SdBusError& e)
85 {
Matt Spinler195550c2018-06-13 13:51:40 -050086 // Empty responses are expected sometimes, and the calling
87 // code is set up to handle it.
Adriana Kobylak0049c982018-06-06 15:33:22 -050088 }
Brad Bishopd1eac882018-03-29 10:34:05 -040089 return resp;
90 }
91
92 /** @brief Register a DBus signal callback. */
93 static auto
94 addMatch(const std::string& match,
95 const sdbusplus::bus::match::match::callback_t& callback)
96 {
97 getWatches().emplace_back(getBus(), match, callback);
98 }
99
100 /** @brief Look up the bus name for a path and interface */
101 static auto getBusName(const std::string& path,
102 const std::string& interface)
103 {
104 std::vector<std::string> interfaces{interface};
Brad Bishopd1eac882018-03-29 10:34:05 -0400105 std::string name;
Adriana Kobylak2ded5e12018-07-10 12:55:51 -0500106
107 try
Brad Bishopfac1b102017-05-15 22:29:20 -0400108 {
Adriana Kobylak2ded5e12018-07-10 12:55:51 -0500109 auto object = callMethodAndRead<GetObject>(
110 MAPPER_BUSNAME, MAPPER_PATH, MAPPER_INTERFACE, "GetObject",
111 path, interfaces);
112
113 if (!object.empty())
114 {
115 name = object.begin()->first;
116 }
117 }
118 catch (const SdBusError& e)
119 {
120 // Empty responses are expected sometimes, and the calling
121 // code is set up to handle it.
Brad Bishopfac1b102017-05-15 22:29:20 -0400122 }
Brad Bishopd1eac882018-03-29 10:34:05 -0400123 return name;
124 }
Brad Bishopfac1b102017-05-15 22:29:20 -0400125
Brad Bishopd1eac882018-03-29 10:34:05 -0400126 friend Loop;
Brad Bishopfac1b102017-05-15 22:29:20 -0400127};
128
129} // namespace monitoring
130} // namespace dbus
131} // namespace phosphor