PEL: Add hidden and subsystem properties

This story adds a new PELEntry interface
org.open_power.Logging.PEL.Entry on existing PEL entry. Then we add 2
properties with their values initialized during the creation of the Interface.

Tested:
1. Verified that the new PEL creation with recoverable error sets the new
attribute in the PEL.entry Interface.
2. Restarted the phosphor-log-manager daemon and made sure the flag is set
with the new Interface created for d-bus
3. Tested with passing a RAWPEL to create from file system and verified
that the hidden attribute is set accordingly on the PEL.entry Interface.
4. Copied the new format error to a system with old code and restored
the error log to make sure it does not crash.
5. Validated both hidden and subsystem properties.

Signed-off-by: Vijay Lobo <vijaylobo@gmail.com>
Change-Id: Ida287ed84a4a3f9ddd054cde37d752219ffb1882
diff --git a/extensions/openpower-pels/manager.cpp b/extensions/openpower-pels/manager.cpp
index db2e2d6..f24f63c 100644
--- a/extensions/openpower-pels/manager.cpp
+++ b/extensions/openpower-pels/manager.cpp
@@ -188,6 +188,7 @@
         checkPelAndQuiesce(pel);
         updateEventId(pel);
         updateResolution(pel);
+        createPELEntry(obmcLogID);
     }
     else
     {
@@ -281,6 +282,8 @@
 {
     Repository::LogID id{Repository::LogID::Obmc(obmcLogID)};
 
+    auto path = std::string(OBJ_ENTRY) + '/' + std::to_string(obmcLogID);
+    _pelEntries.erase(path);
     _repo.remove(id);
 }
 
@@ -386,6 +389,7 @@
     checkPelAndQuiesce(pel);
     updateEventId(pel);
     updateResolution(pel);
+    createPELEntry(obmcLogID);
 }
 
 sdbusplus::message::unix_fd Manager::getPEL(uint32_t pelID)
@@ -782,18 +786,34 @@
         auto entry = _logManager.entries.find(obmcLogID);
         if (entry != _logManager.entries.end())
         {
-            if (attr.actionFlags.test(callHomeFlagBit))
-            {
-                entry->second->serviceProviderNotify(true);
-            }
-            else
-            {
-                entry->second->serviceProviderNotify(false);
-            }
+            entry->second->serviceProviderNotify(
+                attr.actionFlags.test(callHomeFlagBit));
         }
     }
 }
 
+void Manager::createPELEntry(uint32_t obmcLogID)
+{
+    std::map<std::string, PropertiesVariant> varData;
+    Repository::LogID id{Repository::LogID::Obmc(obmcLogID)};
+    if (auto attributes = _repo.getPELAttributes(id); attributes)
+    {
+        namespace pv = openpower::pels::pel_values;
+        auto& attr = attributes.value().get();
+        varData.emplace(std::string("Hidden"),
+                        attr.actionFlags.test(hiddenFlagBit));
+        varData.emplace(
+            std::string("Subsystem"),
+            pv::getValue(attr.subsystem, pel_values::subsystemValues));
+        // Path to create PELEntry Interface is same as PEL
+        auto path = std::string(OBJ_ENTRY) + '/' + std::to_string(obmcLogID);
+        // Create Interface for PELEntry and set properties
+        auto pelEntry = std::make_unique<PELEntry>(_logManager.getBus(),
+                                                   path.c_str(), varData);
+        _pelEntries.emplace(std::move(path), std::move(pelEntry));
+    }
+}
+
 uint32_t Manager::getPELIdFromBMCLogId(uint32_t bmcLogId)
 {
     Repository::LogID id{Repository::LogID::Obmc(bmcLogId)};
diff --git a/extensions/openpower-pels/manager.hpp b/extensions/openpower-pels/manager.hpp
index aa4a393..5923f00 100644
--- a/extensions/openpower-pels/manager.hpp
+++ b/extensions/openpower-pels/manager.hpp
@@ -11,6 +11,7 @@
 #include "registry.hpp"
 #include "repository.hpp"
 
+#include <org/open_power/Logging/PEL/Entry/server.hpp>
 #include <org/open_power/Logging/PEL/server.hpp>
 #include <sdbusplus/server.hpp>
 #include <sdeventplus/event.hpp>
@@ -25,6 +26,9 @@
 using PELInterface = sdbusplus::server::object::object<
     sdbusplus::org::open_power::Logging::server::PEL>;
 
+using PELEntry = sdbusplus::org::open_power::Logging::PEL::server::Entry;
+using PropertiesVariant = PELEntry::PropertiesVariant;
+
 /**
  * @brief PEL manager object
  */
@@ -59,6 +63,8 @@
         {
             setEntryPath(entry.first);
             setServiceProviderNotifyFlag(entry.first);
+            // Create PELEntry interface and setup properties with their values
+            createPELEntry(entry.first);
         }
         setupPELDeleteWatch();
     }
@@ -403,6 +409,16 @@
     void updateResolution(std::unique_ptr<openpower::pels::PEL>& pel);
 
     /**
+     * @brief Create PELEntry Interface with supported properties
+     *
+     * Create PELEntry Interface and update all the properties which are
+     * supported
+     *
+     * @param[in] obmcLogID - The OpenBMC entry log ID
+     */
+    void createPELEntry(uint32_t obmcLogID);
+
+    /**
      * @brief Reference to phosphor-logging's Manager class
      */
     phosphor::logging::internal::Manager& _logManager;
@@ -434,6 +450,15 @@
     std::unique_ptr<DataInterfaceBase> _dataIface;
 
     /**
+     * @brief The map used to keep track of PEL entry pointer associated with
+     *        event log.
+     */
+    std::map<std::string,
+             std::unique_ptr<
+                 sdbusplus::org::open_power::Logging::PEL::server::Entry>>
+        _pelEntries;
+
+    /**
      * @brief The HostNotifier object used for telling the
      *        host about new PELs
      */
diff --git a/extensions/openpower-pels/repository.cpp b/extensions/openpower-pels/repository.cpp
index 9b650ce..6b9408f 100644
--- a/extensions/openpower-pels/repository.cpp
+++ b/extensions/openpower-pels/repository.cpp
@@ -116,6 +116,7 @@
                 PELAttributes attributes{dirEntry.path(),
                                          getFileDiskSize(dirEntry.path()),
                                          pel.privateHeader().creatorID(),
+                                         pel.userHeader().subsystem(),
                                          pel.userHeader().severity(),
                                          pel.userHeader().actionFlags(),
                                          pel.hostTransmissionState(),
@@ -173,6 +174,7 @@
     PELAttributes attributes{path,
                              getFileDiskSize(path),
                              pel->privateHeader().creatorID(),
+                             pel->userHeader().subsystem(),
                              pel->userHeader().severity(),
                              pel->userHeader().actionFlags(),
                              pel->hostTransmissionState(),
diff --git a/extensions/openpower-pels/repository.hpp b/extensions/openpower-pels/repository.hpp
index b8ef126..b2fc797 100644
--- a/extensions/openpower-pels/repository.hpp
+++ b/extensions/openpower-pels/repository.hpp
@@ -29,6 +29,7 @@
         std::filesystem::path path;
         size_t sizeOnDisk;
         uint8_t creator;
+        uint8_t subsystem;
         uint8_t severity;
         std::bitset<16> actionFlags;
         TransmissionState hostState;
@@ -37,11 +38,13 @@
         PELAttributes() = delete;
 
         PELAttributes(const std::filesystem::path& p, size_t size,
-                      uint8_t creator, uint8_t sev, uint16_t flags,
-                      TransmissionState hostState, TransmissionState hmcState) :
+                      uint8_t creator, uint8_t subsystem, uint8_t sev,
+                      uint16_t flags, TransmissionState hostState,
+                      TransmissionState hmcState) :
             path(p),
-            sizeOnDisk(size), creator(creator), severity(sev),
-            actionFlags(flags), hostState(hostState), hmcState(hmcState)
+            sizeOnDisk(size), creator(creator), subsystem(subsystem),
+            severity(sev), actionFlags(flags), hostState(hostState),
+            hmcState(hmcState)
         {
         }
     };