PEL: Create PrivateHeader from parameters

Add a constructor to the PrivateHeader class so it can be built from the
creator's component ID, the OpenBMC log ID, and the creation timestamp.

This will be used when creating PELs from OpenBMC event logs.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I2d1217b9ff0317195366bee50fa72953fd5341dc
diff --git a/extensions/openpower-pels/pel_types.hpp b/extensions/openpower-pels/pel_types.hpp
index b836942..3d9e457 100644
--- a/extensions/openpower-pels/pel_types.hpp
+++ b/extensions/openpower-pels/pel_types.hpp
@@ -5,6 +5,9 @@
 namespace pels
 {
 
+/**
+ * @brief Useful component IDs
+ */
 enum class ComponentID
 {
     phosphorLogging = 0x2000
@@ -35,11 +38,33 @@
     extUserData = 0x4544         // 'ED'
 };
 
+/**
+ * @brief Useful SRC types
+ */
 enum class SRCType
 {
     bmcError = 0xBD,
     powerError = 0x11
 };
 
+/**
+ * @brief Creator IDs
+ */
+enum class CreatorID
+{
+    fsp = 'E',
+    hmc = 'C',
+    hostboot = 'B',
+    ioDrawer = 'M',
+    occ = 'T',
+    openBMC = 'O',
+    partFW = 'L',
+    phyp = 'H',
+    powerControl = 'W',
+    powerNV = 'P',
+    sapphire = 'K',
+    slic = 'S',
+};
+
 } // namespace pels
 } // namespace openpower
diff --git a/extensions/openpower-pels/private_header.cpp b/extensions/openpower-pels/private_header.cpp
index fc62df1..2265497 100644
--- a/extensions/openpower-pels/private_header.cpp
+++ b/extensions/openpower-pels/private_header.cpp
@@ -1,5 +1,6 @@
 #include "private_header.hpp"
 
+#include "log_id.hpp"
 #include "pel_types.hpp"
 
 #include <phosphor-logging/log.hpp>
@@ -11,6 +12,42 @@
 
 using namespace phosphor::logging;
 
+PrivateHeader::PrivateHeader(uint16_t componentID, uint32_t obmcLogID,
+                             uint64_t timestamp)
+{
+    _header.id = static_cast<uint16_t>(SectionID::privateHeader);
+    _header.size = PrivateHeader::flattenedSize();
+    _header.version = privateHeaderVersion;
+    _header.subType = 0;
+    _header.componentID = componentID;
+
+    _createTimestamp = getBCDTime(timestamp);
+
+    auto now = std::chrono::system_clock::now();
+    _commitTimestamp = getBCDTime(now);
+
+    _creatorID = static_cast<uint8_t>(CreatorID::openBMC);
+
+    // Add support for reminder and telemetry log types here if
+    // ever necessary.
+    _logType = 0;
+
+    _reservedByte = 0;
+
+    // the final section count will be updated later
+    _sectionCount = 1;
+
+    _obmcLogID = obmcLogID;
+
+    _id = generatePELID();
+
+    _plid = _id;
+
+    // Leave _creatorVersion at 0
+
+    _valid = true;
+}
+
 PrivateHeader::PrivateHeader(Stream& pel)
 {
     try
diff --git a/extensions/openpower-pels/private_header.hpp b/extensions/openpower-pels/private_header.hpp
index 66126a0..9c522a2 100644
--- a/extensions/openpower-pels/private_header.hpp
+++ b/extensions/openpower-pels/private_header.hpp
@@ -12,6 +12,11 @@
 struct CreatorVersion
 {
     uint8_t version[8];
+
+    CreatorVersion()
+    {
+        memset(version, '\0', sizeof(version));
+    }
 };
 
 static constexpr uint8_t privateHeaderVersion = 0x01;
@@ -42,6 +47,17 @@
     /**
      * @brief Constructor
      *
+     * Creates a valid PrivateHeader with the passed in data
+     *
+     * @param[in] componentID - the creator's component ID
+     * @param[in] obmcLogID - the corresponding OpenBMC event log ID
+     * @param[in] timestamp - the creation timestamp, in epoch milliseconds
+     */
+    PrivateHeader(uint16_t componentID, uint32_t obmcLogID, uint64_t timestamp);
+
+    /**
+     * @brief Constructor
+     *
      * Fills in this class's data fields from the stream.
      *
      * @param[in] pel - the PEL data stream