Add power_state implementation
Added power_state implementation for multi host platform
specific shutdown interfaces like hard shutdown or soft
shutdown interfaces.
Getting the current host state of all the hosts and set
power_state values based on the hosts current host state.
TESTED : Verified the Shutdown alarms trigged and platform
specific actions done in Facebook YosemiteV2 platform.
Signed-off-by: Kumar Thangavel <thangavel.k@hcl.com>
Change-Id: I5e38bb9f28b7840c9de10082905b31deb8ffc4ff
diff --git a/power_state.hpp b/power_state.hpp
index dc74707..ad8a0d5 100644
--- a/power_state.hpp
+++ b/power_state.hpp
@@ -5,9 +5,13 @@
#include <fmt/format.h>
#include <phosphor-logging/log.hpp>
+#include <xyz/openbmc_project/State/Host/server.hpp>
#include <functional>
+using HostState =
+ sdbusplus::xyz::openbmc_project::State::server::Host::HostState;
+
namespace phosphor::fan
{
@@ -221,4 +225,149 @@
sdbusplus::bus::match::match _match;
};
+/**
+ * @class HostPowerState
+ *
+ * This class implements the PowerState API by looking at the 'powerState'
+ * property on the phosphor virtual sensor interface.
+ */
+class HostPowerState : public PowerState
+{
+ public:
+ virtual ~HostPowerState() = default;
+ HostPowerState(const HostPowerState&) = delete;
+ HostPowerState& operator=(const HostPowerState&) = delete;
+ HostPowerState(HostPowerState&&) = delete;
+ HostPowerState& operator=(HostPowerState&&) = delete;
+
+ HostPowerState() :
+ PowerState(),
+ _match(_bus,
+ sdbusplus::bus::match::rules::propertiesChangedNamespace(
+ _hostStatePath, _hostStateInterface),
+ [this](auto& msg) { this->hostStateChanged(msg); })
+ {
+ readHostState();
+ }
+
+ /**
+ * @brief Constructor
+ *
+ * @param[in] bus - The D-Bus bus connection object
+ * @param[in] callback - The function that should be run when
+ * the power state changes
+ */
+ HostPowerState(sdbusplus::bus::bus& bus, StateChangeFunc func) :
+ PowerState(bus, func),
+ _match(_bus,
+ sdbusplus::bus::match::rules::propertiesChangedNamespace(
+ _hostStatePath, _hostStateInterface),
+ [this](auto& msg) { this->hostStateChanged(msg); })
+ {
+ readHostState();
+ }
+
+ /**
+ * @brief PropertiesChanged callback for the CurrentHostState property.
+ *
+ * Will call the registered callback function if necessary.
+ *
+ * @param[in] msg - The payload of the propertiesChanged signal
+ */
+ void hostStateChanged(sdbusplus::message::message& msg)
+ {
+ std::string interface;
+ std::map<std::string, std::variant<std::string>> properties;
+ std::vector<HostState> hostPowerStates;
+
+ msg.read(interface, properties);
+
+ auto hostStateProp = properties.find(_hostStateProperty);
+ if (hostStateProp != properties.end())
+ {
+ auto currentHostState =
+ sdbusplus::message::convert_from_string<HostState>(
+ std::get<std::string>(hostStateProp->second));
+
+ if (!currentHostState)
+ {
+ throw sdbusplus::exception::InvalidEnumString();
+ }
+ HostState hostState = *currentHostState;
+
+ hostPowerStates.emplace_back(hostState);
+ setHostPowerState(hostPowerStates);
+ }
+ }
+
+ private:
+ void setHostPowerState(std::vector<HostState>& hostPowerStates)
+ {
+ bool powerStateflag = false;
+ for (const auto& powerState : hostPowerStates)
+ {
+ if (powerState == HostState::Standby ||
+ powerState == HostState::Running ||
+ powerState == HostState::TransitioningToRunning ||
+ powerState == HostState::Quiesced ||
+ powerState == HostState::DiagnosticMode)
+ {
+ powerStateflag = true;
+ break;
+ }
+ }
+ setPowerState(powerStateflag);
+ }
+
+ /**
+ * @brief Reads the CurrentHostState property from D-Bus and saves it.
+ */
+ void readHostState()
+ {
+
+ std::string hostStatePath;
+ std::string hostStateService;
+ std::string hostService = "xyz.openbmc_project.State.Host";
+ std::vector<HostState> hostPowerStates;
+
+ int32_t depth = 0;
+ const std::string path = "/";
+
+ auto mapperResponse = util::SDBusPlus::getSubTreeRaw(
+ _bus, path, _hostStateInterface, depth);
+
+ for (const auto& path : mapperResponse)
+ {
+ for (const auto& service : path.second)
+ {
+ hostStateService = service.first;
+
+ if (hostStateService.find(hostService) != std::string::npos)
+ {
+ hostStatePath = path.first;
+
+ auto currentHostState =
+ util::SDBusPlus::getProperty<HostState>(
+ hostStateService, hostStatePath,
+ _hostStateInterface, _hostStateProperty);
+
+ hostPowerStates.emplace_back(currentHostState);
+ }
+ }
+ }
+ setHostPowerState(hostPowerStates);
+ }
+
+ const std::string _hostStatePath{"/xyz/openbmc_project/state"};
+
+ /** @brief D-Bus interface constant */
+ const std::string _hostStateInterface{"xyz.openbmc_project.State.Host"};
+
+ /** @brief D-Bus property constant */
+ const std::string _hostStateProperty{"CurrentHostState"};
+
+ /** @brief The propertiesChanged match */
+ sdbusplus::bus::match::match _match;
+};
+
} // namespace phosphor::fan