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/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,