PEL: Add PEL D-Bus methods

Implement the org.open_power.Logging.PEL D-Bus interface on
/xyz/openbmc_project/logging.

It provides the following methods:
* getPEL - Return a unix FD to the PEL data based on the PEL id.
* getPELFromOBMCID - Return PEL data in a vector based on the
                     corresponding OpenBMC event log id.
* hostAck - Called when the host has sent the PEL up to the OS,
            which is the final step in the reporting process.
* hostReject - Called when the host has an issue with a PEL, either:
  - The host doesn't have any more room for PELs at this moment.
  - The PEL was malformed.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I633ae9e26d8336973363a1a207e8fd493f7ff7d2
diff --git a/extensions/openpower-pels/manager.cpp b/extensions/openpower-pels/manager.cpp
index b9c7d94..aec5053 100644
--- a/extensions/openpower-pels/manager.cpp
+++ b/extensions/openpower-pels/manager.cpp
@@ -20,6 +20,7 @@
 
 #include <filesystem>
 #include <fstream>
+#include <xyz/openbmc_project/Common/error.hpp>
 
 namespace openpower
 {
@@ -29,6 +30,8 @@
 using namespace phosphor::logging;
 namespace fs = std::filesystem;
 
+namespace common_error = sdbusplus::xyz::openbmc_project::Common::Error;
+
 namespace additional_data
 {
 constexpr auto rawPEL = "RAWPEL";
@@ -73,7 +76,7 @@
 
         file.close();
 
-        auto pel = std::make_unique<PEL>(data, obmcLogID);
+        auto pel = std::make_unique<openpower::pels::PEL>(data, obmcLogID);
         if (pel->valid())
         {
             // PELs created by others still need these fields set by us.
@@ -132,8 +135,8 @@
     {
         AdditionalData ad{additionalData};
 
-        auto pel = std::make_unique<PEL>(*entry, obmcLogID, timestamp, severity,
-                                         ad, *_dataIface);
+        auto pel = std::make_unique<openpower::pels::PEL>(
+            *entry, obmcLogID, timestamp, severity, ad, *_dataIface);
 
         _repo.add(pel);
 
@@ -160,5 +163,86 @@
     }
 }
 
+sdbusplus::message::unix_fd Manager::getPEL(uint32_t pelID)
+{
+    Repository::LogID id{Repository::LogID::Pel(pelID)};
+    std::optional<int> fd;
+
+    try
+    {
+        fd = _repo.getPELFD(id);
+    }
+    catch (std::exception& e)
+    {
+        throw common_error::InternalFailure();
+    }
+
+    if (!fd)
+    {
+        throw common_error::InvalidArgument();
+    }
+
+    return *fd;
+}
+
+std::vector<uint8_t> Manager::getPELFromOBMCID(uint32_t obmcLogID)
+{
+    Repository::LogID id{Repository::LogID::Obmc(obmcLogID)};
+    std::optional<std::vector<uint8_t>> data;
+
+    try
+    {
+        data = _repo.getPELData(id);
+    }
+    catch (std::exception& e)
+    {
+        throw common_error::InternalFailure();
+    }
+
+    if (!data)
+    {
+        throw common_error::InvalidArgument();
+    }
+
+    return *data;
+}
+
+void Manager::hostAck(uint32_t pelID)
+{
+    Repository::LogID id{Repository::LogID::Pel(pelID)};
+
+    if (!_repo.hasPEL(id))
+    {
+        throw common_error::InvalidArgument();
+    }
+
+    if (_hostNotifier)
+    {
+        _hostNotifier->ackPEL(pelID);
+    }
+}
+
+void Manager::hostReject(uint32_t pelID, RejectionReason reason)
+{
+    Repository::LogID id{Repository::LogID::Pel(pelID)};
+
+    if (!_repo.hasPEL(id))
+    {
+        throw common_error::InvalidArgument();
+    }
+
+    if (_hostNotifier)
+    {
+        if (reason == RejectionReason::BadPEL)
+        {
+            _hostNotifier->setBadPEL(pelID);
+        }
+        else if (reason == RejectionReason::HostFull)
+        {
+            _hostNotifier->setHostFull(pelID);
+        }
+    }
+}
+
 } // namespace pels
 } // namespace openpower