libpldm: fix entity_association_tree_copy method

When we execute the entity_association_tree_copy method and keep the
tree always updated, the parent entity should be updated
synchronously.

Also, add the pldm_entity_is_exist_parent method.

Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: Idf3d9fabb2a623798a47f9cb4189592aa57b2c8c
diff --git a/libpldm/pdr.c b/libpldm/pdr.c
index a9132c7..eeb9805 100644
--- a/libpldm/pdr.c
+++ b/libpldm/pdr.c
@@ -348,7 +348,7 @@
 
 typedef struct pldm_entity_node {
 	pldm_entity entity;
-	pldm_entity_node *parent;
+	pldm_entity parent;
 	pldm_entity_node *first_child;
 	pldm_entity_node *next_sibling;
 	uint8_t association_type;
@@ -422,9 +422,11 @@
 	       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->parent.entity_type = 0;
+	node->parent.entity_instance_num = 0;
+	node->parent.entity_container_id = 0;
 	node->entity.entity_type = entity->entity_type;
 	node->entity.entity_instance_num =
 	    entity_instance_number != 0xFFFF ? entity_instance_number : 1;
@@ -437,7 +439,7 @@
 		node->entity.entity_container_id = 0;
 	} else if (parent != NULL && parent->first_child == NULL) {
 		parent->first_child = node;
-		node->parent = parent;
+		node->parent = parent->entity;
 		node->entity.entity_container_id = next_container_id(tree);
 	} else {
 		pldm_entity_node *start =
@@ -535,13 +537,26 @@
 	return node->first_child != NULL;
 }
 
-inline pldm_entity_node *pldm_entity_get_parent(pldm_entity_node *node)
+inline pldm_entity pldm_entity_get_parent(pldm_entity_node *node)
 {
 	assert(node != NULL);
 
 	return node->parent;
 }
 
+inline bool pldm_entity_is_exist_parent(pldm_entity_node *node)
+{
+	assert(node != NULL);
+
+	if (node->parent.entity_type == 0 &&
+	    node->parent.entity_instance_num == 0 &&
+	    node->parent.entity_container_id == 0) {
+		return false;
+	}
+
+	return true;
+}
+
 uint8_t pldm_entity_get_num_children(pldm_entity_node *node,
 				     uint8_t association_type)
 {
@@ -821,6 +836,7 @@
 		return;
 	}
 	*new_node = malloc(sizeof(pldm_entity_node));
+	(*new_node)->parent = org_node->parent;
 	(*new_node)->entity = org_node->entity;
 	(*new_node)->association_type = org_node->association_type;
 	(*new_node)->first_child = NULL;
diff --git a/libpldm/pdr.h b/libpldm/pdr.h
index 45ac9a6..9e39da3 100644
--- a/libpldm/pdr.h
+++ b/libpldm/pdr.h
@@ -287,9 +287,17 @@
  *
  *  @param[in] node - opaque pointer acting as a handle to an entity node
  *
- *  @return pldm_entity_node* - opaque pointer to parent entity
+ *  @return pldm_entity - pldm entity
  */
-pldm_entity_node *pldm_entity_get_parent(pldm_entity_node *node);
+pldm_entity pldm_entity_get_parent(pldm_entity_node *node);
+
+/** @brief Check the current pldm entity is exist parent
+ *
+ *  @param[in] node - opaque pointer acting as a handle to an entity node
+ *
+ *  @return bool true if exist parent, false otherwise
+ */
+bool pldm_entity_is_exist_parent(pldm_entity_node *node);
 
 /** @brief Convert entity association tree to PDR
  *
diff --git a/libpldm/tests/libpldm_pdr_test.cpp b/libpldm/tests/libpldm_pdr_test.cpp
index 30bd760..d908345 100644
--- a/libpldm/tests/libpldm_pdr_test.cpp
+++ b/libpldm/tests/libpldm_pdr_test.cpp
@@ -570,19 +570,55 @@
     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_is_exist_parent(l1), false);
 
-    EXPECT_EQ(pldm_entity_get_parent(l2a), l1);
-    EXPECT_EQ(pldm_entity_get_parent(l2b), l1);
-    EXPECT_EQ(pldm_entity_get_parent(l2c), l1);
+    pldm_entity nodeL1 = pldm_entity_extract(l1);
+    pldm_entity parentL2a = pldm_entity_get_parent(l2a);
+    pldm_entity parentL2b = pldm_entity_get_parent(l2b);
+    pldm_entity parentL2c = pldm_entity_get_parent(l2c);
+    EXPECT_EQ(pldm_entity_is_exist_parent(l2a), true);
+    EXPECT_EQ(pldm_entity_is_exist_parent(l2b), true);
+    EXPECT_EQ(pldm_entity_is_exist_parent(l2c), true);
+    EXPECT_EQ(parentL2a.entity_type, nodeL1.entity_type);
+    EXPECT_EQ(parentL2a.entity_instance_num, nodeL1.entity_instance_num);
+    EXPECT_EQ(parentL2a.entity_container_id, nodeL1.entity_container_id);
+    EXPECT_EQ(parentL2b.entity_type, nodeL1.entity_type);
+    EXPECT_EQ(parentL2b.entity_instance_num, nodeL1.entity_instance_num);
+    EXPECT_EQ(parentL2b.entity_container_id, nodeL1.entity_container_id);
+    EXPECT_EQ(parentL2c.entity_type, nodeL1.entity_type);
+    EXPECT_EQ(parentL2c.entity_instance_num, nodeL1.entity_instance_num);
+    EXPECT_EQ(parentL2c.entity_container_id, nodeL1.entity_container_id);
 
-    EXPECT_EQ(pldm_entity_get_parent(l3a), l2a);
-    EXPECT_EQ(pldm_entity_get_parent(l3b), l2a);
-    EXPECT_EQ(pldm_entity_get_parent(l3c), l2a);
+    pldm_entity nodeL2a = pldm_entity_extract(l2a);
+    pldm_entity parentL3a = pldm_entity_get_parent(l3a);
+    pldm_entity parentL3b = pldm_entity_get_parent(l3b);
+    pldm_entity parentL3c = pldm_entity_get_parent(l3c);
+    EXPECT_EQ(pldm_entity_is_exist_parent(l3a), true);
+    EXPECT_EQ(pldm_entity_is_exist_parent(l3b), true);
+    EXPECT_EQ(pldm_entity_is_exist_parent(l3c), true);
+    EXPECT_EQ(parentL3a.entity_type, nodeL2a.entity_type);
+    EXPECT_EQ(parentL3a.entity_instance_num, nodeL2a.entity_instance_num);
+    EXPECT_EQ(parentL3a.entity_container_id, nodeL2a.entity_container_id);
+    EXPECT_EQ(parentL3b.entity_type, nodeL2a.entity_type);
+    EXPECT_EQ(parentL3b.entity_instance_num, nodeL2a.entity_instance_num);
+    EXPECT_EQ(parentL3b.entity_container_id, nodeL2a.entity_container_id);
+    EXPECT_EQ(parentL3c.entity_type, nodeL2a.entity_type);
+    EXPECT_EQ(parentL3c.entity_instance_num, nodeL2a.entity_instance_num);
+    EXPECT_EQ(parentL3c.entity_container_id, nodeL2a.entity_container_id);
 
-    EXPECT_EQ(pldm_entity_get_parent(l4a), l3a);
+    pldm_entity nodeL3a = pldm_entity_extract(l3a);
+    pldm_entity parentL4a = pldm_entity_get_parent(l4a);
+    EXPECT_EQ(pldm_entity_is_exist_parent(l4a), true);
+    EXPECT_EQ(parentL4a.entity_type, nodeL3a.entity_type);
+    EXPECT_EQ(parentL4a.entity_instance_num, nodeL3a.entity_instance_num);
+    EXPECT_EQ(parentL4a.entity_container_id, nodeL3a.entity_container_id);
 
-    EXPECT_EQ(pldm_entity_get_parent(l4b), l3b);
+    pldm_entity nodeL3b = pldm_entity_extract(l3b);
+    pldm_entity parentL4b = pldm_entity_get_parent(l4b);
+    EXPECT_EQ(pldm_entity_is_exist_parent(l4b), true);
+    EXPECT_EQ(parentL4b.entity_type, nodeL3b.entity_type);
+    EXPECT_EQ(parentL4b.entity_instance_num, nodeL3b.entity_instance_num);
+    EXPECT_EQ(parentL4b.entity_container_id, nodeL3b.entity_container_id);
 
     size_t num{};
     pldm_entity* out = nullptr;