host-bmc: refine remote terminus functionality
This commit introduces support for migrating remote terminus-related
functionalities into the host-bmc directory, a move aimed at optimizing
remote terminus operations for future endeavors. By consolidating these
functionalities, tracking and implementing future enhancements become
more streamlined and manageable.
Change-Id: I52b6ced7acacb004b6055ae710193a959d986659
Signed-off-by: Kamalkumar Patel <kamalkumar.patel@ibm.com>
diff --git a/host-bmc/host_pdr_handler.cpp b/host-bmc/host_pdr_handler.cpp
index 3f3b964..71e3812 100644
--- a/host-bmc/host_pdr_handler.cpp
+++ b/host-bmc/host_pdr_handler.cpp
@@ -628,7 +628,8 @@
}
if (!nextRecordHandle)
{
- updateEntityAssociation(entityAssociations, entityTree, objPathMap);
+ pldm::hostbmc::utils::updateEntityAssociation(entityAssociations,
+ entityTree, objPathMap);
/*received last record*/
this->parseStateSensorPDRs(stateSensorPDRs);
diff --git a/host-bmc/host_pdr_handler.hpp b/host-bmc/host_pdr_handler.hpp
index 3b05f59..053cfef 100644
--- a/host-bmc/host_pdr_handler.hpp
+++ b/host-bmc/host_pdr_handler.hpp
@@ -7,6 +7,7 @@
#include "libpldmresponder/oem_handler.hpp"
#include "libpldmresponder/pdr_utils.hpp"
#include "requester/handler.hpp"
+#include "utils.hpp"
#include <libpldm/base.h>
#include <libpldm/platform.h>
@@ -314,11 +315,11 @@
/** @brief maps an object path to pldm_entity from the BMC's entity
* association tree
*/
- utils::ObjectPathMaps objPathMap;
+ ObjectPathMaps objPathMap;
/** @brief maps an entity name to map, maps to entity name to pldm_entity
*/
- utils::EntityAssociations entityAssociations;
+ EntityAssociations entityAssociations;
/** @brief the vector of FRU Record Data Format
*/
diff --git a/host-bmc/test/meson.build b/host-bmc/test/meson.build
index 30f6624..66d75b7 100644
--- a/host-bmc/test/meson.build
+++ b/host-bmc/test/meson.build
@@ -5,6 +5,7 @@
test_sources = [
'../../common/utils.cpp',
'../custom_dbus.cpp',
+ '../utils.cpp'
]
tests = [
diff --git a/host-bmc/test/utils_test.cpp b/host-bmc/test/utils_test.cpp
index ab64aa1..701f4cb 100644
--- a/host-bmc/test/utils_test.cpp
+++ b/host-bmc/test/utils_test.cpp
@@ -1,4 +1,4 @@
-#include "common/utils.hpp"
+#include "../utils.hpp"
#include <libpldm/pdr.h>
@@ -80,7 +80,8 @@
l5b}};
ObjectPathMaps objPathMap;
- updateEntityAssociation(entityAssociations, tree, objPathMap);
+ pldm::hostbmc::utils::updateEntityAssociation(entityAssociations, tree,
+ objPathMap);
EXPECT_EQ(objPathMap.size(), retObjectMaps.size());
diff --git a/host-bmc/utils.cpp b/host-bmc/utils.cpp
new file mode 100644
index 0000000..f025ada
--- /dev/null
+++ b/host-bmc/utils.cpp
@@ -0,0 +1,208 @@
+#include "common/utils.hpp"
+
+#include "libpldm/entity.h"
+
+#include "utils.hpp"
+
+#include <iostream>
+
+namespace pldm
+{
+namespace hostbmc
+{
+namespace utils
+{
+Entities getParentEntites(const EntityAssociations& entityAssoc)
+{
+ Entities parents{};
+ for (const auto& et : entityAssoc)
+ {
+ parents.push_back(et[0]);
+ }
+
+ bool found = false;
+ for (auto it = parents.begin(); it != parents.end();
+ it = found ? parents.erase(it) : std::next(it))
+ {
+ uint16_t parent_contained_id =
+ pldm_entity_node_get_remote_container_id(*it);
+ found = false;
+ for (const auto& evs : entityAssoc)
+ {
+ for (size_t i = 1; i < evs.size() && !found; i++)
+ {
+ uint16_t node_contained_id =
+ pldm_entity_node_get_remote_container_id(evs[i]);
+
+ pldm_entity parent_entity = pldm_entity_extract(*it);
+ pldm_entity node_entity = pldm_entity_extract(evs[i]);
+
+ if (node_entity.entity_type == parent_entity.entity_type &&
+ node_entity.entity_instance_num ==
+ parent_entity.entity_instance_num &&
+ node_contained_id == parent_contained_id)
+ {
+ found = true;
+ }
+ }
+ if (found)
+ {
+ break;
+ }
+ }
+ }
+
+ return parents;
+}
+
+void addObjectPathEntityAssociations(const EntityAssociations& entityAssoc,
+ pldm_entity_node* entity,
+ const fs::path& path,
+ ObjectPathMaps& objPathMap)
+{
+ if (entity == nullptr)
+ {
+ return;
+ }
+
+ bool found = false;
+ pldm_entity node_entity = pldm_entity_extract(entity);
+ if (!entityMaps.contains(node_entity.entity_type))
+ {
+ lg2::info(
+ "{ENTITY_TYPE} Entity fetched from remote PLDM terminal does not exist.",
+ "ENTITY_TYPE", (int)node_entity.entity_type);
+ return;
+ }
+
+ std::string entityName = entityMaps.at(node_entity.entity_type);
+ for (const auto& ev : entityAssoc)
+ {
+ pldm_entity ev_entity = pldm_entity_extract(ev[0]);
+ if (ev_entity.entity_instance_num == node_entity.entity_instance_num &&
+ ev_entity.entity_type == node_entity.entity_type)
+ {
+ uint16_t node_contained_id =
+ pldm_entity_node_get_remote_container_id(ev[0]);
+ uint16_t entity_contained_id =
+ pldm_entity_node_get_remote_container_id(entity);
+
+ if (node_contained_id != entity_contained_id)
+ {
+ continue;
+ }
+
+ fs::path p = path / fs::path{entityName +
+ std::to_string(
+ node_entity.entity_instance_num)};
+ std::string entity_path = p.string();
+ // If the entity obtained from the remote PLDM terminal is not in
+ // the MAP, or there is no auxiliary name PDR, add it directly.
+ // Otherwise, check whether the DBus service of entity_path exists,
+ // and overwrite the entity if it does not exist.
+ if (!objPathMap.contains(entity_path))
+ {
+ objPathMap[entity_path] = entity;
+ }
+ else
+ {
+ try
+ {
+ pldm::utils::DBusHandler().getService(entity_path.c_str(),
+ nullptr);
+ }
+ catch (const std::exception& e)
+ {
+ objPathMap[entity_path] = entity;
+ }
+ }
+
+ for (size_t i = 1; i < ev.size(); i++)
+ {
+ addObjectPathEntityAssociations(entityAssoc, ev[i], p,
+ objPathMap);
+ }
+ found = true;
+ }
+ }
+
+ if (!found)
+ {
+ std::string dbusPath =
+ path / fs::path{entityName +
+ std::to_string(node_entity.entity_instance_num)};
+
+ try
+ {
+ pldm::utils::DBusHandler().getService(dbusPath.c_str(), nullptr);
+ }
+ catch (const std::exception& e)
+ {
+ objPathMap[dbusPath] = entity;
+ }
+ }
+}
+
+void updateEntityAssociation(const EntityAssociations& entityAssoc,
+ pldm_entity_association_tree* entityTree,
+ ObjectPathMaps& objPathMap)
+{
+ std::vector<pldm_entity_node*> parentsEntity =
+ getParentEntites(entityAssoc);
+ for (const auto& entity : parentsEntity)
+ {
+ fs::path path{"/xyz/openbmc_project/inventory"};
+ std::deque<std::string> paths{};
+ pldm_entity node_entity = pldm_entity_extract(entity);
+ auto node = pldm_entity_association_tree_find_with_locality(
+ entityTree, &node_entity, false);
+ if (!node)
+ {
+ continue;
+ }
+
+ bool found = true;
+ while (node)
+ {
+ if (!pldm_entity_is_exist_parent(node))
+ {
+ break;
+ }
+
+ pldm_entity parent = pldm_entity_get_parent(node);
+ try
+ {
+ paths.push_back(entityMaps.at(parent.entity_type) +
+ std::to_string(parent.entity_instance_num));
+ }
+ catch (const std::exception& e)
+ {
+ lg2::error(
+ "Parent entity not found in the entityMaps, type: {ENTITY_TYPE}, num: {NUM}, e: {ERROR}",
+ "ENTITY_TYPE", (int)parent.entity_type, "NUM",
+ (int)parent.entity_instance_num, "ERROR", e);
+ found = false;
+ break;
+ }
+
+ node = pldm_entity_association_tree_find_with_locality(
+ entityTree, &parent, false);
+ }
+
+ if (!found)
+ {
+ continue;
+ }
+
+ while (!paths.empty())
+ {
+ path = path / fs::path{paths.back()};
+ paths.pop_back();
+ }
+
+ addObjectPathEntityAssociations(entityAssoc, entity, path, objPathMap);
+ }
+}
+} // namespace utils
+} // namespace hostbmc
+} // namespace pldm
diff --git a/host-bmc/utils.hpp b/host-bmc/utils.hpp
new file mode 100644
index 0000000..857d6c7
--- /dev/null
+++ b/host-bmc/utils.hpp
@@ -0,0 +1,57 @@
+#include "libpldm/pdr.h"
+
+#include "libpldmresponder/oem_handler.hpp"
+
+#include <nlohmann/json.hpp>
+#include <phosphor-logging/lg2.hpp>
+
+#include <filesystem>
+#include <fstream>
+#include <map>
+#include <string>
+#include <vector>
+
+PHOSPHOR_LOG2_USING;
+namespace pldm
+{
+using EntityName = std::string;
+using EntityType = uint16_t;
+
+using Entities = std::vector<pldm_entity_node*>;
+using EntityAssociations = std::vector<Entities>;
+using ObjectPathMaps = std::map<fs::path, pldm_entity_node*>;
+namespace hostbmc
+{
+namespace utils
+{
+
+const std::map<EntityType, EntityName> entityMaps = {
+ {PLDM_ENTITY_SYSTEM_CHASSIS, "chassis"},
+ {PLDM_ENTITY_BOARD, "io_board"},
+ {PLDM_ENTITY_SYS_BOARD, "motherboard"},
+ {PLDM_ENTITY_POWER_SUPPLY, "powersupply"},
+ {PLDM_ENTITY_PROC, "cpu"},
+ {PLDM_ENTITY_SYSTEM_CHASSIS | 0x8000, "system"},
+ {PLDM_ENTITY_PROC_MODULE, "dcm"},
+ {PLDM_ENTITY_PROC | 0x8000, "core"},
+ {PLDM_ENTITY_IO_MODULE, "io_module"},
+ {PLDM_ENTITY_FAN, "fan"},
+ {PLDM_ENTITY_SYS_MGMT_MODULE, "system_management_module"},
+ {PLDM_ENTITY_POWER_CONVERTER, "power_converter"},
+ {PLDM_ENTITY_SLOT, "slot"},
+ {PLDM_ENTITY_CONNECTOR, "connector"}};
+
+/** @brief Vector a entity name to pldm_entity from entity association tree
+ * @param[in] entityAssoc - Vector of associated pldm entities
+ * @param[in] entityTree - entity association tree
+ * @param[out] objPathMap - maps an object path to pldm_entity from the
+ * BMC's entity association tree
+ * @return
+ */
+void updateEntityAssociation(const EntityAssociations& entityAssoc,
+ pldm_entity_association_tree* entityTree,
+ ObjectPathMaps& objPathMap);
+
+} // namespace utils
+} // namespace hostbmc
+} // namespace pldm