1 #include "mctp_endpoint_discovery.hpp"
2 
3 #include "common/types.hpp"
4 #include "common/utils.hpp"
5 
6 #include <algorithm>
7 #include <map>
8 #include <string>
9 #include <string_view>
10 #include <vector>
11 
12 namespace pldm
13 {
14 MctpDiscovery::MctpDiscovery(sdbusplus::bus_t& bus,
15                              fw_update::Manager* fwManager) :
16     bus(bus),
17     fwManager(fwManager),
18     mctpEndpointSignal(bus,
19                        sdbusplus::bus::match::rules::interfacesAdded(
20                            "/xyz/openbmc_project/mctp"),
21                        std::bind_front(&MctpDiscovery::dicoverEndpoints, this))
22 {
23     dbus::ObjectValueTree objects;
24 
25     try
26     {
27         auto method = bus.new_method_call(
28             "xyz.openbmc_project.MCTP", "/xyz/openbmc_project/mctp",
29             "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
30         auto reply = bus.call(method, dbusTimeout);
31         reply.read(objects);
32     }
33     catch (const std::exception& e)
34     {
35         error("Failed to call the D-Bus Method: {ERROR}", "ERROR", e);
36         return;
37     }
38 
39     std::vector<mctp_eid_t> eids;
40 
41     for (const auto& [objectPath, interfaces] : objects)
42     {
43         for (const auto& [intfName, properties] : interfaces)
44         {
45             if (intfName == mctpEndpointIntfName)
46             {
47                 if (properties.contains("EID") &&
48                     properties.contains("SupportedMessageTypes"))
49                 {
50                     auto eid = std::get<mctp_eid_t>(properties.at("EID"));
51                     auto types = std::get<std::vector<uint8_t>>(
52                         properties.at("SupportedMessageTypes"));
53                     if (std::find(types.begin(), types.end(), mctpTypePLDM) !=
54                         types.end())
55                     {
56                         eids.emplace_back(eid);
57                     }
58                 }
59             }
60         }
61     }
62 
63     if (eids.size() && fwManager)
64     {
65         fwManager->handleMCTPEndpoints(eids);
66     }
67 }
68 
69 void MctpDiscovery::dicoverEndpoints(sdbusplus::message_t& msg)
70 {
71     constexpr std::string_view mctpEndpointIntfName{
72         "xyz.openbmc_project.MCTP.Endpoint"};
73     std::vector<mctp_eid_t> eids;
74 
75     sdbusplus::message::object_path objPath;
76     std::map<std::string, std::map<std::string, dbus::Value>> interfaces;
77     msg.read(objPath, interfaces);
78 
79     for (const auto& [intfName, properties] : interfaces)
80     {
81         if (intfName == mctpEndpointIntfName)
82         {
83             if (properties.contains("EID") &&
84                 properties.contains("SupportedMessageTypes"))
85             {
86                 auto eid = std::get<mctp_eid_t>(properties.at("EID"));
87                 auto types = std::get<std::vector<uint8_t>>(
88                     properties.at("SupportedMessageTypes"));
89                 if (std::find(types.begin(), types.end(), mctpTypePLDM) !=
90                     types.end())
91                 {
92                     eids.emplace_back(eid);
93                 }
94             }
95         }
96     }
97 
98     if (eids.size() && fwManager)
99     {
100         fwManager->handleMCTPEndpoints(eids);
101     }
102 }
103 
104 } // namespace pldm
105