xref: /openbmc/pldm/libpldmresponder/platform_config.cpp (revision b4ef4310bdda97566d20a6b8a04215c8fb4fb308)
1 #include "platform_config.hpp"
2 
3 namespace pldm
4 {
5 namespace responder
6 {
7 
8 namespace platform_config
9 {
10 /** @brief callback function invoked when interfaces get added from
11  *      Entity manager
12  *
13  *  @param[in] msg - Data associated with subscribed signal
14  */
15 void Handler::systemCompatibleCallback(sdbusplus::message_t& msg)
16 {
17     sdbusplus::message::object_path path;
18 
19     pldm::utils::InterfaceMap interfaceMap;
20 
21     msg.read(path, interfaceMap);
22 
23     if (!interfaceMap.contains(compatibleInterface))
24     {
25         return;
26     }
27     // Get the "Name" property value of the
28     // "xyz.openbmc_project.Inventory.Decorator.Compatible" interface
29     const auto& properties = interfaceMap.at(compatibleInterface);
30 
31     if (!properties.contains(namesProperty))
32     {
33         return;
34     }
35     auto names =
36         std::get<pldm::utils::Interfaces>(properties.at(namesProperty));
37 
38     std::string systemType;
39     if (!names.empty())
40     {
41         // get only the first system type
42         systemType = names.front();
43     }
44 
45     if (!systemType.empty())
46     {
47         systemCompatibleMatchCallBack.reset();
48     }
49 }
50 
51 /** @brief Method to get the system type information
52  *
53  *  @return - the system type information
54  */
55 std::optional<std::filesystem::path> Handler::getPlatformName()
56 {
57     if (!systemType.empty())
58     {
59         return fs::path{systemType};
60     }
61 
62     namespace fs = std::filesystem;
63     static constexpr auto orgFreeDesktopInterface =
64         "org.freedesktop.DBus.Properties";
65     static constexpr auto getMethod = "Get";
66 
67     static constexpr auto searchpath = "/xyz/openbmc_project/";
68     int depth = 0;
69     std::vector<std::string> systemCompatible = {compatibleInterface};
70     pldm::utils::GetSubTreeResponse response =
71         pldm::utils::DBusHandler().getSubtree(searchpath, depth,
72                                               systemCompatible);
73     auto& bus = pldm::utils::DBusHandler::getBus();
74     std::variant<std::vector<std::string>> value;
75 
76     for (const auto& [objectPath, serviceMap] : response)
77     {
78         try
79         {
80             auto method = bus.new_method_call(
81                 serviceMap[0].first.c_str(), objectPath.c_str(),
82                 orgFreeDesktopInterface, getMethod);
83             method.append(systemCompatible[0].c_str(), namesProperty);
84             auto reply = bus.call(method);
85             reply.read(value);
86             auto systemList = std::get<std::vector<std::string>>(value);
87             if (!systemList.empty())
88             {
89                 systemType = systemList.at(0);
90                 return fs::path{systemType};
91             }
92         }
93         catch (const std::exception& e)
94         {
95             error(
96                 "Error getting Names property at '{PATH}' on '{INTERFACE}': {ERROR}",
97                 "PATH", objectPath, "INTERFACE", systemCompatible[0], "ERROR",
98                 e);
99         }
100     }
101     return std::nullopt;
102 }
103 
104 } // namespace platform_config
105 
106 } // namespace responder
107 
108 } // namespace pldm
109