PEL: PELTool Application

PELTooL application would be used to interact with PELs. This commit has
the first functionality, where a PEL file is passed and all PEL sections
are hexdumped in a JSON object.

Signed-off-by: Aatir <aatrapps@gmail.com>
Change-Id: I155d75bb58cbd14a297b094314f7fd1f271f4f37
diff --git a/extensions/openpower-pels/pel.cpp b/extensions/openpower-pels/pel.cpp
index 29d86d5..c4156a8 100644
--- a/extensions/openpower-pels/pel.cpp
+++ b/extensions/openpower-pels/pel.cpp
@@ -2,12 +2,15 @@
 
 #include "bcd_time.hpp"
 #include "failing_mtms.hpp"
+#include "hexdump.hpp"
 #include "log_id.hpp"
+#include "pel_values.hpp"
 #include "section_factory.hpp"
 #include "src.hpp"
 #include "stream.hpp"
 #include "user_data_formats.hpp"
 
+#include <iostream>
 #include <phosphor-logging/log.hpp>
 
 namespace openpower
@@ -15,6 +18,7 @@
 namespace pels
 {
 namespace message = openpower::pels::message;
+namespace pv = openpower::pels::pel_values;
 
 PEL::PEL(const message::Entry& entry, uint32_t obmcLogID, uint64_t timestamp,
          phosphor::logging::Entry::Level severity,
@@ -171,5 +175,45 @@
 }
 
 } // namespace util
+void PEL::printSectionInJSON(Section& section, std::string& buf) const
+{
+    char tmpB[5];
+    if (section.valid())
+    {
+        uint8_t id[] = {static_cast<uint8_t>(section.header().id >> 8),
+                        static_cast<uint8_t>(section.header().id)};
+        sprintf(tmpB, "%c%c", id[0], id[1]);
+        std::string sectionID(tmpB);
+        std::string sectionName = pv::sectionTitles.count(sectionID)
+                                      ? pv::sectionTitles.at(sectionID)
+                                      : "Unknown Section";
+        buf += "\n\"" + sectionName + "\":[\n ";
+        std::vector<uint8_t> data;
+        Stream s{data};
+        section.flatten(s);
+        std::string dstr = dumpHex(std::data(data), data.size());
+        buf += dstr + "\n],\n";
+    }
+    else
+    {
+        buf += "\n\"Invalid Section  \":[\n invalid \n],\n";
+    }
+}
+
+void PEL::toJSON()
+{
+    std::string buf = "{";
+    printSectionInJSON(*(_ph.get()), buf);
+    printSectionInJSON(*(_uh.get()), buf);
+    for (auto& section : this->optionalSections())
+    {
+        printSectionInJSON(*(section.get()), buf);
+    }
+    buf += "}";
+    std::size_t found = buf.rfind(",");
+    if (found != std::string::npos)
+        buf.replace(found, 1, "");
+    std::cout << buf << std::endl;
+}
 } // namespace pels
 } // namespace openpower