1 #pragma once 2 3 #include "config.h" 4 5 #include <functional> 6 #include <sdbusplus/bus.hpp> 7 #include <sdbusplus/server/object.hpp> 8 #include <sdbusplus/timer.hpp> 9 #include <xyz/openbmc_project/Control/Host/server.hpp> 10 #include <xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/server.hpp> 11 namespace phosphor 12 { 13 namespace ipmi 14 { 15 16 namespace Base = sdbusplus::xyz::openbmc_project::Ipmi::Internal::server; 17 using namespace sdbusplus::xyz::openbmc_project::Control::server; 18 19 namespace sdbusRule = sdbusplus::bus::match::rules; 20 21 /** @class SoftPowerOff 22 * @brief Responsible for coordinating Host SoftPowerOff operation 23 */ 24 class SoftPowerOff 25 : public sdbusplus::server::object::object<Base::SoftPowerOff> 26 { 27 public: 28 /** @brief Constructs SoftPowerOff object. 29 * 30 * @param[in] bus - system dbus handler 31 * @param[in] event - sd_event handler 32 * @param[in] objPath - The Dbus path hosting SoftPowerOff function 33 */ 34 SoftPowerOff(sdbusplus::bus::bus& bus, sd_event* event, 35 const char* objPath) : 36 sdbusplus::server::object::object<Base::SoftPowerOff>(bus, objPath, 37 false), 38 bus(bus), timer(event), 39 hostControlSignal( 40 bus, 41 sdbusRule::type::signal() + sdbusRule::member("CommandComplete") + 42 sdbusRule::path("/xyz/openbmc_project/control/host0") + 43 sdbusRule::interface(CONTROL_HOST_BUSNAME) + 44 sdbusRule::argN(0, convertForMessage(Host::Command::SoftOff)), 45 std::bind(std::mem_fn(&SoftPowerOff::hostControlEvent), this, 46 std::placeholders::_1)) 47 { 48 // Need to announce since we may get the response 49 // very quickly on host shutdown command 50 emit_object_added(); 51 52 // The whole purpose of this application is to send a host shutdown 53 // command and watch for the soft power off to go through. We need 54 // the interface added signal emitted before we send the shutdown 55 // command just to attend to lightning fast response from host 56 sendHostShutDownCmd(); 57 } 58 59 /** @brief Tells if the objective of this application is completed */ 60 inline auto isCompleted() 61 { 62 return completed; 63 } 64 65 /** @brief Tells if the referenced timer is expired or not */ 66 inline auto isTimerExpired() 67 { 68 return timer.isExpired(); 69 } 70 71 /** @brief overloaded property setter function 72 * 73 * @param[in] value - One of SoftOffReceived / HostShutdown 74 * 75 * @return Success or exception thrown 76 */ 77 HostResponse responseReceived(HostResponse value) override; 78 79 /** @brief Using the base class's getter method */ 80 using Base::SoftPowerOff::responseReceived; 81 82 /** @brief Calls to start a timer 83 * 84 * @param[in] usec - Time in microseconds 85 * 86 * @return Success or exception thrown 87 */ 88 int startTimer(const std::chrono::microseconds& usec); 89 90 private: 91 // Need this to send SMS_ATTN 92 // TODO : Switch over to using mapper service in a different patch 93 static constexpr auto HOST_IPMI_BUS = "org.openbmc.HostIpmi"; 94 static constexpr auto HOST_IPMI_OBJ = "/org/openbmc/HostIpmi/1"; 95 static constexpr auto HOST_IPMI_INTF = "org.openbmc.HostIpmi"; 96 97 /* @brief sdbusplus handle */ 98 sdbusplus::bus::bus& bus; 99 100 /** @brief Reference to Timer object */ 101 Timer timer; 102 103 /** @brief Marks the end of life of this application. 104 * 105 * This is set to true if host gives appropriate responses 106 * for the sequence of commands. 107 */ 108 bool completed = false; 109 110 /** @brief Subscribe to host control signals 111 * 112 * Protocol is to send the host power off request to the host 113 * control interface and then wait for a signal indicating pass/fail 114 **/ 115 sdbusplus::bus::match_t hostControlSignal; 116 117 /** @brief Sends host control command to tell host to shut down 118 * 119 * After sending the command, wait for a signal indicating the status 120 * of the command. 121 * 122 * After receiving the initial response, start a timer for 30 minutes 123 * to let host do a clean shutdown of partitions. When the response is 124 * received from the host, it indicates that BMC can do a power off. 125 * If BMC fails to get any response, then a hard power off would 126 * be forced. 127 * 128 * @return - Does not return anything. Error will result in exception 129 * being thrown 130 */ 131 void sendHostShutDownCmd(); 132 133 /** @brief Callback function on host control signals 134 * 135 * @param[in] msg - Data associated with subscribed signal 136 * 137 */ 138 void hostControlEvent(sdbusplus::message::message& msg); 139 }; 140 } // namespace ipmi 141 } // namespace phosphor 142