blob: 278028188653e64e27edde70434ec3ee5d311811 [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) :
Tom Josephfb3bc062021-08-17 07:48:11 -070027 bus(bus),
Gilbert Chen44524a52022-02-14 12:12:25 +000028 mctpEndpointAddedSignal(
29 bus, interfacesAdded(MCTPPath),
30 std::bind_front(&MctpDiscovery::discoverEndpoints, this)),
31 mctpEndpointRemovedSignal(
32 bus, interfacesRemoved(MCTPPath),
33 std::bind_front(&MctpDiscovery::removeEndpoints, this)),
34 handlers(list)
Tom Josephfb3bc062021-08-17 07:48:11 -070035{
Gilbert Chen44524a52022-02-14 12:12:25 +000036 getMctpInfos(existingMctpInfos);
37 handleMctpEndpoints(existingMctpInfos);
38}
Tom Josephfb3bc062021-08-17 07:48:11 -070039
Gilbert Chen44524a52022-02-14 12:12:25 +000040void MctpDiscovery::getMctpInfos(MctpInfos& mctpInfos)
41{
42 // Find all implementations of the MCTP Endpoint interface
43 pldm::utils::GetSubTreeResponse mapperResponse;
Tom Josephfb3bc062021-08-17 07:48:11 -070044 try
45 {
Gilbert Chen44524a52022-02-14 12:12:25 +000046 mapperResponse = pldm::utils::DBusHandler().getSubtree(
47 MCTPPath, 0, std::vector<std::string>({MCTPInterface}));
Tom Josephfb3bc062021-08-17 07:48:11 -070048 }
Gilbert Chen44524a52022-02-14 12:12:25 +000049 catch (const sdbusplus::exception_t& e)
Tom Josephfb3bc062021-08-17 07:48:11 -070050 {
Riya Dixit087a7512024-04-06 14:28:08 -050051 error(
52 "Failed to getSubtree call at path '{PATH}' and interface '{INTERFACE}', error - {ERROR} ",
53 "ERROR", e, "PATH", MCTPPath, "INTERFACE", MCTPInterface);
Tom Josephfb3bc062021-08-17 07:48:11 -070054 return;
55 }
56
Gilbert Chen44524a52022-02-14 12:12:25 +000057 for (const auto& [path, services] : mapperResponse)
Tom Josephfb3bc062021-08-17 07:48:11 -070058 {
Gilbert Chen44524a52022-02-14 12:12:25 +000059 for (const auto& serviceIter : services)
Tom Josephfb3bc062021-08-17 07:48:11 -070060 {
Gilbert Chen44524a52022-02-14 12:12:25 +000061 const std::string& service = serviceIter.first;
62 try
Tom Josephfb3bc062021-08-17 07:48:11 -070063 {
Gilbert Chen44524a52022-02-14 12:12:25 +000064 auto properties =
65 pldm::utils::DBusHandler().getDbusPropertiesVariant(
66 service.c_str(), path.c_str(), MCTPInterface);
67
68 if (properties.contains("NetworkId") &&
69 properties.contains("EID") &&
Tom Josephfb3bc062021-08-17 07:48:11 -070070 properties.contains("SupportedMessageTypes"))
71 {
Gilbert Chen44524a52022-02-14 12:12:25 +000072 auto networkId =
73 std::get<NetworkId>(properties.at("NetworkId"));
Delphine CC Chiuc00594e2023-04-19 11:13:17 +080074 auto eid = std::get<mctp_eid_t>(properties.at("EID"));
Tom Josephfb3bc062021-08-17 07:48:11 -070075 auto types = std::get<std::vector<uint8_t>>(
76 properties.at("SupportedMessageTypes"));
77 if (std::find(types.begin(), types.end(), mctpTypePLDM) !=
78 types.end())
79 {
Riya Dixit087a7512024-04-06 14:28:08 -050080 info(
81 "Adding Endpoint networkId '{NETWORK}' and EID '{EID}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -050082 "NETWORK", networkId, "EID", eid);
Gilbert Chen44524a52022-02-14 12:12:25 +000083 mctpInfos.emplace_back(
84 MctpInfo(eid, emptyUUID, "", networkId));
Tom Josephfb3bc062021-08-17 07:48:11 -070085 }
86 }
87 }
Gilbert Chen44524a52022-02-14 12:12:25 +000088 catch (const sdbusplus::exception_t& e)
89 {
90 error(
Riya Dixit087a7512024-04-06 14:28:08 -050091 "Error reading MCTP Endpoint property at path '{PATH}' and service '{SERVICE}', error - {ERROR}",
Gilbert Chen44524a52022-02-14 12:12:25 +000092 "ERROR", e, "SERVICE", service, "PATH", path);
93 return;
94 }
Tom Josephfb3bc062021-08-17 07:48:11 -070095 }
96 }
Tom Josephfb3bc062021-08-17 07:48:11 -070097}
98
Gilbert Chen44524a52022-02-14 12:12:25 +000099void MctpDiscovery::getAddedMctpInfos(sdbusplus::message_t& msg,
100 MctpInfos& mctpInfos)
Tom Josephfb3bc062021-08-17 07:48:11 -0700101{
Gilbert Chen44524a52022-02-14 12:12:25 +0000102 using ObjectPath = sdbusplus::message::object_path;
103 ObjectPath objPath;
104 using Property = std::string;
105 using PropertyMap = std::map<Property, dbus::Value>;
106 std::map<std::string, PropertyMap> interfaces;
Tom Josephfb3bc062021-08-17 07:48:11 -0700107
Gilbert Chen44524a52022-02-14 12:12:25 +0000108 try
109 {
110 msg.read(objPath, interfaces);
111 }
112 catch (const sdbusplus::exception_t& e)
113 {
Riya Dixit087a7512024-04-06 14:28:08 -0500114 error(
115 "Error reading MCTP Endpoint added interface message, error - {ERROR}",
116 "ERROR", e);
Gilbert Chen44524a52022-02-14 12:12:25 +0000117 return;
118 }
Tom Josephfb3bc062021-08-17 07:48:11 -0700119
120 for (const auto& [intfName, properties] : interfaces)
121 {
Gilbert Chen44524a52022-02-14 12:12:25 +0000122 if (intfName == MCTPInterface)
Tom Josephfb3bc062021-08-17 07:48:11 -0700123 {
Gilbert Chen44524a52022-02-14 12:12:25 +0000124 if (properties.contains("NetworkId") &&
125 properties.contains("EID") &&
Tom Josephfb3bc062021-08-17 07:48:11 -0700126 properties.contains("SupportedMessageTypes"))
127 {
Gilbert Chen44524a52022-02-14 12:12:25 +0000128 auto networkId =
129 std::get<NetworkId>(properties.at("NetworkId"));
Dung Cao66794d02023-10-25 04:06:23 +0000130 auto eid = std::get<mctp_eid_t>(properties.at("EID"));
Tom Josephfb3bc062021-08-17 07:48:11 -0700131 auto types = std::get<std::vector<uint8_t>>(
132 properties.at("SupportedMessageTypes"));
133 if (std::find(types.begin(), types.end(), mctpTypePLDM) !=
134 types.end())
135 {
Riya Dixit087a7512024-04-06 14:28:08 -0500136 info(
137 "Adding Endpoint networkId '{NETWORK}' and EID '{EID}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500138 "NETWORK", networkId, "EID", eid);
Gilbert Chen44524a52022-02-14 12:12:25 +0000139 mctpInfos.emplace_back(
140 MctpInfo(eid, emptyUUID, "", networkId));
Tom Josephfb3bc062021-08-17 07:48:11 -0700141 }
142 }
143 }
144 }
Gilbert Chen44524a52022-02-14 12:12:25 +0000145}
Tom Josephfb3bc062021-08-17 07:48:11 -0700146
Gilbert Chen44524a52022-02-14 12:12:25 +0000147void MctpDiscovery::addToExistingMctpInfos(const MctpInfos& addedInfos)
148{
149 for (const auto& mctpInfo : addedInfos)
Tom Josephfb3bc062021-08-17 07:48:11 -0700150 {
Gilbert Chen44524a52022-02-14 12:12:25 +0000151 if (std::find(existingMctpInfos.begin(), existingMctpInfos.end(),
152 mctpInfo) == existingMctpInfos.end())
153 {
154 existingMctpInfos.emplace_back(mctpInfo);
155 }
156 }
157}
158
159void MctpDiscovery::removeFromExistingMctpInfos(MctpInfos& mctpInfos,
160 MctpInfos& removedInfos)
161{
162 for (const auto& mctpInfo : existingMctpInfos)
163 {
164 if (std::find(mctpInfos.begin(), mctpInfos.end(), mctpInfo) ==
165 mctpInfos.end())
166 {
167 removedInfos.emplace_back(mctpInfo);
168 }
169 }
170 for (const auto& mctpInfo : removedInfos)
171 {
Riya Dixit087a7512024-04-06 14:28:08 -0500172 info("Removing Endpoint networkId '{NETWORK}' and EID '{EID}'",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500173 "NETWORK", std::get<3>(mctpInfo), "EID", std::get<0>(mctpInfo));
Gilbert Chen44524a52022-02-14 12:12:25 +0000174 existingMctpInfos.erase(std::remove(existingMctpInfos.begin(),
175 existingMctpInfos.end(), mctpInfo),
176 existingMctpInfos.end());
177 }
178}
179
180void MctpDiscovery::discoverEndpoints(sdbusplus::message_t& msg)
181{
182 MctpInfos addedInfos;
183 getAddedMctpInfos(msg, addedInfos);
184 addToExistingMctpInfos(addedInfos);
185 handleMctpEndpoints(addedInfos);
186}
187
188void MctpDiscovery::removeEndpoints(sdbusplus::message_t&)
189{
190 MctpInfos mctpInfos;
191 MctpInfos removedInfos;
192 getMctpInfos(mctpInfos);
193 removeFromExistingMctpInfos(mctpInfos, removedInfos);
194 handleRemovedMctpEndpoints(removedInfos);
195}
196
197void MctpDiscovery::handleMctpEndpoints(const MctpInfos& mctpInfos)
198{
199 for (const auto& handler : handlers)
200 {
201 if (handler)
202 {
203 handler->handleMctpEndpoints(mctpInfos);
204 }
205 }
206}
207
208void MctpDiscovery::handleRemovedMctpEndpoints(const MctpInfos& mctpInfos)
209{
210 for (const auto& handler : handlers)
211 {
212 if (handler)
213 {
214 handler->handleRemovedMctpEndpoints(mctpInfos);
215 }
Tom Josephfb3bc062021-08-17 07:48:11 -0700216 }
217}
218
Andrew Jeffery27a022c2022-08-10 23:12:49 +0930219} // namespace pldm