blob: 1b6cd305b0e183bbbece8d1506a1b2bcae1e01e8 [file] [log] [blame]
Gilbert Chen44524a52022-02-14 12:12:25 +00001#include "config.h"
2
Tom Josephfb3bc062021-08-17 07:48:11 -07003#include "mctp_endpoint_discovery.hpp"
4
Tom Josephfb3bc062021-08-17 07:48:11 -07005#include "common/types.hpp"
6#include "common/utils.hpp"
7
Thu Nguyen90274972024-07-17 07:02:16 +00008#include <linux/mctp.h>
9
Gilbert Chen44524a52022-02-14 12:12:25 +000010#include <phosphor-logging/lg2.hpp>
11
Tom Josephfb3bc062021-08-17 07:48:11 -070012#include <algorithm>
Gilbert Chen44524a52022-02-14 12:12:25 +000013#include <fstream>
14#include <iostream>
Tom Josephfb3bc062021-08-17 07:48:11 -070015#include <map>
16#include <string>
17#include <string_view>
18#include <vector>
19
Gilbert Chen44524a52022-02-14 12:12:25 +000020using namespace sdbusplus::bus::match::rules;
21
22PHOSPHOR_LOG2_USING;
23
Tom Josephfb3bc062021-08-17 07:48:11 -070024namespace pldm
25{
Gilbert Chen44524a52022-02-14 12:12:25 +000026MctpDiscovery::MctpDiscovery(
Patrick Williamsba741d52024-05-08 02:32:10 -050027 sdbusplus::bus_t& bus,
Gilbert Chen44524a52022-02-14 12:12:25 +000028 std::initializer_list<MctpDiscoveryHandlerIntf*> list) :
Patrick Williams16c2a0a2024-08-16 15:20:59 -040029 bus(bus), mctpEndpointAddedSignal(
30 bus, interfacesAdded(MCTPPath),
31 std::bind_front(&MctpDiscovery::discoverEndpoints, this)),
Gilbert Chen44524a52022-02-14 12:12:25 +000032 mctpEndpointRemovedSignal(
33 bus, interfacesRemoved(MCTPPath),
34 std::bind_front(&MctpDiscovery::removeEndpoints, this)),
35 handlers(list)
Tom Josephfb3bc062021-08-17 07:48:11 -070036{
Gilbert Chen44524a52022-02-14 12:12:25 +000037 getMctpInfos(existingMctpInfos);
38 handleMctpEndpoints(existingMctpInfos);
39}
Tom Josephfb3bc062021-08-17 07:48:11 -070040
Gilbert Chen44524a52022-02-14 12:12:25 +000041void MctpDiscovery::getMctpInfos(MctpInfos& mctpInfos)
42{
43 // Find all implementations of the MCTP Endpoint interface
44 pldm::utils::GetSubTreeResponse mapperResponse;
Tom Josephfb3bc062021-08-17 07:48:11 -070045 try
46 {
Gilbert Chen44524a52022-02-14 12:12:25 +000047 mapperResponse = pldm::utils::DBusHandler().getSubtree(
48 MCTPPath, 0, std::vector<std::string>({MCTPInterface}));
Tom Josephfb3bc062021-08-17 07:48:11 -070049 }
Gilbert Chen44524a52022-02-14 12:12:25 +000050 catch (const sdbusplus::exception_t& e)
Tom Josephfb3bc062021-08-17 07:48:11 -070051 {
Riya Dixit087a7512024-04-06 14:28:08 -050052 error(
53 "Failed to getSubtree call at path '{PATH}' and interface '{INTERFACE}', error - {ERROR} ",
54 "ERROR", e, "PATH", MCTPPath, "INTERFACE", MCTPInterface);
Tom Josephfb3bc062021-08-17 07:48:11 -070055 return;
56 }
57
Gilbert Chen44524a52022-02-14 12:12:25 +000058 for (const auto& [path, services] : mapperResponse)
Tom Josephfb3bc062021-08-17 07:48:11 -070059 {
Gilbert Chen44524a52022-02-14 12:12:25 +000060 for (const auto& serviceIter : services)
Tom Josephfb3bc062021-08-17 07:48:11 -070061 {
Gilbert Chen44524a52022-02-14 12:12:25 +000062 const std::string& service = serviceIter.first;
Thu Nguyen90274972024-07-17 07:02:16 +000063 const MctpEndpointProps& epProps =
64 getMctpEndpointProps(service, path);
65 const UUID& uuid = getEndpointUUIDProp(service, path);
66 auto types = std::get<MCTPMsgTypes>(epProps);
67 if (std::find(types.begin(), types.end(), mctpTypePLDM) !=
68 types.end())
Tom Josephfb3bc062021-08-17 07:48:11 -070069 {
Thu Nguyen90274972024-07-17 07:02:16 +000070 mctpInfos.emplace_back(
71 MctpInfo(std::get<eid>(epProps), uuid, "",
72 std::get<NetworkId>(epProps)));
Gilbert Chen44524a52022-02-14 12:12:25 +000073 }
Tom Josephfb3bc062021-08-17 07:48:11 -070074 }
75 }
Tom Josephfb3bc062021-08-17 07:48:11 -070076}
77
Thu Nguyen90274972024-07-17 07:02:16 +000078MctpEndpointProps MctpDiscovery::getMctpEndpointProps(
79 const std::string& service, const std::string& path)
80{
81 try
82 {
83 auto properties = pldm::utils::DBusHandler().getDbusPropertiesVariant(
84 service.c_str(), path.c_str(), MCTPInterface);
85
86 if (properties.contains("NetworkId") && properties.contains("EID") &&
87 properties.contains("SupportedMessageTypes"))
88 {
89 auto networkId = std::get<NetworkId>(properties.at("NetworkId"));
90 auto eid = std::get<mctp_eid_t>(properties.at("EID"));
91 auto types = std::get<std::vector<uint8_t>>(
92 properties.at("SupportedMessageTypes"));
93 return MctpEndpointProps(networkId, eid, types);
94 }
95 }
96 catch (const sdbusplus::exception_t& e)
97 {
98 error(
99 "Error reading MCTP Endpoint property at path '{PATH}' and service '{SERVICE}', error - {ERROR}",
100 "SERVICE", service, "PATH", path, "ERROR", e);
101 return MctpEndpointProps(0, MCTP_ADDR_ANY, {});
102 }
103
104 return MctpEndpointProps(0, MCTP_ADDR_ANY, {});
105}
106
107UUID MctpDiscovery::getEndpointUUIDProp(const std::string& service,
108 const std::string& path)
109{
110 try
111 {
112 auto properties = pldm::utils::DBusHandler().getDbusPropertiesVariant(
113 service.c_str(), path.c_str(), EndpointUUID);
114
115 if (properties.contains("UUID"))
116 {
117 return std::get<UUID>(properties.at("UUID"));
118 }
119 }
120 catch (const sdbusplus::exception_t& e)
121 {
122 error(
123 "Error reading Endpoint UUID property at path '{PATH}' and service '{SERVICE}', error - {ERROR}",
124 "SERVICE", service, "PATH", path, "ERROR", e);
125 return static_cast<UUID>(emptyUUID);
126 }
127
128 return static_cast<UUID>(emptyUUID);
129}
130
Gilbert Chen44524a52022-02-14 12:12:25 +0000131void MctpDiscovery::getAddedMctpInfos(sdbusplus::message_t& msg,
132 MctpInfos& mctpInfos)
Tom Josephfb3bc062021-08-17 07:48:11 -0700133{
Gilbert Chen44524a52022-02-14 12:12:25 +0000134 using ObjectPath = sdbusplus::message::object_path;
135 ObjectPath objPath;
136 using Property = std::string;
137 using PropertyMap = std::map<Property, dbus::Value>;
138 std::map<std::string, PropertyMap> interfaces;
Thu Nguyen90274972024-07-17 07:02:16 +0000139 std::string uuid = emptyUUID;
Tom Josephfb3bc062021-08-17 07:48:11 -0700140
Gilbert Chen44524a52022-02-14 12:12:25 +0000141 try
142 {
143 msg.read(objPath, interfaces);
144 }
145 catch (const sdbusplus::exception_t& e)
146 {
Riya Dixit087a7512024-04-06 14:28:08 -0500147 error(
148 "Error reading MCTP Endpoint added interface message, error - {ERROR}",
149 "ERROR", e);
Gilbert Chen44524a52022-02-14 12:12:25 +0000150 return;
151 }
Tom Josephfb3bc062021-08-17 07:48:11 -0700152
Thu Nguyen90274972024-07-17 07:02:16 +0000153 /* Get UUID */
154 try
155 {
156 auto service = pldm::utils::DBusHandler().getService(
157 objPath.str.c_str(), EndpointUUID);
158 uuid = getEndpointUUIDProp(service, objPath.str);
159 }
160 catch (const sdbusplus::exception_t& e)
161 {
162 error("Error getting Endpoint UUID D-Bus interface, error - {ERROR}",
163 "ERROR", e);
164 }
165
Tom Josephfb3bc062021-08-17 07:48:11 -0700166 for (const auto& [intfName, properties] : interfaces)
167 {
Gilbert Chen44524a52022-02-14 12:12:25 +0000168 if (intfName == MCTPInterface)
Tom Josephfb3bc062021-08-17 07:48:11 -0700169 {
Gilbert Chen44524a52022-02-14 12:12:25 +0000170 if (properties.contains("NetworkId") &&
171 properties.contains("EID") &&
Tom Josephfb3bc062021-08-17 07:48:11 -0700172 properties.contains("SupportedMessageTypes"))
173 {
Gilbert Chen44524a52022-02-14 12:12:25 +0000174 auto networkId =
175 std::get<NetworkId>(properties.at("NetworkId"));
Dung Cao66794d02023-10-25 04:06:23 +0000176 auto eid = std::get<mctp_eid_t>(properties.at("EID"));
Tom Josephfb3bc062021-08-17 07:48:11 -0700177 auto types = std::get<std::vector<uint8_t>>(
178 properties.at("SupportedMessageTypes"));
179 if (std::find(types.begin(), types.end(), mctpTypePLDM) !=
180 types.end())
181 {
Riya Dixit087a7512024-04-06 14:28:08 -0500182 info(
Thu Nguyen90274972024-07-17 07:02:16 +0000183 "Adding Endpoint networkId '{NETWORK}' and EID '{EID}' UUID '{UUID}'",
184 "NETWORK", networkId, "EID", eid, "UUID", uuid);
185 mctpInfos.emplace_back(MctpInfo(eid, uuid, "", networkId));
Tom Josephfb3bc062021-08-17 07:48:11 -0700186 }
187 }
188 }
189 }
Gilbert Chen44524a52022-02-14 12:12:25 +0000190}
Tom Josephfb3bc062021-08-17 07:48:11 -0700191
Gilbert Chen44524a52022-02-14 12:12:25 +0000192void MctpDiscovery::addToExistingMctpInfos(const MctpInfos& addedInfos)
193{
194 for (const auto& mctpInfo : addedInfos)
Tom Josephfb3bc062021-08-17 07:48:11 -0700195 {
Gilbert Chen44524a52022-02-14 12:12:25 +0000196 if (std::find(existingMctpInfos.begin(), existingMctpInfos.end(),
197 mctpInfo) == existingMctpInfos.end())
198 {
199 existingMctpInfos.emplace_back(mctpInfo);
200 }
201 }
202}
203
204void MctpDiscovery::removeFromExistingMctpInfos(MctpInfos& mctpInfos,
205 MctpInfos& removedInfos)
206{
207 for (const auto& mctpInfo : existingMctpInfos)
208 {
209 if (std::find(mctpInfos.begin(), mctpInfos.end(), mctpInfo) ==
210 mctpInfos.end())
211 {
212 removedInfos.emplace_back(mctpInfo);
213 }
214 }
215 for (const auto& mctpInfo : removedInfos)
216 {
Riya Dixit087a7512024-04-06 14:28:08 -0500217 info("Removing Endpoint networkId '{NETWORK}' and EID '{EID}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500218 "NETWORK", std::get<3>(mctpInfo), "EID", std::get<0>(mctpInfo));
Gilbert Chen44524a52022-02-14 12:12:25 +0000219 existingMctpInfos.erase(std::remove(existingMctpInfos.begin(),
220 existingMctpInfos.end(), mctpInfo),
221 existingMctpInfos.end());
222 }
223}
224
225void MctpDiscovery::discoverEndpoints(sdbusplus::message_t& msg)
226{
227 MctpInfos addedInfos;
228 getAddedMctpInfos(msg, addedInfos);
229 addToExistingMctpInfos(addedInfos);
230 handleMctpEndpoints(addedInfos);
231}
232
233void MctpDiscovery::removeEndpoints(sdbusplus::message_t&)
234{
235 MctpInfos mctpInfos;
236 MctpInfos removedInfos;
237 getMctpInfos(mctpInfos);
238 removeFromExistingMctpInfos(mctpInfos, removedInfos);
239 handleRemovedMctpEndpoints(removedInfos);
240}
241
242void MctpDiscovery::handleMctpEndpoints(const MctpInfos& mctpInfos)
243{
244 for (const auto& handler : handlers)
245 {
246 if (handler)
247 {
248 handler->handleMctpEndpoints(mctpInfos);
249 }
250 }
251}
252
253void MctpDiscovery::handleRemovedMctpEndpoints(const MctpInfos& mctpInfos)
254{
255 for (const auto& handler : handlers)
256 {
257 if (handler)
258 {
259 handler->handleRemovedMctpEndpoints(mctpInfos);
260 }
Tom Josephfb3bc062021-08-17 07:48:11 -0700261 }
262}
263
Andrew Jeffery27a022c2022-08-10 23:12:49 +0930264} // namespace pldm