Process system state changes

We are currently subscribed to the systemd to get
a signal notifying us when the obmc-standby.target
is ready.  Things may change in the future but this
is what we have decided to do for now.

Change-Id: I81ecdcb45123feb611cf88916c0f9caadcd82dfe
Signed-off-by: Josh D. King <jdking@us.ibm.com>
diff --git a/bmc_state_manager.cpp b/bmc_state_manager.cpp
index 12a04a4..a0308cd 100644
--- a/bmc_state_manager.cpp
+++ b/bmc_state_manager.cpp
@@ -15,6 +15,9 @@
 
 using namespace phosphor::logging;
 
+constexpr auto obmcStandbyTarget = "obmc-standby.target";
+constexpr auto signalDone = "done";
+
 /* Map a transition to it's systemd target */
 const std::map<server::BMC::Transition, const char*> SYSTEMD_TABLE =
 {
@@ -56,6 +59,43 @@
     return;
 }
 
+int BMC::bmcStateChangeSignal(sd_bus_message *msg, void *userData,
+                              sd_bus_error *retError)
+{
+    return static_cast<BMC*>(userData)->bmcStateChange(msg, retError);
+}
+
+int BMC::bmcStateChange(sd_bus_message *msg,
+                        sd_bus_error *retError)
+{
+    uint32_t newStateID {};
+    sdbusplus::message::object_path newStateObjPath;
+    std::string newStateUnit{};
+    std::string newStateResult{};
+
+    auto sdPlusMsg = sdbusplus::message::message(msg);
+    //Read the msg and populate each variable
+    sdPlusMsg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
+
+    //Caught the signal that indicates the BMC is now BMC_READY
+    if((newStateUnit == obmcStandbyTarget) &&
+       (newStateResult == signalDone))
+    {
+        log<level::INFO>("BMC_READY");
+        this->currentBMCState(BMCState::Ready);
+
+        //Unsubscribe so we stop processing all other signals
+        auto method = this->bus.new_method_call(SYSTEMD_SERVICE,
+                                                SYSTEMD_OBJ_PATH,
+                                                SYSTEMD_INTERFACE,
+                                                "Unsubscribe");
+        this->bus.call(method);
+        this->stateSignal.release();
+    }
+
+    return 0;
+}
+
 BMC::Transition BMC::requestedBMCTransition(Transition value)
 {
     log<level::INFO>(
@@ -67,6 +107,16 @@
     return server::BMC::requestedBMCTransition(value);
 }
 
+BMC::BMCState BMC::currentBMCState(BMCState value)
+{
+    log<level::INFO>(
+            "Setting the BMCState field",
+            entry("CURRENT_BMC_STATE=0x%s",
+                  convertForMessage(value).c_str()));
+
+    return server::BMC::currentBMCState(value);
+}
+
 
 } // namespace manager
 } // namespace state