Revert "eSEL: Remove unused code related to logging eSEL"

This reverts commit 54fad6de0541c2f98e9b511f1d30bbcbcd743db6.

This commit is reverted because the mapping of D-Bus object path to
sensor information is still needed. The mapping is needed to serve
the SEL commands which translate D-Bus logging objects to SEL entries.

Change-Id: I2505299671db1f0bd7f116ef0e2ca4a0273eead8
diff --git a/storageaddsel.cpp b/storageaddsel.cpp
index 5cdf535..1dde2a4 100644
--- a/storageaddsel.cpp
+++ b/storageaddsel.cpp
@@ -21,6 +21,7 @@
 using namespace std;
 using namespace phosphor::logging;
 using namespace sdbusplus::xyz::openbmc_project::Logging::server;
+extern const ipmi::sensor::InvObjectIDMap invSensors;
 
 //////////////////////////
 struct esel_section_headers_t
@@ -32,6 +33,225 @@
     uint8_t compid;
 };
 
+struct severity_values_t
+{
+    uint8_t type;
+    Entry::Level level;
+};
+
+const std::vector<severity_values_t> g_sev_desc = {
+    {0x10, Entry::Level::Warning}, // recoverable error
+    {0x20, Entry::Level::Warning}, // predictive error
+                                   // TODO via github issue 3066 : map level
+                                   // below to Level::Unrecoverable
+    {0x40, Entry::Level::Error},   // unrecoverable error
+                                 // TODO via github issue 3066 : map level below
+                                 // to Level::Critical
+    {0x50, Entry::Level::Error},   // critical error
+    {0x60, Entry::Level::Error},   // error from a diagnostic test
+    {0x70, Entry::Level::Warning}, // recoverable symptom
+    {0xFF, Entry::Level::Error},   // unknown error
+};
+
+Entry::Level sev_lookup(uint8_t n)
+{
+    auto i =
+        std::find_if(std::begin(g_sev_desc), std::end(g_sev_desc),
+                     [n](auto p) { return p.type == n || p.type == 0xFF; });
+    return i->level;
+}
+
+int find_sensor_type_string(uint8_t sensor_number, char** s)
+{
+
+    dbus_interface_t a;
+    int r;
+
+    r = find_openbmc_path(sensor_number, &a);
+
+    if ((r < 0) || (a.bus[0] == 0))
+    {
+        // Just make a generic message for errors that
+        // occur on sensors that don't exist
+        r = asprintf(s, "Unknown Sensor (0x%02x)", sensor_number);
+    }
+    else
+    {
+        const char* p;
+
+        if ((p = strrchr(a.path, '/')) == NULL)
+        {
+            p = "/Unknown Sensor";
+        }
+
+        *s = strdup(p + 1);
+    }
+
+    return 0;
+}
+
+size_t getfilestream(const char* fn, uint8_t** buffer)
+{
+
+    FILE* fp;
+    ssize_t size = 0;
+    int r;
+
+    if ((fp = fopen(fn, "rb")) != NULL)
+    {
+
+        r = fseek(fp, 0, SEEK_END);
+        if (r)
+        {
+            log<level::ERR>("Fseek failed");
+            goto fclose_fp;
+        }
+
+        size = ftell(fp);
+        if (size == -1L)
+        {
+            log<level::ERR>("Ftell failed", entry("ERROR=%s", strerror(errno)));
+            size = 0;
+            goto fclose_fp;
+        }
+
+        r = fseek(fp, 0, SEEK_SET);
+        if (r)
+        {
+            log<level::ERR>("Fseek failed");
+            size = 0;
+            goto fclose_fp;
+        }
+
+        *buffer = new uint8_t[size];
+
+        r = fread(*buffer, 1, size, fp);
+        if (r != size)
+        {
+            size = 0;
+            log<level::ERR>("Fread failed\n");
+        }
+
+    fclose_fp:
+        fclose(fp);
+    }
+
+    return static_cast<size_t>(size);
+}
+
+Entry::Level create_esel_severity(const uint8_t* buffer)
+{
+
+    uint8_t severity;
+    // Dive in to the IBM log to find the severity
+    severity = (0xF0 & buffer[0x4A]);
+
+    return sev_lookup(severity);
+}
+
+int create_esel_association(const uint8_t* buffer, std::string& inventoryPath)
+{
+    auto p = reinterpret_cast<const ipmi_add_sel_request_t*>(buffer);
+
+    uint8_t sensor = p->sensornumber;
+
+    inventoryPath = {};
+
+    /*
+     * Search the sensor number to inventory path mapping to figure out the
+     * inventory associated with the ESEL.
+     */
+    auto found = std::find_if(invSensors.begin(), invSensors.end(),
+                              [&sensor](const auto& iter) {
+                                  return (iter.second.sensorID == sensor);
+                              });
+    if (found != invSensors.end())
+    {
+        inventoryPath = found->first;
+    }
+
+    return 0;
+}
+
+int create_esel_description(const uint8_t* buffer, Entry::Level level,
+                            char** message)
+{
+    char* m;
+    int r;
+
+    auto p = reinterpret_cast<const ipmi_add_sel_request_t*>(buffer);
+
+    find_sensor_type_string(p->sensornumber, &m);
+
+    r = asprintf(message, "A %s has experienced an error of level %d", m,
+                 static_cast<uint32_t>(level));
+    if (r == -1)
+    {
+        log<level::ERR>("Failed to allocate memory for ESEL description");
+    }
+
+    free(m);
+
+    return 0;
+}
+
+int send_esel_to_dbus(const char* desc, Entry::Level level,
+                      const std::string& inventoryPath, uint8_t* debug,
+                      size_t debuglen)
+{
+
+    // Allocate enough space to represent the data in hex separated by spaces,
+    // to mimic how IPMI would display the data.
+    unique_ptr<char[]> selData(new char[(debuglen * 3) + 1]());
+    uint32_t i = 0;
+    for (i = 0; i < debuglen; i++)
+    {
+        sprintf(&selData[i * 3], "%02x ", 0xFF & ((char*)debug)[i]);
+    }
+    selData[debuglen * 3] = '\0';
+
+    using error = sdbusplus::org::open_power::Host::Error::Event;
+    using metadata = org::open_power::Host::Event;
+
+    report<error>(level, metadata::ESEL(selData.get()),
+                  metadata::CALLOUT_INVENTORY_PATH(inventoryPath.c_str()));
+
+    return 0;
+}
+
+void send_esel(uint16_t recordid)
+{
+    char* desc;
+    uint8_t* buffer = NULL;
+    const char* path = "/tmp/esel";
+    ssize_t sz;
+    int r;
+    std::string inventoryPath;
+
+    sz = getfilestream(path, &buffer);
+    if (sz == 0)
+    {
+        log<level::ERR>("Error file does not exist",
+                        entry("FILENAME=%s", path));
+        return;
+    }
+
+    auto sev = create_esel_severity(buffer);
+    create_esel_association(buffer, inventoryPath);
+    create_esel_description(buffer, sev, &desc);
+
+    r = send_esel_to_dbus(desc, sev, inventoryPath, buffer, sz);
+    if (r < 0)
+    {
+        log<level::ERR>("Failed to send esel to dbus");
+    }
+
+    free(desc);
+    delete[] buffer;
+
+    return;
+}
+
 std::string readESEL(const char* fileName)
 {
     std::string content;