pdr: Introduce remote_container_id and associated APIs
We have a concept of a Primary PDR repository and merging the PDRs from
a remote PLDM endpoint (DSP0248 section 7: PDRs support functions).
The main functions of the PLDM discovery Agent (DSP0248 section 14)
(assuming a PLDM terminus like BMC) is maintaining a primary PDR
repository, adding/deleting/updating the PDRs to form a complete system
model. And to do so this API (pldm_entity_node_get_remote_container_id)
will help us update the container id field of the PDR obtained by the
remote PLDM terminus.
Change-Id: I249e627a1e05ee6d9644f3f93f326e47256d914a
Signed-off-by: Archana Kakani <archana.kakani@ibm.com>
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2abe408..6f66f63 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,6 +21,7 @@
1. Add encode/decode pldmMessagePollEvent data
2. README: Add a section on working with libpldm
+3. pdr: Introduce remote_container_id and associated APIs
### Changed
diff --git a/include/libpldm/pdr.h b/include/libpldm/pdr.h
index 5443fba..6a72028 100644
--- a/include/libpldm/pdr.h
+++ b/include/libpldm/pdr.h
@@ -280,6 +280,15 @@
*/
pldm_entity pldm_entity_extract(pldm_entity_node *node);
+/** @brief Extract remote container id from the pldm_entity_node
+ *
+ * @param[in] entity - pointer to existing entity
+ *
+ * @param[out] cid - remote container id
+ */
+int pldm_entity_node_get_remote_container_id(const pldm_entity_node *entity,
+ uint16_t *cid);
+
/** @brief Destroy entity association tree
*
* @param[in] tree - opaque pointer acting as a handle to the tree
@@ -362,7 +371,6 @@
* @param[in] tree - pointer to entity association tree
* @param[in/out] entity - entity type and instance id set on input, container
* id set on output
- *
* @return pldm_entity_node* pointer to entity if found, NULL otherwise
*/
pldm_entity_node *
diff --git a/src/pdr.c b/src/pdr.c
index 68342ef..ff4fbd1 100644
--- a/src/pdr.c
+++ b/src/pdr.c
@@ -5,6 +5,7 @@
#include <endian.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
typedef struct pldm_pdr_record {
uint32_t record_handle;
@@ -373,6 +374,7 @@
typedef struct pldm_entity_node {
pldm_entity entity;
pldm_entity parent;
+ uint16_t remote_container_id;
pldm_entity_node *first_child;
pldm_entity_node *next_sibling;
uint8_t association_type;
@@ -394,6 +396,18 @@
return node->entity;
}
+LIBPLDM_ABI_TESTING
+int pldm_entity_node_get_remote_container_id(const pldm_entity_node *entity,
+ uint16_t *cid)
+{
+ if (!entity) {
+ return -EINVAL;
+ }
+
+ *cid = entity->remote_container_id;
+ return 0;
+}
+
LIBPLDM_ABI_STABLE
pldm_entity_association_tree *pldm_entity_association_tree_init(void)
{
@@ -458,12 +472,14 @@
node->entity.entity_instance_num =
entity_instance_number != 0xFFFF ? entity_instance_number : 1;
node->association_type = association_type;
+ node->remote_container_id = 0;
if (tree->root == NULL) {
assert(parent == NULL);
tree->root = node;
/* container_id 0 here indicates this is the top-most entry */
node->entity.entity_container_id = 0;
+ node->remote_container_id = node->entity.entity_container_id;
} else if (parent != NULL && parent->first_child == NULL) {
parent->first_child = node;
node->parent = parent->entity;
@@ -487,6 +503,7 @@
node->next_sibling = next;
node->entity.entity_container_id =
prev->entity.entity_container_id;
+ node->remote_container_id = entity->entity_container_id;
}
entity->entity_instance_num = node->entity.entity_instance_num;
entity->entity_container_id = node->entity.entity_container_id;
@@ -776,13 +793,21 @@
void find_entity_ref_in_tree(pldm_entity_node *tree_node, pldm_entity entity,
pldm_entity_node **node)
{
+ bool is_entity_container_id;
+ bool is_entity_instance_num;
+ bool is_type;
+
if (tree_node == NULL) {
return;
}
- if (tree_node->entity.entity_type == entity.entity_type &&
- tree_node->entity.entity_instance_num ==
- entity.entity_instance_num) {
+ is_type = tree_node->entity.entity_type == entity.entity_type;
+ is_entity_instance_num = tree_node->entity.entity_instance_num ==
+ entity.entity_instance_num;
+ is_entity_container_id = tree_node->entity.entity_container_id ==
+ entity.entity_container_id;
+
+ if (is_type && is_entity_instance_num && is_entity_container_id) {
*node = tree_node;
return;
}
@@ -910,7 +935,6 @@
*out = node;
return;
}
-
entity_association_tree_find(node->next_sibling, entity, out);
entity_association_tree_find(node->first_child, entity, out);
}
@@ -937,6 +961,7 @@
(*new_node)->parent = org_node->parent;
(*new_node)->entity = org_node->entity;
(*new_node)->association_type = org_node->association_type;
+ (*new_node)->remote_container_id = org_node->remote_container_id;
(*new_node)->first_child = NULL;
(*new_node)->next_sibling = NULL;
entity_association_tree_copy(org_node->first_child,