blob: a0308cd7560a30d25e0d4b8e285b95c48ad203ca [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>
Josh D. King6db38222016-12-19 14:52:40 -06003#include <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";
20
Josh D. King5162a7b2016-12-19 16:15:00 -060021/* Map a transition to it's systemd target */
22const std::map<server::BMC::Transition, const char*> SYSTEMD_TABLE =
23{
24 {server::BMC::Transition::Reboot, "reboot.target"}
25};
26
Josh D. King6db38222016-12-19 14:52:40 -060027constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
28constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1";
29constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
30
31void BMC::subscribeToSystemdSignals()
32{
33 auto method = this->bus.new_method_call(SYSTEMD_SERVICE,
34 SYSTEMD_OBJ_PATH,
35 SYSTEMD_INTERFACE,
36 "Subscribe");
37 this->bus.call(method);
38
39 return;
40}
41
Josh D. King5162a7b2016-12-19 16:15:00 -060042void BMC::executeTransition(const Transition tranReq)
43{
44 //Check to make sure it can be found
45 auto iter = SYSTEMD_TABLE.find(tranReq);
46 if (iter == SYSTEMD_TABLE.end()) return;
47
48 const auto& sysdUnit = iter->second;
49
50 auto method = this->bus.new_method_call(SYSTEMD_SERVICE,
51 SYSTEMD_OBJ_PATH,
52 SYSTEMD_INTERFACE,
53 "StartUnit");
54
55 method.append(sysdUnit, "replace");
56
57 this->bus.call(method);
58
59 return;
60}
61
Josh D. Kingd613b812016-12-19 16:47:45 -060062int BMC::bmcStateChangeSignal(sd_bus_message *msg, void *userData,
63 sd_bus_error *retError)
64{
65 return static_cast<BMC*>(userData)->bmcStateChange(msg, retError);
66}
67
68int BMC::bmcStateChange(sd_bus_message *msg,
69 sd_bus_error *retError)
70{
71 uint32_t newStateID {};
72 sdbusplus::message::object_path newStateObjPath;
73 std::string newStateUnit{};
74 std::string newStateResult{};
75
76 auto sdPlusMsg = sdbusplus::message::message(msg);
77 //Read the msg and populate each variable
78 sdPlusMsg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
79
80 //Caught the signal that indicates the BMC is now BMC_READY
81 if((newStateUnit == obmcStandbyTarget) &&
82 (newStateResult == signalDone))
83 {
84 log<level::INFO>("BMC_READY");
85 this->currentBMCState(BMCState::Ready);
86
87 //Unsubscribe so we stop processing all other signals
88 auto method = this->bus.new_method_call(SYSTEMD_SERVICE,
89 SYSTEMD_OBJ_PATH,
90 SYSTEMD_INTERFACE,
91 "Unsubscribe");
92 this->bus.call(method);
93 this->stateSignal.release();
94 }
95
96 return 0;
97}
98
Josh D. King6db38222016-12-19 14:52:40 -060099BMC::Transition BMC::requestedBMCTransition(Transition value)
100{
101 log<level::INFO>(
102 "Setting the RequestedBMCTransition field",
103 entry("REQUESTED_BMC_TRANSITION=0x%s",
104 convertForMessage(value).c_str()));
Josh D. King6db38222016-12-19 14:52:40 -0600105
Josh D. King5162a7b2016-12-19 16:15:00 -0600106 executeTransition(value);
107 return server::BMC::requestedBMCTransition(value);
Josh D. King6db38222016-12-19 14:52:40 -0600108}
109
Josh D. Kingd613b812016-12-19 16:47:45 -0600110BMC::BMCState BMC::currentBMCState(BMCState value)
111{
112 log<level::INFO>(
113 "Setting the BMCState field",
114 entry("CURRENT_BMC_STATE=0x%s",
115 convertForMessage(value).c_str()));
116
117 return server::BMC::currentBMCState(value);
118}
119
Josh D. King6db38222016-12-19 14:52:40 -0600120
Josh D. Kingbdd9cb72016-12-19 11:13:43 -0600121} // namespace manager
122} // namespace state
123} // namepsace phosphor
124