1 #pragma once
2 
3 #include <phosphor-logging/elog.hpp>
4 #include <phosphor-logging/log.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, const std::string& interface,
32                        sdbusplus::bus::bus& bus);
33 
34 /**
35  * @brief Read a D-Bus property
36  *
37  * @param[in] interface - the interface the property is on
38  * @param[in] propertName - the name of the property
39  * @param[in] path - the D-Bus path
40  * @param[in] service - the D-Bus service
41  * @param[in] bus - the D-Bus object
42  * @param[out] value - filled in with the property value
43  */
44 template <typename T>
45 void getProperty(const std::string& interface, const std::string& propertyName,
46                  const std::string& path, const std::string& service,
47                  sdbusplus::bus::bus& bus, T& value)
48 {
49     sdbusplus::message::variant<T> property;
50 
51     auto method = bus.new_method_call(service.c_str(), path.c_str(),
52                                       PROPERTY_INTF, "Get");
53 
54     method.append(interface, propertyName);
55 
56     auto reply = bus.call(method);
57 
58     reply.read(property);
59     value = sdbusplus::message::variant_ns::get<T>(property);
60 }
61 
62 /**
63  * @brief Write a D-Bus property
64  *
65  * @param[in] interface - the interface the property is on
66  * @param[in] propertName - the name of the property
67  * @param[in] path - the D-Bus path
68  * @param[in] service - the D-Bus service
69  * @param[in] bus - the D-Bus object
70  * @param[in] value - the value to set the property to
71  */
72 template <typename T>
73 void setProperty(const std::string& interface, const std::string& propertyName,
74                  const std::string& path, const std::string& service,
75                  sdbusplus::bus::bus& bus, T& value)
76 {
77     sdbusplus::message::variant<T> propertyValue(value);
78 
79     auto method = bus.new_method_call(service.c_str(), path.c_str(),
80                                       PROPERTY_INTF, "Set");
81 
82     method.append(interface, propertyName, propertyValue);
83 
84     auto reply = bus.call(method);
85 }
86 
87 /**
88  * Logs an error and powers off the system.
89  *
90  * @tparam T - error that will be logged before the power off
91  * @param[in] bus - D-Bus object
92  */
93 template <typename T>
94 void powerOff(sdbusplus::bus::bus& bus)
95 {
96     phosphor::logging::report<T>();
97 
98     auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT,
99                                       SYSTEMD_INTERFACE, "StartUnit");
100 
101     method.append(POWEROFF_TARGET);
102     method.append("replace");
103 
104     bus.call_noreply(method);
105 }
106 
107 } // namespace util
108 } // namespace power
109 } // namespace witherspoon
110