| Deepak Kodihalli | 4de4d00 | 2019-11-11 02:41:43 -0600 | [diff] [blame] | 1 | #include "dbus_impl_requester.hpp" | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 2 | #include "invoker.hpp" | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 3 | #include "libpldmresponder/base.hpp" | 
 | 4 | #include "libpldmresponder/bios.hpp" | 
| Deepak Kodihalli | e60c582 | 2019-10-23 03:26:15 -0500 | [diff] [blame] | 5 | #include "libpldmresponder/fru.hpp" | 
| Sampa Misra | a2fa070 | 2019-05-31 01:28:55 -0500 | [diff] [blame] | 6 | #include "libpldmresponder/platform.hpp" | 
| George Liu | 8340957 | 2019-12-24 18:42:54 +0800 | [diff] [blame] | 7 | #include "utils.hpp" | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 8 |  | 
 | 9 | #include <err.h> | 
| Jinu Joy Thomas | 75dd442 | 2019-07-22 12:47:12 +0530 | [diff] [blame] | 10 | #include <getopt.h> | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 11 | #include <poll.h> | 
 | 12 | #include <stdlib.h> | 
 | 13 | #include <sys/socket.h> | 
 | 14 | #include <sys/types.h> | 
 | 15 | #include <sys/un.h> | 
 | 16 | #include <unistd.h> | 
 | 17 |  | 
 | 18 | #include <cstdio> | 
 | 19 | #include <cstring> | 
 | 20 | #include <iomanip> | 
| Jinu Joy Thomas | 75dd442 | 2019-07-22 12:47:12 +0530 | [diff] [blame] | 21 | #include <iostream> | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 22 | #include <iterator> | 
| Deepak Kodihalli | 37998bf | 2019-11-11 04:06:53 -0600 | [diff] [blame] | 23 | #include <sdeventplus/event.hpp> | 
 | 24 | #include <sdeventplus/source/io.hpp> | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 25 | #include <sstream> | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 26 | #include <stdexcept> | 
| Jinu Joy Thomas | 75dd442 | 2019-07-22 12:47:12 +0530 | [diff] [blame] | 27 | #include <string> | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 28 | #include <vector> | 
 | 29 |  | 
 | 30 | #include "libpldm/base.h" | 
 | 31 | #include "libpldm/bios.h" | 
| Sampa Misra | a2fa070 | 2019-05-31 01:28:55 -0500 | [diff] [blame] | 32 | #include "libpldm/platform.h" | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 33 |  | 
 | 34 | #ifdef OEM_IBM | 
 | 35 | #include "libpldmresponder/file_io.hpp" | 
 | 36 | #endif | 
 | 37 |  | 
 | 38 | constexpr uint8_t MCTP_MSG_TYPE_PLDM = 1; | 
 | 39 |  | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 40 | using namespace pldm::responder; | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 41 | using namespace pldm; | 
| Deepak Kodihalli | 37998bf | 2019-11-11 04:06:53 -0600 | [diff] [blame] | 42 | using namespace sdeventplus; | 
 | 43 | using namespace sdeventplus::source; | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 44 |  | 
| Deepak Kodihalli | 4de4d00 | 2019-11-11 02:41:43 -0600 | [diff] [blame] | 45 | static Response processRxMsg(const std::vector<uint8_t>& requestMsg, | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 46 |                              Invoker& invoker, dbus_api::Requester& requester) | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 47 | { | 
 | 48 |  | 
 | 49 |     Response response; | 
 | 50 |     uint8_t eid = requestMsg[0]; | 
 | 51 |     uint8_t type = requestMsg[1]; | 
 | 52 |     pldm_header_info hdrFields{}; | 
 | 53 |     auto hdr = reinterpret_cast<const pldm_msg_hdr*>( | 
 | 54 |         requestMsg.data() + sizeof(eid) + sizeof(type)); | 
 | 55 |     if (PLDM_SUCCESS != unpack_pldm_header(hdr, &hdrFields)) | 
 | 56 |     { | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 57 |         std::cerr << "Empty PLDM request header \n"; | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 58 |     } | 
 | 59 |     else if (PLDM_RESPONSE != hdrFields.msg_type) | 
 | 60 |     { | 
 | 61 |         auto request = reinterpret_cast<const pldm_msg*>(hdr); | 
 | 62 |         size_t requestLen = requestMsg.size() - sizeof(struct pldm_msg_hdr) - | 
 | 63 |                             sizeof(eid) - sizeof(type); | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 64 |         try | 
 | 65 |         { | 
 | 66 |             response = invoker.handle(hdrFields.pldm_type, hdrFields.command, | 
 | 67 |                                       request, requestLen); | 
 | 68 |         } | 
 | 69 |         catch (const std::out_of_range& e) | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 70 |         { | 
 | 71 |             uint8_t completion_code = PLDM_ERROR_UNSUPPORTED_PLDM_CMD; | 
 | 72 |             response.resize(sizeof(pldm_msg_hdr)); | 
 | 73 |             auto responseHdr = reinterpret_cast<pldm_msg_hdr*>(response.data()); | 
 | 74 |             pldm_header_info header{}; | 
 | 75 |             header.msg_type = PLDM_RESPONSE; | 
 | 76 |             header.instance = hdrFields.instance; | 
 | 77 |             header.pldm_type = hdrFields.pldm_type; | 
 | 78 |             header.command = hdrFields.command; | 
 | 79 |             auto result = pack_pldm_header(&header, responseHdr); | 
 | 80 |             if (PLDM_SUCCESS != result) | 
 | 81 |             { | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 82 |                 std::cerr << "Failed adding response header \n"; | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 83 |             } | 
 | 84 |             response.insert(response.end(), completion_code); | 
 | 85 |         } | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 86 |     } | 
| Deepak Kodihalli | 4de4d00 | 2019-11-11 02:41:43 -0600 | [diff] [blame] | 87 |     else | 
 | 88 |     { | 
 | 89 |         requester.markFree(eid, hdr->instance_id); | 
 | 90 |     } | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 91 |     return response; | 
 | 92 | } | 
 | 93 |  | 
 | 94 | void printBuffer(const std::vector<uint8_t>& buffer) | 
 | 95 | { | 
 | 96 |     std::ostringstream tempStream; | 
 | 97 |     tempStream << "Buffer Data: "; | 
 | 98 |     if (!buffer.empty()) | 
 | 99 |     { | 
 | 100 |         for (int byte : buffer) | 
 | 101 |         { | 
 | 102 |             tempStream << std::setfill('0') << std::setw(2) << std::hex << byte | 
 | 103 |                        << " "; | 
 | 104 |         } | 
 | 105 |     } | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 106 |     std::cout << tempStream.str().c_str() << std::endl; | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 107 | } | 
 | 108 |  | 
| Jinu Joy Thomas | 75dd442 | 2019-07-22 12:47:12 +0530 | [diff] [blame] | 109 | void optionUsage(void) | 
 | 110 | { | 
 | 111 |     std::cerr << "Usage: pldmd [options]\n"; | 
 | 112 |     std::cerr << "Options:\n"; | 
 | 113 |     std::cerr | 
 | 114 |         << "  --verbose=<0/1>  0 - Disable verbosity, 1 - Enable verbosity\n"; | 
 | 115 |     std::cerr << "Defaulted settings:  --verbose=0 \n"; | 
 | 116 | } | 
 | 117 |  | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 118 | int main(int argc, char** argv) | 
 | 119 | { | 
 | 120 |  | 
| Jinu Joy Thomas | 75dd442 | 2019-07-22 12:47:12 +0530 | [diff] [blame] | 121 |     bool verbose = false; | 
 | 122 |     static struct option long_options[] = { | 
 | 123 |         {"verbose", required_argument, 0, 'v'}, {0, 0, 0, 0}}; | 
 | 124 |  | 
 | 125 |     auto argflag = getopt_long(argc, argv, "v:", long_options, nullptr); | 
 | 126 |     switch (argflag) | 
 | 127 |     { | 
 | 128 |         case 'v': | 
 | 129 |             switch (std::stoi(optarg)) | 
 | 130 |             { | 
 | 131 |                 case 0: | 
 | 132 |                     verbose = false; | 
 | 133 |                     break; | 
 | 134 |                 case 1: | 
 | 135 |                     verbose = true; | 
 | 136 |                     break; | 
 | 137 |                 default: | 
 | 138 |                     optionUsage(); | 
 | 139 |                     break; | 
 | 140 |             } | 
 | 141 |             break; | 
 | 142 |         default: | 
 | 143 |             optionUsage(); | 
 | 144 |             break; | 
 | 145 |     } | 
 | 146 |  | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 147 |     Invoker invoker{}; | 
 | 148 |     invoker.registerHandler(PLDM_BASE, std::make_unique<base::Handler>()); | 
 | 149 |     invoker.registerHandler(PLDM_BIOS, std::make_unique<bios::Handler>()); | 
 | 150 |     invoker.registerHandler(PLDM_PLATFORM, | 
 | 151 |                             std::make_unique<platform::Handler>()); | 
| Deepak Kodihalli | e60c582 | 2019-10-23 03:26:15 -0500 | [diff] [blame] | 152 |     invoker.registerHandler(PLDM_FRU, | 
 | 153 |                             std::make_unique<fru::Handler>(FRU_JSONS_DIR)); | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 154 |  | 
 | 155 | #ifdef OEM_IBM | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 156 |     invoker.registerHandler(PLDM_OEM, std::make_unique<oem_ibm::Handler>()); | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 157 | #endif | 
 | 158 |  | 
 | 159 |     /* Create local socket. */ | 
 | 160 |     int returnCode = 0; | 
 | 161 |     int sockfd = socket(AF_UNIX, SOCK_SEQPACKET, 0); | 
 | 162 |     if (-1 == sockfd) | 
 | 163 |     { | 
 | 164 |         returnCode = -errno; | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 165 |         std::cerr << "Failed to create the socket, RC= " << returnCode << "\n"; | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 166 |         exit(EXIT_FAILURE); | 
 | 167 |     } | 
 | 168 |  | 
| George Liu | 8340957 | 2019-12-24 18:42:54 +0800 | [diff] [blame] | 169 |     pldm::utils::CustomFD socketFd(sockfd); | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 170 |  | 
 | 171 |     struct sockaddr_un addr | 
 | 172 |     { | 
 | 173 |     }; | 
 | 174 |     addr.sun_family = AF_UNIX; | 
 | 175 |     const char path[] = "\0mctp-mux"; | 
 | 176 |     memcpy(addr.sun_path, path, sizeof(path) - 1); | 
 | 177 |     int result = connect(socketFd(), reinterpret_cast<struct sockaddr*>(&addr), | 
 | 178 |                          sizeof(path) + sizeof(addr.sun_family) - 1); | 
 | 179 |     if (-1 == result) | 
 | 180 |     { | 
 | 181 |         returnCode = -errno; | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 182 |         std::cerr << "Failed to connect to the socket, RC= " << returnCode | 
 | 183 |                   << "\n"; | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 184 |         exit(EXIT_FAILURE); | 
 | 185 |     } | 
 | 186 |  | 
 | 187 |     result = write(socketFd(), &MCTP_MSG_TYPE_PLDM, sizeof(MCTP_MSG_TYPE_PLDM)); | 
 | 188 |     if (-1 == result) | 
 | 189 |     { | 
 | 190 |         returnCode = -errno; | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 191 |         std::cerr << "Failed to send message type as pldm to mctp, RC= " | 
 | 192 |                   << returnCode << "\n"; | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 193 |         exit(EXIT_FAILURE); | 
 | 194 |     } | 
 | 195 |  | 
| George Liu | 0e02c32 | 2020-01-01 09:41:51 +0800 | [diff] [blame] | 196 |     auto& bus = pldm::utils::DBusHandler::getBus(); | 
| Deepak Kodihalli | 4de4d00 | 2019-11-11 02:41:43 -0600 | [diff] [blame] | 197 |     dbus_api::Requester dbusImplReq(bus, "/xyz/openbmc_project/pldm"); | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 198 |     auto callback = [verbose, &invoker, &dbusImplReq](IO& /*io*/, int fd, | 
 | 199 |                                                       uint32_t revents) { | 
| Deepak Kodihalli | 37998bf | 2019-11-11 04:06:53 -0600 | [diff] [blame] | 200 |         if (!(revents & EPOLLIN)) | 
 | 201 |         { | 
 | 202 |             return; | 
 | 203 |         } | 
 | 204 |  | 
 | 205 |         // Outgoing message. | 
 | 206 |         struct iovec iov[2]{}; | 
 | 207 |  | 
 | 208 |         // This structure contains the parameter information for the response | 
 | 209 |         // message. | 
 | 210 |         struct msghdr msg | 
 | 211 |         { | 
 | 212 |         }; | 
 | 213 |  | 
 | 214 |         int returnCode = 0; | 
 | 215 |         ssize_t peekedLength = recv(fd, nullptr, 0, MSG_PEEK | MSG_TRUNC); | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 216 |         if (0 == peekedLength) | 
 | 217 |         { | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 218 |             std::cerr << "Socket has been closed \n"; | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 219 |         } | 
 | 220 |         else if (peekedLength <= -1) | 
 | 221 |         { | 
 | 222 |             returnCode = -errno; | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 223 |             std::cerr << "recv system call failed, RC= " << returnCode << "\n"; | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 224 |         } | 
 | 225 |         else | 
 | 226 |         { | 
 | 227 |             std::vector<uint8_t> requestMsg(peekedLength); | 
 | 228 |             auto recvDataLength = recv( | 
| Deepak Kodihalli | 37998bf | 2019-11-11 04:06:53 -0600 | [diff] [blame] | 229 |                 fd, static_cast<void*>(requestMsg.data()), peekedLength, 0); | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 230 |             if (recvDataLength == peekedLength) | 
 | 231 |             { | 
| Jinu Joy Thomas | 75dd442 | 2019-07-22 12:47:12 +0530 | [diff] [blame] | 232 |                 if (verbose) | 
 | 233 |                 { | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 234 |                     std::cout << "Received Msg" << std::endl; | 
| Jinu Joy Thomas | 75dd442 | 2019-07-22 12:47:12 +0530 | [diff] [blame] | 235 |                     printBuffer(requestMsg); | 
 | 236 |                 } | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 237 |                 if (MCTP_MSG_TYPE_PLDM != requestMsg[1]) | 
 | 238 |                 { | 
 | 239 |                     // Skip this message and continue. | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 240 |                     std::cerr << "Encountered Non-PLDM type message" | 
 | 241 |                               << "\n"; | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 242 |                 } | 
 | 243 |                 else | 
 | 244 |                 { | 
 | 245 |                     // process message and send response | 
| Deepak Kodihalli | bc669f1 | 2019-11-28 08:52:07 -0600 | [diff] [blame] | 246 |                     auto response = | 
 | 247 |                         processRxMsg(requestMsg, invoker, dbusImplReq); | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 248 |                     if (!response.empty()) | 
 | 249 |                     { | 
| Deepak Kodihalli | 8ffbbe0 | 2019-08-14 06:51:38 -0500 | [diff] [blame] | 250 |                         if (verbose) | 
 | 251 |                         { | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 252 |                             std::cout << "Sending Msg" << std::endl; | 
| Deepak Kodihalli | 8ffbbe0 | 2019-08-14 06:51:38 -0500 | [diff] [blame] | 253 |                             printBuffer(response); | 
 | 254 |                         } | 
 | 255 |  | 
| Zahed Hossain | 09a96e0 | 2019-08-06 07:42:37 -0500 | [diff] [blame] | 256 |                         iov[0].iov_base = &requestMsg[0]; | 
 | 257 |                         iov[0].iov_len = | 
 | 258 |                             sizeof(requestMsg[0]) + sizeof(requestMsg[1]); | 
 | 259 |                         iov[1].iov_base = response.data(); | 
 | 260 |                         iov[1].iov_len = response.size(); | 
 | 261 |  | 
 | 262 |                         msg.msg_iov = iov; | 
 | 263 |                         msg.msg_iovlen = sizeof(iov) / sizeof(iov[0]); | 
 | 264 |  | 
| Deepak Kodihalli | 37998bf | 2019-11-11 04:06:53 -0600 | [diff] [blame] | 265 |                         int result = sendmsg(fd, &msg, 0); | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 266 |                         if (-1 == result) | 
 | 267 |                         { | 
 | 268 |                             returnCode = -errno; | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 269 |                             std::cerr << "sendto system call failed, RC= " | 
 | 270 |                                       << returnCode << "\n"; | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 271 |                         } | 
 | 272 |                     } | 
 | 273 |                 } | 
 | 274 |             } | 
 | 275 |             else | 
 | 276 |             { | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 277 |                 std::cerr | 
 | 278 |                     << "Failure to read peeked length packet. peekedLength= " | 
 | 279 |                     << peekedLength << " recvDataLength=" << recvDataLength | 
 | 280 |                     << "\n"; | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 281 |             } | 
 | 282 |         } | 
| Deepak Kodihalli | 37998bf | 2019-11-11 04:06:53 -0600 | [diff] [blame] | 283 |     }; | 
 | 284 |  | 
 | 285 |     auto event = Event::get_default(); | 
| Deepak Kodihalli | 4de4d00 | 2019-11-11 02:41:43 -0600 | [diff] [blame] | 286 |     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); | 
 | 287 |     bus.request_name("xyz.openbmc_project.PLDM"); | 
| Deepak Kodihalli | 37998bf | 2019-11-11 04:06:53 -0600 | [diff] [blame] | 288 |     IO io(event, socketFd(), EPOLLIN, std::move(callback)); | 
 | 289 |     event.loop(); | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 290 |  | 
 | 291 |     result = shutdown(sockfd, SHUT_RDWR); | 
 | 292 |     if (-1 == result) | 
 | 293 |     { | 
 | 294 |         returnCode = -errno; | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 295 |         std::cerr << "Failed to shutdown the socket, RC=" << returnCode << "\n"; | 
| Jinu Joy Thomas | f666db1 | 2019-05-29 05:22:31 -0500 | [diff] [blame] | 296 |         exit(EXIT_FAILURE); | 
 | 297 |     } | 
 | 298 |     exit(EXIT_FAILURE); | 
 | 299 | } |