1 #include <endian.h> 2 #include <libpldm/base.h> 3 #include <libpldm/firmware_update.h> 4 #include <libpldm/pldm_types.h> 5 #include <libpldm/utils.h> 6 7 #include <algorithm> 8 #include <array> 9 #include <bitset> 10 #include <cstddef> 11 #include <cstdint> 12 #include <cstring> 13 #include <span> 14 #include <string> 15 #include <string_view> 16 #include <vector> 17 18 #include "msgbuf.h" 19 20 #include <gmock/gmock.h> 21 #include <gtest/gtest.h> 22 23 using testing::ElementsAreArray; 24 25 constexpr auto hdrSize = sizeof(pldm_msg_hdr); 26 27 #ifdef LIBPLDM_API_TESTING 28 29 static const uint8_t FIXED_INSTANCE_ID = 31; 30 31 /* data is a pointer to pldm message response header */ 32 static void check_response(const void* data, uint8_t command) 33 { 34 auto enc = static_cast<const pldm_msg*>(data); 35 EXPECT_EQ(enc->hdr.request, PLDM_RESPONSE); 36 EXPECT_EQ(enc->hdr.type, PLDM_FWUP); 37 EXPECT_EQ(enc->hdr.command, command); 38 EXPECT_EQ(enc->hdr.reserved, 0); 39 EXPECT_EQ(enc->hdr.datagram, 0); 40 EXPECT_EQ(enc->hdr.header_ver, 0); 41 EXPECT_EQ(enc->hdr.instance_id, FIXED_INSTANCE_ID); 42 } 43 #endif 44 45 static constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> 46 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0{0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 47 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f, 48 0x05, 0x9a, 0xca, 0x02}; 49 50 static constexpr uint8_t PLDM_FWUP_PACKAGE_HEADER_FORMAT_REVISION_V1_0 = 0x01; 51 52 TEST(DecodePackageHeaderInfo, goodPath) 53 { 54 // Random PackageHeaderSize 55 constexpr uint16_t pkgHeaderSize = 303; 56 // PackageReleaseDateTime - "25/12/2021 00:00:00" 57 std::array<uint8_t, PLDM_TIMESTAMP104_SIZE> package_release_date_time{ 58 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00}; 60 constexpr uint16_t componentBitmapBitLength = 8; 61 // PackageVersionString 62 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"}; 63 constexpr size_t packageHeaderSize = 64 sizeof(pldm_package_header_information) + packageVersionStr.size(); 65 66 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{ 67 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f, 68 0x05, 0x9a, 0xca, 0x02, 0x01, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 69 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b, 70 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30}; 71 pldm_package_header_information pkgHeader{}; 72 variable_field packageVersion{}; 73 74 auto rc = decode_pldm_package_header_info(packagerHeaderInfo.data(), 75 packagerHeaderInfo.size(), 76 &pkgHeader, &packageVersion); 77 78 EXPECT_EQ(rc, PLDM_SUCCESS); 79 EXPECT_EQ(true, 80 std::equal(pkgHeader.uuid, pkgHeader.uuid + PLDM_FWUP_UUID_LENGTH, 81 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.begin(), 82 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.end())); 83 EXPECT_EQ(pkgHeader.package_header_format_version, 84 PLDM_FWUP_PACKAGE_HEADER_FORMAT_REVISION_V1_0); 85 EXPECT_EQ(pkgHeader.package_header_size, pkgHeaderSize); 86 EXPECT_EQ(true, std::equal(pkgHeader.package_release_date_time, 87 pkgHeader.package_release_date_time + 88 PLDM_TIMESTAMP104_SIZE, 89 package_release_date_time.begin(), 90 package_release_date_time.end())); 91 EXPECT_EQ(pkgHeader.component_bitmap_bit_length, componentBitmapBitLength); 92 EXPECT_EQ(pkgHeader.package_version_string_type, PLDM_STR_TYPE_ASCII); 93 EXPECT_EQ(pkgHeader.package_version_string_length, 94 packageVersionStr.size()); 95 std::string packageVersionString( 96 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 97 reinterpret_cast<const char*>(packageVersion.ptr), 98 packageVersion.length); 99 EXPECT_EQ(packageVersionString, packageVersionStr); 100 } 101 102 TEST(DecodePackageHeaderInfo, invalidArguments) 103 { 104 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"}; 105 constexpr size_t packageHeaderSize = 106 sizeof(pldm_package_header_information) + packageVersionStr.size(); 107 108 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{ 109 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f, 110 0x05, 0x9a, 0xca, 0x02, 0x01, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 111 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b, 112 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30}; 113 114 pldm_package_header_information packageHeader{}; 115 variable_field packageVersion{}; 116 int rc = 0; 117 118 rc = decode_pldm_package_header_info(nullptr, packagerHeaderInfo.size(), 119 &packageHeader, &packageVersion); 120 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 121 122 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(), 123 packagerHeaderInfo.size(), nullptr, 124 &packageVersion); 125 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 126 127 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(), 128 packagerHeaderInfo.size(), 129 &packageHeader, nullptr); 130 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 131 } 132 133 TEST(DecodePackageHeaderInfo, invalidPackageLengths) 134 { 135 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"}; 136 constexpr size_t packageHeaderSize = 137 sizeof(pldm_package_header_information) + packageVersionStr.size(); 138 139 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{ 140 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f, 141 0x05, 0x9a, 0xca, 0x02, 0x01, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 142 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b, 143 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30}; 144 145 pldm_package_header_information packageHeader{}; 146 variable_field packageVersion{}; 147 int rc = 0; 148 149 rc = decode_pldm_package_header_info( 150 packagerHeaderInfo.data(), sizeof(pldm_package_header_information) - 1, 151 &packageHeader, &packageVersion); 152 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 153 } 154 155 TEST(DecodePackageHeaderInfo, invalidPackageVersionStringType) 156 { 157 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"}; 158 constexpr size_t packageHeaderSize = 159 sizeof(pldm_package_header_information) + packageVersionStr.size(); 160 161 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{ 162 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f, 163 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 164 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x06, 0x0b, 165 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30}; 166 167 pldm_package_header_information packageHeader{}; 168 variable_field packageVersion{}; 169 int rc = 0; 170 171 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(), 172 invalidPackagerHeaderInfo.size(), 173 &packageHeader, &packageVersion); 174 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 175 } 176 177 TEST(DecodePackageHeaderInfo, invalidPackageVersionStringLength) 178 { 179 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"}; 180 constexpr size_t packageHeaderSize = 181 sizeof(pldm_package_header_information) + packageVersionStr.size(); 182 183 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{ 184 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f, 185 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 186 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x00, 187 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30}; 188 189 pldm_package_header_information packageHeader{}; 190 variable_field packageVersion{}; 191 int rc = 0; 192 193 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(), 194 invalidPackagerHeaderInfo.size(), 195 &packageHeader, &packageVersion); 196 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 197 } 198 199 TEST(DecodePackageHeaderInfo, corruptPackageVersionStringLength) 200 { 201 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"}; 202 constexpr size_t packageHeaderSize = 203 sizeof(pldm_package_header_information) + packageVersionStr.size(); 204 205 constexpr std::array<uint8_t, packageHeaderSize - 1> 206 invalidPackagerHeaderInfo{ 207 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 208 0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00, 209 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 210 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 211 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e}; 212 213 pldm_package_header_information packageHeader{}; 214 variable_field packageVersion{}; 215 int rc = 0; 216 217 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(), 218 invalidPackagerHeaderInfo.size(), 219 &packageHeader, &packageVersion); 220 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 221 } 222 223 TEST(DecodePackageHeaderInfo, invalidComponentBitmapBitLength) 224 { 225 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"}; 226 constexpr size_t packageHeaderSize = 227 sizeof(pldm_package_header_information) + packageVersionStr.size(); 228 229 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{ 230 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f, 231 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 232 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x09, 0x00, 0x01, 0x0b, 233 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30}; 234 235 pldm_package_header_information packageHeader{}; 236 variable_field packageVersion{}; 237 int rc = 0; 238 239 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(), 240 invalidPackagerHeaderInfo.size(), 241 &packageHeader, &packageVersion); 242 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 243 } 244 245 TEST(DecodeFirmwareDeviceIdRecord, goodPath) 246 { 247 constexpr uint8_t descriptorCount = 1; 248 // Continue component updates after failure 249 constexpr std::bitset<32> deviceUpdateFlag{1}; 250 constexpr uint16_t componentBitmapBitLength = 16; 251 // Applicable Components - 1,2,5,8,9 252 std::vector<std::bitset<8>> applicableComponentsBitfield{0x93, 0x01}; 253 // ComponentImageSetVersionString 254 constexpr std::string_view imageSetVersionStr{"VersionString1"}; 255 // Initial descriptor - UUID 256 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{ 257 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 258 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b}; 259 constexpr uint16_t fwDevicePkgDataLen = 2; 260 // FirmwareDevicePackageData 261 constexpr std::array<uint8_t, fwDevicePkgDataLen> fwDevicePkgData{0xab, 262 0xcd}; 263 // Size of the firmware device ID record 264 constexpr uint16_t recordLen = 265 sizeof(pldm_firmware_device_id_record) + 266 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) + 267 imageSetVersionStr.size() + sizeof(pldm_descriptor_tlv) - 1 + 268 uuid.size() + fwDevicePkgData.size(); 269 // Firmware device ID record 270 constexpr std::array<uint8_t, recordLen> record{ 271 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02, 272 0x00, 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 273 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10, 274 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 275 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xab, 0xcd}; 276 277 pldm_firmware_device_id_record deviceIdRecHeader{}; 278 variable_field applicableComponents{}; 279 variable_field outCompImageSetVersionStr{}; 280 variable_field recordDescriptors{}; 281 variable_field outFwDevicePkgData{}; 282 283 auto rc = decode_firmware_device_id_record( 284 record.data(), record.size(), componentBitmapBitLength, 285 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr, 286 &recordDescriptors, &outFwDevicePkgData); 287 288 EXPECT_EQ(rc, PLDM_SUCCESS); 289 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen); 290 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount); 291 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value, 292 deviceUpdateFlag); 293 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type, 294 PLDM_STR_TYPE_ASCII); 295 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length, 296 imageSetVersionStr.size()); 297 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, fwDevicePkgDataLen); 298 299 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size()); 300 EXPECT_EQ(true, 301 std::equal(applicableComponents.ptr, 302 applicableComponents.ptr + applicableComponents.length, 303 applicableComponentsBitfield.begin(), 304 applicableComponentsBitfield.end())); 305 306 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size()); 307 std::string compImageSetVersionStr( 308 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 309 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr), 310 outCompImageSetVersionStr.length); 311 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr); 312 313 uint16_t descriptorType = 0; 314 uint16_t descriptorLen = 0; 315 variable_field descriptorData{}; 316 // DescriptorCount is 1, so decode_descriptor_type_length_value called once 317 rc = decode_descriptor_type_length_value(recordDescriptors.ptr, 318 recordDescriptors.length, 319 &descriptorType, &descriptorData); 320 EXPECT_EQ(rc, PLDM_SUCCESS); 321 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) + 322 sizeof(descriptorLen) + 323 descriptorData.length); 324 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID); 325 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH); 326 EXPECT_EQ(true, std::equal(descriptorData.ptr, 327 descriptorData.ptr + descriptorData.length, 328 uuid.begin(), uuid.end())); 329 330 EXPECT_EQ(outFwDevicePkgData.length, fwDevicePkgData.size()); 331 EXPECT_EQ(true, 332 std::equal(outFwDevicePkgData.ptr, 333 outFwDevicePkgData.ptr + outFwDevicePkgData.length, 334 fwDevicePkgData.begin(), fwDevicePkgData.end())); 335 } 336 337 TEST(DecodeFirmwareDeviceIdRecord, goodPathNofwDevicePkgData) 338 { 339 constexpr uint8_t descriptorCount = 1; 340 // Continue component updates after failure 341 constexpr std::bitset<32> deviceUpdateFlag{1}; 342 constexpr uint16_t componentBitmapBitLength = 8; 343 // Applicable Components - 1,2 344 std::vector<std::bitset<8>> applicableComponentsBitfield{0x03}; 345 // ComponentImageSetVersionString 346 constexpr std::string_view imageSetVersionStr{"VersionString1"}; 347 // Initial descriptor - UUID 348 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{ 349 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 350 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b}; 351 constexpr uint16_t fwDevicePkgDataLen = 0; 352 353 // Size of the firmware device ID record 354 constexpr uint16_t recordLen = 355 sizeof(pldm_firmware_device_id_record) + 356 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) + 357 imageSetVersionStr.size() + 358 sizeof(pldm_descriptor_tlv().descriptor_type) + 359 sizeof(pldm_descriptor_tlv().descriptor_length) + uuid.size() + 360 fwDevicePkgDataLen; 361 // Firmware device ID record 362 constexpr std::array<uint8_t, recordLen> record{ 363 0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x03, 364 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 365 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 366 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b}; 367 368 pldm_firmware_device_id_record deviceIdRecHeader{}; 369 variable_field applicableComponents{}; 370 variable_field outCompImageSetVersionStr{}; 371 variable_field recordDescriptors{}; 372 variable_field outFwDevicePkgData{}; 373 374 auto rc = decode_firmware_device_id_record( 375 record.data(), record.size(), componentBitmapBitLength, 376 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr, 377 &recordDescriptors, &outFwDevicePkgData); 378 379 EXPECT_EQ(rc, PLDM_SUCCESS); 380 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen); 381 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount); 382 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value, 383 deviceUpdateFlag); 384 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type, 385 PLDM_STR_TYPE_ASCII); 386 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length, 387 imageSetVersionStr.size()); 388 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, 0); 389 390 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size()); 391 EXPECT_EQ(true, 392 std::equal(applicableComponents.ptr, 393 applicableComponents.ptr + applicableComponents.length, 394 applicableComponentsBitfield.begin(), 395 applicableComponentsBitfield.end())); 396 397 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size()); 398 std::string compImageSetVersionStr( 399 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 400 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr), 401 outCompImageSetVersionStr.length); 402 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr); 403 404 uint16_t descriptorType = 0; 405 uint16_t descriptorLen = 0; 406 variable_field descriptorData{}; 407 // DescriptorCount is 1, so decode_descriptor_type_length_value called once 408 rc = decode_descriptor_type_length_value(recordDescriptors.ptr, 409 recordDescriptors.length, 410 &descriptorType, &descriptorData); 411 EXPECT_EQ(rc, PLDM_SUCCESS); 412 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) + 413 sizeof(descriptorLen) + 414 descriptorData.length); 415 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID); 416 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH); 417 EXPECT_EQ(true, std::equal(descriptorData.ptr, 418 descriptorData.ptr + descriptorData.length, 419 uuid.begin(), uuid.end())); 420 421 EXPECT_EQ(outFwDevicePkgData.ptr, nullptr); 422 EXPECT_EQ(outFwDevicePkgData.length, 0); 423 } 424 425 TEST(DecodeFirmwareDeviceIdRecord, ErrorPaths) 426 { 427 // Invalid ComponentImageSetVersionStringType 428 constexpr std::array<uint8_t, 11> rec{0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 429 0x00, 0x06, 0x0e, 0x00, 0x00}; 430 constexpr uint16_t componentBitmapBitLength = 8; 431 432 pldm_firmware_device_id_record deviceIdRecHeader{}; 433 variable_field outCompImageSetVersionStr{}; 434 variable_field applicableComponents{}; 435 variable_field outFwDevicePkgData{}; 436 variable_field recordDescriptors{}; 437 int rc = 0; 438 439 rc = decode_firmware_device_id_record( 440 nullptr, rec.size(), componentBitmapBitLength, &deviceIdRecHeader, 441 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors, 442 &outFwDevicePkgData); 443 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 444 445 rc = decode_firmware_device_id_record( 446 rec.data(), rec.size(), componentBitmapBitLength, nullptr, 447 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors, 448 &outFwDevicePkgData); 449 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 450 451 rc = decode_firmware_device_id_record( 452 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader, 453 nullptr, &outCompImageSetVersionStr, &recordDescriptors, 454 &outFwDevicePkgData); 455 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 456 457 rc = decode_firmware_device_id_record( 458 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader, 459 &applicableComponents, nullptr, &recordDescriptors, 460 &outFwDevicePkgData); 461 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 462 463 rc = decode_firmware_device_id_record( 464 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader, 465 &applicableComponents, &outCompImageSetVersionStr, nullptr, 466 &outFwDevicePkgData); 467 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 468 469 rc = decode_firmware_device_id_record( 470 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader, 471 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors, 472 nullptr); 473 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 474 475 rc = decode_firmware_device_id_record( 476 rec.data(), rec.size() - 1, componentBitmapBitLength, 477 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr, 478 &recordDescriptors, &outFwDevicePkgData); 479 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 480 481 rc = decode_firmware_device_id_record( 482 rec.data(), rec.size(), componentBitmapBitLength + 1, 483 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr, 484 &recordDescriptors, &outFwDevicePkgData); 485 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 486 487 rc = decode_firmware_device_id_record( 488 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader, 489 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors, 490 &outFwDevicePkgData); 491 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 492 } 493 494 TEST(DecodeFirmwareDeviceIdRecord, invalidComponentImageSetVersionStringLength) 495 { 496 constexpr std::array<uint8_t, 11> rec{0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 497 0x00, 0x01, 0x00, 0x00, 0x00}; 498 constexpr uint16_t componentBitmapBitLength = 8; 499 500 int rc = 0; 501 pldm_firmware_device_id_record deviceIdRecHeader{}; 502 variable_field applicableComponents{}; 503 variable_field outCompImageSetVersionStr{}; 504 variable_field recordDescriptors{}; 505 variable_field outFwDevicePkgData{}; 506 507 rc = decode_firmware_device_id_record( 508 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader, 509 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors, 510 &outFwDevicePkgData); 511 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 512 } 513 514 TEST(DecodeFirmwareDeviceIdRecord, shortBuffer) 515 { 516 constexpr std::array<uint8_t, 11> rec{0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 517 0x00, 0x01, 0x0e, 0x00, 0x00}; 518 constexpr uint16_t componentBitmapBitLength = 8; 519 520 pldm_firmware_device_id_record deviceIdRecHeader{}; 521 variable_field outCompImageSetVersionStr{}; 522 variable_field applicableComponents{}; 523 variable_field outFwDevicePkgData{}; 524 variable_field recordDescriptors{}; 525 int rc = 0; 526 527 rc = decode_firmware_device_id_record( 528 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader, 529 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors, 530 &outFwDevicePkgData); 531 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 532 } 533 534 TEST(DecodeFirmwareDeviceIdRecord, recordLengthMismatch) 535 { 536 constexpr std::array<uint8_t, 11> rec{0x15, 0x00, 0x01, 0x01, 0x00, 0x00, 537 0x00, 0x01, 0x0e, 0x02, 0x00}; 538 constexpr uint16_t componentBitmapBitLength = 8; 539 540 pldm_firmware_device_id_record deviceIdRecHeader{}; 541 variable_field outCompImageSetVersionStr{}; 542 variable_field applicableComponents{}; 543 variable_field outFwDevicePkgData{}; 544 variable_field recordDescriptors{}; 545 int rc = 0; 546 547 rc = decode_firmware_device_id_record( 548 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader, 549 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors, 550 &outFwDevicePkgData); 551 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 552 } 553 554 TEST(DecodeFirmwareDeviceIdRecord, invalidFirmwareDevicePackageDataLength) 555 { 556 constexpr std::array<uint8_t, 49> rec{ 557 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 558 // FirmwareDevicePackageDataLength = 0xffff 559 0xff, 0xff, 560 // 561 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 562 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64, 563 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 564 0xab, 0xcd}; 565 constexpr uint16_t componentBitmapBitLength = 8; 566 567 pldm_firmware_device_id_record deviceIdRecHeader{}; 568 variable_field outCompImageSetVersionStr{}; 569 variable_field applicableComponents{}; 570 variable_field outFwDevicePkgData{}; 571 variable_field recordDescriptors{}; 572 int rc = 0; 573 574 rc = decode_firmware_device_id_record( 575 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader, 576 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors, 577 &outFwDevicePkgData); 578 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 579 } 580 581 TEST(DecodeDescriptors, goodPath3Descriptors) 582 { 583 // In the descriptor data there are 3 descriptor entries 584 // 1) IANA enterprise ID 585 constexpr std::array<uint8_t, PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH> iana{ 586 0x0a, 0x0b, 0x0c, 0xd}; 587 // 2) UUID 588 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{ 589 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 590 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b}; 591 // 3) Vendor Defined 592 constexpr std::string_view vendorTitle{"OpenBMC"}; 593 constexpr size_t vendorDescriptorLen = 2; 594 constexpr std::array<uint8_t, vendorDescriptorLen> vendorDescriptorData{ 595 0x01, 0x02}; 596 597 constexpr size_t vendorDefinedDescriptorLen = 598 sizeof(pldm_vendor_defined_descriptor_title_data() 599 .vendor_defined_descriptor_title_str_type) + 600 sizeof(pldm_vendor_defined_descriptor_title_data() 601 .vendor_defined_descriptor_title_str_len) + 602 vendorTitle.size() + vendorDescriptorData.size(); 603 604 constexpr size_t descriptorsLength = 605 3 * (sizeof(pldm_descriptor_tlv().descriptor_type) + 606 sizeof(pldm_descriptor_tlv().descriptor_length)) + 607 iana.size() + uuid.size() + vendorDefinedDescriptorLen; 608 609 constexpr std::array<uint8_t, descriptorsLength> descriptors{ 610 0x01, 0x00, 0x04, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x02, 0x00, 0x10, 611 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30, 612 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xff, 0xff, 0x0b, 0x00, 0x01, 613 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x01, 0x02}; 614 615 size_t descriptorCount = 1; 616 size_t descriptorsRemainingLength = descriptorsLength; 617 int rc = 0; 618 619 while (descriptorsRemainingLength && (descriptorCount <= 3)) 620 { 621 uint16_t descriptorType = 0; 622 uint16_t descriptorLen = 0; 623 variable_field descriptorData{}; 624 625 rc = decode_descriptor_type_length_value( 626 descriptors.data() + descriptorsLength - descriptorsRemainingLength, 627 descriptorsRemainingLength, &descriptorType, &descriptorData); 628 EXPECT_EQ(rc, PLDM_SUCCESS); 629 630 if (descriptorCount == 1) 631 { 632 EXPECT_EQ(descriptorType, PLDM_FWUP_IANA_ENTERPRISE_ID); 633 EXPECT_EQ(descriptorData.length, 634 PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH); 635 EXPECT_EQ(true, 636 std::equal(descriptorData.ptr, 637 descriptorData.ptr + descriptorData.length, 638 iana.begin(), iana.end())); 639 } 640 else if (descriptorCount == 2) 641 { 642 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID); 643 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH); 644 EXPECT_EQ(true, 645 std::equal(descriptorData.ptr, 646 descriptorData.ptr + descriptorData.length, 647 uuid.begin(), uuid.end())); 648 } 649 else if (descriptorCount == 3) 650 { 651 EXPECT_EQ(descriptorType, PLDM_FWUP_VENDOR_DEFINED); 652 EXPECT_EQ(descriptorData.length, vendorDefinedDescriptorLen); 653 654 uint8_t descriptorTitleStrType = 0; 655 variable_field descriptorTitleStr{}; 656 variable_field vendorDefinedDescriptorData{}; 657 658 rc = decode_vendor_defined_descriptor_value( 659 descriptorData.ptr, descriptorData.length, 660 &descriptorTitleStrType, &descriptorTitleStr, 661 &vendorDefinedDescriptorData); 662 EXPECT_EQ(rc, PLDM_SUCCESS); 663 664 EXPECT_EQ(descriptorTitleStrType, PLDM_STR_TYPE_ASCII); 665 EXPECT_EQ(descriptorTitleStr.length, vendorTitle.size()); 666 std::string vendorTitleStr( 667 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 668 reinterpret_cast<const char*>(descriptorTitleStr.ptr), 669 descriptorTitleStr.length); 670 EXPECT_EQ(vendorTitleStr, vendorTitle); 671 672 EXPECT_EQ(vendorDefinedDescriptorData.length, 673 vendorDescriptorData.size()); 674 EXPECT_EQ(true, std::equal(vendorDefinedDescriptorData.ptr, 675 vendorDefinedDescriptorData.ptr + 676 vendorDefinedDescriptorData.length, 677 vendorDescriptorData.begin(), 678 vendorDescriptorData.end())); 679 } 680 681 descriptorsRemainingLength -= sizeof(descriptorType) + 682 sizeof(descriptorLen) + 683 descriptorData.length; 684 descriptorCount++; 685 } 686 } 687 688 TEST(DecodeDescriptors, errorPathDecodeDescriptorTLV) 689 { 690 int rc = 0; 691 // IANA Enterprise ID descriptor length incorrect 692 constexpr std::array<uint8_t, 7> invalidIANADescriptor1{ 693 0x01, 0x00, 0x03, 0x00, 0x0a, 0x0b, 0x0c}; 694 uint16_t descriptorType = 0; 695 variable_field descriptorData{}; 696 697 rc = decode_descriptor_type_length_value(nullptr, 698 invalidIANADescriptor1.size(), 699 &descriptorType, &descriptorData); 700 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 701 702 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(), 703 invalidIANADescriptor1.size(), 704 nullptr, &descriptorData); 705 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 706 707 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(), 708 invalidIANADescriptor1.size(), 709 &descriptorType, nullptr); 710 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 711 712 rc = decode_descriptor_type_length_value( 713 invalidIANADescriptor1.data(), PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN - 1, 714 &descriptorType, &descriptorData); 715 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 716 717 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(), 718 invalidIANADescriptor1.size(), 719 &descriptorType, &descriptorData); 720 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 721 722 // IANA Enterprise ID descriptor data less than length 723 std::array<uint8_t, 7> invalidIANADescriptor2{0x01, 0x00, 0x04, 0x00, 724 0x0a, 0x0b, 0x0c}; 725 rc = decode_descriptor_type_length_value(invalidIANADescriptor2.data(), 726 invalidIANADescriptor2.size(), 727 &descriptorType, &descriptorData); 728 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 729 } 730 731 TEST(DecodeDescriptors, errorPathVendorDefinedDescriptor) 732 { 733 int rc = 0; 734 // VendorDefinedDescriptorTitleStringType is invalid 735 constexpr std::array<uint8_t, 9> invalidVendorDescriptor1{ 736 0x06, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43}; 737 uint8_t descriptorStringType = 0; 738 variable_field descriptorTitleStr{}; 739 variable_field vendorDefinedDescriptorData{}; 740 741 rc = decode_vendor_defined_descriptor_value( 742 nullptr, invalidVendorDescriptor1.size(), &descriptorStringType, 743 &descriptorTitleStr, &vendorDefinedDescriptorData); 744 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 745 746 rc = decode_vendor_defined_descriptor_value( 747 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(), 748 &descriptorStringType, &descriptorTitleStr, 749 &vendorDefinedDescriptorData); 750 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 751 752 rc = decode_vendor_defined_descriptor_value( 753 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(), 754 nullptr, &descriptorTitleStr, &vendorDefinedDescriptorData); 755 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 756 757 rc = decode_vendor_defined_descriptor_value( 758 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(), 759 &descriptorStringType, nullptr, &vendorDefinedDescriptorData); 760 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 761 762 rc = decode_vendor_defined_descriptor_value( 763 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(), 764 &descriptorStringType, &descriptorTitleStr, nullptr); 765 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 766 767 rc = decode_vendor_defined_descriptor_value( 768 invalidVendorDescriptor1.data(), 769 sizeof(pldm_vendor_defined_descriptor_title_data) - 1, 770 &descriptorStringType, &descriptorTitleStr, 771 &vendorDefinedDescriptorData); 772 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 773 774 rc = decode_vendor_defined_descriptor_value( 775 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(), 776 &descriptorStringType, &descriptorTitleStr, 777 &vendorDefinedDescriptorData); 778 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 779 780 // VendorDefinedDescriptorTitleStringLength is 0 781 std::array<uint8_t, 9> invalidVendorDescriptor2{ 782 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43}; 783 rc = decode_vendor_defined_descriptor_value( 784 invalidVendorDescriptor2.data(), invalidVendorDescriptor2.size(), 785 &descriptorStringType, &descriptorTitleStr, 786 &vendorDefinedDescriptorData); 787 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 788 789 // VendorDefinedDescriptorData not present in the data 790 std::array<uint8_t, 9> invalidVendorDescriptor3{ 791 0x01, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43}; 792 rc = decode_vendor_defined_descriptor_value( 793 invalidVendorDescriptor3.data(), invalidVendorDescriptor3.size(), 794 &descriptorStringType, &descriptorTitleStr, 795 &vendorDefinedDescriptorData); 796 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 797 } 798 799 TEST(DecodeComponentImageInfo, goodPath) 800 { 801 // Firmware 802 constexpr uint16_t compClassification = 16; 803 constexpr uint16_t compIdentifier = 300; 804 constexpr uint32_t compComparisonStamp = 0xffffffff; 805 // Force update 806 constexpr std::bitset<16> compOptions{1}; 807 // System reboot[Bit position 3] & Medium-specific reset[Bit position 2] 808 constexpr std::bitset<16> reqCompActivationMethod{0x0c}; 809 // Random ComponentLocationOffset 810 constexpr uint32_t compLocOffset = 357; 811 // Random ComponentSize 812 constexpr uint32_t compSize = 27; 813 // ComponentVersionString 814 constexpr std::string_view compVersionStr{"VersionString1"}; 815 constexpr size_t compImageInfoSize = 816 sizeof(pldm_component_image_information) + compVersionStr.size(); 817 818 constexpr std::array<uint8_t, compImageInfoSize> compImageInfo{ 819 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00, 820 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65, 821 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31}; 822 pldm_component_image_information outCompImageInfo{}; 823 variable_field outCompVersionStr{}; 824 825 auto rc = 826 decode_pldm_comp_image_info(compImageInfo.data(), compImageInfo.size(), 827 &outCompImageInfo, &outCompVersionStr); 828 829 EXPECT_EQ(rc, PLDM_SUCCESS); 830 EXPECT_EQ(outCompImageInfo.comp_classification, compClassification); 831 EXPECT_EQ(outCompImageInfo.comp_identifier, compIdentifier); 832 EXPECT_EQ(outCompImageInfo.comp_comparison_stamp, compComparisonStamp); 833 EXPECT_EQ(outCompImageInfo.comp_options.value, compOptions); 834 EXPECT_EQ(outCompImageInfo.requested_comp_activation_method.value, 835 reqCompActivationMethod); 836 EXPECT_EQ(outCompImageInfo.comp_location_offset, compLocOffset); 837 EXPECT_EQ(outCompImageInfo.comp_size, compSize); 838 EXPECT_EQ(outCompImageInfo.comp_version_string_type, PLDM_STR_TYPE_ASCII); 839 EXPECT_EQ(outCompImageInfo.comp_version_string_length, 840 compVersionStr.size()); 841 842 EXPECT_EQ(outCompVersionStr.length, 843 outCompImageInfo.comp_version_string_length); 844 std::string componentVersionString( 845 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 846 reinterpret_cast<const char*>(outCompVersionStr.ptr), 847 outCompVersionStr.length); 848 EXPECT_EQ(componentVersionString, compVersionStr); 849 } 850 851 TEST(DecodeComponentImageInfo, errorPaths) 852 { 853 int rc = 0; 854 // ComponentVersionString 855 constexpr std::string_view compVersionStr{"VersionString1"}; 856 constexpr size_t compImageInfoSize = 857 sizeof(pldm_component_image_information) + compVersionStr.size(); 858 // Invalid ComponentVersionStringType - 0x06 859 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo1{ 860 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00, 861 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x56, 0x65, 862 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31}; 863 pldm_component_image_information outCompImageInfo{}; 864 variable_field outCompVersionStr{}; 865 866 rc = decode_pldm_comp_image_info(nullptr, invalidCompImageInfo1.size(), 867 &outCompImageInfo, &outCompVersionStr); 868 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 869 870 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(), 871 invalidCompImageInfo1.size(), nullptr, 872 &outCompVersionStr); 873 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 874 875 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(), 876 invalidCompImageInfo1.size(), 877 &outCompImageInfo, nullptr); 878 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 879 880 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(), 881 sizeof(pldm_component_image_information) - 882 1, 883 &outCompImageInfo, &outCompVersionStr); 884 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 885 886 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(), 887 invalidCompImageInfo1.size(), 888 &outCompImageInfo, &outCompVersionStr); 889 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 890 891 // Invalid ComponentVersionStringLength - 0x00 892 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo2{ 893 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00, 894 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x65, 895 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31}; 896 rc = decode_pldm_comp_image_info(invalidCompImageInfo2.data(), 897 invalidCompImageInfo2.size(), 898 &outCompImageInfo, &outCompVersionStr); 899 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 900 901 // Use Component Comparison Stamp is not set, but ComponentComparisonStamp 902 // is not 0xffffffff 903 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo3{ 904 0x10, 0x00, 0x2c, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00, 905 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65, 906 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31}; 907 908 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(), 909 invalidCompImageInfo3.size() - 1, 910 &outCompImageInfo, &outCompVersionStr); 911 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 912 913 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(), 914 invalidCompImageInfo3.size(), 915 &outCompImageInfo, &outCompVersionStr); 916 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 917 918 // Invalid ComponentLocationOffset - 0 919 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo4{ 920 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00, 921 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65, 922 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31}; 923 rc = decode_pldm_comp_image_info(invalidCompImageInfo4.data(), 924 invalidCompImageInfo4.size(), 925 &outCompImageInfo, &outCompVersionStr); 926 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 927 928 // Invalid ComponentSize - 0 929 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo5{ 930 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00, 931 0x65, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65, 932 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31}; 933 rc = decode_pldm_comp_image_info(invalidCompImageInfo5.data(), 934 invalidCompImageInfo5.size(), 935 &outCompImageInfo, &outCompVersionStr); 936 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 937 } 938 939 TEST(QueryDeviceIdentifiers, goodPathEncodeRequest) 940 { 941 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{}; 942 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 943 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); 944 945 uint8_t instanceId = 0x01; 946 947 auto rc = encode_query_device_identifiers_req( 948 instanceId, PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES, requestPtr); 949 EXPECT_EQ(rc, PLDM_SUCCESS); 950 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST); 951 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId); 952 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP); 953 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DEVICE_IDENTIFIERS); 954 } 955 956 TEST(QueryDeviceIdentifiers, goodPathDecodeResponse) 957 { 958 // descriptorDataLen is not fixed here taking it as 6 959 constexpr uint8_t descriptorDataLen = 6; 960 std::array<uint8_t, hdrSize + 961 sizeof(struct pldm_query_device_identifiers_resp) + 962 descriptorDataLen> 963 responseMsg{}; 964 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 965 auto inResp = reinterpret_cast<struct pldm_query_device_identifiers_resp*>( 966 responseMsg.data() + hdrSize); 967 968 inResp->completion_code = PLDM_SUCCESS; 969 inResp->device_identifiers_len = htole32(descriptorDataLen); 970 inResp->descriptor_count = 1; 971 972 // filling descriptor data 973 std::fill_n(responseMsg.data() + hdrSize + 974 sizeof(struct pldm_query_device_identifiers_resp), 975 descriptorDataLen, 0xff); 976 977 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 978 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 979 uint8_t completionCode = PLDM_SUCCESS; 980 uint32_t deviceIdentifiersLen = 0; 981 uint8_t descriptorCount = 0; 982 uint8_t* outDescriptorData = nullptr; 983 984 auto rc = decode_query_device_identifiers_resp( 985 response, responseMsg.size() - hdrSize, &completionCode, 986 &deviceIdentifiersLen, &descriptorCount, &outDescriptorData); 987 988 EXPECT_EQ(rc, PLDM_SUCCESS); 989 EXPECT_EQ(completionCode, PLDM_SUCCESS); 990 EXPECT_EQ(deviceIdentifiersLen, inResp->device_identifiers_len); 991 EXPECT_EQ(descriptorCount, inResp->descriptor_count); 992 EXPECT_EQ(true, 993 std::equal(outDescriptorData, 994 outDescriptorData + deviceIdentifiersLen, 995 responseMsg.begin() + hdrSize + 996 sizeof(struct pldm_query_device_identifiers_resp), 997 responseMsg.end())); 998 } 999 1000 #ifdef LIBPLDM_API_TESTING 1001 TEST(QueryDeviceIdentifiers, goodPathEncodeResponse) 1002 { 1003 int rc; 1004 PLDM_MSG_DEFINE_P(enc, 1000); 1005 size_t enc_payload_len = 1000; 1006 pldm_descriptor check_desc[] = { 1007 { 1008 .descriptor_type = PLDM_FWUP_IANA_ENTERPRISE_ID, 1009 .descriptor_length = 4, 1010 .descriptor_data = "a123", 1011 }, 1012 { 1013 .descriptor_type = PLDM_FWUP_VENDOR_DEFINED, 1014 .descriptor_length = 3, 1015 .descriptor_data = "987", 1016 }, 1017 }; 1018 rc = encode_query_device_identifiers_resp(FIXED_INSTANCE_ID, 2, check_desc, 1019 enc, &enc_payload_len); 1020 EXPECT_EQ(rc, 0); 1021 EXPECT_THAT(std::span<uint8_t>(enc_buf + hdrSize, enc_payload_len), 1022 ElementsAreArray<uint8_t>({ 1023 // completion code 1024 0x00, 1025 // device identifiers length = 15 1026 0x0f, 1027 0x00, 1028 0x00, 1029 0x00, 1030 // descriptor count 1031 0x02, 1032 // desc 0 1033 0x01, 1034 0x00, 1035 0x04, 1036 0x00, 1037 0x61, 1038 0x31, 1039 0x32, 1040 0x33, 1041 // desc 1 1042 0xff, 1043 0xff, 1044 0x03, 1045 0x00, 1046 0x39, 1047 0x38, 1048 0x37, 1049 })); 1050 1051 check_response(enc, PLDM_QUERY_DEVICE_IDENTIFIERS); 1052 } 1053 #endif 1054 1055 TEST(GetFirmwareParameters, goodPathEncodeRequest) 1056 { 1057 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{}; 1058 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1059 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); 1060 uint8_t instanceId = 0x01; 1061 1062 auto rc = encode_get_firmware_parameters_req( 1063 instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, requestPtr); 1064 EXPECT_EQ(rc, PLDM_SUCCESS); 1065 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST); 1066 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId); 1067 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP); 1068 EXPECT_EQ(requestPtr->hdr.command, PLDM_GET_FIRMWARE_PARAMETERS); 1069 } 1070 1071 TEST(GetFirmwareParameters, decodeResponse) 1072 { 1073 // CapabilitiesDuringUpdate of the firmware device 1074 // Firmware device downgrade restrictions [Bit position 8] & 1075 // Firmware Device Partial Updates [Bit position 3] 1076 constexpr std::bitset<32> fdCapabilities{0x00000104}; 1077 constexpr uint16_t compCount = 1; 1078 constexpr std::string_view activeCompImageSetVersion{"VersionString1"}; 1079 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"}; 1080 1081 // constexpr uint16_t compClassification = 16; 1082 // constexpr uint16_t compIdentifier = 300; 1083 // constexpr uint8_t compClassificationIndex = 20; 1084 // constexpr uint32_t activeCompComparisonStamp = 0xabcdefab; 1085 // constexpr std::array<uint8_t, 8> activeComponentReleaseData = { 1086 // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; 1087 // constexpr uint32_t pendingCompComparisonStamp = 0x12345678; 1088 // constexpr std::array<uint8_t, 8> pendingComponentReleaseData = { 1089 // 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01}; 1090 constexpr std::string_view activeCompVersion{"VersionString3"}; 1091 constexpr std::string_view pendingCompVersion{"VersionString4"}; 1092 1093 constexpr size_t compParamTableSize = 1094 sizeof(pldm_component_parameter_entry) + activeCompVersion.size() + 1095 pendingCompVersion.size(); 1096 1097 constexpr std::array<uint8_t, compParamTableSize> compParamTable{ 1098 0x10, 0x00, 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01, 1099 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01, 1100 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00, 0x02, 1101 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 1102 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 1103 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34}; 1104 1105 constexpr size_t getFwParamsPayloadLen = 1106 sizeof(pldm_get_firmware_parameters_resp) + 1107 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size() + 1108 compParamTableSize; 1109 1110 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen> 1111 getFwParamsResponse{ 1112 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 1113 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 1114 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69, 1115 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x10, 0x00, 1116 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01, 0x02, 1117 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01, 1118 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00, 1119 0x02, 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 1120 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73, 1121 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34}; 1122 1123 auto responseMsg = 1124 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1125 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data()); 1126 pldm_get_firmware_parameters_resp outResp{}; 1127 variable_field outActiveCompImageSetVersion{}; 1128 variable_field outPendingCompImageSetVersion{}; 1129 variable_field outCompParameterTable{}; 1130 1131 auto rc = decode_get_firmware_parameters_resp( 1132 responseMsg, getFwParamsPayloadLen, &outResp, 1133 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, 1134 &outCompParameterTable); 1135 1136 EXPECT_EQ(rc, PLDM_SUCCESS); 1137 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS); 1138 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities); 1139 EXPECT_EQ(outResp.comp_count, compCount); 1140 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII); 1141 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len, 1142 activeCompImageSetVersion.size()); 1143 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII); 1144 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len, 1145 pendingCompImageSetVersion.size()); 1146 std::string activeCompImageSetVersionStr( 1147 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1148 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr), 1149 outActiveCompImageSetVersion.length); 1150 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion); 1151 std::string pendingCompImageSetVersionStr( 1152 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1153 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr), 1154 outPendingCompImageSetVersion.length); 1155 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion); 1156 EXPECT_EQ(outCompParameterTable.length, compParamTableSize); 1157 EXPECT_EQ(true, std::equal(outCompParameterTable.ptr, 1158 outCompParameterTable.ptr + 1159 outCompParameterTable.length, 1160 compParamTable.begin(), compParamTable.end())); 1161 } 1162 1163 TEST(GetFirmwareParameters, decodeResponseZeroCompCount) 1164 { 1165 // CapabilitiesDuringUpdate of the firmware device 1166 // FD Host Functionality during Firmware Update [Bit position 2] & 1167 // Component Update Failure Retry Capability [Bit position 1] 1168 constexpr std::bitset<32> fdCapabilities{0x06}; 1169 constexpr uint16_t compCount = 0; 1170 constexpr std::string_view activeCompImageSetVersion{"VersionString1"}; 1171 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"}; 1172 1173 constexpr size_t getFwParamsPayloadLen = 1174 sizeof(pldm_get_firmware_parameters_resp) + 1175 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size(); 1176 1177 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen> 1178 getFwParamsResponse{ 1179 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 1180 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 1181 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69, 1182 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32}; 1183 1184 auto responseMsg = 1185 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1186 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data()); 1187 pldm_get_firmware_parameters_resp outResp{}; 1188 variable_field outActiveCompImageSetVersion{}; 1189 variable_field outPendingCompImageSetVersion{}; 1190 variable_field outCompParameterTable{}; 1191 1192 auto rc = decode_get_firmware_parameters_resp( 1193 responseMsg, getFwParamsPayloadLen, &outResp, 1194 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, 1195 &outCompParameterTable); 1196 1197 EXPECT_EQ(rc, PLDM_SUCCESS); 1198 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS); 1199 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities); 1200 EXPECT_EQ(outResp.comp_count, compCount); 1201 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII); 1202 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len, 1203 activeCompImageSetVersion.size()); 1204 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII); 1205 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len, 1206 pendingCompImageSetVersion.size()); 1207 std::string activeCompImageSetVersionStr( 1208 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1209 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr), 1210 outActiveCompImageSetVersion.length); 1211 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion); 1212 std::string pendingCompImageSetVersionStr( 1213 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1214 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr), 1215 outPendingCompImageSetVersion.length); 1216 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion); 1217 EXPECT_EQ(outCompParameterTable.ptr, nullptr); 1218 EXPECT_EQ(outCompParameterTable.length, 0); 1219 } 1220 1221 TEST(GetFirmwareParameters, 1222 decodeResponseNoPendingCompImageVersionStrZeroCompCount) 1223 { 1224 // CapabilitiesDuringUpdate of the firmware device 1225 // FD Host Functionality during Firmware Update [Bit position 2] & 1226 // Component Update Failure Retry Capability [Bit position 1] 1227 constexpr std::bitset<32> fdCapabilities{0x06}; 1228 constexpr uint16_t compCount = 0; 1229 constexpr std::string_view activeCompImageSetVersion{"VersionString"}; 1230 1231 constexpr size_t getFwParamsPayloadLen = 1232 sizeof(pldm_get_firmware_parameters_resp) + 1233 activeCompImageSetVersion.size(); 1234 1235 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen> 1236 getFwParamsResponse{0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 1237 0x00, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00, 1238 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 1239 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67}; 1240 1241 auto responseMsg = 1242 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1243 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data()); 1244 pldm_get_firmware_parameters_resp outResp{}; 1245 variable_field outActiveCompImageSetVersion{}; 1246 variable_field outPendingCompImageSetVersion{}; 1247 variable_field outCompParameterTable{}; 1248 1249 auto rc = decode_get_firmware_parameters_resp( 1250 responseMsg, getFwParamsPayloadLen, &outResp, 1251 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, 1252 &outCompParameterTable); 1253 1254 EXPECT_EQ(rc, PLDM_SUCCESS); 1255 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS); 1256 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities); 1257 EXPECT_EQ(outResp.comp_count, compCount); 1258 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII); 1259 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len, 1260 activeCompImageSetVersion.size()); 1261 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, 1262 PLDM_STR_TYPE_UNKNOWN); 1263 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len, 0); 1264 std::string activeCompImageSetVersionStr( 1265 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1266 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr), 1267 outActiveCompImageSetVersion.length); 1268 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion); 1269 EXPECT_EQ(outPendingCompImageSetVersion.ptr, nullptr); 1270 EXPECT_EQ(outPendingCompImageSetVersion.length, 0); 1271 EXPECT_EQ(outCompParameterTable.ptr, nullptr); 1272 EXPECT_EQ(outCompParameterTable.length, 0); 1273 } 1274 1275 TEST(GetFirmwareParameters, decodeResponseErrorCompletionCode) 1276 { 1277 constexpr std::array<uint8_t, hdrSize + sizeof(uint8_t)> 1278 getFwParamsResponse{0x00, 0x00, 0x00, 0x01}; 1279 1280 auto responseMsg = 1281 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1282 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data()); 1283 pldm_get_firmware_parameters_resp outResp{}; 1284 variable_field outActiveCompImageSetVersion{}; 1285 variable_field outPendingCompImageSetVersion{}; 1286 variable_field outCompParameterTable{}; 1287 1288 auto rc = decode_get_firmware_parameters_resp( 1289 responseMsg, getFwParamsResponse.size(), &outResp, 1290 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, 1291 &outCompParameterTable); 1292 1293 EXPECT_EQ(rc, PLDM_SUCCESS); 1294 EXPECT_EQ(outResp.completion_code, PLDM_ERROR); 1295 } 1296 1297 TEST(GetFirmwareParameters, errorPathdecodeResponse) 1298 { 1299 int rc = 0; 1300 // Invalid ActiveComponentImageSetVersionStringType 1301 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse1{ 1302 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1303 0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00}; 1304 1305 auto responseMsg = 1306 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1307 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse1.data()); 1308 pldm_get_firmware_parameters_resp outResp{}; 1309 variable_field outActiveCompImageSetVersion{}; 1310 variable_field outPendingCompImageSetVersion{}; 1311 variable_field outCompParameterTable{}; 1312 1313 rc = decode_get_firmware_parameters_resp( 1314 nullptr, invalidGetFwParamsResponse1.size() - hdrSize, &outResp, 1315 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, 1316 &outCompParameterTable); 1317 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 1318 1319 rc = decode_get_firmware_parameters_resp( 1320 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, nullptr, 1321 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, 1322 &outCompParameterTable); 1323 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 1324 1325 rc = decode_get_firmware_parameters_resp( 1326 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp, 1327 nullptr, &outPendingCompImageSetVersion, &outCompParameterTable); 1328 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 1329 1330 rc = decode_get_firmware_parameters_resp( 1331 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp, 1332 &outActiveCompImageSetVersion, nullptr, &outCompParameterTable); 1333 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 1334 1335 rc = decode_get_firmware_parameters_resp( 1336 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp, 1337 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, nullptr); 1338 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 1339 1340 rc = decode_get_firmware_parameters_resp( 1341 responseMsg, 0, &outResp, &outActiveCompImageSetVersion, 1342 &outPendingCompImageSetVersion, &outCompParameterTable); 1343 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 1344 1345 rc = decode_get_firmware_parameters_resp( 1346 responseMsg, invalidGetFwParamsResponse1.size() - 1 - hdrSize, &outResp, 1347 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, 1348 &outCompParameterTable); 1349 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 1350 1351 rc = decode_get_firmware_parameters_resp( 1352 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp, 1353 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, 1354 &outCompParameterTable); 1355 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 1356 1357 // Invalid ActiveComponentImageSetVersionStringLength 1358 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse2{ 1359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1360 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}; 1361 responseMsg = 1362 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1363 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse2.data()); 1364 rc = decode_get_firmware_parameters_resp( 1365 responseMsg, invalidGetFwParamsResponse2.size() - hdrSize, &outResp, 1366 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, 1367 &outCompParameterTable); 1368 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 1369 1370 // Invalid PendingComponentImageSetVersionStringType & 1371 // PendingComponentImageSetVersionStringLength 1372 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse3{ 1373 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 1374 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x00}; 1375 responseMsg = 1376 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1377 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse3.data()); 1378 rc = decode_get_firmware_parameters_resp( 1379 responseMsg, invalidGetFwParamsResponse3.size() - hdrSize, &outResp, 1380 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, 1381 &outCompParameterTable); 1382 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 1383 1384 // Invalid PendingComponentImageSetVersionStringType & 1385 // PendingComponentImageSetVersionStringLength 1386 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse4{ 1387 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 1388 0x00, 0x00, 0x00, 0x01, 0x0e, 0x06, 0x0e}; 1389 responseMsg = 1390 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1391 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse4.data()); 1392 rc = decode_get_firmware_parameters_resp( 1393 responseMsg, invalidGetFwParamsResponse4.size() - hdrSize, &outResp, 1394 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, 1395 &outCompParameterTable); 1396 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 1397 1398 // Total payload length less than expected 1399 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse5{ 1400 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 1401 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x0e}; 1402 responseMsg = 1403 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1404 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse5.data()); 1405 rc = decode_get_firmware_parameters_resp( 1406 responseMsg, invalidGetFwParamsResponse5.size() - hdrSize, &outResp, 1407 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, 1408 &outCompParameterTable); 1409 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 1410 } 1411 1412 TEST(GetFirmwareParameters, goodPathDecodeComponentParameterEntry) 1413 { 1414 // Random value for component classification 1415 constexpr uint16_t compClassification = 0x0a0b; 1416 // Random value for component classification 1417 constexpr uint16_t compIdentifier = 0x0c0d; 1418 constexpr uint16_t compClassificationIndex = 0xf; 1419 // Random value for component classification 1420 constexpr uint32_t timestamp = 0x12345678; 1421 // Random value for component activation methods 1422 constexpr uint16_t compActivationMethods = 0xbbdd; 1423 // Random value for capabilities during update 1424 constexpr uint32_t capabilitiesDuringUpdate = 0xbadbeefe; 1425 1426 // ActiveCompImageSetVerStrLen is not fixed here taking it as 8 1427 constexpr uint8_t activeCompVerStrLen = 8; 1428 // PendingCompImageSetVerStrLen is not fixed here taking it as 8 1429 constexpr uint8_t pendingCompVerStrLen = 8; 1430 constexpr size_t entryLength = 1431 sizeof(struct pldm_component_parameter_entry) + activeCompVerStrLen + 1432 pendingCompVerStrLen; 1433 std::array<uint8_t, entryLength> entry{}; 1434 1435 auto inEntry = 1436 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1437 reinterpret_cast<struct pldm_component_parameter_entry*>(entry.data()); 1438 1439 inEntry->comp_classification = htole16(compClassification); 1440 inEntry->comp_identifier = htole16(compIdentifier); 1441 inEntry->comp_classification_index = compClassificationIndex; 1442 inEntry->active_comp_comparison_stamp = htole32(timestamp); 1443 inEntry->active_comp_ver_str_type = 1; 1444 inEntry->active_comp_ver_str_len = activeCompVerStrLen; 1445 std::fill_n(inEntry->active_comp_release_date, 1446 sizeof(inEntry->active_comp_release_date), 0xff); 1447 inEntry->pending_comp_comparison_stamp = htole32(timestamp); 1448 inEntry->pending_comp_ver_str_type = 1; 1449 inEntry->pending_comp_ver_str_len = pendingCompVerStrLen; 1450 std::fill_n(inEntry->pending_comp_release_date, 1451 sizeof(inEntry->pending_comp_release_date), 0xff); 1452 inEntry->comp_activation_methods.value = htole16(compActivationMethods); 1453 inEntry->capabilities_during_update.value = 1454 htole32(capabilitiesDuringUpdate); 1455 constexpr auto activeCompVerStrPos = 1456 sizeof(struct pldm_component_parameter_entry); 1457 std::fill_n(entry.data() + activeCompVerStrPos, activeCompVerStrLen, 0xaa); 1458 constexpr auto pendingCompVerStrPos = 1459 activeCompVerStrPos + activeCompVerStrLen; 1460 std::fill_n(entry.data() + pendingCompVerStrPos, pendingCompVerStrLen, 1461 0xbb); 1462 1463 struct pldm_component_parameter_entry outEntry; 1464 struct variable_field outActiveCompVerStr; 1465 struct variable_field outPendingCompVerStr; 1466 1467 auto rc = decode_get_firmware_parameters_resp_comp_entry( 1468 entry.data(), entryLength, &outEntry, &outActiveCompVerStr, 1469 &outPendingCompVerStr); 1470 1471 EXPECT_EQ(rc, PLDM_SUCCESS); 1472 1473 EXPECT_EQ(outEntry.comp_classification, compClassification); 1474 EXPECT_EQ(outEntry.comp_identifier, compIdentifier); 1475 EXPECT_EQ(inEntry->comp_classification_index, 1476 outEntry.comp_classification_index); 1477 EXPECT_EQ(outEntry.active_comp_comparison_stamp, timestamp); 1478 EXPECT_EQ(inEntry->active_comp_ver_str_type, 1479 outEntry.active_comp_ver_str_type); 1480 EXPECT_EQ(inEntry->active_comp_ver_str_len, 1481 outEntry.active_comp_ver_str_len); 1482 EXPECT_EQ(0, memcmp(inEntry->active_comp_release_date, 1483 outEntry.active_comp_release_date, 1484 sizeof(inEntry->active_comp_release_date))); 1485 EXPECT_EQ(outEntry.pending_comp_comparison_stamp, timestamp); 1486 EXPECT_EQ(inEntry->pending_comp_ver_str_type, 1487 outEntry.pending_comp_ver_str_type); 1488 EXPECT_EQ(inEntry->pending_comp_ver_str_len, 1489 outEntry.pending_comp_ver_str_len); 1490 EXPECT_EQ(0, memcmp(inEntry->pending_comp_release_date, 1491 outEntry.pending_comp_release_date, 1492 sizeof(inEntry->pending_comp_release_date))); 1493 EXPECT_EQ(outEntry.comp_activation_methods.value, compActivationMethods); 1494 EXPECT_EQ(outEntry.capabilities_during_update.value, 1495 capabilitiesDuringUpdate); 1496 1497 EXPECT_EQ(0, memcmp(outActiveCompVerStr.ptr, 1498 entry.data() + activeCompVerStrPos, 1499 outActiveCompVerStr.length)); 1500 EXPECT_EQ(0, memcmp(outPendingCompVerStr.ptr, 1501 entry.data() + pendingCompVerStrPos, 1502 outPendingCompVerStr.length)); 1503 1504 #ifdef LIBPLDM_API_TESTING 1505 /* Check the roundtrip matches */ 1506 std::vector<uint8_t> enc_data(1000); 1507 size_t enc_payload_len = enc_data.size(); 1508 struct pldm_component_parameter_entry_full entryFull = { 1509 .comp_classification = compClassification, 1510 .comp_identifier = compIdentifier, 1511 .comp_classification_index = compClassificationIndex, 1512 .active_ver = 1513 { 1514 .comparison_stamp = 0x12345678, 1515 .str = {.str_type = PLDM_STR_TYPE_ASCII, 1516 .str_len = activeCompVerStrLen, 1517 .str_data = {}}, 1518 .date = {}, 1519 }, 1520 .pending_ver = 1521 { 1522 .comparison_stamp = 0x12345678, 1523 .str = {.str_type = PLDM_STR_TYPE_ASCII, 1524 .str_len = pendingCompVerStrLen, 1525 .str_data = {}}, 1526 .date = {}, 1527 }, 1528 .comp_activation_methods = inEntry->comp_activation_methods, 1529 .capabilities_during_update = inEntry->capabilities_during_update, 1530 }; 1531 // Fill strings 1532 std::fill_n(entryFull.active_ver.str.str_data, activeCompVerStrLen, 0xaa); 1533 std::fill_n(entryFull.pending_ver.str.str_data, pendingCompVerStrLen, 0xbb); 1534 std::fill_n(entryFull.active_ver.date, PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN, 1535 0xff); 1536 std::fill_n(entryFull.pending_ver.date, 1537 PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN, 0xff); 1538 1539 rc = encode_get_firmware_parameters_resp_comp_entry( 1540 &entryFull, enc_data.data(), &enc_payload_len); 1541 EXPECT_EQ(rc, PLDM_SUCCESS); 1542 EXPECT_EQ(enc_payload_len, entryLength); 1543 EXPECT_TRUE(std::equal(entry.begin(), entry.end(), enc_data.begin())); 1544 #endif 1545 } 1546 1547 TEST(QueryDownstreamDevices, goodPathEncodeRequest) 1548 { 1549 constexpr uint8_t instanceId = 1; 1550 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{}; 1551 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1552 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); 1553 1554 auto rc = encode_query_downstream_devices_req(instanceId, requestPtr); 1555 1556 EXPECT_EQ(rc, 0); 1557 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST); 1558 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId); 1559 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP); 1560 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DOWNSTREAM_DEVICES); 1561 } 1562 1563 TEST(QueryDownstreamDevices, encodeRequestInvalidData) 1564 { 1565 constexpr uint8_t instanceId = 1; 1566 1567 auto rc = encode_query_downstream_devices_req(instanceId, nullptr); 1568 1569 EXPECT_EQ(rc, -EINVAL); 1570 } 1571 1572 TEST(QueryDownstreamDevices, goodPathDecodeResponse) 1573 { 1574 uint8_t completion_code_resp = PLDM_SUCCESS; 1575 uint8_t downstream_device_update_supported_resp = 1576 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED; 1577 uint16_t number_of_downstream_devices_resp = 1; 1578 uint16_t max_number_of_downstream_devices_resp = 1; 1579 /** Capabilities of updating downstream devices 1580 * FDP supports downstream devices dynamically attached [Bit position 0] & 1581 * FDP supports downstream devices dynamically removed [Bit position 1] 1582 */ 1583 bitfield32_t capabilities_resp = {.value = 0x0002}; 1584 int rc; 1585 1586 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES> 1587 responseMsg{}; 1588 1589 PLDM_MSGBUF_DEFINE_P(buf); 1590 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize, 1591 responseMsg.size() - hdrSize); 1592 EXPECT_EQ(rc, 0); 1593 1594 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 1595 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp); 1596 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 1597 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp); 1598 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value); 1599 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0); 1600 1601 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1602 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 1603 struct pldm_query_downstream_devices_resp resp_data; 1604 1605 rc = decode_query_downstream_devices_resp( 1606 response, responseMsg.size() - hdrSize, &resp_data); 1607 1608 EXPECT_EQ(rc, 0); 1609 EXPECT_EQ(resp_data.completion_code, completion_code_resp); 1610 EXPECT_EQ(resp_data.downstream_device_update_supported, 1611 downstream_device_update_supported_resp); 1612 EXPECT_EQ(resp_data.number_of_downstream_devices, 1613 number_of_downstream_devices_resp); 1614 EXPECT_EQ(resp_data.max_number_of_downstream_devices, 1615 max_number_of_downstream_devices_resp); 1616 EXPECT_EQ(resp_data.capabilities.value, capabilities_resp.value); 1617 } 1618 1619 TEST(QueryDownstreamDevices, decodeRequestUndefinedValue) 1620 { 1621 uint8_t completion_code_resp = PLDM_SUCCESS; 1622 uint8_t downstream_device_update_supported_resp = 0xe; /*Undefined value*/ 1623 uint16_t number_of_downstream_devices_resp = 1; 1624 uint16_t max_number_of_downstream_devices_resp = 1; 1625 /** Capabilities of updating downstream devices 1626 * FDP supports downstream devices dynamically attached [Bit position 0] & 1627 * FDP supports downstream devices dynamically removed [Bit position 1] 1628 */ 1629 bitfield32_t capabilities_resp = {.value = 0x0002}; 1630 int rc; 1631 1632 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES> 1633 responseMsg{}; 1634 1635 PLDM_MSGBUF_DEFINE_P(buf); 1636 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize, 1637 responseMsg.size() - hdrSize); 1638 ASSERT_EQ(rc, 0); 1639 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 1640 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp); 1641 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 1642 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp); 1643 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value); 1644 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0); 1645 1646 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1647 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 1648 struct pldm_query_downstream_devices_resp resp_data; 1649 1650 rc = decode_query_downstream_devices_resp( 1651 response, responseMsg.size() - hdrSize, &resp_data); 1652 1653 ASSERT_EQ(rc, -EINVAL); 1654 } 1655 1656 TEST(QueryDownstreamDevices, decodeRequestErrorBufSize) 1657 { 1658 uint8_t completion_code_resp = PLDM_SUCCESS; 1659 uint8_t downstream_device_update_supported_resp = 1660 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED; 1661 uint16_t number_of_downstream_devices_resp = 1; 1662 uint16_t max_number_of_downstream_devices_resp = 1; 1663 /** Capabilities of updating downstream devices 1664 * FDP supports downstream devices dynamically attached [Bit position 0] & 1665 * FDP supports downstream devices dynamically removed [Bit position 1] 1666 */ 1667 bitfield32_t capabilities_resp = {.value = 0x0002}; 1668 int rc; 1669 1670 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES - 1671 2 /* Inject error length*/> 1672 responseMsg{}; 1673 1674 PLDM_MSGBUF_DEFINE_P(buf); 1675 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize, 1676 responseMsg.size() - hdrSize); 1677 ASSERT_EQ(rc, 0); 1678 1679 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 1680 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp); 1681 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 1682 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp); 1683 // Inject error value 1684 pldm_msgbuf_insert_uint16(buf, (uint16_t)capabilities_resp.value); 1685 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0); 1686 1687 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1688 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 1689 struct pldm_query_downstream_devices_resp resp_data; 1690 1691 rc = decode_query_downstream_devices_resp( 1692 response, responseMsg.size() - hdrSize, &resp_data); 1693 1694 EXPECT_EQ(rc, -EBADMSG); 1695 } 1696 1697 TEST(QueryDownstreamIdentifiers, goodPathEncodeRequest) 1698 { 1699 constexpr uint8_t instanceId = 1; 1700 constexpr size_t payloadLen = PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES; 1701 PLDM_MSG_DEFINE_P(request, payloadLen); 1702 constexpr pldm_query_downstream_identifiers_req params_req{ 1703 0xFFFFFFFF, PLDM_GET_FIRSTPART}; 1704 1705 auto rc = encode_query_downstream_identifiers_req(instanceId, ¶ms_req, 1706 request, payloadLen); 1707 ASSERT_EQ(rc, 0); 1708 EXPECT_THAT(std::span<uint8_t>(request_buf, sizeof(request_buf)), 1709 ElementsAreArray<uint8_t>( 1710 {0x81, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x01})); 1711 } 1712 1713 TEST(QueryDownstreamIdentifiers, encodeRequestInvalidErrorPaths) 1714 { 1715 constexpr uint8_t instanceId = 1; 1716 constexpr pldm_query_downstream_identifiers_req params_req{ 1717 0xFFFFFFFF, PLDM_GET_FIRSTPART}; 1718 constexpr pldm_query_downstream_identifiers_req params_req_invalid{ 1719 0xFFFFFFFF, PLDM_ACKNOWLEDGEMENT_ONLY}; 1720 constexpr size_t payload_length = 1721 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES; 1722 std::array<uint8_t, hdrSize + payload_length> requestMsg{}; 1723 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1724 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); 1725 1726 auto rc = encode_query_downstream_identifiers_req(instanceId, ¶ms_req, 1727 nullptr, payload_length); 1728 EXPECT_EQ(rc, -EINVAL); 1729 1730 rc = encode_query_downstream_identifiers_req( 1731 instanceId, ¶ms_req, requestPtr, payload_length - 1); 1732 EXPECT_EQ(rc, -EOVERFLOW); 1733 1734 rc = encode_query_downstream_identifiers_req( 1735 instanceId, ¶ms_req_invalid, requestPtr, payload_length); 1736 EXPECT_EQ(rc, -EINVAL); 1737 } 1738 1739 TEST(QueryDownstreamIdentifiers, decodeResponseNoDevices) 1740 { 1741 constexpr uint8_t completion_code_resp = PLDM_SUCCESS; 1742 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 1743 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 1744 constexpr uint32_t downstream_devices_length_resp = 0; 1745 constexpr uint16_t number_of_downstream_devices_resp = 0; 1746 1747 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN); 1748 struct pldm_query_downstream_identifiers_resp resp_data = {}; 1749 struct pldm_downstream_device_iter devs; 1750 PLDM_MSGBUF_DEFINE_P(buf); 1751 int rc = 0; 1752 1753 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, 1754 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN); 1755 ASSERT_EQ(rc, 0); 1756 1757 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 1758 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 1759 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 1760 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp); 1761 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 1762 1763 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0); 1764 1765 rc = decode_query_downstream_identifiers_resp( 1766 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp_data, 1767 &devs); 1768 1769 ASSERT_EQ(rc, 0); 1770 EXPECT_EQ(resp_data.completion_code, completion_code_resp); 1771 EXPECT_EQ(resp_data.next_data_transfer_handle, 1772 next_data_transfer_handle_resp); 1773 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp); 1774 EXPECT_EQ(resp_data.downstream_devices_length, 1775 downstream_devices_length_resp); 1776 EXPECT_EQ(resp_data.number_of_downstream_devices, 1777 number_of_downstream_devices_resp); 1778 } 1779 1780 TEST(QueryDownstreamIdentifiers, decodeResponseNoDevicesBadCount) 1781 { 1782 constexpr uint8_t completion_code_resp = PLDM_SUCCESS; 1783 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 1784 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 1785 constexpr uint32_t downstream_devices_length_resp = 0; 1786 constexpr uint16_t number_of_downstream_devices_resp = 1; 1787 1788 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN); 1789 struct pldm_query_downstream_identifiers_resp resp = {}; 1790 struct pldm_downstream_device_iter devs; 1791 struct pldm_downstream_device dev; 1792 PLDM_MSGBUF_DEFINE_P(buf); 1793 int rc = 0; 1794 1795 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, 1796 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN); 1797 ASSERT_EQ(rc, 0); 1798 1799 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 1800 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 1801 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 1802 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp); 1803 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 1804 1805 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0); 1806 1807 rc = decode_query_downstream_identifiers_resp( 1808 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp, &devs); 1809 ASSERT_EQ(rc, 0); 1810 1811 foreach_pldm_downstream_device(devs, dev, rc) 1812 { 1813 FAIL(); 1814 } 1815 ASSERT_NE(rc, 0); 1816 } 1817 1818 TEST(QueryDownstreamIdentifiers, decodeResponseOneDeviceOneDescriptor) 1819 { 1820 constexpr uint32_t downstreamDevicesLen = 11; 1821 constexpr uint8_t completion_code_resp = PLDM_SUCCESS; 1822 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 1823 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 1824 const uint32_t downstream_devices_length_resp = 1825 htole32(downstreamDevicesLen); 1826 constexpr uint16_t number_of_downstream_devices_resp = 1; 1827 constexpr size_t payloadLen = 1828 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstreamDevicesLen; 1829 1830 struct pldm_query_downstream_identifiers_resp resp_data = {}; 1831 PLDM_MSG_DEFINE_P(response, payloadLen); 1832 struct pldm_downstream_device_iter devs; 1833 struct pldm_downstream_device dev; 1834 PLDM_MSGBUF_DEFINE_P(buf); 1835 int rc = 0; 1836 1837 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen); 1838 ASSERT_EQ(rc, 0); 1839 1840 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 1841 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 1842 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 1843 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp); 1844 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 1845 1846 /* Downstream device */ 1847 pldm_msgbuf_insert_uint16(buf, 1); 1848 pldm_msgbuf_insert_uint8(buf, 1); 1849 1850 /* Device descriptor */ 1851 pldm_msgbuf_insert_uint16(buf, 1); 1852 pldm_msgbuf_insert_uint16(buf, 4); 1853 pldm_msgbuf_insert_uint32(buf, 412); 1854 1855 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0); 1856 1857 rc = decode_query_downstream_identifiers_resp(response, payloadLen, 1858 &resp_data, &devs); 1859 1860 ASSERT_EQ(rc, 0); 1861 EXPECT_EQ(resp_data.completion_code, completion_code_resp); 1862 EXPECT_EQ(resp_data.next_data_transfer_handle, 1863 next_data_transfer_handle_resp); 1864 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp); 1865 EXPECT_EQ(resp_data.downstream_devices_length, 1866 downstream_devices_length_resp); 1867 EXPECT_EQ(resp_data.number_of_downstream_devices, 1868 number_of_downstream_devices_resp); 1869 1870 foreach_pldm_downstream_device(devs, dev, rc) 1871 { 1872 struct pldm_descriptor desc; 1873 1874 EXPECT_EQ(dev.downstream_device_index, 1); 1875 EXPECT_EQ(dev.downstream_descriptor_count, 1); 1876 1877 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc) 1878 { 1879 static const uint32_t dmtf = htole32(412); 1880 EXPECT_EQ(desc.descriptor_type, 1); 1881 EXPECT_EQ(desc.descriptor_length, 4); 1882 EXPECT_EQ(memcmp(desc.descriptor_data, &dmtf, sizeof(dmtf)), 0); 1883 } 1884 ASSERT_EQ(rc, 0); 1885 } 1886 ASSERT_EQ(rc, 0); 1887 } 1888 1889 constexpr const uint16_t descriptor_id_type_iana_pen = 0x1; 1890 constexpr const uint16_t descriptor_id_len_iana_pen = 0x4; 1891 const uint32_t iana_pen_openbmc = htole16(49871u); 1892 const uint32_t iana_pen_dmtf = htole16(412u); 1893 1894 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneDescriptorEach) 1895 { 1896 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{ 1897 {0, 1}, 1898 {1, 1}, 1899 }}; 1900 1901 constexpr const std::array<pldm_descriptor, 2> expected_descriptors = {{ 1902 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen, 1903 &iana_pen_dmtf}, 1904 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen, 1905 &iana_pen_openbmc}, 1906 }}; 1907 1908 constexpr uint32_t downstream_devices_len = 22; 1909 constexpr uint8_t completion_code_resp = PLDM_SUCCESS; 1910 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 1911 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 1912 const uint32_t downstream_devices_length_resp = 1913 htole32(downstream_devices_len); 1914 constexpr uint16_t number_of_downstream_devices_resp = 2; 1915 constexpr size_t payloadLen = 1916 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len; 1917 1918 struct pldm_query_downstream_identifiers_resp resp_data{}; 1919 PLDM_MSG_DEFINE_P(response, payloadLen); 1920 struct pldm_downstream_device_iter devs; 1921 struct pldm_downstream_device dev; 1922 PLDM_MSGBUF_DEFINE_P(buf); 1923 int rc = 0; 1924 1925 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen); 1926 ASSERT_EQ(rc, 0); 1927 1928 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 1929 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 1930 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 1931 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp); 1932 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 1933 1934 /* Downstream device */ 1935 pldm_msgbuf_insert_uint16(buf, 0); 1936 pldm_msgbuf_insert_uint8(buf, 1); 1937 1938 /* Device descriptor */ 1939 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen); 1940 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen); 1941 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf); 1942 1943 /* Downstream device */ 1944 pldm_msgbuf_insert_uint16(buf, 1); 1945 pldm_msgbuf_insert_uint8(buf, 1); 1946 1947 /* Device descriptor */ 1948 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen); 1949 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen); 1950 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc); 1951 1952 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0); 1953 1954 rc = decode_query_downstream_identifiers_resp(response, payloadLen, 1955 &resp_data, &devs); 1956 1957 ASSERT_EQ(rc, 0); 1958 EXPECT_EQ(resp_data.number_of_downstream_devices, 1959 number_of_downstream_devices_resp); 1960 1961 size_t devIndex = 0; 1962 size_t descIndex = 0; 1963 foreach_pldm_downstream_device(devs, dev, rc) 1964 { 1965 struct pldm_descriptor desc; 1966 1967 ASSERT_LT(devIndex, expected_devices.size()); 1968 1969 const struct pldm_downstream_device* expectedDev = 1970 &expected_devices[devIndex]; 1971 1972 EXPECT_EQ(dev.downstream_device_index, 1973 expectedDev->downstream_device_index); 1974 EXPECT_EQ(dev.downstream_descriptor_count, 1975 expectedDev->downstream_descriptor_count); 1976 1977 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc) 1978 { 1979 ASSERT_LT(descIndex, expected_descriptors.size()); 1980 1981 const struct pldm_descriptor* expectedDesc = 1982 &expected_descriptors[descIndex]; 1983 1984 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type); 1985 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length); 1986 EXPECT_EQ(memcmp(desc.descriptor_data, 1987 expectedDesc->descriptor_data, 1988 expectedDesc->descriptor_length), 1989 0); 1990 1991 descIndex++; 1992 } 1993 ASSERT_EQ(rc, 0); 1994 EXPECT_EQ(descIndex, 1 * devIndex + 1); 1995 1996 devIndex++; 1997 } 1998 ASSERT_EQ(rc, 0); 1999 EXPECT_EQ(devIndex, 2); 2000 } 2001 2002 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesTwoOneDescriptors) 2003 { 2004 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{ 2005 {0, 2}, 2006 {1, 1}, 2007 }}; 2008 2009 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{ 2010 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen, 2011 &iana_pen_dmtf}, 2012 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen, 2013 &iana_pen_openbmc}, 2014 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen, 2015 &iana_pen_dmtf}, 2016 }}; 2017 2018 constexpr uint32_t downstream_devices_len = 30; 2019 constexpr uint8_t completion_code_resp = PLDM_SUCCESS; 2020 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 2021 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 2022 const uint32_t downstream_devices_length_resp = 2023 htole32(downstream_devices_len); 2024 constexpr uint16_t number_of_downstream_devices_resp = 2; 2025 constexpr size_t payloadLen = 2026 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len; 2027 2028 struct pldm_query_downstream_identifiers_resp resp_data{}; 2029 PLDM_MSG_DEFINE_P(response, payloadLen); 2030 struct pldm_downstream_device_iter devs; 2031 struct pldm_downstream_device dev; 2032 PLDM_MSGBUF_DEFINE_P(buf); 2033 int rc = 0; 2034 2035 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen); 2036 ASSERT_EQ(rc, 0); 2037 2038 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 2039 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 2040 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 2041 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp); 2042 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 2043 2044 /* Downstream device */ 2045 pldm_msgbuf_insert_uint16(buf, 0); 2046 pldm_msgbuf_insert_uint8(buf, 2); 2047 2048 /* Device descriptor */ 2049 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen); 2050 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen); 2051 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf); 2052 2053 /* Device descriptor */ 2054 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen); 2055 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen); 2056 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc); 2057 2058 /* Downstream device */ 2059 pldm_msgbuf_insert_uint16(buf, 1); 2060 pldm_msgbuf_insert_uint8(buf, 1); 2061 2062 /* Device descriptor */ 2063 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen); 2064 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen); 2065 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf); 2066 2067 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0); 2068 2069 rc = decode_query_downstream_identifiers_resp(response, payloadLen, 2070 &resp_data, &devs); 2071 2072 ASSERT_EQ(rc, 0); 2073 EXPECT_EQ(resp_data.number_of_downstream_devices, 2074 number_of_downstream_devices_resp); 2075 2076 size_t devIndex = 0; 2077 size_t descIndex = 0; 2078 foreach_pldm_downstream_device(devs, dev, rc) 2079 { 2080 struct pldm_descriptor desc; 2081 2082 ASSERT_LT(devIndex, expected_devices.size()); 2083 2084 const struct pldm_downstream_device* expectedDev = 2085 &expected_devices[devIndex]; 2086 2087 EXPECT_EQ(dev.downstream_device_index, 2088 expectedDev->downstream_device_index); 2089 EXPECT_EQ(dev.downstream_descriptor_count, 2090 expectedDev->downstream_descriptor_count); 2091 2092 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc) 2093 { 2094 ASSERT_LT(descIndex, expected_descriptors.size()); 2095 2096 const struct pldm_descriptor* expectedDesc = 2097 &expected_descriptors[descIndex]; 2098 2099 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type); 2100 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length); 2101 EXPECT_EQ(memcmp(desc.descriptor_data, 2102 expectedDesc->descriptor_data, 2103 expectedDesc->descriptor_length), 2104 0); 2105 2106 descIndex++; 2107 } 2108 ASSERT_EQ(rc, 0); 2109 2110 devIndex++; 2111 } 2112 ASSERT_EQ(rc, 0); 2113 EXPECT_EQ(devIndex, 2); 2114 EXPECT_EQ(descIndex, 3); 2115 } 2116 2117 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneTwoDescriptors) 2118 { 2119 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{ 2120 {0, 1}, 2121 {1, 2}, 2122 }}; 2123 2124 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{ 2125 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen, 2126 &iana_pen_dmtf}, 2127 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen, 2128 &iana_pen_openbmc}, 2129 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen, 2130 &iana_pen_dmtf}, 2131 }}; 2132 2133 constexpr uint32_t downstream_devices_len = 30; 2134 constexpr uint8_t completion_code_resp = PLDM_SUCCESS; 2135 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 2136 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 2137 const uint32_t downstream_devices_length_resp = 2138 htole32(downstream_devices_len); 2139 constexpr uint16_t number_of_downstream_devices_resp = 2; 2140 constexpr size_t payloadLen = 2141 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len; 2142 2143 struct pldm_query_downstream_identifiers_resp resp_data{}; 2144 PLDM_MSG_DEFINE_P(response, payloadLen); 2145 struct pldm_downstream_device_iter devs; 2146 struct pldm_downstream_device dev; 2147 PLDM_MSGBUF_DEFINE_P(buf); 2148 int rc = 0; 2149 2150 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen); 2151 ASSERT_EQ(rc, 0); 2152 2153 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 2154 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 2155 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 2156 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp); 2157 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 2158 2159 /* Downstream device */ 2160 pldm_msgbuf_insert_uint16(buf, 0); 2161 pldm_msgbuf_insert_uint8(buf, 1); 2162 2163 /* Device descriptor */ 2164 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen); 2165 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen); 2166 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf); 2167 2168 /* Downstream device */ 2169 pldm_msgbuf_insert_uint16(buf, 1); 2170 pldm_msgbuf_insert_uint8(buf, 2); 2171 2172 /* Device descriptor */ 2173 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen); 2174 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen); 2175 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc); 2176 2177 /* Device descriptor */ 2178 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen); 2179 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen); 2180 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf); 2181 2182 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0); 2183 2184 rc = decode_query_downstream_identifiers_resp(response, payloadLen, 2185 &resp_data, &devs); 2186 2187 ASSERT_EQ(rc, 0); 2188 EXPECT_EQ(resp_data.number_of_downstream_devices, 2189 number_of_downstream_devices_resp); 2190 2191 size_t devIndex = 0; 2192 size_t descIndex = 0; 2193 foreach_pldm_downstream_device(devs, dev, rc) 2194 { 2195 struct pldm_descriptor desc; 2196 2197 ASSERT_LT(devIndex, expected_devices.size()); 2198 2199 const struct pldm_downstream_device* expectedDev = 2200 &expected_devices[devIndex]; 2201 2202 EXPECT_EQ(dev.downstream_device_index, 2203 expectedDev->downstream_device_index); 2204 EXPECT_EQ(dev.downstream_descriptor_count, 2205 expectedDev->downstream_descriptor_count); 2206 2207 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc) 2208 { 2209 ASSERT_LT(descIndex, expected_descriptors.size()); 2210 2211 const struct pldm_descriptor* expectedDesc = 2212 &expected_descriptors[descIndex]; 2213 2214 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type); 2215 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length); 2216 EXPECT_EQ(memcmp(desc.descriptor_data, 2217 expectedDesc->descriptor_data, 2218 expectedDesc->descriptor_length), 2219 0); 2220 2221 descIndex++; 2222 } 2223 ASSERT_EQ(rc, 0); 2224 2225 devIndex++; 2226 } 2227 ASSERT_EQ(rc, 0); 2228 EXPECT_EQ(devIndex, 2); 2229 EXPECT_EQ(descIndex, 3); 2230 } 2231 2232 TEST(QueryDownstreamIdentifiers, decodeRequestErrorPaths) 2233 { 2234 constexpr size_t payloadLen = sizeof(uint8_t); 2235 2236 struct pldm_query_downstream_identifiers_resp resp_data = {}; 2237 struct pldm_downstream_device_iter devs; 2238 PLDM_MSG_DEFINE_P(response, payloadLen); 2239 2240 // Test nullptr 2241 auto rc = decode_query_downstream_identifiers_resp(nullptr, payloadLen, 2242 nullptr, &devs); 2243 EXPECT_EQ(rc, -EINVAL); 2244 2245 // Test not PLDM_SUCCESS completion code 2246 response->payload[0] = PLDM_ERROR_UNSUPPORTED_PLDM_CMD; 2247 rc = decode_query_downstream_identifiers_resp(response, payloadLen, 2248 &resp_data, &devs); 2249 EXPECT_EQ(rc, 0); 2250 EXPECT_EQ(resp_data.completion_code, PLDM_ERROR_UNSUPPORTED_PLDM_CMD); 2251 2252 // Test payload length less than minimum length 2253 response->payload[0] = PLDM_SUCCESS; 2254 rc = decode_query_downstream_identifiers_resp(response, payloadLen, 2255 &resp_data, &devs); 2256 2257 EXPECT_EQ(rc, -EBADMSG); 2258 } 2259 2260 TEST(QueryDownstreamIdentifiers, decodeRequestErrorDownstreamDevicesSize) 2261 { 2262 // Len is not fixed here taking it as 9, contains 1 downstream device with 2263 // 1 descriptor 2264 constexpr uint32_t actualDownstreamDevicesLen = 9; 2265 constexpr uint8_t complition_code_resp = PLDM_SUCCESS; 2266 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 2267 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 2268 constexpr uint16_t number_of_downstream_devices_resp = 1; 2269 constexpr size_t payloadLen = 2270 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + 2271 actualDownstreamDevicesLen; 2272 2273 const uint32_t downstream_devices_length_resp = 2274 htole32(actualDownstreamDevicesLen + 1 /* inject error length*/); 2275 2276 struct pldm_query_downstream_identifiers_resp resp_data = {}; 2277 struct pldm_downstream_device_iter devs; 2278 PLDM_MSG_DEFINE_P(response, payloadLen); 2279 PLDM_MSGBUF_DEFINE_P(buf); 2280 void* devicesStart = NULL; 2281 size_t devicesLen; 2282 int rc = 0; 2283 2284 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen); 2285 ASSERT_EQ(rc, 0); 2286 2287 pldm_msgbuf_insert_uint8(buf, complition_code_resp); 2288 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 2289 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 2290 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp); 2291 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 2292 pldm_msgbuf_span_remaining(buf, &devicesStart, &devicesLen); 2293 2294 ASSERT_EQ(0, pldm_msgbuf_complete(buf)); 2295 2296 /** Filling descriptor data, the correctness of the downstream devices data 2297 * is not checked in this test case so filling with 0xff 2298 */ 2299 std::fill_n(static_cast<uint8_t*>(devicesStart), actualDownstreamDevicesLen, 2300 0xff); 2301 2302 EXPECT_NE(decode_query_downstream_identifiers_resp(response, payloadLen, 2303 &resp_data, &devs), 2304 0); 2305 } 2306 2307 TEST(QueryDownstreamIdentifiers, decodeRequestErrorBufSize) 2308 { 2309 constexpr uint32_t actualDownstreamDevicesLen = 0; 2310 constexpr uint16_t number_of_downstream_devices_resp = 1; 2311 constexpr uint8_t complition_code_resp = PLDM_SUCCESS; 2312 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 2313 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 2314 constexpr size_t payloadLen = 2315 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN - 1; 2316 2317 const uint32_t downstream_devices_length_resp = 2318 htole32(actualDownstreamDevicesLen); 2319 2320 struct pldm_query_downstream_identifiers_resp resp_data = {}; 2321 struct pldm_downstream_device_iter devs; 2322 PLDM_MSG_DEFINE_P(response, payloadLen); 2323 PLDM_MSGBUF_DEFINE_P(buf); 2324 int rc = 0; 2325 2326 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen); 2327 ASSERT_EQ(rc, 0); 2328 2329 pldm_msgbuf_insert_uint8(buf, complition_code_resp); 2330 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 2331 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 2332 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp); 2333 // Inject error buffer size 2334 pldm_msgbuf_insert_uint8(buf, (uint8_t)number_of_downstream_devices_resp); 2335 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0); 2336 2337 rc = decode_query_downstream_identifiers_resp(response, payloadLen, 2338 &resp_data, &devs); 2339 2340 EXPECT_EQ(rc, -EBADMSG); 2341 } 2342 2343 TEST(GetDownstreamFirmwareParameters, goodPathEncodeRequest) 2344 { 2345 constexpr uint8_t instanceId = 1; 2346 constexpr pldm_get_downstream_firmware_parameters_req params_req{ 2347 0x0, PLDM_GET_FIRSTPART}; 2348 constexpr size_t payload_length = 2349 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES; 2350 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{}; 2351 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2352 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); 2353 2354 auto rc = encode_get_downstream_firmware_parameters_req( 2355 instanceId, ¶ms_req, requestPtr, payload_length); 2356 EXPECT_EQ(rc, 0); 2357 2358 std::array<uint8_t, 2359 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES> 2360 expectedReq{0x81, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01}; 2361 EXPECT_EQ(requestMsg, expectedReq); 2362 } 2363 2364 TEST(GetDownstreamFirmwareParameters, encodeRequestInvalidTransferOperationFlag) 2365 { 2366 constexpr uint8_t instanceId = 1; 2367 // Setup invalid transfer operation flag 2368 constexpr pldm_get_downstream_firmware_parameters_req params_req{ 2369 0x0, PLDM_ACKNOWLEDGEMENT_ONLY}; 2370 constexpr size_t payload_length = 2371 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES; 2372 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{}; 2373 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2374 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); 2375 2376 auto rc = encode_get_downstream_firmware_parameters_req( 2377 instanceId, ¶ms_req, requestPtr, payload_length); 2378 EXPECT_EQ(rc, -EBADMSG); 2379 } 2380 2381 TEST(GetDownstreamFirmwareParameters, encodeRequestErrorBufSize) 2382 { 2383 constexpr uint8_t instanceId = 1; 2384 // Setup invalid transfer operation flag 2385 constexpr pldm_get_downstream_firmware_parameters_req params_req{ 2386 0x0, PLDM_GET_FIRSTPART}; 2387 constexpr size_t payload_length = 2388 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES - 2389 1 /* inject erro length*/; 2390 2391 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{}; 2392 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2393 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); 2394 2395 auto rc = encode_get_downstream_firmware_parameters_req( 2396 instanceId, ¶ms_req, requestPtr, payload_length); 2397 EXPECT_EQ(rc, -EOVERFLOW); 2398 } 2399 2400 TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseOneEntry) 2401 { 2402 constexpr uint16_t downstreamDeviceCount = 1; 2403 constexpr uint8_t activeComponentVersionStringLength = 8; 2404 constexpr uint8_t pendingComponentVersionStringLength = 8; 2405 constexpr size_t downstreamDeviceParamTableLen = 2406 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN + 2407 activeComponentVersionStringLength + 2408 pendingComponentVersionStringLength; 2409 constexpr uint8_t completion_code_resp = PLDM_SUCCESS; 2410 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 2411 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 2412 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002}; 2413 constexpr size_t payload_len = 2414 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN + 2415 downstreamDeviceParamTableLen; 2416 2417 PLDM_MSG_DEFINE_P(response, payload_len); 2418 PLDM_MSGBUF_DEFINE_P(buf); 2419 int rc = 0; 2420 2421 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len); 2422 ASSERT_EQ(rc, 0); 2423 2424 // Table 24 2425 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 2426 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 2427 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 2428 2429 // Table 25 2430 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value); 2431 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount); 2432 2433 // Table 26 2434 pldm_msgbuf_insert_uint16(buf, 0); 2435 2436 // - Active metadata 2437 pldm_msgbuf_insert_uint32(buf, 0); 2438 pldm_msgbuf_insert_uint8(buf, 1); 2439 pldm_msgbuf_insert_uint8(buf, activeComponentVersionStringLength); 2440 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8); 2441 ASSERT_EQ(rc, 0); 2442 2443 // - Pending metadata 2444 pldm_msgbuf_insert_uint32(buf, 0); 2445 pldm_msgbuf_insert_uint8(buf, 1); 2446 pldm_msgbuf_insert_uint8(buf, pendingComponentVersionStringLength); 2447 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8); 2448 ASSERT_EQ(rc, 0); 2449 2450 // - Methods and capabilities 2451 pldm_msgbuf_insert_uint16(buf, 1); 2452 pldm_msgbuf_insert_uint32(buf, 0); 2453 2454 // - Version strings 2455 rc = pldm__msgbuf_insert_array_void(buf, activeComponentVersionStringLength, 2456 "abcdefgh", 8); 2457 ASSERT_EQ(rc, 0); 2458 rc = pldm__msgbuf_insert_array_void( 2459 buf, pendingComponentVersionStringLength, "zyxwvuts", 8); 2460 ASSERT_EQ(rc, 0); 2461 2462 rc = pldm_msgbuf_complete_consumed(buf); 2463 ASSERT_EQ(rc, 0); 2464 2465 struct pldm_get_downstream_firmware_parameters_resp resp_data = {}; 2466 struct pldm_downstream_device_parameters_iter iter = {}; 2467 2468 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len, 2469 &resp_data, &iter); 2470 2471 ASSERT_EQ(rc, 0); 2472 EXPECT_EQ(resp_data.completion_code, completion_code_resp); 2473 EXPECT_EQ(resp_data.next_data_transfer_handle, 2474 next_data_transfer_handle_resp); 2475 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp); 2476 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount); 2477 2478 struct pldm_downstream_device_parameters_entry entry; 2479 size_t entries = 0; 2480 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc) 2481 { 2482 EXPECT_EQ(entry.downstream_device_index, 0); 2483 EXPECT_EQ(entry.active_comp_comparison_stamp, 0); 2484 EXPECT_EQ(entry.active_comp_ver_str_type, 1); 2485 EXPECT_EQ(entry.active_comp_ver_str_len, 2486 activeComponentVersionStringLength); 2487 EXPECT_STREQ("20241206", entry.active_comp_release_date); 2488 EXPECT_EQ(entry.pending_comp_comparison_stamp, 0); 2489 EXPECT_EQ(entry.pending_comp_ver_str_type, 1); 2490 EXPECT_EQ(entry.pending_comp_ver_str_len, 2491 pendingComponentVersionStringLength); 2492 EXPECT_STREQ("20241206", entry.pending_comp_release_date); 2493 EXPECT_EQ(entry.comp_activation_methods.value, 1); 2494 EXPECT_EQ(entry.capabilities_during_update.value, 0); 2495 EXPECT_FALSE(memcmp("abcdefgh", entry.active_comp_ver_str, 2496 entry.active_comp_ver_str_len)); 2497 EXPECT_FALSE(memcmp("zyxwvuts", entry.pending_comp_ver_str, 2498 entry.pending_comp_ver_str_len)); 2499 entries++; 2500 } 2501 EXPECT_EQ(rc, 0); 2502 EXPECT_EQ(entries, 1); 2503 } 2504 2505 TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseTwoEntries) 2506 { 2507 /** Count is not fixed here taking it as 1, and the downstream device's 2508 * version strings length are set to 8 2509 */ 2510 constexpr uint16_t downstreamDeviceCount = 2; 2511 constexpr uint8_t activeComponentVersionStringLength = 8; 2512 constexpr uint8_t pendingComponentVersionStringLength = 9; 2513 constexpr size_t downstreamDeviceParamTableLen = 2514 static_cast<size_t>(downstreamDeviceCount * 2515 (PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN + 2516 activeComponentVersionStringLength + 2517 pendingComponentVersionStringLength)); 2518 constexpr uint8_t completion_code_resp = PLDM_SUCCESS; 2519 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 2520 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 2521 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002}; 2522 constexpr size_t payload_len = 2523 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN + 2524 downstreamDeviceParamTableLen; 2525 2526 PLDM_MSG_DEFINE_P(response, payload_len); 2527 PLDM_MSGBUF_DEFINE_P(buf); 2528 int rc = 0; 2529 2530 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len); 2531 ASSERT_EQ(rc, 0); 2532 2533 // Table 24 2534 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 2535 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 2536 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 2537 2538 // Table 25 2539 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value); 2540 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount); 2541 2542 constexpr const std::array<pldm_downstream_device_parameters_entry, 2> 2543 table = {{{ 2544 0, 2545 0, 2546 1, 2547 8, 2548 "20241206", 2549 0, 2550 1, 2551 9, 2552 "20241209", 2553 {1}, 2554 {0}, 2555 "active_0", 2556 "pending_0", 2557 }, 2558 { 2559 1, 2560 0, 2561 1, 2562 8, 2563 "20241209", 2564 0, 2565 1, 2566 9, 2567 "20241206", 2568 {1}, 2569 {0}, 2570 "active_1", 2571 "pending_1", 2572 }}}; 2573 for (const auto& e : table) 2574 { 2575 // Table 26 2576 pldm_msgbuf_insert_uint16(buf, e.downstream_device_index); 2577 2578 // - Active metadata 2579 pldm_msgbuf_insert_uint32(buf, e.active_comp_comparison_stamp); 2580 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_type); 2581 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_len); 2582 rc = pldm__msgbuf_insert_array_void(buf, 8, &e.active_comp_release_date, 2583 sizeof(e.active_comp_release_date)); 2584 ASSERT_EQ(rc, 0); 2585 2586 // - Pending metadata 2587 pldm_msgbuf_insert_uint32(buf, e.pending_comp_comparison_stamp); 2588 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_type); 2589 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_len); 2590 rc = 2591 pldm__msgbuf_insert_array_void(buf, 8, e.pending_comp_release_date, 2592 sizeof(e.pending_comp_release_date)); 2593 ASSERT_EQ(rc, 0); 2594 2595 // - Methods and capabilities 2596 pldm_msgbuf_insert_uint16(buf, e.comp_activation_methods.value); 2597 pldm_msgbuf_insert_uint32(buf, e.capabilities_during_update.value); 2598 2599 // - Version strings 2600 rc = pldm__msgbuf_insert_array_void(buf, e.active_comp_ver_str_len, 2601 e.active_comp_ver_str, 2602 e.active_comp_ver_str_len); 2603 ASSERT_EQ(rc, 0); 2604 rc = pldm__msgbuf_insert_array_void(buf, e.pending_comp_ver_str_len, 2605 e.pending_comp_ver_str, 2606 e.pending_comp_ver_str_len); 2607 ASSERT_EQ(rc, 0); 2608 } 2609 2610 rc = pldm_msgbuf_complete_consumed(buf); 2611 ASSERT_EQ(rc, 0); 2612 2613 struct pldm_get_downstream_firmware_parameters_resp resp_data = {}; 2614 struct pldm_downstream_device_parameters_iter iter = {}; 2615 2616 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len, 2617 &resp_data, &iter); 2618 2619 ASSERT_EQ(rc, 0); 2620 EXPECT_EQ(resp_data.completion_code, completion_code_resp); 2621 EXPECT_EQ(resp_data.next_data_transfer_handle, 2622 next_data_transfer_handle_resp); 2623 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp); 2624 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount); 2625 2626 struct pldm_downstream_device_parameters_entry entry; 2627 size_t entryIndex = 0; 2628 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc) 2629 { 2630 ASSERT_LE(entryIndex, table.size()); 2631 2632 EXPECT_EQ(table[entryIndex].downstream_device_index, 2633 entry.downstream_device_index); 2634 EXPECT_EQ(table[entryIndex].active_comp_comparison_stamp, 2635 entry.active_comp_comparison_stamp); 2636 EXPECT_EQ(table[entryIndex].active_comp_ver_str_type, 2637 entry.active_comp_ver_str_type); 2638 EXPECT_EQ(table[entryIndex].active_comp_ver_str_len, 2639 entry.active_comp_ver_str_len); 2640 EXPECT_STREQ(&table[entryIndex].active_comp_release_date[0], 2641 &entry.active_comp_release_date[0]); 2642 EXPECT_EQ(table[entryIndex].pending_comp_comparison_stamp, 2643 entry.pending_comp_comparison_stamp); 2644 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_type, 2645 entry.pending_comp_ver_str_type); 2646 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_len, 2647 entry.pending_comp_ver_str_len); 2648 EXPECT_STREQ(&table[entryIndex].pending_comp_release_date[0], 2649 &entry.pending_comp_release_date[0]); 2650 EXPECT_EQ(table[entryIndex].comp_activation_methods.value, 2651 entry.comp_activation_methods.value); 2652 EXPECT_EQ(table[entryIndex].capabilities_during_update.value, 2653 entry.capabilities_during_update.value); 2654 EXPECT_FALSE(memcmp(table[entryIndex].active_comp_ver_str, 2655 entry.active_comp_ver_str, 2656 table[entryIndex].active_comp_ver_str_len)); 2657 EXPECT_FALSE(memcmp(table[entryIndex].pending_comp_ver_str, 2658 entry.pending_comp_ver_str, 2659 table[entryIndex].pending_comp_ver_str_len)); 2660 entryIndex++; 2661 } 2662 EXPECT_EQ(rc, 0); 2663 EXPECT_EQ(entryIndex, table.size()); 2664 } 2665 2666 TEST(GetDownstreamFirmwareParameters, decodeResponseInvalidLength) 2667 { 2668 /** Count is not fixed here taking it as 1, and the downstream device's 2669 * version strings length are set to 8 2670 */ 2671 constexpr uint16_t downstreamDeviceCount = 1; 2672 constexpr uint8_t activeComponentVersionStringLength = 8; 2673 constexpr uint8_t pendingComponentVersionStringLength = 8; 2674 constexpr size_t downstreamDeviceParamTableLen = 2675 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN + 2676 activeComponentVersionStringLength + 2677 pendingComponentVersionStringLength; 2678 constexpr uint8_t complition_code_resp = PLDM_SUCCESS; 2679 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 2680 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 2681 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002}; 2682 2683 std::array<uint8_t, 2684 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN + 2685 downstreamDeviceParamTableLen - 1 /* inject error length*/> 2686 responseMsg{}; 2687 2688 int rc = 0; 2689 2690 PLDM_MSGBUF_DEFINE_P(buf); 2691 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize, 2692 responseMsg.size() - hdrSize); 2693 ASSERT_EQ(rc, 0); 2694 2695 pldm_msgbuf_insert_uint8(buf, complition_code_resp); 2696 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 2697 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 2698 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value); 2699 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount); 2700 ASSERT_EQ(pldm_msgbuf_complete(buf), 0); 2701 2702 /** Filling paramter table, the correctness of the downstream devices data 2703 * is not checked in this test case so filling with 0xff 2704 */ 2705 std::fill_n(responseMsg.data() + hdrSize + 2706 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN, 2707 downstreamDeviceParamTableLen - 1 /* inject error length*/, 2708 0xff); 2709 2710 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2711 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 2712 struct pldm_get_downstream_firmware_parameters_resp resp_data = {}; 2713 struct pldm_downstream_device_parameters_iter iter; 2714 2715 rc = decode_get_downstream_firmware_parameters_resp( 2716 response, responseMsg.size() - hdrSize, &resp_data, &iter); 2717 EXPECT_EQ(rc, 0); 2718 2719 struct pldm_downstream_device_parameters_entry entry; 2720 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc) 2721 { 2722 FAIL(); 2723 } 2724 EXPECT_EQ(rc, -EOVERFLOW); 2725 } 2726 2727 TEST(RequestUpdate, goodPathEncodeRequest) 2728 { 2729 constexpr uint8_t instanceId = 1; 2730 constexpr uint32_t maxTransferSize = 512; 2731 constexpr uint16_t numOfComp = 3; 2732 constexpr uint8_t maxOutstandingTransferReq = 2; 2733 constexpr uint16_t pkgDataLen = 0x1234; 2734 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0"; 2735 constexpr uint8_t compImgSetVerStrLen = 2736 static_cast<uint8_t>(compImgSetVerStr.size()); 2737 variable_field compImgSetVerStrInfo{}; 2738 compImgSetVerStrInfo.ptr = 2739 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2740 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data()); 2741 compImgSetVerStrInfo.length = compImgSetVerStrLen; 2742 2743 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) + 2744 compImgSetVerStrLen> 2745 request{}; 2746 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2747 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 2748 2749 auto rc = encode_request_update_req( 2750 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq, 2751 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, 2752 &compImgSetVerStrInfo, requestMsg, 2753 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen); 2754 EXPECT_EQ(rc, PLDM_SUCCESS); 2755 2756 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) + 2757 compImgSetVerStrLen> 2758 outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 2759 0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e, 2760 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30}; 2761 EXPECT_EQ(request, outRequest); 2762 } 2763 2764 TEST(RequestUpdate, errorPathEncodeRequest) 2765 { 2766 constexpr uint8_t instanceId = 1; 2767 uint32_t maxTransferSize = 512; 2768 constexpr uint16_t numOfComp = 3; 2769 uint8_t maxOutstandingTransferReq = 2; 2770 constexpr uint16_t pkgDataLen = 0x1234; 2771 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0"; 2772 uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size()); 2773 variable_field compImgSetVerStrInfo{}; 2774 compImgSetVerStrInfo.ptr = 2775 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2776 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data()); 2777 compImgSetVerStrInfo.length = compImgSetVerStrLen; 2778 2779 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) + 2780 compImgSetVerStr.size()> 2781 request{}; 2782 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2783 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 2784 2785 auto rc = encode_request_update_req( 2786 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq, 2787 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr, 2788 requestMsg, 2789 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen); 2790 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2791 2792 compImgSetVerStrInfo.ptr = nullptr; 2793 rc = encode_request_update_req( 2794 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq, 2795 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, 2796 &compImgSetVerStrInfo, requestMsg, 2797 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen); 2798 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2799 compImgSetVerStrInfo.ptr = 2800 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2801 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data()); 2802 2803 rc = encode_request_update_req( 2804 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq, 2805 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, 2806 &compImgSetVerStrInfo, nullptr, 2807 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen); 2808 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2809 2810 rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp, 2811 maxOutstandingTransferReq, pkgDataLen, 2812 PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, 2813 &compImgSetVerStrInfo, requestMsg, 0); 2814 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 2815 2816 compImgSetVerStrLen = 0; 2817 rc = encode_request_update_req( 2818 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq, 2819 pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr, 2820 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen); 2821 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2822 compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size()); 2823 2824 compImgSetVerStrInfo.length = 0xffff; 2825 rc = encode_request_update_req( 2826 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq, 2827 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, 2828 &compImgSetVerStrInfo, nullptr, 2829 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen); 2830 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2831 compImgSetVerStrInfo.length = compImgSetVerStrLen; 2832 2833 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1; 2834 rc = encode_request_update_req( 2835 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq, 2836 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, 2837 &compImgSetVerStrInfo, nullptr, 2838 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen); 2839 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2840 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE; 2841 2842 maxOutstandingTransferReq = 0; 2843 rc = encode_request_update_req( 2844 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq, 2845 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, 2846 &compImgSetVerStrInfo, nullptr, 2847 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen); 2848 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2849 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ; 2850 2851 rc = encode_request_update_req( 2852 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq, 2853 pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen, 2854 &compImgSetVerStrInfo, nullptr, 2855 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen); 2856 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2857 } 2858 2859 TEST(RequestUpdate, goodPathDecodeResponse) 2860 { 2861 /* Test a success completion code */ 2862 constexpr uint16_t fdMetaDataLen = 1024; 2863 constexpr uint8_t fdWillSendPkgData = 1; 2864 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)> 2865 requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01}; 2866 2867 auto responseMsg1 = 2868 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2869 reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data()); 2870 uint8_t outCompletionCode = 0; 2871 uint16_t outFdMetaDataLen = 0; 2872 uint8_t outFdWillSendPkgData = 0; 2873 2874 auto rc = decode_request_update_resp( 2875 responseMsg1, requestUpdateResponse1.size() - hdrSize, 2876 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData); 2877 EXPECT_EQ(rc, PLDM_SUCCESS); 2878 EXPECT_EQ(outCompletionCode, PLDM_SUCCESS); 2879 EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen); 2880 EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData); 2881 2882 #ifdef LIBPLDM_API_TESTING 2883 /* Check the success roundtrip matches */ 2884 PLDM_MSG_DEFINE_P(enc, 1000); 2885 size_t enc_payload_len = 1000; 2886 const struct pldm_request_update_resp resp_data = { 2887 .completion_code = PLDM_SUCCESS, 2888 .fd_meta_data_len = outFdMetaDataLen, 2889 .fd_will_send_pkg_data = outFdWillSendPkgData, 2890 }; 2891 rc = encode_request_update_resp(FIXED_INSTANCE_ID, &resp_data, enc, 2892 &enc_payload_len); 2893 EXPECT_EQ(rc, PLDM_SUCCESS); 2894 EXPECT_EQ(enc_payload_len + hdrSize, requestUpdateResponse1.size()); 2895 EXPECT_TRUE(std::equal(requestUpdateResponse1.begin() + hdrSize, 2896 requestUpdateResponse1.end(), enc_buf + hdrSize)); 2897 check_response(enc, PLDM_REQUEST_UPDATE); 2898 #endif 2899 2900 /* Test a failure completion code */ 2901 outCompletionCode = 0; 2902 outFdMetaDataLen = 0; 2903 outFdWillSendPkgData = 0; 2904 2905 constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)> 2906 requestUpdateResponse2{0x00, 0x00, 0x00, 0x81}; 2907 auto responseMsg2 = 2908 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2909 reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data()); 2910 rc = decode_request_update_resp( 2911 responseMsg2, requestUpdateResponse2.size() - hdrSize, 2912 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData); 2913 EXPECT_EQ(rc, PLDM_SUCCESS); 2914 EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE); 2915 } 2916 2917 TEST(RequestUpdate, errorPathDecodeResponse) 2918 { 2919 constexpr std::array<uint8_t, 2920 hdrSize + sizeof(pldm_request_update_resp) - 1> 2921 requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04}; 2922 2923 auto responseMsg = 2924 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2925 reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data()); 2926 uint8_t outCompletionCode = 0; 2927 uint16_t outFdMetaDataLen = 0; 2928 uint8_t outFdWillSendPkgData = 0; 2929 2930 auto rc = decode_request_update_resp( 2931 nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode, 2932 &outFdMetaDataLen, &outFdWillSendPkgData); 2933 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2934 2935 rc = decode_request_update_resp( 2936 responseMsg, requestUpdateResponse.size() - hdrSize, nullptr, 2937 &outFdMetaDataLen, &outFdWillSendPkgData); 2938 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2939 2940 rc = decode_request_update_resp( 2941 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode, 2942 nullptr, &outFdWillSendPkgData); 2943 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2944 2945 rc = decode_request_update_resp( 2946 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode, 2947 &outFdMetaDataLen, nullptr); 2948 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2949 2950 rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode, 2951 &outFdMetaDataLen, &outFdWillSendPkgData); 2952 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2953 2954 rc = decode_request_update_resp( 2955 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode, 2956 &outFdMetaDataLen, &outFdWillSendPkgData); 2957 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 2958 } 2959 2960 #ifdef LIBPLDM_API_TESTING 2961 TEST(RequestDownstreamDeviceUpdate, goodPathEncodeRequest) 2962 { 2963 constexpr uint8_t instanceId = 1; 2964 2965 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES> 2966 request{}; 2967 2968 auto requestMsg = new (request.data()) pldm_msg; 2969 2970 constexpr struct pldm_request_downstream_device_update_req req_data = { 2971 .maximum_downstream_device_transfer_size = 512, 2972 .maximum_outstanding_transfer_requests = 2, 2973 .downstream_device_package_data_length = 0x1234, 2974 }; 2975 size_t enc_payload_len = PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES; 2976 2977 auto rc = encode_request_downstream_device_update_req( 2978 instanceId, &req_data, requestMsg, &enc_payload_len); 2979 2980 EXPECT_EQ(rc, 0); 2981 2982 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES> 2983 outRequest{0x81, 0x05, 0x20, 0x00, 0x02, 0x00, 0x00, 0x02, 0x34, 0x12}; 2984 EXPECT_EQ(request, outRequest); 2985 } 2986 #endif // LIBPLDM_API_TESTING 2987 2988 #ifdef LIBPLDM_API_TESTING 2989 TEST(RequestDownstreamDeviceUpdate, errorPathEncodeRequest) 2990 { 2991 constexpr uint8_t instanceId = 1; 2992 size_t enc_payload_len = PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES; 2993 2994 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES> 2995 request{}; 2996 2997 struct pldm_request_downstream_device_update_req req_data = { 2998 .maximum_downstream_device_transfer_size = 512, 2999 .maximum_outstanding_transfer_requests = 2, 3000 .downstream_device_package_data_length = 0x1234, 3001 }; 3002 3003 auto requestMsg = new (request.data()) pldm_msg; 3004 3005 auto rc = encode_request_downstream_device_update_req( 3006 instanceId, nullptr, requestMsg, &enc_payload_len); 3007 EXPECT_EQ(rc, -EINVAL); 3008 rc = encode_request_downstream_device_update_req( 3009 instanceId, &req_data, requestMsg, &enc_payload_len); 3010 EXPECT_EQ(rc, 0); 3011 3012 rc = encode_request_downstream_device_update_req(instanceId, &req_data, 3013 nullptr, &enc_payload_len); 3014 EXPECT_EQ(rc, -EINVAL); 3015 rc = encode_request_downstream_device_update_req( 3016 instanceId, &req_data, requestMsg, &enc_payload_len); 3017 EXPECT_EQ(rc, 0); 3018 3019 rc = encode_request_downstream_device_update_req(instanceId, &req_data, 3020 requestMsg, nullptr); 3021 EXPECT_EQ(rc, -EINVAL); 3022 rc = encode_request_downstream_device_update_req( 3023 instanceId, &req_data, requestMsg, &enc_payload_len); 3024 EXPECT_EQ(rc, 0); 3025 3026 enc_payload_len = 3027 static_cast<size_t>(PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES) - 1; 3028 rc = encode_request_downstream_device_update_req( 3029 instanceId, &req_data, requestMsg, &enc_payload_len); 3030 EXPECT_EQ(rc, -EOVERFLOW); 3031 enc_payload_len = 3032 static_cast<size_t>(PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES); 3033 rc = encode_request_downstream_device_update_req( 3034 instanceId, &req_data, requestMsg, &enc_payload_len); 3035 EXPECT_EQ(rc, 0); 3036 3037 req_data.maximum_downstream_device_transfer_size = 31; 3038 rc = encode_request_downstream_device_update_req( 3039 instanceId, &req_data, requestMsg, &enc_payload_len); 3040 EXPECT_EQ(rc, -EINVAL); 3041 req_data.maximum_downstream_device_transfer_size = 3042 PLDM_FWUP_BASELINE_TRANSFER_SIZE; 3043 3044 req_data.maximum_outstanding_transfer_requests = 0; 3045 rc = encode_request_downstream_device_update_req( 3046 instanceId, &req_data, requestMsg, &enc_payload_len); 3047 EXPECT_EQ(rc, -EINVAL); 3048 req_data.maximum_outstanding_transfer_requests = 2; 3049 rc = encode_request_downstream_device_update_req( 3050 instanceId, &req_data, requestMsg, &enc_payload_len); 3051 EXPECT_EQ(rc, 0); 3052 } 3053 #endif // LIBPLDM_API_TESTING 3054 3055 #ifdef LIBPLDM_API_TESTING 3056 TEST(RequestDownstreamDeviceUpdate, goodPathDecodeResponse) 3057 { 3058 /* Test a success completion code */ 3059 constexpr uint16_t ddMetaDataLen = 1024; 3060 constexpr uint8_t ddWillSendPkgData = 1; 3061 constexpr uint16_t getPkgDataMaxTransferSize = 512; 3062 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES> 3063 requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 3064 0x04, 0x01, 0x00, 0x02}; 3065 3066 auto responseMsg1 = new (requestUpdateResponse1.data()) pldm_msg; 3067 3068 struct pldm_request_downstream_device_update_resp resp_data1 = { 3069 .completion_code = 0, 3070 .downstream_device_meta_data_length = 0, 3071 .downstream_device_will_send_get_package_data = 0, 3072 .get_package_data_maximum_transfer_size = 0}; 3073 3074 auto rc = decode_request_downstream_device_update_resp( 3075 responseMsg1, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES, 3076 &resp_data1); 3077 EXPECT_EQ(rc, 0); 3078 EXPECT_EQ(resp_data1.completion_code, PLDM_SUCCESS); 3079 EXPECT_EQ(resp_data1.downstream_device_meta_data_length, ddMetaDataLen); 3080 EXPECT_EQ(resp_data1.downstream_device_will_send_get_package_data, 3081 ddWillSendPkgData); 3082 EXPECT_EQ(resp_data1.get_package_data_maximum_transfer_size, 3083 getPkgDataMaxTransferSize); 3084 3085 /* Test a failure completion code */ 3086 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES> 3087 requestUpdateResponse2{0x00, 0x00, 0x00, 0x81}; 3088 3089 auto responseMsg2 = new (requestUpdateResponse2.data()) pldm_msg; 3090 3091 struct pldm_request_downstream_device_update_resp resp_data2 = { 3092 .completion_code = 0, 3093 .downstream_device_meta_data_length = 0, 3094 .downstream_device_will_send_get_package_data = 0, 3095 .get_package_data_maximum_transfer_size = 0}; 3096 3097 rc = decode_request_downstream_device_update_resp( 3098 responseMsg2, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES, 3099 &resp_data2); 3100 EXPECT_EQ(rc, 0); 3101 EXPECT_EQ(resp_data2.completion_code, PLDM_FWUP_ALREADY_IN_UPDATE_MODE); 3102 } 3103 #endif // LIBPLDM_API_TESTING 3104 3105 #ifdef LIBPLDM_API_TESTING 3106 TEST(RequestDownstreamDeviceUpdate, errorPathDecodeResponse) 3107 { 3108 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES> 3109 requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 3110 0x04, 0x01, 0x00, 0x02}; 3111 3112 auto responseMsg = new (requestUpdateResponse.data()) pldm_msg; 3113 3114 struct pldm_request_downstream_device_update_resp resp_data = { 3115 .completion_code = 0, 3116 .downstream_device_meta_data_length = 0, 3117 .downstream_device_will_send_get_package_data = 0, 3118 .get_package_data_maximum_transfer_size = 0}; 3119 3120 auto rc = decode_request_downstream_device_update_resp( 3121 nullptr, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES, &resp_data); 3122 EXPECT_EQ(rc, -EINVAL); 3123 3124 rc = decode_request_downstream_device_update_resp( 3125 responseMsg, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES, nullptr); 3126 EXPECT_EQ(rc, -EINVAL); 3127 3128 rc = decode_request_downstream_device_update_resp(responseMsg, 0, 3129 &resp_data); 3130 EXPECT_EQ(rc, -EOVERFLOW); 3131 } 3132 #endif // LIBPLDM_API_TESTING 3133 3134 TEST(PassComponentTable, goodPathEncodeRequest) 3135 { 3136 constexpr uint8_t instanceId = 1; 3137 constexpr uint16_t compIdentifier = 400; 3138 constexpr uint8_t compClassificationIndex = 40; 3139 constexpr uint32_t compComparisonStamp = 0x12345678; 3140 constexpr std::string_view compVerStr = "0penBmcv1.1"; 3141 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size()); 3142 variable_field compVerStrInfo{}; 3143 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3144 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data()); 3145 compVerStrInfo.length = compVerStrLen; 3146 3147 std::array<uint8_t, 3148 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen> 3149 request{}; 3150 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3151 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 3152 3153 auto rc = encode_pass_component_table_req( 3154 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier, 3155 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 3156 compVerStrLen, &compVerStrInfo, requestMsg, 3157 sizeof(pldm_pass_component_table_req) + compVerStrLen); 3158 EXPECT_EQ(rc, PLDM_SUCCESS); 3159 3160 std::array<uint8_t, 3161 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen> 3162 outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28, 3163 0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 3164 0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31}; 3165 EXPECT_EQ(request, outRequest); 3166 3167 #ifdef LIBPLDM_API_TESTING 3168 /* Check the roundtrip */ 3169 struct pldm_pass_component_table_req_full req; 3170 PLDM_MSG_DEFINE_P(dec, outRequest.size()); 3171 std::copy(outRequest.begin(), outRequest.end(), dec_buf); 3172 rc = 3173 decode_pass_component_table_req(dec, outRequest.size() - hdrSize, &req); 3174 ASSERT_EQ(rc, 0); 3175 3176 EXPECT_EQ(req.transfer_flag, PLDM_START_AND_END); 3177 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE); 3178 EXPECT_EQ(req.comp_identifier, compIdentifier); 3179 EXPECT_EQ(req.comp_classification_index, compClassificationIndex); 3180 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp); 3181 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII); 3182 EXPECT_EQ(req.version.str_len, compVerStrLen); 3183 EXPECT_TRUE(std::equal(req.version.str_data, 3184 req.version.str_data + req.version.str_len, 3185 compVerStr.data())); 3186 #endif 3187 } 3188 3189 TEST(PassComponentTable, errorPathEncodeRequest) 3190 { 3191 constexpr uint8_t instanceId = 1; 3192 constexpr uint16_t compIdentifier = 400; 3193 constexpr uint8_t compClassificationIndex = 40; 3194 constexpr uint32_t compComparisonStamp = 0x12345678; 3195 constexpr std::string_view compVerStr = "0penBmcv1.1"; 3196 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size()); 3197 variable_field compVerStrInfo{}; 3198 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3199 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data()); 3200 compVerStrInfo.length = compVerStrLen; 3201 3202 std::array<uint8_t, 3203 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen> 3204 request{}; 3205 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3206 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 3207 3208 auto rc = encode_pass_component_table_req( 3209 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier, 3210 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 3211 compVerStrLen, nullptr, requestMsg, 3212 sizeof(pldm_pass_component_table_req) + compVerStrLen); 3213 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3214 3215 compVerStrInfo.ptr = nullptr; 3216 rc = encode_pass_component_table_req( 3217 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier, 3218 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 3219 compVerStrLen, &compVerStrInfo, requestMsg, 3220 sizeof(pldm_pass_component_table_req) + compVerStrLen); 3221 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3222 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3223 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data()); 3224 3225 rc = encode_pass_component_table_req( 3226 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier, 3227 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 3228 compVerStrLen, &compVerStrInfo, nullptr, 3229 sizeof(pldm_pass_component_table_req) + compVerStrLen); 3230 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3231 3232 rc = encode_pass_component_table_req( 3233 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier, 3234 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 3235 compVerStrLen, &compVerStrInfo, requestMsg, 3236 sizeof(pldm_pass_component_table_req)); 3237 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3238 3239 rc = encode_pass_component_table_req( 3240 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier, 3241 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0, 3242 &compVerStrInfo, requestMsg, 3243 sizeof(pldm_pass_component_table_req) + compVerStrLen); 3244 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3245 3246 rc = encode_pass_component_table_req( 3247 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier, 3248 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 3249 compVerStrLen - 1, &compVerStrInfo, requestMsg, 3250 sizeof(pldm_pass_component_table_req) + compVerStrLen); 3251 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3252 3253 rc = encode_pass_component_table_req( 3254 instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier, 3255 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 3256 compVerStrLen, &compVerStrInfo, requestMsg, 3257 sizeof(pldm_pass_component_table_req) + compVerStrLen); 3258 EXPECT_EQ(rc, PLDM_INVALID_TRANSFER_OPERATION_FLAG); 3259 3260 rc = encode_pass_component_table_req( 3261 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier, 3262 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN, 3263 compVerStrLen, &compVerStrInfo, requestMsg, 3264 sizeof(pldm_pass_component_table_req) + compVerStrLen); 3265 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3266 } 3267 3268 TEST(PassComponentTable, goodPathDecodeResponse) 3269 { 3270 constexpr std::array<uint8_t, 3271 hdrSize + sizeof(pldm_pass_component_table_resp)> 3272 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; 3273 auto responseMsg1 = 3274 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3275 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data()); 3276 3277 uint8_t completionCode = 0; 3278 uint8_t compResp = 0; 3279 uint8_t compRespCode = 0; 3280 3281 auto rc = decode_pass_component_table_resp( 3282 responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode, 3283 &compResp, &compRespCode); 3284 3285 EXPECT_EQ(rc, PLDM_SUCCESS); 3286 EXPECT_EQ(completionCode, PLDM_SUCCESS); 3287 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED); 3288 EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL); 3289 3290 constexpr std::array<uint8_t, 3291 hdrSize + sizeof(pldm_pass_component_table_resp)> 3292 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0}; 3293 auto responseMsg2 = 3294 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3295 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data()); 3296 rc = decode_pass_component_table_resp( 3297 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode, 3298 &compResp, &compRespCode); 3299 3300 EXPECT_EQ(rc, PLDM_SUCCESS); 3301 EXPECT_EQ(completionCode, PLDM_SUCCESS); 3302 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED); 3303 EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN); 3304 3305 constexpr std::array<uint8_t, 3306 hdrSize + sizeof(pldm_pass_component_table_resp)> 3307 passCompTableResponse3{0x00, 0x00, 0x00, 0x80}; 3308 auto responseMsg3 = 3309 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3310 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data()); 3311 3312 rc = decode_pass_component_table_resp( 3313 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode, 3314 &compResp, &compRespCode); 3315 3316 EXPECT_EQ(rc, PLDM_SUCCESS); 3317 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE); 3318 } 3319 3320 TEST(PassComponentTable, errorPathDecodeResponse) 3321 { 3322 constexpr std::array<uint8_t, 3323 hdrSize + sizeof(pldm_pass_component_table_resp) - 1> 3324 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00}; 3325 auto responseMsg1 = 3326 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3327 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data()); 3328 3329 uint8_t completionCode = 0; 3330 uint8_t compResp = 0; 3331 uint8_t compRespCode = 0; 3332 3333 auto rc = decode_pass_component_table_resp( 3334 nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode, 3335 &compResp, &compRespCode); 3336 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3337 3338 rc = decode_pass_component_table_resp( 3339 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr, 3340 &compResp, &compRespCode); 3341 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3342 3343 rc = decode_pass_component_table_resp( 3344 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, 3345 &completionCode, nullptr, &compRespCode); 3346 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3347 3348 rc = decode_pass_component_table_resp( 3349 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, 3350 &completionCode, &compResp, nullptr); 3351 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3352 3353 rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode, 3354 &compResp, &compRespCode); 3355 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3356 3357 rc = decode_pass_component_table_resp( 3358 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, 3359 &completionCode, &compResp, &compRespCode); 3360 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3361 3362 constexpr std::array<uint8_t, 3363 hdrSize + sizeof(pldm_pass_component_table_resp)> 3364 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00}; 3365 auto responseMsg2 = 3366 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3367 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data()); 3368 rc = decode_pass_component_table_resp( 3369 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode, 3370 &compResp, &compRespCode); 3371 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3372 3373 constexpr std::array<uint8_t, 3374 hdrSize + sizeof(pldm_pass_component_table_resp)> 3375 passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c}; 3376 auto responseMsg3 = 3377 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3378 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data()); 3379 rc = decode_pass_component_table_resp( 3380 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode, 3381 &compResp, &compRespCode); 3382 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3383 3384 constexpr std::array<uint8_t, 3385 hdrSize + sizeof(pldm_pass_component_table_resp)> 3386 passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0}; 3387 auto responseMsg4 = 3388 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3389 reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data()); 3390 rc = decode_pass_component_table_resp( 3391 responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode, 3392 &compResp, &compRespCode); 3393 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3394 } 3395 3396 TEST(UpdateComponent, goodPathEncodeRequest) 3397 { 3398 constexpr uint8_t instanceId = 2; 3399 constexpr uint16_t compIdentifier = 500; 3400 constexpr uint8_t compClassificationIndex = 50; 3401 constexpr uint32_t compComparisonStamp = 0x89abcdef; 3402 constexpr uint32_t compImageSize = 4096; 3403 constexpr bitfield32_t updateOptionFlags{1}; 3404 constexpr std::string_view compVerStr = "OpenBmcv2.2"; 3405 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size()); 3406 variable_field compVerStrInfo{}; 3407 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3408 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data()); 3409 compVerStrInfo.length = compVerStrLen; 3410 3411 std::array<uint8_t, 3412 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen> 3413 request{}; 3414 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3415 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 3416 3417 auto rc = encode_update_component_req( 3418 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex, 3419 compComparisonStamp, compImageSize, updateOptionFlags, 3420 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg, 3421 sizeof(pldm_update_component_req) + compVerStrLen); 3422 EXPECT_EQ(rc, PLDM_SUCCESS); 3423 3424 std::array<uint8_t, 3425 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen> 3426 outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef, 3427 0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 3428 0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 3429 0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32}; 3430 EXPECT_EQ(request, outRequest); 3431 3432 #ifdef LIBPLDM_API_TESTING 3433 /* Check the roundtrip */ 3434 struct pldm_update_component_req_full req; 3435 PLDM_MSG_DEFINE_P(dec, outRequest.size()); 3436 std::copy(outRequest.begin(), outRequest.end(), dec_buf); 3437 rc = decode_update_component_req(dec, outRequest.size() - hdrSize, &req); 3438 ASSERT_EQ(rc, 0); 3439 3440 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE); 3441 EXPECT_EQ(req.comp_identifier, compIdentifier); 3442 EXPECT_EQ(req.comp_classification_index, compClassificationIndex); 3443 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp); 3444 EXPECT_EQ(req.comp_image_size, compImageSize); 3445 EXPECT_EQ(req.update_option_flags.value, updateOptionFlags.value); 3446 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII); 3447 EXPECT_EQ(req.version.str_len, compVerStrLen); 3448 EXPECT_TRUE(std::equal(req.version.str_data, 3449 req.version.str_data + req.version.str_len, 3450 compVerStr.data())); 3451 #endif 3452 } 3453 3454 TEST(UpdateComponent, errorPathEncodeRequest) 3455 { 3456 constexpr uint8_t instanceId = 2; 3457 constexpr uint16_t compIdentifier = 500; 3458 constexpr uint8_t compClassificationIndex = 50; 3459 constexpr uint32_t compComparisonStamp = 0x89abcdef; 3460 constexpr uint32_t compImageSize = 4096; 3461 constexpr bitfield32_t updateOptionFlags{1}; 3462 constexpr std::string_view compVerStr = "OpenBmcv2.2"; 3463 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size()); 3464 variable_field compVerStrInfo{}; 3465 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3466 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data()); 3467 compVerStrInfo.length = compVerStrLen; 3468 3469 std::array<uint8_t, 3470 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen> 3471 request{}; 3472 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3473 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 3474 3475 auto rc = encode_update_component_req( 3476 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex, 3477 compComparisonStamp, compImageSize, updateOptionFlags, 3478 PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg, 3479 sizeof(pldm_update_component_req) + compVerStrLen); 3480 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3481 3482 compVerStrInfo.ptr = nullptr; 3483 rc = encode_update_component_req( 3484 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex, 3485 compComparisonStamp, compImageSize, updateOptionFlags, 3486 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg, 3487 sizeof(pldm_update_component_req) + compVerStrLen); 3488 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3489 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3490 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data()); 3491 3492 rc = encode_update_component_req( 3493 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex, 3494 compComparisonStamp, compImageSize, updateOptionFlags, 3495 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr, 3496 sizeof(pldm_update_component_req) + compVerStrLen); 3497 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3498 3499 rc = encode_update_component_req( 3500 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex, 3501 compComparisonStamp, compImageSize, updateOptionFlags, 3502 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg, 3503 sizeof(pldm_update_component_req)); 3504 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3505 3506 rc = encode_update_component_req( 3507 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex, 3508 compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII, 3509 compVerStrLen, &compVerStrInfo, requestMsg, 3510 sizeof(pldm_update_component_req) + compVerStrLen); 3511 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3512 3513 rc = encode_update_component_req( 3514 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex, 3515 compComparisonStamp, compImageSize, updateOptionFlags, 3516 PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg, 3517 sizeof(pldm_update_component_req) + compVerStrLen); 3518 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3519 3520 rc = encode_update_component_req( 3521 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex, 3522 compComparisonStamp, compImageSize, updateOptionFlags, 3523 PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg, 3524 sizeof(pldm_update_component_req) + compVerStrLen); 3525 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3526 3527 rc = encode_update_component_req( 3528 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex, 3529 compComparisonStamp, compImageSize, updateOptionFlags, 3530 PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg, 3531 sizeof(pldm_update_component_req) + compVerStrLen); 3532 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3533 } 3534 3535 TEST(UpdateComponent, goodPathDecodeResponse) 3536 { 3537 constexpr std::bitset<32> forceUpdateComp{1}; 3538 constexpr uint16_t timeBeforeSendingReqFwData100s = 100; 3539 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)> 3540 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3541 0x01, 0x00, 0x00, 0x00, 0x64, 0x00}; 3542 auto responseMsg1 = 3543 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3544 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data()); 3545 3546 uint8_t completionCode = 0; 3547 uint8_t compCompatibilityResp = 0; 3548 uint8_t compCompatibilityRespCode = 0; 3549 bitfield32_t updateOptionFlagsEnabled{}; 3550 uint16_t timeBeforeReqFWData = 0; 3551 3552 auto rc = decode_update_component_resp( 3553 responseMsg1, sizeof(pldm_update_component_resp), &completionCode, 3554 &compCompatibilityResp, &compCompatibilityRespCode, 3555 &updateOptionFlagsEnabled, &timeBeforeReqFWData); 3556 3557 EXPECT_EQ(rc, PLDM_SUCCESS); 3558 EXPECT_EQ(completionCode, PLDM_SUCCESS); 3559 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED); 3560 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE); 3561 EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp); 3562 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s); 3563 3564 constexpr std::bitset<32> noFlags{}; 3565 constexpr uint16_t timeBeforeSendingReqFwData0s = 0; 3566 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)> 3567 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 3568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 3569 auto responseMsg2 = 3570 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3571 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data()); 3572 rc = decode_update_component_resp( 3573 responseMsg2, sizeof(pldm_update_component_resp), &completionCode, 3574 &compCompatibilityResp, &compCompatibilityRespCode, 3575 &updateOptionFlagsEnabled, &timeBeforeReqFWData); 3576 3577 EXPECT_EQ(rc, PLDM_SUCCESS); 3578 EXPECT_EQ(completionCode, PLDM_SUCCESS); 3579 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED); 3580 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH); 3581 EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags); 3582 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s); 3583 3584 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)> 3585 updateComponentResponse3{0x00, 0x00, 0x00, 0x80}; 3586 auto responseMsg3 = 3587 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3588 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data()); 3589 3590 rc = decode_update_component_resp( 3591 responseMsg3, sizeof(pldm_update_component_resp), &completionCode, 3592 &compCompatibilityResp, &compCompatibilityRespCode, 3593 &updateOptionFlagsEnabled, &timeBeforeReqFWData); 3594 3595 EXPECT_EQ(rc, PLDM_SUCCESS); 3596 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE); 3597 } 3598 3599 TEST(UpdateComponent, errorPathDecodeResponse) 3600 { 3601 constexpr std::array<uint8_t, 3602 hdrSize + sizeof(pldm_update_component_resp) - 1> 3603 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 3604 0x00, 0x00, 0x00, 0x00, 0x00}; 3605 auto responseMsg1 = 3606 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3607 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data()); 3608 3609 uint8_t completionCode = 0; 3610 uint8_t compCompatibilityResp = 0; 3611 uint8_t compCompatibilityRespCode = 0; 3612 bitfield32_t updateOptionFlagsEnabled{}; 3613 uint16_t timeBeforeReqFWData = 0; 3614 3615 auto rc = decode_update_component_resp( 3616 nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode, 3617 &compCompatibilityResp, &compCompatibilityRespCode, 3618 &updateOptionFlagsEnabled, &timeBeforeReqFWData); 3619 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3620 3621 rc = decode_update_component_resp( 3622 responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr, 3623 &compCompatibilityResp, &compCompatibilityRespCode, 3624 &updateOptionFlagsEnabled, &timeBeforeReqFWData); 3625 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3626 3627 rc = decode_update_component_resp( 3628 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode, 3629 nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled, 3630 &timeBeforeReqFWData); 3631 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3632 3633 rc = decode_update_component_resp( 3634 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode, 3635 &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled, 3636 &timeBeforeReqFWData); 3637 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3638 3639 rc = decode_update_component_resp( 3640 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode, 3641 &compCompatibilityResp, &compCompatibilityRespCode, nullptr, 3642 &timeBeforeReqFWData); 3643 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3644 3645 rc = decode_update_component_resp( 3646 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode, 3647 &compCompatibilityResp, &compCompatibilityRespCode, 3648 &updateOptionFlagsEnabled, nullptr); 3649 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3650 3651 rc = decode_update_component_resp( 3652 responseMsg1, 0, &completionCode, &compCompatibilityResp, 3653 &compCompatibilityRespCode, &updateOptionFlagsEnabled, 3654 &timeBeforeReqFWData); 3655 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3656 3657 rc = decode_update_component_resp( 3658 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode, 3659 &compCompatibilityResp, &compCompatibilityRespCode, 3660 &updateOptionFlagsEnabled, &timeBeforeReqFWData); 3661 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3662 3663 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)> 3664 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 3665 0x01, 0x00, 0x00, 0x00, 0x64, 0x00}; 3666 auto responseMsg2 = 3667 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3668 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data()); 3669 rc = decode_update_component_resp( 3670 responseMsg2, sizeof(pldm_update_component_resp), &completionCode, 3671 &compCompatibilityResp, &compCompatibilityRespCode, 3672 &updateOptionFlagsEnabled, &timeBeforeReqFWData); 3673 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3674 3675 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)> 3676 updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 3677 0x01, 0x00, 0x00, 0x00, 0x64, 0x00}; 3678 auto responseMsg3 = 3679 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3680 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data()); 3681 rc = decode_update_component_resp( 3682 responseMsg3, sizeof(pldm_update_component_resp), &completionCode, 3683 &compCompatibilityResp, &compCompatibilityRespCode, 3684 &updateOptionFlagsEnabled, &timeBeforeReqFWData); 3685 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3686 3687 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)> 3688 updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 3689 0x01, 0x00, 0x00, 0x00, 0x64, 0x00}; 3690 auto responseMsg4 = 3691 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3692 reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data()); 3693 rc = decode_update_component_resp( 3694 responseMsg4, sizeof(pldm_update_component_resp), &completionCode, 3695 &compCompatibilityResp, &compCompatibilityRespCode, 3696 &updateOptionFlagsEnabled, &timeBeforeReqFWData); 3697 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3698 } 3699 3700 TEST(RequestFirmwareData, goodPathDecodeRequest) 3701 { 3702 constexpr uint32_t offset = 300; 3703 constexpr uint32_t length = 255; 3704 constexpr std::array<uint8_t, 3705 hdrSize + sizeof(pldm_request_firmware_data_req)> 3706 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00, 3707 0x00, 0xff, 0x00, 0x00, 0x00}; 3708 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3709 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data()); 3710 3711 uint32_t outOffset = 0; 3712 uint32_t outLength = 0; 3713 auto rc = decode_request_firmware_data_req( 3714 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset, 3715 &outLength); 3716 3717 EXPECT_EQ(rc, PLDM_SUCCESS); 3718 EXPECT_EQ(outOffset, offset); 3719 EXPECT_EQ(outLength, length); 3720 } 3721 3722 TEST(RequestFirmwareData, errorPathDecodeRequest) 3723 { 3724 constexpr std::array<uint8_t, 3725 hdrSize + sizeof(pldm_request_firmware_data_req)> 3726 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00, 3727 0x00, 0x1f, 0x00, 0x00, 0x00}; 3728 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3729 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data()); 3730 3731 uint32_t outOffset = 0; 3732 uint32_t outLength = 0; 3733 auto rc = decode_request_firmware_data_req( 3734 nullptr, sizeof(pldm_request_firmware_data_req), &outOffset, 3735 &outLength); 3736 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3737 3738 rc = decode_request_firmware_data_req( 3739 requestMsg, sizeof(pldm_request_firmware_data_req), nullptr, 3740 &outLength); 3741 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3742 3743 rc = decode_request_firmware_data_req( 3744 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset, 3745 nullptr); 3746 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3747 3748 rc = decode_request_firmware_data_req( 3749 requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset, 3750 &outLength); 3751 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3752 3753 rc = decode_request_firmware_data_req( 3754 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset, 3755 &outLength); 3756 EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH); 3757 } 3758 3759 TEST(RequestFirmwareData, goodPathEncodeResponse) 3760 { 3761 constexpr uint8_t instanceId = 3; 3762 constexpr uint8_t completionCode = PLDM_SUCCESS; 3763 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) + 3764 PLDM_FWUP_BASELINE_TRANSFER_SIZE> 3765 outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04, 3766 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 3767 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 3768 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 3769 0x1d, 0x1e, 0x1f, 0x20}; 3770 std::array<uint8_t, hdrSize + sizeof(completionCode) + 3771 PLDM_FWUP_BASELINE_TRANSFER_SIZE> 3772 reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 3773 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 3774 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 3775 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 3776 0x1d, 0x1e, 0x1f, 0x20}; 3777 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3778 auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data()); 3779 auto rc = encode_request_firmware_data_resp( 3780 instanceId, completionCode, responseMsg1, 3781 sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE); 3782 EXPECT_EQ(rc, PLDM_SUCCESS); 3783 EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1); 3784 3785 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 3786 outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82}; 3787 std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{ 3788 0x00, 0x00, 0x00, 0x00}; 3789 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3790 auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data()); 3791 rc = encode_request_firmware_data_resp( 3792 instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2, 3793 sizeof(completionCode)); 3794 EXPECT_EQ(rc, PLDM_SUCCESS); 3795 EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2); 3796 } 3797 3798 TEST(RequestFirmwareData, errorPathEncodeResponse) 3799 { 3800 std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00}; 3801 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3802 auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data()); 3803 auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0); 3804 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3805 3806 rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0); 3807 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3808 } 3809 3810 TEST(TransferComplete, goodPathDecodeRequest) 3811 { 3812 constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS; 3813 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)> 3814 transferCompleteReq1{0x00, 0x00, 0x00, 0x00}; 3815 auto requestMsg1 = 3816 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3817 reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data()); 3818 uint8_t outTransferResult = 0; 3819 3820 auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult), 3821 &outTransferResult); 3822 EXPECT_EQ(rc, PLDM_SUCCESS); 3823 EXPECT_EQ(outTransferResult, transferResult); 3824 3825 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)> 3826 transferCompleteReq2{0x00, 0x00, 0x00, 0x02}; 3827 auto requestMsg2 = 3828 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3829 reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data()); 3830 rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult), 3831 &outTransferResult); 3832 EXPECT_EQ(rc, PLDM_SUCCESS); 3833 EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT); 3834 } 3835 3836 TEST(TransferComplete, errorPathDecodeRequest) 3837 { 3838 constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00, 3839 0x00}; 3840 auto requestMsg = 3841 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3842 reinterpret_cast<const pldm_msg*>(transferCompleteReq.data()); 3843 uint8_t outTransferResult = 0; 3844 3845 auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult); 3846 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3847 3848 rc = decode_transfer_complete_req(requestMsg, 0, nullptr); 3849 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3850 3851 rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult); 3852 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3853 } 3854 3855 TEST(TransferComplete, goodPathEncodeResponse) 3856 { 3857 constexpr uint8_t instanceId = 4; 3858 constexpr uint8_t completionCode = PLDM_SUCCESS; 3859 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 3860 outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00}; 3861 std::array<uint8_t, hdrSize + sizeof(completionCode)> 3862 transferCompleteResponse1{0x00, 0x00, 0x00, 0x00}; 3863 auto responseMsg1 = 3864 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3865 reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data()); 3866 auto rc = encode_transfer_complete_resp( 3867 instanceId, completionCode, responseMsg1, sizeof(completionCode)); 3868 EXPECT_EQ(rc, PLDM_SUCCESS); 3869 EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1); 3870 3871 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 3872 outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88}; 3873 std::array<uint8_t, hdrSize + sizeof(completionCode)> 3874 transferCompleteResponse2{0x00, 0x00, 0x00, 0x00}; 3875 auto responseMsg2 = 3876 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3877 reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data()); 3878 rc = encode_transfer_complete_resp(instanceId, 3879 PLDM_FWUP_COMMAND_NOT_EXPECTED, 3880 responseMsg2, sizeof(completionCode)); 3881 EXPECT_EQ(rc, PLDM_SUCCESS); 3882 EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2); 3883 } 3884 3885 TEST(TransferComplete, errorPathEncodeResponse) 3886 { 3887 std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00}; 3888 auto responseMsg = 3889 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3890 reinterpret_cast<pldm_msg*>(transferCompleteResponse.data()); 3891 auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0); 3892 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3893 3894 rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0); 3895 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3896 } 3897 3898 TEST(VerifyComplete, goodPathDecodeRequest) 3899 { 3900 constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS; 3901 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)> 3902 verifyCompleteReq1{0x00, 0x00, 0x00, 0x00}; 3903 auto requestMsg1 = 3904 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3905 reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data()); 3906 uint8_t outVerifyResult = 0; 3907 3908 auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult), 3909 &outVerifyResult); 3910 EXPECT_EQ(rc, PLDM_SUCCESS); 3911 EXPECT_EQ(outVerifyResult, verifyResult); 3912 3913 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)> 3914 verifyCompleteReq2{0x00, 0x00, 0x00, 0x03}; 3915 auto requestMsg2 = 3916 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3917 reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data()); 3918 rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult), 3919 &outVerifyResult); 3920 EXPECT_EQ(rc, PLDM_SUCCESS); 3921 EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS); 3922 } 3923 3924 TEST(VerifyComplete, errorPathDecodeRequest) 3925 { 3926 constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00}; 3927 auto requestMsg = 3928 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3929 reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data()); 3930 uint8_t outVerifyResult = 0; 3931 3932 auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult); 3933 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3934 3935 rc = decode_verify_complete_req(requestMsg, 0, nullptr); 3936 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3937 3938 rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult); 3939 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3940 } 3941 3942 TEST(VerifyComplete, goodPathEncodeResponse) 3943 { 3944 constexpr uint8_t instanceId = 5; 3945 constexpr uint8_t completionCode = PLDM_SUCCESS; 3946 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 3947 outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00}; 3948 std::array<uint8_t, hdrSize + sizeof(completionCode)> 3949 verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00}; 3950 auto responseMsg1 = 3951 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3952 reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data()); 3953 auto rc = encode_verify_complete_resp(instanceId, completionCode, 3954 responseMsg1, sizeof(completionCode)); 3955 EXPECT_EQ(rc, PLDM_SUCCESS); 3956 EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1); 3957 3958 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 3959 outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88}; 3960 std::array<uint8_t, hdrSize + sizeof(completionCode)> 3961 verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00}; 3962 auto responseMsg2 = 3963 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3964 reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data()); 3965 rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED, 3966 responseMsg2, sizeof(completionCode)); 3967 EXPECT_EQ(rc, PLDM_SUCCESS); 3968 EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2); 3969 } 3970 3971 TEST(VerifyComplete, errorPathEncodeResponse) 3972 { 3973 std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00}; 3974 auto responseMsg = 3975 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3976 reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data()); 3977 auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0); 3978 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3979 3980 rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0); 3981 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3982 } 3983 3984 TEST(ApplyComplete, goodPathDecodeRequest) 3985 { 3986 constexpr uint8_t applyResult1 = 3987 PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD; 3988 // DC power cycle [Bit position 4] & AC power cycle [Bit position 5] 3989 constexpr std::bitset<16> compActivationModification1{0x30}; 3990 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)> 3991 applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00}; 3992 auto requestMsg1 = 3993 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3994 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data()); 3995 uint8_t outApplyResult = 0; 3996 bitfield16_t outCompActivationModification{}; 3997 auto rc = decode_apply_complete_req( 3998 requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult, 3999 &outCompActivationModification); 4000 EXPECT_EQ(rc, PLDM_SUCCESS); 4001 EXPECT_EQ(outApplyResult, applyResult1); 4002 EXPECT_EQ(outCompActivationModification.value, compActivationModification1); 4003 4004 constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS; 4005 constexpr std::bitset<16> compActivationModification2{}; 4006 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)> 4007 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4008 auto requestMsg2 = 4009 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4010 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data()); 4011 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req), 4012 &outApplyResult, 4013 &outCompActivationModification); 4014 EXPECT_EQ(rc, PLDM_SUCCESS); 4015 EXPECT_EQ(outApplyResult, applyResult2); 4016 EXPECT_EQ(outCompActivationModification.value, compActivationModification2); 4017 } 4018 4019 TEST(ApplyComplete, errorPathDecodeRequest) 4020 { 4021 constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00}; 4022 auto requestMsg1 = 4023 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4024 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data()); 4025 uint8_t outApplyResult = 0; 4026 bitfield16_t outCompActivationModification{}; 4027 4028 auto rc = decode_apply_complete_req( 4029 nullptr, sizeof(pldm_apply_complete_req), &outApplyResult, 4030 &outCompActivationModification); 4031 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4032 4033 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req), 4034 nullptr, &outCompActivationModification); 4035 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4036 4037 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req), 4038 &outApplyResult, nullptr); 4039 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4040 4041 rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult, 4042 &outCompActivationModification); 4043 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 4044 4045 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)> 4046 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00}; 4047 auto requestMsg2 = 4048 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4049 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data()); 4050 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req), 4051 &outApplyResult, 4052 &outCompActivationModification); 4053 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4054 } 4055 4056 TEST(ApplyComplete, goodPathEncodeResponse) 4057 { 4058 constexpr uint8_t instanceId = 6; 4059 constexpr uint8_t completionCode = PLDM_SUCCESS; 4060 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 4061 outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00}; 4062 std::array<uint8_t, hdrSize + sizeof(completionCode)> 4063 applyCompleteResponse1{0x00, 0x00, 0x00, 0x00}; 4064 auto responseMsg1 = 4065 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4066 reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data()); 4067 auto rc = encode_apply_complete_resp(instanceId, completionCode, 4068 responseMsg1, sizeof(completionCode)); 4069 EXPECT_EQ(rc, PLDM_SUCCESS); 4070 EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1); 4071 4072 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 4073 outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88}; 4074 std::array<uint8_t, hdrSize + sizeof(completionCode)> 4075 applyCompleteResponse2{0x00, 0x00, 0x00, 0x00}; 4076 auto responseMsg2 = 4077 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4078 reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data()); 4079 rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED, 4080 responseMsg2, sizeof(completionCode)); 4081 EXPECT_EQ(rc, PLDM_SUCCESS); 4082 EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2); 4083 } 4084 4085 TEST(ApplyComplete, errorPathEncodeResponse) 4086 { 4087 std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00}; 4088 auto responseMsg = 4089 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4090 reinterpret_cast<pldm_msg*>(applyCompleteResponse.data()); 4091 auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0); 4092 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4093 4094 rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0); 4095 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 4096 } 4097 4098 TEST(ActivateFirmware, goodPathEncodeRequest) 4099 { 4100 constexpr uint8_t instanceId = 7; 4101 4102 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{}; 4103 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4104 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 4105 4106 auto rc = encode_activate_firmware_req( 4107 instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 4108 sizeof(pldm_activate_firmware_req)); 4109 EXPECT_EQ(rc, PLDM_SUCCESS); 4110 4111 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> 4112 outRequest{0x87, 0x05, 0x1a, 0x01}; 4113 EXPECT_EQ(request, outRequest); 4114 } 4115 4116 TEST(ActivateFirmware, errorPathEncodeRequest) 4117 { 4118 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{}; 4119 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4120 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 4121 4122 auto rc = encode_activate_firmware_req( 4123 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr, 4124 sizeof(pldm_activate_firmware_req)); 4125 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4126 4127 rc = encode_activate_firmware_req( 4128 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0); 4129 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 4130 4131 rc = encode_activate_firmware_req(0, 2, requestMsg, 4132 sizeof(pldm_activate_firmware_req)); 4133 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4134 } 4135 4136 TEST(ActivateFirmware, goodPathDecodeResponse) 4137 { 4138 constexpr uint16_t estimatedTimeForActivation100s = 100; 4139 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)> 4140 activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00}; 4141 auto responseMsg1 = 4142 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4143 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data()); 4144 4145 uint8_t completionCode = 0; 4146 uint16_t estimatedTimeForActivation = 0; 4147 4148 auto rc = decode_activate_firmware_resp( 4149 responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode, 4150 &estimatedTimeForActivation); 4151 4152 EXPECT_EQ(rc, PLDM_SUCCESS); 4153 EXPECT_EQ(completionCode, PLDM_SUCCESS); 4154 EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s); 4155 4156 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 4157 activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85}; 4158 auto responseMsg2 = 4159 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4160 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data()); 4161 4162 rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode), 4163 &completionCode, 4164 &estimatedTimeForActivation); 4165 4166 EXPECT_EQ(rc, PLDM_SUCCESS); 4167 EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE); 4168 } 4169 4170 TEST(ActivateFirmware, errorPathDecodeResponse) 4171 { 4172 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)> 4173 activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4174 auto responseMsg = 4175 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4176 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data()); 4177 4178 uint8_t completionCode = 0; 4179 uint16_t estimatedTimeForActivation = 0; 4180 4181 auto rc = decode_activate_firmware_resp( 4182 nullptr, sizeof(pldm_activate_firmware_resp), &completionCode, 4183 &estimatedTimeForActivation); 4184 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4185 4186 rc = decode_activate_firmware_resp(responseMsg, 4187 sizeof(pldm_activate_firmware_resp), 4188 nullptr, &estimatedTimeForActivation); 4189 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4190 4191 rc = decode_activate_firmware_resp(responseMsg, 4192 sizeof(pldm_activate_firmware_resp), 4193 &completionCode, nullptr); 4194 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4195 4196 rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode, 4197 &estimatedTimeForActivation); 4198 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4199 4200 rc = decode_activate_firmware_resp( 4201 responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode, 4202 &estimatedTimeForActivation); 4203 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 4204 } 4205 4206 TEST(GetStatus, goodPathEncodeRequest) 4207 { 4208 constexpr uint8_t instanceId = 8; 4209 std::array<uint8_t, hdrSize> request{}; 4210 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4211 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 4212 4213 auto rc = encode_get_status_req(instanceId, requestMsg, 4214 PLDM_GET_STATUS_REQ_BYTES); 4215 EXPECT_EQ(rc, PLDM_SUCCESS); 4216 4217 constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b}; 4218 EXPECT_EQ(request, outRequest); 4219 } 4220 4221 TEST(GetStatus, errorPathEncodeRequest) 4222 { 4223 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{}; 4224 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4225 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 4226 4227 auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES); 4228 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4229 4230 rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1); 4231 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 4232 } 4233 4234 TEST(GetStatus, goodPathDecodeResponse) 4235 { 4236 constexpr std::bitset<32> updateOptionFlagsEnabled1{0}; 4237 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)> 4238 getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 4239 0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00}; 4240 auto responseMsg1 = 4241 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4242 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data()); 4243 4244 uint8_t completionCode = 0; 4245 uint8_t currentState = 0; 4246 uint8_t previousState = 0; 4247 uint8_t auxState = 0; 4248 uint8_t auxStateStatus = 0; 4249 uint8_t progressPercent = 0; 4250 uint8_t reasonCode = 0; 4251 bitfield32_t updateOptionFlagsEnabled{0}; 4252 4253 auto rc = decode_get_status_resp( 4254 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode, 4255 ¤tState, &previousState, &auxState, &auxStateStatus, 4256 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4257 4258 EXPECT_EQ(rc, PLDM_SUCCESS); 4259 EXPECT_EQ(completionCode, PLDM_SUCCESS); 4260 EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE); 4261 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD); 4262 EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER); 4263 EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT); 4264 EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT); 4265 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD); 4266 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1); 4267 4268 // Bit position 0 - Force update of component – FD will perform a force 4269 // update of the component. 4270 constexpr std::bitset<32> updateOptionFlagsEnabled2{1}; 4271 constexpr uint8_t progressPercent2 = 50; 4272 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)> 4273 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 4274 0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00}; 4275 auto responseMsg2 = 4276 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4277 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data()); 4278 4279 rc = decode_get_status_resp( 4280 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode, 4281 ¤tState, &previousState, &auxState, &auxStateStatus, 4282 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4283 4284 EXPECT_EQ(rc, PLDM_SUCCESS); 4285 EXPECT_EQ(completionCode, PLDM_SUCCESS); 4286 EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY); 4287 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD); 4288 EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS); 4289 EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START); 4290 EXPECT_EQ(progressPercent, progressPercent2); 4291 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD); 4292 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2); 4293 4294 #ifdef LIBPLDM_API_TESTING 4295 /* Check the roundtrip */ 4296 PLDM_MSG_DEFINE_P(enc, 1000); 4297 size_t enc_payload_len = 1000; 4298 const struct pldm_get_status_resp status_enc = { 4299 .completion_code = PLDM_SUCCESS, 4300 .current_state = currentState, 4301 .previous_state = previousState, 4302 .aux_state = auxState, 4303 .aux_state_status = auxStateStatus, 4304 .progress_percent = progressPercent, 4305 .reason_code = reasonCode, 4306 .update_option_flags_enabled = updateOptionFlagsEnabled, 4307 }; 4308 rc = encode_get_status_resp(FIXED_INSTANCE_ID, &status_enc, enc, 4309 &enc_payload_len); 4310 EXPECT_EQ(rc, PLDM_SUCCESS); 4311 EXPECT_EQ(enc_payload_len + hdrSize, getStatusResponse2.size()); 4312 EXPECT_TRUE(std::equal(getStatusResponse2.begin() + hdrSize, 4313 getStatusResponse2.end(), enc_buf + hdrSize)); 4314 check_response(enc, PLDM_GET_STATUS); 4315 #endif 4316 4317 /* Check a not-ready completion code */ 4318 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 4319 getStatusResponse3{0x00, 0x00, 0x00, 0x04}; 4320 auto responseMsg3 = 4321 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4322 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data()); 4323 rc = decode_get_status_resp( 4324 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode, 4325 ¤tState, &previousState, &auxState, &auxStateStatus, 4326 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4327 EXPECT_EQ(rc, PLDM_SUCCESS); 4328 EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY); 4329 } 4330 4331 TEST(GetStatus, errorPathDecodeResponse) 4332 { 4333 uint8_t completionCode = 0; 4334 uint8_t currentState = 0; 4335 uint8_t previousState = 0; 4336 uint8_t auxState = 0; 4337 uint8_t auxStateStatus = 0; 4338 uint8_t progressPercent = 0; 4339 uint8_t reasonCode = 0; 4340 bitfield32_t updateOptionFlagsEnabled{0}; 4341 4342 constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00}; 4343 auto responseMsg1 = 4344 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4345 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data()); 4346 4347 auto rc = decode_get_status_resp( 4348 nullptr, getStatusResponse1.size() - hdrSize, &completionCode, 4349 ¤tState, &previousState, &auxState, &auxStateStatus, 4350 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4351 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4352 4353 rc = decode_get_status_resp( 4354 responseMsg1, getStatusResponse1.size() - hdrSize, nullptr, 4355 ¤tState, &previousState, &auxState, &auxStateStatus, 4356 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4357 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4358 4359 rc = decode_get_status_resp( 4360 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode, 4361 nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent, 4362 &reasonCode, &updateOptionFlagsEnabled); 4363 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4364 4365 rc = decode_get_status_resp( 4366 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode, 4367 ¤tState, nullptr, &auxState, &auxStateStatus, &progressPercent, 4368 &reasonCode, &updateOptionFlagsEnabled); 4369 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4370 4371 rc = decode_get_status_resp( 4372 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode, 4373 ¤tState, &previousState, nullptr, &auxStateStatus, 4374 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4375 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4376 4377 rc = decode_get_status_resp( 4378 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode, 4379 ¤tState, &previousState, &auxState, nullptr, &progressPercent, 4380 &reasonCode, &updateOptionFlagsEnabled); 4381 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4382 4383 rc = decode_get_status_resp( 4384 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode, 4385 ¤tState, &previousState, &auxState, &auxStateStatus, nullptr, 4386 &reasonCode, &updateOptionFlagsEnabled); 4387 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4388 4389 rc = decode_get_status_resp( 4390 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode, 4391 ¤tState, &previousState, &auxState, &auxStateStatus, 4392 &progressPercent, nullptr, &updateOptionFlagsEnabled); 4393 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4394 4395 rc = decode_get_status_resp( 4396 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode, 4397 ¤tState, &previousState, &auxState, &auxStateStatus, 4398 &progressPercent, &reasonCode, nullptr); 4399 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4400 4401 rc = decode_get_status_resp( 4402 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode, 4403 ¤tState, &previousState, &auxState, &auxStateStatus, 4404 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4405 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4406 4407 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1> 4408 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4409 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4410 auto responseMsg2 = 4411 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4412 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data()); 4413 rc = decode_get_status_resp( 4414 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode, 4415 ¤tState, &previousState, &auxState, &auxStateStatus, 4416 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4417 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 4418 4419 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)> 4420 getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 4421 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4422 auto responseMsg3 = 4423 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4424 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data()); 4425 rc = decode_get_status_resp( 4426 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode, 4427 ¤tState, &previousState, &auxState, &auxStateStatus, 4428 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4429 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4430 4431 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)> 4432 getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 4433 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4434 auto responseMsg4 = 4435 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4436 reinterpret_cast<const pldm_msg*>(getStatusResponse4.data()); 4437 rc = decode_get_status_resp( 4438 responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode, 4439 ¤tState, &previousState, &auxState, &auxStateStatus, 4440 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4441 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4442 4443 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)> 4444 getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 4445 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4446 auto responseMsg5 = 4447 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4448 reinterpret_cast<const pldm_msg*>(getStatusResponse5.data()); 4449 rc = decode_get_status_resp( 4450 responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode, 4451 ¤tState, &previousState, &auxState, &auxStateStatus, 4452 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4453 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4454 4455 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)> 4456 getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4457 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4458 auto responseMsg6 = 4459 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4460 reinterpret_cast<const pldm_msg*>(getStatusResponse6.data()); 4461 rc = decode_get_status_resp( 4462 responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode, 4463 ¤tState, &previousState, &auxState, &auxStateStatus, 4464 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4465 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4466 4467 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)> 4468 getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4469 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00}; 4470 auto responseMsg7 = 4471 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4472 reinterpret_cast<const pldm_msg*>(getStatusResponse7.data()); 4473 rc = decode_get_status_resp( 4474 responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode, 4475 ¤tState, &previousState, &auxState, &auxStateStatus, 4476 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4477 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4478 4479 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)> 4480 getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4481 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00}; 4482 auto responseMsg8 = 4483 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4484 reinterpret_cast<const pldm_msg*>(getStatusResponse8.data()); 4485 rc = decode_get_status_resp( 4486 responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode, 4487 ¤tState, &previousState, &auxState, &auxStateStatus, 4488 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4489 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4490 4491 // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is 4492 // IDLE 4493 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)> 4494 getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 4495 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4496 auto responseMsg9 = 4497 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4498 reinterpret_cast<const pldm_msg*>(getStatusResponse9.data()); 4499 rc = decode_get_status_resp( 4500 responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode, 4501 ¤tState, &previousState, &auxState, &auxStateStatus, 4502 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4503 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4504 } 4505 4506 TEST(CancelUpdateComponent, goodPathEncodeRequest) 4507 { 4508 constexpr uint8_t instanceId = 9; 4509 std::array<uint8_t, hdrSize> request{}; 4510 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4511 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 4512 4513 auto rc = encode_cancel_update_component_req( 4514 instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES); 4515 EXPECT_EQ(rc, PLDM_SUCCESS); 4516 4517 constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c}; 4518 EXPECT_EQ(request, outRequest); 4519 } 4520 4521 TEST(CancelUpdateComponent, errorPathEncodeRequest) 4522 { 4523 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{}; 4524 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4525 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 4526 4527 auto rc = encode_cancel_update_component_req( 4528 0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES); 4529 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4530 4531 rc = encode_cancel_update_component_req( 4532 0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1); 4533 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 4534 } 4535 4536 TEST(CancelUpdateComponent, testGoodDecodeResponse) 4537 { 4538 uint8_t completionCode = 0; 4539 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 4540 cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00}; 4541 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4542 auto responseMsg1 = reinterpret_cast<const pldm_msg*>( 4543 cancelUpdateComponentResponse1.data()); 4544 auto rc = decode_cancel_update_component_resp( 4545 responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize, 4546 &completionCode); 4547 EXPECT_EQ(rc, PLDM_SUCCESS); 4548 EXPECT_EQ(completionCode, PLDM_SUCCESS); 4549 4550 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 4551 cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86}; 4552 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4553 auto responseMsg2 = reinterpret_cast<const pldm_msg*>( 4554 cancelUpdateComponentResponse2.data()); 4555 rc = decode_cancel_update_component_resp( 4556 responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize, 4557 &completionCode); 4558 EXPECT_EQ(rc, PLDM_SUCCESS); 4559 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND); 4560 } 4561 4562 TEST(CancelUpdateComponent, testBadDecodeResponse) 4563 { 4564 uint8_t completionCode = 0; 4565 constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{ 4566 0x00, 0x00, 0x00}; 4567 auto responseMsg = 4568 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4569 reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data()); 4570 4571 auto rc = decode_cancel_update_component_resp( 4572 nullptr, cancelUpdateComponentResponse.size() - hdrSize, 4573 &completionCode); 4574 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4575 4576 rc = decode_cancel_update_component_resp( 4577 responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr); 4578 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4579 4580 rc = decode_cancel_update_component_resp( 4581 responseMsg, cancelUpdateComponentResponse.size() - hdrSize, 4582 &completionCode); 4583 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 4584 } 4585 4586 TEST(CancelUpdate, goodPathEncodeRequest) 4587 { 4588 constexpr uint8_t instanceId = 10; 4589 std::array<uint8_t, hdrSize> request{}; 4590 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4591 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 4592 4593 auto rc = encode_cancel_update_req(instanceId, requestMsg, 4594 PLDM_CANCEL_UPDATE_REQ_BYTES); 4595 EXPECT_EQ(rc, PLDM_SUCCESS); 4596 4597 constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d}; 4598 EXPECT_EQ(request, outRequest); 4599 } 4600 4601 TEST(CancelUpdate, errorPathEncodeRequest) 4602 { 4603 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{}; 4604 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4605 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 4606 4607 auto rc = 4608 encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES); 4609 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4610 4611 rc = encode_cancel_update_req(0, requestMsg, 4612 PLDM_CANCEL_UPDATE_REQ_BYTES + 1); 4613 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 4614 } 4615 4616 TEST(CancelUpdate, goodPathDecodeResponse) 4617 { 4618 constexpr std::bitset<64> nonFunctioningComponentBitmap1{0}; 4619 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)> 4620 cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4621 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4622 auto responseMsg1 = 4623 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4624 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data()); 4625 uint8_t completionCode = 0; 4626 bool8_t nonFunctioningComponentIndication = 0; 4627 bitfield64_t nonFunctioningComponentBitmap{0}; 4628 auto rc = decode_cancel_update_resp( 4629 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode, 4630 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap); 4631 EXPECT_EQ(rc, PLDM_SUCCESS); 4632 EXPECT_EQ(completionCode, PLDM_SUCCESS); 4633 EXPECT_EQ(nonFunctioningComponentIndication, 4634 PLDM_FWUP_COMPONENTS_FUNCTIONING); 4635 EXPECT_EQ(nonFunctioningComponentBitmap.value, 4636 nonFunctioningComponentBitmap1); 4637 4638 constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101}; 4639 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)> 4640 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 4641 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4642 auto responseMsg2 = 4643 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4644 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data()); 4645 rc = decode_cancel_update_resp( 4646 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode, 4647 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap); 4648 EXPECT_EQ(rc, PLDM_SUCCESS); 4649 EXPECT_EQ(completionCode, PLDM_SUCCESS); 4650 EXPECT_EQ(nonFunctioningComponentIndication, 4651 PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING); 4652 EXPECT_EQ(nonFunctioningComponentBitmap.value, 4653 nonFunctioningComponentBitmap2); 4654 4655 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 4656 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86}; 4657 auto responseMsg3 = 4658 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4659 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data()); 4660 rc = decode_cancel_update_resp( 4661 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode, 4662 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap); 4663 EXPECT_EQ(rc, PLDM_SUCCESS); 4664 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND); 4665 } 4666 4667 TEST(CancelUpdate, errorPathDecodeResponse) 4668 { 4669 constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00, 4670 0x00}; 4671 auto responseMsg1 = 4672 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4673 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data()); 4674 uint8_t completionCode = 0; 4675 bool8_t nonFunctioningComponentIndication = 0; 4676 bitfield64_t nonFunctioningComponentBitmap{0}; 4677 4678 auto rc = decode_cancel_update_resp( 4679 nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode, 4680 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap); 4681 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4682 4683 rc = decode_cancel_update_resp( 4684 responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr, 4685 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap); 4686 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4687 4688 rc = decode_cancel_update_resp( 4689 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode, 4690 nullptr, &nonFunctioningComponentBitmap); 4691 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4692 4693 rc = decode_cancel_update_resp( 4694 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode, 4695 &nonFunctioningComponentIndication, nullptr); 4696 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4697 4698 rc = decode_cancel_update_resp( 4699 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode, 4700 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap); 4701 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4702 4703 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 4704 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00}; 4705 auto responseMsg2 = 4706 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4707 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data()); 4708 rc = decode_cancel_update_resp( 4709 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode, 4710 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap); 4711 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 4712 4713 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)> 4714 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 4715 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4716 auto responseMsg3 = 4717 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4718 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data()); 4719 rc = decode_cancel_update_resp( 4720 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode, 4721 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap); 4722 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4723 } 4724