libpldm: Add encode API for VerifyComplete response

After the component image transfer finishes successfully, the FD
transitions to the VERIFY state and performs a validation check
against the component image that was received. 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: Ia52586ede23b43dc0470910260cfc4ac1f427742
diff --git a/libpldm/firmware_update.c b/libpldm/firmware_update.c
index 9923920..e92da63 100644
--- a/libpldm/firmware_update.c
+++ b/libpldm/firmware_update.c
@@ -1096,4 +1096,30 @@
 

 	*verify_result = msg->payload[0];

 	return PLDM_SUCCESS;

+}

+

+int encode_verify_complete_resp(uint8_t instance_id, uint8_t completion_code,

+				struct pldm_msg *msg, size_t payload_length)

+{

+	if (msg == NULL) {

+		return PLDM_ERROR_INVALID_DATA;

+	}

+

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

+		return PLDM_ERROR_INVALID_LENGTH;

+	}

+

+	struct pldm_header_info header = {0};

+	header.instance = instance_id;

+	header.msg_type = PLDM_RESPONSE;

+	header.pldm_type = PLDM_FWUP;

+	header.command = PLDM_VERIFY_COMPLETE;

+	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));

+	if (rc) {

+		return rc;

+	}

+

+	msg->payload[0] = completion_code;

+

+	return PLDM_SUCCESS;

 }
\ No newline at end of file
diff --git a/libpldm/firmware_update.h b/libpldm/firmware_update.h
index 3458680..9163f96 100644
--- a/libpldm/firmware_update.h
+++ b/libpldm/firmware_update.h
@@ -27,7 +27,8 @@
 	PLDM_PASS_COMPONENT_TABLE = 0x13,

 	PLDM_UPDATE_COMPONENT = 0x14,

 	PLDM_REQUEST_FIRMWARE_DATA = 0x15,

-	PLDM_TRANSFER_COMPLETE = 0x16

+	PLDM_TRANSFER_COMPLETE = 0x16,

+	PLDM_VERIFY_COMPLETE = 0x17

 };

 

 /** @brief PLDM Firmware update completion codes

@@ -208,7 +209,7 @@
 	PLDM_FWUP_VENDOR_TRANSFER_RESULT_RANGE_MAX = 0x8F

 };

 

-/**@brief VerifyResult values in the response of VerifyComplete

+/**@brief VerifyResult values in the request of VerifyComplete

  */

 enum pldm_firmware_update_verify_result_values {

 	PLDM_FWUP_VERIFY_SUCCESS = 0x00,

@@ -803,6 +804,21 @@
 int decode_verify_complete_req(const struct pldm_msg *msg,

 			       size_t payload_length, uint8_t *verify_result);

 

+/** @brief Create PLDM response message for VerifyComplete

+ *

+ *  @param[in] instance_id - Message's instance id

+ *  @param[in] completion_code - CompletionCode

+ *  @param[in,out] msg - Message will be written to this

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

+ *

+ *  @return pldm_completion_codes

+ *

+ *  @note  Caller is responsible for memory alloc and dealloc of param

+ *         'msg.payload'

+ */

+int encode_verify_complete_resp(uint8_t instance_id, uint8_t completion_code,

+				struct pldm_msg *msg, size_t payload_length);

+

 #ifdef __cplusplus

 }

 #endif

diff --git a/libpldm/tests/libpldm_firmware_update_test.cpp b/libpldm/tests/libpldm_firmware_update_test.cpp
index 06641bc..710a209 100644
--- a/libpldm/tests/libpldm_firmware_update_test.cpp
+++ b/libpldm/tests/libpldm_firmware_update_test.cpp
@@ -2203,3 +2203,42 @@
     rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);

     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);

 }

+

+TEST(VerifyComplete, goodPathEncodeResponse)

+{

+    constexpr uint8_t instanceId = 5;

+    constexpr uint8_t completionCode = PLDM_SUCCESS;

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

+        outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};

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

+        verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};

+    auto responseMsg1 =

+        reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());

+    auto rc = encode_verify_complete_resp(instanceId, completionCode,

+                                          responseMsg1, sizeof(completionCode));

+    EXPECT_EQ(rc, PLDM_SUCCESS);

+    EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);

+

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

+        outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x87};

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

+        verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};

+    auto responseMsg2 =

+        reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());

+    rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,

+                                     responseMsg2, sizeof(completionCode));

+    EXPECT_EQ(rc, PLDM_SUCCESS);

+    EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);

+}

+

+TEST(VerifyComplete, errorPathEncodeResponse)

+{

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

+    auto responseMsg =

+        reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());

+    auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);

+}