11285115cSWilliam A. Kennington III // Copyright 2021 Google LLC
21285115cSWilliam A. Kennington III //
31285115cSWilliam A. Kennington III // Licensed under the Apache License, Version 2.0 (the "License");
41285115cSWilliam A. Kennington III // you may not use this file except in compliance with the License.
51285115cSWilliam A. Kennington III // You may obtain a copy of the License at
61285115cSWilliam A. Kennington III //
71285115cSWilliam A. Kennington III //      http://www.apache.org/licenses/LICENSE-2.0
81285115cSWilliam A. Kennington III //
91285115cSWilliam A. Kennington III // Unless required by applicable law or agreed to in writing, software
101285115cSWilliam A. Kennington III // distributed under the License is distributed on an "AS IS" BASIS,
111285115cSWilliam A. Kennington III // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121285115cSWilliam A. Kennington III // See the License for the specific language governing permissions and
131285115cSWilliam A. Kennington III // limitations under the License.
141285115cSWilliam A. Kennington III 
151285115cSWilliam A. Kennington III /*
161285115cSWilliam A. Kennington III  * Based off of sdbusplus:/example/calculator-server.cpp
171285115cSWilliam A. Kennington III  */
181285115cSWilliam A. Kennington III #include <sdbusplus/bus.hpp>
191285115cSWilliam A. Kennington III #include <sdbusplus/server.hpp>
201285115cSWilliam A. Kennington III #include <xyz/openbmc_project/Control/Power/ACPIPowerState/server.hpp>
211285115cSWilliam A. Kennington III 
221285115cSWilliam A. Kennington III #include <exception>
231285115cSWilliam A. Kennington III #include <iostream>
241285115cSWilliam A. Kennington III #include <optional>
251285115cSWilliam A. Kennington III #include <string>
261285115cSWilliam A. Kennington III 
271285115cSWilliam A. Kennington III constexpr auto hostS5Unit = "host-s5-state.target";
281285115cSWilliam A. Kennington III constexpr auto hostS0Unit = "host-s0-state.target";
291285115cSWilliam A. Kennington III 
301285115cSWilliam A. Kennington III constexpr auto systemdBusName = "org.freedesktop.systemd1";
311285115cSWilliam A. Kennington III constexpr auto systemdPath = "/org/freedesktop/systemd1";
321285115cSWilliam A. Kennington III constexpr auto systemdInterface = "org.freedesktop.systemd1.Manager";
331285115cSWilliam A. Kennington III 
341285115cSWilliam A. Kennington III constexpr auto acpiObjPath =
351285115cSWilliam A. Kennington III     "/xyz/openbmc_project/control/host0/acpi_power_state";
361285115cSWilliam A. Kennington III constexpr auto acpiInterface =
371285115cSWilliam A. Kennington III     "xyz.openbmc_project.Control.Power.ACPIPowerState";
381285115cSWilliam A. Kennington III 
391285115cSWilliam A. Kennington III using ACPIPowerStateInherit = sdbusplus::server::object_t<
401285115cSWilliam A. Kennington III     sdbusplus::xyz::openbmc_project::Control::Power::server::ACPIPowerState>;
411285115cSWilliam A. Kennington III 
421285115cSWilliam A. Kennington III // Pulled and modified from arcadia-leds/poll_gpio.cpp
startSystemdUnit(sdbusplus::bus_t & bus,const std::string & unit)43*59ac2c2dSPatrick Williams static void startSystemdUnit(sdbusplus::bus_t& bus, const std::string& unit)
441285115cSWilliam A. Kennington III {
451285115cSWilliam A. Kennington III     auto method = bus.new_method_call(systemdBusName, systemdPath,
461285115cSWilliam A. Kennington III                                       systemdInterface, "StartUnit");
471285115cSWilliam A. Kennington III     method.append(unit, "replace");
481285115cSWilliam A. Kennington III     bus.call(method);
491285115cSWilliam A. Kennington III }
501285115cSWilliam A. Kennington III 
511285115cSWilliam A. Kennington III struct ACPIPowerState : ACPIPowerStateInherit
521285115cSWilliam A. Kennington III {
531285115cSWilliam A. Kennington III     // Keep track of the bus for starting/stopping systemd units
54*59ac2c2dSPatrick Williams     sdbusplus::bus_t& Bus;
551285115cSWilliam A. Kennington III 
ACPIPowerStateACPIPowerState56*59ac2c2dSPatrick Williams     ACPIPowerState(sdbusplus::bus_t& bus, const char* path) :
571285115cSWilliam A. Kennington III         ACPIPowerStateInherit(bus, path), Bus(bus)
581285115cSWilliam A. Kennington III     {}
591285115cSWilliam A. Kennington III 
sysACPIStatusACPIPowerState601285115cSWilliam A. Kennington III     ACPI sysACPIStatus(ACPI value)
611285115cSWilliam A. Kennington III     {
621285115cSWilliam A. Kennington III         std::cout << "State change "
631285115cSWilliam A. Kennington III                   << ACPIPowerStateInherit::convertACPIToString(value)
641285115cSWilliam A. Kennington III                   << std::endl;
651285115cSWilliam A. Kennington III 
661285115cSWilliam A. Kennington III         switch (value)
671285115cSWilliam A. Kennington III         {
681285115cSWilliam A. Kennington III             case ACPI::S5_G2:
691285115cSWilliam A. Kennington III                 std::cout << "Entered S5" << std::endl;
701285115cSWilliam A. Kennington III                 startSystemdUnit(Bus, hostS5Unit);
711285115cSWilliam A. Kennington III                 break;
721285115cSWilliam A. Kennington III             case ACPI::S0_G0_D0:
731285115cSWilliam A. Kennington III                 std::cout << "Entered S0" << std::endl;
741285115cSWilliam A. Kennington III                 startSystemdUnit(Bus, hostS0Unit);
751285115cSWilliam A. Kennington III                 break;
761285115cSWilliam A. Kennington III             default:
771285115cSWilliam A. Kennington III                 break;
781285115cSWilliam A. Kennington III         }
791285115cSWilliam A. Kennington III 
801285115cSWilliam A. Kennington III         return ACPIPowerStateInherit::sysACPIStatus(value);
811285115cSWilliam A. Kennington III     }
821285115cSWilliam A. Kennington III };
831285115cSWilliam A. Kennington III 
main()841285115cSWilliam A. Kennington III int main()
851285115cSWilliam A. Kennington III {
861285115cSWilliam A. Kennington III     auto b = sdbusplus::bus::new_default();
871285115cSWilliam A. Kennington III     sdbusplus::server::manager_t m{b, acpiObjPath};
881285115cSWilliam A. Kennington III 
891285115cSWilliam A. Kennington III     // Reserve the dbus service for ACPI Power state changes coming from the
901285115cSWilliam A. Kennington III     // BIOS
911285115cSWilliam A. Kennington III     b.request_name(acpiInterface);
921285115cSWilliam A. Kennington III 
931285115cSWilliam A. Kennington III     ACPIPowerState aps{b, acpiObjPath};
941285115cSWilliam A. Kennington III 
951285115cSWilliam A. Kennington III     // Handle dbus processing forever.
961285115cSWilliam A. Kennington III     for (;;)
971285115cSWilliam A. Kennington III     {
981285115cSWilliam A. Kennington III         b.process_discard(); // discard any unhandled messages
991285115cSWilliam A. Kennington III         b.wait();
1001285115cSWilliam A. Kennington III     }
1011285115cSWilliam A. Kennington III 
1021285115cSWilliam A. Kennington III     return 1;
1031285115cSWilliam A. Kennington III }
104