17d427f16SKamalkumar Patel #include "utils.hpp"
24e69d252SKamalkumar Patel
341ca40dcSAndrew Jeffery #include <libpldm/entity.h>
44e69d252SKamalkumar Patel
5516122e0SKamalkumar Patel #include <cstdlib>
64e69d252SKamalkumar Patel #include <iostream>
74e69d252SKamalkumar Patel
87d427f16SKamalkumar Patel using namespace pldm::utils;
97d427f16SKamalkumar Patel
104e69d252SKamalkumar Patel namespace pldm
114e69d252SKamalkumar Patel {
124e69d252SKamalkumar Patel namespace hostbmc
134e69d252SKamalkumar Patel {
144e69d252SKamalkumar Patel namespace utils
154e69d252SKamalkumar Patel {
getParentEntites(const EntityAssociations & entityAssoc)164e69d252SKamalkumar Patel Entities getParentEntites(const EntityAssociations& entityAssoc)
174e69d252SKamalkumar Patel {
184e69d252SKamalkumar Patel Entities parents{};
194e69d252SKamalkumar Patel for (const auto& et : entityAssoc)
204e69d252SKamalkumar Patel {
214e69d252SKamalkumar Patel parents.push_back(et[0]);
224e69d252SKamalkumar Patel }
234e69d252SKamalkumar Patel
244e69d252SKamalkumar Patel bool found = false;
254e69d252SKamalkumar Patel for (auto it = parents.begin(); it != parents.end();
264e69d252SKamalkumar Patel it = found ? parents.erase(it) : std::next(it))
274e69d252SKamalkumar Patel {
284e69d252SKamalkumar Patel uint16_t parent_contained_id =
294e69d252SKamalkumar Patel pldm_entity_node_get_remote_container_id(*it);
304e69d252SKamalkumar Patel found = false;
314e69d252SKamalkumar Patel for (const auto& evs : entityAssoc)
324e69d252SKamalkumar Patel {
334e69d252SKamalkumar Patel for (size_t i = 1; i < evs.size() && !found; i++)
344e69d252SKamalkumar Patel {
354e69d252SKamalkumar Patel uint16_t node_contained_id =
364e69d252SKamalkumar Patel pldm_entity_node_get_remote_container_id(evs[i]);
374e69d252SKamalkumar Patel
384e69d252SKamalkumar Patel pldm_entity parent_entity = pldm_entity_extract(*it);
394e69d252SKamalkumar Patel pldm_entity node_entity = pldm_entity_extract(evs[i]);
404e69d252SKamalkumar Patel
414e69d252SKamalkumar Patel if (node_entity.entity_type == parent_entity.entity_type &&
424e69d252SKamalkumar Patel node_entity.entity_instance_num ==
434e69d252SKamalkumar Patel parent_entity.entity_instance_num &&
444e69d252SKamalkumar Patel node_contained_id == parent_contained_id)
454e69d252SKamalkumar Patel {
464e69d252SKamalkumar Patel found = true;
474e69d252SKamalkumar Patel }
484e69d252SKamalkumar Patel }
494e69d252SKamalkumar Patel if (found)
504e69d252SKamalkumar Patel {
514e69d252SKamalkumar Patel break;
524e69d252SKamalkumar Patel }
534e69d252SKamalkumar Patel }
544e69d252SKamalkumar Patel }
554e69d252SKamalkumar Patel
564e69d252SKamalkumar Patel return parents;
574e69d252SKamalkumar Patel }
584e69d252SKamalkumar Patel
addObjectPathEntityAssociations(const EntityAssociations & entityAssoc,pldm_entity_node * entity,const fs::path & path,ObjectPathMaps & objPathMap,EntityMaps entityMaps,pldm::responder::oem_platform::Handler * oemPlatformHandler)5915ce5a18SKamalkumar Patel void addObjectPathEntityAssociations(
6015ce5a18SKamalkumar Patel const EntityAssociations& entityAssoc, pldm_entity_node* entity,
6115ce5a18SKamalkumar Patel const fs::path& path, ObjectPathMaps& objPathMap, EntityMaps entityMaps,
6215ce5a18SKamalkumar Patel pldm::responder::oem_platform::Handler* oemPlatformHandler)
634e69d252SKamalkumar Patel {
644e69d252SKamalkumar Patel if (entity == nullptr)
654e69d252SKamalkumar Patel {
664e69d252SKamalkumar Patel return;
674e69d252SKamalkumar Patel }
684e69d252SKamalkumar Patel
694e69d252SKamalkumar Patel bool found = false;
704e69d252SKamalkumar Patel pldm_entity node_entity = pldm_entity_extract(entity);
714e69d252SKamalkumar Patel if (!entityMaps.contains(node_entity.entity_type))
724e69d252SKamalkumar Patel {
73d06de1cbSKamalkumar Patel // entityMaps doesn't contain entity type which are not required to
74d06de1cbSKamalkumar Patel // build entity object path, so returning from here because this is a
75d06de1cbSKamalkumar Patel // expected behaviour
764e69d252SKamalkumar Patel return;
774e69d252SKamalkumar Patel }
784e69d252SKamalkumar Patel
794e69d252SKamalkumar Patel std::string entityName = entityMaps.at(node_entity.entity_type);
804e69d252SKamalkumar Patel for (const auto& ev : entityAssoc)
814e69d252SKamalkumar Patel {
824e69d252SKamalkumar Patel pldm_entity ev_entity = pldm_entity_extract(ev[0]);
834e69d252SKamalkumar Patel if (ev_entity.entity_instance_num == node_entity.entity_instance_num &&
844e69d252SKamalkumar Patel ev_entity.entity_type == node_entity.entity_type)
854e69d252SKamalkumar Patel {
864e69d252SKamalkumar Patel uint16_t node_contained_id =
874e69d252SKamalkumar Patel pldm_entity_node_get_remote_container_id(ev[0]);
884e69d252SKamalkumar Patel uint16_t entity_contained_id =
894e69d252SKamalkumar Patel pldm_entity_node_get_remote_container_id(entity);
904e69d252SKamalkumar Patel
914e69d252SKamalkumar Patel if (node_contained_id != entity_contained_id)
924e69d252SKamalkumar Patel {
934e69d252SKamalkumar Patel continue;
944e69d252SKamalkumar Patel }
954e69d252SKamalkumar Patel
96*16c2a0a0SPatrick Williams fs::path p =
97*16c2a0a0SPatrick Williams path /
98*16c2a0a0SPatrick Williams fs::path{entityName +
99*16c2a0a0SPatrick Williams std::to_string(node_entity.entity_instance_num)};
1004e69d252SKamalkumar Patel std::string entity_path = p.string();
10115ce5a18SKamalkumar Patel if (oemPlatformHandler)
10215ce5a18SKamalkumar Patel {
10315ce5a18SKamalkumar Patel oemPlatformHandler->updateOemDbusPaths(entity_path);
10415ce5a18SKamalkumar Patel }
1054e69d252SKamalkumar Patel try
1064e69d252SKamalkumar Patel {
1074e69d252SKamalkumar Patel pldm::utils::DBusHandler().getService(entity_path.c_str(),
1084e69d252SKamalkumar Patel nullptr);
109267c7efcSKamalkumar Patel // If the entity obtained from the remote PLDM terminal is not
110267c7efcSKamalkumar Patel // in the MAP, or there is no auxiliary name PDR, add it
111267c7efcSKamalkumar Patel // directly. Otherwise, check whether the DBus service of
112267c7efcSKamalkumar Patel // entity_path exists, and overwrite the entity if it does not
113267c7efcSKamalkumar Patel // exist.
114267c7efcSKamalkumar Patel if (objPathMap.contains(entity_path))
1154e69d252SKamalkumar Patel {
1164e69d252SKamalkumar Patel objPathMap[entity_path] = entity;
1174e69d252SKamalkumar Patel }
1184e69d252SKamalkumar Patel }
119267c7efcSKamalkumar Patel catch (const std::exception&)
120267c7efcSKamalkumar Patel {
121267c7efcSKamalkumar Patel objPathMap[entity_path] = entity;
122267c7efcSKamalkumar Patel }
1234e69d252SKamalkumar Patel
1244e69d252SKamalkumar Patel for (size_t i = 1; i < ev.size(); i++)
1254e69d252SKamalkumar Patel {
1264e69d252SKamalkumar Patel addObjectPathEntityAssociations(entityAssoc, ev[i], p,
12715ce5a18SKamalkumar Patel objPathMap, entityMaps,
12815ce5a18SKamalkumar Patel oemPlatformHandler);
1294e69d252SKamalkumar Patel }
1304e69d252SKamalkumar Patel found = true;
1314e69d252SKamalkumar Patel }
1324e69d252SKamalkumar Patel }
1334e69d252SKamalkumar Patel
1344e69d252SKamalkumar Patel if (!found)
1354e69d252SKamalkumar Patel {
1364e69d252SKamalkumar Patel std::string dbusPath =
1374e69d252SKamalkumar Patel path / fs::path{entityName +
1384e69d252SKamalkumar Patel std::to_string(node_entity.entity_instance_num)};
13915ce5a18SKamalkumar Patel if (oemPlatformHandler)
14015ce5a18SKamalkumar Patel {
14115ce5a18SKamalkumar Patel oemPlatformHandler->updateOemDbusPaths(dbusPath);
14215ce5a18SKamalkumar Patel }
1434e69d252SKamalkumar Patel try
1444e69d252SKamalkumar Patel {
1454e69d252SKamalkumar Patel pldm::utils::DBusHandler().getService(dbusPath.c_str(), nullptr);
146267c7efcSKamalkumar Patel if (objPathMap.contains(dbusPath))
147267c7efcSKamalkumar Patel {
148267c7efcSKamalkumar Patel objPathMap[dbusPath] = entity;
1494e69d252SKamalkumar Patel }
150267c7efcSKamalkumar Patel }
151267c7efcSKamalkumar Patel catch (const std::exception&)
1524e69d252SKamalkumar Patel {
1534e69d252SKamalkumar Patel objPathMap[dbusPath] = entity;
1544e69d252SKamalkumar Patel }
1554e69d252SKamalkumar Patel }
1564e69d252SKamalkumar Patel }
1574e69d252SKamalkumar Patel
updateEntityAssociation(const EntityAssociations & entityAssoc,pldm_entity_association_tree * entityTree,ObjectPathMaps & objPathMap,EntityMaps entityMaps,pldm::responder::oem_platform::Handler * oemPlatformHandler)15815ce5a18SKamalkumar Patel void updateEntityAssociation(
15915ce5a18SKamalkumar Patel const EntityAssociations& entityAssoc,
16015ce5a18SKamalkumar Patel pldm_entity_association_tree* entityTree, ObjectPathMaps& objPathMap,
16115ce5a18SKamalkumar Patel EntityMaps entityMaps,
16215ce5a18SKamalkumar Patel pldm::responder::oem_platform::Handler* oemPlatformHandler)
1634e69d252SKamalkumar Patel {
1644e69d252SKamalkumar Patel std::vector<pldm_entity_node*> parentsEntity =
1654e69d252SKamalkumar Patel getParentEntites(entityAssoc);
1664e69d252SKamalkumar Patel for (const auto& entity : parentsEntity)
1674e69d252SKamalkumar Patel {
1684e69d252SKamalkumar Patel fs::path path{"/xyz/openbmc_project/inventory"};
1694e69d252SKamalkumar Patel std::deque<std::string> paths{};
1704e69d252SKamalkumar Patel pldm_entity node_entity = pldm_entity_extract(entity);
1714e69d252SKamalkumar Patel auto node = pldm_entity_association_tree_find_with_locality(
1724e69d252SKamalkumar Patel entityTree, &node_entity, false);
1734e69d252SKamalkumar Patel if (!node)
1744e69d252SKamalkumar Patel {
1754e69d252SKamalkumar Patel continue;
1764e69d252SKamalkumar Patel }
1774e69d252SKamalkumar Patel
1784e69d252SKamalkumar Patel bool found = true;
1794e69d252SKamalkumar Patel while (node)
1804e69d252SKamalkumar Patel {
1814e69d252SKamalkumar Patel if (!pldm_entity_is_exist_parent(node))
1824e69d252SKamalkumar Patel {
1834e69d252SKamalkumar Patel break;
1844e69d252SKamalkumar Patel }
1854e69d252SKamalkumar Patel
1864e69d252SKamalkumar Patel pldm_entity parent = pldm_entity_get_parent(node);
1874e69d252SKamalkumar Patel try
1884e69d252SKamalkumar Patel {
1894e69d252SKamalkumar Patel paths.push_back(entityMaps.at(parent.entity_type) +
1904e69d252SKamalkumar Patel std::to_string(parent.entity_instance_num));
1914e69d252SKamalkumar Patel }
1924e69d252SKamalkumar Patel catch (const std::exception& e)
1934e69d252SKamalkumar Patel {
1944e69d252SKamalkumar Patel lg2::error(
1954e69d252SKamalkumar Patel "Parent entity not found in the entityMaps, type: {ENTITY_TYPE}, num: {NUM}, e: {ERROR}",
1964e69d252SKamalkumar Patel "ENTITY_TYPE", (int)parent.entity_type, "NUM",
1974e69d252SKamalkumar Patel (int)parent.entity_instance_num, "ERROR", e);
1984e69d252SKamalkumar Patel found = false;
1994e69d252SKamalkumar Patel break;
2004e69d252SKamalkumar Patel }
2014e69d252SKamalkumar Patel
2024e69d252SKamalkumar Patel node = pldm_entity_association_tree_find_with_locality(
2034e69d252SKamalkumar Patel entityTree, &parent, false);
2044e69d252SKamalkumar Patel }
2054e69d252SKamalkumar Patel
2064e69d252SKamalkumar Patel if (!found)
2074e69d252SKamalkumar Patel {
2084e69d252SKamalkumar Patel continue;
2094e69d252SKamalkumar Patel }
2104e69d252SKamalkumar Patel
2114e69d252SKamalkumar Patel while (!paths.empty())
2124e69d252SKamalkumar Patel {
2134e69d252SKamalkumar Patel path = path / fs::path{paths.back()};
2144e69d252SKamalkumar Patel paths.pop_back();
2154e69d252SKamalkumar Patel }
2164e69d252SKamalkumar Patel
217516122e0SKamalkumar Patel addObjectPathEntityAssociations(entityAssoc, entity, path, objPathMap,
21815ce5a18SKamalkumar Patel entityMaps, oemPlatformHandler);
2194e69d252SKamalkumar Patel }
2204e69d252SKamalkumar Patel }
221516122e0SKamalkumar Patel
parseEntityMap(const fs::path & filePath)222516122e0SKamalkumar Patel EntityMaps parseEntityMap(const fs::path& filePath)
223516122e0SKamalkumar Patel {
224516122e0SKamalkumar Patel const Json emptyJson{};
225516122e0SKamalkumar Patel EntityMaps entityMaps{};
226516122e0SKamalkumar Patel std::ifstream jsonFile(filePath);
227516122e0SKamalkumar Patel auto data = Json::parse(jsonFile);
228516122e0SKamalkumar Patel if (data.is_discarded())
229516122e0SKamalkumar Patel {
230516122e0SKamalkumar Patel error("Failed parsing of EntityMap data from json file: '{JSON_PATH}'",
231516122e0SKamalkumar Patel "JSON_PATH", filePath);
232516122e0SKamalkumar Patel return entityMaps;
233516122e0SKamalkumar Patel }
234516122e0SKamalkumar Patel auto entities = data.value("EntityTypeToDbusStringMap", emptyJson);
235516122e0SKamalkumar Patel char* err;
236516122e0SKamalkumar Patel try
237516122e0SKamalkumar Patel {
238*16c2a0a0SPatrick Williams std::ranges::transform(
239*16c2a0a0SPatrick Williams entities.items(), std::inserter(entityMaps, entityMaps.begin()),
240516122e0SKamalkumar Patel [&err](const auto& element) {
241516122e0SKamalkumar Patel std::string key = static_cast<EntityName>(element.key());
242516122e0SKamalkumar Patel return std::make_pair(strtol(key.c_str(), &err, 10),
243516122e0SKamalkumar Patel static_cast<EntityName>(element.value()));
244516122e0SKamalkumar Patel });
245516122e0SKamalkumar Patel }
246516122e0SKamalkumar Patel catch (const std::exception& e)
247516122e0SKamalkumar Patel {
248516122e0SKamalkumar Patel error(
249516122e0SKamalkumar Patel "Failed to create entity to DBus string mapping {ERROR} and Conversion failure is '{ERR}'",
250516122e0SKamalkumar Patel "ERROR", e, "ERR", err);
251516122e0SKamalkumar Patel }
252516122e0SKamalkumar Patel
253516122e0SKamalkumar Patel return entityMaps;
254516122e0SKamalkumar Patel }
255516122e0SKamalkumar Patel
2564e69d252SKamalkumar Patel } // namespace utils
2574e69d252SKamalkumar Patel } // namespace hostbmc
2584e69d252SKamalkumar Patel } // namespace pldm
259