1 #include "platform_config.hpp"
2 
3 #include <phosphor-logging/lg2.hpp>
4 
5 PHOSPHOR_LOG2_USING;
6 
7 namespace pldm
8 {
9 namespace responder
10 {
11 
12 namespace platform_config
13 {
14 /** @brief callback function invoked when interfaces get added from
15  *      Entity manager
16  *
17  *  @param[in] msg - Data associated with subscribed signal
18  */
systemCompatibleCallback(sdbusplus::message_t & msg)19 void Handler::systemCompatibleCallback(sdbusplus::message_t& msg)
20 {
21     sdbusplus::message::object_path path;
22 
23     pldm::utils::InterfaceMap interfaceMap;
24 
25     msg.read(path, interfaceMap);
26 
27     if (!interfaceMap.contains(compatibleInterface))
28     {
29         return;
30     }
31     // Get the "Name" property value of the
32     // "xyz.openbmc_project.Inventory.Decorator.Compatible" interface
33     const auto& properties = interfaceMap.at(compatibleInterface);
34 
35     if (!properties.contains(namesProperty))
36     {
37         return;
38     }
39     auto names =
40         std::get<pldm::utils::Interfaces>(properties.at(namesProperty));
41 
42     std::string systemType;
43     if (!names.empty())
44     {
45         // get only the first system type
46         systemType = names.front();
47         if (sysTypeCallback)
48         {
49             sysTypeCallback(systemType, true);
50         }
51     }
52 
53     if (!systemType.empty())
54     {
55         systemCompatibleMatchCallBack.reset();
56     }
57 }
58 
59 /** @brief Method to get the system type information
60  *
61  *  @return - the system type information
62  */
getPlatformName()63 std::optional<std::filesystem::path> Handler::getPlatformName()
64 {
65     if (!systemType.empty())
66     {
67         return fs::path{systemType};
68     }
69 
70     namespace fs = std::filesystem;
71     static const std::string entityMangerService =
72         "xyz.openbmc_project.EntityManager";
73 
74     static constexpr auto searchpath = "/xyz/openbmc_project/";
75     int depth = 0;
76     std::vector<std::string> systemCompatible = {compatibleInterface};
77 
78     try
79     {
80         pldm::utils::GetSubTreeResponse response =
81             pldm::utils::DBusHandler().getSubtree(searchpath, depth,
82                                                   systemCompatible);
83         auto& bus = pldm::utils::DBusHandler::getBus();
84 
85         for (const auto& [objectPath, serviceMap] : response)
86         {
87             try
88             {
89                 auto record = std::find_if(
90                     serviceMap.begin(), serviceMap.end(),
91                     [](auto map) { return map.first == entityMangerService; });
92 
93                 if (record != serviceMap.end())
94                 {
95                     auto method = bus.new_method_call(
96                         entityMangerService.c_str(), objectPath.c_str(),
97                         "org.freedesktop.DBus.Properties", "Get");
98                     method.append(compatibleInterface, namesProperty);
99                     auto propSystemList =
100                         bus.call(method, dbusTimeout).unpack<PropertyValue>();
101                     auto systemList =
102                         std::get<std::vector<std::string>>(propSystemList);
103 
104                     if (!systemList.empty())
105                     {
106                         systemType = systemList.at(0);
107                         // once systemtype received,then resetting a callback
108                         systemCompatibleMatchCallBack.reset();
109                         return fs::path{systemType};
110                     }
111                 }
112             }
113             catch (const std::exception& e)
114             {
115                 error(
116                     "Failed to get Names property at '{PATH}' on interface '{INTERFACE}', error - {ERROR}",
117                     "PATH", objectPath, "INTERFACE", compatibleInterface,
118                     "ERROR", e);
119             }
120         }
121     }
122     catch (const std::exception& e)
123     {
124         error(
125             "Failed to make a d-bus call to get platform name, error - {ERROR}",
126             "ERROR", e);
127     }
128     return std::nullopt;
129 }
130 
registerSystemTypeCallback(SystemTypeCallback callback)131 void Handler::registerSystemTypeCallback(SystemTypeCallback callback)
132 {
133     sysTypeCallback = callback;
134 }
135 
136 } // namespace platform_config
137 
138 } // namespace responder
139 
140 } // namespace pldm
141