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, constains 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, constains 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 TEST(RequestUpdate, goodPathEncodeRequest)
1688 {
1689     constexpr uint8_t instanceId = 1;
1690     constexpr uint32_t maxTransferSize = 512;
1691     constexpr uint16_t numOfComp = 3;
1692     constexpr uint8_t maxOutstandingTransferReq = 2;
1693     constexpr uint16_t pkgDataLen = 0x1234;
1694     constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
1695     constexpr uint8_t compImgSetVerStrLen =
1696         static_cast<uint8_t>(compImgSetVerStr.size());
1697     variable_field compImgSetVerStrInfo{};
1698     compImgSetVerStrInfo.ptr =
1699         reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
1700     compImgSetVerStrInfo.length = compImgSetVerStrLen;
1701 
1702     std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
1703                             compImgSetVerStrLen>
1704         request{};
1705     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
1706 
1707     auto rc = encode_request_update_req(
1708         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
1709         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
1710         &compImgSetVerStrInfo, requestMsg,
1711         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
1712     EXPECT_EQ(rc, PLDM_SUCCESS);
1713 
1714     std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
1715                             compImgSetVerStrLen>
1716         outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00,
1717                    0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e,
1718                    0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30};
1719     EXPECT_EQ(request, outRequest);
1720 }
1721 
1722 TEST(RequestUpdate, errorPathEncodeRequest)
1723 {
1724     constexpr uint8_t instanceId = 1;
1725     uint32_t maxTransferSize = 512;
1726     constexpr uint16_t numOfComp = 3;
1727     uint8_t maxOutstandingTransferReq = 2;
1728     constexpr uint16_t pkgDataLen = 0x1234;
1729     constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
1730     uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
1731     variable_field compImgSetVerStrInfo{};
1732     compImgSetVerStrInfo.ptr =
1733         reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
1734     compImgSetVerStrInfo.length = compImgSetVerStrLen;
1735 
1736     std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
1737                             compImgSetVerStr.size()>
1738         request{};
1739     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
1740 
1741     auto rc = encode_request_update_req(
1742         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
1743         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr,
1744         requestMsg,
1745         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
1746     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1747 
1748     compImgSetVerStrInfo.ptr = nullptr;
1749     rc = encode_request_update_req(
1750         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
1751         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
1752         &compImgSetVerStrInfo, requestMsg,
1753         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
1754     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1755     compImgSetVerStrInfo.ptr =
1756         reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
1757 
1758     rc = encode_request_update_req(
1759         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
1760         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
1761         &compImgSetVerStrInfo, nullptr,
1762         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
1763     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1764 
1765     rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp,
1766                                    maxOutstandingTransferReq, pkgDataLen,
1767                                    PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
1768                                    &compImgSetVerStrInfo, requestMsg, 0);
1769     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1770 
1771     compImgSetVerStrLen = 0;
1772     rc = encode_request_update_req(
1773         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
1774         pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr,
1775         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
1776     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1777     compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
1778 
1779     compImgSetVerStrInfo.length = 0xffff;
1780     rc = encode_request_update_req(
1781         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
1782         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
1783         &compImgSetVerStrInfo, nullptr,
1784         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
1785     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1786     compImgSetVerStrInfo.length = compImgSetVerStrLen;
1787 
1788     maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1;
1789     rc = encode_request_update_req(
1790         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
1791         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
1792         &compImgSetVerStrInfo, nullptr,
1793         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
1794     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1795     maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE;
1796 
1797     maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ - 1;
1798     rc = encode_request_update_req(
1799         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
1800         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
1801         &compImgSetVerStrInfo, nullptr,
1802         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
1803     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1804     maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ;
1805 
1806     rc = encode_request_update_req(
1807         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
1808         pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen,
1809         &compImgSetVerStrInfo, nullptr,
1810         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
1811     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1812 }
1813 
1814 TEST(RequestUpdate, goodPathDecodeResponse)
1815 {
1816     constexpr uint16_t fdMetaDataLen = 1024;
1817     constexpr uint8_t fdWillSendPkgData = 1;
1818     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)>
1819         requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01};
1820 
1821     auto responseMsg1 =
1822         reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data());
1823     uint8_t outCompletionCode = 0;
1824     uint16_t outFdMetaDataLen = 0;
1825     uint8_t outFdWillSendPkgData = 0;
1826 
1827     auto rc = decode_request_update_resp(
1828         responseMsg1, requestUpdateResponse1.size() - hdrSize,
1829         &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
1830     EXPECT_EQ(rc, PLDM_SUCCESS);
1831     EXPECT_EQ(outCompletionCode, PLDM_SUCCESS);
1832     EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen);
1833     EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData);
1834 
1835     outCompletionCode = 0;
1836     outFdMetaDataLen = 0;
1837     outFdWillSendPkgData = 0;
1838 
1839     constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)>
1840         requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
1841     auto responseMsg2 =
1842         reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data());
1843     rc = decode_request_update_resp(
1844         responseMsg2, requestUpdateResponse2.size() - hdrSize,
1845         &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
1846     EXPECT_EQ(rc, PLDM_SUCCESS);
1847     EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
1848 }
1849 
1850 TEST(RequestUpdate, errorPathDecodeResponse)
1851 {
1852     constexpr std::array<uint8_t,
1853                          hdrSize + sizeof(pldm_request_update_resp) - 1>
1854         requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
1855 
1856     auto responseMsg =
1857         reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data());
1858     uint8_t outCompletionCode = 0;
1859     uint16_t outFdMetaDataLen = 0;
1860     uint8_t outFdWillSendPkgData = 0;
1861 
1862     auto rc = decode_request_update_resp(
1863         nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
1864         &outFdMetaDataLen, &outFdWillSendPkgData);
1865     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1866 
1867     rc = decode_request_update_resp(
1868         responseMsg, requestUpdateResponse.size() - hdrSize, nullptr,
1869         &outFdMetaDataLen, &outFdWillSendPkgData);
1870     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1871 
1872     rc = decode_request_update_resp(
1873         responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
1874         nullptr, &outFdWillSendPkgData);
1875     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1876 
1877     rc = decode_request_update_resp(
1878         responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
1879         &outFdMetaDataLen, nullptr);
1880     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1881 
1882     rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode,
1883                                     &outFdMetaDataLen, &outFdWillSendPkgData);
1884     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1885 
1886     rc = decode_request_update_resp(
1887         responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
1888         &outFdMetaDataLen, &outFdWillSendPkgData);
1889     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1890 }
1891 
1892 TEST(PassComponentTable, goodPathEncodeRequest)
1893 {
1894     constexpr uint8_t instanceId = 1;
1895     constexpr uint16_t compIdentifier = 400;
1896     constexpr uint8_t compClassificationIndex = 40;
1897     constexpr uint32_t compComparisonStamp = 0x12345678;
1898     constexpr std::string_view compVerStr = "0penBmcv1.1";
1899     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
1900     variable_field compVerStrInfo{};
1901     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
1902     compVerStrInfo.length = compVerStrLen;
1903 
1904     std::array<uint8_t,
1905                hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
1906         request{};
1907     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
1908 
1909     auto rc = encode_pass_component_table_req(
1910         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
1911         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
1912         compVerStrLen, &compVerStrInfo, requestMsg,
1913         sizeof(pldm_pass_component_table_req) + compVerStrLen);
1914     EXPECT_EQ(rc, PLDM_SUCCESS);
1915 
1916     std::array<uint8_t,
1917                hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
1918         outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28,
1919                    0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65,
1920                    0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31};
1921     EXPECT_EQ(request, outRequest);
1922 }
1923 
1924 TEST(PassComponentTable, errorPathEncodeRequest)
1925 {
1926     constexpr uint8_t instanceId = 1;
1927     constexpr uint16_t compIdentifier = 400;
1928     constexpr uint8_t compClassificationIndex = 40;
1929     constexpr uint32_t compComparisonStamp = 0x12345678;
1930     constexpr std::string_view compVerStr = "0penBmcv1.1";
1931     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
1932     variable_field compVerStrInfo{};
1933     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
1934     compVerStrInfo.length = compVerStrLen;
1935 
1936     std::array<uint8_t,
1937                hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
1938         request{};
1939     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
1940 
1941     auto rc = encode_pass_component_table_req(
1942         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
1943         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
1944         compVerStrLen, nullptr, requestMsg,
1945         sizeof(pldm_pass_component_table_req) + compVerStrLen);
1946     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1947 
1948     compVerStrInfo.ptr = nullptr;
1949     rc = encode_pass_component_table_req(
1950         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
1951         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
1952         compVerStrLen, &compVerStrInfo, requestMsg,
1953         sizeof(pldm_pass_component_table_req) + compVerStrLen);
1954     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1955     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
1956 
1957     rc = encode_pass_component_table_req(
1958         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
1959         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
1960         compVerStrLen, &compVerStrInfo, nullptr,
1961         sizeof(pldm_pass_component_table_req) + compVerStrLen);
1962     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1963 
1964     rc = encode_pass_component_table_req(
1965         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
1966         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
1967         compVerStrLen, &compVerStrInfo, requestMsg,
1968         sizeof(pldm_pass_component_table_req));
1969     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1970 
1971     rc = encode_pass_component_table_req(
1972         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
1973         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0,
1974         &compVerStrInfo, requestMsg,
1975         sizeof(pldm_pass_component_table_req) + compVerStrLen);
1976     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1977 
1978     rc = encode_pass_component_table_req(
1979         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
1980         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
1981         compVerStrLen - 1, &compVerStrInfo, requestMsg,
1982         sizeof(pldm_pass_component_table_req) + compVerStrLen);
1983     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1984 
1985     rc = encode_pass_component_table_req(
1986         instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier,
1987         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
1988         compVerStrLen, &compVerStrInfo, requestMsg,
1989         sizeof(pldm_pass_component_table_req) + compVerStrLen);
1990     EXPECT_EQ(rc, PLDM_INVALID_TRANSFER_OPERATION_FLAG);
1991 
1992     rc = encode_pass_component_table_req(
1993         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
1994         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN,
1995         compVerStrLen, &compVerStrInfo, requestMsg,
1996         sizeof(pldm_pass_component_table_req) + compVerStrLen);
1997     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1998 }
1999 
2000 TEST(PassComponentTable, goodPathDecodeResponse)
2001 {
2002     constexpr std::array<uint8_t,
2003                          hdrSize + sizeof(pldm_pass_component_table_resp)>
2004         passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
2005     auto responseMsg1 =
2006         reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
2007 
2008     uint8_t completionCode = 0;
2009     uint8_t compResp = 0;
2010     uint8_t compRespCode = 0;
2011 
2012     auto rc = decode_pass_component_table_resp(
2013         responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode,
2014         &compResp, &compRespCode);
2015 
2016     EXPECT_EQ(rc, PLDM_SUCCESS);
2017     EXPECT_EQ(completionCode, PLDM_SUCCESS);
2018     EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
2019     EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL);
2020 
2021     constexpr std::array<uint8_t,
2022                          hdrSize + sizeof(pldm_pass_component_table_resp)>
2023         passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0};
2024     auto responseMsg2 =
2025         reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
2026     rc = decode_pass_component_table_resp(
2027         responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
2028         &compResp, &compRespCode);
2029 
2030     EXPECT_EQ(rc, PLDM_SUCCESS);
2031     EXPECT_EQ(completionCode, PLDM_SUCCESS);
2032     EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
2033     EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN);
2034 
2035     constexpr std::array<uint8_t,
2036                          hdrSize + sizeof(pldm_pass_component_table_resp)>
2037         passCompTableResponse3{0x00, 0x00, 0x00, 0x80};
2038     auto responseMsg3 =
2039         reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
2040 
2041     rc = decode_pass_component_table_resp(
2042         responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
2043         &compResp, &compRespCode);
2044 
2045     EXPECT_EQ(rc, PLDM_SUCCESS);
2046     EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
2047 }
2048 
2049 TEST(PassComponentTable, errorPathDecodeResponse)
2050 {
2051     constexpr std::array<uint8_t,
2052                          hdrSize + sizeof(pldm_pass_component_table_resp) - 1>
2053         passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00};
2054     auto responseMsg1 =
2055         reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
2056 
2057     uint8_t completionCode = 0;
2058     uint8_t compResp = 0;
2059     uint8_t compRespCode = 0;
2060 
2061     auto rc = decode_pass_component_table_resp(
2062         nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode,
2063         &compResp, &compRespCode);
2064     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2065 
2066     rc = decode_pass_component_table_resp(
2067         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr,
2068         &compResp, &compRespCode);
2069     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2070 
2071     rc = decode_pass_component_table_resp(
2072         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
2073         &completionCode, nullptr, &compRespCode);
2074     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2075 
2076     rc = decode_pass_component_table_resp(
2077         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
2078         &completionCode, &compResp, nullptr);
2079     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2080 
2081     rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode,
2082                                           &compResp, &compRespCode);
2083     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2084 
2085     rc = decode_pass_component_table_resp(
2086         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
2087         &completionCode, &compResp, &compRespCode);
2088     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2089 
2090     constexpr std::array<uint8_t,
2091                          hdrSize + sizeof(pldm_pass_component_table_resp)>
2092         passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
2093     auto responseMsg2 =
2094         reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
2095     rc = decode_pass_component_table_resp(
2096         responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
2097         &compResp, &compRespCode);
2098     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2099 
2100     constexpr std::array<uint8_t,
2101                          hdrSize + sizeof(pldm_pass_component_table_resp)>
2102         passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};
2103     auto responseMsg3 =
2104         reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
2105     rc = decode_pass_component_table_resp(
2106         responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
2107         &compResp, &compRespCode);
2108     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2109 
2110     constexpr std::array<uint8_t,
2111                          hdrSize + sizeof(pldm_pass_component_table_resp)>
2112         passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
2113     auto responseMsg4 =
2114         reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data());
2115     rc = decode_pass_component_table_resp(
2116         responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode,
2117         &compResp, &compRespCode);
2118     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2119 }
2120 
2121 TEST(UpdateComponent, goodPathEncodeRequest)
2122 {
2123     constexpr uint8_t instanceId = 2;
2124     constexpr uint16_t compIdentifier = 500;
2125     constexpr uint8_t compClassificationIndex = 50;
2126     constexpr uint32_t compComparisonStamp = 0x89abcdef;
2127     constexpr uint32_t compImageSize = 4096;
2128     constexpr bitfield32_t updateOptionFlags{1};
2129     constexpr std::string_view compVerStr = "OpenBmcv2.2";
2130     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2131     variable_field compVerStrInfo{};
2132     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2133     compVerStrInfo.length = compVerStrLen;
2134 
2135     std::array<uint8_t,
2136                hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
2137         request{};
2138     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2139 
2140     auto rc = encode_update_component_req(
2141         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
2142         compComparisonStamp, compImageSize, updateOptionFlags,
2143         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
2144         sizeof(pldm_update_component_req) + compVerStrLen);
2145     EXPECT_EQ(rc, PLDM_SUCCESS);
2146 
2147     std::array<uint8_t,
2148                hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
2149         outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
2150                    0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
2151                    0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
2152                    0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
2153     EXPECT_EQ(request, outRequest);
2154 }
2155 
2156 TEST(UpdateComponent, errorPathEncodeRequest)
2157 {
2158     constexpr uint8_t instanceId = 2;
2159     constexpr uint16_t compIdentifier = 500;
2160     constexpr uint8_t compClassificationIndex = 50;
2161     constexpr uint32_t compComparisonStamp = 0x89abcdef;
2162     constexpr uint32_t compImageSize = 4096;
2163     constexpr bitfield32_t updateOptionFlags{1};
2164     constexpr std::string_view compVerStr = "OpenBmcv2.2";
2165     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2166     variable_field compVerStrInfo{};
2167     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2168     compVerStrInfo.length = compVerStrLen;
2169 
2170     std::array<uint8_t,
2171                hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
2172         request{};
2173     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2174 
2175     auto rc = encode_update_component_req(
2176         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
2177         compComparisonStamp, compImageSize, updateOptionFlags,
2178         PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
2179         sizeof(pldm_update_component_req) + compVerStrLen);
2180     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2181 
2182     compVerStrInfo.ptr = nullptr;
2183     rc = encode_update_component_req(
2184         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
2185         compComparisonStamp, compImageSize, updateOptionFlags,
2186         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
2187         sizeof(pldm_update_component_req) + compVerStrLen);
2188     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2189     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2190 
2191     rc = encode_update_component_req(
2192         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
2193         compComparisonStamp, compImageSize, updateOptionFlags,
2194         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
2195         sizeof(pldm_update_component_req) + compVerStrLen);
2196     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2197 
2198     rc = encode_update_component_req(
2199         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
2200         compComparisonStamp, compImageSize, updateOptionFlags,
2201         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
2202         sizeof(pldm_update_component_req));
2203     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2204 
2205     rc = encode_update_component_req(
2206         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
2207         compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
2208         compVerStrLen, &compVerStrInfo, requestMsg,
2209         sizeof(pldm_update_component_req) + compVerStrLen);
2210     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2211 
2212     rc = encode_update_component_req(
2213         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
2214         compComparisonStamp, compImageSize, updateOptionFlags,
2215         PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg,
2216         sizeof(pldm_update_component_req) + compVerStrLen);
2217     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2218 
2219     rc = encode_update_component_req(
2220         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
2221         compComparisonStamp, compImageSize, updateOptionFlags,
2222         PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg,
2223         sizeof(pldm_update_component_req) + compVerStrLen);
2224     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2225 
2226     rc = encode_update_component_req(
2227         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
2228         compComparisonStamp, compImageSize, updateOptionFlags,
2229         PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
2230         sizeof(pldm_update_component_req) + compVerStrLen);
2231     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2232 }
2233 
2234 TEST(UpdateComponent, goodPathDecodeResponse)
2235 {
2236     constexpr std::bitset<32> forceUpdateComp{1};
2237     constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
2238     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
2239         updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2240                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
2241     auto responseMsg1 =
2242         reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
2243 
2244     uint8_t completionCode = 0;
2245     uint8_t compCompatibilityResp = 0;
2246     uint8_t compCompatibilityRespCode = 0;
2247     bitfield32_t updateOptionFlagsEnabled{};
2248     uint16_t timeBeforeReqFWData = 0;
2249 
2250     auto rc = decode_update_component_resp(
2251         responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
2252         &compCompatibilityResp, &compCompatibilityRespCode,
2253         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
2254 
2255     EXPECT_EQ(rc, PLDM_SUCCESS);
2256     EXPECT_EQ(completionCode, PLDM_SUCCESS);
2257     EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
2258     EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
2259     EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
2260     EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
2261 
2262     constexpr std::bitset<32> noFlags{};
2263     constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
2264     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
2265         updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
2266                                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2267     auto responseMsg2 =
2268         reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
2269     rc = decode_update_component_resp(
2270         responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
2271         &compCompatibilityResp, &compCompatibilityRespCode,
2272         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
2273 
2274     EXPECT_EQ(rc, PLDM_SUCCESS);
2275     EXPECT_EQ(completionCode, PLDM_SUCCESS);
2276     EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
2277     EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
2278     EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
2279     EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
2280 
2281     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
2282         updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
2283     auto responseMsg3 =
2284         reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
2285 
2286     rc = decode_update_component_resp(
2287         responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
2288         &compCompatibilityResp, &compCompatibilityRespCode,
2289         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
2290 
2291     EXPECT_EQ(rc, PLDM_SUCCESS);
2292     EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
2293 }
2294 
2295 TEST(UpdateComponent, errorPathDecodeResponse)
2296 {
2297     constexpr std::array<uint8_t,
2298                          hdrSize + sizeof(pldm_update_component_resp) - 1>
2299         updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
2300                                  0x00, 0x00, 0x00, 0x00, 0x00};
2301     auto responseMsg1 =
2302         reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
2303 
2304     uint8_t completionCode = 0;
2305     uint8_t compCompatibilityResp = 0;
2306     uint8_t compCompatibilityRespCode = 0;
2307     bitfield32_t updateOptionFlagsEnabled{};
2308     uint16_t timeBeforeReqFWData = 0;
2309 
2310     auto rc = decode_update_component_resp(
2311         nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
2312         &compCompatibilityResp, &compCompatibilityRespCode,
2313         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
2314     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2315 
2316     rc = decode_update_component_resp(
2317         responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
2318         &compCompatibilityResp, &compCompatibilityRespCode,
2319         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
2320     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2321 
2322     rc = decode_update_component_resp(
2323         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
2324         nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
2325         &timeBeforeReqFWData);
2326     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2327 
2328     rc = decode_update_component_resp(
2329         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
2330         &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
2331         &timeBeforeReqFWData);
2332     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2333 
2334     rc = decode_update_component_resp(
2335         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
2336         &compCompatibilityResp, &compCompatibilityRespCode, nullptr,
2337         &timeBeforeReqFWData);
2338     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2339 
2340     rc = decode_update_component_resp(
2341         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
2342         &compCompatibilityResp, &compCompatibilityRespCode,
2343         &updateOptionFlagsEnabled, nullptr);
2344     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2345 
2346     rc = decode_update_component_resp(
2347         responseMsg1, 0, &completionCode, &compCompatibilityResp,
2348         &compCompatibilityRespCode, &updateOptionFlagsEnabled,
2349         &timeBeforeReqFWData);
2350     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2351 
2352     rc = decode_update_component_resp(
2353         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
2354         &compCompatibilityResp, &compCompatibilityRespCode,
2355         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
2356     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2357 
2358     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
2359         updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
2360                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
2361     auto responseMsg2 =
2362         reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
2363     rc = decode_update_component_resp(
2364         responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
2365         &compCompatibilityResp, &compCompatibilityRespCode,
2366         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
2367     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2368 
2369     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
2370         updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
2371                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
2372     auto responseMsg3 =
2373         reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
2374     rc = decode_update_component_resp(
2375         responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
2376         &compCompatibilityResp, &compCompatibilityRespCode,
2377         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
2378     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2379 
2380     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
2381         updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
2382                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
2383     auto responseMsg4 =
2384         reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
2385     rc = decode_update_component_resp(
2386         responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
2387         &compCompatibilityResp, &compCompatibilityRespCode,
2388         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
2389     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2390 }
2391 
2392 TEST(RequestFirmwareData, goodPathDecodeRequest)
2393 {
2394     constexpr uint32_t offset = 300;
2395     constexpr uint32_t length = 255;
2396     constexpr std::array<uint8_t,
2397                          hdrSize + sizeof(pldm_request_firmware_data_req)>
2398         reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
2399                      0x00, 0xff, 0x00, 0x00, 0x00};
2400     auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
2401 
2402     uint32_t outOffset = 0;
2403     uint32_t outLength = 0;
2404     auto rc = decode_request_firmware_data_req(
2405         requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
2406         &outLength);
2407 
2408     EXPECT_EQ(rc, PLDM_SUCCESS);
2409     EXPECT_EQ(outOffset, offset);
2410     EXPECT_EQ(outLength, length);
2411 }
2412 
2413 TEST(RequestFirmwareData, errorPathDecodeRequest)
2414 {
2415     constexpr std::array<uint8_t,
2416                          hdrSize + sizeof(pldm_request_firmware_data_req)>
2417         reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
2418                      0x00, 0x1f, 0x00, 0x00, 0x00};
2419     auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
2420 
2421     uint32_t outOffset = 0;
2422     uint32_t outLength = 0;
2423     auto rc = decode_request_firmware_data_req(
2424         nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
2425         &outLength);
2426     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2427 
2428     rc = decode_request_firmware_data_req(
2429         requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
2430         &outLength);
2431     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2432 
2433     rc = decode_request_firmware_data_req(
2434         requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
2435         nullptr);
2436     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2437 
2438     rc = decode_request_firmware_data_req(
2439         requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
2440         &outLength);
2441     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2442 
2443     rc = decode_request_firmware_data_req(
2444         requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
2445         &outLength);
2446     EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
2447 }
2448 
2449 TEST(RequestFirmwareData, goodPathEncodeResponse)
2450 {
2451     constexpr uint8_t instanceId = 3;
2452     constexpr uint8_t completionCode = PLDM_SUCCESS;
2453     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
2454                                       PLDM_FWUP_BASELINE_TRANSFER_SIZE>
2455         outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
2456                               0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
2457                               0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
2458                               0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
2459                               0x1d, 0x1e, 0x1f, 0x20};
2460     std::array<uint8_t, hdrSize + sizeof(completionCode) +
2461                             PLDM_FWUP_BASELINE_TRANSFER_SIZE>
2462         reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
2463                            0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
2464                            0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
2465                            0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
2466                            0x1d, 0x1e, 0x1f, 0x20};
2467     auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
2468     auto rc = encode_request_firmware_data_resp(
2469         instanceId, completionCode, responseMsg1,
2470         sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
2471     EXPECT_EQ(rc, PLDM_SUCCESS);
2472     EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
2473 
2474     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
2475         outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
2476     std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
2477         0x00, 0x00, 0x00, 0x00};
2478     auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
2479     rc = encode_request_firmware_data_resp(
2480         instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
2481         sizeof(completionCode));
2482     EXPECT_EQ(rc, PLDM_SUCCESS);
2483     EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
2484 }
2485 
2486 TEST(RequestFirmwareData, errorPathEncodeResponse)
2487 {
2488     std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
2489     auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
2490     auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
2491     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2492 
2493     rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
2494     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2495 }
2496 
2497 TEST(TransferComplete, goodPathDecodeRequest)
2498 {
2499     constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
2500     constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
2501         transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
2502     auto requestMsg1 =
2503         reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
2504     uint8_t outTransferResult = 0;
2505 
2506     auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
2507                                            &outTransferResult);
2508     EXPECT_EQ(rc, PLDM_SUCCESS);
2509     EXPECT_EQ(outTransferResult, transferResult);
2510 
2511     constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
2512         transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
2513     auto requestMsg2 =
2514         reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
2515     rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
2516                                       &outTransferResult);
2517     EXPECT_EQ(rc, PLDM_SUCCESS);
2518     EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
2519 }
2520 
2521 TEST(TransferComplete, errorPathDecodeRequest)
2522 {
2523     constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
2524                                                                0x00};
2525     auto requestMsg =
2526         reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
2527     uint8_t outTransferResult = 0;
2528 
2529     auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
2530     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2531 
2532     rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
2533     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2534 
2535     rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
2536     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2537 }
2538 
2539 TEST(TransferComplete, goodPathEncodeResponse)
2540 {
2541     constexpr uint8_t instanceId = 4;
2542     constexpr uint8_t completionCode = PLDM_SUCCESS;
2543     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
2544         outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
2545     std::array<uint8_t, hdrSize + sizeof(completionCode)>
2546         transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
2547     auto responseMsg1 =
2548         reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
2549     auto rc = encode_transfer_complete_resp(
2550         instanceId, completionCode, responseMsg1, sizeof(completionCode));
2551     EXPECT_EQ(rc, PLDM_SUCCESS);
2552     EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
2553 
2554     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
2555         outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
2556     std::array<uint8_t, hdrSize + sizeof(completionCode)>
2557         transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
2558     auto responseMsg2 =
2559         reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
2560     rc = encode_transfer_complete_resp(instanceId,
2561                                        PLDM_FWUP_COMMAND_NOT_EXPECTED,
2562                                        responseMsg2, sizeof(completionCode));
2563     EXPECT_EQ(rc, PLDM_SUCCESS);
2564     EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
2565 }
2566 
2567 TEST(TransferComplete, errorPathEncodeResponse)
2568 {
2569     std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
2570     auto responseMsg =
2571         reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
2572     auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
2573     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2574 
2575     rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
2576     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2577 }
2578 
2579 TEST(VerifyComplete, goodPathDecodeRequest)
2580 {
2581     constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
2582     constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
2583         verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
2584     auto requestMsg1 =
2585         reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
2586     uint8_t outVerifyResult = 0;
2587 
2588     auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
2589                                          &outVerifyResult);
2590     EXPECT_EQ(rc, PLDM_SUCCESS);
2591     EXPECT_EQ(outVerifyResult, verifyResult);
2592 
2593     constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
2594         verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
2595     auto requestMsg2 =
2596         reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
2597     rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
2598                                     &outVerifyResult);
2599     EXPECT_EQ(rc, PLDM_SUCCESS);
2600     EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
2601 }
2602 
2603 TEST(VerifyComplete, errorPathDecodeRequest)
2604 {
2605     constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
2606     auto requestMsg =
2607         reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
2608     uint8_t outVerifyResult = 0;
2609 
2610     auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
2611     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2612 
2613     rc = decode_verify_complete_req(requestMsg, 0, nullptr);
2614     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2615 
2616     rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);
2617     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2618 }
2619 
2620 TEST(VerifyComplete, goodPathEncodeResponse)
2621 {
2622     constexpr uint8_t instanceId = 5;
2623     constexpr uint8_t completionCode = PLDM_SUCCESS;
2624     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
2625         outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};
2626     std::array<uint8_t, hdrSize + sizeof(completionCode)>
2627         verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
2628     auto responseMsg1 =
2629         reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());
2630     auto rc = encode_verify_complete_resp(instanceId, completionCode,
2631                                           responseMsg1, sizeof(completionCode));
2632     EXPECT_EQ(rc, PLDM_SUCCESS);
2633     EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);
2634 
2635     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
2636         outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88};
2637     std::array<uint8_t, hdrSize + sizeof(completionCode)>
2638         verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
2639     auto responseMsg2 =
2640         reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());
2641     rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
2642                                      responseMsg2, sizeof(completionCode));
2643     EXPECT_EQ(rc, PLDM_SUCCESS);
2644     EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);
2645 }
2646 
2647 TEST(VerifyComplete, errorPathEncodeResponse)
2648 {
2649     std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00};
2650     auto responseMsg =
2651         reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());
2652     auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
2653     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2654 
2655     rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
2656     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2657 }
2658 
2659 TEST(ApplyComplete, goodPathDecodeRequest)
2660 {
2661     constexpr uint8_t applyResult1 =
2662         PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
2663     // DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
2664     constexpr std::bitset<16> compActivationModification1{0x30};
2665     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
2666         applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
2667     auto requestMsg1 =
2668         reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
2669     uint8_t outApplyResult = 0;
2670     bitfield16_t outCompActivationModification{};
2671     auto rc = decode_apply_complete_req(
2672         requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
2673         &outCompActivationModification);
2674     EXPECT_EQ(rc, PLDM_SUCCESS);
2675     EXPECT_EQ(outApplyResult, applyResult1);
2676     EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
2677 
2678     constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
2679     constexpr std::bitset<16> compActivationModification2{};
2680     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
2681         applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2682     auto requestMsg2 =
2683         reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
2684     rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
2685                                    &outApplyResult,
2686                                    &outCompActivationModification);
2687     EXPECT_EQ(rc, PLDM_SUCCESS);
2688     EXPECT_EQ(outApplyResult, applyResult2);
2689     EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
2690 }
2691 
2692 TEST(ApplyComplete, errorPathDecodeRequest)
2693 {
2694     constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
2695     auto requestMsg1 =
2696         reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
2697     uint8_t outApplyResult = 0;
2698     bitfield16_t outCompActivationModification{};
2699 
2700     auto rc = decode_apply_complete_req(
2701         nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
2702         &outCompActivationModification);
2703     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2704 
2705     rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
2706                                    nullptr, &outCompActivationModification);
2707     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2708 
2709     rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
2710                                    &outApplyResult, nullptr);
2711     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2712 
2713     rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
2714                                    &outCompActivationModification);
2715     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2716 
2717     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
2718         applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
2719     auto requestMsg2 =
2720         reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
2721     rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
2722                                    &outApplyResult,
2723                                    &outCompActivationModification);
2724     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2725 }
2726 
2727 TEST(ApplyComplete, goodPathEncodeResponse)
2728 {
2729     constexpr uint8_t instanceId = 6;
2730     constexpr uint8_t completionCode = PLDM_SUCCESS;
2731     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
2732         outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
2733     std::array<uint8_t, hdrSize + sizeof(completionCode)>
2734         applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
2735     auto responseMsg1 =
2736         reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
2737     auto rc = encode_apply_complete_resp(instanceId, completionCode,
2738                                          responseMsg1, sizeof(completionCode));
2739     EXPECT_EQ(rc, PLDM_SUCCESS);
2740     EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
2741 
2742     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
2743         outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
2744     std::array<uint8_t, hdrSize + sizeof(completionCode)>
2745         applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
2746     auto responseMsg2 =
2747         reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
2748     rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
2749                                     responseMsg2, sizeof(completionCode));
2750     EXPECT_EQ(rc, PLDM_SUCCESS);
2751     EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
2752 }
2753 
2754 TEST(ApplyComplete, errorPathEncodeResponse)
2755 {
2756     std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
2757     auto responseMsg =
2758         reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
2759     auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
2760     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2761 
2762     rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
2763     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2764 }
2765 
2766 TEST(ActivateFirmware, goodPathEncodeRequest)
2767 {
2768     constexpr uint8_t instanceId = 7;
2769 
2770     std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
2771     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2772 
2773     auto rc = encode_activate_firmware_req(
2774         instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
2775         sizeof(pldm_activate_firmware_req));
2776     EXPECT_EQ(rc, PLDM_SUCCESS);
2777 
2778     std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
2779         outRequest{0x87, 0x05, 0x1a, 0x01};
2780     EXPECT_EQ(request, outRequest);
2781 }
2782 
2783 TEST(ActivateFirmware, errorPathEncodeRequest)
2784 {
2785     std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
2786     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2787 
2788     auto rc = encode_activate_firmware_req(
2789         0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
2790         sizeof(pldm_activate_firmware_req));
2791     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2792 
2793     rc = encode_activate_firmware_req(
2794         0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
2795     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2796 
2797     rc = encode_activate_firmware_req(0, 2, requestMsg,
2798                                       sizeof(pldm_activate_firmware_req));
2799     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2800 }
2801 
2802 TEST(ActivateFirmware, goodPathDecodeResponse)
2803 {
2804     constexpr uint16_t estimatedTimeForActivation100s = 100;
2805     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
2806         activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
2807     auto responseMsg1 =
2808         reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
2809 
2810     uint8_t completionCode = 0;
2811     uint16_t estimatedTimeForActivation = 0;
2812 
2813     auto rc = decode_activate_firmware_resp(
2814         responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
2815         &estimatedTimeForActivation);
2816 
2817     EXPECT_EQ(rc, PLDM_SUCCESS);
2818     EXPECT_EQ(completionCode, PLDM_SUCCESS);
2819     EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
2820 
2821     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
2822         activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
2823     auto responseMsg2 =
2824         reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data());
2825 
2826     rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
2827                                        &completionCode,
2828                                        &estimatedTimeForActivation);
2829 
2830     EXPECT_EQ(rc, PLDM_SUCCESS);
2831     EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
2832 }
2833 
2834 TEST(ActivateFirmware, errorPathDecodeResponse)
2835 {
2836     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
2837         activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2838     auto responseMsg =
2839         reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
2840 
2841     uint8_t completionCode = 0;
2842     uint16_t estimatedTimeForActivation = 0;
2843 
2844     auto rc = decode_activate_firmware_resp(
2845         nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
2846         &estimatedTimeForActivation);
2847     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2848 
2849     rc = decode_activate_firmware_resp(responseMsg,
2850                                        sizeof(pldm_activate_firmware_resp),
2851                                        nullptr, &estimatedTimeForActivation);
2852     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2853 
2854     rc = decode_activate_firmware_resp(responseMsg,
2855                                        sizeof(pldm_activate_firmware_resp),
2856                                        &completionCode, nullptr);
2857     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2858 
2859     rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
2860                                        &estimatedTimeForActivation);
2861     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2862 
2863     rc = decode_activate_firmware_resp(
2864         responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
2865         &estimatedTimeForActivation);
2866     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2867 }
2868 
2869 TEST(GetStatus, goodPathEncodeRequest)
2870 {
2871     constexpr uint8_t instanceId = 8;
2872     std::array<uint8_t, hdrSize> request{};
2873     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2874 
2875     auto rc = encode_get_status_req(instanceId, requestMsg,
2876                                     PLDM_GET_STATUS_REQ_BYTES);
2877     EXPECT_EQ(rc, PLDM_SUCCESS);
2878 
2879     constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
2880     EXPECT_EQ(request, outRequest);
2881 }
2882 
2883 TEST(GetStatus, errorPathEncodeRequest)
2884 {
2885     std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
2886     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2887 
2888     auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
2889     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2890 
2891     rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);
2892     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2893 }
2894 
2895 TEST(GetStatus, goodPathDecodeResponse)
2896 {
2897     constexpr std::bitset<32> updateOptionFlagsEnabled1{0};
2898     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
2899         getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
2900                            0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};
2901     auto responseMsg1 =
2902         reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
2903 
2904     uint8_t completionCode = 0;
2905     uint8_t currentState = 0;
2906     uint8_t previousState = 0;
2907     uint8_t auxState = 0;
2908     uint8_t auxStateStatus = 0;
2909     uint8_t progressPercent = 0;
2910     uint8_t reasonCode = 0;
2911     bitfield32_t updateOptionFlagsEnabled{0};
2912 
2913     auto rc = decode_get_status_resp(
2914         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
2915         &currentState, &previousState, &auxState, &auxStateStatus,
2916         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
2917 
2918     EXPECT_EQ(rc, PLDM_SUCCESS);
2919     EXPECT_EQ(completionCode, PLDM_SUCCESS);
2920     EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);
2921     EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
2922     EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);
2923     EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);
2924     EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);
2925     EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
2926     EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);
2927 
2928     // Bit position 0 - Force update of component – FD will perform a force
2929     // update of the component.
2930     constexpr std::bitset<32> updateOptionFlagsEnabled2{1};
2931     constexpr uint8_t progressPercent2 = 50;
2932     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
2933         getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,
2934                            0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};
2935     auto responseMsg2 =
2936         reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
2937 
2938     rc = decode_get_status_resp(
2939         responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
2940         &currentState, &previousState, &auxState, &auxStateStatus,
2941         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
2942 
2943     EXPECT_EQ(rc, PLDM_SUCCESS);
2944     EXPECT_EQ(completionCode, PLDM_SUCCESS);
2945     EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);
2946     EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
2947     EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);
2948     EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);
2949     EXPECT_EQ(progressPercent, progressPercent2);
2950     EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
2951     EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);
2952 
2953     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
2954         getStatusResponse3{0x00, 0x00, 0x00, 0x04};
2955     auto responseMsg3 =
2956         reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
2957     rc = decode_get_status_resp(
2958         responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
2959         &currentState, &previousState, &auxState, &auxStateStatus,
2960         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
2961     EXPECT_EQ(rc, PLDM_SUCCESS);
2962     EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);
2963 }
2964 
2965 TEST(GetStatus, errorPathDecodeResponse)
2966 {
2967     uint8_t completionCode = 0;
2968     uint8_t currentState = 0;
2969     uint8_t previousState = 0;
2970     uint8_t auxState = 0;
2971     uint8_t auxStateStatus = 0;
2972     uint8_t progressPercent = 0;
2973     uint8_t reasonCode = 0;
2974     bitfield32_t updateOptionFlagsEnabled{0};
2975 
2976     constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};
2977     auto responseMsg1 =
2978         reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
2979 
2980     auto rc = decode_get_status_resp(
2981         nullptr, getStatusResponse1.size() - hdrSize, &completionCode,
2982         &currentState, &previousState, &auxState, &auxStateStatus,
2983         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
2984     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2985 
2986     rc = decode_get_status_resp(
2987         responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,
2988         &currentState, &previousState, &auxState, &auxStateStatus,
2989         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
2990     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2991 
2992     rc = decode_get_status_resp(
2993         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
2994         nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,
2995         &reasonCode, &updateOptionFlagsEnabled);
2996     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2997 
2998     rc = decode_get_status_resp(
2999         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3000         &currentState, nullptr, &auxState, &auxStateStatus, &progressPercent,
3001         &reasonCode, &updateOptionFlagsEnabled);
3002     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3003 
3004     rc = decode_get_status_resp(
3005         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3006         &currentState, &previousState, nullptr, &auxStateStatus,
3007         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3008     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3009 
3010     rc = decode_get_status_resp(
3011         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3012         &currentState, &previousState, &auxState, nullptr, &progressPercent,
3013         &reasonCode, &updateOptionFlagsEnabled);
3014     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3015 
3016     rc = decode_get_status_resp(
3017         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3018         &currentState, &previousState, &auxState, &auxStateStatus, nullptr,
3019         &reasonCode, &updateOptionFlagsEnabled);
3020     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3021 
3022     rc = decode_get_status_resp(
3023         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3024         &currentState, &previousState, &auxState, &auxStateStatus,
3025         &progressPercent, nullptr, &updateOptionFlagsEnabled);
3026     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3027 
3028     rc = decode_get_status_resp(
3029         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3030         &currentState, &previousState, &auxState, &auxStateStatus,
3031         &progressPercent, &reasonCode, nullptr);
3032     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3033 
3034     rc = decode_get_status_resp(
3035         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3036         &currentState, &previousState, &auxState, &auxStateStatus,
3037         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3038     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3039 
3040     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>
3041         getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3042                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3043     auto responseMsg2 =
3044         reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
3045     rc = decode_get_status_resp(
3046         responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
3047         &currentState, &previousState, &auxState, &auxStateStatus,
3048         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3049     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3050 
3051     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3052         getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
3053                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3054     auto responseMsg3 =
3055         reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
3056     rc = decode_get_status_resp(
3057         responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
3058         &currentState, &previousState, &auxState, &auxStateStatus,
3059         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3060     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3061 
3062     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3063         getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
3064                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3065     auto responseMsg4 =
3066         reinterpret_cast<const pldm_msg*>(getStatusResponse4.data());
3067     rc = decode_get_status_resp(
3068         responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,
3069         &currentState, &previousState, &auxState, &auxStateStatus,
3070         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3071     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3072 
3073     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3074         getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
3075                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3076     auto responseMsg5 =
3077         reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());
3078     rc = decode_get_status_resp(
3079         responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,
3080         &currentState, &previousState, &auxState, &auxStateStatus,
3081         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3082     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3083 
3084     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3085         getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3086                            0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3087     auto responseMsg6 =
3088         reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());
3089     rc = decode_get_status_resp(
3090         responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,
3091         &currentState, &previousState, &auxState, &auxStateStatus,
3092         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3093     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3094 
3095     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3096         getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3097                            0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
3098     auto responseMsg7 =
3099         reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());
3100     rc = decode_get_status_resp(
3101         responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,
3102         &currentState, &previousState, &auxState, &auxStateStatus,
3103         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3104     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3105 
3106     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3107         getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3108                            0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00};
3109     auto responseMsg8 =
3110         reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());
3111     rc = decode_get_status_resp(
3112         responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,
3113         &currentState, &previousState, &auxState, &auxStateStatus,
3114         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3115     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3116 
3117     // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is
3118     // IDLE
3119     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3120         getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
3121                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3122     auto responseMsg9 =
3123         reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());
3124     rc = decode_get_status_resp(
3125         responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,
3126         &currentState, &previousState, &auxState, &auxStateStatus,
3127         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3128     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3129 }
3130 
3131 TEST(CancelUpdateComponent, goodPathEncodeRequest)
3132 {
3133     constexpr uint8_t instanceId = 9;
3134     std::array<uint8_t, hdrSize> request{};
3135     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3136 
3137     auto rc = encode_cancel_update_component_req(
3138         instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
3139     EXPECT_EQ(rc, PLDM_SUCCESS);
3140 
3141     constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
3142     EXPECT_EQ(request, outRequest);
3143 }
3144 
3145 TEST(CancelUpdateComponent, errorPathEncodeRequest)
3146 {
3147     std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
3148     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3149 
3150     auto rc = encode_cancel_update_component_req(
3151         0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
3152     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3153 
3154     rc = encode_cancel_update_component_req(
3155         0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);
3156     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3157 }
3158 
3159 TEST(CancelUpdateComponent, testGoodDecodeResponse)
3160 {
3161     uint8_t completionCode = 0;
3162     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3163         cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};
3164     auto responseMsg1 = reinterpret_cast<const pldm_msg*>(
3165         cancelUpdateComponentResponse1.data());
3166     auto rc = decode_cancel_update_component_resp(
3167         responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,
3168         &completionCode);
3169     EXPECT_EQ(rc, PLDM_SUCCESS);
3170     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3171 
3172     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3173         cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};
3174     auto responseMsg2 = reinterpret_cast<const pldm_msg*>(
3175         cancelUpdateComponentResponse2.data());
3176     rc = decode_cancel_update_component_resp(
3177         responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,
3178         &completionCode);
3179     EXPECT_EQ(rc, PLDM_SUCCESS);
3180     EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
3181 }
3182 
3183 TEST(CancelUpdateComponent, testBadDecodeResponse)
3184 {
3185     uint8_t completionCode = 0;
3186     constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{
3187         0x00, 0x00, 0x00};
3188     auto responseMsg =
3189         reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data());
3190 
3191     auto rc = decode_cancel_update_component_resp(
3192         nullptr, cancelUpdateComponentResponse.size() - hdrSize,
3193         &completionCode);
3194     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3195 
3196     rc = decode_cancel_update_component_resp(
3197         responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);
3198     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3199 
3200     rc = decode_cancel_update_component_resp(
3201         responseMsg, cancelUpdateComponentResponse.size() - hdrSize,
3202         &completionCode);
3203     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3204 }
3205 
3206 TEST(CancelUpdate, goodPathEncodeRequest)
3207 {
3208     constexpr uint8_t instanceId = 10;
3209     std::array<uint8_t, hdrSize> request{};
3210     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3211 
3212     auto rc = encode_cancel_update_req(instanceId, requestMsg,
3213                                        PLDM_CANCEL_UPDATE_REQ_BYTES);
3214     EXPECT_EQ(rc, PLDM_SUCCESS);
3215 
3216     constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
3217     EXPECT_EQ(request, outRequest);
3218 }
3219 
3220 TEST(CancelUpdate, errorPathEncodeRequest)
3221 {
3222     std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
3223     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3224 
3225     auto rc =
3226         encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
3227     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3228 
3229     rc = encode_cancel_update_req(0, requestMsg,
3230                                   PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
3231     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3232 }
3233 
3234 TEST(CancelUpdate, goodPathDecodeResponse)
3235 {
3236     constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
3237     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
3238         cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3239                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3240     auto responseMsg1 =
3241         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
3242     uint8_t completionCode = 0;
3243     bool8_t nonFunctioningComponentIndication = 0;
3244     bitfield64_t nonFunctioningComponentBitmap{0};
3245     auto rc = decode_cancel_update_resp(
3246         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
3247         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
3248     EXPECT_EQ(rc, PLDM_SUCCESS);
3249     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3250     EXPECT_EQ(nonFunctioningComponentIndication,
3251               PLDM_FWUP_COMPONENTS_FUNCTIONING);
3252     EXPECT_EQ(nonFunctioningComponentBitmap.value,
3253               nonFunctioningComponentBitmap1);
3254 
3255     constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
3256     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
3257         cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
3258                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3259     auto responseMsg2 =
3260         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
3261     rc = decode_cancel_update_resp(
3262         responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
3263         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
3264     EXPECT_EQ(rc, PLDM_SUCCESS);
3265     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3266     EXPECT_EQ(nonFunctioningComponentIndication,
3267               PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING);
3268     EXPECT_EQ(nonFunctioningComponentBitmap.value,
3269               nonFunctioningComponentBitmap2);
3270 
3271     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3272         cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
3273     auto responseMsg3 =
3274         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
3275     rc = decode_cancel_update_resp(
3276         responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
3277         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
3278     EXPECT_EQ(rc, PLDM_SUCCESS);
3279     EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
3280 }
3281 
3282 TEST(CancelUpdate, errorPathDecodeResponse)
3283 {
3284     constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
3285                                                                  0x00};
3286     auto responseMsg1 =
3287         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
3288     uint8_t completionCode = 0;
3289     bool8_t nonFunctioningComponentIndication = 0;
3290     bitfield64_t nonFunctioningComponentBitmap{0};
3291 
3292     auto rc = decode_cancel_update_resp(
3293         nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
3294         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
3295     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3296 
3297     rc = decode_cancel_update_resp(
3298         responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
3299         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
3300     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3301 
3302     rc = decode_cancel_update_resp(
3303         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
3304         nullptr, &nonFunctioningComponentBitmap);
3305     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3306 
3307     rc = decode_cancel_update_resp(
3308         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
3309         &nonFunctioningComponentIndication, nullptr);
3310     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3311 
3312     rc = decode_cancel_update_resp(
3313         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
3314         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
3315     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3316 
3317     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3318         cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
3319     auto responseMsg2 =
3320         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
3321     rc = decode_cancel_update_resp(
3322         responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
3323         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
3324     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3325 
3326     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
3327         cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
3328                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3329     auto responseMsg3 =
3330         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
3331     rc = decode_cancel_update_resp(
3332         responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
3333         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
3334     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3335 }
3336