1 #pragma once 2 3 #include <sdbusplus/bus.hpp> 4 #include <sdbusplus/message.hpp> 5 #include <sdbusplus/bus/match.hpp> 6 #include "data_types.hpp" 7 8 struct Loop; 9 10 namespace phosphor 11 { 12 namespace dbus 13 { 14 namespace monitoring 15 { 16 17 /** @class SDBusPlus 18 * @brief DBus access delegate implementation for sdbusplus. 19 */ 20 class SDBusPlus 21 { 22 private: 23 static auto& getWatches() 24 { 25 static std::vector<sdbusplus::bus::match::match> watches; 26 return watches; 27 } 28 29 public: 30 static auto& getBus() 31 { 32 static auto bus = sdbusplus::bus::new_default(); 33 return bus; 34 } 35 36 /** @brief Invoke a method; ignore reply. */ 37 template <typename... Args> 38 static void callMethodNoReply(const std::string& busName, 39 const std::string& path, 40 const std::string& interface, 41 const std::string& method, Args&&... args) 42 { 43 auto reqMsg = getBus().new_method_call( 44 busName.c_str(), path.c_str(), interface.c_str(), method.c_str()); 45 reqMsg.append(std::forward<Args>(args)...); 46 getBus().call_noreply(reqMsg); 47 48 // TODO: openbmc/openbmc#1719 49 // invoke these methods async, with a callback 50 // handler that checks for errors and logs. 51 } 52 53 /** @brief Invoke a method. */ 54 template <typename... Args> 55 static auto callMethod(const std::string& busName, const std::string& path, 56 const std::string& interface, 57 const std::string& method, Args&&... args) 58 { 59 auto reqMsg = getBus().new_method_call( 60 busName.c_str(), path.c_str(), interface.c_str(), method.c_str()); 61 reqMsg.append(std::forward<Args>(args)...); 62 return getBus().call(reqMsg); 63 } 64 65 /** @brief Invoke a method and read the response. */ 66 template <typename Ret, typename... Args> 67 static auto callMethodAndRead(const std::string& busName, 68 const std::string& path, 69 const std::string& interface, 70 const std::string& method, Args&&... args) 71 { 72 Ret resp; 73 sdbusplus::message::message respMsg = callMethod<Args...>( 74 busName, path, interface, method, std::forward<Args>(args)...); 75 respMsg.read(resp); 76 return resp; 77 } 78 79 /** @brief Register a DBus signal callback. */ 80 static auto 81 addMatch(const std::string& match, 82 const sdbusplus::bus::match::match::callback_t& callback) 83 { 84 getWatches().emplace_back(getBus(), match, callback); 85 } 86 87 /** @brief Look up the bus name for a path and interface */ 88 static auto getBusName(const std::string& path, 89 const std::string& interface) 90 { 91 std::vector<std::string> interfaces{interface}; 92 93 auto object = callMethodAndRead<GetObject>( 94 MAPPER_BUSNAME, MAPPER_PATH, MAPPER_INTERFACE, "GetObject", path, 95 interfaces); 96 97 std::string name; 98 if (!object.empty()) 99 { 100 name = object.begin()->first; 101 } 102 return name; 103 } 104 105 friend Loop; 106 }; 107 108 } // namespace monitoring 109 } // namespace dbus 110 } // namespace phosphor 111