1 #include "pldm_cmd_helper.hpp"
2
3 #include "common/transport.hpp"
4 #include "xyz/openbmc_project/Common/error.hpp"
5
6 #include <libpldm/transport.h>
7 #include <libpldm/transport/af-mctp.h>
8 #include <libpldm/transport/mctp-demux.h>
9 #include <poll.h>
10 #include <systemd/sd-bus.h>
11
12 #include <sdbusplus/server.hpp>
13 #include <xyz/openbmc_project/Logging/Entry/server.hpp>
14
15 #include <exception>
16
17 using namespace pldm::utils;
18
19 namespace pldmtool
20 {
21 namespace helper
22 {
23
exec()24 void CommandInterface::exec()
25 {
26 instanceId = instanceIdDb.next(mctp_eid);
27 auto [rc, requestMsg] = createRequestMsg();
28 if (rc != PLDM_SUCCESS)
29 {
30 instanceIdDb.free(mctp_eid, instanceId);
31 std::cerr << "Failed to encode request message for " << pldmType << ":"
32 << commandName << " rc = " << rc << "\n";
33 return;
34 }
35
36 std::vector<uint8_t> responseMsg;
37 rc = pldmSendRecv(requestMsg, responseMsg);
38
39 if (rc != PLDM_SUCCESS)
40 {
41 instanceIdDb.free(mctp_eid, instanceId);
42 std::cerr << "pldmSendRecv: Failed to receive RC = " << rc << "\n";
43 return;
44 }
45
46 auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsg.data());
47 parseResponseMsg(responsePtr, responseMsg.size() - sizeof(pldm_msg_hdr));
48 instanceIdDb.free(mctp_eid, instanceId);
49 }
50
pldmSendRecv(std::vector<uint8_t> & requestMsg,std::vector<uint8_t> & responseMsg)51 int CommandInterface::pldmSendRecv(std::vector<uint8_t>& requestMsg,
52 std::vector<uint8_t>& responseMsg)
53 {
54 // By default enable request/response msgs for pldmtool raw commands.
55 if (CommandInterface::pldmType == "raw")
56 {
57 pldmVerbose = true;
58 }
59
60 if (pldmVerbose)
61 {
62 std::cout << "pldmtool: ";
63 printBuffer(Tx, requestMsg);
64 }
65
66 auto tid = mctp_eid;
67 PldmTransport pldmTransport{};
68 uint8_t retry = 0;
69 int rc = PLDM_ERROR;
70
71 while (PLDM_REQUESTER_SUCCESS != rc && retry <= numRetries)
72 {
73 void* responseMessage = nullptr;
74 size_t responseMessageSize{};
75
76 rc =
77 pldmTransport.sendRecvMsg(tid, requestMsg.data(), requestMsg.size(),
78 responseMessage, responseMessageSize);
79 if (rc)
80 {
81 std::cerr << "[" << unsigned(retry) << "] pldm_send_recv error rc "
82 << rc << std::endl;
83 retry++;
84 continue;
85 }
86
87 responseMsg.resize(responseMessageSize);
88 memcpy(responseMsg.data(), responseMessage, responseMsg.size());
89
90 free(responseMessage);
91
92 if (pldmVerbose)
93 {
94 std::cout << "pldmtool: ";
95 printBuffer(Rx, responseMsg);
96 }
97 }
98
99 if (rc)
100 {
101 std::cerr << "failed to pldm send recv error rc " << rc << std::endl;
102 }
103
104 return rc;
105 }
106 } // namespace helper
107 } // namespace pldmtool
108