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