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( 39 const std::string& busName, 40 const std::string& path, 41 const std::string& interface, 42 const std::string& method, 43 Args&& ... args) 44 { 45 auto reqMsg = getBus().new_method_call( 46 busName.c_str(), 47 path.c_str(), 48 interface.c_str(), 49 method.c_str()); 50 reqMsg.append(std::forward<Args>(args)...); 51 getBus().call_noreply(reqMsg); 52 53 // TODO: openbmc/openbmc#1719 54 // invoke these methods async, with a callback 55 // handler that checks for errors and logs. 56 } 57 58 /** @brief Invoke a method. */ 59 template <typename ...Args> 60 static auto callMethod( 61 const std::string& busName, 62 const std::string& path, 63 const std::string& interface, 64 const std::string& method, 65 Args&& ... args) 66 { 67 auto reqMsg = getBus().new_method_call( 68 busName.c_str(), 69 path.c_str(), 70 interface.c_str(), 71 method.c_str()); 72 reqMsg.append(std::forward<Args>(args)...); 73 return getBus().call(reqMsg); 74 } 75 76 /** @brief Invoke a method and read the response. */ 77 template <typename Ret, typename ...Args> 78 static auto callMethodAndRead( 79 const std::string& busName, 80 const std::string& path, 81 const std::string& interface, 82 const std::string& method, 83 Args&& ... args) 84 { 85 Ret resp; 86 sdbusplus::message::message respMsg = 87 callMethod<Args...>( 88 busName, 89 path, 90 interface, 91 method, 92 std::forward<Args>(args)...); 93 respMsg.read(resp); 94 return resp; 95 } 96 97 /** @brief Register a DBus signal callback. */ 98 static auto addMatch( 99 const std::string& match, 100 const sdbusplus::bus::match::match::callback_t& callback) 101 { 102 getWatches().emplace_back( 103 getBus(), 104 match, 105 callback); 106 } 107 108 /** @brief Look up the bus name for a path and interface */ 109 static auto getBusName( 110 const std::string& path, 111 const std::string& interface) 112 { 113 std::vector<std::string> interfaces{interface}; 114 115 auto object = callMethodAndRead<GetObject>( 116 MAPPER_BUSNAME, 117 MAPPER_PATH, 118 MAPPER_INTERFACE, 119 "GetObject", 120 path, 121 interfaces); 122 123 std::string name; 124 if (!object.empty()) 125 { 126 name = object.begin()->first; 127 } 128 return name; 129 } 130 131 friend Loop; 132 }; 133 134 } // namespace monitoring 135 } // namespace dbus 136 } // namespace phosphor 137