fw_update: Add encode req & decode resp for query_downstream_devices
Add support for Query Downstream Devices to ask if a endpoint supports
downstream devices.
The code is developed based on the definition of
'QueryDownstreamDevices' in DSP0267_1.1.0. Section 10.3
Change-Id: I5925290de5023eb48f675e736429fe9f257170c8
Signed-off-by: Delphine CC Chiu <Delphine_CC_Chiu@wiwynn.com>
diff --git a/src/firmware_update.c b/src/firmware_update.c
index 0788d4b..ed1816d 100644
--- a/src/firmware_update.c
+++ b/src/firmware_update.c
@@ -1,4 +1,5 @@
/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
+#include "msgbuf.h"
#include <libpldm/firmware_update.h>
#include <libpldm/utils.h>
@@ -74,6 +75,17 @@
}
}
+static bool is_downstream_device_update_support_valid(uint8_t resp)
+{
+ switch (resp) {
+ case PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_NOT_SUPPORTED:
+ case PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED:
+ return true;
+ default:
+ return false;
+ }
+}
+
/** @brief Check whether ComponentResponse is valid
*
* @return true if ComponentResponse is valid, false if not
@@ -854,6 +866,68 @@
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_TESTING
+int encode_query_downstream_devices_req(uint8_t instance_id,
+ struct pldm_msg *msg)
+{
+ if (msg == NULL) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ return encode_pldm_header_only(PLDM_REQUEST, instance_id, PLDM_FWUP,
+ PLDM_QUERY_DOWNSTREAM_DEVICES, msg);
+}
+
+LIBPLDM_ABI_TESTING
+int decode_query_downstream_devices_resp(
+ const struct pldm_msg *msg, size_t payload_length,
+ struct pldm_query_downstream_devices_resp *resp_data)
+{
+ struct pldm_msgbuf _buf;
+ struct pldm_msgbuf *buf = &_buf;
+ int rc;
+
+ if (msg == NULL || resp_data == NULL || !payload_length) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ rc = pldm_msgbuf_init(buf, PLDM_OPTIONAL_COMMAND_RESP_MIN_LEN,
+ msg->payload, payload_length);
+ if (rc) {
+ return rc;
+ }
+
+ rc = pldm_msgbuf_extract(buf, resp_data->completion_code);
+ if (rc) {
+ return rc;
+ }
+ if (PLDM_SUCCESS != resp_data->completion_code) {
+ // Return the CC directly without decoding the rest of the payload
+ return PLDM_SUCCESS;
+ }
+
+ if (payload_length < PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES) {
+ return PLDM_ERROR_INVALID_LENGTH;
+ }
+
+ rc = pldm_msgbuf_extract(buf,
+ resp_data->downstream_device_update_supported);
+ if (rc) {
+ return rc;
+ }
+
+ if (!is_downstream_device_update_support_valid(
+ resp_data->downstream_device_update_supported)) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ pldm_msgbuf_extract(buf, resp_data->number_of_downstream_devices);
+ pldm_msgbuf_extract(buf, resp_data->max_number_of_downstream_devices);
+ pldm_msgbuf_extract(buf, resp_data->capabilities.value);
+
+ return pldm_msgbuf_destroy_consumed(buf);
+}
+
LIBPLDM_ABI_STABLE
int encode_request_update_req(uint8_t instance_id, uint32_t max_transfer_size,
uint16_t num_of_comp,