blob: f76affb80f6e87c382ff3b516ecc424e7c52a42d [file] [log] [blame]
#include "host_power.hpp"
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/async.hpp>
#include <sdbusplus/async/context.hpp>
#include <sdbusplus/async/match.hpp>
#include <sdbusplus/async/proxy.hpp>
#include <sdbusplus/bus/match.hpp>
#include <sdbusplus/message/native_types.hpp>
#include <xyz/openbmc_project/ObjectMapper/client.hpp>
#include <xyz/openbmc_project/State/Host/client.hpp>
PHOSPHOR_LOG2_USING;
using namespace std::literals;
namespace RulesIntf = sdbusplus::bus::match::rules;
using StateIntf =
sdbusplus::client::xyz::openbmc_project::state::Host<void, void>;
const auto transitionOn =
sdbusplus::client::xyz::openbmc_project::state::Host<>::Transition::On;
const auto transitionOff =
sdbusplus::client::xyz::openbmc_project::state::Host<>::Transition::Off;
namespace phosphor::software::host_power
{
const auto host0ObjectPath = sdbusplus::client::xyz::openbmc_project::state::
Host<>::namespace_path::value +
std::string("/host0");
constexpr const char* service = "xyz.openbmc_project.State.Host";
HostPower::HostPower(sdbusplus::async::context& ctx) :
stateChangedMatch(ctx, RulesIntf::propertiesChanged(host0ObjectPath,
StateIntf::interface))
{}
// NOLINTBEGIN(readability-static-accessed-through-instance)
sdbusplus::async::task<bool> HostPower::setState(sdbusplus::async::context& ctx,
HostState state)
// NOLINTEND(readability-static-accessed-through-instance)
{
if (state != stateOn && state != stateOff)
{
error("Invalid power state {STATE}", "STATE", state);
co_return false;
}
auto client = sdbusplus::client::xyz::openbmc_project::state::Host(ctx)
.service(service)
.path(host0ObjectPath);
co_await client.requested_host_transition(
(state == stateOn) ? transitionOn : transitionOff);
debug("Requested host transition to {STATE}", "STATE", state);
constexpr size_t retries = 4;
constexpr size_t retryTimeout = 3;
for (size_t i = 0; i < retries; i++)
{
co_await sdbusplus::async::sleep_for(
ctx, std::chrono::seconds(retryTimeout));
if ((co_await client.current_host_state()) == state)
{
debug("Successfully achieved state {STATE}", "STATE", state);
co_return true;
}
}
error("Failed to achieve state {STATE} before the timeout of {TIMEOUT}s",
"STATE", state, "TIMEOUT", retries * retryTimeout);
co_return false;
}
// NOLINTBEGIN(readability-static-accessed-through-instance)
sdbusplus::async::task<HostState> HostPower::getState(
sdbusplus::async::context& ctx)
// NOLINTEND(readability-static-accessed-through-instance)
{
auto client = sdbusplus::client::xyz::openbmc_project::state::Host(ctx)
.service(service)
.path(host0ObjectPath);
auto res = co_await client.current_host_state();
if (res != stateOn && res != stateOff)
{
error("Unexpected power state: {STATE}", "STATE", res);
}
co_return res;
}
} // namespace phosphor::software::host_power