16e9cfdb7SBrad Bishop #pragma once 26e9cfdb7SBrad Bishop 36e9cfdb7SBrad Bishop #include <phosphor-logging/elog-errors.hpp> 49e80c87aSMatthew Barth #include <phosphor-logging/elog.hpp> 59e80c87aSMatthew Barth #include <phosphor-logging/log.hpp> 69e80c87aSMatthew Barth #include <sdbusplus/bus.hpp> 79e80c87aSMatthew Barth #include <sdbusplus/bus/match.hpp> 89e80c87aSMatthew Barth #include <sdbusplus/message.hpp> 96e9cfdb7SBrad Bishop #include <xyz/openbmc_project/Common/error.hpp> 106e9cfdb7SBrad Bishop 11fbf4703fSPatrick Williams #include <format> 12fbf4703fSPatrick Williams 136e9cfdb7SBrad Bishop namespace phosphor 146e9cfdb7SBrad Bishop { 156e9cfdb7SBrad Bishop namespace fan 166e9cfdb7SBrad Bishop { 176e9cfdb7SBrad Bishop namespace util 186e9cfdb7SBrad Bishop { 196e9cfdb7SBrad Bishop namespace detail 206e9cfdb7SBrad Bishop { 216e9cfdb7SBrad Bishop namespace errors = sdbusplus::xyz::openbmc_project::Common::Error; 226e9cfdb7SBrad Bishop } // namespace detail 236e9cfdb7SBrad Bishop 24ba7b5feaSMatt Spinler /** 25ba7b5feaSMatt Spinler * @class DBusError 26ba7b5feaSMatt Spinler * 27ba7b5feaSMatt Spinler * The base class for the exceptions thrown on fails in the various 28ba7b5feaSMatt Spinler * SDBusPlus calls. Used so that a single catch statement can catch 29ba7b5feaSMatt Spinler * any type of these exceptions. 30ba7b5feaSMatt Spinler * 31ba7b5feaSMatt Spinler * None of these exceptions will log anything when they are created, 32ba7b5feaSMatt Spinler * it is up to the handler to do that if desired. 33ba7b5feaSMatt Spinler */ 34ba7b5feaSMatt Spinler class DBusError : public std::runtime_error 35ba7b5feaSMatt Spinler { 36ba7b5feaSMatt Spinler public: DBusError(const std::string & msg)3761b73296SPatrick Williams explicit DBusError(const std::string& msg) : std::runtime_error(msg) {} 38ba7b5feaSMatt Spinler }; 39ba7b5feaSMatt Spinler 40ba7b5feaSMatt Spinler /** 41ba7b5feaSMatt Spinler * @class DBusMethodError 42ba7b5feaSMatt Spinler * 43ba7b5feaSMatt Spinler * Thrown on a DBus Method call failure 44ba7b5feaSMatt Spinler */ 45ba7b5feaSMatt Spinler class DBusMethodError : public DBusError 46ba7b5feaSMatt Spinler { 47ba7b5feaSMatt Spinler public: DBusMethodError(const std::string & busName,const std::string & path,const std::string & interface,const std::string & method)489e80c87aSMatthew Barth DBusMethodError(const std::string& busName, const std::string& path, 499e80c87aSMatthew Barth const std::string& interface, const std::string& method) : 50fbf4703fSPatrick Williams DBusError(std::format("DBus method failed: {} {} {} {}", busName, path, 5123f8757eSMatt Spinler interface, method)), 529e80c87aSMatthew Barth busName(busName), path(path), interface(interface), method(method) 539e80c87aSMatthew Barth {} 54ba7b5feaSMatt Spinler 55ba7b5feaSMatt Spinler const std::string busName; 56ba7b5feaSMatt Spinler const std::string path; 57ba7b5feaSMatt Spinler const std::string interface; 58ba7b5feaSMatt Spinler const std::string method; 59ba7b5feaSMatt Spinler }; 60ba7b5feaSMatt Spinler 61ba7b5feaSMatt Spinler /** 62ba7b5feaSMatt Spinler * @class DBusServiceError 63ba7b5feaSMatt Spinler * 64ba7b5feaSMatt Spinler * Thrown when a service lookup fails. Usually this points to 65ba7b5feaSMatt Spinler * the object path not being present in D-Bus. 66ba7b5feaSMatt Spinler */ 67ba7b5feaSMatt Spinler class DBusServiceError : public DBusError 68ba7b5feaSMatt Spinler { 69ba7b5feaSMatt Spinler public: DBusServiceError(const std::string & path,const std::string & interface)709e80c87aSMatthew Barth DBusServiceError(const std::string& path, const std::string& interface) : 7123f8757eSMatt Spinler DBusError( 72fbf4703fSPatrick Williams std::format("DBus service lookup failed: {} {}", path, interface)), 7323f8757eSMatt Spinler path(path), interface(interface) 749e80c87aSMatthew Barth {} 75ba7b5feaSMatt Spinler 76ba7b5feaSMatt Spinler const std::string path; 77ba7b5feaSMatt Spinler const std::string interface; 78ba7b5feaSMatt Spinler }; 79ba7b5feaSMatt Spinler 8088923a06SMatthew Barth /** 8188923a06SMatthew Barth * @class DBusPropertyError 8288923a06SMatthew Barth * 8388923a06SMatthew Barth * Thrown when a set/get property fails. 8488923a06SMatthew Barth */ 8588923a06SMatthew Barth class DBusPropertyError : public DBusError 8688923a06SMatthew Barth { 8788923a06SMatthew Barth public: DBusPropertyError(const std::string & msg,const std::string & busName,const std::string & path,const std::string & interface,const std::string & property)8823f8757eSMatt Spinler DBusPropertyError(const std::string& msg, const std::string& busName, 899e80c87aSMatthew Barth const std::string& path, const std::string& interface, 9088923a06SMatthew Barth const std::string& property) : 91fbf4703fSPatrick Williams DBusError(msg + std::format(": {} {} {} {}", busName, path, interface, 9223f8757eSMatt Spinler property)), 939e80c87aSMatthew Barth busName(busName), path(path), interface(interface), property(property) 949e80c87aSMatthew Barth {} 9588923a06SMatthew Barth 9688923a06SMatthew Barth const std::string busName; 9788923a06SMatthew Barth const std::string path; 9888923a06SMatthew Barth const std::string interface; 9988923a06SMatthew Barth const std::string property; 10088923a06SMatthew Barth }; 10188923a06SMatthew Barth 1021e4922a6SBrad Bishop /** @brief Alias for PropertiesChanged signal callbacks. */ 1031e4922a6SBrad Bishop template <typename... T> 104c21d0b36SPatrick Williams using Properties = std::map<std::string, std::variant<T...>>; 1051e4922a6SBrad Bishop 1066e9cfdb7SBrad Bishop /** @class SDBusPlus 1076e9cfdb7SBrad Bishop * @brief DBus access delegate implementation for sdbusplus. 1086e9cfdb7SBrad Bishop */ 1096e9cfdb7SBrad Bishop class SDBusPlus 1106e9cfdb7SBrad Bishop { 1116e9cfdb7SBrad Bishop public: 1126e9cfdb7SBrad Bishop /** @brief Get the bus connection. */ getBus()1136e9cfdb7SBrad Bishop static auto& getBus() __attribute__((pure)) 1146e9cfdb7SBrad Bishop { 1156e9cfdb7SBrad Bishop static auto bus = sdbusplus::bus::new_default(); 1166e9cfdb7SBrad Bishop return bus; 1176e9cfdb7SBrad Bishop } 1186e9cfdb7SBrad Bishop 1196e9cfdb7SBrad Bishop /** @brief Invoke a method. */ 1206e9cfdb7SBrad Bishop template <typename... Args> callMethod(sdbusplus::bus_t & bus,const std::string & busName,const std::string & path,const std::string & interface,const std::string & method,Args &&...args)121cb356d48SPatrick Williams static auto callMethod(sdbusplus::bus_t& bus, const std::string& busName, 1226e9cfdb7SBrad Bishop const std::string& path, 1236e9cfdb7SBrad Bishop const std::string& interface, 1249e80c87aSMatthew Barth const std::string& method, Args&&... args) 1256e9cfdb7SBrad Bishop { 1269e80c87aSMatthew Barth auto reqMsg = bus.new_method_call(busName.c_str(), path.c_str(), 1279e80c87aSMatthew Barth interface.c_str(), method.c_str()); 1286e9cfdb7SBrad Bishop reqMsg.append(std::forward<Args>(args)...); 12986be476bSMatthew Barth try 13086be476bSMatthew Barth { 131f2238ae6SBrad Bishop auto respMsg = bus.call(reqMsg); 1326e9cfdb7SBrad Bishop if (respMsg.is_method_error()) 1336e9cfdb7SBrad Bishop { 134ba7b5feaSMatt Spinler throw DBusMethodError{busName, path, interface, method}; 1356e9cfdb7SBrad Bishop } 1366e9cfdb7SBrad Bishop return respMsg; 1376e9cfdb7SBrad Bishop } 138cb356d48SPatrick Williams catch (const sdbusplus::exception_t&) 13986be476bSMatthew Barth { 14086be476bSMatthew Barth throw DBusMethodError{busName, path, interface, method}; 14186be476bSMatthew Barth } 14286be476bSMatthew Barth } 1436e9cfdb7SBrad Bishop 144f2238ae6SBrad Bishop /** @brief Invoke a method. */ 145f2238ae6SBrad Bishop template <typename... Args> callMethod(const std::string & busName,const std::string & path,const std::string & interface,const std::string & method,Args &&...args)1469e80c87aSMatthew Barth static auto callMethod(const std::string& busName, const std::string& path, 147f2238ae6SBrad Bishop const std::string& interface, 1489e80c87aSMatthew Barth const std::string& method, Args&&... args) 149f2238ae6SBrad Bishop { 1509e80c87aSMatthew Barth return callMethod(getBus(), busName, path, interface, method, 151f2238ae6SBrad Bishop std::forward<Args>(args)...); 152f2238ae6SBrad Bishop } 153f2238ae6SBrad Bishop 1546e9cfdb7SBrad Bishop /** @brief Invoke a method and read the response. */ 1556e9cfdb7SBrad Bishop template <typename Ret, typename... Args> callMethodAndRead(sdbusplus::bus_t & bus,const std::string & busName,const std::string & path,const std::string & interface,const std::string & method,Args &&...args)156*4fa67aa1SPatrick Williams static auto callMethodAndRead( 157*4fa67aa1SPatrick Williams sdbusplus::bus_t& bus, const std::string& busName, 1589e80c87aSMatthew Barth const std::string& path, const std::string& interface, 1599e80c87aSMatthew Barth const std::string& method, Args&&... args) 1606e9cfdb7SBrad Bishop { 161cb356d48SPatrick Williams sdbusplus::message_t respMsg = callMethod<Args...>( 1629e80c87aSMatthew Barth bus, busName, path, interface, method, std::forward<Args>(args)...); 1636e9cfdb7SBrad Bishop Ret resp; 1646e9cfdb7SBrad Bishop respMsg.read(resp); 1656e9cfdb7SBrad Bishop return resp; 1666e9cfdb7SBrad Bishop } 1676e9cfdb7SBrad Bishop 168f2238ae6SBrad Bishop /** @brief Invoke a method and read the response. */ 169f2238ae6SBrad 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)170dfddd648SPatrick Williams static auto callMethodAndRead( 171dfddd648SPatrick Williams const std::string& busName, const std::string& path, 172dfddd648SPatrick Williams const std::string& interface, const std::string& method, Args&&... args) 173f2238ae6SBrad Bishop { 1749e80c87aSMatthew Barth return callMethodAndRead<Ret>(getBus(), busName, path, interface, 1759e80c87aSMatthew Barth method, std::forward<Args>(args)...); 176f2238ae6SBrad Bishop } 177f2238ae6SBrad Bishop 178d74df09bSMatthew Barth /** @brief Get subtree from the mapper without checking response. */ getSubTreeRaw(sdbusplus::bus_t & bus,const std::string & path,const std::string & interface,int32_t depth)179cb356d48SPatrick Williams static auto getSubTreeRaw(sdbusplus::bus_t& bus, const std::string& path, 1809e80c87aSMatthew Barth const std::string& interface, int32_t depth) 181eca94df8SMatthew Barth { 182eca94df8SMatthew Barth using namespace std::literals::string_literals; 183eca94df8SMatthew Barth 184eca94df8SMatthew Barth using Path = std::string; 185eca94df8SMatthew Barth using Intf = std::string; 186eca94df8SMatthew Barth using Serv = std::string; 187eca94df8SMatthew Barth using Intfs = std::vector<Intf>; 188eca94df8SMatthew Barth using Objects = std::map<Path, std::map<Serv, Intfs>>; 189eca94df8SMatthew Barth Intfs intfs = {interface}; 190eca94df8SMatthew Barth 191dfddd648SPatrick Williams return callMethodAndRead<Objects>( 192dfddd648SPatrick Williams bus, "xyz.openbmc_project.ObjectMapper"s, 193eca94df8SMatthew Barth "/xyz/openbmc_project/object_mapper"s, 194dfddd648SPatrick Williams "xyz.openbmc_project.ObjectMapper"s, "GetSubTree"s, path, depth, 195dfddd648SPatrick Williams intfs); 196d74df09bSMatthew Barth } 197eca94df8SMatthew Barth 1987a401a2cSMike Capps /** @brief Get subtree from the mapper without checking response, 1997a401a2cSMike Capps * (multiple interfaces version). */ getSubTreeRaw(sdbusplus::bus_t & bus,const std::string & path,const std::vector<std::string> & intfs,int32_t depth)200cb356d48SPatrick Williams static auto getSubTreeRaw(sdbusplus::bus_t& bus, const std::string& path, 2017a401a2cSMike Capps const std::vector<std::string>& intfs, 2027a401a2cSMike Capps int32_t depth) 2037a401a2cSMike Capps { 2047a401a2cSMike Capps using namespace std::literals::string_literals; 2057a401a2cSMike Capps 2067a401a2cSMike Capps using Path = std::string; 2077a401a2cSMike Capps using Intf = std::string; 2087a401a2cSMike Capps using Serv = std::string; 2097a401a2cSMike Capps using Intfs = std::vector<Intf>; 2107a401a2cSMike Capps using Objects = std::map<Path, std::map<Serv, Intfs>>; 2117a401a2cSMike Capps 212dfddd648SPatrick Williams return callMethodAndRead<Objects>( 213dfddd648SPatrick Williams bus, "xyz.openbmc_project.ObjectMapper"s, 2147a401a2cSMike Capps "/xyz/openbmc_project/object_mapper"s, 215dfddd648SPatrick Williams "xyz.openbmc_project.ObjectMapper"s, "GetSubTree"s, path, depth, 216dfddd648SPatrick Williams intfs); 2177a401a2cSMike Capps } 2187a401a2cSMike Capps 219d74df09bSMatthew Barth /** @brief Get subtree from the mapper. */ getSubTree(sdbusplus::bus_t & bus,const std::string & path,const std::string & interface,int32_t depth)220cb356d48SPatrick Williams static auto getSubTree(sdbusplus::bus_t& bus, const std::string& path, 2219e80c87aSMatthew Barth const std::string& interface, int32_t depth) 222d74df09bSMatthew Barth { 223d74df09bSMatthew Barth auto mapperResp = getSubTreeRaw(bus, path, interface, depth); 224eca94df8SMatthew Barth if (mapperResp.empty()) 225eca94df8SMatthew Barth { 226eca94df8SMatthew Barth phosphor::logging::log<phosphor::logging::level::ERR>( 227eca94df8SMatthew Barth "Empty response from mapper GetSubTree", 228eca94df8SMatthew Barth phosphor::logging::entry("SUBTREE=%s", path.c_str()), 2299e80c87aSMatthew Barth phosphor::logging::entry("INTERFACE=%s", interface.c_str()), 230eca94df8SMatthew Barth phosphor::logging::entry("DEPTH=%u", depth)); 231eca94df8SMatthew Barth phosphor::logging::elog<detail::errors::InternalFailure>(); 232eca94df8SMatthew Barth } 233eca94df8SMatthew Barth return mapperResp; 234eca94df8SMatthew Barth } 235f2238ae6SBrad Bishop 236fcbdc0e4SMatthew Barth /** @brief Get subtree paths from the mapper without checking response. */ getSubTreePathsRaw(sdbusplus::bus_t & bus,const std::string & path,const std::string & interface,int32_t depth)237cb356d48SPatrick Williams static auto getSubTreePathsRaw(sdbusplus::bus_t& bus, 238fcbdc0e4SMatthew Barth const std::string& path, 239fcbdc0e4SMatthew Barth const std::string& interface, int32_t depth) 240fcbdc0e4SMatthew Barth { 241fcbdc0e4SMatthew Barth using namespace std::literals::string_literals; 242fcbdc0e4SMatthew Barth 243fcbdc0e4SMatthew Barth using Path = std::string; 244fcbdc0e4SMatthew Barth using Intf = std::string; 245fcbdc0e4SMatthew Barth using Intfs = std::vector<Intf>; 246fcbdc0e4SMatthew Barth using ObjectPaths = std::vector<Path>; 247fcbdc0e4SMatthew Barth Intfs intfs = {interface}; 248fcbdc0e4SMatthew Barth 249fcbdc0e4SMatthew Barth return callMethodAndRead<ObjectPaths>( 250fcbdc0e4SMatthew Barth bus, "xyz.openbmc_project.ObjectMapper"s, 251fcbdc0e4SMatthew Barth "/xyz/openbmc_project/object_mapper"s, 252fcbdc0e4SMatthew Barth "xyz.openbmc_project.ObjectMapper"s, "GetSubTreePaths"s, path, 253fcbdc0e4SMatthew Barth depth, intfs); 254fcbdc0e4SMatthew Barth } 255fcbdc0e4SMatthew Barth 256fcbdc0e4SMatthew Barth /** @brief Get subtree paths from the mapper. */ getSubTreePaths(sdbusplus::bus_t & bus,const std::string & path,const std::string & interface,int32_t depth)257cb356d48SPatrick Williams static auto getSubTreePaths(sdbusplus::bus_t& bus, const std::string& path, 258fcbdc0e4SMatthew Barth const std::string& interface, int32_t depth) 259fcbdc0e4SMatthew Barth { 260fcbdc0e4SMatthew Barth auto mapperResp = getSubTreePathsRaw(bus, path, interface, depth); 261fcbdc0e4SMatthew Barth if (mapperResp.empty()) 262fcbdc0e4SMatthew Barth { 263fcbdc0e4SMatthew Barth phosphor::logging::log<phosphor::logging::level::ERR>( 264fcbdc0e4SMatthew Barth "Empty response from mapper GetSubTreePaths", 265fcbdc0e4SMatthew Barth phosphor::logging::entry("SUBTREE=%s", path.c_str()), 266fcbdc0e4SMatthew Barth phosphor::logging::entry("INTERFACE=%s", interface.c_str()), 267fcbdc0e4SMatthew Barth phosphor::logging::entry("DEPTH=%u", depth)); 268fcbdc0e4SMatthew Barth phosphor::logging::elog<detail::errors::InternalFailure>(); 269fcbdc0e4SMatthew Barth } 270fcbdc0e4SMatthew Barth return mapperResp; 271fcbdc0e4SMatthew Barth } 272fcbdc0e4SMatthew Barth 273ce6820abSMike Capps /** @brief Get service from the mapper without checking response. */ getServiceRaw(sdbusplus::bus_t & bus,const std::string & path,const std::string & interface)274cb356d48SPatrick Williams static auto getServiceRaw(sdbusplus::bus_t& bus, const std::string& path, 2756e9cfdb7SBrad Bishop const std::string& interface) 2766e9cfdb7SBrad Bishop { 2776e9cfdb7SBrad Bishop using namespace std::literals::string_literals; 2786e9cfdb7SBrad Bishop using GetObject = std::map<std::string, std::vector<std::string>>; 2796e9cfdb7SBrad Bishop 280ce6820abSMike Capps return callMethodAndRead<GetObject>( 2819e80c87aSMatthew Barth bus, "xyz.openbmc_project.ObjectMapper"s, 2826e9cfdb7SBrad Bishop "/xyz/openbmc_project/object_mapper"s, 2839e80c87aSMatthew Barth "xyz.openbmc_project.ObjectMapper"s, "GetObject"s, path, 2846e9cfdb7SBrad Bishop GetObject::mapped_type{interface}); 285ce6820abSMike Capps } 286ce6820abSMike Capps 287ce6820abSMike Capps /** @brief Get service from the mapper. */ getService(sdbusplus::bus_t & bus,const std::string & path,const std::string & interface)288cb356d48SPatrick Williams static auto getService(sdbusplus::bus_t& bus, const std::string& path, 289ce6820abSMike Capps const std::string& interface) 290ce6820abSMike Capps { 291ce6820abSMike Capps try 292ce6820abSMike Capps { 293ce6820abSMike Capps auto mapperResp = getServiceRaw(bus, path, interface); 2946e9cfdb7SBrad Bishop 2956e9cfdb7SBrad Bishop if (mapperResp.empty()) 2966e9cfdb7SBrad Bishop { 297ba7b5feaSMatt Spinler // Should never happen. A missing object would fail 298ba7b5feaSMatt Spinler // in callMethodAndRead() 299ba7b5feaSMatt Spinler phosphor::logging::log<phosphor::logging::level::ERR>( 300ba7b5feaSMatt Spinler "Empty mapper response on service lookup"); 301ba7b5feaSMatt Spinler throw DBusServiceError{path, interface}; 3026e9cfdb7SBrad Bishop } 3036e9cfdb7SBrad Bishop return mapperResp.begin()->first; 3046e9cfdb7SBrad Bishop } 305ddb773b2SPatrick Williams catch (const DBusMethodError& e) 306ba7b5feaSMatt Spinler { 307ba7b5feaSMatt Spinler throw DBusServiceError{path, interface}; 308ba7b5feaSMatt Spinler } 309ba7b5feaSMatt Spinler } 3106e9cfdb7SBrad Bishop 311f2238ae6SBrad Bishop /** @brief Get service from the mapper. */ getService(const std::string & path,const std::string & interface)3129e80c87aSMatthew Barth static auto getService(const std::string& path, 313f2238ae6SBrad Bishop const std::string& interface) 314f2238ae6SBrad Bishop { 3159e80c87aSMatthew Barth return getService(getBus(), path, interface); 316f2238ae6SBrad Bishop } 317f2238ae6SBrad Bishop 318a3553637SMatthew Barth /** @brief Get managed objects. */ 319a3553637SMatthew Barth template <typename Variant> getManagedObjects(sdbusplus::bus_t & bus,const std::string & service,const std::string & path)320cb356d48SPatrick Williams static auto getManagedObjects(sdbusplus::bus_t& bus, 321a3553637SMatthew Barth const std::string& service, 322a3553637SMatthew Barth const std::string& path) 323a3553637SMatthew Barth { 324a3553637SMatthew Barth using namespace std::literals::string_literals; 325a3553637SMatthew Barth 326a3553637SMatthew Barth using Path = sdbusplus::message::object_path; 327a3553637SMatthew Barth using Intf = std::string; 328a3553637SMatthew Barth using Prop = std::string; 329a3553637SMatthew Barth using GetManagedObjects = 330a3553637SMatthew Barth std::map<Path, std::map<Intf, std::map<Prop, Variant>>>; 331a3553637SMatthew Barth 332a3553637SMatthew Barth return callMethodAndRead<GetManagedObjects>( 333a3553637SMatthew Barth bus, service, path, "org.freedesktop.DBus.ObjectManager"s, 334a3553637SMatthew Barth "GetManagedObjects"s); 335a3553637SMatthew Barth } 336a3553637SMatthew Barth 3376e9cfdb7SBrad Bishop /** @brief Get a property with mapper lookup. */ 3386e9cfdb7SBrad Bishop template <typename Property> getProperty(sdbusplus::bus_t & bus,const std::string & path,const std::string & interface,const std::string & property)339cb356d48SPatrick Williams static auto getProperty(sdbusplus::bus_t& bus, const std::string& path, 3406e9cfdb7SBrad Bishop const std::string& interface, 3416e9cfdb7SBrad Bishop const std::string& property) 3426e9cfdb7SBrad Bishop { 3436e9cfdb7SBrad Bishop using namespace std::literals::string_literals; 3446e9cfdb7SBrad Bishop 34588923a06SMatthew Barth auto service = getService(bus, path, interface); 346dfddd648SPatrick Williams auto msg = 347dfddd648SPatrick Williams callMethod(bus, service, path, "org.freedesktop.DBus.Properties"s, 348dfddd648SPatrick Williams "Get"s, interface, property); 34988923a06SMatthew Barth if (msg.is_method_error()) 35088923a06SMatthew Barth { 3519e80c87aSMatthew Barth throw DBusPropertyError{"DBus get property failed", service, path, 3529e80c87aSMatthew Barth interface, property}; 35388923a06SMatthew Barth } 354c21d0b36SPatrick Williams std::variant<Property> value; 3556e9cfdb7SBrad Bishop msg.read(value); 3561f514fa8SPatrick Williams return std::get<Property>(value); 3576e9cfdb7SBrad Bishop } 3586e9cfdb7SBrad Bishop 359f2238ae6SBrad Bishop /** @brief Get a property with mapper lookup. */ 360f2238ae6SBrad Bishop template <typename Property> getProperty(const std::string & path,const std::string & interface,const std::string & property)3619e80c87aSMatthew Barth static auto getProperty(const std::string& path, 362f2238ae6SBrad Bishop const std::string& interface, 363f2238ae6SBrad Bishop const std::string& property) 364f2238ae6SBrad Bishop { 3659e80c87aSMatthew Barth return getProperty<Property>(getBus(), path, interface, property); 366f2238ae6SBrad Bishop } 367f2238ae6SBrad Bishop 3687311c394SMatthew Barth /** @brief Get a property variant with mapper lookup. */ 3697311c394SMatthew Barth template <typename Variant> getPropertyVariant(sdbusplus::bus_t & bus,const std::string & path,const std::string & interface,const std::string & property)370dfddd648SPatrick Williams static auto getPropertyVariant( 371dfddd648SPatrick Williams sdbusplus::bus_t& bus, const std::string& path, 372dfddd648SPatrick Williams const std::string& interface, const std::string& property) 3737311c394SMatthew Barth { 3747311c394SMatthew Barth using namespace std::literals::string_literals; 3757311c394SMatthew Barth 37688923a06SMatthew Barth auto service = getService(bus, path, interface); 377dfddd648SPatrick Williams auto msg = 378dfddd648SPatrick Williams callMethod(bus, service, path, "org.freedesktop.DBus.Properties"s, 379dfddd648SPatrick Williams "Get"s, interface, property); 38088923a06SMatthew Barth if (msg.is_method_error()) 38188923a06SMatthew Barth { 3829e80c87aSMatthew Barth throw DBusPropertyError{"DBus get property variant failed", service, 3839e80c87aSMatthew Barth path, interface, property}; 38488923a06SMatthew Barth } 3857311c394SMatthew Barth Variant value; 3867311c394SMatthew Barth msg.read(value); 3877311c394SMatthew Barth return value; 3887311c394SMatthew Barth } 3897311c394SMatthew Barth 3907311c394SMatthew Barth /** @brief Get a property variant with mapper lookup. */ 3917311c394SMatthew Barth template <typename Variant> getPropertyVariant(const std::string & path,const std::string & interface,const std::string & property)3929e80c87aSMatthew Barth static auto getPropertyVariant(const std::string& path, 3937311c394SMatthew Barth const std::string& interface, 3947311c394SMatthew Barth const std::string& property) 3957311c394SMatthew Barth { 3969e80c87aSMatthew Barth return getPropertyVariant<Variant>(getBus(), path, interface, property); 3977311c394SMatthew Barth } 3987311c394SMatthew Barth 399808d7fe8SMike Capps /** @brief Invoke a method and return without checking for error. */ 400808d7fe8SMike Capps template <typename... Args> callMethodAndReturn(sdbusplus::bus_t & bus,const std::string & busName,const std::string & path,const std::string & interface,const std::string & method,Args &&...args)401dfddd648SPatrick Williams static auto callMethodAndReturn( 402dfddd648SPatrick Williams sdbusplus::bus_t& bus, const std::string& busName, 403dfddd648SPatrick Williams const std::string& path, const std::string& interface, 404808d7fe8SMike Capps const std::string& method, Args&&... args) 405808d7fe8SMike Capps { 406808d7fe8SMike Capps auto reqMsg = bus.new_method_call(busName.c_str(), path.c_str(), 407808d7fe8SMike Capps interface.c_str(), method.c_str()); 408808d7fe8SMike Capps reqMsg.append(std::forward<Args>(args)...); 409808d7fe8SMike Capps auto respMsg = bus.call(reqMsg); 410808d7fe8SMike Capps 411808d7fe8SMike Capps return respMsg; 412808d7fe8SMike Capps } 413808d7fe8SMike Capps 4145a796e66SMatthew Barth /** @brief Get a property without mapper lookup. */ 4155a796e66SMatthew Barth template <typename Property> getProperty(sdbusplus::bus_t & bus,const std::string & service,const std::string & path,const std::string & interface,const std::string & property)416cb356d48SPatrick Williams static auto getProperty(sdbusplus::bus_t& bus, const std::string& service, 417cb356d48SPatrick Williams const std::string& path, 4185a796e66SMatthew Barth const std::string& interface, 4195a796e66SMatthew Barth const std::string& property) 4205a796e66SMatthew Barth { 4215a796e66SMatthew Barth using namespace std::literals::string_literals; 4225a796e66SMatthew Barth 4239e80c87aSMatthew Barth auto msg = callMethodAndReturn(bus, service, path, 4245a796e66SMatthew Barth "org.freedesktop.DBus.Properties"s, 4259e80c87aSMatthew Barth "Get"s, interface, property); 42688923a06SMatthew Barth if (msg.is_method_error()) 42788923a06SMatthew Barth { 4289e80c87aSMatthew Barth throw DBusPropertyError{"DBus get property failed", service, path, 4299e80c87aSMatthew Barth interface, property}; 43088923a06SMatthew Barth } 431c21d0b36SPatrick Williams std::variant<Property> value; 4325a796e66SMatthew Barth msg.read(value); 4331f514fa8SPatrick Williams return std::get<Property>(value); 4345a796e66SMatthew Barth } 4355a796e66SMatthew Barth 4365a796e66SMatthew Barth /** @brief Get a property without mapper lookup. */ 4375a796e66SMatthew Barth template <typename Property> getProperty(const std::string & service,const std::string & path,const std::string & interface,const std::string & property)4389e80c87aSMatthew Barth static auto getProperty(const std::string& service, const std::string& path, 4395a796e66SMatthew Barth const std::string& interface, 4405a796e66SMatthew Barth const std::string& property) 4415a796e66SMatthew Barth { 4429e80c87aSMatthew Barth return getProperty<Property>(getBus(), service, path, interface, 4435a796e66SMatthew Barth property); 4445a796e66SMatthew Barth } 4455a796e66SMatthew Barth 4467311c394SMatthew Barth /** @brief Get a property variant without mapper lookup. */ 4477311c394SMatthew Barth template <typename Variant> getPropertyVariant(sdbusplus::bus_t & bus,const std::string & service,const std::string & path,const std::string & interface,const std::string & property)448dfddd648SPatrick Williams static auto getPropertyVariant( 449dfddd648SPatrick Williams sdbusplus::bus_t& bus, const std::string& service, 450dfddd648SPatrick Williams const std::string& path, const std::string& interface, 4517311c394SMatthew Barth const std::string& property) 4527311c394SMatthew Barth { 4537311c394SMatthew Barth using namespace std::literals::string_literals; 4547311c394SMatthew Barth 4559e80c87aSMatthew Barth auto msg = callMethodAndReturn(bus, service, path, 4567311c394SMatthew Barth "org.freedesktop.DBus.Properties"s, 4579e80c87aSMatthew Barth "Get"s, interface, property); 45888923a06SMatthew Barth if (msg.is_method_error()) 45988923a06SMatthew Barth { 4609e80c87aSMatthew Barth throw DBusPropertyError{"DBus get property variant failed", service, 4619e80c87aSMatthew Barth path, interface, property}; 46288923a06SMatthew Barth } 4637311c394SMatthew Barth Variant value; 4647311c394SMatthew Barth msg.read(value); 4657311c394SMatthew Barth return value; 4667311c394SMatthew Barth } 4677311c394SMatthew Barth 4687311c394SMatthew Barth /** @brief Get a property variant without mapper lookup. */ 4697311c394SMatthew Barth template <typename Variant> getPropertyVariant(const std::string & service,const std::string & path,const std::string & interface,const std::string & property)470dfddd648SPatrick Williams static auto getPropertyVariant( 471dfddd648SPatrick Williams const std::string& service, const std::string& path, 472dfddd648SPatrick Williams const std::string& interface, const std::string& property) 4737311c394SMatthew Barth { 4749e80c87aSMatthew Barth return getPropertyVariant<Variant>(getBus(), service, path, interface, 4757311c394SMatthew Barth property); 4767311c394SMatthew Barth } 4777311c394SMatthew Barth 4786e9cfdb7SBrad Bishop /** @brief Set a property with mapper lookup. */ 4796e9cfdb7SBrad Bishop template <typename Property> setProperty(sdbusplus::bus_t & bus,const std::string & path,const std::string & interface,const std::string & property,Property && value)480cb356d48SPatrick Williams static void setProperty(sdbusplus::bus_t& bus, const std::string& path, 4816e9cfdb7SBrad Bishop const std::string& interface, 4829e80c87aSMatthew Barth const std::string& property, Property&& value) 4836e9cfdb7SBrad Bishop { 4846e9cfdb7SBrad Bishop using namespace std::literals::string_literals; 4856e9cfdb7SBrad Bishop 4869e80c87aSMatthew Barth std::variant<Property> varValue(std::forward<Property>(value)); 4876e9cfdb7SBrad Bishop 48888923a06SMatthew Barth auto service = getService(bus, path, interface); 4899e80c87aSMatthew Barth auto msg = callMethodAndReturn(bus, service, path, 4906e9cfdb7SBrad Bishop "org.freedesktop.DBus.Properties"s, 4919e80c87aSMatthew Barth "Set"s, interface, property, varValue); 49288923a06SMatthew Barth if (msg.is_method_error()) 49388923a06SMatthew Barth { 4949e80c87aSMatthew Barth throw DBusPropertyError{"DBus set property failed", service, path, 4959e80c87aSMatthew Barth interface, property}; 49688923a06SMatthew Barth } 4976e9cfdb7SBrad Bishop } 4986e9cfdb7SBrad Bishop 499f2238ae6SBrad Bishop /** @brief Set a property with mapper lookup. */ 500f2238ae6SBrad Bishop template <typename Property> setProperty(const std::string & path,const std::string & interface,const std::string & property,Property && value)5019e80c87aSMatthew Barth static void setProperty(const std::string& path, 502f2238ae6SBrad Bishop const std::string& interface, 5039e80c87aSMatthew Barth const std::string& property, Property&& value) 504f2238ae6SBrad Bishop { 5059e80c87aSMatthew Barth return setProperty(getBus(), path, interface, property, 506f2238ae6SBrad Bishop std::forward<Property>(value)); 507f2238ae6SBrad Bishop } 508f2238ae6SBrad Bishop 5096f30fd61SMatthew Barth /** @brief Set a property without mapper lookup. */ 5106f30fd61SMatthew Barth template <typename Property> setProperty(sdbusplus::bus_t & bus,const std::string & service,const std::string & path,const std::string & interface,const std::string & property,Property && value)511cb356d48SPatrick Williams static void setProperty(sdbusplus::bus_t& bus, const std::string& service, 512cb356d48SPatrick Williams const std::string& path, 5136f30fd61SMatthew Barth const std::string& interface, 5149e80c87aSMatthew Barth const std::string& property, Property&& value) 5156f30fd61SMatthew Barth { 5166f30fd61SMatthew Barth using namespace std::literals::string_literals; 5176f30fd61SMatthew Barth 5189e80c87aSMatthew Barth std::variant<Property> varValue(std::forward<Property>(value)); 5196f30fd61SMatthew Barth 5209e80c87aSMatthew Barth auto msg = callMethodAndReturn(bus, service, path, 5216f30fd61SMatthew Barth "org.freedesktop.DBus.Properties"s, 5229e80c87aSMatthew Barth "Set"s, interface, property, varValue); 52388923a06SMatthew Barth if (msg.is_method_error()) 52488923a06SMatthew Barth { 5259e80c87aSMatthew Barth throw DBusPropertyError{"DBus set property failed", service, path, 5269e80c87aSMatthew Barth interface, property}; 52788923a06SMatthew Barth } 5286f30fd61SMatthew Barth } 5296f30fd61SMatthew Barth 5306f30fd61SMatthew Barth /** @brief Set a property without mapper lookup. */ 5316f30fd61SMatthew Barth template <typename Property> setProperty(const std::string & service,const std::string & path,const std::string & interface,const std::string & property,Property && value)5329e80c87aSMatthew Barth static void setProperty(const std::string& service, const std::string& path, 5336f30fd61SMatthew Barth const std::string& interface, 5349e80c87aSMatthew Barth const std::string& property, Property&& value) 5356f30fd61SMatthew Barth { 5369e80c87aSMatthew Barth return setProperty(getBus(), service, path, interface, property, 5376f30fd61SMatthew Barth std::forward<Property>(value)); 5386f30fd61SMatthew Barth } 5396f30fd61SMatthew Barth 540f2238ae6SBrad Bishop /** @brief Invoke method with mapper lookup. */ 541f2238ae6SBrad Bishop template <typename... Args> lookupAndCallMethod(sdbusplus::bus_t & bus,const std::string & path,const std::string & interface,const std::string & method,Args &&...args)542dfddd648SPatrick Williams static auto lookupAndCallMethod( 543dfddd648SPatrick Williams sdbusplus::bus_t& bus, const std::string& path, 544dfddd648SPatrick Williams const std::string& interface, const std::string& method, Args&&... args) 545f2238ae6SBrad Bishop { 5469e80c87aSMatthew Barth return callMethod(bus, getService(bus, path, interface), path, 5479e80c87aSMatthew Barth interface, method, std::forward<Args>(args)...); 548f2238ae6SBrad Bishop } 549f2238ae6SBrad Bishop 5506e9cfdb7SBrad Bishop /** @brief Invoke method with mapper lookup. */ 5516e9cfdb7SBrad Bishop template <typename... Args> lookupAndCallMethod(const std::string & path,const std::string & interface,const std::string & method,Args &&...args)5529e80c87aSMatthew Barth static auto lookupAndCallMethod(const std::string& path, 5536e9cfdb7SBrad Bishop const std::string& interface, 5549e80c87aSMatthew Barth const std::string& method, Args&&... args) 5556e9cfdb7SBrad Bishop { 5569e80c87aSMatthew Barth return lookupAndCallMethod(getBus(), path, interface, method, 557f2238ae6SBrad Bishop std::forward<Args>(args)...); 558f2238ae6SBrad Bishop } 559f2238ae6SBrad Bishop 560f2238ae6SBrad Bishop /** @brief Invoke method and read with mapper lookup. */ 561f2238ae6SBrad Bishop template <typename Ret, typename... Args> lookupCallMethodAndRead(sdbusplus::bus_t & bus,const std::string & path,const std::string & interface,const std::string & method,Args &&...args)562dfddd648SPatrick Williams static auto lookupCallMethodAndRead( 563dfddd648SPatrick Williams sdbusplus::bus_t& bus, const std::string& path, 564dfddd648SPatrick Williams const std::string& interface, const std::string& method, Args&&... args) 565f2238ae6SBrad Bishop { 5669e80c87aSMatthew Barth return callMethodAndRead(bus, getService(bus, path, interface), path, 5679e80c87aSMatthew Barth interface, method, 5686e9cfdb7SBrad Bishop std::forward<Args>(args)...); 5696e9cfdb7SBrad Bishop } 5706e9cfdb7SBrad Bishop 5716e9cfdb7SBrad Bishop /** @brief Invoke method and read with mapper lookup. */ 5726e9cfdb7SBrad Bishop template <typename Ret, typename... Args> lookupCallMethodAndRead(const std::string & path,const std::string & interface,const std::string & method,Args &&...args)573dfddd648SPatrick Williams static auto lookupCallMethodAndRead( 574dfddd648SPatrick Williams const std::string& path, const std::string& interface, 575dfddd648SPatrick Williams const std::string& method, Args&&... args) 5766e9cfdb7SBrad Bishop { 5779e80c87aSMatthew Barth return lookupCallMethodAndRead<Ret>(getBus(), path, interface, method, 5786e9cfdb7SBrad Bishop std::forward<Args>(args)...); 5796e9cfdb7SBrad Bishop } 5806e9cfdb7SBrad Bishop }; 5816e9cfdb7SBrad Bishop 5826e9cfdb7SBrad Bishop } // namespace util 5836e9cfdb7SBrad Bishop } // namespace fan 5846e9cfdb7SBrad Bishop } // namespace phosphor 585