blob: 1e0b9783740e1b355516ae99dc5d73c9c48b02bd [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 {
29 static std::vector<sdbusplus::bus::match::match> watches;
30 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;
77 sdbusplus::message::message respMsg = callMethod<Args...>(
78 busName, path, interface, method, std::forward<Args>(args)...);
Adriana Kobylak0049c982018-06-06 15:33:22 -050079 try
80 {
81 respMsg.read(resp);
82 }
Patrick Williams764adb52021-09-02 09:36:47 -050083 catch (const sdbusplus::exception::exception& 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. */
92 static auto
93 addMatch(const std::string& match,
94 const sdbusplus::bus::match::match::callback_t& callback)
95 {
96 getWatches().emplace_back(getBus(), match, callback);
97 }
98
99 /** @brief Look up the bus name for a path and interface */
100 static auto getBusName(const std::string& path,
101 const std::string& interface)
102 {
103 std::vector<std::string> interfaces{interface};
Brad Bishopd1eac882018-03-29 10:34:05 -0400104 std::string name;
Adriana Kobylak2ded5e12018-07-10 12:55:51 -0500105
106 try
Brad Bishopfac1b102017-05-15 22:29:20 -0400107 {
Adriana Kobylak2ded5e12018-07-10 12:55:51 -0500108 auto object = callMethodAndRead<GetObject>(
109 MAPPER_BUSNAME, MAPPER_PATH, MAPPER_INTERFACE, "GetObject",
110 path, interfaces);
111
112 if (!object.empty())
113 {
114 name = object.begin()->first;
115 }
116 }
Patrick Williams764adb52021-09-02 09:36:47 -0500117 catch (const sdbusplus::exception::exception& e)
Adriana Kobylak2ded5e12018-07-10 12:55:51 -0500118 {
119 // Empty responses are expected sometimes, and the calling
120 // code is set up to handle it.
Brad Bishopfac1b102017-05-15 22:29:20 -0400121 }
Brad Bishopd1eac882018-03-29 10:34:05 -0400122 return name;
123 }
Brad Bishopfac1b102017-05-15 22:29:20 -0400124
Brad Bishopd1eac882018-03-29 10:34:05 -0400125 friend Loop;
Brad Bishopfac1b102017-05-15 22:29:20 -0400126};
127
128} // namespace monitoring
129} // namespace dbus
130} // namespace phosphor