summaryrefslogtreecommitdiffstats
path: root/softoff
diff options
context:
space:
mode:
Diffstat (limited to 'softoff')
-rw-r--r--softoff/Makefile.am3
-rw-r--r--softoff/elog-gen-softoff.hpp61
-rw-r--r--softoff/softoff.cpp96
-rw-r--r--softoff/softoff.hpp61
4 files changed, 174 insertions, 47 deletions
diff --git a/softoff/Makefile.am b/softoff/Makefile.am
index b7f4c92..cf50cdb 100644
--- a/softoff/Makefile.am
+++ b/softoff/Makefile.am
@@ -8,7 +8,8 @@ phosphor_softpoweroff_SOURCES = \
softoff.cpp \
../timer.cpp \
mainapp.cpp \
- xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/server.cpp
+ xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/server.cpp \
+ ../utils.cpp
BUILT_SOURCES = xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/server.cpp \
xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/server.hpp
diff --git a/softoff/elog-gen-softoff.hpp b/softoff/elog-gen-softoff.hpp
new file mode 100644
index 0000000..e863633
--- /dev/null
+++ b/softoff/elog-gen-softoff.hpp
@@ -0,0 +1,61 @@
+// This file was autogenerated. Do not edit!
+// See elog-gen.py for more details
+#pragma once
+
+#include <string>
+#include <tuple>
+#include <type_traits>
+#include <sdbusplus/exception.hpp>
+#include <phosphor-logging/log.hpp>
+#include <phosphor-logging/elog.hpp>
+
+
+namespace phosphor
+{
+
+namespace logging
+{
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace SoftPowerOff
+{
+namespace Internal
+{
+namespace _SoftOffFailed
+{
+
+} // namespace _SoftOffFailed
+
+struct SoftOffFailed : public sdbusplus::exception_t
+{
+ static constexpr auto errName = "xyz.openbmc_project.SoftPowerOff.Internal.SoftOffFailed";
+ static constexpr auto errDesc = "The SoftOff command to the host control object returned an error";
+ static constexpr auto L = level::ERR;
+ using metadata_types = std::tuple<>;
+
+ const char* name() const noexcept
+ {
+ return errName;
+ }
+
+ const char* description() const noexcept
+ {
+ return errDesc;
+ }
+
+ const char* what() const noexcept
+ {
+ return errName;
+ }
+};
+
+} // namespace Internal
+} // namespace SoftPowerOff
+} // namespace openbmc_project
+} // namespace xyz
+
+} // namespace logging
+} // namespace phosphor
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
diff --git a/softoff/softoff.hpp b/softoff/softoff.hpp
index f0e992c..43bc303 100644
--- a/softoff/softoff.hpp
+++ b/softoff/softoff.hpp
@@ -2,14 +2,20 @@
#include <sdbusplus/bus.hpp>
#include <sdbusplus/server/object.hpp>
+#include <functional>
+#include <xyz/openbmc_project/Control/Host/server.hpp>
#include <xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/server.hpp>
#include "timer.hpp"
+#include "config.h"
namespace phosphor
{
namespace ipmi
{
namespace Base = sdbusplus::xyz::openbmc_project::Ipmi::Internal::server;
+using namespace sdbusplus::xyz::openbmc_project::Control::server;
+
+namespace sdbusRule = sdbusplus::bus::match::rules;
/** @class SoftPowerOff
* @brief Responsible for coordinating Host SoftPowerOff operation
@@ -30,17 +36,27 @@ class SoftPowerOff : public sdbusplus::server::object::object<
sdbusplus::server::object::object<
Base::SoftPowerOff>(bus, objPath, false),
bus(bus),
- timer(event)
+ timer(event),
+ hostControlSignal(
+ bus,
+ sdbusRule::type::signal() +
+ sdbusRule::member("CommandComplete") +
+ sdbusRule::path("/xyz/openbmc_project/control/host0") +
+ sdbusRule::interface(CONTROL_HOST_BUSNAME) +
+ sdbusRule::argN(0,convertForMessage(
+ Host::Command::SoftOff)),
+ std::bind(std::mem_fn(&SoftPowerOff::hostControlEvent),
+ this, std::placeholders::_1))
{
// Need to announce since we may get the response
- // very quickly on SMS_ATN
+ // very quickly on host shutdown command
emit_object_added();
- // The whole purpose of this application is to send SMS_ATTN
- // and watch for the soft power off to go through. We need the
- // interface added signal emitted before we send SMS_ATN just to
- // attend to lightning fast response from host
- sendSMSAttn();
+ // The whole purpose of this application is to send a host shutdown
+ // command and watch for the soft power off to go through. We need
+ // the interface added signal emitted before we send the shutdown
+ // command just to attend to lightning fast response from host
+ sendHostShutDownCmd();
}
/** @brief Tells if the objective of this application is completed */
@@ -94,21 +110,36 @@ class SoftPowerOff : public sdbusplus::server::object::object<
*/
bool completed = false;
- /** @brief Sends SMS_ATN to host to initiate soft power off process.
+ /** @brief Subscribe to host control signals
+ *
+ * Protocol is to send the host power off request to the host
+ * control interface and then wait for a signal indicating pass/fail
+ **/
+ sdbusplus::bus::match_t hostControlSignal;
+
+ /** @brief Sends host control command to tell host to shut down
*
- * After sending the SMS_ATN, starts a timer for 30
- * seconds and expects a initial response from the host.
- * After receiving the initial response, starts another
- * timer for 30 minutes to let host do a clean shutdown of
- * partitions. When the second response is received from the
- * host, it indicates that BMC can do a power off.
+ * After sending the command, wait for a signal indicating the status
+ * of the command.
+ *
+ * After receiving the initial response, start a timer for 30 minutes
+ * to let host do a clean shutdown of partitions. When the response is
+ * received from the host, it indicates that BMC can do a power off.
* If BMC fails to get any response, then a hard power off would
* be forced.
*
* @return - Does not return anything. Error will result in exception
* being thrown
*/
- void sendSMSAttn();
+ void sendHostShutDownCmd();
+
+ /** @brief Callback function on host control signals
+ *
+ * @param[in] msg - Data associated with subscribed signal
+ *
+ */
+ void hostControlEvent(sdbusplus::message::message& msg);
+
};
} // namespace ipmi
} // namespace phosphor
OpenPOWER on IntegriCloud