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