PEL: Save AdditionalData in a UserData section

Save the contents of the AdditionalData OpenBMC event log property as
JSON in a UserData PEL section.

For example, if the AdditionalData property, which is an array of
strings, looks like:
    ["KEY1=VALUE1", "KEY=VALUE2"]

Then the data stored as ASCII text in the UserData section is:
    {"KEY1":"VALUE1","KEY2":"VALUE2"}

If one of the keys is "ESEL", then that entry is removed from the
UserData output as that contains a full raw PEL from the host sent down
as ASCII text.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: Ia6ffabb39fdb4315ec2152744414e44f7d2ec4aa
diff --git a/extensions/openpower-pels/pel.cpp b/extensions/openpower-pels/pel.cpp
index ffd4974..af904ff 100644
--- a/extensions/openpower-pels/pel.cpp
+++ b/extensions/openpower-pels/pel.cpp
@@ -6,6 +6,7 @@
 #include "section_factory.hpp"
 #include "src.hpp"
 #include "stream.hpp"
+#include "user_data_formats.hpp"
 
 #include <phosphor-logging/log.hpp>
 
@@ -30,6 +31,12 @@
     auto mtms = std::make_unique<FailingMTMS>(dataIface);
     _optionalSections.push_back(std::move(mtms));
 
+    if (!additionalData.empty())
+    {
+        auto ud = util::makeADUserDataSection(additionalData);
+        _optionalSections.push_back(std::move(ud));
+    }
+
     _ph->sectionCount() = 2 + _optionalSections.size();
 }
 
@@ -134,5 +141,35 @@
     return std::nullopt;
 }
 
+namespace util
+{
+
+std::unique_ptr<UserData> makeADUserDataSection(const AdditionalData& ad)
+{
+    assert(!ad.empty());
+    nlohmann::json json;
+
+    // Remove the 'ESEL' entry, as it contains a full PEL in the value.
+    if (ad.getValue("ESEL"))
+    {
+        auto newAD = ad;
+        newAD.remove("ESEL");
+        json = newAD.toJSON();
+    }
+    else
+    {
+        json = ad.toJSON();
+    }
+
+    auto jsonString = json.dump();
+    std::vector<uint8_t> jsonData(jsonString.begin(), jsonString.end());
+
+    return std::make_unique<UserData>(
+        static_cast<uint16_t>(ComponentID::phosphorLogging),
+        static_cast<uint8_t>(UserDataFormat::json),
+        static_cast<uint8_t>(UserDataFormatVersion::json), jsonData);
+}
+
+} // namespace util
 } // namespace pels
 } // namespace openpower