libpldm: Add decode API for GetStatus response

The UA sends this command to acquire the status of the FD/FDP. This
implementation works with DSP0267_1.1.0, DSP0267_1.0.1 and
DSP0267_1.0.0.

Tested: Unit tests passed

Signed-off-by: gokulsanker <gokul.sanker.v.g@intel.com>
Change-Id: Ia7e3600d6847cc76ee2d37c61e6d0166315f6490
diff --git a/libpldm/firmware_update.c b/libpldm/firmware_update.c
index 4e98e59..370f37a 100644
--- a/libpldm/firmware_update.c
+++ b/libpldm/firmware_update.c
@@ -185,6 +185,101 @@
 	}

 }

 

+/** @brief Check if current or previous status in GetStatus command response is

+ *         valid

+ *

+ *	@param[in] state - current or previous different state machine state of

+ *                     the FD

+ *	@return true if state is valid, false if not

+ */

+static bool is_state_valid(uint8_t state)

+{

+	switch (state) {

+	case PLDM_FD_STATE_IDLE:

+	case PLDM_FD_STATE_LEARN_COMPONENTS:

+	case PLDM_FD_STATE_READY_XFER:

+	case PLDM_FD_STATE_DOWNLOAD:

+	case PLDM_FD_STATE_VERIFY:

+	case PLDM_FD_STATE_APPLY:

+	case PLDM_FD_STATE_ACTIVATE:

+		return true;

+

+	default:

+		return false;

+	}

+}

+

+/** @brief Check if aux state in GetStatus command response is valid

+ *

+ *  @param[in] aux_state - provides additional information to the UA to describe

+ *                         the current operation state of the FD/FDP

+ *

+ *	@return true if aux state is valid, false if not

+ */

+static bool is_aux_state_valid(uint8_t aux_state)

+{

+	switch (aux_state) {

+	case PLDM_FD_OPERATION_IN_PROGRESS:

+	case PLDM_FD_OPERATION_SUCCESSFUL:

+	case PLDM_FD_OPERATION_FAILED:

+	case PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER:

+		return true;

+

+	default:

+		return false;

+	}

+}

+

+/** @brief Check if aux state status in GetStatus command response is valid

+ *

+ *	@param[in] aux_state_status - aux state status

+ *

+ *	@return true if aux state status is valid, false if not

+ */

+static bool is_aux_state_status_valid(uint8_t aux_state_status)

+{

+	if (aux_state_status == PLDM_FD_AUX_STATE_IN_PROGRESS_OR_SUCCESS ||

+	    aux_state_status == PLDM_FD_TIMEOUT ||

+	    aux_state_status == PLDM_FD_GENERIC_ERROR) {

+		return true;

+	} else if (aux_state_status >=

+		       PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START &&

+		   aux_state_status <= PLDM_FD_VENDOR_DEFINED_STATUS_CODE_END) {

+		return true;

+	}

+

+	return false;

+}

+

+/** @brief Check if reason code in GetStatus command response is valid

+ *

+ *	@param[in] reason_code - provides the reason for why the current state

+ *                           entered the IDLE state

+ *

+ *	@return true if reason code is valid, false if not

+ */

+static bool is_reason_code_valid(uint8_t reason_code)

+{

+

+	switch (reason_code) {

+	case PLDM_FD_INITIALIZATION:

+	case PLDM_FD_ACTIVATE_FW:

+	case PLDM_FD_CANCEL_UPDATE:

+	case PLDM_FD_TIMEOUT_LEARN_COMPONENT:

+	case PLDM_FD_TIMEOUT_READY_XFER:

+	case PLDM_FD_TIMEOUT_DOWNLOAD:

+	case PLDM_FD_TIMEOUT_VERIFY:

+	case PLDM_FD_TIMEOUT_APPLY:

+		return true;

+

+	default:

+		if (reason_code >= PLDM_FD_STATUS_VENDOR_DEFINED_MIN) {

+			return true;

+		}

+		return false;

+	}

+}

+

 int decode_pldm_package_header_info(

     const uint8_t *data, size_t length,

     struct pldm_package_header_information *package_header_info,

@@ -1281,3 +1376,69 @@
 

 	return PLDM_SUCCESS;

 }

+

+int decode_get_status_resp(const struct pldm_msg *msg, size_t payload_length,

+			   uint8_t *completion_code, uint8_t *current_state,

+			   uint8_t *previous_state, uint8_t *aux_state,

+			   uint8_t *aux_state_status, uint8_t *progress_percent,

+			   uint8_t *reason_code,

+			   bitfield32_t *update_option_flags_enabled)

+{

+	if (msg == NULL || completion_code == NULL || current_state == NULL ||

+	    previous_state == NULL || aux_state == NULL ||

+	    aux_state_status == NULL || progress_percent == NULL ||

+	    reason_code == NULL || update_option_flags_enabled == NULL ||

+	    !payload_length) {

+		return PLDM_ERROR_INVALID_DATA;

+	}

+

+	*completion_code = msg->payload[0];

+	if (*completion_code != PLDM_SUCCESS) {

+		return PLDM_SUCCESS;

+	}

+

+	if (payload_length != sizeof(struct pldm_get_status_resp)) {

+		return PLDM_ERROR_INVALID_LENGTH;

+	}

+	struct pldm_get_status_resp *response =

+	    (struct pldm_get_status_resp *)msg->payload;

+

+	if (!is_state_valid(response->current_state)) {

+		return PLDM_ERROR_INVALID_DATA;

+	}

+	if (!is_state_valid(response->previous_state)) {

+		return PLDM_ERROR_INVALID_DATA;

+	}

+	if (!is_aux_state_valid(response->aux_state)) {

+		return PLDM_ERROR_INVALID_DATA;

+	}

+	if (!is_aux_state_status_valid(response->aux_state_status)) {

+		return PLDM_ERROR_INVALID_DATA;

+	}

+	if (response->progress_percent > PLDM_FWUP_MAX_PROGRESS_PERCENT) {

+		return PLDM_ERROR_INVALID_DATA;

+	}

+	if (!is_reason_code_valid(response->reason_code)) {

+		return PLDM_ERROR_INVALID_DATA;

+	}

+

+	if ((response->current_state == PLDM_FD_STATE_IDLE) ||

+	    (response->current_state == PLDM_FD_STATE_LEARN_COMPONENTS) ||

+	    (response->current_state == PLDM_FD_STATE_READY_XFER)) {

+		if (response->aux_state !=

+		    PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER) {

+			return PLDM_ERROR_INVALID_DATA;

+		}

+	}

+

+	*current_state = response->current_state;

+	*previous_state = response->previous_state;

+	*aux_state = response->aux_state;

+	*aux_state_status = response->aux_state_status;

+	*progress_percent = response->progress_percent;

+	*reason_code = response->reason_code;

+	update_option_flags_enabled->value =

+	    le32toh(response->update_option_flags_enabled.value);

+

+	return PLDM_SUCCESS;

+}

diff --git a/libpldm/firmware_update.h b/libpldm/firmware_update.h
index 231aaa0..a7e5023 100644
--- a/libpldm/firmware_update.h
+++ b/libpldm/firmware_update.h
@@ -19,6 +19,8 @@
 #define PLDM_FWUP_BASELINE_TRANSFER_SIZE 32

 #define PLDM_FWUP_MIN_OUTSTANDING_REQ 1

 #define PLDM_GET_STATUS_REQ_BYTES 0

+/* Maximum progress percentage value*/

+#define PLDM_FWUP_MAX_PROGRESS_PERCENT 0x65

 

 /** @brief PLDM Firmware update commands

  */

@@ -258,6 +260,53 @@
 	PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS = true

 };

 

+/** @brief Current state/previous state of the FD or FDP returned in GetStatus

+ *         response

+ */

+enum pldm_firmware_device_states {

+	PLDM_FD_STATE_IDLE = 0,

+	PLDM_FD_STATE_LEARN_COMPONENTS = 1,

+	PLDM_FD_STATE_READY_XFER = 2,

+	PLDM_FD_STATE_DOWNLOAD = 3,

+	PLDM_FD_STATE_VERIFY = 4,

+	PLDM_FD_STATE_APPLY = 5,

+	PLDM_FD_STATE_ACTIVATE = 6

+};

+

+/** @brief Firmware device aux state in GetStatus response

+ */

+enum pldm_get_status_aux_states {

+	PLDM_FD_OPERATION_IN_PROGRESS = 0,

+	PLDM_FD_OPERATION_SUCCESSFUL = 1,

+	PLDM_FD_OPERATION_FAILED = 2,

+	PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER = 3

+};

+

+/** @brief Firmware device aux state status in GetStatus response

+ */

+enum pldm_get_status_aux_state_status_values {

+	PLDM_FD_AUX_STATE_IN_PROGRESS_OR_SUCCESS = 0x00,

+	PLDM_FD_TIMEOUT = 0x09,

+	PLDM_FD_GENERIC_ERROR = 0x0A,

+	PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START = 0x70,

+	PLDM_FD_VENDOR_DEFINED_STATUS_CODE_END = 0xEF

+};

+

+/** @brief Firmware device reason code in GetStatus response

+ */

+enum pldm_get_status_reason_code_values {

+	PLDM_FD_INITIALIZATION = 0,

+	PLDM_FD_ACTIVATE_FW = 1,

+	PLDM_FD_CANCEL_UPDATE = 2,

+	PLDM_FD_TIMEOUT_LEARN_COMPONENT = 3,

+	PLDM_FD_TIMEOUT_READY_XFER = 4,

+	PLDM_FD_TIMEOUT_DOWNLOAD = 5,

+	PLDM_FD_TIMEOUT_VERIFY = 6,

+	PLDM_FD_TIMEOUT_APPLY = 7,

+	PLDM_FD_STATUS_VENDOR_DEFINED_MIN = 200,

+	PLDM_FD_STATUS_VENDOR_DEFINED_MAX = 255

+};

+

 /** @struct pldm_package_header_information

  *

  *  Structure representing fixed part of package header information

@@ -475,6 +524,21 @@
 	uint16_t estimated_time_activation;

 } __attribute__((packed));

 

+/** @struct pldm_get_status_resp

+ *

+ *  Structure representing GetStatus response.

+ */

+struct pldm_get_status_resp {

+	uint8_t completion_code;

+	uint8_t current_state;

+	uint8_t previous_state;

+	uint8_t aux_state;

+	uint8_t aux_state_status;

+	uint8_t progress_percent;

+	uint8_t reason_code;

+	bitfield32_t update_option_flags_enabled;

+} __attribute__((packed));

+

 /** @brief Decode the PLDM package header information

  *

  *  @param[in] data - pointer to package header information

@@ -956,6 +1020,30 @@
 int encode_get_status_req(uint8_t instance_id, struct pldm_msg *msg,

 			  size_t payload_length);

 

+/** @brief Decode GetStatus response message

+ *

+ *  @param[in] msg - Response message

+ *  @param[in] payload_length - Length of response message payload

+ *  @param[out] completion_code - Pointer to completion code

+ *  @param[out] current_state - Pointer to current state machine state

+ *  @param[out] previous_state - Pointer to previous different state machine

+ *                               state

+ *  @param[out] aux_state - Pointer to current operation state of FD/FDP

+ *  @param[out] aux_state_status - Pointer to aux state status

+ *  @param[out] progress_percent - Pointer to progress percentage

+ *  @param[out] reason_code - Pointer to reason for entering current state

+ *  @param[out] update_option_flags_enabled - Pointer to update option flags

+ *                                            enabled

+ *

+ *  @return pldm_completion_codes

+ */

+int decode_get_status_resp(const struct pldm_msg *msg, size_t payload_length,

+			   uint8_t *completion_code, uint8_t *current_state,

+			   uint8_t *previous_state, uint8_t *aux_state,

+			   uint8_t *aux_state_status, uint8_t *progress_percent,

+			   uint8_t *reason_code,

+			   bitfield32_t *update_option_flags_enabled);

+

 #ifdef __cplusplus

 }

 #endif

diff --git a/libpldm/tests/libpldm_firmware_update_test.cpp b/libpldm/tests/libpldm_firmware_update_test.cpp
index 0577c51..c8e2954 100644
--- a/libpldm/tests/libpldm_firmware_update_test.cpp
+++ b/libpldm/tests/libpldm_firmware_update_test.cpp
@@ -2478,3 +2478,239 @@
     rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);

     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);

 }

+

+TEST(GetStatus, goodPathDecodeResponse)

+{

+    constexpr std::bitset<32> updateOptionFlagsEnabled1{0};

+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>

+        getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,

+                           0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};

+    auto responseMsg1 =

+        reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());

+

+    uint8_t completionCode = 0;

+    uint8_t currentState = 0;

+    uint8_t previousState = 0;

+    uint8_t auxState = 0;

+    uint8_t auxStateStatus = 0;

+    uint8_t progressPercent = 0;

+    uint8_t reasonCode = 0;

+    bitfield32_t updateOptionFlagsEnabled{0};

+

+    auto rc = decode_get_status_resp(

+        responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,

+        &currentState, &previousState, &auxState, &auxStateStatus,

+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);

+

+    EXPECT_EQ(rc, PLDM_SUCCESS);

+    EXPECT_EQ(completionCode, PLDM_SUCCESS);

+    EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);

+    EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);

+    EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);

+    EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);

+    EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);

+    EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);

+    EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);

+

+    // Bit position 0 - Force update of component – FD will perform a force

+    // update of the component.

+    constexpr std::bitset<32> updateOptionFlagsEnabled2{1};

+    constexpr uint8_t progressPercent2 = 50;

+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>

+        getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,

+                           0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};

+    auto responseMsg2 =

+        reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());

+

+    rc = decode_get_status_resp(

+        responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,

+        &currentState, &previousState, &auxState, &auxStateStatus,

+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);

+

+    EXPECT_EQ(rc, PLDM_SUCCESS);

+    EXPECT_EQ(completionCode, PLDM_SUCCESS);

+    EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);

+    EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);

+    EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);

+    EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);

+    EXPECT_EQ(progressPercent, progressPercent2);

+    EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);

+    EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);

+

+    constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>

+        getStatusResponse3{0x00, 0x00, 0x00, 0x04};

+    auto responseMsg3 =

+        reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());

+    rc = decode_get_status_resp(

+        responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,

+        &currentState, &previousState, &auxState, &auxStateStatus,

+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);

+    EXPECT_EQ(rc, PLDM_SUCCESS);

+    EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);

+}

+

+TEST(GetStatus, errorPathDecodeResponse)

+{

+    uint8_t completionCode = 0;

+    uint8_t currentState = 0;

+    uint8_t previousState = 0;

+    uint8_t auxState = 0;

+    uint8_t auxStateStatus = 0;

+    uint8_t progressPercent = 0;

+    uint8_t reasonCode = 0;

+    bitfield32_t updateOptionFlagsEnabled{0};

+

+    constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};

+    auto responseMsg1 =

+        reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());

+

+    auto rc = decode_get_status_resp(

+        nullptr, getStatusResponse1.size() - hdrSize, &completionCode,

+        &currentState, &previousState, &auxState, &auxStateStatus,

+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    rc = decode_get_status_resp(

+        responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,

+        &currentState, &previousState, &auxState, &auxStateStatus,

+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    rc = decode_get_status_resp(

+        responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,

+        nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,

+        &reasonCode, &updateOptionFlagsEnabled);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    rc = decode_get_status_resp(

+        responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,

+        &currentState, nullptr, &auxState, &auxStateStatus, &progressPercent,

+        &reasonCode, &updateOptionFlagsEnabled);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    rc = decode_get_status_resp(

+        responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,

+        &currentState, &previousState, nullptr, &auxStateStatus,

+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    rc = decode_get_status_resp(

+        responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,

+        &currentState, &previousState, &auxState, nullptr, &progressPercent,

+        &reasonCode, &updateOptionFlagsEnabled);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    rc = decode_get_status_resp(

+        responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,

+        &currentState, &previousState, &auxState, &auxStateStatus, nullptr,

+        &reasonCode, &updateOptionFlagsEnabled);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    rc = decode_get_status_resp(

+        responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,

+        &currentState, &previousState, &auxState, &auxStateStatus,

+        &progressPercent, nullptr, &updateOptionFlagsEnabled);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    rc = decode_get_status_resp(

+        responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,

+        &currentState, &previousState, &auxState, &auxStateStatus,

+        &progressPercent, &reasonCode, nullptr);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    rc = decode_get_status_resp(

+        responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,

+        &currentState, &previousState, &auxState, &auxStateStatus,

+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>

+        getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

+                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

+    auto responseMsg2 =

+        reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());

+    rc = decode_get_status_resp(

+        responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,

+        &currentState, &previousState, &auxState, &auxStateStatus,

+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);

+

+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>

+        getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,

+                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

+    auto responseMsg3 =

+        reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());

+    rc = decode_get_status_resp(

+        responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,

+        &currentState, &previousState, &auxState, &auxStateStatus,

+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>

+        getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,

+                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

+    auto responseMsg4 =

+        reinterpret_cast<const pldm_msg*>(getStatusResponse4.data());

+    rc = decode_get_status_resp(

+        responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,

+        &currentState, &previousState, &auxState, &auxStateStatus,

+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>

+        getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,

+                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

+    auto responseMsg5 =

+        reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());

+    rc = decode_get_status_resp(

+        responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,

+        &currentState, &previousState, &auxState, &auxStateStatus,

+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>

+        getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

+                           0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

+    auto responseMsg6 =

+        reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());

+    rc = decode_get_status_resp(

+        responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,

+        &currentState, &previousState, &auxState, &auxStateStatus,

+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>

+        getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

+                           0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};

+    auto responseMsg7 =

+        reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());

+    rc = decode_get_status_resp(

+        responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,

+        &currentState, &previousState, &auxState, &auxStateStatus,

+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>

+        getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

+                           0x00, 0x00, 0xC7, 0x00, 0x00, 0x00, 0x00};

+    auto responseMsg8 =

+        reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());

+    rc = decode_get_status_resp(

+        responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,

+        &currentState, &previousState, &auxState, &auxStateStatus,

+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is

+    // IDLE

+    constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>

+        getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,

+                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

+    auto responseMsg9 =

+        reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());

+    rc = decode_get_status_resp(

+        responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,

+        &currentState, &previousState, &auxState, &auxStateStatus,

+        &progressPercent, &reasonCode, &updateOptionFlagsEnabled);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+}