libpldm: Implement encode/decode for GetBIOSAttributeCurrentValueByHandle
The GetBIOSAttributeCurrentValueByHandle command is used to get the
current value of the BIOS attribute by AttributeNameHandle.
The spec of GetBIOSAttributeCurrentValueByHandle command refers to
DSP0247_1.0.0: 8.8.
Signed-off-by: Adair Li <lichao.lc01@inspur.com>
Change-Id: Ic87408b0c02fd686033907f197130543ed7515c5
diff --git a/libpldm/bios.c b/libpldm/bios.c
index 958b7c8..151ba29 100644
--- a/libpldm/bios.c
+++ b/libpldm/bios.c
@@ -321,6 +321,66 @@
return PLDM_SUCCESS;
}
+int encode_get_bios_attribute_current_value_by_handle_req(
+ uint8_t instance_id, uint32_t transfer_handle, uint8_t transfer_op_flag,
+ uint16_t attribute_handle, struct pldm_msg *msg)
+{
+ struct pldm_header_info header = {0};
+
+ if (msg == NULL) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ header.msg_type = PLDM_REQUEST;
+ header.instance = instance_id;
+ header.pldm_type = PLDM_BIOS;
+ header.command = PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE;
+ pack_pldm_header(&header, &(msg->hdr));
+
+ struct pldm_get_bios_attribute_current_value_by_handle_req *request =
+ (struct pldm_get_bios_attribute_current_value_by_handle_req *)
+ msg->payload;
+
+ request->transfer_handle = htole32(transfer_handle);
+ request->transfer_op_flag = transfer_op_flag;
+ request->attribute_handle = htole16(attribute_handle);
+ return PLDM_SUCCESS;
+}
+
+int decode_get_bios_attribute_current_value_by_handle_resp(
+ const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
+ uint32_t *next_transfer_handle, uint8_t *transfer_flag,
+ struct variable_field *attribute_data)
+{
+ if (msg == NULL || transfer_flag == NULL ||
+ next_transfer_handle == NULL || completion_code == NULL) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ struct pldm_get_bios_attribute_current_value_by_handle_resp *response =
+ (struct pldm_get_bios_attribute_current_value_by_handle_resp *)
+ msg->payload;
+
+ *completion_code = response->completion_code;
+
+ if (PLDM_SUCCESS != *completion_code) {
+ return PLDM_SUCCESS;
+ }
+
+ if (payload_length <=
+ PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_MIN_RESP_BYTES) {
+ return PLDM_ERROR_INVALID_LENGTH;
+ }
+
+ *next_transfer_handle = le32toh(response->next_transfer_handle);
+ *transfer_flag = response->transfer_flag;
+
+ attribute_data->ptr = response->attribute_data;
+ attribute_data->length = payload_length - sizeof(*response) + 1;
+
+ 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 64ee683..d405706 100644
--- a/libpldm/bios.h
+++ b/libpldm/bios.h
@@ -351,6 +351,37 @@
/** @brief Decode GetBIOSAttributeCurrentValueByHandle request packet
*
+ * @param[in] instance_id - Message's instance id
+ * @param[in] transfer_handle - Handle to identify a BIOS attribute transfer
+ * @param[in] transfer_op_flag - Flag to indicate the start of a multipart
+ * transfer
+ * @param[in] attribute_handle - Handle to identify the BIOS attribute
+ * @param[out] msg - Message will be written to this
+ * @return pldm_completion_codes
+ */
+int encode_get_bios_attribute_current_value_by_handle_req(
+ uint8_t instance_id, uint32_t transfer_handle, uint8_t transfer_op_flag,
+ uint16_t attribute_handle, struct pldm_msg *msg);
+
+/** @brief Decode GetBIOSAttributeCurrentValueByHandle response packet
+ *
+ * @param[in] msg - Response message
+ * @param[in] payload_length - Length of response message payload
+ * @param[out] completion_code - PLDM completion code
+ * @param[out] next_transfer_handle - handle to identify the next portion of
+ * the transfer
+ * @param[out] transfer_flag - To indicate what part of the transfer this
+ * response represents
+ * @param[out] attribute_data - contains current value of attribute
+ * @return pldm_completion_codes
+ */
+int decode_get_bios_attribute_current_value_by_handle_resp(
+ const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
+ uint32_t *next_transfer_handle, uint8_t *transfer_flag,
+ struct variable_field *attribute_data);
+
+/** @brief Decode GetBIOSAttributeCurrentValueByHandle request packet
+ *
* @param[in] msg - Request message
* @param[in] payload_length - Length of request message payload
* @param[out] transfer_handle - Handle to identify a BIOS table transfer
diff --git a/libpldm/tests/libpldm_bios_test.cpp b/libpldm/tests/libpldm_bios_test.cpp
index 795daec..d8f8e73 100644
--- a/libpldm/tests/libpldm_bios_test.cpp
+++ b/libpldm/tests/libpldm_bios_test.cpp
@@ -553,6 +553,42 @@
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
}
+TEST(GetBIOSAttributeCurrentValueByHandle, testGoodEncodeRequest)
+{
+ std::array<uint8_t, sizeof(pldm_msg_hdr) +
+ PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_REQ_BYTES>
+ requestMsg{};
+ uint32_t transferHandle = 45;
+ uint8_t transferOpFlag = PLDM_GET_FIRSTPART;
+ uint8_t attributeHandle = 10;
+
+ auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+ auto rc = encode_get_bios_attribute_current_value_by_handle_req(
+ 0, transferHandle, transferOpFlag, attributeHandle, request);
+
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+
+ struct pldm_get_bios_attribute_current_value_by_handle_req* req =
+ reinterpret_cast<
+ struct pldm_get_bios_attribute_current_value_by_handle_req*>(
+ request->payload);
+ EXPECT_EQ(transferHandle, le32toh(req->transfer_handle));
+ EXPECT_EQ(transferOpFlag, req->transfer_op_flag);
+ EXPECT_EQ(attributeHandle, le16toh(req->attribute_handle));
+}
+
+TEST(GetBIOSAttributeCurrentValueByHandle, testBadEncodeRequest)
+{
+ uint32_t transferHandle = 0;
+ uint8_t transferOpFlag = PLDM_GET_FIRSTPART;
+ uint8_t attributeHandle = 0;
+
+ auto rc = encode_get_bios_attribute_current_value_by_handle_req(
+ 0, transferHandle, transferOpFlag, attributeHandle, nullptr);
+
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
TEST(GetBIOSAttributeCurrentValueByHandle, testGoodEncodeResponse)
{
@@ -821,3 +857,44 @@
ASSERT_EQ(transfer_flag, retransfer_flag);
ASSERT_EQ(biosTableOffset, rebiosTableOffset);
}
+
+TEST(GetBIOSAttributeCurrentValueByHandle, testDecodeResponse)
+{
+ uint32_t nextTransferHandle = 32;
+ uint8_t completionCode = PLDM_SUCCESS;
+ uint8_t transfer_flag = PLDM_START_AND_END;
+ uint32_t attributeData = 44;
+
+ std::array<uint8_t,
+ hdrSize + PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_MIN_RESP_BYTES +
+ sizeof(attributeData)>
+ responseMsg{};
+ struct pldm_msg* response =
+ reinterpret_cast<struct pldm_msg*>(responseMsg.data());
+
+ struct pldm_get_bios_attribute_current_value_by_handle_resp* resp =
+ reinterpret_cast<
+ struct pldm_get_bios_attribute_current_value_by_handle_resp*>(
+ response->payload);
+
+ resp->completion_code = completionCode;
+ resp->next_transfer_handle = htole32(nextTransferHandle);
+ resp->transfer_flag = transfer_flag;
+ memcpy(resp->attribute_data, &attributeData, sizeof(attributeData));
+
+ uint8_t retCompletionCode;
+ uint32_t retNextTransferHandle;
+ uint8_t retransfer_flag;
+ struct variable_field retAttributeData;
+ auto rc = decode_get_bios_attribute_current_value_by_handle_resp(
+ response, responseMsg.size() - hdrSize, &retCompletionCode,
+ &retNextTransferHandle, &retransfer_flag, &retAttributeData);
+
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+ EXPECT_EQ(completionCode, retCompletionCode);
+ EXPECT_EQ(nextTransferHandle, retNextTransferHandle);
+ EXPECT_EQ(transfer_flag, retransfer_flag);
+ EXPECT_EQ(sizeof(attributeData), retAttributeData.length);
+ EXPECT_EQ(
+ 0, memcmp(retAttributeData.ptr, &attributeData, sizeof(attributeData)));
+}
\ No newline at end of file