Add decode GetPDRRepositoryInfo resp API

Add decode response API for GetPDRRepositoryInfo command(0x50).
DSP0248_1.2.0 Table 67

Signed-off-by: Gilbert Chen <gilbertc@nvidia.com>
Change-Id: I000be34a217499340bee60dc412ccd72530a52db
diff --git a/include/libpldm/platform.h b/include/libpldm/platform.h
index f0eea51..c6f992d 100644
--- a/include/libpldm/platform.h
+++ b/include/libpldm/platform.h
@@ -1202,6 +1202,29 @@
     uint32_t largest_record_size, uint8_t data_transfer_handle_timeout,
     struct pldm_msg *msg);
 
+/** @brief Decode GetPDRRepositoryInfo response data
+ *
+ *  @param[in] msg - Response message
+ *  @param[in] payload_length - Length of response message payload
+ *  @param[out] completion_code - PLDM completion code
+ *  @param[out] repository_state - PLDM repository state
+ *  @param[out] update_time - When the standard PDR repository data was
+ *                           originally created
+ *  @param[out] oem_update_time - when OEM PDRs in the PDR Repository were
+ *                               originally created
+ *  @param[out] record_count - Total number of PDRs in this repository
+ *  @param[out] repository_size - Size of the PDR Repository in bytes
+ *  @param[out] largest_record_size - Size of the largest record in the PDR
+ * Repository in bytes
+ *  @param[out] data_transfer_handle_timeout - Data transmission timeout
+ *  @return pldm_completion_codes
+ */
+int decode_get_pdr_repository_info_resp(
+    const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
+    uint8_t *repository_state, uint8_t *update_time, uint8_t *oem_update_time,
+    uint32_t *record_count, uint32_t *repository_size,
+    uint32_t *largest_record_size, uint8_t *data_transfer_handle_timeout);
+
 /* GetPDR */
 
 /** @brief Create a PLDM request message for GetPDR
diff --git a/src/platform.c b/src/platform.c
index a781f3c..492fe65 100644
--- a/src/platform.c
+++ b/src/platform.c
@@ -360,6 +360,48 @@
 	return PLDM_SUCCESS;
 }
 
+int decode_get_pdr_repository_info_resp(
+    const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
+    uint8_t *repository_state, uint8_t *update_time, uint8_t *oem_update_time,
+    uint32_t *record_count, uint32_t *repository_size,
+    uint32_t *largest_record_size, uint8_t *data_transfer_handle_timeout)
+{
+	if (msg == NULL || completion_code == NULL ||
+	    repository_state == NULL || update_time == NULL ||
+	    oem_update_time == NULL || record_count == NULL ||
+	    repository_size == NULL || largest_record_size == NULL ||
+	    data_transfer_handle_timeout == NULL) {
+		return PLDM_ERROR_INVALID_DATA;
+	}
+
+	*completion_code = msg->payload[0];
+	if (PLDM_SUCCESS != *completion_code) {
+		return PLDM_SUCCESS;
+	}
+
+	if (payload_length < PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES) {
+		return PLDM_ERROR_INVALID_LENGTH;
+	}
+
+	struct pldm_pdr_repository_info_resp *response =
+	    (struct pldm_pdr_repository_info_resp *)msg->payload;
+
+	*repository_state = response->repository_state;
+	if (*repository_state > PLDM_FAILED) {
+		return PLDM_ERROR_INVALID_DATA;
+	}
+
+	memcpy(update_time, response->update_time, PLDM_TIMESTAMP104_SIZE);
+	memcpy(oem_update_time, response->oem_update_time,
+	       PLDM_TIMESTAMP104_SIZE);
+	*record_count = le32toh(response->record_count);
+	*repository_size = le32toh(response->repository_size);
+	*largest_record_size = le32toh(response->largest_record_size);
+	*data_transfer_handle_timeout = response->data_transfer_handle_timeout;
+
+	return PLDM_SUCCESS;
+}
+
 int encode_get_pdr_req(uint8_t instance_id, uint32_t record_hndl,
 		       uint32_t data_transfer_hndl, uint8_t transfer_op_flag,
 		       uint16_t request_cnt, uint16_t record_chg_num,
diff --git a/tests/libpldm_platform_test.cpp b/tests/libpldm_platform_test.cpp
index 9c5e3b0..329f4ff 100644
--- a/tests/libpldm_platform_test.cpp
+++ b/tests/libpldm_platform_test.cpp
@@ -434,6 +434,115 @@
     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
 }
 
+TEST(GetPDRRepositoryInfo, testGoodDecodeResponse)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t repositoryState = PLDM_AVAILABLE;
+    uint8_t updateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint8_t oemUpdateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint32_t recordCount = 100;
+    uint32_t repositorySize = 100;
+    uint32_t largestRecordSize = UINT32_MAX;
+    uint8_t dataTransferHandleTimeout = PLDM_NO_TIMEOUT;
+
+    std::array<uint8_t, hdrSize + PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES>
+        responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_pdr_repository_info_resp* resp =
+        reinterpret_cast<struct pldm_pdr_repository_info_resp*>(
+            response->payload);
+    resp->completion_code = completionCode;
+    resp->repository_state = repositoryState;
+    memcpy(resp->update_time, updateTime, PLDM_TIMESTAMP104_SIZE);
+    memcpy(resp->oem_update_time, oemUpdateTime, PLDM_TIMESTAMP104_SIZE);
+    resp->record_count = htole32(recordCount);
+    resp->repository_size = htole32(repositorySize);
+    resp->largest_record_size = htole32(largestRecordSize);
+    resp->data_transfer_handle_timeout = dataTransferHandleTimeout;
+
+    uint8_t retCompletionCode = 0;
+    uint8_t retRepositoryState = 0;
+    uint8_t retUpdateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint8_t retOemUpdateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint32_t retRecordCount = 0;
+    uint32_t retRepositorySize = 0;
+    uint32_t retLargestRecordSize = 0;
+    uint8_t retDataTransferHandleTimeout = 0;
+
+    auto rc = decode_get_pdr_repository_info_resp(
+        response, responseMsg.size() - hdrSize, &retCompletionCode,
+        &retRepositoryState, retUpdateTime, retOemUpdateTime, &retRecordCount,
+        &retRepositorySize, &retLargestRecordSize,
+        &retDataTransferHandleTimeout);
+
+    EXPECT_EQ(rc, PLDM_SUCCESS);
+    EXPECT_EQ(completionCode, retCompletionCode);
+    EXPECT_EQ(repositoryState, retRepositoryState);
+    EXPECT_EQ(0, memcmp(updateTime, retUpdateTime, PLDM_TIMESTAMP104_SIZE));
+    EXPECT_EQ(0,
+              memcmp(oemUpdateTime, retOemUpdateTime, PLDM_TIMESTAMP104_SIZE));
+    EXPECT_EQ(recordCount, recordCount);
+    EXPECT_EQ(repositorySize, repositorySize);
+    EXPECT_EQ(largestRecordSize, largestRecordSize);
+    EXPECT_EQ(dataTransferHandleTimeout, dataTransferHandleTimeout);
+}
+
+TEST(GetPDRRepositoryInfo, testBadDecodeResponse)
+{
+    uint8_t completionCode = PLDM_SUCCESS;
+    uint8_t repositoryState = PLDM_AVAILABLE;
+    uint8_t updateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint8_t oemUpdateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint32_t recordCount = htole32(100);
+    uint32_t repositorySize = htole32(100);
+    uint32_t largestRecordSize = htole32(UINT32_MAX);
+    uint8_t dataTransferHandleTimeout = PLDM_NO_TIMEOUT;
+
+    std::array<uint8_t, hdrSize + PLDM_GET_PDR_REPOSITORY_INFO_RESP_BYTES>
+        responseMsg{};
+    auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+    struct pldm_pdr_repository_info_resp* resp =
+        reinterpret_cast<struct pldm_pdr_repository_info_resp*>(
+            response->payload);
+    resp->completion_code = completionCode;
+    resp->repository_state = repositoryState;
+    memcpy(resp->update_time, updateTime, PLDM_TIMESTAMP104_SIZE);
+    memcpy(resp->oem_update_time, oemUpdateTime, PLDM_TIMESTAMP104_SIZE);
+    resp->record_count = recordCount;
+    resp->repository_size = repositorySize;
+    resp->largest_record_size = largestRecordSize;
+    resp->data_transfer_handle_timeout = dataTransferHandleTimeout;
+
+    uint8_t retCompletionCode = 0;
+    uint8_t retRepositoryState = 0;
+    uint8_t retUpdateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint8_t retOemUpdateTime[PLDM_TIMESTAMP104_SIZE] = {0};
+    uint32_t retRecordCount = 0;
+    uint32_t retRepositorySize = 0;
+    uint32_t retLargestRecordSize = 0;
+    uint8_t retDataTransferHandleTimeout = 0;
+
+    auto rc = decode_get_pdr_repository_info_resp(
+        response, responseMsg.size() - hdrSize, NULL, NULL, NULL, NULL, NULL,
+        NULL, NULL, NULL);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+    rc = decode_get_pdr_repository_info_resp(
+        response, responseMsg.size() - hdrSize - 1, &retCompletionCode,
+        &retRepositoryState, retUpdateTime, retOemUpdateTime, &retRecordCount,
+        &retRepositorySize, &retLargestRecordSize,
+        &retDataTransferHandleTimeout);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+    resp->repository_state = PLDM_FAILED + 1;
+    rc = decode_get_pdr_repository_info_resp(
+        response, responseMsg.size() - hdrSize, &retCompletionCode,
+        &retRepositoryState, retUpdateTime, retOemUpdateTime, &retRecordCount,
+        &retRepositorySize, &retLargestRecordSize,
+        &retDataTransferHandleTimeout);
+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
 TEST(SetNumericEffecterValue, testGoodDecodeRequest)
 {
     std::array<uint8_t,