Add HostPDRHandler class
HostPDRHandler has an API to fetch PDRs from the host.
The class HostPDRHandler has a function fetchPDR which basically calls
GetPDR on the host using libpldm's pldm_send_recv API.
The retrieved PDRs are stored in the BMCs primary PDR repo.
Change-Id: Ifd727316caf37d49f17e117b32ee105f6d941e0e
Signed-off-by: Pavithra Barithaya <pbaritha@in.ibm.com>
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
diff --git a/host_pdr_handler.cpp b/host_pdr_handler.cpp
new file mode 100644
index 0000000..1e78846
--- /dev/null
+++ b/host_pdr_handler.cpp
@@ -0,0 +1,81 @@
+#include "host_pdr_handler.hpp"
+
+#include "libpldm/requester/pldm.h"
+
+namespace pldm
+{
+
+void HostPDRHandler::fetchPDR(const std::vector<uint32_t>& recordHandles)
+{
+ std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
+ PLDM_GET_PDR_REQ_BYTES);
+ auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+ for (auto recordHandle : recordHandles)
+ {
+ 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 << "\n";
+ 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);
+ if (requesterRc != PLDM_REQUESTER_SUCCESS)
+ {
+ std::cerr << "Failed to send msg to fetch pdrs, rc = "
+ << requesterRc << "\n";
+ return;
+ }
+
+ auto responsePtr =
+ reinterpret_cast<struct pldm_msg*>(responseMsgPtr.get());
+ uint8_t completionCode{};
+ uint32_t nextRecordHandle{};
+ uint32_t nextDataTransferHandle{};
+ uint8_t transferFlag{};
+ uint16_t respCount{};
+ uint8_t transferCRC{};
+ rc = decode_get_pdr_resp(
+ responsePtr, responseMsgSize - sizeof(pldm_msg_hdr),
+ &completionCode, &nextRecordHandle, &nextDataTransferHandle,
+ &transferFlag, &respCount, nullptr, 0, &transferCRC);
+ if (rc != PLDM_SUCCESS)
+ {
+ std::cerr << "Failed to decode_get_pdr_resp, rc = " << rc << "\n";
+ }
+ 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<int>(completionCode)
+ << "\n";
+ }
+ else
+ {
+ pldm_pdr_add(repo, pdr.data(), respCount, 0);
+ }
+ }
+ }
+}
+
+} // namespace pldm