xref: /openbmc/phosphor-fan-presence/sdbusplus.hpp (revision 4fa67aa12bd73f7d528225f0c3c93c3242bbcc23)
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