| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 1 | #include "pldm_cmd_helper.hpp" | 
|  | 2 |  | 
| George Liu | 6492f52 | 2020-06-16 10:34:05 +0800 | [diff] [blame] | 3 | #include "libpldm/requester/pldm.h" | 
|  | 4 |  | 
| Pavithra Barithaya | ac3c45a | 2020-03-05 02:28:26 -0600 | [diff] [blame] | 5 | #include "xyz/openbmc_project/Common/error.hpp" | 
|  | 6 |  | 
|  | 7 | #include <systemd/sd-bus.h> | 
|  | 8 |  | 
| Pavithra Barithaya | ac3c45a | 2020-03-05 02:28:26 -0600 | [diff] [blame] | 9 | #include <sdbusplus/server.hpp> | 
|  | 10 | #include <xyz/openbmc_project/Logging/Entry/server.hpp> | 
|  | 11 |  | 
| George Liu | 6492f52 | 2020-06-16 10:34:05 +0800 | [diff] [blame] | 12 | #include <exception> | 
| Pavithra Barithaya | f5ad6c7 | 2019-12-06 15:10:52 +0800 | [diff] [blame] | 13 |  | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 14 | namespace pldmtool | 
|  | 15 | { | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 16 |  | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 17 | namespace helper | 
|  | 18 | { | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 19 | /* | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 20 | * Initialize the socket, send pldm command & recieve response from socket | 
|  | 21 | * | 
|  | 22 | */ | 
|  | 23 | int mctpSockSendRecv(const std::vector<uint8_t>& requestMsg, | 
| Sridevi Ramesh | c91822b | 2020-02-27 09:26:41 -0600 | [diff] [blame] | 24 | std::vector<uint8_t>& responseMsg, bool pldmVerbose) | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 25 | { | 
| Sridevi Ramesh | c91822b | 2020-02-27 09:26:41 -0600 | [diff] [blame] | 26 |  | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 27 | const char devPath[] = "\0mctp-mux"; | 
|  | 28 | int returnCode = 0; | 
|  | 29 |  | 
|  | 30 | int sockFd = socket(AF_UNIX, SOCK_SEQPACKET, 0); | 
|  | 31 | if (-1 == sockFd) | 
|  | 32 | { | 
|  | 33 | returnCode = -errno; | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 34 | std::cerr << "Failed to create the socket : RC = " << sockFd << "\n"; | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 35 | return returnCode; | 
|  | 36 | } | 
| Sridevi Ramesh | c91822b | 2020-02-27 09:26:41 -0600 | [diff] [blame] | 37 | Logger(pldmVerbose, "Success in creating the socket : RC = ", sockFd); | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 38 |  | 
|  | 39 | struct sockaddr_un addr | 
| George Liu | 6492f52 | 2020-06-16 10:34:05 +0800 | [diff] [blame] | 40 | {}; | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 41 | addr.sun_family = AF_UNIX; | 
|  | 42 |  | 
|  | 43 | memcpy(addr.sun_path, devPath, sizeof(devPath) - 1); | 
|  | 44 |  | 
|  | 45 | CustomFD socketFd(sockFd); | 
|  | 46 | int result = connect(socketFd(), reinterpret_cast<struct sockaddr*>(&addr), | 
|  | 47 | sizeof(devPath) + sizeof(addr.sun_family) - 1); | 
|  | 48 | if (-1 == result) | 
|  | 49 | { | 
|  | 50 | returnCode = -errno; | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 51 | std::cerr << "Failed to connect to socket : RC = " << returnCode | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 52 | << "\n"; | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 53 | return returnCode; | 
|  | 54 | } | 
| Sridevi Ramesh | c91822b | 2020-02-27 09:26:41 -0600 | [diff] [blame] | 55 | Logger(pldmVerbose, "Success in connecting to socket : RC = ", returnCode); | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 56 |  | 
|  | 57 | auto pldmType = MCTP_MSG_TYPE_PLDM; | 
|  | 58 | result = write(socketFd(), &pldmType, sizeof(pldmType)); | 
|  | 59 | if (-1 == result) | 
|  | 60 | { | 
|  | 61 | returnCode = -errno; | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 62 | std::cerr << "Failed to send message type as pldm to mctp : RC = " | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 63 | << returnCode << "\n"; | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 64 | return returnCode; | 
|  | 65 | } | 
| Sridevi Ramesh | c91822b | 2020-02-27 09:26:41 -0600 | [diff] [blame] | 66 | Logger( | 
|  | 67 | pldmVerbose, | 
|  | 68 | "Success in sending message type as pldm to mctp : RC = ", returnCode); | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 69 |  | 
|  | 70 | result = send(socketFd(), requestMsg.data(), requestMsg.size(), 0); | 
|  | 71 | if (-1 == result) | 
|  | 72 | { | 
|  | 73 | returnCode = -errno; | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 74 | std::cerr << "Write to socket failure : RC = " << returnCode << "\n"; | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 75 | return returnCode; | 
|  | 76 | } | 
| Sridevi Ramesh | c91822b | 2020-02-27 09:26:41 -0600 | [diff] [blame] | 77 | Logger(pldmVerbose, "Write to socket successful : RC = ", result); | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 78 |  | 
|  | 79 | // Read the response from socket | 
|  | 80 | ssize_t peekedLength = recv(socketFd(), nullptr, 0, MSG_TRUNC | MSG_PEEK); | 
|  | 81 | if (0 == peekedLength) | 
|  | 82 | { | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 83 | std::cerr << "Socket is closed : peekedLength = " << peekedLength | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 84 | << "\n"; | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 85 | return returnCode; | 
|  | 86 | } | 
|  | 87 | else if (peekedLength <= -1) | 
|  | 88 | { | 
|  | 89 | returnCode = -errno; | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 90 | std::cerr << "recv() system call failed : RC = " << returnCode << "\n"; | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 91 | return returnCode; | 
|  | 92 | } | 
|  | 93 | else | 
|  | 94 | { | 
| Pavithra Barithaya | ac3c45a | 2020-03-05 02:28:26 -0600 | [diff] [blame] | 95 | auto reqhdr = reinterpret_cast<const pldm_msg_hdr*>(&requestMsg[2]); | 
|  | 96 | do | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 97 | { | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 98 | ssize_t peekedLength = | 
|  | 99 | recv(socketFd(), nullptr, 0, MSG_PEEK | MSG_TRUNC); | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 100 | responseMsg.resize(peekedLength); | 
| Pavithra Barithaya | ac3c45a | 2020-03-05 02:28:26 -0600 | [diff] [blame] | 101 | auto recvDataLength = | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 102 | recv(socketFd(), reinterpret_cast<void*>(responseMsg.data()), | 
|  | 103 | peekedLength, 0); | 
| Pavithra Barithaya | ac3c45a | 2020-03-05 02:28:26 -0600 | [diff] [blame] | 104 | auto resphdr = | 
|  | 105 | reinterpret_cast<const pldm_msg_hdr*>(&responseMsg[2]); | 
|  | 106 | if (recvDataLength == peekedLength && | 
|  | 107 | resphdr->instance_id == reqhdr->instance_id && | 
|  | 108 | resphdr->request != PLDM_REQUEST) | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 109 | { | 
| Sridevi Ramesh | c91822b | 2020-02-27 09:26:41 -0600 | [diff] [blame] | 110 | Logger(pldmVerbose, "Total length:", recvDataLength); | 
| Pavithra Barithaya | ac3c45a | 2020-03-05 02:28:26 -0600 | [diff] [blame] | 111 | break; | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 112 | } | 
| Pavithra Barithaya | ac3c45a | 2020-03-05 02:28:26 -0600 | [diff] [blame] | 113 | else if (recvDataLength != peekedLength) | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 114 | { | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 115 | std::cerr << "Failure to read response length packet: length = " | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 116 | << recvDataLength << "\n"; | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 117 | return returnCode; | 
|  | 118 | } | 
| Pavithra Barithaya | ac3c45a | 2020-03-05 02:28:26 -0600 | [diff] [blame] | 119 | } while (1); | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 120 | } | 
| Pavithra Barithaya | f5ad6c7 | 2019-12-06 15:10:52 +0800 | [diff] [blame] | 121 |  | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 122 | returnCode = shutdown(socketFd(), SHUT_RDWR); | 
|  | 123 | if (-1 == returnCode) | 
|  | 124 | { | 
|  | 125 | returnCode = -errno; | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 126 | std::cerr << "Failed to shutdown the socket : RC = " << returnCode | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 127 | << "\n"; | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 128 | return returnCode; | 
|  | 129 | } | 
|  | 130 |  | 
| Sridevi Ramesh | c91822b | 2020-02-27 09:26:41 -0600 | [diff] [blame] | 131 | Logger(pldmVerbose, "Shutdown Socket successful :  RC = ", returnCode); | 
| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 132 | return PLDM_SUCCESS; | 
|  | 133 | } | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 134 |  | 
|  | 135 | void CommandInterface::exec() | 
|  | 136 | { | 
| Pavithra Barithaya | ac3c45a | 2020-03-05 02:28:26 -0600 | [diff] [blame] | 137 | static constexpr auto pldmObjPath = "/xyz/openbmc_project/pldm"; | 
|  | 138 | static constexpr auto pldmRequester = "xyz.openbmc_project.PLDM.Requester"; | 
|  | 139 | auto& bus = pldm::utils::DBusHandler::getBus(); | 
|  | 140 | try | 
|  | 141 | { | 
|  | 142 | auto service = | 
|  | 143 | pldm::utils::DBusHandler().getService(pldmObjPath, pldmRequester); | 
|  | 144 | auto method = bus.new_method_call(service.c_str(), pldmObjPath, | 
|  | 145 | pldmRequester, "GetInstanceId"); | 
|  | 146 | method.append(mctp_eid); | 
|  | 147 | auto reply = bus.call(method); | 
|  | 148 | reply.read(instanceId); | 
|  | 149 | } | 
|  | 150 | catch (const std::exception& e) | 
|  | 151 | { | 
|  | 152 | std::cerr << "GetInstanceId D-Bus call failed, MCTP id = " << mctp_eid | 
|  | 153 | << ", error = " << e.what() << "\n"; | 
|  | 154 | return; | 
|  | 155 | } | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 156 | auto [rc, requestMsg] = createRequestMsg(); | 
|  | 157 | if (rc != PLDM_SUCCESS) | 
|  | 158 | { | 
|  | 159 | std::cerr << "Failed to encode request message for " << pldmType << ":" | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 160 | << commandName << " rc = " << rc << "\n"; | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 161 | return; | 
|  | 162 | } | 
|  | 163 |  | 
| John Wang | b754eee | 2020-02-15 16:10:25 +0800 | [diff] [blame] | 164 | std::vector<uint8_t> responseMsg; | 
|  | 165 | rc = pldmSendRecv(requestMsg, responseMsg); | 
|  | 166 |  | 
|  | 167 | if (rc != PLDM_SUCCESS) | 
|  | 168 | { | 
|  | 169 | std::cerr << "pldmSendRecv: Failed to receive RC = " << rc << "\n"; | 
|  | 170 | return; | 
|  | 171 | } | 
|  | 172 |  | 
|  | 173 | auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsg.data()); | 
|  | 174 | parseResponseMsg(responsePtr, responseMsg.size() - sizeof(pldm_msg_hdr)); | 
|  | 175 | } | 
|  | 176 |  | 
|  | 177 | int CommandInterface::pldmSendRecv(std::vector<uint8_t>& requestMsg, | 
|  | 178 | std::vector<uint8_t>& responseMsg) | 
|  | 179 | { | 
| Sridevi Ramesh | c91822b | 2020-02-27 09:26:41 -0600 | [diff] [blame] | 180 |  | 
| Pavithra Barithaya | f5ad6c7 | 2019-12-06 15:10:52 +0800 | [diff] [blame] | 181 | // Insert the PLDM message type and EID at the beginning of the | 
|  | 182 | // msg. | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 183 | requestMsg.insert(requestMsg.begin(), MCTP_MSG_TYPE_PLDM); | 
| Pavithra Barithaya | f5ad6c7 | 2019-12-06 15:10:52 +0800 | [diff] [blame] | 184 | requestMsg.insert(requestMsg.begin(), mctp_eid); | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 185 |  | 
| Sridevi Ramesh | c91822b | 2020-02-27 09:26:41 -0600 | [diff] [blame] | 186 | bool mctpVerbose = pldmVerbose; | 
|  | 187 |  | 
|  | 188 | // By default enable request/response msgs for pldmtool raw commands. | 
|  | 189 | if (CommandInterface::pldmType == "raw") | 
|  | 190 | { | 
|  | 191 | pldmVerbose = true; | 
|  | 192 | } | 
|  | 193 |  | 
|  | 194 | Logger(pldmVerbose, "Request Message:", ""); | 
|  | 195 | printBuffer(requestMsg, pldmVerbose); | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 196 |  | 
| Pavithra Barithaya | f5ad6c7 | 2019-12-06 15:10:52 +0800 | [diff] [blame] | 197 | if (mctp_eid != PLDM_ENTITY_ID) | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 198 | { | 
| Pavithra Barithaya | f5ad6c7 | 2019-12-06 15:10:52 +0800 | [diff] [blame] | 199 | int fd = pldm_open(); | 
|  | 200 | if (-1 == fd) | 
|  | 201 | { | 
|  | 202 | std::cerr << "failed to init mctp " | 
|  | 203 | << "\n"; | 
|  | 204 | return -1; | 
|  | 205 | } | 
|  | 206 | uint8_t* responseMessage = nullptr; | 
|  | 207 | size_t responseMessageSize{}; | 
| Sampa Misra | 9f8d2b0 | 2021-03-24 08:33:14 +0000 | [diff] [blame] | 208 | pldm_send_recv(mctp_eid, fd, requestMsg.data() + 2, | 
|  | 209 | requestMsg.size() - 2, &responseMessage, | 
|  | 210 | &responseMessageSize); | 
| Pavithra Barithaya | f5ad6c7 | 2019-12-06 15:10:52 +0800 | [diff] [blame] | 211 |  | 
| Sridevi Ramesh | c91822b | 2020-02-27 09:26:41 -0600 | [diff] [blame] | 212 | Logger(pldmVerbose, "Response Message:", ""); | 
| Pavithra Barithaya | f5ad6c7 | 2019-12-06 15:10:52 +0800 | [diff] [blame] | 213 | responseMsg.resize(responseMessageSize); | 
|  | 214 | memcpy(responseMsg.data(), responseMessage, responseMsg.size()); | 
|  | 215 |  | 
|  | 216 | free(responseMessage); | 
| Sridevi Ramesh | c91822b | 2020-02-27 09:26:41 -0600 | [diff] [blame] | 217 | printBuffer(responseMsg, pldmVerbose); | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 218 | } | 
| Pavithra Barithaya | f5ad6c7 | 2019-12-06 15:10:52 +0800 | [diff] [blame] | 219 | else | 
|  | 220 | { | 
| Sridevi Ramesh | c91822b | 2020-02-27 09:26:41 -0600 | [diff] [blame] | 221 | mctpSockSendRecv(requestMsg, responseMsg, mctpVerbose); | 
|  | 222 | Logger(pldmVerbose, "Response Message:", ""); | 
|  | 223 | printBuffer(responseMsg, pldmVerbose); | 
| Pavithra Barithaya | f5ad6c7 | 2019-12-06 15:10:52 +0800 | [diff] [blame] | 224 | responseMsg.erase(responseMsg.begin(), | 
|  | 225 | responseMsg.begin() + 2 /* skip the mctp header */); | 
|  | 226 | } | 
| John Wang | b754eee | 2020-02-15 16:10:25 +0800 | [diff] [blame] | 227 | return PLDM_SUCCESS; | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 228 | } | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 229 | } // namespace helper | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 230 | } // namespace pldmtool |