libpldm: Add decode API for CancelUpdate response
Update agent sends this command to FD/FDP to exit from update mode
even if activation is required to begin operating at the new firmware
level. FD/FDP will transition to IDLE state on CancelUpdate. 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: I302418f85dd0b870c4d3ace7e04fcc4b873f54a7
diff --git a/libpldm/tests/libpldm_firmware_update_test.cpp b/libpldm/tests/libpldm_firmware_update_test.cpp
index 9ef53f7..746dfd6 100644
--- a/libpldm/tests/libpldm_firmware_update_test.cpp
+++ b/libpldm/tests/libpldm_firmware_update_test.cpp
@@ -2817,3 +2817,106 @@
PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
}
+
+TEST(CancelUpdate, goodPathDecodeResponse)
+{
+ constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
+ constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
+ cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ auto responseMsg1 =
+ reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
+ uint8_t completionCode = 0;
+ bool8_t nonFunctioningComponentIndication = 0;
+ bitfield64_t nonFunctioningComponentBitmap{0};
+ auto rc = decode_cancel_update_resp(
+ responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
+ &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+ EXPECT_EQ(completionCode, PLDM_SUCCESS);
+ EXPECT_EQ(nonFunctioningComponentIndication,
+ PLDM_FWUP_COMPONENTS_FUNCTIONING);
+ EXPECT_EQ(nonFunctioningComponentBitmap.value,
+ nonFunctioningComponentBitmap1);
+
+ constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
+ constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
+ cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ auto responseMsg2 =
+ reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
+ rc = decode_cancel_update_resp(
+ responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
+ &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+ EXPECT_EQ(completionCode, PLDM_SUCCESS);
+ EXPECT_EQ(nonFunctioningComponentIndication,
+ PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING);
+ EXPECT_EQ(nonFunctioningComponentBitmap.value,
+ nonFunctioningComponentBitmap2);
+
+ constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
+ cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
+ auto responseMsg3 =
+ reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
+ rc = decode_cancel_update_resp(
+ responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
+ &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+ EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
+}
+
+TEST(CancelUpdate, errorPathDecodeResponse)
+{
+ constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
+ 0x00};
+ auto responseMsg1 =
+ reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
+ uint8_t completionCode = 0;
+ bool8_t nonFunctioningComponentIndication = 0;
+ bitfield64_t nonFunctioningComponentBitmap{0};
+
+ auto rc = decode_cancel_update_resp(
+ nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
+ &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+ rc = decode_cancel_update_resp(
+ responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
+ &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+ rc = decode_cancel_update_resp(
+ responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
+ nullptr, &nonFunctioningComponentBitmap);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+ rc = decode_cancel_update_resp(
+ responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
+ &nonFunctioningComponentIndication, nullptr);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+ rc = decode_cancel_update_resp(
+ responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
+ &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+ constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
+ cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
+ auto responseMsg2 =
+ reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
+ rc = decode_cancel_update_resp(
+ responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
+ &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+ constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
+ cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ auto responseMsg3 =
+ reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
+ rc = decode_cancel_update_resp(
+ responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
+ &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}