blob: 8f3ab3c499addb15e29bbd7a07d4d8deec104db9 [file] [log] [blame]
#include <endian.h>
#include <libpldm/base.h>
#include <libpldm/firmware_update.h>
#include <libpldm/pldm_types.h>
#include <libpldm/utils.h>
#include <algorithm>
#include <array>
#include <bitset>
#include <cstdint>
#include <cstring>
#include <string>
#include <string_view>
#include <vector>
#include "msgbuf.h"
#include <gtest/gtest.h>
constexpr auto hdrSize = sizeof(pldm_msg_hdr);
TEST(DecodePackageHeaderInfo, goodPath)
{
// Package header identifier for Version 1.0.x
constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43,
0x98, 0x00, 0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02};
// Package header version for DSP0267 version 1.0.x
constexpr uint8_t pkgHeaderFormatRevision = 0x01;
// Random PackageHeaderSize
constexpr uint16_t pkgHeaderSize = 303;
// PackageReleaseDateTime - "25/12/2021 00:00:00"
std::array<uint8_t, PLDM_TIMESTAMP104_SIZE> package_release_date_time{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00};
constexpr uint16_t componentBitmapBitLength = 8;
// PackageVersionString
constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
constexpr size_t packagerHeaderSize =
sizeof(pldm_package_header_information) + packageVersionStr.size();
constexpr std::array<uint8_t, packagerHeaderSize> packagerHeaderInfo{
0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
0x05, 0x9a, 0xca, 0x02, 0x01, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b,
0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
pldm_package_header_information pkgHeader{};
variable_field packageVersion{};
auto rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
packagerHeaderInfo.size(),
&pkgHeader, &packageVersion);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(true,
std::equal(pkgHeader.uuid, pkgHeader.uuid + PLDM_FWUP_UUID_LENGTH,
uuid.begin(), uuid.end()));
EXPECT_EQ(pkgHeader.package_header_format_version, pkgHeaderFormatRevision);
EXPECT_EQ(pkgHeader.package_header_size, pkgHeaderSize);
EXPECT_EQ(true, std::equal(pkgHeader.package_release_date_time,
pkgHeader.package_release_date_time +
PLDM_TIMESTAMP104_SIZE,
package_release_date_time.begin(),
package_release_date_time.end()));
EXPECT_EQ(pkgHeader.component_bitmap_bit_length, componentBitmapBitLength);
EXPECT_EQ(pkgHeader.package_version_string_type, PLDM_STR_TYPE_ASCII);
EXPECT_EQ(pkgHeader.package_version_string_length,
packageVersionStr.size());
std::string packageVersionString(
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const char*>(packageVersion.ptr),
packageVersion.length);
EXPECT_EQ(packageVersionString, packageVersionStr);
}
TEST(DecodePackageHeaderInfo, errorPaths)
{
int rc = 0;
constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
constexpr size_t packagerHeaderSize =
sizeof(pldm_package_header_information) + packageVersionStr.size();
// Invalid Package Version String Type - 0x06
constexpr std::array<uint8_t, packagerHeaderSize>
invalidPackagerHeaderInfo1{
0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
0x07, 0x00, 0x08, 0x00, 0x06, 0x0b, 0x4f, 0x70, 0x65, 0x6e,
0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
pldm_package_header_information packageHeader{};
variable_field packageVersion{};
rc = decode_pldm_package_header_info(nullptr,
invalidPackagerHeaderInfo1.size(),
&packageHeader, &packageVersion);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
invalidPackagerHeaderInfo1.size(),
nullptr, &packageVersion);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
invalidPackagerHeaderInfo1.size(),
&packageHeader, nullptr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_pldm_package_header_info(
invalidPackagerHeaderInfo1.data(),
sizeof(pldm_package_header_information) - 1, &packageHeader,
&packageVersion);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
invalidPackagerHeaderInfo1.size(),
&packageHeader, &packageVersion);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
// Invalid Package Version String Length - 0x00
constexpr std::array<uint8_t, packagerHeaderSize>
invalidPackagerHeaderInfo2{
0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
0x07, 0x00, 0x08, 0x00, 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e,
0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo2.data(),
invalidPackagerHeaderInfo2.size(),
&packageHeader, &packageVersion);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
// Package version string length less than in the header information
constexpr std::array<uint8_t, packagerHeaderSize - 1>
invalidPackagerHeaderInfo3{
0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
0x07, 0x00, 0x08, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e,
0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e};
rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo3.data(),
invalidPackagerHeaderInfo3.size(),
&packageHeader, &packageVersion);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
// ComponentBitmapBitLength not a multiple of 8
constexpr std::array<uint8_t, packagerHeaderSize>
invalidPackagerHeaderInfo4{
0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
0x07, 0x00, 0x09, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e,
0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo4.data(),
invalidPackagerHeaderInfo4.size(),
&packageHeader, &packageVersion);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
}
TEST(DecodeFirmwareDeviceIdRecord, goodPath)
{
constexpr uint8_t descriptorCount = 1;
// Continue component updates after failure
constexpr std::bitset<32> deviceUpdateFlag{1};
constexpr uint16_t componentBitmapBitLength = 16;
// Applicable Components - 1,2,5,8,9
std::vector<std::bitset<8>> applicableComponentsBitfield{0x93, 0x01};
// ComponentImageSetVersionString
constexpr std::string_view imageSetVersionStr{"VersionString1"};
// Initial descriptor - UUID
constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
constexpr uint16_t fwDevicePkgDataLen = 2;
// FirmwareDevicePackageData
constexpr std::array<uint8_t, fwDevicePkgDataLen> fwDevicePkgData{0xab,
0xcd};
// Size of the firmware device ID record
constexpr uint16_t recordLen =
sizeof(pldm_firmware_device_id_record) +
(componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
imageSetVersionStr.size() + sizeof(pldm_descriptor_tlv) - 1 +
uuid.size() + fwDevicePkgData.size();
// Firmware device ID record
constexpr std::array<uint8_t, recordLen> record{
0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02,
0x00, 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10,
0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0,
0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xab, 0xcd};
pldm_firmware_device_id_record deviceIdRecHeader{};
variable_field applicableComponents{};
variable_field outCompImageSetVersionStr{};
variable_field recordDescriptors{};
variable_field outFwDevicePkgData{};
auto rc = decode_firmware_device_id_record(
record.data(), record.size(), componentBitmapBitLength,
&deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
&recordDescriptors, &outFwDevicePkgData);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
deviceUpdateFlag);
EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
PLDM_STR_TYPE_ASCII);
EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
imageSetVersionStr.size());
EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, fwDevicePkgDataLen);
EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
EXPECT_EQ(true,
std::equal(applicableComponents.ptr,
applicableComponents.ptr + applicableComponents.length,
applicableComponentsBitfield.begin(),
applicableComponentsBitfield.end()));
EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
std::string compImageSetVersionStr(
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
outCompImageSetVersionStr.length);
EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
uint16_t descriptorType = 0;
uint16_t descriptorLen = 0;
variable_field descriptorData{};
// DescriptorCount is 1, so decode_descriptor_type_length_value called once
rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
recordDescriptors.length,
&descriptorType, &descriptorData);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
sizeof(descriptorLen) +
descriptorData.length);
EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
EXPECT_EQ(true, std::equal(descriptorData.ptr,
descriptorData.ptr + descriptorData.length,
uuid.begin(), uuid.end()));
EXPECT_EQ(outFwDevicePkgData.length, fwDevicePkgData.size());
EXPECT_EQ(true,
std::equal(outFwDevicePkgData.ptr,
outFwDevicePkgData.ptr + outFwDevicePkgData.length,
fwDevicePkgData.begin(), fwDevicePkgData.end()));
}
TEST(DecodeFirmwareDeviceIdRecord, goodPathNofwDevicePkgData)
{
constexpr uint8_t descriptorCount = 1;
// Continue component updates after failure
constexpr std::bitset<32> deviceUpdateFlag{1};
constexpr uint16_t componentBitmapBitLength = 8;
// Applicable Components - 1,2
std::vector<std::bitset<8>> applicableComponentsBitfield{0x03};
// ComponentImageSetVersionString
constexpr std::string_view imageSetVersionStr{"VersionString1"};
// Initial descriptor - UUID
constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
constexpr uint16_t fwDevicePkgDataLen = 0;
// Size of the firmware device ID record
constexpr uint16_t recordLen =
sizeof(pldm_firmware_device_id_record) +
(componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
imageSetVersionStr.size() +
sizeof(pldm_descriptor_tlv().descriptor_type) +
sizeof(pldm_descriptor_tlv().descriptor_length) + uuid.size() +
fwDevicePkgDataLen;
// Firmware device ID record
constexpr std::array<uint8_t, recordLen> record{
0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x03,
0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e,
0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d,
0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
pldm_firmware_device_id_record deviceIdRecHeader{};
variable_field applicableComponents{};
variable_field outCompImageSetVersionStr{};
variable_field recordDescriptors{};
variable_field outFwDevicePkgData{};
auto rc = decode_firmware_device_id_record(
record.data(), record.size(), componentBitmapBitLength,
&deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
&recordDescriptors, &outFwDevicePkgData);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
deviceUpdateFlag);
EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
PLDM_STR_TYPE_ASCII);
EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
imageSetVersionStr.size());
EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, 0);
EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
EXPECT_EQ(true,
std::equal(applicableComponents.ptr,
applicableComponents.ptr + applicableComponents.length,
applicableComponentsBitfield.begin(),
applicableComponentsBitfield.end()));
EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
std::string compImageSetVersionStr(
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
outCompImageSetVersionStr.length);
EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
uint16_t descriptorType = 0;
uint16_t descriptorLen = 0;
variable_field descriptorData{};
// DescriptorCount is 1, so decode_descriptor_type_length_value called once
rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
recordDescriptors.length,
&descriptorType, &descriptorData);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
sizeof(descriptorLen) +
descriptorData.length);
EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
EXPECT_EQ(true, std::equal(descriptorData.ptr,
descriptorData.ptr + descriptorData.length,
uuid.begin(), uuid.end()));
EXPECT_EQ(outFwDevicePkgData.ptr, nullptr);
EXPECT_EQ(outFwDevicePkgData.length, 0);
}
TEST(DecodeFirmwareDeviceIdRecord, ErrorPaths)
{
constexpr uint16_t componentBitmapBitLength = 8;
// Invalid ComponentImageSetVersionStringType
constexpr std::array<uint8_t, 11> invalidRecord1{
0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
int rc = 0;
pldm_firmware_device_id_record deviceIdRecHeader{};
variable_field applicableComponents{};
variable_field outCompImageSetVersionStr{};
variable_field recordDescriptors{};
variable_field outFwDevicePkgData{};
rc = decode_firmware_device_id_record(
nullptr, invalidRecord1.size(), componentBitmapBitLength,
&deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
&recordDescriptors, &outFwDevicePkgData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_firmware_device_id_record(
invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
nullptr, &applicableComponents, &outCompImageSetVersionStr,
&recordDescriptors, &outFwDevicePkgData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_firmware_device_id_record(
invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
&deviceIdRecHeader, nullptr, &outCompImageSetVersionStr,
&recordDescriptors, &outFwDevicePkgData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_firmware_device_id_record(
invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
&deviceIdRecHeader, &applicableComponents, nullptr, &recordDescriptors,
&outFwDevicePkgData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_firmware_device_id_record(
invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
&deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
nullptr, &outFwDevicePkgData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_firmware_device_id_record(
invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
&deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
&recordDescriptors, nullptr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_firmware_device_id_record(
invalidRecord1.data(), invalidRecord1.size() - 1,
componentBitmapBitLength, &deviceIdRecHeader, &applicableComponents,
&outCompImageSetVersionStr, &recordDescriptors, &outFwDevicePkgData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
rc = decode_firmware_device_id_record(
invalidRecord1.data(), invalidRecord1.size(),
componentBitmapBitLength + 1, &deviceIdRecHeader, &applicableComponents,
&outCompImageSetVersionStr, &recordDescriptors, &outFwDevicePkgData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_firmware_device_id_record(
invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
&deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
&recordDescriptors, &outFwDevicePkgData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
// Invalid ComponentImageSetVersionStringLength
constexpr std::array<uint8_t, 11> invalidRecord2{
0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
rc = decode_firmware_device_id_record(
invalidRecord2.data(), invalidRecord2.size(), componentBitmapBitLength,
&deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
&recordDescriptors, &outFwDevicePkgData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
// invalidRecord3 size is less than RecordLength
constexpr std::array<uint8_t, 11> invalidRecord3{
0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00};
rc = decode_firmware_device_id_record(
invalidRecord3.data(), invalidRecord3.size(), componentBitmapBitLength,
&deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
&recordDescriptors, &outFwDevicePkgData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
// RecordLength is less than the calculated RecordLength
constexpr std::array<uint8_t, 11> invalidRecord4{
0x15, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02, 0x00};
rc = decode_firmware_device_id_record(
invalidRecord4.data(), invalidRecord4.size(), componentBitmapBitLength,
&deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
&recordDescriptors, &outFwDevicePkgData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
}
TEST(DecodeDescriptors, goodPath3Descriptors)
{
// In the descriptor data there are 3 descriptor entries
// 1) IANA enterprise ID
constexpr std::array<uint8_t, PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH> iana{
0x0a, 0x0b, 0x0c, 0xd};
// 2) UUID
constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
// 3) Vendor Defined
constexpr std::string_view vendorTitle{"OpenBMC"};
constexpr size_t vendorDescriptorLen = 2;
constexpr std::array<uint8_t, vendorDescriptorLen> vendorDescriptorData{
0x01, 0x02};
constexpr size_t vendorDefinedDescriptorLen =
sizeof(pldm_vendor_defined_descriptor_title_data()
.vendor_defined_descriptor_title_str_type) +
sizeof(pldm_vendor_defined_descriptor_title_data()
.vendor_defined_descriptor_title_str_len) +
vendorTitle.size() + vendorDescriptorData.size();
constexpr size_t descriptorsLength =
3 * (sizeof(pldm_descriptor_tlv().descriptor_type) +
sizeof(pldm_descriptor_tlv().descriptor_length)) +
iana.size() + uuid.size() + vendorDefinedDescriptorLen;
constexpr std::array<uint8_t, descriptorsLength> descriptors{
0x01, 0x00, 0x04, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x02, 0x00, 0x10,
0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xff, 0xff, 0x0b, 0x00, 0x01,
0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x01, 0x02};
size_t descriptorCount = 1;
size_t descriptorsRemainingLength = descriptorsLength;
int rc = 0;
while (descriptorsRemainingLength && (descriptorCount <= 3))
{
uint16_t descriptorType = 0;
uint16_t descriptorLen = 0;
variable_field descriptorData{};
rc = decode_descriptor_type_length_value(
descriptors.data() + descriptorsLength - descriptorsRemainingLength,
descriptorsRemainingLength, &descriptorType, &descriptorData);
EXPECT_EQ(rc, PLDM_SUCCESS);
if (descriptorCount == 1)
{
EXPECT_EQ(descriptorType, PLDM_FWUP_IANA_ENTERPRISE_ID);
EXPECT_EQ(descriptorData.length,
PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH);
EXPECT_EQ(true,
std::equal(descriptorData.ptr,
descriptorData.ptr + descriptorData.length,
iana.begin(), iana.end()));
}
else if (descriptorCount == 2)
{
EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
EXPECT_EQ(true,
std::equal(descriptorData.ptr,
descriptorData.ptr + descriptorData.length,
uuid.begin(), uuid.end()));
}
else if (descriptorCount == 3)
{
EXPECT_EQ(descriptorType, PLDM_FWUP_VENDOR_DEFINED);
EXPECT_EQ(descriptorData.length, vendorDefinedDescriptorLen);
uint8_t descriptorTitleStrType = 0;
variable_field descriptorTitleStr{};
variable_field vendorDefinedDescriptorData{};
rc = decode_vendor_defined_descriptor_value(
descriptorData.ptr, descriptorData.length,
&descriptorTitleStrType, &descriptorTitleStr,
&vendorDefinedDescriptorData);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(descriptorTitleStrType, PLDM_STR_TYPE_ASCII);
EXPECT_EQ(descriptorTitleStr.length, vendorTitle.size());
std::string vendorTitleStr(
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const char*>(descriptorTitleStr.ptr),
descriptorTitleStr.length);
EXPECT_EQ(vendorTitleStr, vendorTitle);
EXPECT_EQ(vendorDefinedDescriptorData.length,
vendorDescriptorData.size());
EXPECT_EQ(true, std::equal(vendorDefinedDescriptorData.ptr,
vendorDefinedDescriptorData.ptr +
vendorDefinedDescriptorData.length,
vendorDescriptorData.begin(),
vendorDescriptorData.end()));
}
descriptorsRemainingLength -= sizeof(descriptorType) +
sizeof(descriptorLen) +
descriptorData.length;
descriptorCount++;
}
}
TEST(DecodeDescriptors, errorPathDecodeDescriptorTLV)
{
int rc = 0;
// IANA Enterprise ID descriptor length incorrect
constexpr std::array<uint8_t, 7> invalidIANADescriptor1{
0x01, 0x00, 0x03, 0x00, 0x0a, 0x0b, 0x0c};
uint16_t descriptorType = 0;
variable_field descriptorData{};
rc = decode_descriptor_type_length_value(nullptr,
invalidIANADescriptor1.size(),
&descriptorType, &descriptorData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
invalidIANADescriptor1.size(),
nullptr, &descriptorData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
invalidIANADescriptor1.size(),
&descriptorType, nullptr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_descriptor_type_length_value(
invalidIANADescriptor1.data(), PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN - 1,
&descriptorType, &descriptorData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
invalidIANADescriptor1.size(),
&descriptorType, &descriptorData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
// IANA Enterprise ID descriptor data less than length
std::array<uint8_t, 7> invalidIANADescriptor2{0x01, 0x00, 0x04, 0x00,
0x0a, 0x0b, 0x0c};
rc = decode_descriptor_type_length_value(invalidIANADescriptor2.data(),
invalidIANADescriptor2.size(),
&descriptorType, &descriptorData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
}
TEST(DecodeDescriptors, errorPathVendorDefinedDescriptor)
{
int rc = 0;
// VendorDefinedDescriptorTitleStringType is invalid
constexpr std::array<uint8_t, 9> invalidVendorDescriptor1{
0x06, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
uint8_t descriptorStringType = 0;
variable_field descriptorTitleStr{};
variable_field vendorDefinedDescriptorData{};
rc = decode_vendor_defined_descriptor_value(
nullptr, invalidVendorDescriptor1.size(), &descriptorStringType,
&descriptorTitleStr, &vendorDefinedDescriptorData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_vendor_defined_descriptor_value(
invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
&descriptorStringType, &descriptorTitleStr,
&vendorDefinedDescriptorData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_vendor_defined_descriptor_value(
invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
nullptr, &descriptorTitleStr, &vendorDefinedDescriptorData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_vendor_defined_descriptor_value(
invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
&descriptorStringType, nullptr, &vendorDefinedDescriptorData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_vendor_defined_descriptor_value(
invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
&descriptorStringType, &descriptorTitleStr, nullptr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_vendor_defined_descriptor_value(
invalidVendorDescriptor1.data(),
sizeof(pldm_vendor_defined_descriptor_title_data) - 1,
&descriptorStringType, &descriptorTitleStr,
&vendorDefinedDescriptorData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
rc = decode_vendor_defined_descriptor_value(
invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
&descriptorStringType, &descriptorTitleStr,
&vendorDefinedDescriptorData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
// VendorDefinedDescriptorTitleStringLength is 0
std::array<uint8_t, 9> invalidVendorDescriptor2{
0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
rc = decode_vendor_defined_descriptor_value(
invalidVendorDescriptor2.data(), invalidVendorDescriptor2.size(),
&descriptorStringType, &descriptorTitleStr,
&vendorDefinedDescriptorData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
// VendorDefinedDescriptorData not present in the data
std::array<uint8_t, 9> invalidVendorDescriptor3{
0x01, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
rc = decode_vendor_defined_descriptor_value(
invalidVendorDescriptor3.data(), invalidVendorDescriptor3.size(),
&descriptorStringType, &descriptorTitleStr,
&vendorDefinedDescriptorData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
}
TEST(DecodeComponentImageInfo, goodPath)
{
// Firmware
constexpr uint16_t compClassification = 16;
constexpr uint16_t compIdentifier = 300;
constexpr uint32_t compComparisonStamp = 0xffffffff;
// Force update
constexpr std::bitset<16> compOptions{1};
// System reboot[Bit position 3] & Medium-specific reset[Bit position 2]
constexpr std::bitset<16> reqCompActivationMethod{0x0c};
// Random ComponentLocationOffset
constexpr uint32_t compLocOffset = 357;
// Random ComponentSize
constexpr uint32_t compSize = 27;
// ComponentVersionString
constexpr std::string_view compVersionStr{"VersionString1"};
constexpr size_t compImageInfoSize =
sizeof(pldm_component_image_information) + compVersionStr.size();
constexpr std::array<uint8_t, compImageInfoSize> compImageInfo{
0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
pldm_component_image_information outCompImageInfo{};
variable_field outCompVersionStr{};
auto rc =
decode_pldm_comp_image_info(compImageInfo.data(), compImageInfo.size(),
&outCompImageInfo, &outCompVersionStr);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(outCompImageInfo.comp_classification, compClassification);
EXPECT_EQ(outCompImageInfo.comp_identifier, compIdentifier);
EXPECT_EQ(outCompImageInfo.comp_comparison_stamp, compComparisonStamp);
EXPECT_EQ(outCompImageInfo.comp_options.value, compOptions);
EXPECT_EQ(outCompImageInfo.requested_comp_activation_method.value,
reqCompActivationMethod);
EXPECT_EQ(outCompImageInfo.comp_location_offset, compLocOffset);
EXPECT_EQ(outCompImageInfo.comp_size, compSize);
EXPECT_EQ(outCompImageInfo.comp_version_string_type, PLDM_STR_TYPE_ASCII);
EXPECT_EQ(outCompImageInfo.comp_version_string_length,
compVersionStr.size());
EXPECT_EQ(outCompVersionStr.length,
outCompImageInfo.comp_version_string_length);
std::string componentVersionString(
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const char*>(outCompVersionStr.ptr),
outCompVersionStr.length);
EXPECT_EQ(componentVersionString, compVersionStr);
}
TEST(DecodeComponentImageInfo, errorPaths)
{
int rc = 0;
// ComponentVersionString
constexpr std::string_view compVersionStr{"VersionString1"};
constexpr size_t compImageInfoSize =
sizeof(pldm_component_image_information) + compVersionStr.size();
// Invalid ComponentVersionStringType - 0x06
constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo1{
0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x56, 0x65,
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
pldm_component_image_information outCompImageInfo{};
variable_field outCompVersionStr{};
rc = decode_pldm_comp_image_info(nullptr, invalidCompImageInfo1.size(),
&outCompImageInfo, &outCompVersionStr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
invalidCompImageInfo1.size(), nullptr,
&outCompVersionStr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
invalidCompImageInfo1.size(),
&outCompImageInfo, nullptr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
sizeof(pldm_component_image_information) -
1,
&outCompImageInfo, &outCompVersionStr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
invalidCompImageInfo1.size(),
&outCompImageInfo, &outCompVersionStr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
// Invalid ComponentVersionStringLength - 0x00
constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo2{
0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x65,
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
rc = decode_pldm_comp_image_info(invalidCompImageInfo2.data(),
invalidCompImageInfo2.size(),
&outCompImageInfo, &outCompVersionStr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
// Use Component Comparison Stamp is not set, but ComponentComparisonStamp
// is not 0xffffffff
constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo3{
0x10, 0x00, 0x2c, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00,
0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
invalidCompImageInfo3.size() - 1,
&outCompImageInfo, &outCompVersionStr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
invalidCompImageInfo3.size(),
&outCompImageInfo, &outCompVersionStr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
// Invalid ComponentLocationOffset - 0
constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo4{
0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
rc = decode_pldm_comp_image_info(invalidCompImageInfo4.data(),
invalidCompImageInfo4.size(),
&outCompImageInfo, &outCompVersionStr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
// Invalid ComponentSize - 0
constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo5{
0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
0x65, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
rc = decode_pldm_comp_image_info(invalidCompImageInfo5.data(),
invalidCompImageInfo5.size(),
&outCompImageInfo, &outCompVersionStr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
}
TEST(QueryDeviceIdentifiers, goodPathEncodeRequest)
{
std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
uint8_t instanceId = 0x01;
auto rc = encode_query_device_identifiers_req(
instanceId, PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES, requestPtr);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DEVICE_IDENTIFIERS);
}
TEST(QueryDeviceIdentifiers, goodPathDecodeResponse)
{
// descriptorDataLen is not fixed here taking it as 6
constexpr uint8_t descriptorDataLen = 6;
std::array<uint8_t, hdrSize +
sizeof(struct pldm_query_device_identifiers_resp) +
descriptorDataLen>
responseMsg{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto inResp = reinterpret_cast<struct pldm_query_device_identifiers_resp*>(
responseMsg.data() + hdrSize);
inResp->completion_code = PLDM_SUCCESS;
inResp->device_identifiers_len = htole32(descriptorDataLen);
inResp->descriptor_count = 1;
// filling descriptor data
std::fill_n(responseMsg.data() + hdrSize +
sizeof(struct pldm_query_device_identifiers_resp),
descriptorDataLen, 0xff);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
uint8_t completionCode = PLDM_SUCCESS;
uint32_t deviceIdentifiersLen = 0;
uint8_t descriptorCount = 0;
uint8_t* outDescriptorData = nullptr;
auto rc = decode_query_device_identifiers_resp(
response, responseMsg.size() - hdrSize, &completionCode,
&deviceIdentifiersLen, &descriptorCount, &outDescriptorData);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(completionCode, PLDM_SUCCESS);
EXPECT_EQ(deviceIdentifiersLen, inResp->device_identifiers_len);
EXPECT_EQ(descriptorCount, inResp->descriptor_count);
EXPECT_EQ(true,
std::equal(outDescriptorData,
outDescriptorData + deviceIdentifiersLen,
responseMsg.begin() + hdrSize +
sizeof(struct pldm_query_device_identifiers_resp),
responseMsg.end()));
}
TEST(GetFirmwareParameters, goodPathEncodeRequest)
{
std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
uint8_t instanceId = 0x01;
auto rc = encode_get_firmware_parameters_req(
instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, requestPtr);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
EXPECT_EQ(requestPtr->hdr.command, PLDM_GET_FIRMWARE_PARAMETERS);
}
TEST(GetFirmwareParameters, decodeResponse)
{
// CapabilitiesDuringUpdate of the firmware device
// Firmware device downgrade restrictions [Bit position 8] &
// Firmware Device Partial Updates [Bit position 3]
constexpr std::bitset<32> fdCapabilities{0x00000104};
constexpr uint16_t compCount = 1;
constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
// constexpr uint16_t compClassification = 16;
// constexpr uint16_t compIdentifier = 300;
// constexpr uint8_t compClassificationIndex = 20;
// constexpr uint32_t activeCompComparisonStamp = 0xabcdefab;
// constexpr std::array<uint8_t, 8> activeComponentReleaseData = {
// 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
// constexpr uint32_t pendingCompComparisonStamp = 0x12345678;
// constexpr std::array<uint8_t, 8> pendingComponentReleaseData = {
// 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
constexpr std::string_view activeCompVersion{"VersionString3"};
constexpr std::string_view pendingCompVersion{"VersionString4"};
constexpr size_t compParamTableSize =
sizeof(pldm_component_parameter_entry) + activeCompVersion.size() +
pendingCompVersion.size();
constexpr std::array<uint8_t, compParamTableSize> compParamTable{
0x10, 0x00, 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01,
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00, 0x02,
0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74,
0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
constexpr size_t getFwParamsPayloadLen =
sizeof(pldm_get_firmware_parameters_resp) +
activeCompImageSetVersion.size() + pendingCompImageSetVersion.size() +
compParamTableSize;
constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
getFwParamsResponse{
0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01,
0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x10, 0x00,
0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01, 0x02,
0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00,
0x02, 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
auto responseMsg =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
pldm_get_firmware_parameters_resp outResp{};
variable_field outActiveCompImageSetVersion{};
variable_field outPendingCompImageSetVersion{};
variable_field outCompParameterTable{};
auto rc = decode_get_firmware_parameters_resp(
responseMsg, getFwParamsPayloadLen, &outResp,
&outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
&outCompParameterTable);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
EXPECT_EQ(outResp.comp_count, compCount);
EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
activeCompImageSetVersion.size());
EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
pendingCompImageSetVersion.size());
std::string activeCompImageSetVersionStr(
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
outActiveCompImageSetVersion.length);
EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
std::string pendingCompImageSetVersionStr(
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
outPendingCompImageSetVersion.length);
EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
EXPECT_EQ(outCompParameterTable.length, compParamTableSize);
EXPECT_EQ(true, std::equal(outCompParameterTable.ptr,
outCompParameterTable.ptr +
outCompParameterTable.length,
compParamTable.begin(), compParamTable.end()));
}
TEST(GetFirmwareParameters, decodeResponseZeroCompCount)
{
// CapabilitiesDuringUpdate of the firmware device
// FD Host Functionality during Firmware Update [Bit position 2] &
// Component Update Failure Retry Capability [Bit position 1]
constexpr std::bitset<32> fdCapabilities{0x06};
constexpr uint16_t compCount = 0;
constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
constexpr size_t getFwParamsPayloadLen =
sizeof(pldm_get_firmware_parameters_resp) +
activeCompImageSetVersion.size() + pendingCompImageSetVersion.size();
constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
getFwParamsResponse{
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32};
auto responseMsg =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
pldm_get_firmware_parameters_resp outResp{};
variable_field outActiveCompImageSetVersion{};
variable_field outPendingCompImageSetVersion{};
variable_field outCompParameterTable{};
auto rc = decode_get_firmware_parameters_resp(
responseMsg, getFwParamsPayloadLen, &outResp,
&outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
&outCompParameterTable);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
EXPECT_EQ(outResp.comp_count, compCount);
EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
activeCompImageSetVersion.size());
EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
pendingCompImageSetVersion.size());
std::string activeCompImageSetVersionStr(
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
outActiveCompImageSetVersion.length);
EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
std::string pendingCompImageSetVersionStr(
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
outPendingCompImageSetVersion.length);
EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
EXPECT_EQ(outCompParameterTable.ptr, nullptr);
EXPECT_EQ(outCompParameterTable.length, 0);
}
TEST(GetFirmwareParameters,
decodeResponseNoPendingCompImageVersionStrZeroCompCount)
{
// CapabilitiesDuringUpdate of the firmware device
// FD Host Functionality during Firmware Update [Bit position 2] &
// Component Update Failure Retry Capability [Bit position 1]
constexpr std::bitset<32> fdCapabilities{0x06};
constexpr uint16_t compCount = 0;
constexpr std::string_view activeCompImageSetVersion{"VersionString"};
constexpr size_t getFwParamsPayloadLen =
sizeof(pldm_get_firmware_parameters_resp) +
activeCompImageSetVersion.size();
constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
getFwParamsResponse{0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00,
0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x53, 0x74, 0x72, 0x69, 0x6e, 0x67};
auto responseMsg =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
pldm_get_firmware_parameters_resp outResp{};
variable_field outActiveCompImageSetVersion{};
variable_field outPendingCompImageSetVersion{};
variable_field outCompParameterTable{};
auto rc = decode_get_firmware_parameters_resp(
responseMsg, getFwParamsPayloadLen, &outResp,
&outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
&outCompParameterTable);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
EXPECT_EQ(outResp.comp_count, compCount);
EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
activeCompImageSetVersion.size());
EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type,
PLDM_STR_TYPE_UNKNOWN);
EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len, 0);
std::string activeCompImageSetVersionStr(
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
outActiveCompImageSetVersion.length);
EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
EXPECT_EQ(outPendingCompImageSetVersion.ptr, nullptr);
EXPECT_EQ(outPendingCompImageSetVersion.length, 0);
EXPECT_EQ(outCompParameterTable.ptr, nullptr);
EXPECT_EQ(outCompParameterTable.length, 0);
}
TEST(GetFirmwareParameters, decodeResponseErrorCompletionCode)
{
constexpr std::array<uint8_t, hdrSize + sizeof(uint8_t)>
getFwParamsResponse{0x00, 0x00, 0x00, 0x01};
auto responseMsg =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
pldm_get_firmware_parameters_resp outResp{};
variable_field outActiveCompImageSetVersion{};
variable_field outPendingCompImageSetVersion{};
variable_field outCompParameterTable{};
auto rc = decode_get_firmware_parameters_resp(
responseMsg, getFwParamsResponse.size(), &outResp,
&outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
&outCompParameterTable);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(outResp.completion_code, PLDM_ERROR);
}
TEST(GetFirmwareParameters, errorPathdecodeResponse)
{
int rc = 0;
// Invalid ActiveComponentImageSetVersionStringType
constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse1{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
auto responseMsg =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse1.data());
pldm_get_firmware_parameters_resp outResp{};
variable_field outActiveCompImageSetVersion{};
variable_field outPendingCompImageSetVersion{};
variable_field outCompParameterTable{};
rc = decode_get_firmware_parameters_resp(
nullptr, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
&outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
&outCompParameterTable);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_get_firmware_parameters_resp(
responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, nullptr,
&outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
&outCompParameterTable);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_get_firmware_parameters_resp(
responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
nullptr, &outPendingCompImageSetVersion, &outCompParameterTable);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_get_firmware_parameters_resp(
responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
&outActiveCompImageSetVersion, nullptr, &outCompParameterTable);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_get_firmware_parameters_resp(
responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
&outActiveCompImageSetVersion, &outPendingCompImageSetVersion, nullptr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_get_firmware_parameters_resp(
responseMsg, 0, &outResp, &outActiveCompImageSetVersion,
&outPendingCompImageSetVersion, &outCompParameterTable);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_get_firmware_parameters_resp(
responseMsg, invalidGetFwParamsResponse1.size() - 1 - hdrSize, &outResp,
&outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
&outCompParameterTable);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
rc = decode_get_firmware_parameters_resp(
responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
&outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
&outCompParameterTable);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
// Invalid ActiveComponentImageSetVersionStringLength
constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse2{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
responseMsg =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse2.data());
rc = decode_get_firmware_parameters_resp(
responseMsg, invalidGetFwParamsResponse2.size() - hdrSize, &outResp,
&outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
&outCompParameterTable);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
// Invalid PendingComponentImageSetVersionStringType &
// PendingComponentImageSetVersionStringLength
constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse3{
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x00};
responseMsg =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse3.data());
rc = decode_get_firmware_parameters_resp(
responseMsg, invalidGetFwParamsResponse3.size() - hdrSize, &outResp,
&outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
&outCompParameterTable);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
// Invalid PendingComponentImageSetVersionStringType &
// PendingComponentImageSetVersionStringLength
constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse4{
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x0e, 0x06, 0x0e};
responseMsg =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse4.data());
rc = decode_get_firmware_parameters_resp(
responseMsg, invalidGetFwParamsResponse4.size() - hdrSize, &outResp,
&outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
&outCompParameterTable);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
// Total payload length less than expected
constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse5{
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x0e};
responseMsg =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse5.data());
rc = decode_get_firmware_parameters_resp(
responseMsg, invalidGetFwParamsResponse5.size() - hdrSize, &outResp,
&outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
&outCompParameterTable);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
}
TEST(GetFirmwareParameters, goodPathDecodeComponentParameterEntry)
{
// Random value for component classification
constexpr uint16_t compClassification = 0x0a0b;
// Random value for component classification
constexpr uint16_t compIdentifier = 0x0c0d;
// Random value for component classification
constexpr uint32_t timestamp = 0x12345678;
// Random value for component activation methods
constexpr uint16_t compActivationMethods = 0xbbdd;
// Random value for capabilities during update
constexpr uint32_t capabilitiesDuringUpdate = 0xbadbeefe;
// ActiveCompImageSetVerStrLen is not fixed here taking it as 8
constexpr uint8_t activeCompVerStrLen = 8;
// PendingCompImageSetVerStrLen is not fixed here taking it as 8
constexpr uint8_t pendingCompVerStrLen = 8;
constexpr size_t entryLength =
sizeof(struct pldm_component_parameter_entry) + activeCompVerStrLen +
pendingCompVerStrLen;
std::array<uint8_t, entryLength> entry{};
auto inEntry =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<struct pldm_component_parameter_entry*>(entry.data());
inEntry->comp_classification = htole16(compClassification);
inEntry->comp_identifier = htole16(compIdentifier);
inEntry->comp_classification_index = 0x0f;
inEntry->active_comp_comparison_stamp = htole32(timestamp);
inEntry->active_comp_ver_str_type = 1;
inEntry->active_comp_ver_str_len = activeCompVerStrLen;
std::fill_n(inEntry->active_comp_release_date,
sizeof(inEntry->active_comp_release_date), 0xff);
inEntry->pending_comp_comparison_stamp = htole32(timestamp);
inEntry->pending_comp_ver_str_type = 1;
inEntry->pending_comp_ver_str_len = pendingCompVerStrLen;
std::fill_n(inEntry->pending_comp_release_date,
sizeof(inEntry->pending_comp_release_date), 0xff);
inEntry->comp_activation_methods.value = htole16(compActivationMethods);
inEntry->capabilities_during_update.value =
htole32(capabilitiesDuringUpdate);
constexpr auto activeCompVerStrPos =
sizeof(struct pldm_component_parameter_entry);
std::fill_n(entry.data() + activeCompVerStrPos, activeCompVerStrLen, 0xaa);
constexpr auto pendingCompVerStrPos =
activeCompVerStrPos + activeCompVerStrLen;
std::fill_n(entry.data() + pendingCompVerStrPos, pendingCompVerStrLen,
0xbb);
struct pldm_component_parameter_entry outEntry;
struct variable_field outActiveCompVerStr;
struct variable_field outPendingCompVerStr;
auto rc = decode_get_firmware_parameters_resp_comp_entry(
entry.data(), entryLength, &outEntry, &outActiveCompVerStr,
&outPendingCompVerStr);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(outEntry.comp_classification, compClassification);
EXPECT_EQ(outEntry.comp_identifier, compIdentifier);
EXPECT_EQ(inEntry->comp_classification_index,
outEntry.comp_classification_index);
EXPECT_EQ(outEntry.active_comp_comparison_stamp, timestamp);
EXPECT_EQ(inEntry->active_comp_ver_str_type,
outEntry.active_comp_ver_str_type);
EXPECT_EQ(inEntry->active_comp_ver_str_len,
outEntry.active_comp_ver_str_len);
EXPECT_EQ(0, memcmp(inEntry->active_comp_release_date,
outEntry.active_comp_release_date,
sizeof(inEntry->active_comp_release_date)));
EXPECT_EQ(outEntry.pending_comp_comparison_stamp, timestamp);
EXPECT_EQ(inEntry->pending_comp_ver_str_type,
outEntry.pending_comp_ver_str_type);
EXPECT_EQ(inEntry->pending_comp_ver_str_len,
outEntry.pending_comp_ver_str_len);
EXPECT_EQ(0, memcmp(inEntry->pending_comp_release_date,
outEntry.pending_comp_release_date,
sizeof(inEntry->pending_comp_release_date)));
EXPECT_EQ(outEntry.comp_activation_methods.value, compActivationMethods);
EXPECT_EQ(outEntry.capabilities_during_update.value,
capabilitiesDuringUpdate);
EXPECT_EQ(0, memcmp(outActiveCompVerStr.ptr,
entry.data() + activeCompVerStrPos,
outActiveCompVerStr.length));
EXPECT_EQ(0, memcmp(outPendingCompVerStr.ptr,
entry.data() + pendingCompVerStrPos,
outPendingCompVerStr.length));
}
#ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamDevices, goodPathEncodeRequest)
{
constexpr uint8_t instanceId = 1;
std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
auto rc = encode_query_downstream_devices_req(instanceId, requestPtr);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DOWNSTREAM_DEVICES);
}
#endif
#ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamDevices, encodeRequestInvalidData)
{
constexpr uint8_t instanceId = 1;
auto rc = encode_query_downstream_devices_req(instanceId, nullptr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
}
#endif
#ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamDevices, goodPathDecodeResponse)
{
uint8_t completion_code_resp = PLDM_SUCCESS;
uint8_t downstream_device_update_supported_resp =
PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
uint16_t number_of_downstream_devices_resp = 1;
uint16_t max_number_of_downstream_devices_resp = 1;
/** Capabilities of updating downstream devices
* FDP supports downstream devices dynamically attached [Bit position 0] &
* FDP supports downstream devices dynamically removed [Bit position 1]
*/
bitfield32_t capabilities_resp = {.value = 0x0002};
int rc;
std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
responseMsg{};
struct pldm_msgbuf _buf;
struct pldm_msgbuf* buf = &_buf;
rc = pldm_msgbuf_init_cc(buf, 0, responseMsg.data() + hdrSize,
responseMsg.size() - hdrSize);
EXPECT_EQ(rc, PLDM_SUCCESS);
pldm_msgbuf_insert_uint8(buf, completion_code_resp);
pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
struct pldm_query_downstream_devices_resp resp_data;
rc = decode_query_downstream_devices_resp(
response, responseMsg.size() - hdrSize, &resp_data);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(resp_data.completion_code, completion_code_resp);
EXPECT_EQ(resp_data.downstream_device_update_supported,
downstream_device_update_supported_resp);
EXPECT_EQ(resp_data.number_of_downstream_devices,
number_of_downstream_devices_resp);
EXPECT_EQ(resp_data.max_number_of_downstream_devices,
max_number_of_downstream_devices_resp);
EXPECT_EQ(resp_data.capabilities.value, capabilities_resp.value);
}
#endif
#ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamDevices, decodeRequestUndefinedValue)
{
uint8_t completion_code_resp = PLDM_SUCCESS;
uint8_t downstream_device_update_supported_resp = 0xe; /*Undefined value*/
uint16_t number_of_downstream_devices_resp = 1;
uint16_t max_number_of_downstream_devices_resp = 1;
/** Capabilities of updating downstream devices
* FDP supports downstream devices dynamically attached [Bit position 0] &
* FDP supports downstream devices dynamically removed [Bit position 1]
*/
bitfield32_t capabilities_resp = {.value = 0x0002};
int rc;
std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
responseMsg{};
struct pldm_msgbuf _buf;
struct pldm_msgbuf* buf = &_buf;
rc = pldm_msgbuf_init_cc(buf, 0, responseMsg.data() + hdrSize,
responseMsg.size() - hdrSize);
EXPECT_EQ(rc, PLDM_SUCCESS);
pldm_msgbuf_insert_uint8(buf, completion_code_resp);
pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
struct pldm_query_downstream_devices_resp resp_data;
rc = decode_query_downstream_devices_resp(
response, responseMsg.size() - hdrSize, &resp_data);
ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
}
#endif
#ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamDevices, decodeRequestErrorBufSize)
{
uint8_t completion_code_resp = PLDM_SUCCESS;
uint8_t downstream_device_update_supported_resp =
PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
uint16_t number_of_downstream_devices_resp = 1;
uint16_t max_number_of_downstream_devices_resp = 1;
/** Capabilities of updating downstream devices
* FDP supports downstream devices dynamically attached [Bit position 0] &
* FDP supports downstream devices dynamically removed [Bit position 1]
*/
bitfield32_t capabilities_resp = {.value = 0x0002};
int rc;
std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES -
2 /* Inject error length*/>
responseMsg{};
struct pldm_msgbuf _buf;
struct pldm_msgbuf* buf = &_buf;
rc = pldm_msgbuf_init_cc(buf, 0, responseMsg.data() + hdrSize,
responseMsg.size() - hdrSize);
EXPECT_EQ(rc, PLDM_SUCCESS);
pldm_msgbuf_insert_uint8(buf, completion_code_resp);
pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
// Inject error value
pldm_msgbuf_insert_uint16(buf, (uint16_t)capabilities_resp.value);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
struct pldm_query_downstream_devices_resp resp_data;
rc = decode_query_downstream_devices_resp(
response, responseMsg.size() - hdrSize, &resp_data);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
}
#endif
#ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamIdentifiers, goodPathEncodeRequest)
{
constexpr uint8_t instanceId = 1;
constexpr uint32_t dataTransferHandle = 0xFFFFFFFF;
constexpr enum transfer_op_flag transferOperationFlag = PLDM_GET_FIRSTPART;
constexpr size_t payload_length =
PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
std::array<uint8_t, hdrSize + payload_length> requestMsg{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
auto rc = encode_query_downstream_identifiers_req(
instanceId, dataTransferHandle, transferOperationFlag, requestPtr,
payload_length);
EXPECT_EQ(rc, PLDM_SUCCESS);
std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES>
expectedReq{0x81, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x01};
EXPECT_EQ(requestMsg, expectedReq);
}
#endif
#ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamIdentifiers, encodeRequestInvalidErrorPaths)
{
constexpr uint8_t instanceId = 1;
constexpr uint32_t dataTransferHandle = 0x0;
constexpr enum transfer_op_flag transferOperationFlag = PLDM_GET_FIRSTPART;
constexpr enum transfer_op_flag invalidTransferOperationFlag =
PLDM_ACKNOWLEDGEMENT_ONLY;
constexpr size_t payload_length =
PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
std::array<uint8_t, hdrSize + payload_length> requestMsg{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
auto rc = encode_query_downstream_identifiers_req(
instanceId, dataTransferHandle, transferOperationFlag, nullptr,
payload_length);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = encode_query_downstream_identifiers_req(
instanceId, dataTransferHandle, transferOperationFlag, requestPtr,
payload_length - 1);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
rc = encode_query_downstream_identifiers_req(instanceId, dataTransferHandle,
invalidTransferOperationFlag,
requestPtr, payload_length);
EXPECT_EQ(rc, PLDM_INVALID_TRANSFER_OPERATION_FLAG);
}
#endif
#ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamIdentifiers, goodPathDecodeResponse)
{
// Len is not fixed here taking it as 9, contains 1 downstream device with
// 1 descriptor
constexpr uint32_t downstreamDevicesLen = 9;
constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
constexpr uint32_t next_data_transfer_handle_resp = 0x0;
constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
const uint32_t downstream_devices_length_resp =
htole32(downstreamDevicesLen);
constexpr uint16_t number_of_downstream_devices_resp = 1;
std::array<uint8_t, hdrSize +
PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN +
downstreamDevicesLen>
responseMsg{};
int rc = 0;
struct pldm_msgbuf _buf;
struct pldm_msgbuf* buf = &_buf;
rc = pldm_msgbuf_init_cc(buf, 0, responseMsg.data() + hdrSize,
responseMsg.size() - hdrSize);
EXPECT_EQ(rc, PLDM_SUCCESS);
pldm_msgbuf_insert_uint8(buf, complition_code_resp);
pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
/** Filling descriptor data, the correctness of the downstream devices data
* is not checked in this test case so filling with 0xff
*/
std::fill_n(responseMsg.data() + hdrSize +
PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN,
downstreamDevicesLen, 0xff);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
struct pldm_query_downstream_identifiers_resp resp_data = {};
struct variable_field downstreamDevices = {};
rc = decode_query_downstream_identifiers_resp(
response, responseMsg.size() - hdrSize, &resp_data, &downstreamDevices);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(resp_data.completion_code, complition_code_resp);
EXPECT_EQ(resp_data.next_data_transfer_handle,
next_data_transfer_handle_resp);
EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
EXPECT_EQ(resp_data.downstream_devices_length,
downstream_devices_length_resp);
EXPECT_EQ(resp_data.number_of_downstream_devices,
number_of_downstream_devices_resp);
EXPECT_EQ(downstreamDevices.length, downstreamDevicesLen);
EXPECT_EQ(true,
std::equal(downstreamDevices.ptr,
downstreamDevices.ptr + downstreamDevices.length,
responseMsg.begin() + hdrSize +
PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN,
responseMsg.end()));
}
#endif
#ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamIdentifiers, decodeRequestErrorPaths)
{
std::array<uint8_t, hdrSize + sizeof(uint8_t)> responseMsg{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
struct pldm_query_downstream_identifiers_resp resp_data = {};
struct variable_field downstreamDevices = {};
// Test nullptr
auto rc = decode_query_downstream_identifiers_resp(
nullptr, responseMsg.size() - hdrSize, nullptr, &downstreamDevices);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
// Test not PLDM_SUCCESS completion code
response->payload[0] = PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
rc = decode_query_downstream_identifiers_resp(
response, responseMsg.size() - hdrSize, &resp_data, &downstreamDevices);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(resp_data.completion_code, PLDM_ERROR_UNSUPPORTED_PLDM_CMD);
// Test payload length less than minimum length
response->payload[0] = PLDM_SUCCESS;
rc = decode_query_downstream_identifiers_resp(
response, responseMsg.size() - hdrSize, &resp_data, &downstreamDevices);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
}
#endif
#ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamIdentifiers, decodeRequestErrorDownstreamDevicesSize)
{
// Len is not fixed here taking it as 9, contains 1 downstream device with
// 1 descriptor
constexpr uint32_t actualDownstreamDevicesLen = 9;
constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
constexpr uint32_t next_data_transfer_handle_resp = 0x0;
constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
const uint32_t downstream_devices_length_resp =
htole32(actualDownstreamDevicesLen + 1 /* inject error length*/);
constexpr uint16_t number_of_downstream_devices_resp = 1;
std::array<uint8_t, hdrSize +
PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN +
actualDownstreamDevicesLen>
responseMsg{};
int rc = 0;
struct pldm_msgbuf _buf;
struct pldm_msgbuf* buf = &_buf;
rc = pldm_msgbuf_init_cc(buf, 0, responseMsg.data() + hdrSize,
responseMsg.size() - hdrSize);
EXPECT_EQ(rc, PLDM_SUCCESS);
pldm_msgbuf_insert_uint8(buf, complition_code_resp);
pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
/** Filling descriptor data, the correctness of the downstream devices data
* is not checked in this test case so filling with 0xff
*/
std::fill_n(responseMsg.data() + hdrSize +
PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN,
actualDownstreamDevicesLen, 0xff);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
struct pldm_query_downstream_identifiers_resp resp_data = {};
struct variable_field downstreamDevices = {};
/** In test mode, this will trigger an assert failure and cause the unit
* test to fail if only testing by the rc. Use ASSERT_DEATH to test this
* scenario.
*
* The 1st parameter is the function under test.
* The 2nd parameter compares the output of the program.
*/
#ifdef NDEBUG
EXPECT_NE(decode_query_downstream_identifiers_resp(
response, responseMsg.size() - hdrSize, &resp_data,
&downstreamDevices),
PLDM_SUCCESS);
#else
EXPECT_DEATH(
decode_query_downstream_identifiers_resp(
response, responseMsg.size() - hdrSize, &resp_data,
&downstreamDevices),
// This error doesn't output any error message, leave it be empty
"");
#endif
}
#endif
#ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamIdentifiers, decodeRequestErrorBufSize)
{
constexpr uint32_t actualDownstreamDevicesLen = 0;
constexpr uint16_t number_of_downstream_devices_resp = 1;
constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
constexpr uint32_t next_data_transfer_handle_resp = 0x0;
constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
const uint32_t downstream_devices_length_resp =
htole32(actualDownstreamDevicesLen);
std::array<uint8_t, hdrSize +
PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN -
1 /* Inject error length*/>
responseMsg{};
int rc = 0;
struct pldm_msgbuf _buf;
struct pldm_msgbuf* buf = &_buf;
rc = pldm_msgbuf_init_cc(buf, 0, responseMsg.data() + hdrSize,
responseMsg.size() - hdrSize);
EXPECT_EQ(rc, PLDM_SUCCESS);
pldm_msgbuf_insert_uint8(buf, complition_code_resp);
pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
// Inject error buffer size
pldm_msgbuf_insert_uint8(buf, (uint8_t)number_of_downstream_devices_resp);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
struct pldm_query_downstream_identifiers_resp resp_data = {};
struct variable_field downstreamDevices = {};
rc = decode_query_downstream_identifiers_resp(
response, responseMsg.size() - hdrSize, &resp_data, &downstreamDevices);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
}
#endif
#ifdef LIBPLDM_API_TESTING
TEST(GetDownstreamFirmwareParameters, goodPathEncodeRequest)
{
constexpr uint8_t instanceId = 1;
constexpr uint32_t dataTransferHandle = 0x0;
constexpr enum transfer_op_flag transferOperationFlag = PLDM_GET_FIRSTPART;
constexpr size_t payload_length =
PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_REQ_BYTES;
std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
auto rc = encode_get_downstream_firmware_params_req(
instanceId, dataTransferHandle, transferOperationFlag, requestPtr,
payload_length);
EXPECT_EQ(rc, 0);
std::array<uint8_t, hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_REQ_BYTES>
expectedReq{0x81, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01};
EXPECT_EQ(requestMsg, expectedReq);
}
#endif
#ifdef LIBPLDM_API_TESTING
TEST(GetDownstreamFirmwareParameters, encodeRequestInvalidTransferOperationFlag)
{
constexpr uint8_t instanceId = 1;
constexpr uint32_t dataTransferHandle = 0x0;
// Setup invalid transfer operation flag
constexpr enum transfer_op_flag transferOperationFlag =
PLDM_ACKNOWLEDGEMENT_ONLY;
constexpr size_t payload_length =
PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_REQ_BYTES;
std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
auto rc = encode_get_downstream_firmware_params_req(
instanceId, dataTransferHandle, transferOperationFlag, requestPtr,
payload_length);
EXPECT_EQ(rc, -EBADMSG);
}
#endif
#ifdef LIBPLDM_API_TESTING
TEST(GetDownstreamFirmwareParameters, encodeRequestErrorBufSize)
{
constexpr uint8_t instanceId = 1;
constexpr uint32_t dataTransferHandle = 0x0;
// Setup invalid transfer operation flag
constexpr enum transfer_op_flag transferOperationFlag =
PLDM_ACKNOWLEDGEMENT_ONLY;
constexpr size_t payload_length =
PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_REQ_BYTES -
1 /* inject erro length*/;
std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
auto rc = encode_get_downstream_firmware_params_req(
instanceId, dataTransferHandle, transferOperationFlag, requestPtr,
payload_length);
EXPECT_EQ(rc, -EOVERFLOW);
}
#endif
#ifdef LIBPLDM_API_TESTING
TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponse)
{
/** Count is not fixed here taking it as 1, and the downstream device's
* version strings length are set to 8
*/
constexpr uint16_t downstreamDeviceCount = 1;
constexpr uint8_t activeComponentVersionStringLength = 8;
constexpr uint8_t pendingComponentVersionStringLength = 8;
constexpr size_t downstreamDeviceParamTableLen =
sizeof(pldm_component_parameter_entry) +
activeComponentVersionStringLength +
pendingComponentVersionStringLength;
constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
constexpr uint32_t next_data_transfer_handle_resp = 0x0;
constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
std::array<uint8_t, hdrSize +
PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_RESP_MIN_LEN +
downstreamDeviceParamTableLen>
responseMsg{};
int rc = 0;
struct pldm_msgbuf _buf;
struct pldm_msgbuf* buf = &_buf;
rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
responseMsg.size() - hdrSize);
EXPECT_EQ(rc, 0);
pldm_msgbuf_insert_uint8(buf, complition_code_resp);
pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
/** Filling paramter table, the correctness of the downstream devices data
* is not checked in this test case so filling with 0xff
*/
std::fill_n(responseMsg.data() + hdrSize +
PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_RESP_MIN_LEN,
downstreamDeviceParamTableLen, 0xff);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto table = reinterpret_cast<pldm_component_parameter_entry*>(
responseMsg.data() + hdrSize +
PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_RESP_MIN_LEN);
table->active_comp_ver_str_len = activeComponentVersionStringLength;
table->pending_comp_ver_str_len = pendingComponentVersionStringLength;
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
struct pldm_get_downstream_firmware_params_resp resp_data = {};
struct variable_field downstreamDeviceParamTable = {};
rc = decode_get_downstream_firmware_params_resp(
response, responseMsg.size() - hdrSize, &resp_data,
&downstreamDeviceParamTable);
EXPECT_EQ(rc, 0);
EXPECT_EQ(resp_data.completion_code, complition_code_resp);
EXPECT_EQ(resp_data.next_data_transfer_handle,
next_data_transfer_handle_resp);
EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
EXPECT_EQ(downstreamDeviceParamTable.length, downstreamDeviceParamTableLen);
EXPECT_EQ(true,
std::equal(downstreamDeviceParamTable.ptr,
downstreamDeviceParamTable.ptr +
downstreamDeviceParamTable.length,
responseMsg.begin() + hdrSize +
PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_RESP_MIN_LEN,
responseMsg.end()));
}
#endif
#ifdef LIBPLDM_API_TESTING
TEST(GetDownstreamFirmwareParameters, decodeResponseInvalidLength)
{
/** Count is not fixed here taking it as 1, and the downstream device's
* version strings length are set to 8
*/
constexpr uint16_t downstreamDeviceCount = 1;
constexpr uint8_t activeComponentVersionStringLength = 8;
constexpr uint8_t pendingComponentVersionStringLength = 8;
constexpr size_t downstreamDeviceParamTableLen =
PLDM_DOWNSTREAM_DEVICE_PARAMETER_ENTRY_MIN_LEN +
activeComponentVersionStringLength +
pendingComponentVersionStringLength;
constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
constexpr uint32_t next_data_transfer_handle_resp = 0x0;
constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
std::array<uint8_t,
hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_RESP_MIN_LEN +
downstreamDeviceParamTableLen - 1 /* inject error length*/>
responseMsg{};
int rc = 0;
struct pldm_msgbuf _buf;
struct pldm_msgbuf* buf = &_buf;
rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
responseMsg.size() - hdrSize);
EXPECT_EQ(rc, 0);
pldm_msgbuf_insert_uint8(buf, complition_code_resp);
pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
/** Filling paramter table, the correctness of the downstream devices data
* is not checked in this test case so filling with 0xff
*/
std::fill_n(responseMsg.data() + hdrSize +
PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_RESP_MIN_LEN,
downstreamDeviceParamTableLen - 1 /* inject error length*/,
0xff);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
struct pldm_get_downstream_firmware_params_resp resp_data = {};
struct variable_field downstreamDeviceParamTable = {};
rc = decode_get_downstream_firmware_params_resp(
response, responseMsg.size() - hdrSize, &resp_data,
&downstreamDeviceParamTable);
EXPECT_EQ(rc, 0);
pldm_downstream_device_parameter_entry entry{};
variable_field versions{};
/** In test mode, this will trigger an assert failure and cause the unit
* test to fail if only testing by the rc. Use ASSERT_DEATH to test this
* scenario.
*
* The 1st parameter is the function under test.
* The 2nd parameter compares the output of the program.
*/
#ifdef NDEBUG
EXPECT_NE(decode_downstream_device_parameter_table_entry(
&downstreamDeviceParamTable, &entry, &versions),
0);
#else
EXPECT_DEATH(
decode_downstream_device_parameter_table_entry(
&downstreamDeviceParamTable, &entry, &versions),
// This error doesn't output any error message, leave it be empty
"");
#endif
}
#endif
#ifdef LIBPLDM_API_TESTING
TEST(GetDownstreamFirmwareParameters, goodPathDecodeDownstreamDeviceParamTable)
{
// Arbitrary downstream device index
constexpr uint16_t downstreamDeviceIndex = 1;
// Arbitrary value for component classification
constexpr uint32_t comparisonStamp = 0x12345678;
// Arbitrary value for component activation methods
constexpr uint16_t compActivationMethods = 0xbbdd;
// Arbitrary value for capabilities during update
constexpr uint32_t capabilitiesDuringUpdate = 0xbadbeefe;
// ActiveCompImageSetVerStrLen is not fixed here taking it as 8
constexpr uint8_t activeCompVerStrLen = 8;
// PendingCompImageSetVerStrLen is not fixed here taking it as 8
constexpr uint8_t pendingCompVerStrLen = 8;
// Arbitrary value for release date
constexpr char release_date[8] = {'2', '0', '2', '4', '0', '6', '2', '1'};
// Arbitrary version strings
constexpr char activeCompVerStr[activeCompVerStrLen] = {'1', '2', '3', '4',
'5', '6', '7', '8'};
constexpr char pendingCompVerStr[pendingCompVerStrLen] = {
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
std::array<uint8_t, PLDM_DOWNSTREAM_DEVICE_PARAMETER_ENTRY_MIN_LEN +
activeCompVerStrLen + pendingCompVerStrLen>
responseMsg{};
int rc = 0;
struct pldm_msgbuf _buf;
struct pldm_msgbuf* buf = &_buf;
rc = pldm_msgbuf_init_errno(buf,
PLDM_DOWNSTREAM_DEVICE_PARAMETER_ENTRY_MIN_LEN,
responseMsg.data(), responseMsg.size());
EXPECT_EQ(rc, 0);
pldm_msgbuf_insert_uint16(buf, downstreamDeviceIndex);
pldm_msgbuf_insert_uint32(buf, comparisonStamp);
pldm_msgbuf_insert_uint8(buf, (uint8_t)PLDM_STR_TYPE_ASCII);
pldm_msgbuf_insert_uint8(buf, activeCompVerStrLen);
rc = pldm_msgbuf_insert_array_char(buf, sizeof(release_date), release_date,
sizeof(release_date));
ASSERT_EQ(rc, 0);
pldm_msgbuf_insert_uint32(buf, comparisonStamp);
pldm_msgbuf_insert_uint8(buf, (uint8_t)PLDM_STR_TYPE_ASCII);
pldm_msgbuf_insert_uint8(buf, pendingCompVerStrLen);
rc = pldm_msgbuf_insert_array_char(buf, sizeof(release_date), release_date,
sizeof(release_date));
ASSERT_EQ(rc, 0);
pldm_msgbuf_insert_uint16(buf, compActivationMethods);
pldm_msgbuf_insert_uint32(buf, capabilitiesDuringUpdate);
rc = pldm_msgbuf_insert_array_char(
buf, activeCompVerStrLen, activeCompVerStr, sizeof(activeCompVerStr));
ASSERT_EQ(rc, 0);
rc = pldm_msgbuf_insert_array_char(buf, pendingCompVerStrLen,
pendingCompVerStr,
sizeof(pendingCompVerStr));
ASSERT_EQ(rc, 0);
variable_field rawData = {.ptr = responseMsg.data(),
.length = responseMsg.size()};
struct pldm_downstream_device_parameter_entry_versions entry_version = {};
struct variable_field versions = {};
const uint8_t* original_ptr = rawData.ptr;
rc = decode_downstream_device_parameter_table_entry(
&rawData, &entry_version.entry, &versions);
EXPECT_EQ(rc, 0);
EXPECT_EQ(rawData.ptr, original_ptr +
PLDM_DOWNSTREAM_DEVICE_PARAMETER_ENTRY_MIN_LEN +
entry_version.entry.active_comp_ver_str_len +
entry_version.entry.pending_comp_ver_str_len);
EXPECT_EQ(rawData.length, 0);
// Further decode the version strings
rc = decode_downstream_device_parameter_table_entry_versions(
&versions, &entry_version.entry, entry_version.active_comp_ver_str,
entry_version.pending_comp_ver_str);
struct pldm_downstream_device_parameter_entry entry = entry_version.entry;
EXPECT_EQ(rc, 0);
// Verify the decoded table entry
EXPECT_EQ(entry.downstream_device_index, downstreamDeviceIndex);
EXPECT_EQ(entry.active_comp_comparison_stamp, comparisonStamp);
EXPECT_EQ(entry.active_comp_ver_str_type, PLDM_STR_TYPE_ASCII);
EXPECT_EQ(entry.active_comp_ver_str_len, activeCompVerStrLen);
EXPECT_EQ(0, memcmp(entry.active_comp_release_date, release_date,
sizeof(release_date)));
EXPECT_EQ(entry.pending_comp_comparison_stamp, comparisonStamp);
EXPECT_EQ(entry.pending_comp_ver_str_type, PLDM_STR_TYPE_ASCII);
EXPECT_EQ(entry.pending_comp_ver_str_len, pendingCompVerStrLen);
EXPECT_EQ(0, memcmp(entry.pending_comp_release_date, release_date,
sizeof(release_date)));
EXPECT_EQ(entry.comp_activation_methods.value, compActivationMethods);
EXPECT_EQ(entry.capabilities_during_update.value, capabilitiesDuringUpdate);
EXPECT_EQ(entry.active_comp_ver_str_len + entry.pending_comp_ver_str_len,
versions.length);
EXPECT_EQ(0, memcmp(versions.ptr, activeCompVerStr, activeCompVerStrLen));
EXPECT_EQ(0, memcmp(versions.ptr + entry.active_comp_ver_str_len,
pendingCompVerStr, pendingCompVerStrLen));
// Verify version strings
EXPECT_EQ(0, memcmp(entry_version.entry.active_comp_ver_str,
activeCompVerStr, activeCompVerStrLen));
EXPECT_EQ('\0',
entry_version.entry.active_comp_ver_str[activeCompVerStrLen]);
EXPECT_EQ(0, memcmp(entry_version.entry.pending_comp_ver_str,
pendingCompVerStr, pendingCompVerStrLen));
EXPECT_EQ('\0',
entry_version.entry.pending_comp_ver_str[pendingCompVerStrLen]);
EXPECT_EQ(0, memcmp(entry_version.active_comp_ver_str, activeCompVerStr,
activeCompVerStrLen));
EXPECT_EQ('\0', entry_version.active_comp_ver_str[activeCompVerStrLen]);
EXPECT_EQ(0, memcmp(entry_version.pending_comp_ver_str, pendingCompVerStr,
pendingCompVerStrLen));
EXPECT_EQ('\0', entry_version.pending_comp_ver_str[pendingCompVerStrLen]);
}
#endif
#ifdef LIBPLDM_API_TESTING
TEST(GetDownstreamFirmwareParameters, goodPathDecodeDownstreamTableVersions)
{
// Arbitrary component version string length
constexpr uint8_t activeCompVerStrLen = 8;
constexpr uint8_t pendingCompVerStrLen = 8;
// Arbitrary ActiveVersionStr and pendingVersionStr
constexpr char versionsStr[] = {'1', '2', '3', '4', '5', '6', '7', '8',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
const struct variable_field versions = {
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
.ptr = reinterpret_cast<const uint8_t*>(versionsStr),
.length = sizeof(versionsStr)};
struct pldm_downstream_device_parameter_entry_versions entryVersion = {};
entryVersion.entry.active_comp_ver_str_len = activeCompVerStrLen;
entryVersion.entry.pending_comp_ver_str_len = pendingCompVerStrLen;
int rc = decode_downstream_device_parameter_table_entry_versions(
&versions, &entryVersion.entry, entryVersion.active_comp_ver_str,
entryVersion.pending_comp_ver_str);
EXPECT_EQ(rc, 0);
EXPECT_EQ(0, memcmp(entryVersion.active_comp_ver_str, versions.ptr,
activeCompVerStrLen));
EXPECT_EQ('\0', entryVersion.active_comp_ver_str[activeCompVerStrLen]);
EXPECT_EQ(0,
memcmp(entryVersion.pending_comp_ver_str,
versions.ptr + activeCompVerStrLen, pendingCompVerStrLen));
EXPECT_EQ('\0', entryVersion.pending_comp_ver_str[activeCompVerStrLen]);
EXPECT_EQ(0, memcmp(entryVersion.entry.active_comp_ver_str, versions.ptr,
activeCompVerStrLen));
EXPECT_EQ('\0',
entryVersion.entry.pending_comp_ver_str[activeCompVerStrLen]);
EXPECT_EQ(0,
memcmp(entryVersion.entry.pending_comp_ver_str,
versions.ptr + activeCompVerStrLen, pendingCompVerStrLen));
EXPECT_EQ('\0',
entryVersion.entry.pending_comp_ver_str[activeCompVerStrLen]);
}
#endif
#ifdef LIBPLDM_API_TESTING
TEST(GetDownstreamFirmwareParameters, decodeInvalidDownstreamTableVersions)
{
// Arbitrary ActiveVersionStr and pendingVersionStr
constexpr char versionsStr[] = {'1', '2', '3', '4', '5', '6', '7', '8',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
const struct variable_field versions = {
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
.ptr = reinterpret_cast<const uint8_t*>(versionsStr),
.length = sizeof(versionsStr)};
struct pldm_downstream_device_parameter_entry_versions entryVersion = {};
int rc = decode_downstream_device_parameter_table_entry_versions(
&versions, nullptr, entryVersion.active_comp_ver_str,
entryVersion.pending_comp_ver_str);
EXPECT_EQ(rc, -EINVAL);
}
#endif
#ifdef LIBPLDM_API_TESTING
TEST(GetDownstreamFirmwareParameters, decodeOverflowDownstreamTableVersions)
{
// Arbitrary component version string length
constexpr uint8_t activeCompVerStrLen = 8;
constexpr uint8_t pendingCompVerStrLen = 8;
// Arbitrary ActiveVersionStr and pendingVersionStr
constexpr char versionsStr[] = {'1', '2', '3', '4', '5', '6', '7', '8',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
const struct variable_field versions = {
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
.ptr = reinterpret_cast<const uint8_t*>(versionsStr),
.length = sizeof(versionsStr) - 1 // Inject error length
};
struct pldm_downstream_device_parameter_entry_versions entryVersion = {};
entryVersion.entry.active_comp_ver_str_len = activeCompVerStrLen;
entryVersion.entry.pending_comp_ver_str_len = pendingCompVerStrLen;
EXPECT_EQ(decode_downstream_device_parameter_table_entry_versions(
&versions, &entryVersion.entry,
entryVersion.active_comp_ver_str,
entryVersion.pending_comp_ver_str),
-EOVERFLOW);
}
#endif
TEST(RequestUpdate, goodPathEncodeRequest)
{
constexpr uint8_t instanceId = 1;
constexpr uint32_t maxTransferSize = 512;
constexpr uint16_t numOfComp = 3;
constexpr uint8_t maxOutstandingTransferReq = 2;
constexpr uint16_t pkgDataLen = 0x1234;
constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
constexpr uint8_t compImgSetVerStrLen =
static_cast<uint8_t>(compImgSetVerStr.size());
variable_field compImgSetVerStrInfo{};
compImgSetVerStrInfo.ptr =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
compImgSetVerStrInfo.length = compImgSetVerStrLen;
std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
compImgSetVerStrLen>
request{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
auto rc = encode_request_update_req(
instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
&compImgSetVerStrInfo, requestMsg,
sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
EXPECT_EQ(rc, PLDM_SUCCESS);
std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
compImgSetVerStrLen>
outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00,
0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e,
0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30};
EXPECT_EQ(request, outRequest);
}
TEST(RequestUpdate, errorPathEncodeRequest)
{
constexpr uint8_t instanceId = 1;
uint32_t maxTransferSize = 512;
constexpr uint16_t numOfComp = 3;
uint8_t maxOutstandingTransferReq = 2;
constexpr uint16_t pkgDataLen = 0x1234;
constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
variable_field compImgSetVerStrInfo{};
compImgSetVerStrInfo.ptr =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
compImgSetVerStrInfo.length = compImgSetVerStrLen;
std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
compImgSetVerStr.size()>
request{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
auto rc = encode_request_update_req(
instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr,
requestMsg,
sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
compImgSetVerStrInfo.ptr = nullptr;
rc = encode_request_update_req(
instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
&compImgSetVerStrInfo, requestMsg,
sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
compImgSetVerStrInfo.ptr =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
rc = encode_request_update_req(
instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
&compImgSetVerStrInfo, nullptr,
sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp,
maxOutstandingTransferReq, pkgDataLen,
PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
&compImgSetVerStrInfo, requestMsg, 0);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
compImgSetVerStrLen = 0;
rc = encode_request_update_req(
instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr,
sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
compImgSetVerStrInfo.length = 0xffff;
rc = encode_request_update_req(
instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
&compImgSetVerStrInfo, nullptr,
sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
compImgSetVerStrInfo.length = compImgSetVerStrLen;
maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1;
rc = encode_request_update_req(
instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
&compImgSetVerStrInfo, nullptr,
sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE;
maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ - 1;
rc = encode_request_update_req(
instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
&compImgSetVerStrInfo, nullptr,
sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ;
rc = encode_request_update_req(
instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen,
&compImgSetVerStrInfo, nullptr,
sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
}
TEST(RequestUpdate, goodPathDecodeResponse)
{
constexpr uint16_t fdMetaDataLen = 1024;
constexpr uint8_t fdWillSendPkgData = 1;
constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)>
requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01};
auto responseMsg1 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data());
uint8_t outCompletionCode = 0;
uint16_t outFdMetaDataLen = 0;
uint8_t outFdWillSendPkgData = 0;
auto rc = decode_request_update_resp(
responseMsg1, requestUpdateResponse1.size() - hdrSize,
&outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(outCompletionCode, PLDM_SUCCESS);
EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen);
EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData);
outCompletionCode = 0;
outFdMetaDataLen = 0;
outFdWillSendPkgData = 0;
constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)>
requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
auto responseMsg2 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data());
rc = decode_request_update_resp(
responseMsg2, requestUpdateResponse2.size() - hdrSize,
&outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
}
TEST(RequestUpdate, errorPathDecodeResponse)
{
constexpr std::array<uint8_t,
hdrSize + sizeof(pldm_request_update_resp) - 1>
requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
auto responseMsg =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data());
uint8_t outCompletionCode = 0;
uint16_t outFdMetaDataLen = 0;
uint8_t outFdWillSendPkgData = 0;
auto rc = decode_request_update_resp(
nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
&outFdMetaDataLen, &outFdWillSendPkgData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_request_update_resp(
responseMsg, requestUpdateResponse.size() - hdrSize, nullptr,
&outFdMetaDataLen, &outFdWillSendPkgData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_request_update_resp(
responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
nullptr, &outFdWillSendPkgData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_request_update_resp(
responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
&outFdMetaDataLen, nullptr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode,
&outFdMetaDataLen, &outFdWillSendPkgData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_request_update_resp(
responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
&outFdMetaDataLen, &outFdWillSendPkgData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
}
TEST(PassComponentTable, goodPathEncodeRequest)
{
constexpr uint8_t instanceId = 1;
constexpr uint16_t compIdentifier = 400;
constexpr uint8_t compClassificationIndex = 40;
constexpr uint32_t compComparisonStamp = 0x12345678;
constexpr std::string_view compVerStr = "0penBmcv1.1";
constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
variable_field compVerStrInfo{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
compVerStrInfo.length = compVerStrLen;
std::array<uint8_t,
hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
request{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
auto rc = encode_pass_component_table_req(
instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
compVerStrLen, &compVerStrInfo, requestMsg,
sizeof(pldm_pass_component_table_req) + compVerStrLen);
EXPECT_EQ(rc, PLDM_SUCCESS);
std::array<uint8_t,
hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28,
0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65,
0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31};
EXPECT_EQ(request, outRequest);
}
TEST(PassComponentTable, errorPathEncodeRequest)
{
constexpr uint8_t instanceId = 1;
constexpr uint16_t compIdentifier = 400;
constexpr uint8_t compClassificationIndex = 40;
constexpr uint32_t compComparisonStamp = 0x12345678;
constexpr std::string_view compVerStr = "0penBmcv1.1";
constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
variable_field compVerStrInfo{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
compVerStrInfo.length = compVerStrLen;
std::array<uint8_t,
hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
request{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
auto rc = encode_pass_component_table_req(
instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
compVerStrLen, nullptr, requestMsg,
sizeof(pldm_pass_component_table_req) + compVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
compVerStrInfo.ptr = nullptr;
rc = encode_pass_component_table_req(
instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
compVerStrLen, &compVerStrInfo, requestMsg,
sizeof(pldm_pass_component_table_req) + compVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
rc = encode_pass_component_table_req(
instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
compVerStrLen, &compVerStrInfo, nullptr,
sizeof(pldm_pass_component_table_req) + compVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = encode_pass_component_table_req(
instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
compVerStrLen, &compVerStrInfo, requestMsg,
sizeof(pldm_pass_component_table_req));
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
rc = encode_pass_component_table_req(
instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0,
&compVerStrInfo, requestMsg,
sizeof(pldm_pass_component_table_req) + compVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = encode_pass_component_table_req(
instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
compVerStrLen - 1, &compVerStrInfo, requestMsg,
sizeof(pldm_pass_component_table_req) + compVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = encode_pass_component_table_req(
instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier,
compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
compVerStrLen, &compVerStrInfo, requestMsg,
sizeof(pldm_pass_component_table_req) + compVerStrLen);
EXPECT_EQ(rc, PLDM_INVALID_TRANSFER_OPERATION_FLAG);
rc = encode_pass_component_table_req(
instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN,
compVerStrLen, &compVerStrInfo, requestMsg,
sizeof(pldm_pass_component_table_req) + compVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
}
TEST(PassComponentTable, goodPathDecodeResponse)
{
constexpr std::array<uint8_t,
hdrSize + sizeof(pldm_pass_component_table_resp)>
passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
auto responseMsg1 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
uint8_t completionCode = 0;
uint8_t compResp = 0;
uint8_t compRespCode = 0;
auto rc = decode_pass_component_table_resp(
responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode,
&compResp, &compRespCode);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(completionCode, PLDM_SUCCESS);
EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL);
constexpr std::array<uint8_t,
hdrSize + sizeof(pldm_pass_component_table_resp)>
passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0};
auto responseMsg2 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
rc = decode_pass_component_table_resp(
responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
&compResp, &compRespCode);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(completionCode, PLDM_SUCCESS);
EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN);
constexpr std::array<uint8_t,
hdrSize + sizeof(pldm_pass_component_table_resp)>
passCompTableResponse3{0x00, 0x00, 0x00, 0x80};
auto responseMsg3 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
rc = decode_pass_component_table_resp(
responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
&compResp, &compRespCode);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
}
TEST(PassComponentTable, errorPathDecodeResponse)
{
constexpr std::array<uint8_t,
hdrSize + sizeof(pldm_pass_component_table_resp) - 1>
passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00};
auto responseMsg1 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
uint8_t completionCode = 0;
uint8_t compResp = 0;
uint8_t compRespCode = 0;
auto rc = decode_pass_component_table_resp(
nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode,
&compResp, &compRespCode);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_pass_component_table_resp(
responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr,
&compResp, &compRespCode);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_pass_component_table_resp(
responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
&completionCode, nullptr, &compRespCode);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_pass_component_table_resp(
responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
&completionCode, &compResp, nullptr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode,
&compResp, &compRespCode);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_pass_component_table_resp(
responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
&completionCode, &compResp, &compRespCode);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
constexpr std::array<uint8_t,
hdrSize + sizeof(pldm_pass_component_table_resp)>
passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
auto responseMsg2 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
rc = decode_pass_component_table_resp(
responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
&compResp, &compRespCode);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
constexpr std::array<uint8_t,
hdrSize + sizeof(pldm_pass_component_table_resp)>
passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};
auto responseMsg3 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
rc = decode_pass_component_table_resp(
responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
&compResp, &compRespCode);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
constexpr std::array<uint8_t,
hdrSize + sizeof(pldm_pass_component_table_resp)>
passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
auto responseMsg4 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data());
rc = decode_pass_component_table_resp(
responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode,
&compResp, &compRespCode);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
}
TEST(UpdateComponent, goodPathEncodeRequest)
{
constexpr uint8_t instanceId = 2;
constexpr uint16_t compIdentifier = 500;
constexpr uint8_t compClassificationIndex = 50;
constexpr uint32_t compComparisonStamp = 0x89abcdef;
constexpr uint32_t compImageSize = 4096;
constexpr bitfield32_t updateOptionFlags{1};
constexpr std::string_view compVerStr = "OpenBmcv2.2";
constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
variable_field compVerStrInfo{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
compVerStrInfo.length = compVerStrLen;
std::array<uint8_t,
hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
request{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
auto rc = encode_update_component_req(
instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
compComparisonStamp, compImageSize, updateOptionFlags,
PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
sizeof(pldm_update_component_req) + compVerStrLen);
EXPECT_EQ(rc, PLDM_SUCCESS);
std::array<uint8_t,
hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
EXPECT_EQ(request, outRequest);
}
TEST(UpdateComponent, errorPathEncodeRequest)
{
constexpr uint8_t instanceId = 2;
constexpr uint16_t compIdentifier = 500;
constexpr uint8_t compClassificationIndex = 50;
constexpr uint32_t compComparisonStamp = 0x89abcdef;
constexpr uint32_t compImageSize = 4096;
constexpr bitfield32_t updateOptionFlags{1};
constexpr std::string_view compVerStr = "OpenBmcv2.2";
constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
variable_field compVerStrInfo{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
compVerStrInfo.length = compVerStrLen;
std::array<uint8_t,
hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
request{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
auto rc = encode_update_component_req(
instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
compComparisonStamp, compImageSize, updateOptionFlags,
PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
sizeof(pldm_update_component_req) + compVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
compVerStrInfo.ptr = nullptr;
rc = encode_update_component_req(
instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
compComparisonStamp, compImageSize, updateOptionFlags,
PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
sizeof(pldm_update_component_req) + compVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
rc = encode_update_component_req(
instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
compComparisonStamp, compImageSize, updateOptionFlags,
PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
sizeof(pldm_update_component_req) + compVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = encode_update_component_req(
instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
compComparisonStamp, compImageSize, updateOptionFlags,
PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
sizeof(pldm_update_component_req));
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
rc = encode_update_component_req(
instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
compVerStrLen, &compVerStrInfo, requestMsg,
sizeof(pldm_update_component_req) + compVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = encode_update_component_req(
instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
compComparisonStamp, compImageSize, updateOptionFlags,
PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg,
sizeof(pldm_update_component_req) + compVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = encode_update_component_req(
instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
compComparisonStamp, compImageSize, updateOptionFlags,
PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg,
sizeof(pldm_update_component_req) + compVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = encode_update_component_req(
instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
compComparisonStamp, compImageSize, updateOptionFlags,
PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
sizeof(pldm_update_component_req) + compVerStrLen);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
}
TEST(UpdateComponent, goodPathDecodeResponse)
{
constexpr std::bitset<32> forceUpdateComp{1};
constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
auto responseMsg1 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
uint8_t completionCode = 0;
uint8_t compCompatibilityResp = 0;
uint8_t compCompatibilityRespCode = 0;
bitfield32_t updateOptionFlagsEnabled{};
uint16_t timeBeforeReqFWData = 0;
auto rc = decode_update_component_resp(
responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
&compCompatibilityResp, &compCompatibilityRespCode,
&updateOptionFlagsEnabled, &timeBeforeReqFWData);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(completionCode, PLDM_SUCCESS);
EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
constexpr std::bitset<32> noFlags{};
constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
auto responseMsg2 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
rc = decode_update_component_resp(
responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
&compCompatibilityResp, &compCompatibilityRespCode,
&updateOptionFlagsEnabled, &timeBeforeReqFWData);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(completionCode, PLDM_SUCCESS);
EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
auto responseMsg3 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
rc = decode_update_component_resp(
responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
&compCompatibilityResp, &compCompatibilityRespCode,
&updateOptionFlagsEnabled, &timeBeforeReqFWData);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
}
TEST(UpdateComponent, errorPathDecodeResponse)
{
constexpr std::array<uint8_t,
hdrSize + sizeof(pldm_update_component_resp) - 1>
updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
0x00, 0x00, 0x00, 0x00, 0x00};
auto responseMsg1 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
uint8_t completionCode = 0;
uint8_t compCompatibilityResp = 0;
uint8_t compCompatibilityRespCode = 0;
bitfield32_t updateOptionFlagsEnabled{};
uint16_t timeBeforeReqFWData = 0;
auto rc = decode_update_component_resp(
nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
&compCompatibilityResp, &compCompatibilityRespCode,
&updateOptionFlagsEnabled, &timeBeforeReqFWData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_update_component_resp(
responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
&compCompatibilityResp, &compCompatibilityRespCode,
&updateOptionFlagsEnabled, &timeBeforeReqFWData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_update_component_resp(
responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
&timeBeforeReqFWData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_update_component_resp(
responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
&compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
&timeBeforeReqFWData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_update_component_resp(
responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
&compCompatibilityResp, &compCompatibilityRespCode, nullptr,
&timeBeforeReqFWData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_update_component_resp(
responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
&compCompatibilityResp, &compCompatibilityRespCode,
&updateOptionFlagsEnabled, nullptr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_update_component_resp(
responseMsg1, 0, &completionCode, &compCompatibilityResp,
&compCompatibilityRespCode, &updateOptionFlagsEnabled,
&timeBeforeReqFWData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_update_component_resp(
responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
&compCompatibilityResp, &compCompatibilityRespCode,
&updateOptionFlagsEnabled, &timeBeforeReqFWData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
auto responseMsg2 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
rc = decode_update_component_resp(
responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
&compCompatibilityResp, &compCompatibilityRespCode,
&updateOptionFlagsEnabled, &timeBeforeReqFWData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
auto responseMsg3 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
rc = decode_update_component_resp(
responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
&compCompatibilityResp, &compCompatibilityRespCode,
&updateOptionFlagsEnabled, &timeBeforeReqFWData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
auto responseMsg4 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
rc = decode_update_component_resp(
responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
&compCompatibilityResp, &compCompatibilityRespCode,
&updateOptionFlagsEnabled, &timeBeforeReqFWData);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
}
TEST(RequestFirmwareData, goodPathDecodeRequest)
{
constexpr uint32_t offset = 300;
constexpr uint32_t length = 255;
constexpr std::array<uint8_t,
hdrSize + sizeof(pldm_request_firmware_data_req)>
reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
uint32_t outOffset = 0;
uint32_t outLength = 0;
auto rc = decode_request_firmware_data_req(
requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
&outLength);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(outOffset, offset);
EXPECT_EQ(outLength, length);
}
TEST(RequestFirmwareData, errorPathDecodeRequest)
{
constexpr std::array<uint8_t,
hdrSize + sizeof(pldm_request_firmware_data_req)>
reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
0x00, 0x1f, 0x00, 0x00, 0x00};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
uint32_t outOffset = 0;
uint32_t outLength = 0;
auto rc = decode_request_firmware_data_req(
nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
&outLength);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_request_firmware_data_req(
requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
&outLength);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_request_firmware_data_req(
requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
nullptr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_request_firmware_data_req(
requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
&outLength);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
rc = decode_request_firmware_data_req(
requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
&outLength);
EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
}
TEST(RequestFirmwareData, goodPathEncodeResponse)
{
constexpr uint8_t instanceId = 3;
constexpr uint8_t completionCode = PLDM_SUCCESS;
constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
PLDM_FWUP_BASELINE_TRANSFER_SIZE>
outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
0x1d, 0x1e, 0x1f, 0x20};
std::array<uint8_t, hdrSize + sizeof(completionCode) +
PLDM_FWUP_BASELINE_TRANSFER_SIZE>
reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
0x1d, 0x1e, 0x1f, 0x20};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
auto rc = encode_request_firmware_data_resp(
instanceId, completionCode, responseMsg1,
sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
0x00, 0x00, 0x00, 0x00};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
rc = encode_request_firmware_data_resp(
instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
sizeof(completionCode));
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
}
TEST(RequestFirmwareData, errorPathEncodeResponse)
{
std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
}
TEST(TransferComplete, goodPathDecodeRequest)
{
constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
auto requestMsg1 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
uint8_t outTransferResult = 0;
auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
&outTransferResult);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(outTransferResult, transferResult);
constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
auto requestMsg2 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
&outTransferResult);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
}
TEST(TransferComplete, errorPathDecodeRequest)
{
constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
0x00};
auto requestMsg =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
uint8_t outTransferResult = 0;
auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
}
TEST(TransferComplete, goodPathEncodeResponse)
{
constexpr uint8_t instanceId = 4;
constexpr uint8_t completionCode = PLDM_SUCCESS;
constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
std::array<uint8_t, hdrSize + sizeof(completionCode)>
transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
auto responseMsg1 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
auto rc = encode_transfer_complete_resp(
instanceId, completionCode, responseMsg1, sizeof(completionCode));
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
std::array<uint8_t, hdrSize + sizeof(completionCode)>
transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
auto responseMsg2 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
rc = encode_transfer_complete_resp(instanceId,
PLDM_FWUP_COMMAND_NOT_EXPECTED,
responseMsg2, sizeof(completionCode));
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
}
TEST(TransferComplete, errorPathEncodeResponse)
{
std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
auto responseMsg =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
}
TEST(VerifyComplete, goodPathDecodeRequest)
{
constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
auto requestMsg1 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
uint8_t outVerifyResult = 0;
auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
&outVerifyResult);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(outVerifyResult, verifyResult);
constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
auto requestMsg2 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
&outVerifyResult);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
}
TEST(VerifyComplete, errorPathDecodeRequest)
{
constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
auto requestMsg =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
uint8_t outVerifyResult = 0;
auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_verify_complete_req(requestMsg, 0, nullptr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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, 0x88};
std::array<uint8_t, hdrSize + sizeof(completionCode)>
verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
auto responseMsg2 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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);
}
TEST(ApplyComplete, goodPathDecodeRequest)
{
constexpr uint8_t applyResult1 =
PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
// DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
constexpr std::bitset<16> compActivationModification1{0x30};
constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
auto requestMsg1 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
uint8_t outApplyResult = 0;
bitfield16_t outCompActivationModification{};
auto rc = decode_apply_complete_req(
requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
&outCompActivationModification);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(outApplyResult, applyResult1);
EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
constexpr std::bitset<16> compActivationModification2{};
constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
auto requestMsg2 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
&outApplyResult,
&outCompActivationModification);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(outApplyResult, applyResult2);
EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
}
TEST(ApplyComplete, errorPathDecodeRequest)
{
constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
auto requestMsg1 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
uint8_t outApplyResult = 0;
bitfield16_t outCompActivationModification{};
auto rc = decode_apply_complete_req(
nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
&outCompActivationModification);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
nullptr, &outCompActivationModification);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
&outApplyResult, nullptr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
&outCompActivationModification);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
auto requestMsg2 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
&outApplyResult,
&outCompActivationModification);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
}
TEST(ApplyComplete, goodPathEncodeResponse)
{
constexpr uint8_t instanceId = 6;
constexpr uint8_t completionCode = PLDM_SUCCESS;
constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
std::array<uint8_t, hdrSize + sizeof(completionCode)>
applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
auto responseMsg1 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
auto rc = encode_apply_complete_resp(instanceId, completionCode,
responseMsg1, sizeof(completionCode));
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
std::array<uint8_t, hdrSize + sizeof(completionCode)>
applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
auto responseMsg2 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
responseMsg2, sizeof(completionCode));
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
}
TEST(ApplyComplete, errorPathEncodeResponse)
{
std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
auto responseMsg =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
}
TEST(ActivateFirmware, goodPathEncodeRequest)
{
constexpr uint8_t instanceId = 7;
std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
auto rc = encode_activate_firmware_req(
instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
sizeof(pldm_activate_firmware_req));
EXPECT_EQ(rc, PLDM_SUCCESS);
std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
outRequest{0x87, 0x05, 0x1a, 0x01};
EXPECT_EQ(request, outRequest);
}
TEST(ActivateFirmware, errorPathEncodeRequest)
{
std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
auto rc = encode_activate_firmware_req(
0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
sizeof(pldm_activate_firmware_req));
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = encode_activate_firmware_req(
0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
rc = encode_activate_firmware_req(0, 2, requestMsg,
sizeof(pldm_activate_firmware_req));
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
}
TEST(ActivateFirmware, goodPathDecodeResponse)
{
constexpr uint16_t estimatedTimeForActivation100s = 100;
constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
auto responseMsg1 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
uint8_t completionCode = 0;
uint16_t estimatedTimeForActivation = 0;
auto rc = decode_activate_firmware_resp(
responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
&estimatedTimeForActivation);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(completionCode, PLDM_SUCCESS);
EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
auto responseMsg2 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data());
rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
&completionCode,
&estimatedTimeForActivation);
EXPECT_EQ(rc, PLDM_SUCCESS);
EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
}
TEST(ActivateFirmware, errorPathDecodeResponse)
{
constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
auto responseMsg =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
uint8_t completionCode = 0;
uint16_t estimatedTimeForActivation = 0;
auto rc = decode_activate_firmware_resp(
nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
&estimatedTimeForActivation);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_activate_firmware_resp(responseMsg,
sizeof(pldm_activate_firmware_resp),
nullptr, &estimatedTimeForActivation);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_activate_firmware_resp(responseMsg,
sizeof(pldm_activate_firmware_resp),
&completionCode, nullptr);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
&estimatedTimeForActivation);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = decode_activate_firmware_resp(
responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
&estimatedTimeForActivation);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
}
TEST(GetStatus, goodPathEncodeRequest)
{
constexpr uint8_t instanceId = 8;
std::array<uint8_t, hdrSize> request{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
auto rc = encode_get_status_req(instanceId, requestMsg,
PLDM_GET_STATUS_REQ_BYTES);
EXPECT_EQ(rc, PLDM_SUCCESS);
constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
EXPECT_EQ(request, outRequest);
}
TEST(GetStatus, errorPathEncodeRequest)
{
std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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);
}
TEST(CancelUpdateComponent, goodPathEncodeRequest)
{
constexpr uint8_t instanceId = 9;
std::array<uint8_t, hdrSize> request{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
auto rc = encode_cancel_update_component_req(
instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
EXPECT_EQ(rc, PLDM_SUCCESS);
constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
EXPECT_EQ(request, outRequest);
}
TEST(CancelUpdateComponent, errorPathEncodeRequest)
{
std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
auto rc = encode_cancel_update_component_req(
0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = encode_cancel_update_component_req(
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};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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);
}
TEST(CancelUpdate, goodPathEncodeRequest)
{
constexpr uint8_t instanceId = 10;
std::array<uint8_t, hdrSize> request{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
auto rc = encode_cancel_update_req(instanceId, requestMsg,
PLDM_CANCEL_UPDATE_REQ_BYTES);
EXPECT_EQ(rc, PLDM_SUCCESS);
constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
EXPECT_EQ(request, outRequest);
}
TEST(CancelUpdate, errorPathEncodeRequest)
{
std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
auto rc =
encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
rc = encode_cancel_update_req(0, requestMsg,
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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 =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
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);
}