blob: 1ff38a8d7fc2ea79874b752163eaa3f8a7fd93f3 [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
Adriana Kobylak0049c982018-06-06 15:33:22 -05005#include <phosphor-logging/log.hpp>
Brad Bishopfac1b102017-05-15 22:29:20 -04006#include <sdbusplus/bus.hpp>
Patrick Venture3d6d3182018-08-31 09:33:09 -07007#include <sdbusplus/bus/match.hpp>
Adriana Kobylak0049c982018-06-06 15:33:22 -05008#include <sdbusplus/exception.hpp>
Brad Bishopfac1b102017-05-15 22:29:20 -04009#include <sdbusplus/message.hpp>
George Liu3fe976c2022-06-21 09:37:04 +080010
Andrew Geisslerae4c95c2020-05-16 13:58:53 -050011#include <string>
Brad Bishopfac1b102017-05-15 22:29:20 -040012
Brad Bishopd9c1fab2017-06-04 22:32:12 -040013struct Loop;
14
Brad Bishopfac1b102017-05-15 22:29:20 -040015namespace phosphor
16{
17namespace dbus
18{
19namespace monitoring
20{
21
Adriana Kobylak0049c982018-06-06 15:33:22 -050022using namespace phosphor::logging;
Adriana Kobylak0049c982018-06-06 15:33:22 -050023
Brad Bishopfac1b102017-05-15 22:29:20 -040024/** @class SDBusPlus
25 * @brief DBus access delegate implementation for sdbusplus.
26 */
27class SDBusPlus
28{
Brad Bishopd1eac882018-03-29 10:34:05 -040029 private:
30 static auto& getWatches()
31 {
32 static std::vector<sdbusplus::bus::match::match> watches;
33 return watches;
34 }
35
36 public:
37 static auto& getBus()
38 {
39 static auto bus = sdbusplus::bus::new_default();
40 return bus;
41 }
42
43 /** @brief Invoke a method; ignore reply. */
44 template <typename... Args>
45 static void callMethodNoReply(const std::string& busName,
46 const std::string& path,
47 const std::string& interface,
48 const std::string& method, Args&&... args)
49 {
50 auto reqMsg = getBus().new_method_call(
51 busName.c_str(), path.c_str(), interface.c_str(), method.c_str());
52 reqMsg.append(std::forward<Args>(args)...);
53 getBus().call_noreply(reqMsg);
54
55 // TODO: openbmc/openbmc#1719
56 // invoke these methods async, with a callback
57 // handler that checks for errors and logs.
58 }
59
60 /** @brief Invoke a method. */
61 template <typename... Args>
62 static auto callMethod(const std::string& busName, const std::string& path,
63 const std::string& interface,
64 const std::string& method, Args&&... args)
65 {
66 auto reqMsg = getBus().new_method_call(
67 busName.c_str(), path.c_str(), interface.c_str(), method.c_str());
68 reqMsg.append(std::forward<Args>(args)...);
69 return getBus().call(reqMsg);
70 }
71
72 /** @brief Invoke a method and read the response. */
73 template <typename Ret, typename... Args>
74 static auto callMethodAndRead(const std::string& busName,
75 const std::string& path,
76 const std::string& interface,
77 const std::string& method, Args&&... args)
78 {
79 Ret resp;
80 sdbusplus::message::message respMsg = callMethod<Args...>(
81 busName, path, interface, method, std::forward<Args>(args)...);
Adriana Kobylak0049c982018-06-06 15:33:22 -050082 try
83 {
84 respMsg.read(resp);
85 }
Patrick Williams764adb52021-09-02 09:36:47 -050086 catch (const sdbusplus::exception::exception& e)
Adriana Kobylak0049c982018-06-06 15:33:22 -050087 {
Matt Spinler195550c2018-06-13 13:51:40 -050088 // Empty responses are expected sometimes, and the calling
89 // code is set up to handle it.
Adriana Kobylak0049c982018-06-06 15:33:22 -050090 }
Brad Bishopd1eac882018-03-29 10:34:05 -040091 return resp;
92 }
93
94 /** @brief Register a DBus signal callback. */
95 static auto
96 addMatch(const std::string& match,
97 const sdbusplus::bus::match::match::callback_t& callback)
98 {
99 getWatches().emplace_back(getBus(), match, callback);
100 }
101
102 /** @brief Look up the bus name for a path and interface */
103 static auto getBusName(const std::string& path,
104 const std::string& interface)
105 {
106 std::vector<std::string> interfaces{interface};
Brad Bishopd1eac882018-03-29 10:34:05 -0400107 std::string name;
Adriana Kobylak2ded5e12018-07-10 12:55:51 -0500108
109 try
Brad Bishopfac1b102017-05-15 22:29:20 -0400110 {
Adriana Kobylak2ded5e12018-07-10 12:55:51 -0500111 auto object = callMethodAndRead<GetObject>(
112 MAPPER_BUSNAME, MAPPER_PATH, MAPPER_INTERFACE, "GetObject",
113 path, interfaces);
114
115 if (!object.empty())
116 {
117 name = object.begin()->first;
118 }
119 }
Patrick Williams764adb52021-09-02 09:36:47 -0500120 catch (const sdbusplus::exception::exception& e)
Adriana Kobylak2ded5e12018-07-10 12:55:51 -0500121 {
122 // Empty responses are expected sometimes, and the calling
123 // code is set up to handle it.
Brad Bishopfac1b102017-05-15 22:29:20 -0400124 }
Brad Bishopd1eac882018-03-29 10:34:05 -0400125 return name;
126 }
Brad Bishopfac1b102017-05-15 22:29:20 -0400127
Brad Bishopd1eac882018-03-29 10:34:05 -0400128 friend Loop;
Brad Bishopfac1b102017-05-15 22:29:20 -0400129};
130
131} // namespace monitoring
132} // namespace dbus
133} // namespace phosphor