blob: 992905907573d62c1a591a8e3bd9b6c1f0277319 [file] [log] [blame]
Josh D. Kingbdd9cb72016-12-19 11:13:43 -06001#include <iostream>
Josh D. King5162a7b2016-12-19 16:15:00 -06002#include <string>
Saqib Khana8006a22017-02-14 11:37:08 -06003#include <phosphor-logging/log.hpp>
Josh D. Kingbdd9cb72016-12-19 11:13:43 -06004#include "bmc_state_manager.hpp"
5
6namespace phosphor
7{
8namespace state
9{
10namespace manager
11{
12
Josh D. King6db38222016-12-19 14:52:40 -060013// When you see server:: you know we're referencing our base class
14namespace server = sdbusplus::xyz::openbmc_project::State::server;
15
16using namespace phosphor::logging;
17
Josh D. Kingd613b812016-12-19 16:47:45 -060018constexpr auto obmcStandbyTarget = "obmc-standby.target";
19constexpr auto signalDone = "done";
Josh D. Kingd3e58472017-02-02 11:09:11 -060020constexpr auto activeState = "active";
Josh D. Kingd613b812016-12-19 16:47:45 -060021
Josh D. King5162a7b2016-12-19 16:15:00 -060022/* Map a transition to it's systemd target */
23const std::map<server::BMC::Transition, const char*> SYSTEMD_TABLE =
24{
25 {server::BMC::Transition::Reboot, "reboot.target"}
26};
27
Josh D. King2b5d8872017-02-21 13:37:17 -060028constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
29constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1";
30constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
Josh D. Kingd3e58472017-02-02 11:09:11 -060031constexpr auto SYSTEMD_PRP_INTERFACE = "org.freedesktop.DBus.Properties";
Josh D. Kingd3e58472017-02-02 11:09:11 -060032
33void BMC::discoverInitialState()
34{
35 sdbusplus::message::variant<std::string> currentState;
Josh D. King2b5d8872017-02-21 13:37:17 -060036 sdbusplus::message::object_path unitTargetPath;
Josh D. Kingd3e58472017-02-02 11:09:11 -060037
38 auto method = this->bus.new_method_call(SYSTEMD_SERVICE,
Josh D. King2b5d8872017-02-21 13:37:17 -060039 SYSTEMD_OBJ_PATH,
40 SYSTEMD_INTERFACE,
41 "GetUnit");
42
43 method.append(obmcStandbyTarget);
44
45 auto result = this->bus.call(method);
46
47 //Check that the bus call didn't result in an error
48 if(result.is_method_error())
49 {
50 log<level::ERR>("Error in bus call.");
51 return;
52 }
53
54 result.read(unitTargetPath);
55
56 method = this->bus.new_method_call(SYSTEMD_SERVICE,
57 static_cast<const std::string&>
58 (unitTargetPath).c_str(),
59 SYSTEMD_PRP_INTERFACE,
60 "Get");
Josh D. Kingd3e58472017-02-02 11:09:11 -060061
62 method.append("org.freedesktop.systemd1.Unit", "ActiveState");
63
Josh D. King2b5d8872017-02-21 13:37:17 -060064 result = this->bus.call(method);
65
66 //Check that the bus call didn't result in an error
67 if(result.is_method_error())
68 {
69 log<level::INFO>("Error in bus call.");
70 return;
71 }
Josh D. Kingd3e58472017-02-02 11:09:11 -060072
73 //Is obmc-standby.target active or inactive?
74 result.read(currentState);
75
76 if(currentState == activeState)
77 {
78 log<level::INFO>("Setting the BMCState field",
79 entry("CURRENT_BMC_STATE=%s",
80 "BMC_READY"));
81 this->currentBMCState(BMCState::Ready);
82
83 //Unsubscribe so we stop processing all other signals
84 method = this->bus.new_method_call(SYSTEMD_SERVICE,
85 SYSTEMD_OBJ_PATH,
86 SYSTEMD_INTERFACE,
87 "Unsubscribe");
88 this->bus.call(method);
89 this->stateSignal.release();
90 }
91 else
92 {
93 log<level::INFO>("Setting the BMCState field",
94 entry("CURRENT_BMC_STATE=%s",
95 "BMC_NOTREADY"));
96 this->currentBMCState(BMCState::NotReady);
97 }
98
99 return;
100}
101
Josh D. King6db38222016-12-19 14:52:40 -0600102void BMC::subscribeToSystemdSignals()
103{
104 auto method = this->bus.new_method_call(SYSTEMD_SERVICE,
105 SYSTEMD_OBJ_PATH,
106 SYSTEMD_INTERFACE,
107 "Subscribe");
108 this->bus.call(method);
109
110 return;
111}
112
Josh D. King5162a7b2016-12-19 16:15:00 -0600113void BMC::executeTransition(const Transition tranReq)
114{
115 //Check to make sure it can be found
116 auto iter = SYSTEMD_TABLE.find(tranReq);
117 if (iter == SYSTEMD_TABLE.end()) return;
118
119 const auto& sysdUnit = iter->second;
120
121 auto method = this->bus.new_method_call(SYSTEMD_SERVICE,
122 SYSTEMD_OBJ_PATH,
123 SYSTEMD_INTERFACE,
124 "StartUnit");
125
126 method.append(sysdUnit, "replace");
127
128 this->bus.call(method);
129
130 return;
131}
132
Patrick Williamsd32f8182017-05-05 15:55:24 -0500133int BMC::bmcStateChange(sdbusplus::message::message& msg)
Josh D. Kingd613b812016-12-19 16:47:45 -0600134{
135 uint32_t newStateID {};
136 sdbusplus::message::object_path newStateObjPath;
137 std::string newStateUnit{};
138 std::string newStateResult{};
139
Josh D. Kingd613b812016-12-19 16:47:45 -0600140 //Read the msg and populate each variable
Patrick Williamsd32f8182017-05-05 15:55:24 -0500141 msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
Josh D. Kingd613b812016-12-19 16:47:45 -0600142
143 //Caught the signal that indicates the BMC is now BMC_READY
144 if((newStateUnit == obmcStandbyTarget) &&
145 (newStateResult == signalDone))
146 {
147 log<level::INFO>("BMC_READY");
148 this->currentBMCState(BMCState::Ready);
149
150 //Unsubscribe so we stop processing all other signals
151 auto method = this->bus.new_method_call(SYSTEMD_SERVICE,
152 SYSTEMD_OBJ_PATH,
153 SYSTEMD_INTERFACE,
154 "Unsubscribe");
155 this->bus.call(method);
156 this->stateSignal.release();
157 }
158
159 return 0;
160}
161
Josh D. King6db38222016-12-19 14:52:40 -0600162BMC::Transition BMC::requestedBMCTransition(Transition value)
163{
164 log<level::INFO>(
165 "Setting the RequestedBMCTransition field",
166 entry("REQUESTED_BMC_TRANSITION=0x%s",
167 convertForMessage(value).c_str()));
Josh D. King6db38222016-12-19 14:52:40 -0600168
Josh D. King5162a7b2016-12-19 16:15:00 -0600169 executeTransition(value);
170 return server::BMC::requestedBMCTransition(value);
Josh D. King6db38222016-12-19 14:52:40 -0600171}
172
Josh D. Kingd613b812016-12-19 16:47:45 -0600173BMC::BMCState BMC::currentBMCState(BMCState value)
174{
175 log<level::INFO>(
176 "Setting the BMCState field",
177 entry("CURRENT_BMC_STATE=0x%s",
178 convertForMessage(value).c_str()));
179
180 return server::BMC::currentBMCState(value);
181}
182
Josh D. King6db38222016-12-19 14:52:40 -0600183
Josh D. Kingbdd9cb72016-12-19 11:13:43 -0600184} // namespace manager
185} // namespace state
186} // namepsace phosphor
187