blob: 0a9bdb40f0075d334b404a9d132dfd1a4f6ac25a [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/**
Matt Spinler882ce952017-10-05 16:12:41 -050079 * Logs an error and powers off the system.
Matt Spinler48b4a432017-08-04 11:57:37 -050080 *
Matt Spinler882ce952017-10-05 16:12:41 -050081 * @tparam T - error that will be logged before the power off
Matt Spinler48b4a432017-08-04 11:57:37 -050082 * @param[in] bus - D-Bus object
83 */
Matt Spinler882ce952017-10-05 16:12:41 -050084template<typename T>
85void 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}
Matt Spinler48b4a432017-08-04 11:57:37 -050099
Matt Spinler974c9162017-08-04 08:36:37 -0500100}
101}
102}