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