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/meson.build b/libpldmresponder/meson.build
index e4e6a87..ab3aeb4 100644
--- a/libpldmresponder/meson.build
+++ b/libpldmresponder/meson.build
@@ -10,6 +10,7 @@
   'bios.cpp',
   'bios_table.cpp',
   'bios_parser.cpp',
+  'pdr_utils.cpp',
   'pdr.cpp',
   'effecters.cpp',
   'platform.cpp',
diff --git a/libpldmresponder/pdr.cpp b/libpldmresponder/pdr.cpp
index e252cb3..d2c8214 100644
--- a/libpldmresponder/pdr.cpp
+++ b/libpldmresponder/pdr.cpp
@@ -8,11 +8,145 @@
 
 namespace pdr
 {
+using namespace pldm::responder::pdr_utils;
 
-Repo& get(const std::string& dir)
+void generate(const std::string& dir, RepoInterface& repo)
 {
-    using namespace internal;
-    static IndexedRepo repo;
+    // A map of PDR type to a lambda that handles creation of that PDR type.
+    // The lambda essentially would parse the platform specific PDR JSONs to
+    // generate the PDR structures. This function iterates through the map to
+    // invoke all lambdas, so that all PDR types can be created.
+    std::map<Type, std::function<void(const Json& json, RepoInterface& repo)>>
+        generators = {
+            {PLDM_STATE_EFFECTER_PDR,
+             [](const auto& json, RepoInterface& repo) {
+                 static const std::vector<Json> emptyList{};
+                 static const Json empty{};
+                 auto entries = json.value("entries", emptyList);
+                 for (const auto& e : entries)
+                 {
+                     size_t pdrSize = 0;
+                     auto effecters = e.value("effecters", emptyList);
+                     static const Json empty{};
+                     for (const auto& effecter : effecters)
+                     {
+                         auto set = effecter.value("set", empty);
+                         auto statesSize = set.value("size", 0);
+                         if (!statesSize)
+                         {
+                             std::cerr << "Malformed PDR JSON return "
+                                          "pdrEntry;- no state set "
+                                          "info, TYPE="
+                                       << PLDM_STATE_EFFECTER_PDR << "\n";
+                             throw InternalFailure();
+                         }
+                         pdrSize += sizeof(state_effecter_possible_states) -
+                                    sizeof(bitfield8_t) +
+                                    (sizeof(bitfield8_t) * statesSize);
+                     }
+                     pdrSize +=
+                         sizeof(pldm_state_effecter_pdr) - sizeof(uint8_t);
+
+                     std::vector<uint8_t> entry{};
+                     entry.resize(pdrSize);
+
+                     pldm_state_effecter_pdr* pdr =
+                         reinterpret_cast<pldm_state_effecter_pdr*>(
+                             entry.data());
+                     pdr->hdr.record_handle = 0;
+                     pdr->hdr.version = 1;
+                     pdr->hdr.type = PLDM_STATE_EFFECTER_PDR;
+                     pdr->hdr.record_change_num = 0;
+                     pdr->hdr.length = pdrSize - sizeof(pldm_pdr_hdr);
+
+                     pdr->terminus_handle = 0;
+                     pdr->effecter_id = effecter::nextId();
+                     pdr->entity_type = e.value("type", 0);
+                     pdr->entity_instance = e.value("instance", 0);
+                     pdr->container_id = e.value("container", 0);
+                     pdr->effecter_semantic_id = 0;
+                     pdr->effecter_init = PLDM_NO_INIT;
+                     pdr->has_description_pdr = false;
+                     pdr->composite_effecter_count = effecters.size();
+
+                     using namespace effecter::dbus_mapping;
+                     Paths paths{};
+                     uint8_t* start = entry.data() +
+                                      sizeof(pldm_state_effecter_pdr) -
+                                      sizeof(uint8_t);
+                     for (const auto& effecter : effecters)
+                     {
+                         auto set = effecter.value("set", empty);
+                         state_effecter_possible_states* possibleStates =
+                             reinterpret_cast<state_effecter_possible_states*>(
+                                 start);
+                         possibleStates->state_set_id = set.value("id", 0);
+                         possibleStates->possible_states_size =
+                             set.value("size", 0);
+
+                         start += sizeof(possibleStates->state_set_id) +
+                                  sizeof(possibleStates->possible_states_size);
+                         static const std::vector<uint8_t> emptyStates{};
+                         auto states = set.value("states", emptyStates);
+                         for (const auto& state : states)
+                         {
+                             auto index = state / 8;
+                             auto bit = state - (index * 8);
+                             bitfield8_t* bf =
+                                 reinterpret_cast<bitfield8_t*>(start + index);
+                             bf->byte |= 1 << bit;
+                         }
+                         start += possibleStates->possible_states_size;
+
+                         auto dbus = effecter.value("dbus", empty);
+                         paths.emplace_back(std::move(dbus));
+                     }
+                     add(pdr->effecter_id, std::move(paths));
+                     PdrEntry pdrEntry{};
+                     pdrEntry.data = entry.data();
+                     pdrEntry.size = pdrSize;
+                     repo.addRecord(pdrEntry);
+                 }
+             }}};
+
+    Type pdrType{};
+    for (const auto& dirEntry : fs::directory_iterator(dir))
+    {
+        try
+        {
+            auto json = readJson(dirEntry.path().string());
+            if (!json.empty())
+            {
+                pdrType = json.value("pdrType", 0);
+                generators.at(pdrType)(json, repo);
+            }
+        }
+        catch (const InternalFailure& e)
+        {
+            std::cerr << "PDR config directory does not exist or empty, TYPE= "
+                      << pdrType << "PATH= " << dirEntry
+                      << " ERROR=" << e.what() << "\n";
+        }
+        catch (const Json::exception& e)
+        {
+            std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType
+                      << "PATH= " << dirEntry << " ERROR=" << e.what() << "\n";
+            pldm::utils::reportError(
+                "xyz.openbmc_project.bmc.pldm.InternalFailure");
+        }
+        catch (const std::exception& e)
+        {
+            std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType
+                      << " ERROR=" << e.what() << "\n";
+            pldm::utils::reportError(
+                "xyz.openbmc_project.bmc.pldm.InternalFailure");
+        }
+    }
+}
+
+RepoInterface& getRepo(const std::string& dir)
+{
+    static Repo repo;
     if (repo.empty())
     {
         generate(dir, repo);
@@ -21,6 +155,48 @@
     return repo;
 }
 
+Repo getRepoByType(const std::string& dir, Type pdrType)
+{
+    Repo pdrRepo;
+    RepoInterface& repo = getRepo(dir);
+
+    uint8_t* pdrData = nullptr;
+    uint32_t pdrSize{};
+    auto record = pldm_pdr_find_record_by_type(repo.getPdr(), pdrType, NULL,
+                                               &pdrData, &pdrSize);
+    while (record)
+    {
+        PdrEntry pdrEntry{};
+        pdrEntry.data = pdrData;
+        pdrEntry.size = pdrSize;
+        pdrEntry.handle.recordHandle = repo.getRecordHandle(record);
+        pdrRepo.addRecord(pdrEntry);
+
+        pdrData = nullptr;
+        pdrSize = 0;
+        record = pldm_pdr_find_record_by_type(repo.getPdr(), pdrType, record,
+                                              &pdrData, &pdrSize);
+    }
+
+    return pdrRepo;
+}
+
+const pldm_pdr_record* getRecordByHandle(RepoInterface& pdrRepo,
+                                         RecordHandle recordHandle,
+                                         PdrEntry& pdrEntry)
+{
+    uint8_t* pdrData = nullptr;
+    auto record =
+        pldm_pdr_find_record(pdrRepo.getPdr(), recordHandle, &pdrData,
+                             &pdrEntry.size, &pdrEntry.handle.nextRecordHandle);
+    if (record)
+    {
+        pdrEntry.data = pdrData;
+    }
+
+    return record;
+}
+
 } // namespace pdr
 } // namespace responder
 } // namespace pldm
diff --git a/libpldmresponder/pdr.hpp b/libpldmresponder/pdr.hpp
index 9432f3e..0cf9385 100644
--- a/libpldmresponder/pdr.hpp
+++ b/libpldmresponder/pdr.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "effecters.hpp"
+#include "libpldmresponder/pdr_utils.hpp"
 #include "utils.hpp"
 
 #include <stdint.h>
@@ -15,12 +16,15 @@
 #include <vector>
 #include <xyz/openbmc_project/Common/error.hpp>
 
+#include "libpldm/pdr.h"
 #include "libpldm/platform.h"
 
 using InternalFailure =
     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
 namespace fs = std::filesystem;
 
+using namespace pldm::responder::pdr_utils;
+
 namespace pldm
 {
 
@@ -29,294 +33,42 @@
 
 namespace pdr
 {
-
-using Type = uint8_t;
-using Json = nlohmann::json;
-using RecordHandle = uint32_t;
-using Entry = std::vector<uint8_t>;
-using Pdr = std::vector<Entry>;
-
-/** @class Repo
- *
- *  @brief Abstract class describing the interface API to the PDR repository
- *
- *  Concrete implementations of this must handle storing and addressing the
- *  PDR entries by a "record handle", which can be indices, offsets, etc.
- */
-class Repo
-{
-  public:
-    virtual ~Repo() = default;
-
-    /** @brief Add a new entry to the PDR
-     *
-     *  @param[in] entry - new PDR entry
-     */
-    virtual void add(Entry&& entry) = 0;
-
-    /** @brief Access PDR entry at inout record handle
-     *
-     *  @param[in] handle - record handle
-     *
-     *  @return Entry - PDR entry
-     */
-    virtual Entry at(RecordHandle handle) const = 0;
-
-    /** @brief Get next available record handle for assignment
-     *
-     *  @return RecordHandle - PDR record handle
-     */
-    virtual RecordHandle getNextRecordHandle() const = 0;
-
-    /** @brief Get record handle immediately suceeding the input record
-     *         handle
-     *
-     *  @param[in] current - input record handle
-     *
-     *  @return RecordHandle - PDR record handle
-     */
-    virtual RecordHandle getNextRecordHandle(RecordHandle current) const = 0;
-
-    /** @brief Get number of entries in the PDR
-     *
-     *  @return size_t - number of entries
-     */
-    virtual size_t numEntries() const = 0;
-
-    /** @brief Check if PDR is empty
-     *
-     *  @return bool - true if PDR is empty, false otherwise
-     */
-    virtual bool empty() const = 0;
-
-    /** @brief Empty the PDR
-     */
-    virtual void makeEmpty() = 0;
-};
-
-namespace internal
-{
-
-/** @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)
-{
-    std::ifstream jsonFile(path);
-    if (!jsonFile.is_open())
-    {
-        std::cout << "Error opening PDR JSON file, PATH=" << path.c_str()
-                  << std::endl;
-        return {};
-    }
-
-    return Json::parse(jsonFile);
-}
-
-/** @class IndexedRepo
- *
- *  @brief Inherits and implements Repo
- *
- *  Stores the PDR as a vector of entries, and addresses PDR entries based on an
- *  incrementing record handle, starting at 1.
- */
-class IndexedRepo : public Repo
-{
-  public:
-    void add(Entry&& entry)
-    {
-        repo.emplace_back(std::move(entry));
-    }
-
-    Entry at(RecordHandle handle) const
-    {
-        if (!handle)
-        {
-            handle = 1;
-        }
-        return repo.at(handle - 1);
-    }
-
-    RecordHandle getNextRecordHandle() const
-    {
-        return repo.size() + 1;
-    }
-
-    RecordHandle getNextRecordHandle(RecordHandle current) const
-    {
-        if (current >= repo.size())
-        {
-            return 0;
-        }
-        if (!current)
-        {
-            current = 1;
-        }
-        return current + 1;
-    }
-
-    size_t numEntries() const
-    {
-        return repo.size();
-    }
-
-    bool empty() const
-    {
-        return repo.empty();
-    }
-
-    void makeEmpty()
-    {
-        repo.clear();
-    }
-
-  private:
-    Pdr repo{};
-};
-
 /** @brief Parse PDR JSONs and build PDR repository
  *
  *  @param[in] dir - directory housing platform specific PDR JSON files
- *  @tparam[in] repo - instance of concrete implementation of Repo
+ *  @param[in] repo - instance of the concrete implementation of RepoInterface
  */
-template <typename T>
-void generate(const std::string& dir, T& repo)
-{
-    using namespace internal;
-    // A map of PDR type to a lambda that handles creation of that PDR type.
-    // The lambda essentially would parse the platform specific PDR JSONs to
-    // generate the PDR structures. This function iterates through the map to
-    // invoke all lambdas, so that all PDR types can be created.
-    std::map<Type, std::function<void(const Json& json, T& repo)>> generators =
-        {{PLDM_STATE_EFFECTER_PDR, [](const auto& json, T& repo) {
-              static const std::vector<Json> emptyList{};
-              static const Json empty{};
-              auto entries = json.value("entries", emptyList);
-              for (const auto& e : entries)
-              {
-                  size_t pdrSize = 0;
-                  auto effecters = e.value("effecters", emptyList);
-                  static const Json empty{};
-                  for (const auto& effecter : effecters)
-                  {
-                      auto set = effecter.value("set", empty);
-                      auto statesSize = set.value("size", 0);
-                      if (!statesSize)
-                      {
-                          std::cerr
-                              << "Malformed PDR JSON - no state set info, TYPE="
-                              << PLDM_STATE_EFFECTER_PDR << "\n";
-                          throw InternalFailure();
-                      }
-                      pdrSize += sizeof(state_effecter_possible_states) -
-                                 sizeof(bitfield8_t) +
-                                 (sizeof(bitfield8_t) * statesSize);
-                  }
-                  pdrSize += sizeof(pldm_state_effecter_pdr) - sizeof(uint8_t);
-
-                  Entry pdrEntry{};
-                  pdrEntry.resize(pdrSize);
-
-                  pldm_state_effecter_pdr* pdr =
-                      reinterpret_cast<pldm_state_effecter_pdr*>(
-                          pdrEntry.data());
-                  pdr->hdr.record_handle = repo.getNextRecordHandle();
-                  pdr->hdr.version = 1;
-                  pdr->hdr.type = PLDM_STATE_EFFECTER_PDR;
-                  pdr->hdr.record_change_num = 0;
-                  pdr->hdr.length = pdrSize - sizeof(pldm_pdr_hdr);
-
-                  pdr->terminus_handle = 0;
-                  pdr->effecter_id = effecter::nextId();
-                  pdr->entity_type = e.value("type", 0);
-                  pdr->entity_instance = e.value("instance", 0);
-                  pdr->container_id = e.value("container", 0);
-                  pdr->effecter_semantic_id = 0;
-                  pdr->effecter_init = PLDM_NO_INIT;
-                  pdr->has_description_pdr = false;
-                  pdr->composite_effecter_count = effecters.size();
-
-                  using namespace effecter::dbus_mapping;
-                  Paths paths{};
-                  uint8_t* start = pdrEntry.data() +
-                                   sizeof(pldm_state_effecter_pdr) -
-                                   sizeof(uint8_t);
-                  for (const auto& effecter : effecters)
-                  {
-                      auto set = effecter.value("set", empty);
-                      state_effecter_possible_states* possibleStates =
-                          reinterpret_cast<state_effecter_possible_states*>(
-                              start);
-                      possibleStates->state_set_id = set.value("id", 0);
-                      possibleStates->possible_states_size =
-                          set.value("size", 0);
-
-                      start += sizeof(possibleStates->state_set_id) +
-                               sizeof(possibleStates->possible_states_size);
-                      static const std::vector<uint8_t> emptyStates{};
-                      auto states = set.value("states", emptyStates);
-                      for (const auto& state : states)
-                      {
-                          auto index = state / 8;
-                          auto bit = state - (index * 8);
-                          bitfield8_t* bf =
-                              reinterpret_cast<bitfield8_t*>(start + index);
-                          bf->byte |= 1 << bit;
-                      }
-                      start += possibleStates->possible_states_size;
-
-                      auto dbus = effecter.value("dbus", empty);
-                      paths.emplace_back(std::move(dbus));
-                  }
-                  add(pdr->effecter_id, std::move(paths));
-                  repo.add(std::move(pdrEntry));
-              }
-          }}};
-
-    Type pdrType{};
-    for (const auto& dirEntry : fs::directory_iterator(dir))
-    {
-        try
-        {
-            auto json = readJson(dirEntry.path().string());
-            if (!json.empty())
-            {
-                pdrType = json.value("pdrType", 0);
-                generators.at(pdrType)(json, repo);
-            }
-        }
-        catch (const InternalFailure& e)
-        {
-        }
-        catch (const Json::exception& e)
-        {
-            std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType
-                      << " ERROR=" << e.what() << "\n";
-            pldm::utils::reportError(
-                "xyz.openbmc_project.bmc.pldm.InternalFailure");
-        }
-        catch (const std::exception& e)
-        {
-            std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType
-                      << " ERROR=" << e.what() << "\n";
-            pldm::utils::reportError(
-                "xyz.openbmc_project.bmc.pldm.InternalFailure");
-        }
-    }
-}
-
-} // namespace internal
+void generate(const std::string& dir, RepoInterface& repo);
 
 /** @brief Build (if not built already) and retrieve PDR
  *
  *  @param[in] dir - directory housing platform specific PDR JSON files
  *
- *  @return Repo& - Reference to instance of pdr::Repo
+ *  @return RepoInterface& - Reference to instance of pdr::RepoInterface
  */
-Repo& get(const std::string& dir);
+RepoInterface& getRepo(const std::string& dir);
+
+/** @brief Build (if not built already) and retrieve PDR by the PDR types
+ *
+ *  @param[in] dir - directory housing platform specific PDR JSON files
+ *  @param[in] pdrType - the type of PDRs
+ *
+ *  @return Repo - Instance of pdr::Repo
+ */
+Repo getRepoByType(const std::string& dir, Type pdrType);
+
+/** @brief Get the record of PDR by the record handle
+ *
+ *  @param[in] pdrRepo - pdr::RepoInterface
+ *  @param[in] recordHandle - The recordHandle value for the PDR to be
+ * retrieved.
+ *  @param[out] pdrEntry - PDR entry structure reference
+ *
+ *  @return pldm_pdr_record - Instance of pdr::RepoInterface
+ */
+const pldm_pdr_record* getRecordByHandle(RepoInterface& pdrRepo,
+                                         RecordHandle recordHandle,
+                                         PdrEntry& pdrEntry);
 
 } // namespace pdr
 } // namespace responder
diff --git a/libpldmresponder/pdr_utils.cpp b/libpldmresponder/pdr_utils.cpp
new file mode 100644
index 0000000..850dbcb
--- /dev/null
+++ b/libpldmresponder/pdr_utils.cpp
@@ -0,0 +1,70 @@
+#include "pdr.hpp"
+
+namespace pldm
+{
+
+namespace responder
+{
+
+namespace pdr_utils
+{
+
+const pldm_pdr* Repo::getPdr()
+{
+    return repo;
+}
+
+RecordHandle Repo::addRecord(const PdrEntry& pdrEntry)
+{
+    return pldm_pdr_add(repo, pdrEntry.data, pdrEntry.size,
+                        pdrEntry.handle.recordHandle);
+}
+
+const pldm_pdr_record* Repo::getFirstRecord(PdrEntry& pdrEntry)
+{
+    constexpr uint32_t firstNum = 0;
+    uint8_t* pdrData = nullptr;
+    auto record =
+        pldm_pdr_find_record(getPdr(), firstNum, &pdrData, &pdrEntry.size,
+                             &pdrEntry.handle.nextRecordHandle);
+    if (record)
+    {
+        pdrEntry.data = pdrData;
+    }
+
+    return record;
+}
+
+const pldm_pdr_record* Repo::getNextRecord(const pldm_pdr_record* currRecord,
+                                           PdrEntry& pdrEntry)
+{
+    uint8_t* pdrData = nullptr;
+    auto record =
+        pldm_pdr_get_next_record(getPdr(), currRecord, &pdrData, &pdrEntry.size,
+                                 &pdrEntry.handle.nextRecordHandle);
+    if (record)
+    {
+        pdrEntry.data = pdrData;
+    }
+
+    return record;
+}
+
+uint32_t Repo::getRecordHandle(const pldm_pdr_record* record)
+{
+    return pldm_pdr_get_record_handle(getPdr(), record);
+}
+
+uint32_t Repo::getRecordCount()
+{
+    return pldm_pdr_get_record_count(getPdr());
+}
+
+bool Repo::empty()
+{
+    return !getRecordCount();
+}
+
+} // namespace pdr_utils
+} // namespace responder
+} // namespace pldm
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
diff --git a/libpldmresponder/platform.cpp b/libpldmresponder/platform.cpp
index 3f93ff4..4d297f0 100644
--- a/libpldmresponder/platform.cpp
+++ b/libpldmresponder/platform.cpp
@@ -36,41 +36,40 @@
         return CmdHandler::ccOnlyResponse(request, rc);
     }
 
-    uint32_t nextRecordHandle{};
     uint16_t respSizeBytes{};
     uint8_t* recordData = nullptr;
     try
     {
-        pdr::Repo& pdrRepo = pdr::get(PDR_JSONS_DIR);
-        nextRecordHandle = pdrRepo.getNextRecordHandle(recordHandle);
-        pdr::Entry e;
+        pdr_utils::RepoInterface& pdrRepo = pdr::getRepo(PDR_JSONS_DIR);
+        pdr_utils::PdrEntry e;
+        auto record = pdr::getRecordByHandle(pdrRepo, recordHandle, e);
+        if (record == NULL)
+        {
+            return CmdHandler::ccOnlyResponse(
+                request, PLDM_PLATFORM_INVALID_RECORD_HANDLE);
+        }
+
         if (reqSizeBytes)
         {
-            e = pdrRepo.at(recordHandle);
-            respSizeBytes = e.size();
+            respSizeBytes = e.size;
             if (respSizeBytes > reqSizeBytes)
             {
                 respSizeBytes = reqSizeBytes;
             }
-            recordData = e.data();
+            recordData = e.data;
         }
         response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES +
                             respSizeBytes,
                         0);
         responsePtr = reinterpret_cast<pldm_msg*>(response.data());
         rc = encode_get_pdr_resp(request->hdr.instance_id, PLDM_SUCCESS,
-                                 nextRecordHandle, 0, PLDM_START, respSizeBytes,
-                                 recordData, 0, responsePtr);
+                                 e.handle.nextRecordHandle, 0, PLDM_START,
+                                 respSizeBytes, recordData, 0, responsePtr);
         if (rc != PLDM_SUCCESS)
         {
             return ccOnlyResponse(request, rc);
         }
     }
-    catch (const std::out_of_range& e)
-    {
-        return CmdHandler::ccOnlyResponse(request,
-                                          PLDM_PLATFORM_INVALID_RECORD_HANDLE);
-    }
     catch (const std::exception& e)
     {
         std::cerr << "Error accessing PDR, HANDLE=" << recordHandle
diff --git a/libpldmresponder/platform.hpp b/libpldmresponder/platform.hpp
index 3de0e1f..dde51e0 100644
--- a/libpldmresponder/platform.hpp
+++ b/libpldmresponder/platform.hpp
@@ -4,6 +4,7 @@
 
 #include "handler.hpp"
 #include "libpldmresponder/pdr.hpp"
+#include "libpldmresponder/pdr_utils.hpp"
 #include "utils.hpp"
 
 #include <stdint.h>
@@ -66,6 +67,7 @@
         const DBusInterface& dBusIntf, effecter::Id effecterId,
         const std::vector<set_effecter_state_field>& stateField)
     {
+        using namespace pldm::responder::pdr;
         using namespace std::string_literals;
         using DBusProperty = std::variant<std::string, bool>;
         using StateSetId = uint16_t;
@@ -89,46 +91,42 @@
         state_effecter_possible_states* states = nullptr;
         pldm_state_effecter_pdr* pdr = nullptr;
         uint8_t compEffecterCnt = stateField.size();
-        uint32_t recordHndl{};
-        Repo& pdrRepo = get(PDR_JSONS_DIR);
-        pdr::Entry pdrEntry{};
 
-        while (!pdr)
+        pdr_utils::Repo repo =
+            getRepoByType(PDR_JSONS_DIR, PLDM_STATE_EFFECTER_PDR);
+        if (repo.empty())
         {
-            pdrEntry = pdrRepo.at(recordHndl);
-            pldm_pdr_hdr* header =
-                reinterpret_cast<pldm_pdr_hdr*>(pdrEntry.data());
-            if (header->type != PLDM_STATE_EFFECTER_PDR)
+            std::cerr << "Failed to get record by PDR type\n";
+            return PLDM_PLATFORM_INVALID_EFFECTER_ID;
+        }
+        PdrEntry pdrEntry{};
+        auto pdrRecord = repo.getFirstRecord(pdrEntry);
+        while (pdrRecord)
+        {
+            pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data);
+            if (pdr->effecter_id != effecterId)
             {
-                recordHndl = pdrRepo.getNextRecordHandle(recordHndl);
-                if (recordHndl)
-                {
-                    continue;
-                }
-                return PLDM_PLATFORM_INVALID_EFFECTER_ID;
+                pdr = nullptr;
+                pdrRecord = repo.getNextRecord(pdrRecord, pdrEntry);
+                continue;
             }
-            pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data());
-            recordHndl = pdr->hdr.record_handle;
-            if (pdr->effecter_id == effecterId)
+
+            states = reinterpret_cast<state_effecter_possible_states*>(
+                pdr->possible_states);
+            if (compEffecterCnt > pdr->composite_effecter_count)
             {
-                states = reinterpret_cast<state_effecter_possible_states*>(
-                    pdr->possible_states);
-                if (compEffecterCnt > pdr->composite_effecter_count)
-                {
-                    std::cerr
-                        << "The requester sent wrong composite effecter"
-                        << " count for the effecter, EFFECTER_ID=" << effecterId
-                        << "COMP_EFF_CNT=" << compEffecterCnt << "\n";
-                    return PLDM_ERROR_INVALID_DATA;
-                }
-                break;
+                std::cerr << "The requester sent wrong composite effecter"
+                          << " count for the effecter, EFFECTER_ID="
+                          << effecterId << "COMP_EFF_CNT=" << compEffecterCnt
+                          << "\n";
+                return PLDM_ERROR_INVALID_DATA;
             }
-            recordHndl = pdrRepo.getNextRecordHandle(recordHndl);
-            if (!recordHndl)
-            {
-                return PLDM_PLATFORM_INVALID_EFFECTER_ID;
-            }
-            pdr = nullptr;
+            break;
+        }
+
+        if (!pdr)
+        {
+            return PLDM_PLATFORM_INVALID_EFFECTER_ID;
         }
 
         std::map<StateSetId, std::function<int(const std::string& objPath,
diff --git a/test/libpldmresponder_pdr_state_effecter_test.cpp b/test/libpldmresponder_pdr_state_effecter_test.cpp
index e758f63..c2b114c 100644
--- a/test/libpldmresponder_pdr_state_effecter_test.cpp
+++ b/test/libpldmresponder_pdr_state_effecter_test.cpp
@@ -1,5 +1,6 @@
 #include "libpldmresponder/effecters.hpp"
 #include "libpldmresponder/pdr.hpp"
+#include "libpldmresponder/pdr_utils.hpp"
 
 #include "libpldm/platform.h"
 
@@ -9,17 +10,19 @@
 
 TEST(GeneratePDR, testGoodJson)
 {
-    using namespace pdr;
     using namespace effecter::dbus_mapping;
-    Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
+    pdr_utils::Repo pdrRepo = pdr::getRepoByType(
+        "./pdr_jsons/state_effecter/good", PLDM_STATE_EFFECTER_PDR);
 
     // 2 entries
-    ASSERT_EQ(pdrRepo.numEntries(), 2);
+    ASSERT_EQ(pdrRepo.getRecordCount(), 2);
 
     // Check first PDR
-    pdr::Entry e = pdrRepo.at(1);
+    pdr_utils::PdrEntry e;
+    auto record1 = pdr::getRecordByHandle(pdrRepo, 1, e);
+    ASSERT_NE(record1, nullptr);
     pldm_state_effecter_pdr* pdr =
-        reinterpret_cast<pldm_state_effecter_pdr*>(e.data());
+        reinterpret_cast<pldm_state_effecter_pdr*>(e.data);
 
     ASSERT_EQ(pdr->hdr.record_handle, 1);
     ASSERT_EQ(pdr->hdr.version, 1);
@@ -48,8 +51,9 @@
     ASSERT_EQ(paths[0], "/foo/bar");
 
     // Check second PDR
-    e = pdrRepo.at(2);
-    pdr = reinterpret_cast<pldm_state_effecter_pdr*>(e.data());
+    auto record2 = pdr::getRecordByHandle(pdrRepo, 2, e);
+    ASSERT_NE(record2, nullptr);
+    pdr = reinterpret_cast<pldm_state_effecter_pdr*>(e.data);
 
     ASSERT_EQ(pdr->hdr.record_handle, 2);
     ASSERT_EQ(pdr->hdr.version, 1);
@@ -91,19 +95,14 @@
 
 TEST(GeneratePDR, testNoJson)
 {
-    using namespace pdr;
-    Repo& pdrRepo = get("./pdr_jsons/not_there");
-
-    ASSERT_EQ(pdrRepo.numEntries(), 2);
+    ASSERT_THROW(pdr_utils::readJson("./pdr_jsons/not_there"), std::exception);
 }
 
 TEST(GeneratePDR, testMalformedJson)
 {
-    using namespace pdr;
-    Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
-    ASSERT_EQ(pdrRepo.numEntries(), 2);
-    pdrRepo.makeEmpty();
-    ASSERT_THROW(pldm::responder::pdr::internal::readJson(
-                     "./pdr_jsons/state_effecter/malformed"),
+    pdr_utils::Repo pdrRepo = pdr::getRepoByType(
+        "./pdr_jsons/state_effecter/good", PLDM_STATE_EFFECTER_PDR);
+    ASSERT_EQ(pdrRepo.getRecordCount(), 2);
+    ASSERT_THROW(pdr_utils::readJson("./pdr_jsons/state_effecter/malformed"),
                  std::exception);
 }
diff --git a/test/libpldmresponder_platform_test.cpp b/test/libpldmresponder_platform_test.cpp
index 208edc3..8252920 100644
--- a/test/libpldmresponder_platform_test.cpp
+++ b/test/libpldmresponder_platform_test.cpp
@@ -1,5 +1,6 @@
 #include "libpldmresponder/effecters.hpp"
 #include "libpldmresponder/pdr.hpp"
+#include "libpldmresponder/pdr_utils.hpp"
 #include "libpldmresponder/platform.hpp"
 
 #include <iostream>
@@ -9,87 +10,76 @@
 #include <gtest/gtest.h>
 
 using namespace pldm::responder;
-using namespace pldm::responder::pdr;
 
 TEST(getPDR, testGoodPath)
 {
     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
         requestPayload{};
-    auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+    auto req = reinterpret_cast<pldm_msg*>(requestPayload.data());
     size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
 
-    uint8_t* start = request->payload;
-    start += sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
-    uint16_t* reqCount = reinterpret_cast<uint16_t*>(start);
-    *reqCount = 100;
-    using namespace pdr;
-    Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
+    struct pldm_get_pdr_req* request =
+        reinterpret_cast<struct pldm_get_pdr_req*>(req->payload);
+    request->request_count = 100;
+
+    pdr_utils::RepoInterface& pdrRepo =
+        pdr::getRepo("./pdr_jsons/state_effecter/good");
     ASSERT_EQ(pdrRepo.empty(), false);
     platform::Handler handler;
-    auto response = handler.getPDR(request, requestPayloadLength);
+    auto response = handler.getPDR(req, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
 
-    ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
-    start = responsePtr->payload;
-    start += sizeof(uint8_t);
-    uint32_t* nextRecordHandle = reinterpret_cast<uint32_t*>(start);
-    ASSERT_EQ(*nextRecordHandle, 2);
-    start += sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
-    uint16_t* recordCount = reinterpret_cast<uint16_t*>(start);
-    ASSERT_EQ(*recordCount != 0, true);
-    start += sizeof(uint16_t);
-    // Check a bit of the PDR common header
-    pldm_state_effecter_pdr* pdr =
-        reinterpret_cast<pldm_state_effecter_pdr*>(start);
-    ASSERT_EQ(pdr->hdr.record_handle, 1);
-    ASSERT_EQ(pdr->hdr.version, 1);
+    struct pldm_get_pdr_resp* resp =
+        reinterpret_cast<struct pldm_get_pdr_resp*>(responsePtr->payload);
+    ASSERT_EQ(PLDM_SUCCESS, resp->completion_code);
+    ASSERT_EQ(2, resp->next_record_handle);
+    ASSERT_EQ(true, resp->response_count != 0);
+
+    pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(resp->record_data);
+    ASSERT_EQ(hdr->record_handle, 1);
+    ASSERT_EQ(hdr->version, 1);
 }
 
 TEST(getPDR, testShortRead)
 {
     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
         requestPayload{};
-    auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+    auto req = reinterpret_cast<pldm_msg*>(requestPayload.data());
     size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
 
-    uint8_t* start = request->payload;
-    start += sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
-    uint16_t* reqCount = reinterpret_cast<uint16_t*>(start);
-    // Read 1 byte of PDR
-    *reqCount = 1;
-    using namespace pdr;
-    Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
+    struct pldm_get_pdr_req* request =
+        reinterpret_cast<struct pldm_get_pdr_req*>(req->payload);
+    request->request_count = 1;
+
+    pdr_utils::RepoInterface& pdrRepo =
+        pdr::getRepo("./pdr_jsons/state_effecter/good");
     ASSERT_EQ(pdrRepo.empty(), false);
     platform::Handler handler;
-    auto response = handler.getPDR(request, requestPayloadLength);
+    auto response = handler.getPDR(req, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
-
-    ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
-    start = responsePtr->payload;
-    start +=
-        sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
-    uint16_t* recordCount = reinterpret_cast<uint16_t*>(start);
-    ASSERT_EQ(*recordCount, 1);
+    struct pldm_get_pdr_resp* resp =
+        reinterpret_cast<struct pldm_get_pdr_resp*>(responsePtr->payload);
+    ASSERT_EQ(PLDM_SUCCESS, resp->completion_code);
+    ASSERT_EQ(1, resp->response_count);
 }
 
 TEST(getPDR, testBadRecordHandle)
 {
     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
         requestPayload{};
-    auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+    auto req = reinterpret_cast<pldm_msg*>(requestPayload.data());
     size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
 
-    uint8_t* start = request->payload;
-    uint32_t* recordHandle = reinterpret_cast<uint32_t*>(start);
-    *recordHandle = 100000;
-    start += sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
-    uint16_t* reqCount = reinterpret_cast<uint16_t*>(start);
-    *reqCount = 1;
-    using namespace pdr;
-    Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
+    struct pldm_get_pdr_req* request =
+        reinterpret_cast<struct pldm_get_pdr_req*>(req->payload);
+    request->record_handle = 100000;
+    request->request_count = 1;
+
+    pdr_utils::RepoInterface& pdrRepo =
+        pdr::getRepo("./pdr_jsons/state_effecter/good");
     ASSERT_EQ(pdrRepo.empty(), false);
     platform::Handler handler;
-    auto response = handler.getPDR(request, requestPayloadLength);
+    auto response = handler.getPDR(req, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
 
     ASSERT_EQ(responsePtr->payload[0], PLDM_PLATFORM_INVALID_RECORD_HANDLE);
@@ -99,73 +89,66 @@
 {
     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
         requestPayload{};
-    auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+    auto req = reinterpret_cast<pldm_msg*>(requestPayload.data());
     size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
 
-    uint8_t* start = request->payload;
-    uint32_t* recordHandle = reinterpret_cast<uint32_t*>(start);
-    *recordHandle = 3;
-    using namespace pdr;
-    Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
+    struct pldm_get_pdr_req* request =
+        reinterpret_cast<struct pldm_get_pdr_req*>(req->payload);
+    request->record_handle = 1;
+
+    pdr_utils::RepoInterface& pdrRepo =
+        pdr::getRepo("./pdr_jsons/state_effecter/good");
     ASSERT_EQ(pdrRepo.empty(), false);
     platform::Handler handler;
-    auto response = handler.getPDR(request, requestPayloadLength);
+    auto response = handler.getPDR(req, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
-
-    ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
-    start = responsePtr->payload;
-    start += sizeof(uint8_t);
-    uint32_t* nextRecordHandle = reinterpret_cast<uint32_t*>(start);
-    ASSERT_EQ(*nextRecordHandle, 0);
+    struct pldm_get_pdr_resp* resp =
+        reinterpret_cast<struct pldm_get_pdr_resp*>(responsePtr->payload);
+    ASSERT_EQ(PLDM_SUCCESS, resp->completion_code);
+    ASSERT_EQ(2, resp->next_record_handle);
 }
 
 TEST(getPDR, testFindPDR)
 {
     std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
         requestPayload{};
-    auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+    auto req = reinterpret_cast<pldm_msg*>(requestPayload.data());
     size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
 
-    uint8_t* start = request->payload;
-    start += sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
-    uint16_t* reqCount = reinterpret_cast<uint16_t*>(start);
-    *reqCount = 100;
-    using namespace pdr;
-    Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
+    struct pldm_get_pdr_req* request =
+        reinterpret_cast<struct pldm_get_pdr_req*>(req->payload);
+    request->request_count = 100;
+
+    pdr_utils::RepoInterface& pdrRepo =
+        pdr::getRepo("./pdr_jsons/state_effecter/good");
     ASSERT_EQ(pdrRepo.empty(), false);
     platform::Handler handler;
-    auto response = handler.getPDR(request, requestPayloadLength);
+    auto response = handler.getPDR(req, requestPayloadLength);
 
     // Let's try to find a PDR of type stateEffecter (= 11) and entity type =
     // 100
     bool found = false;
     uint32_t handle = 0; // start asking for PDRs from recordHandle 0
-    uint32_t* recordHandle = nullptr;
     while (!found)
     {
-        start = request->payload;
-        recordHandle = reinterpret_cast<uint32_t*>(start);
-        *recordHandle = handle;
+        request->record_handle = handle;
         platform::Handler handler;
-        auto response = handler.getPDR(request, requestPayloadLength);
+        auto response = handler.getPDR(req, requestPayloadLength);
         auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+        struct pldm_get_pdr_resp* resp =
+            reinterpret_cast<struct pldm_get_pdr_resp*>(responsePtr->payload);
+        ASSERT_EQ(PLDM_SUCCESS, resp->completion_code);
 
-        ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
-        start = responsePtr->payload;
-        start += sizeof(uint8_t);
-        uint32_t* nextRecordHandle = reinterpret_cast<uint32_t*>(start);
-        handle = *nextRecordHandle; // point to the next pdr in case current is
-                                    // not what we want
-        start += sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t) +
-                 sizeof(uint16_t);
-        pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
-        uint32_t intType = hdr->type;
+        handle = resp->next_record_handle; // point to the next pdr in case
+                                           // current is not what we want
+
+        pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(resp->record_data);
         std::cerr << "PDR next record handle " << handle << "\n";
-        std::cerr << "PDR type " << intType << "\n";
+        std::cerr << "PDR type " << hdr->type << "\n";
         if (hdr->type == PLDM_STATE_EFFECTER_PDR)
         {
             pldm_state_effecter_pdr* pdr =
-                reinterpret_cast<pldm_state_effecter_pdr*>(start);
+                reinterpret_cast<pldm_state_effecter_pdr*>(resp->record_data);
             std::cerr << "PDR entity type " << pdr->entity_type << "\n";
             if (pdr->entity_type == 100)
             {
@@ -174,7 +157,7 @@
                 break;
             }
         }
-        if (!*nextRecordHandle) // no more records
+        if (!resp->next_record_handle) // no more records
         {
             break;
         }
@@ -204,10 +187,13 @@
 
 TEST(setStateEffecterStatesHandler, testGoodRequest)
 {
-    Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
-    pdr::Entry e = pdrRepo.at(1);
+    pdr_utils::Repo pdrRepo = pdr::getRepoByType(
+        "./pdr_jsons/state_effecter/good", PLDM_STATE_EFFECTER_PDR);
+    pdr_utils::PdrEntry e;
+    auto record1 = pdr::getRecordByHandle(pdrRepo, 1, e);
+    ASSERT_NE(record1, nullptr);
     pldm_state_effecter_pdr* pdr =
-        reinterpret_cast<pldm_state_effecter_pdr*>(e.data());
+        reinterpret_cast<pldm_state_effecter_pdr*>(e.data);
     EXPECT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR);
 
     std::vector<set_effecter_state_field> stateField;
@@ -232,10 +218,13 @@
 
 TEST(setStateEffecterStatesHandler, testBadRequest)
 {
-    Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
-    pdr::Entry e = pdrRepo.at(1);
+    pdr_utils::Repo pdrRepo = pdr::getRepoByType(
+        "./pdr_jsons/state_effecter/good", PLDM_STATE_EFFECTER_PDR);
+    pdr_utils::PdrEntry e;
+    auto record1 = pdr::getRecordByHandle(pdrRepo, 1, e);
+    ASSERT_NE(record1, nullptr);
     pldm_state_effecter_pdr* pdr =
-        reinterpret_cast<pldm_state_effecter_pdr*>(e.data());
+        reinterpret_cast<pldm_state_effecter_pdr*>(e.data);
     EXPECT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR);
 
     std::vector<set_effecter_state_field> stateField;