pldm: Add Redfish PDR support patch

This change adds support in rded daemon to extract the Redfish
PDRs from miniBMC using the PLDM M&C Type and Redfish Resource PDR.
Additionally it removes the previously hardcoded list of resource IDs

Design Doc: go/redfish-pdr-support

Tested: Ran the complete minibmc weekly tests workflow
including the rde soak tests. All tests passed successfully.
Verified that the Action commands like Drive reset action also
work fine.

Fusion-Link: https://fusion2.corp.google.com/c0e4c574-b87b-3184-a2fa-1bec790cdf41

Platforms-Affected: platform6
Google-Bug-Id: 344927358
Google-Bug-Id: 341389695
Google-Bug-Id: 286465868
Change-Id: I224e84bcf97e8b18c9f64fc22bcbed57e69c8361
Signed-off-by: Nikhil Namjoshi <nikhilnamjoshi@google.com>
diff --git a/recipes-phosphor/pldm/pldm/0015-Add-Redfish-PDR-support.patch b/recipes-phosphor/pldm/pldm/0015-Add-Redfish-PDR-support.patch
new file mode 100644
index 0000000..2d7ed5a
--- /dev/null
+++ b/recipes-phosphor/pldm/pldm/0015-Add-Redfish-PDR-support.patch
@@ -0,0 +1,1032 @@
+From 964ce7458284b13f500cf7afda61f1fd3d004183 Mon Sep 17 00:00:00 2001
+From: Nikhil Namjoshi <nikhilnamjoshi@google.com>
+Date: Wed, 29 May 2024 04:54:22 +0000
+Subject: [PATCH] Add Redfish PDR support
+
+This change adds support in rded daemon to extract the Redfish
+PDRs from miniBMC using the PLDM M&C Type and Redfish Resource PDR.
+Additionally it removes the previously hardcoded list of resource IDs
+
+Tested: Ran the complete minibmc weekly tests workflow
+including the rde soak tests. All tests passed successfully.
+Verified that the Action commands like Drive reset action also
+work fine.
+
+Fusion-Link: https://fusion2.corp.google.com/c8be2eaa-dfd9-322e-965d-fb2fe908a678
+
+Patch Tracking Bug: b/344927358
+Upstream info / review: NA
+Upstream-Status: Pending
+Justification:
+There is dependency on upstreaming rded first, followed by other
+libpldm command support like OperationInit, Operation,Status,
+OperationComplete and OperationKill. It is possible that we can
+never upstream this support as the upstream did not reach consensus
+for the rded patches.
+
+Google-Bug-Id: 341389695
+Google-Bug-Id: 286465868
+Change-Id: I35dad7d187c0a946f19cd8e144afff9467c83cdd
+Signed-off-by: Nikhil Namjoshi <nikhilnamjoshi@google.com>
+---
+ rded/helper/discovery/platform_discovery.cpp | 354 +++++++++++++++++++
+ rded/helper/discovery/platform_discovery.hpp |  27 ++
+ rded/helper/discovery/rde_discovery.cpp      |  72 +++-
+ rded/helper/discovery/rde_discovery.hpp      |  13 +-
+ rded/helper/resource_id_mapper.hpp           | 221 ------------
+ rded/meson.build                             |   1 +
+ rded/rded.cpp                                |  74 +++-
+ 7 files changed, 513 insertions(+), 249 deletions(-)
+ create mode 100644 rded/helper/discovery/platform_discovery.cpp
+ create mode 100644 rded/helper/discovery/platform_discovery.hpp
+ delete mode 100644 rded/helper/resource_id_mapper.hpp
+
+diff --git a/rded/helper/discovery/platform_discovery.cpp b/rded/helper/discovery/platform_discovery.cpp
+new file mode 100644
+index 0000000..9185025
+--- /dev/null
++++ b/rded/helper/discovery/platform_discovery.cpp
+@@ -0,0 +1,354 @@
++#include "helper/discovery/platform_discovery.hpp"
++
++#include "libpldm/base.h"
++#include "libpldm/platform.h"
++#include "libpldm/pldm.h"
++#include "libpldm/requester/pldm_platform_requester.h"
++#include "libpldm/utils.h"
++
++#include "helper/common.hpp"
++
++#include <cstdint>
++#include <cstring>
++#include <iostream>
++#include <iterator>
++#include <memory>
++#include <unordered_map>
++
++std::unordered_map<uint8_t, int> platformCommandRequestSize = {
++    {PLDM_GET_PDR, PLDM_GET_PDR_REQ_BYTES}};
++
++/**
++ * @brief Sends the current GetPDR request to rde device, decodes
++ * response and stores the response data in containers
++ *
++ * @param[in] fd - Socket Id.
++ * @param[in] eid - Destination EID.
++ * @param[in] instanceId - Instance ID of rde device.
++ * @param[in] netId - Net Id of the rde device.
++ * @param[in] ctx - Pointer to platform requester context
++ * @param[inout] requestMsg - Vector to store requestMsg bytes
++ * @param[inout] resourceIdToSubUriMap - Resource Id to Sub URI map
++ * @param[inout] resourceIdToContainingResourceIdMap - Resource Id to
++ * Containing resource Id map
++ * @param[inout] completePdrRecordBytes - Vector to store the complete Pdr
++ * Record Data bytes
++ */
++static int processGetPdrRequest(
++    int fd, uint8_t eid, int instanceId, int netId,
++    struct pldm_platform_requester_context* ctx,
++    const std::vector<uint8_t>& requestMsg,
++    std::unordered_map<uint32_t, std::string>& resourceIdToSubUriMap,
++    std::unordered_map<uint32_t, uint32_t>& resourceIdToContainingResourceIdMap,
++    std::vector<uint8_t>& completePdrRecordBytes)
++{
++    ctx->requester_status = PLDM_PLATFORM_REQUESTER_WAITING_FOR_RESPONSE;
++    int rc = pldm_send_at_network(eid, netId, fd, requestMsg.data(),
++                                  requestMsg.size());
++    if (rc)
++    {
++        ctx->requester_status = PLDM_PLATFORM_REQUESTER_REQUEST_FAILED;
++        return PLDM_PLATFORM_REQUESTER_SEND_FAIL;
++    }
++    std::vector<uint8_t> response(sizeof(pldm_msg_hdr) + PLDM_MAX_REQUEST_BYTES,
++                                  0);
++    uint8_t* responseMsg = response.data();
++    size_t responseMsgSize = response.size();
++    auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsg);
++    rc = pldm_recv_at_network(eid, fd, instanceId, &responseMsg,
++                              &responseMsgSize, netId);
++    if (rc)
++    {
++        ctx->requester_status = PLDM_PLATFORM_REQUESTER_REQUEST_FAILED;
++        return PLDM_PLATFORM_REQUESTER_RECV_FAIL;
++    }
++
++    bool isRecordDataComplete = false;
++    size_t recordDataLength = PLDM_MAX_REQUEST_BYTES -
++                              PLDM_GET_PDR_MIN_RESP_BYTES;
++
++    std::vector<uint8_t> recordData(recordDataLength);
++    rc = pldm_platform_push_get_pdr_response(
++        ctx, responsePtr, responseMsgSize, 1 /*expected_pdr_header_version*/,
++        recordData.data(), recordDataLength, &isRecordDataComplete);
++    if (rc)
++    {
++        ctx->requester_status = PLDM_PLATFORM_REQUESTER_REQUEST_FAILED;
++        std::cerr << "Saving Get PDR Response failed..." << std::endl;
++        return PLDM_PLATFORM_REQUESTER_NOT_RESP_MSG;
++    }
++
++    // Insert all the bytes excluding the command header bytes
++    completePdrRecordBytes.resize(completePdrRecordBytes.size() +
++                                  recordDataLength);
++    std::memcpy((void*)(completePdrRecordBytes.data() +
++                        completePdrRecordBytes.size() - recordDataLength),
++                (void*)(recordData.data() + sizeof(pldm_pdr_hdr)),
++                recordDataLength);
++
++    if (isRecordDataComplete)
++    {
++        uint32_t resourceId = 0;
++        uint8_t resourceFlags = 0;
++        uint32_t containingResourceId = 0;
++        uint16_t proposedContainingResourceLength = 0;
++        char* proposedContainingResourceName = NULL;
++        uint16_t resourceUriLength = 0;
++        char* resourceUri = NULL;
++        uint16_t additionalResourceIdCount = 0;
++        rc = pldm_platform_decode_first_pdr_resource(
++            completePdrRecordBytes.data(), &resourceId, &resourceFlags,
++            &containingResourceId, &proposedContainingResourceLength,
++            &proposedContainingResourceName, &resourceUriLength, &resourceUri,
++            &additionalResourceIdCount);
++        if (rc)
++        {
++            ctx->requester_status = PLDM_PLATFORM_REQUESTER_REQUEST_FAILED;
++            std::cerr << "Decoding PDR's first resource failed with rc " << rc
++                      << std::endl;
++            return PLDM_PLATFORM_REQUESTER_NOT_RESP_MSG;
++        }
++
++        if (containingResourceId == PLDM_EXTERNAL_RESOURCE_ID)
++        {
++            resourceIdToSubUriMap.emplace(resourceId,
++                                          proposedContainingResourceName);
++        }
++        else
++        {
++            resourceIdToSubUriMap.emplace(resourceId, resourceUri);
++        }
++        resourceIdToContainingResourceIdMap.emplace(resourceId,
++                                                    containingResourceId);
++
++        for (uint16_t id = 0; id < additionalResourceIdCount; id++)
++        {
++            rc = pldm_platform_decode_additional_pdr_resource(
++                completePdrRecordBytes.data(), id, &resourceId,
++                &resourceUriLength, &resourceUri);
++            if (rc)
++            {
++                ctx->requester_status = PLDM_PLATFORM_REQUESTER_REQUEST_FAILED;
++                std::cerr << "Decoding PDR's additional resource failed..."
++                          << std::endl;
++                return PLDM_PLATFORM_REQUESTER_NOT_RESP_MSG;
++            }
++
++            resourceIdToSubUriMap.emplace(resourceId, resourceUri);
++            resourceIdToContainingResourceIdMap.emplace(resourceId,
++                                                        containingResourceId);
++        }
++
++        // Clear the container so it can be used for next set of PDR data
++        completePdrRecordBytes.clear();
++    }
++
++    return PLDM_PLATFORM_REQUESTER_SUCCESS;
++}
++
++/**
++ * @brief Initializes platform context for the plaform requests
++ *
++ * @param[inout] platformCtx - Pointer to platform requester context
++ * @param[inout] pdrOpCtx - Pointer to pdr operation context
++ * @param[in] rdeDeviceId - Rde device Id
++ * @param[in] netId - Net Id of the rde device.
++ * @param[in] negotiatedTransferSize - Negotiated PLDM message size
++ * @return 0 on success, -1 on failure
++ */
++static int initPlatformContextForRde(
++    struct pldm_platform_requester_context* platformCtx,
++    struct pldm_platform_get_pdr_operation* pdrOpCtx,
++    const std::string& rdeDeviceId, int netId, uint32_t negotiatedTransferSize)
++{
++    if (pldm_platform_init_context(platformCtx, rdeDeviceId.c_str(), netId,
++                                   negotiatedTransferSize) != 0)
++    {
++        std::cerr << "Unable to initialize platform context" << std::endl;
++        return -1;
++    }
++
++    if (pldm_platform_init_get_pdr_operation_context(platformCtx, pdrOpCtx) !=
++        0)
++    {
++        std::cerr << "Unable to initialize GetPDR Operation context"
++                  << std::endl;
++        return -1;
++    }
++
++    return 0;
++}
++
++/**
++ * @brief API to recursively construct complere Redfish resource URI
++ * using the sub URI fragments
++ * @param[in] resourceIdToSubUriMap - Resource ID to Sub Uri map
++ * @param[in] resourceIdToContainingResourceIdMap - Resource ID to
++ * Containing resource ID map
++ * @param[inout] resourcePartialUri - Partially constructed Redfish
++ * resource URI
++ * @param[in] containingResourceId - Containing Resource ID
++ * @return string representing the complete Redfish resource URI
++ */
++static std::string constructResourceUri(
++    const std::unordered_map<uint32_t, std::string>& resourceIdToSubUriMap,
++    const std::unordered_map<uint32_t, uint32_t>&
++        resourceIdToContainingResourceIdMap,
++    std::string& resourcePartialUri, uint32_t containingResourceId)
++{
++    // Break the recusion when the resource is root level resource
++    if (containingResourceId == 0x00000000)
++    {
++        return "/redfish/v1/" + resourcePartialUri;
++    }
++
++    auto resourceIdToSubUriMapItr =
++        resourceIdToSubUriMap.find(containingResourceId);
++    if (resourceIdToSubUriMapItr == resourceIdToSubUriMap.end())
++    {
++        std::cerr << "Cannot find containingResourceId : "
++                  << containingResourceId << " in resourceIdToSubUriMap"
++                  << std::endl;
++        return "";
++    }
++
++    std::string subUri = resourceIdToSubUriMapItr->second;
++
++    resourcePartialUri = subUri + "/" + resourcePartialUri;
++
++    auto resourceIdToContainingResourceIdMapItr =
++        resourceIdToContainingResourceIdMap.find(containingResourceId);
++    if (resourceIdToContainingResourceIdMapItr ==
++        resourceIdToContainingResourceIdMap.end())
++    {
++        std::cerr << "Cannot find containingResourceId : "
++                  << containingResourceId
++                  << " in resourceIdToContainingResourceIdMap" << std::endl;
++        return "";
++    }
++
++    uint32_t nextContainingResourceId =
++        resourceIdToContainingResourceIdMapItr->second;
++    return constructResourceUri(resourceIdToSubUriMap,
++                                resourceIdToContainingResourceIdMap,
++                                resourcePartialUri, nextContainingResourceId);
++}
++
++/**
++ * @brief API to recursively construct Redfish resource URI
++ * to Resource ID Map
++ * @param[inout] resourceIdMap - Redfish Resource URI to Resource ID map
++ * @param[in] resourceIdToSubUriMap - Resource ID to Sub Uri map
++ * @param[in] resourceIdToContainingResourceIdMap - Resource ID to
++ * Containing resource ID map
++ * @return string representing the complete Redfish resource URI
++ */
++static void constructResourceIdMap(
++    std::unordered_map<std::string, uint32_t>& resourceIdMap,
++    const std::unordered_map<uint32_t, std::string>& resourceIdToSubUriMap,
++    const std::unordered_map<uint32_t, uint32_t>&
++        resourceIdToContainingResourceIdMap)
++{
++    for (auto it = resourceIdToContainingResourceIdMap.begin();
++         it != resourceIdToContainingResourceIdMap.end(); ++it)
++    {
++        uint32_t resourceId = it->first;
++        uint32_t containingResourceId = it->second;
++
++        auto resourceIdToSubUriMapItr = resourceIdToSubUriMap.find(resourceId);
++        if (resourceIdToSubUriMapItr == resourceIdToSubUriMap.end())
++        {
++            std::cerr << "Cannot find resourceId : " << resourceId
++                      << " in resourceIdToSubUriMap" << std::endl;
++            return;
++        }
++
++        std::string resourcePartialUri = resourceIdToSubUriMapItr->second;
++        std::string resourceFullUri = constructResourceUri(
++            resourceIdToSubUriMap, resourceIdToContainingResourceIdMap,
++            resourcePartialUri, containingResourceId);
++        std::cerr << "Adding resourceId " << std::showbase << std::hex
++                  << resourceId << " with resource URI " << resourceFullUri
++                  << std::endl;
++        resourceIdMap.emplace(resourceFullUri, resourceId);
++    }
++}
++
++int performPdrDiscovery(
++    const std::string& rdeDeviceId, int fd, int netId, uint8_t destEid,
++    uint8_t instanceId, uint32_t negotiatedTransferSize,
++    std::unordered_map<std::string, uint32_t>& resourceIdMap)
++{
++    struct pldm_platform_requester_context platformContext;
++    struct pldm_platform_get_pdr_operation pdrOpContext;
++
++    int rc = initPlatformContextForRde(&platformContext, &pdrOpContext,
++                                       rdeDeviceId, netId,
++                                       negotiatedTransferSize);
++    if (rc)
++    {
++        return -1;
++    }
++
++    rc = pldm_platform_start_pdr_discovery(&platformContext);
++    if (rc)
++    {
++        std::cerr << "PDR Discovery failed due to context busy with ec: " << rc
++                  << std::endl;
++        return -1;
++    }
++
++    std::unordered_map<uint32_t, std::string> resourceIdToSubUriMap;
++    std::unordered_map<uint32_t, uint32_t> resourceIdToContainingResourceIdMap;
++    std::vector<uint8_t> completePdrRecordBytes;
++
++    std::cerr << "Sending Platform PDR Discovery requests." << std::endl;
++
++    while (true)
++    {
++        size_t requestBytes;
++        if (platformContext.requester_status ==
++            PLDM_PLATFORM_REQUESTER_NO_PENDING_ACTION)
++        {
++            break;
++        }
++        if (platformCommandRequestSize.find(platformContext.next_command) !=
++            platformCommandRequestSize.end())
++        {
++            requestBytes =
++                platformCommandRequestSize[platformContext.next_command];
++        }
++        else
++        {
++            requestBytes = PLDM_MAX_REQUEST_BYTES;
++        }
++
++        std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + requestBytes);
++        auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
++
++        rc = pldm_platform_get_next_get_pdr_request(
++            &platformContext, instanceId, request, requestBytes);
++        if (rc)
++        {
++            std::cerr << "Not a valid request to process" << std::endl;
++            return rc;
++        }
++
++        rc = processGetPdrRequest(fd, destEid, 1, netId, &platformContext,
++                                  requestMsg, resourceIdToSubUriMap,
++                                  resourceIdToContainingResourceIdMap,
++                                  completePdrRecordBytes);
++
++        if (rc)
++        {
++            std::cerr << "Unable to process next platform request: "
++                      << std::to_string(rc) << std::endl;
++            return rc;
++        }
++    }
++
++    std::cerr << "PDR Discovery complete." << std::endl;
++    constructResourceIdMap(resourceIdMap, resourceIdToSubUriMap,
++                           resourceIdToContainingResourceIdMap);
++    return 0;
++}
+diff --git a/rded/helper/discovery/platform_discovery.hpp b/rded/helper/discovery/platform_discovery.hpp
+new file mode 100644
+index 0000000..864af62
+--- /dev/null
++++ b/rded/helper/discovery/platform_discovery.hpp
+@@ -0,0 +1,27 @@
++#include "libpldm/requester/pldm_platform_requester.h"
++
++#include <iostream>
++#include <optional>
++#include <string>
++#include <unordered_map>
++#include <vector>
++
++#pragma once
++
++/**
++ * @brief Collects all the PDRs from rde device
++ *
++ * @param[in] rdeDeviceId - Udev Id of the rde device.
++ * @param[in] fd - Socket Id.
++ * @param[in] netId - Net Id of the rde device.
++ * @param[in] destEid - Destination EID.
++ * @param[in] instanceId - Instance ID of rde device.
++ * @param[in] negotiatedTransferSize - Pldm msg transfer size negotiated with
++ * rde device.
++ * @param[inout] resourceIdMap - Map of resource URI against resource Id.
++ * @return 0 on success and negative errono on failure
++ */
++int performPdrDiscovery(
++    const std::string& rdeDeviceId, int fd, int netId, uint8_t destEid,
++    uint8_t instanceId, uint32_t negotiatedTransferSize,
++    std::unordered_map<std::string, uint32_t>& resourceIdMap);
+diff --git a/rded/helper/discovery/rde_discovery.cpp b/rded/helper/discovery/rde_discovery.cpp
+index 3ccae41..37e475e 100644
+--- a/rded/helper/discovery/rde_discovery.cpp
++++ b/rded/helper/discovery/rde_discovery.cpp
+@@ -1,5 +1,3 @@
+-#include "helper/discovery/rde_discovery.hpp"
+-
+ #include "libpldm/base.h"
+ #include "libpldm/pldm.h"
+ #include "libpldm/pldm_rde.h"
+@@ -7,7 +5,9 @@
+ #include "libpldm/utils.h"
+ 
+ #include "helper/common.hpp"
++#include "helper/discovery/rde_discovery.hpp"
+ 
++#include <algorithm>
+ #include <cstdint>
+ #include <iostream>
+ #include <map>
+@@ -139,11 +139,6 @@ int initManager(const std::string& rdeDeviceId, int netId)
+     std::unique_ptr<bitfield16_t> mcFeatures = std::make_unique<bitfield16_t>();
+     mcFeatures->value = 102; // Fixed for now
+     std::cout << "Initializing RDE Manager...\n";
+-    std::vector<uint32_t> resourceIds = {
+-        0x00000000, 0x00010000, 0x00020000, 0x00030000, 0x00040000,
+-        0x00050000, 0x00060000, 0x00070000, 0x00080000, 0x00090000,
+-        0x000a0000, 0x000b0000, 0x000c0000, 0x000d0000, 0x000e0000,
+-        0x000f0000, 0x00100000, 0x00110000, 0xffffffff};
+ 
+     std::unique_ptr<struct pldm_rde_requester_manager> manager =
+         std::make_unique<struct pldm_rde_requester_manager>();
+@@ -151,8 +146,7 @@ int initManager(const std::string& rdeDeviceId, int netId)
+     managerCtxCounter.insert({rdeDeviceId, rdeContextCounter});
+     int rc = pldm_rde_init_context(
+         rdeDeviceId.c_str(), netId, manager.get(), mcConcurrency,
+-        mcTransferSize, mcFeatures.get(), resourceIds.size(),
+-        &resourceIds.front(), allocateMemoryToContexts, freeMemory);
++        mcTransferSize, mcFeatures.get(), allocateMemoryToContexts, freeMemory);
+ 
+     if (rc)
+     {
+@@ -168,6 +162,18 @@ int initManager(const std::string& rdeDeviceId, int netId)
+     return PLDM_RDE_REQUESTER_SUCCESS;
+ }
+ 
++/**
++ * @param[in] manager - Rde manager for the device
++ * @param[in] resourceIds - List of dictionary schema resource IDs
++ * @return 0 on success, non zero error code on failure.
++ */
++static int setResourcesIdsInManager(struct pldm_rde_requester_manager* manager,
++                                    std::vector<uint32_t>& resourceIds)
++{
++    return pldm_rde_set_resources_in_context(manager, resourceIds.size(),
++                                             resourceIds.data());
++}
++
+ int getRdeContextForRdeDevice(const std::string& rdeDevice)
+ {
+     auto it = managerCtxCounter.find(rdeDevice);
+@@ -542,7 +548,8 @@ int processNextRdeRequest(int fd, uint8_t eid, int instanceId,
+ }
+ 
+ int performRdeDiscovery(const std::string& rdeDeviceId, int fd, int netId,
+-                        uint8_t destEid, uint8_t instanceId)
++                        uint8_t destEid, uint8_t instanceId,
++                        uint32_t& negotiatedTransferSize)
+ {
+     int rc = initManager(rdeDeviceId, netId);
+ 
+@@ -625,6 +632,8 @@ int performRdeDiscovery(const std::string& rdeDeviceId, int fd, int netId,
+         }
+     }
+ 
++    negotiatedTransferSize = manager->negotiated_transfer_size;
++
+     if (DEBUG)
+     {
+         printRDENegotiateContext(manager);
+@@ -632,12 +641,35 @@ int performRdeDiscovery(const std::string& rdeDeviceId, int fd, int netId,
+     return rc;
+ }
+ 
+-int performDictionaryDiscoveryForDevice(const std::string& rdeDeviceId, int fd,
+-                                        uint8_t destEid, uint8_t instanceId)
++int performDictionaryDiscoveryForDevice(
++    const std::string& rdeDeviceId, int fd, uint8_t destEid, uint8_t instanceId,
++    std::unordered_map<std::string, uint32_t>& resourceIdMap)
+ {
+     std::unordered_map<uint32_t, std::vector<uint8_t>> dictionaryRidMap;
+     std::unordered_map<uint32_t, std::tuple<uint8_t, uint8_t>>
+         dictionaryMetaRidMap;
++    std::vector<uint32_t> schemaResourceIds;
++
++    for (const auto& [key, value] : resourceIdMap)
++    {
++        // We need to extract just the schema resource IDs. There will be
++        // multiple resources which share the same schema, but we only need
++        // the resource ID of the first resource of that schema
++        // For e.g. We only need resource ID of /redfish/v1/Chassis/Tray i.e.
++        // 0x00020000 instead of resource ID of /redfish/v1/Chassis/SATA_0 i.e.
++        // 0x00020001. Here the MSB 0x0002 represents the resource type while
++        // the LSB 0x0001 represent the resource index. So we exclude the
++        // resource index
++        uint32_t schemaResourceId = value & 0xFFFF0000;
++        auto it = std::find(schemaResourceIds.begin(), schemaResourceIds.end(),
++                            schemaResourceId);
++        if (it == schemaResourceIds.end())
++        {
++            schemaResourceIds.emplace_back(schemaResourceId);
++        }
++    }
++    // Add the annotation dictionary
++    schemaResourceIds.emplace_back(0xffffffff);
+ 
+     dictionaryDeviceMap.insert({rdeDeviceId, dictionaryRidMap});
+ 
+@@ -678,6 +710,15 @@ int performDictionaryDiscoveryForDevice(const std::string& rdeDeviceId, int fd,
+     }
+     struct pldm_rde_requester_manager* manager = managerOpt.value();
+ 
++    rc = setResourcesIdsInManager(manager, schemaResourceIds);
++    if (rc)
++    {
++        std::cerr
++            << "RDE Discovery failed due to failed to set resource IDs in context: "
++            << rc << "\n";
++        return -1;
++    }
++
+     std::cout << "Getting Dictionaries..." << std::endl;
+     int retryCounter = 0;
+     while (retryCounter < MAX_RETRIES_FOR_REQUEST)
+@@ -704,7 +745,7 @@ int performDictionaryDiscoveryForDevice(const std::string& rdeDeviceId, int fd,
+         {
+             std::cerr << "Getting dictionary for "
+                       << manager->resource_ids[baseContext.current_pdr_resource
+-                                         ->resource_id_index]
++                                                   ->resource_id_index]
+                       << "..." << std::endl;
+         }
+ 
+@@ -733,7 +774,8 @@ int performDictionaryDiscoveryForDevice(const std::string& rdeDeviceId, int fd,
+ }
+ 
+ int getRdeFreeContextForRdeDevice(
+-    const std::string& rdeDevice, struct pldm_rde_requester_context* baseContext)
++    const std::string& rdeDevice,
++    struct pldm_rde_requester_context* baseContext)
+ {
+     auto it = managerCtxCounter.find(rdeDevice);
+     if (it != managerCtxCounter.end())
+@@ -756,7 +798,7 @@ int getDictionaryForRidDev(const std::string& rdeDeviceId, uint32_t resourceId,
+ 
+     std::optional<std::unordered_map<uint32_t, std::vector<uint8_t>>*>
+         dictionaryRidMapOpt = getDictionaryMap(rdeDeviceId);
+-    
++
+     if (!dictionaryRidMapOpt.has_value())
+     {
+         std::cerr << "Unable to fetch dictionary from map while storing\n";
+diff --git a/rded/helper/discovery/rde_discovery.hpp b/rded/helper/discovery/rde_discovery.hpp
+index 1e5efa7..e40fc31 100644
+--- a/rded/helper/discovery/rde_discovery.hpp
++++ b/rded/helper/discovery/rde_discovery.hpp
+@@ -1,9 +1,10 @@
+ #include "libpldm/requester/pldm_rde_requester.h"
+ 
+ #include <iostream>
++#include <optional>
+ #include <string>
++#include <unordered_map>
+ #include <vector>
+-#include <optional>
+ 
+ #pragma once
+ 
+@@ -12,10 +13,12 @@
+ #define RDE_GET_DICT_SCHEMA_RESP_SIZE 6
+ 
+ int performRdeDiscovery(const std::string& rdeDeviceId, int fd, int netId,
+-                        uint8_t destEid, uint8_t instanceId);
++                        uint8_t destEid, uint8_t instanceId,
++                        uint32_t& negotiatedTransferSize);
+ 
+-int performDictionaryDiscoveryForDevice(const std::string& rdeDeviceId, int fd,
+-                                        uint8_t destEid, uint8_t instanceId);
++int performDictionaryDiscoveryForDevice(
++    const std::string& rdeDeviceId, int fd, uint8_t destEid, uint8_t instanceId,
++    std::unordered_map<std::string, uint32_t>& resourceIdMap);
+ 
+ void cleanupDictionaries(const std::string& rdeDeviceId);
+ 
+@@ -33,4 +36,4 @@ std::optional<struct pldm_rde_requester_manager*>
+ void cleanupDictionaries(const std::string& rdeDeviceId);
+ 
+ // cleanup disc data at exit
+-void cleanupRdeDiscAtExit();
+\ No newline at end of file
++void cleanupRdeDiscAtExit();
+diff --git a/rded/helper/resource_id_mapper.hpp b/rded/helper/resource_id_mapper.hpp
+deleted file mode 100644
+index c605cb4..0000000
+--- a/rded/helper/resource_id_mapper.hpp
++++ /dev/null
+@@ -1,221 +0,0 @@
+-/**
+- *
+- * This file has a hardcoded resource id mapper for machines
+- * This would not be used once the PDR is implemented
+- *
+- */
+-#include <iostream>
+-#include <string>
+-#include <string_view>
+-#include <unordered_map>
+-
+-std::unordered_map<std::string_view, uint32_t> resourceIdMap = {
+-    {"/redfish/v1/Chassis", 0x00000000},
+-    {"/redfish/v1/Chassis/Tray", 0x00010000},
+-    {"/redfish/v1/Chassis/SATA_0", 0x00010001},
+-    {"/redfish/v1/Chassis/SATA_1", 0x00010002},
+-    {"/redfish/v1/Chassis/SATA_2", 0x00010003},
+-    {"/redfish/v1/Chassis/SATA_3", 0x00010004},
+-    {"/redfish/v1/Chassis/SATA_4", 0x00010005},
+-    {"/redfish/v1/Chassis/SATA_5", 0x00010006},
+-    {"/redfish/v1/Chassis/SATA_6", 0x00010007},
+-    {"/redfish/v1/Chassis/SATA_7", 0x00010008},
+-    {"/redfish/v1/Chassis/SATA_8", 0x00010009},
+-    {"/redfish/v1/Chassis/SATA_9", 0x0001000a},
+-    {"/redfish/v1/Chassis/SATA_10", 0x0001000b},
+-    {"/redfish/v1/Chassis/SATA_11", 0x0001000c},
+-    {"/redfish/v1/Chassis/SATA_12", 0x0001000d},
+-    {"/redfish/v1/Chassis/SATA_13", 0x0001000e},
+-    {"/redfish/v1/Chassis/SATA_14", 0x0001000f},
+-    {"/redfish/v1/Chassis/SATA_15", 0x00010010},
+-    {"/redfish/v1/Chassis/SATA_16", 0x00010011},
+-    {"/redfish/v1/Chassis/SATA_17", 0x00010012},
+-    {"/redfish/v1/Chassis/SATA_18", 0x00010013},
+-    {"/redfish/v1/Chassis/SATA_19", 0x00010014},
+-    {"/redfish/v1/Chassis/SATA_20", 0x00010015},
+-    {"/redfish/v1/Chassis/SATA_21", 0x00010016},
+-    {"/redfish/v1/Chassis/SATA_22", 0x00010017},
+-    {"/redfish/v1/Chassis/SATA_23", 0x00010018},
+-    {"/redfish/v1/Chassis/Tray/Sensors", 0x00020000},
+-    {"/redfish/v1/Chassis/SATA_0/Sensors", 0x00020001},
+-    {"/redfish/v1/Chassis/SATA_1/Sensors", 0x00020002},
+-    {"/redfish/v1/Chassis/SATA_2/Sensors", 0x00020003},
+-    {"/redfish/v1/Chassis/SATA_3/Sensors", 0x00020004},
+-    {"/redfish/v1/Chassis/SATA_4/Sensors", 0x00020005},
+-    {"/redfish/v1/Chassis/SATA_5/Sensors", 0x00020006},
+-    {"/redfish/v1/Chassis/SATA_6/Sensors", 0x00020007},
+-    {"/redfish/v1/Chassis/SATA_7/Sensors", 0x00020008},
+-    {"/redfish/v1/Chassis/SATA_8/Sensors", 0x00020009},
+-    {"/redfish/v1/Chassis/SATA_9/Sensors", 0x0002000a},
+-    {"/redfish/v1/Chassis/SATA_10/Sensors", 0x0002000b},
+-    {"/redfish/v1/Chassis/SATA_11/Sensors", 0x0002000c},
+-    {"/redfish/v1/Chassis/SATA_12/Sensors", 0x0002000d},
+-    {"/redfish/v1/Chassis/SATA_13/Sensors", 0x0002000e},
+-    {"/redfish/v1/Chassis/SATA_14/Sensors", 0x0002000f},
+-    {"/redfish/v1/Chassis/SATA_15/Sensors", 0x00020010},
+-    {"/redfish/v1/Chassis/SATA_16/Sensors", 0x00020011},
+-    {"/redfish/v1/Chassis/SATA_17/Sensors", 0x00020012},
+-    {"/redfish/v1/Chassis/SATA_18/Sensors", 0x00020013},
+-    {"/redfish/v1/Chassis/SATA_19/Sensors", 0x00020014},
+-    {"/redfish/v1/Chassis/SATA_20/Sensors", 0x00020015},
+-    {"/redfish/v1/Chassis/SATA_21/Sensors", 0x00020016},
+-    {"/redfish/v1/Chassis/SATA_22/Sensors", 0x00020017},
+-    {"/redfish/v1/Chassis/SATA_23/Sensors", 0x00020018},
+-    {"/redfish/v1/Chassis/Tray/Sensors/vol_p12v_scaled", 0x00030000},
+-    {"/redfish/v1/Chassis/Tray/Sensors/vol_p5v1_scaled", 0x00030001},
+-    {"/redfish/v1/Chassis/Tray/Sensors/vol_p5v2_scaled", 0x00030002},
+-    {"/redfish/v1/Chassis/Tray/Sensors/vol_p3v3_aux_scaled", 0x00030003},
+-    {"/redfish/v1/Chassis/Tray/Sensors/vol_p1v8_scaled", 0x00030004},
+-    {"/redfish/v1/Chassis/Tray/Sensors/vol_p0v86_scaled", 0x00030005},
+-    {"/redfish/v1/Chassis/Tray/Sensors/vol_p1v45_scaled", 0x00030006},
+-    {"/redfish/v1/Chassis/Tray/Sensors/temp_i2tang", 0x00030007},
+-    {"/redfish/v1/Chassis/Tray/Sensors/hsc_temp", 0x00030008},
+-    {"/redfish/v1/Chassis/Tray/Sensors/hsc_vin", 0x00030009},
+-    {"/redfish/v1/Chassis/Tray/Sensors/hsc_vout", 0x0003000a},
+-    {"/redfish/v1/Chassis/Tray/Sensors/hsc_pin", 0x0003000b},
+-    {"/redfish/v1/Chassis/Tray/Sensors/hsc_iout", 0x0003000c},
+-    {"/redfish/v1/Chassis/Tray/Sensors/hsc_peak_iout", 0x0003000d},
+-    {"/redfish/v1/Chassis/Tray/Sensors/hsc_peak_vin", 0x0003000e},
+-    {"/redfish/v1/Chassis/Tray/Sensors/hsc_peak_temp", 0x0003000f},
+-    {"/redfish/v1/Chassis/Tray/Sensors/hsc_peak_pin", 0x00030010},
+-    {"/redfish/v1/Chassis/Tray/Sensors/brick_p12v_temp", 0x00030011},
+-    {"/redfish/v1/Chassis/Tray/Sensors/brick_p12v_vin", 0x00030012},
+-    {"/redfish/v1/Chassis/Tray/Sensors/brick_p12v_vout", 0x00030013},
+-    {"/redfish/v1/Chassis/Tray/Sensors/brick_p12v_iout", 0x00030014},
+-    {"/redfish/v1/Chassis/Tray/Sensors/brick_p12v_pout", 0x00030015},
+-    {"/redfish/v1/Chassis/Tray/Sensors/p5v_1_vin", 0x00030016},
+-    {"/redfish/v1/Chassis/Tray/Sensors/p5v_1_vout", 0x00030017},
+-    {"/redfish/v1/Chassis/Tray/Sensors/p5v_1_iout", 0x00030018},
+-    {"/redfish/v1/Chassis/Tray/Sensors/p5v_1_temp", 0x00030019},
+-    {"/redfish/v1/Chassis/Tray/Sensors/p5v_2_vin", 0x0003001a},
+-    {"/redfish/v1/Chassis/Tray/Sensors/p5v_2_vout", 0x0003001b},
+-    {"/redfish/v1/Chassis/Tray/Sensors/p5v_2_iout", 0x0003001c},
+-    {"/redfish/v1/Chassis/Tray/Sensors/p5v_2_temp", 0x0003001d},
+-    {"/redfish/v1/Chassis/Tray/Sensors/p0v86_vin", 0x0003001e},
+-    {"/redfish/v1/Chassis/Tray/Sensors/p0v86_vout", 0x0003001f},
+-    {"/redfish/v1/Chassis/Tray/Sensors/p0v86_iout", 0x00030020},
+-    {"/redfish/v1/Chassis/Tray/Sensors/p0v86_temp", 0x00030021},
+-    {"/redfish/v1/Chassis/Tray/Sensors/fan0_tach", 0x00030022},
+-    {"/redfish/v1/Chassis/Tray/Sensors/fan1_tach", 0x00030023},
+-    {"/redfish/v1/Chassis/Tray/Sensors/fan0_duty", 0x00030024},
+-    {"/redfish/v1/Chassis/Tray/Sensors/fan1_duty", 0x00030025},
+-    {"/redfish/v1/Chassis/Tray/Sensors/ioc_temp", 0x00030026},
+-    {"/redfish/v1/Chassis/SATA_0/Sensors/Drive_0t", 0x00030027},
+-    {"/redfish/v1/Chassis/SATA_1/Sensors/Drive_0t", 0x00030028},
+-    {"/redfish/v1/Chassis/SATA_2/Sensors/Drive_0t", 0x00030029},
+-    {"/redfish/v1/Chassis/SATA_3/Sensors/Drive_0t", 0x0003002a},
+-    {"/redfish/v1/Chassis/SATA_4/Sensors/Drive_0t", 0x0003002b},
+-    {"/redfish/v1/Chassis/SATA_5/Sensors/Drive_0t", 0x0003002c},
+-    {"/redfish/v1/Chassis/SATA_6/Sensors/Drive_0t", 0x0003002d},
+-    {"/redfish/v1/Chassis/SATA_7/Sensors/Drive_0t", 0x0003002e},
+-    {"/redfish/v1/Chassis/SATA_8/Sensors/Drive_0t", 0x0003002f},
+-    {"/redfish/v1/Chassis/SATA_9/Sensors/Drive_0t", 0x00030030},
+-    {"/redfish/v1/Chassis/SATA_10/Sensors/Drive_0t", 0x00030031},
+-    {"/redfish/v1/Chassis/SATA_11/Sensors/Drive_0t", 0x00030032},
+-    {"/redfish/v1/Chassis/SATA_12/Sensors/Drive_0t", 0x00030033},
+-    {"/redfish/v1/Chassis/SATA_13/Sensors/Drive_0t", 0x00030034},
+-    {"/redfish/v1/Chassis/SATA_14/Sensors/Drive_0t", 0x00030035},
+-    {"/redfish/v1/Chassis/SATA_15/Sensors/Drive_0t", 0x00030036},
+-    {"/redfish/v1/Chassis/SATA_16/Sensors/Drive_0t", 0x00030037},
+-    {"/redfish/v1/Chassis/SATA_17/Sensors/Drive_0t", 0x00030038},
+-    {"/redfish/v1/Chassis/SATA_18/Sensors/Drive_0t", 0x00030039},
+-    {"/redfish/v1/Chassis/SATA_19/Sensors/Drive_0t", 0x0003003a},
+-    {"/redfish/v1/Chassis/SATA_20/Sensors/Drive_0t", 0x0003003b},
+-    {"/redfish/v1/Chassis/SATA_21/Sensors/Drive_0t", 0x0003003c},
+-    {"/redfish/v1/Chassis/SATA_22/Sensors/Drive_0t", 0x0003003d},
+-    {"/redfish/v1/Chassis/SATA_23/Sensors/Drive_0t", 0x0003003e},
+-    {"/redfish/v1/Chassis/Tray/Sensors/host_fan0_pwm", 0x0003003f},
+-    {"/redfish/v1/Chassis/Tray/Sensors/p12v_cem_imon", 0x00030040},
+-    {"/redfish/v1/Chassis/Tray/Sensors/p12v_cem", 0x00030041},
+-    {"/redfish/v1/Chassis/Tray/Sensors/mb_pwr_status", 0x00030042},
+-    {"/redfish/v1/Chassis/Tray/Sensors/fan0_imon", 0x00030043},
+-    {"/redfish/v1/Chassis/Tray/Sensors/fan1_imon", 0x00030044},
+-    {"/redfish/v1/Managers", 0x00040000},
+-    {"/redfish/v1/Managers/mbmc", 0x00050000},
+-    {"/redfish/v1/Chassis/SATA_0/Drives", 0x00060001},
+-    {"/redfish/v1/Chassis/SATA_1/Drives", 0x00060002},
+-    {"/redfish/v1/Chassis/SATA_2/Drives", 0x00060003},
+-    {"/redfish/v1/Chassis/SATA_3/Drives", 0x00060004},
+-    {"/redfish/v1/Chassis/SATA_4/Drives", 0x00060005},
+-    {"/redfish/v1/Chassis/SATA_5/Drives", 0x00060006},
+-    {"/redfish/v1/Chassis/SATA_6/Drives", 0x00060007},
+-    {"/redfish/v1/Chassis/SATA_7/Drives", 0x00060008},
+-    {"/redfish/v1/Chassis/SATA_8/Drives", 0x00060009},
+-    {"/redfish/v1/Chassis/SATA_9/Drives", 0x0006000a},
+-    {"/redfish/v1/Chassis/SATA_10/Drives", 0x0006000b},
+-    {"/redfish/v1/Chassis/SATA_11/Drives", 0x0006000c},
+-    {"/redfish/v1/Chassis/SATA_12/Drives", 0x0006000d},
+-    {"/redfish/v1/Chassis/SATA_13/Drives", 0x0006000e},
+-    {"/redfish/v1/Chassis/SATA_14/Drives", 0x0006000f},
+-    {"/redfish/v1/Chassis/SATA_15/Drives", 0x00060010},
+-    {"/redfish/v1/Chassis/SATA_16/Drives", 0x00060011},
+-    {"/redfish/v1/Chassis/SATA_17/Drives", 0x00060012},
+-    {"/redfish/v1/Chassis/SATA_18/Drives", 0x00060013},
+-    {"/redfish/v1/Chassis/SATA_19/Drives", 0x00060014},
+-    {"/redfish/v1/Chassis/SATA_20/Drives", 0x00060015},
+-    {"/redfish/v1/Chassis/SATA_21/Drives", 0x00060016},
+-    {"/redfish/v1/Chassis/SATA_22/Drives", 0x00060017},
+-    {"/redfish/v1/Chassis/SATA_23/Drives", 0x00060018},
+-    {"/redfish/v1/Chassis/SATA_0/Drives/SATA_0", 0x00070000},
+-    {"/redfish/v1/Chassis/SATA_1/Drives/SATA_1", 0x00070001},
+-    {"/redfish/v1/Chassis/SATA_2/Drives/SATA_2", 0x00070002},
+-    {"/redfish/v1/Chassis/SATA_3/Drives/SATA_3", 0x00070003},
+-    {"/redfish/v1/Chassis/SATA_4/Drives/SATA_4", 0x00070004},
+-    {"/redfish/v1/Chassis/SATA_5/Drives/SATA_5", 0x00070005},
+-    {"/redfish/v1/Chassis/SATA_6/Drives/SATA_6", 0x00070006},
+-    {"/redfish/v1/Chassis/SATA_7/Drives/SATA_7", 0x00070007},
+-    {"/redfish/v1/Chassis/SATA_8/Drives/SATA_8", 0x00070008},
+-    {"/redfish/v1/Chassis/SATA_9/Drives/SATA_9", 0x00070009},
+-    {"/redfish/v1/Chassis/SATA_10/Drives/SATA_10", 0x0007000a},
+-    {"/redfish/v1/Chassis/SATA_11/Drives/SATA_11", 0x0007000b},
+-    {"/redfish/v1/Chassis/SATA_12/Drives/SATA_12", 0x0007000c},
+-    {"/redfish/v1/Chassis/SATA_13/Drives/SATA_13", 0x0007000d},
+-    {"/redfish/v1/Chassis/SATA_14/Drives/SATA_14", 0x0007000e},
+-    {"/redfish/v1/Chassis/SATA_15/Drives/SATA_15", 0x0007000f},
+-    {"/redfish/v1/Chassis/SATA_16/Drives/SATA_16", 0x00070010},
+-    {"/redfish/v1/Chassis/SATA_17/Drives/SATA_17", 0x00070011},
+-    {"/redfish/v1/Chassis/SATA_18/Drives/SATA_18", 0x00070012},
+-    {"/redfish/v1/Chassis/SATA_19/Drives/SATA_19", 0x00070013},
+-    {"/redfish/v1/Chassis/SATA_20/Drives/SATA_20", 0x00070014},
+-    {"/redfish/v1/Chassis/SATA_21/Drives/SATA_21", 0x00070015},
+-    {"/redfish/v1/Chassis/SATA_22/Drives/SATA_22", 0x00070016},
+-    {"/redfish/v1/Chassis/SATA_23/Drives/SATA_23", 0x00070017},
+-    {"/redfish/v1/UpdateService", 0x00080000},
+-    {"/redfish/v1/UpdateService/FirmwareInventory", 0x000a0000},
+-    {"/redfish/v1/UpdateService/FirmwareInventory/mbmc", 0x00090000},
+-    {"/redfish/v1/Chassis/Tray/Controls", 0x000c0000},
+-    {"/redfish/v1/Chassis/Tray/Controls/bmc_pid", 0x000b0000},
+-    {"/redfish/v1/Chassis/Tray/Controls/lat_pid", 0x000b0001},
+-    {"/redfish/v1/Chassis/Tray/Controls/ioc_pid", 0x000b0002},
+-    {"/redfish/v1/Chassis/Tray/Controls/vr_pid", 0x000b0003},
+-    {"/redfish/v1/Chassis/Tray/Controls/powerbrick_pid", 0x000b0004},
+-    {"/redfish/v1/Chassis/Tray/Controls/hdd_max_pid", 0x000b0005},
+-    {"/redfish/v1/Chassis/Tray/Controls/hdd_avg_pid", 0x000b0006},
+-    {"/redfish/v1/Chassis/Tray/Controls/fans", 0x000b0007},
+-    {"/redfish/v1/Storage", 0x000d0000},
+-    {"/redfish/v1/Storage/SATA", 0x000e0000},
+-    {"/redfish/v1/Storage/SATA/Controllers", 0x000f0000},
+-    {"/redfish/v1/Storage/SATA/Controllers/ioc", 0x00100000},
+-    {"/redfish/v1/Managers/mbmc/ManagerDiagnosticData", 0x00110000}
+-};
+-
+-int getResourceIdForUri(std::string_view uri, uint32_t& resourceId)
+-{
+-    auto it = resourceIdMap.find(uri);
+-    if (it != resourceIdMap.end())
+-    {
+-        resourceId = it->second;
+-        if (DEBUG)
+-        {
+-            std::cout << "Resource id found: " << std::to_string(it->second)
+-                      << "\n";
+-        }
+-        return 0;
+-    }
+-    if ((uri.find("Cables") == std::string::npos) &&
+-        (uri.find("Systems") == std::string::npos))
+-    {
+-        std::cerr << "Resource id not found for uri: " << uri << std::endl;
+-    }
+-    return 1;
+-}
+diff --git a/rded/meson.build b/rded/meson.build
+index ca2b087..ae622d5 100644
+--- a/rded/meson.build
++++ b/rded/meson.build
+@@ -2,6 +2,7 @@ sources = [
+   'rded.cpp',
+   'helper/discovery/base_discovery.cpp',
+   'helper/discovery/rde_discovery.cpp',
++  'helper/discovery/platform_discovery.cpp',
+   'helper/rde_operation/rde_operation.cpp',
+   'helper/rde_operation/rde_update_utils.cpp'
+ ]
+diff --git a/rded/rded.cpp b/rded/rded.cpp
+index ecd83d0..bc367dc 100644
+--- a/rded/rded.cpp
++++ b/rded/rded.cpp
+@@ -1,16 +1,16 @@
+ #include "common/utils.hpp"
+ #include "helper/common.hpp"
+ #include "helper/discovery/base_discovery.hpp"
++#include "helper/discovery/platform_discovery.hpp"
+ #include "helper/discovery/rde_discovery.hpp"
+ #include "helper/rde_operation/rde_operation.hpp"
+-#include "helper/resource_id_mapper.hpp"
+ 
+ // libbej
+ #include "libbej/bej_common.h"
+ #include "libbej/bej_encoder_core.h"
+ 
+ #include "libbej/bej_encoder_json.hpp"
+-#include <csignal>
++
+ #include <locale.h>
+ #include <signal.h>
+ #include <string.h>
+@@ -29,6 +29,7 @@
+ #include <sdbusplus/unpack_properties.hpp>
+ #include <sdeventplus/event.hpp>
+ 
++#include <csignal>
+ #include <cstddef>
+ #include <iostream>
+ #include <unordered_map>
+@@ -60,11 +61,41 @@ std::unordered_map<std::string,
+     dbusIntfMap;
+ std::unordered_map<std::string, std::string> objectPathDeviceId;
+ 
++std::unordered_map<std::string, std::unordered_map<std::string, uint32_t>>
++    rdeResourceIdMap;
++
++static int getResourceIdForUri(std::string& uri, std::string& udevId,
++                               uint32_t& resourceId)
++{
++    if (rdeResourceIdMap.find(udevId) != rdeResourceIdMap.end())
++    {
++        std::unordered_map<std::string, uint32_t>::iterator it =
++            rdeResourceIdMap[udevId].find(uri);
++        if (it != rdeResourceIdMap[udevId].end())
++        {
++            resourceId = it->second;
++            if (DEBUG)
++            {
++                std::cout << "Resource id found: " << std::to_string(it->second)
++                          << "\n";
++            }
++            return 0;
++        }
++    }
++
++    if ((uri.find("Cables") == std::string::npos) &&
++        (uri.find("Systems") == std::string::npos))
++    {
++        std::cerr << "Resource id not found for uri: " << uri << std::endl;
++    }
++    return 1;
++}
++
+ void cleanupAtExit()
+ {
+     // cleans up at daemon termination
+     fd = 0;
+-    resourceIdMap.clear();
++    rdeResourceIdMap.clear();
+     deviceNetIdMap.clear();
+     dbusIntfMap.clear();
+     objectPathDeviceId.clear();
+@@ -74,7 +105,8 @@ void cleanupAtExit()
+     cleanupMctpAtExit();
+ }
+ 
+-void signalHandler(int signal) {
++void signalHandler(int signal)
++{
+     std::cerr << "Received signal " << signal << ". Cleaning up...\n";
+     cleanupAtExit();
+     std::exit(signal);
+@@ -96,7 +128,30 @@ int initiateDiscovery(int fd, std::string udevId, int netId, uint8_t destEid,
+     }
+ 
+     std::cerr << "Initializing RDE Discovery...\n";
+-    rc = performRdeDiscovery(udevId, fd, netId, destEid, instanceId);
++    uint32_t negotiatedTransferSize = 0;
++    rc = performRdeDiscovery(udevId, fd, netId, destEid, instanceId,
++                             negotiatedTransferSize);
++
++    if (rc)
++    {
++        std::cerr << "Failure in Base Discovery with error code: " << rc
++                  << "\n";
++        return rc;
++    }
++
++    std::unordered_map<std::string, uint32_t> resourceIdMap;
++    rdeResourceIdMap.emplace(std::make_pair(udevId, std::move(resourceIdMap)));
++    auto it = rdeResourceIdMap.find(udevId);
++    if (it == rdeResourceIdMap.end())
++    {
++        std::cerr << "Failed to find Resource ID map for " << udevId
++                  << " device" << std::endl;
++        return -1;
++    }
++
++    std::cerr << "Initializing PDR Discovery...\n";
++    rc = performPdrDiscovery(udevId, fd, netId, destEid, instanceId,
++                             negotiatedTransferSize, it->second);
+ 
+     if (rc)
+     {
+@@ -105,7 +160,8 @@ int initiateDiscovery(int fd, std::string udevId, int netId, uint8_t destEid,
+         return rc;
+     }
+ 
+-    rc = performDictionaryDiscoveryForDevice(udevId, fd, destEid, instanceId);
++    rc = performDictionaryDiscoveryForDevice(udevId, fd, destEid, instanceId,
++                                             it->second);
+ 
+     if (rc)
+     {
+@@ -310,7 +366,7 @@ std::string
+     }
+     truncateTrailingFwSlash(uri);
+ 
+-    rc = getResourceIdForUri(uri, resourceId);
++    rc = getResourceIdForUri(uri, udevid, resourceId);
+     if (rc)
+     {
+         // TODO(@harshtya) - Define operation Types to be GET or POST
+@@ -336,7 +392,7 @@ std::string
+ 
+         if (isActionOperation(uri, resource_uri))
+         {
+-            rc = getResourceIdForUri(resource_uri, resourceId);
++            rc = getResourceIdForUri(resource_uri, udevid, resourceId);
+             if (rc)
+             {
+                 std::cerr
+@@ -654,6 +710,8 @@ int triggerRdeReactor(int fd)
+             {
+                 cleanupDictionaries(deviceId);
+                 cleanupMctpLink(deviceId);
++                // Remove the resource ID maps for the rde device
++                rdeResourceIdMap.erase(deviceId);
+             }
+             // TODO (@harshtya): clean up the manager for this object path
+             // TODO (@harshtya): clean up the dictionaries
+-- 
+2.47.0.277.g8800431eea-goog
+
diff --git a/recipes-phosphor/pldm/pldm_%.bbappend b/recipes-phosphor/pldm/pldm_%.bbappend
index af23030..9ae0cb4 100644
--- a/recipes-phosphor/pldm/pldm_%.bbappend
+++ b/recipes-phosphor/pldm/pldm_%.bbappend
@@ -22,6 +22,7 @@
     file://0012-Update-rde-resource-map.patch \
     file://0013-Use-Rde-Op-Enumerate-to-recover-BMC-RDE-device-commu.patch \
     file://0014-rded-support-redfish-expand-feature-for-RDE-Devices.patch \
+    file://0015-Add-Redfish-PDR-support.patch \
 "