bios: table construct: Add support for integer attribute

Add support for integer attribute to construct attribute
table and attribute value table

Signed-off-by: John Wang <wangzqbj@inspur.com>
Change-Id: I98a027a32d935cef704b3e7052f87c1af57fddf8
diff --git a/libpldmresponder/bios.cpp b/libpldmresponder/bios.cpp
index e0ded59..47bfc0a 100644
--- a/libpldmresponder/bios.cpp
+++ b/libpldmresponder/bios.cpp
@@ -504,6 +504,77 @@
 
 } // end namespace bios_type_string
 
+namespace bios_type_integer
+{
+
+using namespace bios_parser::bios_integer;
+
+/** @brief Construct the attibute table for BIOS type Integer and
+ *         Integer ReadOnly
+ *  @param[in] BIOSStringTable - the string table
+ *  @param[in,out] attributeTable - the attribute table
+ *
+ */
+void constructAttrTable(const BIOSTable& BIOSStringTable, Table& attributeTable)
+{
+    const auto& attributeMap = getValues();
+    StringHandle strHandle;
+    for (const auto& [key, value] : attributeMap)
+    {
+        try
+        {
+            strHandle = findStringHandle(key, BIOSStringTable);
+        }
+        catch (InternalFailure& e)
+        {
+            log<level::ERR>("Could not find handle for BIOS string",
+                            entry("ATTRIBUTE=%s", key.c_str()));
+            continue;
+        }
+
+        const auto& [readOnly, lowerBound, upperBound, scalarIncrement,
+                     defaultValue] = value;
+        auto entryLength = pldm_bios_table_attr_entry_integer_encode_length();
+
+        struct pldm_bios_table_attr_entry_integer_info info = {
+            strHandle,  readOnly,        lowerBound,
+            upperBound, scalarIncrement, defaultValue,
+        };
+        auto attrTableSize = attributeTable.size();
+        attributeTable.resize(attrTableSize + entryLength, 0);
+        pldm_bios_table_attr_entry_integer_encode(
+            attributeTable.data() + attrTableSize, entryLength, &info);
+    }
+}
+
+void constructAttrValueEntry(const pldm_bios_attr_table_entry* attrTableEntry,
+                             const std::string& attrName,
+                             const BIOSTable& BIOSStringTable,
+                             Table& attrValueTable)
+{
+    std::ignore = BIOSStringTable;
+    uint64_t currentValue;
+    try
+    {
+        currentValue = getAttrValue(attrName);
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>("Failed to get attribute value",
+                        entry("NAME=%s", attrName.c_str()),
+                        entry("ERROR=%s", e.what()));
+        return;
+    }
+    auto entryLength = pldm_bios_table_attr_value_entry_encode_integer_length();
+    auto tableSize = attrValueTable.size();
+    attrValueTable.resize(tableSize + entryLength);
+    pldm_bios_table_attr_value_entry_encode_integer(
+        attrValueTable.data() + tableSize, entryLength,
+        attrTableEntry->attr_handle, attrTableEntry->attr_type, currentValue);
+}
+
+} // namespace bios_type_integer
+
 void traverseBIOSAttrTable(const Table& biosAttrTable,
                            AttrTableEntryHandler handler)
 {
@@ -532,7 +603,9 @@
                                        Table& attributeTable)>;
 std::map<BIOSJsonName, typeHandler> attrTypeHandlers{
     {bios_parser::bIOSEnumJson, bios_type_enum::constructAttrTable},
-    {bios_parser::bIOSStrJson, bios_type_string::constructAttrTable}};
+    {bios_parser::bIOSStrJson, bios_type_string::constructAttrTable},
+    {bios_parser::bIOSIntegerJson, bios_type_integer::constructAttrTable},
+};
 
 /** @brief Construct the BIOS attribute table
  *
@@ -612,6 +685,9 @@
         {PLDM_BIOS_ENUMERATION, bios_type_enum::constructAttrValueEntry},
         {PLDM_BIOS_ENUMERATION_READ_ONLY,
          bios_type_enum::constructAttrValueEntry},
+        {PLDM_BIOS_INTEGER, bios_type_integer::constructAttrValueEntry},
+        {PLDM_BIOS_INTEGER_READ_ONLY,
+         bios_type_integer::constructAttrValueEntry},
     };
 
 void constructAttrValueTableEntry(
diff --git a/test/libpldmresponder_bios_test.cpp b/test/libpldmresponder_bios_test.cpp
index 5bfbfb9..7271567 100644
--- a/test/libpldmresponder_bios_test.cpp
+++ b/test/libpldmresponder_bios_test.cpp
@@ -593,3 +593,63 @@
     }
 
 } // end TEST
+
+TEST_F(TestSingleTypeBIOSTable,
+       getBIOSAttributeValueTableBasedOnIntegerTypeTest)
+{
+    // Copy integer json file to the destination
+    TestSingleTypeBIOSTable::CopySingleJsonFile(bios_parser::bIOSIntegerJson);
+    auto fpath = TestSingleTypeBIOSTable::destBiosPath.c_str();
+
+    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;
+
+    // Get string table with integer json file only
+    req->transfer_handle = 9;
+    req->transfer_op_flag = PLDM_GET_FIRSTPART;
+    req->table_type = PLDM_BIOS_STRING_TABLE;
+
+    size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
+    internal::buildBIOSTables(request, requestPayloadLength, fpath, fpath);
+
+    // Get attribute table with integer json file only
+    req->transfer_handle = 9;
+    req->transfer_op_flag = PLDM_GET_FIRSTPART;
+    req->table_type = PLDM_BIOS_ATTR_TABLE;
+
+    auto attr_response =
+        internal::buildBIOSTables(request, requestPayloadLength, fpath, fpath);
+
+    // Get attribute value table with integer type
+    req->transfer_handle = 9;
+    req->transfer_op_flag = PLDM_GET_FIRSTPART;
+    req->table_type = PLDM_BIOS_ATTR_VAL_TABLE;
+
+    // Test attribute SBE_IMAGE_MINIMUM_VALID_ECS here, which has no dbus
+    for (uint8_t times = 0; times < 2; times++)
+    { // first time first table second time existing table
+        auto response = internal::buildBIOSTables(request, requestPayloadLength,
+                                                  fpath, fpath);
+        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);
+
+        EXPECT_EQ(0, resp->completion_code);
+        EXPECT_EQ(0, resp->next_transfer_handle);
+        EXPECT_EQ(PLDM_START_AND_END, resp->transfer_flag);
+        uint8_t* tableData = reinterpret_cast<uint8_t*>(resp->table_data);
+        auto ptr =
+            reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(tableData);
+        uint16_t attrHdl = ptr->attr_handle;
+        uint8_t attrType = ptr->attr_type;
+        EXPECT_EQ(PLDM_BIOS_INTEGER_READ_ONLY, attrType);
+        tableData += sizeof(attrHdl) + sizeof(attrType);
+        auto cv = *(reinterpret_cast<uint64_t*>(tableData));
+        EXPECT_EQ(2, cv);
+    }
+}