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