Move to libpldm instance id APIs
libpldm provides APIs for allocating instance IDs directly, which
eliminates the need for remote dbus calls to the pldm daemon. Refactor
the code to use these APIs and eliminate all the dbus operations.
Change-Id: Ie73a1abb30e12a40014b2d35209e6e90c38a148b
Signed-off-by: Pavithra Barithaya <pavithrabarithaya07@gmail.com>
diff --git a/util/pldm.cpp b/util/pldm.cpp
index c161e51..a86d440 100644
--- a/util/pldm.cpp
+++ b/util/pldm.cpp
@@ -3,12 +3,103 @@
#include <libpldm/pldm.h>
#include <util/dbus.hpp>
+#include <util/pldm.hpp>
#include <util/trace.hpp>
namespace util
{
namespace pldm
{
+
+class PLDMInstanceManager
+{
+ public:
+ // Singleton access method
+ static PLDMInstanceManager& getInstance()
+ {
+ static PLDMInstanceManager instance;
+ return instance;
+ }
+
+ bool getPldmInstanceID(uint8_t& pldmInstance, uint8_t tid);
+ void freePLDMInstanceID(pldm_instance_id_t instanceID, uint8_t tid);
+
+ private:
+ // Private constructor and destructor to prevent creating multiple instances
+ PLDMInstanceManager();
+ ~PLDMInstanceManager();
+
+ // Deleted copy constructor and assignment operator to prevent copying
+ PLDMInstanceManager(const PLDMInstanceManager&) = delete;
+ PLDMInstanceManager& operator=(const PLDMInstanceManager&) = delete;
+
+ // Private member for the instance database
+ pldm_instance_db* pldmInstanceIdDb;
+};
+
+PLDMInstanceManager::PLDMInstanceManager() : pldmInstanceIdDb(nullptr)
+{
+ // Initialize the database object directly in the constructor
+ auto rc = pldm_instance_db_init_default(&pldmInstanceIdDb);
+ if (rc)
+ {
+ trace::err("Error calling pldm_instance_db_init_default, rc = %d",
+ (unsigned)rc);
+ }
+}
+
+PLDMInstanceManager::~PLDMInstanceManager()
+{
+ // Directly destroy the database object in the destructor
+ if (pldmInstanceIdDb)
+ {
+ auto rc = pldm_instance_db_destroy(pldmInstanceIdDb);
+ if (rc)
+ {
+ trace::err("pldm_instance_db_destroy failed rc = %d", (unsigned)rc);
+ }
+ }
+}
+
+// Get the PLDM instance ID for the given terminus ID
+bool PLDMInstanceManager::getPldmInstanceID(uint8_t& pldmInstance, uint8_t tid)
+{
+ pldm_instance_id_t id;
+ int rc = pldm_instance_id_alloc(pldmInstanceIdDb, tid, &id);
+ if (rc == -EAGAIN)
+ {
+ std::this_thread::sleep_for(
+ std::chrono::milliseconds(100)); // Retry after 100ms
+ rc = pldm_instance_id_alloc(pldmInstanceIdDb, tid,
+ &id); // Retry allocation
+ }
+
+ if (rc)
+ {
+ trace::err("getPldmInstanceId: Failed to alloc ID for TID = %d, RC= %d",
+ (unsigned)tid, (unsigned)rc);
+ return false;
+ }
+
+ pldmInstance = id; // Return the allocated instance ID
+ trace::inf("Got instanceId: %d, for PLDM TID: %d", (unsigned)pldmInstance,
+ (unsigned)tid);
+ return true;
+}
+
+// Free the PLDM instance ID associated with the terminus ID
+void PLDMInstanceManager::freePLDMInstanceID(pldm_instance_id_t instanceID,
+ uint8_t tid)
+{
+ int rc = pldm_instance_id_free(pldmInstanceIdDb, tid, instanceID);
+ if (rc)
+ {
+ trace::err(
+ "pldm_instance_id_free failed to free id=%d of TID=%d with rc= %d",
+ (unsigned)instanceID, (unsigned)tid, (unsigned)rc);
+ }
+}
+
/** @brief Send PLDM request
*
* @param[in] request - the request data
@@ -50,9 +141,11 @@
uint16_t effecterId, uint8_t effecterCount, uint8_t stateIdPos,
uint8_t stateSetValue, uint8_t mctpEid)
{
+ PLDMInstanceManager& manager = PLDMInstanceManager::getInstance();
+
// get pldm instance associated with the endpoint ID
uint8_t pldmInstanceID;
- if (!util::dbus::getPldmInstanceID(pldmInstanceID, mctpEid))
+ if (!manager.getPldmInstanceID(pldmInstanceID, mctpEid))
{
return std::vector<uint8_t>();
}
@@ -87,6 +180,7 @@
if (rc != PLDM_SUCCESS)
{
trace::err("encode set effecter states request failed");
+ manager.freePLDMInstanceID(pldmInstanceID, mctpEid);
request.clear();
}
@@ -293,6 +387,9 @@
if (!fetchSensorInfo(PLDM_OEM_IBM_SBE_HRESET_STATE, sensorToSbeInstance,
sbeSensorOffset))
{
+ PLDMInstanceManager& manager = PLDMInstanceManager::getInstance();
+ auto reqhdr = reinterpret_cast<const pldm_msg_hdr*>(&request);
+ manager.freePLDMInstanceID(reqhdr->instance_id, hbrtMctpEid);
return false;
}
@@ -355,8 +452,13 @@
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);
+
return false;
}
@@ -386,6 +488,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
return hresetStatus == "success" ? true : false;