[PATCH phosphor-host-ipmid] Moved from gdbus to sdbus. Fixed sdbus memory leak. Added commands to get a Palmetto to IPL further

OpenBMC Patches patches at stwcx.xyz
Mon Oct 12 11:33:49 AEDT 2015


From: Chris Austen <austenc at us.ibm.com>

---
 Makefile         |  29 ++++-
 apphandler.C     | 151 ++++++++++++++++++++++++-
 apphandler.h     |   6 +
 ipmid-api.h      |   3 +-
 ipmid.C          | 334 ++++++++++++++++++++++++++++++++++++-------------------
 ipmid.H          |   2 +-
 oemhandler.C     | 105 +++++++++++++++++
 oemhandler.h     |  12 ++
 sensorhandler.C  | 225 +++++++++++++++++++++++++++++++++++++
 sensorhandler.h  |  13 +++
 storagehandler.C | 222 ++++++++++++++++++++++++++++++++++++
 storagehandler.h |  16 +++
 12 files changed, 993 insertions(+), 125 deletions(-)
 create mode 100644 oemhandler.C
 create mode 100644 oemhandler.h
 create mode 100644 sensorhandler.C
 create mode 100644 sensorhandler.h
 create mode 100644 storagehandler.C
 create mode 100644 storagehandler.h

diff --git a/Makefile b/Makefile
index 4baf209..929ef21 100755
--- a/Makefile
+++ b/Makefile
@@ -2,19 +2,36 @@ CXX ?= $(CROSS_COMPILE)g++
 
 DAEMON = ipmid
 DAEMON_OBJ = $(DAEMON).o
-LIB_OBJ = apphandler.o
-LIBS = libapphandler.so
+LIB_APP_OBJ     = apphandler.o
+LIB_SEN_OBJ     = sensorhandler.o
+LIB_STORAGE_OBJ = storagehandler.o
+LIB_OEM_OBJ     = oemhandler.o
 
-INC_FLAG += $(shell pkg-config --cflags glib-2.0 gio-unix-2.0) -I. -O2 --std=gnu++11
-LIB_FLAG += $(shell pkg-config --libs glib-2.0 gio-unix-2.0) -rdynamic
+LIB_APP     = libsenhandler.so
+LIB_SEN     = libapphandler.so
+LIB_STORAGE = libstoragehandler.so
+LIB_OEM     = liboemhandler.so
+
+INC_FLAG += $(shell pkg-config --cflags --libs libsystemd) -I. -O2 --std=gnu++11
+LIB_FLAG += $(shell pkg-config  --libs libsystemd) -rdynamic
 IPMID_PATH ?= -DHOST_IPMI_LIB_PATH=\"/usr/lib/host-ipmid/\" 
 
-all: $(DAEMON) $(LIBS)
+all: $(DAEMON) $(LIB_APP) $(LIB_SEN) $(LIB_STORAGE) $(LIB_OEM)
 
 %.o: %.C
 	$(CXX) -fpic -c $< $(CXXFLAGS) $(INC_FLAG) $(IPMID_PATH) -o $@
+	
+
+$(LIB_APP): $(LIB_APP_OBJ)
+	$(CXX) $^ -shared $(LDFLAGS) $(LIB_FLAG) -o $@
+
+$(LIB_OEM): $(LIB_OEM_OBJ)
+	$(CXX) $^ -shared $(LDFLAGS) $(LIB_FLAG) -o $@
+
+$(LIB_STORAGE): $(LIB_STORAGE_OBJ)
+	$(CXX) $^ -shared $(LDFLAGS) $(LIB_FLAG) -o $@
 
-$(LIBS): $(LIB_OBJ)
+$(LIB_SEN): $(LIB_SEN_OBJ)
 	$(CXX) $^ -shared $(LDFLAGS) $(LIB_FLAG) -o $@
 
 $(DAEMON): $(DAEMON_OBJ)
diff --git a/apphandler.C b/apphandler.C
index c86997f..1058b82 100755
--- a/apphandler.C
+++ b/apphandler.C
@@ -1,12 +1,67 @@
 #include "apphandler.h"
 #include "ipmid-api.h"
+#include "ipmid.H"
 #include <stdio.h>
 #include <string.h>
 
 void register_netfn_app_cap_bit() __attribute__((constructor));
 void register_netfn_app_wildcard() __attribute__((constructor));
+void register_netfn_app_reset_wd() __attribute__((constructor));
+void register_netfn_app_set_wd() __attribute__((constructor));
+void register_netfn_app_get_device_id() __attribute__((constructor));
+void register_netfn_app_set_acpi_power_state() __attribute__((constructor));
+void register_netfn_app_read_event()  __attribute__((constructor));
 
-ipmi_ret_t ipmi_app_cap_bit_handler(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 
+
+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 Ignoring for now\n");
+    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)
+{
+    ipmi_ret_t rc = IPMI_CC_OK;
+    *data_len = 0;
+
+    printf("IPMI SET ACPI STATE Ignoring for now\n");
+    return rc;
+}
+
+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;
+
+    // TODO GET REAL VALUES HERE....  I made these ones up because 
+    // we are in bringup mode.  Version Major and Minor can be what we
+    // want like v1.03  but the IANA really should be something that 
+    // we own.  I would suggest getting the IANA from Hostboot as 
+    // long as IBM owns it then no problem.  If some other company 
+    // gave us the IANA to use then use the one we have from the 
+    // FSP ipmi code.
+    unsigned char str[] = {0x00, 0, 1, 1,2, 0xD, 0x49, 0x42, 0x4D, 0x43, 0x40};
+
+    // Data length
+    *data_len = sizeof(str);
+
+    // Pack the actual response
+    memcpy(response, &str, *data_len);
+    return rc;
+}
+
+
+ipmi_ret_t ipmi_app_get_bt_capabilities(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)
 {
@@ -15,7 +70,7 @@ ipmi_ret_t ipmi_app_cap_bit_handler(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
     // Status code.
     ipmi_ret_t rc = IPMI_CC_OK;
 
-    unsigned char str[] = {0x00, 0x01, 0xFE, 0xFF, 0x0A, 0x01};
+    unsigned char str[] = {0x01, MAX_IPMI_BUFFER, MAX_IPMI_BUFFER, 0x0A, 0x01};
 
     // Data length
     *data_len = sizeof(str);
@@ -26,6 +81,60 @@ ipmi_ret_t ipmi_app_cap_bit_handler(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
     return rc;
 }
 
+
+typedef struct {
+    unsigned char  t_use;
+    unsigned char  t_action;
+    unsigned char  preset;
+    unsigned char  flags;
+    unsigned char  ls;
+    unsigned char  ms;
+} SET_WD_DATA ;
+
+
+
+ipmi_ret_t ipmi_app_set_watchdog(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)
+{
+
+    SET_WD_DATA *reqptr = (SET_WD_DATA*) request;
+    unsigned short timer = 0;
+    // Status code.
+    ipmi_ret_t rc = IPMI_CC_OK;
+
+    *data_len = 0;
+
+    timer = (((unsigned short)reqptr->ms) << 8) + reqptr->ls;
+
+    printf("WATCHDOG SET Timer:[0x%X] 100ms intervals\n",timer);
+
+    // TODO: Right here is where we would call some dbus method as a timer.
+    // If the timer expires it would iniate a reboot of the host.
+
+    return rc;
+}
+
+
+ipmi_ret_t ipmi_app_reset_watchdog(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)
+{
+    // Status code.
+    ipmi_ret_t rc = IPMI_CC_OK;
+    *data_len = 0;
+
+    printf("WATCHDOG RESET\n");
+    // TODO Right here is where we would call some sdbus timer.
+    // If your are experiencing dejavu you are right.  the
+    // set and the reset do similar things
+    return rc;
+}
+
+
+
+
+
 ipmi_ret_t ipmi_app_wildcard_handler(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)
@@ -46,7 +155,7 @@ ipmi_ret_t ipmi_app_wildcard_handler(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
 void register_netfn_app_cap_bit()
 {
     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_CAP_BIT);
-    ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CAP_BIT, NULL, ipmi_app_cap_bit_handler);
+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CAP_BIT, NULL, ipmi_app_get_bt_capabilities);
     return;
 }
 
@@ -56,3 +165,39 @@ void register_netfn_app_wildcard()
     ipmi_register_callback(NETFUN_APP, IPMI_CMD_WILDCARD, NULL, ipmi_app_wildcard_handler);
     return;
 }
+
+void register_netfn_app_reset_wd()
+{
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_RESET_WD);
+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_RESET_WD, NULL, ipmi_app_reset_watchdog);
+    return;
+}
+void register_netfn_app_set_wd()
+{
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_SET_WD);
+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_WD, NULL, ipmi_app_set_watchdog);
+    return;
+}
+
+void register_netfn_app_get_device_id()
+{
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_DEVICE_ID);
+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_DEVICE_ID, NULL, ipmi_app_get_device_id);
+    return;
+}
+
+void register_netfn_app_set_acpi_power_state()
+{
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_SET_ACPI);
+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_ACPI, NULL, ipmi_app_set_acpi_power_state);
+    return;
+}
+
+void register_netfn_app_read_event()
+{
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_READ_EVENT);
+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_READ_EVENT, NULL, ipmi_app_read_event);
+    return;
+}
+
+
diff --git a/apphandler.h b/apphandler.h
index 602801b..2c4ea22 100644
--- a/apphandler.h
+++ b/apphandler.h
@@ -5,7 +5,13 @@
 enum ipmi_netfn_app_cmds
 {
     // Get capability bits
+    IPMI_CMD_RESET_WD       = 0x22,
+    IPMI_CMD_SET_WD         = 0x24,
     IPMI_CMD_GET_CAP_BIT    = 0x36,
+    IPMI_CMD_GET_DEVICE_ID  = 0x00,
+    IPMI_CMD_SET_ACPI       = 0x06,
+    IPMI_CMD_READ_EVENT     = 0x35,
+
 };
 
 #endif
diff --git a/ipmid-api.h b/ipmid-api.h
index 615e0d5..03e1cb6 100755
--- a/ipmid-api.h
+++ b/ipmid-api.h
@@ -70,7 +70,8 @@ enum ipmi_net_fns
     NETFUN_STORAGE  =   (0x0a << 2),
     NETFUN_TRANPORT =   (0x0c << 2),
     NETFUN_GRPEXT   =   (0x2c << 2),
-    NETFUN_NONE     =   (0x30 << 2)
+    NETFUN_NONE     =   (0x30 << 2), 
+    NETFUN_OEM_IBM  =   (0x32 << 2)
 };
 
 // IPMI commands for net functions. Since this is to be used both by the ipmi
diff --git a/ipmid.C b/ipmid.C
index 37ac771..38dba91 100644
--- a/ipmid.C
+++ b/ipmid.C
@@ -4,22 +4,82 @@
 #include <unistd.h>
 #include <assert.h>
 #include <dirent.h>
-#include <gio/gio.h>
+#include <systemd/sd-bus.h>
 #include <string.h>
 #include <stdlib.h>
 #include <map>
 #include "ipmid.H"
+#include <sys/time.h>
+#include <errno.h>
+
+
+sd_bus *bus = NULL;
 
 // Channel that is used for OpenBMC Barreleye
 const char * DBUS_NAME = "org.openbmc.HostIpmi";
 const char * OBJ_NAME = "/org/openbmc/HostIpmi/1";
 
+#define FILTER "type='signal',sender='org.openbmc.HostIpmi',member='ReceivedMessage'"
+
+
 typedef std::pair<ipmi_netfn_t, ipmi_cmd_t> ipmi_fn_cmd_t;
 typedef std::pair<ipmid_callback_t, ipmi_context_t> ipmi_fn_context_t;
 
 // 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;
 
+
+
+#ifndef HEXDUMP_COLS
+#define HEXDUMP_COLS 16
+#endif
+
+void hexdump(void *mem, size_t len)
+{
+        unsigned int i, j;
+        
+        for(i = 0; i < len + ((len % HEXDUMP_COLS) ? (HEXDUMP_COLS - len % HEXDUMP_COLS) : 0); i++)
+        {
+                /* print offset */
+                if(i % HEXDUMP_COLS == 0)
+                {
+                        printf("0x%06x: ", i);
+                }
+ 
+                /* print hex data */
+                if(i < len)
+                {
+                        printf("%02x ", 0xFF & ((char*)mem)[i]);
+                }
+                else /* end of block, just aligning for ASCII dump */
+                {
+                        printf("   ");
+                }
+                
+                /* print ASCII dump */
+                if(i % HEXDUMP_COLS == (HEXDUMP_COLS - 1))
+                {
+                        for(j = i - (HEXDUMP_COLS - 1); j <= i; j++)
+                        {
+                                if(j >= len) /* end of block, not really printing */
+                                {
+                                        putchar(' ');
+                                }
+                                else if(isprint(((char*)mem)[j])) /* printable char */
+                                {
+                                        putchar(0xFF & ((char*)mem)[j]);        
+                                }
+                                else /* other char */
+                                {
+                                        putchar('.');
+                                }
+                        }
+                        putchar('\n');
+                }
+        }
+}
+
+
 // Method that gets called by shared libraries to get their command handlers registered
 void ipmi_register_callback(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                        ipmi_context_t context, ipmid_callback_t handler)
@@ -101,107 +161,134 @@ ipmi_ret_t ipmi_netfn_router(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t
     return rc;
 }
 
-// This gets called by Glib loop on seeing a Dbus signal 
-static void handle_ipmi_command(GDBusProxy *proxy,
-                        gchar      *sender_name,
-                        gchar      *signal_name,
-                        GVariant   *parameters,
-                        gpointer    user_data)
-{
-    // Used to re-construct the message into IPMI specific ones.
-    guchar *parameters_str;
-    unsigned char sequence, netfn, cmd;
-
-    // Request and Response buffer.
-    unsigned char request[MAX_IPMI_BUFFER] = {0};
-    unsigned char response[MAX_IPMI_BUFFER] = {0};
-
-    size_t msg_length = 0;
-    size_t data_len = 0;
-
-    // Response from Net Function Router
-    ipmi_ret_t rc = 0;
-
-    // Variables to marshall and unmarshall the messages.
-    GVariantIter *iter;
-    guchar data;
-    GVariant *dbus_response;
-    GVariantBuilder *builder;
-
-    // Pretty print the message that came on Dbus
-    parameters_str = (guchar *) g_variant_print (parameters, TRUE);
-    printf ("*** Received Signal: %s: %s :%s\n",
-            signal_name,
-            sender_name,
-            parameters_str);
-
-    // Consume the data pattern "<bYte><bYte><bYte><Array_of_bYtes>
-    g_variant_get(parameters, "(yyyay)", &sequence, &netfn, &cmd, &iter);
-
-    printf("Sequence: %x\n",sequence );
-    printf("Netfn   : %x\n",netfn );
-    printf("Cmd     : %x\n",cmd );
-
-    // Further break down the GVariant byte array
-    while (g_variant_iter_loop (iter, "y", &data))
-    {
-        request[msg_length++] = data;
+
+
+
+static int send_ipmi_message(unsigned char seq, unsigned char netfn, unsigned char cmd, unsigned char *buf, unsigned char len) {
+
+    sd_bus_error error = SD_BUS_ERROR_NULL;
+    sd_bus_message *reply = NULL, *m=NULL;
+
+
+    const char *path;
+    int r, pty;
+
+
+    r = sd_bus_message_new_method_call(bus,&m,DBUS_NAME,OBJ_NAME,DBUS_NAME,"sendMessage");
+    if (r < 0) {
+        fprintf(stderr, "Failed to add the method object: %s\n", strerror(-r));
+        return -1;
     }
 
-    // Done with consuming data.
-    g_free (parameters_str);
 
-    // Needed to see what we get back from the handlers.
-    data_len = msg_length;
+    // Responses in IPMI require a bit set.  So there ya go...
+    netfn |= 0x04;
 
-    // Now that we have parsed the entire byte array from the caller 
-    // we can call the ipmi router to do the work...
-    rc = ipmi_netfn_router(netfn, cmd, (void *)request, (void *)response, &data_len);
-    if(rc == 0)
-    {
-        printf("SUCCESS handling NetFn:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
+
+    // Add the bytes needed for the methos to obe called
+    r = sd_bus_message_append(m, "yyy", seq, netfn, cmd);
+    if (r < 0) {
+        fprintf(stderr, "Failed add the netfn and others : %s\n", strerror(-r));
+        return -1;
     }
-    else
-    {
-        fprintf(stderr,"ERROR:[0x%X] handling NetFn:[0x%X], Cmd:[0x%X]\n",rc, netfn, cmd);
+   
+    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;
     }
 
-    // Now build a response Gvariant package
-    // This example may help
-    // http://stackoverflow.com/questions/22937588/how-to-send-byte-array-over-gdbus
 
-    printf("Bytes to return\n");
-   // hexdump(response,data_len);
 
-    // Now we need to put the data as "Array Of Bytes" as we got them.
-    builder = g_variant_builder_new (G_VARIANT_TYPE ("ay"));
+    // 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;
+    }
+
+    r = sd_bus_message_read(reply, "x", &pty);
+#ifdef __IPMI_DEBUG__
+    printf("RC from the ipmi dbus method :%d \n", pty);
+#endif    
+    if (r < 0) {
+       fprintf(stderr, "Failed to get a rc from the method: %s\n", strerror(-r));
 
-    for (uint out_data = 0; out_data < data_len; out_data++)
-    {
-        g_variant_builder_add (builder, "y", response[out_data]);
     }
 
-    dbus_response = g_variant_new ("(yyyay)", sequence, netfn+1, cmd, builder);
 
-    // Variant builder is no longer needed.
-    g_variant_builder_unref (builder);
+    sd_bus_error_free(&error);
+    sd_bus_message_unref(m);
 
-    parameters_str = (guchar *) g_variant_print (dbus_response, TRUE);
-    printf (" *** Response Signal :%s\n", parameters_str);
 
-    // Done packing the data.
-    g_free (parameters_str);
+#ifdef __IPMI_DEBUG__
+    printf("%d : %s\n", __LINE__, __PRETTY_FUNCTION__ );
+#endif    
+    return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 
-    // NOW send the respone message in the Dbus calling "sendMessage" interface.
-    g_dbus_proxy_call_sync (proxy,
-            "sendMessage",
-            dbus_response,
-            G_DBUS_CALL_FLAGS_NONE,
-            -1,
-            NULL,
-            NULL);
 }
 
+static int handle_ipmi_command(sd_bus_message *m, void *user_data, sd_bus_error
+                         *ret_error) {
+    int r = 0;
+    const char *msg = NULL;
+    char sequence, netfn, cmd;
+    const void *request;
+    size_t sz;
+    size_t resplen =MAX_IPMI_BUFFER;
+    unsigned char response[MAX_IPMI_BUFFER];
+
+    printf(" *** Received Signal: ");
+
+    memset(response, 0, MAX_IPMI_BUFFER);
+
+    r = sd_bus_message_read(m, "yyy",  &sequence, &netfn, &cmd);
+    if (r < 0) {
+        fprintf(stderr, "Failed to parse signal message: %s\n", strerror(-r));
+        return -1;
+    }
+
+    r = sd_bus_message_read_array(m, 'y',  &request, &sz );
+    if (r < 0) {
+        fprintf(stderr, "Failed to parse signal message: %s\n", strerror(-r));
+        return -1;
+    }
+
+
+    printf("Seq 0x%02x, NetFn 0x%02x, CMD: 0x%02x \n", sequence, netfn, cmd);
+    hexdump((void*)request, sz);
+
+    // TODO: Need to pass the buffer length of the request bytes
+    // Probably should just pass an ipmi object with all the 
+    // interesting stuff in there and just one parameter.  
+    // May be easier to add testing too
+    // Also this is not thread safe at all.  response is a single buffer
+    // used by all commands.  Seems wrong
+    resplen = sz;
+
+    // Now that we have parsed the entire byte array from the caller 
+    // we can call the ipmi router to do the work...
+    r = ipmi_netfn_router(netfn, cmd, (void *)request, (void *)response, &resplen);
+    if(r != 0)
+    {
+        fprintf(stderr,"ERROR:[0x%X] handling NetFn:[0x%X], Cmd:[0x%X]\n",r, netfn, cmd);
+    }
+
+    printf("Response...\n");
+    hexdump((void*)response, resplen);
+
+    // Send the response buffer from the ipmi command
+    r = send_ipmi_message(sequence, netfn, cmd, response, resplen);
+    if (r < 0) {
+        fprintf(stderr, "Failed to send the response message\n");
+        return -1;
+    }
+
+
+    return 0;
+}
+
+
 //----------------------------------------------------------------------
 // handler_select
 // Select all the files ending with with .so. in the given diretcory
@@ -260,13 +347,14 @@ void ipmi_register_callback_handlers(const char* ipmi_lib_path)
         num_handlers = scandir(ipmi_lib_path, &handler_list, handler_select, alphasort);
         while(num_handlers--)
         {
-            printf("Registering handler:[%s]\n",handler_list[num_handlers]->d_name);
-
+            handler_fqdn = ipmi_lib_path;
             handler_fqdn += handler_list[num_handlers]->d_name;
+            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]\n",handler_list[num_handlers]->d_name);
+                fprintf(stderr,"ERROR opening:[%s]\n",handler_fqdn.c_str());
                 dlerror();
             }
             // Wipe the memory allocated for this particular entry.
@@ -282,6 +370,11 @@ void ipmi_register_callback_handlers(const char* ipmi_lib_path)
 
 int main(int argc, char *argv[])
 {
+    sd_bus_slot *slot = NULL;
+    int r;
+    char *mode = NULL;
+
+
     // Register all the handlers that provider implementation to IPMI commands.
     ipmi_register_callback_handlers(HOST_IPMI_LIB_PATH);
 
@@ -295,32 +388,45 @@ int main(int argc, char *argv[])
         printf("NETFN:[0x%X], cmd[0x%X]\n", fn_and_cmd.first, fn_and_cmd.second);  
     }
 #endif
-       
-    // Infrastructure that will wait for IPMi Dbus messages and will call 
-    // into the corresponding IPMI providers.
-    GDBusProxy *proxy;
-    GMainLoop *loop;
-
-    loop = g_main_loop_new (NULL, FALSE);
-
-    // Proxy to use GDbus for OpenBMC channel.
-    proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
-                                           G_DBUS_PROXY_FLAGS_NONE,
-                                           NULL, /* GDBusInterfaceInfo */
-                                           DBUS_NAME,
-                                           OBJ_NAME,
-                                           DBUS_NAME,
-                                           NULL,
-                                           NULL);
-
-    // On receiving the Dbus Signal, handle_ipmi_command gets invoked.
-    g_signal_connect (proxy,
-                    "g-signal",
-                    G_CALLBACK (handle_ipmi_command),
-                    NULL);
-
-    // This will not return unless we return false from the upmi_handler function.
-    g_main_loop_run (loop);
 
-    return 0;
+
+    /* Connect to system bus */
+    r = sd_bus_open_system(&bus);
+    if (r < 0) {
+        fprintf(stderr, "Failed to connect to system bus: %s\n",
+                strerror(-r));
+        goto finish;
+    }
+
+    r = sd_bus_add_match(bus, &slot, FILTER, handle_ipmi_command, NULL);
+    if (r < 0) {
+        fprintf(stderr, "Failed: sd_bus_add_match: %s : %s\n", strerror(-r), FILTER);
+        goto finish;
+    }
+
+
+    for (;;) {
+        /* Process requests */
+
+        r = sd_bus_process(bus, NULL);
+        if (r < 0) {
+            fprintf(stderr, "Failed to process bus: %s\n", strerror(-r));
+            goto finish;
+        }
+        if (r > 0) {
+            continue;
+        }
+
+        r = sd_bus_wait(bus, (uint64_t) - 1);
+        if (r < 0) {
+            fprintf(stderr, "Failed to wait on bus: %s\n", strerror(-r));
+            goto finish;
+        }
+    }
+
+finish:
+    sd_bus_slot_unref(slot);
+    sd_bus_unref(bus);
+    return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+
 }
diff --git a/ipmid.H b/ipmid.H
index 6b7d2c9..ab8b030 100755
--- a/ipmid.H
+++ b/ipmid.H
@@ -10,6 +10,6 @@ ipmi_ret_t ipmi_netfn_router(const ipmi_netfn_t, const ipmi_cmd_t, ipmi_request_
 
 // Plugin libraries need to _end_ with .so
 #define IPMI_PLUGIN_EXTN ".so"
-#define MAX_IPMI_BUFFER 255
+#define MAX_IPMI_BUFFER 64
 
 #endif
diff --git a/oemhandler.C b/oemhandler.C
new file mode 100644
index 0000000..a686c1f
--- /dev/null
+++ b/oemhandler.C
@@ -0,0 +1,105 @@
+#include "oemhandler.h"
+#include "ipmid-api.h"
+#include <stdio.h>
+#include <string.h>
+
+
+void register_netfn_oem_wildcard() __attribute__((constructor));
+void register_netfn_oem_partial_esel() __attribute__((constructor));
+
+
+ipmi_ret_t ipmi_ibm_oem_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)
+{
+    printf("Handling OEM WILDCARD\n");
+    // Status code.
+    ipmi_ret_t rc = IPMI_CC_OK;
+    *data_len = 0;
+    return rc;
+}
+
+
+unsigned short g_record_id = 0x0100;
+
+
+typedef struct {
+    unsigned char  residls;
+    unsigned char  residms;
+    unsigned short selrecord;
+    unsigned short offset;
+    unsigned char  progress;
+    unsigned char  data;
+
+} ESEL_DATA ;
+
+
+// This function creates a /tmp/esel# file to store the 
+// incoming partial esel.  It is the role of some other
+// function to commit the error log in to long term 
+// storage.  Likely via the ipmi add_sel command.  
+ipmi_ret_t ipmi_ibm_oem_partial_esel(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)
+{
+    ESEL_DATA *reqptr = (ESEL_DATA*) request;
+    FILE *fp;
+    char string[16];
+    short offset = 0;
+    unsigned short rlen;
+    ipmi_ret_t rc = IPMI_CC_OK;
+    char iocmd[3];
+
+    sprintf(string, "%s%04x", "/tmp/esel", reqptr->selrecord);
+
+
+    // Length is the number of request bytes minus the header itself.
+    // The header contains an extra byte to indicate the start of
+    // the data (so didn't need to worry about word/byte boundaries)
+    // hence the -1...
+    rlen = ((unsigned short)*data_len) - (sizeof(ESEL_DATA)-1);
+
+
+    printf("IPMI PARTIAL ESEL for %s  Offset = %d Length = %d\n", 
+        string, reqptr->offset, rlen);
+
+    if (reqptr->offset == 0) {
+        strcpy(iocmd, "wb");
+    } else {
+        // I was thinking "ab+" but it appears it doesn't
+        // do what fseek asks.  Modify to rb+ and fseek 
+        // works great...
+        strcpy(iocmd, "rb+");
+    }
+
+    if ((fp = fopen(string, iocmd)) != NULL) {
+        fseek(fp, reqptr->offset, SEEK_SET);
+        fwrite(&reqptr->data,rlen,1,fp);
+        fclose(fp);
+
+        *data_len = sizeof(g_record_id);
+        memcpy(response, &g_record_id, *data_len);
+
+
+    } else {
+        fprintf(stderr, "Error trying to perform %s for esel%s\n",cmd, string);
+        ipmi_ret_t rc = IPMI_CC_INVALID;   
+        *data_len     = 0;
+    }
+    
+    return rc;
+}
+
+void register_netfn_oem_wildcard()
+{
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_OEM_IBM, IPMI_CMD_WILDCARD);
+    ipmi_register_callback(NETFUN_OEM_IBM, IPMI_CMD_WILDCARD, NULL, ipmi_ibm_oem_wildcard);
+    return;
+}
+
+void register_netfn_oem_partial_esel()
+{
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_OEM_IBM, IPMI_CMD_PESEL);
+    ipmi_register_callback(NETFUN_OEM_IBM, IPMI_CMD_PESEL, NULL, ipmi_ibm_oem_partial_esel);
+    return;
+}
diff --git a/oemhandler.h b/oemhandler.h
new file mode 100644
index 0000000..dd80e9f
--- /dev/null
+++ b/oemhandler.h
@@ -0,0 +1,12 @@
+#ifndef __HOST_IPMI_IBMOEM_HANDLER_H__
+#define __HOST_IPMI_IBMOEM_HANDLER_H__
+
+// IPMI commands for net functions.
+enum ipmi_netfn_sen_cmds
+{
+    // Get capability bits
+    IPMI_CMD_PESEL = 0xF0,
+
+};
+
+#endif
diff --git a/sensorhandler.C b/sensorhandler.C
new file mode 100644
index 0000000..3bef067
--- /dev/null
+++ b/sensorhandler.C
@@ -0,0 +1,225 @@
+#include "sensorhandler.h"
+#include "ipmid-api.h"
+#include <stdio.h>
+#include <string.h>
+
+
+
+void register_netfn_sen_wildcard()   __attribute__((constructor));
+void register_netfn_sen_set_sensor() __attribute__((constructor));
+void register_netfn_sen_get_sensor_type() __attribute__((constructor));
+
+
+
+typedef struct {
+    unsigned char  sennum;
+} SENSOR_DATA ;
+
+unsigned char g_sensortype [][2] = {
+    {0xc7, 58},
+{0x01, 113},
+{0xc7, 56},
+{0x01, 114},
+{0xc6, 54},
+{0x07, 40},
+{0xC1, 121},
+{0xC2, 137},
+{0x07, 36},
+{0x07, 43},
+{0xC1, 122},
+{0xC1, 119},
+{0x01, 12},
+{0x01, 111},
+{0x01, 116},
+{0xC1, 127},
+{0xC2, 134},
+{0xC2, 130},
+{0xc, 33},
+{0xC1, 125},
+{0x01, 115},
+{0x22, 4},
+{0xC2, 138},
+{0x01, 108},
+{0x01, 102},
+{0xc, 46},
+{0x7, 11},
+{0xC1, 120},
+{0x07, 39},
+{0x07, 42},
+{0x5, 21},
+{0xC2, 131},
+{0xc1, 48},
+{0x12, 53},
+{0xC1, 124},
+{0x01, 117},
+{0xC1, 126},
+{0xf, 5},
+{0x23, 0},
+{0xC2, 139},
+{0x07, 34},
+{0x09, 146},
+{0x02, 178},
+{0xC2, 140},
+{0xC1, 118},
+{0xC2, 133},
+{0x07, 38},
+{0xC2, 143},
+{0x01, 101},
+{0xc3, 9},
+{0x7, 10},
+{0xc2, 51},
+{0x01, 109},
+{0xc, 32},
+{0x7, 8},
+{0xC1, 129},
+{0x01, 112},
+{0x01, 107},
+{0x07, 37},
+{0x07, 44},
+{0x1f, 50},
+{0xC2, 144},
+{0xc7, 52},
+{0xC2, 141},
+{0x01, 106},
+{0x01, 110},
+{0x01, 103},
+{0x9, 28},
+{0x07, 35},
+{0xc7, 55},
+{0x03, 179},
+{0x07, 41},
+{0xc, 30},
+{0x01, 100},
+{0xC1, 128},
+{0xC2, 135},
+{0x01, 105},
+{0x7, 47},
+{0xC2, 145},
+{0xc7, 57},
+{0x01, 104},
+{0x07, 45},
+{0xC2, 132},
+{0xc4, 49},
+{0xC1, 123},
+{0xC2, 142},
+{0x01, 13},
+{0xC2, 136},
+{0xc, 31},
+{0xff,0xff}
+};
+
+
+unsigned char findSensor(char sensor_number) {
+
+    int i=0;
+
+    // TODO : This function should actually call
+    // a dbus object and have it return the data
+    // it is not ready yet so use a Palmetto 
+    // based lookup table for now.  The g_sensortype
+    // can be removed once the dbus method exists
+    while (g_sensortype[i][0] != 0xff) {
+        if (g_sensortype[i][1] == sensor_number) {
+            break;
+        } else {
+            i++;
+        }
+
+    }
+
+    return g_sensortype[i][0];
+
+}
+
+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)
+{
+    SENSOR_DATA *reqptr = (SENSOR_DATA*)request;
+    ipmi_ret_t rc = IPMI_CC_OK;
+
+    printf("IPMI GET_SENSOR_TYPE [0x%02X]\n",reqptr->sennum);
+
+    // TODO Not sure what the System-event-sensor is suppose to return
+    // need to ask Hostboot team
+    unsigned char buf[] = {0x00,0x6F};
+
+    buf[0] = findSensor(reqptr->sennum);
+
+    *data_len = sizeof(buf);
+    memcpy(response, &buf, *data_len);
+
+
+
+    return rc;
+}
+
+
+
+// TODO: Saves the sensor information to a file in /tmp.  This
+// will need to change to calling the correct method 
+// once it exists in the stack.  
+ipmi_ret_t ipmi_sen_set_sensor(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)
+{
+    FILE *fp;
+    char string[16];
+    SENSOR_DATA *reqptr = (SENSOR_DATA*)request;
+    ipmi_ret_t rc = IPMI_CC_OK;
+    unsigned short rlen;
+
+    rlen = (unsigned short) *data_len - 1;
+
+    sprintf(string, "%s%02x", "/tmp/sen", reqptr->sennum);
+
+    printf("IPMI SET_SENSOR [%s]\n",string);
+
+    if ((fp = fopen(string, "wb")) != NULL) {
+        fwrite(reqptr+1,rlen,1,fp);
+        fclose(fp);
+    } else {
+        fprintf(stderr, "Error trying to write to sensor file %s\n",string);
+        ipmi_ret_t rc = IPMI_CC_INVALID;        
+    }
+
+    *data_len=0;
+
+
+    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)
+{
+    ipmi_ret_t rc = IPMI_CC_OK;
+
+    printf("IPMI S/E Wildcard Netfn:[0x%X], Cmd:[0x%X]\n",netfn,cmd);
+    *data_len = 0;
+
+    return rc;
+}
+
+
+void register_netfn_sen_wildcard()
+{
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_SENSOR, IPMI_CMD_WILDCARD);
+    ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_WILDCARD, NULL, ipmi_sen_wildcard);
+    return;
+}
+
+
+void register_netfn_sen_get_sensor_type()
+{
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_TYPE);
+    ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_TYPE, NULL, ipmi_sen_get_sensor_type);
+    return;
+}
+
+void register_netfn_sen_set_sensor()
+{
+    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);
+    return;
+}
diff --git a/sensorhandler.h b/sensorhandler.h
new file mode 100644
index 0000000..da63bcb
--- /dev/null
+++ b/sensorhandler.h
@@ -0,0 +1,13 @@
+#ifndef __HOST_IPMI_SEN_HANDLER_H__
+#define __HOST_IPMI_SEN_HANDLER_H__
+
+// IPMI commands for net functions.
+enum ipmi_netfn_sen_cmds
+{
+    // Get capability bits
+    IPMI_CMD_GET_SENSOR_TYPE = 0x2F,
+    IPMI_CMD_SET_SENSOR      = 0x30,
+
+};
+
+#endif
diff --git a/storagehandler.C b/storagehandler.C
new file mode 100644
index 0000000..085b442
--- /dev/null
+++ b/storagehandler.C
@@ -0,0 +1,222 @@
+#include "storagehandler.h"
+#include "ipmid-api.h"
+#include <stdio.h>
+#include <string.h>
+
+
+void register_netfn_storage_wildcard() __attribute__((constructor));
+void register_netfn_stoage_set_sel_time() __attribute__((constructor));
+void register_netfn_stoage_write_fru_data() __attribute__((constructor));
+void register_netfn_stoage_get_sel_info() __attribute__((constructor));
+void register_netfn_stoage_reserve_sel() __attribute__((constructor));
+void register_netfn_stoage_add_sel() __attribute__((constructor));
+
+
+unsigned int   g_sel_time    = 0xFFFFFFFF;
+unsigned short g_sel_reserve = 0x1;
+
+ipmi_ret_t ipmi_storage_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)
+{
+    printf("Handling STORAGE WILDCARD Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
+    // Status code.
+    ipmi_ret_t rc = IPMI_CC_OK;
+    *data_len = 0;
+    return rc;
+}
+
+
+ipmi_ret_t ipmi_storage_set_sel_time(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 int *bufftype = (unsigned int *) request;
+
+    printf("Handling Set-SEL-Time:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
+    printf("Data: 0x%X]\n",*bufftype);
+
+    g_sel_time = *bufftype;
+
+    ipmi_ret_t rc = IPMI_CC_OK;
+    *data_len = 0;
+    return rc;
+}
+
+typedef struct {
+    unsigned char  frunum;
+    unsigned char  offsetls;
+    unsigned char  offsetms;
+    unsigned char  data;
+} WRITE_FRU_DATA ;
+
+ipmi_ret_t ipmi_storage_write_fru_data(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)
+{
+    WRITE_FRU_DATA *reqptr = (WRITE_FRU_DATA*) request;
+    FILE *fp;
+    char string[16];
+    short offset = 0;
+    unsigned short rlen;
+    ipmi_ret_t rc = IPMI_CC_OK;
+    char iocmd[3];
+
+    sprintf(string, "%s%02x", "/tmp/fru", reqptr->frunum);
+
+    offset = (reqptr->offsetms) << 8 | reqptr->offsetls;
+
+
+    // Length is the number of request bytes minus the header itself.
+    // The header contains an extra byte to indicate the start of
+    // the data (so didn't need to worry about word/byte boundaries)
+    // hence the -1...
+    rlen = ((unsigned short)*data_len) - (sizeof(WRITE_FRU_DATA)-1);
+    
+
+    printf("IPMI WRITE-FRU-DATA for %s  Offset = %d Length = %d\n",
+        string, offset, rlen);
+
+
+    // I was thinking "ab+" but it appears it doesn't
+    // do what fseek asks.  Modify to rb+ and fseek 
+    // works great...
+    if (offset == 0) {
+        strcpy(iocmd, "wb");
+    } else {
+        strcpy(iocmd, "rb+");
+    }
+
+    if ((fp = fopen(string, iocmd)) != NULL) {
+        fseek(fp, offset, SEEK_SET);
+        fwrite(&reqptr->data,rlen,1,fp);
+        fclose(fp);
+    } else {
+        fprintf(stderr, "Error trying to write to fru file %s\n",string);
+        ipmi_ret_t rc = IPMI_CC_INVALID;        
+    }
+    
+
+    // TODO : Here is where some validation code could determine if the 
+    // fru data is a legitimate FRU record (not just a partial).  Once
+    // the record is valid the code should call a parser routine to call
+    // the various methods updating interesting properties.  Perhaps 
+    // thinigs like Model#, Serial#, DIMM Size, etc
+    
+
+    *data_len = 0;
+    
+    return rc;
+}
+
+ipmi_ret_t ipmi_storage_get_sel_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;
+    unsigned char buf[] = {0x51,0,0,0xff, 0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0x06};
+
+    printf("IPMI Handling GET-SEL-INFO\n");
+
+    *data_len = sizeof(buf);
+
+    // TODO There is plently of work here.  The SEL DB needs to hold a bunch
+    // of things in a header.  Items like Time Stamp, number of entries, etc
+    // This is one place where the dbus object with the SEL information could
+    // mimic what IPMI needs.
+
+    // Pack the actual response
+    memcpy(response, &buf, *data_len);
+
+    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)
+{
+
+    ipmi_ret_t rc = IPMI_CC_OK;
+
+    printf("IPMI Handling RESERVE-SEL 0x%04x\n", g_sel_reserve);
+
+    *data_len = sizeof(g_sel_reserve);
+
+    // Pack the actual response
+    memcpy(response, &g_sel_reserve, *data_len);
+
+    return rc;
+}
+
+
+ipmi_ret_t ipmi_storage_add_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)
+{
+
+    ipmi_ret_t rc = IPMI_CC_OK;
+
+    printf("IPMI Handling ADD-SEL \n");
+
+    *data_len = sizeof(g_sel_reserve);
+
+    // Pack the actual response
+    memcpy(response, &g_sel_reserve, *data_len);
+
+    // TODO This code should grab the completed partial esel located in 
+    // the /tmp/esel0100 file and commit it to the error log handler.  
+
+
+    // TODO I advanced the sel reservation number so next time HB asks
+    // for a reservation they get a new number.  This tech may change 
+    // based on how the HB team currently uses sel reservations but
+    // for now provide the ability to get new reservations 
+    g_sel_reserve++;
+
+    return rc;
+}
+
+
+
+void register_netfn_storage_wildcard()
+{
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_WILDCARD);
+    ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_WILDCARD, NULL, ipmi_storage_wildcard);
+    return;
+}
+
+void register_netfn_stoage_set_sel_time()
+{
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_SET_SEL_TIME);
+    ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_SET_SEL_TIME, NULL, ipmi_storage_set_sel_time);
+    return;
+}
+
+void register_netfn_stoage_write_fru_data()
+{
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_WRITE_FRU_DATA);
+    ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_WRITE_FRU_DATA, NULL, ipmi_storage_write_fru_data);
+    return;
+}
+void register_netfn_stoage_get_sel_info()
+{
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_GET_SEL_INFO);
+    ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_GET_SEL_INFO, NULL, ipmi_storage_get_sel_info);
+    return;
+}
+void register_netfn_stoage_reserve_sel()
+{
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_RESERVE_SEL);
+    ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_RESERVE_SEL, NULL, ipmi_storage_reserve_sel);
+    return;
+}
+void register_netfn_stoage_add_sel()
+{
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_ADD_SEL);
+    ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_ADD_SEL, NULL, ipmi_storage_add_sel);
+    return;
+}
+
diff --git a/storagehandler.h b/storagehandler.h
new file mode 100644
index 0000000..56c1a8b
--- /dev/null
+++ b/storagehandler.h
@@ -0,0 +1,16 @@
+#ifndef __HOST_IPMI_STORAGE_HANDLER_H__
+#define __HOST_IPMI_STORAGE_HANDLER_H__
+
+// IPMI commands for net functions.
+enum ipmi_netfn_storage_cmds
+{
+    // Get capability bits
+    IPMI_CMD_SET_SEL_TIME   = 0x49,
+    IPMI_CMD_WRITE_FRU_DATA = 0x12,
+    IPMI_CMD_GET_SEL_INFO   = 0x40,
+    IPMI_CMD_RESERVE_SEL    = 0x42,
+    IPMI_CMD_ADD_SEL        = 0x44,
+
+};
+
+#endif
-- 
2.6.0




More information about the openbmc mailing list