1 #include "host_power.hpp" 2 3 #include "common_config.h" 4 5 #include <phosphor-logging/lg2.hpp> 6 #include <sdbusplus/async.hpp> 7 #include <sdbusplus/async/context.hpp> 8 #include <sdbusplus/async/match.hpp> 9 #include <sdbusplus/async/proxy.hpp> 10 #include <sdbusplus/bus/match.hpp> 11 #include <sdbusplus/message/native_types.hpp> 12 #include <xyz/openbmc_project/ObjectMapper/client.hpp> 13 #include <xyz/openbmc_project/State/Host/client.hpp> 14 15 PHOSPHOR_LOG2_USING; 16 17 using namespace std::literals; 18 19 namespace RulesIntf = sdbusplus::bus::match::rules; 20 21 using StateIntf = 22 sdbusplus::client::xyz::openbmc_project::state::Host<void, void>; 23 24 const auto transitionOn = 25 sdbusplus::client::xyz::openbmc_project::state::Host<>::Transition::On; 26 const auto transitionOff = 27 sdbusplus::client::xyz::openbmc_project::state::Host<>::Transition::Off; 28 29 namespace phosphor::software::host_power 30 { 31 32 const auto host0ObjectPath = sdbusplus::client::xyz::openbmc_project::state:: 33 Host<>::namespace_path::value + 34 std::string("/host0"); 35 36 constexpr const char* service = "xyz.openbmc_project.State.Host"; 37 38 HostPower::HostPower(sdbusplus::async::context& ctx) : 39 stateChangedMatch(ctx, RulesIntf::propertiesChanged(host0ObjectPath, 40 StateIntf::interface)) 41 {} 42 43 sdbusplus::async::task<bool> HostPower::setState(sdbusplus::async::context& ctx, 44 HostState state) 45 { 46 if (state != stateOn && state != stateOff) 47 { 48 error("Invalid power state {STATE}", "STATE", state); 49 co_return false; 50 } 51 52 auto client = sdbusplus::client::xyz::openbmc_project::state::Host(ctx) 53 .service(service) 54 .path(host0ObjectPath); 55 56 co_await client.requested_host_transition( 57 (state == stateOn) ? transitionOn : transitionOff); 58 59 debug("Requested host transition to {STATE}", "STATE", state); 60 61 constexpr size_t transitionTimeout = HOST_STATE_TRANSITION_TIMEOUT; 62 63 for (size_t i = 0; i < transitionTimeout; i++) 64 { 65 co_await sdbusplus::async::sleep_for(ctx, std::chrono::seconds(1)); 66 67 if ((co_await client.current_host_state()) == state) 68 { 69 debug("Successfully achieved state {STATE}", "STATE", state); 70 co_return true; 71 } 72 } 73 74 error("Failed to achieve state {STATE} before the timeout of {TIMEOUT}s", 75 "STATE", state, "TIMEOUT", transitionTimeout); 76 77 co_return false; 78 } 79 80 sdbusplus::async::task<HostState> HostPower::getState( 81 sdbusplus::async::context& ctx) 82 { 83 auto client = sdbusplus::client::xyz::openbmc_project::state::Host(ctx) 84 .service(service) 85 .path(host0ObjectPath); 86 87 auto res = co_await client.current_host_state(); 88 89 if (res != stateOn && res != stateOff) 90 { 91 error("Unexpected power state: {STATE}", "STATE", res); 92 } 93 94 co_return res; 95 } 96 97 } // namespace phosphor::software::host_power 98