1506aa0f3SVishwanatha Subbanna #pragma once
2506aa0f3SVishwanatha Subbanna 
3*0b02be92SPatrick Venture #include "config.h"
4*0b02be92SPatrick Venture 
5*0b02be92SPatrick Venture #include "timer.hpp"
6*0b02be92SPatrick Venture 
7*0b02be92SPatrick Venture #include <functional>
8506aa0f3SVishwanatha Subbanna #include <sdbusplus/bus.hpp>
9506aa0f3SVishwanatha Subbanna #include <sdbusplus/server/object.hpp>
10f0f496c1SAndrew Geissler #include <xyz/openbmc_project/Control/Host/server.hpp>
11506aa0f3SVishwanatha Subbanna #include <xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/server.hpp>
12506aa0f3SVishwanatha Subbanna namespace phosphor
13506aa0f3SVishwanatha Subbanna {
14506aa0f3SVishwanatha Subbanna namespace ipmi
15506aa0f3SVishwanatha Subbanna {
16506aa0f3SVishwanatha Subbanna 
17506aa0f3SVishwanatha Subbanna namespace Base = sdbusplus::xyz::openbmc_project::Ipmi::Internal::server;
18f0f496c1SAndrew Geissler using namespace sdbusplus::xyz::openbmc_project::Control::server;
19f0f496c1SAndrew Geissler 
20f0f496c1SAndrew Geissler namespace sdbusRule = sdbusplus::bus::match::rules;
21506aa0f3SVishwanatha Subbanna 
22506aa0f3SVishwanatha Subbanna /** @class SoftPowerOff
23506aa0f3SVishwanatha Subbanna  *  @brief Responsible for coordinating Host SoftPowerOff operation
24506aa0f3SVishwanatha Subbanna  */
25*0b02be92SPatrick Venture class SoftPowerOff
26*0b02be92SPatrick Venture     : public sdbusplus::server::object::object<Base::SoftPowerOff>
27506aa0f3SVishwanatha Subbanna {
28506aa0f3SVishwanatha Subbanna   public:
29506aa0f3SVishwanatha Subbanna     /** @brief Constructs SoftPowerOff object.
30506aa0f3SVishwanatha Subbanna      *
31506aa0f3SVishwanatha Subbanna      *  @param[in] bus       - system dbus handler
32bcb76886SVishwanatha Subbanna      *  @param[in] event     - sd_event handler
33bcb76886SVishwanatha Subbanna      *  @param[in] objPath   - The Dbus path hosting SoftPowerOff function
34506aa0f3SVishwanatha Subbanna      */
35*0b02be92SPatrick Venture     SoftPowerOff(sdbusplus::bus::bus& bus, sd_event* event,
36506aa0f3SVishwanatha Subbanna                  const char* objPath) :
37*0b02be92SPatrick Venture         sdbusplus::server::object::object<Base::SoftPowerOff>(bus, objPath,
38*0b02be92SPatrick Venture                                                               false),
39*0b02be92SPatrick Venture         bus(bus), timer(event),
40f0f496c1SAndrew Geissler         hostControlSignal(
41f0f496c1SAndrew Geissler             bus,
42*0b02be92SPatrick Venture             sdbusRule::type::signal() + sdbusRule::member("CommandComplete") +
43f0f496c1SAndrew Geissler                 sdbusRule::path("/xyz/openbmc_project/control/host0") +
44f0f496c1SAndrew Geissler                 sdbusRule::interface(CONTROL_HOST_BUSNAME) +
45*0b02be92SPatrick Venture                 sdbusRule::argN(0, convertForMessage(Host::Command::SoftOff)),
46*0b02be92SPatrick Venture             std::bind(std::mem_fn(&SoftPowerOff::hostControlEvent), this,
47*0b02be92SPatrick Venture                       std::placeholders::_1))
48506aa0f3SVishwanatha Subbanna     {
49bcb76886SVishwanatha Subbanna         // Need to announce since we may get the response
50f0f496c1SAndrew Geissler         // very quickly on host shutdown command
51bcb76886SVishwanatha Subbanna         emit_object_added();
52bcb76886SVishwanatha Subbanna 
53f0f496c1SAndrew Geissler         // The whole purpose of this application is to send a host shutdown
54f0f496c1SAndrew Geissler         // command and watch for the soft power off to go through. We need
55f0f496c1SAndrew Geissler         // the interface added signal emitted before we send the shutdown
56f0f496c1SAndrew Geissler         // command just to attend to lightning fast response from host
57f0f496c1SAndrew Geissler         sendHostShutDownCmd();
58506aa0f3SVishwanatha Subbanna     }
597cc9d716SVishwanatha Subbanna 
60bcb76886SVishwanatha Subbanna     /** @brief Tells if the objective of this application is completed */
61bcb76886SVishwanatha Subbanna     inline auto isCompleted()
62bcb76886SVishwanatha Subbanna     {
63bcb76886SVishwanatha Subbanna         return completed;
64bcb76886SVishwanatha Subbanna     }
65bcb76886SVishwanatha Subbanna 
66bcb76886SVishwanatha Subbanna     /** @brief Tells if the referenced timer is expired or not */
67bcb76886SVishwanatha Subbanna     inline auto isTimerExpired()
68bcb76886SVishwanatha Subbanna     {
69bcb76886SVishwanatha Subbanna         return timer.isExpired();
70bcb76886SVishwanatha Subbanna     }
71bcb76886SVishwanatha Subbanna 
7231272b84SVishwanatha Subbanna     /** @brief overloaded property setter function
7331272b84SVishwanatha Subbanna      *
7431272b84SVishwanatha Subbanna      *  @param[in] value - One of SoftOffReceived / HostShutdown
7531272b84SVishwanatha Subbanna      *
7631272b84SVishwanatha Subbanna      *  @return Success or exception thrown
7731272b84SVishwanatha Subbanna      */
7831272b84SVishwanatha Subbanna     HostResponse responseReceived(HostResponse value) override;
7931272b84SVishwanatha Subbanna 
80917454bbSVishwanatha Subbanna     /** @brief Using the base class's getter method */
81917454bbSVishwanatha Subbanna     using Base::SoftPowerOff::responseReceived;
82917454bbSVishwanatha Subbanna 
83917454bbSVishwanatha Subbanna     /** @brief Calls to start a timer
84917454bbSVishwanatha Subbanna      *
85917454bbSVishwanatha Subbanna      *  @param[in] usec - Time in microseconds
86917454bbSVishwanatha Subbanna      *
87917454bbSVishwanatha Subbanna      *  @return Success or exception thrown
88917454bbSVishwanatha Subbanna      */
89917454bbSVishwanatha Subbanna     int startTimer(const std::chrono::microseconds& usec);
90917454bbSVishwanatha Subbanna 
917cc9d716SVishwanatha Subbanna   private:
92bcb76886SVishwanatha Subbanna     // Need this to send SMS_ATTN
93bcb76886SVishwanatha Subbanna     // TODO : Switch over to using mapper service in a different patch
94bcb76886SVishwanatha Subbanna     static constexpr auto HOST_IPMI_BUS = "org.openbmc.HostIpmi";
95bcb76886SVishwanatha Subbanna     static constexpr auto HOST_IPMI_OBJ = "/org/openbmc/HostIpmi/1";
96bcb76886SVishwanatha Subbanna     static constexpr auto HOST_IPMI_INTF = "org.openbmc.HostIpmi";
97bcb76886SVishwanatha Subbanna 
98bcb76886SVishwanatha Subbanna     /* @brief sdbusplus handle */
99bcb76886SVishwanatha Subbanna     sdbusplus::bus::bus& bus;
100bcb76886SVishwanatha Subbanna 
101bcb76886SVishwanatha Subbanna     /** @brief Reference to Timer object */
102bcb76886SVishwanatha Subbanna     Timer timer;
103bcb76886SVishwanatha Subbanna 
104bcb76886SVishwanatha Subbanna     /** @brief Marks the end of life of this application.
105bcb76886SVishwanatha Subbanna      *
106bcb76886SVishwanatha Subbanna      *  This is set to true if host gives appropriate responses
107bcb76886SVishwanatha Subbanna      *  for the sequence of commands.
108bcb76886SVishwanatha Subbanna      */
109bcb76886SVishwanatha Subbanna     bool completed = false;
110bcb76886SVishwanatha Subbanna 
111f0f496c1SAndrew Geissler     /** @brief Subscribe to host control signals
1127cc9d716SVishwanatha Subbanna      *
113f0f496c1SAndrew Geissler      *  Protocol is to send the host power off request to the host
114f0f496c1SAndrew Geissler      *  control interface and then wait for a signal indicating pass/fail
115f0f496c1SAndrew Geissler      **/
116f0f496c1SAndrew Geissler     sdbusplus::bus::match_t hostControlSignal;
117f0f496c1SAndrew Geissler 
118f0f496c1SAndrew Geissler     /** @brief Sends host control command to tell host to shut down
119f0f496c1SAndrew Geissler      *
120f0f496c1SAndrew Geissler      *  After sending the command, wait for a signal indicating the status
121f0f496c1SAndrew Geissler      *  of the command.
122f0f496c1SAndrew Geissler      *
123f0f496c1SAndrew Geissler      *  After receiving the initial response, start a timer for 30 minutes
124f0f496c1SAndrew Geissler      *  to let host do a clean shutdown of partitions. When the response is
125f0f496c1SAndrew Geissler      *  received from the host, it indicates that BMC can do a power off.
1267cc9d716SVishwanatha Subbanna      *  If BMC fails to get any response, then a hard power off would
1277cc9d716SVishwanatha Subbanna      *  be forced.
1287cc9d716SVishwanatha Subbanna      *
1297cc9d716SVishwanatha Subbanna      *  @return - Does not return anything. Error will result in exception
1307cc9d716SVishwanatha Subbanna      *            being thrown
1317cc9d716SVishwanatha Subbanna      */
132f0f496c1SAndrew Geissler     void sendHostShutDownCmd();
133f0f496c1SAndrew Geissler 
134f0f496c1SAndrew Geissler     /** @brief Callback function on host control signals
135f0f496c1SAndrew Geissler      *
136f0f496c1SAndrew Geissler      * @param[in]  msg       - Data associated with subscribed signal
137f0f496c1SAndrew Geissler      *
138f0f496c1SAndrew Geissler      */
139f0f496c1SAndrew Geissler     void hostControlEvent(sdbusplus::message::message& msg);
140506aa0f3SVishwanatha Subbanna };
141506aa0f3SVishwanatha Subbanna } // namespace ipmi
142506aa0f3SVishwanatha Subbanna } // namespace phosphor
143