Add kernel MCTP (AF_MCTP) support and transport-implementation option

-Added support for kernel MCTP (AF_MCTP) to enable MCTP communication
 using AF_MCTP sockets.

- Introduced a new configuration option 'transport-implementation'

The 'transport-implementation' option can be set to either:
- 'mctp-demux': Uses the existing mctp-demux transport method.
- 'af-mctp': Uses the new kernel AF_MCTP transport method.

Change-Id: I2978273fe4579d1dce00368dabb7f90815dbbce8
Signed-off-by: Lakshmi Yadlapati <lakshmiy@us.ibm.com>
Signed-off-by: Eddie James <eajames@linux.ibm.com>
diff --git a/meson.options b/meson.options
index c187f79..ddb3246 100644
--- a/meson.options
+++ b/meson.options
@@ -59,3 +59,10 @@
     value: '/org/openpower/dump',
     description : 'Object path requesting OpenPOWER dumps'
 )
+
+option(
+    'transport-implementation',
+    type: 'combo',
+    choices: ['mctp-demux', 'af-mctp'],
+    description: 'transport via af-mctp or mctp-demux'
+)
diff --git a/pldm.cpp b/pldm.cpp
index 67847c8..67c8cc4 100644
--- a/pldm.cpp
+++ b/pldm.cpp
@@ -9,6 +9,7 @@
 #include <libpldm/platform.h>
 #include <libpldm/state_set.h>
 #include <libpldm/transport.h>
+#include <libpldm/transport/af-mctp.h>
 #include <libpldm/transport/mctp-demux.h>
 #include <poll.h>
 
@@ -581,10 +582,10 @@
     }
 }
 
-int Interface::openMctpDemuxTransport()
+[[maybe_unused]] int Interface::openMctpDemuxTransport()
 {
-    mctpDemux = nullptr;
-    int rc = pldm_transport_mctp_demux_init(&mctpDemux);
+    impl.mctpDemux = nullptr;
+    int rc = pldm_transport_mctp_demux_init(&impl.mctpDemux);
     if (rc)
     {
         log<level::ERR>(
@@ -595,7 +596,7 @@
         return -1;
     }
 
-    if (pldm_transport_mctp_demux_map_tid(mctpDemux, mctpEid, mctpEid))
+    if (pldm_transport_mctp_demux_map_tid(impl.mctpDemux, mctpEid, mctpEid))
     {
         log<level::ERR>(
             std::format(
@@ -605,7 +606,7 @@
         pldmClose();
         return -1;
     }
-    pldmTransport = pldm_transport_mctp_demux_core(mctpDemux);
+    pldmTransport = pldm_transport_mctp_demux_core(impl.mctpDemux);
 
     struct pollfd pollfd;
     if (pldm_transport_mctp_demux_init_pollfd(pldmTransport, &pollfd))
@@ -628,6 +629,53 @@
     return 0;
 }
 
+[[maybe_unused]] int Interface::openAfMctpTransport()
+{
+    impl.afMctp = nullptr;
+    int rc = pldm_transport_af_mctp_init(&impl.afMctp);
+    if (rc)
+    {
+        log<level::ERR>(
+            std::format(
+                "openAfMctpTransport: Failed to init af MCTP transport, errno={}/{}",
+                rc, strerror(rc))
+                .c_str());
+        return -1;
+    }
+
+    if (pldm_transport_af_mctp_map_tid(impl.afMctp, mctpEid, mctpEid))
+    {
+        log<level::ERR>(
+            std::format(
+                "openAfMctpTransport: Failed to setup tid to eid mapping, errno={}/{}",
+                errno, strerror(errno))
+                .c_str());
+        pldmClose();
+        return -1;
+    }
+    pldmTransport = pldm_transport_af_mctp_core(impl.afMctp);
+
+    struct pollfd pollfd;
+    if (pldm_transport_af_mctp_init_pollfd(pldmTransport, &pollfd))
+    {
+        log<level::ERR>(
+            std::format(
+                "openAfMctpTransport: Failed to get pollfd , errno={}/{}",
+                errno, strerror(errno))
+                .c_str());
+        pldmClose();
+        return -1;
+    }
+    pldmFd = pollfd.fd;
+    if (!throttleTraces)
+    {
+        log<level::INFO>(
+            std::format("openAfMctpTransport: pldmFd has fd={}", pldmFd)
+                .c_str());
+    }
+    return 0;
+}
+
 int Interface::pldmOpen()
 {
     if (pldmTransport)
@@ -638,7 +686,15 @@
                 .c_str());
         return -1;
     }
+#if defined(PLDM_TRANSPORT_WITH_MCTP_DEMUX)
     return openMctpDemuxTransport();
+#elif defined(PLDM_TRANSPORT_WITH_AF_MCTP)
+    return openAfMctpTransport();
+#else
+    return -1;
+#endif
+
+    return 0;
 }
 
 void Interface::sendPldm(const std::vector<uint8_t>& request,
@@ -781,8 +837,13 @@
         pldmRspTimer.setEnabled(false);
     }
 
-    pldm_transport_mctp_demux_destroy(mctpDemux);
-    mctpDemux = NULL;
+#if defined(PLDM_TRANSPORT_WITH_MCTP_DEMUX)
+    pldm_transport_mctp_demux_destroy(impl.mctpDemux);
+    impl.mctpDemux = NULL;
+#elif defined(PLDM_TRANSPORT_WITH_AF_MCTP)
+    pldm_transport_af_mctp_destroy(impl.afMctp);
+    impl.afMctp = NULL;
+#endif
     pldmFd = -1;
     pldmTransport = NULL;
     eventSource.reset();
diff --git a/pldm.hpp b/pldm.hpp
index 384ad20..7238c02 100644
--- a/pldm.hpp
+++ b/pldm.hpp
@@ -7,6 +7,7 @@
 #include <libpldm/instance-id.h>
 #include <libpldm/pldm.h>
 #include <libpldm/transport.h>
+#include <libpldm/transport/af-mctp.h>
 #include <libpldm/transport/mctp-demux.h>
 
 #include <sdbusplus/bus/match.hpp>
@@ -255,7 +256,13 @@
     /** pldm transport instance  */
     struct pldm_transport* pldmTransport = NULL;
 
-    struct pldm_transport_mctp_demux* mctpDemux;
+    union TransportImpl
+    {
+        struct pldm_transport_mctp_demux* mctpDemux;
+        struct pldm_transport_af_mctp* afMctp;
+    };
+
+    TransportImpl impl;
 
     /** @brief The response for the PLDM request msg is received flag.
      */
@@ -355,10 +362,16 @@
 
     /** @brief Opens the MCTP socket for sending and receiving messages.
      *
-     * @return true on success, otherwise returns a negative error code
+     * @return 0 on success, otherwise returns a negative error code
      */
     int openMctpDemuxTransport();
 
+    /** @brief Opens the MCTP AF_MCTP for sending and receiving messages.
+     *
+     * @return 0 on success, otherwise returns a negative error code
+     */
+    int openAfMctpTransport();
+
     /** @brief Send the PLDM request
      *
      * @param[in] request - the request data