[PATCH phosphor-host-ipmid v2 2/3] Patch set-2 for IPMI function router

OpenBMC Patches patches at stwcx.xyz
Thu Oct 8 19:59:04 AEDT 2015


From: vishwabmc <vishwanath at in.ibm.com>

---
 Makefile      | 21 +++++++++--------
 apphandler.C  | 15 +++++++-----
 apphandler.H  | 32 ++++++++++++++++++++++++++
 ipmid.C       | 74 +++++++++++++++++++++++++++++++++--------------------------
 ipmid.H       | 69 +++++++------------------------------------------------
 ipmidcommon.H | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 165 insertions(+), 109 deletions(-)
 create mode 100644 apphandler.H
 create mode 100755 ipmidcommon.H

diff --git a/Makefile b/Makefile
index 81e5d1f..dc83143 100755
--- a/Makefile
+++ b/Makefile
@@ -1,23 +1,24 @@
-CC=g++
-CFLAGS = -I. -I/usr/include/gio-unix-2.0 -Wall -rdynamic
-CFLAGS += $(shell pkg-config --cflags --libs glib-2.0 gio-unix-2.0)
-CFLAGS += -DHOST_IPMI_LIB_PATH=\"/home/OpenBMC/1_EDUCATION/IPMI_DBUS/\"
+CXX ?= $(CROSS_COMPILE)g++
 
-DAEMON_OBJ = ipmid.o
-LIB_OBJ = apphandler.o
 DAEMON = ipmid
+DAEMON_OBJ = $(DAEMON).o
+LIB_OBJ = apphandler.o
 LIBS = libapphandler.so
 
+INC_FLAG += $(shell pkg-config --cflags glib-2.0 gio-unix-2.0) -I. -O2 --std=gnu++11 -D__IPMI_DEBUG__
+LIB_FLAG += $(shell pkg-config --libs glib-2.0 gio-unix-2.0) -rdynamic
+IPMID_PATH = -DHOST_IPMI_LIB_PATH=\"/usr/lib/host-ipmid/\" 
+
 all: $(DAEMON) $(LIBS)
 
 %.o: %.C
-	$(CC) -fpic -c -o $@ $< $(CFLAGS)
+	$(CXX) -fpic -c $< $(CXXFLAGS) $(INC_FLAG) $(IPMID_PATH) -o $@
 
 $(LIBS): $(LIB_OBJ)
-	$(CC) -shared -o $@ $^ $(CFLAGS)
+	$(CXX) $^ -shared $(LDFLAGS) $(LIB_FLAG) -o $@
 
 $(DAEMON): $(DAEMON_OBJ)
-	$(CC) -o $@ $^ $(CFLAGS) -ldl
+	$(CXX) $^ $(LDFLAGS) $(LIB_FLAG) -o $@ -ldl
 
 clean:
-	rm -f $(DAEMON) *.o *.d *.so
+	rm -f $(DAEMON) *.o *.so
diff --git a/apphandler.C b/apphandler.C
index 090adf5..eb5bf09 100755
--- a/apphandler.C
+++ b/apphandler.C
@@ -1,12 +1,14 @@
 #include <stdio.h>
 #include "ipmid.H"
 #include <string.h>
+#include "apphandler.H"
 
 void register_netfn_app_cap_bit() __attribute__((constructor));
 void register_netfn_app_wildcard() __attribute__((constructor));
 
-int ipmi_app_cap_bit_handler(ipmi_netfn_t netfn, ipmi_cmd_t cmd, void *request, 
-                             void *response, unsigned int *data_len, void *context)
+int ipmi_app_cap_bit_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)
 {
     printf("Handling Netfn:[0x%X], Cmd:[0x%X]\n",netfn,cmd);
 
@@ -17,8 +19,9 @@ int ipmi_app_cap_bit_handler(ipmi_netfn_t netfn, ipmi_cmd_t cmd, void *request,
     return CC_OK;
 }
 
-int ipmi_app_wildcard_handler(ipmi_netfn_t netfn, ipmi_cmd_t cmd, void *request, 
-                        void *response, unsigned int *data_len, void *context)
+int 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)
 {
     printf("Handling WILDCARD Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
 
@@ -31,7 +34,7 @@ void register_netfn_app_cap_bit()
 {
     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_CAP_BIT);
 
-    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_cap_bit_handler);
     return;
 }
 
@@ -39,6 +42,6 @@ void register_netfn_app_wildcard()
 {
     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_WILDCARD);
 
-    register_callback(NETFUN_APP, IPMI_CMD_WILDCARD, NULL, ipmi_app_wildcard_handler);
+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_WILDCARD, NULL, ipmi_app_wildcard_handler);
     return;
 }
diff --git a/apphandler.H b/apphandler.H
new file mode 100644
index 0000000..fdcd66f
--- /dev/null
+++ b/apphandler.H
@@ -0,0 +1,32 @@
+#ifndef  __HOST_IPMI_APP_HANDLER_H__
+#define __HOST_IPMI_APP_HANDLER_H__
+
+// 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
+// associated with a response, subtract 1.
+// Note: these are also shifted left to make room for the LUN.
+enum ipmi_net_fns
+{
+    NETFUN_CHASSIS  =   (0x00 << 2),
+    NETFUN_BRIDGE   =   (0x02 << 2),
+    NETFUN_SENSOR   =   (0x04 << 2),
+    NETFUN_APP      =   (0x06 << 2),
+    NETFUN_FIRMWARE =   (0x08 << 2),
+    NETFUN_STORAGE  =   (0x0a << 2),
+    NETFUN_TRANPORT =   (0x0c << 2),
+    NETFUN_GRPEXT   =   (0x2c << 2),
+    NETFUN_NONE     =   (0x30 << 2)
+};
+
+// TODO :: As and when we write plugin's these will go into apporpriate
+// provider space.
+
+// IPMI commands for net functions.
+enum ipmi_netfn_app_cmds
+{
+    // Get capability bits
+    IPMI_CMD_GET_CAP_BIT    = 0x36,
+};
+
+#endif
diff --git a/ipmid.C b/ipmid.C
index cdcb765..f9a2e83 100644
--- a/ipmid.C
+++ b/ipmid.C
@@ -8,37 +8,38 @@
 #include <string.h>
 #include <stdlib.h>
 #include <map>
-#include "./ipmid.H"
+#include "ipmid.H"
 
-using namespace std;
+// Channel that is used for OpenBMC Barreleye
+const char * DBUS_NAME = "org.openbmc.HostIpmi";
+const char * OBJ_NAME = "/org/openbmc/HostIpmi/1";
+
+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;
-typedef std::map<ipmi_fn_cmd_t, ipmi_fn_context_t>::iterator router_iter_t;
 
 // Method that gets called by shared libraries to get their command handlers registered
-void register_callback(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+void ipmi_register_callback(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                        ipmi_context_t context, ipmid_callback_t handler)
 {
-    ipmi_fn_cmd_t netfn_and_cmd;
-    ipmi_fn_context_t handler_and_context;
-
     // Pack NetFn and Command in one.
-    netfn_and_cmd = std::make_pair(netfn, cmd);
+    auto netfn_and_cmd = std::make_pair(netfn, cmd);
 
     // Pack Function handler and Data in another.
-    handler_and_context = std::make_pair(handler, context);
+    auto handler_and_context = std::make_pair(handler, context);
 
     // Check if the registration has already been made..
-    router_iter_t iter = g_ipmid_router_map.find(netfn_and_cmd);
+    auto iter = g_ipmid_router_map.find(std::make_pair(netfn,cmd));
     if(iter != g_ipmid_router_map.end())
     {
-        printf("ERROR : Duplicate registration for NetFn [0x%X], Cmd:[0x%X]\n",netfn, cmd);
+        fprintf(stderr,"ERROR : Duplicate registration for NetFn [0x%X], Cmd:[0x%X]\n",netfn, cmd);
     }
     else
     {
         // This is a fresh registration.. Add it to the map.
-        g_ipmid_router_map.insert(make_pair(netfn_and_cmd, handler_and_context));
+        g_ipmid_router_map.insert(std::make_pair(netfn_and_cmd, handler_and_context));
     }
 
     return;
@@ -46,17 +47,17 @@ void register_callback(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
 
 // Looks at the map and calls corresponding handler functions.
 int ipmi_netfn_router(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
-                      ipmi_response_t response, unsigned int *data_len)
+                      ipmi_response_t response, ipmi_data_len_t data_len)
 {
     // return from the Command handlers.
     int rc = 0;
 
     // Extract Handler and context from Map.
-    ipmi_fn_context_t handler_and_context;
+    //ipmi_fn_context_t handler_and_context;
 
     // Walk the map that has the registered handlers and invoke the approprite
     // handlers for matching commands.
-    router_iter_t iter = g_ipmid_router_map.find(make_pair(netfn, cmd));
+    auto iter = g_ipmid_router_map.find(std::make_pair(netfn, cmd));
     if(iter == g_ipmid_router_map.end())
     {
         printf("No registered handlers for NetFn:[0x%X], Cmd:[0x%X]"
@@ -64,7 +65,7 @@ int ipmi_netfn_router(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request
 
         // Now that we did not find any specific [NetFn,Cmd], tuple, check for
         // NetFn, WildCard command present.
-        iter = g_ipmid_router_map.find(make_pair(netfn, IPMI_CMD_WILDCARD));
+        iter = g_ipmid_router_map.find(std::make_pair(netfn, IPMI_CMD_WILDCARD));
         if(iter == g_ipmid_router_map.end())
         {
             printf("No Registered handlers for NetFn:[0x%X],Cmd:[0x%X]\n",netfn, IPMI_CMD_WILDCARD);
@@ -77,12 +78,11 @@ int ipmi_netfn_router(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request
     printf("Calling Net function:[0x%X], Command:[0x%X]\n", netfn, cmd);
 #endif
 
-    // Extract the map data onto appropriate containers.
-    handler_and_context = iter->second;
+    // Extract the map data onto appropriate containers
+    auto handler_and_context = iter->second;
 
     rc = (handler_and_context.first) (netfn, cmd, request, response,
                                       data_len, handler_and_context.second);
-
     return rc;
 }
 
@@ -115,7 +115,7 @@ static void handle_ipmi_command(GDBusProxy *proxy,
 
     // Pretty print the message that came on Dbus
     parameters_str = (guchar *) g_variant_print (parameters, TRUE);
-    g_print ("*** Received Signal: %s: %s :%s\n",
+    printf ("*** Received Signal: %s: %s :%s\n",
             signal_name,
             sender_name,
             parameters_str);
@@ -148,7 +148,7 @@ static void handle_ipmi_command(GDBusProxy *proxy,
     }
     else
     {
-        printf("ERROR:[0x%X] handling NetFn:[0x%X], Cmd:[0x%X]\n",rc, netfn, cmd);
+        fprintf(stderr,"ERROR:[0x%X] handling NetFn:[0x%X], Cmd:[0x%X]\n",rc, netfn, cmd);
     }
 
     // TODO mark the write bit
@@ -173,7 +173,7 @@ static void handle_ipmi_command(GDBusProxy *proxy,
     g_variant_builder_unref (builder);
 
     parameters_str = (guchar *) g_variant_print (dbus_response, TRUE);
-    g_print (" *** Response Signal :%s\n", parameters_str);
+    printf (" *** Response Signal :%s\n", parameters_str);
 
     // Done packing the data.
     g_free (parameters_str);
@@ -195,17 +195,28 @@ static void handle_ipmi_command(GDBusProxy *proxy,
 //----------------------------------------------------------------------
 int handler_select(const struct dirent *entry)
 {
-    if(strstr(entry->d_name, LIBRARY_EXTN))
+    // To hold ".so" from entry->d_name;
+    char dname_copy[4] = {0};
+
+    // We want to avoid checking for everything and isolate to the ones having
+    // .so in them.
+    if(strstr(entry->d_name, IPMI_PLUGIN_EXTN))
     {
-        return 1;
+        // It is possible that .so could be anywhere in the string but unlikely
+        // But being careful here. Get the base address of the string, move 
+        // until end and come back 3 steps and that gets what we need.
+        strcpy(dname_copy, (entry->d_name + strlen(entry->d_name)-strlen(IPMI_PLUGIN_EXTN)));
+        if(strcmp(dname_copy, IPMI_PLUGIN_EXTN) == 0)
+        {
+            return 1;
+        }
     }
-
     return 0;
 }
 
 // This will do a dlopen of every .so in ipmi_lib_path and will dlopen everything so that they will
 // register a callback handler 
-void register_callback_handlers(const char* ipmi_lib_path)
+void ipmi_register_callback_handlers(const char* ipmi_lib_path)
 {
     // For walking the ipmi_lib_path
     struct dirent **handler_list;
@@ -216,7 +227,7 @@ void register_callback_handlers(const char* ipmi_lib_path)
 
     if(ipmi_lib_path == NULL)
     {
-        printf("ERROR; No handlers to be registered for ipmi.. Aborting\n");
+        fprintf(stderr,"ERROR; No handlers to be registered for ipmi.. Aborting\n");
         assert(0);
     }
     else
@@ -241,7 +252,7 @@ void register_callback_handlers(const char* ipmi_lib_path)
             lib_handler = dlopen(handler_fqdn.c_str(), RTLD_NOW);
             if(lib_handler == NULL)
             {
-                printf("ERROR opening:[%s]\n",handler_list[num_handlers]->d_name);
+                fprintf(stderr,"ERROR opening:[%s]\n",handler_list[num_handlers]->d_name);
                 dlerror();
             }
             // Wipe the memory allocated for this particular entry.
@@ -258,16 +269,15 @@ void register_callback_handlers(const char* ipmi_lib_path)
 int main(int argc, char *argv[])
 {
     // Register all the handlers that provider implementation to IPMI commands.
-    register_callback_handlers(HOST_IPMI_LIB_PATH);
+    ipmi_register_callback_handlers(HOST_IPMI_LIB_PATH);
 
 #ifdef __IPMI_DEBUG__
     printf("Registered Function handlers:\n");
 
     // Print the registered handlers and their arguments.
-    router_iter_t iter;
-    for(iter = g_ipmid_router_map.begin() ; iter != g_ipmid_router_map.end(); iter++)
+    for(auto& iter : g_ipmid_router_map)
     {
-        ipmi_fn_cmd_t fn_and_cmd = iter->first;
+        ipmi_fn_cmd_t fn_and_cmd = iter.first;
         printf("NETFN:[0x%X], cmd[0x%X]\n", fn_and_cmd.first, fn_and_cmd.second);  
     }
 #endif
diff --git a/ipmid.H b/ipmid.H
index 31a2ba2..3dfe309 100755
--- a/ipmid.H
+++ b/ipmid.H
@@ -1,68 +1,15 @@
-#ifndef __IPMI_H__
-#define __IPMI_H__
-#include <utility>
+#ifndef __HOST_IPMID_IPMI_H__
+#define __HOST_IPMID_IPMI_H__
+#include "ipmidcommon.H"
 
-typedef unsigned char   ipmi_netfn_t;
-typedef unsigned char   ipmi_cmd_t;
-typedef void*           ipmi_request_t;
-typedef void*           ipmi_response_t;
-typedef void*           ipmi_context_t;
-
-// This is the provider of the net function. 
-typedef int (*ipmid_callback_t)(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
-                                ipmi_response_t, unsigned int *, ipmi_context_t);
-
-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;
-
-// This is a callback function defined in ipmid and called into by providers.
-void register_callback(ipmi_netfn_t, ipmi_cmd_t, ipmi_context_t, ipmid_callback_t);
-
-// This looks up in router map and calls corresponding Net function handlers.
+// 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]
+// and will make a call to that plugin implementation and send back the response.
 int ipmi_router(const ipmi_netfn_t, const ipmi_cmd_t, ipmi_request_t,
                 ipmi_response_t, unsigned int *data_len);
 
-#define LIBRARY_EXTN ".so"
+// Plugin libraries need to _end_ with .so
+#define IPMI_PLUGIN_EXTN ".so"
 #define MAX_IPMI_BUFFER 255
 
-// 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
-// associated with a response, subtract 1.
-// Note: these are also shifted left to make room for the LUN.
-
-enum ipmi_net_fns
-{
-    NETFUN_CHASSIS  =   (0x00 << 2),
-    NETFUN_BRIDGE   =   (0x02 << 2),
-    NETFUN_SENSOR   =   (0x04 << 2),
-    NETFUN_APP      =   (0x06 << 2),
-    NETFUN_FIRMWARE =   (0x08 << 2),
-    NETFUN_STORAGE  =   (0x0a << 2),
-    NETFUN_TRANPORT =   (0x0c << 2),
-    NETFUN_GRPEXT   =   (0x2c << 2),
-    NETFUN_AMI      =   (0x32 << 2),
-    NETFUN_IBM      =   (0x3a << 2),
-    NETFUN_NONE     =   (0x30 << 2)
-};
-
-// IPMI commands for net functions.
-enum ipmi_netfn_cmds
-{
-    IPMI_CMD_GET_CAP_BIT    = 0x36,
-    IPMI_CMD_WILDCARD       = 0xFF
-};
-
-// Return codes from a IPMI operation.
-
-enum ipmi_return_codes
-{
-    CC_OK = 0x00,
-    CC_INVALID = 0xC1
-};
-
-// Channel that is used for OpenBMC Barreleye
-const char * DBUS_NAME = "org.openbmc.HostIpmi";
-const char * OBJ_NAME = "/org/openbmc/HostIpmi/1";
-
 #endif
diff --git a/ipmidcommon.H b/ipmidcommon.H
new file mode 100755
index 0000000..9fa2284
--- /dev/null
+++ b/ipmidcommon.H
@@ -0,0 +1,63 @@
+#ifndef __HOST_IPMID_IPMI_COMMON_H__
+#define __HOST_IPMID_IPMI_COMMON_H__
+
+// IPMI Net Function number as specified by IPMI V2.0 spec.
+// Example : 
+// NETFUN_APP      =   (0x06 << 2),
+typedef unsigned char   ipmi_netfn_t;
+
+// IPMI Command for a Net Function number as specified by IPMI V2.0 spec.
+typedef unsigned char   ipmi_cmd_t;
+
+// Buffer containing data from sender of netfn and command as part of request
+typedef void*           ipmi_request_t;
+
+// This is the response buffer that the provider of [netfn,cmd] will send back
+// to the caller. Provider will allocate the memory inside the handler and then
+// will do a memcpy to this response buffer and also will set the data size
+// parameter to the size of the buffer.
+// EXAMPLE :
+// unsigned char str[] = {0x00, 0x01, 0xFE, 0xFF, 0x0A, 0x01};
+// *data_len = 6;
+// memcpy(response, &str, *data_len);
+typedef void*           ipmi_response_t;
+
+// This buffer contains any *user specific* data that is of interest only to the
+// plugin. For a ipmi function router, this data is opaque. At the time of
+// registering the plugin handlers, plugin may optionally allocate a memory and
+// fill in whatever needed that will be of help during the actual handling of
+// command. IPMID will just pass the netfn, cmd and also this data to plugins
+// during the command handler invocation.
+typedef void*           ipmi_context_t;
+
+// Length of request / response buffer depending on whether the data is a
+// request or a response from a plugin handler.
+typedef unsigned int*   ipmi_data_len_t;
+
+// This is the callback handler that the plugin registers with IPMID. IPMI
+// function router will then make a call to this callback handler with the
+// necessary arguments of netfn, cmd, request, response, size and context.
+typedef int (*ipmid_callback_t)(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
+                                ipmi_response_t, ipmi_data_len_t, ipmi_context_t);
+
+// 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.
+void ipmi_register_callback(ipmi_netfn_t, ipmi_cmd_t, ipmi_context_t, ipmid_callback_t);
+
+// IPMI commands for net functions. Since this is to be used both by the ipmi
+// function router and also the callback handler registration function, its put
+// in this .H file.
+enum ipmi_netfn_wild_card_cmd
+{
+    IPMI_CMD_WILDCARD       = 0xFF,
+};
+
+// Return codes from a IPMI operation as needed by IPMI V2.0 spec.
+enum ipmi_return_codes
+{
+    CC_OK = 0x00,
+    CC_INVALID = 0xC1
+};
+
+#endif
-- 
2.6.0




More information about the openbmc mailing list