Move to libpldm pldm_transport APIs
Replaced pldm transport APIs with libpldm pldm_transport APIs to
remove the dependency on pldm.
This change removes the dependency on pldm by utilizing the
standardized libpldm APIs for transport operations, improving
maintainability and compatibility.
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.
***Testing in progress***
Change-Id: I2bb9927fea254fe5bf88e1181476d491e533cf20
Signed-off-by: Pavithra Barithaya <pavithrabarithaya07@gmail.com>
diff --git a/meson.build b/meson.build
index 269ec49..a0fa425 100644
--- a/meson.build
+++ b/meson.build
@@ -45,6 +45,10 @@
conf.set('CONFIG_PHAL_API', get_option('phal').allowed())
+if cmplr.has_header('poll.h')
+ add_project_arguments('-DPLDM_HAS_POLL=1', language: 'cpp')
+endif
+
configure_file(input: 'config.h.in', output: 'config.h', configuration: conf)
#-------------------------------------------------------------------------------
diff --git a/util/pldm.cpp b/util/pldm.cpp
index a86d440..daa28c4 100644
--- a/util/pldm.cpp
+++ b/util/pldm.cpp
@@ -1,6 +1,11 @@
+#include "config.h"
+
#include <libpldm/oem/ibm/state_set.h>
#include <libpldm/platform.h>
#include <libpldm/pldm.h>
+#include <libpldm/transport.h>
+#include <libpldm/transport/mctp-demux.h>
+#include <poll.h>
#include <util/dbus.hpp>
#include <util/pldm.hpp>
@@ -24,6 +29,27 @@
bool getPldmInstanceID(uint8_t& pldmInstance, uint8_t tid);
void freePLDMInstanceID(pldm_instance_id_t instanceID, uint8_t tid);
+ /**
+ * @brief setup PLDM transport for sending and receiving messages
+ *
+ * @param[in] eid - MCTP endpoint ID
+ * @return file descriptor on success and throw
+ * exception (xyz::openbmc_project::Common::Error::NotAllowed) on
+ * failures.
+ */
+ int openPLDM(mctp_eid_t eid);
+ /** @brief Opens the MCTP socket for sending and receiving messages.
+ *
+ * @param[in] eid - MCTP endpoint ID
+ */
+ int openMctpDemuxTransport(mctp_eid_t eid);
+
+ /** @brief Close the PLDM file */
+ void closePLDM();
+
+ /** @brief sending PLDM file */
+ bool sendPldm(const std::vector<uint8_t>& request, uint8_t mctpEid);
+
private:
// Private constructor and destructor to prevent creating multiple instances
PLDMInstanceManager();
@@ -35,6 +61,11 @@
// Private member for the instance database
pldm_instance_db* pldmInstanceIdDb;
+
+ /** pldm transport instance */
+ struct pldm_transport* pldmTransport = NULL;
+
+ pldm_transport_mctp_demux* mctpDemux;
};
PLDMInstanceManager::PLDMInstanceManager() : pldmInstanceIdDb(nullptr)
@@ -100,27 +131,86 @@
}
}
+int PLDMInstanceManager::openPLDM(mctp_eid_t eid)
+{
+ auto fd = -1;
+ if (pldmTransport)
+ {
+ trace::inf("open: pldmTransport already setup!");
+ return fd;
+ }
+ fd = openMctpDemuxTransport(eid);
+ if (fd < 0)
+ {
+ auto e = errno;
+ trace::err("openPLDM failed, fd = %d and error= %d", (unsigned)fd, e);
+ }
+ return fd;
+}
+
+int PLDMInstanceManager::openMctpDemuxTransport(mctp_eid_t eid)
+{
+ int rc = pldm_transport_mctp_demux_init(&mctpDemux);
+ if (rc)
+ {
+ trace::err(
+ "openMctpDemuxTransport: Failed to setup tid to eid mapping. rc = %d",
+ (unsigned)rc);
+ closePLDM();
+ return rc;
+ }
+
+ rc = pldm_transport_mctp_demux_map_tid(mctpDemux, eid, eid);
+ if (rc)
+ {
+ trace::err(
+ "openMctpDemuxTransport: Failed to setup tid to eid mapping. rc = %d",
+ (unsigned)rc);
+ closePLDM();
+ return rc;
+ }
+
+ pldmTransport = pldm_transport_mctp_demux_core(mctpDemux);
+ struct pollfd pollfd;
+ rc = pldm_transport_mctp_demux_init_pollfd(pldmTransport, &pollfd);
+ if (rc)
+ {
+ trace::err("openMctpDemuxTransport: Failed to get pollfd. rc= %d",
+ (unsigned)rc);
+ closePLDM();
+ return rc;
+ }
+ return pollfd.fd;
+}
+void PLDMInstanceManager::closePLDM()
+{
+ pldm_transport_mctp_demux_destroy(mctpDemux);
+ mctpDemux = NULL;
+ pldmTransport = NULL;
+}
+
/** @brief Send PLDM request
*
* @param[in] request - the request data
* @param[in] mcptEid - the mctp endpoint ID
- * @param[out] pldmFd - pldm socket file descriptor
*
* @pre a mctp instance must have been
* @return true if send is successful false otherwise
*/
-bool sendPldm(const std::vector<uint8_t>& request, uint8_t mctpEid, int& pldmFd)
+bool PLDMInstanceManager::sendPldm(const std::vector<uint8_t>& request,
+ uint8_t mctpEid)
{
- // connect to socket
- pldmFd = pldm_open();
- if (-1 == pldmFd)
+ auto rc = openPLDM(mctpEid);
+ if (rc)
{
trace::err("failed to connect to pldm");
return false;
}
+ pldm_tid_t pldmTID = static_cast<pldm_tid_t>(mctpEid);
// send PLDM request
- auto pldmRc = pldm_send(mctpEid, pldmFd, request.data(), request.size());
+ auto pldmRc = pldm_transport_send_msg(pldmTransport, pldmTID,
+ request.data(), request.size());
trace::inf("sent pldm request");
@@ -446,16 +536,10 @@
});
// send request to issue hreset of sbe
- int pldmFd = -1; // mctp socket file descriptor
- if (!sendPldm(request, hbrtMctpEid, pldmFd))
+ PLDMInstanceManager& manager = PLDMInstanceManager::getInstance();
+ if (!(manager.sendPldm(request, hbrtMctpEid)))
{
trace::err("send pldm request failed");
- if (-1 != pldmFd)
- {
- trace::err("failed to connect to pldm");
- close(pldmFd);
- }
- PLDMInstanceManager& manager = PLDMInstanceManager::getInstance();
auto reqhdr = reinterpret_cast<const pldm_msg_hdr*>(&request);
manager.freePLDMInstanceID(reqhdr->instance_id, hbrtMctpEid);
@@ -488,10 +572,9 @@
trace::err("hreset timed out");
}
- PLDMInstanceManager& manager = PLDMInstanceManager::getInstance();
auto reqhdr = reinterpret_cast<const pldm_msg_hdr*>(&request);
manager.freePLDMInstanceID(reqhdr->instance_id, hbrtMctpEid);
- close(pldmFd); // close pldm socket
+ manager.closePLDM();
return hresetStatus == "success" ? true : false;
}