implement async handlers for all requester commands

this commit makes use of 74f27c730ef3925a0f2a3adfaa04f8790f931372 to
convert the existing blocking requester commands in pldm to async
ones.
this is tested with Host code and seems to work fine

Change-Id: I8d4762c3cd5bce49f854b30f8325bfcd1dcb4ff9
Signed-off-by: Sampa Misra <sampmisr@in.ibm.com>
diff --git a/host-bmc/dbus_to_event_handler.cpp b/host-bmc/dbus_to_event_handler.cpp
index ac8778f..bb38cb8 100644
--- a/host-bmc/dbus_to_event_handler.cpp
+++ b/host-bmc/dbus_to_event_handler.cpp
@@ -15,10 +15,11 @@
 {
 const std::vector<uint8_t> pdrTypes{PLDM_STATE_SENSOR_PDR};
 
-DbusToPLDMEvent::DbusToPLDMEvent(int mctp_fd, uint8_t mctp_eid,
-                                 Requester& requester) :
+DbusToPLDMEvent::DbusToPLDMEvent(
+    int mctp_fd, uint8_t mctp_eid, Requester& requester,
+    pldm::requester::Handler<pldm::requester::Request>* handler) :
     mctp_fd(mctp_fd),
-    mctp_eid(mctp_eid), requester(requester)
+    mctp_eid(mctp_eid), requester(requester), handler(handler)
 {}
 
 void DbusToPLDMEvent::sendEventMsg(uint8_t eventType,
@@ -42,36 +43,34 @@
         return;
     }
 
-    uint8_t* responseMsg = nullptr;
-    size_t responseMsgSize{};
+    auto platformEventMessageResponseHandler = [](mctp_eid_t /*eid*/,
+                                                  const pldm_msg* response,
+                                                  size_t respMsgLen) {
+        if (response == nullptr || !respMsgLen)
+        {
+            std::cerr
+                << "Failed to receive response for platform event message \n";
+            return;
+        }
+        uint8_t completionCode{};
+        uint8_t status{};
+        auto rc = decode_platform_event_message_resp(response, respMsgLen,
+                                                     &completionCode, &status);
+        if (rc || completionCode)
+        {
+            std::cerr << "Failed to decode_platform_event_message_resp: "
+                      << "rc=" << rc
+                      << ", cc=" << static_cast<unsigned>(completionCode)
+                      << std::endl;
+        }
+    };
 
-    auto requesterRc =
-        pldm_send_recv(mctp_eid, mctp_fd, requestMsg.data(), requestMsg.size(),
-                       &responseMsg, &responseMsgSize);
-    std::unique_ptr<uint8_t, decltype(std::free)*> responseMsgPtr{responseMsg,
-                                                                  std::free};
-
-    requester.markFree(mctp_eid, instanceId);
-    if (requesterRc != PLDM_REQUESTER_SUCCESS)
+    rc = handler->registerRequest(
+        mctp_eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE,
+        std::move(requestMsg), std::move(platformEventMessageResponseHandler));
+    if (rc)
     {
-        std::cerr
-            << "Failed to send msg to report state sensor event changes, rc = "
-            << requesterRc << std::endl;
-        return;
-    }
-    uint8_t completionCode{};
-    uint8_t status{};
-    auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsgPtr.get());
-    rc = decode_platform_event_message_resp(
-        responsePtr, responseMsgSize - sizeof(pldm_msg_hdr), &completionCode,
-        &status);
-
-    if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
-    {
-        std::cerr << "Failed to decode_platform_event_message_resp: "
-                  << "rc=" << rc
-                  << ", cc=" << static_cast<unsigned>(completionCode)
-                  << std::endl;
+        std::cerr << "Failed to send the platform event message \n";
     }
 }
 
diff --git a/host-bmc/dbus_to_event_handler.hpp b/host-bmc/dbus_to_event_handler.hpp
index add5c2d..2a25243 100644
--- a/host-bmc/dbus_to_event_handler.hpp
+++ b/host-bmc/dbus_to_event_handler.hpp
@@ -4,6 +4,7 @@
 
 #include "libpldmresponder/pdr_utils.hpp"
 #include "pldmd/dbus_impl_requester.hpp"
+#include "requester/handler.hpp"
 
 #include <map>
 
@@ -40,9 +41,11 @@
      *  @param[in] mctp_fd - fd of MCTP communications socket
      *  @param[in] mctp_eid - MCTP EID of host firmware
      *  @param[in] requester - reference to Requester object
+     *  @param[in] handler - PLDM request handler
      */
-    explicit DbusToPLDMEvent(int mctp_fd, uint8_t mctp_eid,
-                             Requester& requester);
+    explicit DbusToPLDMEvent(
+        int mctp_fd, uint8_t mctp_eid, Requester& requester,
+        pldm::requester::Handler<pldm::requester::Request>* handler);
 
   public:
     /** @brief Listen all of the state sensor PDRs
@@ -79,6 +82,9 @@
     /** @brief D-Bus property changed signal match */
     std::vector<std::unique_ptr<sdbusplus::bus::match::match>>
         stateSensorMatchs;
+
+    /** @brief PLDM request handler */
+    pldm::requester::Handler<pldm::requester::Request>* handler;
 };
 
 } // namespace state_sensor
diff --git a/host-bmc/dbus_to_host_effecters.cpp b/host-bmc/dbus_to_host_effecters.cpp
index 4bdeda5..6dff8af 100644
--- a/host-bmc/dbus_to_host_effecters.cpp
+++ b/host-bmc/dbus_to_host_effecters.cpp
@@ -280,42 +280,40 @@
             std::cout << tempStream.str() << std::endl;
         }
     }
+    auto setStateEffecterStatesRespHandler =
+        [](mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
+            if (response == nullptr || !respMsgLen)
+            {
+                std::cerr << "Failed to receive response for "
+                          << "setStateEffecterStates command \n";
+                return;
+            }
+            uint8_t completionCode{};
+            auto rc = decode_set_state_effecter_states_resp(
+                response, respMsgLen, &completionCode);
+            if (rc)
+            {
+                std::cerr << "Failed to decode setStateEffecterStates response,"
+                          << " rc " << rc << "\n";
+                pldm::utils::reportError(
+                    "xyz.openbmc_project.bmc.pldm.SetHostEffecterFailed");
+            }
+            if (completionCode)
+            {
+                std::cerr << "Failed to set a Host effecter "
+                          << ", cc=" << static_cast<unsigned>(completionCode)
+                          << "\n";
+                pldm::utils::reportError(
+                    "xyz.openbmc_project.bmc.pldm.SetHostEffecterFailed");
+            }
+        };
 
-    uint8_t* responseMsg = nullptr;
-    size_t responseMsgSize{};
-
-    rc = pldm_send_recv(mctpEid, sockFd, requestMsg.data(), requestMsg.size(),
-                        &responseMsg, &responseMsgSize);
-    std::unique_ptr<uint8_t, decltype(std::free)*> responseMsgPtr{responseMsg,
-                                                                  std::free};
-    requester->markFree(mctpEid, instanceId);
-
-    if (rc != PLDM_REQUESTER_SUCCESS)
+    rc = handler->registerRequest(
+        mctpEid, instanceId, PLDM_PLATFORM, PLDM_SET_STATE_EFFECTER_STATES,
+        std::move(requestMsg), std::move(setStateEffecterStatesRespHandler));
+    if (rc)
     {
-        std::cerr << "Failed to send message/receive response. RC = " << rc
-                  << ", errno = " << errno << " for setting host effecter "
-                  << effecterId << "\n";
-        pldm::utils::reportError(
-            "xyz.openbmc_project.bmc.pldm.InternalFailure");
-        return rc;
-    }
-    auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsgPtr.get());
-    uint8_t completionCode{};
-    rc = decode_set_state_effecter_states_resp(
-        responsePtr, responseMsgSize - sizeof(pldm_msg_hdr), &completionCode);
-    if (rc != PLDM_SUCCESS)
-    {
-        std::cerr << "Failed to decode setStateEffecterStates response, rc = "
-                  << rc << "\n";
-        return rc;
-    }
-    if (completionCode != PLDM_SUCCESS)
-    {
-        std::cerr << "Failed setStateEffecterStates for effecter " << effecterId
-                  << ". Response from Host " << (uint32_t)completionCode
-                  << "\n";
-        pldm::utils::reportError(
-            "xyz.openbmc_project.bmc.pldm.InternalFailure");
+        std::cerr << "Failed to send request to set an effecter on Host \n";
     }
     return rc;
 }
diff --git a/host-bmc/dbus_to_host_effecters.hpp b/host-bmc/dbus_to_host_effecters.hpp
index d024ed6..9c0314d 100644
--- a/host-bmc/dbus_to_host_effecters.hpp
+++ b/host-bmc/dbus_to_host_effecters.hpp
@@ -3,6 +3,7 @@
 #include "common/types.hpp"
 #include "common/utils.hpp"
 #include "pldmd/dbus_impl_requester.hpp"
+#include "requester/handler.hpp"
 
 #include <string>
 #include <utility>
@@ -75,15 +76,17 @@
      *  @param[in] repo -  PLDM PDR repository
      *  @param[in] dbusHandler - D-bus Handler
      *  @param[in] jsonPath - path for the json file
+     *  @param[in] handler - PLDM request handler
      *  @param[in] verbose - verbosity
      */
-    explicit HostEffecterParser(Requester* requester, int fd,
-                                const pldm_pdr* repo,
-                                DBusHandler* const dbusHandler,
-                                const std::string& jsonPath,
-                                bool verbose = false) :
+    explicit HostEffecterParser(
+        Requester* requester, int fd, const pldm_pdr* repo,
+        DBusHandler* const dbusHandler, const std::string& jsonPath,
+        pldm::requester::Handler<pldm::requester::Request>* handler,
+        bool verbose = false) :
         requester(requester),
-        sockFd(fd), pdrRepo(repo), dbusHandler(dbusHandler), verbose(verbose)
+        sockFd(fd), pdrRepo(repo), dbusHandler(dbusHandler), handler(handler),
+        verbose(verbose)
     {
         try
         {
@@ -175,7 +178,9 @@
         effecterInfoMatch; //!< vector to catch the D-Bus property change
                            //!< signals for the effecters
     const DBusHandler* dbusHandler; //!< D-bus Handler
-    bool verbose;                   //!< verbose flag
+    /** @brief PLDM request handler */
+    pldm::requester::Handler<pldm::requester::Request>* handler;
+    bool verbose; //!< verbose flag
 };
 
 } // namespace host_effecters
diff --git a/host-bmc/host_pdr_handler.cpp b/host-bmc/host_pdr_handler.cpp
index 4c5a9a4..f9d30b5 100644
--- a/host-bmc/host_pdr_handler.cpp
+++ b/host-bmc/host_pdr_handler.cpp
@@ -25,7 +25,7 @@
     int mctp_fd, uint8_t mctp_eid, sdeventplus::Event& event, pldm_pdr* repo,
     const std::string& eventsJsonsDir, pldm_entity_association_tree* entityTree,
     pldm_entity_association_tree* bmcEntityTree, Requester& requester,
-    pldm::requester::Handler<pldm::requester::Request>& handler, bool verbose) :
+    pldm::requester::Handler<pldm::requester::Request>* handler, bool verbose) :
     mctp_fd(mctp_fd),
     mctp_eid(mctp_eid), event(event), repo(repo),
     stateSensorHandler(eventsJsonsDir), entityTree(entityTree),
@@ -107,151 +107,53 @@
 
 void HostPDRHandler::_fetchPDR(sdeventplus::source::EventBase& /*source*/)
 {
+    getHostPDR();
+}
+
+void HostPDRHandler::getHostPDR(uint32_t nextRecordHandle)
+{
     pdrFetchEvent.reset();
 
     std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
                                     PLDM_GET_PDR_REQ_BYTES);
     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
-    bool merged = false;
-    PDRList stateSensorPDRs{};
-    TLPDRMap tlpdrInfo{};
-
-    uint32_t nextRecordHandle{};
     uint32_t recordHandle{};
-    bool isFormatRecHandles = false;
-    if (!pdrRecordHandles.empty())
+    if (!nextRecordHandle)
     {
-        recordHandle = pdrRecordHandles.front();
-        pdrRecordHandles.pop_front();
-        isFormatRecHandles = true;
+        if (!pdrRecordHandles.empty())
+        {
+            recordHandle = pdrRecordHandles.front();
+            pdrRecordHandles.pop_front();
+        }
+    }
+    else
+    {
+        recordHandle = nextRecordHandle;
+    }
+    auto instanceId = requester.getInstanceId(mctp_eid);
+
+    auto rc =
+        encode_get_pdr_req(instanceId, recordHandle, 0, PLDM_GET_FIRSTPART,
+                           UINT16_MAX, 0, request, PLDM_GET_PDR_REQ_BYTES);
+    if (rc != PLDM_SUCCESS)
+    {
+        requester.markFree(mctp_eid, instanceId);
+        std::cerr << "Failed to encode_get_pdr_req, rc = " << rc << std::endl;
+        return;
+    }
+    if (verbose)
+    {
+        std::cout << "Sending Msg:" << std::endl;
+        printBuffer(requestMsg, verbose);
     }
 
-    do
+    rc = handler->registerRequest(
+        mctp_eid, instanceId, PLDM_PLATFORM, PLDM_GET_PDR,
+        std::move(requestMsg),
+        std::move(std::bind_front(&HostPDRHandler::processHostPDRs, this)));
+    if (rc)
     {
-        auto instanceId = requester.getInstanceId(mctp_eid);
-
-        auto rc =
-            encode_get_pdr_req(instanceId, recordHandle, 0, PLDM_GET_FIRSTPART,
-                               UINT16_MAX, 0, request, PLDM_GET_PDR_REQ_BYTES);
-        if (rc != PLDM_SUCCESS)
-        {
-            requester.markFree(mctp_eid, instanceId);
-            std::cerr << "Failed to encode_get_pdr_req, rc = " << rc
-                      << std::endl;
-            return;
-        }
-        if (verbose)
-        {
-            std::cout << "Sending Msg:" << std::endl;
-            printBuffer(requestMsg, verbose);
-        }
-
-        uint8_t* responseMsg = nullptr;
-        size_t responseMsgSize{};
-        auto requesterRc =
-            pldm_send_recv(mctp_eid, mctp_fd, requestMsg.data(),
-                           requestMsg.size(), &responseMsg, &responseMsgSize);
-        std::unique_ptr<uint8_t, decltype(std::free)*> responseMsgPtr{
-            responseMsg, std::free};
-        requester.markFree(mctp_eid, instanceId);
-        if (requesterRc != PLDM_REQUESTER_SUCCESS)
-        {
-            std::cerr << "Failed to send msg to fetch pdrs, rc = "
-                      << requesterRc << std::endl;
-            return;
-        }
-
-        uint8_t completionCode{};
-        uint32_t nextDataTransferHandle{};
-        uint8_t transferFlag{};
-        uint16_t respCount{};
-        uint8_t transferCRC{};
-        auto responsePtr =
-            reinterpret_cast<struct pldm_msg*>(responseMsgPtr.get());
-        rc = decode_get_pdr_resp(
-            responsePtr, responseMsgSize - sizeof(pldm_msg_hdr),
-            &completionCode, &nextRecordHandle, &nextDataTransferHandle,
-            &transferFlag, &respCount, nullptr, 0, &transferCRC);
-
-        std::vector<uint8_t> responsePDRMsg;
-        responsePDRMsg.resize(responseMsgSize);
-        memcpy(responsePDRMsg.data(), responsePtr, responsePDRMsg.size());
-        if (verbose)
-        {
-            std::cout << "Receiving Msg:" << std::endl;
-            printBuffer(responsePDRMsg, verbose);
-        }
-        if (rc != PLDM_SUCCESS)
-        {
-            std::cerr << "Failed to decode_get_pdr_resp, rc = " << rc
-                      << std::endl;
-        }
-        else
-        {
-            std::vector<uint8_t> pdr(respCount, 0);
-            rc = decode_get_pdr_resp(
-                responsePtr, responseMsgSize - sizeof(pldm_msg_hdr),
-                &completionCode, &nextRecordHandle, &nextDataTransferHandle,
-                &transferFlag, &respCount, pdr.data(), respCount, &transferCRC);
-            if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
-            {
-                std::cerr << "Failed to decode_get_pdr_resp: "
-                          << "rc=" << rc
-                          << ", cc=" << static_cast<unsigned>(completionCode)
-                          << std::endl;
-            }
-            else
-            {
-                // Process the PDR host firmware sent us. The most common action
-                // is to add the PDR to the the BMC's PDR repo.
-                auto pdrHdr = reinterpret_cast<pldm_pdr_hdr*>(pdr.data());
-                if (pdrHdr->type == PLDM_PDR_ENTITY_ASSOCIATION)
-                {
-                    mergeEntityAssociations(pdr);
-                    merged = true;
-                }
-                else
-                {
-                    if (pdrHdr->type == PLDM_TERMINUS_LOCATOR_PDR)
-                    {
-                        auto tlpdr =
-                            reinterpret_cast<const pldm_terminus_locator_pdr*>(
-                                pdr.data());
-                        tlpdrInfo.emplace(
-                            static_cast<pdr::TerminusHandle>(
-                                tlpdr->terminus_handle),
-                            static_cast<pdr::TerminusID>(tlpdr->tid));
-                    }
-                    else if (pdrHdr->type == PLDM_STATE_SENSOR_PDR)
-                    {
-                        stateSensorPDRs.emplace_back(pdr);
-                    }
-                    pldm_pdr_add(repo, pdr.data(), respCount, 0, true);
-                }
-            }
-
-            recordHandle = nextRecordHandle;
-            if (!pdrRecordHandles.empty())
-            {
-                recordHandle = pdrRecordHandles.front();
-                pdrRecordHandles.pop_front();
-            }
-            else if (isFormatRecHandles)
-            {
-                break;
-            }
-        }
-    } while (recordHandle);
-
-    parseStateSensorPDRs(stateSensorPDRs, tlpdrInfo);
-
-    if (merged)
-    {
-        // We have merged host's entity association PDRs with our own. Send an
-        // event to the host firmware to indicate the same.
-        sendPDRRepositoryChgEvent(
-            std::move(std::vector<uint8_t>(1, PLDM_PDR_ENTITY_ASSOCIATION)),
-            FORMAT_IS_PDR_HANDLES);
+        std::cerr << "Failed to send the GetPDR request to Host \n";
     }
 }
 
@@ -400,7 +302,7 @@
         auto rc = decode_platform_event_message_resp(
             responsePtr, respMsgLen - sizeof(pldm_msg_hdr), &completionCode,
             &status);
-        if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
+        if (rc || completionCode)
         {
             std::cerr << "Failed to decode_platform_event_message_resp: "
                       << "rc=" << rc
@@ -409,10 +311,10 @@
         }
     };
 
-    rc = handler.registerRequest(
+    rc = handler->registerRequest(
         mctp_eid, instanceId, PLDM_PLATFORM, PLDM_PDR_REPOSITORY_CHG_EVENT,
         std::move(requestMsg), std::move(platformEventMessageResponseHandler));
-    if (rc != PLDM_SUCCESS)
+    if (rc)
     {
         std::cerr << "Failed to send the PDR repository changed event request"
                   << "\n";
@@ -442,4 +344,131 @@
     }
 }
 
+void HostPDRHandler::processHostPDRs(mctp_eid_t /*eid*/,
+                                     const pldm_msg* response,
+                                     size_t respMsgLen)
+{
+    static bool merged = false;
+    static PDRList stateSensorPDRs{};
+    static TLPDRMap tlpdrInfo{};
+    uint32_t nextRecordHandle{};
+    uint8_t completionCode{};
+    uint32_t nextDataTransferHandle{};
+    uint8_t transferFlag{};
+    uint16_t respCount{};
+    uint8_t transferCRC{};
+    if (response == nullptr || !respMsgLen)
+    {
+        std::cerr << "Failed to receive response for the GetPDR"
+                     " command \n";
+        return;
+    }
+
+    auto rc = decode_get_pdr_resp(
+        response, respMsgLen /*- sizeof(pldm_msg_hdr)*/, &completionCode,
+        &nextRecordHandle, &nextDataTransferHandle, &transferFlag, &respCount,
+        nullptr, 0, &transferCRC);
+    std::vector<uint8_t> responsePDRMsg;
+    responsePDRMsg.resize(respMsgLen + sizeof(pldm_msg_hdr));
+    memcpy(responsePDRMsg.data(), response, respMsgLen + sizeof(pldm_msg_hdr));
+    if (verbose)
+    {
+        std::cout << "Receiving Msg:" << std::endl;
+        printBuffer(responsePDRMsg, verbose);
+    }
+    if (rc != PLDM_SUCCESS)
+    {
+        std::cerr << "Failed to decode_get_pdr_resp, rc = " << rc << std::endl;
+        return;
+    }
+    else
+    {
+        std::vector<uint8_t> pdr(respCount, 0);
+        rc = decode_get_pdr_resp(response, respMsgLen, &completionCode,
+                                 &nextRecordHandle, &nextDataTransferHandle,
+                                 &transferFlag, &respCount, pdr.data(),
+                                 respCount, &transferCRC);
+        if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
+        {
+            std::cerr << "Failed to decode_get_pdr_resp: "
+                      << "rc=" << rc
+                      << ", cc=" << static_cast<unsigned>(completionCode)
+                      << std::endl;
+            return;
+        }
+        else
+        {
+            auto pdrHdr = reinterpret_cast<pldm_pdr_hdr*>(pdr.data());
+            if (pdrHdr->type == PLDM_PDR_ENTITY_ASSOCIATION)
+            {
+                this->mergeEntityAssociations(pdr);
+                merged = true;
+            }
+            else
+            {
+                if (pdrHdr->type == PLDM_TERMINUS_LOCATOR_PDR)
+                {
+                    auto tlpdr =
+                        reinterpret_cast<const pldm_terminus_locator_pdr*>(
+                            pdr.data());
+                    tlpdrInfo.emplace(
+                        static_cast<pldm::pdr::TerminusHandle>(
+                            tlpdr->terminus_handle),
+                        static_cast<pldm::pdr::TerminusID>(tlpdr->tid));
+                }
+                else if (pdrHdr->type == PLDM_STATE_SENSOR_PDR)
+                {
+                    stateSensorPDRs.emplace_back(pdr);
+                }
+                pldm_pdr_add(repo, pdr.data(), respCount, 0, true);
+            }
+        }
+    }
+    if (!nextRecordHandle)
+    {
+        /*received last record*/
+        this->parseStateSensorPDRs(stateSensorPDRs, tlpdrInfo);
+        stateSensorPDRs.clear();
+        tlpdrInfo.clear();
+        if (merged)
+        {
+            merged = false;
+            deferredPDRRepoChgEvent =
+                std::make_unique<sdeventplus::source::Defer>(
+                    event,
+                    std::bind(
+                        std::mem_fn((&HostPDRHandler::_processPDRRepoChgEvent)),
+                        this, std::placeholders::_1));
+        }
+    }
+    else
+    {
+        deferredFetchPDREvent = std::make_unique<sdeventplus::source::Defer>(
+            event,
+            std::bind(std::mem_fn((&HostPDRHandler::_processFetchPDREvent)),
+                      this, nextRecordHandle, std::placeholders::_1));
+    }
+}
+
+void HostPDRHandler::_processPDRRepoChgEvent(
+    sdeventplus::source::EventBase& /*source */)
+{
+    deferredPDRRepoChgEvent.reset();
+    this->sendPDRRepositoryChgEvent(
+        std::move(std::vector<uint8_t>(1, PLDM_PDR_ENTITY_ASSOCIATION)),
+        FORMAT_IS_PDR_HANDLES);
+}
+
+void HostPDRHandler::_processFetchPDREvent(
+    uint32_t nextRecordHandle, sdeventplus::source::EventBase& /*source */)
+{
+    deferredFetchPDREvent.reset();
+    if (!this->pdrRecordHandles.empty())
+    {
+        nextRecordHandle = this->pdrRecordHandles.front();
+        this->pdrRecordHandles.pop_front();
+    }
+    this->getHostPDR(nextRecordHandle);
+}
+
 } // namespace pldm
diff --git a/host-bmc/host_pdr_handler.hpp b/host-bmc/host_pdr_handler.hpp
index 5ca8f91..2e0d331 100644
--- a/host-bmc/host_pdr_handler.hpp
+++ b/host-bmc/host_pdr_handler.hpp
@@ -93,7 +93,7 @@
         pldm_pdr* repo, const std::string& eventsJsonsDir,
         pldm_entity_association_tree* entityTree,
         pldm_entity_association_tree* bmcEntityTree, Requester& requester,
-        pldm::requester::Handler<pldm::requester::Request>& handler,
+        pldm::requester::Handler<pldm::requester::Request>* handler,
         bool verbose = false);
 
     /** @brief fetch PDRs from host firmware. See @class.
@@ -145,12 +145,19 @@
                               const TLPDRMap& tlpdrInfo);
 
   private:
-    /** @brief fetchPDR schedules work on the event loop, this method does the
-     *  actual work. This is so that the PDR exchg with the host is async.
+    /** @brief deferred function to fetch PDR from Host, scheduled to work on
+     *  the event loop. The PDR exchg with the host is async.
      *  @param[in] source - sdeventplus event source
      */
     void _fetchPDR(sdeventplus::source::EventBase& source);
 
+    /** @brief this function sends a GetPDR request to Host firmware.
+     *  And processes the PDRs based on type
+     *
+     *  @param[in] - nextRecordHandle - the next record handle to ask for
+     */
+    void getHostPDR(uint32_t nextRecordHandle = 0);
+
     /** @brief Merge host firmware's entity association PDRs into BMC's
      *  @details A merge operation involves adding a pldm_entity under the
      *  appropriate parent, and updating container ids.
@@ -166,6 +173,26 @@
      */
     bool getParent(EntityType type, pldm_entity& parent);
 
+    /** @brief process the Host's PDR and add to BMC's PDR repo
+     *  @param[in] eid - MCTP id of Host
+     *  @param[in] response - response from Host for GetPDR
+     *  @param[in] respMsgLen - response message length
+     */
+    void processHostPDRs(mctp_eid_t eid, const pldm_msg* response,
+                         size_t respMsgLen);
+
+    /** @brief send PDR Repo change after merging Host's PDR to BMC PDR repo
+     *  @param[in] source - sdeventplus event source
+     */
+    void _processPDRRepoChgEvent(sdeventplus::source::EventBase& source);
+
+    /** @brief fetch the next PDR based on the record handle sent by Host
+     *  @param[in] nextRecordHandle - next record handle
+     *  @param[in] source - sdeventplus event source
+     */
+    void _processFetchPDREvent(uint32_t nextRecordHandle,
+                               sdeventplus::source::EventBase& source);
+
     /** @brief fd of MCTP communications socket */
     int mctp_fd;
     /** @brief MCTP EID of host firmware */
@@ -190,10 +217,13 @@
     Requester& requester;
 
     /** @brief PLDM request handler */
-    pldm::requester::Handler<pldm::requester::Request>& handler;
+    pldm::requester::Handler<pldm::requester::Request>* handler;
 
     /** @brief sdeventplus event source */
     std::unique_ptr<sdeventplus::source::Defer> pdrFetchEvent;
+    std::unique_ptr<sdeventplus::source::Defer> deferredFetchPDREvent;
+    std::unique_ptr<sdeventplus::source::Defer> deferredPDRRepoChgEvent;
+
     /** @brief list of PDR record handles pointing to host's PDRs */
     PDRRecordHandles pdrRecordHandles;
     /** @brief maps an entity type to parent pldm_entity from the BMC's entity
diff --git a/host-bmc/test/dbus_to_host_effecter_test.cpp b/host-bmc/test/dbus_to_host_effecter_test.cpp
index 72b820d..76025eb 100644
--- a/host-bmc/test/dbus_to_host_effecter_test.cpp
+++ b/host-bmc/test/dbus_to_host_effecter_test.cpp
@@ -18,7 +18,7 @@
     MockHostEffecterParser(int fd, const pldm_pdr* repo,
                            DBusHandler* const dbusHandler,
                            const std::string& jsonPath) :
-        HostEffecterParser(nullptr, fd, repo, dbusHandler, jsonPath)
+        HostEffecterParser(nullptr, fd, repo, dbusHandler, jsonPath, nullptr)
     {}
 
     MOCK_METHOD(void, setHostStateEffecter,
diff --git a/host-bmc/test/meson.build b/host-bmc/test/meson.build
index 2254a3a..c7f0532 100644
--- a/host-bmc/test/meson.build
+++ b/host-bmc/test/meson.build
@@ -2,7 +2,8 @@
           sources: [
             '../dbus_to_host_effecters.cpp',
             '../../pldmd/dbus_impl_requester.cpp',
-            '../../pldmd/instance_id.cpp'])
+            '../../pldmd/instance_id.cpp'],
+            include_directories: '../../requester')
 
 tests = [
   'dbus_to_host_effecter_test',
@@ -20,6 +21,7 @@
                          libpldm_dep,
                          libpldmutils,
                          phosphor_dbus_interfaces,
-                         sdbusplus]),
+                         sdbusplus,
+                         sdeventplus]),
        workdir: meson.current_source_dir())
 endforeach
diff --git a/libpldmresponder/bios.cpp b/libpldmresponder/bios.cpp
index fbe6144..e7d4c5e 100644
--- a/libpldmresponder/bios.cpp
+++ b/libpldmresponder/bios.cpp
@@ -67,9 +67,10 @@
 
 DBusHandler dbusHandler;
 
-Handler::Handler(int fd, uint8_t eid, dbus_api::Requester* requester) :
+Handler::Handler(int fd, uint8_t eid, dbus_api::Requester* requester,
+                 pldm::requester::Handler<pldm::requester::Request>* handler) :
     biosConfig(BIOS_JSONS_DIR, BIOS_TABLES_DIR, &dbusHandler, fd, eid,
-               requester)
+               requester, handler)
 {
     biosConfig.removeTables();
     biosConfig.buildTables();
diff --git a/libpldmresponder/bios.hpp b/libpldmresponder/bios.hpp
index 2fbf8ab..3ec3a57 100644
--- a/libpldmresponder/bios.hpp
+++ b/libpldmresponder/bios.hpp
@@ -9,6 +9,7 @@
 #include "bios_table.hpp"
 #include "pldmd/dbus_impl_requester.hpp"
 #include "pldmd/handler.hpp"
+#include "requester/handler.hpp"
 
 #include <stdint.h>
 
@@ -34,8 +35,10 @@
      *  @param[in] fd - socket descriptor to communicate to host
      *  @param[in] eid - MCTP EID of host firmware
      *  @param[in] requester - pointer to Requester object
+     *  @param[in] handler - PLDM request handler
      */
-    Handler(int fd, uint8_t eid, dbus_api::Requester* requester);
+    Handler(int fd, uint8_t eid, dbus_api::Requester* requester,
+            pldm::requester::Handler<pldm::requester::Request>* handler);
 
     /** @brief Handler for GetDateTime
      *
diff --git a/libpldmresponder/bios_config.cpp b/libpldmresponder/bios_config.cpp
index c7c408e..b538cf1 100644
--- a/libpldmresponder/bios_config.cpp
+++ b/libpldmresponder/bios_config.cpp
@@ -37,12 +37,13 @@
 
 } // namespace
 
-BIOSConfig::BIOSConfig(const char* jsonDir, const char* tableDir,
-                       DBusHandler* const dbusHandler, int fd, uint8_t eid,
-                       dbus_api::Requester* requester) :
+BIOSConfig::BIOSConfig(
+    const char* jsonDir, const char* tableDir, DBusHandler* const dbusHandler,
+    int fd, uint8_t eid, dbus_api::Requester* requester,
+    pldm::requester::Handler<pldm::requester::Request>* handler) :
     jsonDir(jsonDir),
     tableDir(tableDir), dbusHandler(dbusHandler), fd(fd), eid(eid),
-    requester(requester)
+    requester(requester), handler(handler)
 
 {
     fs::create_directories(tableDir);
@@ -924,7 +925,7 @@
     {
 #ifdef OEM_IBM
         auto rc = pldm::responder::platform::sendBiosAttributeUpdateEvent(
-            fd, eid, requester, listOfHandles);
+            eid, requester, listOfHandles, handler);
         if (rc != PLDM_SUCCESS)
         {
             return;
diff --git a/libpldmresponder/bios_config.hpp b/libpldmresponder/bios_config.hpp
index a6ae3e7..8477628 100644
--- a/libpldmresponder/bios_config.hpp
+++ b/libpldmresponder/bios_config.hpp
@@ -5,6 +5,7 @@
 #include "bios_attribute.hpp"
 #include "bios_table.hpp"
 #include "pldmd/dbus_impl_requester.hpp"
+#include "requester/handler.hpp"
 
 #include <nlohmann/json.hpp>
 
@@ -72,10 +73,13 @@
      *  @param[in] fd - socket descriptor to communicate to host
      *  @param[in] eid - MCTP EID of host firmware
      *  @param[in] requester - pointer to Requester object
+     *  @param[in] handler - PLDM request handler
      */
-    explicit BIOSConfig(const char* jsonDir, const char* tableDir,
-                        DBusHandler* const dbusHandler, int fd, uint8_t eid,
-                        dbus_api::Requester* requester);
+    explicit BIOSConfig(
+        const char* jsonDir, const char* tableDir,
+        DBusHandler* const dbusHandler, int fd, uint8_t eid,
+        dbus_api::Requester* requester,
+        pldm::requester::Handler<pldm::requester::Request>* handler);
 
     /** @brief Set attribute value on dbus and attribute value table
      *  @param[in] entry - attribute value entry
@@ -144,6 +148,9 @@
      */
     dbus_api::Requester* requester;
 
+    /** @brief PLDM request handler */
+    pldm::requester::Handler<pldm::requester::Request>* handler;
+
     // vector persists all attributes
     using BIOSAttributes = std::vector<std::unique_ptr<BIOSAttribute>>;
     BIOSAttributes biosAttributes;
diff --git a/libpldmresponder/test/libpldmresponder_bios_config_test.cpp b/libpldmresponder/test/libpldmresponder_bios_config_test.cpp
index 25300ca..00ec927 100644
--- a/libpldmresponder/test/libpldmresponder_bios_config_test.cpp
+++ b/libpldmresponder/test/libpldmresponder_bios_config_test.cpp
@@ -80,7 +80,7 @@
         .WillByDefault(Throw(std::exception()));
 
     BIOSConfig biosConfig("./bios_jsons", tableDir.c_str(), &dbusHandler, 0, 0,
-                          nullptr);
+                          nullptr, nullptr);
     biosConfig.buildTables();
 
     auto stringTable = biosConfig.getBIOSTable(PLDM_BIOS_STRING_TABLE);
@@ -249,7 +249,7 @@
     MockdBusHandler dbusHandler;
 
     BIOSConfig biosConfig("./bios_jsons", tableDir.c_str(), &dbusHandler, 0, 0,
-                          nullptr);
+                          nullptr, nullptr);
     biosConfig.removeTables();
     biosConfig.buildTables();
 
diff --git a/libpldmresponder/test/meson.build b/libpldmresponder/test/meson.build
index 623e28e..49e5a23 100644
--- a/libpldmresponder/test/meson.build
+++ b/libpldmresponder/test/meson.build
@@ -24,7 +24,7 @@
   '../../pldmd/instance_id.cpp',
   '../../pldmd/dbus_impl_requester.cpp'
   ]
-dep_src = declare_dependency(sources: dep_src_files)
+dep_src = declare_dependency(sources: dep_src_files,include_directories: '../../requester')
 
 foreach t : tests
   test(t, executable(t.underscorify(), t + '.cpp',
diff --git a/oem/ibm/libpldmresponder/file_io.hpp b/oem/ibm/libpldmresponder/file_io.hpp
index 430811e..10c6d47 100644
--- a/oem/ibm/libpldmresponder/file_io.hpp
+++ b/oem/ibm/libpldmresponder/file_io.hpp
@@ -10,6 +10,7 @@
 #include "oem/ibm/requester/dbus_to_file_handler.hpp"
 #include "oem_ibm_handler.hpp"
 #include "pldmd/handler.hpp"
+#include "requester/handler.hpp"
 
 #include <fcntl.h>
 #include <stdint.h>
@@ -166,10 +167,11 @@
 {
   public:
     Handler(oem_platform::Handler* oemPlatformHandler, int hostSockFd,
-            uint8_t hostEid, dbus_api::Requester* dbusImplReqester) :
+            uint8_t hostEid, dbus_api::Requester* dbusImplReqester,
+            pldm::requester::Handler<pldm::requester::Request>* handler) :
         oemPlatformHandler(oemPlatformHandler),
         hostSockFd(hostSockFd), hostEid(hostEid),
-        dbusImplReqester(dbusImplReqester)
+        dbusImplReqester(dbusImplReqester), handler(handler)
     {
         handlers.emplace(PLDM_READ_FILE_INTO_MEMORY,
                          [this](const pldm_msg* request, size_t payloadLength) {
@@ -231,8 +233,8 @@
             pldm::utils::DBusHandler::getBus(),
             sdbusplus::bus::match::rules::interfacesAdded() +
                 sdbusplus::bus::match::rules::argNpath(0, dumpObjPath),
-            [hostSockFd, hostEid,
-             dbusImplReqester](sdbusplus::message::message& msg) {
+            [this, hostSockFd, hostEid, dbusImplReqester,
+             &handler](sdbusplus::message::message& msg) {
                 std::map<
                     std::string,
                     std::map<std::string, std::variant<std::string, uint32_t>>>
@@ -259,11 +261,13 @@
                                     std::get<std::string>(property.second);
                             }
                         }
-                        auto dbusToFileHandler = std::make_unique<
-                            pldm::requester::oem_ibm::DbusToFileHandler>(
-                            hostSockFd, hostEid, dbusImplReqester, path);
-                        dbusToFileHandler->processNewResourceDump(vspstring,
-                                                                  password);
+                        dbusToFileHandlers
+                            .emplace_back(
+                                std::make_unique<pldm::requester::oem_ibm::
+                                                     DbusToFileHandler>(
+                                    hostSockFd, hostEid, dbusImplReqester, path,
+                                    handler))
+                            ->processNewResourceDump(vspstring, password);
                         break;
                     }
                 }
@@ -272,8 +276,8 @@
             pldm::utils::DBusHandler::getBus(),
             sdbusplus::bus::match::rules::interfacesAdded() +
                 sdbusplus::bus::match::rules::argNpath(0, certObjPath),
-            [hostSockFd, hostEid,
-             dbusImplReqester](sdbusplus::message::message& msg) {
+            [this, hostSockFd, hostEid, dbusImplReqester,
+             &handler](sdbusplus::message::message& msg) {
                 std::map<
                     std::string,
                     std::map<std::string, std::variant<std::string, uint32_t>>>
@@ -295,13 +299,13 @@
                                     sdbusplus::message::object_path(path)
                                         .filename();
 
-                                auto dbusToFileHandler =
-                                    std::make_unique<pldm::requester::oem_ibm::
-                                                         DbusToFileHandler>(
+                                dbusToFileHandlers
+                                    .emplace_back(std::make_unique<
+                                                  pldm::requester::oem_ibm::
+                                                      DbusToFileHandler>(
                                         hostSockFd, hostEid, dbusImplReqester,
-                                        path);
-                                dbusToFileHandler->newCsrFileAvailable(
-                                    csr, fileHandle);
+                                        path, handler))
+                                    ->newCsrFileAvailable(csr, fileHandle);
                                 break;
                             }
                         }
@@ -416,12 +420,18 @@
     using DBusInterfaceAdded = std::vector<std::pair<
         std::string,
         std::vector<std::pair<std::string, std::variant<std::string>>>>>;
+    std::unique_ptr<pldm::requester::oem_ibm::DbusToFileHandler>
+        dbusToFileHandler; //!< pointer to send request to Host
     std::unique_ptr<sdbusplus::bus::match::match>
         resDumpMatcher; //!< Pointer to capture the interface added signal
                         //!< for new resource dump
     std::unique_ptr<sdbusplus::bus::match::match>
         vmiCertMatcher; //!< Pointer to capture the interface added signal
                         //!< for new csr string
+    /** @brief PLDM request handler */
+    pldm::requester::Handler<pldm::requester::Request>* handler;
+    std::vector<std::unique_ptr<pldm::requester::oem_ibm::DbusToFileHandler>>
+        dbusToFileHandlers;
 };
 
 } // namespace oem_ibm
diff --git a/oem/ibm/libpldmresponder/oem_ibm_handler.cpp b/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
index 7fa7570..9b64bd9 100644
--- a/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
+++ b/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
@@ -291,10 +291,8 @@
 }
 
 int pldm::responder::oem_ibm_platform::Handler::sendEventToHost(
-    std::vector<uint8_t>& requestMsg)
+    std::vector<uint8_t>& requestMsg, uint8_t instanceId)
 {
-    uint8_t* responseMsg = nullptr;
-    size_t responseMsgSize{};
     if (requestMsg.size())
     {
         std::ostringstream tempStream;
@@ -305,33 +303,29 @@
         }
         std::cout << tempStream.str() << std::endl;
     }
-
-    auto requesterRc =
-        pldm_send_recv(mctp_eid, mctp_fd, requestMsg.data(), requestMsg.size(),
-                       &responseMsg, &responseMsgSize);
-    std::unique_ptr<uint8_t, decltype(std::free)*> responseMsgPtr{responseMsg,
-                                                                  std::free};
-    if (requesterRc != PLDM_REQUESTER_SUCCESS)
+    auto oemPlatformEventMessageResponseHandler =
+        [](mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
+            uint8_t completionCode{};
+            uint8_t status{};
+            auto rc = decode_platform_event_message_resp(
+                response, respMsgLen, &completionCode, &status);
+            if (rc || completionCode)
+            {
+                std::cerr << "Failed to decode_platform_event_message_resp: "
+                          << " for code update event rc=" << rc
+                          << ", cc=" << static_cast<unsigned>(completionCode)
+                          << std::endl;
+            }
+        };
+    auto rc = handler->registerRequest(
+        mctp_eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE,
+        std::move(requestMsg),
+        std::move(oemPlatformEventMessageResponseHandler));
+    if (rc)
     {
-        std::cerr << "Failed to send message/receive response. RC = "
-                  << requesterRc << ", errno = " << errno
-                  << "for sending event to host \n";
-        return requesterRc;
+        std::cerr << "Failed to send BIOS attribute change event message \n";
     }
-    uint8_t completionCode{};
-    uint8_t status{};
-    auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsgPtr.get());
-    auto rc = decode_platform_event_message_resp(
-        responsePtr, responseMsgSize - sizeof(pldm_msg_hdr), &completionCode,
-        &status);
 
-    if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
-    {
-        std::cerr << "Failure in decode platform event message response, rc= "
-                  << rc << " cc=" << static_cast<unsigned>(completionCode)
-                  << "\n";
-        return rc;
-    }
     return rc;
 }
 
@@ -376,15 +370,15 @@
     {
         std::cerr << "Failed to encode state sensor event, rc = " << rc
                   << std::endl;
+        requester.markFree(mctp_eid, instanceId);
         return;
     }
-    rc = sendEventToHost(requestMsg);
+    rc = sendEventToHost(requestMsg, instanceId);
     if (rc != PLDM_SUCCESS)
     {
         std::cerr << "Failed to send event to host: "
                   << "rc=" << rc << std::endl;
     }
-    requester.markFree(mctp_eid, instanceId);
     return;
 }
 
diff --git a/oem/ibm/libpldmresponder/oem_ibm_handler.hpp b/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
index ee1081e..a713980 100644
--- a/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
+++ b/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
@@ -6,6 +6,7 @@
 #include "libpldmresponder/oem_handler.hpp"
 #include "libpldmresponder/pdr_utils.hpp"
 #include "libpldmresponder/platform.hpp"
+#include "requester/handler.hpp"
 
 namespace pldm
 {
@@ -51,10 +52,11 @@
   public:
     Handler(const pldm::utils::DBusHandler* dBusIntf,
             pldm::responder::CodeUpdate* codeUpdate, int mctp_fd,
-            uint8_t mctp_eid, Requester& requester, sdeventplus::Event& event) :
+            uint8_t mctp_eid, Requester& requester, sdeventplus::Event& event,
+            pldm::requester::Handler<pldm::requester::Request>* handler) :
         oem_platform::Handler(dBusIntf),
         codeUpdate(codeUpdate), platformHandler(nullptr), mctp_fd(mctp_fd),
-        mctp_eid(mctp_eid), requester(requester), event(event)
+        mctp_eid(mctp_eid), requester(requester), event(event), handler(handler)
     {
         codeUpdate->setVersions();
     }
@@ -116,9 +118,10 @@
 
     /** @brief Method to send encoded request msg of code update event to host
      *  @param[in] requestMsg - encoded request msg
+     *  @param[in] instanceId - instance id of the message
      *  @return PLDM status code
      */
-    int sendEventToHost(std::vector<uint8_t>& requestMsg);
+    int sendEventToHost(std::vector<uint8_t>& requestMsg, uint8_t instanceId);
 
     /** @brief _processEndUpdate processes the actual work that needs
      *  to be carried out after EndUpdate effecter is set. This is done async
@@ -170,6 +173,9 @@
   private:
     /** @brief D-Bus property changed signal match for CurrentPowerState*/
     std::unique_ptr<sdbusplus::bus::match::match> chassisOffMatch;
+
+    /** @brief PLDM request handler */
+    pldm::requester::Handler<pldm::requester::Request>* handler;
 };
 
 /** @brief Method to encode code update event msg
diff --git a/oem/ibm/libpldmresponder/platform_oem_ibm.cpp b/oem/ibm/libpldmresponder/platform_oem_ibm.cpp
index d5c6528..0ae1adb 100644
--- a/oem/ibm/libpldmresponder/platform_oem_ibm.cpp
+++ b/oem/ibm/libpldmresponder/platform_oem_ibm.cpp
@@ -15,9 +15,10 @@
 namespace platform

 {

 

-int sendBiosAttributeUpdateEvent(int fd, uint8_t eid,

-                                 dbus_api::Requester* requester,

-                                 const std::vector<uint16_t>& handles)

+int sendBiosAttributeUpdateEvent(

+    uint8_t eid, dbus_api::Requester* requester,

+    const std::vector<uint16_t>& handles,

+    pldm::requester::Handler<pldm::requester::Request>* handler)

 {

     constexpr auto hostStatePath = "/xyz/openbmc_project/state/host0";

     constexpr auto hostStateInterface =

@@ -77,50 +78,40 @@
         std::cout << tempStream.str() << std::endl;

     }

 

-    uint8_t* responseMsg = nullptr;

-    size_t responseMsgSize{};

-

-    rc = pldm_send_recv(eid, fd, requestMsg.data(), requestMsg.size(),

-                        &responseMsg, &responseMsgSize);

-    std::unique_ptr<uint8_t, decltype(std::free)*> responseMsgPtr{responseMsg,

-                                                                  std::free};

-    requester->markFree(eid, instanceId);

-

-    if (rc != PLDM_REQUESTER_SUCCESS)

+    auto platformEventMessageResponseHandler = [](mctp_eid_t /*eid*/,

+                                                  const pldm_msg* response,

+                                                  size_t respMsgLen) {

+        if (response == nullptr || !respMsgLen)

+        {

+            std::cerr

+                << "Failed to receive response for platform event message \n";

+            return;

+        }

+        uint8_t completionCode{};

+        uint8_t status{};

+        auto rc = decode_platform_event_message_resp(response, respMsgLen,

+                                                     &completionCode, &status);

+        if (rc || completionCode)

+        {

+            std::cerr << "Failed to decode_platform_event_message_resp: "

+                      << "rc=" << rc

+                      << ", cc=" << static_cast<unsigned>(completionCode)

+                      << std::endl;

+        }

+    };

+    rc = handler->registerRequest(

+        eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE,

+        std::move(requestMsg), std::move(platformEventMessageResponseHandler));

+    if (rc)

     {

-        std::cerr << "Failed to send BIOS attribute update event. RC = " << rc

-                  << ", errno = " << errno << "\n";

-        pldm::utils::reportError(

-            "xyz.openbmc_project.bmc.pldm.InternalFailure");

-        return rc;

+        std::cerr << "Failed to send the platform event message \n";

     }

 

-    auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsgPtr.get());

-    uint8_t completionCode{};

-    uint8_t status{};

-    rc = decode_platform_event_message_resp(

-        responsePtr, responseMsgSize - sizeof(pldm_msg_hdr), &completionCode,

-        &status);

-    if (rc != PLDM_SUCCESS)

-    {

-        std::cerr << "Failed to decode PlatformEventMessage response, rc = "

-                  << rc << "\n";

-        return rc;

-    }

-

-    if (completionCode != PLDM_SUCCESS)

-    {

-        std::cerr << "Failed to send the BIOS attribute update event, rc = "

-                  << (uint32_t)completionCode << "\n";

-        pldm::utils::reportError(

-            "xyz.openbmc_project.bmc.pldm.InternalFailure");

-    }

-

-    return completionCode;

+    return rc;

 }

 

 } // namespace platform

 

 } // namespace responder

 

-} // namespace pldm
\ No newline at end of file
+} // namespace pldm

diff --git a/oem/ibm/libpldmresponder/platform_oem_ibm.hpp b/oem/ibm/libpldmresponder/platform_oem_ibm.hpp
index 639f1d5..6f3a320 100644
--- a/oem/ibm/libpldmresponder/platform_oem_ibm.hpp
+++ b/oem/ibm/libpldmresponder/platform_oem_ibm.hpp
@@ -1,6 +1,7 @@
 #pragma once

 

 #include "pldmd/dbus_impl_requester.hpp"

+#include "requester/handler.hpp"

 

 #include <vector>

 

@@ -18,14 +19,15 @@
  *  PLDM_EVENT_TYPE_OEM_EVENT_BIOS_ATTRIBUTE_UPDATE is send to host with the

  *  list of BIOS attribute handles.

  *

- *  @param[in] fd - socket descriptor to communicate to host

  *  @param[in] eid - MCTP EID of host firmware

  *  @param[in] requester - pointer to Requester object

  *  @param[in] handles - List of BIOS attribute handles

+ *  @param[in] handler - PLDM request handler

  */

-int sendBiosAttributeUpdateEvent(int fd, uint8_t eid,

-                                 dbus_api::Requester* requester,

-                                 const std::vector<uint16_t>& handles);

+int sendBiosAttributeUpdateEvent(

+    uint8_t eid, dbus_api::Requester* requester,

+    const std::vector<uint16_t>& handles,

+    pldm::requester::Handler<pldm::requester::Request>* handler);

 

 } // namespace platform

 

diff --git a/oem/ibm/requester/dbus_to_file_handler.cpp b/oem/ibm/requester/dbus_to_file_handler.cpp
index e256bc8..44eb5f7 100644
--- a/oem/ibm/requester/dbus_to_file_handler.cpp
+++ b/oem/ibm/requester/dbus_to_file_handler.cpp
@@ -25,10 +25,11 @@
 
 DbusToFileHandler::DbusToFileHandler(
     int mctp_fd, uint8_t mctp_eid, dbus_api::Requester* requester,
-    sdbusplus::message::object_path resDumpCurrentObjPath) :
+    sdbusplus::message::object_path resDumpCurrentObjPath,
+    pldm::requester::Handler<pldm::requester::Request>* handler) :
     mctp_fd(mctp_fd),
     mctp_eid(mctp_eid), requester(requester),
-    resDumpCurrentObjPath(resDumpCurrentObjPath)
+    resDumpCurrentObjPath(resDumpCurrentObjPath), handler(handler)
 {}
 
 void DbusToFileHandler::sendNewFileAvailableCmd(uint64_t fileSize)
@@ -58,60 +59,54 @@
         return;
     }
 
-    uint8_t* responseMsg = nullptr;
-    size_t responseMsgSize{};
-
-    auto requesterRc =
-        pldm_send_recv(mctp_eid, mctp_fd, requestMsg.data(), requestMsg.size(),
-                       &responseMsg, &responseMsgSize);
-
-    std::unique_ptr<uint8_t, decltype(std::free)*> responseMsgPtr{responseMsg,
-                                                                  std::free};
-
-    requester->markFree(mctp_eid, instanceId);
-    bool isDecodeNewFileRespFailed = false;
-    if (requesterRc != PLDM_REQUESTER_SUCCESS)
-    {
-        std::cerr << "Failed to send resource dump parameters, rc = "
-                  << requesterRc << std::endl;
-    }
-    else
-    {
+    auto newFileAvailableRespHandler = [this](mctp_eid_t /*eid*/,
+                                              const pldm_msg* response,
+                                              size_t respMsgLen) {
+        if (response == nullptr || !respMsgLen)
+        {
+            std::cerr
+                << "Failed to receive response for NewFileAvailable command \n";
+            return;
+        }
         uint8_t completionCode{};
-        auto responsePtr =
-            reinterpret_cast<struct pldm_msg*>(responseMsgPtr.get());
-
-        rc = decode_new_file_resp(responsePtr, PLDM_NEW_FILE_RESP_BYTES,
-                                  &completionCode);
-
-        if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
+        auto rc = decode_new_file_resp(response, respMsgLen, &completionCode);
+        if (rc || completionCode)
         {
-            std::cerr << "Failed to decode_new_file_resp: "
-                      << "rc=" << rc
+            std::cerr << "Failed to decode_new_file_resp or"
+                      << " Host returned error for new_file_available"
+                      << " rc=" << rc
                       << ", cc=" << static_cast<unsigned>(completionCode)
-                      << std::endl;
-            isDecodeNewFileRespFailed = true;
+                      << "\n";
+            reportResourceDumpFailure();
         }
-    }
-
-    if ((requesterRc != PLDM_REQUESTER_SUCCESS) || (isDecodeNewFileRespFailed))
+    };
+    rc = handler->registerRequest(
+        mctp_eid, instanceId, PLDM_OEM, PLDM_NEW_FILE_AVAILABLE,
+        std::move(requestMsg), std::move(newFileAvailableRespHandler));
+    if (rc)
     {
-        pldm::utils::reportError(
-            "xyz.openbmc_project.bmc.pldm.InternalFailure");
+        std::cerr << "Failed to send NewFileAvailable Request to Host \n";
+        reportResourceDumpFailure();
+    }
+}
 
-        PropertyValue value{resDumpStatus};
-        DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
-                                "Status", "string"};
-        try
-        {
-            pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
-        }
-        catch (const std::exception& e)
-        {
-            std::cerr << "failed to set resource dump operation status, "
-                         "ERROR="
-                      << e.what() << "\n";
-        }
+void DbusToFileHandler::reportResourceDumpFailure()
+{
+
+    pldm::utils::reportError("xyz.openbmc_project.bmc.pldm.InternalFailure");
+
+    PropertyValue value{resDumpStatus};
+    DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
+                            "Status", "string"};
+    try
+    {
+        pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
+    }
+    catch (const std::exception& e)
+    {
+        std::cerr << "failed to set resource dump operation status, "
+                     "ERROR="
+                  << e.what() << "\n";
     }
 }
 
@@ -249,48 +244,35 @@
         std::cerr << "Failed to encode_new_file_req, rc = " << rc << std::endl;
         return;
     }
-
-    uint8_t* responseMsg = nullptr;
-    size_t responseMsgSize{};
-
-    auto requesterRc =
-        pldm_send_recv(mctp_eid, mctp_fd, requestMsg.data(), requestMsg.size(),
-                       &responseMsg, &responseMsgSize);
-
-    std::unique_ptr<uint8_t, decltype(std::free)*> responseMsgPtr{responseMsg,
-                                                                  std::free};
-
-    requester->markFree(mctp_eid, instanceId);
-    bool isDecodeNewFileRespFailed = false;
-    if (requesterRc != PLDM_REQUESTER_SUCCESS)
-    {
-        std::cerr << "Failed to send file to host, rc = " << requesterRc
-                  << std::endl;
-    }
-    else
-    {
-        uint8_t completionCode{};
-        auto responsePtr =
-            reinterpret_cast<struct pldm_msg*>(responseMsgPtr.get());
-
-        rc = decode_new_file_resp(responsePtr, PLDM_NEW_FILE_RESP_BYTES,
-                                  &completionCode);
-
-        std::vector<uint8_t> responseMsgVec;
-        responseMsgVec.resize(responseMsgSize);
-        memcpy(responseMsgVec.data(), responseMsg, responseMsgVec.size());
-
-        if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
+    auto newFileAvailableRespHandler = [](mctp_eid_t /*eid*/,
+                                          const pldm_msg* response,
+                                          size_t respMsgLen) {
+        if (response == nullptr || !respMsgLen)
         {
-            std::cerr << "Failed to decode_new_file_resp: "
-                      << "rc=" << rc
-                      << ", cc=" << static_cast<unsigned>(completionCode)
-                      << std::endl;
-            isDecodeNewFileRespFailed = true;
+            std::cerr << "Failed to receive response for NewFileAvailable "
+                         "command for vmi \n";
+            return;
         }
-    }
-    if ((requesterRc != PLDM_REQUESTER_SUCCESS) || (isDecodeNewFileRespFailed))
+        uint8_t completionCode{};
+        auto rc = decode_new_file_resp(response, respMsgLen, &completionCode);
+        if (rc || completionCode)
+        {
+            std::cerr << "Failed to decode_new_file_resp for vmi, or"
+                      << " Host returned error for new_file_available"
+                      << " rc=" << rc
+                      << ", cc=" << static_cast<unsigned>(completionCode)
+                      << "\n";
+            pldm::utils::reportError(
+                "xyz.openbmc_project.bmc.pldm.InternalFailure");
+        }
+    };
+    rc = handler->registerRequest(
+        mctp_eid, instanceId, PLDM_OEM, PLDM_NEW_FILE_AVAILABLE,
+        std::move(requestMsg), std::move(newFileAvailableRespHandler));
+    if (rc)
     {
+        std::cerr
+            << "Failed to send NewFileAvailable Request to Host for vmi \n";
         pldm::utils::reportError(
             "xyz.openbmc_project.bmc.pldm.InternalFailure");
     }
diff --git a/oem/ibm/requester/dbus_to_file_handler.hpp b/oem/ibm/requester/dbus_to_file_handler.hpp
index bd7b3c6..739e864 100644
--- a/oem/ibm/requester/dbus_to_file_handler.hpp
+++ b/oem/ibm/requester/dbus_to_file_handler.hpp
@@ -3,6 +3,7 @@
 #include "libpldm/platform.h"
 
 #include "pldmd/dbus_impl_requester.hpp"
+#include "requester/handler.hpp"
 
 #include <filesystem>
 #include <fstream>
@@ -36,10 +37,12 @@
      *  @param[in] mctp_eid - MCTP EID of host firmware
      *  @param[in] requester - pointer to a Requester object
      *  @param[in] resDumpCurrentObjPath - resource dump current object path
+     *  @param[in] handler - PLDM request handler
      */
-    DbusToFileHandler(int mctp_fd, uint8_t mctp_eid,
-                      dbus_api::Requester* requester,
-                      sdbusplus::message::object_path resDumpCurrentObjPath);
+    DbusToFileHandler(
+        int mctp_fd, uint8_t mctp_eid, dbus_api::Requester* requester,
+        sdbusplus::message::object_path resDumpCurrentObjPath,
+        pldm::requester::Handler<pldm::requester::Request>* handler);
 
     /** @brief Process the new resource dump request
      *  @param[in] vspString - vsp string
@@ -70,6 +73,10 @@
                                     const uint32_t fileHandle,
                                     const uint16_t type);
 
+    /** @brief report failure that a resource dump has failed
+     */
+    void reportResourceDumpFailure();
+
     /** @brief fd of MCTP communications socket */
     int mctp_fd;
 
@@ -83,6 +90,9 @@
 
     /** @brief Hold the current resource dump object path */
     sdbusplus::message::object_path resDumpCurrentObjPath;
+
+    /** @brief PLDM request handler */
+    pldm::requester::Handler<pldm::requester::Request>* handler;
 };
 
 } // namespace oem_ibm
diff --git a/oem/ibm/test/libpldmresponder_fileio_test.cpp b/oem/ibm/test/libpldmresponder_fileio_test.cpp
index e7a5945..0c0492a 100644
--- a/oem/ibm/test/libpldmresponder_fileio_test.cpp
+++ b/oem/ibm/test/libpldmresponder_fileio_test.cpp
@@ -226,7 +226,7 @@
     // Pass invalid payload length
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
     oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
-                             nullptr);
+                             nullptr, nullptr);
     auto response = handler.readFileIntoMemory(request, 0);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -260,7 +260,7 @@
 
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
     oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
-                             nullptr);
+                             nullptr, nullptr);
     auto response = handler.readFileIntoMemory(request, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
@@ -295,7 +295,7 @@
 
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
     oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
-                             nullptr);
+                             nullptr, nullptr);
     auto response = handler.readFileIntoMemory(request, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
@@ -330,7 +330,7 @@
 
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
     oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
-                             nullptr);
+                             nullptr, nullptr);
     auto response = handler.readFileIntoMemory(request, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -368,7 +368,7 @@
 
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
     oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
-                             nullptr);
+                             nullptr, nullptr);
     auto response = handler.readFileIntoMemory(request, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -400,7 +400,7 @@
     // Pass invalid payload length
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
     oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
-                             nullptr);
+                             nullptr, nullptr);
     auto response = handler.writeFileFromMemory(request, 0);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -439,7 +439,7 @@
 
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
     oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
-                             nullptr);
+                             nullptr, nullptr);
     auto response = handler.writeFileFromMemory(request, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_HANDLE);
@@ -475,7 +475,7 @@
 
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
     oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
-                             nullptr);
+                             nullptr, nullptr);
     auto response = handler.writeFileFromMemory(request, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_DATA_OUT_OF_RANGE);
@@ -548,7 +548,7 @@
 
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
     oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
-                             nullptr);
+                             nullptr, nullptr);
     auto response = handler.getFileTable(requestMsgPtr, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
@@ -575,7 +575,7 @@
     // Pass invalid command payload length
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
     oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
-                             nullptr);
+                             nullptr, nullptr);
     auto response = handler.getFileTable(request, 0);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -601,7 +601,7 @@
 
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
     oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
-                             nullptr);
+                             nullptr, nullptr);
     auto response = handler.getFileTable(requestMsgPtr, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_INVALID_FILE_TABLE_TYPE);
@@ -633,7 +633,7 @@
     // Invalid payload length
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
     oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
-                             nullptr);
+                             nullptr, nullptr);
     auto response = handler.readFile(requestMsgPtr, 0);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -687,7 +687,7 @@
 
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
     oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
-                             nullptr);
+                             nullptr, nullptr);
     auto responseMsg = handler.readFile(requestMsgPtr, payload_length);
     auto response = reinterpret_cast<pldm_read_file_resp*>(
         responseMsg.data() + sizeof(pldm_msg_hdr));
@@ -741,7 +741,7 @@
     // Invalid payload length
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
     oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
-                             nullptr);
+                             nullptr, nullptr);
     auto response = handler.writeFile(requestMsgPtr, 0);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     ASSERT_EQ(responsePtr->payload[0], PLDM_ERROR_INVALID_LENGTH);
@@ -792,7 +792,7 @@
 
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
     oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
-                             nullptr);
+                             nullptr, nullptr);
     auto responseMsg = handler.writeFile(requestMsgPtr, payload_length);
     auto response = reinterpret_cast<pldm_read_file_resp*>(
         responseMsg.data() + sizeof(pldm_msg_hdr));
@@ -830,7 +830,7 @@
 
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
     oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
-                             nullptr);
+                             nullptr, nullptr);
     auto response = handler.writeFileByTypeFromMemory(req, 0);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
 
@@ -910,7 +910,7 @@
 
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
     oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
-                             nullptr);
+                             nullptr, nullptr);
     auto response = handler.readFileByTypeIntoMemory(req, 0);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     struct pldm_read_write_file_by_type_memory_resp* resp =
@@ -952,7 +952,7 @@
 
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
     oem_ibm::Handler handler(oemPlatformHandler.get(), hostSocketFd, host_eid,
-                             nullptr);
+                             nullptr, nullptr);
     auto response = handler.readFileByType(req, 0);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     struct pldm_read_write_file_by_type_resp* resp =
diff --git a/oem/ibm/test/libpldmresponder_oem_platform_test.cpp b/oem/ibm/test/libpldmresponder_oem_platform_test.cpp
index aa986f4..8108713 100644
--- a/oem/ibm/test/libpldmresponder_oem_platform_test.cpp
+++ b/oem/ibm/test/libpldmresponder_oem_platform_test.cpp
@@ -37,7 +37,7 @@
                            uint8_t mctp_eid, Requester& requester,
                            sdeventplus::Event& event) :
         oem_ibm_platform::Handler(dBusIntf, codeUpdate, mctp_fd, mctp_eid,
-                                  requester, event)
+                                  requester, event, nullptr)
     {}
     MOCK_METHOD(uint16_t, getNextEffecterId, ());
     MOCK_METHOD(uint16_t, getNextSensorId, ());
@@ -61,8 +61,8 @@
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
 
     oemPlatformHandler = std::make_unique<oem_ibm_platform::Handler>(
-        mockDbusHandler.get(), mockCodeUpdate.get(), 0x1, 0x9, requester,
-        event);
+        mockDbusHandler.get(), mockCodeUpdate.get(), 0x1, 0x9, requester, event,
+        nullptr);
 
     auto rc = oemPlatformHandler->getOemStateSensorReadingsHandler(
         entityID_, entityInstance_, stateSetId_, compSensorCnt_, stateField);
diff --git a/pldmd/pldmd.cpp b/pldmd/pldmd.cpp
index 4e3bea3..ca62bbd 100644
--- a/pldmd/pldmd.cpp
+++ b/pldmd/pldmd.cpp
@@ -193,14 +193,14 @@
     {
         hostPDRHandler = std::make_unique<HostPDRHandler>(
             sockfd, hostEID, event, pdrRepo.get(), EVENTS_JSONS_DIR,
-            entityTree.get(), bmcEntityTree.get(), dbusImplReq, reqHandler,
+            entityTree.get(), bmcEntityTree.get(), dbusImplReq, &reqHandler,
             verbose);
         hostEffecterParser =
             std::make_unique<pldm::host_effecters::HostEffecterParser>(
                 &dbusImplReq, sockfd, pdrRepo.get(), dbusHandler.get(),
-                HOST_JSONS_DIR, verbose);
-        dbusToPLDMEventHandler =
-            std::make_unique<DbusToPLDMEvent>(sockfd, hostEID, dbusImplReq);
+                HOST_JSONS_DIR, &reqHandler, verbose);
+        dbusToPLDMEventHandler = std::make_unique<DbusToPLDMEvent>(
+            sockfd, hostEID, dbusImplReq, &reqHandler);
     }
     std::unique_ptr<oem_platform::Handler> oemPlatformHandler{};
 
@@ -210,15 +210,16 @@
     codeUpdate->clearDirPath(LID_STAGING_DIR);
     oemPlatformHandler = std::make_unique<oem_ibm_platform::Handler>(
         dbusHandler.get(), codeUpdate.get(), sockfd, hostEID, dbusImplReq,
-        event);
+        event, &reqHandler);
     codeUpdate->setOemPlatformHandler(oemPlatformHandler.get());
-    invoker.registerHandler(
-        PLDM_OEM, std::make_unique<oem_ibm::Handler>(
-                      oemPlatformHandler.get(), sockfd, hostEID, &dbusImplReq));
+    invoker.registerHandler(PLDM_OEM, std::make_unique<oem_ibm::Handler>(
+                                          oemPlatformHandler.get(), sockfd,
+                                          hostEID, &dbusImplReq, &reqHandler));
 #endif
     invoker.registerHandler(PLDM_BASE, std::make_unique<base::Handler>());
-    invoker.registerHandler(PLDM_BIOS, std::make_unique<bios::Handler>(
-                                           sockfd, hostEID, &dbusImplReq));
+    invoker.registerHandler(
+        PLDM_BIOS, std::make_unique<bios::Handler>(sockfd, hostEID,
+                                                   &dbusImplReq, &reqHandler));
     auto fruHandler = std::make_unique<fru::Handler>(
         FRU_JSONS_DIR, pdrRepo.get(), entityTree.get(), bmcEntityTree.get());
     // FRU table is built lazily when a FRU command or Get PDR command is
diff --git a/requester/request.hpp b/requester/request.hpp
index 2d74147..3b4dbb0 100644
--- a/requester/request.hpp
+++ b/requester/request.hpp
@@ -176,4 +176,4 @@
 
 } // namespace requester
 
-} // namespace pldm
\ No newline at end of file
+} // namespace pldm