GetBIOSTable responder implementation
This commit implements the GetBIOSTable responder handler
for the BIOS Enumeration type.
One of the tables among String table, Attribute table and Attribute
Value Table are created/fetched and sent to PLDM requester as response to
the command.
Tested:
Following are the tables constructed from the sample json file present at
"test/bios_jsons/enum_attrs.json"
-bash-4.2$ hexdump -C /tmp/AllBiosTables/stringTable
00000000 00 00 07 00 41 6c 6c 6f 77 65 64 01 00 10 00 43 |....Allowed....C|
00000010 6f 64 65 55 70 64 61 74 65 50 6f 6c 69 63 79 02 |odeUpdatePolicy.|
00000020 00 0a 00 43 6f 6e 63 75 72 72 65 6e 74 03 00 0a |...Concurrent...|
00000030 00 44 69 73 72 75 70 74 69 76 65 04 00 0a 00 46 |.Disruptive....F|
00000040 57 42 6f 6f 74 53 69 64 65 05 00 0f 00 48 4d 43 |WBootSide....HMC|
00000050 4d 61 6e 61 67 65 64 53 74 61 74 65 06 00 10 00 |ManagedState....|
00000060 49 6e 62 61 6e 64 43 6f 64 65 55 70 64 61 74 65 |InbandCodeUpdate|
00000070 07 00 0a 00 4e 6f 74 41 6c 6c 6f 77 65 64 08 00 |....NotAllowed..|
00000080 03 00 4f 66 66 09 00 02 00 4f 6e 0a 00 04 00 50 |..Off....On....P|
00000090 65 72 6d 0b 00 04 00 54 65 6d 70 00 37 90 c0 da |erm....Temp.7...|
000000a0
-bash-4.2$ hexdump -C /tmp/AllBiosTables/attributeTable
00000000 00 00 00 01 00 02 02 00 03 00 01 00 01 00 00 04 |................|
00000010 00 02 0a 00 0b 00 01 00 02 00 00 05 00 02 08 00 |................|
00000020 09 00 01 01 03 00 00 06 00 02 00 00 07 00 01 00 |................|
00000030 3b 85 69 a7 |;.i.|
00000034
-bash-4.2$ hexdump -C /tmp/AllBiosTables/attributeValueTable
00000000 00 00 00 01 00 00 00 00 d9 f6 42 58 |..........BX|
0000000c
Change-Id: I06aebcc2c2deea66e867fb775afa76a1e5d18dca
Signed-off-by: Sampa Misra <sampmisr@in.ibm.com>
diff --git a/test/Makefile.am b/test/Makefile.am
index cc0d6c2..4b0acca 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -72,16 +72,21 @@
libpldmresponder_bios_test_CXXFLAGS = $(test_cxxflags)
libpldmresponder_bios_test_LDFLAGS = \
$(test_ldflags) \
- $(SDBUSPLUS_LIBS)
+ $(SDBUSPLUS_LIBS) \
+ -lstdc++fs
libpldmresponder_bios_test_LDADD = \
$(top_builddir)/pldmd-registration.o \
$(top_builddir)/libpldmresponder/libpldmresponder_la-bios.o \
- $(top_builddir)/libpldmresponder/libpldmresponder_la-bios_parser.o \
$(top_builddir)/libpldmresponder/libpldmresponder_la-utils.o \
+ $(top_builddir)/libpldmresponder/libpldmresponder_la-bios_table.o \
$(top_builddir)/libpldm/libpldm_la-base.o \
$(top_builddir)/libpldm/libpldm_la-bios.o \
+ $(top_builddir)/libpldmresponder/libpldmresponder_la-bios_parser.o \
$(CODE_COVERAGE_LIBS) \
- $(SDBUSPLUS_LIBS)
+ $(PHOSPHOR_LOGGING_LIBS) \
+ $(PHOSPHOR_DBUS_INTERFACES_LIBS) \
+ $(SDBUSPLUS_LIBS) \
+ -lstdc++fs
libpldmresponder_bios_test_SOURCES = \
libpldmresponder_bios_test.cpp
@@ -112,7 +117,7 @@
libpldmoemresponder_fileio_test_CXXFLAGS = $(test_cxxflags)
libpldmoemresponder_fileio_test_LDFLAGS = $(test_ldflags)
libpldmoemresponder_fileio_test_LDADD = \
- $(top_builddir)/pldmd-registration.o \
+ $(top_builddir)/pldmd-registration.o \
$(top_builddir)/libpldm/libpldm_la-base.o \
$(top_builddir)/oem/ibm/libpldm/libpldm_la-file_io.o \
$(top_builddir)/oem/ibm/libpldmresponder/libpldmresponder_la-file_io.o\
@@ -136,17 +141,20 @@
libpldmresponder_bios_table_test_CPPFLAGS = $(test_cppflags)
libpldmresponder_bios_table_test_CXXFLAGS = $(test_cxxflags)
libpldmresponder_bios_table_test_LDFLAGS = \
- $(test_ldflags) \
- $(SDBUSPLUS_LIBS)
+ $(test_ldflags) \
+ $(SDBUSPLUS_LIBS)
libpldmresponder_bios_table_test_LDADD = \
- $(top_builddir)/libpldmresponder/libpldmresponder_la-bios.o \
- $(top_builddir)/libpldmresponder/libpldmresponder_la-bios_table.o \
- $(top_builddir)/libpldmresponder/libpldmresponder_la-utils.o \
- $(top_builddir)/libpldm/libpldm_la-base.o \
- $(top_builddir)/libpldm/libpldm_la-bios.o \
+ $(top_builddir)/libpldmresponder/libpldmresponder_la-bios.o \
+ $(top_builddir)/libpldmresponder/libpldmresponder_la-bios_table.o \
+ $(top_builddir)/libpldmresponder/libpldmresponder_la-utils.o \
+ $(top_builddir)/libpldm/libpldm_la-base.o \
+ $(top_builddir)/libpldm/libpldm_la-bios.o \
+ $(top_builddir)/libpldmresponder/libpldmresponder_la-bios_parser.o \
$(top_builddir)/pldmd-registration.o \
- $(CODE_COVERAGE_LIBS) \
- $(SDBUSPLUS_LIBS) \
+ $(CODE_COVERAGE_LIBS) \
+ $(SDBUSPLUS_LIBS) \
+ $(PHOSPHOR_LOGGING_LIBS) \
+ $(PHOSPHOR_DBUS_INTERFACES_LIBS) \
-lstdc++fs
libpldmresponder_bios_table_test_SOURCES = \
libpldmresponder_bios_table_test.cpp
diff --git a/test/libpldm_bios_test.cpp b/test/libpldm_bios_test.cpp
index 495a0d2..aff5d6d 100644
--- a/test/libpldm_bios_test.cpp
+++ b/test/libpldm_bios_test.cpp
@@ -112,3 +112,97 @@
ASSERT_EQ(month, retMonth);
ASSERT_EQ(year, retYear);
}
+
+TEST(GetBIOSTable, testGoodEncodeResponse)
+{
+ std::array<uint8_t,
+ sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES + 4>
+ responseMsg{};
+ auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+ uint8_t completionCode = PLDM_SUCCESS;
+ uint32_t nextTransferHandle = 32;
+ uint8_t transferFlag = PLDM_START_AND_END;
+ std::array<uint8_t, 4> tableData{1, 2, 3, 4};
+
+ auto rc = encode_get_bios_table_resp(
+ 0, PLDM_SUCCESS, nextTransferHandle, transferFlag, tableData.data(),
+ sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES + 4,
+ response);
+ ASSERT_EQ(rc, PLDM_SUCCESS);
+
+ struct pldm_get_bios_table_resp* resp =
+ reinterpret_cast<struct pldm_get_bios_table_resp*>(response->payload);
+
+ ASSERT_EQ(completionCode, resp->completion_code);
+ ASSERT_EQ(nextTransferHandle, resp->next_transfer_handle);
+ ASSERT_EQ(transferFlag, resp->transfer_flag);
+ ASSERT_EQ(0, memcmp(tableData.data(), resp->table_data, tableData.size()));
+}
+
+TEST(GetBIOSTable, testBadEncodeResponse)
+{
+ uint32_t nextTransferHandle = 32;
+ uint8_t transferFlag = PLDM_START_AND_END;
+ std::array<uint8_t, 4> tableData{1, 2, 3, 4};
+
+ auto rc = encode_get_bios_table_resp(
+ 0, PLDM_SUCCESS, nextTransferHandle, transferFlag, tableData.data(),
+ sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES + 4, nullptr);
+ ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(GetBIOSTable, testGoodDecodeRequest)
+{
+ const auto hdr_size = sizeof(pldm_msg_hdr);
+ std::array<uint8_t, hdr_size + PLDM_GET_BIOS_TABLE_REQ_BYTES> requestMsg{};
+ uint32_t transferHandle = 31;
+ uint8_t transferOpFlag = PLDM_GET_FIRSTPART;
+ uint8_t tableType = PLDM_BIOS_ATTR_TABLE;
+ uint32_t retTransferHandle = 0;
+ uint8_t retTransferOpFlag = 0;
+ uint8_t retTableType = 0;
+
+ auto req = reinterpret_cast<pldm_msg*>(requestMsg.data());
+ struct pldm_get_bios_table_req* request =
+ reinterpret_cast<struct pldm_get_bios_table_req*>(req->payload);
+
+ request->transfer_handle = transferHandle;
+ request->transfer_op_flag = transferOpFlag;
+ request->table_type = tableType;
+
+ auto rc = decode_get_bios_table_req(req, requestMsg.size() - hdr_size,
+ &retTransferHandle, &retTransferOpFlag,
+ &retTableType);
+
+ ASSERT_EQ(rc, PLDM_SUCCESS);
+ ASSERT_EQ(transferHandle, retTransferHandle);
+ ASSERT_EQ(transferOpFlag, retTransferOpFlag);
+ ASSERT_EQ(tableType, retTableType);
+}
+
+TEST(GetBIOSTable, testBadDecodeRequest)
+{
+ const auto hdr_size = sizeof(pldm_msg_hdr);
+ std::array<uint8_t, hdr_size + PLDM_GET_BIOS_TABLE_REQ_BYTES> requestMsg{};
+ uint32_t transferHandle = 31;
+ uint8_t transferOpFlag = PLDM_GET_FIRSTPART;
+ uint8_t tableType = PLDM_BIOS_ATTR_TABLE;
+ uint32_t retTransferHandle = 0;
+ uint8_t retTransferOpFlag = 0;
+ uint8_t retTableType = 0;
+
+ auto req = reinterpret_cast<pldm_msg*>(requestMsg.data());
+ struct pldm_get_bios_table_req* request =
+ reinterpret_cast<struct pldm_get_bios_table_req*>(req->payload);
+
+ request->transfer_handle = transferHandle;
+ request->transfer_op_flag = transferOpFlag;
+ request->table_type = tableType;
+
+ auto rc = decode_get_bios_table_req(req, requestMsg.size() - hdr_size - 3,
+ &retTransferHandle, &retTransferOpFlag,
+ &retTableType);
+
+ ASSERT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}
diff --git a/test/libpldmresponder_bios_test.cpp b/test/libpldmresponder_bios_test.cpp
index 6e404de..b5b207b 100644
--- a/test/libpldmresponder_bios_test.cpp
+++ b/test/libpldmresponder_bios_test.cpp
@@ -1,18 +1,24 @@
#include "libpldmresponder/bios.hpp"
#include "libpldmresponder/bios_parser.hpp"
+#include "libpldmresponder/bios_table.hpp"
#include <string.h>
#include <array>
#include <ctime>
+#include <filesystem>
#include "libpldm/base.h"
#include "libpldm/bios.h"
#include <gtest/gtest.h>
+using namespace pldm;
using namespace pldm::responder;
+using namespace pldm::responder::bios;
using namespace pldm::responder::utils;
+using namespace bios_parser;
+using namespace bios_parser::bios_enum;
TEST(epochToBCDTime, testTime)
{
@@ -67,15 +73,6 @@
TEST(getAttrValue, allScenarios)
{
using namespace bios_parser::bios_enum;
-
- // Invalid directory
- auto rc = setupValueLookup("./bios_json");
- ASSERT_EQ(rc, -1);
-
- // Initializes the lookup data structures
- rc = setupValueLookup("./bios_jsons");
- ASSERT_EQ(rc, 0);
-
// All the BIOS Strings in the BIOS JSON config files.
AttrValuesMap valueMap{
{"HMCManagedState", {false, {"On", "Off"}, {"On"}}},
@@ -84,6 +81,9 @@
{"CodeUpdatePolicy",
{false, {"Concurrent", "Disruptive"}, {"Concurrent"}}}};
+ auto rc = setupValueLookup("./bios_jsons");
+ ASSERT_EQ(rc, 0);
+
auto values = getValues();
ASSERT_EQ(valueMap == values, true);
@@ -94,3 +94,291 @@
// Invalid attribute name
ASSERT_THROW(getAttrValue("CodeUpdatePolic"), std::out_of_range);
}
+
+namespace fs = std::filesystem;
+class TestAllBIOSTables : public ::testing::Test
+{
+ public:
+ static void SetUpTestCase() // will execute once at the begining of all
+ // TestAllBIOSTables objects
+ {
+ char tmpdir[] = "/tmp/allBiosTables.XXXXXX";
+ biosPath = fs::path(mkdtemp(tmpdir));
+ }
+
+ static void TearDownTestCase() // will be executed once at th eend of all
+ // TestAllBIOSTables objects
+ {
+ fs::remove_all(biosPath);
+ }
+
+ static fs::path biosPath;
+};
+
+fs::path TestAllBIOSTables::biosPath;
+
+TEST_F(TestAllBIOSTables, GetBIOSTableTestBadRequest)
+{
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
+ requestPayload{};
+ auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+ struct pldm_get_bios_table_req* req =
+ (struct pldm_get_bios_table_req*)request->payload;
+ req->transfer_handle = 9;
+ req->transfer_op_flag = PLDM_GET_FIRSTPART;
+ req->table_type = 0xFF;
+
+ size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
+
+ auto response = internal::buildBIOSTables(request, requestPayloadLength,
+ "./bios_jsons", biosPath.c_str());
+ auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+
+ struct pldm_get_bios_table_resp* resp =
+ reinterpret_cast<struct pldm_get_bios_table_resp*>(
+ responsePtr->payload);
+
+ ASSERT_EQ(PLDM_INVALID_BIOS_TABLE_TYPE, resp->completion_code);
+}
+
+TEST_F(TestAllBIOSTables, buildBIOSTablesTestBadRequest)
+{
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
+ requestPayload{};
+ auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+ struct pldm_get_bios_table_req* req =
+ (struct pldm_get_bios_table_req*)request->payload;
+ req->transfer_handle = 9;
+ req->transfer_op_flag = PLDM_GET_FIRSTPART;
+ req->table_type = PLDM_BIOS_ATTR_VAL_TABLE;
+
+ size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
+
+ auto response = internal::buildBIOSTables(request, requestPayloadLength,
+ "./bios_jsons", biosPath.c_str());
+ auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+ struct pldm_get_bios_table_resp* resp =
+ reinterpret_cast<struct pldm_get_bios_table_resp*>(
+ responsePtr->payload);
+ ASSERT_EQ(PLDM_BIOS_TABLE_UNAVAILABLE, resp->completion_code);
+
+ req->table_type = PLDM_BIOS_ATTR_TABLE;
+ response = internal::buildBIOSTables(request, requestPayloadLength,
+ "./bios_jsons", biosPath.c_str());
+ responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+ resp = reinterpret_cast<struct pldm_get_bios_table_resp*>(
+ responsePtr->payload);
+ ASSERT_EQ(PLDM_BIOS_TABLE_UNAVAILABLE, resp->completion_code);
+}
+
+TEST_F(TestAllBIOSTables, GetBIOSStringTableTestGoodRequest)
+{
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
+ requestPayload{};
+ auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+ struct pldm_get_bios_table_req* req =
+ (struct pldm_get_bios_table_req*)request->payload;
+ req->transfer_handle = 9;
+ req->transfer_op_flag = PLDM_GET_FIRSTPART;
+ req->table_type = PLDM_BIOS_STRING_TABLE;
+
+ Strings biosStrings = getStrings("./bios_jsons");
+ std::sort(biosStrings.begin(), biosStrings.end());
+ biosStrings.erase(std::unique(biosStrings.begin(), biosStrings.end()),
+ biosStrings.end());
+
+ size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
+ uint8_t times = 0;
+ while (times < 2)
+ { // first time fresh table second time existing table
+ auto response = internal::buildBIOSTables(
+ request, requestPayloadLength, "./bios_jsons", biosPath.c_str());
+ auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+
+ struct pldm_get_bios_table_resp* resp =
+ reinterpret_cast<struct pldm_get_bios_table_resp*>(
+ responsePtr->payload);
+
+ ASSERT_EQ(0, resp->completion_code);
+ ASSERT_EQ(0, resp->next_transfer_handle);
+ ASSERT_EQ(PLDM_START_AND_END, resp->transfer_flag);
+
+ uint16_t strLen = 0;
+ uint8_t* tableData = reinterpret_cast<uint8_t*>(resp->table_data);
+
+ for (auto elem : biosStrings)
+ {
+ struct pldm_bios_string_table_entry* ptr =
+ reinterpret_cast<struct pldm_bios_string_table_entry*>(
+ tableData);
+ strLen = ptr->string_length;
+ ASSERT_EQ(strLen, elem.size());
+ ASSERT_EQ(0, memcmp(elem.c_str(), ptr->name, strLen));
+ tableData += (sizeof(pldm_bios_string_table_entry) - 1) + strLen;
+
+ } // end for
+ times++;
+ }
+}
+
+TEST_F(TestAllBIOSTables, getBIOSAttributeTableTestGoodRequest)
+{
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
+ requestPayload{};
+ auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+ struct pldm_get_bios_table_req* req =
+ (struct pldm_get_bios_table_req*)request->payload;
+ req->transfer_handle = 9;
+ req->transfer_op_flag = PLDM_GET_FIRSTPART;
+ req->table_type = PLDM_BIOS_ATTR_TABLE;
+
+ size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
+
+ uint8_t times = 0;
+ while (times < 2)
+ { // first time fresh table second time existing table
+ auto response = internal::buildBIOSTables(
+ request, requestPayloadLength, "./bios_jsons", biosPath.c_str());
+ auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+
+ struct pldm_get_bios_table_resp* resp =
+ reinterpret_cast<struct pldm_get_bios_table_resp*>(
+ responsePtr->payload);
+
+ ASSERT_EQ(0, resp->completion_code);
+ ASSERT_EQ(0, resp->next_transfer_handle);
+ ASSERT_EQ(PLDM_START_AND_END, resp->transfer_flag);
+
+ uint32_t attrTableLen =
+ response.size() - sizeof(pldm_msg_hdr) -
+ (sizeof(resp->completion_code) +
+ sizeof(resp->next_transfer_handle) + sizeof(resp->transfer_flag));
+ uint32_t traversed = 0;
+ uint16_t attrHdl = 0;
+ uint16_t stringHdl = 0;
+ uint8_t attrType = 0;
+ uint8_t numPosVals = 0;
+ uint8_t numDefVals = 0;
+ uint8_t defIndex = 0;
+
+ uint8_t* tableData = reinterpret_cast<uint8_t*>(resp->table_data);
+ while (1)
+ {
+ struct pldm_bios_attr_table_entry* ptr =
+ reinterpret_cast<struct pldm_bios_attr_table_entry*>(tableData);
+ attrHdl = ptr->attr_handle;
+ attrType = ptr->attr_type;
+ EXPECT_EQ(0, attrHdl);
+ EXPECT_EQ(PLDM_BIOS_ENUMERATION, attrType);
+ stringHdl = ptr->string_handle;
+ EXPECT_EQ(stringHdl, 1);
+ tableData += sizeof(attrHdl) + sizeof(attrType) + sizeof(stringHdl);
+ numPosVals = *tableData;
+ EXPECT_EQ(numPosVals, 2);
+ traversed += sizeof(attrHdl) + sizeof(attrType) + sizeof(stringHdl);
+ traversed += sizeof(numPosVals);
+ PossibleValuesByHandle possiVals;
+ tableData++;
+ uint16_t* temp = reinterpret_cast<uint16_t*>(tableData);
+ uint32_t i = 0;
+ while (i < numPosVals)
+ {
+ uint16_t val = *temp;
+ possiVals.push_back(val);
+ temp++;
+ i++;
+ }
+ EXPECT_EQ(possiVals.size(), 2);
+ tableData += numPosVals * sizeof(stringHdl);
+ traversed += numPosVals * sizeof(stringHdl);
+ numDefVals = *tableData;
+ EXPECT_EQ(numDefVals, 1);
+ tableData += numDefVals * sizeof(defIndex);
+ traversed += numDefVals + sizeof(numDefVals);
+
+ break; // test for first row only
+
+ if ((attrTableLen - traversed) < 8)
+ {
+ // reached pad
+ break;
+ }
+
+ } // end while
+ times++;
+ }
+
+} // end TEST
+
+TEST_F(TestAllBIOSTables, getBIOSAttributeValueTableTestGoodRequest)
+{
+ std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_BIOS_TABLE_REQ_BYTES>
+ requestPayload{};
+ auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
+ struct pldm_get_bios_table_req* req =
+ (struct pldm_get_bios_table_req*)request->payload;
+ req->transfer_handle = 9;
+ req->transfer_op_flag = PLDM_GET_FIRSTPART;
+ req->table_type = PLDM_BIOS_ATTR_VAL_TABLE;
+
+ std::string attrName("CodeUpdatePolicy");
+ CurrentValues currVals = getAttrValue(attrName);
+
+ size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
+
+ uint8_t times = 0;
+ while (times < 2)
+ { // first time frest table second time existing table
+ auto response = internal::buildBIOSTables(
+ request, requestPayloadLength, "./bios_jsons", biosPath.c_str());
+ auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+
+ struct pldm_get_bios_table_resp* resp =
+ reinterpret_cast<struct pldm_get_bios_table_resp*>(
+ responsePtr->payload);
+
+ ASSERT_EQ(0, resp->completion_code);
+ ASSERT_EQ(0, resp->next_transfer_handle);
+ ASSERT_EQ(PLDM_START_AND_END, resp->transfer_flag);
+
+ uint32_t attrValTableLen =
+ response.size() - sizeof(pldm_msg_hdr) -
+ (sizeof(resp->completion_code) +
+ sizeof(resp->next_transfer_handle) + sizeof(resp->transfer_flag));
+ uint32_t traversed = 0;
+ uint8_t* tableData = reinterpret_cast<uint8_t*>(resp->table_data);
+
+ uint16_t attrHdl;
+ uint8_t attrType;
+ uint8_t numCurrVals;
+ uint8_t currValStrIndex;
+
+ while (1)
+ {
+ struct pldm_bios_attr_val_table_entry* ptr =
+ reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(
+ tableData);
+ attrHdl = ptr->attr_handle;
+ attrType = ptr->attr_type;
+ EXPECT_EQ(0, attrHdl);
+ EXPECT_EQ(PLDM_BIOS_ENUMERATION, attrType);
+ tableData += sizeof(attrHdl) + sizeof(attrType);
+ traversed += sizeof(attrHdl) + sizeof(attrType);
+ numCurrVals = *tableData;
+ EXPECT_EQ(1, numCurrVals);
+ tableData += sizeof(numCurrVals);
+ traversed += sizeof(numCurrVals);
+ currValStrIndex = *tableData;
+ EXPECT_EQ(0, currValStrIndex);
+ tableData += numCurrVals;
+ traversed += numCurrVals;
+ break; // testing for first row
+ if ((attrValTableLen - traversed) < 8)
+ {
+ break;
+ }
+ }
+ times++;
+ }
+
+} // end TEST