blob: eba4ae8cddeda4d21df48aafdbd6a21615733bdf [file] [log] [blame]
Alexander Hansen1e833b42025-03-04 10:20:33 +01001#include "host_power.hpp"
2
Kevin Tung0d1c20b2025-09-22 10:08:18 +08003#include "common_config.h"
4
Alexander Hansen1e833b42025-03-04 10:20:33 +01005#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
15PHOSPHOR_LOG2_USING;
16
17using namespace std::literals;
18
19namespace RulesIntf = sdbusplus::bus::match::rules;
20
21using StateIntf =
22 sdbusplus::client::xyz::openbmc_project::state::Host<void, void>;
23
24const auto transitionOn =
25 sdbusplus::client::xyz::openbmc_project::state::Host<>::Transition::On;
26const auto transitionOff =
27 sdbusplus::client::xyz::openbmc_project::state::Host<>::Transition::Off;
28
29namespace phosphor::software::host_power
30{
31
Alexander Hansen8e44d572025-03-17 11:06:18 +010032const auto host0ObjectPath = sdbusplus::client::xyz::openbmc_project::state::
33 Host<>::namespace_path::value +
34 std::string("/host0");
35
Alexander Hansen1e833b42025-03-04 10:20:33 +010036constexpr const char* service = "xyz.openbmc_project.State.Host";
37
38HostPower::HostPower(sdbusplus::async::context& ctx) :
39 stateChangedMatch(ctx, RulesIntf::propertiesChanged(host0ObjectPath,
40 StateIntf::interface))
41{}
42
Alexander Hansen1e833b42025-03-04 10:20:33 +010043sdbusplus::async::task<bool> HostPower::setState(sdbusplus::async::context& ctx,
44 HostState state)
Alexander Hansen1e833b42025-03-04 10:20:33 +010045{
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
Kevin Tung0d1c20b2025-09-22 10:08:18 +080061 constexpr size_t transitionTimeout = HOST_STATE_TRANSITION_TIMEOUT;
Alexander Hansen1e833b42025-03-04 10:20:33 +010062
Kevin Tung0d1c20b2025-09-22 10:08:18 +080063 for (size_t i = 0; i < transitionTimeout; i++)
Alexander Hansen1e833b42025-03-04 10:20:33 +010064 {
Kevin Tung0d1c20b2025-09-22 10:08:18 +080065 co_await sdbusplus::async::sleep_for(ctx, std::chrono::seconds(1));
Alexander Hansen1e833b42025-03-04 10:20:33 +010066
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",
Kevin Tung0d1c20b2025-09-22 10:08:18 +080075 "STATE", state, "TIMEOUT", transitionTimeout);
Alexander Hansen1e833b42025-03-04 10:20:33 +010076
77 co_return false;
78}
79
Alexander Hansen1e833b42025-03-04 10:20:33 +010080sdbusplus::async::task<HostState> HostPower::getState(
81 sdbusplus::async::context& ctx)
Alexander Hansen1e833b42025-03-04 10:20:33 +010082{
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