pldm: Convert to using libpldm transport APIs

A significant amount of logic can be removed by exploiting the new
transport APIs provided by libpldm. Switch the pldm repository over to
use these by introducing an RAII wrapper for the APIs. The current
stance is to continue using the legacy mctp-demux transport
implementation, but we also provide a build option to switch to the
AF_MCTP transport.

We don't currently have the infrastructure in place to get the correct
TIDs, so to keep everything working as before use the EID as the TID in
the EID-to-TID mapping.

Change-Id: I366f079082b102cfc0e90db0f62208581eb8693e
Signed-off-by: Rashmica Gupta <rashmica@linux.ibm.com>
Signed-off-by: Delphine CC Chiu <Delphine_CC_Chiu@wiwynn.com>
Signed-off-by: Thu Nguyen <thu@os.amperecomputing.com>
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Signed-off-by: Konstantin Aladyshev <aladyshev22@gmail.com>
diff --git a/pldmtool/pldm_cmd_helper.cpp b/pldmtool/pldm_cmd_helper.cpp
index db44c5a..9c7f94a 100644
--- a/pldmtool/pldm_cmd_helper.cpp
+++ b/pldmtool/pldm_cmd_helper.cpp
@@ -1,8 +1,12 @@
 #include "pldm_cmd_helper.hpp"
 
+#include "common/transport.hpp"
 #include "xyz/openbmc_project/Common/error.hpp"
 
-#include <libpldm/pldm.h>
+#include <libpldm/transport.h>
+#include <libpldm/transport/af-mctp.h>
+#include <libpldm/transport/mctp-demux.h>
+#include <poll.h>
 #include <systemd/sd-bus.h>
 
 #include <sdbusplus/server.hpp>
@@ -16,120 +20,6 @@
 {
 namespace helper
 {
-/*
- * Initialize the socket, send pldm command & recieve response from socket
- *
- */
-int mctpSockSendRecv(const std::vector<uint8_t>& requestMsg,
-                     std::vector<uint8_t>& responseMsg, bool pldmVerbose)
-{
-    const char devPath[] = "\0mctp-mux";
-    int returnCode = 0;
-
-    int sockFd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
-    if (-1 == sockFd)
-    {
-        returnCode = -errno;
-        std::cerr << "Failed to create the socket : RC = " << sockFd << "\n";
-        return returnCode;
-    }
-    Logger(pldmVerbose, "Success in creating the socket : RC = ", sockFd);
-
-    struct sockaddr_un addr
-    {};
-    addr.sun_family = AF_UNIX;
-
-    memcpy(addr.sun_path, devPath, sizeof(devPath) - 1);
-
-    CustomFD socketFd(sockFd);
-    int result = connect(socketFd(), reinterpret_cast<struct sockaddr*>(&addr),
-                         sizeof(devPath) + sizeof(addr.sun_family) - 1);
-    if (-1 == result)
-    {
-        returnCode = -errno;
-        std::cerr << "Failed to connect to socket : RC = " << returnCode
-                  << "\n";
-        return returnCode;
-    }
-    Logger(pldmVerbose, "Success in connecting to socket : RC = ", returnCode);
-
-    auto pldmType = MCTP_MSG_TYPE_PLDM;
-    result = write(socketFd(), &pldmType, sizeof(pldmType));
-    if (-1 == result)
-    {
-        returnCode = -errno;
-        std::cerr << "Failed to send message type as pldm to mctp : RC = "
-                  << returnCode << "\n";
-        return returnCode;
-    }
-    Logger(
-        pldmVerbose,
-        "Success in sending message type as pldm to mctp : RC = ", returnCode);
-
-    result = send(socketFd(), requestMsg.data(), requestMsg.size(), 0);
-    if (-1 == result)
-    {
-        returnCode = -errno;
-        std::cerr << "Write to socket failure : RC = " << returnCode << "\n";
-        return returnCode;
-    }
-    Logger(pldmVerbose, "Write to socket successful : RC = ", result);
-
-    // Read the response from socket
-    ssize_t peekedLength = recv(socketFd(), nullptr, 0, MSG_TRUNC | MSG_PEEK);
-    if (0 == peekedLength)
-    {
-        std::cerr << "Socket is closed : peekedLength = " << peekedLength
-                  << "\n";
-        return returnCode;
-    }
-    else if (peekedLength <= -1)
-    {
-        returnCode = -errno;
-        std::cerr << "recv() system call failed : RC = " << returnCode << "\n";
-        return returnCode;
-    }
-    else
-    {
-        auto reqhdr = reinterpret_cast<const pldm_msg_hdr*>(&requestMsg[2]);
-        do
-        {
-            ssize_t peekedLength = recv(socketFd(), nullptr, 0,
-                                        MSG_PEEK | MSG_TRUNC);
-            responseMsg.resize(peekedLength);
-            auto recvDataLength =
-                recv(socketFd(), reinterpret_cast<void*>(responseMsg.data()),
-                     peekedLength, 0);
-            auto resphdr =
-                reinterpret_cast<const pldm_msg_hdr*>(&responseMsg[2]);
-            if (recvDataLength == peekedLength &&
-                resphdr->instance_id == reqhdr->instance_id &&
-                resphdr->request != PLDM_REQUEST)
-            {
-                Logger(pldmVerbose, "Total length:", recvDataLength);
-                break;
-            }
-            else if (recvDataLength != peekedLength)
-            {
-                std::cerr << "Failure to read response length packet: length = "
-                          << recvDataLength << "\n";
-                return returnCode;
-            }
-        } while (1);
-    }
-
-    returnCode = shutdown(socketFd(), SHUT_RDWR);
-    if (-1 == returnCode)
-    {
-        returnCode = -errno;
-        std::cerr << "Failed to shutdown the socket : RC = " << returnCode
-                  << "\n";
-        return returnCode;
-    }
-
-    Logger(pldmVerbose, "Shutdown Socket successful :  RC = ", returnCode);
-    return PLDM_SUCCESS;
-}
 
 void CommandInterface::exec()
 {
@@ -161,13 +51,6 @@
 int CommandInterface::pldmSendRecv(std::vector<uint8_t>& requestMsg,
                                    std::vector<uint8_t>& responseMsg)
 {
-    // Insert the PLDM message type and EID at the beginning of the
-    // msg.
-    requestMsg.insert(requestMsg.begin(), MCTP_MSG_TYPE_PLDM);
-    requestMsg.insert(requestMsg.begin(), mctp_eid);
-
-    bool mctpVerbose = pldmVerbose;
-
     // By default enable request/response msgs for pldmtool raw commands.
     if (CommandInterface::pldmType == "raw")
     {
@@ -180,43 +63,29 @@
         printBuffer(Tx, requestMsg);
     }
 
-    if (mctp_eid != PLDM_ENTITY_ID)
+    void* responseMessage = nullptr;
+    size_t responseMessageSize{};
+    auto tid = mctp_eid;
+    PldmTransport pldmTransport{};
+
+    int rc = pldmTransport.sendRecvMsg(tid, requestMsg.data(),
+                                       requestMsg.size(), responseMessage,
+                                       responseMessageSize);
+    if (rc)
     {
-        int fd = pldm_open();
-        if (-1 == fd)
-        {
-            std::cerr << "failed to init mctp "
-                      << "\n";
-            return -1;
-        }
-        uint8_t* responseMessage = nullptr;
-        size_t responseMessageSize{};
-        pldm_send_recv(mctp_eid, fd, requestMsg.data() + 2,
-                       requestMsg.size() - 2, &responseMessage,
-                       &responseMessageSize);
-
-        responseMsg.resize(responseMessageSize);
-        memcpy(responseMsg.data(), responseMessage, responseMsg.size());
-
-        shutdown(fd, SHUT_RDWR);
-        free(responseMessage);
-
-        if (pldmVerbose)
-        {
-            std::cout << "pldmtool: ";
-            printBuffer(Rx, responseMsg);
-        }
+        std::cerr << "failed to pldm send recv\n";
+        return rc;
     }
-    else
+
+    responseMsg.resize(responseMessageSize);
+    memcpy(responseMsg.data(), responseMessage, responseMsg.size());
+
+    free(responseMessage);
+
+    if (pldmVerbose)
     {
-        mctpSockSendRecv(requestMsg, responseMsg, mctpVerbose);
-        if (pldmVerbose)
-        {
-            std::cout << "pldmtool: ";
-            printBuffer(Rx, responseMsg);
-        }
-        responseMsg.erase(responseMsg.begin(),
-                          responseMsg.begin() + 2 /* skip the mctp header */);
+        std::cout << "pldmtool: ";
+        printBuffer(Rx, responseMsg);
     }
     return PLDM_SUCCESS;
 }