xref: /openbmc/phosphor-power/utility.hpp (revision 882ce9562ff3a5a899801b59bf7805cdf7952d8a)
1974c916eSMatt Spinler #pragma once
2974c916eSMatt Spinler 
3974c916eSMatt Spinler #include <phosphor-logging/log.hpp>
4*882ce956SMatt Spinler #include <phosphor-logging/elog.hpp>
5974c916eSMatt Spinler #include <sdbusplus/bus.hpp>
6974c916eSMatt Spinler #include <string>
7974c916eSMatt Spinler 
8974c916eSMatt Spinler namespace witherspoon
9974c916eSMatt Spinler {
10974c916eSMatt Spinler namespace power
11974c916eSMatt Spinler {
12974c916eSMatt Spinler namespace util
13974c916eSMatt Spinler {
14974c916eSMatt Spinler 
15*882ce956SMatt Spinler constexpr auto SYSTEMD_SERVICE   = "org.freedesktop.systemd1";
16*882ce956SMatt Spinler constexpr auto SYSTEMD_ROOT      = "/org/freedesktop/systemd1";
17*882ce956SMatt Spinler constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
18*882ce956SMatt Spinler constexpr auto POWEROFF_TARGET   = "obmc-chassis-hard-poweroff@0.target";
19974c916eSMatt Spinler constexpr auto PROPERTY_INTF = "org.freedesktop.DBus.Properties";
20974c916eSMatt Spinler 
21974c916eSMatt Spinler /**
22974c916eSMatt Spinler  * @brief Get the service name from the mapper for the
23974c916eSMatt Spinler  *        interface and path passed in.
24974c916eSMatt Spinler  *
25974c916eSMatt Spinler  * @param[in] path - the D-Bus path name
26974c916eSMatt Spinler  * @param[in] interface - the D-Bus interface name
27974c916eSMatt Spinler  * @param[in] bus - the D-Bus object
28974c916eSMatt Spinler  *
29974c916eSMatt Spinler  * @return The service name
30974c916eSMatt Spinler  */
31974c916eSMatt Spinler std::string getService(const std::string& path,
32974c916eSMatt Spinler                        const std::string& interface,
33974c916eSMatt Spinler                        sdbusplus::bus::bus& bus);
34974c916eSMatt Spinler 
35974c916eSMatt Spinler /**
36974c916eSMatt Spinler  * @brief Read a D-Bus property
37974c916eSMatt Spinler  *
38974c916eSMatt Spinler  * @param[in] interface - the interface the property is on
39974c916eSMatt Spinler  * @param[in] propertName - the name of the property
40974c916eSMatt Spinler  * @param[in] path - the D-Bus path
41974c916eSMatt Spinler  * @param[in] service - the D-Bus service
42974c916eSMatt Spinler  * @param[in] bus - the D-Bus object
43974c916eSMatt Spinler  * @param[out] value - filled in with the property value
44974c916eSMatt Spinler  */
45974c916eSMatt Spinler template<typename T>
46974c916eSMatt Spinler void getProperty(const std::string& interface,
47974c916eSMatt Spinler                  const std::string& propertyName,
48974c916eSMatt Spinler                  const std::string& path,
49974c916eSMatt Spinler                  const std::string& service,
50974c916eSMatt Spinler                  sdbusplus::bus::bus& bus,
51974c916eSMatt Spinler                  T& value)
52974c916eSMatt Spinler {
53974c916eSMatt Spinler     sdbusplus::message::variant<T> property;
54974c916eSMatt Spinler 
55974c916eSMatt Spinler     auto method = bus.new_method_call(service.c_str(),
56974c916eSMatt Spinler                                       path.c_str(),
57974c916eSMatt Spinler                                       PROPERTY_INTF,
58974c916eSMatt Spinler                                       "Get");
59974c916eSMatt Spinler 
60974c916eSMatt Spinler     method.append(interface, propertyName);
61974c916eSMatt Spinler 
62974c916eSMatt Spinler     auto reply = bus.call(method);
63974c916eSMatt Spinler     if (reply.is_method_error())
64974c916eSMatt Spinler     {
65974c916eSMatt Spinler         using namespace phosphor::logging;
66974c916eSMatt Spinler         log<level::ERR>("Error in property get call",
67974c916eSMatt Spinler                         entry("PATH=%s", path.c_str()),
68974c916eSMatt Spinler                         entry("PROPERTY=%s", propertyName.c_str()));
69*882ce956SMatt Spinler 
70974c916eSMatt Spinler         // TODO openbmc/openbmc#851 - Once available, throw returned error
71974c916eSMatt Spinler         throw std::runtime_error("Error in property get call");
72974c916eSMatt Spinler     }
73974c916eSMatt Spinler 
74974c916eSMatt Spinler     reply.read(property);
75974c916eSMatt Spinler     value = sdbusplus::message::variant_ns::get<T>(property);
76974c916eSMatt Spinler }
77974c916eSMatt Spinler 
7848b4a430SMatt Spinler /**
79*882ce956SMatt Spinler  * Logs an error and powers off the system.
8048b4a430SMatt Spinler  *
81*882ce956SMatt Spinler  * @tparam T - error that will be logged before the power off
8248b4a430SMatt Spinler  * @param[in] bus - D-Bus object
8348b4a430SMatt Spinler  */
84*882ce956SMatt Spinler template<typename T>
85*882ce956SMatt Spinler void powerOff(sdbusplus::bus::bus& bus)
86*882ce956SMatt Spinler {
87*882ce956SMatt Spinler     phosphor::logging::report<T>();
88*882ce956SMatt Spinler 
89*882ce956SMatt Spinler     auto method = bus.new_method_call(SYSTEMD_SERVICE,
90*882ce956SMatt Spinler                                       SYSTEMD_ROOT,
91*882ce956SMatt Spinler                                       SYSTEMD_INTERFACE,
92*882ce956SMatt Spinler                                       "StartUnit");
93*882ce956SMatt Spinler 
94*882ce956SMatt Spinler     method.append(POWEROFF_TARGET);
95*882ce956SMatt Spinler     method.append("replace");
96*882ce956SMatt Spinler 
97*882ce956SMatt Spinler     bus.call_noreply(method);
98*882ce956SMatt Spinler }
9948b4a430SMatt Spinler 
100974c916eSMatt Spinler }
101974c916eSMatt Spinler }
102974c916eSMatt Spinler }
103