1 #pragma once
2
3 #include <phosphor-logging/elog.hpp>
4 #include <phosphor-logging/log.hpp>
5 #include <sdbusplus/bus.hpp>
6
7 #include <string>
8
9 namespace witherspoon
10 {
11 namespace power
12 {
13 namespace util
14 {
15
16 constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
17 constexpr auto SYSTEMD_ROOT = "/org/freedesktop/systemd1";
18 constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
19 constexpr auto POWEROFF_TARGET = "obmc-chassis-hard-poweroff@0.target";
20 constexpr auto PROPERTY_INTF = "org.freedesktop.DBus.Properties";
21
22 /**
23 * @brief Get the service name from the mapper for the
24 * interface and path passed in.
25 *
26 * @param[in] path - the D-Bus path name
27 * @param[in] interface - the D-Bus interface name
28 * @param[in] bus - the D-Bus object
29 *
30 * @return The service name
31 */
32 std::string getService(const std::string& path, const std::string& interface,
33 sdbusplus::bus_t& 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>
getProperty(const std::string & interface,const std::string & propertyName,const std::string & path,const std::string & service,sdbusplus::bus_t & bus,T & value)46 void getProperty(const std::string& interface, const std::string& propertyName,
47 const std::string& path, const std::string& service,
48 sdbusplus::bus_t& bus, T& value)
49 {
50 std::variant<T> property;
51
52 auto method = bus.new_method_call(service.c_str(), path.c_str(),
53 PROPERTY_INTF, "Get");
54
55 method.append(interface, propertyName);
56
57 auto reply = bus.call(method);
58
59 reply.read(property);
60 value = std::get<T>(property);
61 }
62
63 /**
64 * @brief Write a D-Bus property
65 *
66 * @param[in] interface - the interface the property is on
67 * @param[in] propertName - the name of the property
68 * @param[in] path - the D-Bus path
69 * @param[in] service - the D-Bus service
70 * @param[in] bus - the D-Bus object
71 * @param[in] value - the value to set the property to
72 */
73 template <typename T>
setProperty(const std::string & interface,const std::string & propertyName,const std::string & path,const std::string & service,sdbusplus::bus_t & bus,T & value)74 void setProperty(const std::string& interface, const std::string& propertyName,
75 const std::string& path, const std::string& service,
76 sdbusplus::bus_t& bus, T& value)
77 {
78 std::variant<T> propertyValue(value);
79
80 auto method = bus.new_method_call(service.c_str(), path.c_str(),
81 PROPERTY_INTF, "Set");
82
83 method.append(interface, propertyName, propertyValue);
84
85 auto reply = bus.call(method);
86 }
87
88 /**
89 * Logs an error and powers off the system.
90 *
91 * @tparam T - error that will be logged before the power off
92 * @param[in] bus - D-Bus object
93 */
94 template <typename T>
powerOff(sdbusplus::bus_t & bus)95 void powerOff(sdbusplus::bus_t& bus)
96 {
97 phosphor::logging::report<T>();
98
99 auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT,
100 SYSTEMD_INTERFACE, "StartUnit");
101
102 method.append(POWEROFF_TARGET);
103 method.append("replace");
104
105 bus.call_noreply(method);
106 }
107
108 } // namespace util
109 } // namespace power
110 } // namespace witherspoon
111