diff options
Diffstat (limited to 'softoff/softoff.cpp')
-rw-r--r-- | softoff/softoff.cpp | 96 |
1 files changed, 65 insertions, 31 deletions
diff --git a/softoff/softoff.cpp b/softoff/softoff.cpp index 88aa6cf..3511814 100644 --- a/softoff/softoff.cpp +++ b/softoff/softoff.cpp @@ -15,54 +15,70 @@ */ #include <chrono> #include <phosphor-logging/log.hpp> +#include <phosphor-logging/elog.hpp> +#include <xyz/openbmc_project/Control/Host/server.hpp> +#include <utils.hpp> #include "softoff.hpp" +#include "elog-gen-softoff.hpp" #include "config.h" namespace phosphor { namespace ipmi { -// Sends the SMS_ATN to host if value is set -void SoftPowerOff::sendSMSAttn() +using namespace phosphor::logging; +using namespace sdbusplus::xyz::openbmc_project::Control::server; + +void SoftPowerOff::sendHostShutDownCmd() { - using namespace std::chrono; - auto method = bus.new_method_call(HOST_IPMI_BUS, - HOST_IPMI_OBJ, - HOST_IPMI_INTF, - "setAttention"); - - // If there is any exception, would be thrown here. - // BT returns '0' on success and bus_error on failure. - bus.call_noreply(method); - - // Start the timer - auto time = duration_cast<microseconds>( - seconds(IPMI_SMS_ATN_ACK_TIMEOUT_SECS)); - auto r = timer.startTimer(time); - if (r < 0) + std::string ctrlHostPath{CONTROL_HOST_OBJPATH}; + ctrlHostPath += "0"; + auto host = ::ipmi::getService(this->bus, + CONTROL_HOST_BUSNAME, + ctrlHostPath.c_str()); + + auto method = bus.new_method_call(host.c_str(), + ctrlHostPath.c_str(), + CONTROL_HOST_BUSNAME, + "Execute"); + + method.append(convertForMessage(Host::Command::SoftOff).c_str()); + + auto reply = bus.call(method); + if (reply.is_method_error()) { - throw std::runtime_error("Error starting timer"); + log<level::ERR>("Error in call to control host Execute"); + // TODO openbmc/openbmc#851 - Once available, throw returned error + throw std::runtime_error("Error in call to control host Execute"); } + return; } -// Starts a timer -int SoftPowerOff::startTimer(const std::chrono::microseconds& usec) -{ - return timer.startTimer(usec); -} -// Host Response handler -auto SoftPowerOff::responseReceived(HostResponse response) -> HostResponse +// Function called on host control signals +void SoftPowerOff::hostControlEvent(sdbusplus::message::message& msg) { - using namespace std::chrono; - using namespace phosphor::logging; + std::string cmdCompleted{}; + std::string cmdStatus{}; + + msg.read(cmdCompleted, cmdStatus); - if (response == HostResponse::SoftOffReceived) + log<level::DEBUG>("Host control signal values", + entry("COMMAND=%s",cmdCompleted.c_str()), + entry("STATUS=%s",cmdStatus.c_str())); + + if(Host::convertResultFromString(cmdStatus) == Host::Result::Success) { - // Need to stop the running timer and then start a new timer + // Set our internal property indicating we got host attention + sdbusplus::xyz::openbmc_project::Ipmi::Internal + ::server::SoftPowerOff::responseReceived( + HostResponse::SoftOffReceived); + + // Start timer for host shutdown + using namespace std::chrono; auto time = duration_cast<microseconds>( - seconds(IPMI_HOST_SHUTDOWN_COMPLETE_TIMEOUT_SECS)); + seconds(IPMI_HOST_SHUTDOWN_COMPLETE_TIMEOUT_SECS)); auto r = startTimer(time); if (r < 0) { @@ -77,7 +93,25 @@ auto SoftPowerOff::responseReceived(HostResponse response) -> HostResponse (IPMI_HOST_SHUTDOWN_COMPLETE_TIMEOUT_SECS)))); } } - else if (response == HostResponse::HostShutdown) + else + { + elog<xyz::openbmc_project::SoftPowerOff::Internal::SoftOffFailed>(); + } + return; +} + +// Starts a timer +int SoftPowerOff::startTimer(const std::chrono::microseconds& usec) +{ + return timer.startTimer(usec); +} + +// Host Response handler +auto SoftPowerOff::responseReceived(HostResponse response) -> HostResponse +{ + using namespace std::chrono; + + if (response == HostResponse::HostShutdown) { // Disable the timer since Host has quiesced and we are // done with soft power off part |