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