blob: 083cdf456b50c733262d5a0b1aeb8d6588f16d99 [file] [log] [blame]
Brad Bishopfac1b102017-05-15 22:29:20 -04001#pragma once
2
Patrick Venture3d6d3182018-08-31 09:33:09 -07003#include "data_types.hpp"
4
Brad Bishopfac1b102017-05-15 22:29:20 -04005#include <sdbusplus/bus.hpp>
Patrick Venture3d6d3182018-08-31 09:33:09 -07006#include <sdbusplus/bus/match.hpp>
Adriana Kobylak0049c982018-06-06 15:33:22 -05007#include <sdbusplus/exception.hpp>
Brad Bishopfac1b102017-05-15 22:29:20 -04008#include <sdbusplus/message.hpp>
George Liu3fe976c2022-06-21 09:37:04 +08009
Andrew Geisslerae4c95c2020-05-16 13:58:53 -050010#include <string>
Brad Bishopfac1b102017-05-15 22:29:20 -040011
Brad Bishopd9c1fab2017-06-04 22:32:12 -040012struct Loop;
13
Brad Bishopfac1b102017-05-15 22:29:20 -040014namespace phosphor
15{
16namespace dbus
17{
18namespace monitoring
19{
20
21/** @class SDBusPlus
22 * @brief DBus access delegate implementation for sdbusplus.
23 */
24class SDBusPlus
25{
Brad Bishopd1eac882018-03-29 10:34:05 -040026 private:
27 static auto& getWatches()
28 {
Patrick Williams413a4852022-07-22 19:26:52 -050029 static std::vector<sdbusplus::bus::match_t> watches;
Brad Bishopd1eac882018-03-29 10:34:05 -040030 return watches;
31 }
32
33 public:
34 static auto& getBus()
35 {
36 static auto bus = sdbusplus::bus::new_default();
37 return bus;
38 }
39
40 /** @brief Invoke a method; ignore reply. */
41 template <typename... Args>
Patrick Williamseab4f8c2024-08-16 15:20:10 -040042 static void callMethodNoReply(
43 const std::string& busName, const std::string& path,
44 const std::string& interface, const std::string& method, Args&&... args)
Brad Bishopd1eac882018-03-29 10:34:05 -040045 {
46 auto reqMsg = getBus().new_method_call(
47 busName.c_str(), path.c_str(), interface.c_str(), method.c_str());
48 reqMsg.append(std::forward<Args>(args)...);
49 getBus().call_noreply(reqMsg);
50
51 // TODO: openbmc/openbmc#1719
52 // invoke these methods async, with a callback
53 // handler that checks for errors and logs.
54 }
55
56 /** @brief Invoke a method. */
57 template <typename... Args>
58 static auto callMethod(const std::string& busName, const std::string& path,
59 const std::string& interface,
60 const std::string& method, Args&&... args)
61 {
62 auto reqMsg = getBus().new_method_call(
63 busName.c_str(), path.c_str(), interface.c_str(), method.c_str());
64 reqMsg.append(std::forward<Args>(args)...);
65 return getBus().call(reqMsg);
66 }
67
68 /** @brief Invoke a method and read the response. */
69 template <typename Ret, typename... Args>
Patrick Williamseab4f8c2024-08-16 15:20:10 -040070 static auto callMethodAndRead(
71 const std::string& busName, const std::string& path,
72 const std::string& interface, const std::string& method, Args&&... args)
Brad Bishopd1eac882018-03-29 10:34:05 -040073 {
74 Ret resp;
Patrick Williams413a4852022-07-22 19:26:52 -050075 sdbusplus::message_t respMsg = callMethod<Args...>(
Brad Bishopd1eac882018-03-29 10:34:05 -040076 busName, path, interface, method, std::forward<Args>(args)...);
Adriana Kobylak0049c982018-06-06 15:33:22 -050077 try
78 {
79 respMsg.read(resp);
80 }
Patrick Williams413a4852022-07-22 19:26:52 -050081 catch (const sdbusplus::exception_t& e)
Adriana Kobylak0049c982018-06-06 15:33:22 -050082 {
Matt Spinler195550c2018-06-13 13:51:40 -050083 // Empty responses are expected sometimes, and the calling
84 // code is set up to handle it.
Adriana Kobylak0049c982018-06-06 15:33:22 -050085 }
Brad Bishopd1eac882018-03-29 10:34:05 -040086 return resp;
87 }
88
89 /** @brief Register a DBus signal callback. */
Patrick Williams413a4852022-07-22 19:26:52 -050090 static auto addMatch(const std::string& match,
William A. Kennington IIIbf975832022-11-24 05:38:04 -080091 sdbusplus::bus::match_t::callback_t&& callback)
Brad Bishopd1eac882018-03-29 10:34:05 -040092 {
William A. Kennington IIIbf975832022-11-24 05:38:04 -080093 getWatches().emplace_back(getBus(), match, std::move(callback));
Brad Bishopd1eac882018-03-29 10:34:05 -040094 }
95
96 /** @brief Look up the bus name for a path and interface */
97 static auto getBusName(const std::string& path,
98 const std::string& interface)
99 {
100 std::vector<std::string> interfaces{interface};
Brad Bishopd1eac882018-03-29 10:34:05 -0400101 std::string name;
Adriana Kobylak2ded5e12018-07-10 12:55:51 -0500102
103 try
Brad Bishopfac1b102017-05-15 22:29:20 -0400104 {
Adriana Kobylak2ded5e12018-07-10 12:55:51 -0500105 auto object = callMethodAndRead<GetObject>(
106 MAPPER_BUSNAME, MAPPER_PATH, MAPPER_INTERFACE, "GetObject",
107 path, interfaces);
108
109 if (!object.empty())
110 {
111 name = object.begin()->first;
112 }
113 }
Patrick Williams413a4852022-07-22 19:26:52 -0500114 catch (const sdbusplus::exception_t& e)
Adriana Kobylak2ded5e12018-07-10 12:55:51 -0500115 {
116 // Empty responses are expected sometimes, and the calling
117 // code is set up to handle it.
Brad Bishopfac1b102017-05-15 22:29:20 -0400118 }
Brad Bishopd1eac882018-03-29 10:34:05 -0400119 return name;
120 }
Brad Bishopfac1b102017-05-15 22:29:20 -0400121
Brad Bishopd1eac882018-03-29 10:34:05 -0400122 friend Loop;
Brad Bishopfac1b102017-05-15 22:29:20 -0400123};
124
125} // namespace monitoring
126} // namespace dbus
127} // namespace phosphor