blob: 1c031212d5db0caec54965b9a55a92474f4f23ba [file] [log] [blame]
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -05001#include "pldm_cmd_helper.hpp"
2
John Wang58a0e062019-11-08 15:38:15 +08003namespace pldmtool
4{
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -05005
John Wang58a0e062019-11-08 15:38:15 +08006namespace helper
7{
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -05008
9/*
10 * print the input buffer
11 *
12 */
13void printBuffer(const std::vector<uint8_t>& buffer)
14{
15 std::ostringstream tempStream;
16 if (!buffer.empty())
17 {
18 for (int byte : buffer)
19 {
20 tempStream << std::setfill('0') << std::setw(2) << std::hex << byte
21 << " ";
22 }
23 }
John Wang58a0e062019-11-08 15:38:15 +080024 std::cout << tempStream.str() << std::endl;
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050025}
26
27/*
28 * Initialize the socket, send pldm command & recieve response from socket
29 *
30 */
31int mctpSockSendRecv(const std::vector<uint8_t>& requestMsg,
32 std::vector<uint8_t>& responseMsg)
33{
34 const char devPath[] = "\0mctp-mux";
35 int returnCode = 0;
36
37 int sockFd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
38 if (-1 == sockFd)
39 {
40 returnCode = -errno;
Sampa Misraaa8ae722019-12-12 03:20:40 -060041 std::cerr << "Failed to create the socket : RC = " << sockFd << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050042 return returnCode;
43 }
John Wang58a0e062019-11-08 15:38:15 +080044 std::cout << "Success in creating the socket : RC = " << sockFd
45 << std::endl;
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050046
47 struct sockaddr_un addr
48 {
49 };
50 addr.sun_family = AF_UNIX;
51
52 memcpy(addr.sun_path, devPath, sizeof(devPath) - 1);
53
54 CustomFD socketFd(sockFd);
55 int result = connect(socketFd(), reinterpret_cast<struct sockaddr*>(&addr),
56 sizeof(devPath) + sizeof(addr.sun_family) - 1);
57 if (-1 == result)
58 {
59 returnCode = -errno;
John Wang58a0e062019-11-08 15:38:15 +080060 std::cerr << "Failed to connect to socket : RC = " << returnCode
Sampa Misraaa8ae722019-12-12 03:20:40 -060061 << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050062 return returnCode;
63 }
John Wang58a0e062019-11-08 15:38:15 +080064 std::cout << "Success in connecting to socket : RC = " << returnCode
65 << std::endl;
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050066
67 auto pldmType = MCTP_MSG_TYPE_PLDM;
68 result = write(socketFd(), &pldmType, sizeof(pldmType));
69 if (-1 == result)
70 {
71 returnCode = -errno;
John Wang58a0e062019-11-08 15:38:15 +080072 std::cerr << "Failed to send message type as pldm to mctp : RC = "
Sampa Misraaa8ae722019-12-12 03:20:40 -060073 << returnCode << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050074 return returnCode;
75 }
John Wang58a0e062019-11-08 15:38:15 +080076 std::cout << "Success in sending message type as pldm to mctp : RC = "
77 << returnCode << std::endl;
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050078
79 result = send(socketFd(), requestMsg.data(), requestMsg.size(), 0);
80 if (-1 == result)
81 {
82 returnCode = -errno;
Sampa Misraaa8ae722019-12-12 03:20:40 -060083 std::cerr << "Write to socket failure : RC = " << returnCode << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050084 return returnCode;
85 }
John Wang58a0e062019-11-08 15:38:15 +080086 std::cout << "Write to socket successful : RC = " << result << std::endl;
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050087
88 // Read the response from socket
89 ssize_t peekedLength = recv(socketFd(), nullptr, 0, MSG_TRUNC | MSG_PEEK);
90 if (0 == peekedLength)
91 {
John Wang58a0e062019-11-08 15:38:15 +080092 std::cerr << "Socket is closed : peekedLength = " << peekedLength
Sampa Misraaa8ae722019-12-12 03:20:40 -060093 << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -050094 return returnCode;
95 }
96 else if (peekedLength <= -1)
97 {
98 returnCode = -errno;
Sampa Misraaa8ae722019-12-12 03:20:40 -060099 std::cerr << "recv() system call failed : RC = " << returnCode << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500100 return returnCode;
101 }
102 else
103 {
104 // loopback response message
105 std::vector<uint8_t> loopBackRespMsg(peekedLength);
106 auto recvDataLength =
107 recv(socketFd(), reinterpret_cast<void*>(loopBackRespMsg.data()),
108 peekedLength, 0);
109 if (recvDataLength == peekedLength)
110 {
John Wang58a0e062019-11-08 15:38:15 +0800111 std::cout << "Total length:" << recvDataLength << std::endl;
112 std::cout << "Loopback response message:" << std::endl;
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500113 printBuffer(loopBackRespMsg);
114 }
115 else
116 {
John Wang58a0e062019-11-08 15:38:15 +0800117 std::cerr << "Failure to read peeked length packet : RC = "
Sampa Misraaa8ae722019-12-12 03:20:40 -0600118 << returnCode << "\n";
119 std::cerr << "peekedLength: " << peekedLength << "\n";
120 std::cerr << "Total length: " << recvDataLength << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500121 return returnCode;
122 }
123
124 // Confirming on the first recv() the Request bit is set in
125 // pldm_msg_hdr struct. If set proceed with recv() or else, quit.
126 auto hdr = reinterpret_cast<const pldm_msg_hdr*>(&loopBackRespMsg[2]);
127 uint8_t request = hdr->request;
128 if (request == PLDM_REQUEST)
129 {
John Wang58a0e062019-11-08 15:38:15 +0800130 std::cout << "On first recv(),response == request : RC = "
131 << returnCode << std::endl;
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500132 ssize_t peekedLength =
133 recv(socketFd(), nullptr, 0, MSG_PEEK | MSG_TRUNC);
134
135 responseMsg.resize(peekedLength);
136 recvDataLength =
137 recv(socketFd(), reinterpret_cast<void*>(responseMsg.data()),
138 peekedLength, 0);
139 if (recvDataLength == peekedLength)
140 {
John Wang58a0e062019-11-08 15:38:15 +0800141 std::cout << "Total length: " << recvDataLength << std::endl;
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500142 }
143 else
144 {
John Wang58a0e062019-11-08 15:38:15 +0800145 std::cerr << "Failure to read response length packet: length = "
Sampa Misraaa8ae722019-12-12 03:20:40 -0600146 << recvDataLength << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500147 return returnCode;
148 }
149 }
150 else
151 {
John Wang58a0e062019-11-08 15:38:15 +0800152 std::cerr << "On first recv(),request != response : RC = "
Sampa Misraaa8ae722019-12-12 03:20:40 -0600153 << returnCode << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500154 return returnCode;
155 }
156 }
157 returnCode = shutdown(socketFd(), SHUT_RDWR);
158 if (-1 == returnCode)
159 {
160 returnCode = -errno;
John Wang58a0e062019-11-08 15:38:15 +0800161 std::cerr << "Failed to shutdown the socket : RC = " << returnCode
Sampa Misraaa8ae722019-12-12 03:20:40 -0600162 << "\n";
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500163 return returnCode;
164 }
165
John Wang58a0e062019-11-08 15:38:15 +0800166 std::cout << "Shutdown Socket successful : RC = " << returnCode
167 << std::endl;
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -0500168 return PLDM_SUCCESS;
169}
John Wang58a0e062019-11-08 15:38:15 +0800170
171void CommandInterface::exec()
172{
173 auto [rc, requestMsg] = createRequestMsg();
174 if (rc != PLDM_SUCCESS)
175 {
176 std::cerr << "Failed to encode request message for " << pldmType << ":"
Sampa Misraaa8ae722019-12-12 03:20:40 -0600177 << commandName << " rc = " << rc << "\n";
John Wang58a0e062019-11-08 15:38:15 +0800178 return;
179 }
180
181 std::cout << "Encode request successfully" << std::endl;
182
John Wangb754eee2020-02-15 16:10:25 +0800183 std::vector<uint8_t> responseMsg;
184 rc = pldmSendRecv(requestMsg, responseMsg);
185
186 if (rc != PLDM_SUCCESS)
187 {
188 std::cerr << "pldmSendRecv: Failed to receive RC = " << rc << "\n";
189 return;
190 }
191
192 auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsg.data());
193 parseResponseMsg(responsePtr, responseMsg.size() - sizeof(pldm_msg_hdr));
194}
195
196int CommandInterface::pldmSendRecv(std::vector<uint8_t>& requestMsg,
197 std::vector<uint8_t>& responseMsg)
198{
199
John Wang58a0e062019-11-08 15:38:15 +0800200 // Insert the PLDM message type and EID at the begining of the request msg.
201 requestMsg.insert(requestMsg.begin(), MCTP_MSG_TYPE_PLDM);
202 requestMsg.insert(requestMsg.begin(), PLDM_ENTITY_ID);
203
204 std::cout << "Request Message:" << std::endl;
205 printBuffer(requestMsg);
206
John Wangb754eee2020-02-15 16:10:25 +0800207 auto rc = mctpSockSendRecv(requestMsg, responseMsg);
John Wang58a0e062019-11-08 15:38:15 +0800208
209 if (rc != PLDM_SUCCESS)
210 {
John Wangb754eee2020-02-15 16:10:25 +0800211 std::cerr << "Failed to receive from mctpSocket: RC = " << rc << "\n";
212 return rc;
John Wang58a0e062019-11-08 15:38:15 +0800213 }
214
215 std::cout << "Response Message:" << std::endl;
216 printBuffer(responseMsg);
217
John Wangb754eee2020-02-15 16:10:25 +0800218 responseMsg.erase(responseMsg.begin(),
219 responseMsg.begin() + 2 /* skip the mctp header */);
220 return PLDM_SUCCESS;
John Wang58a0e062019-11-08 15:38:15 +0800221}
222
223} // namespace helper
Sampa Misraaa8ae722019-12-12 03:20:40 -0600224} // namespace pldmtool