xref: /openbmc/pldm/pldmtool/pldm_cmd_helper.cpp (revision 146ff92b)
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 
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 
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 = pldmTransport.sendRecvMsg(tid, requestMsg.data(),
77                                        requestMsg.size(), responseMessage,
78                                        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