All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI
@ 2015-10-21 12:48 OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 01/20] Convert to SDBus OpenBMC Patches
                   ` (19 more replies)
  0 siblings, 20 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

https://github.com/openbmc/phosphor-host-ipmid/pull/4

Adriana Kobylak (1):
  Watchdog support

Chris Austen (15):
  Convert to SDBus
  Set response bit returning from the ipmi call
  Reset the lib path string per .so
  Reduced MAX_IPMI_BUFFER to support ast2400 FIFO
  Add more ipmi commands for app function
  Add sensor ipmi commands
  Add storage ipmi commands
  Add support for the the dcmi package
  Print the dlopen failure for debugging
  Add routines for getting lookup data from the system dbus object
  Suport examining sensor records and calling dbus
  Added testcases for sensor record parsing
  Add virtual sensor support
  C7 and & virtual sensor support
  Fix a buffer overrun

Patrick Williams (2):
  Remove stray whitespace.
  Add 'make install' directive

vishwabmc (2):
  FRU validator CLI
  Refactored fru validator to use sd_bus

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 01/20] Convert to SDBus
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 02/20] Set response bit returning from the ipmi call OpenBMC Patches
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

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

---
 Makefile |   4 +-
 ipmid.C  | 319 +++++++++++++++++++++++++++++++++++++++++----------------------
 2 files changed, 212 insertions(+), 111 deletions(-)

diff --git a/Makefile b/Makefile
index 4baf209..be3aedd 100755
--- a/Makefile
+++ b/Makefile
@@ -5,8 +5,8 @@ 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
-LIB_FLAG += $(shell pkg-config --libs glib-2.0 gio-unix-2.0) -rdynamic
+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)
diff --git a/ipmid.C b/ipmid.C
index 37ac771..10422e1 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";
 
+const char * 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,130 @@ 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;
 
-    // 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 methods to be 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);
+
+    // Allow the length field to be used for both input and output of the 
+    // ipmi call
+    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
@@ -282,6 +365,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 +383,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;
+
 }
-- 
2.6.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 02/20] Set response bit returning from the ipmi call
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 01/20] Convert to SDBus OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 03/20] Reset the lib path string per .so OpenBMC Patches
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

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

---
 ipmid.C | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/ipmid.C b/ipmid.C
index 10422e1..3b136d0 100644
--- a/ipmid.C
+++ b/ipmid.C
@@ -181,8 +181,8 @@ static int send_ipmi_message(unsigned char seq, unsigned char netfn, unsigned ch
     }
 
 
-    // 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;
 
 
     // Add the bytes needed for the methods to be called
-- 
2.6.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 03/20] Reset the lib path string per .so
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 01/20] Convert to SDBus OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 02/20] Set response bit returning from the ipmi call OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 04/20] Reduced MAX_IPMI_BUFFER to support ast2400 FIFO OpenBMC Patches
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

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

---
 ipmid.C | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/ipmid.C b/ipmid.C
index 3b136d0..d0dfba8 100644
--- a/ipmid.C
+++ b/ipmid.C
@@ -343,13 +343,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.
-- 
2.6.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 04/20] Reduced MAX_IPMI_BUFFER to support ast2400 FIFO
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
                   ` (2 preceding siblings ...)
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 03/20] Reset the lib path string per .so OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 05/20] Add more ipmi commands for app function OpenBMC Patches
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

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

---
 ipmid.H | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/ipmid.H b/ipmid.H
index 6b7d2c9..1cfe4c3 100755
--- a/ipmid.H
+++ b/ipmid.H
@@ -10,6 +10,10 @@ 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
+
+// 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
 
 #endif
-- 
2.6.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 05/20] Add more ipmi commands for app function
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
                   ` (3 preceding siblings ...)
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 04/20] Reduced MAX_IPMI_BUFFER to support ast2400 FIFO OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 06/20] Add sensor ipmi commands OpenBMC Patches
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

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

---
 apphandler.C | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 apphandler.h |   6 +++
 2 files changed, 133 insertions(+), 10 deletions(-)

diff --git a/apphandler.C b/apphandler.C
index c86997f..596ec9c 100755
--- a/apphandler.C
+++ b/apphandler.C
@@ -1,12 +1,62 @@
 #include "apphandler.h"
 #include "ipmid-api.h"
+#include "ipmid.H"
 #include <stdio.h>
 #include <string.h>
+#include <stdint.h>
 
-void register_netfn_app_cap_bit() __attribute__((constructor));
-void register_netfn_app_wildcard() __attribute__((constructor));
+void register_netfn_app_functions() __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.
+    uint8_t str[] = {0x00, 0, 1, 1,2, 0xD, 0x41, 0xA7, 0x00, 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 +65,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};
+    uint8_t str[] = {0x01, MAX_IPMI_BUFFER, MAX_IPMI_BUFFER, 0x0A, 0x01};
 
     // Data length
     *data_len = sizeof(str);
@@ -26,6 +76,60 @@ ipmi_ret_t ipmi_app_cap_bit_handler(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
     return rc;
 }
 
+
+struct set_wd_data_t {
+    uint8_t t_use;
+    uint8_t t_action;
+    uint8_t preset;
+    uint8_t flags;
+    uint8_t ls;
+    uint8_t ms;
+}  __attribute__ ((packed));
+
+
+
+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_t *reqptr = (set_wd_data_t*) request;
+    uint16_t timer = 0;
+    // Status code.
+    ipmi_ret_t rc = IPMI_CC_OK;
+
+    *data_len = 0;
+
+    timer = (((uint16_t)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)
@@ -43,16 +147,29 @@ ipmi_ret_t ipmi_app_wildcard_handler(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
     return rc;
 }
 
-void register_netfn_app_cap_bit()
+void register_netfn_app_functions()
 {
     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);
-    return;
-}
+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CAP_BIT, NULL, ipmi_app_get_bt_capabilities);
 
-void register_netfn_app_wildcard()
-{
     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_WILDCARD);
     ipmi_register_callback(NETFUN_APP, IPMI_CMD_WILDCARD, NULL, ipmi_app_wildcard_handler);
+
+    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);
+
+    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);
+
+    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);
+
+    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);
+
+    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
-- 
2.6.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 06/20] Add sensor ipmi commands
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
                   ` (4 preceding siblings ...)
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 05/20] Add more ipmi commands for app function OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 07/20] Add storage " OpenBMC Patches
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

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

---
 Makefile        |  12 ++--
 sensorhandler.C | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sensorhandler.h |  13 ++++
 3 files changed, 233 insertions(+), 5 deletions(-)
 create mode 100644 sensorhandler.C
 create mode 100644 sensorhandler.h

diff --git a/Makefile b/Makefile
index be3aedd..9ce7c8f 100755
--- a/Makefile
+++ b/Makefile
@@ -1,20 +1,22 @@
 CXX ?= $(CROSS_COMPILE)g++
 
 DAEMON = ipmid
-DAEMON_OBJ = $(DAEMON).o
-LIB_OBJ = apphandler.o
-LIBS = libapphandler.so
+DAEMON_OBJ  = $(DAEMON).o
+LIB_APP_OBJ = apphandler.o     \
+              sensorhandler.o  \
+
+LIB_APP     = libapphandler.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) 
 
 %.o: %.C
 	$(CXX) -fpic -c $< $(CXXFLAGS) $(INC_FLAG) $(IPMID_PATH) -o $@
 
-$(LIBS): $(LIB_OBJ)
+$(LIB_APP): $(LIB_APP_OBJ)
 	$(CXX) $^ -shared $(LDFLAGS) $(LIB_FLAG) -o $@
 
 $(DAEMON): $(DAEMON_OBJ)
diff --git a/sensorhandler.C b/sensorhandler.C
new file mode 100644
index 0000000..9f0c975
--- /dev/null
+++ b/sensorhandler.C
@@ -0,0 +1,213 @@
+#include "sensorhandler.h"
+#include "ipmid-api.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+
+void register_netfn_sen_functions()   __attribute__((constructor));
+
+
+struct sensor_data_t {
+    uint8_t sennum;
+}  __attribute__ ((packed)) ;
+
+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_t *reqptr = (sensor_data_t*)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_t *reqptr = (sensor_data_t*)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_functions()
+{
+    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);
+
+    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);
+
+    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
-- 
2.6.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 07/20] Add storage ipmi commands
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
                   ` (5 preceding siblings ...)
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 06/20] Add sensor ipmi commands OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 08/20] Add support for the the dcmi package OpenBMC Patches
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

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

---
 Makefile         |   1 +
 storagehandler.C | 200 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 storagehandler.h |  16 +++++
 3 files changed, 217 insertions(+)
 create mode 100644 storagehandler.C
 create mode 100644 storagehandler.h

diff --git a/Makefile b/Makefile
index 9ce7c8f..93d3256 100755
--- a/Makefile
+++ b/Makefile
@@ -4,6 +4,7 @@ DAEMON = ipmid
 DAEMON_OBJ  = $(DAEMON).o
 LIB_APP_OBJ = apphandler.o     \
               sensorhandler.o  \
+              storagehandler.o \
 
 LIB_APP     = libapphandler.so
 
diff --git a/storagehandler.C b/storagehandler.C
new file mode 100644
index 0000000..659fff5
--- /dev/null
+++ b/storagehandler.C
@@ -0,0 +1,200 @@
+#include "storagehandler.h"
+#include "ipmid-api.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+void register_netfn_storage_functions() __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;
+}
+
+struct write_fru_data_t {
+    uint8_t  frunum;
+    uint8_t  offsetls;
+    uint8_t  offsetms;
+    uint8_t  data;
+} __attribute__ ((packed)) ;
+
+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_t *reqptr = (write_fru_data_t*) request;
+    FILE *fp;
+    char string[16];
+    short offset = 0;
+    uint16_t rlen;
+    ipmi_ret_t rc = IPMI_CC_OK;
+    char iocmd[4];
+
+    sprintf(string, "%s%02x", "/tmp/fru", reqptr->frunum);
+
+    offset = ((uint16_t)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 = ((uint16_t)*data_len) - (sizeof(write_fru_data_t)-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_functions()
+{
+    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);
+
+    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);
+
+    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);
+
+    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);
+
+    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);
+
+    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

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 08/20] Add support for the the dcmi package
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
                   ` (6 preceding siblings ...)
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 07/20] Add storage " OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 09/20] FRU validator CLI OpenBMC Patches
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

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

---
 Makefile      |  1 +
 dcmihandler.C | 40 ++++++++++++++++++++++++++++++++++++++++
 dcmihandler.h | 12 ++++++++++++
 ipmid-api.h   |  1 +
 4 files changed, 54 insertions(+)
 create mode 100644 dcmihandler.C
 create mode 100644 dcmihandler.h

diff --git a/Makefile b/Makefile
index 93d3256..2177c9d 100755
--- a/Makefile
+++ b/Makefile
@@ -5,6 +5,7 @@ DAEMON_OBJ  = $(DAEMON).o
 LIB_APP_OBJ = apphandler.o     \
               sensorhandler.o  \
               storagehandler.o \
+              dcmihandler.o
 
 LIB_APP     = libapphandler.so
 
diff --git a/dcmihandler.C b/dcmihandler.C
new file mode 100644
index 0000000..fafebdc
--- /dev/null
+++ b/dcmihandler.C
@@ -0,0 +1,40 @@
+#include "dcmihandler.h"
+#include "ipmid-api.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+void register_netfn_dcmi_functions() __attribute__((constructor));
+
+
+ipmi_ret_t ipmi_dcmi_get_power_limit(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_DCMI_CC_NO_ACTIVE_POWER_LIMIT;
+
+    // dcmi-v1-5-rev-spec.pdf 6.6.2.   
+    // This is good enough for OpenBMC support for OpenPOWER based systems
+    // TODO research if more is needed
+    uint8_t data_response[] = { 0xDC, 0x00, 0x00, 0x01, 0x00, 0x00, 
+                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                                0x00, 0x01};
+
+
+
+    printf("IPMI DCMI_GET_POWER_LEVEL\n");
+
+    memcpy(response, data_response, sizeof(data_response));
+    *data_len = sizeof(data_response);
+
+    return rc;
+}
+
+
+void register_netfn_dcmi_functions()
+{
+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_GRPEXT, IPMI_CMD_DCMI_GET_POWER);
+    ipmi_register_callback(NETFUN_GRPEXT, IPMI_CMD_DCMI_GET_POWER, NULL, ipmi_dcmi_get_power_limit);
+    return;
+}
+// 956379
\ No newline at end of file
diff --git a/dcmihandler.h b/dcmihandler.h
new file mode 100644
index 0000000..5fc0c10
--- /dev/null
+++ b/dcmihandler.h
@@ -0,0 +1,12 @@
+#ifndef __HOST_IPMI_DCMI_HANDLER_H__
+#define __HOST_IPMI_DCMI_HANDLER_H__
+
+// IPMI commands for net functions.
+enum ipmi_netfn_sen_cmds
+{
+    // Get capability bits
+    IPMI_CMD_DCMI_GET_POWER = 0x03,
+    
+};
+
+#endif
diff --git a/ipmid-api.h b/ipmid-api.h
index 615e0d5..caf18e8 100755
--- a/ipmid-api.h
+++ b/ipmid-api.h
@@ -85,6 +85,7 @@ enum ipmi_netfn_wild_card_cmd
 enum ipmi_return_codes
 {
     IPMI_CC_OK = 0x00,
+    IPMI_DCMI_CC_NO_ACTIVE_POWER_LIMIT = 0x80,
     IPMI_CC_INVALID = 0xC1
 };
 
-- 
2.6.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 09/20] FRU validator CLI
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
                   ` (7 preceding siblings ...)
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 08/20] Add support for the the dcmi package OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 10/20] Remove stray whitespace OpenBMC Patches
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

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

---
 fruvalidator.C | 252 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 252 insertions(+)
 create mode 100644 fruvalidator.C

diff --git a/fruvalidator.C b/fruvalidator.C
new file mode 100644
index 0000000..5e2ffaf
--- /dev/null
+++ b/fruvalidator.C
@@ -0,0 +1,252 @@
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+
+typedef unsigned char uint8_t;
+
+/*
+ * --- For Reference.----
+typedef struct
+{
+    uint8_t fixed;
+    uint8_t internal_offset;
+    uint8_t chassis_offset;
+    uint8_t board_offset;
+    uint8_t product_offset;
+    uint8_t multi_offset;
+    uint8_t pad;
+    uint8_t crc;
+}common_header_t;
+*/
+
+#define HDR_BYTE_ZERO   1
+#define INTERNAL_OFFSET 1
+#define HDR_CRC_OFFSET  7
+#define COMMON_HDR_SIZE 8
+
+#define RECORD_NOT_PRESENT 0
+#define EIGHT_BYTES 8
+
+uint8_t common_hdr[COMMON_HDR_SIZE] = {0};
+
+//------------------------------------------------
+// Takes the pointer to stream of bytes and length 
+// returns the 8 bit checksum per IPMI spec.
+//--------------------------------------------------
+unsigned char calculate_checksum(unsigned char *ptr, int len)
+{
+    // REFER :: http://coreipm.googlecode.com/svn-history/r40/trunk/coreipm/ipmi_pkt.c
+    char checksum = 0;
+    int byte = 0;
+
+    for(byte = 0; byte < len; byte++)
+    {
+        checksum += *ptr++;
+    }
+    
+    return( -checksum );
+}
+
+//---------------
+// Display Usage
+//---------------
+void usage(char *binary)
+{
+    printf("Usage: %s <valid binary ipmi fru file>\n", binary);
+    return;
+}    
+
+//-----------------------------------------------------
+// Accepts the filename and validated per IPMI FRU spec
+//------------------------------------------------------
+bool validate_fru_record(char *fru_file_name)
+{    
+    // Used for generic checksum calculation
+    uint8_t checksum = 0;
+
+    // This can point to 
+    uint8_t fru_section;
+
+    // A generic offset locator for any FRU record.
+    uint8_t record_offset = 0;
+
+    // Number of bytes read from FRU file.
+    size_t bytes_read = 0;
+
+    // First 2 bytes in the record.
+    uint8_t fru_record_hdr[2] = {0};
+
+    //common_header_t com_hdr;
+    memset(common_hdr, 0x0, sizeof(common_hdr));
+
+    // For now, this is user supplied in CLI. But this will be a parameter from
+    // fru handler
+    FILE *fru_file = fopen(fru_file_name,"rb");
+    if(fru_file == NULL)
+    {
+        fprintf(stderr, "ERROR: opening:[%s]\n",fru_file_name);
+        return false;
+    }
+
+    // Read first 8 bytes into common_header so we know the offsets and hdr
+    // checksum.
+    fseek(fru_file, 0, SEEK_SET);
+    bytes_read = fread(common_hdr, sizeof(common_hdr), 1, fru_file);
+    if(bytes_read != 1)
+    {
+        fprintf(stderr, "ERROR reading common header. Bytes read=:[%ld]\n",bytes_read);
+        return false;
+    }
+    
+    // 1: Validate for first byte to always have a value of [1]
+    if(common_hdr[0] != HDR_BYTE_ZERO)
+    {
+        fprintf(stderr, "ERROR: Common Header entry_1:[0x%X] Invalid.\n",common_hdr[0]);
+        return false;
+    }
+    else
+    {
+        printf("SUCCESS: Validated [0x%X] in common header\n",common_hdr[0]);
+    }
+
+    // 2: Validate the header checskum that is at last byte ( Offset: 7 )
+    checksum = calculate_checksum(common_hdr, sizeof(common_hdr)-1);
+    if(checksum != common_hdr[HDR_CRC_OFFSET])
+    {
+        fprintf(stderr, "ERROR: Common Header checksum mismatch."
+                " Calculated:[0x%X], Embedded:[0x%X]\n", 
+                checksum, common_hdr[HDR_CRC_OFFSET]);
+    
+        return false;
+    }
+    else
+    {
+        printf("SUCCESS: Common Header checksum MATCH:[0x%X]\n",checksum);
+    }
+
+    // !! FIXME FIXME FIXME FIXME
+    // This below logic fails if the record type is "Multi". I however have not
+    // seen a usecase of that in FRU inventory.. But, if I need to fix, its
+    // easy.
+    // !! FIXME FIXME FIXME FIXME
+
+    // 3: Now start walking the common_hdr array that has offsets into other FRU
+    //    record areas and validate those. Starting with second entry since the
+    //    first one is always a [0x01]
+    for(fru_section = INTERNAL_OFFSET ; fru_section < (COMMON_HDR_SIZE - 2)  ; fru_section++)
+    {
+        // Offset is 'value given in' internal_offset * 8 from the START of
+        // common header. So an an example, 01 00 00 00 01 00 00 fe has
+        // product area set at the offset 01 * 8 --> 8 bytes from the START of
+        // common header. That means, soon after the header checksum.
+        record_offset = common_hdr[fru_section] * EIGHT_BYTES;
+
+        if(record_offset)
+        {
+            // A NON zero value means that the vpd packet has the data for that
+            // section.  These are the things needed at this moment:
+
+            // 1: Goto beginning of the FILE
+            rewind(fru_file);
+
+            // 2: Move the file pointer to record_offset
+            fseek(fru_file, record_offset, SEEK_SET);
+
+            // 3: Read first 2 bytes containing FIXED[0x1] and record Length.
+            fread(fru_record_hdr, sizeof(fru_record_hdr), 1, fru_file);
+
+            // 5: If first element in the record header is _not_ a fixed:[0x01], err out.
+            if(fru_record_hdr[0] != HDR_BYTE_ZERO)
+            {
+                fprintf(stderr, "ERROR: Unexpected :[0x%X] found at Record header",
+                        fru_record_hdr[0]);
+
+                return false;
+            }
+            else
+            {
+                printf("SUCCESS: Validated [0x%X] in fru record:[%d] header\n",
+                        fru_record_hdr[0],fru_section);
+            }
+
+            // 4: Read Length bytes ( makes a complete record read now )
+            uint8_t fru_record_len = fru_record_hdr[1] * EIGHT_BYTES;
+
+            printf("RECORD NO[%d], SIZE = [%d] \n",fru_section, fru_record_len);
+
+            uint8_t fru_record_data[fru_record_len];
+            memset(fru_record_data, 0x0, sizeof(fru_record_data));
+
+            // Since the data is from record data[0], move the file pointer again to
+            // beginning of record.
+            fseek(fru_file, -2, SEEK_CUR);
+            fread(fru_record_data, sizeof(fru_record_data), 1, fru_file);
+
+            // 5: Calculate checksum (from offset -> (Length-1)).
+            //    All the bytes except the last byte( which is CRC :) ) will
+            //    participate in calculating the checksum.
+            checksum = calculate_checksum(fru_record_data, sizeof(fru_record_data)-1);
+
+            // 6: Verify the embedded checksum in last byte with calculated checksum
+            //    record_len -1 since length is some N but numbering is 0..N-1
+            if(checksum != fru_record_data[fru_record_len-1])
+            {
+                fprintf(stderr, "ERROR: FRU Header checksum mismatch. "
+                        " Calculated:[0x%X], Embedded:[0x%X]\n", 
+                        checksum, fru_record_data[fru_record_len-1]);
+
+                return false;
+            }
+            else
+            {
+                printf("SUCCESS: FRU Header checksum MATCH:[0x%X]\n",checksum);
+            }
+
+            // 7: If everything is okay, then we are fine.. Else mostly we are
+            //    awaiting another FRU write -OR- worst case, the VPD is corrupted
+            //    over BT.
+        } // If the packet has data for a particular data record.
+    } // End walking all the fru records.
+        
+    return true;
+}
+
+//---------------------------------------------------------------------
+// Main function but this will be integrated as a API for
+// Open BMC code that accepts a filename and returns success or failure
+//----------------------------------------------------------------------
+int main(int argc, char *argv[])
+{
+    // Right way is to do a parse_opt but that is poky for now.
+    if(argc != 2)
+    {
+        usage(argv[0]);
+        return -1;
+    }
+
+    // Check if this file is really present.
+    struct stat statbuff;
+    if(stat(argv[1], &statbuff) == -1)
+    {
+        usage(argv[0]);
+        return -1;
+    }
+    else if(statbuff.st_mode & S_IFMT != S_IFREG)
+    {
+        usage(argv[0]);
+        return -1;
+    }
+        
+    bool scan_result = validate_fru_record(argv[1]);
+    if(scan_result == true)
+    {
+        printf("SUCCESS: Validated:[%s]\n",argv[1]);
+    }
+    else
+    {
+        printf("ERROR: Validation failed for:[%s]\n",argv[1]);
+        return -1;
+    }
+
+    return 0;
+}
-- 
2.6.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 10/20] Remove stray whitespace.
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
                   ` (8 preceding siblings ...)
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 09/20] FRU validator CLI OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 11/20] Add 'make install' directive OpenBMC Patches
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

From: Patrick Williams <patrick@stwcx.xyz>

---
 Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 2177c9d..73cefc6 100755
--- a/Makefile
+++ b/Makefile
@@ -11,9 +11,9 @@ LIB_APP     = libapphandler.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/\" 
+IPMID_PATH ?= -DHOST_IPMI_LIB_PATH=\"/usr/lib/host-ipmid/\"
 
-all: $(DAEMON) $(LIB_APP) 
+all: $(DAEMON) $(LIB_APP)
 
 %.o: %.C
 	$(CXX) -fpic -c $< $(CXXFLAGS) $(INC_FLAG) $(IPMID_PATH) -o $@
-- 
2.6.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 11/20] Add 'make install' directive
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
                   ` (9 preceding siblings ...)
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 10/20] Remove stray whitespace OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 12/20] Watchdog support OpenBMC Patches
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

From: Patrick Williams <patrick@stwcx.xyz>

---
 Makefile | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/Makefile b/Makefile
index 73cefc6..cf1d9cb 100755
--- a/Makefile
+++ b/Makefile
@@ -8,11 +8,18 @@ LIB_APP_OBJ = apphandler.o     \
               dcmihandler.o
 
 LIB_APP     = libapphandler.so
+INSTALLED_LIBS += $(LIB_APP)
+INSTALLED_HEADERS = ipmid-api.h
 
 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/\"
 
+DESTDIR ?= /
+SBINDIR ?= /usr/sbin
+INCLUDEDIR ?= /usr/include
+LIBDIR ?= /usr/lib
+
 all: $(DAEMON) $(LIB_APP)
 
 %.o: %.C
@@ -26,3 +33,12 @@ $(DAEMON): $(DAEMON_OBJ)
 
 clean:
 	rm -f $(DAEMON) *.o *.so
+
+install:
+		install -m 0755 -d $(DESTDIR)$(SBINDIR)
+		install -m 0755 ipmid $(DESTDIR)$(SBINDIR)
+		install -m 0755 -d $(DESTDIR)$(LIBDIR)/host-ipmid
+		install -m 0755 $(INSTALLED_LIBS) $(DESTDIR)$(LIBDIR)/host-ipmid
+		install -m 0755 -d $(DESTDIR)$(INCLUDEDIR)/host-ipmid
+		install -m 0644 $(INSTALLED_HEADERS) $(DESTDIR)$(INCLUDEDIR)/host-ipmid
+
-- 
2.6.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 12/20] Watchdog support
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
                   ` (10 preceding siblings ...)
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 11/20] Add 'make install' directive OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 13/20] Print the dlopen failure for debugging OpenBMC Patches
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

From: Adriana Kobylak <anoo@us.ibm.com>

---
 apphandler.C | 110 ++++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 86 insertions(+), 24 deletions(-)

diff --git a/apphandler.C b/apphandler.C
index 596ec9c..9d53552 100755
--- a/apphandler.C
+++ b/apphandler.C
@@ -4,12 +4,15 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdint.h>
+#include <systemd/sd-bus.h>
+
+extern sd_bus *bus;
 
 void register_netfn_app_functions() __attribute__((constructor));
 
 
-ipmi_ret_t ipmi_app_read_event(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 
-                             ipmi_request_t request, ipmi_response_t response, 
+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;
@@ -21,8 +24,8 @@ ipmi_ret_t ipmi_app_read_event(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
 }
 
 
-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_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;
@@ -32,18 +35,18 @@ ipmi_ret_t ipmi_app_set_acpi_power_state(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
     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_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 
+    // 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 
+    // 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.
     uint8_t str[] = {0x00, 0, 1, 1,2, 0xD, 0x41, 0xA7, 0x00, 0x43, 0x40};
 
@@ -56,8 +59,8 @@ ipmi_ret_t ipmi_app_get_device_id(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
 }
 
 
-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_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)
 {
     printf("Handling Netfn:[0x%X], Cmd:[0x%X]\n",netfn,cmd);
@@ -88,41 +91,100 @@ struct set_wd_data_t {
 
 
 
-ipmi_ret_t ipmi_app_set_watchdog(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 
-                             ipmi_request_t request, ipmi_response_t response, 
+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)
 {
+    const char  *busname = "org.openbmc.watchdog.Host";
+    const char  *objname = "/org/openbmc/watchdog/HostWatchdog_0";
+    const char  *iface = "org.openbmc.Watchdog";
+    sd_bus_message *reply = NULL, *m = 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;
 
+    // Get number of 100ms intervals
     timer = (((uint16_t)reqptr->ms) << 8) + reqptr->ls;
+    // Get timer value in ms
+    timer_ms = timer * 100;
 
     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.
+    // 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;
+    }
+
+    // Start watchdog
+    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;
+    }
+
+    sd_bus_error_free(&error);
+    sd_bus_message_unref(m);
 
     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_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)
 {
+    const char  *busname = "org.openbmc.watchdog.Host";
+    const char  *objname = "/org/openbmc/watchdog/HostWatchdog_0";
+    const char  *iface = "org.openbmc.Watchdog";
+    sd_bus_message *reply = NULL, *m = NULL;
+    sd_bus_error error = SD_BUS_ERROR_NULL;
+    int r = 0;
+
     // 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
+
+    // Refresh watchdog
+    r = sd_bus_message_new_method_call(bus,&m,busname,objname,iface,"poke");
+    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;
+    }
+
+    sd_bus_error_free(&error);
+    sd_bus_message_unref(m);
+
     return rc;
 }
 
@@ -130,8 +192,8 @@ ipmi_ret_t ipmi_app_reset_watchdog(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
 
 
 
-ipmi_ret_t ipmi_app_wildcard_handler(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 
-                              ipmi_request_t request, ipmi_response_t response, 
+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)
 {
     printf("Handling WILDCARD Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
-- 
2.6.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 13/20] Print the dlopen failure for debugging
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
                   ` (11 preceding siblings ...)
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 12/20] Watchdog support OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 14/20] Add routines for getting lookup data from the system dbus object OpenBMC Patches
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

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

---
 ipmid.C | 36 ++++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/ipmid.C b/ipmid.C
index d0dfba8..3f697f1 100644
--- a/ipmid.C
+++ b/ipmid.C
@@ -37,7 +37,7 @@ std::map<ipmi_fn_cmd_t, ipmi_fn_context_t> g_ipmid_router_map;
 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 */
@@ -45,7 +45,7 @@ void hexdump(void *mem, size_t len)
                 {
                         printf("0x%06x: ", i);
                 }
- 
+
                 /* print hex data */
                 if(i < len)
                 {
@@ -55,7 +55,7 @@ void hexdump(void *mem, size_t len)
                 {
                         printf("   ");
                 }
-                
+
                 /* print ASCII dump */
                 if(i % HEXDUMP_COLS == (HEXDUMP_COLS - 1))
                 {
@@ -67,7 +67,7 @@ void hexdump(void *mem, size_t len)
                                 }
                                 else if(isprint(((char*)mem)[j])) /* printable char */
                                 {
-                                        putchar(0xFF & ((char*)mem)[j]);        
+                                        putchar(0xFF & ((char*)mem)[j]);
                                 }
                                 else /* other char */
                                 {
@@ -150,11 +150,11 @@ ipmi_ret_t ipmi_netfn_router(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t
     // Response message from the plugin goes into a byte post the base response
     rc = (handler_and_context.first) (netfn, cmd, request, respo,
                                       data_len, handler_and_context.second);
- 
+
     // Now copy the return code that we got from handler and pack it in first
     // byte.
     memcpy(response, &rc, IPMI_CC_LEN);
- 
+
     // Data length is now actual data + completion code.
     *data_len = *data_len + IPMI_CC_LEN;
 
@@ -191,7 +191,7 @@ static int send_ipmi_message(unsigned char seq, unsigned char netfn, unsigned ch
         fprintf(stderr, "Failed add the netfn and others : %s\n", strerror(-r));
         return -1;
     }
-   
+
     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));
@@ -210,7 +210,7 @@ static int send_ipmi_message(unsigned char seq, unsigned char netfn, unsigned ch
     r = sd_bus_message_read(reply, "x", &pty);
 #ifdef __IPMI_DEBUG__
     printf("RC from the ipmi dbus method :%d \n", pty);
-#endif    
+#endif
     if (r < 0) {
        fprintf(stderr, "Failed to get a rc from the method: %s\n", strerror(-r));
 
@@ -223,7 +223,7 @@ static int send_ipmi_message(unsigned char seq, unsigned char netfn, unsigned ch
 
 #ifdef __IPMI_DEBUG__
     printf("%d : %s\n", __LINE__, __PRETTY_FUNCTION__ );
-#endif    
+#endif
     return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 
 }
@@ -258,11 +258,11 @@ static int handle_ipmi_command(sd_bus_message *m, void *user_data, sd_bus_error
     printf("Seq 0x%02x, NetFn 0x%02x, CMD: 0x%02x \n", sequence, netfn, cmd);
     hexdump((void*)request, sz);
 
-    // Allow the length field to be used for both input and output of the 
+    // Allow the length field to be used for both input and output of the
     // ipmi call
     resplen = sz;
 
-    // Now that we have parsed the entire byte array from the caller 
+    // 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)
@@ -300,7 +300,7 @@ int handler_select(const struct dirent *entry)
     if(strstr(entry->d_name, IPMI_PLUGIN_EXTN))
     {
         // 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 
+        // 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)
@@ -312,7 +312,7 @@ int handler_select(const struct dirent *entry)
 }
 
 // This will do a dlopen of every .so in ipmi_lib_path and will dlopen everything so that they will
-// register a callback handler 
+// register a callback handler
 void ipmi_register_callback_handlers(const char* ipmi_lib_path)
 {
     // For walking the ipmi_lib_path
@@ -331,11 +331,11 @@ void ipmi_register_callback_handlers(const char* ipmi_lib_path)
     {
         // 1: Open ipmi_lib_path. Its usually "/usr/lib/phosphor-host-ipmid"
         // 2: Scan the directory for the files that end with .so
-        // 3: For each one of them, just do a 'dlopen' so that they register 
+        // 3: For each one of them, just do a 'dlopen' so that they register
         //    the handlers for callback routines.
 
         std::string handler_fqdn = ipmi_lib_path;
-        
+
         // Append a "/" since we need to add the name of the .so. If there is
         // already a .so, adding one more is not any harm.
         handler_fqdn += "/";
@@ -350,8 +350,8 @@ void ipmi_register_callback_handlers(const char* ipmi_lib_path)
             lib_handler = dlopen(handler_fqdn.c_str(), RTLD_NOW);
             if(lib_handler == NULL)
             {
-                fprintf(stderr,"ERROR opening:[%s]\n",handler_fqdn.c_str());
-                dlerror();
+                fprintf(stderr,"ERROR opening [%s]: %s\n",
+                        handler_fqdn.c_str(), dlerror());
             }
             // Wipe the memory allocated for this particular entry.
             free(handler_list[num_handlers]);
@@ -381,7 +381,7 @@ int main(int argc, char *argv[])
     for(auto& iter : g_ipmid_router_map)
     {
         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);  
+        printf("NETFN:[0x%X], cmd[0x%X]\n", fn_and_cmd.first, fn_and_cmd.second);
     }
 #endif
 
-- 
2.6.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 14/20] Add routines for getting lookup data from the system dbus object
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
                   ` (12 preceding siblings ...)
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 13/20] Print the dlopen failure for debugging OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 15/20] Suport examining sensor records and calling dbus OpenBMC Patches
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

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

---
 ipmid.C | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 121 insertions(+)

diff --git a/ipmid.C b/ipmid.C
index 3f697f1..a134832 100644
--- a/ipmid.C
+++ b/ipmid.C
@@ -426,3 +426,124 @@ finish:
     return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 
 }
+
+
+#define MAX_DBUS_PATH 128
+struct dbus_interface_t {
+    uint8_t  sensornumber;
+    uint8_t  sensortype;
+
+    char  bus[MAX_DBUS_PATH];
+    char  path[MAX_DBUS_PATH];
+    char  interface[MAX_DBUS_PATH];
+};
+
+
+
+// Use a lookup table to find the interface name of a specific sensor
+// This will be used until an alternative is found.  this is the first
+// step for mapping IPMI
+int find_openbmc_path(const char *type, const uint8_t num, dbus_interface_t *interface) {
+
+    const char  *busname = "org.openbmc.managers.System";
+    const char  *objname = "/org/openbmc/managers/System";
+
+    char  *str1, *str2, *str3;
+    sd_bus_error error = SD_BUS_ERROR_NULL;
+    sd_bus_message *reply = NULL, *m=NULL;
+
+
+    int r;
+
+    r = sd_bus_message_new_method_call(bus,&m,busname,objname,busname,"getObjectFromByteId");
+    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));
+        goto final;
+    }
+
+    strncpy(interface->bus, str1, MAX_DBUS_PATH);
+    strncpy(interface->path, str2, MAX_DBUS_PATH);
+    strncpy(interface->interface, str3, MAX_DBUS_PATH);
+
+    interface->sensornumber = num;
+
+
+final:
+
+    sd_bus_error_free(&error);
+    sd_bus_message_unref(m);
+
+    return r;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+//
+// 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) {
+
+
+    dbus_interface_t a;
+    int r;
+    sd_bus_error error = SD_BUS_ERROR_NULL;
+    sd_bus_message *reply = NULL, *m=NULL;
+
+    printf("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);
+
+    printf("**********************\n");
+    printf("%s\n", a.bus);
+    printf("%s\n", a.path);
+    printf("%s\n", a.interface);
+
+
+    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));
+    }
+
+    // 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));
+    }
+
+
+
+    sd_bus_error_free(&error);
+    sd_bus_message_unref(m);
+
+    return 0;
+
+
+}
-- 
2.6.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 15/20] Suport examining sensor records and calling dbus
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
                   ` (13 preceding siblings ...)
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 14/20] Add routines for getting lookup data from the system dbus object OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 16/20] Added testcases for sensor record parsing OpenBMC Patches
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

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

---
 Makefile        |   3 +-
 ipmisensor.C    | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sensorhandler.C |   8 +++-
 3 files changed, 127 insertions(+), 3 deletions(-)
 create mode 100644 ipmisensor.C

diff --git a/Makefile b/Makefile
index cf1d9cb..cebf798 100755
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,8 @@ DAEMON_OBJ  = $(DAEMON).o
 LIB_APP_OBJ = apphandler.o     \
               sensorhandler.o  \
               storagehandler.o \
-              dcmihandler.o
+              dcmihandler.o    \
+              ipmisensor.o
 
 LIB_APP     = libapphandler.so
 INSTALLED_LIBS += $(LIB_APP)
diff --git a/ipmisensor.C b/ipmisensor.C
new file mode 100644
index 0000000..c2370b8
--- /dev/null
+++ b/ipmisensor.C
@@ -0,0 +1,119 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+
+extern unsigned char findSensor(char);
+
+struct sensorRES_t {
+	uint8_t sensor_number;
+	uint8_t operation;
+	uint8_t sensor_reading;
+	uint8_t assert_state7_0;
+	uint8_t assert_state14_8;	
+	uint8_t deassert_state7_0;
+	uint8_t deassert_state14_8;	
+	uint8_t event_data1;
+	uint8_t event_data2;
+	uint8_t event_data3;	
+} __attribute__ ((packed));
+
+#define ISBITSET(x,y) ((x>>y)&0x01)
+#define ASSERTINDEX 0
+#define DEASSERTINDEX 1
+
+
+extern int updateDbusInterface(uint8_t , const char *, const char *) ;
+extern int set_sensor_dbus_state(uint8_t ,const char *, const char *);
+
+
+
+// Sensor Type,  Offset, function handler, Dbus Method, Assert value, Deassert value
+struct lookup_t {
+	uint8_t sensor_type;
+	uint8_t offset;
+	int (*func)(uint8_t, const char *, const char *);
+	char    method[16];
+	char    assertion[16];
+	char    deassertion[16];
+};
+
+
+//  This table lists only senors we care about telling dbus about.
+//  Offset definition cab be found in section 42.2 of the IPMI 2.0 
+//  spec.  Add more if/when there are more items of interest.
+lookup_t ipmidbuslookup[] = {
+
+	{0x07, 0x07, set_sensor_dbus_state, "setPresent", "True", "False"},
+	{0x07, 0x08, set_sensor_dbus_state, "setFault",   "True", "False"},
+	{0x0C, 0x06, set_sensor_dbus_state, "setPresent", "True", "False"},
+	{0x0C, 0x04, set_sensor_dbus_state, "setFault",   "True", "False"},
+	{0xFF, 0xFF, NULL,                  "",            "" ,    ""}
+};
+
+int findindex(const uint8_t sensor_type, int offset, int *index) {
+	
+	int i=0, rc=0;
+	lookup_t *pTable = ipmidbuslookup;
+
+	do {
+
+		if ( ((pTable+i)->sensor_type == sensor_type) && 
+			 ((pTable+i)->offset  == offset)  ) {
+			rc = 1;
+			*index = i;
+			break;
+		}
+		i++;
+	} while ((pTable+i)->sensor_type  != 0xFF);
+
+	return rc;
+}
+
+int shouldReport(sensorRES_t *pRec, uint8_t sensorType, int offset, int assertState) {
+
+	int index;
+	char *pState;
+	lookup_t *pTable = ipmidbuslookup;
+
+	if (findindex(sensorType, offset, &index)) {
+
+		if (assertState == ASSERTINDEX) {
+			pState = (pTable+index)->assertion;
+		} else {
+			pState = (pTable+index)->deassertion;
+		}
+		(*((pTable+index)->func))(pRec->sensor_number, (pTable+index)->method, pState);
+	}
+
+	return 0;
+}
+
+
+int updateSensorRecordFromSSRAESC(const void *record) {
+
+	sensorRES_t *pRec = (sensorRES_t *) record;
+	unsigned char stype;
+	int index, i=0;
+
+	stype = findSensor(pRec->sensor_number);
+
+	// Scroll through each bit position .  Determine 
+	// if any bit is either asserted or Deasserted.
+	for(i=0;i<8;i++) {
+		if (ISBITSET(pRec->assert_state7_0,i)) { 
+			shouldReport(pRec, stype, i, ASSERTINDEX);
+		}
+		if (ISBITSET(pRec->assert_state14_8,i)) { 
+			shouldReport(pRec, stype, i+8, ASSERTINDEX);
+		}
+		if (ISBITSET(pRec->deassert_state7_0,i)) { 
+			shouldReport(pRec, stype, i, DEASSERTINDEX);
+		}
+		if (ISBITSET(pRec->deassert_state14_8,i)) { 
+			shouldReport(pRec, stype, i+8, DEASSERTINDEX);
+		}
+	}
+
+	return 0;
+}
diff --git a/sensorhandler.C b/sensorhandler.C
index 9f0c975..0b16d10 100644
--- a/sensorhandler.C
+++ b/sensorhandler.C
@@ -4,6 +4,7 @@
 #include <string.h>
 #include <stdint.h>
 
+extern int updateSensorRecordFromSSRAESC(const void *);
 
 void register_netfn_sen_functions()   __attribute__((constructor));
 
@@ -166,20 +167,22 @@ ipmi_ret_t ipmi_sen_set_sensor(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
     ipmi_ret_t rc = IPMI_CC_OK;
     unsigned short rlen;
 
-    rlen = (unsigned short) *data_len - 1;
+    rlen = (unsigned short) *data_len;
 
     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);
+        fwrite(reqptr,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;        
     }
 
+    updateSensorRecordFromSSRAESC(reqptr);
+
     *data_len=0;
 
 
@@ -209,5 +212,6 @@ void register_netfn_sen_functions()
 
     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;
 }
-- 
2.6.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 16/20] Added testcases for sensor record parsing
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
                   ` (14 preceding siblings ...)
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 15/20] Suport examining sensor records and calling dbus OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 17/20] Add virtual sensor support OpenBMC Patches
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

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

---
 Makefile |  14 ++++--
 testit.C | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 173 insertions(+), 3 deletions(-)
 create mode 100644 testit.C

diff --git a/Makefile b/Makefile
index cebf798..45e3d0f 100755
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,17 @@
 CXX ?= $(CROSS_COMPILE)g++
 
+TESTER = testit
+
 DAEMON = ipmid
 DAEMON_OBJ  = $(DAEMON).o
 LIB_APP_OBJ = apphandler.o     \
               sensorhandler.o  \
               storagehandler.o \
               dcmihandler.o    \
-              ipmisensor.o
+
+
+TESTER_OBJ = ipmisensor.o 	   \
+			 testit.o
 
 LIB_APP     = libapphandler.so
 INSTALLED_LIBS += $(LIB_APP)
@@ -21,7 +26,7 @@ SBINDIR ?= /usr/sbin
 INCLUDEDIR ?= /usr/include
 LIBDIR ?= /usr/lib
 
-all: $(DAEMON) $(LIB_APP)
+all: $(DAEMON) $(LIB_APP) $(TESTER)
 
 %.o: %.C
 	$(CXX) -fpic -c $< $(CXXFLAGS) $(INC_FLAG) $(IPMID_PATH) -o $@
@@ -32,8 +37,11 @@ $(LIB_APP): $(LIB_APP_OBJ)
 $(DAEMON): $(DAEMON_OBJ)
 	$(CXX) $^ $(LDFLAGS) $(LIB_FLAG) -o $@ -ldl
 
+$(TESTER): $(TESTER_OBJ)
+	$(CXX) $^ $(LDFLAGS) $(LIB_FLAG) -o $@ -ldl
+
 clean:
-	rm -f $(DAEMON) *.o *.so
+	rm -f $(DAEMON) $(TESTER) *.o *.so
 
 install:
 		install -m 0755 -d $(DESTDIR)$(SBINDIR)
diff --git a/testit.C b/testit.C
new file mode 100644
index 0000000..0641a55
--- /dev/null
+++ b/testit.C
@@ -0,0 +1,162 @@
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+
+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];
+
+}
+
+
+int set_sensor_dbus_state(uint8_t number, const char *method, const char *value) {
+
+	printf("Attempting to log Sensor 0x%02x via %s with a value of %s\n", 
+		number, method, value);
+
+	return 0;
+}
+
+
+extern int updateSensorRecordFromSSRAESC(const void *record);
+
+
+
+
+
+uint8_t testrec_boot1[] = {0x05, 0xa9, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00};
+uint8_t testrec_boot2[] = {0x05, 0xa9, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
+uint8_t testrec_boot3[] = {0x05, 0xa9, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00};
+uint8_t testrec_boot4[] = {0x05, 0xa9, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00};                       
+
+
+
+// DIMM Present
+uint8_t testrec_sensor1[] {0x1F, 0xa9, 0x00, 0x40, 0x00, 0x10, 0x00, 0x00};
+
+// DIMM Not present
+uint8_t testrec_sensor2[] {0x1F, 0xa9, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00};
+
+
+uint8_t testrec_bootprogress[]  = {05, 0xa9, 0x00, 0x04, 0x00, 0x00, 0x14, 0x00 };
+
+int main() {
+
+	updateSensorRecordFromSSRAESC(testrec_bootprogress);
+	updateSensorRecordFromSSRAESC(testrec_sensor1);
+	updateSensorRecordFromSSRAESC(testrec_sensor2);
+
+
+	return 0;
+}
\ No newline at end of file
-- 
2.6.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 17/20] Add virtual sensor support
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
                   ` (15 preceding siblings ...)
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 16/20] Added testcases for sensor record parsing OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 18/20] C7 and & " OpenBMC Patches
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

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

---
 Makefile     |   1 +
 ipmid.C      |  44 ++++++++++++++++
 ipmisensor.C | 170 +++++++++++++++++++++++++++++++++++++++++++++--------------
 testit.C     |   8 ++-
 4 files changed, 180 insertions(+), 43 deletions(-)

diff --git a/Makefile b/Makefile
index 45e3d0f..1f2c7aa 100755
--- a/Makefile
+++ b/Makefile
@@ -8,6 +8,7 @@ LIB_APP_OBJ = apphandler.o     \
               sensorhandler.o  \
               storagehandler.o \
               dcmihandler.o    \
+              ipmisensor.o     \
 
 
 TESTER_OBJ = ipmisensor.o 	   \
diff --git a/ipmid.C b/ipmid.C
index a134832..4f0831e 100644
--- a/ipmid.C
+++ b/ipmid.C
@@ -547,3 +547,47 @@ int set_sensor_dbus_state(uint8_t number, const char *method, const char *value)
 
 
 }
+
+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;
+
+    printf("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);
+
+    printf("**********************\n");
+    printf("%s\n", a.bus);
+    printf("%s\n", a.path);
+    printf("%s\n", a.interface);
+
+
+    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, "v", "s", value);
+    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, NULL);
+    if (r < 0) {
+        fprintf(stderr, "12 Failed to call the method: %s", strerror(-r));
+    }
+
+
+
+    sd_bus_error_free(&error);
+    sd_bus_message_unref(m);
+
+    return 0;
+}
diff --git a/ipmisensor.C b/ipmisensor.C
index c2370b8..72cb576 100644
--- a/ipmisensor.C
+++ b/ipmisensor.C
@@ -4,6 +4,9 @@
 
 
 extern unsigned char findSensor(char);
+extern int set_sensor_dbus_state_v(uint8_t , const char *, char *);
+
+
 
 struct sensorRES_t {
 	uint8_t sensor_number;
@@ -18,48 +21,136 @@ struct sensorRES_t {
 	uint8_t event_data3;	
 } __attribute__ ((packed));
 
-#define ISBITSET(x,y) ((x>>y)&0x01)
+#define ISBITSET(x,y) (((x)>>(y))&0x01)
 #define ASSERTINDEX 0
 #define DEASSERTINDEX 1
 
-
-extern int updateDbusInterface(uint8_t , const char *, const char *) ;
-extern int set_sensor_dbus_state(uint8_t ,const char *, const char *);
-
-
-
 // Sensor Type,  Offset, function handler, Dbus Method, Assert value, Deassert value
 struct lookup_t {
 	uint8_t sensor_type;
 	uint8_t offset;
-	int (*func)(uint8_t, const char *, const char *);
+	int (*func)(const sensorRES_t *, const lookup_t *, const char *);
 	char    method[16];
 	char    assertion[16];
 	char    deassertion[16];
 };
 
 
+extern int updateDbusInterface(uint8_t , const char *, const char *) ;
+extern int set_sensor_dbus_state(uint8_t ,const char *, const char *);
+
+
+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);
+}
+
+struct event_data_t {
+	uint8_t data;
+	char    text[32];
+};
+
+event_data_t g_fwprogress02h[] = {
+	{0x00, "Unspecified"},
+	{0x01, "Memory Init"},
+	{0x02, "HD Init"},
+	{0x03, "Secondary Proc Init"},
+	{0x04, "User Authentication"},
+	{0x05, "User init system setup"},
+	{0x06, "USB configuration"},
+	{0x07, "PCI configuration"},
+	{0x08, "Option ROM Init"},
+	{0x09, "Video Init"},
+	{0x0A, "Cache Init"},
+	{0x0B, "SM Bus init"},
+	{0x0C, "Keyboard Init"},
+	{0x0D, "Embedded ctrl init"},
+	{0x0E, "Docking station attachment"},
+	{0x0F, "Enable docking station"},
+	{0x10, "Docking station ejection"},
+	{0x11, "Disabling docking station"},
+	{0x12, "Calling OS Wakeup"},
+	{0x13, "Starting OS"},
+	{0x14, "Baseboard Init"},
+	{0x15, ""},
+	{0x16, "Floppy Init"},
+	{0x17, "Keyboard Test"},
+	{0x18, "Pointing Device Test"},
+	{0x19, "Primary Proc Init"},
+	{0xFF, "Unknown"}
+};
+
+
+char *getfw02string(uint8_t b) {
+
+	int i = 0;
+	event_data_t *p = g_fwprogress02h;
+
+	do {
+
+		if ((p+i)->data == b)
+			break;
+		i++;
+	} while ((p+i)->data != 0xFF);
+
+	return p->text;
+}
+//  The fw progress sensor contains some additional information that needs to be processed
+//  prior to calling the dbus code.  
+int set_sensor_dbus_state_fwprogress(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) {
+
+	char valuestring[32];
+	char* pStr = valuestring;
+
+	switch (pTable->offset) {
+
+		case 0x00 : sprintf(valuestring, "POST Error, 0x%02x", pRec->event_data2);
+					break;
+		case 0x01 : sprintf(valuestring, "FW Hang, 0x%02x", pRec->event_data2);
+					break;
+		case 0x02 : sprintf(valuestring, "FW Progress, 0x%02x", getfw02string(pRec->event_data2));
+	}
+
+	return set_sensor_dbus_state_v(pRec->sensor_number, pTable->method, pStr);
+}
+
+
 //  This table lists only senors we care about telling dbus about.
 //  Offset definition cab be found in section 42.2 of the IPMI 2.0 
 //  spec.  Add more if/when there are more items of interest.
-lookup_t ipmidbuslookup[] = {
+lookup_t g_ipmidbuslookup[] = {
 
-	{0x07, 0x07, set_sensor_dbus_state, "setPresent", "True", "False"},
-	{0x07, 0x08, set_sensor_dbus_state, "setFault",   "True", "False"},
-	{0x0C, 0x06, set_sensor_dbus_state, "setPresent", "True", "False"},
-	{0x0C, 0x04, set_sensor_dbus_state, "setFault",   "True", "False"},
-	{0xFF, 0xFF, NULL,                  "",            "" ,    ""}
+	{0x07, 0x07, set_sensor_dbus_state_simple, "setPresent", "True", "False"},
+	{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", "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"},
+
+	{0xFF, 0xFF, NULL, "", "", ""}
 };
 
+
+
+void reportSensorEventAssert(sensorRES_t *pRec, int index) {
+	lookup_t *pTable = &g_ipmidbuslookup[index];
+	(*pTable->func)(pRec, pTable, pTable->assertion);
+}
+void reportSensorEventDeassert(sensorRES_t *pRec, int index) {
+	lookup_t *pTable = &g_ipmidbuslookup[index];
+	(*pTable->func)(pRec, pTable, pTable->deassertion);
+}
+
+
 int findindex(const uint8_t sensor_type, int offset, int *index) {
 	
 	int i=0, rc=0;
-	lookup_t *pTable = ipmidbuslookup;
+	lookup_t *pTable = g_ipmidbuslookup;
 
 	do {
-
 		if ( ((pTable+i)->sensor_type == sensor_type) && 
-			 ((pTable+i)->offset  == offset)  ) {
+			 ((pTable+i)->offset  == offset) ) {
 			rc = 1;
 			*index = i;
 			break;
@@ -70,23 +161,12 @@ int findindex(const uint8_t sensor_type, int offset, int *index) {
 	return rc;
 }
 
-int shouldReport(sensorRES_t *pRec, uint8_t sensorType, int offset, int assertState) {
-
-	int index;
-	char *pState;
-	lookup_t *pTable = ipmidbuslookup;
+bool shouldReport(uint8_t sensorType, int offset, int *index) {
 
-	if (findindex(sensorType, offset, &index)) {
+	bool rc = false;
+	if (findindex(sensorType, offset, index)) { rc = true;	}
 
-		if (assertState == ASSERTINDEX) {
-			pState = (pTable+index)->assertion;
-		} else {
-			pState = (pTable+index)->deassertion;
-		}
-		(*((pTable+index)->func))(pRec->sensor_number, (pTable+index)->method, pState);
-	}
-
-	return 0;
+	return rc;
 }
 
 
@@ -95,23 +175,31 @@ int updateSensorRecordFromSSRAESC(const void *record) {
 	sensorRES_t *pRec = (sensorRES_t *) record;
 	unsigned char stype;
 	int index, i=0;
-
 	stype = findSensor(pRec->sensor_number);
 
+
 	// Scroll through each bit position .  Determine 
 	// if any bit is either asserted or Deasserted.
 	for(i=0;i<8;i++) {
-		if (ISBITSET(pRec->assert_state7_0,i)) { 
-			shouldReport(pRec, stype, i, ASSERTINDEX);
+		if ((ISBITSET(pRec->assert_state7_0,i))  &&
+			(shouldReport(stype, i, &index)))
+		{
+			reportSensorEventAssert(pRec, index);
 		}
-		if (ISBITSET(pRec->assert_state14_8,i)) { 
-			shouldReport(pRec, stype, i+8, ASSERTINDEX);
+		if ((ISBITSET(pRec->assert_state14_8,i+8))  &&
+			(shouldReport(stype, i+8, &index)))
+		{
+			reportSensorEventAssert(pRec, index);
 		}
-		if (ISBITSET(pRec->deassert_state7_0,i)) { 
-			shouldReport(pRec, stype, i, DEASSERTINDEX);
+		if ((ISBITSET(pRec->deassert_state7_0,i))  &&
+			(shouldReport(stype, i, &index)))
+		{
+			reportSensorEventDeassert(pRec, index);
 		}
-		if (ISBITSET(pRec->deassert_state14_8,i)) { 
-			shouldReport(pRec, stype, i+8, DEASSERTINDEX);
+		if ((ISBITSET(pRec->deassert_state14_8,i+8))  &&
+			(shouldReport(stype, i+8, &index)))
+		{
+			reportSensorEventDeassert(pRec, index);
 		}
 	}
 
diff --git a/testit.C b/testit.C
index 0641a55..021d534 100644
--- a/testit.C
+++ b/testit.C
@@ -120,6 +120,12 @@ unsigned char findSensor(char sensor_number) {
 }
 
 
+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(uint8_t number, const char *method, const char *value) {
 
 	printf("Attempting to log Sensor 0x%02x via %s with a value of %s\n", 
@@ -133,8 +139,6 @@ extern int updateSensorRecordFromSSRAESC(const void *record);
 
 
 
-
-
 uint8_t testrec_boot1[] = {0x05, 0xa9, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00};
 uint8_t testrec_boot2[] = {0x05, 0xa9, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
 uint8_t testrec_boot3[] = {0x05, 0xa9, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00};
-- 
2.6.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 18/20] C7 and & virtual sensor support
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
                   ` (16 preceding siblings ...)
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 17/20] Add virtual sensor support OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 19/20] Fix a buffer overrun OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 20/20] Refactored fru validator to use sd_bus OpenBMC Patches
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

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

---
 ipmisensor.C | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/ipmisensor.C b/ipmisensor.C
index 72cb576..f60db18 100644
--- a/ipmisensor.C
+++ b/ipmisensor.C
@@ -7,7 +7,6 @@ extern unsigned char findSensor(char);
 extern int set_sensor_dbus_state_v(uint8_t , const char *, char *);
 
 
-
 struct sensorRES_t {
 	uint8_t sensor_number;
 	uint8_t operation;
@@ -93,7 +92,7 @@ char *getfw02string(uint8_t b) {
 		i++;
 	} while ((p+i)->data != 0xFF);
 
-	return p->text;
+	return (p+i)->text;
 }
 //  The fw progress sensor contains some additional information that needs to be processed
 //  prior to calling the dbus code.  
@@ -108,12 +107,23 @@ int set_sensor_dbus_state_fwprogress(const sensorRES_t *pRec, const lookup_t *pT
 					break;
 		case 0x01 : sprintf(valuestring, "FW Hang, 0x%02x", pRec->event_data2);
 					break;
-		case 0x02 : sprintf(valuestring, "FW Progress, 0x%02x", getfw02string(pRec->event_data2));
+		case 0x02 : sprintf(valuestring, "FW Progress, %s", getfw02string(pRec->event_data2));
 	}
 
 	return set_sensor_dbus_state_v(pRec->sensor_number, pTable->method, pStr);
 }
 
+// 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_osboot(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);
+}
+
 
 //  This table lists only senors we care about telling dbus about.
 //  Offset definition cab be found in section 42.2 of the IPMI 2.0 
@@ -127,6 +137,10 @@ lookup_t g_ipmidbuslookup[] = {
 	{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", "False"},
+	{0x07, 0x00, set_sensor_dbus_state_simple, "setPresent", "False", "False"}, // OCC Inactive 0
+	{0x07, 0x01, set_sensor_dbus_state_simple, "setPresent", "True", "True"},   // OCC Active 1 
+	{0xc3, 0x00, set_sensor_dbus_state_osboot, "setValue", "" ,""},
 
 	{0xFF, 0xFF, NULL, "", "", ""}
 };
@@ -161,11 +175,20 @@ int findindex(const uint8_t sensor_type, int offset, int *index) {
 	return rc;
 }
 
+void debug_print_ok_to_dont_care(uint8_t stype, int offset)
+{
+	printf("Sensor should not be reported:  Type 0x%02x, Offset 0x%02x\n",
+		stype, offset);
+}
+
 bool shouldReport(uint8_t sensorType, int offset, int *index) {
 
 	bool rc = false;
+
 	if (findindex(sensorType, offset, index)) { rc = true;	}
 
+	if (rc==false) { debug_print_ok_to_dont_care(sensorType, offset); }
+
 	return rc;
 }
 
@@ -177,7 +200,6 @@ int updateSensorRecordFromSSRAESC(const void *record) {
 	int index, i=0;
 	stype = findSensor(pRec->sensor_number);
 
-
 	// Scroll through each bit position .  Determine 
 	// if any bit is either asserted or Deasserted.
 	for(i=0;i<8;i++) {
-- 
2.6.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 19/20] Fix a buffer overrun
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
                   ` (17 preceding siblings ...)
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 18/20] C7 and & " OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 20/20] Refactored fru validator to use sd_bus OpenBMC Patches
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

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

---
 ipmisensor.C | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/ipmisensor.C b/ipmisensor.C
index f60db18..568f4a4 100644
--- a/ipmisensor.C
+++ b/ipmisensor.C
@@ -98,16 +98,16 @@ char *getfw02string(uint8_t b) {
 //  prior to calling the dbus code.  
 int set_sensor_dbus_state_fwprogress(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) {
 
-	char valuestring[32];
+	char valuestring[48];
 	char* pStr = valuestring;
 
 	switch (pTable->offset) {
 
-		case 0x00 : sprintf(valuestring, "POST Error, 0x%02x", pRec->event_data2);
+		case 0x00 : snprintf(valuestring, sizeof(valuestring), "POST Error, 0x%02x", pRec->event_data2);
 					break;
-		case 0x01 : sprintf(valuestring, "FW Hang, 0x%02x", pRec->event_data2);
+		case 0x01 : snprintf(valuestring, sizeof(valuestring), "FW Hang, 0x%02x", pRec->event_data2);
 					break;
-		case 0x02 : sprintf(valuestring, "FW Progress, %s", getfw02string(pRec->event_data2));
+		case 0x02 : snprintf(valuestring, sizeof(valuestring), "FW Progress, %s", getfw02string(pRec->event_data2));
 	}
 
 	return set_sensor_dbus_state_v(pRec->sensor_number, pTable->method, pStr);
-- 
2.6.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH phosphor-host-ipmid v2 20/20] Refactored fru validator to use sd_bus
  2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
                   ` (18 preceding siblings ...)
  2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 19/20] Fix a buffer overrun OpenBMC Patches
@ 2015-10-21 12:48 ` OpenBMC Patches
  19 siblings, 0 replies; 21+ messages in thread
From: OpenBMC Patches @ 2015-10-21 12:48 UTC (permalink / raw)
  To: openbmc

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

---
 fruvalidator.C        | 252 ----------------------
 sd_bus_fruvalidator.C | 568 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 568 insertions(+), 252 deletions(-)
 delete mode 100644 fruvalidator.C
 create mode 100644 sd_bus_fruvalidator.C

diff --git a/fruvalidator.C b/fruvalidator.C
deleted file mode 100644
index 5e2ffaf..0000000
--- a/fruvalidator.C
+++ /dev/null
@@ -1,252 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-
-typedef unsigned char uint8_t;
-
-/*
- * --- For Reference.----
-typedef struct
-{
-    uint8_t fixed;
-    uint8_t internal_offset;
-    uint8_t chassis_offset;
-    uint8_t board_offset;
-    uint8_t product_offset;
-    uint8_t multi_offset;
-    uint8_t pad;
-    uint8_t crc;
-}common_header_t;
-*/
-
-#define HDR_BYTE_ZERO   1
-#define INTERNAL_OFFSET 1
-#define HDR_CRC_OFFSET  7
-#define COMMON_HDR_SIZE 8
-
-#define RECORD_NOT_PRESENT 0
-#define EIGHT_BYTES 8
-
-uint8_t common_hdr[COMMON_HDR_SIZE] = {0};
-
-//------------------------------------------------
-// Takes the pointer to stream of bytes and length 
-// returns the 8 bit checksum per IPMI spec.
-//--------------------------------------------------
-unsigned char calculate_checksum(unsigned char *ptr, int len)
-{
-    // REFER :: http://coreipm.googlecode.com/svn-history/r40/trunk/coreipm/ipmi_pkt.c
-    char checksum = 0;
-    int byte = 0;
-
-    for(byte = 0; byte < len; byte++)
-    {
-        checksum += *ptr++;
-    }
-    
-    return( -checksum );
-}
-
-//---------------
-// Display Usage
-//---------------
-void usage(char *binary)
-{
-    printf("Usage: %s <valid binary ipmi fru file>\n", binary);
-    return;
-}    
-
-//-----------------------------------------------------
-// Accepts the filename and validated per IPMI FRU spec
-//------------------------------------------------------
-bool validate_fru_record(char *fru_file_name)
-{    
-    // Used for generic checksum calculation
-    uint8_t checksum = 0;
-
-    // This can point to 
-    uint8_t fru_section;
-
-    // A generic offset locator for any FRU record.
-    uint8_t record_offset = 0;
-
-    // Number of bytes read from FRU file.
-    size_t bytes_read = 0;
-
-    // First 2 bytes in the record.
-    uint8_t fru_record_hdr[2] = {0};
-
-    //common_header_t com_hdr;
-    memset(common_hdr, 0x0, sizeof(common_hdr));
-
-    // For now, this is user supplied in CLI. But this will be a parameter from
-    // fru handler
-    FILE *fru_file = fopen(fru_file_name,"rb");
-    if(fru_file == NULL)
-    {
-        fprintf(stderr, "ERROR: opening:[%s]\n",fru_file_name);
-        return false;
-    }
-
-    // Read first 8 bytes into common_header so we know the offsets and hdr
-    // checksum.
-    fseek(fru_file, 0, SEEK_SET);
-    bytes_read = fread(common_hdr, sizeof(common_hdr), 1, fru_file);
-    if(bytes_read != 1)
-    {
-        fprintf(stderr, "ERROR reading common header. Bytes read=:[%ld]\n",bytes_read);
-        return false;
-    }
-    
-    // 1: Validate for first byte to always have a value of [1]
-    if(common_hdr[0] != HDR_BYTE_ZERO)
-    {
-        fprintf(stderr, "ERROR: Common Header entry_1:[0x%X] Invalid.\n",common_hdr[0]);
-        return false;
-    }
-    else
-    {
-        printf("SUCCESS: Validated [0x%X] in common header\n",common_hdr[0]);
-    }
-
-    // 2: Validate the header checskum that is at last byte ( Offset: 7 )
-    checksum = calculate_checksum(common_hdr, sizeof(common_hdr)-1);
-    if(checksum != common_hdr[HDR_CRC_OFFSET])
-    {
-        fprintf(stderr, "ERROR: Common Header checksum mismatch."
-                " Calculated:[0x%X], Embedded:[0x%X]\n", 
-                checksum, common_hdr[HDR_CRC_OFFSET]);
-    
-        return false;
-    }
-    else
-    {
-        printf("SUCCESS: Common Header checksum MATCH:[0x%X]\n",checksum);
-    }
-
-    // !! FIXME FIXME FIXME FIXME
-    // This below logic fails if the record type is "Multi". I however have not
-    // seen a usecase of that in FRU inventory.. But, if I need to fix, its
-    // easy.
-    // !! FIXME FIXME FIXME FIXME
-
-    // 3: Now start walking the common_hdr array that has offsets into other FRU
-    //    record areas and validate those. Starting with second entry since the
-    //    first one is always a [0x01]
-    for(fru_section = INTERNAL_OFFSET ; fru_section < (COMMON_HDR_SIZE - 2)  ; fru_section++)
-    {
-        // Offset is 'value given in' internal_offset * 8 from the START of
-        // common header. So an an example, 01 00 00 00 01 00 00 fe has
-        // product area set at the offset 01 * 8 --> 8 bytes from the START of
-        // common header. That means, soon after the header checksum.
-        record_offset = common_hdr[fru_section] * EIGHT_BYTES;
-
-        if(record_offset)
-        {
-            // A NON zero value means that the vpd packet has the data for that
-            // section.  These are the things needed at this moment:
-
-            // 1: Goto beginning of the FILE
-            rewind(fru_file);
-
-            // 2: Move the file pointer to record_offset
-            fseek(fru_file, record_offset, SEEK_SET);
-
-            // 3: Read first 2 bytes containing FIXED[0x1] and record Length.
-            fread(fru_record_hdr, sizeof(fru_record_hdr), 1, fru_file);
-
-            // 5: If first element in the record header is _not_ a fixed:[0x01], err out.
-            if(fru_record_hdr[0] != HDR_BYTE_ZERO)
-            {
-                fprintf(stderr, "ERROR: Unexpected :[0x%X] found at Record header",
-                        fru_record_hdr[0]);
-
-                return false;
-            }
-            else
-            {
-                printf("SUCCESS: Validated [0x%X] in fru record:[%d] header\n",
-                        fru_record_hdr[0],fru_section);
-            }
-
-            // 4: Read Length bytes ( makes a complete record read now )
-            uint8_t fru_record_len = fru_record_hdr[1] * EIGHT_BYTES;
-
-            printf("RECORD NO[%d], SIZE = [%d] \n",fru_section, fru_record_len);
-
-            uint8_t fru_record_data[fru_record_len];
-            memset(fru_record_data, 0x0, sizeof(fru_record_data));
-
-            // Since the data is from record data[0], move the file pointer again to
-            // beginning of record.
-            fseek(fru_file, -2, SEEK_CUR);
-            fread(fru_record_data, sizeof(fru_record_data), 1, fru_file);
-
-            // 5: Calculate checksum (from offset -> (Length-1)).
-            //    All the bytes except the last byte( which is CRC :) ) will
-            //    participate in calculating the checksum.
-            checksum = calculate_checksum(fru_record_data, sizeof(fru_record_data)-1);
-
-            // 6: Verify the embedded checksum in last byte with calculated checksum
-            //    record_len -1 since length is some N but numbering is 0..N-1
-            if(checksum != fru_record_data[fru_record_len-1])
-            {
-                fprintf(stderr, "ERROR: FRU Header checksum mismatch. "
-                        " Calculated:[0x%X], Embedded:[0x%X]\n", 
-                        checksum, fru_record_data[fru_record_len-1]);
-
-                return false;
-            }
-            else
-            {
-                printf("SUCCESS: FRU Header checksum MATCH:[0x%X]\n",checksum);
-            }
-
-            // 7: If everything is okay, then we are fine.. Else mostly we are
-            //    awaiting another FRU write -OR- worst case, the VPD is corrupted
-            //    over BT.
-        } // If the packet has data for a particular data record.
-    } // End walking all the fru records.
-        
-    return true;
-}
-
-//---------------------------------------------------------------------
-// Main function but this will be integrated as a API for
-// Open BMC code that accepts a filename and returns success or failure
-//----------------------------------------------------------------------
-int main(int argc, char *argv[])
-{
-    // Right way is to do a parse_opt but that is poky for now.
-    if(argc != 2)
-    {
-        usage(argv[0]);
-        return -1;
-    }
-
-    // Check if this file is really present.
-    struct stat statbuff;
-    if(stat(argv[1], &statbuff) == -1)
-    {
-        usage(argv[0]);
-        return -1;
-    }
-    else if(statbuff.st_mode & S_IFMT != S_IFREG)
-    {
-        usage(argv[0]);
-        return -1;
-    }
-        
-    bool scan_result = validate_fru_record(argv[1]);
-    if(scan_result == true)
-    {
-        printf("SUCCESS: Validated:[%s]\n",argv[1]);
-    }
-    else
-    {
-        printf("ERROR: Validation failed for:[%s]\n",argv[1]);
-        return -1;
-    }
-
-    return 0;
-}
diff --git a/sd_bus_fruvalidator.C b/sd_bus_fruvalidator.C
new file mode 100644
index 0000000..632873c
--- /dev/null
+++ b/sd_bus_fruvalidator.C
@@ -0,0 +1,568 @@
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <systemd/sd-bus.h>
+#include <errno.h>
+#include <vector>
+#include <iostream>
+#include <sstream>
+#include "frup.h" // copied to host-ipmid folder for now
+#include <dlfcn.h>
+
+// Per IPMI v2.0 FRU specification
+struct common_header
+{
+    uint8_t fixed;
+    uint8_t internal_offset;
+    uint8_t chassis_offset;
+    uint8_t board_offset;
+    uint8_t product_offset;
+    uint8_t multi_offset;
+    uint8_t pad;
+    uint8_t crc;
+}__attribute__((packed));
+
+// Contains key info about a particular area.
+typedef struct
+{
+    uint8_t type;
+    uint8_t *offset;
+    size_t  len;
+}__attribute__((packed)) fru_area_t;
+
+// Needed to be passed into fru parser alorithm
+typedef std::vector<fru_area_t> fru_area_vec_t;
+
+// To call parse_fru_area function until its packaged and it's .h file is in dev
+// repo.
+typedef int (*parse_fun)(uint8_t, void *, uint8_t, sd_bus_message*);  
+
+// first byte in header is 1h per IPMI V2 spec.
+#define HDR_BYTE_ZERO   1
+#define INTERNAL_OFFSET offsetof(struct common_header, internal_offset)
+#define CHASSIS_OFFSET  offsetof(struct common_header, chassis_offset)
+#define BOARD_OFFSET    offsetof(struct common_header, board_offset)
+#define PRODUCT_OFFSET  offsetof(struct common_header, product_offset)
+#define MULTI_OFFSET    offsetof(struct common_header, multi_offset)
+#define HDR_CRC_OFFSET  offsetof(struct common_header, crc)
+#define EIGHT_BYTES     8
+
+// OpenBMC System Manager dbus framework
+const char  *bus_name      =  "org.openbmc.managers.System";
+const char  *object_name   =  "/org/openbmc/managers/System";
+const char  *intf_name     =  "org.openbmc.managers.System";
+
+//int update_inventory(const uint8_t, const uint8_t *, fru_area_vec_t &);
+
+//------------------------------------------------
+// Takes the pointer to stream of bytes and length 
+// returns the 8 bit checksum per IPMI spec.
+//-------------------------------------------------
+unsigned char calculate_crc(unsigned char *data, int len)
+{
+    char crc = 0;
+    int byte = 0;
+
+    for(byte = 0; byte < len; byte++)
+    {
+        crc += *data++;
+    }
+    
+    return(-crc);
+}
+
+//---------------
+// Display Usage
+//---------------
+void usage(char *binary)
+{
+    printf("Usage: %s <valid binary ipmi fru file>\n", binary);
+}    
+
+//---------------------------------------------------------------------------
+// fru parser wrapper until we get things working okay from FRU parser library
+//---------------------------------------------------------------------------
+int _parse_fru_area(uint8_t area_type, void *fru_data, size_t len, sd_bus_message *fru_dictn)
+{
+    int rc = 0;
+    parse_fun fru_parse_fun;
+
+    void *lib_handle = dlopen("/usr/lib/libifp.so", RTLD_LAZY); 
+    fru_parse_fun = (parse_fun)dlsym(lib_handle, "_Z14parse_fru_areahPKvhP14sd_bus_message");
+
+    rc = (*fru_parse_fun)(area_type, fru_data, (uint8_t)len, fru_dictn);
+
+    return rc;
+}
+
+//---------------------------------------------------------------------
+// Accepts a fru area offset in commom hdr and tells which area it is.
+//---------------------------------------------------------------------
+uint8_t get_fru_area_type(uint8_t area_offset)
+{
+    openbmc_ipmi_fru_area_type type = IPMI_FRU_AREA_TYPE_MAX;
+
+    switch(area_offset)
+    {
+        case INTERNAL_OFFSET:
+            type = IPMI_FRU_AREA_INTERNAL_USE;
+            break;
+
+        case CHASSIS_OFFSET:
+            type = IPMI_FRU_AREA_CHASSIS_INFO;
+            break;
+
+        case BOARD_OFFSET:
+            type = IPMI_FRU_AREA_BOARD_INFO;
+            break;
+
+        case PRODUCT_OFFSET:
+            type = IPMI_FRU_AREA_PRODUCT_INFO;
+            break;
+
+        case MULTI_OFFSET:
+            type = IPMI_FRU_AREA_MULTI_RECORD;
+            break;
+
+        default:
+            type = IPMI_FRU_AREA_TYPE_MAX;
+    }
+
+    return type;
+}
+
+//------------------------------------------------------------------------
+// Takes FRU data, invokes Parser for each fru record area and updates
+// Inventory
+//------------------------------------------------------------------------
+int update_inventory(const uint8_t fruid, const uint8_t *fru_data, 
+                     fru_area_vec_t & area_vec)
+{
+    // Now, use this fru dictionary object and connect with FRU Inventory Dbus
+    // and update the data for this FRU ID.
+    int rc = 0;
+    
+    // Dictionary object to hold Name:Value pair
+    sd_bus_message *fru_dict = NULL;
+
+    // SD Bus error report mechanism.
+    sd_bus_error bus_error = SD_BUS_ERROR_NULL;
+
+    // Gets a hook onto either a SYSTEM or SESSION bus
+    sd_bus *bus_type = NULL;
+
+    // Req message contains the specifics about which method etc that we want to
+    // access on which bus, object
+    sd_bus_message *response = NULL;
+
+    rc = sd_bus_open_system(&bus_type);
+    if(rc < 0)
+    {
+        fprintf(stderr,"ERROR: Getting a SYSTEM bus hook\n");
+        return -1;
+    }
+
+    // For each FRU area, extract the needed data , get it parsed and update
+    // the Inventory.
+    for(auto& iter : area_vec)
+    {
+        uint8_t area_type = (iter).type;
+
+        uint8_t area_data[(iter).len];
+        memset(area_data, 0x0, sizeof(area_data));
+
+        // Grab area specific data
+        memmove(area_data, (iter).offset, (iter).len);
+
+        // Need this to get respective DBUS objects
+        const char *area_name  = NULL;
+
+        if(area_type == IPMI_FRU_AREA_CHASSIS_INFO)
+        {
+            area_name = "CHASSIS_";
+        }
+        else if(area_type == IPMI_FRU_AREA_BOARD_INFO)
+        {
+            area_name = "BOARD_";
+        }
+        else if(area_type == IPMI_FRU_AREA_PRODUCT_INFO)
+        {
+            area_name = "PRODUCT_";
+        }
+        else
+        {
+            fprintf(stderr, "ERROR: Invalid Area type :[%d]",area_type);
+            break;
+        }
+ 
+        // What we need is BOARD_1, PRODUCT_1, CHASSIS_1 etc..
+        char fru_area_name[16] = {0};
+        sprintf(fru_area_name,"%s%d",area_name, fruid);
+
+#ifdef __IPMI_DEBUG__
+        printf("Updating Inventory with :[%s]\n",fru_area_name);
+#endif
+        // Each area needs a clean set.       
+        sd_bus_error_free(&bus_error);
+        sd_bus_message_unref(response);
+        sd_bus_message_unref(fru_dict);
+    
+        // We want to call a method "getObjectFromId" on System Bus that is
+        // made available over  OpenBmc system services.
+        rc = sd_bus_call_method(bus_type,                   // On the System Bus
+                                bus_name,                   // Service to contact
+                                object_name,                // Object path 
+                                intf_name,                  // Interface name
+                                "getObjectFromId",          // Method to be called
+                                &bus_error,                 // object to return error
+                                &response,                  // Response message on success
+                                "ss",                       // input message (string,byte)
+                                "FRU_STR",                  // First argument to getObjectFromId
+                                fru_area_name);             // Second Argument
+
+        if(rc < 0)
+        {
+            fprintf(stderr, "Failed to issue method call: %s\n", bus_error.message);
+            break;
+        }
+
+        // Method getObjectFromId returns 3 parameters and all are strings, namely
+        // bus_name , object_path and interface name for accessing that particular 
+        // FRU over Inventory SDBUS manager. 'sss' here mentions that format.
+        char *inv_bus_name, *inv_obj_path, *inv_intf_name;
+        rc = sd_bus_message_read(response, "(sss)", &inv_bus_name, &inv_obj_path, &inv_intf_name);
+        if(rc < 0)
+        {
+            fprintf(stderr, "Failed to parse response message:[%s]\n", strerror(-rc));
+            break;
+        }
+
+#ifdef __IPMI_DEBUG__
+        printf("fru_area=[%s], inv_bus_name=[%s], inv_obj_path=[%s],inv_intf_name=[%s]\n",
+                fru_area_name, inv_bus_name, inv_obj_path, inv_intf_name);
+#endif
+
+        // Constructor to allow further initializations and customization.
+        rc = sd_bus_message_new_method_call(bus_type,
+                                            &fru_dict,
+                                            inv_bus_name,
+                                            inv_obj_path,
+                                            inv_intf_name,
+                                            "update");
+        if(rc < 0)
+        {
+            fprintf(stderr,"ERROR: creating a update method call\n");
+            break;
+        }
+
+        // A Dictionary ({}) having (string, variant)
+        rc = sd_bus_message_open_container(fru_dict, 'a', "{sv}");
+        if(rc < 0)
+        {
+            fprintf(stderr,"ERROR:[%d] creating a dict container:\n",errno);
+            break;
+        }
+
+        // Fill the container with information
+        rc = _parse_fru_area((iter).type, (void *)area_data, (iter).len, fru_dict);
+        if(rc < 0)
+        {
+            fprintf(stderr,"ERROR parsing FRU records\n");
+            break;
+        }
+
+        sd_bus_message_close_container(fru_dict);
+
+        // Now, Make the actual call to update the FRU inventory database with the
+        // dictionary given by FRU Parser. There is no response message expected for
+        // this.
+        rc = sd_bus_call(bus_type,            // On the System Bus
+                         fru_dict,            // With the Name:value dictionary array
+                         0,                   // 
+                         &bus_error,          // Object to return error.
+                         &response);          // Response message if any.
+
+        if(rc < 0)
+        {
+            fprintf(stderr, "ERROR:[%s] updating FRU inventory for ID:[0x%X]\n",
+                    bus_error.message, fruid);
+        }
+        else
+        {
+            printf("SUCCESS: Updated:[%s] successfully\n",fru_area_name);
+        }
+    } // END walking the vector of areas and updating
+
+    sd_bus_error_free(&bus_error);
+    sd_bus_message_unref(response);
+    sd_bus_message_unref(fru_dict);
+    sd_bus_unref(bus_type);
+
+    return rc;
+}
+
+//-------------------------------------------------------------------------
+// Validates the CRC and if found good, calls fru areas parser and calls
+// Inventory Dbus with the dictionary of Name:Value for updating. 
+//-------------------------------------------------------------------------
+int validate_and_update_inventory(const uint8_t fruid, const uint8_t *fru_data)
+{
+    // Used for generic checksum calculation
+    uint8_t checksum = 0;
+
+    // This can point to any FRU entry.
+    uint8_t fru_entry;
+
+    // A generic offset locator for any FRU record.
+    uint8_t area_offset = 0;
+
+    // First 2 bytes in the record.
+    uint8_t fru_area_hdr[2] = {0};
+
+    // To hold info about individual FRU record areas.
+    fru_area_t fru_area;
+
+    // For parsing and updating Inventory.
+    fru_area_vec_t fru_area_vec;
+
+    int rc = 0;
+
+    uint8_t common_hdr[sizeof(struct common_header)] = {0};
+    memset(common_hdr, 0x0, sizeof(common_hdr));
+
+    // Copy first 8 bytes to verify common header
+    memcpy(common_hdr, fru_data, sizeof(common_hdr));
+
+    // Validate for first byte to always have a value of [1]
+    if(common_hdr[0] != HDR_BYTE_ZERO)
+    {
+        fprintf(stderr, "ERROR: Common Header entry_1:[0x%X] Invalid.\n",common_hdr[0]);
+        return -1;
+    }
+    else
+    {
+        printf("SUCCESS: Validated [0x%X] in common header\n",common_hdr[0]);
+    }
+
+    // Validate the header checskum that is at last byte ( Offset: 7 )
+    checksum = calculate_crc(common_hdr, sizeof(common_hdr)-1);
+    if(checksum != common_hdr[HDR_CRC_OFFSET])
+    {
+#ifdef __IPMI__DEBUG__
+        fprintf(stderr, "ERROR: Common Header checksum mismatch."
+                " Calculated:[0x%X], Embedded:[0x%X]\n", 
+                checksum, common_hdr[HDR_CRC_OFFSET]);
+#endif    
+        return -1;
+    }
+    else
+    {
+        printf("SUCCESS: Common Header checksum MATCH:[0x%X]\n",checksum);
+    }
+
+    //-------------------------------------------
+    // TODO:  Add support for Multi Record later
+    //-------------------------------------------
+
+    //  Now start walking the common_hdr array that has offsets into other FRU
+    //  record areas and validate those. Starting with second entry since the
+    //  first one is always a [0x01]
+    for(fru_entry = INTERNAL_OFFSET; fru_entry < (sizeof(struct common_header) -2); fru_entry++)
+    {
+        // Offset is 'value given in' internal_offset * 8 from the START of
+        // common header. So an an example, 01 00 00 00 01 00 00 fe has
+        // product area set at the offset 01 * 8 --> 8 bytes from the START of
+        // common header. That means, soon after the header checksum.
+        area_offset = common_hdr[fru_entry] * EIGHT_BYTES;
+        
+        if(area_offset)
+        {
+            memset((void *)&fru_area, 0x0, sizeof(fru_area_t));
+
+            // Enumerated FRU area.
+            fru_area.type = get_fru_area_type(fru_entry);
+
+            // From start of fru header + record offset, copy 2 bytes.
+            fru_area.offset = &((uint8_t *)fru_data)[area_offset];
+            memcpy(fru_area_hdr, fru_area.offset, sizeof(fru_area_hdr));
+
+            // A NON zero value means that the vpd packet has the data for that
+            // area. err if first element in the record header is _not_ a [0x01].
+            if(fru_area_hdr[0] != HDR_BYTE_ZERO)
+            {
+                fprintf(stderr, "ERROR: Unexpected :[0x%X] found at Record header\n",
+                        fru_area_hdr[0]);
+
+                // This vector by now may have had some entries. Since this is a
+                // failure now, clear the state data.
+                fru_area_vec.clear();
+                return -1;
+            }
+            else
+            {
+                printf("SUCCESS: Validated [0x%X] in fru record:[%d] header\n",
+                        fru_area_hdr[0],fru_entry);
+            }
+
+            // Read Length bytes ( makes a complete record read now )
+            fru_area.len = fru_area_hdr[1] * EIGHT_BYTES;
+#ifdef __IPMI_DEBUG__
+            printf("AREA NO[%d], SIZE = [%d]\n",fru_entry, fru_area.len);
+#endif
+            uint8_t fru_area_data[fru_area.len];
+            memset(fru_area_data, 0x0, sizeof(fru_area_data));
+
+            memmove(fru_area_data, fru_area.offset, sizeof(fru_area_data));
+
+            // Calculate checksum (from offset -> (Length-1)).
+            // All the bytes except the last byte( which is CRC :) ) will
+            // participate in calculating the checksum.
+            checksum = calculate_crc(fru_area_data, sizeof(fru_area_data)-1);
+
+            // Verify the embedded checksum in last byte with calculated checksum
+            // record_len -1 since length is some N but numbering is 0..N-1
+            if(checksum != fru_area_data[fru_area.len-1])
+            {
+#ifdef __IPMI_DEBUG__
+                fprintf(stderr, "ERROR: FRU Header checksum mismatch. "
+                        " Calculated:[0x%X], Embedded:[0x%X]\n", 
+                        checksum, fru_area_data[fru_area.len - 1]);
+#endif
+                // This vector by now may have had some entries. Since this is a
+                // failure now, clear the state data.
+                fru_area_vec.clear();
+                return -1;
+            }
+            else
+            {
+                printf("SUCCESS: FRU Header checksum MATCH:[0x%X]\n",checksum);
+            }
+
+            // Everything is rihgt about this particular FRU record,
+            fru_area_vec.push_back(fru_area);
+
+            // Update the internal structure with info about this entry that is
+            // needed while handling each areas.
+        } // If the packet has data for a particular data record.
+    } // End walking all the fru records.
+        
+    // If we reach here, then we have validated the crc for all the records and
+    // time to call FRU area parser to get a Name:Value pair dictionary.
+    // This will start iterating all over again on the buffer -BUT- now with the
+    // job of taking each areas, getting it parsed and then updating the
+    // DBUS.
+        
+    if(!(fru_area_vec.empty()))
+    {
+        rc =  update_inventory(fruid, fru_data, fru_area_vec);
+    }
+ 
+    // We are done with this FRU write packet. 
+    fru_area_vec.clear();
+
+    return rc;
+}
+
+///-----------------------------------------------------
+// Accepts the filename and validates per IPMI FRU spec
+//----------------------------------------------------
+int validate_fru_area(const uint8_t fruid, const char *fru_file_name)
+{    
+    int file_size = 0;
+    uint8_t *fru_data = NULL;
+    int bytes_read = 0;
+    int rc = 0;
+
+    // For now, this is user supplied in CLI. But this will be a parameter from
+    // fru handler
+    FILE *fru_file = fopen(fru_file_name,"rb");
+    if(fru_file == NULL)
+    {
+        fprintf(stderr, "ERROR: opening:[%s]\n",fru_file_name);
+        perror("Error:");
+        return -1;
+    }
+
+    // Get the size of the file to allocate buffer to hold the entire contents.
+    if(fseek(fru_file, 0, SEEK_END))
+    {
+        perror("Error:");
+        return -1;
+    }
+
+    file_size = ftell(fru_file);
+    fru_data = (uint8_t *)malloc(file_size);
+
+    // Read entire file contents to the internal buffer
+    if(fseek(fru_file, 0, SEEK_SET))
+    {
+        perror("Error:");
+        return -1;
+    }
+
+    bytes_read = fread(fru_data, file_size, 1, fru_file);
+    if(bytes_read != 1)
+    {
+        fprintf(stderr, "ERROR reading common header. Bytes read=:[%d]\n",bytes_read);
+        perror("Error:");
+        return -1;
+    }
+    fclose(fru_file);
+
+    rc = validate_and_update_inventory(fruid, fru_data);
+
+    if(fru_data)
+    {
+        free(fru_data);
+        fru_data = NULL;
+    }
+
+    return rc;
+}
+
+// ---------------------------------------------------------------------
+// Main function but this will be integrated as a API for
+// Open BMC code that accepts a filename and returns success or failure
+//--------------------------------------------------------------------
+int main(int argc, char *argv[])
+{
+    // Right way is to do a parse_opt but that is poky for now.
+    if(argc != 2)
+    {
+        usage(argv[0]);
+        return -1;
+    }
+
+    /* Check if this file is really present. */
+    struct stat statbuff;
+    if(stat(argv[1], &statbuff) == -1)
+    {
+        usage(argv[0]);
+        return -1;
+    }
+    else if((statbuff.st_mode & S_IFMT) != S_IFREG)
+    {
+        usage(argv[0]);
+        return -1;
+    }
+
+    // For now, I am having FRU file numbers as 1 , 2 , 3..
+    uint8_t fruid = 0;
+    fruid = atoi(argv[1]);
+
+    int scan_result = validate_fru_area(fruid, argv[1]);
+    if(scan_result < 0)
+    {
+        printf("ERROR: Validation failed for:[%d]\n",fruid);
+        return -1;
+    }
+    else
+    {
+        printf("SUCCESS: Validated:[%s]\n",argv[1]);
+    }
+
+    return 0;
+}
-- 
2.6.0

^ permalink raw reply related	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2015-10-21 12:49 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-21 12:48 [PATCH phosphor-host-ipmid v2 00/20] FRU validator CLI OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 01/20] Convert to SDBus OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 02/20] Set response bit returning from the ipmi call OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 03/20] Reset the lib path string per .so OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 04/20] Reduced MAX_IPMI_BUFFER to support ast2400 FIFO OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 05/20] Add more ipmi commands for app function OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 06/20] Add sensor ipmi commands OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 07/20] Add storage " OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 08/20] Add support for the the dcmi package OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 09/20] FRU validator CLI OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 10/20] Remove stray whitespace OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 11/20] Add 'make install' directive OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 12/20] Watchdog support OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 13/20] Print the dlopen failure for debugging OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 14/20] Add routines for getting lookup data from the system dbus object OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 15/20] Suport examining sensor records and calling dbus OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 16/20] Added testcases for sensor record parsing OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 17/20] Add virtual sensor support OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 18/20] C7 and & " OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 19/20] Fix a buffer overrun OpenBMC Patches
2015-10-21 12:48 ` [PATCH phosphor-host-ipmid v2 20/20] Refactored fru validator to use sd_bus OpenBMC Patches

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.