blob: 3989b3fbb573b45f7392c8b579d0e3ce6f971cc2 [file] [log] [blame]
Michael Tritz3ed10082017-03-20 23:28:09 -05001#include <iostream>
2#include <map>
3#include <string>
4#include <config.h>
5#include <systemd/sd-bus.h>
6#include <sdbusplus/server.hpp>
7#include <phosphor-logging/log.hpp>
8#include "chassis_state_manager.hpp"
9#include "host_state_manager.hpp"
10
11namespace phosphor
12{
13namespace state
14{
15namespace manager
16{
17
18using namespace phosphor::logging;
19
20constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
21constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
22constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
23
24constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
25
26constexpr auto HOST_PATH = "/xyz/openbmc_project/state/host0";
27
28constexpr auto SETTINGS_PATH = "/org/openbmc/settings/host0";
29constexpr auto SETTINGS_INTERFACE = "org.openbmc.settings.Host";
30
31constexpr auto CHASSIS_PATH = "/xyz/openbmc_project/state/chassis0";
32
33std::string getService(sdbusplus::bus::bus& bus, std::string path,
34 std::string interface)
35{
36 auto mapper = bus.new_method_call(MAPPER_BUSNAME,
37 MAPPER_PATH,
38 MAPPER_INTERFACE,
39 "GetObject");
40
41 mapper.append(path, std::vector<std::string>({interface}));
42 auto mapperResponseMsg = bus.call(mapper);
43
44 if (mapperResponseMsg.is_method_error())
45 {
46 log<level::ERR>("Error in mapper call",
47 entry("PATH=%s", path.c_str()),
48 entry("INTERFACE=%s", interface.c_str()));
49 throw std::runtime_error("Error in mapper call");
50 }
51
52 std::map<std::string, std::vector<std::string>> mapperResponse;
53 mapperResponseMsg.read(mapperResponse);
54 if (mapperResponse.empty())
55 {
56 log<level::ERR>("Error reading mapper response",
57 entry("PATH=%s", path.c_str()),
58 entry("INTERFACE=%s", interface.c_str()));
59 throw std::runtime_error("Error reading mapper response");
60 }
61
62 return mapperResponse.begin()->first;
63}
64
65std::string getProperty(sdbusplus::bus::bus& bus, std::string path,
66 std::string interface, std::string propertyName)
67{
68 sdbusplus::message::variant<std::string> property;
69 std::string service = getService(bus, path, interface);
70
71 auto method = bus.new_method_call(service.c_str(),
72 path.c_str(),
73 PROPERTY_INTERFACE,
74 "Get");
75
76 method.append(interface, propertyName);
77 auto reply = bus.call(method);
78
79 if (reply.is_method_error())
80 {
81 log<level::ERR>("Error in property Get",
82 entry("PROPERTY=%s", propertyName.c_str()));
83 throw std::runtime_error("Error in property Get");
84 }
85
86 reply.read(property);
87
88 if (sdbusplus::message::variant_ns::get<std::string>(property).empty())
89 {
90 log<level::ERR>("Error reading property response",
91 entry("PROPERTY=%s", propertyName.c_str()));
92 throw std::runtime_error("Error reading property response");
93 }
94
95 return sdbusplus::message::variant_ns::get<std::string>(property);
96}
97
98void setProperty(sdbusplus::bus::bus& bus, std::string path,
99 std::string interface, std::string property, std::string value)
100{
101 sdbusplus::message::variant<std::string> variantValue = value;
102 std::string service = getService(bus, path, interface);
103
104 auto method = bus.new_method_call(service.c_str(),
105 path.c_str(),
106 PROPERTY_INTERFACE,
107 "Set");
108
109 method.append(interface, property, variantValue);
110 bus.call_noreply(method);
111
112 return;
113}
114
115} // namespace manager
116} // namespace state
117} // namepsace phosphor
118
119int main()
120{
121 auto bus = sdbusplus::bus::new_default();
122
123 using namespace phosphor::state::manager;
124 namespace server = sdbusplus::xyz::openbmc_project::State::server;
125
126 std::string currentPowerState = getProperty(bus, CHASSIS_PATH,
127 CHASSIS_BUSNAME,
128 "CurrentPowerState");
129
130 if(currentPowerState == convertForMessage(server::Chassis::PowerState::Off))
131 {
132 std::string power_policy = getProperty(bus, SETTINGS_PATH,
133 SETTINGS_INTERFACE,
134 "power_policy");
135
136 log<level::INFO>("Host power is off, checking power policy",
137 entry("POWER_POLICY=%s", power_policy.c_str()));
138
139 if (power_policy == "ALWAYS_POWER_ON")
140 {
141 log<level::INFO>("power_policy=ALWAYS_POWER_ON, powering host on");
142 setProperty(bus, HOST_PATH, HOST_BUSNAME,
143 "RequestedHostTransition",
144 convertForMessage(server::Host::Transition::On));
145 }
146
147 }
148
149 return 0;
150}