blob: 3cd7873ee2db88683828df87cf0338548831f85b [file] [log] [blame]
Pavithra Barithaya51efaf82020-04-02 02:42:27 -05001#include "host_pdr_handler.hpp"
2
3#include "libpldm/requester/pldm.h"
4
5namespace pldm
6{
7
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -05008void HostPDRHandler::fetchPDR(std::vector<uint32_t>&& recordHandles)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -05009{
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -050010 pdrRecordHandles.clear();
11 pdrRecordHandles = std::move(recordHandles);
12
13 // Defer the actual fetch of PDRs from the host (by queuing the call on the
14 // main event loop). That way, we can respond to the platform event msg from
15 // the host firmware.
16 pdrFetchEvent = std::make_unique<sdeventplus::source::Defer>(
17 event, std::bind(std::mem_fn(&HostPDRHandler::_fetchPDR), this,
18 std::placeholders::_1));
19}
20
21void HostPDRHandler::_fetchPDR(sdeventplus::source::EventBase& /*source*/)
22{
23 pdrFetchEvent.reset();
24
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050025 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
26 PLDM_GET_PDR_REQ_BYTES);
27 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
28
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -050029 for (auto recordHandle : pdrRecordHandles)
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050030 {
31 auto instanceId = requester.getInstanceId(mctp_eid);
32
33 auto rc =
34 encode_get_pdr_req(instanceId, recordHandle, 0, PLDM_GET_FIRSTPART,
35 UINT16_MAX, 0, request, PLDM_GET_PDR_REQ_BYTES);
36 if (rc != PLDM_SUCCESS)
37 {
38 requester.markFree(mctp_eid, instanceId);
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -050039 std::cerr << "Failed to encode_get_pdr_req, rc = " << rc
40 << std::endl;
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050041 return;
42 }
43
44 uint8_t* responseMsg = nullptr;
45 size_t responseMsgSize{};
46 auto requesterRc =
47 pldm_send_recv(mctp_eid, mctp_fd, requestMsg.data(),
48 requestMsg.size(), &responseMsg, &responseMsgSize);
49 std::unique_ptr<uint8_t, decltype(std::free)*> responseMsgPtr{
50 responseMsg, std::free};
51 requester.markFree(mctp_eid, instanceId);
52 if (requesterRc != PLDM_REQUESTER_SUCCESS)
53 {
54 std::cerr << "Failed to send msg to fetch pdrs, rc = "
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -050055 << requesterRc << std::endl;
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050056 return;
57 }
58
59 auto responsePtr =
60 reinterpret_cast<struct pldm_msg*>(responseMsgPtr.get());
61 uint8_t completionCode{};
62 uint32_t nextRecordHandle{};
63 uint32_t nextDataTransferHandle{};
64 uint8_t transferFlag{};
65 uint16_t respCount{};
66 uint8_t transferCRC{};
67 rc = decode_get_pdr_resp(
68 responsePtr, responseMsgSize - sizeof(pldm_msg_hdr),
69 &completionCode, &nextRecordHandle, &nextDataTransferHandle,
70 &transferFlag, &respCount, nullptr, 0, &transferCRC);
71 if (rc != PLDM_SUCCESS)
72 {
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -050073 std::cerr << "Failed to decode_get_pdr_resp, rc = " << rc
74 << std::endl;
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050075 }
76 else
77 {
78 std::vector<uint8_t> pdr(respCount, 0);
79 rc = decode_get_pdr_resp(
80 responsePtr, responseMsgSize - sizeof(pldm_msg_hdr),
81 &completionCode, &nextRecordHandle, &nextDataTransferHandle,
82 &transferFlag, &respCount, pdr.data(), respCount, &transferCRC);
83 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
84 {
85 std::cerr << "Failed to decode_get_pdr_resp: "
86 << "rc=" << rc
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -050087 << ", cc=" << static_cast<unsigned>(completionCode)
88 << std::endl;
Pavithra Barithaya51efaf82020-04-02 02:42:27 -050089 }
90 else
91 {
92 pldm_pdr_add(repo, pdr.data(), respCount, 0);
93 }
94 }
95 }
96}
97
98} // namespace pldm