#pragma once #include "data_types.hpp" #include #include #include #include #include struct Loop; namespace phosphor { namespace dbus { namespace monitoring { /** @class SDBusPlus * @brief DBus access delegate implementation for sdbusplus. */ class SDBusPlus { private: static auto& getWatches() { static std::vector watches; return watches; } public: static auto& getBus() { static auto bus = sdbusplus::bus::new_default(); return bus; } /** @brief Invoke a method; ignore reply. */ template static void callMethodNoReply(const std::string& busName, const std::string& path, const std::string& interface, const std::string& method, Args&&... args) { auto reqMsg = getBus().new_method_call( busName.c_str(), path.c_str(), interface.c_str(), method.c_str()); reqMsg.append(std::forward(args)...); getBus().call_noreply(reqMsg); // TODO: openbmc/openbmc#1719 // invoke these methods async, with a callback // handler that checks for errors and logs. } /** @brief Invoke a method. */ template static auto callMethod(const std::string& busName, const std::string& path, const std::string& interface, const std::string& method, Args&&... args) { auto reqMsg = getBus().new_method_call( busName.c_str(), path.c_str(), interface.c_str(), method.c_str()); reqMsg.append(std::forward(args)...); return getBus().call(reqMsg); } /** @brief Invoke a method and read the response. */ template static auto callMethodAndRead(const std::string& busName, const std::string& path, const std::string& interface, const std::string& method, Args&&... args) { Ret resp; sdbusplus::message_t respMsg = callMethod( busName, path, interface, method, std::forward(args)...); try { respMsg.read(resp); } catch (const sdbusplus::exception_t& e) { // Empty responses are expected sometimes, and the calling // code is set up to handle it. } return resp; } /** @brief Register a DBus signal callback. */ static auto addMatch(const std::string& match, sdbusplus::bus::match_t::callback_t&& callback) { getWatches().emplace_back(getBus(), match, std::move(callback)); } /** @brief Look up the bus name for a path and interface */ static auto getBusName(const std::string& path, const std::string& interface) { std::vector interfaces{interface}; std::string name; try { auto object = callMethodAndRead( MAPPER_BUSNAME, MAPPER_PATH, MAPPER_INTERFACE, "GetObject", path, interfaces); if (!object.empty()) { name = object.begin()->first; } } catch (const sdbusplus::exception_t& e) { // Empty responses are expected sometimes, and the calling // code is set up to handle it. } return name; } friend Loop; }; } // namespace monitoring } // namespace dbus } // namespace phosphor