Rewrite Read Event Buffer to use new API

Lots of hard-coded values in this one, but one value did get replaced
with a lookup. The output matches previous output with the one exception
that now the current manufacturer is used instead of a hard-coded value.

Tested: run ipmitool raw 6 0x35 and check the output
        Before:
        ipmitool raw 6 0x35
         55 55 c0 41 a7 00 00 00 00 00 3a ff 00 ff ff ff
        After:
        ipmitool raw 6 0x35
         55 55 c0 57 01 00 00 00 00 00 3a ff 00 ff ff ff

Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
Change-Id: I4910d8ee07db6f24d639f9322a0246e10a0260e3
diff --git a/meson.build b/meson.build
index b300247..f73b214 100644
--- a/meson.build
+++ b/meson.build
@@ -181,6 +181,7 @@
     channellayer_dep,
     crypto,
     mapper,
+    nlohmann_json_dep,
     phosphor_dbus_interfaces_dep,
     phosphor_logging_dep,
     sdbusplus_dep,
diff --git a/systemintfcmds.cpp b/systemintfcmds.cpp
index 8e1cdb0..fb5dde5 100644
--- a/systemintfcmds.cpp
+++ b/systemintfcmds.cpp
@@ -7,8 +7,10 @@
 
 #include <ipmid-host/cmd.hpp>
 #include <ipmid/api.hpp>
+#include <nlohmann/json.hpp>
 
 #include <cstring>
+#include <fstream>
 
 void register_netfn_app_functions() __attribute__((constructor));
 
@@ -21,40 +23,54 @@
 //-------------------------------------------------------------------
 // Called by Host post response from Get_Message_Flags
 //-------------------------------------------------------------------
-ipmi_ret_t ipmi_app_read_event(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
-                               ipmi_response_t response,
-                               ipmi_data_len_t data_len, ipmi_context_t)
+ipmi::RspType<uint16_t,              // id
+              uint8_t,               // type
+              uint24_t,              //  manuf_id
+              uint32_t,              // timestamp
+              uint8_t,               // netfun
+              uint8_t,               // cmd
+              std::array<uint8_t, 4> // data
+              >
+    ipmiAppReadEventBuffer(ipmi::Context::ptr& ctx)
 {
-    ipmi_ret_t rc = IPMI_CC_OK;
+    // require this to be limited to system interface
+    if (ctx->channel != ipmi::channelSystemIface)
+    {
+        return ipmi::responseInvalidCommand();
+    }
 
-    struct oem_sel_timestamped oem_sel = {};
-    *data_len = sizeof(struct oem_sel_timestamped);
+    constexpr uint16_t selOemId = 0x5555;
+    constexpr uint8_t selRecordTypeOem = 0xc0;
 
-    // either id[0] -or- id[1] can be filled in. We will use id[0]
-    oem_sel.id[0] = SEL_OEM_ID_0;
-    oem_sel.id[1] = SEL_OEM_ID_0;
-    oem_sel.type = SEL_RECORD_TYPE_OEM;
+    // read manufacturer ID from dev_id file
+    static uint24_t manufId{};
+    if (!manufId)
+    {
+        const char* filename = "/usr/share/ipmi-providers/dev_id.json";
+        std::ifstream devIdFile(filename);
+        if (devIdFile.is_open())
+        {
+            auto data = nlohmann::json::parse(devIdFile, nullptr, false);
+            if (!data.is_discarded())
+            {
+                manufId = data.value("manuf_id", 0);
+            }
+        }
+    }
 
-    // Following 3 bytes are from IANA Manufactre_Id field. See below
-    oem_sel.manuf_id[0] = 0x41;
-    oem_sel.manuf_id[1] = 0xA7;
-    oem_sel.manuf_id[2] = 0x00;
+    constexpr uint32_t timestamp{0};
 
     // per IPMI spec NetFuntion for OEM
-    oem_sel.netfun = 0x3A;
+    constexpr uint8_t netfun = 0x3a;
 
     // Read from the Command Manager queue. What gets returned is a
     // pair of <command, data> that can be directly used here
-    auto hostCmd = ipmid_get_host_cmd_manager()->getNextCommand();
-    oem_sel.cmd = hostCmd.first;
-    oem_sel.data[0] = hostCmd.second;
+    const auto& [cmd, data0] = ipmid_get_host_cmd_manager()->getNextCommand();
+    constexpr uint8_t dataUnused = 0xff;
 
-    // All '0xFF' since unused.
-    std::memset(&oem_sel.data[1], 0xFF, 3);
-
-    // Pack the actual response
-    std::memcpy(response, &oem_sel, *data_len);
-    return rc;
+    return ipmi::responseSuccess(
+        selOemId, selRecordTypeOem, manufId, timestamp, netfun, cmd,
+        std::to_array<uint8_t>({data0, dataUnused, dataUnused, dataUnused}));
 }
 
 //---------------------------------------------------------------------
@@ -137,8 +153,9 @@
 void register_netfn_app_functions()
 {
     // <Read Event Message Buffer>
-    ipmi_register_callback(NETFUN_APP, IPMI_CMD_READ_EVENT, NULL,
-                           ipmi_app_read_event, SYSTEM_INTERFACE);
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdReadEventMessageBuffer,
+                          ipmi::Privilege::Admin, ipmiAppReadEventBuffer);
 
     // <Set BMC Global Enables>
     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
diff --git a/systemintfcmds.hpp b/systemintfcmds.hpp
index 4eb30be..b263a96 100644
--- a/systemintfcmds.hpp
+++ b/systemintfcmds.hpp
@@ -4,41 +4,9 @@
 
 // These are per skiboot ipmi-sel code
 
-// OEM_SEL type with Timestamp
-#define SEL_OEM_ID_0 0x55
-// SEL type is OEM and -not- general SEL
-#define SEL_RECORD_TYPE_OEM 0xC0
 // Minor command for soft shurdown
 #define SOFT_OFF 0x00
 // Major command for Any kind of power ops
 #define CMD_POWER 0x04
 // Major command for the heartbeat operation (verify host is alive)
 #define CMD_HEARTBEAT 0xFF
-
-// IPMI commands used via System Interface functions.
-enum ipmi_netfn_system_intf_cmds
-{
-    IPMI_CMD_SET_BMC_GLOBAL_ENABLES = 0x2E,
-    IPMI_CMD_GET_BMC_GLOBAL_ENABLES = 0x2F,
-    IPMI_CMD_GET_MSG_FLAGS = 0x31,
-    IPMI_CMD_READ_EVENT = 0x35,
-};
-
-// A Mechanism to tell host to shtudown hosts by sending this PEM SEL. Really
-// the only used fields by skiboot are:
-// id[0] / id[1] for ID_0 , ID_1
-// type : SEL_RECORD_TYPE_OEM as standard SELs are ignored by skiboot
-// cmd : CMD_POWER for power functions
-// data[0], specific commands.  example Soft power off. power cycle, etc.
-struct oem_sel_timestamped
-{
-    /* SEL header */
-    uint8_t id[2];
-    uint8_t type;
-    uint8_t manuf_id[3];
-    uint8_t timestamp[4];
-    /* OEM SEL data (6 bytes) follows */
-    uint8_t netfun;
-    uint8_t cmd;
-    uint8_t data[4];
-};