blob: 3767282acd6f2d3c0dc29f4c488ce71fe67cff36 [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>
42 static void callMethodNoReply(const std::string& busName,
43 const std::string& path,
44 const std::string& interface,
45 const std::string& method, Args&&... args)
46 {
47 auto reqMsg = getBus().new_method_call(
48 busName.c_str(), path.c_str(), interface.c_str(), method.c_str());
49 reqMsg.append(std::forward<Args>(args)...);
50 getBus().call_noreply(reqMsg);
51
52 // TODO: openbmc/openbmc#1719
53 // invoke these methods async, with a callback
54 // handler that checks for errors and logs.
55 }
56
57 /** @brief Invoke a method. */
58 template <typename... Args>
59 static auto callMethod(const std::string& busName, const std::string& path,
60 const std::string& interface,
61 const std::string& method, Args&&... args)
62 {
63 auto reqMsg = getBus().new_method_call(
64 busName.c_str(), path.c_str(), interface.c_str(), method.c_str());
65 reqMsg.append(std::forward<Args>(args)...);
66 return getBus().call(reqMsg);
67 }
68
69 /** @brief Invoke a method and read the response. */
70 template <typename Ret, typename... Args>
71 static auto callMethodAndRead(const std::string& busName,
72 const std::string& path,
73 const std::string& interface,
74 const std::string& method, Args&&... args)
75 {
76 Ret resp;
Patrick Williams413a4852022-07-22 19:26:52 -050077 sdbusplus::message_t respMsg = callMethod<Args...>(
Brad Bishopd1eac882018-03-29 10:34:05 -040078 busName, path, interface, method, std::forward<Args>(args)...);
Adriana Kobylak0049c982018-06-06 15:33:22 -050079 try
80 {
81 respMsg.read(resp);
82 }
Patrick Williams413a4852022-07-22 19:26:52 -050083 catch (const sdbusplus::exception_t& e)
Adriana Kobylak0049c982018-06-06 15:33:22 -050084 {
Matt Spinler195550c2018-06-13 13:51:40 -050085 // Empty responses are expected sometimes, and the calling
86 // code is set up to handle it.
Adriana Kobylak0049c982018-06-06 15:33:22 -050087 }
Brad Bishopd1eac882018-03-29 10:34:05 -040088 return resp;
89 }
90
91 /** @brief Register a DBus signal callback. */
Patrick Williams413a4852022-07-22 19:26:52 -050092 static auto addMatch(const std::string& match,
93 const sdbusplus::bus::match_t::callback_t& callback)
Brad Bishopd1eac882018-03-29 10:34:05 -040094 {
95 getWatches().emplace_back(getBus(), match, callback);
96 }
97
98 /** @brief Look up the bus name for a path and interface */
99 static auto getBusName(const std::string& path,
100 const std::string& interface)
101 {
102 std::vector<std::string> interfaces{interface};
Brad Bishopd1eac882018-03-29 10:34:05 -0400103 std::string name;
Adriana Kobylak2ded5e12018-07-10 12:55:51 -0500104
105 try
Brad Bishopfac1b102017-05-15 22:29:20 -0400106 {
Adriana Kobylak2ded5e12018-07-10 12:55:51 -0500107 auto object = callMethodAndRead<GetObject>(
108 MAPPER_BUSNAME, MAPPER_PATH, MAPPER_INTERFACE, "GetObject",
109 path, interfaces);
110
111 if (!object.empty())
112 {
113 name = object.begin()->first;
114 }
115 }
Patrick Williams413a4852022-07-22 19:26:52 -0500116 catch (const sdbusplus::exception_t& e)
Adriana Kobylak2ded5e12018-07-10 12:55:51 -0500117 {
118 // Empty responses are expected sometimes, and the calling
119 // code is set up to handle it.
Brad Bishopfac1b102017-05-15 22:29:20 -0400120 }
Brad Bishopd1eac882018-03-29 10:34:05 -0400121 return name;
122 }
Brad Bishopfac1b102017-05-15 22:29:20 -0400123
Brad Bishopd1eac882018-03-29 10:34:05 -0400124 friend Loop;
Brad Bishopfac1b102017-05-15 22:29:20 -0400125};
126
127} // namespace monitoring
128} // namespace dbus
129} // namespace phosphor