openpower-pels: Move to libpldm pldm_transport APIs

- Replaced the deprecated pldm transport APIs with the new libpldm
  pldm_transport APIs.
- Updated the receive function to pass pldm_transport as a parameter.
- Modified the function signatures and their calls to ensure the
  pldm_transport parameter is properly passed.

This change migrates the application off of the deprecated "requester"
APIs in libpldm.

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: Ib143dc122637ef7e390fceb64f1f94c65172ae39
Signed-off-by: Lakshmi Yadlapati <lakshmiy@us.ibm.com>
diff --git a/config/meson.build b/config/meson.build
index ff8f946..661ded3 100644
--- a/config/meson.build
+++ b/config/meson.build
@@ -3,6 +3,12 @@
 conf_data.set('error_cap', get_option('error_cap'))
 conf_data.set('error_info_cap', get_option('error_info_cap'))
 conf_data.set('rsyslog_server_conf', get_option('rsyslog_server_conf'))
+
+cxx = meson.get_compiler('cpp')
+if cxx.has_header('poll.h')
+    add_project_arguments('-DPLDM_HAS_POLL=1', language: 'cpp')
+endif
+
 conf_h_dep = declare_dependency(
     include_directories: include_directories('.'),
     sources: configure_file(
diff --git a/extensions/openpower-pels/host_interface.hpp b/extensions/openpower-pels/host_interface.hpp
index 11ebe87..857b1fc 100644
--- a/extensions/openpower-pels/host_interface.hpp
+++ b/extensions/openpower-pels/host_interface.hpp
@@ -2,6 +2,7 @@
 
 #include "data_interface.hpp"
 
+#include <libpldm/transport.h>
 #include <stdint.h>
 
 #include <phosphor-logging/lg2.hpp>
@@ -195,9 +196,10 @@
      *                 invoked from.
      * @param[in] fd - The file descriptor being used
      * @param[in] revents - The event status bits
+     * @param[in] transport - The transport data pointer
      */
-    virtual void receive(sdeventplus::source::IO& io, int fd,
-                         uint32_t revents) = 0;
+    virtual void receive(sdeventplus::source::IO& io, int fd, uint32_t revents,
+                         pldm_transport* transport) = 0;
 
     /**
      * @brief An optional function to call on a successful command response.
diff --git a/extensions/openpower-pels/pldm_interface.cpp b/extensions/openpower-pels/pldm_interface.cpp
index aab7a54..51160f8 100644
--- a/extensions/openpower-pels/pldm_interface.cpp
+++ b/extensions/openpower-pels/pldm_interface.cpp
@@ -17,6 +17,9 @@
 
 #include <libpldm/base.h>
 #include <libpldm/oem/ibm/file_io.h>
+#include <libpldm/transport.h>
+#include <libpldm/transport/mctp-demux.h>
+#include <poll.h>
 #include <unistd.h>
 
 #include <phosphor-logging/lg2.hpp>
@@ -28,9 +31,11 @@
 
 using namespace sdeventplus;
 using namespace sdeventplus::source;
+using TerminusID = uint8_t;
 
 constexpr auto eidPath = "/usr/share/pldm/host_eid";
 constexpr mctp_eid_t defaultEIDValue = 9;
+constexpr TerminusID tid = defaultEIDValue;
 
 constexpr uint16_t pelFileType = 0;
 
@@ -43,11 +48,10 @@
 
 void PLDMInterface::closeFD()
 {
-    if (_fd >= 0)
-    {
-        close(_fd);
-        _fd = -1;
-    }
+    pldm_transport_mctp_demux_destroy(mctpDemux);
+    mctpDemux = nullptr;
+    _fd = -1;
+    pldmTransport = nullptr;
 }
 
 void PLDMInterface::readEID()
@@ -76,16 +80,56 @@
 
 void PLDMInterface::open()
 {
-    _fd = pldm_open();
+    if (pldmTransport)
+    {
+        lg2::error("open: pldmTransport already setup!");
+        throw std::runtime_error{"open failed"};
+    }
+
+    _fd = openMctpDemuxTransport();
     if (_fd < 0)
     {
         auto e = errno;
-        lg2::error("pldm_open failed.  errno = {ERRNO}, rc = {RC}", "ERRNO", e,
-                   "RC", _fd);
-        throw std::runtime_error{"pldm_open failed"};
+        lg2::error("Transport open failed. errno = {ERRNO}, rc = {RC}", "ERRNO",
+                   e, "RC", _fd);
+        throw std::runtime_error{"Transport open failed"};
     }
 }
 
+int PLDMInterface::openMctpDemuxTransport()
+{
+    int rc = pldm_transport_mctp_demux_init(&mctpDemux);
+    if (rc)
+    {
+        lg2::error(
+            "openMctpDemuxTransport: Failed to init MCTP demux transport. rc = {RC}",
+            "RC", rc);
+        return rc;
+    }
+
+    rc = pldm_transport_mctp_demux_map_tid(mctpDemux, tid, tid);
+    if (rc)
+    {
+        lg2::error(
+            "openMctpDemuxTransport: Failed to setup tid to eid mapping. rc = {RC}",
+            "RC", rc);
+        cleanupCmd();
+        return rc;
+    }
+    pldmTransport = pldm_transport_mctp_demux_core(mctpDemux);
+
+    struct pollfd pollfd;
+    rc = pldm_transport_mctp_demux_init_pollfd(pldmTransport, &pollfd);
+    if (rc)
+    {
+        lg2::error("openMctpDemuxTransport: Failed to get pollfd. rc = {RC}",
+                   "RC", rc);
+        cleanupCmd();
+        return rc;
+    }
+    return pollfd.fd;
+}
+
 void PLDMInterface::startCommand()
 {
     try
@@ -185,7 +229,7 @@
         _event, _fd, EPOLLIN,
         std::bind(std::mem_fn(&PLDMInterface::receive), this,
                   std::placeholders::_1, std::placeholders::_2,
-                  std::placeholders::_3));
+                  std::placeholders::_3, pldmTransport));
 }
 
 void PLDMInterface::doSend()
@@ -203,37 +247,42 @@
         lg2::error("encode_new_file_req failed, rc = {RC}", "RC", rc);
         throw std::runtime_error{"encode_new_file_req failed"};
     }
-
-    rc = pldm_send(_eid, _fd, requestMsg.data(), requestMsg.size());
+    pldm_tid_t pldmTID = static_cast<pldm_tid_t>(_eid);
+    rc = pldm_transport_send_msg(pldmTransport, pldmTID, requestMsg.data(),
+                                 requestMsg.size());
     if (rc < 0)
     {
         auto e = errno;
-        lg2::error("pldm_send failed, rc = {RC}, errno = {ERRNO}", "RC", rc,
-                   "ERRNO", e);
-        throw std::runtime_error{"pldm_send failed"};
+        lg2::error("pldm_transport_send_msg failed, rc = {RC}, errno = {ERRNO}",
+                   "RC", rc, "ERRNO", e);
+        throw std::runtime_error{"pldm_transport_send_msg failed"};
     }
 }
 
-void PLDMInterface::receive(IO& /*io*/, int fd, uint32_t revents)
+void PLDMInterface::receive(IO& /*io*/, int /*fd*/, uint32_t revents,
+                            pldm_transport* transport)
+
 {
     if (!(revents & EPOLLIN))
     {
         return;
     }
 
-    uint8_t* responseMsg = nullptr;
+    void* responseMsg = nullptr;
     size_t responseSize = 0;
     ResponseStatus status = ResponseStatus::success;
 
-    auto rc = pldm_recv(_eid, fd, *_instanceID, &responseMsg, &responseSize);
-    if (rc < 0)
+    pldm_tid_t pldmTID;
+    auto rc = pldm_transport_recv_msg(transport, &pldmTID, &responseMsg,
+                                      &responseSize);
+    if (pldmTID != _eid)
     {
-        if (rc == PLDM_REQUESTER_INSTANCE_ID_MISMATCH)
-        {
-            // We got a response to someone else's message. Ignore it.
-            return;
-        }
-        else if (rc == PLDM_REQUESTER_NOT_RESP_MSG)
+        // We got a response to someone else's message. Ignore it.
+        return;
+    }
+    if (rc)
+    {
+        if (rc == PLDM_REQUESTER_NOT_RESP_MSG)
         {
             // Due to the MCTP loopback, we may get notified of the message
             // we just sent.
@@ -241,7 +290,8 @@
         }
 
         auto e = errno;
-        lg2::error("pldm_recv failed, rc = {RC}, errno = {ERRNO}", "RC",
+        lg2::error("pldm_transport_recv_msg failed, rc = {RC}, errno = {ERRNO}",
+                   "RC",
                    static_cast<std::underlying_type_t<pldm_requester_rc_t>>(rc),
                    "ERRNO", e);
         status = ResponseStatus::failure;
@@ -259,7 +309,7 @@
         uint8_t completionCode = 0;
         auto response = reinterpret_cast<pldm_msg*>(responseMsg);
 
-        auto decodeRC = decode_new_file_resp(response, PLDM_NEW_FILE_RESP_BYTES,
+        auto decodeRC = decode_new_file_resp(response, responseSize,
                                              &completionCode);
         if (decodeRC < 0)
         {
diff --git a/extensions/openpower-pels/pldm_interface.hpp b/extensions/openpower-pels/pldm_interface.hpp
index 51ab5c1..b907af4 100644
--- a/extensions/openpower-pels/pldm_interface.hpp
+++ b/extensions/openpower-pels/pldm_interface.hpp
@@ -4,6 +4,8 @@
 
 #include <libpldm/instance-id.h>
 #include <libpldm/pldm.h>
+#include <libpldm/transport.h>
+#include <libpldm/transport/mctp-demux.h>
 
 #include <sdeventplus/clock.hpp>
 #include <sdeventplus/source/io.hpp>
@@ -93,9 +95,10 @@
      * @param[in] io - The event source object
      * @param[in] fd - The FD used
      * @param[in] revents - The event bits
+     * @param[in] transport - The transport data pointer
      */
-    void receive(sdeventplus::source::IO& io, int fd,
-                 uint32_t revents) override;
+    void receive(sdeventplus::source::IO& io, int fd, uint32_t revents,
+                 pldm_transport* transport) override;
 
     /**
      * @brief Function called when the receive timer expires.
@@ -123,6 +126,11 @@
      */
     void open();
 
+    /** @brief Opens the MCTP socket for sending and receiving messages.
+     *
+     */
+    int openMctpDemuxTransport();
+
     /**
      * @brief Encodes and sends the PLDM 'new file available' cmd
      */
@@ -200,6 +208,13 @@
      * @brief The size of the PEL to notify the host of.
      */
     uint32_t _pelSize = 0;
+
+    /**
+     * @brief pldm transport instance.
+     */
+    pldm_transport* pldmTransport = nullptr;
+
+    pldm_transport_mctp_demux* mctpDemux = nullptr;
 };
 
 } // namespace openpower::pels
diff --git a/test/openpower-pels/mocks.hpp b/test/openpower-pels/mocks.hpp
index 6f40fe2..2e06627 100644
--- a/test/openpower-pels/mocks.hpp
+++ b/test/openpower-pels/mocks.hpp
@@ -204,7 +204,7 @@
 
         auto callback = [this](sdeventplus::source::IO& source, int fd,
                                uint32_t events) {
-            this->receive(source, fd, events);
+            this->receive(source, fd, events, nullptr);
         };
 
         try
@@ -242,7 +242,7 @@
      * @param[in] events - The event bits
      */
     void receive(sdeventplus::source::IO& /*source*/, int /*fd*/,
-                 uint32_t events) override
+                 uint32_t events, pldm_transport* /*transport*/) override
     {
         if (!(events & EPOLLIN))
         {