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