blob: f025ada32e234ec4dcf654cd95af9c34de52b50a [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
7#include <iostream>
8
9namespace pldm
10{
11namespace hostbmc
12{
13namespace utils
14{
15Entities getParentEntites(const EntityAssociations& entityAssoc)
16{
17 Entities parents{};
18 for (const auto& et : entityAssoc)
19 {
20 parents.push_back(et[0]);
21 }
22
23 bool found = false;
24 for (auto it = parents.begin(); it != parents.end();
25 it = found ? parents.erase(it) : std::next(it))
26 {
27 uint16_t parent_contained_id =
28 pldm_entity_node_get_remote_container_id(*it);
29 found = false;
30 for (const auto& evs : entityAssoc)
31 {
32 for (size_t i = 1; i < evs.size() && !found; i++)
33 {
34 uint16_t node_contained_id =
35 pldm_entity_node_get_remote_container_id(evs[i]);
36
37 pldm_entity parent_entity = pldm_entity_extract(*it);
38 pldm_entity node_entity = pldm_entity_extract(evs[i]);
39
40 if (node_entity.entity_type == parent_entity.entity_type &&
41 node_entity.entity_instance_num ==
42 parent_entity.entity_instance_num &&
43 node_contained_id == parent_contained_id)
44 {
45 found = true;
46 }
47 }
48 if (found)
49 {
50 break;
51 }
52 }
53 }
54
55 return parents;
56}
57
58void addObjectPathEntityAssociations(const EntityAssociations& entityAssoc,
59 pldm_entity_node* entity,
60 const fs::path& path,
61 ObjectPathMaps& objPathMap)
62{
63 if (entity == nullptr)
64 {
65 return;
66 }
67
68 bool found = false;
69 pldm_entity node_entity = pldm_entity_extract(entity);
70 if (!entityMaps.contains(node_entity.entity_type))
71 {
72 lg2::info(
73 "{ENTITY_TYPE} Entity fetched from remote PLDM terminal does not exist.",
74 "ENTITY_TYPE", (int)node_entity.entity_type);
75 return;
76 }
77
78 std::string entityName = entityMaps.at(node_entity.entity_type);
79 for (const auto& ev : entityAssoc)
80 {
81 pldm_entity ev_entity = pldm_entity_extract(ev[0]);
82 if (ev_entity.entity_instance_num == node_entity.entity_instance_num &&
83 ev_entity.entity_type == node_entity.entity_type)
84 {
85 uint16_t node_contained_id =
86 pldm_entity_node_get_remote_container_id(ev[0]);
87 uint16_t entity_contained_id =
88 pldm_entity_node_get_remote_container_id(entity);
89
90 if (node_contained_id != entity_contained_id)
91 {
92 continue;
93 }
94
95 fs::path p = path / fs::path{entityName +
96 std::to_string(
97 node_entity.entity_instance_num)};
98 std::string entity_path = p.string();
99 // If the entity obtained from the remote PLDM terminal is not in
100 // the MAP, or there is no auxiliary name PDR, add it directly.
101 // Otherwise, check whether the DBus service of entity_path exists,
102 // and overwrite the entity if it does not exist.
103 if (!objPathMap.contains(entity_path))
104 {
105 objPathMap[entity_path] = entity;
106 }
107 else
108 {
109 try
110 {
111 pldm::utils::DBusHandler().getService(entity_path.c_str(),
112 nullptr);
113 }
114 catch (const std::exception& e)
115 {
116 objPathMap[entity_path] = entity;
117 }
118 }
119
120 for (size_t i = 1; i < ev.size(); i++)
121 {
122 addObjectPathEntityAssociations(entityAssoc, ev[i], p,
123 objPathMap);
124 }
125 found = true;
126 }
127 }
128
129 if (!found)
130 {
131 std::string dbusPath =
132 path / fs::path{entityName +
133 std::to_string(node_entity.entity_instance_num)};
134
135 try
136 {
137 pldm::utils::DBusHandler().getService(dbusPath.c_str(), nullptr);
138 }
139 catch (const std::exception& e)
140 {
141 objPathMap[dbusPath] = entity;
142 }
143 }
144}
145
146void updateEntityAssociation(const EntityAssociations& entityAssoc,
147 pldm_entity_association_tree* entityTree,
148 ObjectPathMaps& objPathMap)
149{
150 std::vector<pldm_entity_node*> parentsEntity =
151 getParentEntites(entityAssoc);
152 for (const auto& entity : parentsEntity)
153 {
154 fs::path path{"/xyz/openbmc_project/inventory"};
155 std::deque<std::string> paths{};
156 pldm_entity node_entity = pldm_entity_extract(entity);
157 auto node = pldm_entity_association_tree_find_with_locality(
158 entityTree, &node_entity, false);
159 if (!node)
160 {
161 continue;
162 }
163
164 bool found = true;
165 while (node)
166 {
167 if (!pldm_entity_is_exist_parent(node))
168 {
169 break;
170 }
171
172 pldm_entity parent = pldm_entity_get_parent(node);
173 try
174 {
175 paths.push_back(entityMaps.at(parent.entity_type) +
176 std::to_string(parent.entity_instance_num));
177 }
178 catch (const std::exception& e)
179 {
180 lg2::error(
181 "Parent entity not found in the entityMaps, type: {ENTITY_TYPE}, num: {NUM}, e: {ERROR}",
182 "ENTITY_TYPE", (int)parent.entity_type, "NUM",
183 (int)parent.entity_instance_num, "ERROR", e);
184 found = false;
185 break;
186 }
187
188 node = pldm_entity_association_tree_find_with_locality(
189 entityTree, &parent, false);
190 }
191
192 if (!found)
193 {
194 continue;
195 }
196
197 while (!paths.empty())
198 {
199 path = path / fs::path{paths.back()};
200 paths.pop_back();
201 }
202
203 addObjectPathEntityAssociations(entityAssoc, entity, path, objPathMap);
204 }
205}
206} // namespace utils
207} // namespace hostbmc
208} // namespace pldm