pldm: Refector PDR repo based on the new PDR APIs

The related APIs for PDR operations is implemented in
pldm/libpldm/pdr.h and pldm/libpldm/pdr.c, we need to use this instead
of pdr::Repo(defined in libpldmresponder/pdr.hpp).
pdr::Repo is now a C++ wrapper around the PDR APIs in libpldm.

Tested with unit tests, with JSON files:
 https://gist.github.com/lxwinspur/2c3fd68cdb35e06480c4a5f7890e3a06#file-effecter_pdr-json.

 $ pldmtool platform GetPDR -d 0
 Encode request successfully
 Request Message:
 08 01 80 02 51 00 00 00 00 00 00 00 00 01 80 00 00 00
 Success in creating the socket : RC = 3
 Success in connecting to socket : RC = 0
 Success in sending message type as pldm to mctp : RC = 0
 Write to socket successful : RC = 18
 Total length:18
 Loopback response message:
 08 01 80 02 51 00 00 00 00 00 00 00 00 01 80 00 00 00
 On first recv(),response == request : RC = 0
 Total length: 46
 Shutdown Socket successful :  RC = 0
 Response Message:
 08 01 00 02 51 00 02 00 00 00 00 00 00 00 01 1d 00 01 00 00 00 01 0b 00 00 13 00 00 00 01 00 21 00 00 00 00 00 00 00 00 00 01 c4 00 01 06
 Parsed Response Msg:
 nextRecordHandle: 2
 responseCount: 29
 recordHandle: 1
 PDRHeaderVersion: 1
 PDRType: 11
 recordChangeNumber: 0
 dataLength: 19
 PLDMTerminusHandle: 0
 effecterID: 1
 entityType: 33
 entityInstanceNumber: 0
 containerID: 0
 effecterSemanticID: 0
 effecterInit: 0
 effecterDescriptionPDR: false
 compositeEffecterCount: 1
 stateSetID: 196
 possibleStatesSize: 1
 possibleStates: 6

Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I0c41f888b2e36a5a49968dff190ad8d53255b9ed
diff --git a/libpldmresponder/pdr_utils.hpp b/libpldmresponder/pdr_utils.hpp
new file mode 100644
index 0000000..4c2af02
--- /dev/null
+++ b/libpldmresponder/pdr_utils.hpp
@@ -0,0 +1,180 @@
+#pragma once
+
+#include <stdint.h>
+
+#include <filesystem>
+#include <fstream>
+#include <functional>
+#include <iostream>
+#include <nlohmann/json.hpp>
+#include <string>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+#include "libpldm/pdr.h"
+
+using InternalFailure =
+    sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+
+namespace fs = std::filesystem;
+
+namespace pldm
+{
+
+namespace responder
+{
+
+namespace pdr_utils
+{
+
+/** @struct PdrEntry
+ *  PDR entry structure that acts as a PDR record structure in the PDR
+ *  repository to handle PDR APIs.
+ */
+struct PdrEntry
+{
+    uint8_t* data;
+    uint32_t size;
+    union
+    {
+        uint32_t recordHandle;
+        uint32_t nextRecordHandle;
+    } handle;
+};
+using Type = uint8_t;
+using Json = nlohmann::json;
+using RecordHandle = uint32_t;
+
+/** @brief Parse PDR JSON file and output Json object
+ *
+ *  @param[in] path - path of PDR JSON file
+ *
+ *  @return Json - Json object
+ */
+inline Json readJson(const std::string& path)
+{
+    fs::path dir(path);
+    if (!fs::exists(dir) || fs::is_empty(dir))
+    {
+        throw InternalFailure();
+    }
+
+    std::ifstream jsonFile(path);
+    if (!jsonFile.is_open())
+    {
+        std::cerr << "Error opening PDR JSON file, PATH=" << path << "\n";
+        return {};
+    }
+
+    return Json::parse(jsonFile);
+}
+
+/**
+ *  @class RepoInterface
+ *
+ *  @brief Abstract class describing the interface API to the PDR repository,
+ *         this class wraps operations used to handle the new PDR APIs.
+ */
+class RepoInterface
+{
+  public:
+    virtual ~RepoInterface() = default;
+
+    /** @brief Get an opaque pldm_pdr structure
+     *
+     *  @return pldm_pdr - pldm_pdr structure
+     */
+    virtual const pldm_pdr* getPdr() = 0;
+
+    /** @brief Add a PDR record to a PDR repository
+     *
+     *  @param[in] pdrEntry - PDR records entry(data, size, recordHandle)
+     *
+     *  @return uint32_t - record handle assigned to PDR record
+     */
+    virtual RecordHandle addRecord(const PdrEntry& pdrEntry) = 0;
+
+    /** @brief Get the first PDR record from a PDR repository
+     *
+     *  @param[in] pdrEntry - PDR records entry(data, size, nextRecordHandle)
+     *
+     *  @return opaque pointer acting as PDR record handle, will be NULL if
+     *          record was not found
+     */
+    virtual const pldm_pdr_record* getFirstRecord(PdrEntry& pdrEntry) = 0;
+
+    /** @brief Get the next PDR record from a PDR repository
+     *
+     *  @param[in] currRecord - opaque pointer acting as a PDR record handle
+     *  @param[in] pdrEntry - PDR records entry(data, size, nextRecordHandle)
+     *
+     *  @return opaque pointer acting as PDR record handle, will be NULL if
+     *          record was not found
+     */
+    virtual const pldm_pdr_record*
+        getNextRecord(const pldm_pdr_record* currRecord,
+                      PdrEntry& pdrEntry) = 0;
+
+    /** @brief Get record handle of a PDR record
+     *
+     *  @param[in] record - opaque pointer acting as a PDR record handle
+     *
+     *  @return uint32_t - record handle assigned to PDR record; 0 if record is
+     *                     not found
+     */
+    virtual uint32_t getRecordHandle(const pldm_pdr_record* record) = 0;
+
+    /** @brief Get number of records in a PDR repository
+     *
+     *  @return uint32_t - number of records
+     */
+    virtual uint32_t getRecordCount() = 0;
+
+    /** @brief Determine if records are empty in a PDR repository
+     *
+     *  @return bool - true means empty and false means not empty
+     */
+    virtual bool empty() = 0;
+
+  protected:
+    pldm_pdr* repo;
+};
+
+/**
+ *  @class Repo
+ *
+ *  Wrapper class to handle the PDR APIs
+ *
+ *  This class wraps operations used to handle PDR APIs.
+ */
+class Repo : public RepoInterface
+{
+  public:
+    Repo()
+    {
+        repo = pldm_pdr_init();
+    }
+
+    ~Repo()
+    {
+        pldm_pdr_destroy(repo);
+    }
+
+    const pldm_pdr* getPdr();
+
+    RecordHandle addRecord(const PdrEntry& pdrEntry);
+
+    const pldm_pdr_record* getFirstRecord(PdrEntry& pdrEntry);
+
+    const pldm_pdr_record* getNextRecord(const pldm_pdr_record* currRecord,
+                                         PdrEntry& pdrEntry);
+
+    uint32_t getRecordHandle(const pldm_pdr_record* record);
+
+    uint32_t getRecordCount();
+
+    bool empty();
+};
+
+} // namespace pdr_utils
+} // namespace responder
+} // namespace pldm