Add function to send SMS_ATTN to host

This patch overrides one of the base API and sends a message that
enables the current HOST IPMI BT provider to actually set the SMS_ATTN.

Change-Id: I250ea6bed99e569e493251f6fc298aa7ed7c776f
Signed-off-by: Vishwanatha Subbanna <vishwa@linux.vnet.ibm.com>
diff --git a/softoff/mainapp.cpp b/softoff/mainapp.cpp
index a974ed7..38b6984 100644
--- a/softoff/mainapp.cpp
+++ b/softoff/mainapp.cpp
@@ -13,9 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include <phosphor-logging/log.hpp>
 #include "softoff.hpp"
 #include "config.h"
 
+using namespace phosphor::logging;
+
 int main(int argc, char** argv)
 {
     // Get a handle to system dbus.
@@ -25,7 +28,7 @@
     sdbusplus::server::manager::manager(bus, SOFTOFF_OBJPATH);
 
     // Create the SoftPowerOff object.
-    phosphor::ipmi::SoftPowerOff obj(bus, SOFTOFF_OBJPATH);
+    phosphor::ipmi::SoftPowerOff object(bus, SOFTOFF_OBJPATH);
 
     /** @brief Claim the bus */
     bus.request_name(SOFTOFF_BUSNAME);
diff --git a/softoff/softoff.cpp b/softoff/softoff.cpp
index 3505e5a..bd6a72d 100644
--- a/softoff/softoff.cpp
+++ b/softoff/softoff.cpp
@@ -13,10 +13,30 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include "softoff.hpp"
 namespace phosphor
 {
 namespace ipmi
 {
-    // Will be populated in the next patchset.
+
+// Need this to send SMS_ATTN
+constexpr auto HOST_IPMI_BUS  = "org.openbmc.HostIpmi";
+constexpr auto HOST_IPMI_OBJ  = "/org/openbmc/HostIpmi/1";
+constexpr auto HOST_IPMI_INTF = "org.openbmc.HostIpmi";
+
+/** @brief Send the SMS_ATN to host if value is set */
+void SoftPowerOff::sendSMSAttn()
+{
+    auto method = bus.new_method_call(HOST_IPMI_BUS,
+                                      HOST_IPMI_OBJ,
+                                      HOST_IPMI_INTF,
+                                      "setAttention");
+
+    // If there is any exception, would be thrown here.
+    // BT returns '0' on success and bus_error on failure.
+    bus.call_noreply(method);
+
+    return;
+}
 } // namespace ipmi
 } // namespace phosphor
diff --git a/softoff/softoff.hpp b/softoff/softoff.hpp
index 93dfb26..dcb4b18 100644
--- a/softoff/softoff.hpp
+++ b/softoff/softoff.hpp
@@ -19,15 +19,41 @@
     public:
         /** @brief Constructs SoftPowerOff object.
          *
-         *  @param[in] bus       - system dbus handler
-         *  @param[in] objPath   - The Dbus path that hosts SoftPowerOff function
+         *  @param[in] bus      - system dbus handler
+         *  @param[in] objPath  - The Dbus path that hosts SoftPowerOff function
          */
         SoftPowerOff(sdbusplus::bus::bus& bus,
                      const char* objPath) :
-            sdbusplus::server::object::object<Base::SoftPowerOff>(bus, objPath)
+            sdbusplus::server::object::object<
+                Base::SoftPowerOff>(bus, objPath),
+                bus(bus)
         {
-            // Nothing to do here
+            // 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();
         }
+
+    private:
+        /** @brief Sends SMS_ATN to host to initiate soft power off process.
+         *
+         *  After sending the SMS_ATN, starts a watchdog timer for 30
+         *  seconds and expects a initial response from the host.
+         *  After receiving the initial response, starts another watchdog
+         *  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();
+
+        /* @brief sdbusplus handle */
+        sdbusplus::bus::bus& bus;
 };
 } // namespace ipmi
 } // namespace phosphor