1506aa0f3SVishwanatha Subbanna #pragma once
2506aa0f3SVishwanatha Subbanna 
30b02be92SPatrick Venture #include "config.h"
40b02be92SPatrick Venture 
5506aa0f3SVishwanatha Subbanna #include <sdbusplus/bus.hpp>
6506aa0f3SVishwanatha Subbanna #include <sdbusplus/server/object.hpp>
71181af74SVernon Mauery #include <sdbusplus/timer.hpp>
8f0f496c1SAndrew Geissler #include <xyz/openbmc_project/Control/Host/server.hpp>
9506aa0f3SVishwanatha Subbanna #include <xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/server.hpp>
10fbc6c9d7SPatrick Williams 
11fbc6c9d7SPatrick Williams #include <functional>
12506aa0f3SVishwanatha Subbanna namespace phosphor
13506aa0f3SVishwanatha Subbanna {
14506aa0f3SVishwanatha Subbanna namespace ipmi
15506aa0f3SVishwanatha Subbanna {
16506aa0f3SVishwanatha Subbanna 
17523e2d1bSWilly Tu namespace Base = sdbusplus::server::xyz::openbmc_project::ipmi::internal;
18523e2d1bSWilly Tu using namespace sdbusplus::server::xyz::openbmc_project::control;
19f0f496c1SAndrew Geissler 
20f0f496c1SAndrew Geissler namespace sdbusRule = sdbusplus::bus::match::rules;
21506aa0f3SVishwanatha Subbanna 
225adc2d41SPatrick Williams namespace
235adc2d41SPatrick Williams {
245adc2d41SPatrick Williams using SoftPowerOffInherit = sdbusplus::server::object_t<Base::SoftPowerOff>;
255adc2d41SPatrick Williams }
265adc2d41SPatrick Williams 
27506aa0f3SVishwanatha Subbanna /** @class SoftPowerOff
28506aa0f3SVishwanatha Subbanna  *  @brief Responsible for coordinating Host SoftPowerOff operation
29506aa0f3SVishwanatha Subbanna  */
305adc2d41SPatrick Williams class SoftPowerOff : public SoftPowerOffInherit
31506aa0f3SVishwanatha Subbanna {
32506aa0f3SVishwanatha Subbanna   public:
33506aa0f3SVishwanatha Subbanna     /** @brief Constructs SoftPowerOff object.
34506aa0f3SVishwanatha Subbanna      *
35506aa0f3SVishwanatha Subbanna      *  @param[in] bus       - system dbus handler
36bcb76886SVishwanatha Subbanna      *  @param[in] event     - sd_event handler
37bcb76886SVishwanatha Subbanna      *  @param[in] objPath   - The Dbus path hosting SoftPowerOff function
38506aa0f3SVishwanatha Subbanna      */
SoftPowerOff(sdbusplus::bus_t & bus,sd_event * event,const char * objPath)395d82f474SPatrick Williams     SoftPowerOff(sdbusplus::bus_t& bus, sd_event* event, const char* objPath) :
405adc2d41SPatrick Williams         SoftPowerOffInherit(bus, objPath,
415adc2d41SPatrick Williams                             SoftPowerOffInherit::action::defer_emit),
420b02be92SPatrick Venture         bus(bus), timer(event),
43f0f496c1SAndrew Geissler         hostControlSignal(
44f0f496c1SAndrew Geissler             bus,
450b02be92SPatrick Venture             sdbusRule::type::signal() + sdbusRule::member("CommandComplete") +
46f0f496c1SAndrew Geissler                 sdbusRule::path("/xyz/openbmc_project/control/host0") +
47f0f496c1SAndrew Geissler                 sdbusRule::interface(CONTROL_HOST_BUSNAME) +
480b02be92SPatrick Venture                 sdbusRule::argN(0, convertForMessage(Host::Command::SoftOff)),
490b02be92SPatrick Venture             std::bind(std::mem_fn(&SoftPowerOff::hostControlEvent), this,
500b02be92SPatrick Venture                       std::placeholders::_1))
51506aa0f3SVishwanatha Subbanna     {
52bcb76886SVishwanatha Subbanna         // Need to announce since we may get the response
53f0f496c1SAndrew Geissler         // very quickly on host shutdown command
54bcb76886SVishwanatha Subbanna         emit_object_added();
55bcb76886SVishwanatha Subbanna 
56f0f496c1SAndrew Geissler         // The whole purpose of this application is to send a host shutdown
57f0f496c1SAndrew Geissler         // command and watch for the soft power off to go through. We need
58f0f496c1SAndrew Geissler         // the interface added signal emitted before we send the shutdown
59f0f496c1SAndrew Geissler         // command just to attend to lightning fast response from host
60f0f496c1SAndrew Geissler         sendHostShutDownCmd();
61506aa0f3SVishwanatha Subbanna     }
627cc9d716SVishwanatha Subbanna 
63bcb76886SVishwanatha Subbanna     /** @brief Tells if the objective of this application is completed */
isCompleted()64bcb76886SVishwanatha Subbanna     inline auto isCompleted()
65bcb76886SVishwanatha Subbanna     {
66bcb76886SVishwanatha Subbanna         return completed;
67bcb76886SVishwanatha Subbanna     }
68bcb76886SVishwanatha Subbanna 
69bcb76886SVishwanatha Subbanna     /** @brief Tells if the referenced timer is expired or not */
isTimerExpired()70bcb76886SVishwanatha Subbanna     inline auto isTimerExpired()
71bcb76886SVishwanatha Subbanna     {
72bcb76886SVishwanatha Subbanna         return timer.isExpired();
73bcb76886SVishwanatha Subbanna     }
74bcb76886SVishwanatha Subbanna 
7531272b84SVishwanatha Subbanna     /** @brief overloaded property setter function
7631272b84SVishwanatha Subbanna      *
7731272b84SVishwanatha Subbanna      *  @param[in] value - One of SoftOffReceived / HostShutdown
7831272b84SVishwanatha Subbanna      *
7931272b84SVishwanatha Subbanna      *  @return Success or exception thrown
8031272b84SVishwanatha Subbanna      */
8131272b84SVishwanatha Subbanna     HostResponse responseReceived(HostResponse value) override;
8231272b84SVishwanatha Subbanna 
83917454bbSVishwanatha Subbanna     /** @brief Using the base class's getter method */
84917454bbSVishwanatha Subbanna     using Base::SoftPowerOff::responseReceived;
85917454bbSVishwanatha Subbanna 
86917454bbSVishwanatha Subbanna     /** @brief Calls to start a timer
87917454bbSVishwanatha Subbanna      *
88917454bbSVishwanatha Subbanna      *  @param[in] usec - Time in microseconds
89917454bbSVishwanatha Subbanna      *
90917454bbSVishwanatha Subbanna      *  @return Success or exception thrown
91917454bbSVishwanatha Subbanna      */
92917454bbSVishwanatha Subbanna     int startTimer(const std::chrono::microseconds& usec);
93917454bbSVishwanatha Subbanna 
947cc9d716SVishwanatha Subbanna   private:
95bcb76886SVishwanatha Subbanna     // Need this to send SMS_ATTN
96bcb76886SVishwanatha Subbanna     // TODO : Switch over to using mapper service in a different patch
97bcb76886SVishwanatha Subbanna     static constexpr auto HOST_IPMI_BUS = "org.openbmc.HostIpmi";
98bcb76886SVishwanatha Subbanna     static constexpr auto HOST_IPMI_OBJ = "/org/openbmc/HostIpmi/1";
99bcb76886SVishwanatha Subbanna     static constexpr auto HOST_IPMI_INTF = "org.openbmc.HostIpmi";
100bcb76886SVishwanatha Subbanna 
101bcb76886SVishwanatha Subbanna     /* @brief sdbusplus handle */
1025d82f474SPatrick Williams     sdbusplus::bus_t& bus;
103bcb76886SVishwanatha Subbanna 
104bcb76886SVishwanatha Subbanna     /** @brief Reference to Timer object */
105*ba0da6b3SPatrick Williams     sdbusplus::Timer timer;
106bcb76886SVishwanatha Subbanna 
107bcb76886SVishwanatha Subbanna     /** @brief Marks the end of life of this application.
108bcb76886SVishwanatha Subbanna      *
109bcb76886SVishwanatha Subbanna      *  This is set to true if host gives appropriate responses
110bcb76886SVishwanatha Subbanna      *  for the sequence of commands.
111bcb76886SVishwanatha Subbanna      */
112bcb76886SVishwanatha Subbanna     bool completed = false;
113bcb76886SVishwanatha Subbanna 
114f0f496c1SAndrew Geissler     /** @brief Subscribe to host control signals
1157cc9d716SVishwanatha Subbanna      *
116f0f496c1SAndrew Geissler      *  Protocol is to send the host power off request to the host
117f0f496c1SAndrew Geissler      *  control interface and then wait for a signal indicating pass/fail
118f0f496c1SAndrew Geissler      **/
119f0f496c1SAndrew Geissler     sdbusplus::bus::match_t hostControlSignal;
120f0f496c1SAndrew Geissler 
121f0f496c1SAndrew Geissler     /** @brief Sends host control command to tell host to shut down
122f0f496c1SAndrew Geissler      *
123f0f496c1SAndrew Geissler      *  After sending the command, wait for a signal indicating the status
124f0f496c1SAndrew Geissler      *  of the command.
125f0f496c1SAndrew Geissler      *
126f0f496c1SAndrew Geissler      *  After receiving the initial response, start a timer for 30 minutes
127f0f496c1SAndrew Geissler      *  to let host do a clean shutdown of partitions. When the response is
128f0f496c1SAndrew Geissler      *  received from the host, it indicates that BMC can do a power off.
1297cc9d716SVishwanatha Subbanna      *  If BMC fails to get any response, then a hard power off would
1307cc9d716SVishwanatha Subbanna      *  be forced.
1317cc9d716SVishwanatha Subbanna      *
1327cc9d716SVishwanatha Subbanna      *  @return - Does not return anything. Error will result in exception
1337cc9d716SVishwanatha Subbanna      *            being thrown
1347cc9d716SVishwanatha Subbanna      */
135f0f496c1SAndrew Geissler     void sendHostShutDownCmd();
136f0f496c1SAndrew Geissler 
137f0f496c1SAndrew Geissler     /** @brief Callback function on host control signals
138f0f496c1SAndrew Geissler      *
139f0f496c1SAndrew Geissler      * @param[in]  msg       - Data associated with subscribed signal
140f0f496c1SAndrew Geissler      *
141f0f496c1SAndrew Geissler      */
1425d82f474SPatrick Williams     void hostControlEvent(sdbusplus::message_t& msg);
143506aa0f3SVishwanatha Subbanna };
144506aa0f3SVishwanatha Subbanna } // namespace ipmi
145506aa0f3SVishwanatha Subbanna } // namespace phosphor
146