IPMI soft power off
diff --git a/host-services.c b/host-services.c
new file mode 100644
index 0000000..89f0b6c
--- /dev/null
+++ b/host-services.c
@@ -0,0 +1,119 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <systemd/sd-bus.h>
+
+// OpenBMC Host IPMI dbus framework
+const char  *bus_name      =  "org.openbmc.HostIpmi";
+const char  *object_name   =  "/org/openbmc/HostIpmi/1";
+const char  *intf_name     =  "org.openbmc.HostIpmi";
+
+//-------------------------------------------------------------------
+// Gets called by PowerOff handler when a Soft Power off is requested
+//-------------------------------------------------------------------
+static int soft_power_off(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) 
+{
+	int64_t bt_resp = -1;
+	int rc = 0;
+
+	// Steps to be taken when we get this.
+	// 	1: Send a SMS_ATN to the Host
+	// 	2: Host receives it and sends a GetMsgFlags IPMI command
+	// 	3: IPMID app handler will respond to that with a MSgFlag with bit:0x2
+	// 	   set indicating we have a message for Host
+	// 	4: Host sends a GetMsgBuffer command and app handler will respond to
+	// 	   that with a OEM-SEL with certain fields packed indicating to the 
+	// 	   host	that it do a shutdown of the partitions.   
+	// 	5: Host does the partition shutdown and calls Chassis Power off command
+	// 	6: App handler handles the command by making a call to ChassisManager
+	// 	   Dbus
+	
+	// Now the job is to send the SMS_ATTN.
+	
+    // Req message contains the specifics about which method etc that we want to
+    // access on which bus, object
+    sd_bus_message *response = NULL;
+
+	// Error return mechanism
+    sd_bus_error bus_error = SD_BUS_ERROR_NULL;
+
+	// Gets a hook onto either a SYSTEM or SESSION bus
+	sd_bus *bus = (sd_bus *)ipmid_get_sd_bus_connection();
+
+	rc = sd_bus_call_method(bus,        // On the System Bus
+							bus_name,        // Service to contact
+							object_name,     // Object path 
+							intf_name,       // Interface name
+							"setAttention",  // Method to be called
+							&bus_error,      // object to return error
+							&response,		 // Response buffer if any
+							NULL);			 // No input arguments
+	if(rc < 0)
+	{
+		fprintf(stderr,"ERROR initiating Power Off:[%s]\n",bus_error.message);
+		goto finish;
+	}
+
+	// See if we were able to successfully raise SMS_ATN
+    rc = sd_bus_message_read(response, "x", &bt_resp);
+    if (rc < 0) 
+	{
+		fprintf(stderr, "Failed to get a rc from BT for SMS_ATN: %s\n", strerror(-rc));
+		goto finish;
+    }
+
+finish:
+    sd_bus_error_free(&bus_error);
+    sd_bus_message_unref(response);
+
+	if(rc < 0)
+	{
+		return sd_bus_reply_method_return(m, "x", rc);
+	}
+	else
+	{
+		return sd_bus_reply_method_return(m, "x", bt_resp);
+	}
+}
+
+//-------------------------------------------
+// Function pointer of APIs exposed via Dbus
+//-------------------------------------------
+static const sd_bus_vtable host_services_vtable[] =
+{
+	SD_BUS_VTABLE_START(0),
+	// Takes No("") arguments -but- returns a value of type 64 bit integer("x")
+	SD_BUS_METHOD("SoftPowerOff", "", "x", &soft_power_off, SD_BUS_VTABLE_UNPRIVILEGED),
+	SD_BUS_VTABLE_END,
+};
+
+//------------------------------------------------------
+// Called by IPMID as part of the start up
+// -----------------------------------------------------
+int start_host_service(sd_bus *bus, sd_bus_slot *slot)
+{
+	int rc = 0;
+
+	/* Install the object */
+	rc = sd_bus_add_object_vtable(bus,
+								 &slot,
+								"/org/openbmc/HostServices",  /* object path */
+								"org.openbmc.HostServices",   /* interface name */
+								host_services_vtable,
+								NULL);
+	if (rc < 0) 
+	{
+		fprintf(stderr, "Failed to issue method call: %s\n", strerror(-rc));
+	}
+	else
+	{
+		/* Take one in OpenBmc */
+		rc = sd_bus_request_name(bus, "org.openbmc.HostServices", 0);
+		if (rc < 0) 
+		{
+			fprintf(stderr, "Failed to acquire service name: %s\n", strerror(-rc));
+		}
+	}
+
+	return rc < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}