Support `terminus_name` option in `dbus_to_terminus_effecter`
Support `terminus_name` configuration option in
`dbus_to_terminus_effecter` to allow setting the destination terminus
beside `mctp_eid`. This is helpful when the mctp endpoint Eid is not
static.
Change-Id: I8b1ed15741807086254146017c99c13ae667dac1
Signed-off-by: Thu Nguyen <thu@os.amperecomputing.com>
diff --git a/platform-mc/manager.hpp b/platform-mc/manager.hpp
index 039d6f9..45a311a 100644
--- a/platform-mc/manager.hpp
+++ b/platform-mc/manager.hpp
@@ -255,6 +255,17 @@
*/
exec::task<int> oemPollForPlatformEvent(pldm_tid_t tid);
+ /** @brief Get Active EIDs.
+ *
+ * @param[in] addr - MCTP address of terminus
+ * @param[in] terminiNames - MCTP terminus name
+ */
+ std::optional<mctp_eid_t> getActiveEidByName(
+ const std::string& terminusName)
+ {
+ return terminusManager.getActiveEidByName(terminusName);
+ }
+
private:
/** @brief List of discovered termini */
TerminiMapper termini{};
diff --git a/platform-mc/terminus_manager.cpp b/platform-mc/terminus_manager.cpp
index 1086292..c64c0c3 100644
--- a/platform-mc/terminus_manager.cpp
+++ b/platform-mc/terminus_manager.cpp
@@ -734,5 +734,44 @@
co_return completionCode;
}
+std::optional<mctp_eid_t> TerminusManager::getActiveEidByName(
+ const std::string& terminusName)
+{
+ if (!termini.size() || terminusName.empty())
+ {
+ return std::nullopt;
+ }
+
+ for (auto& [tid, terminus] : termini)
+ {
+ if (!terminus)
+ {
+ continue;
+ }
+
+ auto tmp = terminus->getTerminusName();
+ if (!tmp || std::empty(*tmp) || *tmp != terminusName)
+ {
+ continue;
+ }
+
+ try
+ {
+ auto mctpInfo = toMctpInfo(tid);
+ if (!mctpInfo || !mctpInfoAvailTable[*mctpInfo])
+ {
+ return std::nullopt;
+ }
+
+ return std::get<0>(*mctpInfo);
+ }
+ catch (const std::exception& e)
+ {
+ return std::nullopt;
+ }
+ }
+
+ return std::nullopt;
+}
} // namespace platform_mc
} // namespace pldm
diff --git a/platform-mc/terminus_manager.hpp b/platform-mc/terminus_manager.hpp
index 0eb2869..f8611f7 100644
--- a/platform-mc/terminus_manager.hpp
+++ b/platform-mc/terminus_manager.hpp
@@ -170,6 +170,16 @@
*/
std::string constructEndpointObjPath(const MctpInfo& mctpInfo);
+ /** @brief Member functions to get the MCTP eid of active MCTP medium
+ * interface of one terminus by terminus name
+ *
+ * @param[in] terminusName - terminus name
+ *
+ * @return option mctp_eid_t - the mctp eid or std::nullopt
+ */
+ std::optional<mctp_eid_t> getActiveEidByName(
+ const std::string& terminusName);
+
private:
/** @brief Find the terminus object pointer in termini list.
*
diff --git a/platform-mc/test/terminus_manager_test.cpp b/platform-mc/test/terminus_manager_test.cpp
index 7fa8506..80d2699 100644
--- a/platform-mc/test/terminus_manager_test.cpp
+++ b/platform-mc/test/terminus_manager_test.cpp
@@ -6,6 +6,7 @@
#include "common/instance_id.hpp"
#include "common/types.hpp"
#include "mock_terminus_manager.hpp"
+#include "platform-mc/platform_manager.hpp"
#include "platform-mc/terminus_manager.hpp"
#include "requester/handler.hpp"
#include "requester/mctp_endpoint_discovery.hpp"
@@ -34,7 +35,8 @@
std::chrono::seconds(1), 2, std::chrono::milliseconds(100)),
terminusManager(event, reqHandler, instanceIdDb, termini, nullptr,
pldm::BmcMctpEid),
- mockTerminusManager(event, reqHandler, instanceIdDb, termini, nullptr)
+ mockTerminusManager(event, reqHandler, instanceIdDb, termini, nullptr),
+ platformManager(mockTerminusManager, termini, nullptr)
{}
PldmTransport* pldmTransport = nullptr;
@@ -44,6 +46,7 @@
pldm::requester::Handler<pldm::requester::Request> reqHandler;
pldm::platform_mc::TerminusManager terminusManager;
pldm::platform_mc::MockTerminusManager mockTerminusManager;
+ pldm::platform_mc::PlatformManager platformManager;
std::map<pldm_tid_t, std::shared_ptr<pldm::platform_mc::Terminus>> termini;
};
@@ -542,3 +545,174 @@
EXPECT_EQ(false, termini[1]->doesSupportCommand(
PLDM_FRU, PLDM_GET_FRU_RECORD_BY_OPTION));
}
+
+TEST_F(TerminusManagerTest, getActiveEidByNameTest)
+{
+ // Add terminus
+ pldm::MctpInfo mctpInfo(10, "", "", 1);
+ auto mappedTid = mockTerminusManager.mapTid(mctpInfo);
+ auto tid = mappedTid.value();
+ termini[tid] = std::make_shared<pldm::platform_mc::Terminus>(
+ tid, 1 << PLDM_BASE | 1 << PLDM_PLATFORM);
+ auto terminus = termini[tid];
+
+ auto mappedTid1 = terminusManager.mapTid(mctpInfo);
+ EXPECT_EQ(mappedTid1, mappedTid);
+
+ auto mctpInfo1 = terminusManager.toMctpInfo(tid);
+ EXPECT_EQ(mctpInfo, mctpInfo1.value());
+
+ /* Set supported command by terminus */
+ auto size = PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8);
+ std::vector<uint8_t> pldmCmds(size);
+ uint8_t type = PLDM_PLATFORM;
+ uint8_t cmd = PLDM_GET_PDR;
+ auto idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8);
+ pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8));
+ cmd = PLDM_GET_PDR_REPOSITORY_INFO;
+ idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (cmd / 8);
+ pldmCmds[idx] = pldmCmds[idx] | (1 << (cmd % 8));
+ termini[tid]->setSupportedCommands(pldmCmds);
+
+ // queue getPDRRepositoryInfo response
+ const size_t getPDRRepositoryInfoLen =
+ PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES;
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + getPDRRepositoryInfoLen>
+ getPDRRepositoryInfoResp{
+ 0x0, 0x02, 0x50, PLDM_SUCCESS,
+ 0x0, // repositoryState
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // updateTime
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // OEMUpdateTime
+ 2, 0x0, 0x0, 0x0, // recordCount
+ 0x0, 0x1, 0x0, 0x0, // repositorySize
+ 59, 0x0, 0x0, 0x0, // largestRecordSize
+ 0x0 // dataTransferHandleTimeout
+ };
+ auto rc = mockTerminusManager.enqueueResponse(
+ reinterpret_cast<pldm_msg*>(getPDRRepositoryInfoResp.data()),
+ sizeof(getPDRRepositoryInfoResp));
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+
+ // queue getPDR responses
+ const size_t getPdrRespLen = 81;
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + getPdrRespLen> getPdrResp{
+ 0x0, 0x02, 0x51, PLDM_SUCCESS, 0x1, 0x0, 0x0, 0x0, // nextRecordHandle
+ 0x0, 0x0, 0x0, 0x0, // nextDataTransferHandle
+ 0x5, // transferFlag
+ 69, 0x0, // responseCount
+ // numeric Sensor PDR
+ 0x0, 0x0, 0x0,
+ 0x0, // record handle
+ 0x1, // PDRHeaderVersion
+ PLDM_NUMERIC_SENSOR_PDR, // PDRType
+ 0x0,
+ 0x0, // recordChangeNumber
+ PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH +
+ PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_SENSOR_DATA_SIZE_MIN_LENGTH +
+ PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_RANGE_FIELD_MIN_LENGTH,
+ 0, // dataLength
+ 0,
+ 0, // PLDMTerminusHandle
+ 0x1,
+ 0x0, // sensorID=1
+ 120,
+ 0, // entityType=Power Supply(120)
+ 1,
+ 0, // entityInstanceNumber
+ 0x1,
+ 0x0, // containerID=1
+ PLDM_NO_INIT, // sensorInit
+ false, // sensorAuxiliaryNamesPDR
+ PLDM_SENSOR_UNIT_DEGRESS_C, // baseUint(2)=degrees C
+ 1, // unitModifier = 1
+ 0, // rateUnit
+ 0, // baseOEMUnitHandle
+ 0, // auxUnit
+ 0, // auxUnitModifier
+ 0, // auxRateUnit
+ 0, // rel
+ 0, // auxOEMUnitHandle
+ true, // isLinear
+ PLDM_SENSOR_DATA_SIZE_UINT8, // sensorDataSize
+ 0, 0, 0xc0,
+ 0x3f, // resolution=1.5
+ 0, 0, 0x80,
+ 0x3f, // offset=1.0
+ 0,
+ 0, // accuracy
+ 0, // plusTolerance
+ 0, // minusTolerance
+ 2, // hysteresis
+ 0, // supportedThresholds
+ 0, // thresholdAndHysteresisVolatility
+ 0, 0, 0x80,
+ 0x3f, // stateTransistionInterval=1.0
+ 0, 0, 0x80,
+ 0x3f, // updateInverval=1.0
+ 255, // maxReadable
+ 0, // minReadable
+ PLDM_RANGE_FIELD_FORMAT_UINT8, // rangeFieldFormat
+ 0, // rangeFieldsupport
+ 0, // nominalValue
+ 0, // normalMax
+ 0, // normalMin
+ 0, // warningHigh
+ 0, // warningLow
+ 0, // criticalHigh
+ 0, // criticalLow
+ 0, // fatalHigh
+ 0 // fatalLow
+ };
+ rc = mockTerminusManager.enqueueResponse(
+ reinterpret_cast<pldm_msg*>(getPdrResp.data()), sizeof(getPdrResp));
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+
+ const size_t getPdrAuxNameRespLen = 39;
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + getPdrAuxNameRespLen>
+ getPdrAuxNameResp{
+ 0x0, 0x02, 0x51, PLDM_SUCCESS, 0x0, 0x0, 0x0,
+ 0x0, // nextRecordHandle
+ 0x0, 0x0, 0x0, 0x0, // nextDataTransferHandle
+ 0x5, // transferFlag
+ 0x1b, 0x0, // responseCount
+ // Common PDR Header
+ 0x1, 0x0, 0x0,
+ 0x0, // record handle
+ 0x1, // PDRHeaderVersion
+ PLDM_ENTITY_AUXILIARY_NAMES_PDR, // PDRType
+ 0x1,
+ 0x0, // recordChangeNumber
+ 0x11,
+ 0, // dataLength
+ /* Entity Auxiliary Names PDR Data*/
+ 3,
+ 0x80, // entityType system software
+ 0x1,
+ 0x0, // Entity instance number =1
+ 0,
+ 0, // Overall system
+ 0, // shared Name Count one name only
+ 01, // nameStringCount
+ 0x65, 0x6e, 0x00,
+ 0x00, // Language Tag "en"
+ 0x53, 0x00, 0x30, 0x00,
+ 0x00 // Entity Name "S0"
+ };
+ rc = mockTerminusManager.enqueueResponse(
+ reinterpret_cast<pldm_msg*>(getPdrAuxNameResp.data()),
+ sizeof(getPdrAuxNameResp));
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+
+ mockTerminusManager.updateMctpEndpointAvailability(mctpInfo, true);
+ terminusManager.updateMctpEndpointAvailability(mctpInfo, true);
+
+ stdexec::sync_wait(platformManager.initTerminus());
+ EXPECT_EQ(true, terminus->initialized);
+ EXPECT_EQ(2, terminus->pdrs.size());
+ EXPECT_EQ(1, termini.size());
+ EXPECT_EQ("S0", terminus->getTerminusName().value());
+ EXPECT_EQ(10, terminusManager.getActiveEidByName("S0").value());
+ EXPECT_EQ(false, terminusManager.getActiveEidByName("S1").has_value());
+}