Merge pull request #42 from shenki/travis

travis: Add Travis CI building
diff --git a/Makefile b/Makefile
index 1a37c0f..7a3b6af 100644
--- a/Makefile
+++ b/Makefile
@@ -5,8 +5,7 @@
 TESTADDSEL = testaddsel
 
 DAEMON = ipmid
-DAEMON_OBJ  = $(DAEMON).o
-
+DAEMON_OBJ  = ipmid.o
 
 LIB_APP_OBJ = apphandler.o     \
               sensorhandler.o  \
@@ -16,7 +15,10 @@
               ipmisensor.o     \
               storageaddsel.o  \
               transporthandler.o  \
+              globalhandler.o  \
+              groupext.o
 
+LIB_HOST_SRV_OBJ = host-services.o
 
 TESTADDSEL_OBJ = $(TESTADDSEL).o \
                  storageaddsel.o
@@ -25,10 +27,15 @@
 	     testit.o
 
 LIB_APP     = libapphandler.so
-INSTALLED_LIBS += $(LIB_APP)
+LIB_HOST_SRV = libhostservice.so
+
+INSTALLED_LIBS += $(LIB_APP) $(LIB_HOST_SRV)
 INSTALLED_HEADERS = ipmid-api.h
 
-INC_FLAG += $(shell pkg-config --cflags --libs libsystemd) -I. -O2 
+CXXFLAGS += -Wall -Wno-unused-result
+CFLAGS += -Wall -Wno-unused-result
+
+INC_FLAG += $(shell pkg-config --cflags --libs libsystemd) -I. -O2
 LIB_FLAG += $(shell pkg-config  --libs libsystemd) -rdynamic
 IPMID_PATH ?= -DHOST_IPMI_LIB_PATH=\"/usr/lib/host-ipmid/\"
 
@@ -37,7 +44,7 @@
 INCLUDEDIR ?= /usr/include
 LIBDIR ?= /usr/lib
 
-all: $(DAEMON) $(LIB_APP) $(TESTER)
+all: $(DAEMON) $(LIB_APP) $(LIB_HOST_SRV) $(TESTER)
 
 %.o: %.C
 	$(CXX) -std=c++14 -fpic -c $< $(CXXFLAGS) $(INC_FLAG) $(IPMID_PATH) -o $@
@@ -45,6 +52,9 @@
 $(LIB_APP): $(LIB_APP_OBJ)
 	$(CXX) $^ -shared $(LDFLAGS) $(LIB_FLAG) -o $@
 
+$(LIB_HOST_SRV): $(LIB_HOST_SRV_OBJ)
+	$(CXX) $^ -shared $(LDFLAGS) $(LIB_FLAG) -o $@
+
 $(DAEMON): $(DAEMON_OBJ)
 	$(CXX) $^ $(LDFLAGS) $(LIB_FLAG) -o $@ -ldl
 
diff --git a/apphandler.C b/apphandler.C
index 6467397..71dba66 100644
--- a/apphandler.C
+++ b/apphandler.C
@@ -10,20 +10,80 @@
 
 void register_netfn_app_functions() __attribute__((constructor));
 
+#define DEVICE_FW1 2
+#define DEVICE_FW2 3
+#define DEVICE_AUX 11
 
+//---------------------------------------------------------------------
+// Called by Host on seeing a SMS_ATN bit set. Return a hardcoded 
+// value of 0x2 indicating we need Host read some data.
+//-------------------------------------------------------------------
+ipmi_ret_t ipmi_app_get_msg_flags(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                             ipmi_request_t request, ipmi_response_t response,
+                             ipmi_data_len_t data_len, ipmi_context_t context)
+{
+	// Generic return from IPMI commands.
+    ipmi_ret_t rc = IPMI_CC_OK;
+
+    printf("IPMI APP GET MSG FLAGS returning with [bit:2] set\n");
+
+	// From IPMI spec V2.0 for Get Message Flags Command :
+	// bit:[1] from LSB : 1b = Event Message Buffer Full. 
+	// Return as 0 if Event Message Buffer is not supported, 
+	// or when the Event Message buffer is disabled.
+	// TODO. For now. assume its not disabled and send "0x2" anyway:
+
+	uint8_t set_event_msg_buffer_full = 0x2;
+    *data_len = sizeof(set_event_msg_buffer_full);
+
+    // Pack the actual response
+    memcpy(response, &set_event_msg_buffer_full, *data_len);
+
+    return rc;
+}
+
+//-------------------------------------------------------------------
+// Called by Host post response from Get_Message_Flags
+//-------------------------------------------------------------------
 ipmi_ret_t ipmi_app_read_event(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                              ipmi_request_t request, ipmi_response_t response,
                              ipmi_data_len_t data_len, ipmi_context_t context)
 {
     ipmi_ret_t rc = IPMI_CC_OK;
-    *data_len = 0;
+    printf("IPMI APP READ EVENT command received\n");
 
-    printf("IPMI APP READ EVENT Ignoring for now\n");
+	// TODO : For now, this is catering only to the Soft Power Off via OEM SEL
+	//        mechanism. If we need to make this generically used for some
+	//        other conditions, then we can take advantage of context pointer.
+
+	struct oem_sel_timestamped soft_off = {0};
+    *data_len = sizeof(struct oem_sel_timestamped);
+
+	// either id[0] -or- id[1] can be filled in. We will use id[0]
+	soft_off.id[0]	 = SEL_OEM_ID_0;
+	soft_off.id[1]	 = SEL_OEM_ID_0;
+	soft_off.type	 = SEL_RECORD_TYPE_OEM;
+
+	// Following 3 bytes are from IANA Manufactre_Id field. See below
+	soft_off.manuf_id[0]= 0x41;
+	soft_off.manuf_id[1]= 0xA7;
+	soft_off.manuf_id[2]= 0x00;
+
+	// per IPMI spec NetFuntion for OEM
+	soft_off.netfun	 = 0x3A;
+
+	// Mechanism to kick start soft shutdown.
+	soft_off.cmd	 = CMD_POWER;
+	soft_off.data[0] = SOFT_OFF;
+
+	// All '0xFF' since unused.
+	memset(&soft_off.data[1], 0xFF, 3);
+
+    // Pack the actual response
+    memcpy(response, &soft_off, *data_len);
     return rc;
-
 }
 
-
 ipmi_ret_t ipmi_app_set_acpi_power_state(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                              ipmi_request_t request, ipmi_response_t response,
                              ipmi_data_len_t data_len, ipmi_context_t context)
@@ -35,23 +95,105 @@
     return rc;
 }
 
+
+typedef struct
+{
+    char major;
+    char minor;
+    uint16_t d[2];
+} rev_t;
+
+
+/* Currently only supports the vx.x-x-[-x] format Will return -1 if not in  */
+/* the format this routine knows how to parse                               */
+/* version = v0.6-19-gf363f61-dirty                                         */
+/*            ^ ^ ^^          ^                                             */
+/*            | |  |----------|-- additional details                        */
+/*            | |---------------- Minor                                     */
+/*            |------------------ Major                                     */
+/* Additional details : If the option group exists it will force Auxiliary  */
+/* Firmware Revision Information 4th byte to 1 indicating the build was     */
+/* derived with additional edits                                            */
+int convert_version(const char *p, rev_t *rev)
+{
+    char *s, *token;
+    char hexbyte[5];
+    int l;
+    uint16_t commits;
+
+    if (*p != 'v')
+        return -1;
+    p++;
+
+    s = strdup(p);
+    token = strtok(s,".-");
+
+    rev->major = (int8_t) atoi(token);
+
+    token = strtok(NULL, ".-");
+    rev->minor = (int8_t) atoi(token);
+
+    // Capture the number of commits on top of the minor tag.
+    // I'm using BE format like the ipmi spec asked for
+    token = strtok(NULL,".-");
+
+    if (token) {
+        commits = (int16_t) atoi(token);
+        rev->d[0] = (commits>>8) | (commits<<8);
+
+        // commit number we skip
+        token = strtok(NULL,".-");
+
+    } else {
+        rev->d[0] = 0;
+    }
+
+    // Any value of the optional parameter forces it to 1
+    if (token)
+        token = strtok(NULL,".-");
+
+    rev->d[1] = (token != NULL) ? 1 : 0;
+
+    free(s);
+    return 0;
+}
+
 ipmi_ret_t ipmi_app_get_device_id(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                              ipmi_request_t request, ipmi_response_t response,
                              ipmi_data_len_t data_len, ipmi_context_t context)
 {
     ipmi_ret_t rc = IPMI_CC_OK;
+    const char  *busname = "org.openbmc.Inventory";
+    const char  *objname = "/org/openbmc/inventory/system/chassis/motherboard/bmc";
+    const char  *iface   = "org.openbmc.InventoryItem";
+    char *ver = NULL;
+    int r;
+    rev_t rev = {0};
 
     // TODO:
     // This value is the IANA number assigned to "IBM Platform Firmware
     // Division", which is also used by our service processor.  We may want
     // a different number or at least a different version?
-    uint8_t str[] = {0x00, 0, 1, 1,2, 0xD, 0x41, 0xA7, 0x00, 0x43, 0x40};
+    uint8_t dev_id[] = {0, 0, 0, 0, 2, 0xD, 0x41, 0xA7, 0x00, 0x43, 0x40, 0, 0, 0, 0};
 
     // Data length
-    *data_len = sizeof(str);
+    *data_len = sizeof(dev_id);
+
+    r = sd_bus_get_property_string(bus,busname,objname,iface,"version", NULL, &ver);
+    if ( r < 0 ) {
+        fprintf(stderr, "Failed to obtain version property: %s\n", strerror(-r));
+    } else {
+        r = convert_version(ver, &rev);
+        if( r >= 0 ) {
+            // bit7 identifies state of SDR repository, hence the mask
+            dev_id[DEVICE_FW1] |= 0x7F & rev.major;
+            dev_id[DEVICE_FW2] = rev.minor;
+            memcpy(&dev_id[DEVICE_AUX], rev.d, 4);
+        }
+    }
 
     // Pack the actual response
-    memcpy(response, &str, *data_len);
+    memcpy(response, &dev_id, *data_len);
     return rc;
 }
 
@@ -63,44 +205,11 @@
     const char  *objname = "/org/openbmc/control/chassis0";
     const char  *iface = "org.freedesktop.DBus.Properties";
     const char  *chassis_iface = "org.openbmc.control.Chassis";
-    sd_bus_message *reply = NULL, *m = NULL;
+    sd_bus_message *reply = NULL;
     sd_bus_error error = SD_BUS_ERROR_NULL;
     int r = 0;
     char *uuid = NULL;
 
-    // Status code.
-    ipmi_ret_t rc = IPMI_CC_OK;
-    *data_len = 0;
-
-    printf("IPMI GET DEVICE GUID\n");
-
-    // Call Get properties method with the interface and property name
-    r = sd_bus_message_new_method_call(bus,&m,busname,objname,iface,"Get");
-    if (r < 0) {
-        fprintf(stderr, "Failed to add the Get method object: %s\n", strerror(-r));
-        return IPMI_CC_UNSPECIFIED_ERROR;
-    }
-    r = sd_bus_message_append(m, "ss", chassis_iface, "uuid");
-    if (r < 0) {
-        fprintf(stderr, "Failed to append arguments: %s\n", strerror(-r));
-        return -1;
-    }
-    r = sd_bus_call(bus, m, 0, &error, &reply);
-    if (r < 0) {
-        fprintf(stderr, "Failed to call the Get method: %s\n", strerror(-r));
-        return IPMI_CC_UNSPECIFIED_ERROR;
-    }
-    r = sd_bus_message_read(reply, "v", "s", &uuid);
-    if (r < 0) {
-        fprintf(stderr, "Failed to get a response: %s", strerror(-r));
-        return IPMI_CC_RESPONSE_ERROR;
-    }
-    if (uuid == NULL)
-    {
-        fprintf(stderr, "Failed to get a valid response: %s", strerror(-r));
-        return IPMI_CC_RESPONSE_ERROR;
-    }
-
     // UUID is in RFC4122 format. Ex: 61a39523-78f2-11e5-9862-e6402cfc3223
     // Per IPMI Spec 2.0 need to convert to 16 hex bytes and reverse the byte order
     // Ex: 0x2332fc2c40e66298e511f2782395a361
@@ -110,14 +219,42 @@
     int resp_loc = resp_size-1; // Point resp end of array to save in reverse order
     int i = 0;
     char *tokptr = NULL;
+    char *id_octet = NULL;
+
+    // Status code.
+    ipmi_ret_t rc = IPMI_CC_OK;
+    *data_len = 0;
+
+    printf("IPMI GET DEVICE GUID\n");
+
+    // Call Get properties method with the interface and property name
+    r = sd_bus_call_method(bus,busname,objname,iface,
+                           "Get",&error, &reply, "ss",
+                           chassis_iface, "uuid");
+    if (r < 0)
+    {
+        fprintf(stderr, "Failed to call Get Method: %s\n", strerror(-r));
+        rc = IPMI_CC_UNSPECIFIED_ERROR;
+        goto finish;
+    }
+
+    r = sd_bus_message_read(reply, "v", "s", &uuid);
+    if (r < 0 || uuid == NULL)
+    {
+        fprintf(stderr, "Failed to get a response: %s", strerror(-r));
+        rc = IPMI_CC_RESPONSE_ERROR;
+        goto finish;
+    }
 
     // Traverse the UUID
-    char* id_octet = strtok_r(uuid, "-", &tokptr); // Get the UUID octects separated by dash
+    id_octet = strtok_r(uuid, "-", &tokptr); // Get the UUID octects separated by dash
 
     if (id_octet == NULL)
-    { // Error
+    {
+        // Error
         fprintf(stderr, "Unexpected UUID format: %s", uuid);
-        return IPMI_CC_RESPONSE_ERROR;
+        rc = IPMI_CC_RESPONSE_ERROR;
+        goto finish;
     }
 
     while (id_octet != NULL)
@@ -128,8 +265,7 @@
 
         for(i = 0; i < tmp_size; i++)
         {
-            char tmp_array[3]; // Holder of the 2 chars that will become a byte
-            tmp_array[3] = '\0';
+            char tmp_array[3] = {0}; // Holder of the 2 chars that will become a byte
             strncpy(tmp_array, id_octet, 2); // 2 chars at a time
 
             int resp_byte = strtoul(tmp_array, NULL, 16); // Convert to hex byte
@@ -146,8 +282,9 @@
     // Pack the actual response
     memcpy(response, &resp_uuid, *data_len);
 
+finish:
     sd_bus_error_free(&error);
-    sd_bus_message_unref(m);
+    reply = sd_bus_message_unref(reply);
 
     return rc;
 }
@@ -191,15 +328,13 @@
     const char  *busname = "org.openbmc.watchdog.Host";
     const char  *objname = "/org/openbmc/watchdog/host0";
     const char  *iface = "org.openbmc.Watchdog";
-    sd_bus_message *reply = NULL, *m = NULL;
+    sd_bus_message *reply = NULL;
     sd_bus_error error = SD_BUS_ERROR_NULL;
     int r = 0;
 
     set_wd_data_t *reqptr = (set_wd_data_t*) request;
     uint16_t timer = 0;
     uint32_t timer_ms = 0;
-    // Status code.
-    ipmi_ret_t rc = IPMI_CC_OK;
 
     *data_len = 0;
 
@@ -211,53 +346,45 @@
     printf("WATCHDOG SET Timer:[0x%X] 100ms intervals\n",timer);
 
     // Set watchdog timer
-    r = sd_bus_message_new_method_call(bus,&m,busname,objname,iface,"set");
-    if (r < 0) {
-        fprintf(stderr, "Failed to add the set method object: %s\n", strerror(-r));
-        return -1;
-    }
-    r = sd_bus_message_append(m, "i", timer_ms);
-    if (r < 0) {
-        fprintf(stderr, "Failed to add timer value: %s\n", strerror(-r));
-        return -1;
-    }
-    r = sd_bus_call(bus, m, 0, &error, &reply);
-    if (r < 0) {
-        fprintf(stderr, "Failed to call the set method: %s\n", strerror(-r));
-        return -1;
-    }
-
-    // Stop the current watchdog if any
-    r = sd_bus_message_new_method_call(bus,&m,busname,objname,iface,"stop");
-    if (r < 0) {
-        fprintf(stderr, "Failed to add the start method object: %s\n", strerror(-r));
-        return -1;
-    }
-    r = sd_bus_call(bus, m, 0, &error, &reply);
-    if (r < 0) {
-        fprintf(stderr, "Failed to call the start method: %s\n", strerror(-r));
-        return -1;
-    }
-
-    // Start the watchdog if requested
-    if (reqptr->t_use & 0x40)
+    r = sd_bus_call_method(bus, busname, objname, iface,
+                           "set", &error, &reply, "i", timer_ms);
+    if(r < 0)
     {
-        r = sd_bus_message_new_method_call(bus,&m,busname,objname,iface,"start");
-        if (r < 0) {
-            fprintf(stderr, "Failed to add the start method object: %s\n", strerror(-r));
-            return -1;
-        }
-        r = sd_bus_call(bus, m, 0, &error, &reply);
-        if (r < 0) {
-            fprintf(stderr, "Failed to call the start method: %s\n", strerror(-r));
-            return -1;
-        }
+        fprintf(stderr, "Failed to call the SET method: %s\n", strerror(-r));
+        goto finish;
     }
 
     sd_bus_error_free(&error);
-    sd_bus_message_unref(m);
+    reply = sd_bus_message_unref(reply);
 
-    return rc;
+    // Stop the current watchdog if any
+    r = sd_bus_call_method(bus, busname, objname, iface,
+                           "stop", &error, &reply, NULL);
+    if(r < 0)
+    {
+        fprintf(stderr, "Failed to call the STOP method: %s\n", strerror(-r));
+        goto finish;
+    }
+
+    if (reqptr->t_use & 0x40)
+    {
+        sd_bus_error_free(&error);
+        reply = sd_bus_message_unref(reply);
+
+        // Start the watchdog if requested
+        r = sd_bus_call_method(bus, busname, objname, iface,
+                               "start", &error, &reply, NULL);
+        if(r < 0)
+        {
+            fprintf(stderr, "Failed to call the START method: %s\n", strerror(-r));
+        }
+    }
+
+finish:
+    sd_bus_error_free(&error);
+    reply = sd_bus_message_unref(reply);
+
+    return (r < 0) ? -1 : IPMI_CC_OK;
 }
 
 
@@ -268,7 +395,7 @@
     const char  *busname = "org.openbmc.watchdog.Host";
     const char  *objname = "/org/openbmc/watchdog/host0";
     const char  *iface = "org.openbmc.Watchdog";
-    sd_bus_message *reply = NULL, *m = NULL;
+    sd_bus_message *reply = NULL;
     sd_bus_error error = SD_BUS_ERROR_NULL;
     int r = 0;
 
@@ -279,19 +406,53 @@
     printf("WATCHDOG RESET\n");
 
     // Refresh watchdog
-    r = sd_bus_message_new_method_call(bus,&m,busname,objname,iface,"poke");
+    r = sd_bus_call_method(bus, busname, objname, iface,
+                           "poke", &error, &reply, NULL);
     if (r < 0) {
-        fprintf(stderr, "Failed to add the method object: %s\n", strerror(-r));
-        return -1;
-    }
-    r = sd_bus_call(bus, m, 0, &error, &reply);
-    if (r < 0) {
-        fprintf(stderr, "Failed to call the method: %s\n", strerror(-r));
-        return -1;
+        fprintf(stderr, "Failed to add reset  watchdog: %s\n", strerror(-r));
+        rc = -1;
     }
 
     sd_bus_error_free(&error);
-    sd_bus_message_unref(m);
+    reply = sd_bus_message_unref(reply);
+
+    return rc;
+}
+
+// ATTENTION: This ipmi function is very hardcoded on purpose
+// OpenBMC does not fully support IPMI.  This command is useful
+// to have around because it enables testing of interfaces with
+// the IPMI tool.
+#define GET_CHANNEL_INFO_CHANNEL_OFFSET 0
+// IPMI Table 6-2
+#define IPMI_CHANNEL_TYPE_IPMB 1
+// IPMI Table 6-3
+#define IPMI_CHANNEL_MEDIUM_TYPE_OTHER 6
+
+ipmi_ret_t ipmi_app_channel_info(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                             ipmi_request_t request, ipmi_response_t response,
+                             ipmi_data_len_t data_len, ipmi_context_t context)
+{
+    ipmi_ret_t rc = IPMI_CC_OK;
+    uint8_t resp[] = {
+        1,
+        IPMI_CHANNEL_MEDIUM_TYPE_OTHER,
+        IPMI_CHANNEL_TYPE_IPMB,
+        1,0x41,0xA7,0x00,0,0};
+    uint8_t *p = (uint8_t*) request;
+
+    printf("IPMI APP GET CHANNEL INFO\n");
+
+    // I"m only supporting channel 1.  0xE is the 'default channel'
+    if (*p == 0xe || *p == 1 || *p == 8) {
+
+        *data_len = sizeof(resp);
+        memcpy(response, resp, *data_len);
+
+    } else {
+        rc = IPMI_CC_PARM_OUT_OF_RANGE;
+        *data_len = 0;
+    }
 
     return rc;
 }
@@ -359,6 +520,15 @@
     ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_BMC_GLOBAL_ENABLES, NULL,
                                             ipmi_app_set_bmc_global_enables);
 
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_MSG_FLAGS);
+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_MSG_FLAGS, NULL, ipmi_app_get_msg_flags);
+
+
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_CHAN_INFO);
+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHAN_INFO, NULL, ipmi_app_channel_info);
+
+
+
     return;
 }
 
diff --git a/apphandler.h b/apphandler.h
index 35a2b20..a17ee7f 100644
--- a/apphandler.h
+++ b/apphandler.h
@@ -1,6 +1,19 @@
 #ifndef __HOST_IPMI_APP_HANDLER_H__
 #define __HOST_IPMI_APP_HANDLER_H__
 
+#include <stdint.h>
+
+// These are per skiboot ipmi-sel code
+
+// OEM_SEL type with Timestamp
+#define SEL_OEM_ID_0		0x55
+// SEL type is OEM and -not- general SEL
+#define SEL_RECORD_TYPE_OEM	0xC0
+// Minor command for soft shurdown
+#define SOFT_OFF			0x00
+// Major command for Any kind of power ops
+#define CMD_POWER			0x04
+
 // IPMI commands for App net functions.
 enum ipmi_netfn_app_cmds
 {
@@ -11,9 +24,29 @@
     IPMI_CMD_RESET_WD               = 0x22,
     IPMI_CMD_SET_WD                 = 0x24,
     IPMI_CMD_SET_BMC_GLOBAL_ENABLES = 0x2E,
+    IPMI_CMD_GET_MSG_FLAGS          = 0x31,
     IPMI_CMD_READ_EVENT             = 0x35,
     IPMI_CMD_GET_CAP_BIT            = 0x36,
+    IPMI_CMD_GET_CHAN_INFO          = 0x42,
 
 };
 
+// A Mechanism to tell host to shtudown hosts by sending this PEM SEL. Really
+// the only used fields by skiboot are:
+// id[0] / id[1] for ID_0 , ID_1
+// type : SEL_RECORD_TYPE_OEM as standard SELs are ignored by skiboot
+// cmd : CMD_POWER for power functions
+// data[0], specific commands.  example Soft power off. power cycle, etc.
+struct oem_sel_timestamped
+{
+	/* SEL header */
+	uint8_t id[2];
+	uint8_t type;
+	uint8_t manuf_id[3];
+	uint8_t timestamp[4];
+	/* OEM SEL data (6 bytes) follows */
+	uint8_t netfun;
+	uint8_t cmd;
+	uint8_t data[4];
+};
 #endif
diff --git a/chassishandler.C b/chassishandler.C
index d00a124..d5b3404 100644
--- a/chassishandler.C
+++ b/chassishandler.C
@@ -4,14 +4,243 @@
 #include <string.h>
 #include <stdint.h>
 
+
+//Defines
+#define SET_PARM_VERSION 1
+#define SET_PARM_BOOT_FLAGS_PERMANENT 0x40 //boot flags data1 7th bit on
+#define SET_PARM_BOOT_FLAGS_VALID_ONE_TIME   0x80 //boot flags data1 8th bit on
+#define SET_PARM_BOOT_FLAGS_VALID_PERMANENT  0xC0 //boot flags data1 7 & 8 bit on 
+
+
+
+// OpenBMC Chassis Manager dbus framework
+const char  *chassis_bus_name      =  "org.openbmc.control.Chassis";
+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));
 
+// Host settings in dbus
+// Service name should be referenced by connection name got via object mapper
+const char *settings_object_name  =  "/org/openbmc/settings/host0";
+const char *settings_intf_name    =  "org.freedesktop.DBus.Properties";
+const char *host_intf_name        =  "org.openbmc.settings.Host";
+
+const char *objmapper_service_name =  "org.openbmc.objectmapper";
+const char *objmapper_object_name  =  "/org/openbmc/objectmapper/objectmapper";
+const char *objmapper_intf_name    =  "org.openbmc.objectmapper.ObjectMapper";
+
+int object_mapper_get_connection(char **buf, const char *obj_path)
+{
+    sd_bus_error error = SD_BUS_ERROR_NULL;
+    sd_bus_message *m = NULL;
+    sd_bus *bus = NULL;
+    char *temp_buf = NULL, *intf = NULL;
+    size_t buf_size = 0;
+    int r;
+
+    // Get the system bus where most system services are provided.
+    bus = ipmid_get_sd_bus_connection();
+
+    /*
+     * Bus, service, object path, interface and method are provided to call
+     * the method.
+     * Signatures and input arguments are provided by the arguments at the
+     * end.
+     */
+    r = sd_bus_call_method(bus,
+                           objmapper_service_name,                      /* service to contact */
+                           objmapper_object_name,                       /* object path */
+                           objmapper_intf_name,                         /* interface name */
+                           "GetObject",                                 /* method name */
+                           &error,                                      /* object to return error in */
+                           &m,                                          /* return message on success */
+                           "s",                                         /* input signature */
+                           obj_path                                     /* first argument */
+                          );
+
+    if (r < 0) {
+        fprintf(stderr, "Failed to issue method call: %s\n", error.message);
+        goto finish;
+    }
+
+    // Get the key, aka, the connection name
+    sd_bus_message_read(m, "a{sas}", 1, &temp_buf, 1, &intf);
+
+    /*
+     * TODO: check the return code. Currently for no reason the message
+     * parsing of object mapper is always complaining about
+     * "Device or resource busy", but the result seems OK for now. Need
+     * further checks.
+     * TODO: The following code is preserved in the comments so that it can be
+     * resumed after the problem aforementioned is resolved.
+     *r = sd_bus_message_read(m, "a{sas}", 1, &temp_buf, 1, &intf);
+     *if (r < 0) {
+     *    fprintf(stderr, "Failed to parse response message: %s\n", strerror(-r));
+     *    goto finish;
+     *}
+     */
+
+    buf_size = strlen(temp_buf) + 1;
+    printf("IPMID connection name: %s\n", temp_buf);
+    *buf = (char *)malloc(buf_size);
+
+    if (*buf == NULL) {
+        fprintf(stderr, "Malloc failed for get_sys_boot_options");
+        r = -1;
+        goto finish;
+    }
+
+    memcpy(*buf, temp_buf, buf_size);
+
+finish:
+    sd_bus_error_free(&error);
+    sd_bus_message_unref(m);
+
+    return r;
+}
+
+int dbus_get_property(const char *name, char **buf)
+{
+    sd_bus_error error = SD_BUS_ERROR_NULL;
+    sd_bus_message *m = NULL;
+    sd_bus *bus = NULL;
+    char *temp_buf = NULL;
+    char *connection = NULL;
+    int r;
+
+    r = object_mapper_get_connection(&connection, settings_object_name);
+
+    if (r < 0) {
+        fprintf(stderr, "Failed to get connection, return value: %d.\n", r);
+        goto finish;
+    }
+
+    printf("connection: %s\n", connection);
+
+    // Get the system bus where most system services are provided.
+    bus = ipmid_get_sd_bus_connection();
+
+    /*
+     * Bus, service, object path, interface and method are provided to call
+     * the method.
+     * Signatures and input arguments are provided by the arguments at the
+     * end.
+     */
+    r = sd_bus_call_method(bus,
+                           connection,                                 /* service to contact */
+                           settings_object_name,                       /* object path */
+                           settings_intf_name,                         /* interface name */
+                           "Get",                                      /* method name */
+                           &error,                                     /* object to return error in */
+                           &m,                                         /* return message on success */
+                           "ss",                                       /* input signature */
+                           host_intf_name,                             /* first argument */
+                           name);                                      /* second argument */
+
+    if (r < 0) {
+        fprintf(stderr, "Failed to issue method call: %s\n", error.message);
+        goto finish;
+    }
+
+    /*
+     * The output should be parsed exactly the same as the output formatting
+     * specified.
+     */
+    r = sd_bus_message_read(m, "v", "s", &temp_buf);
+    if (r < 0) {
+        fprintf(stderr, "Failed to parse response message: %s\n", strerror(-r));
+        goto finish;
+    }
+
+    asprintf(buf, "%s", temp_buf);
+/*    *buf = (char*) malloc(strlen(temp_buf));
+    if (*buf) {
+        strcpy(*buf, temp_buf);
+    }
+*/
+    printf("IPMID boot option property get: {%s}.\n", (char *) temp_buf);
+
+finish:
+    sd_bus_error_free(&error);
+    sd_bus_message_unref(m);
+    free(connection);
+
+    return r;
+}
+
+int dbus_set_property(const char * name, const char *value)
+{
+    sd_bus_error error = SD_BUS_ERROR_NULL;
+    sd_bus_message *m = NULL;
+    sd_bus *bus = NULL;
+    char *connection = NULL;
+    int r;
+
+    r = object_mapper_get_connection(&connection, settings_object_name);
+
+    if (r < 0) {
+        fprintf(stderr, "Failed to get connection, return value: %d.\n", r);
+        goto finish;
+    }
+
+    printf("connection: %s\n", connection);
+
+    // Get the system bus where most system services are provided.
+    bus = ipmid_get_sd_bus_connection();
+
+    /*
+     * Bus, service, object path, interface and method are provided to call
+     * the method.
+     * Signatures and input arguments are provided by the arguments at the
+     * end.
+     */
+    r = sd_bus_call_method(bus,
+                           connection,                                 /* service to contact */
+                           settings_object_name,                       /* object path */
+                           settings_intf_name,                         /* interface name */
+                           "Set",                                      /* method name */
+                           &error,                                     /* object to return error in */
+                           &m,                                         /* return message on success */
+                           "ssv",                                      /* input signature */
+                           host_intf_name,                             /* first argument */
+                           name,                                       /* second argument */
+                           "s",                                        /* third argument */
+                           value);                                     /* fourth argument */
+
+    if (r < 0) {
+        fprintf(stderr, "Failed to issue method call: %s\n", error.message);
+        goto finish;
+    }
+
+    printf("IPMID boot option property set: {%s}.\n", value);
+
+finish:
+    sd_bus_error_free(&error);
+    sd_bus_message_unref(m);
+    free(connection);
+
+    return r;
+}
+
 struct get_sys_boot_options_t {
     uint8_t parameter;
     uint8_t set;
     uint8_t block;
 }  __attribute__ ((packed));
 
+struct get_sys_boot_options_response_t {
+    uint8_t version;
+    uint8_t parm;
+    uint8_t data[5];
+}  __attribute__ ((packed));
+
+struct set_sys_boot_options_t {
+    uint8_t parameter;
+    uint8_t data[8];
+}  __attribute__ ((packed));
+
 ipmi_ret_t ipmi_chassis_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 
                               ipmi_request_t request, ipmi_response_t response, 
                               ipmi_data_len_t data_len, ipmi_context_t context)
@@ -23,29 +252,264 @@
     return rc;
 }
 
+//------------------------------------------------------------
+// Calls into Chassis Control Dbus object to do the power off
+//------------------------------------------------------------
+int ipmi_chassis_power_control(const char *method)
+{
+	// sd_bus error
+	int rc = 0;
+
+    // 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 = sd_bus_call_method(bus_type,        		 // On the System Bus
+							chassis_bus_name,        // 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
+	if(rc < 0)
+	{
+		fprintf(stderr,"ERROR initiating Power Off:[%s]\n",bus_error.message);
+	}
+	else
+	{
+		printf("Chassis Power Off initiated successfully\n");
+	}
+
+    sd_bus_error_free(&bus_error);
+    sd_bus_message_unref(response);
+
+	return rc;
+}
+
+
+//----------------------------------------------------------------------
+// Chassis Control commands
+//----------------------------------------------------------------------
+ipmi_ret_t ipmi_chassis_control(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 
+                        ipmi_request_t request, ipmi_response_t response, 
+                        ipmi_data_len_t data_len, ipmi_context_t context)
+{
+	// Error from power off.
+	int rc = 0;
+
+	// No response for this command.
+    *data_len = 0;
+
+	// Catch the actual operaton by peeking into request buffer
+	uint8_t chassis_ctrl_cmd = *(uint8_t *)request;
+	printf("Chassis Control Command: Operation:[0x%X]\n",chassis_ctrl_cmd);
+
+	switch(chassis_ctrl_cmd)
+	{
+		case CMD_POWER_OFF:
+			rc = ipmi_chassis_power_control("powerOff");
+			break;
+		case CMD_HARD_RESET:
+			rc = ipmi_chassis_power_control("reboot");
+			break;
+		default:
+		{
+			fprintf(stderr, "Invalid Chassis Control command:[0x%X] received\n",chassis_ctrl_cmd);
+			rc = -1;
+		}
+	}
+
+	return ( (rc < 0) ? IPMI_CC_INVALID : IPMI_CC_OK);
+}
+
+struct bootOptionTypeMap_t {
+    uint8_t ipmibootflag;
+    char    dbusname[8];
+};
+
+#define INVALID_STRING "Invalid"
+// dbus supports this list of boot devices.
+bootOptionTypeMap_t g_bootOptionTypeMap_t[] = {
+
+    {0x01, "Network"},
+    {0x02, "Disk"},
+    {0x03, "Safe"},
+    {0x05, "CDROM"},
+    {0x06, "Setup"},
+    {0x00, "Default"},
+    {0xFF, INVALID_STRING}
+};
+
+uint8_t get_ipmi_boot_option(char *p) {
+
+    bootOptionTypeMap_t *s = g_bootOptionTypeMap_t;
+
+    while (s->ipmibootflag != 0xFF) {
+        if (!strcmp(s->dbusname,p))
+            break;
+        s++;
+    }
+
+    if (!s->ipmibootflag)
+        printf("Failed to find Sensor Type %s\n", p);
+
+    return s->ipmibootflag;
+}
+
+char* get_boot_option_by_ipmi(uint8_t p) {
+
+    bootOptionTypeMap_t *s = g_bootOptionTypeMap_t;
+
+    while (s->ipmibootflag != 0xFF) {
+
+        if (s->ipmibootflag == p)
+            break;
+
+        s++;
+    }
+
+
+    if (!s->ipmibootflag)
+        printf("Failed to find Sensor Type 0x%x\n", p);
+
+    return s->dbusname;
+}
+
 ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 
                               ipmi_request_t request, ipmi_response_t response, 
                               ipmi_data_len_t data_len, ipmi_context_t context)
 {
-    ipmi_ret_t rc = IPMI_CC_OK;
-    *data_len = 0;
+    ipmi_ret_t rc = IPMI_CC_PARM_NOT_SUPPORTED;
+    char *p = NULL;
+    get_sys_boot_options_response_t *resp = (get_sys_boot_options_response_t *) response;
+    get_sys_boot_options_t *reqptr = (get_sys_boot_options_t*) request;
+    uint8_t s;
 
     printf("IPMI GET_SYS_BOOT_OPTIONS\n");
 
-    get_sys_boot_options_t *reqptr = (get_sys_boot_options_t*) request;
+    memset(resp,0,sizeof(*resp));
+    resp->version   = SET_PARM_VERSION;
+    resp->parm      = 5;
+    resp->data[0]   = SET_PARM_BOOT_FLAGS_VALID_ONE_TIME;
 
-    // TODO Return default values to OPAL until dbus interface is available
+    *data_len = sizeof(*resp);
 
-    if (reqptr->parameter == 5) // Parameter #5
-    {
-        uint8_t buf[] = {0x1,0x5,80,0,0,0,0};
-        *data_len = sizeof(buf);
-        memcpy(response, &buf, *data_len);
-    }
-    else
-    {
+    /*
+     * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
+     * This is the only parameter used by petitboot.
+     */
+    if (reqptr->parameter == 5) {
+
+        /* Get the boot device */
+        int r = dbus_get_property("boot_flags",&p);
+
+        if (r < 0) {
+            fprintf(stderr, "Dbus get property(boot_flags) failed for get_sys_boot_options.\n");
+            rc = IPMI_CC_UNSPECIFIED_ERROR;
+
+        } else {
+
+            s = get_ipmi_boot_option(p);
+            resp->data[1] = (s << 2);
+            rc = IPMI_CC_OK;
+
+        }
+
+        if (p)
+        {
+          free(p);
+          p = NULL;
+        }
+
+        /* Get the boot policy */
+        r = dbus_get_property("boot_policy",&p);
+
+        if (r < 0) {
+            fprintf(stderr, "Dbus get property(boot_policy) failed for get_sys_boot_options.\n");
+            rc = IPMI_CC_UNSPECIFIED_ERROR;
+
+        } else {
+
+            printf("BootPolicy is[%s]", p); 
+            resp->data[0] = (strncmp(p,"ONETIME",strlen("ONETIME"))==0) ? 
+                            SET_PARM_BOOT_FLAGS_VALID_ONE_TIME:
+                            SET_PARM_BOOT_FLAGS_VALID_PERMANENT;
+            rc = IPMI_CC_OK;
+
+        }
+
+
+    } else {
         fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
-        return IPMI_CC_PARM_NOT_SUPPORTED;        
+    }
+
+    if (p)
+        free(p);
+
+    return rc;
+}
+
+
+
+ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                              ipmi_request_t request, ipmi_response_t response,
+                              ipmi_data_len_t data_len, ipmi_context_t context)
+{
+    ipmi_ret_t rc = IPMI_CC_OK;
+    char *s;
+
+    printf("IPMI SET_SYS_BOOT_OPTIONS\n");
+
+    set_sys_boot_options_t *reqptr = (set_sys_boot_options_t *) request;
+
+    // This IPMI command does not have any resposne data
+    *data_len = 0;
+
+    /*  000101
+     * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
+     * This is the only parameter used by petitboot.
+     */
+    if (reqptr->parameter == 5) {
+
+        s = get_boot_option_by_ipmi(((reqptr->data[1] & 0x3C) >> 2));
+
+        printf("%d: %s\n", __LINE__, s);
+        if (!strcmp(s,INVALID_STRING)) {
+
+            rc = IPMI_CC_PARM_NOT_SUPPORTED;
+
+        } else {
+
+            int r = dbus_set_property("boot_flags",s);
+
+            if (r < 0) {
+                fprintf(stderr, "Dbus set property(boot_flags) failed for set_sys_boot_options.\n");
+                rc = IPMI_CC_UNSPECIFIED_ERROR;
+            }
+        }
+      
+        /* setting the boot policy */
+        s = (char *)(((reqptr->data[0] & SET_PARM_BOOT_FLAGS_PERMANENT) == 
+                       SET_PARM_BOOT_FLAGS_PERMANENT) ?"PERMANENT":"ONETIME");
+
+        printf ( "\nBoot Policy is %s",s); 
+        int r = dbus_set_property("boot_policy",s);
+
+        if (r < 0) {
+            fprintf(stderr, "Dbus set property(boot_policy) failed for set_sys_boot_options.\n");
+            rc = IPMI_CC_UNSPECIFIED_ERROR;
+        }
+
+    } else {
+        fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
+        rc = IPMI_CC_PARM_NOT_SUPPORTED;
     }
 
     return rc;
@@ -58,5 +522,11 @@
 
     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS);
     ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS, NULL, ipmi_chassis_get_sys_boot_options);
+
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL);
+    ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL, NULL, ipmi_chassis_control);
+
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n", NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS);
+    ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS, NULL, ipmi_chassis_set_sys_boot_options);
 }
 
diff --git a/chassishandler.h b/chassishandler.h
index 99ed366..b6f7d93 100644
--- a/chassishandler.h
+++ b/chassishandler.h
@@ -1,17 +1,41 @@
 #ifndef __HOST_IPMI_CHASSIS_HANDLER_H__
 #define __HOST_IPMI_CHASSIS_HANDLER_H__
 
+#include <stdint.h>
+
 // IPMI commands for Chassis net functions.
 enum ipmi_netfn_app_cmds
 {
+	// Chassis Control
+	IPMI_CMD_CHASSIS_CONTROL	  = 0x02,
     // Get capability bits
+    IPMI_CMD_SET_SYS_BOOT_OPTIONS = 0x08,
     IPMI_CMD_GET_SYS_BOOT_OPTIONS = 0x09,
 };
 
 // Command specific completion codes
 enum ipmi_chassis_return_codes
 {
+    IPMI_OK = 0x0,
     IPMI_CC_PARM_NOT_SUPPORTED = 0x80,
 };
 
+// Generic completion codes,
+// see IPMI doc section 5.2
+enum ipmi_generic_return_codes
+{
+    IPMI_OUT_OF_SPACE = 0xC4,
+};
+
+// Various Chassis operations under a single command.
+enum ipmi_chassis_control_cmds : uint8_t
+{
+	CMD_POWER_OFF 			   = 0x00,
+	CMD_POWER_ON 			   = 0x01,
+	CMD_POWER_CYCLE 		   = 0x02,
+	CMD_HARD_RESET 			   = 0x03,
+	CMD_PULSE_DIAGNOSTIC_INTR  = 0x04,
+	CMD_SOFT_OFF_VIA_OVER_TEMP = 0x05,
+};
+
 #endif
diff --git a/globalhandler.C b/globalhandler.C
new file mode 100644
index 0000000..2d3af92
--- /dev/null
+++ b/globalhandler.C
@@ -0,0 +1,152 @@
+#include "globalhandler.h"
+#include "ipmid-api.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+const char  *control_object_name  =  "/org/openbmc/control/bmc0";
+const char  *control_intf_name    =  "org.openbmc.control.Bmc";
+
+const char  *objectmapper_service_name =  "org.openbmc.objectmapper";
+const char  *objectmapper_object_name  =  "/org/openbmc/objectmapper/objectmapper";
+const char  *objectmapper_intf_name    =  "org.openbmc.objectmapper.ObjectMapper";
+
+void register_netfn_global_functions() __attribute__((constructor));
+
+int obj_mapper_get_connection(char** buf, const char* obj_path)
+{
+    sd_bus_error error = SD_BUS_ERROR_NULL;
+    sd_bus_message *m = NULL;
+    sd_bus *bus = NULL;
+    char *temp_buf = NULL, *intf = NULL;
+    size_t buf_size = 0;
+    int r;
+
+    //Get the system bus where most system services are provided.
+    bus = ipmid_get_sd_bus_connection();
+
+    /*
+     * Bus, service, object path, interface and method are provided to call
+     * the method.
+     * Signatures and input arguments are provided by the arguments at the
+     * end.
+     */
+    r = sd_bus_call_method(bus,
+            objectmapper_service_name,                      /* service to contact */
+            objectmapper_object_name,                       /* object path */
+            objectmapper_intf_name,                         /* interface name */
+            "GetObject",                                    /* method name */
+            &error,                                         /* object to return error in */
+            &m,                                             /* return message on success */
+            "s",                                            /* input signature */
+            obj_path                                        /* first argument */
+            );
+
+    if (r < 0) {
+        fprintf(stderr, "Failed to issue method call: %s\n", error.message);
+        goto finish;
+    }
+
+    // Get the key, aka, the connection name
+    sd_bus_message_read(m, "a{sas}", 1, &temp_buf, 1, &intf);
+    
+	/* 
+     * TODO: check the return code. Currently for no reason the message
+     * parsing of object mapper is always complaining about
+     * "Device or resource busy", but the result seems OK for now. Need
+     *  further checks.
+     */
+
+    buf_size = strlen(temp_buf) + 1;
+    printf("IPMID connection name: %s\n", temp_buf);
+    *buf = (char*)malloc(buf_size);
+
+    if (*buf == NULL) {
+        fprintf(stderr, "Malloc failed for warm reset");
+        r = -1;
+        goto finish;
+    }
+
+    memcpy(*buf, temp_buf, buf_size);
+
+finish:
+    sd_bus_error_free(&error);
+    sd_bus_message_unref(m);
+
+    return r;
+}
+
+int dbus_warm_reset()
+{
+    sd_bus_error error = SD_BUS_ERROR_NULL;
+    sd_bus_message *m = NULL;
+    sd_bus *bus = NULL;
+    char* temp_buf = NULL;
+    uint8_t* get_value = NULL;
+    char* connection = NULL;
+    int r, i;
+
+    r = obj_mapper_get_connection(&connection, control_object_name);
+    if (r < 0) {
+        fprintf(stderr, "Failed to get connection, return value: %d.\n", r);
+        goto finish;
+    }
+
+    printf("connection: %s\n", connection);
+
+    // Open the system bus where most system services are provided.
+    bus = ipmid_get_sd_bus_connection();
+    
+    /*
+     * Bus, service, object path, interface and method are provided to call
+     * the method.
+     * Signatures and input arguments are provided by the arguments at the
+     * end.
+	 */
+    r = sd_bus_call_method(bus,
+            connection,                                /* service to contact */
+            control_object_name,                       /* object path */
+            control_intf_name,                         /* interface name */
+            "warmReset",                               /* method name */
+            &error,                                    /* object to return error in */
+            &m,                                        /* return message on success */
+            NULL,
+            NULL
+            );
+
+    if (r < 0) {
+        fprintf(stderr, "Failed to issue method call: %s\n", error.message);
+        goto finish;
+    }
+
+finish:
+    sd_bus_error_free(&error);
+    sd_bus_message_unref(m);
+    free(connection);
+
+    return r;
+}
+
+ipmi_ret_t ipmi_global_warm_reset(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                              ipmi_request_t request, ipmi_response_t response,
+                              ipmi_data_len_t data_len, ipmi_context_t context)
+{
+    printf("Handling GLOBAL warmReset Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
+
+    // TODO: call the correct dbus method for warmReset.
+    dbus_warm_reset();
+
+    // Status code.
+    ipmi_ret_t rc = IPMI_CC_OK;
+    *data_len = 0;
+    return rc;
+}
+
+
+void register_netfn_global_functions()
+{
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_WARM_RESET);
+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_WARM_RESET, NULL, ipmi_global_warm_reset);
+
+    return;
+}
diff --git a/globalhandler.h b/globalhandler.h
new file mode 100644
index 0000000..608df3b
--- /dev/null
+++ b/globalhandler.h
@@ -0,0 +1,12 @@
+#ifndef __HOST_IPMI_GLOBAL_HANDLER_H__
+#define __HOST_IPMI_GLOBAL_HANDLER_H__
+
+#include <stdint.h>
+
+// Various GLOBAL operations under a single command.
+enum ipmi_global_control_cmds : uint8_t
+{
+IPMI_CMD_WARM_RESET 			   = 0x02,
+};
+
+#endif
diff --git a/groupext.C b/groupext.C
new file mode 100644
index 0000000..b834f9b
--- /dev/null
+++ b/groupext.C
@@ -0,0 +1,31 @@
+#include "ipmid-api.h"
+#include "ipmid.H"
+#include <stdio.h>
+#include <stdint.h>
+
+#define GRPEXT_GET_GROUP_CMD 0
+void register_netfn_groupext_functions() __attribute__((constructor));
+
+ipmi_ret_t ipmi_groupext(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                             ipmi_request_t request, ipmi_response_t response,
+                             ipmi_data_len_t data_len, ipmi_context_t context)
+{
+	// Generic return from IPMI commands.
+    ipmi_ret_t rc = IPMI_CC_OK;
+    uint8_t *p = (uint8_t*) response;
+
+    printf("IPMI GROUP EXTENTIONS\n");
+
+    *data_len = 1;
+    *p = 0;
+
+    return rc;
+}
+
+void register_netfn_groupext_functions()
+{
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_GRPEXT, GRPEXT_GET_GROUP_CMD);
+    ipmi_register_callback(NETFUN_GRPEXT, GRPEXT_GET_GROUP_CMD, NULL, ipmi_groupext);
+
+    return;
+}
diff --git a/host-services.c b/host-services.c
new file mode 100644
index 0000000..cc47439
--- /dev/null
+++ b/host-services.c
@@ -0,0 +1,138 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <systemd/sd-bus.h>
+
+#include "ipmid-api.h"
+
+void register_host_services() __attribute__((constructor));
+
+// 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 = ipmid_get_sd_bus_connection();
+
+    rc = sd_bus_call_method(bus,             // In 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);
+    response = 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;
+}
+
+//------------------------------------------------------
+// Callback register function
+// -----------------------------------------------------
+void register_host_services()
+{
+    // Gets a hook onto SYSTEM bus used by host-ipmid
+    sd_bus *bus = ipmid_get_sd_bus_connection();
+
+    // Gets a hook onto SYSTEM bus slot used by host-ipmid
+    sd_bus_slot *ipmid_slot = ipmid_get_sd_bus_slot();
+
+    //start_host_service(bus, ipmid_slot);
+    start_host_service(bus, ipmid_slot);
+}
diff --git a/host-services.h b/host-services.h
new file mode 100644
index 0000000..0d93480
--- /dev/null
+++ b/host-services.h
@@ -0,0 +1,3 @@
+#include <systemd/sd-bus.h>
+
+extern "C" int start_host_service(sd_bus *, sd_bus_slot *);
diff --git a/ipmid-api.h b/ipmid-api.h
index 34d3bbe..cf3eaab 100644
--- a/ipmid-api.h
+++ b/ipmid-api.h
@@ -3,6 +3,10 @@
 #include <stdlib.h>
 #include <systemd/sd-bus.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 // length of Completion Code and its ALWAYS _1_
 #define IPMI_CC_LEN 1
 
@@ -51,11 +55,11 @@
 // This is the constructor function that is called into by each plugin handlers.
 // When ipmi sets up the callback handlers, a call is made to this with
 // information of netfn, cmd, callback handler pointer and context data.
-// Making this a extern "C" so that plugin libraries written in C can also use
-// it.
-extern "C" void ipmi_register_callback(ipmi_netfn_t, ipmi_cmd_t, 
+void ipmi_register_callback(ipmi_netfn_t, ipmi_cmd_t,
                                        ipmi_context_t, ipmid_callback_t);
 
+unsigned short get_sel_reserve_id(void);
+
 // These are the command network functions, the response
 // network functions are the function + 1. So to determine
 // the proper network function which issued the command
@@ -89,10 +93,18 @@
     IPMI_CC_OK = 0x00,
     IPMI_DCMI_CC_NO_ACTIVE_POWER_LIMIT = 0x80,
     IPMI_CC_INVALID = 0xC1,
+    IPMI_CC_INVALID_RESERVATION_ID = 0xC5,
+    IPMI_CC_PARM_OUT_OF_RANGE = 0xC9,
     IPMI_CC_SENSOR_INVALID = 0xCB,
     IPMI_CC_RESPONSE_ERROR = 0xCE,
     IPMI_CC_UNSPECIFIED_ERROR = 0xFF,
 };
 
 sd_bus *ipmid_get_sd_bus_connection(void);
+sd_bus_slot *ipmid_get_sd_bus_slot(void);
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif
diff --git a/ipmid.C b/ipmid.C
index 6b1eacc..7354958 100644
--- a/ipmid.C
+++ b/ipmid.C
@@ -13,8 +13,8 @@
 #include <errno.h>
 #include "sensorhandler.h"
 
-
 sd_bus *bus = NULL;
+sd_bus_slot *ipmid_slot = NULL;
 
 FILE *ipmiio, *ipmidbus, *ipmicmddetails;
 
@@ -26,8 +26,6 @@
   fprintf(stderr, "    mask : 0xFF - Print all trace\n");
 }
 
-
-
 const char * DBUS_INTF = "org.openbmc.HostIpmi";
 
 const char * FILTER = "type='signal',interface='org.openbmc.HostIpmi',member='ReceivedMessage'";
@@ -39,7 +37,13 @@
 // Global data structure that contains the IPMI command handler's registrations.
 std::map<ipmi_fn_cmd_t, ipmi_fn_context_t> g_ipmid_router_map;
 
+// IPMI Spec, shared Reservation ID.
+unsigned short g_sel_reserve = 0xFFFF;
 
+unsigned short get_sel_reserve_id(void)
+{
+    return g_sel_reserve;
+}
 
 #ifndef HEXDUMP_COLS
 #define HEXDUMP_COLS 16
@@ -200,13 +204,13 @@
     r = sd_bus_message_append(m, "yyyyy", seq, netfn, lun, cmd, cc);
     if (r < 0) {
         fprintf(stderr, "Failed add the netfn and others : %s\n", strerror(-r));
-        return -1;
+        goto final;
     }
 
     r = sd_bus_message_append_array(m, 'y', buf, len);
     if (r < 0) {
         fprintf(stderr, "Failed to add the string of response bytes: %s\n", strerror(-r));
-        return -1;
+        goto final;
     }
 
 
@@ -214,19 +218,20 @@
     // Call the IPMI responder on the bus so the message can be sent to the CEC
     r = sd_bus_call(bus, m, 0, &error, &reply);
     if (r < 0) {
-        fprintf(stderr, "Failed to call the method: %s", strerror(-r));
-        return -1;
+        fprintf(stderr, "Failed to call the method: %s\n", strerror(-r));
+        fprintf(stderr, "Dest: %s, Path: %s\n", dest, path);
+        goto final;
     }
 
     r = sd_bus_message_read(reply, "x", &pty);
     if (r < 0) {
        fprintf(stderr, "Failed to get a rc from the method: %s\n", strerror(-r));
-
     }
 
+final:
     sd_bus_error_free(&error);
-    sd_bus_message_unref(m);
-
+    m = sd_bus_message_unref(m);
+    reply = sd_bus_message_unref(reply);
 
     return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
@@ -234,7 +239,6 @@
 static int handle_ipmi_command(sd_bus_message *m, void *user_data, sd_bus_error
                          *ret_error) {
     int r = 0;
-    const char *msg = NULL;
     unsigned char sequence, netfn, lun, cmd;
     const void *request;
     size_t sz;
@@ -268,6 +272,10 @@
     if(r != 0)
     {
         fprintf(stderr,"ERROR:[0x%X] handling NetFn:[0x%X], Cmd:[0x%X]\n",r, netfn, cmd);
+
+        if(r == -1) {
+           response[0] = IPMI_CC_UNSPECIFIED_ERROR;
+        }
     }
 
     fprintf(ipmiio, "IPMI Response:\n");
@@ -342,8 +350,8 @@
         handler_fqdn += "/";
 
         num_handlers = scandir(ipmi_lib_path, &handler_list, handler_select, alphasort);
-	if (num_handlers < 0)
-		return;
+        if (num_handlers < 0)
+            return;
 
         while(num_handlers--)
         {
@@ -352,6 +360,7 @@
             printf("Registering handler:[%s]\n",handler_fqdn.c_str());
 
             lib_handler = dlopen(handler_fqdn.c_str(), RTLD_NOW);
+
             if(lib_handler == NULL)
             {
                 fprintf(stderr,"ERROR opening [%s]: %s\n",
@@ -360,6 +369,7 @@
             // Wipe the memory allocated for this particular entry.
             free(handler_list[num_handlers]);
         }
+
         // Done with all registration.
         free(handler_list);
     }
@@ -372,11 +382,13 @@
     return bus;
 }
 
+sd_bus_slot *ipmid_get_sd_bus_slot(void) {
+    return ipmid_slot;
+}
+
 int main(int argc, char *argv[])
 {
-    sd_bus_slot *slot = NULL;
     int r;
-    char *mode = NULL;
     unsigned long tvalue;
     int c;
 
@@ -418,7 +430,8 @@
     // Register all the handlers that provider implementation to IPMI commands.
     ipmi_register_callback_handlers(HOST_IPMI_LIB_PATH);
 
-    r = sd_bus_add_match(bus, &slot, FILTER, handle_ipmi_command, NULL);
+	// Watch for BT messages
+    r = sd_bus_add_match(bus, &ipmid_slot, FILTER, handle_ipmi_command, NULL);
     if (r < 0) {
         fprintf(stderr, "Failed: sd_bus_add_match: %s : %s\n", strerror(-r), FILTER);
         goto finish;
@@ -427,7 +440,6 @@
 
     for (;;) {
         /* Process requests */
-
         r = sd_bus_process(bus, NULL);
         if (r < 0) {
             fprintf(stderr, "Failed to process bus: %s\n", strerror(-r));
@@ -445,7 +457,7 @@
     }
 
 finish:
-    sd_bus_slot_unref(slot);
+    sd_bus_slot_unref(ipmid_slot);
     sd_bus_unref(bus);
     return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 
@@ -456,7 +468,7 @@
 // step for mapping IPMI
 int find_interface_property_fru_type(dbus_interface_t *interface, const char *property_name, char *property_value) {
 
-    char  *str1, *str2, *str3;
+    char  *str1;
     sd_bus_error error = SD_BUS_ERROR_NULL;
     sd_bus_message *reply = NULL, *m=NULL;
 
@@ -468,6 +480,7 @@
         fprintf(stderr, "Failed to create a method call: %s", strerror(-r));
         fprintf(stderr,"Bus: %s Path: %s Interface: %s \n",
                 interface->bus, interface->path, interface->interface);
+        goto final;
     }
 
     r = sd_bus_message_append(m, "ss", "org.openbmc.InventoryItem", property_name);
@@ -475,6 +488,7 @@
         fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r));
         fprintf(stderr,"Bus: %s Path: %s Interface: %s \n",
                 interface->bus, interface->path, interface->interface);
+        goto final;
     }
 
     r = sd_bus_call(bus, m, 0, &error, &reply);
@@ -494,7 +508,8 @@
 final:
 
     sd_bus_error_free(&error);
-    sd_bus_message_unref(m);
+    m = sd_bus_message_unref(m);
+    reply = sd_bus_message_unref(reply);
 
     return r;
 }
@@ -510,29 +525,18 @@
 
     char  *str1, *str2, *str3;
     sd_bus_error error = SD_BUS_ERROR_NULL;
-    sd_bus_message *reply = NULL, *m=NULL;
+    sd_bus_message *reply = NULL;
 
 
     int r;
 
-    r = sd_bus_message_new_method_call(bus,&m,busname,objname,busname,"getObjectFromByteId");
+    r = sd_bus_call_method(bus,busname,objname,busname, "getObjectFromByteId",
+                           &error, &reply, "sy", type, num);
     if (r < 0) {
         fprintf(stderr, "Failed to create a method call: %s", strerror(-r));
-    }
-
-    r = sd_bus_message_append(m, "sy", type, num);
-    if (r < 0) {
-        fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r));
-    }
-
-    // Call the IPMI responder on the bus so the message can be sent to the CEC
-    r = sd_bus_call(bus, m, 0, &error, &reply);
-    if (r < 0) {
-        fprintf(stderr, "Failed to call the method: %s", strerror(-r));
         goto final;
     }
 
-
     r = sd_bus_message_read(reply, "(sss)", &str1, &str2, &str3);
     if (r < 0) {
         fprintf(stderr, "Failed to get a response: %s", strerror(-r));
@@ -548,7 +552,7 @@
 final:
 
     sd_bus_error_free(&error);
-    sd_bus_message_unref(m);
+    reply = sd_bus_message_unref(reply);
 
     return r;
 }
@@ -559,64 +563,76 @@
 // Routines used by ipmi commands wanting to interact on the dbus
 //
 /////////////////////////////////////////////////////////////////////
-
-
-// Simple set routine because some methods are standard.
-int set_sensor_dbus_state(uint8_t number, const char *method, const char *value) {
+int set_sensor_dbus_state_s(uint8_t number, const char *method, const char *value) {
 
 
     dbus_interface_t a;
     int r;
     sd_bus_error error = SD_BUS_ERROR_NULL;
-    sd_bus_message *reply = NULL, *m=NULL;
-
-    fprintf(ipmidbus, "Attempting to set a dbus Sensor 0x%02x via %s with a value of %s\n",
-        number, method, value);
-
-    r = find_openbmc_path("SENSOR", number, &a);
-
-    r = sd_bus_message_new_method_call(bus,&m,a.bus,a.path,a.interface,method);
-    if (r < 0) {
-        fprintf(stderr, "Failed to create a method call: %s", strerror(-r));
-    }
-
-    r = sd_bus_message_append(m, "s", value);
-    if (r < 0) {
-        fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r));
-    }
-
-    r = sd_bus_call(bus, m, 0, &error, &reply);
-    if (r < 0) {
-        fprintf(stderr, "Failed to call the method: %s", strerror(-r));
-    }
-
-    sd_bus_error_free(&error);
-    sd_bus_message_unref(m);
-
-    return 0;
-}
-
-int set_sensor_dbus_state_v(uint8_t number, const char *method, char *value) {
-
-
-    dbus_interface_t a;
-    int r;
-    sd_bus_error error = SD_BUS_ERROR_NULL;
-    sd_bus_message *reply = NULL, *m=NULL;
+    sd_bus_message *m=NULL;
 
     fprintf(ipmidbus, "Attempting to set a dbus Variant Sensor 0x%02x via %s with a value of %s\n",
         number, method, value);
 
     r = find_openbmc_path("SENSOR", number, &a);
 
+    if (r < 0) {
+        fprintf(stderr, "Failed to find Sensor 0x%02x\n", number);
+        return 0;
+    }
+
     r = sd_bus_message_new_method_call(bus,&m,a.bus,a.path,a.interface,method);
     if (r < 0) {
         fprintf(stderr, "Failed to create a method call: %s", strerror(-r));
+        goto final;
     }
 
     r = sd_bus_message_append(m, "v", "s", value);
     if (r < 0) {
         fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r));
+        goto final;
+    }
+
+
+    r = sd_bus_call(bus, m, 0, &error, NULL);
+    if (r < 0) {
+        fprintf(stderr, "Failed to call the method: %s", strerror(-r));
+    }
+
+final:
+    sd_bus_error_free(&error);
+    m = sd_bus_message_unref(m);
+
+    return 0;
+}
+int set_sensor_dbus_state_y(uint8_t number, const char *method, const uint8_t value) {
+
+
+    dbus_interface_t a;
+    int r;
+    sd_bus_error error = SD_BUS_ERROR_NULL;
+    sd_bus_message *m=NULL;
+
+    fprintf(ipmidbus, "Attempting to set a dbus Variant Sensor 0x%02x via %s with a value of 0x%02x\n",
+        number, method, value);
+
+    r = find_openbmc_path("SENSOR", number, &a);
+
+    if (r < 0) {
+        fprintf(stderr, "Failed to find Sensor 0x%02x\n", number);
+        return 0;
+    }
+
+    r = sd_bus_message_new_method_call(bus,&m,a.bus,a.path,a.interface,method);
+    if (r < 0) {
+        fprintf(stderr, "Failed to create a method call: %s", strerror(-r));
+        goto final;
+    }
+
+    r = sd_bus_message_append(m, "v", "i", value);
+    if (r < 0) {
+        fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r));
+        goto final;
     }
 
 
@@ -625,9 +641,9 @@
         fprintf(stderr, "12 Failed to call the method: %s", strerror(-r));
     }
 
-
+final:
     sd_bus_error_free(&error);
-    sd_bus_message_unref(m);
+    m = sd_bus_message_unref(m);
 
     return 0;
 }
diff --git a/ipmid.H b/ipmid.H
index 73b60e6..679392d 100644
--- a/ipmid.H
+++ b/ipmid.H
@@ -2,6 +2,7 @@
 #define __HOST_IPMID_IPMI_H__
 #include "ipmid-api.h"
 #include <stdio.h>
+#include "host-services.h"
 
 // When the requester sends in a netfn and a command along with data, this
 // function will look for registered handlers that will handle that [netfn,cmd]
@@ -15,8 +16,10 @@
 // The BT FIFO in the AST2400 can only handle 64 bytes.  
 // Can only allow 63 because the BT interface still 
 // needs 1 byte for the length field. 
-#define MAX_IPMI_BUFFER 63
+#define MAX_IPMI_BUFFER 64
 
 extern FILE *ipmiio, *ipmidbus, *ipmicmddetails;
 
-#endif
+int set_sensor_dbus_state_s(uint8_t , const char *, const char *);
+int set_sensor_dbus_state_y(uint8_t , const char *, const uint8_t);
+#endif
\ No newline at end of file
diff --git a/ipmisensor.C b/ipmisensor.C
index 6d3d3bd..b6927ac 100644
--- a/ipmisensor.C
+++ b/ipmisensor.C
@@ -2,10 +2,10 @@
 #include <string.h>
 #include <stdint.h>
 #include <malloc.h>
-
+#include <ipmid.H>
+#include "sensorhandler.h"
 
 extern uint8_t find_sensor(uint8_t);
-extern int set_sensor_dbus_state_v(uint8_t , const char *, char *);
 
 
 struct sensorRES_t {
@@ -30,19 +30,20 @@
 	uint8_t sensor_type;
 	uint8_t offset;
 	int (*func)(const sensorRES_t *, const lookup_t *, const char *);
-	char    method[16];
+	char    member[16];
 	char    assertion[64];
 	char    deassertion[64];
 };
 
-
-extern int updateDbusInterface(uint8_t , const char *, const char *) ;
-extern int set_sensor_dbus_state(uint8_t ,const char *, const char *);
+extern int updateDbusInterface(uint8_t , const char *, const char *);
+extern int find_openbmc_path(const char *, const uint8_t , dbus_interface_t *) ;
 
 
 int set_sensor_dbus_state_simple(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) {
 
-	return set_sensor_dbus_state(pRec->sensor_number, pTable->method, value);
+	return set_sensor_dbus_state_s(pRec->sensor_number,
+                                   pTable->member,
+                                   value);
 }
 
 struct event_data_t {
@@ -129,22 +130,47 @@
 					break;
 		case 0x02 : snprintf(p, sizeof(valuestring), "FW Progress, %s", event_data_lookup(g_fwprogress02h, pRec->event_data2));
 					break;
+		default : snprintf(p, sizeof(valuestring), "Internal warning, fw_progres offset unknown (0x%02x)", pTable->offset);
+					break;
 	}
 
-	return set_sensor_dbus_state_v(pRec->sensor_number, pTable->method, p);
+	return set_sensor_dbus_state_s(pRec->sensor_number,
+                                   pTable->member,
+                                   p);
 }
 
 // Handling this special OEM sensor by coping what is in byte 4.  I also think that is odd
 // considering byte 3 is for sensor reading.  This seems like a misuse of the IPMI spec
 int set_sensor_dbus_state_osbootcount(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) {
-	char valuestring[32];
-	char* pStr = valuestring;
-
-	sprintf(valuestring, "%d", pRec->assert_state7_0);
-
-	return set_sensor_dbus_state_v(pRec->sensor_number, pTable->method, pStr);
+	return set_sensor_dbus_state_y(pRec->sensor_number,
+                                   "setValue",
+                                   pRec->assert_state7_0);
 }
 
+int set_sensor_dbus_state_system_event(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) {
+	char valuestring[128];
+	char* p = valuestring;
+
+	switch (pTable->offset) {
+
+		case 0x00 : snprintf(p, sizeof(valuestring), "System Reconfigured");
+					break;
+		case 0x01 : snprintf(p, sizeof(valuestring), "OEM Boot Event");
+					break;
+		case 0x02 : snprintf(p, sizeof(valuestring), "Undetermine System Hardware Failure");
+					break;
+		case 0x03 : snprintf(p, sizeof(valuestring), "System Failure see error log for more details (0x%02x)", pRec->event_data2);
+					break;
+		case 0x04 : snprintf(p, sizeof(valuestring), "System Failure see PEF error log for more details (0x%02x)", pRec->event_data2);
+					break;
+		default : snprintf(p, sizeof(valuestring), "Internal warning, system_event offset unknown (0x%02x)", pTable->offset);
+					break;
+	}
+
+	return set_sensor_dbus_state_s(pRec->sensor_number,
+                                   pTable->member,
+                                   p);
+}
 
 
 //  This table lists only senors we care about telling dbus about.
@@ -155,13 +181,13 @@
 	{0xe9, 0x00, set_sensor_dbus_state_simple, "setValue", "Disabled", ""}, // OCC Inactive 0
 	{0xe9, 0x01, set_sensor_dbus_state_simple, "setValue", "Enabled", ""},   // OCC Active 1
 	{0x07, 0x07, set_sensor_dbus_state_simple, "setPresent", "True", "False"},
-	{0x07, 0x08, set_sensor_dbus_state_simple, "setFault",   "True", ""},
+	{0x07, 0x08, set_sensor_dbus_state_simple, "setFault",   "True", "False"},
 	{0x0C, 0x06, set_sensor_dbus_state_simple, "setPresent", "True", "False"},
-	{0x0C, 0x04, set_sensor_dbus_state_simple, "setFault",   "True", ""},
+	{0x0C, 0x04, set_sensor_dbus_state_simple, "setFault",   "True", "False"},
 	{0x0F, 0x02, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"},
 	{0x0F, 0x01, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"},
 	{0x0F, 0x00, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"},
-	{0xC7, 0x01, set_sensor_dbus_state_simple, "setFault", "True", ""},
+	{0xC7, 0x01, set_sensor_dbus_state_simple, "setFault", "True", "False"},
 	{0xc3, 0x00, set_sensor_dbus_state_osbootcount, "setValue", "" ,""},
 	{0x1F, 0x00, set_sensor_dbus_state_simple, "setValue", "Boot completed (00)", ""},
 	{0x1F, 0x01, set_sensor_dbus_state_simple, "setValue", "Boot completed (01)", ""},
@@ -170,6 +196,11 @@
 	{0x1F, 0x04, set_sensor_dbus_state_simple, "setValue", "CD-ROM boot completed", ""},
 	{0x1F, 0x05, set_sensor_dbus_state_simple, "setValue", "ROM boot completed", ""},
 	{0x1F, 0x06, set_sensor_dbus_state_simple, "setValue", "Boot completed (06)", ""},
+	{0x12, 0x00, set_sensor_dbus_state_system_event, "setValue", "", ""},
+	{0x12, 0x01, set_sensor_dbus_state_system_event, "setValue", "", ""},
+	{0x12, 0x02, set_sensor_dbus_state_system_event, "setValue", "", ""},
+	{0x12, 0x03, set_sensor_dbus_state_system_event, "setValue", "", ""},
+	{0x12, 0x04, set_sensor_dbus_state_system_event, "setValue", "", ""},
 
 	{0xFF, 0xFF, NULL, "", "", ""}
 };
diff --git a/sensorhandler.C b/sensorhandler.C
index cd57dd4..39de660 100644
--- a/sensorhandler.C
+++ b/sensorhandler.C
@@ -3,6 +3,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdint.h>
+#include <systemd/sd-bus.h>
 
 extern int updateSensorRecordFromSSRAESC(const void *);
 extern int find_interface_property_fru_type(dbus_interface_t *interface, const char *property_name, char *property_value) ;
@@ -29,15 +30,23 @@
     {0xe9, 0x09, "OccStatus"},  // E9 is an internal mapping to handle sensor type code os 0x09
     {0xC3, 0x6F, "BootCount"},
     {0x1F, 0x6F, "OperatingSystemStatus"},
+    {0x12, 0x6F, "SYSTEM_EVENT"},
+    {0xC7, 0x03, "SYSTEM"},
+    {0xC7, 0x03, "MAIN_PLANAR"},
+    {0xC2, 0x6F, "PowerCap"},
     {0xFF, 0x00, ""},
 };
 
 
-
 struct sensor_data_t {
     uint8_t sennum;
 }  __attribute__ ((packed)) ;
 
+struct sensorreadingresp_t {
+    uint8_t value;
+    uint8_t operation;
+    uint8_t indication[2];
+}  __attribute__ ((packed)) ;
 
 uint8_t dbus_to_sensor_type(char *p) {
 
@@ -102,6 +111,10 @@
     return r;
  }
 
+
+
+
+
 ipmi_ret_t ipmi_sen_get_sensor_type(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                              ipmi_request_t request, ipmi_response_t response,
                              ipmi_data_len_t data_len, ipmi_context_t context)
@@ -119,15 +132,7 @@
 
     // HACK UNTIL Dbus gets updated or we find a better way
     if (buf[0] == 0) {
-
-        switch(reqptr->sennum) {
-            case 0x35 : buf[0] = 0x12; buf[1] = 0x6F; break;
-            case 0x37 : buf[0] = 0xC7; buf[1] = 0x03; break;
-            case 0x38 : buf[0] = 0xC7; buf[1] = 0x03; break;
-            case 0x39 : buf[0] = 0xC7; buf[1] = 0x03; break;
-            case 0x3A : buf[0] = 0xC7; buf[1] = 0x03; break;
-            default: rc = IPMI_CC_SENSOR_INVALID;
-        }
+        rc = IPMI_CC_SENSOR_INVALID;
     }
 
 
@@ -145,9 +150,6 @@
 {
     sensor_data_t *reqptr = (sensor_data_t*)request;
     ipmi_ret_t rc = IPMI_CC_OK;
-    unsigned short rlen;
-
-    rlen = (unsigned short) *data_len;
 
     printf("IPMI SET_SENSOR [0x%02x]\n",reqptr->sennum);
 
@@ -158,6 +160,77 @@
     return rc;
 }
 
+
+ipmi_ret_t ipmi_sen_get_sensor_reading(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+                             ipmi_request_t request, ipmi_response_t response,
+                             ipmi_data_len_t data_len, ipmi_context_t context)
+{
+    sensor_data_t *reqptr = (sensor_data_t*)request;
+    ipmi_ret_t rc = IPMI_CC_SENSOR_INVALID;
+    uint8_t type;
+    sensorreadingresp_t *resp = (sensorreadingresp_t*) response;
+    int r;
+    dbus_interface_t a;
+    sd_bus *bus = ipmid_get_sd_bus_connection();
+    sd_bus_message *reply = NULL;
+    int reading = 0;
+
+
+    printf("IPMI GET_SENSOR_READING [0x%02x]\n",reqptr->sennum);
+
+    r = find_openbmc_path("SENSOR", reqptr->sennum, &a);
+
+    if (r < 0) {
+        fprintf(stderr, "Failed to find Sensor 0x%02x\n", reqptr->sennum);
+        return IPMI_CC_SENSOR_INVALID;
+    }
+
+    type = find_sensor(reqptr->sennum);
+
+    fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n", a.bus, a.path, a.interface);
+
+    *data_len=0;
+
+    switch(type) {
+        case 0xC3:
+        case 0xC2:
+            r = sd_bus_get_property(bus,a.bus, a.path, a.interface, "value", NULL, &reply, "i");
+            if (r < 0) {
+                fprintf(stderr, "Failed to call sd_bus_get_property:%d,  %s\n", r, strerror(-r));
+                fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n",
+                        a.bus, a.path, a.interface);
+                break;
+            }
+
+            r = sd_bus_message_read(reply, "i", &reading);
+            if (r < 0) {
+                fprintf(stderr, "Failed to read sensor: %s\n", strerror(-r));
+                break;
+            }
+
+            printf("Contents of a 0x%02x is 0x%02x\n", type, reading);
+
+            rc = IPMI_CC_OK;
+            *data_len=sizeof(sensorreadingresp_t);
+
+            resp->value         = (uint8_t)reading;
+            resp->operation     = 0;
+            resp->indication[0] = 0;
+            resp->indication[1] = 0;
+            break;
+
+        default:
+            *data_len=0;
+            rc = IPMI_CC_SENSOR_INVALID;
+            break;
+    }
+
+
+    reply = sd_bus_message_unref(reply);
+
+    return rc;
+}
+
 ipmi_ret_t ipmi_sen_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                              ipmi_request_t request, ipmi_response_t response,
                              ipmi_data_len_t data_len, ipmi_context_t context)
@@ -182,5 +255,8 @@
     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_SENSOR, IPMI_CMD_SET_SENSOR);
     ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_SET_SENSOR, NULL, ipmi_sen_set_sensor);
 
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_READING);
+    ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_READING, NULL, ipmi_sen_get_sensor_reading);
+
     return;
 }
diff --git a/sensorhandler.h b/sensorhandler.h
index 7b89a18..dd940dc 100644
--- a/sensorhandler.h
+++ b/sensorhandler.h
@@ -6,6 +6,7 @@
 // IPMI commands for net functions.
 enum ipmi_netfn_sen_cmds
 {
+    IPMI_CMD_GET_SENSOR_READING = 0x2D,
     IPMI_CMD_GET_SENSOR_TYPE = 0x2F,
     IPMI_CMD_SET_SENSOR      = 0x30,
 };
diff --git a/storageaddsel.C b/storageaddsel.C
index 64b0e6a..3343772 100644
--- a/storageaddsel.C
+++ b/storageaddsel.C
@@ -80,18 +80,39 @@
 
 	FILE *fp;
 	size_t size = 0;
+	int r;
 
 	if ((fp = fopen(fn, "rb")) != NULL) {
 
-		fseek(fp, 0, SEEK_END);
-		size = ftell(fp);
-		fseek(fp, 0, SEEK_SET);
+		r = fseek(fp, 0, SEEK_END);
+		if (r) {
+			fprintf(stderr,"Fseek failed\n");
+			goto fclose_fp;
+		}
 
-		size = 0x100;
+		size = ftell(fp);
+		if (size == -1L) {
+			fprintf(stderr,"Ftell failed for %s\n", strerror(errno));
+			size = 0;
+			goto fclose_fp;
+		}
+
+		r = fseek(fp, 0, SEEK_SET);
+		if (r) {
+			fprintf(stderr,"Fseek failed\n");
+			size = 0;
+			goto fclose_fp;
+		}
 
 		*buffer = new uint8_t [size];
 
-		fread(*buffer, 1, size, fp);
+		r = fread(*buffer, 1, size, fp);
+		if ( r != size) {
+			size = 0;
+			fprintf(stderr,"Fread failed\n");
+		}
+
+fclose_fp:
 		fclose(fp);
 	}
 
@@ -120,9 +141,10 @@
 
 	find_openbmc_path("SENSOR", sensor, &dbusint);
 
+	// Simply no associations if the sensor can not be found
 	if (strlen(dbusint.path) < 1) {
-		printf("Sensor not found\n");
-		snprintf(dbusint.path, sizeof(dbusint.path), "0x%x", sensor);
+		printf("Sensor 0x%x not found\n", sensor);
+		memset(dbusint.path,0,sizeof(dbusint.path));
 	}
 
 	asprintf(m, "%s", dbusint.path);
@@ -136,7 +158,6 @@
 
 
 	ipmi_add_sel_request_t *p;
-	int r;
 	char *m;
 
 	p =  ( ipmi_add_sel_request_t *) buffer;
@@ -156,7 +177,7 @@
 	sd_bus *mbus = NULL;
     sd_bus_error error = SD_BUS_ERROR_NULL;
     sd_bus_message *reply = NULL, *m=NULL;
-    uint16_t *pty;
+    uint16_t x;
     int r;
 
     mbus = ipmid_get_sd_bus_connection();
@@ -168,88 +189,65 @@
     									"acceptHostMessage");
     if (r < 0) {
         fprintf(stderr, "Failed to add the method object: %s\n", strerror(-r));
-        return -1;
+        goto finish;
     }
 
     r = sd_bus_message_append(m, "sss", desc, sev, details);
     if (r < 0) {
         fprintf(stderr, "Failed add the message strings : %s\n", strerror(-r));
-        return -1;
+        goto finish;
     }
 
     r = sd_bus_message_append_array(m, 'y', debug, debuglen);
     if (r < 0) {
         fprintf(stderr, "Failed to add the raw array of bytes: %s\n", strerror(-r));
-        return -1;
+        goto finish;
     }
-
     // Call the IPMI responder on the bus so the message can be sent to the CEC
     r = sd_bus_call(mbus, m, 0, &error, &reply);
     if (r < 0) {
-        fprintf(stderr, "Failed to call the method: %s", strerror(-r));
-        return -1;
+        fprintf(stderr, "Failed to call the method: %s %s\n", __FUNCTION__, strerror(-r));
+        goto finish;
     }
-
-    r = sd_bus_message_read(reply, "q", &pty);
+    r = sd_bus_message_read(reply, "q", &x);
     if (r < 0) {
         fprintf(stderr, "Failed to get a rc from the method: %s\n", strerror(-r));
-    } else {
-        r = *pty;
     }
 
 finish:
     sd_bus_error_free(&error);
-    sd_bus_message_unref(m);
-    sd_bus_message_unref(reply);
-
+    m = sd_bus_message_unref(m);
+    reply = sd_bus_message_unref(reply);
     return r;
 }
 
 
 void send_esel(uint16_t recordid) {
-	char *desc, *assoc, *ascii;
+	char *desc, *assoc;
 	const char *sev;
 	uint8_t *buffer = NULL;
-	char *path, *pathsent;
+	const char *path = "/tmp/esel";
 	size_t sz;
 	int r;
 
-	uint8_t hack[] = {0x30, 0x32, 0x34};
-
-	asprintf(&path,"%s%04x", "/tmp/esel", recordid);
-
 	sz = getfilestream(path, &buffer);
-
 	if (sz == 0) {
 		printf("Error file does not exist %d\n",__LINE__);
-		free(path);
 		return;
 	}
 
-
 	sev = create_esel_severity(buffer);
-
 	create_esel_association(buffer, &assoc);
-
 	create_esel_description(buffer, sev, &desc);
 
+	r = send_esel_to_dbus(desc, sev, assoc, buffer, sz);
+	if (r < 0) {
+		fprintf(stderr, "Failed to send esel to dbus\n");
+	}
 
-	// TODO until ISSUE https://github.com/openbmc/rest-dbus/issues/2
-	// I cant send extended ascii chars.  So 0,2,4 for now...
-	r = send_esel_to_dbus(desc, sev, assoc, hack, 3);
-
-	asprintf(&pathsent,"%s_%d", path, r);
-
-
-	rename(path, pathsent);
-
-	free(path);
-	free(pathsent);
 	free(assoc);
 	free(desc);
-
 	delete[] buffer;
 
-
 	return;
 }
diff --git a/storagehandler.C b/storagehandler.C
index 1459f94..9622ed9 100644
--- a/storagehandler.C
+++ b/storagehandler.C
@@ -2,6 +2,7 @@
 #include <string.h>
 #include <stdint.h>
 #include <time.h>
+#include <sys/time.h>
 #include <arpa/inet.h>
 
 #include "storagehandler.h"
@@ -12,7 +13,7 @@
 
 
 unsigned int   g_sel_time    = 0xFFFFFFFF;
-unsigned short g_sel_reserve = 0x1;
+extern unsigned short g_sel_reserve;
 
 ipmi_ret_t ipmi_storage_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                               ipmi_request_t request, ipmi_response_t response,
@@ -52,14 +53,26 @@
                               ipmi_request_t request, ipmi_response_t response,
                               ipmi_data_len_t data_len, ipmi_context_t context)
 {
-    unsigned int *bufftype = (unsigned int *) request;
+    uint32_t* secs = (uint32_t*)request;
 
     printf("Handling Set-SEL-Time:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
-    printf("Data: 0x%X]\n",*bufftype);
+    printf("Data: 0x%X]\n",*secs);
 
-    g_sel_time = *bufftype;
-
+    struct timeval sel_time;
+    sel_time.tv_sec = le32toh(*secs);
+    sel_time.tv_usec = 0;
     ipmi_ret_t rc = IPMI_CC_OK;
+    int rct = settimeofday(&sel_time, NULL);
+
+    if(rct == 0)
+    {
+	system("hwclock -w");
+    }
+    else
+    {
+        printf("settimeofday() failed\n");
+        rc = IPMI_CC_UNSPECIFIED_ERROR;
+    }
     *data_len = 0;
     return rc;
 }
@@ -87,17 +100,19 @@
     return rc;
 }
 
-
-
 ipmi_ret_t ipmi_storage_reserve_sel(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                               ipmi_request_t request, ipmi_response_t response,
                               ipmi_data_len_t data_len, ipmi_context_t context)
 {
+    unsigned short res_id;
 
     ipmi_ret_t rc = IPMI_CC_OK;
 
-    printf("IPMI Handling RESERVE-SEL 0x%04x\n", g_sel_reserve);
+    // IPMI spec, Reservation ID, the value simply increases against each execution of reserve_sel command.
+    if( ++g_sel_reserve == 0)
+        g_sel_reserve = 1;
 
+    printf("IPMI Handling RESERVE-SEL 0x%04x\n", g_sel_reserve);
 
     *data_len = sizeof(g_sel_reserve);
 
@@ -125,8 +140,6 @@
     // Pack the actual response
     memcpy(response, &p->eventdata[1], 2);
 
-    // TODO This code should grab the completed partial esel located in
-    // the /tmp/esel0100 file and commit it to the error log handler.
     send_esel(recordid);
 
     return rc;
diff --git a/testit.C b/testit.C
index bfd9334..a0cd2c1 100644
--- a/testit.C
+++ b/testit.C
@@ -37,25 +37,31 @@
 char g_results_value[64];
 
 
-int set_sensor_dbus_state_v(uint8_t number, const char *method, char *value) {
-    printf("Attempting to log Variant Sensor 0x%02x via %s with a value of %s\n",
-        number, method, value);
+int set_sensor_dbus_state_s(unsigned char number, const char *member, const char *value) {
+    printf("Attempting to log 0x%02x via %s with a value of %s\n",
+        number, member, value);
 
-    strcpy(g_results_method, method);
+    strcpy(g_results_method, member);
     strcpy(g_results_value, value);
 
     return 0;
 }
 
-int set_sensor_dbus_state(uint8_t number, const char *method, const char *value) {
+int set_sensor_dbus_state_y(unsigned char number, char const* member, uint8_t value) {
+    
+    char val[2];
 
-	printf("Attempting to log Sensor 0x%02x via %s with a value of %s\n",
-		number, method, value);
 
-    strcpy(g_results_method, method);
-    strcpy(g_results_value, value);
+    printf("Attempting to log Variant Sensor 0x%02x via %s with a value of 0x%02x\n",
+        number, member, value);
 
-	return 0;
+
+    snprintf(val, 2, "%d", value);
+
+    strcpy(g_results_method, member);
+    strcpy(g_results_value, val);
+
+    return 0;
 }
 
 
diff --git a/transporthandler.C b/transporthandler.C
index ca8522d..3b4cf07 100644
--- a/transporthandler.C
+++ b/transporthandler.C
@@ -1,13 +1,127 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdint.h>
+#include <arpa/inet.h>
+#include <string>
 
 #include "ipmid-api.h"
 #include "ipmid.H"
 #include "transporthandler.h"
 
+#define SYSTEMD_NETWORKD_DBUS 1
+
+#ifdef SYSTEMD_NETWORKD_DBUS
+#include <systemd/sd-bus.h>
+#endif
+
+// OpenBMC System Manager dbus framework
+const char  *app   =  "org.openbmc.NetworkManager";
+const char  *obj   =  "/org/openbmc/NetworkManager/Interface";
+const char  *ifc   =  "org.openbmc.NetworkManager";
+
+const char *nwinterface = "eth0";
+
+const int SIZE_MAC = 18; //xx:xx:xx:xx:xx:xx
+
+char new_ipaddr  [INET_ADDRSTRLEN] = "";
+char new_netmask [INET_ADDRSTRLEN] = "";
+char new_gateway [INET_ADDRSTRLEN] = "";
+
+const uint8_t SET_COMPLETE = 0;
+const uint8_t SET_IN_PROGRESS = 1;
+const uint8_t SET_COMMIT_WRITE = 2; //Optional
+const uint8_t SET_IN_PROGRESS_RESERVED = 3; //Reserved
+
+// Status of Set-In-Progress Parameter (# 0)
+uint8_t lan_set_in_progress = SET_COMPLETE;
+
+
+
 void register_netfn_transport_functions() __attribute__((constructor));
 
+// Helper Function to get IP Address/NetMask/Gateway from Network Manager or Cache
+// based on Set-In-Progress State
+ipmi_ret_t getNetworkData(uint8_t lan_param, uint8_t * data)
+{
+    sd_bus *bus = ipmid_get_sd_bus_connection();
+    sd_bus_message *reply = NULL;
+    sd_bus_error error = SD_BUS_ERROR_NULL;
+    int family;
+    unsigned char prefixlen;
+    char* ipaddr = NULL;
+    unsigned long mask = 0xFFFFFFFF;
+    char* gateway = NULL;
+    int r = 0;
+    ipmi_ret_t rc = IPMI_CC_OK;
+
+    r = sd_bus_call_method(bus, app, obj, ifc, "GetAddress4", &error,
+                            &reply, "s", nwinterface);
+    if(r < 0)
+    {
+        fprintf(stderr, "Failed to call Get Method: %s\n", strerror(-r));
+        rc = IPMI_CC_UNSPECIFIED_ERROR;
+        goto cleanup;
+    }
+
+    r = sd_bus_message_read(reply, "iyss", &family, &prefixlen, &ipaddr, &gateway);
+    if(r < 0)
+    {
+        fprintf(stderr, "Failed to get a response: %s\n", strerror(-rc));
+        rc = IPMI_CC_RESPONSE_ERROR;
+        goto cleanup;
+    }
+
+    printf("N/W data from HW %s:%d:%s:%s\n", family==AF_INET?"IPv4":"IPv6", prefixlen, ipaddr,gateway);
+    printf("N/W data from Cache: %s:%s:%s\n", new_ipaddr, new_netmask, new_gateway);
+
+    if(lan_param == LAN_PARM_IP)
+    {
+        if(lan_set_in_progress == SET_COMPLETE)
+        {
+            std::string ipaddrstr(ipaddr);
+            inet_pton(AF_INET, ipaddrstr.c_str(),(void *)data);
+        }
+        else if(lan_set_in_progress == SET_IN_PROGRESS)
+        {
+            inet_pton(AF_INET, new_ipaddr, (void *)data);
+        }
+    }
+    else if(lan_param == LAN_PARM_SUBNET)
+    {
+        if(lan_set_in_progress == SET_COMPLETE)
+         {
+            mask = htonl(mask<<(32-prefixlen));
+            memcpy(data, &mask, 4);
+         }
+         else if(lan_set_in_progress == SET_IN_PROGRESS)
+         {
+             inet_pton(AF_INET, new_netmask, (void *)data);
+         }
+    }
+    else if(lan_param == LAN_PARM_GATEWAY)
+    {
+        if(lan_set_in_progress == SET_COMPLETE)
+         {
+            std::string gatewaystr(gateway);
+            inet_pton(AF_INET, gatewaystr.c_str(), (void *)data);
+         }
+         else if(lan_set_in_progress == SET_IN_PROGRESS)
+         {
+             inet_pton(AF_INET, new_gateway,(void *)data);
+         }
+    }
+    else
+    {
+        rc = IPMI_CC_PARM_OUT_OF_RANGE;
+    }
+
+cleanup:
+    sd_bus_error_free(&error);
+    reply = sd_bus_message_unref(reply);
+
+    return rc;
+}
+
 ipmi_ret_t ipmi_transport_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                               ipmi_request_t request, ipmi_response_t response,
                               ipmi_data_len_t data_len, ipmi_context_t context)
@@ -31,9 +145,10 @@
 {
     ipmi_ret_t rc = IPMI_CC_OK;
     *data_len = 0;
-
-    int i = 0;
-    char syscmd[128];
+    sd_bus *bus = ipmid_get_sd_bus_connection();
+    sd_bus_message *reply = NULL;
+    sd_bus_error error = SD_BUS_ERROR_NULL;
+    int r = 0;
 
     printf("IPMI SET_LAN\n");
 
@@ -43,27 +158,90 @@
     // TODO Add the rest of the parameters like setting auth type
     // TODO Add error handling
 
-    if (reqptr->parameter == 3) // IP
+    if (reqptr->parameter == LAN_PARM_IP)
     {
-        sprintf(syscmd, "ifconfig eth0 %d.%d.%d.%d", reqptr->data[0], reqptr->data[1], reqptr->data[2], reqptr->data[3]);
-        system(syscmd);
+        snprintf(new_ipaddr, INET_ADDRSTRLEN, "%d.%d.%d.%d",
+            reqptr->data[0], reqptr->data[1], reqptr->data[2], reqptr->data[3]);
     }
-    else if (reqptr->parameter == 6) // Subnet
+    else if (reqptr->parameter == LAN_PARM_MAC)
     {
-        sprintf(syscmd, "ifconfig eth0 netmask %d.%d.%d.%d", reqptr->data[0], reqptr->data[1], reqptr->data[2], reqptr->data[3]);
-        system(syscmd);
+        char mac[SIZE_MAC];
+
+        snprintf(mac, SIZE_MAC, "%02x:%02x:%02x:%02x:%02x:%02x",
+                reqptr->data[0],
+                reqptr->data[1],
+                reqptr->data[2],
+                reqptr->data[3],
+                reqptr->data[4],
+                reqptr->data[5]);
+
+        r = sd_bus_call_method(bus, app, obj, ifc, "SetHwAddress", &error,
+                                &reply, "ss", nwinterface, mac);
+        if(r < 0)
+        {
+            fprintf(stderr, "Failed to call the method: %s\n", strerror(-r));
+            rc = IPMI_CC_UNSPECIFIED_ERROR;
+        }
     }
-    else if (reqptr->parameter == 12) // Gateway
+    else if (reqptr->parameter == LAN_PARM_SUBNET)
     {
-        sprintf(syscmd, "route add default gw %d.%d.%d.%d", reqptr->data[0], reqptr->data[1], reqptr->data[2], reqptr->data[3]);
-        system(syscmd);
+        snprintf(new_netmask, INET_ADDRSTRLEN, "%d.%d.%d.%d",
+            reqptr->data[0], reqptr->data[1], reqptr->data[2], reqptr->data[3]);
+    }
+    else if (reqptr->parameter == LAN_PARM_GATEWAY)
+    {
+        snprintf(new_gateway, INET_ADDRSTRLEN, "%d.%d.%d.%d",
+            reqptr->data[0], reqptr->data[1], reqptr->data[2], reqptr->data[3]);
+    }
+    else if (reqptr->parameter == LAN_PARM_INPROGRESS)
+    {
+        if(reqptr->data[0] == SET_COMPLETE) // Set Complete
+        {
+            lan_set_in_progress = SET_COMPLETE;
+            // Apply the IP settings once IP Address, Netmask and Gateway  is set
+            if (!strcmp(new_ipaddr, "") || !strcmp (new_netmask, "") || !strcmp (new_gateway, ""))
+            {
+                printf("ERROR: Incomplete LAN Parameters\n");
+            }
+            else
+            {
+
+                r = sd_bus_call_method(bus,            // On the System Bus
+                                        app,            // Service to contact
+                                        obj,            // Object path
+                                        ifc,            // Interface name
+                                        "SetAddress4",  // Method to be called
+                                        &error,         // object to return error
+                                        &reply,         // Response message on success
+                                        "ssss",         // input message (Interface, IP Address, Netmask, Gateway)
+                                        nwinterface,    // eth0
+                                        new_ipaddr,
+                                        new_netmask,
+                                        new_gateway);
+                if(r < 0)
+                {
+                    fprintf(stderr, "Failed to set network data %s:%s:%s %s\n", new_ipaddr, new_netmask, new_gateway, error.message);
+                    rc = IPMI_CC_UNSPECIFIED_ERROR;
+                }
+                memset(new_ipaddr, 0, INET_ADDRSTRLEN);
+                memset(new_netmask, 0, INET_ADDRSTRLEN);
+                memset(new_gateway, 0, INET_ADDRSTRLEN);
+            }
+        }
+        else if(reqptr->data[0] == SET_IN_PROGRESS) // Set In Progress
+        {
+            lan_set_in_progress = SET_IN_PROGRESS;
+        }
     }
     else
     {
         fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
-        return IPMI_CC_PARM_NOT_SUPPORTED;
+        rc = IPMI_CC_PARM_NOT_SUPPORTED;
     }
 
+    sd_bus_error_free(&error);
+    reply = sd_bus_message_unref(reply);
+
     return rc;
 }
 
@@ -80,9 +258,11 @@
 {
     ipmi_ret_t rc = IPMI_CC_OK;
     *data_len = 0;
-
+    sd_bus *bus = ipmid_get_sd_bus_connection();
+    sd_bus_message *reply = NULL;
+    sd_bus_error error = SD_BUS_ERROR_NULL;
+    int r = 0;
     const uint8_t current_revision = 0x11; // Current rev per IPMI Spec 2.0
-    char syscmd[128];
     int i = 0;
 
     printf("IPMI GET_LAN\n");
@@ -100,87 +280,103 @@
     // TODO Use dbus interface once available. For now use ip cmd.
     // TODO Add the rest of the parameters, like gateway
 
-    if (reqptr->parameter == 0) // In progress
+    if (reqptr->parameter == LAN_PARM_INPROGRESS)
     {
-        uint8_t buf[] = {current_revision,0};
+        uint8_t buf[] = {current_revision, lan_set_in_progress};
         *data_len = sizeof(buf);
         memcpy(response, &buf, *data_len);
-        return IPMI_CC_OK;
     }
-    else if (reqptr->parameter == 1) // Authentication support
+    else if (reqptr->parameter == LAN_PARM_AUTHSUPPORT)
     {
         uint8_t buf[] = {current_revision,0x04};
         *data_len = sizeof(buf);
         memcpy(response, &buf, *data_len);
-        return IPMI_CC_OK;
     }
-    else if (reqptr->parameter == 2) // Authentication enables
+    else if (reqptr->parameter == LAN_PARM_AUTHENABLES)
     {
         uint8_t buf[] = {current_revision,0x04,0x04,0x04,0x04,0x04};
         *data_len = sizeof(buf);
         memcpy(response, &buf, *data_len);
-        return IPMI_CC_OK;
     }
-    else if (reqptr->parameter == 3) // IP
+    else if ((reqptr->parameter == LAN_PARM_IP) || (reqptr->parameter == LAN_PARM_SUBNET) || (reqptr->parameter == LAN_PARM_GATEWAY))
     {
-        //string to parse: inet xx.xx.xxx.xxx/xx
-
         uint8_t buf[5];
-        memcpy((void*)&buf[0], &current_revision, 1);
 
-        for (i=0; i<4; i++)
+        *data_len = sizeof(current_revision);
+        memcpy(buf, &current_revision, *data_len);
+
+        if(getNetworkData(reqptr->parameter, &buf[1]) == IPMI_CC_OK)
         {
-            char ip[5];
-
-            sprintf(syscmd, "ip address show dev eth0|grep inet|cut -d'/' -f1|cut -d' ' -f 6|cut -d'.' -f%d|head -n1", i+1);
-            FILE *fp = popen(syscmd, "r");
-
-            memset(ip,0,sizeof(ip));
-            while (fgets(ip, sizeof(ip), fp) != 0)
-            {
-                int tmpip = strtoul(ip, NULL, 10);
-                memcpy((void*)&buf[i+1], &tmpip, 1);
-            }
-            pclose(fp);
+            *data_len = sizeof(buf);
+            memcpy(response, &buf, *data_len);
         }
-
-        *data_len = sizeof(buf);
-        memcpy(response, &buf, *data_len);
-        return IPMI_CC_OK;
+        else
+        {
+            rc = IPMI_CC_UNSPECIFIED_ERROR;
+        }
     }
-    else if (reqptr->parameter == 5) // MAC
+    else if (reqptr->parameter == LAN_PARM_MAC)
     {
         //string to parse: link/ether xx:xx:xx:xx:xx:xx
-
         uint8_t buf[7];
+        char *eaddr1 = NULL;
+
+        r = sd_bus_call_method(bus, app, obj, ifc, "GetHwAddress", &error,
+                                &reply, "s", nwinterface);
+        if(r < 0)
+        {
+            fprintf(stderr, "Failed to call Get Method: %s\n", strerror(-r));
+            rc = IPMI_CC_UNSPECIFIED_ERROR;
+            goto cleanup;
+        }
+
+        r = sd_bus_message_read(reply, "s", &eaddr1);
+        if (r < 0)
+        {
+            fprintf(stderr, "Failed to get a response: %s", strerror(-r));
+            rc = IPMI_CC_UNSPECIFIED_ERROR;
+            goto cleanup;
+        }
+        if (eaddr1 == NULL)
+        {
+            fprintf(stderr, "Failed to get a valid response: %s", strerror(-r));
+            rc = IPMI_CC_UNSPECIFIED_ERROR;
+            goto cleanup;
+        }
+
         memcpy((void*)&buf[0], &current_revision, 1);
 
-        for (i=0; i<6; i++)
+        char *tokptr = NULL;
+        char* digit = strtok_r(eaddr1, ":", &tokptr);
+        if (digit == NULL)
         {
-            char mac[4];
+            fprintf(stderr, "Unexpected MAC format: %s", eaddr1);
+            rc = IPMI_CC_RESPONSE_ERROR;
+            goto cleanup;
+        }
 
-            sprintf(syscmd, "ip address show dev eth0|grep link|cut -d' ' -f 6|cut -d':' -f%d", i+1);
-            FILE *fp = popen(syscmd, "r");
-
-            memset(mac,0,sizeof(mac));
-            while (fgets(mac, sizeof(mac), fp) != 0)
-            {
-                int tmpmac = strtoul(mac, NULL, 16);
-                memcpy((void*)&buf[i+1], &tmpmac, 1);
-            }
-            pclose(fp);
+        i=0;
+        while (digit != NULL)
+        {
+            int resp_byte = strtoul(digit, NULL, 16);
+            memcpy((void*)&buf[i+1], &resp_byte, 1);
+            i++;
+            digit = strtok_r(NULL, ":", &tokptr);
         }
 
         *data_len = sizeof(buf);
         memcpy(response, &buf, *data_len);
-        return IPMI_CC_OK;
     }
     else
     {
         fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
-        return IPMI_CC_PARM_NOT_SUPPORTED;
+        rc = IPMI_CC_PARM_NOT_SUPPORTED;
     }
 
+cleanup:
+    sd_bus_error_free(&error);
+    reply = sd_bus_message_unref(reply);
+
     return rc;
 }
 
@@ -197,4 +393,3 @@
 
     return;
 }
-
diff --git a/transporthandler.h b/transporthandler.h
index 49b1d95..ce7842b 100644
--- a/transporthandler.h
+++ b/transporthandler.h
@@ -15,4 +15,13 @@
     IPMI_CC_PARM_NOT_SUPPORTED = 0x80,
 };
 
+// Parameters
+static const int LAN_PARM_INPROGRESS  = 0;
+static const int LAN_PARM_AUTHSUPPORT = 1;
+static const int LAN_PARM_AUTHENABLES = 2;
+static const int LAN_PARM_IP          = 3;
+static const int LAN_PARM_MAC         = 5;
+static const int LAN_PARM_SUBNET      = 6;
+static const int LAN_PARM_GATEWAY     = 12;
+
 #endif