blob: db44c5a35a8dd8d9c6b45ba40d82cbffbafa9d6a [file] [log] [blame]
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -05001#include "pldm_cmd_helper.hpp"
2
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -06003#include "xyz/openbmc_project/Common/error.hpp"
4
George Liuc453e162022-12-21 17:16:23 +08005#include <libpldm/pldm.h>
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -06006#include <systemd/sd-bus.h>
7
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -06008#include <sdbusplus/server.hpp>
9#include <xyz/openbmc_project/Logging/Entry/server.hpp>
10
George Liu6492f522020-06-16 10:34:05 +080011#include <exception>
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +080012
Brad Bishop5079ac42021-08-19 18:35:06 -040013using namespace pldm::utils;
14
John Wang58a0e062019-11-08 15:38:15 +080015namespace pldmtool
16{
John Wang58a0e062019-11-08 15:38:15 +080017namespace helper
18{
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050019/*
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050020 * Initialize the socket, send pldm command & recieve response from socket
21 *
22 */
23int mctpSockSendRecv(const std::vector<uint8_t>& requestMsg,
Sridevi Rameshc91822b2020-02-27 09:26:41 -060024 std::vector<uint8_t>& responseMsg, bool pldmVerbose)
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050025{
26 const char devPath[] = "\0mctp-mux";
27 int returnCode = 0;
28
29 int sockFd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
30 if (-1 == sockFd)
31 {
32 returnCode = -errno;
Sampa Misraaa8ae722019-12-12 03:20:40 -060033 std::cerr << "Failed to create the socket : RC = " << sockFd << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050034 return returnCode;
35 }
Sridevi Rameshc91822b2020-02-27 09:26:41 -060036 Logger(pldmVerbose, "Success in creating the socket : RC = ", sockFd);
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050037
38 struct sockaddr_un addr
George Liu6492f522020-06-16 10:34:05 +080039 {};
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050040 addr.sun_family = AF_UNIX;
41
42 memcpy(addr.sun_path, devPath, sizeof(devPath) - 1);
43
44 CustomFD socketFd(sockFd);
45 int result = connect(socketFd(), reinterpret_cast<struct sockaddr*>(&addr),
46 sizeof(devPath) + sizeof(addr.sun_family) - 1);
47 if (-1 == result)
48 {
49 returnCode = -errno;
John Wang58a0e062019-11-08 15:38:15 +080050 std::cerr << "Failed to connect to socket : RC = " << returnCode
Sampa Misraaa8ae722019-12-12 03:20:40 -060051 << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050052 return returnCode;
53 }
Sridevi Rameshc91822b2020-02-27 09:26:41 -060054 Logger(pldmVerbose, "Success in connecting to socket : RC = ", returnCode);
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050055
56 auto pldmType = MCTP_MSG_TYPE_PLDM;
57 result = write(socketFd(), &pldmType, sizeof(pldmType));
58 if (-1 == result)
59 {
60 returnCode = -errno;
John Wang58a0e062019-11-08 15:38:15 +080061 std::cerr << "Failed to send message type as pldm to mctp : RC = "
Sampa Misraaa8ae722019-12-12 03:20:40 -060062 << returnCode << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050063 return returnCode;
64 }
Sridevi Rameshc91822b2020-02-27 09:26:41 -060065 Logger(
66 pldmVerbose,
67 "Success in sending message type as pldm to mctp : RC = ", returnCode);
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050068
69 result = send(socketFd(), requestMsg.data(), requestMsg.size(), 0);
70 if (-1 == result)
71 {
72 returnCode = -errno;
Sampa Misraaa8ae722019-12-12 03:20:40 -060073 std::cerr << "Write to socket failure : RC = " << returnCode << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050074 return returnCode;
75 }
Sridevi Rameshc91822b2020-02-27 09:26:41 -060076 Logger(pldmVerbose, "Write to socket successful : RC = ", result);
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050077
78 // Read the response from socket
79 ssize_t peekedLength = recv(socketFd(), nullptr, 0, MSG_TRUNC | MSG_PEEK);
80 if (0 == peekedLength)
81 {
John Wang58a0e062019-11-08 15:38:15 +080082 std::cerr << "Socket is closed : peekedLength = " << peekedLength
Sampa Misraaa8ae722019-12-12 03:20:40 -060083 << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050084 return returnCode;
85 }
86 else if (peekedLength <= -1)
87 {
88 returnCode = -errno;
Sampa Misraaa8ae722019-12-12 03:20:40 -060089 std::cerr << "recv() system call failed : RC = " << returnCode << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050090 return returnCode;
91 }
92 else
93 {
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -060094 auto reqhdr = reinterpret_cast<const pldm_msg_hdr*>(&requestMsg[2]);
95 do
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050096 {
Patrick Williams6da4f912023-05-10 07:50:53 -050097 ssize_t peekedLength = recv(socketFd(), nullptr, 0,
98 MSG_PEEK | MSG_TRUNC);
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050099 responseMsg.resize(peekedLength);
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600100 auto recvDataLength =
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500101 recv(socketFd(), reinterpret_cast<void*>(responseMsg.data()),
102 peekedLength, 0);
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600103 auto resphdr =
104 reinterpret_cast<const pldm_msg_hdr*>(&responseMsg[2]);
105 if (recvDataLength == peekedLength &&
106 resphdr->instance_id == reqhdr->instance_id &&
107 resphdr->request != PLDM_REQUEST)
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500108 {
Sridevi Rameshc91822b2020-02-27 09:26:41 -0600109 Logger(pldmVerbose, "Total length:", recvDataLength);
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600110 break;
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500111 }
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600112 else if (recvDataLength != peekedLength)
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500113 {
John Wang58a0e062019-11-08 15:38:15 +0800114 std::cerr << "Failure to read response length packet: length = "
Sampa Misraaa8ae722019-12-12 03:20:40 -0600115 << recvDataLength << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500116 return returnCode;
117 }
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600118 } while (1);
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500119 }
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +0800120
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500121 returnCode = shutdown(socketFd(), SHUT_RDWR);
122 if (-1 == returnCode)
123 {
124 returnCode = -errno;
John Wang58a0e062019-11-08 15:38:15 +0800125 std::cerr << "Failed to shutdown the socket : RC = " << returnCode
Sampa Misraaa8ae722019-12-12 03:20:40 -0600126 << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500127 return returnCode;
128 }
129
Sridevi Rameshc91822b2020-02-27 09:26:41 -0600130 Logger(pldmVerbose, "Shutdown Socket successful : RC = ", returnCode);
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500131 return PLDM_SUCCESS;
132}
John Wang58a0e062019-11-08 15:38:15 +0800133
134void CommandInterface::exec()
135{
Dung Cao3d03f3f2023-09-07 06:51:33 +0000136 instanceId = instanceIdDb.next(mctp_eid);
John Wang58a0e062019-11-08 15:38:15 +0800137 auto [rc, requestMsg] = createRequestMsg();
138 if (rc != PLDM_SUCCESS)
139 {
Dung Cao3d03f3f2023-09-07 06:51:33 +0000140 instanceIdDb.free(mctp_eid, instanceId);
John Wang58a0e062019-11-08 15:38:15 +0800141 std::cerr << "Failed to encode request message for " << pldmType << ":"
Sampa Misraaa8ae722019-12-12 03:20:40 -0600142 << commandName << " rc = " << rc << "\n";
John Wang58a0e062019-11-08 15:38:15 +0800143 return;
144 }
145
John Wangb754eee2020-02-15 16:10:25 +0800146 std::vector<uint8_t> responseMsg;
147 rc = pldmSendRecv(requestMsg, responseMsg);
148
149 if (rc != PLDM_SUCCESS)
150 {
Dung Cao3d03f3f2023-09-07 06:51:33 +0000151 instanceIdDb.free(mctp_eid, instanceId);
John Wangb754eee2020-02-15 16:10:25 +0800152 std::cerr << "pldmSendRecv: Failed to receive RC = " << rc << "\n";
153 return;
154 }
155
156 auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsg.data());
157 parseResponseMsg(responsePtr, responseMsg.size() - sizeof(pldm_msg_hdr));
Dung Cao3d03f3f2023-09-07 06:51:33 +0000158 instanceIdDb.free(mctp_eid, instanceId);
John Wangb754eee2020-02-15 16:10:25 +0800159}
160
161int CommandInterface::pldmSendRecv(std::vector<uint8_t>& requestMsg,
162 std::vector<uint8_t>& responseMsg)
163{
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +0800164 // Insert the PLDM message type and EID at the beginning of the
165 // msg.
John Wang58a0e062019-11-08 15:38:15 +0800166 requestMsg.insert(requestMsg.begin(), MCTP_MSG_TYPE_PLDM);
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +0800167 requestMsg.insert(requestMsg.begin(), mctp_eid);
John Wang58a0e062019-11-08 15:38:15 +0800168
Sridevi Rameshc91822b2020-02-27 09:26:41 -0600169 bool mctpVerbose = pldmVerbose;
170
171 // By default enable request/response msgs for pldmtool raw commands.
172 if (CommandInterface::pldmType == "raw")
173 {
174 pldmVerbose = true;
175 }
176
Tom Josephe5268cd2021-09-07 13:04:03 +0530177 if (pldmVerbose)
178 {
179 std::cout << "pldmtool: ";
180 printBuffer(Tx, requestMsg);
181 }
John Wang58a0e062019-11-08 15:38:15 +0800182
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +0800183 if (mctp_eid != PLDM_ENTITY_ID)
John Wang58a0e062019-11-08 15:38:15 +0800184 {
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +0800185 int fd = pldm_open();
186 if (-1 == fd)
187 {
188 std::cerr << "failed to init mctp "
189 << "\n";
190 return -1;
191 }
192 uint8_t* responseMessage = nullptr;
193 size_t responseMessageSize{};
Sampa Misra9f8d2b02021-03-24 08:33:14 +0000194 pldm_send_recv(mctp_eid, fd, requestMsg.data() + 2,
195 requestMsg.size() - 2, &responseMessage,
196 &responseMessageSize);
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +0800197
198 responseMsg.resize(responseMessageSize);
199 memcpy(responseMsg.data(), responseMessage, responseMsg.size());
200
Dung Cao2b85d782022-05-24 09:28:48 +0000201 shutdown(fd, SHUT_RDWR);
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +0800202 free(responseMessage);
Dung Cao2b85d782022-05-24 09:28:48 +0000203
Tom Josephe5268cd2021-09-07 13:04:03 +0530204 if (pldmVerbose)
205 {
206 std::cout << "pldmtool: ";
207 printBuffer(Rx, responseMsg);
208 }
John Wang58a0e062019-11-08 15:38:15 +0800209 }
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +0800210 else
211 {
Sridevi Rameshc91822b2020-02-27 09:26:41 -0600212 mctpSockSendRecv(requestMsg, responseMsg, mctpVerbose);
Tom Josephe5268cd2021-09-07 13:04:03 +0530213 if (pldmVerbose)
214 {
215 std::cout << "pldmtool: ";
216 printBuffer(Rx, responseMsg);
217 }
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +0800218 responseMsg.erase(responseMsg.begin(),
219 responseMsg.begin() + 2 /* skip the mctp header */);
220 }
John Wangb754eee2020-02-15 16:10:25 +0800221 return PLDM_SUCCESS;
John Wang58a0e062019-11-08 15:38:15 +0800222}
John Wang58a0e062019-11-08 15:38:15 +0800223} // namespace helper
Sampa Misraaa8ae722019-12-12 03:20:40 -0600224} // namespace pldmtool