blob: f3c62d122f4fff3e2668e645b9062d7539bdc4f0 [file] [log] [blame]
Matt Spinler974c9162017-08-04 08:36:37 -05001#pragma once
2
3#include <phosphor-logging/log.hpp>
Matt Spinler882ce952017-10-05 16:12:41 -05004#include <phosphor-logging/elog.hpp>
Matt Spinler974c9162017-08-04 08:36:37 -05005#include <sdbusplus/bus.hpp>
6#include <string>
7
8namespace witherspoon
9{
10namespace power
11{
12namespace util
13{
14
Matt Spinler882ce952017-10-05 16:12:41 -050015constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
16constexpr auto SYSTEMD_ROOT = "/org/freedesktop/systemd1";
17constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
18constexpr auto POWEROFF_TARGET = "obmc-chassis-hard-poweroff@0.target";
Matt Spinler974c9162017-08-04 08:36:37 -050019constexpr 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 */
31std::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 */
45template<typename T>
46void 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(),
Matt Spinler882ce952017-10-05 16:12:41 -050056 path.c_str(),
57 PROPERTY_INTF,
58 "Get");
Matt Spinler974c9162017-08-04 08:36:37 -050059
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",
Matt Spinler882ce952017-10-05 16:12:41 -050067 entry("PATH=%s", path.c_str()),
68 entry("PROPERTY=%s", propertyName.c_str()));
69
Matt Spinler974c9162017-08-04 08:36:37 -050070 // 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
Matt Spinler48b4a432017-08-04 11:57:37 -050078/**
Brandon Wyman0a4f5192017-12-06 20:19:08 -060079 * @brief Write a D-Bus property
80 *
81 * @param[in] interface - the interface the property is on
82 * @param[in] propertName - the name of the property
83 * @param[in] path - the D-Bus path
84 * @param[in] service - the D-Bus service
85 * @param[in] bus - the D-Bus object
86 * @param[in] value - the value to set the property to
87 */
88template<typename T>
89void setProperty(const std::string& interface,
90 const std::string& propertyName,
91 const std::string& path,
92 const std::string& service,
93 sdbusplus::bus::bus& bus,
94 T& value)
95{
96 sdbusplus::message::variant<T> propertyValue(value);
97
98 auto method = bus.new_method_call(service.c_str(),
99 path.c_str(),
100 PROPERTY_INTF,
101 "Set");
102
103 method.append(interface, propertyName, propertyValue);
104
105 auto reply = bus.call(method);
106 if (reply.is_method_error())
107 {
108 using namespace phosphor::logging;
109 log<level::ERR>("Error in property set call",
110 entry("SERVICE=%s", service.c_str()),
111 entry("PATH=%s", path.c_str()),
112 entry("PROPERTY=%s", propertyName.c_str()));
113
114 // TODO openbmc/openbmc#851 - Once available, throw returned error
115 throw std::runtime_error("Error in property set call");
116 }
117
118}
119
120/**
Matt Spinler882ce952017-10-05 16:12:41 -0500121 * Logs an error and powers off the system.
Matt Spinler48b4a432017-08-04 11:57:37 -0500122 *
Matt Spinler882ce952017-10-05 16:12:41 -0500123 * @tparam T - error that will be logged before the power off
Matt Spinler48b4a432017-08-04 11:57:37 -0500124 * @param[in] bus - D-Bus object
125 */
Matt Spinler882ce952017-10-05 16:12:41 -0500126template<typename T>
127void powerOff(sdbusplus::bus::bus& bus)
128{
129 phosphor::logging::report<T>();
130
131 auto method = bus.new_method_call(SYSTEMD_SERVICE,
132 SYSTEMD_ROOT,
133 SYSTEMD_INTERFACE,
134 "StartUnit");
135
136 method.append(POWEROFF_TARGET);
137 method.append("replace");
138
139 bus.call_noreply(method);
140}
Matt Spinler48b4a432017-08-04 11:57:37 -0500141
Matt Spinler974c9162017-08-04 08:36:37 -0500142}
143}
144}