Update chassis command handler to use state manager services

Until now, IPMI chassis command handler was utilising services from
chassis_control script and this patch makes a transition to use the
services from the latest State Manager daemon.

Fixes openbmc/openbmc#1238

Change-Id: Ic075971bbda44829a3ebe9c0c1de3053a8e97cfa
Signed-off-by: Vishwanatha Subbanna <vishwa@linux.vnet.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index 6c934ef..ef4cdc5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -31,8 +31,8 @@
 	transporthandler.cpp \
 	globalhandler.cpp \
 	groupext.cpp
-libapphandler_la_LDFLAGS = $(SYSTEMD_LIBS) $(libmapper_LIBS) $(PHOSPHOR_LOGGING_LIBS) -version-info 0:0:0 -shared
-libapphandler_la_CXXFLAGS = $(SYSTEMD_CFLAGS) $(libmapper_CFLAGS) $(PHOSPHOR_LOGGING_CFLAGS)
+libapphandler_la_LDFLAGS = $(SYSTEMD_LIBS) $(libmapper_LIBS) $(PHOSPHOR_LOGGING_LIBS) $(PHOSPHOR_DBUS_INTERFACES_LIBS) -version-info 0:0:0 -shared
+libapphandler_la_CXXFLAGS = $(SYSTEMD_CFLAGS) $(libmapper_CFLAGS) $(PHOSPHOR_LOGGING_CFLAGS) $(PHOSPHOR_DBUS_INTERFACES_CFLAGS)
 
 libsysintfcmdsdir = ${libdir}/ipmid-providers
 libsysintfcmds_LTLIBRARIES = libsysintfcmds.la
diff --git a/chassishandler.cpp b/chassishandler.cpp
index b2d4d2b..b2a1e7c 100644
--- a/chassishandler.cpp
+++ b/chassishandler.cpp
@@ -11,6 +11,8 @@
 #include <endian.h>
 #include <sstream>
 #include <array>
+#include <phosphor-logging/log.hpp>
+#include <xyz/openbmc_project/State/Host/server.hpp>
 
 //Defines
 #define SET_PARM_VERSION                     0x01
@@ -42,9 +44,6 @@
 static constexpr size_t GATEWAY_OFFSET = 22;
 
 
-// OpenBMC Chassis Manager dbus framework
-const char  *chassis_object_name   =  "/org/openbmc/control/chassis0";
-const char  *chassis_intf_name     =  "org.openbmc.control.Chassis";
 
 
 void register_netfn_chassis_functions() __attribute__((constructor));
@@ -73,6 +72,9 @@
    uint8_t front_panel_button_cap_status;
 }__attribute__((packed)) ipmi_get_chassis_status_t;
 
+// Phosphor Host State manager
+namespace State = sdbusplus::xyz::openbmc_project::State::server;
+
 int dbus_get_property(const char *name, char **buf)
 {
     sd_bus_error error = SD_BUS_ERROR_NULL;
@@ -562,11 +564,19 @@
     return rc;
 }
 
-//------------------------------------------------------------
-// Calls into Chassis Control Dbus object to do the power off
-//------------------------------------------------------------
-int ipmi_chassis_power_control(const char *method)
+//------------------------------------------
+// Calls into Host State Manager Dbus object
+//------------------------------------------
+int initiate_state_transition(State::Host::Transition transition)
 {
+	using namespace phosphor::logging;
+
+	// OpenBMC Host State Manager dbus framework
+	constexpr auto HOST_STATE_MANAGER_ROOT  = "/xyz/openbmc_project/state/host0";
+	constexpr auto HOST_STATE_MANAGER_IFACE = "xyz.openbmc_project.State.Host";
+	constexpr auto DBUS_PROPERTY_IFACE      = "org.freedesktop.DBus.Properties";
+	constexpr auto PROPERTY                 = "RequestedHostTransition";
+
 	// sd_bus error
 	int rc = 0;
 	char  *busname = NULL;
@@ -574,38 +584,42 @@
 	// SD Bus error report mechanism.
 	sd_bus_error bus_error = SD_BUS_ERROR_NULL;
 
-	// Response from the call. Although there is no response for this call,
-	// obligated to mention this to make compiler happy.
-	sd_bus_message *response = NULL;
-
 	// Gets a hook onto either a SYSTEM or SESSION bus
 	sd_bus *bus_type = ipmid_get_sd_bus_connection();
-	rc = mapper_get_service(bus_type, chassis_object_name, &busname);
+	rc = mapper_get_service(bus_type, HOST_STATE_MANAGER_ROOT, &busname);
 	if (rc < 0) {
-		fprintf(stderr, "Failed to get %s bus name: %s\n",
-				chassis_object_name, strerror(-rc));
-	goto finish;
+		log<level::ERR>("Failed to get bus name",
+				entry("ERROR=%s, OBJPATH=%s",
+					strerror(-rc), HOST_STATE_MANAGER_ROOT));
+		return rc;
 	}
-	rc = sd_bus_call_method(bus_type,        		 // On the System Bus
-							busname,        // Service to contact
-							chassis_object_name,     // Object path 
-							chassis_intf_name,       // Interface name
-							method,      		 // Method to be called
-							&bus_error,      		 // object to return error
-							&response,		 		 // Response buffer if any
-							NULL);			 		 // No input arguments
+
+	// Convert to string equivalent of the passed in transition enum.
+	auto request = State::convertForMessage(transition);
+
+	rc = sd_bus_call_method(bus_type,                // On the system bus
+							busname,                 // Service to contact
+							HOST_STATE_MANAGER_ROOT, // Object path
+							DBUS_PROPERTY_IFACE,     // Interface name
+							"Set",                   // Method to be called
+							&bus_error,              // object to return error
+							nullptr,                 // Response buffer if any
+							"ssv",                   // Takes 3 arguments
+							HOST_STATE_MANAGER_IFACE,
+							PROPERTY,
+							"s", request.c_str());
 	if(rc < 0)
 	{
-		fprintf(stderr,"ERROR initiating Power Off:[%s]\n",bus_error.message);
+		log<level::ERR>("Failed to initiate transition",
+				entry("ERROR=%s, REQUEST=%s",
+					bus_error.message, request.c_str()));
 	}
 	else
 	{
-		printf("Chassis Power Off initiated successfully\n");
+		log<level::INFO>("Transition request initiated successfully");
 	}
 
-finish:
     sd_bus_error_free(&bus_error);
-    sd_bus_message_unref(response);
     free(busname);
 
     return rc;
@@ -804,17 +818,17 @@
 	switch(chassis_ctrl_cmd)
 	{
 		case CMD_POWER_ON:
-			rc = ipmi_chassis_power_control("powerOn");
+			rc = initiate_state_transition(State::Host::Transition::On);
 			break;
 		case CMD_POWER_OFF:
-			rc = ipmi_chassis_power_control("powerOff");
+			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
 			// PowerOn if power is Off when a command to power cycle is
 			// requested
-			rc = ipmi_chassis_power_control("reboot");
+			rc = initiate_state_transition(State::Host::Transition::Reboot);
 			break;
 		default:
 		{
diff --git a/configure.ac b/configure.ac
index f9acc0f..4ffc554 100644
--- a/configure.ac
+++ b/configure.ac
@@ -16,6 +16,7 @@
 AC_CHECK_LIB([mapper], [mapper_get_service], ,[AC_MSG_ERROR([Could not find libmapper...openbmc/phosphor-objmgr package required])])
 PKG_CHECK_MODULES([SYSTEMD], [libsystemd >= 221])
 PKG_CHECK_MODULES([PHOSPHOR_LOGGING], [phosphor-logging],, [AC_MSG_ERROR([Could not find phosphor-logging...openbmc/phosphor-logging package required])])
+PKG_CHECK_MODULES([PHOSPHOR_DBUS_INTERFACES], [phosphor-dbus-interfaces],, [AC_MSG_ERROR([Could not find phosphor-dbus-interfaces...openbmc/phosphor-dbus-interfaces package required])])
 
 # Checks for header files.
 AC_CHECK_HEADER(systemd/sd-bus.h, ,[AC_MSG_ERROR([Could not find systemd/sd-bus.h...systemd developement package required])])