diff options
author | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2017-06-08 11:59:58 -0400 |
---|---|---|
committer | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2017-07-08 16:52:38 -0400 |
commit | 6e9cfdb7cc15539bc7e7589c8284c4e2eebf08fe (patch) | |
tree | 8729bb8a44131800650b2507753ecaf9597ef149 /sdbusplus.hpp | |
parent | be605c5f8da935afb7dd13300cab24e986d3a474 (diff) | |
download | phosphor-fan-presence-6e9cfdb7cc15539bc7e7589c8284c4e2eebf08fe.tar.gz phosphor-fan-presence-6e9cfdb7cc15539bc7e7589c8284c4e2eebf08fe.zip |
Add sdbusplus wrapper
Facilitate mocking.
Avoid sdbusplus::bus::bus reference proliferation.
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
Change-Id: I0a55fa178a96af4fd63f249cde0a129b7007731f
Diffstat (limited to 'sdbusplus.hpp')
-rw-r--r-- | sdbusplus.hpp | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/sdbusplus.hpp b/sdbusplus.hpp new file mode 100644 index 0000000..133443f --- /dev/null +++ b/sdbusplus.hpp @@ -0,0 +1,195 @@ +#pragma once + +#include <sdbusplus/bus.hpp> +#include <sdbusplus/message.hpp> +#include <sdbusplus/bus/match.hpp> +#include <phosphor-logging/log.hpp> +#include <phosphor-logging/elog.hpp> +#include <phosphor-logging/elog-errors.hpp> +#include <xyz/openbmc_project/Common/error.hpp> + +namespace phosphor +{ +namespace fan +{ +namespace util +{ +namespace detail +{ +namespace errors = sdbusplus::xyz::openbmc_project::Common::Error; +} // namespace detail + +/** @class SDBusPlus + * @brief DBus access delegate implementation for sdbusplus. + */ +class SDBusPlus +{ + + public: + /** @brief Get the bus connection. */ + static auto& getBus() __attribute__((pure)) + { + static auto bus = sdbusplus::bus::new_default(); + return bus; + } + + /** @brief Invoke a method. */ + template <typename ...Args> + 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>(args)...); + auto respMsg = getBus().call(reqMsg); + + if (respMsg.is_method_error()) + { + phosphor::logging::log<phosphor::logging::level::INFO>( + "Failed to invoke DBus method.", + phosphor::logging::entry("PATH=%s", path.c_str()), + phosphor::logging::entry( + "INTERFACE=%s", interface.c_str()), + phosphor::logging::entry("METHOD=%s", method.c_str())); + phosphor::logging::elog<detail::errors::InternalFailure>(); + } + + return respMsg; + } + + /** @brief Invoke a method and read the response. */ + template <typename Ret, typename ...Args> + static auto callMethodAndRead( + const std::string& busName, + const std::string& path, + const std::string& interface, + const std::string& method, + Args&& ... args) + { + sdbusplus::message::message respMsg = + callMethod<Args...>( + busName, + path, + interface, + method, + std::forward<Args>(args)...); + Ret resp; + respMsg.read(resp); + return resp; + } + + /** @brief Get service from the mapper. */ + static auto getService( + const std::string& path, + const std::string& interface) + { + using namespace std::literals::string_literals; + using GetObject = std::map<std::string, std::vector<std::string>>; + + auto mapperResp = callMethodAndRead<GetObject>( + "xyz.openbmc_project.ObjectMapper"s, + "/xyz/openbmc_project/object_mapper"s, + "xyz.openbmc_project.ObjectMapper"s, + "GetObject"s, + path, + GetObject::mapped_type{interface}); + + if (mapperResp.empty()) + { + phosphor::logging::log<phosphor::logging::level::INFO>( + "Object not found.", + phosphor::logging::entry("PATH=%s", path.c_str()), + phosphor::logging::entry( + "INTERFACE=%s", interface.c_str())); + phosphor::logging::elog<detail::errors::InternalFailure>(); + } + return mapperResp.begin()->first; + } + + /** @brief Get a property with mapper lookup. */ + template <typename Property> + static auto getProperty( + const std::string& path, + const std::string& interface, + const std::string& property) + { + using namespace std::literals::string_literals; + + auto msg = callMethod( + getService(path, interface), + path, + "org.freedesktop.DBus.Properties"s, + "Get"s, + interface, + property); + sdbusplus::message::variant<Property> value; + msg.read(value); + return value.template get<Property>(); + } + + /** @brief Set a property with mapper lookup. */ + template <typename Property> + static void setProperty( + const std::string& path, + const std::string& interface, + const std::string& property, + Property&& value) + { + using namespace std::literals::string_literals; + + sdbusplus::message::variant<Property> varValue( + std::forward<Property>(value)); + + callMethod( + getService(path, interface), + path, + "org.freedesktop.DBus.Properties"s, + "Set"s, + interface, + property, + varValue); + } + + /** @brief Invoke method with mapper lookup. */ + template <typename ...Args> + static auto lookupAndCallMethod( + const std::string& path, + const std::string& interface, + const std::string& method, + Args&& ... args) + { + return callMethod( + getService(path, interface), + path, + interface, + method, + std::forward<Args>(args)...); + } + + /** @brief Invoke method and read with mapper lookup. */ + template <typename Ret, typename ...Args> + static auto lookupCallMethodAndRead( + const std::string& path, + const std::string& interface, + const std::string& method, + Args&& ... args) + { + return callMethodAndRead( + getService(path, interface), + path, + interface, + method, + std::forward<Args>(args)...); + } +}; + +} // namespace util +} // namespace fan +} // namespace phosphor |