xref: /openbmc/witherspoon-pfault-analysis/utility.hpp (revision 882ce9562ff3a5a899801b59bf7805cdf7952d8a)
1 #pragma once
2 
3 #include <phosphor-logging/log.hpp>
4 #include <phosphor-logging/elog.hpp>
5 #include <sdbusplus/bus.hpp>
6 #include <string>
7 
8 namespace witherspoon
9 {
10 namespace power
11 {
12 namespace util
13 {
14 
15 constexpr auto SYSTEMD_SERVICE   = "org.freedesktop.systemd1";
16 constexpr auto SYSTEMD_ROOT      = "/org/freedesktop/systemd1";
17 constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
18 constexpr auto POWEROFF_TARGET   = "obmc-chassis-hard-poweroff@0.target";
19 constexpr auto PROPERTY_INTF = "org.freedesktop.DBus.Properties";
20 
21 /**
22  * @brief Get the service name from the mapper for the
23  *        interface and path passed in.
24  *
25  * @param[in] path - the D-Bus path name
26  * @param[in] interface - the D-Bus interface name
27  * @param[in] bus - the D-Bus object
28  *
29  * @return The service name
30  */
31 std::string getService(const std::string& path,
32                        const std::string& interface,
33                        sdbusplus::bus::bus& bus);
34 
35 /**
36  * @brief Read a D-Bus property
37  *
38  * @param[in] interface - the interface the property is on
39  * @param[in] propertName - the name of the property
40  * @param[in] path - the D-Bus path
41  * @param[in] service - the D-Bus service
42  * @param[in] bus - the D-Bus object
43  * @param[out] value - filled in with the property value
44  */
45 template<typename T>
46 void getProperty(const std::string& interface,
47                  const std::string& propertyName,
48                  const std::string& path,
49                  const std::string& service,
50                  sdbusplus::bus::bus& bus,
51                  T& value)
52 {
53     sdbusplus::message::variant<T> property;
54 
55     auto method = bus.new_method_call(service.c_str(),
56                                       path.c_str(),
57                                       PROPERTY_INTF,
58                                       "Get");
59 
60     method.append(interface, propertyName);
61 
62     auto reply = bus.call(method);
63     if (reply.is_method_error())
64     {
65         using namespace phosphor::logging;
66         log<level::ERR>("Error in property get call",
67                         entry("PATH=%s", path.c_str()),
68                         entry("PROPERTY=%s", propertyName.c_str()));
69 
70         // TODO openbmc/openbmc#851 - Once available, throw returned error
71         throw std::runtime_error("Error in property get call");
72     }
73 
74     reply.read(property);
75     value = sdbusplus::message::variant_ns::get<T>(property);
76 }
77 
78 /**
79  * Logs an error and powers off the system.
80  *
81  * @tparam T - error that will be logged before the power off
82  * @param[in] bus - D-Bus object
83  */
84 template<typename T>
85 void powerOff(sdbusplus::bus::bus& bus)
86 {
87     phosphor::logging::report<T>();
88 
89     auto method = bus.new_method_call(SYSTEMD_SERVICE,
90                                       SYSTEMD_ROOT,
91                                       SYSTEMD_INTERFACE,
92                                       "StartUnit");
93 
94     method.append(POWEROFF_TARGET);
95     method.append("replace");
96 
97     bus.call_noreply(method);
98 }
99 
100 }
101 }
102 }
103