Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 1 | #pragma once |
| 2 | |
Patrick Venture | 3d6d318 | 2018-08-31 09:33:09 -0700 | [diff] [blame] | 3 | #include <phosphor-logging/elog-errors.hpp> |
| 4 | #include <phosphor-logging/elog.hpp> |
| 5 | #include <phosphor-logging/log.hpp> |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 6 | #include <sdbusplus/bus.hpp> |
| 7 | #include <sdbusplus/message.hpp> |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 8 | #include <xyz/openbmc_project/Common/error.hpp> |
| 9 | |
George Liu | 3fe976c | 2022-06-21 09:37:04 +0800 | [diff] [blame] | 10 | #include <string> |
| 11 | |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 12 | namespace util |
| 13 | { |
| 14 | namespace detail |
| 15 | { |
| 16 | namespace errors = sdbusplus::xyz::openbmc_project::Common::Error; |
| 17 | } // namespace detail |
| 18 | |
| 19 | /** @brief Alias for PropertiesChanged signal callbacks. */ |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 20 | template <typename... T> |
Patrick Williams | 35b4f33 | 2020-05-13 17:53:09 -0500 | [diff] [blame] | 21 | using Properties = std::map<std::string, std::variant<T...>>; |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 22 | |
| 23 | namespace sdbusplus |
| 24 | { |
| 25 | |
| 26 | /** @brief Get the bus connection. */ |
| 27 | static auto& getBus() __attribute__((pure)); |
| 28 | static auto& getBus() |
| 29 | { |
| 30 | static auto bus = ::sdbusplus::bus::new_default(); |
| 31 | return bus; |
| 32 | } |
| 33 | |
| 34 | /** @brief Invoke a method. */ |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 35 | template <typename... Args> |
| 36 | static auto callMethod(::sdbusplus::bus::bus& bus, const std::string& busName, |
| 37 | const std::string& path, const std::string& interface, |
| 38 | const std::string& method, Args&&... args) |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 39 | { |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 40 | auto reqMsg = bus.new_method_call(busName.c_str(), path.c_str(), |
| 41 | interface.c_str(), method.c_str()); |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 42 | reqMsg.append(std::forward<Args>(args)...); |
| 43 | auto respMsg = bus.call(reqMsg); |
| 44 | |
| 45 | if (respMsg.is_method_error()) |
| 46 | { |
| 47 | phosphor::logging::log<phosphor::logging::level::INFO>( |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 48 | "Failed to invoke DBus method.", |
| 49 | phosphor::logging::entry("PATH=%s", path.c_str()), |
| 50 | phosphor::logging::entry("INTERFACE=%s", interface.c_str()), |
| 51 | phosphor::logging::entry("METHOD=%s", method.c_str())); |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 52 | phosphor::logging::elog<detail::errors::InternalFailure>(); |
| 53 | } |
| 54 | |
| 55 | return respMsg; |
| 56 | } |
| 57 | |
| 58 | /** @brief Invoke a method. */ |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 59 | template <typename... Args> |
| 60 | static auto callMethod(const std::string& busName, const std::string& path, |
| 61 | const std::string& interface, const std::string& method, |
| 62 | Args&&... args) |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 63 | { |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 64 | return callMethod(getBus(), busName, path, interface, method, |
| 65 | std::forward<Args>(args)...); |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 66 | } |
| 67 | |
| 68 | /** @brief Invoke a method and read the response. */ |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 69 | template <typename Ret, typename... Args> |
| 70 | static auto |
| 71 | callMethodAndRead(::sdbusplus::bus::bus& bus, const std::string& busName, |
| 72 | const std::string& path, const std::string& interface, |
| 73 | const std::string& method, Args&&... args) |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 74 | { |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 75 | ::sdbusplus::message::message respMsg = callMethod<Args...>( |
| 76 | bus, busName, path, interface, method, std::forward<Args>(args)...); |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 77 | Ret resp; |
| 78 | respMsg.read(resp); |
| 79 | return resp; |
| 80 | } |
| 81 | |
| 82 | /** @brief Invoke a method and read the response. */ |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 83 | template <typename Ret, typename... Args> |
| 84 | static auto callMethodAndRead(const std::string& busName, |
| 85 | const std::string& path, |
| 86 | const std::string& interface, |
| 87 | const std::string& method, Args&&... args) |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 88 | { |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 89 | return callMethodAndRead<Ret>(getBus(), busName, path, interface, method, |
| 90 | std::forward<Args>(args)...); |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 91 | } |
| 92 | |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 93 | /** @brief Get service from the mapper. */ |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 94 | static auto getService(::sdbusplus::bus::bus& bus, const std::string& path, |
| 95 | const std::string& interface) |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 96 | { |
| 97 | using namespace std::literals::string_literals; |
| 98 | using GetObject = std::map<std::string, std::vector<std::string>>; |
| 99 | |
| 100 | auto mapperResp = callMethodAndRead<GetObject>( |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 101 | bus, "xyz.openbmc_project.ObjectMapper"s, |
| 102 | "/xyz/openbmc_project/object_mapper"s, |
| 103 | "xyz.openbmc_project.ObjectMapper"s, "GetObject"s, path, |
| 104 | GetObject::mapped_type{interface}); |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 105 | |
| 106 | if (mapperResp.empty()) |
| 107 | { |
| 108 | phosphor::logging::log<phosphor::logging::level::INFO>( |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 109 | "Object not found.", |
| 110 | phosphor::logging::entry("PATH=%s", path.c_str()), |
| 111 | phosphor::logging::entry("INTERFACE=%s", interface.c_str())); |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 112 | phosphor::logging::elog<detail::errors::InternalFailure>(); |
| 113 | } |
| 114 | return mapperResp.begin()->first; |
| 115 | } |
| 116 | |
| 117 | /** @brief Get a property without mapper lookup. */ |
| 118 | template <typename Property> |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 119 | static auto getProperty(::sdbusplus::bus::bus& bus, const std::string& busName, |
| 120 | const std::string& path, const std::string& interface, |
| 121 | const std::string& property) |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 122 | { |
| 123 | using namespace std::literals::string_literals; |
| 124 | |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 125 | auto msg = |
| 126 | callMethod(bus, busName, path, "org.freedesktop.DBus.Properties"s, |
| 127 | "Get"s, interface, property); |
Patrick Williams | 35b4f33 | 2020-05-13 17:53:09 -0500 | [diff] [blame] | 128 | ::std::variant<Property> value; |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 129 | msg.read(value); |
Patrick Williams | 34ef1e5 | 2020-05-13 11:07:43 -0500 | [diff] [blame] | 130 | return std::get<Property>(value); |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 131 | } |
| 132 | |
| 133 | /** @brief Get a property without mapper lookup. */ |
| 134 | template <typename Property> |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 135 | static auto getProperty(const std::string& busName, const std::string& path, |
| 136 | const std::string& interface, |
| 137 | const std::string& property) |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 138 | { |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 139 | return getProperty<Property>(getBus(), busName, path, interface, property); |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 140 | } |
| 141 | |
| 142 | /** @brief Get a property with mapper lookup. */ |
| 143 | template <typename Property> |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 144 | static auto getProperty(::sdbusplus::bus::bus& bus, const std::string& path, |
| 145 | const std::string& interface, |
| 146 | const std::string& property) |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 147 | { |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 148 | return getProperty<Property>(bus, getService(bus, path, interface), path, |
| 149 | interface, property); |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 150 | } |
| 151 | |
| 152 | /** @brief Get a property with mapper lookup. */ |
| 153 | template <typename Property> |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 154 | static auto getProperty(const std::string& path, const std::string& interface, |
| 155 | const std::string& property) |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 156 | { |
Brad Bishop | d1eac88 | 2018-03-29 10:34:05 -0400 | [diff] [blame] | 157 | return getProperty<Property>(getBus(), path, interface, property); |
Brad Bishop | b1e329a | 2017-08-02 01:23:12 -0400 | [diff] [blame] | 158 | } |
| 159 | |
| 160 | } // namespace sdbusplus |
| 161 | } // namespace util |