blob: c055f9fe6125517e066989e37a090cc89ce4db5d [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>
Deepak Kodihalli55f132b2017-07-25 07:36:06 -05008#include <phosphor-logging/elog-errors.hpp>
Michael Tritz3ed10082017-03-20 23:28:09 -05009#include "chassis_state_manager.hpp"
10#include "host_state_manager.hpp"
Deepak Kodihalli55f132b2017-07-25 07:36:06 -050011#include "settings.hpp"
12#include "xyz/openbmc_project/Common/error.hpp"
13#include "xyz/openbmc_project/Control/Power/RestorePolicy/server.hpp"
Michael Tritz3ed10082017-03-20 23:28:09 -050014
15namespace phosphor
16{
17namespace state
18{
19namespace manager
20{
21
22using namespace phosphor::logging;
Deepak Kodihalli55f132b2017-07-25 07:36:06 -050023using namespace sdbusplus::xyz::openbmc_project::Common::Error;
24using namespace sdbusplus::xyz::openbmc_project::Control::Power::server;
Michael Tritz3ed10082017-03-20 23:28:09 -050025
26constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
27constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
28constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
29
30constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
31
32constexpr auto HOST_PATH = "/xyz/openbmc_project/state/host0";
33
Michael Tritz3ed10082017-03-20 23:28:09 -050034constexpr auto CHASSIS_PATH = "/xyz/openbmc_project/state/chassis0";
35
36std::string getService(sdbusplus::bus::bus& bus, std::string path,
37 std::string interface)
38{
39 auto mapper = bus.new_method_call(MAPPER_BUSNAME,
40 MAPPER_PATH,
41 MAPPER_INTERFACE,
42 "GetObject");
43
44 mapper.append(path, std::vector<std::string>({interface}));
45 auto mapperResponseMsg = bus.call(mapper);
46
47 if (mapperResponseMsg.is_method_error())
48 {
49 log<level::ERR>("Error in mapper call",
50 entry("PATH=%s", path.c_str()),
51 entry("INTERFACE=%s", interface.c_str()));
52 throw std::runtime_error("Error in mapper call");
53 }
54
55 std::map<std::string, std::vector<std::string>> mapperResponse;
56 mapperResponseMsg.read(mapperResponse);
57 if (mapperResponse.empty())
58 {
59 log<level::ERR>("Error reading mapper response",
60 entry("PATH=%s", path.c_str()),
61 entry("INTERFACE=%s", interface.c_str()));
62 throw std::runtime_error("Error reading mapper response");
63 }
64
65 return mapperResponse.begin()->first;
66}
67
68std::string getProperty(sdbusplus::bus::bus& bus, std::string path,
69 std::string interface, std::string propertyName)
70{
71 sdbusplus::message::variant<std::string> property;
72 std::string service = getService(bus, path, interface);
73
74 auto method = bus.new_method_call(service.c_str(),
75 path.c_str(),
76 PROPERTY_INTERFACE,
77 "Get");
78
79 method.append(interface, propertyName);
80 auto reply = bus.call(method);
81
82 if (reply.is_method_error())
83 {
84 log<level::ERR>("Error in property Get",
85 entry("PROPERTY=%s", propertyName.c_str()));
86 throw std::runtime_error("Error in property Get");
87 }
88
89 reply.read(property);
90
91 if (sdbusplus::message::variant_ns::get<std::string>(property).empty())
92 {
93 log<level::ERR>("Error reading property response",
94 entry("PROPERTY=%s", propertyName.c_str()));
95 throw std::runtime_error("Error reading property response");
96 }
97
98 return sdbusplus::message::variant_ns::get<std::string>(property);
99}
100
101void setProperty(sdbusplus::bus::bus& bus, std::string path,
102 std::string interface, std::string property, std::string value)
103{
104 sdbusplus::message::variant<std::string> variantValue = value;
105 std::string service = getService(bus, path, interface);
106
107 auto method = bus.new_method_call(service.c_str(),
108 path.c_str(),
109 PROPERTY_INTERFACE,
110 "Set");
111
112 method.append(interface, property, variantValue);
113 bus.call_noreply(method);
114
115 return;
116}
117
118} // namespace manager
119} // namespace state
120} // namepsace phosphor
121
122int main()
123{
Deepak Kodihalli55f132b2017-07-25 07:36:06 -0500124 using namespace phosphor::logging;
125
Michael Tritz3ed10082017-03-20 23:28:09 -0500126 auto bus = sdbusplus::bus::new_default();
127
Deepak Kodihalli55f132b2017-07-25 07:36:06 -0500128 using namespace settings;
129 Objects settings(bus);
130
Michael Tritz3ed10082017-03-20 23:28:09 -0500131 using namespace phosphor::state::manager;
132 namespace server = sdbusplus::xyz::openbmc_project::State::server;
133
134 std::string currentPowerState = getProperty(bus, CHASSIS_PATH,
135 CHASSIS_BUSNAME,
136 "CurrentPowerState");
137
138 if(currentPowerState == convertForMessage(server::Chassis::PowerState::Off))
139 {
Deepak Kodihalli55f132b2017-07-25 07:36:06 -0500140 auto method =
141 bus.new_method_call(
142 settings.service(settings.powerRestorePolicy,
143 powerRestoreIntf).c_str(),
144 settings.powerRestorePolicy.c_str(),
145 "org.freedesktop.DBus.Properties",
146 "Get");
147 method.append(powerRestoreIntf, "PowerRestorePolicy");
148 auto reply = bus.call(method);
149 if (reply.is_method_error())
150 {
151 log<level::ERR>("Error in PowerRestorePolicy Get");
152 elog<InternalFailure>();
153 }
154
155 sdbusplus::message::variant<std::string> result;
156 reply.read(result);
157 auto powerPolicy = result.get<std::string>();
Michael Tritz3ed10082017-03-20 23:28:09 -0500158
159 log<level::INFO>("Host power is off, checking power policy",
Deepak Kodihalli55f132b2017-07-25 07:36:06 -0500160 entry("POWER_POLICY=%s", powerPolicy.c_str()));
Michael Tritz3ed10082017-03-20 23:28:09 -0500161
Deepak Kodihalli55f132b2017-07-25 07:36:06 -0500162 if (RestorePolicy::Policy::AlwaysOn ==
163 RestorePolicy::convertPolicyFromString(powerPolicy))
Michael Tritz3ed10082017-03-20 23:28:09 -0500164 {
165 log<level::INFO>("power_policy=ALWAYS_POWER_ON, powering host on");
166 setProperty(bus, HOST_PATH, HOST_BUSNAME,
167 "RequestedHostTransition",
168 convertForMessage(server::Host::Transition::On));
169 }
170
171 }
172
173 return 0;
174}