diff --git a/common/types.hpp b/common/types.hpp index 68d3c3c755..312565152b 100644 --- a/common/types.hpp +++ b/common/types.hpp @@ -31,20 +31,25 @@ using MctpMedium = std::string; * uint32_t is used as defined in MCTP Endpoint D-Bus Interface */ using NetworkId = uint32_t; +using NetworkInterface = std::string; +using LocalEid = uint8_t; /** @brief Type definition of MCTP name in string */ using MctpInfoName = std::optional; /** @brief Type definition of MCTP interface information between two endpoints. - * eid : Endpoint EID in byte. Defined to match with MCTP D-Bus - * interface - * UUID : Endpoint UUID which is used to different the endpoints - * MctpMedium: Endpoint MCTP Medium info (Resersed) - * NetworkId: MCTP network index - * name: Alias name of the endpoint, e.g. BMC, NIC, etc. + * + * eid : Endpoint EID (byte). Matches MCTP D-Bus endpoint EID. + * UUID : Endpoint UUID used to uniquely identify endpoints. + * MctpMedium : Endpoint MCTP medium information (reserved/transport-specific). + * NetworkId : MCTP network index identifying the MCTP network. + * MctpInfoName : Alias name of the endpoint (e.g. BMC, NIC, etc.). + * NetworkInterface : Underlying transport interface used for MCTP communication + * (e.g. mctpi3c4, mctppcie0). + * LocalEid : Host-assigned identifier associated with the interface. */ -using MctpInfo = std::tuple; +using MctpInfo = std::tuple; /** @brief Type definition of MCTP endpoint D-Bus properties in * xyz.openbmc_project.MCTP.Endpoint D-Bus interface. @@ -54,7 +59,7 @@ using MctpInfo = std::tuple; * interface * MCTPMsgTypes: MCTP message types */ -using MctpEndpointProps = std::tuple; +using MctpEndpointProps = std::tuple; /** @brief Type defined for list of MCTP interface information */ diff --git a/configurations/pdr/com.amd.Hardware.Chassis/pdr_config.json b/configurations/pdr/com.amd.Hardware.Chassis/pdr_config.json index e068623a78..b3e1073f61 100644 --- a/configurations/pdr/com.amd.Hardware.Chassis/pdr_config.json +++ b/configurations/pdr/com.amd.Hardware.Chassis/pdr_config.json @@ -1,7 +1,13 @@ { "uuids": { - "28318908-bc42-4463-a8f8-f0cc7b43c5e6": 0, - "8bc76e13-94c1-4e52-992b-d4d845e3572a": 1 + "28318908-bc42-4463-a8f8-f0cc7b43c5e6": { + "mctpi3c4": 0, + "mctpi3c5": 1 + }, + "8bc76e13-94c1-4e52-992b-d4d845e3572a": { + "mctpi3c4": 0, + "mctpi3c5": 1 + } }, "excludeNumericEffecterPDRs": [ diff --git a/fw-update/manager.hpp b/fw-update/manager.hpp index db5cb64744..9d738b0952 100644 --- a/fw-update/manager.hpp +++ b/fw-update/manager.hpp @@ -56,7 +56,7 @@ class Manager : public pldm::MctpDiscoveryHandlerIntf std::vector eids; for (const auto& mctpInfo : mctpInfos) { - eids.emplace_back(std::get(mctpInfo)); + eids.emplace_back(std::get<0>(mctpInfo)); } inventoryMgr.discoverFDs(eids); diff --git a/oem/amd/platform-mc/platform_manager.cpp b/oem/amd/platform-mc/platform_manager.cpp index 9e8cca46ff..faebf93031 100644 --- a/oem/amd/platform-mc/platform_manager.cpp +++ b/oem/amd/platform-mc/platform_manager.cpp @@ -324,7 +324,8 @@ std::optional> decode_compact_numeric_sensor_pdr( /* Setting default values when getPDRRepositoryInfo fails or does not support */ exec::task PlatformManager::get_pdr_from_json( - std::shared_ptr terminus, std::string targetUuid) + std::shared_ptr terminus, std::string targetUuid, + std::string networkInterface) { pldm_tid_t tid = terminus->getTid(); @@ -345,15 +346,24 @@ exec::task PlatformManager::get_pdr_from_json( throw std::runtime_error("Could not open UUID mapping file"); } - // 2. Parse directly into a map + using InterfaceMap = std::unordered_map; + using UuidMap = std::unordered_map; + + // Parse JSON auto j = nlohmann::json::parse(uuidFile); - auto uuid_map = j["uuids"].get>(); + auto uuidMap = j["uuids"].get(); + + // Find UUID + auto uuidIt = uuidMap.find(targetUuid); + if (uuidIt == uuidMap.end()) + { + co_return PLDM_ERROR_INVALID_DATA; + } - // Early exit if the UUID is not in the map - auto it = uuid_map.find(targetUuid); - if (it == uuid_map.end()) + // Find interface + auto ifaceIt = uuidIt->second.find(networkInterface); + if (ifaceIt == uuidIt->second.end()) { - // UUID not found in the mapping co_return PLDM_ERROR_INVALID_DATA; } @@ -378,7 +388,7 @@ exec::task PlatformManager::get_pdr_from_json( } #endif - int processorIndex = it->second; + int processorIndex = ifaceIt->second; std::string procName = "Processor" + std::to_string(processorIndex); std::string procPdrDir = pdrDir + "/" + procName; lg2::info("Loading PDRs for TID {TID} from {PATH}", "TID", tid, "PATH", procPdrDir); diff --git a/platform-mc/platform_manager.cpp b/platform-mc/platform_manager.cpp index fc5a0b301e..a6fffeac9f 100644 --- a/platform-mc/platform_manager.cpp +++ b/platform-mc/platform_manager.cpp @@ -77,7 +77,8 @@ exec::task PlatformManager::initTerminus() auto mctpInfo = terminusManager.getMctpInfoForTid(tid); if (mctpInfo.has_value()) { std::string uuid = std::get<1>(*mctpInfo); - auto rc = co_await get_pdr_from_json(terminus, uuid); + std::string networkInterface = std::get<2>(*mctpInfo); + auto rc = co_await get_pdr_from_json(terminus, uuid, networkInterface); if (rc) { lg2::error( @@ -140,7 +141,7 @@ exec::task PlatformManager::initTerminus() if (info) { pldm::utils::emitRDEDeviceDetectedSignal( - tid, info->first, info->second, redfishResources); + tid, std::get<0>(*info), std::get<1>(*info), redfishResources); } else { @@ -541,6 +542,7 @@ exec::task PlatformManager::setEventReceiver( pldm_tid_t tid, pldm_event_message_global_enable eventMessageGlobalEnable, pldm_transport_protocol_type protocolType, uint16_t heartbeatTimer) { + uint8_t localEid = 0; size_t requestBytes = PLDM_SET_EVENT_RECEIVER_REQ_BYTES; /** * Ignore heartbeatTimer bytes when eventMessageGlobalEnable is not @@ -553,9 +555,21 @@ exec::task PlatformManager::setEventReceiver( } Request request(sizeof(pldm_msg_hdr) + requestBytes); auto requestMsg = new (request.data()) pldm_msg; + + auto info = terminusManager.getMctpInfoForTid(tid); + if (info) + { + localEid = std::get<3>(*info); + } + else + { + lg2::error("Failed to find Mctp Info for terminus with TID: {TID}", "TID", tid); + } + lg2::info("Set event receiver: LocalEid {LID} for tid: {TID}", "LID", localEid, "TID", tid); + auto rc = encode_set_event_receiver_req( 0, eventMessageGlobalEnable, protocolType, - terminusManager.getLocalEid(), heartbeatTimer, requestMsg); + localEid, heartbeatTimer, requestMsg); if (rc) { lg2::error( diff --git a/platform-mc/platform_manager.hpp b/platform-mc/platform_manager.hpp index 6e30be8d89..16dba5f0d8 100644 --- a/platform-mc/platform_manager.hpp +++ b/platform-mc/platform_manager.hpp @@ -57,7 +57,9 @@ class PlatformManager exec::task getPDRs(std::shared_ptr terminus); #ifdef OEM_AMD - exec::task get_pdr_from_json(std::shared_ptr terminus, std::string targetUuid); + exec::task get_pdr_from_json( + std::shared_ptr terminus, std::string targetUuid, + std::string networkInterface); #endif /** @brief Fetch PDR from terminus diff --git a/platform-mc/terminus_manager.cpp b/platform-mc/terminus_manager.cpp index 935cdd8f22..8f2b4c49e2 100644 --- a/platform-mc/terminus_manager.cpp +++ b/platform-mc/terminus_manager.cpp @@ -780,8 +780,8 @@ std::optional TerminusManager::getActiveEidByName( return std::nullopt; } -std::optional> TerminusManager::getMctpInfoForTid( - pldm_tid_t tid) +std::optional> +TerminusManager::getMctpInfoForTid(pldm_tid_t tid) { auto it = mctpInfoTable.find(tid); if (it == mctpInfoTable.end()) @@ -790,33 +790,14 @@ std::optional> TerminusManager::getMctpInfoForTid( } const auto& mctpInfo = it->second; - return std::make_pair(std::get<0>(mctpInfo), std::get<1>(mctpInfo)); -} - -std::optional TerminusManager::getBmcMctpEid() -{ - const std::string fileName = "/var/run/bmceid0"; - - try - { - std::ifstream toDevice; - - toDevice.exceptions(std::ios::failbit | std::ios::badbit); - toDevice.open(fileName); - - uint8_t bmcMctpEid = 0; - toDevice.read(reinterpret_cast(&bmcMctpEid), sizeof(bmcMctpEid)); - return bmcMctpEid; - } - - catch (const std::ios_base::failure& iose) - { - std::cerr << "In file I/O error: " << iose.what() << fileName - << std::endl; - } - - return std::nullopt; + return std::make_tuple( + std::get<0>(mctpInfo), // eid + std::get<1>(mctpInfo), // uuid + std::get<5>(mctpInfo), // interface + std::get<6>(mctpInfo) // hostid + ); } + } // namespace platform_mc } // namespace pldm diff --git a/platform-mc/terminus_manager.hpp b/platform-mc/terminus_manager.hpp index 250fe995ce..b0e53eb0d8 100644 --- a/platform-mc/terminus_manager.hpp +++ b/platform-mc/terminus_manager.hpp @@ -146,20 +146,6 @@ class TerminusManager */ bool unmapTid(const pldm_tid_t& tid); - /** @brief getter of local EID - * - * @return uint8_t - local EID - */ - mctp_eid_t getLocalEid() - { - auto hostEid = getBmcMctpEid(); - - if (hostEid.has_value()) - return *hostEid; - - return localEid; - } - /** @brief Helper function to invoke registered handlers for * updating the availability status of the MCTP endpoint * @@ -196,18 +182,20 @@ class TerminusManager * @return std::optional> Returns a pair of EID and * UUID if the TID is found, or std::nullopt if not found. */ - std::optional> getMctpInfoForTid(pldm_tid_t tid); + std::optional> getMctpInfoForTid( + pldm_tid_t tid); /** * @brief Get the BMC Host EID stored in a file * - * This function looks up the a file and if the file exists and + * This function looks up a file and, if the file exists and * can be read, reads the MCTP EID stored in that file. * - * @return std::optional Returns a BMC MCTP EID - * stored in the file and in case of any errors, return NULL value. + * @param[in] hostNumber The identifier of the specific host. + * @return std::optional Returns the BMC MCTP EID stored + * in the file, or std::nullopt in case of any errors. */ - std::optional getBmcMctpEid(); + std::optional getBmcMctpEid(const int hostNumber); private: /** @brief Find the terminus object pointer in termini list. diff --git a/requester/mctp_endpoint_discovery.cpp b/requester/mctp_endpoint_discovery.cpp index db764bfe75..393ada58ca 100644 --- a/requester/mctp_endpoint_discovery.cpp +++ b/requester/mctp_endpoint_discovery.cpp @@ -75,18 +75,26 @@ void MctpDiscovery::getMctpInfos(std::map& mctpInfoMap) for (const auto& serviceIter : services) { const std::string& service = serviceIter.first; - const MctpEndpointProps& epProps = + const MctpEndpointProps epProps = getMctpEndpointProps(service, path); const UUID& uuid = getEndpointUUIDProp(service, path); const Availability& availability = getEndpointConnectivityProp(path); auto types = std::get(epProps); + + const auto& networkInterface = std::get<3>(epProps); + const std::string localEidPath = + std::string(LocalEidInterfacePath) + networkInterface; + const LocalEid localEid = getInterfaceLocalEidProp(service, localEidPath); + if (std::find(types.begin(), types.end(), mctpTypePLDM) != types.end()) { auto mctpInfo = - MctpInfo(std::get(epProps), uuid, "", - std::get(epProps), std::nullopt); + MctpInfo(std::get<1>(epProps), uuid, "", + std::get<0>(epProps), std::nullopt, + std::get<3>(epProps), + localEid); searchConfigurationFor(pldm::utils::DBusHandler(), mctpInfo); mctpInfoMap[std::move(mctpInfo)] = availability; } @@ -103,13 +111,16 @@ MctpEndpointProps MctpDiscovery::getMctpEndpointProps( service.c_str(), path.c_str(), MCTPInterface); if (properties.contains("NetworkId") && properties.contains("EID") && + properties.contains("NetworkInterface") && properties.contains("SupportedMessageTypes")) { auto networkId = std::get(properties.at("NetworkId")); auto eid = std::get(properties.at("EID")); auto types = std::get>( properties.at("SupportedMessageTypes")); - return MctpEndpointProps(networkId, eid, types); + auto networkInterface = std::get(properties.at("NetworkInterface")); + + return MctpEndpointProps(networkId, eid, types, networkInterface); } } catch (const sdbusplus::exception_t& e) @@ -117,10 +128,10 @@ MctpEndpointProps MctpDiscovery::getMctpEndpointProps( error( "Error reading MCTP Endpoint property at path '{PATH}' and service '{SERVICE}', error - {ERROR}", "SERVICE", service, "PATH", path, "ERROR", e); - return MctpEndpointProps(0, MCTP_ADDR_ANY, {}); + return MctpEndpointProps(0, MCTP_ADDR_ANY, {}, ""); } - return MctpEndpointProps(0, MCTP_ADDR_ANY, {}); + return MctpEndpointProps(0, MCTP_ADDR_ANY, {}, ""); } UUID MctpDiscovery::getEndpointUUIDProp(const std::string& service, @@ -170,6 +181,30 @@ Availability MctpDiscovery::getEndpointConnectivityProp(const std::string& path) return available; } +LocalEid MctpDiscovery::getInterfaceLocalEidProp(const std::string& service, + const std::string& path) +{ + try + { + auto properties = pldm::utils::DBusHandler().getDbusPropertiesVariant( + service.c_str(), path.c_str(), LocalEidInterface); + + if (properties.contains("LocalEid")) + { + return std::get(properties.at("LocalEid")); + } + } + catch (const sdbusplus::exception_t& e) + { + error( + "Error reading Interface LocalEid property at path '{PATH}' and service '{SERVICE}', error - {ERROR}", + "SERVICE", service, "PATH", path, "ERROR", e); + return static_cast(0); + } + + return static_cast(0); +} + void MctpDiscovery::getAddedMctpInfos(sdbusplus::message_t& msg, MctpInfos& mctpInfos) { @@ -212,6 +247,7 @@ void MctpDiscovery::getAddedMctpInfos(sdbusplus::message_t& msg, { if (properties.contains("NetworkId") && properties.contains("EID") && + properties.contains("NetworkInterface") && properties.contains("SupportedMessageTypes")) { auto networkId = @@ -219,6 +255,12 @@ void MctpDiscovery::getAddedMctpInfos(sdbusplus::message_t& msg, auto eid = std::get(properties.at("EID")); auto types = std::get>( properties.at("SupportedMessageTypes")); + auto networkInterface = + std::get(properties.at("NetworkInterface")); + + const std::string localEidPath = + std::string(LocalEidInterfacePath) + networkInterface; + const LocalEid localEid = getInterfaceLocalEidProp(MCTPService, localEidPath); if (!availability) { @@ -232,10 +274,12 @@ void MctpDiscovery::getAddedMctpInfos(sdbusplus::message_t& msg, types.end()) { info( - "Adding Endpoint networkId '{NETWORK}' and EID '{EID}' UUID '{UUID}'", - "NETWORK", networkId, "EID", eid, "UUID", uuid); + "Adding Endpoint networkId '{NETWORK}' and EID '{EID}' " + "UUID '{UUID}' Interface '{NINTF}' LocalEid '{LID}'", + "NETWORK", networkId, "EID", eid, + "UUID", uuid, "NINTF", networkInterface, "LID", localEid); auto mctpInfo = - MctpInfo(eid, uuid, "", networkId, std::nullopt); + MctpInfo(eid, uuid, "", networkId, std::nullopt, networkInterface, localEid); searchConfigurationFor(pldm::utils::DBusHandler(), mctpInfo); mctpInfos.emplace_back(std::move(mctpInfo)); @@ -312,18 +356,25 @@ void MctpDiscovery::propertiesChangedCb(sdbusplus::message_t& msg) { service = pldm::utils::DBusHandler().getService(objPath.c_str(), MCTPInterface); - const MctpEndpointProps& epProps = + const MctpEndpointProps epProps = getMctpEndpointProps(service, objPath); - auto types = std::get(epProps); + auto types = std::get<2>(epProps); if (!std::ranges::contains(types, mctpTypePLDM)) { return; } const UUID& uuid = getEndpointUUIDProp(service, objPath); - MctpInfo mctpInfo(std::get(epProps), uuid, "", - std::get(epProps), std::nullopt); + const auto& networkInterface = std::get<3>(epProps); + const std::string localEidPath = + std::string(LocalEidInterfacePath) + networkInterface; + const LocalEid localEid = getInterfaceLocalEidProp(service, localEidPath); + + MctpInfo mctpInfo(std::get<1>(epProps), uuid, "", + std::get<0>(epProps), std::nullopt, + std::get<3>(epProps), + localEid); searchConfigurationFor(pldm::utils::DBusHandler(), mctpInfo); if (!std::ranges::contains(existingMctpInfos, mctpInfo)) { @@ -420,8 +471,8 @@ std::string MctpDiscovery::getNameFromProperties( std::string MctpDiscovery::constructMctpReactorObjectPath( const MctpInfo& mctpInfo) { - const auto networkId = std::get(mctpInfo); - const auto eid = std::get(mctpInfo); + const auto networkId = std::get<3>(mctpInfo); + const auto eid = std::get<0>(mctpInfo); return std::string{MCTPPath} + "/networks/" + std::to_string(networkId) + "/endpoints/" + std::to_string(eid) + "/configured_by"; } @@ -498,10 +549,10 @@ void MctpDiscovery::removeConfigs(const MctpInfos& removedInfos) { for (const auto& mctpInfo : removedInfos) { - auto eidToRemove = std::get(mctpInfo); + auto eidToRemove = std::get<0>(mctpInfo); std::erase_if(configurations, [eidToRemove](const auto& config) { auto& [__, mctpInfo] = config; - auto eidValue = std::get(mctpInfo); + auto eidValue = std::get<0>(mctpInfo); return eidValue == eidToRemove; }); } diff --git a/requester/mctp_endpoint_discovery.hpp b/requester/mctp_endpoint_discovery.hpp index 76928492f6..3123a63942 100644 --- a/requester/mctp_endpoint_discovery.hpp +++ b/requester/mctp_endpoint_discovery.hpp @@ -20,6 +20,8 @@ const std::string emptyUUID = "00000000-0000-0000-0000-000000000000"; constexpr const char* MCTPService = "au.com.codeconstruct.MCTP1"; constexpr const char* MCTPInterface = "xyz.openbmc_project.MCTP.Endpoint"; constexpr const char* EndpointUUID = "xyz.openbmc_project.Common.UUID"; +constexpr const char* LocalEidInterface = "au.com.codeconstruct.MCTP.Interface1"; +constexpr const char* LocalEidInterfacePath = "/au/com/codeconstruct/mctp1/interfaces/"; constexpr const char* MCTPPath = "/au/com/codeconstruct/mctp1"; constexpr const char* MCTPInterfaceCC = "au.com.codeconstruct.MCTP.Endpoint1"; constexpr const char* MCTPConnectivityProp = "Connectivity"; @@ -191,6 +193,11 @@ class MctpDiscovery UUID getEndpointUUIDProp(const std::string& service, const std::string& path); + + LocalEid getInterfaceLocalEidProp(const std::string& service, + const std::string& path); + + /** @brief Get Endpoint Availability status from `Connectivity` D-Bus * property in the `au.com.codeconstruct.MCTP.Endpoint1` D-Bus * interface.