blob: f76affb80f6e87c382ff3b516ecc424e7c52a42d [file] [log] [blame]
Alexander Hansen1e833b42025-03-04 10:20:33 +01001#include "host_power.hpp"
2
3#include <phosphor-logging/lg2.hpp>
4#include <sdbusplus/async.hpp>
5#include <sdbusplus/async/context.hpp>
6#include <sdbusplus/async/match.hpp>
7#include <sdbusplus/async/proxy.hpp>
8#include <sdbusplus/bus/match.hpp>
9#include <sdbusplus/message/native_types.hpp>
10#include <xyz/openbmc_project/ObjectMapper/client.hpp>
11#include <xyz/openbmc_project/State/Host/client.hpp>
12
13PHOSPHOR_LOG2_USING;
14
15using namespace std::literals;
16
17namespace RulesIntf = sdbusplus::bus::match::rules;
18
19using StateIntf =
20 sdbusplus::client::xyz::openbmc_project::state::Host<void, void>;
21
22const auto transitionOn =
23 sdbusplus::client::xyz::openbmc_project::state::Host<>::Transition::On;
24const auto transitionOff =
25 sdbusplus::client::xyz::openbmc_project::state::Host<>::Transition::Off;
26
27namespace phosphor::software::host_power
28{
29
Alexander Hansen8e44d572025-03-17 11:06:18 +010030const auto host0ObjectPath = sdbusplus::client::xyz::openbmc_project::state::
31 Host<>::namespace_path::value +
32 std::string("/host0");
33
Alexander Hansen1e833b42025-03-04 10:20:33 +010034constexpr const char* service = "xyz.openbmc_project.State.Host";
35
36HostPower::HostPower(sdbusplus::async::context& ctx) :
37 stateChangedMatch(ctx, RulesIntf::propertiesChanged(host0ObjectPath,
38 StateIntf::interface))
39{}
40
41// NOLINTBEGIN(readability-static-accessed-through-instance)
42sdbusplus::async::task<bool> HostPower::setState(sdbusplus::async::context& ctx,
43 HostState state)
44// NOLINTEND(readability-static-accessed-through-instance)
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 retries = 4;
62 constexpr size_t retryTimeout = 3;
63
64 for (size_t i = 0; i < retries; i++)
65 {
66 co_await sdbusplus::async::sleep_for(
67 ctx, std::chrono::seconds(retryTimeout));
68
69 if ((co_await client.current_host_state()) == state)
70 {
71 debug("Successfully achieved state {STATE}", "STATE", state);
72 co_return true;
73 }
74 }
75
76 error("Failed to achieve state {STATE} before the timeout of {TIMEOUT}s",
77 "STATE", state, "TIMEOUT", retries * retryTimeout);
78
79 co_return false;
80}
81
82// NOLINTBEGIN(readability-static-accessed-through-instance)
83sdbusplus::async::task<HostState> HostPower::getState(
84 sdbusplus::async::context& ctx)
85// NOLINTEND(readability-static-accessed-through-instance)
86{
87 auto client = sdbusplus::client::xyz::openbmc_project::state::Host(ctx)
88 .service(service)
89 .path(host0ObjectPath);
90
91 auto res = co_await client.current_host_state();
92
93 if (res != stateOn && res != stateOff)
94 {
95 error("Unexpected power state: {STATE}", "STATE", res);
96 }
97
98 co_return res;
99}
100
101} // namespace phosphor::software::host_power