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