blob: 0d63cb2a7f7f79f88a905d550d9106e0e4152164 [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 {
Gilbert Chen44524a52022-02-14 12:12:25 +000051 error("getSubtree call failed with, {ERROR} {PATH} {INTERFACE}",
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 {
Gilbert Chen44524a52022-02-14 12:12:25 +000079 info("Adding Endpoint networkId={NETWORK} EID={EID}",
80 "NETWORK", networkId, "EID", unsigned(eid));
81 mctpInfos.emplace_back(
82 MctpInfo(eid, emptyUUID, "", networkId));
Tom Josephfb3bc062021-08-17 07:48:11 -070083 }
84 }
85 }
Gilbert Chen44524a52022-02-14 12:12:25 +000086 catch (const sdbusplus::exception_t& e)
87 {
88 error(
89 "Error reading MCTP Endpoint property, {ERROR} {SERVICE} {PATH}",
90 "ERROR", e, "SERVICE", service, "PATH", path);
91 return;
92 }
Tom Josephfb3bc062021-08-17 07:48:11 -070093 }
94 }
Tom Josephfb3bc062021-08-17 07:48:11 -070095}
96
Gilbert Chen44524a52022-02-14 12:12:25 +000097void MctpDiscovery::getAddedMctpInfos(sdbusplus::message_t& msg,
98 MctpInfos& mctpInfos)
Tom Josephfb3bc062021-08-17 07:48:11 -070099{
Gilbert Chen44524a52022-02-14 12:12:25 +0000100 using ObjectPath = sdbusplus::message::object_path;
101 ObjectPath objPath;
102 using Property = std::string;
103 using PropertyMap = std::map<Property, dbus::Value>;
104 std::map<std::string, PropertyMap> interfaces;
Tom Josephfb3bc062021-08-17 07:48:11 -0700105
Gilbert Chen44524a52022-02-14 12:12:25 +0000106 try
107 {
108 msg.read(objPath, interfaces);
109 }
110 catch (const sdbusplus::exception_t& e)
111 {
112 error("Error reading MCTP Endpoint addedInterace message, {ERROR}",
113 "ERROR", e);
114 return;
115 }
Tom Josephfb3bc062021-08-17 07:48:11 -0700116
117 for (const auto& [intfName, properties] : interfaces)
118 {
Gilbert Chen44524a52022-02-14 12:12:25 +0000119 if (intfName == MCTPInterface)
Tom Josephfb3bc062021-08-17 07:48:11 -0700120 {
Gilbert Chen44524a52022-02-14 12:12:25 +0000121 if (properties.contains("NetworkId") &&
122 properties.contains("EID") &&
Tom Josephfb3bc062021-08-17 07:48:11 -0700123 properties.contains("SupportedMessageTypes"))
124 {
Gilbert Chen44524a52022-02-14 12:12:25 +0000125 auto networkId =
126 std::get<NetworkId>(properties.at("NetworkId"));
Dung Cao66794d02023-10-25 04:06:23 +0000127 auto eid = std::get<mctp_eid_t>(properties.at("EID"));
Tom Josephfb3bc062021-08-17 07:48:11 -0700128 auto types = std::get<std::vector<uint8_t>>(
129 properties.at("SupportedMessageTypes"));
130 if (std::find(types.begin(), types.end(), mctpTypePLDM) !=
131 types.end())
132 {
Gilbert Chen44524a52022-02-14 12:12:25 +0000133 info("Adding Endpoint networkId={NETWORK} EID={EID}",
134 "NETWORK", networkId, "EID", unsigned(eid));
135 mctpInfos.emplace_back(
136 MctpInfo(eid, emptyUUID, "", networkId));
Tom Josephfb3bc062021-08-17 07:48:11 -0700137 }
138 }
139 }
140 }
Gilbert Chen44524a52022-02-14 12:12:25 +0000141}
Tom Josephfb3bc062021-08-17 07:48:11 -0700142
Gilbert Chen44524a52022-02-14 12:12:25 +0000143void MctpDiscovery::addToExistingMctpInfos(const MctpInfos& addedInfos)
144{
145 for (const auto& mctpInfo : addedInfos)
Tom Josephfb3bc062021-08-17 07:48:11 -0700146 {
Gilbert Chen44524a52022-02-14 12:12:25 +0000147 if (std::find(existingMctpInfos.begin(), existingMctpInfos.end(),
148 mctpInfo) == existingMctpInfos.end())
149 {
150 existingMctpInfos.emplace_back(mctpInfo);
151 }
152 }
153}
154
155void MctpDiscovery::removeFromExistingMctpInfos(MctpInfos& mctpInfos,
156 MctpInfos& removedInfos)
157{
158 for (const auto& mctpInfo : existingMctpInfos)
159 {
160 if (std::find(mctpInfos.begin(), mctpInfos.end(), mctpInfo) ==
161 mctpInfos.end())
162 {
163 removedInfos.emplace_back(mctpInfo);
164 }
165 }
166 for (const auto& mctpInfo : removedInfos)
167 {
168 info("Removing Endpoint networkId={NETWORK} EID={EID}", "NETWORK",
169 std::get<3>(mctpInfo), "EID", unsigned(std::get<0>(mctpInfo)));
170 existingMctpInfos.erase(std::remove(existingMctpInfos.begin(),
171 existingMctpInfos.end(), mctpInfo),
172 existingMctpInfos.end());
173 }
174}
175
176void MctpDiscovery::discoverEndpoints(sdbusplus::message_t& msg)
177{
178 MctpInfos addedInfos;
179 getAddedMctpInfos(msg, addedInfos);
180 addToExistingMctpInfos(addedInfos);
181 handleMctpEndpoints(addedInfos);
182}
183
184void MctpDiscovery::removeEndpoints(sdbusplus::message_t&)
185{
186 MctpInfos mctpInfos;
187 MctpInfos removedInfos;
188 getMctpInfos(mctpInfos);
189 removeFromExistingMctpInfos(mctpInfos, removedInfos);
190 handleRemovedMctpEndpoints(removedInfos);
191}
192
193void MctpDiscovery::handleMctpEndpoints(const MctpInfos& mctpInfos)
194{
195 for (const auto& handler : handlers)
196 {
197 if (handler)
198 {
199 handler->handleMctpEndpoints(mctpInfos);
200 }
201 }
202}
203
204void MctpDiscovery::handleRemovedMctpEndpoints(const MctpInfos& mctpInfos)
205{
206 for (const auto& handler : handlers)
207 {
208 if (handler)
209 {
210 handler->handleRemovedMctpEndpoints(mctpInfos);
211 }
Tom Josephfb3bc062021-08-17 07:48:11 -0700212 }
213}
214
Andrew Jeffery27a022c2022-08-10 23:12:49 +0930215} // namespace pldm