blob: f0e992c4b753ff215d1c2ffc360ea32e7a369608 [file] [log] [blame]
#pragma once
#include <sdbusplus/bus.hpp>
#include <sdbusplus/server/object.hpp>
#include <xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/server.hpp>
#include "timer.hpp"
namespace phosphor
{
namespace ipmi
{
namespace Base = sdbusplus::xyz::openbmc_project::Ipmi::Internal::server;
/** @class SoftPowerOff
* @brief Responsible for coordinating Host SoftPowerOff operation
*/
class SoftPowerOff : public sdbusplus::server::object::object<
Base::SoftPowerOff>
{
public:
/** @brief Constructs SoftPowerOff object.
*
* @param[in] bus - system dbus handler
* @param[in] event - sd_event handler
* @param[in] objPath - The Dbus path hosting SoftPowerOff function
*/
SoftPowerOff(sdbusplus::bus::bus& bus,
sd_event* event,
const char* objPath) :
sdbusplus::server::object::object<
Base::SoftPowerOff>(bus, objPath, false),
bus(bus),
timer(event)
{
// Need to announce since we may get the response
// very quickly on SMS_ATN
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();
}
/** @brief Tells if the objective of this application is completed */
inline auto isCompleted()
{
return completed;
}
/** @brief Tells if the referenced timer is expired or not */
inline auto isTimerExpired()
{
return timer.isExpired();
}
/** @brief overloaded property setter function
*
* @param[in] value - One of SoftOffReceived / HostShutdown
*
* @return Success or exception thrown
*/
HostResponse responseReceived(HostResponse value) override;
/** @brief Using the base class's getter method */
using Base::SoftPowerOff::responseReceived;
/** @brief Calls to start a timer
*
* @param[in] usec - Time in microseconds
*
* @return Success or exception thrown
*/
int startTimer(const std::chrono::microseconds& usec);
private:
// Need this to send SMS_ATTN
// TODO : Switch over to using mapper service in a different patch
static constexpr auto HOST_IPMI_BUS = "org.openbmc.HostIpmi";
static constexpr auto HOST_IPMI_OBJ = "/org/openbmc/HostIpmi/1";
static constexpr auto HOST_IPMI_INTF = "org.openbmc.HostIpmi";
/* @brief sdbusplus handle */
sdbusplus::bus::bus& bus;
/** @brief Reference to Timer object */
Timer timer;
/** @brief Marks the end of life of this application.
*
* This is set to true if host gives appropriate responses
* for the sequence of commands.
*/
bool completed = false;
/** @brief Sends SMS_ATN to host to initiate soft power off process.
*
* 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.
* 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();
};
} // namespace ipmi
} // namespace phosphor