blob: a178d48f015d96779aa0a2fd95a236d4d44b2ea8 [file] [log] [blame]
Kamalkumar Patel4e69d252024-05-10 08:48:03 -05001#include "common/utils.hpp"
2
3#include "libpldm/entity.h"
4
5#include "utils.hpp"
6
Kamalkumar Patel516122e2024-05-07 04:39:32 -05007#include <cstdlib>
Kamalkumar Patel4e69d252024-05-10 08:48:03 -05008#include <iostream>
9
10namespace 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
59void addObjectPathEntityAssociations(const EntityAssociations& entityAssoc,
60 pldm_entity_node* entity,
61 const fs::path& path,
Kamalkumar Patel516122e2024-05-07 04:39:32 -050062 ObjectPathMaps& objPathMap,
63 EntityMaps entityMaps)
Kamalkumar Patel4e69d252024-05-10 08:48:03 -050064{
65 if (entity == nullptr)
66 {
67 return;
68 }
69
70 bool found = false;
71 pldm_entity node_entity = pldm_entity_extract(entity);
72 if (!entityMaps.contains(node_entity.entity_type))
73 {
74 lg2::info(
75 "{ENTITY_TYPE} Entity fetched from remote PLDM terminal does not exist.",
76 "ENTITY_TYPE", (int)node_entity.entity_type);
77 return;
78 }
79
80 std::string entityName = entityMaps.at(node_entity.entity_type);
81 for (const auto& ev : entityAssoc)
82 {
83 pldm_entity ev_entity = pldm_entity_extract(ev[0]);
84 if (ev_entity.entity_instance_num == node_entity.entity_instance_num &&
85 ev_entity.entity_type == node_entity.entity_type)
86 {
87 uint16_t node_contained_id =
88 pldm_entity_node_get_remote_container_id(ev[0]);
89 uint16_t entity_contained_id =
90 pldm_entity_node_get_remote_container_id(entity);
91
92 if (node_contained_id != entity_contained_id)
93 {
94 continue;
95 }
96
97 fs::path p = path / fs::path{entityName +
98 std::to_string(
99 node_entity.entity_instance_num)};
100 std::string entity_path = p.string();
101 // If the entity obtained from the remote PLDM terminal is not in
102 // the MAP, or there is no auxiliary name PDR, add it directly.
103 // Otherwise, check whether the DBus service of entity_path exists,
104 // and overwrite the entity if it does not exist.
105 if (!objPathMap.contains(entity_path))
106 {
107 objPathMap[entity_path] = entity;
108 }
109 else
110 {
111 try
112 {
113 pldm::utils::DBusHandler().getService(entity_path.c_str(),
114 nullptr);
115 }
116 catch (const std::exception& e)
117 {
118 objPathMap[entity_path] = entity;
119 }
120 }
121
122 for (size_t i = 1; i < ev.size(); i++)
123 {
124 addObjectPathEntityAssociations(entityAssoc, ev[i], p,
Kamalkumar Patel516122e2024-05-07 04:39:32 -0500125 objPathMap, entityMaps);
Kamalkumar Patel4e69d252024-05-10 08:48:03 -0500126 }
127 found = true;
128 }
129 }
130
131 if (!found)
132 {
133 std::string dbusPath =
134 path / fs::path{entityName +
135 std::to_string(node_entity.entity_instance_num)};
Kamalkumar Patel4e69d252024-05-10 08:48:03 -0500136 try
137 {
138 pldm::utils::DBusHandler().getService(dbusPath.c_str(), nullptr);
139 }
140 catch (const std::exception& e)
141 {
142 objPathMap[dbusPath] = entity;
143 }
144 }
145}
146
147void updateEntityAssociation(const EntityAssociations& entityAssoc,
148 pldm_entity_association_tree* entityTree,
Kamalkumar Patel516122e2024-05-07 04:39:32 -0500149 ObjectPathMaps& objPathMap, EntityMaps entityMaps)
Kamalkumar Patel4e69d252024-05-10 08:48:03 -0500150{
151 std::vector<pldm_entity_node*> parentsEntity =
152 getParentEntites(entityAssoc);
153 for (const auto& entity : parentsEntity)
154 {
155 fs::path path{"/xyz/openbmc_project/inventory"};
156 std::deque<std::string> paths{};
157 pldm_entity node_entity = pldm_entity_extract(entity);
158 auto node = pldm_entity_association_tree_find_with_locality(
159 entityTree, &node_entity, false);
160 if (!node)
161 {
162 continue;
163 }
164
165 bool found = true;
166 while (node)
167 {
168 if (!pldm_entity_is_exist_parent(node))
169 {
170 break;
171 }
172
173 pldm_entity parent = pldm_entity_get_parent(node);
174 try
175 {
176 paths.push_back(entityMaps.at(parent.entity_type) +
177 std::to_string(parent.entity_instance_num));
178 }
179 catch (const std::exception& e)
180 {
181 lg2::error(
182 "Parent entity not found in the entityMaps, type: {ENTITY_TYPE}, num: {NUM}, e: {ERROR}",
183 "ENTITY_TYPE", (int)parent.entity_type, "NUM",
184 (int)parent.entity_instance_num, "ERROR", e);
185 found = false;
186 break;
187 }
188
189 node = pldm_entity_association_tree_find_with_locality(
190 entityTree, &parent, false);
191 }
192
193 if (!found)
194 {
195 continue;
196 }
197
198 while (!paths.empty())
199 {
200 path = path / fs::path{paths.back()};
201 paths.pop_back();
202 }
203
Kamalkumar Patel516122e2024-05-07 04:39:32 -0500204 addObjectPathEntityAssociations(entityAssoc, entity, path, objPathMap,
205 entityMaps);
Kamalkumar Patel4e69d252024-05-10 08:48:03 -0500206 }
207}
Kamalkumar Patel516122e2024-05-07 04:39:32 -0500208
209EntityMaps parseEntityMap(const fs::path& filePath)
210{
211 const Json emptyJson{};
212 EntityMaps entityMaps{};
213 std::ifstream jsonFile(filePath);
214 auto data = Json::parse(jsonFile);
215 if (data.is_discarded())
216 {
217 error("Failed parsing of EntityMap data from json file: '{JSON_PATH}'",
218 "JSON_PATH", filePath);
219 return entityMaps;
220 }
221 auto entities = data.value("EntityTypeToDbusStringMap", emptyJson);
222 char* err;
223 try
224 {
225 std::ranges::transform(entities.items(),
226 std::inserter(entityMaps, entityMaps.begin()),
227 [&err](const auto& element) {
228 std::string key = static_cast<EntityName>(element.key());
229 return std::make_pair(strtol(key.c_str(), &err, 10),
230 static_cast<EntityName>(element.value()));
231 });
232 }
233 catch (const std::exception& e)
234 {
235 error(
236 "Failed to create entity to DBus string mapping {ERROR} and Conversion failure is '{ERR}'",
237 "ERROR", e, "ERR", err);
238 }
239
240 return entityMaps;
241}
242
Kamalkumar Patel4e69d252024-05-10 08:48:03 -0500243} // namespace utils
244} // namespace hostbmc
245} // namespace pldm