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
diff --git a/bmc_state_manager.hpp b/bmc_state_manager.hpp
index 1ddef53..bbace38 100644
--- a/bmc_state_manager.hpp
+++ b/bmc_state_manager.hpp
@@ -21,10 +21,6 @@
public:
/** @brief Constructs BMC State Manager
*
- * @note This constructor passes 'true' to the base class in order to
- * defer dbus object registration until we can run
- * subscribeToSystemdSignals() and set our properties
- *
* @param[in] bus - The Dbus bus object
* @param[in] busName - The Dbus name to own
* @param[in] objPath - The Dbus object path
@@ -34,7 +30,17 @@
sdbusplus::server::object::object<
sdbusplus::xyz::openbmc_project::State::server::BMC>(
bus, objPath),
- bus(bus)
+ bus(bus),
+ stateSignal(
+ std::make_unique<
+ decltype(stateSignal)::element_type>(
+ bus,
+ "type='signal',"
+ "member='JobRemoved',"
+ "path='/org/freedesktop/systemd1',"
+ "interface='org.freedesktop.systemd1.Manager'",
+ bmcStateChangeSignal,
+ this))
{
subscribeToSystemdSignals();
};
@@ -42,6 +48,8 @@
/** @brief Set value of BMCTransition **/
Transition requestedBMCTransition(Transition value) override;
+ /** @brief Set value of CurrentBMCState **/
+ BMCState currentBMCState(BMCState value) override;
private:
/**
@@ -55,9 +63,34 @@
*/
void executeTransition(Transition tranReq);
+ /** @brief Callback used to direct you into the class
+ *
+ * @param[in] msg - Data associated with subscribed signal
+ * @param[in] userData - Pointer to this object instance
+ * @param[out] retError - return error data if any
+ *
+ */
+ static int bmcStateChangeSignal(sd_bus_message* msg,
+ void* userData,
+ sd_bus_error* retError);
+
+ /** @brief Callback function on bmc state change
+ *
+ * Check if the state is relevant to the BMC and if so, update
+ * corresponding BMC object's state
+ *
+ * @param[in] msg - Data associated with subscribed signal
+ * @param[out] retError - return error data if any
+ *
+ */
+ int bmcStateChange(sd_bus_message* msg,
+ sd_bus_error* retError);
+
/** @brief Persistent sdbusplus DBus bus connection. **/
sdbusplus::bus::bus& bus;
+ /** @brief Used to subscribe to dbus system state changes **/
+ std::unique_ptr<sdbusplus::server::match::match> stateSignal;
};
} // namespace manager