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_LENGTH); 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 #ifdef LIBPLDM_API_TESTING 1443 TEST(QueryDownstreamDevices, goodPathEncodeRequest) 1444 { 1445 constexpr uint8_t instanceId = 1; 1446 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{}; 1447 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1448 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); 1449 1450 auto rc = encode_query_downstream_devices_req(instanceId, requestPtr); 1451 1452 EXPECT_EQ(rc, 0); 1453 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST); 1454 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId); 1455 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP); 1456 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DOWNSTREAM_DEVICES); 1457 } 1458 #endif 1459 1460 #ifdef LIBPLDM_API_TESTING 1461 TEST(QueryDownstreamDevices, encodeRequestInvalidData) 1462 { 1463 constexpr uint8_t instanceId = 1; 1464 1465 auto rc = encode_query_downstream_devices_req(instanceId, nullptr); 1466 1467 EXPECT_EQ(rc, -EINVAL); 1468 } 1469 #endif 1470 1471 #ifdef LIBPLDM_API_TESTING 1472 TEST(QueryDownstreamDevices, goodPathDecodeResponse) 1473 { 1474 uint8_t completion_code_resp = PLDM_SUCCESS; 1475 uint8_t downstream_device_update_supported_resp = 1476 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED; 1477 uint16_t number_of_downstream_devices_resp = 1; 1478 uint16_t max_number_of_downstream_devices_resp = 1; 1479 /** Capabilities of updating downstream devices 1480 * FDP supports downstream devices dynamically attached [Bit position 0] & 1481 * FDP supports downstream devices dynamically removed [Bit position 1] 1482 */ 1483 bitfield32_t capabilities_resp = {.value = 0x0002}; 1484 int rc; 1485 1486 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES> 1487 responseMsg{}; 1488 1489 struct pldm_msgbuf _buf; 1490 struct pldm_msgbuf* buf = &_buf; 1491 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize, 1492 responseMsg.size() - hdrSize); 1493 EXPECT_EQ(rc, 0); 1494 1495 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 1496 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp); 1497 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 1498 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp); 1499 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value); 1500 1501 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1502 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 1503 struct pldm_query_downstream_devices_resp resp_data; 1504 1505 rc = decode_query_downstream_devices_resp( 1506 response, responseMsg.size() - hdrSize, &resp_data); 1507 1508 EXPECT_EQ(rc, 0); 1509 EXPECT_EQ(resp_data.completion_code, completion_code_resp); 1510 EXPECT_EQ(resp_data.downstream_device_update_supported, 1511 downstream_device_update_supported_resp); 1512 EXPECT_EQ(resp_data.number_of_downstream_devices, 1513 number_of_downstream_devices_resp); 1514 EXPECT_EQ(resp_data.max_number_of_downstream_devices, 1515 max_number_of_downstream_devices_resp); 1516 EXPECT_EQ(resp_data.capabilities.value, capabilities_resp.value); 1517 } 1518 #endif 1519 1520 #ifdef LIBPLDM_API_TESTING 1521 TEST(QueryDownstreamDevices, decodeRequestUndefinedValue) 1522 { 1523 uint8_t completion_code_resp = PLDM_SUCCESS; 1524 uint8_t downstream_device_update_supported_resp = 0xe; /*Undefined value*/ 1525 uint16_t number_of_downstream_devices_resp = 1; 1526 uint16_t max_number_of_downstream_devices_resp = 1; 1527 /** Capabilities of updating downstream devices 1528 * FDP supports downstream devices dynamically attached [Bit position 0] & 1529 * FDP supports downstream devices dynamically removed [Bit position 1] 1530 */ 1531 bitfield32_t capabilities_resp = {.value = 0x0002}; 1532 int rc; 1533 1534 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES> 1535 responseMsg{}; 1536 1537 struct pldm_msgbuf _buf; 1538 struct pldm_msgbuf* buf = &_buf; 1539 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize, 1540 responseMsg.size() - hdrSize); 1541 EXPECT_EQ(rc, 0); 1542 1543 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 1544 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp); 1545 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 1546 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp); 1547 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value); 1548 1549 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1550 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 1551 struct pldm_query_downstream_devices_resp resp_data; 1552 1553 rc = decode_query_downstream_devices_resp( 1554 response, responseMsg.size() - hdrSize, &resp_data); 1555 1556 ASSERT_EQ(rc, -EINVAL); 1557 } 1558 #endif 1559 1560 #ifdef LIBPLDM_API_TESTING 1561 TEST(QueryDownstreamDevices, decodeRequestErrorBufSize) 1562 { 1563 uint8_t completion_code_resp = PLDM_SUCCESS; 1564 uint8_t downstream_device_update_supported_resp = 1565 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED; 1566 uint16_t number_of_downstream_devices_resp = 1; 1567 uint16_t max_number_of_downstream_devices_resp = 1; 1568 /** Capabilities of updating downstream devices 1569 * FDP supports downstream devices dynamically attached [Bit position 0] & 1570 * FDP supports downstream devices dynamically removed [Bit position 1] 1571 */ 1572 bitfield32_t capabilities_resp = {.value = 0x0002}; 1573 int rc; 1574 1575 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES - 1576 2 /* Inject error length*/> 1577 responseMsg{}; 1578 1579 struct pldm_msgbuf _buf; 1580 struct pldm_msgbuf* buf = &_buf; 1581 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize, 1582 responseMsg.size() - hdrSize); 1583 EXPECT_EQ(rc, 0); 1584 1585 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 1586 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp); 1587 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 1588 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp); 1589 // Inject error value 1590 pldm_msgbuf_insert_uint16(buf, (uint16_t)capabilities_resp.value); 1591 1592 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1593 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 1594 struct pldm_query_downstream_devices_resp resp_data; 1595 1596 rc = decode_query_downstream_devices_resp( 1597 response, responseMsg.size() - hdrSize, &resp_data); 1598 1599 EXPECT_EQ(rc, -EBADMSG); 1600 } 1601 #endif 1602 1603 #ifdef LIBPLDM_API_TESTING 1604 TEST(QueryDownstreamIdentifiers, goodPathEncodeRequest) 1605 { 1606 constexpr uint8_t instanceId = 1; 1607 constexpr size_t payloadLen = PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES; 1608 PLDM_MSG_DEFINE_P(request, payloadLen); 1609 constexpr pldm_query_downstream_identifiers_req params_req{ 1610 0xFFFFFFFF, PLDM_GET_FIRSTPART}; 1611 1612 auto rc = encode_query_downstream_identifiers_req(instanceId, ¶ms_req, 1613 request, payloadLen); 1614 ASSERT_EQ(rc, 0); 1615 EXPECT_THAT(std::span<uint8_t>(request_buf, sizeof(request_buf)), 1616 ElementsAreArray<uint8_t>( 1617 {0x81, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x01})); 1618 } 1619 #endif 1620 1621 #ifdef LIBPLDM_API_TESTING 1622 TEST(QueryDownstreamIdentifiers, encodeRequestInvalidErrorPaths) 1623 { 1624 constexpr uint8_t instanceId = 1; 1625 constexpr pldm_query_downstream_identifiers_req params_req{ 1626 0xFFFFFFFF, PLDM_GET_FIRSTPART}; 1627 constexpr pldm_query_downstream_identifiers_req params_req_invalid{ 1628 0xFFFFFFFF, PLDM_ACKNOWLEDGEMENT_ONLY}; 1629 constexpr size_t payload_length = 1630 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES; 1631 std::array<uint8_t, hdrSize + payload_length> requestMsg{}; 1632 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1633 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); 1634 1635 auto rc = encode_query_downstream_identifiers_req(instanceId, ¶ms_req, 1636 nullptr, payload_length); 1637 EXPECT_EQ(rc, -EINVAL); 1638 1639 rc = encode_query_downstream_identifiers_req( 1640 instanceId, ¶ms_req, requestPtr, payload_length - 1); 1641 EXPECT_EQ(rc, -EOVERFLOW); 1642 1643 rc = encode_query_downstream_identifiers_req( 1644 instanceId, ¶ms_req_invalid, requestPtr, payload_length); 1645 EXPECT_EQ(rc, -EINVAL); 1646 } 1647 #endif 1648 1649 #ifdef LIBPLDM_API_TESTING 1650 TEST(QueryDownstreamIdentifiers, decodeResponseNoDevices) 1651 { 1652 constexpr uint8_t completion_code_resp = PLDM_SUCCESS; 1653 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 1654 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 1655 constexpr uint32_t downstream_devices_length_resp = 0; 1656 constexpr uint16_t number_of_downstream_devices_resp = 0; 1657 1658 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN); 1659 struct pldm_query_downstream_identifiers_resp resp_data = {}; 1660 struct pldm_downstream_device_iter devs; 1661 struct pldm_msgbuf _buf; 1662 struct pldm_msgbuf* buf = &_buf; 1663 int rc = 0; 1664 1665 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, 1666 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN); 1667 ASSERT_EQ(rc, 0); 1668 1669 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 1670 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 1671 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 1672 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp); 1673 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 1674 1675 ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0); 1676 1677 rc = decode_query_downstream_identifiers_resp( 1678 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp_data, 1679 &devs); 1680 1681 ASSERT_EQ(rc, 0); 1682 EXPECT_EQ(resp_data.completion_code, completion_code_resp); 1683 EXPECT_EQ(resp_data.next_data_transfer_handle, 1684 next_data_transfer_handle_resp); 1685 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp); 1686 EXPECT_EQ(resp_data.downstream_devices_length, 1687 downstream_devices_length_resp); 1688 EXPECT_EQ(resp_data.number_of_downstream_devices, 1689 number_of_downstream_devices_resp); 1690 } 1691 #endif 1692 1693 #ifdef LIBPLDM_API_TESTING 1694 TEST(QueryDownstreamIdentifiers, decodeResponseNoDevicesBadCount) 1695 { 1696 constexpr uint8_t completion_code_resp = PLDM_SUCCESS; 1697 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 1698 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 1699 constexpr uint32_t downstream_devices_length_resp = 0; 1700 constexpr uint16_t number_of_downstream_devices_resp = 1; 1701 1702 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN); 1703 struct pldm_query_downstream_identifiers_resp resp = {}; 1704 struct pldm_downstream_device_iter devs; 1705 struct pldm_downstream_device dev; 1706 struct pldm_msgbuf _buf; 1707 struct pldm_msgbuf* buf = &_buf; 1708 int rc = 0; 1709 1710 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, 1711 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN); 1712 ASSERT_EQ(rc, 0); 1713 1714 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 1715 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 1716 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 1717 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp); 1718 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 1719 1720 ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0); 1721 1722 rc = decode_query_downstream_identifiers_resp( 1723 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp, &devs); 1724 ASSERT_EQ(rc, 0); 1725 1726 foreach_pldm_downstream_device(devs, dev, rc) 1727 { 1728 FAIL(); 1729 } 1730 ASSERT_NE(rc, 0); 1731 } 1732 #endif 1733 1734 #ifdef LIBPLDM_API_TESTING 1735 TEST(QueryDownstreamIdentifiers, decodeResponseOneDeviceOneDescriptor) 1736 { 1737 constexpr uint32_t downstreamDevicesLen = 11; 1738 constexpr uint8_t completion_code_resp = PLDM_SUCCESS; 1739 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 1740 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 1741 const uint32_t downstream_devices_length_resp = 1742 htole32(downstreamDevicesLen); 1743 constexpr uint16_t number_of_downstream_devices_resp = 1; 1744 constexpr size_t payloadLen = 1745 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstreamDevicesLen; 1746 1747 struct pldm_query_downstream_identifiers_resp resp_data = {}; 1748 PLDM_MSG_DEFINE_P(response, payloadLen); 1749 struct pldm_downstream_device_iter devs; 1750 struct pldm_downstream_device dev; 1751 struct pldm_msgbuf _buf; 1752 struct pldm_msgbuf* buf = &_buf; 1753 int rc = 0; 1754 1755 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen); 1756 ASSERT_EQ(rc, 0); 1757 1758 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 1759 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 1760 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 1761 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp); 1762 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 1763 1764 /* Downstream device */ 1765 pldm_msgbuf_insert_uint16(buf, 1); 1766 pldm_msgbuf_insert_uint8(buf, 1); 1767 1768 /* Device descriptor */ 1769 pldm_msgbuf_insert_uint16(buf, 1); 1770 pldm_msgbuf_insert_uint16(buf, 4); 1771 pldm_msgbuf_insert_uint32(buf, 412); 1772 1773 ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0); 1774 1775 rc = decode_query_downstream_identifiers_resp(response, payloadLen, 1776 &resp_data, &devs); 1777 1778 ASSERT_EQ(rc, 0); 1779 EXPECT_EQ(resp_data.completion_code, completion_code_resp); 1780 EXPECT_EQ(resp_data.next_data_transfer_handle, 1781 next_data_transfer_handle_resp); 1782 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp); 1783 EXPECT_EQ(resp_data.downstream_devices_length, 1784 downstream_devices_length_resp); 1785 EXPECT_EQ(resp_data.number_of_downstream_devices, 1786 number_of_downstream_devices_resp); 1787 1788 foreach_pldm_downstream_device(devs, dev, rc) 1789 { 1790 struct pldm_descriptor desc; 1791 1792 EXPECT_EQ(dev.downstream_device_index, 1); 1793 EXPECT_EQ(dev.downstream_descriptor_count, 1); 1794 1795 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc) 1796 { 1797 static const uint32_t dmtf = htole32(412); 1798 EXPECT_EQ(desc.descriptor_type, 1); 1799 EXPECT_EQ(desc.descriptor_length, 4); 1800 EXPECT_EQ(memcmp(desc.descriptor_data, &dmtf, sizeof(dmtf)), 0); 1801 } 1802 ASSERT_EQ(rc, 0); 1803 } 1804 ASSERT_EQ(rc, 0); 1805 } 1806 #endif 1807 1808 #ifdef LIBPLDM_API_TESTING 1809 constexpr const uint16_t descriptor_id_type_iana_pen = 0x1; 1810 constexpr const uint16_t descriptor_id_len_iana_pen = 0x4; 1811 const uint32_t iana_pen_openbmc = htole16(49871u); 1812 const uint32_t iana_pen_dmtf = htole16(412u); 1813 #endif 1814 1815 #ifdef LIBPLDM_API_TESTING 1816 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneDescriptorEach) 1817 { 1818 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{ 1819 {0, 1}, 1820 {1, 1}, 1821 }}; 1822 1823 constexpr const std::array<pldm_descriptor, 2> expected_descriptors = {{ 1824 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen, 1825 &iana_pen_dmtf}, 1826 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen, 1827 &iana_pen_openbmc}, 1828 }}; 1829 1830 constexpr uint32_t downstream_devices_len = 22; 1831 constexpr uint8_t completion_code_resp = PLDM_SUCCESS; 1832 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 1833 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 1834 const uint32_t downstream_devices_length_resp = 1835 htole32(downstream_devices_len); 1836 constexpr uint16_t number_of_downstream_devices_resp = 2; 1837 constexpr size_t payloadLen = 1838 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len; 1839 1840 struct pldm_query_downstream_identifiers_resp resp_data{}; 1841 PLDM_MSG_DEFINE_P(response, payloadLen); 1842 struct pldm_downstream_device_iter devs; 1843 struct pldm_downstream_device dev; 1844 struct pldm_msgbuf _buf; 1845 struct pldm_msgbuf* buf = &_buf; 1846 int rc = 0; 1847 1848 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen); 1849 ASSERT_EQ(rc, 0); 1850 1851 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 1852 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 1853 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 1854 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp); 1855 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 1856 1857 /* Downstream device */ 1858 pldm_msgbuf_insert_uint16(buf, 0); 1859 pldm_msgbuf_insert_uint8(buf, 1); 1860 1861 /* Device descriptor */ 1862 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen); 1863 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen); 1864 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf); 1865 1866 /* Downstream device */ 1867 pldm_msgbuf_insert_uint16(buf, 1); 1868 pldm_msgbuf_insert_uint8(buf, 1); 1869 1870 /* Device descriptor */ 1871 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen); 1872 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen); 1873 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc); 1874 1875 ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0); 1876 1877 rc = decode_query_downstream_identifiers_resp(response, payloadLen, 1878 &resp_data, &devs); 1879 1880 ASSERT_EQ(rc, 0); 1881 EXPECT_EQ(resp_data.number_of_downstream_devices, 1882 number_of_downstream_devices_resp); 1883 1884 size_t devIndex = 0; 1885 size_t descIndex = 0; 1886 foreach_pldm_downstream_device(devs, dev, rc) 1887 { 1888 struct pldm_descriptor desc; 1889 1890 ASSERT_LT(devIndex, expected_devices.size()); 1891 1892 const struct pldm_downstream_device* expectedDev = 1893 &expected_devices[devIndex]; 1894 1895 EXPECT_EQ(dev.downstream_device_index, 1896 expectedDev->downstream_device_index); 1897 EXPECT_EQ(dev.downstream_descriptor_count, 1898 expectedDev->downstream_descriptor_count); 1899 1900 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc) 1901 { 1902 ASSERT_LT(descIndex, expected_descriptors.size()); 1903 1904 const struct pldm_descriptor* expectedDesc = 1905 &expected_descriptors[descIndex]; 1906 1907 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type); 1908 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length); 1909 EXPECT_EQ(memcmp(desc.descriptor_data, 1910 expectedDesc->descriptor_data, 1911 expectedDesc->descriptor_length), 1912 0); 1913 1914 descIndex++; 1915 } 1916 ASSERT_EQ(rc, 0); 1917 EXPECT_EQ(descIndex, 1 * devIndex + 1); 1918 1919 devIndex++; 1920 } 1921 ASSERT_EQ(rc, 0); 1922 EXPECT_EQ(devIndex, 2); 1923 } 1924 #endif 1925 1926 #ifdef LIBPLDM_API_TESTING 1927 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesTwoOneDescriptors) 1928 { 1929 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{ 1930 {0, 2}, 1931 {1, 1}, 1932 }}; 1933 1934 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{ 1935 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen, 1936 &iana_pen_dmtf}, 1937 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen, 1938 &iana_pen_openbmc}, 1939 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen, 1940 &iana_pen_dmtf}, 1941 }}; 1942 1943 constexpr uint32_t downstream_devices_len = 30; 1944 constexpr uint8_t completion_code_resp = PLDM_SUCCESS; 1945 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 1946 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 1947 const uint32_t downstream_devices_length_resp = 1948 htole32(downstream_devices_len); 1949 constexpr uint16_t number_of_downstream_devices_resp = 2; 1950 constexpr size_t payloadLen = 1951 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len; 1952 1953 struct pldm_query_downstream_identifiers_resp resp_data{}; 1954 PLDM_MSG_DEFINE_P(response, payloadLen); 1955 struct pldm_downstream_device_iter devs; 1956 struct pldm_downstream_device dev; 1957 struct pldm_msgbuf _buf; 1958 struct pldm_msgbuf* buf = &_buf; 1959 int rc = 0; 1960 1961 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen); 1962 ASSERT_EQ(rc, 0); 1963 1964 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 1965 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 1966 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 1967 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp); 1968 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 1969 1970 /* Downstream device */ 1971 pldm_msgbuf_insert_uint16(buf, 0); 1972 pldm_msgbuf_insert_uint8(buf, 2); 1973 1974 /* Device descriptor */ 1975 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen); 1976 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen); 1977 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf); 1978 1979 /* Device descriptor */ 1980 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen); 1981 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen); 1982 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc); 1983 1984 /* Downstream device */ 1985 pldm_msgbuf_insert_uint16(buf, 1); 1986 pldm_msgbuf_insert_uint8(buf, 1); 1987 1988 /* Device descriptor */ 1989 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen); 1990 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen); 1991 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf); 1992 1993 ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0); 1994 1995 rc = decode_query_downstream_identifiers_resp(response, payloadLen, 1996 &resp_data, &devs); 1997 1998 ASSERT_EQ(rc, 0); 1999 EXPECT_EQ(resp_data.number_of_downstream_devices, 2000 number_of_downstream_devices_resp); 2001 2002 size_t devIndex = 0; 2003 size_t descIndex = 0; 2004 foreach_pldm_downstream_device(devs, dev, rc) 2005 { 2006 struct pldm_descriptor desc; 2007 2008 ASSERT_LT(devIndex, expected_devices.size()); 2009 2010 const struct pldm_downstream_device* expectedDev = 2011 &expected_devices[devIndex]; 2012 2013 EXPECT_EQ(dev.downstream_device_index, 2014 expectedDev->downstream_device_index); 2015 EXPECT_EQ(dev.downstream_descriptor_count, 2016 expectedDev->downstream_descriptor_count); 2017 2018 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc) 2019 { 2020 ASSERT_LT(descIndex, expected_descriptors.size()); 2021 2022 const struct pldm_descriptor* expectedDesc = 2023 &expected_descriptors[descIndex]; 2024 2025 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type); 2026 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length); 2027 EXPECT_EQ(memcmp(desc.descriptor_data, 2028 expectedDesc->descriptor_data, 2029 expectedDesc->descriptor_length), 2030 0); 2031 2032 descIndex++; 2033 } 2034 ASSERT_EQ(rc, 0); 2035 2036 devIndex++; 2037 } 2038 ASSERT_EQ(rc, 0); 2039 EXPECT_EQ(devIndex, 2); 2040 EXPECT_EQ(descIndex, 3); 2041 } 2042 #endif 2043 2044 #ifdef LIBPLDM_API_TESTING 2045 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneTwoDescriptors) 2046 { 2047 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{ 2048 {0, 1}, 2049 {1, 2}, 2050 }}; 2051 2052 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{ 2053 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen, 2054 &iana_pen_dmtf}, 2055 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen, 2056 &iana_pen_openbmc}, 2057 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen, 2058 &iana_pen_dmtf}, 2059 }}; 2060 2061 constexpr uint32_t downstream_devices_len = 30; 2062 constexpr uint8_t completion_code_resp = PLDM_SUCCESS; 2063 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 2064 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 2065 const uint32_t downstream_devices_length_resp = 2066 htole32(downstream_devices_len); 2067 constexpr uint16_t number_of_downstream_devices_resp = 2; 2068 constexpr size_t payloadLen = 2069 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len; 2070 2071 struct pldm_query_downstream_identifiers_resp resp_data{}; 2072 PLDM_MSG_DEFINE_P(response, payloadLen); 2073 struct pldm_downstream_device_iter devs; 2074 struct pldm_downstream_device dev; 2075 struct pldm_msgbuf _buf; 2076 struct pldm_msgbuf* buf = &_buf; 2077 int rc = 0; 2078 2079 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen); 2080 ASSERT_EQ(rc, 0); 2081 2082 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 2083 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 2084 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 2085 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp); 2086 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 2087 2088 /* Downstream device */ 2089 pldm_msgbuf_insert_uint16(buf, 0); 2090 pldm_msgbuf_insert_uint8(buf, 1); 2091 2092 /* Device descriptor */ 2093 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen); 2094 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen); 2095 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf); 2096 2097 /* Downstream device */ 2098 pldm_msgbuf_insert_uint16(buf, 1); 2099 pldm_msgbuf_insert_uint8(buf, 2); 2100 2101 /* Device descriptor */ 2102 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen); 2103 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen); 2104 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc); 2105 2106 /* Device descriptor */ 2107 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen); 2108 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen); 2109 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf); 2110 2111 ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0); 2112 2113 rc = decode_query_downstream_identifiers_resp(response, payloadLen, 2114 &resp_data, &devs); 2115 2116 ASSERT_EQ(rc, 0); 2117 EXPECT_EQ(resp_data.number_of_downstream_devices, 2118 number_of_downstream_devices_resp); 2119 2120 size_t devIndex = 0; 2121 size_t descIndex = 0; 2122 foreach_pldm_downstream_device(devs, dev, rc) 2123 { 2124 struct pldm_descriptor desc; 2125 2126 ASSERT_LT(devIndex, expected_devices.size()); 2127 2128 const struct pldm_downstream_device* expectedDev = 2129 &expected_devices[devIndex]; 2130 2131 EXPECT_EQ(dev.downstream_device_index, 2132 expectedDev->downstream_device_index); 2133 EXPECT_EQ(dev.downstream_descriptor_count, 2134 expectedDev->downstream_descriptor_count); 2135 2136 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc) 2137 { 2138 ASSERT_LT(descIndex, expected_descriptors.size()); 2139 2140 const struct pldm_descriptor* expectedDesc = 2141 &expected_descriptors[descIndex]; 2142 2143 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type); 2144 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length); 2145 EXPECT_EQ(memcmp(desc.descriptor_data, 2146 expectedDesc->descriptor_data, 2147 expectedDesc->descriptor_length), 2148 0); 2149 2150 descIndex++; 2151 } 2152 ASSERT_EQ(rc, 0); 2153 2154 devIndex++; 2155 } 2156 ASSERT_EQ(rc, 0); 2157 EXPECT_EQ(devIndex, 2); 2158 EXPECT_EQ(descIndex, 3); 2159 } 2160 #endif 2161 2162 #ifdef LIBPLDM_API_TESTING 2163 TEST(QueryDownstreamIdentifiers, decodeRequestErrorPaths) 2164 { 2165 constexpr size_t payloadLen = sizeof(uint8_t); 2166 2167 struct pldm_query_downstream_identifiers_resp resp_data = {}; 2168 struct pldm_downstream_device_iter devs; 2169 PLDM_MSG_DEFINE_P(response, payloadLen); 2170 2171 // Test nullptr 2172 auto rc = decode_query_downstream_identifiers_resp(nullptr, payloadLen, 2173 nullptr, &devs); 2174 EXPECT_EQ(rc, -EINVAL); 2175 2176 // Test not PLDM_SUCCESS completion code 2177 response->payload[0] = PLDM_ERROR_UNSUPPORTED_PLDM_CMD; 2178 rc = decode_query_downstream_identifiers_resp(response, payloadLen, 2179 &resp_data, &devs); 2180 EXPECT_EQ(rc, 0); 2181 EXPECT_EQ(resp_data.completion_code, PLDM_ERROR_UNSUPPORTED_PLDM_CMD); 2182 2183 // Test payload length less than minimum length 2184 response->payload[0] = PLDM_SUCCESS; 2185 rc = decode_query_downstream_identifiers_resp(response, payloadLen, 2186 &resp_data, &devs); 2187 2188 EXPECT_EQ(rc, -EBADMSG); 2189 } 2190 #endif 2191 2192 #ifdef LIBPLDM_API_TESTING 2193 TEST(QueryDownstreamIdentifiers, decodeRequestErrorDownstreamDevicesSize) 2194 { 2195 // Len is not fixed here taking it as 9, contains 1 downstream device with 2196 // 1 descriptor 2197 constexpr uint32_t actualDownstreamDevicesLen = 9; 2198 constexpr uint8_t complition_code_resp = PLDM_SUCCESS; 2199 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 2200 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 2201 constexpr uint16_t number_of_downstream_devices_resp = 1; 2202 constexpr size_t payloadLen = 2203 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + 2204 actualDownstreamDevicesLen; 2205 2206 const uint32_t downstream_devices_length_resp = 2207 htole32(actualDownstreamDevicesLen + 1 /* inject error length*/); 2208 2209 struct pldm_query_downstream_identifiers_resp resp_data = {}; 2210 struct pldm_downstream_device_iter devs; 2211 PLDM_MSG_DEFINE_P(response, payloadLen); 2212 struct pldm_msgbuf _buf; 2213 struct pldm_msgbuf* buf = &_buf; 2214 void* devicesStart = NULL; 2215 size_t devicesLen; 2216 int rc = 0; 2217 2218 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen); 2219 EXPECT_EQ(rc, 0); 2220 2221 pldm_msgbuf_insert_uint8(buf, complition_code_resp); 2222 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 2223 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 2224 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp); 2225 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp); 2226 pldm_msgbuf_span_remaining(buf, &devicesStart, &devicesLen); 2227 2228 /** Filling descriptor data, the correctness of the downstream devices data 2229 * is not checked in this test case so filling with 0xff 2230 */ 2231 std::fill_n(static_cast<uint8_t*>(devicesStart), actualDownstreamDevicesLen, 2232 0xff); 2233 2234 EXPECT_NE(decode_query_downstream_identifiers_resp(response, payloadLen, 2235 &resp_data, &devs), 2236 0); 2237 } 2238 #endif 2239 2240 #ifdef LIBPLDM_API_TESTING 2241 TEST(QueryDownstreamIdentifiers, decodeRequestErrorBufSize) 2242 { 2243 constexpr uint32_t actualDownstreamDevicesLen = 0; 2244 constexpr uint16_t number_of_downstream_devices_resp = 1; 2245 constexpr uint8_t complition_code_resp = PLDM_SUCCESS; 2246 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 2247 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 2248 constexpr size_t payloadLen = 2249 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN - 1; 2250 2251 const uint32_t downstream_devices_length_resp = 2252 htole32(actualDownstreamDevicesLen); 2253 2254 struct pldm_query_downstream_identifiers_resp resp_data = {}; 2255 struct pldm_downstream_device_iter devs; 2256 PLDM_MSG_DEFINE_P(response, payloadLen); 2257 struct pldm_msgbuf _buf; 2258 struct pldm_msgbuf* buf = &_buf; 2259 int rc = 0; 2260 2261 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen); 2262 ASSERT_EQ(rc, 0); 2263 2264 pldm_msgbuf_insert_uint8(buf, complition_code_resp); 2265 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 2266 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 2267 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp); 2268 // Inject error buffer size 2269 pldm_msgbuf_insert_uint8(buf, (uint8_t)number_of_downstream_devices_resp); 2270 2271 rc = decode_query_downstream_identifiers_resp(response, payloadLen, 2272 &resp_data, &devs); 2273 2274 EXPECT_EQ(rc, -EBADMSG); 2275 } 2276 #endif 2277 2278 #ifdef LIBPLDM_API_TESTING 2279 TEST(GetDownstreamFirmwareParameters, goodPathEncodeRequest) 2280 { 2281 constexpr uint8_t instanceId = 1; 2282 constexpr pldm_get_downstream_firmware_parameters_req params_req{ 2283 0x0, PLDM_GET_FIRSTPART}; 2284 constexpr size_t payload_length = 2285 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES; 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, 0); 2293 2294 std::array<uint8_t, 2295 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES> 2296 expectedReq{0x81, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01}; 2297 EXPECT_EQ(requestMsg, expectedReq); 2298 } 2299 #endif 2300 2301 #ifdef LIBPLDM_API_TESTING 2302 TEST(GetDownstreamFirmwareParameters, encodeRequestInvalidTransferOperationFlag) 2303 { 2304 constexpr uint8_t instanceId = 1; 2305 // Setup invalid transfer operation flag 2306 constexpr pldm_get_downstream_firmware_parameters_req params_req{ 2307 0x0, PLDM_ACKNOWLEDGEMENT_ONLY}; 2308 constexpr size_t payload_length = 2309 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES; 2310 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{}; 2311 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2312 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); 2313 2314 auto rc = encode_get_downstream_firmware_parameters_req( 2315 instanceId, ¶ms_req, requestPtr, payload_length); 2316 EXPECT_EQ(rc, -EBADMSG); 2317 } 2318 #endif 2319 2320 #ifdef LIBPLDM_API_TESTING 2321 TEST(GetDownstreamFirmwareParameters, encodeRequestErrorBufSize) 2322 { 2323 constexpr uint8_t instanceId = 1; 2324 // Setup invalid transfer operation flag 2325 constexpr pldm_get_downstream_firmware_parameters_req params_req{ 2326 0x0, PLDM_ACKNOWLEDGEMENT_ONLY}; 2327 constexpr size_t payload_length = 2328 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES - 2329 1 /* inject erro length*/; 2330 2331 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{}; 2332 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2333 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data()); 2334 2335 auto rc = encode_get_downstream_firmware_parameters_req( 2336 instanceId, ¶ms_req, requestPtr, payload_length); 2337 EXPECT_EQ(rc, -EOVERFLOW); 2338 } 2339 #endif 2340 2341 #ifdef LIBPLDM_API_TESTING 2342 TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseOneEntry) 2343 { 2344 constexpr uint16_t downstreamDeviceCount = 1; 2345 constexpr uint8_t activeComponentVersionStringLength = 8; 2346 constexpr uint8_t pendingComponentVersionStringLength = 8; 2347 constexpr size_t downstreamDeviceParamTableLen = 2348 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN + 2349 activeComponentVersionStringLength + 2350 pendingComponentVersionStringLength; 2351 constexpr uint8_t completion_code_resp = PLDM_SUCCESS; 2352 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 2353 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 2354 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002}; 2355 constexpr size_t payload_len = 2356 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN + 2357 downstreamDeviceParamTableLen; 2358 2359 PLDM_MSG_DEFINE_P(response, payload_len); 2360 struct pldm_msgbuf _buf; 2361 struct pldm_msgbuf* buf = &_buf; 2362 int rc = 0; 2363 2364 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len); 2365 EXPECT_EQ(rc, 0); 2366 2367 // Table 24 2368 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 2369 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 2370 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 2371 2372 // Table 25 2373 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value); 2374 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount); 2375 2376 // Table 26 2377 pldm_msgbuf_insert_uint16(buf, 0); 2378 2379 // - Active metadata 2380 pldm_msgbuf_insert_uint32(buf, 0); 2381 pldm_msgbuf_insert_uint8(buf, 1); 2382 pldm_msgbuf_insert_uint8(buf, activeComponentVersionStringLength); 2383 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8); 2384 ASSERT_EQ(rc, 0); 2385 2386 // - Pending metadata 2387 pldm_msgbuf_insert_uint32(buf, 0); 2388 pldm_msgbuf_insert_uint8(buf, 1); 2389 pldm_msgbuf_insert_uint8(buf, pendingComponentVersionStringLength); 2390 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8); 2391 ASSERT_EQ(rc, 0); 2392 2393 // - Methods and capabilities 2394 pldm_msgbuf_insert_uint16(buf, 1); 2395 pldm_msgbuf_insert_uint32(buf, 0); 2396 2397 // - Version strings 2398 rc = pldm__msgbuf_insert_array_void(buf, activeComponentVersionStringLength, 2399 "abcdefgh", 8); 2400 ASSERT_EQ(rc, 0); 2401 rc = pldm__msgbuf_insert_array_void( 2402 buf, pendingComponentVersionStringLength, "zyxwvuts", 8); 2403 ASSERT_EQ(rc, 0); 2404 2405 rc = pldm_msgbuf_destroy_consumed(buf); 2406 ASSERT_EQ(rc, 0); 2407 2408 struct pldm_get_downstream_firmware_parameters_resp resp_data = {}; 2409 struct pldm_downstream_device_parameters_iter iter = {}; 2410 2411 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len, 2412 &resp_data, &iter); 2413 2414 ASSERT_EQ(rc, 0); 2415 EXPECT_EQ(resp_data.completion_code, completion_code_resp); 2416 EXPECT_EQ(resp_data.next_data_transfer_handle, 2417 next_data_transfer_handle_resp); 2418 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp); 2419 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount); 2420 2421 struct pldm_downstream_device_parameters_entry entry; 2422 size_t entries = 0; 2423 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc) 2424 { 2425 EXPECT_EQ(entry.downstream_device_index, 0); 2426 EXPECT_EQ(entry.active_comp_comparison_stamp, 0); 2427 EXPECT_EQ(entry.active_comp_ver_str_type, 1); 2428 EXPECT_EQ(entry.active_comp_ver_str_len, 2429 activeComponentVersionStringLength); 2430 EXPECT_STREQ("20241206", entry.active_comp_release_date); 2431 EXPECT_EQ(entry.pending_comp_comparison_stamp, 0); 2432 EXPECT_EQ(entry.pending_comp_ver_str_type, 1); 2433 EXPECT_EQ(entry.pending_comp_ver_str_len, 2434 pendingComponentVersionStringLength); 2435 EXPECT_STREQ("20241206", entry.pending_comp_release_date); 2436 EXPECT_EQ(entry.comp_activation_methods.value, 1); 2437 EXPECT_EQ(entry.capabilities_during_update.value, 0); 2438 EXPECT_FALSE(memcmp("abcdefgh", entry.active_comp_ver_str, 2439 entry.active_comp_ver_str_len)); 2440 EXPECT_FALSE(memcmp("zyxwvuts", entry.pending_comp_ver_str, 2441 entry.pending_comp_ver_str_len)); 2442 entries++; 2443 } 2444 EXPECT_EQ(rc, 0); 2445 EXPECT_EQ(entries, 1); 2446 } 2447 #endif 2448 2449 #ifdef LIBPLDM_API_TESTING 2450 TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseTwoEntries) 2451 { 2452 /** Count is not fixed here taking it as 1, and the downstream device's 2453 * version strings length are set to 8 2454 */ 2455 constexpr uint16_t downstreamDeviceCount = 2; 2456 constexpr uint8_t activeComponentVersionStringLength = 8; 2457 constexpr uint8_t pendingComponentVersionStringLength = 9; 2458 constexpr size_t downstreamDeviceParamTableLen = 2459 static_cast<size_t>(downstreamDeviceCount * 2460 (PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN + 2461 activeComponentVersionStringLength + 2462 pendingComponentVersionStringLength)); 2463 constexpr uint8_t completion_code_resp = PLDM_SUCCESS; 2464 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 2465 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 2466 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002}; 2467 constexpr size_t payload_len = 2468 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN + 2469 downstreamDeviceParamTableLen; 2470 2471 PLDM_MSG_DEFINE_P(response, payload_len); 2472 struct pldm_msgbuf _buf; 2473 struct pldm_msgbuf* buf = &_buf; 2474 int rc = 0; 2475 2476 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len); 2477 EXPECT_EQ(rc, 0); 2478 2479 // Table 24 2480 pldm_msgbuf_insert_uint8(buf, completion_code_resp); 2481 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 2482 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 2483 2484 // Table 25 2485 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value); 2486 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount); 2487 2488 constexpr const std::array<pldm_downstream_device_parameters_entry, 2> 2489 table = {{{ 2490 0, 2491 0, 2492 1, 2493 8, 2494 "20241206", 2495 0, 2496 1, 2497 9, 2498 "20241209", 2499 {1}, 2500 {0}, 2501 "active_0", 2502 "pending_0", 2503 }, 2504 { 2505 1, 2506 0, 2507 1, 2508 8, 2509 "20241209", 2510 0, 2511 1, 2512 9, 2513 "20241206", 2514 {1}, 2515 {0}, 2516 "active_1", 2517 "pending_1", 2518 }}}; 2519 for (const auto& e : table) 2520 { 2521 // Table 26 2522 pldm_msgbuf_insert_uint16(buf, e.downstream_device_index); 2523 2524 // - Active metadata 2525 pldm_msgbuf_insert_uint32(buf, e.active_comp_comparison_stamp); 2526 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_type); 2527 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_len); 2528 rc = pldm__msgbuf_insert_array_void(buf, 8, &e.active_comp_release_date, 2529 sizeof(e.active_comp_release_date)); 2530 ASSERT_EQ(rc, 0); 2531 2532 // - Pending metadata 2533 pldm_msgbuf_insert_uint32(buf, e.pending_comp_comparison_stamp); 2534 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_type); 2535 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_len); 2536 rc = 2537 pldm__msgbuf_insert_array_void(buf, 8, e.pending_comp_release_date, 2538 sizeof(e.pending_comp_release_date)); 2539 ASSERT_EQ(rc, 0); 2540 2541 // - Methods and capabilities 2542 pldm_msgbuf_insert_uint16(buf, e.comp_activation_methods.value); 2543 pldm_msgbuf_insert_uint32(buf, e.capabilities_during_update.value); 2544 2545 // - Version strings 2546 rc = pldm__msgbuf_insert_array_void(buf, e.active_comp_ver_str_len, 2547 e.active_comp_ver_str, 2548 e.active_comp_ver_str_len); 2549 ASSERT_EQ(rc, 0); 2550 rc = pldm__msgbuf_insert_array_void(buf, e.pending_comp_ver_str_len, 2551 e.pending_comp_ver_str, 2552 e.pending_comp_ver_str_len); 2553 ASSERT_EQ(rc, 0); 2554 } 2555 2556 rc = pldm_msgbuf_destroy_consumed(buf); 2557 ASSERT_EQ(rc, 0); 2558 2559 struct pldm_get_downstream_firmware_parameters_resp resp_data = {}; 2560 struct pldm_downstream_device_parameters_iter iter = {}; 2561 2562 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len, 2563 &resp_data, &iter); 2564 2565 ASSERT_EQ(rc, 0); 2566 EXPECT_EQ(resp_data.completion_code, completion_code_resp); 2567 EXPECT_EQ(resp_data.next_data_transfer_handle, 2568 next_data_transfer_handle_resp); 2569 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp); 2570 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount); 2571 2572 struct pldm_downstream_device_parameters_entry entry; 2573 size_t entryIndex = 0; 2574 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc) 2575 { 2576 ASSERT_LE(entryIndex, table.size()); 2577 2578 EXPECT_EQ(table[entryIndex].downstream_device_index, 2579 entry.downstream_device_index); 2580 EXPECT_EQ(table[entryIndex].active_comp_comparison_stamp, 2581 entry.active_comp_comparison_stamp); 2582 EXPECT_EQ(table[entryIndex].active_comp_ver_str_type, 2583 entry.active_comp_ver_str_type); 2584 EXPECT_EQ(table[entryIndex].active_comp_ver_str_len, 2585 entry.active_comp_ver_str_len); 2586 EXPECT_STREQ(&table[entryIndex].active_comp_release_date[0], 2587 &entry.active_comp_release_date[0]); 2588 EXPECT_EQ(table[entryIndex].pending_comp_comparison_stamp, 2589 entry.pending_comp_comparison_stamp); 2590 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_type, 2591 entry.pending_comp_ver_str_type); 2592 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_len, 2593 entry.pending_comp_ver_str_len); 2594 EXPECT_STREQ(&table[entryIndex].pending_comp_release_date[0], 2595 &entry.pending_comp_release_date[0]); 2596 EXPECT_EQ(table[entryIndex].comp_activation_methods.value, 2597 entry.comp_activation_methods.value); 2598 EXPECT_EQ(table[entryIndex].capabilities_during_update.value, 2599 entry.capabilities_during_update.value); 2600 EXPECT_FALSE(memcmp(table[entryIndex].active_comp_ver_str, 2601 entry.active_comp_ver_str, 2602 table[entryIndex].active_comp_ver_str_len)); 2603 EXPECT_FALSE(memcmp(table[entryIndex].pending_comp_ver_str, 2604 entry.pending_comp_ver_str, 2605 table[entryIndex].pending_comp_ver_str_len)); 2606 entryIndex++; 2607 } 2608 EXPECT_EQ(rc, 0); 2609 EXPECT_EQ(entryIndex, table.size()); 2610 } 2611 #endif 2612 2613 #ifdef LIBPLDM_API_TESTING 2614 TEST(GetDownstreamFirmwareParameters, decodeResponseInvalidLength) 2615 { 2616 /** Count is not fixed here taking it as 1, and the downstream device's 2617 * version strings length are set to 8 2618 */ 2619 constexpr uint16_t downstreamDeviceCount = 1; 2620 constexpr uint8_t activeComponentVersionStringLength = 8; 2621 constexpr uint8_t pendingComponentVersionStringLength = 8; 2622 constexpr size_t downstreamDeviceParamTableLen = 2623 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN + 2624 activeComponentVersionStringLength + 2625 pendingComponentVersionStringLength; 2626 constexpr uint8_t complition_code_resp = PLDM_SUCCESS; 2627 constexpr uint32_t next_data_transfer_handle_resp = 0x0; 2628 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END; 2629 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002}; 2630 2631 std::array<uint8_t, 2632 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN + 2633 downstreamDeviceParamTableLen - 1 /* inject error length*/> 2634 responseMsg{}; 2635 2636 int rc = 0; 2637 2638 struct pldm_msgbuf _buf; 2639 struct pldm_msgbuf* buf = &_buf; 2640 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize, 2641 responseMsg.size() - hdrSize); 2642 EXPECT_EQ(rc, 0); 2643 2644 pldm_msgbuf_insert_uint8(buf, complition_code_resp); 2645 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp); 2646 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp); 2647 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value); 2648 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount); 2649 2650 /** Filling paramter table, the correctness of the downstream devices data 2651 * is not checked in this test case so filling with 0xff 2652 */ 2653 std::fill_n(responseMsg.data() + hdrSize + 2654 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN, 2655 downstreamDeviceParamTableLen - 1 /* inject error length*/, 2656 0xff); 2657 2658 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2659 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data()); 2660 struct pldm_get_downstream_firmware_parameters_resp resp_data = {}; 2661 struct pldm_downstream_device_parameters_iter iter; 2662 2663 rc = decode_get_downstream_firmware_parameters_resp( 2664 response, responseMsg.size() - hdrSize, &resp_data, &iter); 2665 EXPECT_EQ(rc, 0); 2666 2667 struct pldm_downstream_device_parameters_entry entry; 2668 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc) 2669 { 2670 FAIL(); 2671 } 2672 EXPECT_EQ(rc, -EOVERFLOW); 2673 } 2674 #endif 2675 2676 TEST(RequestUpdate, goodPathEncodeRequest) 2677 { 2678 constexpr uint8_t instanceId = 1; 2679 constexpr uint32_t maxTransferSize = 512; 2680 constexpr uint16_t numOfComp = 3; 2681 constexpr uint8_t maxOutstandingTransferReq = 2; 2682 constexpr uint16_t pkgDataLen = 0x1234; 2683 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0"; 2684 constexpr uint8_t compImgSetVerStrLen = 2685 static_cast<uint8_t>(compImgSetVerStr.size()); 2686 variable_field compImgSetVerStrInfo{}; 2687 compImgSetVerStrInfo.ptr = 2688 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2689 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data()); 2690 compImgSetVerStrInfo.length = compImgSetVerStrLen; 2691 2692 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) + 2693 compImgSetVerStrLen> 2694 request{}; 2695 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2696 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 2697 2698 auto rc = encode_request_update_req( 2699 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq, 2700 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, 2701 &compImgSetVerStrInfo, requestMsg, 2702 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen); 2703 EXPECT_EQ(rc, PLDM_SUCCESS); 2704 2705 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) + 2706 compImgSetVerStrLen> 2707 outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 2708 0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e, 2709 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30}; 2710 EXPECT_EQ(request, outRequest); 2711 } 2712 2713 TEST(RequestUpdate, errorPathEncodeRequest) 2714 { 2715 constexpr uint8_t instanceId = 1; 2716 uint32_t maxTransferSize = 512; 2717 constexpr uint16_t numOfComp = 3; 2718 uint8_t maxOutstandingTransferReq = 2; 2719 constexpr uint16_t pkgDataLen = 0x1234; 2720 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0"; 2721 uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size()); 2722 variable_field compImgSetVerStrInfo{}; 2723 compImgSetVerStrInfo.ptr = 2724 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2725 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data()); 2726 compImgSetVerStrInfo.length = compImgSetVerStrLen; 2727 2728 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) + 2729 compImgSetVerStr.size()> 2730 request{}; 2731 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2732 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 2733 2734 auto rc = encode_request_update_req( 2735 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq, 2736 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr, 2737 requestMsg, 2738 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen); 2739 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2740 2741 compImgSetVerStrInfo.ptr = nullptr; 2742 rc = encode_request_update_req( 2743 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq, 2744 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, 2745 &compImgSetVerStrInfo, requestMsg, 2746 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen); 2747 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2748 compImgSetVerStrInfo.ptr = 2749 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2750 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data()); 2751 2752 rc = encode_request_update_req( 2753 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq, 2754 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, 2755 &compImgSetVerStrInfo, nullptr, 2756 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen); 2757 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2758 2759 rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp, 2760 maxOutstandingTransferReq, pkgDataLen, 2761 PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, 2762 &compImgSetVerStrInfo, requestMsg, 0); 2763 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 2764 2765 compImgSetVerStrLen = 0; 2766 rc = encode_request_update_req( 2767 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq, 2768 pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr, 2769 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen); 2770 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2771 compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size()); 2772 2773 compImgSetVerStrInfo.length = 0xffff; 2774 rc = encode_request_update_req( 2775 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq, 2776 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, 2777 &compImgSetVerStrInfo, nullptr, 2778 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen); 2779 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2780 compImgSetVerStrInfo.length = compImgSetVerStrLen; 2781 2782 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1; 2783 rc = encode_request_update_req( 2784 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq, 2785 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, 2786 &compImgSetVerStrInfo, nullptr, 2787 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen); 2788 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2789 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE; 2790 2791 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ - 1; 2792 rc = encode_request_update_req( 2793 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq, 2794 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, 2795 &compImgSetVerStrInfo, nullptr, 2796 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen); 2797 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2798 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ; 2799 2800 rc = encode_request_update_req( 2801 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq, 2802 pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen, 2803 &compImgSetVerStrInfo, nullptr, 2804 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen); 2805 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2806 } 2807 2808 TEST(RequestUpdate, goodPathDecodeResponse) 2809 { 2810 /* Test a success completion code */ 2811 constexpr uint16_t fdMetaDataLen = 1024; 2812 constexpr uint8_t fdWillSendPkgData = 1; 2813 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)> 2814 requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01}; 2815 2816 auto responseMsg1 = 2817 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2818 reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data()); 2819 uint8_t outCompletionCode = 0; 2820 uint16_t outFdMetaDataLen = 0; 2821 uint8_t outFdWillSendPkgData = 0; 2822 2823 auto rc = decode_request_update_resp( 2824 responseMsg1, requestUpdateResponse1.size() - hdrSize, 2825 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData); 2826 EXPECT_EQ(rc, PLDM_SUCCESS); 2827 EXPECT_EQ(outCompletionCode, PLDM_SUCCESS); 2828 EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen); 2829 EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData); 2830 2831 #ifdef LIBPLDM_API_TESTING 2832 /* Check the success roundtrip matches */ 2833 PLDM_MSG_DEFINE_P(enc, 1000); 2834 size_t enc_payload_len = 1000; 2835 const struct pldm_request_update_resp resp_data = { 2836 .completion_code = PLDM_SUCCESS, 2837 .fd_meta_data_len = outFdMetaDataLen, 2838 .fd_will_send_pkg_data = outFdWillSendPkgData, 2839 }; 2840 rc = encode_request_update_resp(FIXED_INSTANCE_ID, &resp_data, enc, 2841 &enc_payload_len); 2842 EXPECT_EQ(rc, PLDM_SUCCESS); 2843 EXPECT_EQ(enc_payload_len + hdrSize, requestUpdateResponse1.size()); 2844 EXPECT_TRUE(std::equal(requestUpdateResponse1.begin() + hdrSize, 2845 requestUpdateResponse1.end(), enc_buf + hdrSize)); 2846 check_response(enc, PLDM_REQUEST_UPDATE); 2847 #endif 2848 2849 /* Test a failure completion code */ 2850 outCompletionCode = 0; 2851 outFdMetaDataLen = 0; 2852 outFdWillSendPkgData = 0; 2853 2854 constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)> 2855 requestUpdateResponse2{0x00, 0x00, 0x00, 0x81}; 2856 auto responseMsg2 = 2857 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2858 reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data()); 2859 rc = decode_request_update_resp( 2860 responseMsg2, requestUpdateResponse2.size() - hdrSize, 2861 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData); 2862 EXPECT_EQ(rc, PLDM_SUCCESS); 2863 EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE); 2864 } 2865 2866 TEST(RequestUpdate, errorPathDecodeResponse) 2867 { 2868 constexpr std::array<uint8_t, 2869 hdrSize + sizeof(pldm_request_update_resp) - 1> 2870 requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04}; 2871 2872 auto responseMsg = 2873 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2874 reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data()); 2875 uint8_t outCompletionCode = 0; 2876 uint16_t outFdMetaDataLen = 0; 2877 uint8_t outFdWillSendPkgData = 0; 2878 2879 auto rc = decode_request_update_resp( 2880 nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode, 2881 &outFdMetaDataLen, &outFdWillSendPkgData); 2882 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2883 2884 rc = decode_request_update_resp( 2885 responseMsg, requestUpdateResponse.size() - hdrSize, nullptr, 2886 &outFdMetaDataLen, &outFdWillSendPkgData); 2887 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2888 2889 rc = decode_request_update_resp( 2890 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode, 2891 nullptr, &outFdWillSendPkgData); 2892 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2893 2894 rc = decode_request_update_resp( 2895 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode, 2896 &outFdMetaDataLen, nullptr); 2897 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2898 2899 rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode, 2900 &outFdMetaDataLen, &outFdWillSendPkgData); 2901 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2902 2903 rc = decode_request_update_resp( 2904 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode, 2905 &outFdMetaDataLen, &outFdWillSendPkgData); 2906 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 2907 } 2908 2909 TEST(PassComponentTable, goodPathEncodeRequest) 2910 { 2911 constexpr uint8_t instanceId = 1; 2912 constexpr uint16_t compIdentifier = 400; 2913 constexpr uint8_t compClassificationIndex = 40; 2914 constexpr uint32_t compComparisonStamp = 0x12345678; 2915 constexpr std::string_view compVerStr = "0penBmcv1.1"; 2916 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size()); 2917 variable_field compVerStrInfo{}; 2918 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2919 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data()); 2920 compVerStrInfo.length = compVerStrLen; 2921 2922 std::array<uint8_t, 2923 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen> 2924 request{}; 2925 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2926 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 2927 2928 auto rc = encode_pass_component_table_req( 2929 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier, 2930 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 2931 compVerStrLen, &compVerStrInfo, requestMsg, 2932 sizeof(pldm_pass_component_table_req) + compVerStrLen); 2933 EXPECT_EQ(rc, PLDM_SUCCESS); 2934 2935 std::array<uint8_t, 2936 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen> 2937 outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28, 2938 0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 2939 0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31}; 2940 EXPECT_EQ(request, outRequest); 2941 2942 #ifdef LIBPLDM_API_TESTING 2943 /* Check the roundtrip */ 2944 struct pldm_pass_component_table_req_full req; 2945 PLDM_MSG_DEFINE_P(dec, outRequest.size()); 2946 std::copy(outRequest.begin(), outRequest.end(), dec_buf); 2947 rc = 2948 decode_pass_component_table_req(dec, outRequest.size() - hdrSize, &req); 2949 ASSERT_EQ(rc, 0); 2950 2951 EXPECT_EQ(req.transfer_flag, PLDM_START_AND_END); 2952 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE); 2953 EXPECT_EQ(req.comp_identifier, compIdentifier); 2954 EXPECT_EQ(req.comp_classification_index, compClassificationIndex); 2955 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp); 2956 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII); 2957 EXPECT_EQ(req.version.str_len, compVerStrLen); 2958 EXPECT_TRUE(std::equal(req.version.str_data, 2959 req.version.str_data + req.version.str_len, 2960 compVerStr.data())); 2961 #endif 2962 } 2963 2964 TEST(PassComponentTable, errorPathEncodeRequest) 2965 { 2966 constexpr uint8_t instanceId = 1; 2967 constexpr uint16_t compIdentifier = 400; 2968 constexpr uint8_t compClassificationIndex = 40; 2969 constexpr uint32_t compComparisonStamp = 0x12345678; 2970 constexpr std::string_view compVerStr = "0penBmcv1.1"; 2971 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size()); 2972 variable_field compVerStrInfo{}; 2973 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2974 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data()); 2975 compVerStrInfo.length = compVerStrLen; 2976 2977 std::array<uint8_t, 2978 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen> 2979 request{}; 2980 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2981 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 2982 2983 auto rc = encode_pass_component_table_req( 2984 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier, 2985 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 2986 compVerStrLen, nullptr, requestMsg, 2987 sizeof(pldm_pass_component_table_req) + compVerStrLen); 2988 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2989 2990 compVerStrInfo.ptr = nullptr; 2991 rc = encode_pass_component_table_req( 2992 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier, 2993 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 2994 compVerStrLen, &compVerStrInfo, requestMsg, 2995 sizeof(pldm_pass_component_table_req) + compVerStrLen); 2996 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 2997 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 2998 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data()); 2999 3000 rc = encode_pass_component_table_req( 3001 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier, 3002 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 3003 compVerStrLen, &compVerStrInfo, nullptr, 3004 sizeof(pldm_pass_component_table_req) + compVerStrLen); 3005 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3006 3007 rc = encode_pass_component_table_req( 3008 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier, 3009 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 3010 compVerStrLen, &compVerStrInfo, requestMsg, 3011 sizeof(pldm_pass_component_table_req)); 3012 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3013 3014 rc = encode_pass_component_table_req( 3015 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier, 3016 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0, 3017 &compVerStrInfo, requestMsg, 3018 sizeof(pldm_pass_component_table_req) + compVerStrLen); 3019 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3020 3021 rc = encode_pass_component_table_req( 3022 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier, 3023 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 3024 compVerStrLen - 1, &compVerStrInfo, requestMsg, 3025 sizeof(pldm_pass_component_table_req) + compVerStrLen); 3026 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3027 3028 rc = encode_pass_component_table_req( 3029 instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier, 3030 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 3031 compVerStrLen, &compVerStrInfo, requestMsg, 3032 sizeof(pldm_pass_component_table_req) + compVerStrLen); 3033 EXPECT_EQ(rc, PLDM_INVALID_TRANSFER_OPERATION_FLAG); 3034 3035 rc = encode_pass_component_table_req( 3036 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier, 3037 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN, 3038 compVerStrLen, &compVerStrInfo, requestMsg, 3039 sizeof(pldm_pass_component_table_req) + compVerStrLen); 3040 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3041 } 3042 3043 TEST(PassComponentTable, goodPathDecodeResponse) 3044 { 3045 constexpr std::array<uint8_t, 3046 hdrSize + sizeof(pldm_pass_component_table_resp)> 3047 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; 3048 auto responseMsg1 = 3049 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3050 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data()); 3051 3052 uint8_t completionCode = 0; 3053 uint8_t compResp = 0; 3054 uint8_t compRespCode = 0; 3055 3056 auto rc = decode_pass_component_table_resp( 3057 responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode, 3058 &compResp, &compRespCode); 3059 3060 EXPECT_EQ(rc, PLDM_SUCCESS); 3061 EXPECT_EQ(completionCode, PLDM_SUCCESS); 3062 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED); 3063 EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL); 3064 3065 constexpr std::array<uint8_t, 3066 hdrSize + sizeof(pldm_pass_component_table_resp)> 3067 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0}; 3068 auto responseMsg2 = 3069 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3070 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data()); 3071 rc = decode_pass_component_table_resp( 3072 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode, 3073 &compResp, &compRespCode); 3074 3075 EXPECT_EQ(rc, PLDM_SUCCESS); 3076 EXPECT_EQ(completionCode, PLDM_SUCCESS); 3077 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED); 3078 EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN); 3079 3080 constexpr std::array<uint8_t, 3081 hdrSize + sizeof(pldm_pass_component_table_resp)> 3082 passCompTableResponse3{0x00, 0x00, 0x00, 0x80}; 3083 auto responseMsg3 = 3084 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3085 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data()); 3086 3087 rc = decode_pass_component_table_resp( 3088 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode, 3089 &compResp, &compRespCode); 3090 3091 EXPECT_EQ(rc, PLDM_SUCCESS); 3092 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE); 3093 } 3094 3095 TEST(PassComponentTable, errorPathDecodeResponse) 3096 { 3097 constexpr std::array<uint8_t, 3098 hdrSize + sizeof(pldm_pass_component_table_resp) - 1> 3099 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00}; 3100 auto responseMsg1 = 3101 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3102 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data()); 3103 3104 uint8_t completionCode = 0; 3105 uint8_t compResp = 0; 3106 uint8_t compRespCode = 0; 3107 3108 auto rc = decode_pass_component_table_resp( 3109 nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode, 3110 &compResp, &compRespCode); 3111 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3112 3113 rc = decode_pass_component_table_resp( 3114 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr, 3115 &compResp, &compRespCode); 3116 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3117 3118 rc = decode_pass_component_table_resp( 3119 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, 3120 &completionCode, nullptr, &compRespCode); 3121 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3122 3123 rc = decode_pass_component_table_resp( 3124 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, 3125 &completionCode, &compResp, nullptr); 3126 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3127 3128 rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode, 3129 &compResp, &compRespCode); 3130 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3131 3132 rc = decode_pass_component_table_resp( 3133 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, 3134 &completionCode, &compResp, &compRespCode); 3135 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3136 3137 constexpr std::array<uint8_t, 3138 hdrSize + sizeof(pldm_pass_component_table_resp)> 3139 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00}; 3140 auto responseMsg2 = 3141 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3142 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data()); 3143 rc = decode_pass_component_table_resp( 3144 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode, 3145 &compResp, &compRespCode); 3146 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3147 3148 constexpr std::array<uint8_t, 3149 hdrSize + sizeof(pldm_pass_component_table_resp)> 3150 passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c}; 3151 auto responseMsg3 = 3152 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3153 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data()); 3154 rc = decode_pass_component_table_resp( 3155 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode, 3156 &compResp, &compRespCode); 3157 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3158 3159 constexpr std::array<uint8_t, 3160 hdrSize + sizeof(pldm_pass_component_table_resp)> 3161 passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0}; 3162 auto responseMsg4 = 3163 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3164 reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data()); 3165 rc = decode_pass_component_table_resp( 3166 responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode, 3167 &compResp, &compRespCode); 3168 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3169 } 3170 3171 TEST(UpdateComponent, goodPathEncodeRequest) 3172 { 3173 constexpr uint8_t instanceId = 2; 3174 constexpr uint16_t compIdentifier = 500; 3175 constexpr uint8_t compClassificationIndex = 50; 3176 constexpr uint32_t compComparisonStamp = 0x89abcdef; 3177 constexpr uint32_t compImageSize = 4096; 3178 constexpr bitfield32_t updateOptionFlags{1}; 3179 constexpr std::string_view compVerStr = "OpenBmcv2.2"; 3180 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size()); 3181 variable_field compVerStrInfo{}; 3182 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3183 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data()); 3184 compVerStrInfo.length = compVerStrLen; 3185 3186 std::array<uint8_t, 3187 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen> 3188 request{}; 3189 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3190 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 3191 3192 auto rc = encode_update_component_req( 3193 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex, 3194 compComparisonStamp, compImageSize, updateOptionFlags, 3195 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg, 3196 sizeof(pldm_update_component_req) + compVerStrLen); 3197 EXPECT_EQ(rc, PLDM_SUCCESS); 3198 3199 std::array<uint8_t, 3200 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen> 3201 outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef, 3202 0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 3203 0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 3204 0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32}; 3205 EXPECT_EQ(request, outRequest); 3206 3207 #ifdef LIBPLDM_API_TESTING 3208 /* Check the roundtrip */ 3209 struct pldm_update_component_req_full req; 3210 PLDM_MSG_DEFINE_P(dec, outRequest.size()); 3211 std::copy(outRequest.begin(), outRequest.end(), dec_buf); 3212 rc = decode_update_component_req(dec, outRequest.size() - hdrSize, &req); 3213 ASSERT_EQ(rc, 0); 3214 3215 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE); 3216 EXPECT_EQ(req.comp_identifier, compIdentifier); 3217 EXPECT_EQ(req.comp_classification_index, compClassificationIndex); 3218 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp); 3219 EXPECT_EQ(req.comp_image_size, compImageSize); 3220 EXPECT_EQ(req.update_option_flags.value, updateOptionFlags.value); 3221 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII); 3222 EXPECT_EQ(req.version.str_len, compVerStrLen); 3223 EXPECT_TRUE(std::equal(req.version.str_data, 3224 req.version.str_data + req.version.str_len, 3225 compVerStr.data())); 3226 #endif 3227 } 3228 3229 TEST(UpdateComponent, errorPathEncodeRequest) 3230 { 3231 constexpr uint8_t instanceId = 2; 3232 constexpr uint16_t compIdentifier = 500; 3233 constexpr uint8_t compClassificationIndex = 50; 3234 constexpr uint32_t compComparisonStamp = 0x89abcdef; 3235 constexpr uint32_t compImageSize = 4096; 3236 constexpr bitfield32_t updateOptionFlags{1}; 3237 constexpr std::string_view compVerStr = "OpenBmcv2.2"; 3238 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size()); 3239 variable_field compVerStrInfo{}; 3240 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3241 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data()); 3242 compVerStrInfo.length = compVerStrLen; 3243 3244 std::array<uint8_t, 3245 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen> 3246 request{}; 3247 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3248 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 3249 3250 auto rc = encode_update_component_req( 3251 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex, 3252 compComparisonStamp, compImageSize, updateOptionFlags, 3253 PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg, 3254 sizeof(pldm_update_component_req) + compVerStrLen); 3255 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3256 3257 compVerStrInfo.ptr = nullptr; 3258 rc = encode_update_component_req( 3259 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex, 3260 compComparisonStamp, compImageSize, updateOptionFlags, 3261 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg, 3262 sizeof(pldm_update_component_req) + compVerStrLen); 3263 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3264 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3265 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data()); 3266 3267 rc = encode_update_component_req( 3268 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex, 3269 compComparisonStamp, compImageSize, updateOptionFlags, 3270 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr, 3271 sizeof(pldm_update_component_req) + compVerStrLen); 3272 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3273 3274 rc = encode_update_component_req( 3275 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex, 3276 compComparisonStamp, compImageSize, updateOptionFlags, 3277 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg, 3278 sizeof(pldm_update_component_req)); 3279 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3280 3281 rc = encode_update_component_req( 3282 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex, 3283 compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII, 3284 compVerStrLen, &compVerStrInfo, requestMsg, 3285 sizeof(pldm_update_component_req) + compVerStrLen); 3286 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3287 3288 rc = encode_update_component_req( 3289 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex, 3290 compComparisonStamp, compImageSize, updateOptionFlags, 3291 PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg, 3292 sizeof(pldm_update_component_req) + compVerStrLen); 3293 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3294 3295 rc = encode_update_component_req( 3296 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex, 3297 compComparisonStamp, compImageSize, updateOptionFlags, 3298 PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg, 3299 sizeof(pldm_update_component_req) + compVerStrLen); 3300 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3301 3302 rc = encode_update_component_req( 3303 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex, 3304 compComparisonStamp, compImageSize, updateOptionFlags, 3305 PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg, 3306 sizeof(pldm_update_component_req) + compVerStrLen); 3307 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3308 } 3309 3310 TEST(UpdateComponent, goodPathDecodeResponse) 3311 { 3312 constexpr std::bitset<32> forceUpdateComp{1}; 3313 constexpr uint16_t timeBeforeSendingReqFwData100s = 100; 3314 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)> 3315 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3316 0x01, 0x00, 0x00, 0x00, 0x64, 0x00}; 3317 auto responseMsg1 = 3318 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3319 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data()); 3320 3321 uint8_t completionCode = 0; 3322 uint8_t compCompatibilityResp = 0; 3323 uint8_t compCompatibilityRespCode = 0; 3324 bitfield32_t updateOptionFlagsEnabled{}; 3325 uint16_t timeBeforeReqFWData = 0; 3326 3327 auto rc = decode_update_component_resp( 3328 responseMsg1, sizeof(pldm_update_component_resp), &completionCode, 3329 &compCompatibilityResp, &compCompatibilityRespCode, 3330 &updateOptionFlagsEnabled, &timeBeforeReqFWData); 3331 3332 EXPECT_EQ(rc, PLDM_SUCCESS); 3333 EXPECT_EQ(completionCode, PLDM_SUCCESS); 3334 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED); 3335 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE); 3336 EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp); 3337 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s); 3338 3339 constexpr std::bitset<32> noFlags{}; 3340 constexpr uint16_t timeBeforeSendingReqFwData0s = 0; 3341 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)> 3342 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 3343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 3344 auto responseMsg2 = 3345 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3346 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data()); 3347 rc = decode_update_component_resp( 3348 responseMsg2, sizeof(pldm_update_component_resp), &completionCode, 3349 &compCompatibilityResp, &compCompatibilityRespCode, 3350 &updateOptionFlagsEnabled, &timeBeforeReqFWData); 3351 3352 EXPECT_EQ(rc, PLDM_SUCCESS); 3353 EXPECT_EQ(completionCode, PLDM_SUCCESS); 3354 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED); 3355 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH); 3356 EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags); 3357 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s); 3358 3359 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)> 3360 updateComponentResponse3{0x00, 0x00, 0x00, 0x80}; 3361 auto responseMsg3 = 3362 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3363 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data()); 3364 3365 rc = decode_update_component_resp( 3366 responseMsg3, sizeof(pldm_update_component_resp), &completionCode, 3367 &compCompatibilityResp, &compCompatibilityRespCode, 3368 &updateOptionFlagsEnabled, &timeBeforeReqFWData); 3369 3370 EXPECT_EQ(rc, PLDM_SUCCESS); 3371 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE); 3372 } 3373 3374 TEST(UpdateComponent, errorPathDecodeResponse) 3375 { 3376 constexpr std::array<uint8_t, 3377 hdrSize + sizeof(pldm_update_component_resp) - 1> 3378 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 3379 0x00, 0x00, 0x00, 0x00, 0x00}; 3380 auto responseMsg1 = 3381 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3382 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data()); 3383 3384 uint8_t completionCode = 0; 3385 uint8_t compCompatibilityResp = 0; 3386 uint8_t compCompatibilityRespCode = 0; 3387 bitfield32_t updateOptionFlagsEnabled{}; 3388 uint16_t timeBeforeReqFWData = 0; 3389 3390 auto rc = decode_update_component_resp( 3391 nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode, 3392 &compCompatibilityResp, &compCompatibilityRespCode, 3393 &updateOptionFlagsEnabled, &timeBeforeReqFWData); 3394 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3395 3396 rc = decode_update_component_resp( 3397 responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr, 3398 &compCompatibilityResp, &compCompatibilityRespCode, 3399 &updateOptionFlagsEnabled, &timeBeforeReqFWData); 3400 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3401 3402 rc = decode_update_component_resp( 3403 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode, 3404 nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled, 3405 &timeBeforeReqFWData); 3406 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3407 3408 rc = decode_update_component_resp( 3409 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode, 3410 &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled, 3411 &timeBeforeReqFWData); 3412 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3413 3414 rc = decode_update_component_resp( 3415 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode, 3416 &compCompatibilityResp, &compCompatibilityRespCode, nullptr, 3417 &timeBeforeReqFWData); 3418 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3419 3420 rc = decode_update_component_resp( 3421 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode, 3422 &compCompatibilityResp, &compCompatibilityRespCode, 3423 &updateOptionFlagsEnabled, nullptr); 3424 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3425 3426 rc = decode_update_component_resp( 3427 responseMsg1, 0, &completionCode, &compCompatibilityResp, 3428 &compCompatibilityRespCode, &updateOptionFlagsEnabled, 3429 &timeBeforeReqFWData); 3430 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3431 3432 rc = decode_update_component_resp( 3433 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode, 3434 &compCompatibilityResp, &compCompatibilityRespCode, 3435 &updateOptionFlagsEnabled, &timeBeforeReqFWData); 3436 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3437 3438 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)> 3439 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 3440 0x01, 0x00, 0x00, 0x00, 0x64, 0x00}; 3441 auto responseMsg2 = 3442 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3443 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data()); 3444 rc = decode_update_component_resp( 3445 responseMsg2, sizeof(pldm_update_component_resp), &completionCode, 3446 &compCompatibilityResp, &compCompatibilityRespCode, 3447 &updateOptionFlagsEnabled, &timeBeforeReqFWData); 3448 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3449 3450 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)> 3451 updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 3452 0x01, 0x00, 0x00, 0x00, 0x64, 0x00}; 3453 auto responseMsg3 = 3454 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3455 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data()); 3456 rc = decode_update_component_resp( 3457 responseMsg3, sizeof(pldm_update_component_resp), &completionCode, 3458 &compCompatibilityResp, &compCompatibilityRespCode, 3459 &updateOptionFlagsEnabled, &timeBeforeReqFWData); 3460 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3461 3462 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)> 3463 updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 3464 0x01, 0x00, 0x00, 0x00, 0x64, 0x00}; 3465 auto responseMsg4 = 3466 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3467 reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data()); 3468 rc = decode_update_component_resp( 3469 responseMsg4, sizeof(pldm_update_component_resp), &completionCode, 3470 &compCompatibilityResp, &compCompatibilityRespCode, 3471 &updateOptionFlagsEnabled, &timeBeforeReqFWData); 3472 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3473 } 3474 3475 TEST(RequestFirmwareData, goodPathDecodeRequest) 3476 { 3477 constexpr uint32_t offset = 300; 3478 constexpr uint32_t length = 255; 3479 constexpr std::array<uint8_t, 3480 hdrSize + sizeof(pldm_request_firmware_data_req)> 3481 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00, 3482 0x00, 0xff, 0x00, 0x00, 0x00}; 3483 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3484 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data()); 3485 3486 uint32_t outOffset = 0; 3487 uint32_t outLength = 0; 3488 auto rc = decode_request_firmware_data_req( 3489 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset, 3490 &outLength); 3491 3492 EXPECT_EQ(rc, PLDM_SUCCESS); 3493 EXPECT_EQ(outOffset, offset); 3494 EXPECT_EQ(outLength, length); 3495 } 3496 3497 TEST(RequestFirmwareData, errorPathDecodeRequest) 3498 { 3499 constexpr std::array<uint8_t, 3500 hdrSize + sizeof(pldm_request_firmware_data_req)> 3501 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00, 3502 0x00, 0x1f, 0x00, 0x00, 0x00}; 3503 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3504 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data()); 3505 3506 uint32_t outOffset = 0; 3507 uint32_t outLength = 0; 3508 auto rc = decode_request_firmware_data_req( 3509 nullptr, sizeof(pldm_request_firmware_data_req), &outOffset, 3510 &outLength); 3511 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3512 3513 rc = decode_request_firmware_data_req( 3514 requestMsg, sizeof(pldm_request_firmware_data_req), nullptr, 3515 &outLength); 3516 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3517 3518 rc = decode_request_firmware_data_req( 3519 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset, 3520 nullptr); 3521 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3522 3523 rc = decode_request_firmware_data_req( 3524 requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset, 3525 &outLength); 3526 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3527 3528 rc = decode_request_firmware_data_req( 3529 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset, 3530 &outLength); 3531 EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH); 3532 } 3533 3534 TEST(RequestFirmwareData, goodPathEncodeResponse) 3535 { 3536 constexpr uint8_t instanceId = 3; 3537 constexpr uint8_t completionCode = PLDM_SUCCESS; 3538 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) + 3539 PLDM_FWUP_BASELINE_TRANSFER_SIZE> 3540 outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04, 3541 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 3542 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 3543 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 3544 0x1d, 0x1e, 0x1f, 0x20}; 3545 std::array<uint8_t, hdrSize + sizeof(completionCode) + 3546 PLDM_FWUP_BASELINE_TRANSFER_SIZE> 3547 reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 3548 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 3549 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 3550 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 3551 0x1d, 0x1e, 0x1f, 0x20}; 3552 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3553 auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data()); 3554 auto rc = encode_request_firmware_data_resp( 3555 instanceId, completionCode, responseMsg1, 3556 sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE); 3557 EXPECT_EQ(rc, PLDM_SUCCESS); 3558 EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1); 3559 3560 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 3561 outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82}; 3562 std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{ 3563 0x00, 0x00, 0x00, 0x00}; 3564 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3565 auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data()); 3566 rc = encode_request_firmware_data_resp( 3567 instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2, 3568 sizeof(completionCode)); 3569 EXPECT_EQ(rc, PLDM_SUCCESS); 3570 EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2); 3571 } 3572 3573 TEST(RequestFirmwareData, errorPathEncodeResponse) 3574 { 3575 std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00}; 3576 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3577 auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data()); 3578 auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0); 3579 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3580 3581 rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0); 3582 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3583 } 3584 3585 TEST(TransferComplete, goodPathDecodeRequest) 3586 { 3587 constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS; 3588 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)> 3589 transferCompleteReq1{0x00, 0x00, 0x00, 0x00}; 3590 auto requestMsg1 = 3591 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3592 reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data()); 3593 uint8_t outTransferResult = 0; 3594 3595 auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult), 3596 &outTransferResult); 3597 EXPECT_EQ(rc, PLDM_SUCCESS); 3598 EXPECT_EQ(outTransferResult, transferResult); 3599 3600 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)> 3601 transferCompleteReq2{0x00, 0x00, 0x00, 0x02}; 3602 auto requestMsg2 = 3603 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3604 reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data()); 3605 rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult), 3606 &outTransferResult); 3607 EXPECT_EQ(rc, PLDM_SUCCESS); 3608 EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT); 3609 } 3610 3611 TEST(TransferComplete, errorPathDecodeRequest) 3612 { 3613 constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00, 3614 0x00}; 3615 auto requestMsg = 3616 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3617 reinterpret_cast<const pldm_msg*>(transferCompleteReq.data()); 3618 uint8_t outTransferResult = 0; 3619 3620 auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult); 3621 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3622 3623 rc = decode_transfer_complete_req(requestMsg, 0, nullptr); 3624 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3625 3626 rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult); 3627 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3628 } 3629 3630 TEST(TransferComplete, goodPathEncodeResponse) 3631 { 3632 constexpr uint8_t instanceId = 4; 3633 constexpr uint8_t completionCode = PLDM_SUCCESS; 3634 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 3635 outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00}; 3636 std::array<uint8_t, hdrSize + sizeof(completionCode)> 3637 transferCompleteResponse1{0x00, 0x00, 0x00, 0x00}; 3638 auto responseMsg1 = 3639 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3640 reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data()); 3641 auto rc = encode_transfer_complete_resp( 3642 instanceId, completionCode, responseMsg1, sizeof(completionCode)); 3643 EXPECT_EQ(rc, PLDM_SUCCESS); 3644 EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1); 3645 3646 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 3647 outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88}; 3648 std::array<uint8_t, hdrSize + sizeof(completionCode)> 3649 transferCompleteResponse2{0x00, 0x00, 0x00, 0x00}; 3650 auto responseMsg2 = 3651 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3652 reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data()); 3653 rc = encode_transfer_complete_resp(instanceId, 3654 PLDM_FWUP_COMMAND_NOT_EXPECTED, 3655 responseMsg2, sizeof(completionCode)); 3656 EXPECT_EQ(rc, PLDM_SUCCESS); 3657 EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2); 3658 } 3659 3660 TEST(TransferComplete, errorPathEncodeResponse) 3661 { 3662 std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00}; 3663 auto responseMsg = 3664 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3665 reinterpret_cast<pldm_msg*>(transferCompleteResponse.data()); 3666 auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0); 3667 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3668 3669 rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0); 3670 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3671 } 3672 3673 TEST(VerifyComplete, goodPathDecodeRequest) 3674 { 3675 constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS; 3676 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)> 3677 verifyCompleteReq1{0x00, 0x00, 0x00, 0x00}; 3678 auto requestMsg1 = 3679 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3680 reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data()); 3681 uint8_t outVerifyResult = 0; 3682 3683 auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult), 3684 &outVerifyResult); 3685 EXPECT_EQ(rc, PLDM_SUCCESS); 3686 EXPECT_EQ(outVerifyResult, verifyResult); 3687 3688 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)> 3689 verifyCompleteReq2{0x00, 0x00, 0x00, 0x03}; 3690 auto requestMsg2 = 3691 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3692 reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data()); 3693 rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult), 3694 &outVerifyResult); 3695 EXPECT_EQ(rc, PLDM_SUCCESS); 3696 EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS); 3697 } 3698 3699 TEST(VerifyComplete, errorPathDecodeRequest) 3700 { 3701 constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00}; 3702 auto requestMsg = 3703 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3704 reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data()); 3705 uint8_t outVerifyResult = 0; 3706 3707 auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult); 3708 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3709 3710 rc = decode_verify_complete_req(requestMsg, 0, nullptr); 3711 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3712 3713 rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult); 3714 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3715 } 3716 3717 TEST(VerifyComplete, goodPathEncodeResponse) 3718 { 3719 constexpr uint8_t instanceId = 5; 3720 constexpr uint8_t completionCode = PLDM_SUCCESS; 3721 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 3722 outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00}; 3723 std::array<uint8_t, hdrSize + sizeof(completionCode)> 3724 verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00}; 3725 auto responseMsg1 = 3726 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3727 reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data()); 3728 auto rc = encode_verify_complete_resp(instanceId, completionCode, 3729 responseMsg1, sizeof(completionCode)); 3730 EXPECT_EQ(rc, PLDM_SUCCESS); 3731 EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1); 3732 3733 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 3734 outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88}; 3735 std::array<uint8_t, hdrSize + sizeof(completionCode)> 3736 verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00}; 3737 auto responseMsg2 = 3738 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3739 reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data()); 3740 rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED, 3741 responseMsg2, sizeof(completionCode)); 3742 EXPECT_EQ(rc, PLDM_SUCCESS); 3743 EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2); 3744 } 3745 3746 TEST(VerifyComplete, errorPathEncodeResponse) 3747 { 3748 std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00}; 3749 auto responseMsg = 3750 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3751 reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data()); 3752 auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0); 3753 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3754 3755 rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0); 3756 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3757 } 3758 3759 TEST(ApplyComplete, goodPathDecodeRequest) 3760 { 3761 constexpr uint8_t applyResult1 = 3762 PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD; 3763 // DC power cycle [Bit position 4] & AC power cycle [Bit position 5] 3764 constexpr std::bitset<16> compActivationModification1{0x30}; 3765 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)> 3766 applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00}; 3767 auto requestMsg1 = 3768 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3769 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data()); 3770 uint8_t outApplyResult = 0; 3771 bitfield16_t outCompActivationModification{}; 3772 auto rc = decode_apply_complete_req( 3773 requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult, 3774 &outCompActivationModification); 3775 EXPECT_EQ(rc, PLDM_SUCCESS); 3776 EXPECT_EQ(outApplyResult, applyResult1); 3777 EXPECT_EQ(outCompActivationModification.value, compActivationModification1); 3778 3779 constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS; 3780 constexpr std::bitset<16> compActivationModification2{}; 3781 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)> 3782 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 3783 auto requestMsg2 = 3784 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3785 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data()); 3786 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req), 3787 &outApplyResult, 3788 &outCompActivationModification); 3789 EXPECT_EQ(rc, PLDM_SUCCESS); 3790 EXPECT_EQ(outApplyResult, applyResult2); 3791 EXPECT_EQ(outCompActivationModification.value, compActivationModification2); 3792 } 3793 3794 TEST(ApplyComplete, errorPathDecodeRequest) 3795 { 3796 constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00}; 3797 auto requestMsg1 = 3798 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3799 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data()); 3800 uint8_t outApplyResult = 0; 3801 bitfield16_t outCompActivationModification{}; 3802 3803 auto rc = decode_apply_complete_req( 3804 nullptr, sizeof(pldm_apply_complete_req), &outApplyResult, 3805 &outCompActivationModification); 3806 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3807 3808 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req), 3809 nullptr, &outCompActivationModification); 3810 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3811 3812 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req), 3813 &outApplyResult, nullptr); 3814 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3815 3816 rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult, 3817 &outCompActivationModification); 3818 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3819 3820 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)> 3821 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00}; 3822 auto requestMsg2 = 3823 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3824 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data()); 3825 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req), 3826 &outApplyResult, 3827 &outCompActivationModification); 3828 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3829 } 3830 3831 TEST(ApplyComplete, goodPathEncodeResponse) 3832 { 3833 constexpr uint8_t instanceId = 6; 3834 constexpr uint8_t completionCode = PLDM_SUCCESS; 3835 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 3836 outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00}; 3837 std::array<uint8_t, hdrSize + sizeof(completionCode)> 3838 applyCompleteResponse1{0x00, 0x00, 0x00, 0x00}; 3839 auto responseMsg1 = 3840 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3841 reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data()); 3842 auto rc = encode_apply_complete_resp(instanceId, completionCode, 3843 responseMsg1, sizeof(completionCode)); 3844 EXPECT_EQ(rc, PLDM_SUCCESS); 3845 EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1); 3846 3847 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 3848 outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88}; 3849 std::array<uint8_t, hdrSize + sizeof(completionCode)> 3850 applyCompleteResponse2{0x00, 0x00, 0x00, 0x00}; 3851 auto responseMsg2 = 3852 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3853 reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data()); 3854 rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED, 3855 responseMsg2, sizeof(completionCode)); 3856 EXPECT_EQ(rc, PLDM_SUCCESS); 3857 EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2); 3858 } 3859 3860 TEST(ApplyComplete, errorPathEncodeResponse) 3861 { 3862 std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00}; 3863 auto responseMsg = 3864 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3865 reinterpret_cast<pldm_msg*>(applyCompleteResponse.data()); 3866 auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0); 3867 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3868 3869 rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0); 3870 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3871 } 3872 3873 TEST(ActivateFirmware, goodPathEncodeRequest) 3874 { 3875 constexpr uint8_t instanceId = 7; 3876 3877 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{}; 3878 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3879 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 3880 3881 auto rc = encode_activate_firmware_req( 3882 instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 3883 sizeof(pldm_activate_firmware_req)); 3884 EXPECT_EQ(rc, PLDM_SUCCESS); 3885 3886 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> 3887 outRequest{0x87, 0x05, 0x1a, 0x01}; 3888 EXPECT_EQ(request, outRequest); 3889 } 3890 3891 TEST(ActivateFirmware, errorPathEncodeRequest) 3892 { 3893 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{}; 3894 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3895 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 3896 3897 auto rc = encode_activate_firmware_req( 3898 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr, 3899 sizeof(pldm_activate_firmware_req)); 3900 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3901 3902 rc = encode_activate_firmware_req( 3903 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0); 3904 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3905 3906 rc = encode_activate_firmware_req(0, 2, requestMsg, 3907 sizeof(pldm_activate_firmware_req)); 3908 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3909 } 3910 3911 TEST(ActivateFirmware, goodPathDecodeResponse) 3912 { 3913 constexpr uint16_t estimatedTimeForActivation100s = 100; 3914 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)> 3915 activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00}; 3916 auto responseMsg1 = 3917 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3918 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data()); 3919 3920 uint8_t completionCode = 0; 3921 uint16_t estimatedTimeForActivation = 0; 3922 3923 auto rc = decode_activate_firmware_resp( 3924 responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode, 3925 &estimatedTimeForActivation); 3926 3927 EXPECT_EQ(rc, PLDM_SUCCESS); 3928 EXPECT_EQ(completionCode, PLDM_SUCCESS); 3929 EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s); 3930 3931 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 3932 activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85}; 3933 auto responseMsg2 = 3934 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3935 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data()); 3936 3937 rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode), 3938 &completionCode, 3939 &estimatedTimeForActivation); 3940 3941 EXPECT_EQ(rc, PLDM_SUCCESS); 3942 EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE); 3943 } 3944 3945 TEST(ActivateFirmware, errorPathDecodeResponse) 3946 { 3947 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)> 3948 activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 3949 auto responseMsg = 3950 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3951 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data()); 3952 3953 uint8_t completionCode = 0; 3954 uint16_t estimatedTimeForActivation = 0; 3955 3956 auto rc = decode_activate_firmware_resp( 3957 nullptr, sizeof(pldm_activate_firmware_resp), &completionCode, 3958 &estimatedTimeForActivation); 3959 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3960 3961 rc = decode_activate_firmware_resp(responseMsg, 3962 sizeof(pldm_activate_firmware_resp), 3963 nullptr, &estimatedTimeForActivation); 3964 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3965 3966 rc = decode_activate_firmware_resp(responseMsg, 3967 sizeof(pldm_activate_firmware_resp), 3968 &completionCode, nullptr); 3969 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3970 3971 rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode, 3972 &estimatedTimeForActivation); 3973 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 3974 3975 rc = decode_activate_firmware_resp( 3976 responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode, 3977 &estimatedTimeForActivation); 3978 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 3979 } 3980 3981 TEST(GetStatus, goodPathEncodeRequest) 3982 { 3983 constexpr uint8_t instanceId = 8; 3984 std::array<uint8_t, hdrSize> request{}; 3985 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 3986 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 3987 3988 auto rc = encode_get_status_req(instanceId, requestMsg, 3989 PLDM_GET_STATUS_REQ_BYTES); 3990 EXPECT_EQ(rc, PLDM_SUCCESS); 3991 3992 constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b}; 3993 EXPECT_EQ(request, outRequest); 3994 } 3995 3996 TEST(GetStatus, errorPathEncodeRequest) 3997 { 3998 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{}; 3999 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4000 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 4001 4002 auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES); 4003 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4004 4005 rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1); 4006 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 4007 } 4008 4009 TEST(GetStatus, goodPathDecodeResponse) 4010 { 4011 constexpr std::bitset<32> updateOptionFlagsEnabled1{0}; 4012 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)> 4013 getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 4014 0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00}; 4015 auto responseMsg1 = 4016 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4017 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data()); 4018 4019 uint8_t completionCode = 0; 4020 uint8_t currentState = 0; 4021 uint8_t previousState = 0; 4022 uint8_t auxState = 0; 4023 uint8_t auxStateStatus = 0; 4024 uint8_t progressPercent = 0; 4025 uint8_t reasonCode = 0; 4026 bitfield32_t updateOptionFlagsEnabled{0}; 4027 4028 auto rc = decode_get_status_resp( 4029 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode, 4030 ¤tState, &previousState, &auxState, &auxStateStatus, 4031 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4032 4033 EXPECT_EQ(rc, PLDM_SUCCESS); 4034 EXPECT_EQ(completionCode, PLDM_SUCCESS); 4035 EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE); 4036 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD); 4037 EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER); 4038 EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT); 4039 EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT); 4040 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD); 4041 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1); 4042 4043 // Bit position 0 - Force update of component – FD will perform a force 4044 // update of the component. 4045 constexpr std::bitset<32> updateOptionFlagsEnabled2{1}; 4046 constexpr uint8_t progressPercent2 = 50; 4047 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)> 4048 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 4049 0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00}; 4050 auto responseMsg2 = 4051 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4052 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data()); 4053 4054 rc = decode_get_status_resp( 4055 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode, 4056 ¤tState, &previousState, &auxState, &auxStateStatus, 4057 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4058 4059 EXPECT_EQ(rc, PLDM_SUCCESS); 4060 EXPECT_EQ(completionCode, PLDM_SUCCESS); 4061 EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY); 4062 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD); 4063 EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS); 4064 EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START); 4065 EXPECT_EQ(progressPercent, progressPercent2); 4066 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD); 4067 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2); 4068 4069 #ifdef LIBPLDM_API_TESTING 4070 /* Check the roundtrip */ 4071 PLDM_MSG_DEFINE_P(enc, 1000); 4072 size_t enc_payload_len = 1000; 4073 const struct pldm_get_status_resp status_enc = { 4074 .completion_code = PLDM_SUCCESS, 4075 .current_state = currentState, 4076 .previous_state = previousState, 4077 .aux_state = auxState, 4078 .aux_state_status = auxStateStatus, 4079 .progress_percent = progressPercent, 4080 .reason_code = reasonCode, 4081 .update_option_flags_enabled = updateOptionFlagsEnabled, 4082 }; 4083 rc = encode_get_status_resp(FIXED_INSTANCE_ID, &status_enc, enc, 4084 &enc_payload_len); 4085 EXPECT_EQ(rc, PLDM_SUCCESS); 4086 EXPECT_EQ(enc_payload_len + hdrSize, getStatusResponse2.size()); 4087 EXPECT_TRUE(std::equal(getStatusResponse2.begin() + hdrSize, 4088 getStatusResponse2.end(), enc_buf + hdrSize)); 4089 check_response(enc, PLDM_GET_STATUS); 4090 #endif 4091 4092 /* Check a not-ready completion code */ 4093 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 4094 getStatusResponse3{0x00, 0x00, 0x00, 0x04}; 4095 auto responseMsg3 = 4096 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4097 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data()); 4098 rc = decode_get_status_resp( 4099 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode, 4100 ¤tState, &previousState, &auxState, &auxStateStatus, 4101 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4102 EXPECT_EQ(rc, PLDM_SUCCESS); 4103 EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY); 4104 } 4105 4106 TEST(GetStatus, errorPathDecodeResponse) 4107 { 4108 uint8_t completionCode = 0; 4109 uint8_t currentState = 0; 4110 uint8_t previousState = 0; 4111 uint8_t auxState = 0; 4112 uint8_t auxStateStatus = 0; 4113 uint8_t progressPercent = 0; 4114 uint8_t reasonCode = 0; 4115 bitfield32_t updateOptionFlagsEnabled{0}; 4116 4117 constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00}; 4118 auto responseMsg1 = 4119 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4120 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data()); 4121 4122 auto rc = decode_get_status_resp( 4123 nullptr, getStatusResponse1.size() - hdrSize, &completionCode, 4124 ¤tState, &previousState, &auxState, &auxStateStatus, 4125 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4126 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4127 4128 rc = decode_get_status_resp( 4129 responseMsg1, getStatusResponse1.size() - hdrSize, nullptr, 4130 ¤tState, &previousState, &auxState, &auxStateStatus, 4131 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4132 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4133 4134 rc = decode_get_status_resp( 4135 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode, 4136 nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent, 4137 &reasonCode, &updateOptionFlagsEnabled); 4138 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4139 4140 rc = decode_get_status_resp( 4141 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode, 4142 ¤tState, nullptr, &auxState, &auxStateStatus, &progressPercent, 4143 &reasonCode, &updateOptionFlagsEnabled); 4144 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4145 4146 rc = decode_get_status_resp( 4147 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode, 4148 ¤tState, &previousState, nullptr, &auxStateStatus, 4149 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4150 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4151 4152 rc = decode_get_status_resp( 4153 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode, 4154 ¤tState, &previousState, &auxState, nullptr, &progressPercent, 4155 &reasonCode, &updateOptionFlagsEnabled); 4156 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4157 4158 rc = decode_get_status_resp( 4159 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode, 4160 ¤tState, &previousState, &auxState, &auxStateStatus, nullptr, 4161 &reasonCode, &updateOptionFlagsEnabled); 4162 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4163 4164 rc = decode_get_status_resp( 4165 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode, 4166 ¤tState, &previousState, &auxState, &auxStateStatus, 4167 &progressPercent, nullptr, &updateOptionFlagsEnabled); 4168 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4169 4170 rc = decode_get_status_resp( 4171 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode, 4172 ¤tState, &previousState, &auxState, &auxStateStatus, 4173 &progressPercent, &reasonCode, nullptr); 4174 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4175 4176 rc = decode_get_status_resp( 4177 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode, 4178 ¤tState, &previousState, &auxState, &auxStateStatus, 4179 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4180 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4181 4182 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1> 4183 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4185 auto responseMsg2 = 4186 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4187 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data()); 4188 rc = decode_get_status_resp( 4189 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode, 4190 ¤tState, &previousState, &auxState, &auxStateStatus, 4191 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4192 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 4193 4194 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)> 4195 getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 4196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4197 auto responseMsg3 = 4198 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4199 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data()); 4200 rc = decode_get_status_resp( 4201 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode, 4202 ¤tState, &previousState, &auxState, &auxStateStatus, 4203 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4204 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4205 4206 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)> 4207 getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 4208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4209 auto responseMsg4 = 4210 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4211 reinterpret_cast<const pldm_msg*>(getStatusResponse4.data()); 4212 rc = decode_get_status_resp( 4213 responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode, 4214 ¤tState, &previousState, &auxState, &auxStateStatus, 4215 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4216 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4217 4218 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)> 4219 getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 4220 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4221 auto responseMsg5 = 4222 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4223 reinterpret_cast<const pldm_msg*>(getStatusResponse5.data()); 4224 rc = decode_get_status_resp( 4225 responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode, 4226 ¤tState, &previousState, &auxState, &auxStateStatus, 4227 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4228 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4229 4230 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)> 4231 getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4232 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4233 auto responseMsg6 = 4234 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4235 reinterpret_cast<const pldm_msg*>(getStatusResponse6.data()); 4236 rc = decode_get_status_resp( 4237 responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode, 4238 ¤tState, &previousState, &auxState, &auxStateStatus, 4239 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4240 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4241 4242 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)> 4243 getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4244 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00}; 4245 auto responseMsg7 = 4246 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4247 reinterpret_cast<const pldm_msg*>(getStatusResponse7.data()); 4248 rc = decode_get_status_resp( 4249 responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode, 4250 ¤tState, &previousState, &auxState, &auxStateStatus, 4251 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4252 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4253 4254 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)> 4255 getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4256 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00}; 4257 auto responseMsg8 = 4258 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4259 reinterpret_cast<const pldm_msg*>(getStatusResponse8.data()); 4260 rc = decode_get_status_resp( 4261 responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode, 4262 ¤tState, &previousState, &auxState, &auxStateStatus, 4263 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4264 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4265 4266 // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is 4267 // IDLE 4268 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)> 4269 getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 4270 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4271 auto responseMsg9 = 4272 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4273 reinterpret_cast<const pldm_msg*>(getStatusResponse9.data()); 4274 rc = decode_get_status_resp( 4275 responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode, 4276 ¤tState, &previousState, &auxState, &auxStateStatus, 4277 &progressPercent, &reasonCode, &updateOptionFlagsEnabled); 4278 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4279 } 4280 4281 TEST(CancelUpdateComponent, goodPathEncodeRequest) 4282 { 4283 constexpr uint8_t instanceId = 9; 4284 std::array<uint8_t, hdrSize> request{}; 4285 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4286 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 4287 4288 auto rc = encode_cancel_update_component_req( 4289 instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES); 4290 EXPECT_EQ(rc, PLDM_SUCCESS); 4291 4292 constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c}; 4293 EXPECT_EQ(request, outRequest); 4294 } 4295 4296 TEST(CancelUpdateComponent, errorPathEncodeRequest) 4297 { 4298 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{}; 4299 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4300 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 4301 4302 auto rc = encode_cancel_update_component_req( 4303 0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES); 4304 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4305 4306 rc = encode_cancel_update_component_req( 4307 0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1); 4308 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 4309 } 4310 4311 TEST(CancelUpdateComponent, testGoodDecodeResponse) 4312 { 4313 uint8_t completionCode = 0; 4314 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 4315 cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00}; 4316 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4317 auto responseMsg1 = reinterpret_cast<const pldm_msg*>( 4318 cancelUpdateComponentResponse1.data()); 4319 auto rc = decode_cancel_update_component_resp( 4320 responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize, 4321 &completionCode); 4322 EXPECT_EQ(rc, PLDM_SUCCESS); 4323 EXPECT_EQ(completionCode, PLDM_SUCCESS); 4324 4325 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 4326 cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86}; 4327 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4328 auto responseMsg2 = reinterpret_cast<const pldm_msg*>( 4329 cancelUpdateComponentResponse2.data()); 4330 rc = decode_cancel_update_component_resp( 4331 responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize, 4332 &completionCode); 4333 EXPECT_EQ(rc, PLDM_SUCCESS); 4334 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND); 4335 } 4336 4337 TEST(CancelUpdateComponent, testBadDecodeResponse) 4338 { 4339 uint8_t completionCode = 0; 4340 constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{ 4341 0x00, 0x00, 0x00}; 4342 auto responseMsg = 4343 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4344 reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data()); 4345 4346 auto rc = decode_cancel_update_component_resp( 4347 nullptr, cancelUpdateComponentResponse.size() - hdrSize, 4348 &completionCode); 4349 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4350 4351 rc = decode_cancel_update_component_resp( 4352 responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr); 4353 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4354 4355 rc = decode_cancel_update_component_resp( 4356 responseMsg, cancelUpdateComponentResponse.size() - hdrSize, 4357 &completionCode); 4358 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 4359 } 4360 4361 TEST(CancelUpdate, goodPathEncodeRequest) 4362 { 4363 constexpr uint8_t instanceId = 10; 4364 std::array<uint8_t, hdrSize> request{}; 4365 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4366 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 4367 4368 auto rc = encode_cancel_update_req(instanceId, requestMsg, 4369 PLDM_CANCEL_UPDATE_REQ_BYTES); 4370 EXPECT_EQ(rc, PLDM_SUCCESS); 4371 4372 constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d}; 4373 EXPECT_EQ(request, outRequest); 4374 } 4375 4376 TEST(CancelUpdate, errorPathEncodeRequest) 4377 { 4378 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{}; 4379 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4380 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 4381 4382 auto rc = 4383 encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES); 4384 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4385 4386 rc = encode_cancel_update_req(0, requestMsg, 4387 PLDM_CANCEL_UPDATE_REQ_BYTES + 1); 4388 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 4389 } 4390 4391 TEST(CancelUpdate, goodPathDecodeResponse) 4392 { 4393 constexpr std::bitset<64> nonFunctioningComponentBitmap1{0}; 4394 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)> 4395 cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4397 auto responseMsg1 = 4398 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4399 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data()); 4400 uint8_t completionCode = 0; 4401 bool8_t nonFunctioningComponentIndication = 0; 4402 bitfield64_t nonFunctioningComponentBitmap{0}; 4403 auto rc = decode_cancel_update_resp( 4404 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode, 4405 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap); 4406 EXPECT_EQ(rc, PLDM_SUCCESS); 4407 EXPECT_EQ(completionCode, PLDM_SUCCESS); 4408 EXPECT_EQ(nonFunctioningComponentIndication, 4409 PLDM_FWUP_COMPONENTS_FUNCTIONING); 4410 EXPECT_EQ(nonFunctioningComponentBitmap.value, 4411 nonFunctioningComponentBitmap1); 4412 4413 constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101}; 4414 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)> 4415 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 4416 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4417 auto responseMsg2 = 4418 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4419 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data()); 4420 rc = decode_cancel_update_resp( 4421 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode, 4422 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap); 4423 EXPECT_EQ(rc, PLDM_SUCCESS); 4424 EXPECT_EQ(completionCode, PLDM_SUCCESS); 4425 EXPECT_EQ(nonFunctioningComponentIndication, 4426 PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING); 4427 EXPECT_EQ(nonFunctioningComponentBitmap.value, 4428 nonFunctioningComponentBitmap2); 4429 4430 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 4431 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86}; 4432 auto responseMsg3 = 4433 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4434 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data()); 4435 rc = decode_cancel_update_resp( 4436 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode, 4437 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap); 4438 EXPECT_EQ(rc, PLDM_SUCCESS); 4439 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND); 4440 } 4441 4442 TEST(CancelUpdate, errorPathDecodeResponse) 4443 { 4444 constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00, 4445 0x00}; 4446 auto responseMsg1 = 4447 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4448 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data()); 4449 uint8_t completionCode = 0; 4450 bool8_t nonFunctioningComponentIndication = 0; 4451 bitfield64_t nonFunctioningComponentBitmap{0}; 4452 4453 auto rc = decode_cancel_update_resp( 4454 nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode, 4455 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap); 4456 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4457 4458 rc = decode_cancel_update_resp( 4459 responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr, 4460 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap); 4461 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4462 4463 rc = decode_cancel_update_resp( 4464 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode, 4465 nullptr, &nonFunctioningComponentBitmap); 4466 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4467 4468 rc = decode_cancel_update_resp( 4469 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode, 4470 &nonFunctioningComponentIndication, nullptr); 4471 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4472 4473 rc = decode_cancel_update_resp( 4474 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode, 4475 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap); 4476 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4477 4478 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)> 4479 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00}; 4480 auto responseMsg2 = 4481 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4482 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data()); 4483 rc = decode_cancel_update_resp( 4484 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode, 4485 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap); 4486 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 4487 4488 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)> 4489 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 4490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 4491 auto responseMsg3 = 4492 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 4493 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data()); 4494 rc = decode_cancel_update_resp( 4495 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode, 4496 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap); 4497 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 4498 } 4499