libpldm: Add decode API for CancelUpdateComponent response

Update agent send this command to FD/FDP during firmware component
transfer process.The FD/FDP, upon receiving this command shall stop
sending RequestFirmwareData commands to the UA, and cancel the
current component update procedure. The FD/FDP controller shall
transition to the READY XFER state of update mode and be ready to
accept another UpdateComponent command. 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: I1625489bd78729367439e3c495c91c9699341007
diff --git a/libpldm/base.h b/libpldm/base.h
index d9f5faf..99fd6af 100644
--- a/libpldm/base.h
+++ b/libpldm/base.h
@@ -497,6 +497,7 @@
 int encode_pldm_header_only(uint8_t msg_type, uint8_t instance_id,
 			    uint8_t pldm_type, uint8_t command,
 			    struct pldm_msg *msg);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/libpldm/firmware_update.c b/libpldm/firmware_update.c
index 0df6aaf..6714136 100644
--- a/libpldm/firmware_update.c
+++ b/libpldm/firmware_update.c
@@ -1467,3 +1467,19 @@
 

 	return PLDM_SUCCESS;

 }

+

+int decode_cancel_update_component_resp(const struct pldm_msg *msg,

+					size_t payload_length,

+					uint8_t *completion_code)

+{

+	if (msg == NULL || completion_code == NULL) {

+		return PLDM_ERROR_INVALID_DATA;

+	}

+

+	if (payload_length != sizeof(*completion_code)) {

+		return PLDM_ERROR_INVALID_LENGTH;

+	}

+

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

+	return PLDM_SUCCESS;

+}

diff --git a/libpldm/firmware_update.h b/libpldm/firmware_update.h
index b66e2e1..29bcc86 100644
--- a/libpldm/firmware_update.h
+++ b/libpldm/firmware_update.h
@@ -1061,6 +1061,18 @@
 				       struct pldm_msg *msg,

 				       size_t payload_length);

 

+/** @brief Decode CancelUpdateComponent response message

+ *

+ *  @param[in] msg - Response message

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

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

+ *

+ *  @return pldm_completion_codes

+ */

+int decode_cancel_update_component_resp(const struct pldm_msg *msg,

+					size_t payload_length,

+					uint8_t *completion_code);

+

 #ifdef __cplusplus

 }

 #endif

diff --git a/libpldm/tests/libpldm_firmware_update_test.cpp b/libpldm/tests/libpldm_firmware_update_test.cpp
index 22ee122..1e6bdb5 100644
--- a/libpldm/tests/libpldm_firmware_update_test.cpp
+++ b/libpldm/tests/libpldm_firmware_update_test.cpp
@@ -2742,3 +2742,50 @@
         0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);

     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);

 }

+

+TEST(CancelUpdateComponent, testGoodDecodeResponse)

+{

+    uint8_t completionCode = 0;

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

+        cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};

+    auto responseMsg1 = reinterpret_cast<const pldm_msg*>(

+        cancelUpdateComponentResponse1.data());

+    auto rc = decode_cancel_update_component_resp(

+        responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,

+        &completionCode);

+    EXPECT_EQ(rc, PLDM_SUCCESS);

+    EXPECT_EQ(completionCode, PLDM_SUCCESS);

+

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

+        cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};

+    auto responseMsg2 = reinterpret_cast<const pldm_msg*>(

+        cancelUpdateComponentResponse2.data());

+    rc = decode_cancel_update_component_resp(

+        responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,

+        &completionCode);

+    EXPECT_EQ(rc, PLDM_SUCCESS);

+    EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);

+}

+

+TEST(CancelUpdateComponent, testBadDecodeResponse)

+{

+    uint8_t completionCode = 0;

+    constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{

+        0x00, 0x00, 0x00};

+    auto responseMsg =

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

+

+    auto rc = decode_cancel_update_component_resp(

+        nullptr, cancelUpdateComponentResponse.size() - hdrSize,

+        &completionCode);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    rc = decode_cancel_update_component_resp(

+        responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    rc = decode_cancel_update_component_resp(

+        responseMsg, cancelUpdateComponentResponse.size() - hdrSize,

+        &completionCode);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);

+}
\ No newline at end of file