blob: d0122c9155fbaefc4c1b7fdd4fcf76f5764f2a03 [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
Gilbert Chen44524a52022-02-14 12:12:25 +00008#include <phosphor-logging/lg2.hpp>
9
Tom Josephfb3bc062021-08-17 07:48:11 -070010#include <algorithm>
Gilbert Chen44524a52022-02-14 12:12:25 +000011#include <fstream>
12#include <iostream>
Tom Josephfb3bc062021-08-17 07:48:11 -070013#include <map>
14#include <string>
15#include <string_view>
16#include <vector>
17
Gilbert Chen44524a52022-02-14 12:12:25 +000018using namespace sdbusplus::bus::match::rules;
19
20PHOSPHOR_LOG2_USING;
21
Tom Josephfb3bc062021-08-17 07:48:11 -070022namespace pldm
23{
Gilbert Chen44524a52022-02-14 12:12:25 +000024MctpDiscovery::MctpDiscovery(
Patrick Williamsba741d52024-05-08 02:32:10 -050025 sdbusplus::bus_t& bus,
Gilbert Chen44524a52022-02-14 12:12:25 +000026 std::initializer_list<MctpDiscoveryHandlerIntf*> list) :
Patrick Williams16c2a0a2024-08-16 15:20:59 -040027 bus(bus), mctpEndpointAddedSignal(
28 bus, interfacesAdded(MCTPPath),
29 std::bind_front(&MctpDiscovery::discoverEndpoints, this)),
Gilbert Chen44524a52022-02-14 12:12:25 +000030 mctpEndpointRemovedSignal(
31 bus, interfacesRemoved(MCTPPath),
32 std::bind_front(&MctpDiscovery::removeEndpoints, this)),
33 handlers(list)
Tom Josephfb3bc062021-08-17 07:48:11 -070034{
Gilbert Chen44524a52022-02-14 12:12:25 +000035 getMctpInfos(existingMctpInfos);
36 handleMctpEndpoints(existingMctpInfos);
37}
Tom Josephfb3bc062021-08-17 07:48:11 -070038
Gilbert Chen44524a52022-02-14 12:12:25 +000039void MctpDiscovery::getMctpInfos(MctpInfos& mctpInfos)
40{
41 // Find all implementations of the MCTP Endpoint interface
42 pldm::utils::GetSubTreeResponse mapperResponse;
Tom Josephfb3bc062021-08-17 07:48:11 -070043 try
44 {
Gilbert Chen44524a52022-02-14 12:12:25 +000045 mapperResponse = pldm::utils::DBusHandler().getSubtree(
46 MCTPPath, 0, std::vector<std::string>({MCTPInterface}));
Tom Josephfb3bc062021-08-17 07:48:11 -070047 }
Gilbert Chen44524a52022-02-14 12:12:25 +000048 catch (const sdbusplus::exception_t& e)
Tom Josephfb3bc062021-08-17 07:48:11 -070049 {
Riya Dixit087a7512024-04-06 14:28:08 -050050 error(
51 "Failed to getSubtree call at path '{PATH}' and interface '{INTERFACE}', error - {ERROR} ",
52 "ERROR", e, "PATH", MCTPPath, "INTERFACE", MCTPInterface);
Tom Josephfb3bc062021-08-17 07:48:11 -070053 return;
54 }
55
Gilbert Chen44524a52022-02-14 12:12:25 +000056 for (const auto& [path, services] : mapperResponse)
Tom Josephfb3bc062021-08-17 07:48:11 -070057 {
Gilbert Chen44524a52022-02-14 12:12:25 +000058 for (const auto& serviceIter : services)
Tom Josephfb3bc062021-08-17 07:48:11 -070059 {
Gilbert Chen44524a52022-02-14 12:12:25 +000060 const std::string& service = serviceIter.first;
61 try
Tom Josephfb3bc062021-08-17 07:48:11 -070062 {
Gilbert Chen44524a52022-02-14 12:12:25 +000063 auto properties =
64 pldm::utils::DBusHandler().getDbusPropertiesVariant(
65 service.c_str(), path.c_str(), MCTPInterface);
66
67 if (properties.contains("NetworkId") &&
68 properties.contains("EID") &&
Tom Josephfb3bc062021-08-17 07:48:11 -070069 properties.contains("SupportedMessageTypes"))
70 {
Gilbert Chen44524a52022-02-14 12:12:25 +000071 auto networkId =
72 std::get<NetworkId>(properties.at("NetworkId"));
Delphine CC Chiuc00594e2023-04-19 11:13:17 +080073 auto eid = std::get<mctp_eid_t>(properties.at("EID"));
Tom Josephfb3bc062021-08-17 07:48:11 -070074 auto types = std::get<std::vector<uint8_t>>(
75 properties.at("SupportedMessageTypes"));
76 if (std::find(types.begin(), types.end(), mctpTypePLDM) !=
77 types.end())
78 {
Riya Dixit087a7512024-04-06 14:28:08 -050079 info(
80 "Adding Endpoint networkId '{NETWORK}' and EID '{EID}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -050081 "NETWORK", networkId, "EID", eid);
Gilbert Chen44524a52022-02-14 12:12:25 +000082 mctpInfos.emplace_back(
83 MctpInfo(eid, emptyUUID, "", networkId));
Tom Josephfb3bc062021-08-17 07:48:11 -070084 }
85 }
86 }
Gilbert Chen44524a52022-02-14 12:12:25 +000087 catch (const sdbusplus::exception_t& e)
88 {
89 error(
Riya Dixit087a7512024-04-06 14:28:08 -050090 "Error reading MCTP Endpoint property at path '{PATH}' and service '{SERVICE}', error - {ERROR}",
Gilbert Chen44524a52022-02-14 12:12:25 +000091 "ERROR", e, "SERVICE", service, "PATH", path);
92 return;
93 }
Tom Josephfb3bc062021-08-17 07:48:11 -070094 }
95 }
Tom Josephfb3bc062021-08-17 07:48:11 -070096}
97
Gilbert Chen44524a52022-02-14 12:12:25 +000098void MctpDiscovery::getAddedMctpInfos(sdbusplus::message_t& msg,
99 MctpInfos& mctpInfos)
Tom Josephfb3bc062021-08-17 07:48:11 -0700100{
Gilbert Chen44524a52022-02-14 12:12:25 +0000101 using ObjectPath = sdbusplus::message::object_path;
102 ObjectPath objPath;
103 using Property = std::string;
104 using PropertyMap = std::map<Property, dbus::Value>;
105 std::map<std::string, PropertyMap> interfaces;
Tom Josephfb3bc062021-08-17 07:48:11 -0700106
Gilbert Chen44524a52022-02-14 12:12:25 +0000107 try
108 {
109 msg.read(objPath, interfaces);
110 }
111 catch (const sdbusplus::exception_t& e)
112 {
Riya Dixit087a7512024-04-06 14:28:08 -0500113 error(
114 "Error reading MCTP Endpoint added interface message, error - {ERROR}",
115 "ERROR", e);
Gilbert Chen44524a52022-02-14 12:12:25 +0000116 return;
117 }
Tom Josephfb3bc062021-08-17 07:48:11 -0700118
119 for (const auto& [intfName, properties] : interfaces)
120 {
Gilbert Chen44524a52022-02-14 12:12:25 +0000121 if (intfName == MCTPInterface)
Tom Josephfb3bc062021-08-17 07:48:11 -0700122 {
Gilbert Chen44524a52022-02-14 12:12:25 +0000123 if (properties.contains("NetworkId") &&
124 properties.contains("EID") &&
Tom Josephfb3bc062021-08-17 07:48:11 -0700125 properties.contains("SupportedMessageTypes"))
126 {
Gilbert Chen44524a52022-02-14 12:12:25 +0000127 auto networkId =
128 std::get<NetworkId>(properties.at("NetworkId"));
Dung Cao66794d02023-10-25 04:06:23 +0000129 auto eid = std::get<mctp_eid_t>(properties.at("EID"));
Tom Josephfb3bc062021-08-17 07:48:11 -0700130 auto types = std::get<std::vector<uint8_t>>(
131 properties.at("SupportedMessageTypes"));
132 if (std::find(types.begin(), types.end(), mctpTypePLDM) !=
133 types.end())
134 {
Riya Dixit087a7512024-04-06 14:28:08 -0500135 info(
136 "Adding Endpoint networkId '{NETWORK}' and EID '{EID}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500137 "NETWORK", networkId, "EID", eid);
Gilbert Chen44524a52022-02-14 12:12:25 +0000138 mctpInfos.emplace_back(
139 MctpInfo(eid, emptyUUID, "", networkId));
Tom Josephfb3bc062021-08-17 07:48:11 -0700140 }
141 }
142 }
143 }
Gilbert Chen44524a52022-02-14 12:12:25 +0000144}
Tom Josephfb3bc062021-08-17 07:48:11 -0700145
Gilbert Chen44524a52022-02-14 12:12:25 +0000146void MctpDiscovery::addToExistingMctpInfos(const MctpInfos& addedInfos)
147{
148 for (const auto& mctpInfo : addedInfos)
Tom Josephfb3bc062021-08-17 07:48:11 -0700149 {
Gilbert Chen44524a52022-02-14 12:12:25 +0000150 if (std::find(existingMctpInfos.begin(), existingMctpInfos.end(),
151 mctpInfo) == existingMctpInfos.end())
152 {
153 existingMctpInfos.emplace_back(mctpInfo);
154 }
155 }
156}
157
158void MctpDiscovery::removeFromExistingMctpInfos(MctpInfos& mctpInfos,
159 MctpInfos& removedInfos)
160{
161 for (const auto& mctpInfo : existingMctpInfos)
162 {
163 if (std::find(mctpInfos.begin(), mctpInfos.end(), mctpInfo) ==
164 mctpInfos.end())
165 {
166 removedInfos.emplace_back(mctpInfo);
167 }
168 }
169 for (const auto& mctpInfo : removedInfos)
170 {
Riya Dixit087a7512024-04-06 14:28:08 -0500171 info("Removing Endpoint networkId '{NETWORK}' and EID '{EID}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500172 "NETWORK", std::get<3>(mctpInfo), "EID", std::get<0>(mctpInfo));
Gilbert Chen44524a52022-02-14 12:12:25 +0000173 existingMctpInfos.erase(std::remove(existingMctpInfos.begin(),
174 existingMctpInfos.end(), mctpInfo),
175 existingMctpInfos.end());
176 }
177}
178
179void MctpDiscovery::discoverEndpoints(sdbusplus::message_t& msg)
180{
181 MctpInfos addedInfos;
182 getAddedMctpInfos(msg, addedInfos);
183 addToExistingMctpInfos(addedInfos);
184 handleMctpEndpoints(addedInfos);
185}
186
187void MctpDiscovery::removeEndpoints(sdbusplus::message_t&)
188{
189 MctpInfos mctpInfos;
190 MctpInfos removedInfos;
191 getMctpInfos(mctpInfos);
192 removeFromExistingMctpInfos(mctpInfos, removedInfos);
193 handleRemovedMctpEndpoints(removedInfos);
194}
195
196void MctpDiscovery::handleMctpEndpoints(const MctpInfos& mctpInfos)
197{
198 for (const auto& handler : handlers)
199 {
200 if (handler)
201 {
202 handler->handleMctpEndpoints(mctpInfos);
203 }
204 }
205}
206
207void MctpDiscovery::handleRemovedMctpEndpoints(const MctpInfos& mctpInfos)
208{
209 for (const auto& handler : handlers)
210 {
211 if (handler)
212 {
213 handler->handleRemovedMctpEndpoints(mctpInfos);
214 }
Tom Josephfb3bc062021-08-17 07:48:11 -0700215 }
216}
217
Andrew Jeffery27a022c2022-08-10 23:12:49 +0930218} // namespace pldm