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