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