blob: 8f181f1350556cf863695e571ec2f5884a03a35d [file] [log] [blame]
Kamalkumar Patel3c50c822024-01-30 07:14:40 -06001#include "platform_config.hpp"
2
Riya Dixit89644442024-03-31 05:39:59 -05003#include <phosphor-logging/lg2.hpp>
4
5PHOSPHOR_LOG2_USING;
6
Kamalkumar Patel3c50c822024-01-30 07:14:40 -06007namespace pldm
8{
9namespace responder
10{
11
12namespace 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 */
19void 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
Kamalkumar Patel3c50c822024-01-30 07:14:40 -060042 if (!names.empty())
43 {
Patrick Williams16c2a0a2024-08-16 15:20:59 -040044 std::optional<std::string> sysType =
45 getSysSpecificJsonDir(sysDirPath, names);
Kamalkumar Patel0a422692024-06-03 00:42:56 -050046 if (sysType.has_value())
47 {
48 systemType = sysType.value();
49 }
Archana Kakani62dd8ff2024-02-12 10:00:40 -060050 if (sysTypeCallback)
51 {
Archana Kakani46f352e2024-03-17 08:21:08 -050052 sysTypeCallback(systemType, true);
Archana Kakani62dd8ff2024-02-12 10:00:40 -060053 }
Kamalkumar Patel3c50c822024-01-30 07:14:40 -060054 }
55
56 if (!systemType.empty())
57 {
58 systemCompatibleMatchCallBack.reset();
59 }
60}
61
62/** @brief Method to get the system type information
63 *
64 * @return - the system type information
65 */
66std::optional<std::filesystem::path> Handler::getPlatformName()
67{
68 if (!systemType.empty())
69 {
70 return fs::path{systemType};
71 }
72
73 namespace fs = std::filesystem;
Kamalkumar Patel2edc34b2024-02-23 03:27:01 -060074 static const std::string entityMangerService =
75 "xyz.openbmc_project.EntityManager";
Kamalkumar Patel3c50c822024-01-30 07:14:40 -060076
77 static constexpr auto searchpath = "/xyz/openbmc_project/";
78 int depth = 0;
79 std::vector<std::string> systemCompatible = {compatibleInterface};
Kamalkumar Patel3c50c822024-01-30 07:14:40 -060080
Kamalkumar Patel2edc34b2024-02-23 03:27:01 -060081 try
Kamalkumar Patel3c50c822024-01-30 07:14:40 -060082 {
Kamalkumar Patel2edc34b2024-02-23 03:27:01 -060083 pldm::utils::GetSubTreeResponse response =
84 pldm::utils::DBusHandler().getSubtree(searchpath, depth,
85 systemCompatible);
86 auto& bus = pldm::utils::DBusHandler::getBus();
87
88 for (const auto& [objectPath, serviceMap] : response)
Kamalkumar Patel3c50c822024-01-30 07:14:40 -060089 {
Kamalkumar Patel2edc34b2024-02-23 03:27:01 -060090 try
Kamalkumar Patel3c50c822024-01-30 07:14:40 -060091 {
Kamalkumar Patel2edc34b2024-02-23 03:27:01 -060092 auto record = std::find_if(
93 serviceMap.begin(), serviceMap.end(),
94 [](auto map) { return map.first == entityMangerService; });
95
96 if (record != serviceMap.end())
97 {
98 auto method = bus.new_method_call(
99 entityMangerService.c_str(), objectPath.c_str(),
100 "org.freedesktop.DBus.Properties", "Get");
101 method.append(compatibleInterface, namesProperty);
102 auto propSystemList =
103 bus.call(method, dbusTimeout).unpack<PropertyValue>();
104 auto systemList =
105 std::get<std::vector<std::string>>(propSystemList);
106
107 if (!systemList.empty())
108 {
Kamalkumar Patel0a422692024-06-03 00:42:56 -0500109 std::optional<std::string> sysType =
110 getSysSpecificJsonDir(sysDirPath, systemList);
Kamalkumar Patel2edc34b2024-02-23 03:27:01 -0600111 // once systemtype received,then resetting a callback
112 systemCompatibleMatchCallBack.reset();
Kamalkumar Patel0a422692024-06-03 00:42:56 -0500113 if (sysType.has_value())
114 {
115 systemType = sysType.value();
116 }
Kamalkumar Patel2edc34b2024-02-23 03:27:01 -0600117 return fs::path{systemType};
118 }
119 }
120 }
121 catch (const std::exception& e)
122 {
123 error(
Riya Dixit89644442024-03-31 05:39:59 -0500124 "Failed to get Names property at '{PATH}' on interface '{INTERFACE}', error - {ERROR}",
Kamalkumar Patel2edc34b2024-02-23 03:27:01 -0600125 "PATH", objectPath, "INTERFACE", compatibleInterface,
126 "ERROR", e);
Kamalkumar Patel3c50c822024-01-30 07:14:40 -0600127 }
128 }
Kamalkumar Patel2edc34b2024-02-23 03:27:01 -0600129 }
130 catch (const std::exception& e)
131 {
Riya Dixit89644442024-03-31 05:39:59 -0500132 error(
133 "Failed to make a d-bus call to get platform name, error - {ERROR}",
134 "ERROR", e);
Kamalkumar Patel3c50c822024-01-30 07:14:40 -0600135 }
136 return std::nullopt;
137}
138
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400139std::optional<std::string> Handler::getSysSpecificJsonDir(
140 const fs::path& dirPath, const std::vector<std::string>& dirNames)
Kamalkumar Patel0a422692024-06-03 00:42:56 -0500141{
142 // The current setup assumes that the BIOS and PDR configurations always
143 // come from the same system type. If, in the future, we need to use BIOS
144 // and PDR configurations from different system types, we should create
145 // separate system type folders for each and update the logic to support
146 // this.
147
148 if (dirPath.empty())
149 {
150 return std::nullopt;
151 }
152
153 for (const auto& dirEntry : std::filesystem::directory_iterator{dirPath})
154 {
155 if (dirEntry.is_directory())
156 {
157 const auto sysDir = dirEntry.path().filename().string();
158 if (std::find(dirNames.begin(), dirNames.end(), sysDir) !=
159 dirNames.end())
160 {
161 return sysDir;
162 }
163 }
164 }
165
166 return std::nullopt;
167}
168
Archana Kakani62dd8ff2024-02-12 10:00:40 -0600169void Handler::registerSystemTypeCallback(SystemTypeCallback callback)
170{
171 sysTypeCallback = callback;
172}
173
Kamalkumar Patel3c50c822024-01-30 07:14:40 -0600174} // namespace platform_config
175
176} // namespace responder
177
178} // namespace pldm