pdr: Add pldm_pdr_find_last_in_range()
Adds a new libpldm API to find the last PDR record from the PDR repo
based on the range of record handle values given as input. This API is
used when a record needs to be added in a particular range of record
handles to the repo that contains all PDRs (inclusive of BMC and remote
endpoints).
Change-Id: Ica5187053361b27810577a4985fab4b994d35961
Signed-off-by: Pavithra Barithaya <pavithra.b@ibm.com>
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d76c6a8..9d7a152 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,6 +23,7 @@
2. README: Add a section on working with libpldm
3. pdr: Introduce remote_container_id and associated APIs
4. pdr: Add APIs for creating and locating remote PDRs
+5. pdr: Add pldm_pdr_find_last_in_range()
### Changed
diff --git a/include/libpldm/pdr.h b/include/libpldm/pdr.h
index 7542624..dc4928c 100644
--- a/include/libpldm/pdr.h
+++ b/include/libpldm/pdr.h
@@ -167,6 +167,19 @@
void pldm_pdr_update_TL_pdr(const pldm_pdr *repo, uint16_t terminus_handle,
uint8_t tid, uint8_t tl_eid, bool valid);
+/** @brief Find the last record within the particular range
+ * of record handles
+ *
+ * @param[in] repo - pointer acting as a PDR repo handle
+ * @param[in] first - first record handle value of the records in the range
+ * @param[in] last - last record handle value of the records in the range
+ *
+ * @return pointer to the PDR record,will be NULL if record was not
+ * found
+ */
+pldm_pdr_record *pldm_pdr_find_last_in_range(const pldm_pdr *repo,
+ uint32_t first, uint32_t last);
+
/* ======================= */
/* FRU Record Set PDR APIs */
/* ======================= */
diff --git a/src/pdr.c b/src/pdr.c
index 752fd57..8a63e95 100644
--- a/src/pdr.c
+++ b/src/pdr.c
@@ -966,6 +966,28 @@
}
}
+LIBPLDM_ABI_TESTING
+pldm_pdr_record *pldm_pdr_find_last_in_range(const pldm_pdr *repo,
+ uint32_t first, uint32_t last)
+{
+ pldm_pdr_record *record = NULL;
+ pldm_pdr_record *curr;
+
+ if (!repo) {
+ return NULL;
+ }
+ for (curr = repo->first; curr; curr = curr->next) {
+ if (first > curr->record_handle || last < curr->record_handle) {
+ continue;
+ }
+ if (!record || curr->record_handle > record->record_handle) {
+ record = curr;
+ }
+ }
+
+ return record;
+}
+
static void entity_association_tree_find_if_remote(pldm_entity_node *node,
pldm_entity *entity,
pldm_entity_node **out,
diff --git a/tests/libpldm_pdr_test.cpp b/tests/libpldm_pdr_test.cpp
index 72860d7..f29fb97 100644
--- a/tests/libpldm_pdr_test.cpp
+++ b/tests/libpldm_pdr_test.cpp
@@ -547,6 +547,34 @@
pldm_pdr_destroy(repo);
}
+#ifdef LIBPLDM_API_TESTING
+TEST(PDRUpdate, testFindLastInRange)
+{
+ auto repo = pldm_pdr_init();
+
+ std::array<uint8_t, 10> data{};
+ auto handle1 = pldm_pdr_add(repo, data.data(), data.size(), 0, false, 1);
+ auto handle2 = pldm_pdr_add(repo, data.data(), data.size(), 23, false, 1);
+ auto handle3 = pldm_pdr_add(repo, data.data(), data.size(), 77, false, 1);
+ auto handle4 =
+ pldm_pdr_add(repo, data.data(), data.size(), 16777325, true, 1);
+ auto handle5 =
+ pldm_pdr_add(repo, data.data(), data.size(), 16777344, true, 1);
+
+ auto rec1 = pldm_pdr_find_last_in_range(repo, 0, 100);
+ auto rec2 = pldm_pdr_find_last_in_range(repo, 16777300, 33554431);
+ EXPECT_NE(rec1, nullptr);
+ EXPECT_NE(rec2, nullptr);
+ EXPECT_NE(handle1, pldm_pdr_get_record_handle(repo, rec1));
+ EXPECT_NE(handle2, pldm_pdr_get_record_handle(repo, rec1));
+ EXPECT_EQ(handle3, pldm_pdr_get_record_handle(repo, rec1));
+ EXPECT_NE(handle4, pldm_pdr_get_record_handle(repo, rec2));
+ EXPECT_EQ(handle5, pldm_pdr_get_record_handle(repo, rec2));
+
+ pldm_pdr_destroy(repo);
+}
+#endif
+
TEST(EntityAssociationPDR, testInit)
{
auto tree = pldm_entity_association_tree_init();