blob: f7049acae6f222cbefbcae2267b6721c1d9878a0 [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>
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
Adriana Kobylak0049c982018-06-06 15:33:22 -050021using namespace phosphor::logging;
Adriana Kobylak0049c982018-06-06 15:33:22 -050022
Brad Bishopfac1b102017-05-15 22:29:20 -040023/** @class SDBusPlus
24 * @brief DBus access delegate implementation for sdbusplus.
25 */
26class SDBusPlus
27{
Brad Bishopd1eac882018-03-29 10:34:05 -040028 private:
29 static auto& getWatches()
30 {
31 static std::vector<sdbusplus::bus::match::match> watches;
32 return watches;
33 }
34
35 public:
36 static auto& getBus()
37 {
38 static auto bus = sdbusplus::bus::new_default();
39 return bus;
40 }
41
42 /** @brief Invoke a method; ignore reply. */
43 template <typename... Args>
44 static void callMethodNoReply(const std::string& busName,
45 const std::string& path,
46 const std::string& interface,
47 const std::string& method, Args&&... args)
48 {
49 auto reqMsg = getBus().new_method_call(
50 busName.c_str(), path.c_str(), interface.c_str(), method.c_str());
51 reqMsg.append(std::forward<Args>(args)...);
52 getBus().call_noreply(reqMsg);
53
54 // TODO: openbmc/openbmc#1719
55 // invoke these methods async, with a callback
56 // handler that checks for errors and logs.
57 }
58
59 /** @brief Invoke a method. */
60 template <typename... Args>
61 static auto callMethod(const std::string& busName, const std::string& path,
62 const std::string& interface,
63 const std::string& method, Args&&... args)
64 {
65 auto reqMsg = getBus().new_method_call(
66 busName.c_str(), path.c_str(), interface.c_str(), method.c_str());
67 reqMsg.append(std::forward<Args>(args)...);
68 return getBus().call(reqMsg);
69 }
70
71 /** @brief Invoke a method and read the response. */
72 template <typename Ret, typename... Args>
73 static auto callMethodAndRead(const std::string& busName,
74 const std::string& path,
75 const std::string& interface,
76 const std::string& method, Args&&... args)
77 {
78 Ret resp;
79 sdbusplus::message::message respMsg = callMethod<Args...>(
80 busName, path, interface, method, std::forward<Args>(args)...);
Adriana Kobylak0049c982018-06-06 15:33:22 -050081 try
82 {
83 respMsg.read(resp);
84 }
Patrick Williams764adb52021-09-02 09:36:47 -050085 catch (const sdbusplus::exception::exception& e)
Adriana Kobylak0049c982018-06-06 15:33:22 -050086 {
Matt Spinler195550c2018-06-13 13:51:40 -050087 // Empty responses are expected sometimes, and the calling
88 // code is set up to handle it.
Adriana Kobylak0049c982018-06-06 15:33:22 -050089 }
Brad Bishopd1eac882018-03-29 10:34:05 -040090 return resp;
91 }
92
93 /** @brief Register a DBus signal callback. */
94 static auto
95 addMatch(const std::string& match,
96 const sdbusplus::bus::match::match::callback_t& callback)
97 {
98 getWatches().emplace_back(getBus(), match, callback);
99 }
100
101 /** @brief Look up the bus name for a path and interface */
102 static auto getBusName(const std::string& path,
103 const std::string& interface)
104 {
105 std::vector<std::string> interfaces{interface};
Brad Bishopd1eac882018-03-29 10:34:05 -0400106 std::string name;
Adriana Kobylak2ded5e12018-07-10 12:55:51 -0500107
108 try
Brad Bishopfac1b102017-05-15 22:29:20 -0400109 {
Adriana Kobylak2ded5e12018-07-10 12:55:51 -0500110 auto object = callMethodAndRead<GetObject>(
111 MAPPER_BUSNAME, MAPPER_PATH, MAPPER_INTERFACE, "GetObject",
112 path, interfaces);
113
114 if (!object.empty())
115 {
116 name = object.begin()->first;
117 }
118 }
Patrick Williams764adb52021-09-02 09:36:47 -0500119 catch (const sdbusplus::exception::exception& e)
Adriana Kobylak2ded5e12018-07-10 12:55:51 -0500120 {
121 // Empty responses are expected sometimes, and the calling
122 // code is set up to handle it.
Brad Bishopfac1b102017-05-15 22:29:20 -0400123 }
Brad Bishopd1eac882018-03-29 10:34:05 -0400124 return name;
125 }
Brad Bishopfac1b102017-05-15 22:29:20 -0400126
Brad Bishopd1eac882018-03-29 10:34:05 -0400127 friend Loop;
Brad Bishopfac1b102017-05-15 22:29:20 -0400128};
129
130} // namespace monitoring
131} // namespace dbus
132} // namespace phosphor