SEL log Generator ID should Conform to IPMI Spec

In IMPI specification, the generator ID for SEL log is 2 bytes long.
Apart from the Generator ID, it contains LUN and channel information.
The fix is to change 1-Byte Generator ID to 2-byte generator ID and
include all missing information into it.

Tested
Following tests were executed:
1) Run ipmitool raw -l 1 0x4 0x2 0x4 0x8 0x1 0x6 0x1 0x5
This ensures that non-zero LUN information is included
in the SEL record.

2) Instrument the code to look like ME has created an event
and make sure that logs are saved properly.

For 1) and 2) logs are read from the WebUI to make sure that
they are being saved as expected.

Signed-off-by: Sujoy Ray <sujoy.ray@intel.com>
Change-Id: I78d4423cc24c941af7bf0cd70423a95747ba4a76
diff --git a/include/ipmi_to_redfish_hooks.hpp b/include/ipmi_to_redfish_hooks.hpp
index caef644..76f8b92 100644
--- a/include/ipmi_to_redfish_hooks.hpp
+++ b/include/ipmi_to_redfish_hooks.hpp
@@ -26,7 +26,7 @@
                        uint8_t sensorType, uint8_t sensorNum, uint8_t eventType,
                        uint8_t eventData1, uint8_t eventData2,
                        uint8_t eventData3);
-bool checkRedfishHooks(uint8_t generatorID, uint8_t evmRev, uint8_t sensorType,
+bool checkRedfishHooks(uint16_t generatorID, uint8_t evmRev, uint8_t sensorType,
                        uint8_t sensorNum, uint8_t eventType, uint8_t eventData1,
                        uint8_t eventData2, uint8_t eventData3);
 namespace redfish_hooks
diff --git a/src/ipmi_to_redfish_hooks.cpp b/src/ipmi_to_redfish_hooks.cpp
index 92f9f2e..206b9e6 100644
--- a/src/ipmi_to_redfish_hooks.cpp
+++ b/src/ipmi_to_redfish_hooks.cpp
@@ -833,7 +833,11 @@
 
 static bool startRedfishHook(const SELData& selData, const std::string& ipmiRaw)
 {
-    switch (selData.generatorID)
+    uint8_t generatorIDLowByte = static_cast<uint8_t>(selData.generatorID);
+    // Generator ID is 7 bit and LS Bit contains '1' or '0' depending on the
+    // source. Refer IPMI SPEC, Table 32, SEL Event Records.
+    generatorIDLowByte >>= 1;
+    switch (generatorIDLowByte)
     {
         case 0x01: // Check if this message is from the BIOS Generator ID
             // Let the BIOS hook handle this request
@@ -900,14 +904,21 @@
     return redfish_hooks::startRedfishHook(selData, ipmiRaw);
 }
 
-bool checkRedfishHooks(uint8_t generatorID, uint8_t evmRev, uint8_t sensorType,
+bool checkRedfishHooks(uint16_t generatorID, uint8_t evmRev, uint8_t sensorType,
                        uint8_t sensorNum, uint8_t eventType, uint8_t eventData1,
                        uint8_t eventData2, uint8_t eventData3)
 {
     // Save the raw IPMI string of the selData
     std::string ipmiRaw;
-    std::array selBytes = {generatorID, evmRev,     sensorType, sensorNum,
-                           eventType,   eventData1, eventData2, eventData3};
+    std::array selBytes = {static_cast<uint8_t>(generatorID),
+                           static_cast<uint8_t>(generatorID >> 8),
+                           evmRev,
+                           sensorType,
+                           sensorNum,
+                           eventType,
+                           eventData1,
+                           eventData2,
+                           eventData3};
     redfish_hooks::toHexStr(boost::beast::span<uint8_t>(selBytes), ipmiRaw);
 
     // Extract the SEL data for the hook
diff --git a/src/sensorcommands.cpp b/src/sensorcommands.cpp
index 3927ef2..73b74cc 100644
--- a/src/sensorcommands.cpp
+++ b/src/sensorcommands.cpp
@@ -355,7 +355,7 @@
     constexpr const uint8_t meSensorNum = 0x17;
     constexpr const uint8_t disabled = 0x80;
 
-    uint8_t generatorID = 0;
+    uint8_t sysgeneratorID = 0;
     uint8_t evmRev = 0;
     uint8_t sensorType = 0;
     uint8_t sensorNum = 0;
@@ -363,6 +363,7 @@
     uint8_t eventData1 = 0;
     std::optional<uint8_t> eventData2 = 0;
     std::optional<uint8_t> eventData3 = 0;
+    uint16_t generatorID = 0;
     ipmi::ChannelInfo chInfo;
 
     if (ipmi::getChannelInfo(ctx->channel, chInfo) != ipmi::ccSuccess)
@@ -377,15 +378,24 @@
         ipmi::EChannelMediumType::systemInterface)
     {
 
-        p.unpack(generatorID, evmRev, sensorType, sensorNum, eventType,
+        p.unpack(sysgeneratorID, evmRev, sensorType, sensorNum, eventType,
                  eventData1, eventData2, eventData3);
+        // Refer to IPMI Spec Table 32: SEL Event Records
+        generatorID = (ctx->channel << 12) // Channel
+                      | (0x0 << 10)        // Reserved
+                      | (0x0 << 8)         // 0x0 for sys-soft ID
+                      | ((sysgeneratorID << 1) | 0x1);
     }
     else
     {
 
         p.unpack(evmRev, sensorType, sensorNum, eventType, eventData1,
                  eventData2, eventData3);
-        generatorID = ctx->rqSA << 1;
+        // Refer to IPMI Spec Table 32: SEL Event Records
+        generatorID = (ctx->channel << 12)      // Channel
+                      | (0x0 << 10)             // Reserved
+                      | ((ctx->lun & 0x3) << 8) // Lun
+                      | (ctx->rqSA << 1);
     }
 
     if (!p.fullyUnpacked())
@@ -409,8 +419,8 @@
         generatorID, evmRev, sensorType, sensorNum, eventType, eventData1,
         eventData2.value_or(0xFF), eventData3.value_or(0xFF));
 
-    if (generatorID == meId && sensorNum == meSensorNum && eventData2 &&
-        eventData3)
+    if (((generatorID & 0xFF) >> 1) == meId && sensorNum == meSensorNum &&
+        eventData2 && eventData3)
     {
         setMeStatus(*eventData2, *eventData3, (eventType & disabled));
     }