11e833b44SAlexander Hansen #include "host_power.hpp"
21e833b44SAlexander Hansen
3*0d1c20b0SKevin Tung #include "common_config.h"
4*0d1c20b0SKevin Tung
51e833b44SAlexander Hansen #include <phosphor-logging/lg2.hpp>
61e833b44SAlexander Hansen #include <sdbusplus/async.hpp>
71e833b44SAlexander Hansen #include <sdbusplus/async/context.hpp>
81e833b44SAlexander Hansen #include <sdbusplus/async/match.hpp>
91e833b44SAlexander Hansen #include <sdbusplus/async/proxy.hpp>
101e833b44SAlexander Hansen #include <sdbusplus/bus/match.hpp>
111e833b44SAlexander Hansen #include <sdbusplus/message/native_types.hpp>
121e833b44SAlexander Hansen #include <xyz/openbmc_project/ObjectMapper/client.hpp>
131e833b44SAlexander Hansen #include <xyz/openbmc_project/State/Host/client.hpp>
141e833b44SAlexander Hansen
151e833b44SAlexander Hansen PHOSPHOR_LOG2_USING;
161e833b44SAlexander Hansen
171e833b44SAlexander Hansen using namespace std::literals;
181e833b44SAlexander Hansen
191e833b44SAlexander Hansen namespace RulesIntf = sdbusplus::bus::match::rules;
201e833b44SAlexander Hansen
211e833b44SAlexander Hansen using StateIntf =
221e833b44SAlexander Hansen sdbusplus::client::xyz::openbmc_project::state::Host<void, void>;
231e833b44SAlexander Hansen
241e833b44SAlexander Hansen const auto transitionOn =
251e833b44SAlexander Hansen sdbusplus::client::xyz::openbmc_project::state::Host<>::Transition::On;
261e833b44SAlexander Hansen const auto transitionOff =
271e833b44SAlexander Hansen sdbusplus::client::xyz::openbmc_project::state::Host<>::Transition::Off;
281e833b44SAlexander Hansen
291e833b44SAlexander Hansen namespace phosphor::software::host_power
301e833b44SAlexander Hansen {
311e833b44SAlexander Hansen
328e44d578SAlexander Hansen const auto host0ObjectPath = sdbusplus::client::xyz::openbmc_project::state::
338e44d578SAlexander Hansen Host<>::namespace_path::value +
348e44d578SAlexander Hansen std::string("/host0");
358e44d578SAlexander Hansen
361e833b44SAlexander Hansen constexpr const char* service = "xyz.openbmc_project.State.Host";
371e833b44SAlexander Hansen
HostPower(sdbusplus::async::context & ctx)381e833b44SAlexander Hansen HostPower::HostPower(sdbusplus::async::context& ctx) :
391e833b44SAlexander Hansen stateChangedMatch(ctx, RulesIntf::propertiesChanged(host0ObjectPath,
401e833b44SAlexander Hansen StateIntf::interface))
411e833b44SAlexander Hansen {}
421e833b44SAlexander Hansen
setState(sdbusplus::async::context & ctx,HostState state)431e833b44SAlexander Hansen sdbusplus::async::task<bool> HostPower::setState(sdbusplus::async::context& ctx,
441e833b44SAlexander Hansen HostState state)
451e833b44SAlexander Hansen {
461e833b44SAlexander Hansen if (state != stateOn && state != stateOff)
471e833b44SAlexander Hansen {
481e833b44SAlexander Hansen error("Invalid power state {STATE}", "STATE", state);
491e833b44SAlexander Hansen co_return false;
501e833b44SAlexander Hansen }
511e833b44SAlexander Hansen
521e833b44SAlexander Hansen auto client = sdbusplus::client::xyz::openbmc_project::state::Host(ctx)
531e833b44SAlexander Hansen .service(service)
541e833b44SAlexander Hansen .path(host0ObjectPath);
551e833b44SAlexander Hansen
561e833b44SAlexander Hansen co_await client.requested_host_transition(
571e833b44SAlexander Hansen (state == stateOn) ? transitionOn : transitionOff);
581e833b44SAlexander Hansen
591e833b44SAlexander Hansen debug("Requested host transition to {STATE}", "STATE", state);
601e833b44SAlexander Hansen
61*0d1c20b0SKevin Tung constexpr size_t transitionTimeout = HOST_STATE_TRANSITION_TIMEOUT;
621e833b44SAlexander Hansen
63*0d1c20b0SKevin Tung for (size_t i = 0; i < transitionTimeout; i++)
641e833b44SAlexander Hansen {
65*0d1c20b0SKevin Tung co_await sdbusplus::async::sleep_for(ctx, std::chrono::seconds(1));
661e833b44SAlexander Hansen
671e833b44SAlexander Hansen if ((co_await client.current_host_state()) == state)
681e833b44SAlexander Hansen {
691e833b44SAlexander Hansen debug("Successfully achieved state {STATE}", "STATE", state);
701e833b44SAlexander Hansen co_return true;
711e833b44SAlexander Hansen }
721e833b44SAlexander Hansen }
731e833b44SAlexander Hansen
741e833b44SAlexander Hansen error("Failed to achieve state {STATE} before the timeout of {TIMEOUT}s",
75*0d1c20b0SKevin Tung "STATE", state, "TIMEOUT", transitionTimeout);
761e833b44SAlexander Hansen
771e833b44SAlexander Hansen co_return false;
781e833b44SAlexander Hansen }
791e833b44SAlexander Hansen
getState(sdbusplus::async::context & ctx)801e833b44SAlexander Hansen sdbusplus::async::task<HostState> HostPower::getState(
811e833b44SAlexander Hansen sdbusplus::async::context& ctx)
821e833b44SAlexander Hansen {
831e833b44SAlexander Hansen auto client = sdbusplus::client::xyz::openbmc_project::state::Host(ctx)
841e833b44SAlexander Hansen .service(service)
851e833b44SAlexander Hansen .path(host0ObjectPath);
861e833b44SAlexander Hansen
871e833b44SAlexander Hansen auto res = co_await client.current_host_state();
881e833b44SAlexander Hansen
891e833b44SAlexander Hansen if (res != stateOn && res != stateOff)
901e833b44SAlexander Hansen {
911e833b44SAlexander Hansen error("Unexpected power state: {STATE}", "STATE", res);
921e833b44SAlexander Hansen }
931e833b44SAlexander Hansen
941e833b44SAlexander Hansen co_return res;
951e833b44SAlexander Hansen }
961e833b44SAlexander Hansen
971e833b44SAlexander Hansen } // namespace phosphor::software::host_power
98