xref: /openbmc/phosphor-dbus-monitor/src/sdbusplus.hpp (revision eab4f8c0a047e1aaedf74d6144d83132d1b003de)
1fac1b103SBrad Bishop #pragma once
2fac1b103SBrad Bishop 
33d6d3182SPatrick Venture #include "data_types.hpp"
43d6d3182SPatrick Venture 
5fac1b103SBrad Bishop #include <sdbusplus/bus.hpp>
63d6d3182SPatrick Venture #include <sdbusplus/bus/match.hpp>
70049c98bSAdriana Kobylak #include <sdbusplus/exception.hpp>
8fac1b103SBrad Bishop #include <sdbusplus/message.hpp>
93fe976ccSGeorge Liu 
10ae4c95c6SAndrew Geissler #include <string>
11fac1b103SBrad Bishop 
12d9c1fabbSBrad Bishop struct Loop;
13d9c1fabbSBrad Bishop 
14fac1b103SBrad Bishop namespace phosphor
15fac1b103SBrad Bishop {
16fac1b103SBrad Bishop namespace dbus
17fac1b103SBrad Bishop {
18fac1b103SBrad Bishop namespace monitoring
19fac1b103SBrad Bishop {
20fac1b103SBrad Bishop 
21fac1b103SBrad Bishop /** @class SDBusPlus
22fac1b103SBrad Bishop  *  @brief DBus access delegate implementation for sdbusplus.
23fac1b103SBrad Bishop  */
24fac1b103SBrad Bishop class SDBusPlus
25fac1b103SBrad Bishop {
26fac1b103SBrad Bishop   private:
getWatches()27fac1b103SBrad Bishop     static auto& getWatches()
28fac1b103SBrad Bishop     {
29413a4857SPatrick Williams         static std::vector<sdbusplus::bus::match_t> watches;
30fac1b103SBrad Bishop         return watches;
31fac1b103SBrad Bishop     }
32fac1b103SBrad Bishop 
33fac1b103SBrad Bishop   public:
getBus()34c3dfe617SRatan Gupta     static auto& getBus()
35c3dfe617SRatan Gupta     {
36c3dfe617SRatan Gupta         static auto bus = sdbusplus::bus::new_default();
37c3dfe617SRatan Gupta         return bus;
38c3dfe617SRatan Gupta     }
39c3dfe617SRatan Gupta 
400df00be0SBrad Bishop     /** @brief Invoke a method; ignore reply. */
410df00be0SBrad Bishop     template <typename... Args>
callMethodNoReply(const std::string & busName,const std::string & path,const std::string & interface,const std::string & method,Args &&...args)42*eab4f8c0SPatrick Williams     static void callMethodNoReply(
43*eab4f8c0SPatrick Williams         const std::string& busName, const std::string& path,
44*eab4f8c0SPatrick Williams         const std::string& interface, const std::string& method, Args&&... args)
450df00be0SBrad Bishop     {
460df00be0SBrad Bishop         auto reqMsg = getBus().new_method_call(
47d1eac88dSBrad Bishop             busName.c_str(), path.c_str(), interface.c_str(), method.c_str());
480df00be0SBrad Bishop         reqMsg.append(std::forward<Args>(args)...);
490df00be0SBrad Bishop         getBus().call_noreply(reqMsg);
500df00be0SBrad Bishop 
510df00be0SBrad Bishop         // TODO: openbmc/openbmc#1719
520df00be0SBrad Bishop         // invoke these methods async, with a callback
530df00be0SBrad Bishop         // handler that checks for errors and logs.
540df00be0SBrad Bishop     }
550df00be0SBrad Bishop 
56fac1b103SBrad Bishop     /** @brief Invoke a method. */
57fac1b103SBrad Bishop     template <typename... Args>
callMethod(const std::string & busName,const std::string & path,const std::string & interface,const std::string & method,Args &&...args)58d1eac88dSBrad Bishop     static auto callMethod(const std::string& busName, const std::string& path,
59fac1b103SBrad Bishop                            const std::string& interface,
60d1eac88dSBrad Bishop                            const std::string& method, Args&&... args)
61fac1b103SBrad Bishop     {
62fac1b103SBrad Bishop         auto reqMsg = getBus().new_method_call(
63d1eac88dSBrad Bishop             busName.c_str(), path.c_str(), interface.c_str(), method.c_str());
64fac1b103SBrad Bishop         reqMsg.append(std::forward<Args>(args)...);
65fac1b103SBrad Bishop         return getBus().call(reqMsg);
66fac1b103SBrad Bishop     }
67fac1b103SBrad Bishop 
68fac1b103SBrad Bishop     /** @brief Invoke a method and read the response. */
69fac1b103SBrad Bishop     template <typename Ret, typename... Args>
callMethodAndRead(const std::string & busName,const std::string & path,const std::string & interface,const std::string & method,Args &&...args)70*eab4f8c0SPatrick Williams     static auto callMethodAndRead(
71*eab4f8c0SPatrick Williams         const std::string& busName, const std::string& path,
72*eab4f8c0SPatrick Williams         const std::string& interface, const std::string& method, Args&&... args)
73fac1b103SBrad Bishop     {
74fac1b103SBrad Bishop         Ret resp;
75413a4857SPatrick Williams         sdbusplus::message_t respMsg = callMethod<Args...>(
76d1eac88dSBrad Bishop             busName, path, interface, method, std::forward<Args>(args)...);
770049c98bSAdriana Kobylak         try
780049c98bSAdriana Kobylak         {
79fac1b103SBrad Bishop             respMsg.read(resp);
800049c98bSAdriana Kobylak         }
81413a4857SPatrick Williams         catch (const sdbusplus::exception_t& e)
820049c98bSAdriana Kobylak         {
83195550c6SMatt Spinler             // Empty responses are expected sometimes, and the calling
84195550c6SMatt Spinler             // code is set up to handle it.
850049c98bSAdriana Kobylak         }
86fac1b103SBrad Bishop         return resp;
87fac1b103SBrad Bishop     }
88fac1b103SBrad Bishop 
89fac1b103SBrad Bishop     /** @brief Register a DBus signal callback. */
addMatch(const std::string & match,sdbusplus::bus::match_t::callback_t && callback)90413a4857SPatrick Williams     static auto addMatch(const std::string& match,
91bf97583eSWilliam A. Kennington III                          sdbusplus::bus::match_t::callback_t&& callback)
92fac1b103SBrad Bishop     {
93bf97583eSWilliam A. Kennington III         getWatches().emplace_back(getBus(), match, std::move(callback));
94fac1b103SBrad Bishop     }
95d9c1fabbSBrad Bishop 
96df1b7cfcSMatt Spinler     /** @brief Look up the bus name for a path and interface */
getBusName(const std::string & path,const std::string & interface)97d1eac88dSBrad Bishop     static auto getBusName(const std::string& path,
98df1b7cfcSMatt Spinler                            const std::string& interface)
99df1b7cfcSMatt Spinler     {
100df1b7cfcSMatt Spinler         std::vector<std::string> interfaces{interface};
101df1b7cfcSMatt Spinler         std::string name;
1022ded5e1eSAdriana Kobylak 
1032ded5e1eSAdriana Kobylak         try
1042ded5e1eSAdriana Kobylak         {
1052ded5e1eSAdriana Kobylak             auto object = callMethodAndRead<GetObject>(
1062ded5e1eSAdriana Kobylak                 MAPPER_BUSNAME, MAPPER_PATH, MAPPER_INTERFACE, "GetObject",
1072ded5e1eSAdriana Kobylak                 path, interfaces);
1082ded5e1eSAdriana Kobylak 
109df1b7cfcSMatt Spinler             if (!object.empty())
110df1b7cfcSMatt Spinler             {
111df1b7cfcSMatt Spinler                 name = object.begin()->first;
112df1b7cfcSMatt Spinler             }
1132ded5e1eSAdriana Kobylak         }
114413a4857SPatrick Williams         catch (const sdbusplus::exception_t& e)
1152ded5e1eSAdriana Kobylak         {
1162ded5e1eSAdriana Kobylak             // Empty responses are expected sometimes, and the calling
1172ded5e1eSAdriana Kobylak             // code is set up to handle it.
1182ded5e1eSAdriana Kobylak         }
119df1b7cfcSMatt Spinler         return name;
120df1b7cfcSMatt Spinler     }
121df1b7cfcSMatt Spinler 
122d9c1fabbSBrad Bishop     friend Loop;
123fac1b103SBrad Bishop };
124fac1b103SBrad Bishop 
125fac1b103SBrad Bishop } // namespace monitoring
126fac1b103SBrad Bishop } // namespace dbus
127fac1b103SBrad Bishop } // namespace phosphor
128