blob: 9b5d5d2c9f0322f10290ddfca732cf6f07d9d220 [file] [log] [blame]
Brandon Kim15fe1692021-03-08 21:29:39 -08001// Copyright 2021 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15/*
16 * Based off of sdbusplus:/example/calculator-server.cpp
17 */
18#include <sdbusplus/bus.hpp>
19#include <sdbusplus/server.hpp>
20#include <xyz/openbmc_project/Control/Power/ACPIPowerState/server.hpp>
21
22#include <exception>
23#include <iostream>
24#include <optional>
25#include <string>
26
27constexpr auto hostS5Unit = "host-s5-state.target";
28constexpr auto hostS0Unit = "host-s0-state.target";
29
30constexpr auto systemdBusName = "org.freedesktop.systemd1";
31constexpr auto systemdPath = "/org/freedesktop/systemd1";
32constexpr auto systemdInterface = "org.freedesktop.systemd1.Manager";
33
34constexpr auto acpiObjPath =
35 "/xyz/openbmc_project/control/host0/acpi_power_state";
36constexpr auto acpiInterface =
37 "xyz.openbmc_project.Control.Power.ACPIPowerState";
38
39using ACPIPowerStateInherit = sdbusplus::server::object_t<
40 sdbusplus::xyz::openbmc_project::Control::Power::server::ACPIPowerState>;
41
42// Pulled and modified from arcadia-leds/poll_gpio.cpp
43static void startSystemdUnit(sdbusplus::bus::bus& bus, const std::string& unit)
44{
45 auto method = bus.new_method_call(systemdBusName, systemdPath,
46 systemdInterface, "StartUnit");
47 method.append(unit, "replace");
48 bus.call(method);
49}
50
51struct ACPIPowerState : ACPIPowerStateInherit
52{
53 // Keep track of the bus for starting/stopping systemd units
54 sdbusplus::bus::bus& Bus;
55
56 ACPIPowerState(sdbusplus::bus::bus& bus, const char* path) :
57 ACPIPowerStateInherit(bus, path), Bus(bus)
58 {}
59
60 ACPI sysACPIStatus(ACPI value)
61 {
62 std::cout << "State change "
63 << ACPIPowerStateInherit::convertACPIToString(value)
64 << std::endl;
65
66 switch (value)
67 {
68 case ACPI::S5_G2:
69 std::cout << "Entered S5" << std::endl;
70 startSystemdUnit(Bus, hostS5Unit);
71 break;
72 case ACPI::S0_G0_D0:
73 std::cout << "Entered S0" << std::endl;
74 startSystemdUnit(Bus, hostS0Unit);
75 break;
76 default:
77 break;
78 }
79
80 return ACPIPowerStateInherit::sysACPIStatus(value);
81 }
82};
83
84int main()
85{
86
87 auto b = sdbusplus::bus::new_default();
88 sdbusplus::server::manager_t m{b, acpiObjPath};
89
90 // Reserve the dbus service for ACPI Power state changes coming from the
91 // BIOS
92 b.request_name(acpiInterface);
93
94 ACPIPowerState aps{b, acpiObjPath};
95
96 // Handle dbus processing forever.
97 for (;;)
98 {
99 b.process_discard(); // discard any unhandled messages
100 b.wait();
101 }
102
103 return 1;
104}