blob: 78f3df2ee7bbd214f41d9497e4cfe17328e0ebe4 [file] [log] [blame]
Kamalkumar Patel7d427f12024-05-16 03:44:00 -05001#include "utils.hpp"
Kamalkumar Patel4e69d252024-05-10 08:48:03 -05002
Andrew Jeffery41ca40d2024-06-19 16:52:21 +09303#include <libpldm/entity.h>
Kamalkumar Patel4e69d252024-05-10 08:48:03 -05004
Kamalkumar Patel516122e2024-05-07 04:39:32 -05005#include <cstdlib>
Kamalkumar Patel4e69d252024-05-10 08:48:03 -05006#include <iostream>
7
Kamalkumar Patel7d427f12024-05-16 03:44:00 -05008using namespace pldm::utils;
9
Kamalkumar Patel4e69d252024-05-10 08:48:03 -050010namespace pldm
11{
12namespace hostbmc
13{
14namespace utils
15{
16Entities getParentEntites(const EntityAssociations& entityAssoc)
17{
18 Entities parents{};
19 for (const auto& et : entityAssoc)
20 {
21 parents.push_back(et[0]);
22 }
23
24 bool found = false;
25 for (auto it = parents.begin(); it != parents.end();
26 it = found ? parents.erase(it) : std::next(it))
27 {
28 uint16_t parent_contained_id =
29 pldm_entity_node_get_remote_container_id(*it);
30 found = false;
31 for (const auto& evs : entityAssoc)
32 {
33 for (size_t i = 1; i < evs.size() && !found; i++)
34 {
35 uint16_t node_contained_id =
36 pldm_entity_node_get_remote_container_id(evs[i]);
37
38 pldm_entity parent_entity = pldm_entity_extract(*it);
39 pldm_entity node_entity = pldm_entity_extract(evs[i]);
40
41 if (node_entity.entity_type == parent_entity.entity_type &&
42 node_entity.entity_instance_num ==
43 parent_entity.entity_instance_num &&
44 node_contained_id == parent_contained_id)
45 {
46 found = true;
47 }
48 }
49 if (found)
50 {
51 break;
52 }
53 }
54 }
55
56 return parents;
57}
58
Kamalkumar Patel15ce5a12024-05-07 11:45:11 -050059void addObjectPathEntityAssociations(
60 const EntityAssociations& entityAssoc, pldm_entity_node* entity,
61 const fs::path& path, ObjectPathMaps& objPathMap, EntityMaps entityMaps,
62 pldm::responder::oem_platform::Handler* oemPlatformHandler)
Kamalkumar Patel4e69d252024-05-10 08:48:03 -050063{
64 if (entity == nullptr)
65 {
66 return;
67 }
68
69 bool found = false;
70 pldm_entity node_entity = pldm_entity_extract(entity);
71 if (!entityMaps.contains(node_entity.entity_type))
72 {
Kamalkumar Pateld06de1c2024-05-31 00:44:45 -050073 // entityMaps doesn't contain entity type which are not required to
74 // build entity object path, so returning from here because this is a
75 // expected behaviour
Kamalkumar Patel4e69d252024-05-10 08:48:03 -050076 return;
77 }
78
79 std::string entityName = entityMaps.at(node_entity.entity_type);
80 for (const auto& ev : entityAssoc)
81 {
82 pldm_entity ev_entity = pldm_entity_extract(ev[0]);
83 if (ev_entity.entity_instance_num == node_entity.entity_instance_num &&
84 ev_entity.entity_type == node_entity.entity_type)
85 {
86 uint16_t node_contained_id =
87 pldm_entity_node_get_remote_container_id(ev[0]);
88 uint16_t entity_contained_id =
89 pldm_entity_node_get_remote_container_id(entity);
90
91 if (node_contained_id != entity_contained_id)
92 {
93 continue;
94 }
95
96 fs::path p = path / fs::path{entityName +
97 std::to_string(
98 node_entity.entity_instance_num)};
99 std::string entity_path = p.string();
Kamalkumar Patel15ce5a12024-05-07 11:45:11 -0500100 if (oemPlatformHandler)
101 {
102 oemPlatformHandler->updateOemDbusPaths(entity_path);
103 }
Kamalkumar Patel4e69d252024-05-10 08:48:03 -0500104 // If the entity obtained from the remote PLDM terminal is not in
105 // the MAP, or there is no auxiliary name PDR, add it directly.
106 // Otherwise, check whether the DBus service of entity_path exists,
107 // and overwrite the entity if it does not exist.
108 if (!objPathMap.contains(entity_path))
109 {
110 objPathMap[entity_path] = entity;
111 }
112 else
113 {
114 try
115 {
116 pldm::utils::DBusHandler().getService(entity_path.c_str(),
117 nullptr);
118 }
119 catch (const std::exception& e)
120 {
121 objPathMap[entity_path] = entity;
122 }
123 }
124
125 for (size_t i = 1; i < ev.size(); i++)
126 {
127 addObjectPathEntityAssociations(entityAssoc, ev[i], p,
Kamalkumar Patel15ce5a12024-05-07 11:45:11 -0500128 objPathMap, entityMaps,
129 oemPlatformHandler);
Kamalkumar Patel4e69d252024-05-10 08:48:03 -0500130 }
131 found = true;
132 }
133 }
134
135 if (!found)
136 {
137 std::string dbusPath =
138 path / fs::path{entityName +
139 std::to_string(node_entity.entity_instance_num)};
Kamalkumar Patel15ce5a12024-05-07 11:45:11 -0500140 if (oemPlatformHandler)
141 {
142 oemPlatformHandler->updateOemDbusPaths(dbusPath);
143 }
Kamalkumar Patel4e69d252024-05-10 08:48:03 -0500144 try
145 {
146 pldm::utils::DBusHandler().getService(dbusPath.c_str(), nullptr);
147 }
148 catch (const std::exception& e)
149 {
150 objPathMap[dbusPath] = entity;
151 }
152 }
153}
154
Kamalkumar Patel15ce5a12024-05-07 11:45:11 -0500155void updateEntityAssociation(
156 const EntityAssociations& entityAssoc,
157 pldm_entity_association_tree* entityTree, ObjectPathMaps& objPathMap,
158 EntityMaps entityMaps,
159 pldm::responder::oem_platform::Handler* oemPlatformHandler)
Kamalkumar Patel4e69d252024-05-10 08:48:03 -0500160{
161 std::vector<pldm_entity_node*> parentsEntity =
162 getParentEntites(entityAssoc);
163 for (const auto& entity : parentsEntity)
164 {
165 fs::path path{"/xyz/openbmc_project/inventory"};
166 std::deque<std::string> paths{};
167 pldm_entity node_entity = pldm_entity_extract(entity);
168 auto node = pldm_entity_association_tree_find_with_locality(
169 entityTree, &node_entity, false);
170 if (!node)
171 {
172 continue;
173 }
174
175 bool found = true;
176 while (node)
177 {
178 if (!pldm_entity_is_exist_parent(node))
179 {
180 break;
181 }
182
183 pldm_entity parent = pldm_entity_get_parent(node);
184 try
185 {
186 paths.push_back(entityMaps.at(parent.entity_type) +
187 std::to_string(parent.entity_instance_num));
188 }
189 catch (const std::exception& e)
190 {
191 lg2::error(
192 "Parent entity not found in the entityMaps, type: {ENTITY_TYPE}, num: {NUM}, e: {ERROR}",
193 "ENTITY_TYPE", (int)parent.entity_type, "NUM",
194 (int)parent.entity_instance_num, "ERROR", e);
195 found = false;
196 break;
197 }
198
199 node = pldm_entity_association_tree_find_with_locality(
200 entityTree, &parent, false);
201 }
202
203 if (!found)
204 {
205 continue;
206 }
207
208 while (!paths.empty())
209 {
210 path = path / fs::path{paths.back()};
211 paths.pop_back();
212 }
213
Kamalkumar Patel516122e2024-05-07 04:39:32 -0500214 addObjectPathEntityAssociations(entityAssoc, entity, path, objPathMap,
Kamalkumar Patel15ce5a12024-05-07 11:45:11 -0500215 entityMaps, oemPlatformHandler);
Kamalkumar Patel4e69d252024-05-10 08:48:03 -0500216 }
217}
Kamalkumar Patel516122e2024-05-07 04:39:32 -0500218
219EntityMaps parseEntityMap(const fs::path& filePath)
220{
221 const Json emptyJson{};
222 EntityMaps entityMaps{};
223 std::ifstream jsonFile(filePath);
224 auto data = Json::parse(jsonFile);
225 if (data.is_discarded())
226 {
227 error("Failed parsing of EntityMap data from json file: '{JSON_PATH}'",
228 "JSON_PATH", filePath);
229 return entityMaps;
230 }
231 auto entities = data.value("EntityTypeToDbusStringMap", emptyJson);
232 char* err;
233 try
234 {
235 std::ranges::transform(entities.items(),
236 std::inserter(entityMaps, entityMaps.begin()),
237 [&err](const auto& element) {
238 std::string key = static_cast<EntityName>(element.key());
239 return std::make_pair(strtol(key.c_str(), &err, 10),
240 static_cast<EntityName>(element.value()));
241 });
242 }
243 catch (const std::exception& e)
244 {
245 error(
246 "Failed to create entity to DBus string mapping {ERROR} and Conversion failure is '{ERR}'",
247 "ERROR", e, "ERR", err);
248 }
249
250 return entityMaps;
251}
252
Kamalkumar Patel4e69d252024-05-10 08:48:03 -0500253} // namespace utils
254} // namespace hostbmc
255} // namespace pldm