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