requester: Modified MctpDiscovery class
Modified MctpDiscovery class to take list of managers instead of single
fwManager. The change is for adding platform-mc manager.
Added loadStaticEndpoints API for MCTP layer which doesn't implement
/xyz/openbmc_project/MCTP/Endpoint.Interface
The patch is part of implementation of design document below.
https://gerrit.openbmc-project.xyz/c/openbmc/docs/+/47252
Signed-off-by: Gilbert Chen <gilbert.chen@arm.com>
Signed-off-by: Thu Nguyen <thu@os.amperecomputing.com>
Change-Id: I1e1673504583a87f2a9bc3adf76fb49c2dc30254
diff --git a/requester/mctp_endpoint_discovery.cpp b/requester/mctp_endpoint_discovery.cpp
index a962228..9440ed0 100644
--- a/requester/mctp_endpoint_discovery.cpp
+++ b/requester/mctp_endpoint_discovery.cpp
@@ -1,100 +1,214 @@
+#include "config.h"
+
#include "mctp_endpoint_discovery.hpp"
#include "common/types.hpp"
#include "common/utils.hpp"
+#include <phosphor-logging/lg2.hpp>
+
#include <algorithm>
+#include <fstream>
+#include <iostream>
#include <map>
#include <string>
#include <string_view>
#include <vector>
+using namespace sdbusplus::bus::match::rules;
+
+PHOSPHOR_LOG2_USING;
+
namespace pldm
{
-MctpDiscovery::MctpDiscovery(sdbusplus::bus_t& bus,
- fw_update::Manager* fwManager) :
+MctpDiscovery::MctpDiscovery(
+ sdbusplus::bus::bus& bus,
+ std::initializer_list<MctpDiscoveryHandlerIntf*> list) :
bus(bus),
- fwManager(fwManager),
- mctpEndpointSignal(bus,
- sdbusplus::bus::match::rules::interfacesAdded(
- "/xyz/openbmc_project/mctp"),
- std::bind_front(&MctpDiscovery::dicoverEndpoints, this))
+ mctpEndpointAddedSignal(
+ bus, interfacesAdded(MCTPPath),
+ std::bind_front(&MctpDiscovery::discoverEndpoints, this)),
+ mctpEndpointRemovedSignal(
+ bus, interfacesRemoved(MCTPPath),
+ std::bind_front(&MctpDiscovery::removeEndpoints, this)),
+ handlers(list)
{
- pldm::utils::ObjectValueTree objects;
+ getMctpInfos(existingMctpInfos);
+ handleMctpEndpoints(existingMctpInfos);
+}
+void MctpDiscovery::getMctpInfos(MctpInfos& mctpInfos)
+{
+ // Find all implementations of the MCTP Endpoint interface
+ pldm::utils::GetSubTreeResponse mapperResponse;
try
{
- objects = pldm::utils::DBusHandler::getManagedObj(MCTPService,
- MCTPPath);
+ mapperResponse = pldm::utils::DBusHandler().getSubtree(
+ MCTPPath, 0, std::vector<std::string>({MCTPInterface}));
}
- catch (const std::exception& e)
+ catch (const sdbusplus::exception_t& e)
{
- error("Failed to call the D-Bus Method: {ERROR}", "ERROR", e);
+ error("getSubtree call failed with, {ERROR} {PATH} {INTERFACE}",
+ "ERROR", e, "PATH", MCTPPath, "INTERFACE", MCTPInterface);
return;
}
- std::vector<mctp_eid_t> eids;
-
- for (const auto& [objectPath, interfaces] : objects)
+ for (const auto& [path, services] : mapperResponse)
{
- for (const auto& [intfName, properties] : interfaces)
+ for (const auto& serviceIter : services)
{
- if (intfName == mctpEndpointIntfName)
+ const std::string& service = serviceIter.first;
+ try
{
- if (properties.contains("EID") &&
+ auto properties =
+ pldm::utils::DBusHandler().getDbusPropertiesVariant(
+ service.c_str(), path.c_str(), MCTPInterface);
+
+ if (properties.contains("NetworkId") &&
+ properties.contains("EID") &&
properties.contains("SupportedMessageTypes"))
{
+ auto networkId =
+ std::get<NetworkId>(properties.at("NetworkId"));
auto eid = std::get<mctp_eid_t>(properties.at("EID"));
auto types = std::get<std::vector<uint8_t>>(
properties.at("SupportedMessageTypes"));
if (std::find(types.begin(), types.end(), mctpTypePLDM) !=
types.end())
{
- eids.emplace_back(eid);
+ info("Adding Endpoint networkId={NETWORK} EID={EID}",
+ "NETWORK", networkId, "EID", unsigned(eid));
+ mctpInfos.emplace_back(
+ MctpInfo(eid, emptyUUID, "", networkId));
}
}
}
+ catch (const sdbusplus::exception_t& e)
+ {
+ error(
+ "Error reading MCTP Endpoint property, {ERROR} {SERVICE} {PATH}",
+ "ERROR", e, "SERVICE", service, "PATH", path);
+ return;
+ }
}
}
-
- if (eids.size() && fwManager)
- {
- fwManager->handleMCTPEndpoints(eids);
- }
}
-void MctpDiscovery::dicoverEndpoints(sdbusplus::message_t& msg)
+void MctpDiscovery::getAddedMctpInfos(sdbusplus::message_t& msg,
+ MctpInfos& mctpInfos)
{
- constexpr std::string_view mctpEndpointIntfName{
- "xyz.openbmc_project.MCTP.Endpoint"};
- std::vector<mctp_eid_t> eids;
+ using ObjectPath = sdbusplus::message::object_path;
+ ObjectPath objPath;
+ using Property = std::string;
+ using PropertyMap = std::map<Property, dbus::Value>;
+ std::map<std::string, PropertyMap> interfaces;
- sdbusplus::message::object_path objPath;
- std::map<std::string, std::map<std::string, dbus::Value>> interfaces;
- msg.read(objPath, interfaces);
+ try
+ {
+ msg.read(objPath, interfaces);
+ }
+ catch (const sdbusplus::exception_t& e)
+ {
+ error("Error reading MCTP Endpoint addedInterace message, {ERROR}",
+ "ERROR", e);
+ return;
+ }
for (const auto& [intfName, properties] : interfaces)
{
- if (intfName == mctpEndpointIntfName)
+ if (intfName == MCTPInterface)
{
- if (properties.contains("EID") &&
+ if (properties.contains("NetworkId") &&
+ properties.contains("EID") &&
properties.contains("SupportedMessageTypes"))
{
+ auto networkId =
+ std::get<NetworkId>(properties.at("NetworkId"));
auto eid = std::get<mctp_eid_t>(properties.at("EID"));
auto types = std::get<std::vector<uint8_t>>(
properties.at("SupportedMessageTypes"));
if (std::find(types.begin(), types.end(), mctpTypePLDM) !=
types.end())
{
- eids.emplace_back(eid);
+ info("Adding Endpoint networkId={NETWORK} EID={EID}",
+ "NETWORK", networkId, "EID", unsigned(eid));
+ mctpInfos.emplace_back(
+ MctpInfo(eid, emptyUUID, "", networkId));
}
}
}
}
+}
- if (eids.size() && fwManager)
+void MctpDiscovery::addToExistingMctpInfos(const MctpInfos& addedInfos)
+{
+ for (const auto& mctpInfo : addedInfos)
{
- fwManager->handleMCTPEndpoints(eids);
+ if (std::find(existingMctpInfos.begin(), existingMctpInfos.end(),
+ mctpInfo) == existingMctpInfos.end())
+ {
+ existingMctpInfos.emplace_back(mctpInfo);
+ }
+ }
+}
+
+void MctpDiscovery::removeFromExistingMctpInfos(MctpInfos& mctpInfos,
+ MctpInfos& removedInfos)
+{
+ for (const auto& mctpInfo : existingMctpInfos)
+ {
+ if (std::find(mctpInfos.begin(), mctpInfos.end(), mctpInfo) ==
+ mctpInfos.end())
+ {
+ removedInfos.emplace_back(mctpInfo);
+ }
+ }
+ for (const auto& mctpInfo : removedInfos)
+ {
+ info("Removing Endpoint networkId={NETWORK} EID={EID}", "NETWORK",
+ std::get<3>(mctpInfo), "EID", unsigned(std::get<0>(mctpInfo)));
+ existingMctpInfos.erase(std::remove(existingMctpInfos.begin(),
+ existingMctpInfos.end(), mctpInfo),
+ existingMctpInfos.end());
+ }
+}
+
+void MctpDiscovery::discoverEndpoints(sdbusplus::message_t& msg)
+{
+ MctpInfos addedInfos;
+ getAddedMctpInfos(msg, addedInfos);
+ addToExistingMctpInfos(addedInfos);
+ handleMctpEndpoints(addedInfos);
+}
+
+void MctpDiscovery::removeEndpoints(sdbusplus::message_t&)
+{
+ MctpInfos mctpInfos;
+ MctpInfos removedInfos;
+ getMctpInfos(mctpInfos);
+ removeFromExistingMctpInfos(mctpInfos, removedInfos);
+ handleRemovedMctpEndpoints(removedInfos);
+}
+
+void MctpDiscovery::handleMctpEndpoints(const MctpInfos& mctpInfos)
+{
+ for (const auto& handler : handlers)
+ {
+ if (handler)
+ {
+ handler->handleMctpEndpoints(mctpInfos);
+ }
+ }
+}
+
+void MctpDiscovery::handleRemovedMctpEndpoints(const MctpInfos& mctpInfos)
+{
+ for (const auto& handler : handlers)
+ {
+ if (handler)
+ {
+ handler->handleRemovedMctpEndpoints(mctpInfos);
+ }
}
}