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