| #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)) | 
 | {} | 
 |  | 
 | sdbusplus::async::task<bool> HostPower::setState(sdbusplus::async::context& ctx, | 
 |                                                  HostState state) | 
 | { | 
 |     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; | 
 | } | 
 |  | 
 | sdbusplus::async::task<HostState> HostPower::getState( | 
 |     sdbusplus::async::context& ctx) | 
 | { | 
 |     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 |