libpldm: Add API to find an attribute value entry
Add an API to find an attribute value entry by handle
and a pair of APIs to get the length and address of
the value field from the entry
Signed-off-by: John Wang <wangzqbj@inspur.com>
Change-Id: I955e3c1faa91abb951d823386e3360c6f6278cd3
diff --git a/libpldm/bios_table.c b/libpldm/bios_table.c
index 1b98c1d..6430923 100644
--- a/libpldm/bios_table.c
+++ b/libpldm/bios_table.c
@@ -699,6 +699,30 @@
return entry_length->entry_length_handler(entry);
}
+uint16_t pldm_bios_table_attr_value_entry_decode_handle(
+ const struct pldm_bios_attr_val_table_entry *entry)
+{
+ return le16toh(entry->attr_handle);
+}
+
+size_t pldm_bios_table_attr_value_entry_value_length(
+ const struct pldm_bios_attr_val_table_entry *entry)
+{
+ size_t entry_length = attr_value_table_entry_length(entry);
+ size_t header_length =
+ MEMBER_SIZE(pldm_bios_attr_val_table_entry, attr_handle) +
+ MEMBER_SIZE(pldm_bios_attr_val_table_entry, attr_type);
+ assert(entry_length > header_length);
+
+ return (entry_length - header_length);
+}
+
+const uint8_t *pldm_bios_table_attr_value_entry_value(
+ const struct pldm_bios_attr_val_table_entry *entry)
+{
+ return entry->value;
+}
+
static size_t pad_size_get(size_t size_without_pad)
{
return ((size_without_pad % 4) ? (4 - size_without_pad % 4) : 0);
@@ -801,9 +825,11 @@
return iter->table_data + iter->current_pos;
}
+typedef bool (*equal_handler)(const void *entry, const void *key);
+
static const void *
-pldm_bios_table_entry_find(struct pldm_bios_table_iter *iter, const void *key,
- int (*equal)(const void *entry, const void *key))
+pldm_bios_table_entry_find_by_iter(struct pldm_bios_table_iter *iter,
+ const void *key, equal_handler equal)
{
const void *entry;
while (!pldm_bios_table_iter_is_end(iter)) {
@@ -815,7 +841,20 @@
return NULL;
}
-static int string_table_handle_equal(const void *entry, const void *key)
+static const void *
+pldm_bios_table_entry_find_from_table(const void *table, size_t length,
+ enum pldm_bios_table_types type,
+ equal_handler equal, const void *key)
+{
+ struct pldm_bios_table_iter *iter =
+ pldm_bios_table_iter_create(table, length, type);
+ const void *entry =
+ pldm_bios_table_entry_find_by_iter(iter, key, equal);
+ pldm_bios_table_iter_free(iter);
+ return entry;
+}
+
+static bool string_table_handle_equal(const void *entry, const void *key)
{
const struct pldm_bios_string_table_entry *string_entry = entry;
uint16_t handle = *(uint16_t *)key;
@@ -824,12 +863,21 @@
return false;
}
+const struct pldm_bios_string_table_entry *
+pldm_bios_table_string_find_by_handle(const void *table, size_t length,
+ uint16_t handle)
+{
+ return pldm_bios_table_entry_find_from_table(
+ table, length, PLDM_BIOS_STRING_TABLE, string_table_handle_equal,
+ &handle);
+}
+
struct string_equal_arg {
uint16_t str_length;
const char *str;
};
-static int string_table_string_equal(const void *entry, const void *key)
+static bool string_table_string_equal(const void *entry, const void *key)
{
const struct pldm_bios_string_table_entry *string_entry = entry;
const struct string_equal_arg *arg = key;
@@ -847,22 +895,22 @@
{
uint16_t str_length = strlen(str);
struct string_equal_arg arg = {str_length, str};
- struct pldm_bios_table_iter *iter =
- pldm_bios_table_iter_create(table, length, PLDM_BIOS_STRING_TABLE);
- const void *entry =
- pldm_bios_table_entry_find(iter, &arg, string_table_string_equal);
- pldm_bios_table_iter_free(iter);
- return entry;
+ return pldm_bios_table_entry_find_from_table(
+ table, length, PLDM_BIOS_STRING_TABLE, string_table_string_equal,
+ &arg);
}
-const struct pldm_bios_string_table_entry *
-pldm_bios_table_string_find_by_handle(const void *table, size_t length,
- uint16_t handle)
+static bool attr_value_table_handle_equal(const void *entry, const void *key)
{
- struct pldm_bios_table_iter *iter =
- pldm_bios_table_iter_create(table, length, PLDM_BIOS_STRING_TABLE);
- const void *entry = pldm_bios_table_entry_find(
- iter, &handle, string_table_handle_equal);
- pldm_bios_table_iter_free(iter);
- return entry;
+ uint16_t handle = *(uint16_t *)key;
+ return pldm_bios_table_attr_value_entry_decode_handle(entry) == handle;
+}
+
+const struct pldm_bios_attr_val_table_entry *
+pldm_bios_table_attr_value_find_by_handle(const void *table, size_t length,
+ uint16_t handle)
+{
+ return pldm_bios_table_entry_find_from_table(
+ table, length, PLDM_BIOS_ATTR_VAL_TABLE,
+ attr_value_table_handle_equal, &handle);
}
diff --git a/libpldm/bios_table.h b/libpldm/bios_table.h
index 0327c59..b1a7f51 100644
--- a/libpldm/bios_table.h
+++ b/libpldm/bios_table.h
@@ -517,6 +517,38 @@
uint8_t attr_type,
uint64_t cv);
+/** @brief Get the handle from the attribute value entry
+ * @param[in] entry - Pointer to bios attribute value entry
+ * @return handle to identify the attribute in the attribute value table
+ */
+uint16_t pldm_bios_table_attr_value_entry_decode_handle(
+ const struct pldm_bios_attr_val_table_entry *entry);
+
+/** @brief Get the value field length from the attribute value entry
+ * @param[in] entry - Pointer to bios attribute value entry
+ * @return Length of the value filed
+ */
+size_t pldm_bios_table_attr_value_entry_value_length(
+ const struct pldm_bios_attr_val_table_entry *entry);
+
+/** @brief Get the value field address from the attribute value entry
+ * @param[in] entry - Pointer to bios attribute value entry
+ * @return Pointer to the value field in the attribute value entry;
+ */
+const uint8_t *pldm_bios_table_attr_value_entry_value(
+ const struct pldm_bios_attr_val_table_entry *entry);
+
+/** @brief Find an entry in attribute value table by handle
+ * @param[in] table - The BIOS Attribute Value Table
+ * @param[in] length - Length of the BIOS Attribute Value Table
+ * @param[in] handle - handle to identify the attribute in the attribute value
+ * table
+ * @return Pointer to the entry
+ */
+const struct pldm_bios_attr_val_table_entry *
+pldm_bios_table_attr_value_find_by_handle(const void *table, size_t length,
+ uint16_t handle);
+
/** @brief Get the size of pad and checksum
* @param[in] size_without_pad - Table size without pad
* @return The size of pad and checksum
diff --git a/test/libpldm_bios_table_test.cpp b/test/libpldm_bios_table_test.cpp
index b5459c5..b573821 100644
--- a/test/libpldm_bios_table_test.cpp
+++ b/test/libpldm_bios_table_test.cpp
@@ -518,6 +518,14 @@
stringEntry.data());
auto length = pldm_bios_table_attr_value_entry_string_decode_length(entry);
EXPECT_EQ(3, length);
+
+ auto handle = pldm_bios_table_attr_value_entry_decode_handle(entry);
+ EXPECT_EQ(0, handle);
+
+ auto valueLength = pldm_bios_table_attr_value_entry_value_length(entry);
+ EXPECT_EQ(5, valueLength);
+ auto value = pldm_bios_table_attr_value_entry_value(entry);
+ EXPECT_EQ(0, std::memcmp(value, stringEntry.data() + 3, valueLength));
}
TEST(AttrValTable, integerEntryEncodeTest)
@@ -618,6 +626,49 @@
pldm_bios_table_iter_free(iter);
}
+TEST(AttrValTable, FindTest)
+{
+ std::vector<uint8_t> enumEntry{
+ 0, 0, /* attr handle */
+ 0, /* attr type */
+ 2, /* number of current value */
+ 0, /* current value string handle index */
+ 1, /* current value string handle index */
+ };
+ std::vector<uint8_t> stringEntry{
+ 1, 0, /* attr handle */
+ 1, /* attr type */
+ 3, 0, /* current string length */
+ 'a', 'b', 'c', /* defaut value string handle index */
+ };
+ std::vector<uint8_t> integerEntry{
+ 2, 0, /* attr handle */
+ 3, /* attr type */
+ 10, 0, 0, 0, 0, 0, 0, 0, /* current value */
+ };
+
+ Table table;
+ buildTable(table, enumEntry, stringEntry, integerEntry);
+
+ auto entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
+ table.size(), 1);
+ EXPECT_NE(entry, nullptr);
+ auto p = reinterpret_cast<const uint8_t*>(entry);
+ EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()),
+ ElementsAreArray(stringEntry));
+
+ entry = pldm_bios_table_attr_value_find_by_handle(table.data(),
+ table.size(), 3);
+ EXPECT_EQ(entry, nullptr);
+
+ auto firstEntry =
+ reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(table.data());
+ firstEntry->attr_type = PLDM_BIOS_PASSWORD;
+ EXPECT_DEATH(pldm_bios_table_attr_value_find_by_handle(table.data(),
+ table.size(), 1),
+ "entry_length != NULL");
+}
+
TEST(StringTable, EntryEncodeTest)
{
std::vector<uint8_t> stringEntry{