libpldm : Add decode API for QueryDeviceIdentifiers cmd
QueryDeviceIdentifiers command is used by update agent to obtain the
firmware identifiers for the firmware device and its defined in DSP0267
Version 1.1.0 sec:10.1.
Tested: Unit tests passed
Signed-off-by: gokulsanker <gokul.sanker.v.g@intel.com>
Change-Id: I9ef81ce75aaedaae2fff9f5632ce16aa952cda17
diff --git a/libpldm/firmware_update.c b/libpldm/firmware_update.c
index 25b2997..031ec85 100644
--- a/libpldm/firmware_update.c
+++ b/libpldm/firmware_update.c
@@ -1,4 +1,5 @@
#include "firmware_update.h"
+#include <endian.h>
int encode_query_device_identifiers_req(uint8_t instance_id,
size_t payload_length,
@@ -15,3 +16,51 @@
return encode_pldm_header_only(PLDM_REQUEST, instance_id, PLDM_FWUP,
PLDM_QUERY_DEVICE_IDENTIFIERS, msg);
}
+
+int decode_query_device_identifiers_resp(const struct pldm_msg *msg,
+ size_t payload_length,
+ uint8_t *completion_code,
+ uint32_t *device_identifiers_len,
+ uint8_t *descriptor_count,
+ uint8_t **descriptor_data)
+{
+ if (msg == NULL || completion_code == NULL ||
+ device_identifiers_len == NULL || descriptor_count == NULL ||
+ descriptor_data == NULL) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ *completion_code = msg->payload[0];
+ if (PLDM_SUCCESS != *completion_code) {
+ return PLDM_SUCCESS;
+ }
+
+ if (payload_length <
+ sizeof(struct pldm_query_device_identifiers_resp)) {
+ return PLDM_ERROR_INVALID_LENGTH;
+ }
+
+ struct pldm_query_device_identifiers_resp *response =
+ (struct pldm_query_device_identifiers_resp *)msg->payload;
+ *device_identifiers_len = le32toh(response->device_identifiers_len);
+
+ if (*device_identifiers_len < PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN) {
+ return PLDM_ERROR_INVALID_LENGTH;
+ }
+
+ if (payload_length !=
+ sizeof(struct pldm_query_device_identifiers_resp) +
+ *device_identifiers_len) {
+ return PLDM_ERROR_INVALID_LENGTH;
+ }
+ *descriptor_count = response->descriptor_count;
+
+ if (*descriptor_count == 0) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ *descriptor_data =
+ (uint8_t *)(msg->payload +
+ sizeof(struct pldm_query_device_identifiers_resp));
+ return PLDM_SUCCESS;
+}
diff --git a/libpldm/firmware_update.h b/libpldm/firmware_update.h
index dbff92d..6ebfa79 100644
--- a/libpldm/firmware_update.h
+++ b/libpldm/firmware_update.h
@@ -7,11 +7,25 @@
#include "base.h"
#define PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES 0
+/** @brief Minimum length of device descriptor, 2 bytes for descriptor type,
+ * 2 bytes for descriptor length and atleast 1 byte of descriptor data
+ */
+#define PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN 5
/** @brief PLDM Firmware update commands
*/
enum pldm_firmware_update_commands { PLDM_QUERY_DEVICE_IDENTIFIERS = 0x01 };
+/** @struct pldm_query_device_identifiers_resp
+ *
+ * Structure representing query device identifiers response.
+ */
+struct pldm_query_device_identifiers_resp {
+ uint8_t completion_code;
+ uint32_t device_identifiers_len;
+ uint8_t descriptor_count;
+} __attribute__((packed));
+
/** @brief Create a PLDM request message for QueryDeviceIdentifiers
*
* @param[in] instance_id - Message's instance id
@@ -26,6 +40,24 @@
int encode_query_device_identifiers_req(uint8_t instance_id,
size_t payload_length,
struct pldm_msg *msg);
+
+/** @brief Decode QueryDeviceIdentifiers response message
+ *
+ * @param[in] msg - Response message
+ * @param[in] payload_length - Length of response message payload
+ * @param[out] completion_code - Pointer to response msg's PLDM completion code
+ * @param[out] device_identifiers_len - Pointer to device identifiers length
+ * @param[out] descriptor_count - Pointer to descriptor count
+ * @param[out] descriptor_data - Pointer to descriptor data
+ *
+ * @return pldm_completion_codes
+ */
+int decode_query_device_identifiers_resp(const struct pldm_msg *msg,
+ size_t payload_length,
+ uint8_t *completion_code,
+ uint32_t *device_identifiers_len,
+ uint8_t *descriptor_count,
+ uint8_t **descriptor_data);
#ifdef __cplusplus
}
#endif
diff --git a/libpldm/tests/libpldm_firmware_update_test.cpp b/libpldm/tests/libpldm_firmware_update_test.cpp
index 8387b77..489be16 100644
--- a/libpldm/tests/libpldm_firmware_update_test.cpp
+++ b/libpldm/tests/libpldm_firmware_update_test.cpp
@@ -20,3 +20,45 @@
EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DEVICE_IDENTIFIERS);
}
+
+TEST(QueryDeviceIdentifiers, goodPathDecodeResponse)
+{
+ // descriptorDataLen is not fixed here taking it as 6
+ constexpr uint8_t descriptorDataLen = 6;
+ std::array<uint8_t, hdrSize +
+ sizeof(struct pldm_query_device_identifiers_resp) +
+ descriptorDataLen>
+ responseMsg{};
+ auto inResp = reinterpret_cast<struct pldm_query_device_identifiers_resp*>(
+ responseMsg.data() + hdrSize);
+
+ inResp->completion_code = PLDM_SUCCESS;
+ inResp->device_identifiers_len = htole32(descriptorDataLen);
+ inResp->descriptor_count = 1;
+
+ // filling descriptor data
+ std::fill_n(responseMsg.data() + hdrSize +
+ sizeof(struct pldm_query_device_identifiers_resp),
+ descriptorDataLen, 0xFF);
+
+ auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+ uint8_t completionCode = PLDM_SUCCESS;
+ uint32_t deviceIdentifiersLen = 0;
+ uint8_t descriptorCount = 0;
+ uint8_t* outDescriptorData = nullptr;
+
+ auto rc = decode_query_device_identifiers_resp(
+ response, responseMsg.size() - hdrSize, &completionCode,
+ &deviceIdentifiersLen, &descriptorCount, &outDescriptorData);
+
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+ EXPECT_EQ(completionCode, PLDM_SUCCESS);
+ EXPECT_EQ(deviceIdentifiersLen, inResp->device_identifiers_len);
+ EXPECT_EQ(descriptorCount, inResp->descriptor_count);
+ EXPECT_EQ(true,
+ std::equal(outDescriptorData,
+ outDescriptorData + deviceIdentifiersLen,
+ responseMsg.begin() + hdrSize +
+ sizeof(struct pldm_query_device_identifiers_resp),
+ responseMsg.end()));
+}