libpldm: Add parent to pldm_entity_node structure

Add its own parent entity to the pldm_entity_node structure, and then
use pldm_entity_get_parent to get the entity's parent.

Also, add UTest code for it.

Tested: Built pldm daemon successfully and UTest passes.

Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I067f82ad6d03f3cffd2ca24cd771274777901b61
diff --git a/libpldm/pdr.c b/libpldm/pdr.c
index 92ac843..65a2591 100644
--- a/libpldm/pdr.c
+++ b/libpldm/pdr.c
@@ -320,6 +320,7 @@
 
 typedef struct pldm_entity_node {
 	pldm_entity entity;
+	pldm_entity_node *parent;
 	pldm_entity_node *first_child;
 	pldm_entity_node *next_sibling;
 	uint8_t association_type;
@@ -382,6 +383,7 @@
 	       association_type == PLDM_ENTITY_ASSOCIAION_LOGICAL);
 	pldm_entity_node *node = malloc(sizeof(pldm_entity_node));
 	assert(node != NULL);
+	node->parent = NULL;
 	node->first_child = NULL;
 	node->next_sibling = NULL;
 	node->entity.entity_type = entity->entity_type;
@@ -395,6 +397,7 @@
 		node->entity.entity_container_id = 0;
 	} else if (parent != NULL && parent->first_child == NULL) {
 		parent->first_child = node;
+		node->parent = parent;
 		node->entity.entity_container_id = next_container_id(tree);
 	} else {
 		pldm_entity_node *start =
@@ -409,6 +412,7 @@
 			    prev->entity.entity_instance_num + 1;
 		}
 		prev->next_sibling = node;
+		node->parent = prev->parent;
 		node->next_sibling = next;
 		node->entity.entity_container_id =
 		    prev->entity.entity_container_id;
@@ -489,6 +493,13 @@
 	return node->first_child != NULL;
 }
 
+inline pldm_entity_node *pldm_entity_get_parent(pldm_entity_node *node)
+{
+	assert(node != NULL);
+
+	return node->parent;
+}
+
 uint8_t pldm_entity_get_num_children(pldm_entity_node *node,
 				     uint8_t association_type)
 {
diff --git a/libpldm/pdr.h b/libpldm/pdr.h
index 24137ab..68702f3 100644
--- a/libpldm/pdr.h
+++ b/libpldm/pdr.h
@@ -266,6 +266,14 @@
  */
 bool pldm_entity_is_node_parent(pldm_entity_node *node);
 
+/** @brief Get parent of entity
+ *
+ *  @param[in] node - opaque pointer acting as a handle to an entity node
+ *
+ *  @return pldm_entity_node* - opaque pointer to parent entity
+ */
+pldm_entity_node *pldm_entity_get_parent(pldm_entity_node *node);
+
 /** @brief Convert entity association tree to PDR
  *
  *  @param[in] tree - opaque pointer to entity association tree
diff --git a/libpldm/tests/libpldm_pdr_test.cpp b/libpldm/tests/libpldm_pdr_test.cpp
index 454b072..416764b 100644
--- a/libpldm/tests/libpldm_pdr_test.cpp
+++ b/libpldm/tests/libpldm_pdr_test.cpp
@@ -570,6 +570,20 @@
     EXPECT_EQ(pldm_entity_is_node_parent(l4a), false);
     EXPECT_EQ(pldm_entity_is_node_parent(l4b), false);
 
+    EXPECT_EQ(pldm_entity_get_parent(l1), nullptr);
+
+    EXPECT_EQ(pldm_entity_get_parent(l2a), l1);
+    EXPECT_EQ(pldm_entity_get_parent(l2b), l1);
+    EXPECT_EQ(pldm_entity_get_parent(l2c), l1);
+
+    EXPECT_EQ(pldm_entity_get_parent(l3a), l2a);
+    EXPECT_EQ(pldm_entity_get_parent(l3b), l2a);
+    EXPECT_EQ(pldm_entity_get_parent(l3c), l2a);
+
+    EXPECT_EQ(pldm_entity_get_parent(l4a), l3a);
+
+    EXPECT_EQ(pldm_entity_get_parent(l4b), l3b);
+
     size_t num{};
     pldm_entity* out = nullptr;
     pldm_entity_association_tree_visit(tree, &out, &num);