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