Make IPMI changes to stop timer that is started by SoftPowerOff

As part of Soft Power Off, there may be a timer that would be
running. This patch will stop the timer when IPMI daemon receives
response from host for SoftPowerOff sequence of commands.

Change-Id: Idacbff36444629623f8754de3d81d292ca19bb85
Signed-off-by: Vishwanatha Subbanna <vishwa@linux.vnet.ibm.com>
diff --git a/chassishandler.cpp b/chassishandler.cpp
index b2a1e7c..39b2994 100644
--- a/chassishandler.cpp
+++ b/chassishandler.cpp
@@ -798,6 +798,46 @@
     return rc;
 }
 
+//-------------------------------------------------------------
+// Send a command to SoftPowerOff application to stop any timer
+//-------------------------------------------------------------
+int stop_soft_off_timer()
+{
+    constexpr auto objname          = "/xyz/openbmc_project/ipmi/internal/"
+                                      "softpoweroff";
+    constexpr auto iface            = "org.freedesktop.DBus.Properties";
+    constexpr auto soft_off_iface   = "xyz.openbmc_project.Ipmi.Internal."
+                                      "SoftPowerOff";
+
+    constexpr auto property         = "ResponseReceived";
+    constexpr auto value            = "xyz.openbmc_project.Ipmi.Internal."
+                                      "SoftPowerOff.HostResponse.HostShutdown";
+    char *busname = nullptr;
+
+    // Get the system bus where most system services are provided.
+    auto bus = ipmid_get_sd_bus_connection();
+
+    // Get the service name
+    auto r = mapper_get_service(bus, objname, &busname);
+    if (r < 0) {
+        fprintf(stderr, "Failed to get %s bus name: %s\n",
+                objname, strerror(-r));
+        return r;
+    }
+
+    // No error object or reply expected.
+    int rc = sd_bus_call_method(bus, busname, objname, iface,
+                           "Set", nullptr, nullptr, "ssv",
+                           soft_off_iface, property, "s", value);
+    if (rc < 0)
+    {
+        fprintf(stderr, "Failed to set property in SoftPowerOff object: %s\n",
+                strerror(-rc));
+    }
+    free(busname);
+    return rc;
+}
+
 //----------------------------------------------------------------------
 // Chassis Control commands
 //----------------------------------------------------------------------
@@ -821,8 +861,18 @@
 			rc = initiate_state_transition(State::Host::Transition::On);
 			break;
 		case CMD_POWER_OFF:
+			// Need to Nudge SoftPowerOff application that it needs to stop the
+			// watchdog timer if running.
+			rc = stop_soft_off_timer();
+			if (!rc)
+			{
+				fprintf(stderr, "Error stopping watchdog timer");
+			}
+			// Does not matter if we are able to stop the timer,
+			// just get going and do the hard power off
 			rc = initiate_state_transition(State::Host::Transition::Off);
 			break;
+
 		case CMD_HARD_RESET:
 		case CMD_POWER_CYCLE:
 			// SPEC has a section that says certain implementations can trigger