#include #include #include #include #include #include #include #include #include "chassis_state_manager.hpp" #include "host_state_manager.hpp" #include "settings.hpp" #include "xyz/openbmc_project/Common/error.hpp" #include "xyz/openbmc_project/Control/Power/RestorePolicy/server.hpp" namespace phosphor { namespace state { namespace manager { using namespace phosphor::logging; using namespace sdbusplus::xyz::openbmc_project::Common::Error; using namespace sdbusplus::xyz::openbmc_project::Control::Power::server; constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper"; constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper"; constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper"; constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties"; constexpr auto HOST_PATH = "/xyz/openbmc_project/state/host0"; constexpr auto CHASSIS_PATH = "/xyz/openbmc_project/state/chassis0"; std::string getService(sdbusplus::bus::bus& bus, std::string path, std::string interface) { auto mapper = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH, MAPPER_INTERFACE, "GetObject"); mapper.append(path, std::vector({interface})); auto mapperResponseMsg = bus.call(mapper); if (mapperResponseMsg.is_method_error()) { log("Error in mapper call", entry("PATH=%s", path.c_str()), entry("INTERFACE=%s", interface.c_str())); throw std::runtime_error("Error in mapper call"); } std::map> mapperResponse; mapperResponseMsg.read(mapperResponse); if (mapperResponse.empty()) { log("Error reading mapper response", entry("PATH=%s", path.c_str()), entry("INTERFACE=%s", interface.c_str())); throw std::runtime_error("Error reading mapper response"); } return mapperResponse.begin()->first; } std::string getProperty(sdbusplus::bus::bus& bus, std::string path, std::string interface, std::string propertyName) { sdbusplus::message::variant property; std::string service = getService(bus, path, interface); auto method = bus.new_method_call(service.c_str(), path.c_str(), PROPERTY_INTERFACE, "Get"); method.append(interface, propertyName); auto reply = bus.call(method); if (reply.is_method_error()) { log("Error in property Get", entry("PROPERTY=%s", propertyName.c_str())); throw std::runtime_error("Error in property Get"); } reply.read(property); if (sdbusplus::message::variant_ns::get(property).empty()) { log("Error reading property response", entry("PROPERTY=%s", propertyName.c_str())); throw std::runtime_error("Error reading property response"); } return sdbusplus::message::variant_ns::get(property); } void setProperty(sdbusplus::bus::bus& bus, std::string path, std::string interface, std::string property, std::string value) { sdbusplus::message::variant variantValue = value; std::string service = getService(bus, path, interface); auto method = bus.new_method_call(service.c_str(), path.c_str(), PROPERTY_INTERFACE, "Set"); method.append(interface, property, variantValue); bus.call_noreply(method); return; } } // namespace manager } // namespace state } // namepsace phosphor int main() { using namespace phosphor::logging; auto bus = sdbusplus::bus::new_default(); using namespace settings; Objects settings(bus); using namespace phosphor::state::manager; namespace server = sdbusplus::xyz::openbmc_project::State::server; std::string currentPowerState = getProperty(bus, CHASSIS_PATH, CHASSIS_BUSNAME, "CurrentPowerState"); if(currentPowerState == convertForMessage(server::Chassis::PowerState::Off)) { auto method = bus.new_method_call( settings.service(settings.powerRestorePolicy, powerRestoreIntf).c_str(), settings.powerRestorePolicy.c_str(), "org.freedesktop.DBus.Properties", "Get"); method.append(powerRestoreIntf, "PowerRestorePolicy"); auto reply = bus.call(method); if (reply.is_method_error()) { log("Error in PowerRestorePolicy Get"); elog(); } sdbusplus::message::variant result; reply.read(result); auto powerPolicy = result.get(); log("Host power is off, checking power policy", entry("POWER_POLICY=%s", powerPolicy.c_str())); if (RestorePolicy::Policy::AlwaysOn == RestorePolicy::convertPolicyFromString(powerPolicy)) { log("power_policy=ALWAYS_POWER_ON, powering host on"); setProperty(bus, HOST_PATH, HOST_BUSNAME, "RequestedHostTransition", convertForMessage(server::Host::Transition::On)); } } return 0; }