Add decode_get_bios_table_resp() in PLDM BIOS.

Resolves openbmc/openbmc-test-automation#1973

Signed-off-by: Sridevi Ramesh <sridevra@in.ibm.com>
Change-Id: Ic5d9277f92d0034e4611cf2c7f4c767902c92b89
diff --git a/libpldm/bios.c b/libpldm/bios.c
index d5ba736..1a705ff 100644
--- a/libpldm/bios.c
+++ b/libpldm/bios.c
@@ -285,6 +285,40 @@
 	return PLDM_SUCCESS;
 }
 
+int decode_get_bios_table_resp(const struct pldm_msg *msg,
+			       size_t payload_length, uint8_t *completion_code,
+			       uint32_t *next_transfer_handle,
+			       uint8_t *transfer_flag,
+			       size_t *bios_table_offset)
+
+{
+	if (msg == NULL || transfer_flag == NULL ||
+	    next_transfer_handle == NULL || completion_code == NULL) {
+		return PLDM_ERROR_INVALID_DATA;
+	}
+	if (payload_length <= PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES) {
+		return PLDM_ERROR_INVALID_LENGTH;
+	}
+
+	struct pldm_get_bios_table_resp *response =
+	    (struct pldm_get_bios_table_resp *)msg->payload;
+
+	*completion_code = response->completion_code;
+
+	if (PLDM_SUCCESS != *completion_code) {
+		return PLDM_SUCCESS;
+	}
+
+	*next_transfer_handle = le32toh(response->next_transfer_handle);
+	*transfer_flag = response->transfer_flag;
+
+	*bios_table_offset = sizeof(*completion_code) +
+			     sizeof(*next_transfer_handle) +
+			     sizeof(*transfer_flag);
+
+	return PLDM_SUCCESS;
+}
+
 int decode_get_bios_attribute_current_value_by_handle_req(
     const struct pldm_msg *msg, size_t payload_length,
     uint32_t *transfer_handle, uint8_t *transfer_op_flag,
diff --git a/libpldm/bios.h b/libpldm/bios.h
index d4ec031..8306576 100644
--- a/libpldm/bios.h
+++ b/libpldm/bios.h
@@ -315,6 +315,25 @@
 			      uint32_t *transfer_handle,
 			      uint8_t *transfer_op_flag, uint8_t *table_type);
 
+/** @brief Decode GetBIOSTable response packet
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[in] completion_code - PLDM completion code
+ *  @param[in] next_transfer_handle - handle to identify the next portion of the
+ *                                    transfer
+ *  @param[in] transfer_flag - To indicate what part of the transfer this
+ *                             response represents
+ *  @param[out] bios_table_offset - Offset where bios table data should be read
+ *                                  in pldm msg
+ *  @return pldm_completion_codes
+ */
+int decode_get_bios_table_resp(const struct pldm_msg *msg,
+			       size_t payload_length, uint8_t *completion_code,
+			       uint32_t *next_transfer_handle,
+			       uint8_t *transfer_flag,
+			       size_t *bios_table_offset);
+
 /* GetBIOSAttributeCurrentValueByHandle */
 
 /** @brief Decode GetBIOSAttributeCurrentValueByHandle request packet
diff --git a/test/libpldm_bios_test.cpp b/test/libpldm_bios_test.cpp
index 3e0938f..89d3747 100644
--- a/test/libpldm_bios_test.cpp
+++ b/test/libpldm_bios_test.cpp
@@ -782,3 +782,38 @@
 
     ASSERT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
 }
+
+TEST(GetBIOSTable, testDecodeResponse)
+{
+    uint32_t nextTransferHandle = 32;
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t transfer_flag = PLDM_START_AND_END;
+
+    std::array<uint8_t, hdrSize + PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES>
+        responseMsg{};
+    struct pldm_msg* response =
+        reinterpret_cast<struct pldm_msg*>(responseMsg.data());
+
+    struct pldm_get_bios_table_resp* resp =
+        reinterpret_cast<struct pldm_get_bios_table_resp*>(response->payload);
+
+    resp->completion_code = completionCode;
+    resp->next_transfer_handle = htole32(nextTransferHandle);
+    resp->transfer_flag = transfer_flag;
+    size_t biosTableOffset = sizeof(completionCode) +
+                             sizeof(nextTransferHandle) + sizeof(transfer_flag);
+
+    uint8_t retCompletionCode;
+    uint32_t retNextTransferHandle;
+    uint8_t retransfer_flag;
+    size_t rebiosTableOffset = 0;
+    auto rc = decode_get_bios_table_resp(
+        response, responseMsg.size(), &retCompletionCode,
+        &retNextTransferHandle, &retransfer_flag, &rebiosTableOffset);
+
+    ASSERT_EQ(rc, PLDM_SUCCESS);
+    ASSERT_EQ(completionCode, retCompletionCode);
+    ASSERT_EQ(nextTransferHandle, retNextTransferHandle);
+    ASSERT_EQ(transfer_flag, retransfer_flag);
+    ASSERT_EQ(biosTableOffset, rebiosTableOffset);
+}