blob: c8ce8df7c85b4054b0f69d9ea0f60eefc4d7e260 [file] [log] [blame]
vkaverap@in.ibm.com9138c202023-05-19 07:50:47 -05001#include "config.h"
2
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -05003#include "pldm_cmd_helper.hpp"
4
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -06005#include "xyz/openbmc_project/Common/error.hpp"
6
George Liuc453e162022-12-21 17:16:23 +08007#include <libpldm/pldm.h>
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -06008#include <systemd/sd-bus.h>
9
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -060010#include <sdbusplus/server.hpp>
11#include <xyz/openbmc_project/Logging/Entry/server.hpp>
12
George Liu6492f522020-06-16 10:34:05 +080013#include <exception>
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +080014
Brad Bishop5079ac42021-08-19 18:35:06 -040015using namespace pldm::utils;
16
John Wang58a0e062019-11-08 15:38:15 +080017namespace pldmtool
18{
John Wang58a0e062019-11-08 15:38:15 +080019namespace helper
20{
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050021/*
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050022 * Initialize the socket, send pldm command & recieve response from socket
23 *
24 */
25int mctpSockSendRecv(const std::vector<uint8_t>& requestMsg,
Sridevi Rameshc91822b2020-02-27 09:26:41 -060026 std::vector<uint8_t>& responseMsg, bool pldmVerbose)
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050027{
28 const char devPath[] = "\0mctp-mux";
29 int returnCode = 0;
30
31 int sockFd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
32 if (-1 == sockFd)
33 {
34 returnCode = -errno;
Sampa Misraaa8ae722019-12-12 03:20:40 -060035 std::cerr << "Failed to create the socket : RC = " << sockFd << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050036 return returnCode;
37 }
Sridevi Rameshc91822b2020-02-27 09:26:41 -060038 Logger(pldmVerbose, "Success in creating the socket : RC = ", sockFd);
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050039
40 struct sockaddr_un addr
George Liu6492f522020-06-16 10:34:05 +080041 {};
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050042 addr.sun_family = AF_UNIX;
43
44 memcpy(addr.sun_path, devPath, sizeof(devPath) - 1);
45
46 CustomFD socketFd(sockFd);
47 int result = connect(socketFd(), reinterpret_cast<struct sockaddr*>(&addr),
48 sizeof(devPath) + sizeof(addr.sun_family) - 1);
49 if (-1 == result)
50 {
51 returnCode = -errno;
John Wang58a0e062019-11-08 15:38:15 +080052 std::cerr << "Failed to connect to socket : RC = " << returnCode
Sampa Misraaa8ae722019-12-12 03:20:40 -060053 << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050054 return returnCode;
55 }
Sridevi Rameshc91822b2020-02-27 09:26:41 -060056 Logger(pldmVerbose, "Success in connecting to socket : RC = ", returnCode);
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050057
58 auto pldmType = MCTP_MSG_TYPE_PLDM;
59 result = write(socketFd(), &pldmType, sizeof(pldmType));
60 if (-1 == result)
61 {
62 returnCode = -errno;
John Wang58a0e062019-11-08 15:38:15 +080063 std::cerr << "Failed to send message type as pldm to mctp : RC = "
Sampa Misraaa8ae722019-12-12 03:20:40 -060064 << returnCode << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050065 return returnCode;
66 }
Sridevi Rameshc91822b2020-02-27 09:26:41 -060067 Logger(
68 pldmVerbose,
69 "Success in sending message type as pldm to mctp : RC = ", returnCode);
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050070
71 result = send(socketFd(), requestMsg.data(), requestMsg.size(), 0);
72 if (-1 == result)
73 {
74 returnCode = -errno;
Sampa Misraaa8ae722019-12-12 03:20:40 -060075 std::cerr << "Write to socket failure : RC = " << returnCode << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050076 return returnCode;
77 }
Sridevi Rameshc91822b2020-02-27 09:26:41 -060078 Logger(pldmVerbose, "Write to socket successful : RC = ", result);
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050079
80 // Read the response from socket
81 ssize_t peekedLength = recv(socketFd(), nullptr, 0, MSG_TRUNC | MSG_PEEK);
82 if (0 == peekedLength)
83 {
John Wang58a0e062019-11-08 15:38:15 +080084 std::cerr << "Socket is closed : peekedLength = " << peekedLength
Sampa Misraaa8ae722019-12-12 03:20:40 -060085 << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050086 return returnCode;
87 }
88 else if (peekedLength <= -1)
89 {
90 returnCode = -errno;
Sampa Misraaa8ae722019-12-12 03:20:40 -060091 std::cerr << "recv() system call failed : RC = " << returnCode << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050092 return returnCode;
93 }
94 else
95 {
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -060096 auto reqhdr = reinterpret_cast<const pldm_msg_hdr*>(&requestMsg[2]);
97 do
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050098 {
Patrick Williams6da4f912023-05-10 07:50:53 -050099 ssize_t peekedLength = recv(socketFd(), nullptr, 0,
100 MSG_PEEK | MSG_TRUNC);
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500101 responseMsg.resize(peekedLength);
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600102 auto recvDataLength =
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500103 recv(socketFd(), reinterpret_cast<void*>(responseMsg.data()),
104 peekedLength, 0);
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600105 auto resphdr =
106 reinterpret_cast<const pldm_msg_hdr*>(&responseMsg[2]);
107 if (recvDataLength == peekedLength &&
108 resphdr->instance_id == reqhdr->instance_id &&
109 resphdr->request != PLDM_REQUEST)
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500110 {
Sridevi Rameshc91822b2020-02-27 09:26:41 -0600111 Logger(pldmVerbose, "Total length:", recvDataLength);
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600112 break;
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500113 }
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600114 else if (recvDataLength != peekedLength)
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500115 {
John Wang58a0e062019-11-08 15:38:15 +0800116 std::cerr << "Failure to read response length packet: length = "
Sampa Misraaa8ae722019-12-12 03:20:40 -0600117 << recvDataLength << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500118 return returnCode;
119 }
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600120 } while (1);
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500121 }
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +0800122
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500123 returnCode = shutdown(socketFd(), SHUT_RDWR);
124 if (-1 == returnCode)
125 {
126 returnCode = -errno;
John Wang58a0e062019-11-08 15:38:15 +0800127 std::cerr << "Failed to shutdown the socket : RC = " << returnCode
Sampa Misraaa8ae722019-12-12 03:20:40 -0600128 << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500129 return returnCode;
130 }
131
Sridevi Rameshc91822b2020-02-27 09:26:41 -0600132 Logger(pldmVerbose, "Shutdown Socket successful : RC = ", returnCode);
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500133 return PLDM_SUCCESS;
134}
John Wang58a0e062019-11-08 15:38:15 +0800135
136void CommandInterface::exec()
137{
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600138 static constexpr auto pldmObjPath = "/xyz/openbmc_project/pldm";
139 static constexpr auto pldmRequester = "xyz.openbmc_project.PLDM.Requester";
140 auto& bus = pldm::utils::DBusHandler::getBus();
141 try
142 {
Patrick Williams6da4f912023-05-10 07:50:53 -0500143 auto service = pldm::utils::DBusHandler().getService(pldmObjPath,
144 pldmRequester);
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600145 auto method = bus.new_method_call(service.c_str(), pldmObjPath,
146 pldmRequester, "GetInstanceId");
147 method.append(mctp_eid);
vkaverap@in.ibm.com9138c202023-05-19 07:50:47 -0500148 auto reply = bus.call(
149 method,
150 std::chrono::duration_cast<microsec>(sec(DBUS_TIMEOUT)).count());
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600151 reply.read(instanceId);
152 }
153 catch (const std::exception& e)
154 {
Manojkiran Eda0a725f82021-10-23 06:02:26 +0530155 std::cerr << "GetInstanceId D-Bus call failed, MCTP id = "
156 << (unsigned)mctp_eid << ", error = " << e.what() << "\n";
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600157 return;
158 }
John Wang58a0e062019-11-08 15:38:15 +0800159 auto [rc, requestMsg] = createRequestMsg();
160 if (rc != PLDM_SUCCESS)
161 {
162 std::cerr << "Failed to encode request message for " << pldmType << ":"
Sampa Misraaa8ae722019-12-12 03:20:40 -0600163 << commandName << " rc = " << rc << "\n";
John Wang58a0e062019-11-08 15:38:15 +0800164 return;
165 }
166
John Wangb754eee2020-02-15 16:10:25 +0800167 std::vector<uint8_t> responseMsg;
168 rc = pldmSendRecv(requestMsg, responseMsg);
169
170 if (rc != PLDM_SUCCESS)
171 {
172 std::cerr << "pldmSendRecv: Failed to receive RC = " << rc << "\n";
173 return;
174 }
175
176 auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsg.data());
177 parseResponseMsg(responsePtr, responseMsg.size() - sizeof(pldm_msg_hdr));
178}
179
180int CommandInterface::pldmSendRecv(std::vector<uint8_t>& requestMsg,
181 std::vector<uint8_t>& responseMsg)
182{
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +0800183 // Insert the PLDM message type and EID at the beginning of the
184 // msg.
John Wang58a0e062019-11-08 15:38:15 +0800185 requestMsg.insert(requestMsg.begin(), MCTP_MSG_TYPE_PLDM);
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +0800186 requestMsg.insert(requestMsg.begin(), mctp_eid);
John Wang58a0e062019-11-08 15:38:15 +0800187
Sridevi Rameshc91822b2020-02-27 09:26:41 -0600188 bool mctpVerbose = pldmVerbose;
189
190 // By default enable request/response msgs for pldmtool raw commands.
191 if (CommandInterface::pldmType == "raw")
192 {
193 pldmVerbose = true;
194 }
195
Tom Josephe5268cd2021-09-07 13:04:03 +0530196 if (pldmVerbose)
197 {
198 std::cout << "pldmtool: ";
199 printBuffer(Tx, requestMsg);
200 }
John Wang58a0e062019-11-08 15:38:15 +0800201
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +0800202 if (mctp_eid != PLDM_ENTITY_ID)
John Wang58a0e062019-11-08 15:38:15 +0800203 {
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +0800204 int fd = pldm_open();
205 if (-1 == fd)
206 {
207 std::cerr << "failed to init mctp "
208 << "\n";
209 return -1;
210 }
211 uint8_t* responseMessage = nullptr;
212 size_t responseMessageSize{};
Sampa Misra9f8d2b02021-03-24 08:33:14 +0000213 pldm_send_recv(mctp_eid, fd, requestMsg.data() + 2,
214 requestMsg.size() - 2, &responseMessage,
215 &responseMessageSize);
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +0800216
217 responseMsg.resize(responseMessageSize);
218 memcpy(responseMsg.data(), responseMessage, responseMsg.size());
219
Dung Cao2b85d782022-05-24 09:28:48 +0000220 shutdown(fd, SHUT_RDWR);
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +0800221 free(responseMessage);
Dung Cao2b85d782022-05-24 09:28:48 +0000222
Tom Josephe5268cd2021-09-07 13:04:03 +0530223 if (pldmVerbose)
224 {
225 std::cout << "pldmtool: ";
226 printBuffer(Rx, responseMsg);
227 }
John Wang58a0e062019-11-08 15:38:15 +0800228 }
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +0800229 else
230 {
Sridevi Rameshc91822b2020-02-27 09:26:41 -0600231 mctpSockSendRecv(requestMsg, responseMsg, mctpVerbose);
Tom Josephe5268cd2021-09-07 13:04:03 +0530232 if (pldmVerbose)
233 {
234 std::cout << "pldmtool: ";
235 printBuffer(Rx, responseMsg);
236 }
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +0800237 responseMsg.erase(responseMsg.begin(),
238 responseMsg.begin() + 2 /* skip the mctp header */);
239 }
John Wangb754eee2020-02-15 16:10:25 +0800240 return PLDM_SUCCESS;
John Wang58a0e062019-11-08 15:38:15 +0800241}
John Wang58a0e062019-11-08 15:38:15 +0800242} // namespace helper
Sampa Misraaa8ae722019-12-12 03:20:40 -0600243} // namespace pldmtool