xref: /openbmc/libpldm/tests/dsp/firmware_update.cpp (revision 6a97b79ebcfe4d91f8150d62b61e1a2fb2ac3a12)
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, 0);
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, -EINVAL);
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, 0);
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, -EINVAL);
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, -EBADMSG);
1467 }
1468 #endif
1469 
1470 #ifdef LIBPLDM_API_TESTING
1471 TEST(QueryDownstreamIdentifiers, goodPathEncodeRequest)
1472 {
1473     constexpr uint8_t instanceId = 1;
1474     constexpr size_t payloadLen = PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1475     PLDM_MSG_DEFINE_P(request, payloadLen);
1476     constexpr pldm_query_downstream_identifiers_req params_req{
1477         0xFFFFFFFF, PLDM_GET_FIRSTPART};
1478 
1479     auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1480                                                       request, payloadLen);
1481     ASSERT_EQ(rc, 0);
1482     EXPECT_THAT(std::span<uint8_t>(request_buf, sizeof(request_buf)),
1483                 ElementsAreArray<uint8_t>(
1484                     {0x81, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x01}));
1485 }
1486 #endif
1487 
1488 #ifdef LIBPLDM_API_TESTING
1489 TEST(QueryDownstreamIdentifiers, encodeRequestInvalidErrorPaths)
1490 {
1491     constexpr uint8_t instanceId = 1;
1492     constexpr pldm_query_downstream_identifiers_req params_req{
1493         0xFFFFFFFF, PLDM_GET_FIRSTPART};
1494     constexpr pldm_query_downstream_identifiers_req params_req_invalid{
1495         0xFFFFFFFF, PLDM_ACKNOWLEDGEMENT_ONLY};
1496     constexpr size_t payload_length =
1497         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1498     std::array<uint8_t, hdrSize + payload_length> requestMsg{};
1499     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1500     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1501 
1502     auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1503                                                       nullptr, payload_length);
1504     EXPECT_EQ(rc, -EINVAL);
1505 
1506     rc = encode_query_downstream_identifiers_req(
1507         instanceId, &params_req, requestPtr, payload_length - 1);
1508     EXPECT_EQ(rc, -EOVERFLOW);
1509 
1510     rc = encode_query_downstream_identifiers_req(
1511         instanceId, &params_req_invalid, requestPtr, payload_length);
1512     EXPECT_EQ(rc, -EINVAL);
1513 }
1514 #endif
1515 
1516 #ifdef LIBPLDM_API_TESTING
1517 TEST(QueryDownstreamIdentifiers, decodeResponseNoDevices)
1518 {
1519     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1520     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1521     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1522     constexpr uint32_t downstream_devices_length_resp = 0;
1523     constexpr uint16_t number_of_downstream_devices_resp = 0;
1524 
1525     PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1526     struct pldm_query_downstream_identifiers_resp resp_data = {};
1527     struct pldm_downstream_device_iter devs;
1528     struct pldm_msgbuf _buf;
1529     struct pldm_msgbuf* buf = &_buf;
1530     int rc = 0;
1531 
1532     rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1533                                 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1534     ASSERT_EQ(rc, 0);
1535 
1536     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1537     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1538     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1539     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1540     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1541 
1542     ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1543 
1544     rc = decode_query_downstream_identifiers_resp(
1545         response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp_data,
1546         &devs);
1547 
1548     ASSERT_EQ(rc, 0);
1549     EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1550     EXPECT_EQ(resp_data.next_data_transfer_handle,
1551               next_data_transfer_handle_resp);
1552     EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1553     EXPECT_EQ(resp_data.downstream_devices_length,
1554               downstream_devices_length_resp);
1555     EXPECT_EQ(resp_data.number_of_downstream_devices,
1556               number_of_downstream_devices_resp);
1557 }
1558 #endif
1559 
1560 #ifdef LIBPLDM_API_TESTING
1561 TEST(QueryDownstreamIdentifiers, decodeResponseNoDevicesBadCount)
1562 {
1563     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1564     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1565     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1566     constexpr uint32_t downstream_devices_length_resp = 0;
1567     constexpr uint16_t number_of_downstream_devices_resp = 1;
1568 
1569     PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1570     struct pldm_query_downstream_identifiers_resp resp = {};
1571     struct pldm_downstream_device_iter devs;
1572     struct pldm_downstream_device dev;
1573     struct pldm_msgbuf _buf;
1574     struct pldm_msgbuf* buf = &_buf;
1575     int rc = 0;
1576 
1577     rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1578                                 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1579     ASSERT_EQ(rc, 0);
1580 
1581     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1582     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1583     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1584     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1585     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1586 
1587     ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1588 
1589     rc = decode_query_downstream_identifiers_resp(
1590         response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp, &devs);
1591     ASSERT_EQ(rc, 0);
1592 
1593     foreach_pldm_downstream_device(devs, dev, rc)
1594     {
1595         ASSERT_TRUE(false);
1596     }
1597     ASSERT_NE(rc, 0);
1598 }
1599 #endif
1600 
1601 #ifdef LIBPLDM_API_TESTING
1602 TEST(QueryDownstreamIdentifiers, decodeResponseOneDeviceOneDescriptor)
1603 {
1604     constexpr uint32_t downstreamDevicesLen = 11;
1605     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1606     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1607     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1608     const uint32_t downstream_devices_length_resp =
1609         htole32(downstreamDevicesLen);
1610     constexpr uint16_t number_of_downstream_devices_resp = 1;
1611     constexpr size_t payloadLen =
1612         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstreamDevicesLen;
1613 
1614     struct pldm_query_downstream_identifiers_resp resp_data = {};
1615     PLDM_MSG_DEFINE_P(response, payloadLen);
1616     struct pldm_downstream_device_iter devs;
1617     struct pldm_downstream_device dev;
1618     struct pldm_msgbuf _buf;
1619     struct pldm_msgbuf* buf = &_buf;
1620     int rc = 0;
1621 
1622     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1623     ASSERT_EQ(rc, 0);
1624 
1625     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1626     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1627     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1628     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1629     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1630 
1631     /* Downstream device */
1632     pldm_msgbuf_insert_uint16(buf, 1);
1633     pldm_msgbuf_insert_uint8(buf, 1);
1634 
1635     /* Device descriptor */
1636     pldm_msgbuf_insert_uint16(buf, 1);
1637     pldm_msgbuf_insert_uint16(buf, 4);
1638     pldm_msgbuf_insert_uint32(buf, 412);
1639 
1640     ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1641 
1642     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1643                                                   &resp_data, &devs);
1644 
1645     ASSERT_EQ(rc, 0);
1646     EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1647     EXPECT_EQ(resp_data.next_data_transfer_handle,
1648               next_data_transfer_handle_resp);
1649     EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1650     EXPECT_EQ(resp_data.downstream_devices_length,
1651               downstream_devices_length_resp);
1652     EXPECT_EQ(resp_data.number_of_downstream_devices,
1653               number_of_downstream_devices_resp);
1654 
1655     foreach_pldm_downstream_device(devs, dev, rc)
1656     {
1657         struct pldm_descriptor desc;
1658 
1659         EXPECT_EQ(dev.downstream_device_index, 1);
1660         EXPECT_EQ(dev.downstream_descriptor_count, 1);
1661 
1662         foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1663         {
1664             static const uint32_t dmtf = htole32(412);
1665             EXPECT_EQ(desc.descriptor_type, 1);
1666             EXPECT_EQ(desc.descriptor_length, 4);
1667             EXPECT_EQ(memcmp(desc.descriptor_data, &dmtf, sizeof(dmtf)), 0);
1668         }
1669         ASSERT_EQ(rc, 0);
1670     }
1671     ASSERT_EQ(rc, 0);
1672 }
1673 #endif
1674 
1675 #ifdef LIBPLDM_API_TESTING
1676 constexpr const uint16_t descriptor_id_type_iana_pen = 0x1;
1677 constexpr const uint16_t descriptor_id_len_iana_pen = 0x4;
1678 const uint32_t iana_pen_openbmc = htole16(49871u);
1679 const uint32_t iana_pen_dmtf = htole16(412u);
1680 #endif
1681 
1682 #ifdef LIBPLDM_API_TESTING
1683 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneDescriptorEach)
1684 {
1685     constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1686         {0, 1},
1687         {1, 1},
1688     }};
1689 
1690     constexpr const std::array<pldm_descriptor, 2> expected_descriptors = {{
1691         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1692          &iana_pen_dmtf},
1693         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1694          &iana_pen_openbmc},
1695     }};
1696 
1697     constexpr uint32_t downstream_devices_len = 22;
1698     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1699     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1700     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1701     const uint32_t downstream_devices_length_resp =
1702         htole32(downstream_devices_len);
1703     constexpr uint16_t number_of_downstream_devices_resp = 2;
1704     constexpr size_t payloadLen =
1705         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
1706 
1707     struct pldm_query_downstream_identifiers_resp resp_data
1708     {
1709     };
1710     PLDM_MSG_DEFINE_P(response, payloadLen);
1711     struct pldm_downstream_device_iter devs;
1712     struct pldm_downstream_device dev;
1713     struct pldm_msgbuf _buf;
1714     struct pldm_msgbuf* buf = &_buf;
1715     int rc = 0;
1716 
1717     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1718     ASSERT_EQ(rc, 0);
1719 
1720     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1721     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1722     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1723     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1724     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1725 
1726     /* Downstream device */
1727     pldm_msgbuf_insert_uint16(buf, 0);
1728     pldm_msgbuf_insert_uint8(buf, 1);
1729 
1730     /* Device descriptor */
1731     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1732     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1733     pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1734 
1735     /* Downstream device */
1736     pldm_msgbuf_insert_uint16(buf, 1);
1737     pldm_msgbuf_insert_uint8(buf, 1);
1738 
1739     /* Device descriptor */
1740     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1741     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1742     pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
1743 
1744     ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1745 
1746     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1747                                                   &resp_data, &devs);
1748 
1749     ASSERT_EQ(rc, 0);
1750     EXPECT_EQ(resp_data.number_of_downstream_devices,
1751               number_of_downstream_devices_resp);
1752 
1753     size_t devIndex = 0;
1754     size_t descIndex = 0;
1755     foreach_pldm_downstream_device(devs, dev, rc)
1756     {
1757         struct pldm_descriptor desc;
1758 
1759         ASSERT_LT(devIndex, expected_devices.size());
1760 
1761         const struct pldm_downstream_device* expectedDev =
1762             &expected_devices[devIndex];
1763 
1764         EXPECT_EQ(dev.downstream_device_index,
1765                   expectedDev->downstream_device_index);
1766         EXPECT_EQ(dev.downstream_descriptor_count,
1767                   expectedDev->downstream_descriptor_count);
1768 
1769         foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1770         {
1771             ASSERT_LT(descIndex, expected_descriptors.size());
1772 
1773             const struct pldm_descriptor* expectedDesc =
1774                 &expected_descriptors[descIndex];
1775 
1776             EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
1777             ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
1778             EXPECT_EQ(memcmp(desc.descriptor_data,
1779                              expectedDesc->descriptor_data,
1780                              expectedDesc->descriptor_length),
1781                       0);
1782 
1783             descIndex++;
1784         }
1785         ASSERT_EQ(rc, 0);
1786         EXPECT_EQ(descIndex, 1 * devIndex + 1);
1787 
1788         devIndex++;
1789     }
1790     ASSERT_EQ(rc, 0);
1791     EXPECT_EQ(devIndex, 2);
1792 }
1793 #endif
1794 
1795 #ifdef LIBPLDM_API_TESTING
1796 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesTwoOneDescriptors)
1797 {
1798     constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1799         {0, 2},
1800         {1, 1},
1801     }};
1802 
1803     constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
1804         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1805          &iana_pen_dmtf},
1806         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1807          &iana_pen_openbmc},
1808         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1809          &iana_pen_dmtf},
1810     }};
1811 
1812     constexpr uint32_t downstream_devices_len = 30;
1813     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1814     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1815     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1816     const uint32_t downstream_devices_length_resp =
1817         htole32(downstream_devices_len);
1818     constexpr uint16_t number_of_downstream_devices_resp = 2;
1819     constexpr size_t payloadLen =
1820         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
1821 
1822     struct pldm_query_downstream_identifiers_resp resp_data
1823     {
1824     };
1825     PLDM_MSG_DEFINE_P(response, payloadLen);
1826     struct pldm_downstream_device_iter devs;
1827     struct pldm_downstream_device dev;
1828     struct pldm_msgbuf _buf;
1829     struct pldm_msgbuf* buf = &_buf;
1830     int rc = 0;
1831 
1832     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1833     ASSERT_EQ(rc, 0);
1834 
1835     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1836     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1837     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1838     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1839     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1840 
1841     /* Downstream device */
1842     pldm_msgbuf_insert_uint16(buf, 0);
1843     pldm_msgbuf_insert_uint8(buf, 2);
1844 
1845     /* Device descriptor */
1846     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1847     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1848     pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1849 
1850     /* Device descriptor */
1851     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1852     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1853     pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
1854 
1855     /* Downstream device */
1856     pldm_msgbuf_insert_uint16(buf, 1);
1857     pldm_msgbuf_insert_uint8(buf, 1);
1858 
1859     /* Device descriptor */
1860     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1861     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1862     pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1863 
1864     ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1865 
1866     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1867                                                   &resp_data, &devs);
1868 
1869     ASSERT_EQ(rc, 0);
1870     EXPECT_EQ(resp_data.number_of_downstream_devices,
1871               number_of_downstream_devices_resp);
1872 
1873     size_t devIndex = 0;
1874     size_t descIndex = 0;
1875     foreach_pldm_downstream_device(devs, dev, rc)
1876     {
1877         struct pldm_descriptor desc;
1878 
1879         ASSERT_LT(devIndex, expected_devices.size());
1880 
1881         const struct pldm_downstream_device* expectedDev =
1882             &expected_devices[devIndex];
1883 
1884         EXPECT_EQ(dev.downstream_device_index,
1885                   expectedDev->downstream_device_index);
1886         EXPECT_EQ(dev.downstream_descriptor_count,
1887                   expectedDev->downstream_descriptor_count);
1888 
1889         foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1890         {
1891             ASSERT_LT(descIndex, expected_descriptors.size());
1892 
1893             const struct pldm_descriptor* expectedDesc =
1894                 &expected_descriptors[descIndex];
1895 
1896             EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
1897             ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
1898             EXPECT_EQ(memcmp(desc.descriptor_data,
1899                              expectedDesc->descriptor_data,
1900                              expectedDesc->descriptor_length),
1901                       0);
1902 
1903             descIndex++;
1904         }
1905         ASSERT_EQ(rc, 0);
1906 
1907         devIndex++;
1908     }
1909     ASSERT_EQ(rc, 0);
1910     EXPECT_EQ(devIndex, 2);
1911     EXPECT_EQ(descIndex, 3);
1912 }
1913 #endif
1914 
1915 #ifdef LIBPLDM_API_TESTING
1916 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneTwoDescriptors)
1917 {
1918     constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1919         {0, 1},
1920         {1, 2},
1921     }};
1922 
1923     constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
1924         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1925          &iana_pen_dmtf},
1926         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1927          &iana_pen_openbmc},
1928         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1929          &iana_pen_dmtf},
1930     }};
1931 
1932     constexpr uint32_t downstream_devices_len = 30;
1933     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1934     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1935     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1936     const uint32_t downstream_devices_length_resp =
1937         htole32(downstream_devices_len);
1938     constexpr uint16_t number_of_downstream_devices_resp = 2;
1939     constexpr size_t payloadLen =
1940         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
1941 
1942     struct pldm_query_downstream_identifiers_resp resp_data
1943     {
1944     };
1945     PLDM_MSG_DEFINE_P(response, payloadLen);
1946     struct pldm_downstream_device_iter devs;
1947     struct pldm_downstream_device dev;
1948     struct pldm_msgbuf _buf;
1949     struct pldm_msgbuf* buf = &_buf;
1950     int rc = 0;
1951 
1952     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1953     ASSERT_EQ(rc, 0);
1954 
1955     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1956     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1957     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1958     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1959     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1960 
1961     /* Downstream device */
1962     pldm_msgbuf_insert_uint16(buf, 0);
1963     pldm_msgbuf_insert_uint8(buf, 1);
1964 
1965     /* Device descriptor */
1966     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1967     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1968     pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1969 
1970     /* Downstream device */
1971     pldm_msgbuf_insert_uint16(buf, 1);
1972     pldm_msgbuf_insert_uint8(buf, 2);
1973 
1974     /* Device descriptor */
1975     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1976     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1977     pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
1978 
1979     /* Device descriptor */
1980     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1981     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1982     pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1983 
1984     ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1985 
1986     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1987                                                   &resp_data, &devs);
1988 
1989     ASSERT_EQ(rc, 0);
1990     EXPECT_EQ(resp_data.number_of_downstream_devices,
1991               number_of_downstream_devices_resp);
1992 
1993     size_t devIndex = 0;
1994     size_t descIndex = 0;
1995     foreach_pldm_downstream_device(devs, dev, rc)
1996     {
1997         struct pldm_descriptor desc;
1998 
1999         ASSERT_LT(devIndex, expected_devices.size());
2000 
2001         const struct pldm_downstream_device* expectedDev =
2002             &expected_devices[devIndex];
2003 
2004         EXPECT_EQ(dev.downstream_device_index,
2005                   expectedDev->downstream_device_index);
2006         EXPECT_EQ(dev.downstream_descriptor_count,
2007                   expectedDev->downstream_descriptor_count);
2008 
2009         foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2010         {
2011             ASSERT_LT(descIndex, expected_descriptors.size());
2012 
2013             const struct pldm_descriptor* expectedDesc =
2014                 &expected_descriptors[descIndex];
2015 
2016             EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2017             ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2018             EXPECT_EQ(memcmp(desc.descriptor_data,
2019                              expectedDesc->descriptor_data,
2020                              expectedDesc->descriptor_length),
2021                       0);
2022 
2023             descIndex++;
2024         }
2025         ASSERT_EQ(rc, 0);
2026 
2027         devIndex++;
2028     }
2029     ASSERT_EQ(rc, 0);
2030     EXPECT_EQ(devIndex, 2);
2031     EXPECT_EQ(descIndex, 3);
2032 }
2033 #endif
2034 
2035 #ifdef LIBPLDM_API_TESTING
2036 TEST(QueryDownstreamIdentifiers, decodeRequestErrorPaths)
2037 {
2038     constexpr size_t payloadLen = sizeof(uint8_t);
2039 
2040     struct pldm_query_downstream_identifiers_resp resp_data = {};
2041     struct pldm_downstream_device_iter devs;
2042     PLDM_MSG_DEFINE_P(response, payloadLen);
2043 
2044     // Test nullptr
2045     auto rc = decode_query_downstream_identifiers_resp(nullptr, payloadLen,
2046                                                        nullptr, &devs);
2047     EXPECT_EQ(rc, -EINVAL);
2048 
2049     // Test not PLDM_SUCCESS completion code
2050     response->payload[0] = PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
2051     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2052                                                   &resp_data, &devs);
2053     EXPECT_EQ(rc, 0);
2054     EXPECT_EQ(resp_data.completion_code, PLDM_ERROR_UNSUPPORTED_PLDM_CMD);
2055 
2056     // Test payload length less than minimum length
2057     response->payload[0] = PLDM_SUCCESS;
2058     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2059                                                   &resp_data, &devs);
2060 
2061     EXPECT_EQ(rc, -EBADMSG);
2062 }
2063 #endif
2064 
2065 #ifdef LIBPLDM_API_TESTING
2066 TEST(QueryDownstreamIdentifiers, decodeRequestErrorDownstreamDevicesSize)
2067 {
2068     // Len is not fixed here taking it as 9, contains 1 downstream device with
2069     // 1 descriptor
2070     constexpr uint32_t actualDownstreamDevicesLen = 9;
2071     constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2072     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2073     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2074     constexpr uint16_t number_of_downstream_devices_resp = 1;
2075     constexpr size_t payloadLen =
2076         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN +
2077         actualDownstreamDevicesLen;
2078 
2079     const uint32_t downstream_devices_length_resp =
2080         htole32(actualDownstreamDevicesLen + 1 /* inject error length*/);
2081 
2082     struct pldm_query_downstream_identifiers_resp resp_data = {};
2083     struct pldm_downstream_device_iter devs;
2084     PLDM_MSG_DEFINE_P(response, payloadLen);
2085     struct pldm_msgbuf _buf;
2086     struct pldm_msgbuf* buf = &_buf;
2087     void* devicesStart = NULL;
2088     size_t devicesLen;
2089     int rc = 0;
2090 
2091     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2092     EXPECT_EQ(rc, 0);
2093 
2094     pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2095     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2096     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2097     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2098     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2099     pldm_msgbuf_span_remaining(buf, &devicesStart, &devicesLen);
2100 
2101     /** Filling descriptor data, the correctness of the downstream devices data
2102      *  is not checked in this test case so filling with 0xff
2103      */
2104     std::fill_n(static_cast<uint8_t*>(devicesStart), actualDownstreamDevicesLen,
2105                 0xff);
2106 
2107     EXPECT_NE(decode_query_downstream_identifiers_resp(response, payloadLen,
2108                                                        &resp_data, &devs),
2109               0);
2110 }
2111 #endif
2112 
2113 #ifdef LIBPLDM_API_TESTING
2114 TEST(QueryDownstreamIdentifiers, decodeRequestErrorBufSize)
2115 {
2116     constexpr uint32_t actualDownstreamDevicesLen = 0;
2117     constexpr uint16_t number_of_downstream_devices_resp = 1;
2118     constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2119     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2120     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2121     constexpr size_t payloadLen =
2122         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN - 1;
2123 
2124     const uint32_t downstream_devices_length_resp =
2125         htole32(actualDownstreamDevicesLen);
2126 
2127     struct pldm_query_downstream_identifiers_resp resp_data = {};
2128     struct pldm_downstream_device_iter devs;
2129     PLDM_MSG_DEFINE_P(response, payloadLen);
2130     struct pldm_msgbuf _buf;
2131     struct pldm_msgbuf* buf = &_buf;
2132     int rc = 0;
2133 
2134     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2135     ASSERT_EQ(rc, 0);
2136 
2137     pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2138     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2139     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2140     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2141     // Inject error buffer size
2142     pldm_msgbuf_insert_uint8(buf, (uint8_t)number_of_downstream_devices_resp);
2143 
2144     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2145                                                   &resp_data, &devs);
2146 
2147     EXPECT_EQ(rc, -EBADMSG);
2148 }
2149 #endif
2150 
2151 #ifdef LIBPLDM_API_TESTING
2152 TEST(GetDownstreamFirmwareParameters, goodPathEncodeRequest)
2153 {
2154     constexpr uint8_t instanceId = 1;
2155     constexpr pldm_get_downstream_firmware_parameters_req params_req{
2156         0x0, PLDM_GET_FIRSTPART};
2157     constexpr size_t payload_length =
2158         PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
2159     std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
2160     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2161     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2162 
2163     auto rc = encode_get_downstream_firmware_parameters_req(
2164         instanceId, &params_req, requestPtr, payload_length);
2165     EXPECT_EQ(rc, 0);
2166 
2167     std::array<uint8_t,
2168                hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES>
2169         expectedReq{0x81, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01};
2170     EXPECT_EQ(requestMsg, expectedReq);
2171 }
2172 #endif
2173 
2174 #ifdef LIBPLDM_API_TESTING
2175 TEST(GetDownstreamFirmwareParameters, encodeRequestInvalidTransferOperationFlag)
2176 {
2177     constexpr uint8_t instanceId = 1;
2178     // Setup invalid transfer operation flag
2179     constexpr pldm_get_downstream_firmware_parameters_req params_req{
2180         0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
2181     constexpr size_t payload_length =
2182         PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
2183     std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
2184     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2185     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2186 
2187     auto rc = encode_get_downstream_firmware_parameters_req(
2188         instanceId, &params_req, requestPtr, payload_length);
2189     EXPECT_EQ(rc, -EBADMSG);
2190 }
2191 #endif
2192 
2193 #ifdef LIBPLDM_API_TESTING
2194 TEST(GetDownstreamFirmwareParameters, encodeRequestErrorBufSize)
2195 {
2196     constexpr uint8_t instanceId = 1;
2197     // Setup invalid transfer operation flag
2198     constexpr pldm_get_downstream_firmware_parameters_req params_req{
2199         0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
2200     constexpr size_t payload_length =
2201         PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES -
2202         1 /* inject erro length*/;
2203 
2204     std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
2205     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2206     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2207 
2208     auto rc = encode_get_downstream_firmware_parameters_req(
2209         instanceId, &params_req, requestPtr, payload_length);
2210     EXPECT_EQ(rc, -EOVERFLOW);
2211 }
2212 #endif
2213 
2214 #ifdef LIBPLDM_API_TESTING
2215 TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponse)
2216 {
2217     /** Count is not fixed here taking it as 1, and the downstream device's
2218      *  version strings length are set to 8
2219      */
2220     constexpr uint16_t downstreamDeviceCount = 1;
2221     constexpr uint8_t activeComponentVersionStringLength = 8;
2222     constexpr uint8_t pendingComponentVersionStringLength = 8;
2223     constexpr size_t downstreamDeviceParamTableLen =
2224         sizeof(pldm_component_parameter_entry) +
2225         activeComponentVersionStringLength +
2226         pendingComponentVersionStringLength;
2227     constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2228     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2229     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2230     constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2231 
2232     std::array<uint8_t,
2233                hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2234                    downstreamDeviceParamTableLen>
2235         responseMsg{};
2236 
2237     int rc = 0;
2238 
2239     struct pldm_msgbuf _buf;
2240     struct pldm_msgbuf* buf = &_buf;
2241     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
2242                                 responseMsg.size() - hdrSize);
2243     EXPECT_EQ(rc, 0);
2244 
2245     pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2246     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2247     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2248     pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2249     pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2250 
2251     /** Filling paramter table, the correctness of the downstream devices data
2252      *  is not checked in this test case so filling with 0xff
2253      */
2254     std::fill_n(responseMsg.data() + hdrSize +
2255                     PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN,
2256                 downstreamDeviceParamTableLen, 0xff);
2257     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2258     auto table = reinterpret_cast<pldm_component_parameter_entry*>(
2259         responseMsg.data() + hdrSize +
2260         PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN);
2261     table->active_comp_ver_str_len = activeComponentVersionStringLength;
2262     table->pending_comp_ver_str_len = pendingComponentVersionStringLength;
2263 
2264     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2265     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
2266     struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2267     struct variable_field downstreamDeviceParamTable = {};
2268 
2269     rc = decode_get_downstream_firmware_parameters_resp(
2270         response, responseMsg.size() - hdrSize, &resp_data,
2271         &downstreamDeviceParamTable);
2272 
2273     EXPECT_EQ(rc, 0);
2274     EXPECT_EQ(resp_data.completion_code, complition_code_resp);
2275     EXPECT_EQ(resp_data.next_data_transfer_handle,
2276               next_data_transfer_handle_resp);
2277     EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2278     EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
2279     EXPECT_EQ(downstreamDeviceParamTable.length, downstreamDeviceParamTableLen);
2280     EXPECT_EQ(
2281         true,
2282         std::equal(downstreamDeviceParamTable.ptr,
2283                    downstreamDeviceParamTable.ptr +
2284                        downstreamDeviceParamTable.length,
2285                    responseMsg.begin() + hdrSize +
2286                        PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN,
2287                    responseMsg.end()));
2288 }
2289 #endif
2290 
2291 #ifdef LIBPLDM_API_TESTING
2292 TEST(GetDownstreamFirmwareParameters, decodeResponseInvalidLength)
2293 {
2294     /** Count is not fixed here taking it as 1, and the downstream device's
2295      *  version strings length are set to 8
2296      */
2297     constexpr uint16_t downstreamDeviceCount = 1;
2298     constexpr uint8_t activeComponentVersionStringLength = 8;
2299     constexpr uint8_t pendingComponentVersionStringLength = 8;
2300     constexpr size_t downstreamDeviceParamTableLen =
2301         PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2302         activeComponentVersionStringLength +
2303         pendingComponentVersionStringLength;
2304     constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2305     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2306     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2307     constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2308 
2309     std::array<uint8_t,
2310                hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2311                    downstreamDeviceParamTableLen - 1 /* inject error length*/>
2312         responseMsg{};
2313 
2314     int rc = 0;
2315 
2316     struct pldm_msgbuf _buf;
2317     struct pldm_msgbuf* buf = &_buf;
2318     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
2319                                 responseMsg.size() - hdrSize);
2320     EXPECT_EQ(rc, 0);
2321 
2322     pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2323     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2324     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2325     pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2326     pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2327 
2328     /** Filling paramter table, the correctness of the downstream devices data
2329      *  is not checked in this test case so filling with 0xff
2330      */
2331     std::fill_n(responseMsg.data() + hdrSize +
2332                     PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN,
2333                 downstreamDeviceParamTableLen - 1 /* inject error length*/,
2334                 0xff);
2335 
2336     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2337     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
2338     struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2339     struct variable_field downstreamDeviceParamTable = {};
2340 
2341     rc = decode_get_downstream_firmware_parameters_resp(
2342         response, responseMsg.size() - hdrSize, &resp_data,
2343         &downstreamDeviceParamTable);
2344     EXPECT_EQ(rc, 0);
2345 
2346     pldm_downstream_device_parameters_entry entry{};
2347     variable_field versions{};
2348 
2349     EXPECT_NE(decode_downstream_device_parameter_table_entry(
2350                   &downstreamDeviceParamTable, &entry, &versions),
2351               0);
2352 }
2353 #endif
2354 
2355 #ifdef LIBPLDM_API_TESTING
2356 TEST(GetDownstreamFirmwareParameters, goodPathDecodeDownstreamDeviceParamTable)
2357 {
2358     // Arbitrary downstream device index
2359     constexpr uint16_t downstreamDeviceIndex = 1;
2360     // Arbitrary value for component classification
2361     constexpr uint32_t comparisonStamp = 0x12345678;
2362     // Arbitrary value for component activation methods
2363     constexpr uint16_t compActivationMethods = 0xbbdd;
2364     // Arbitrary value for capabilities during update
2365     constexpr uint32_t capabilitiesDuringUpdate = 0xbadbeefe;
2366     // ActiveCompImageSetVerStrLen is not fixed here taking it as 8
2367     constexpr uint8_t activeCompVerStrLen = 8;
2368     // PendingCompImageSetVerStrLen is not fixed here taking it as 8
2369     constexpr uint8_t pendingCompVerStrLen = 8;
2370     // Arbitrary value for release date
2371     constexpr char release_date[8] = {'2', '0', '2', '4', '0', '6', '2', '1'};
2372     // Arbitrary version strings
2373     constexpr char activeCompVerStr[activeCompVerStrLen] = {'1', '2', '3', '4',
2374                                                             '5', '6', '7', '8'};
2375     constexpr char pendingCompVerStr[pendingCompVerStrLen] = {
2376         'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
2377 
2378     std::array<uint8_t, PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2379                             activeCompVerStrLen + pendingCompVerStrLen>
2380         responseMsg{};
2381 
2382     int rc = 0;
2383 
2384     struct pldm_msgbuf _buf;
2385     struct pldm_msgbuf* buf = &_buf;
2386     rc = pldm_msgbuf_init_errno(buf,
2387                                 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN,
2388                                 responseMsg.data(), responseMsg.size());
2389     EXPECT_EQ(rc, 0);
2390 
2391     pldm_msgbuf_insert_uint16(buf, downstreamDeviceIndex);
2392     pldm_msgbuf_insert_uint32(buf, comparisonStamp);
2393     pldm_msgbuf_insert_uint8(buf, (uint8_t)PLDM_STR_TYPE_ASCII);
2394     pldm_msgbuf_insert_uint8(buf, activeCompVerStrLen);
2395     rc = pldm_msgbuf_insert_array_char(buf, sizeof(release_date), release_date,
2396                                        sizeof(release_date));
2397     ASSERT_EQ(rc, 0);
2398     pldm_msgbuf_insert_uint32(buf, comparisonStamp);
2399     pldm_msgbuf_insert_uint8(buf, (uint8_t)PLDM_STR_TYPE_ASCII);
2400     pldm_msgbuf_insert_uint8(buf, pendingCompVerStrLen);
2401     rc = pldm_msgbuf_insert_array_char(buf, sizeof(release_date), release_date,
2402                                        sizeof(release_date));
2403     ASSERT_EQ(rc, 0);
2404     pldm_msgbuf_insert_uint16(buf, compActivationMethods);
2405     pldm_msgbuf_insert_uint32(buf, capabilitiesDuringUpdate);
2406     rc = pldm_msgbuf_insert_array_char(
2407         buf, activeCompVerStrLen, activeCompVerStr, sizeof(activeCompVerStr));
2408     ASSERT_EQ(rc, 0);
2409     rc = pldm_msgbuf_insert_array_char(buf, pendingCompVerStrLen,
2410                                        pendingCompVerStr,
2411                                        sizeof(pendingCompVerStr));
2412     ASSERT_EQ(rc, 0);
2413 
2414     variable_field rawData = {.ptr = responseMsg.data(),
2415                               .length = responseMsg.size()};
2416     struct pldm_downstream_device_parameter_entry_versions entry_version = {};
2417     struct variable_field versions = {};
2418     const uint8_t* original_ptr = rawData.ptr;
2419 
2420     rc = decode_downstream_device_parameter_table_entry(
2421         &rawData, &entry_version.entry, &versions);
2422 
2423     EXPECT_EQ(rc, 0);
2424     EXPECT_EQ(rawData.ptr, original_ptr +
2425                                PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2426                                entry_version.entry.active_comp_ver_str_len +
2427                                entry_version.entry.pending_comp_ver_str_len);
2428     EXPECT_EQ(rawData.length, 0);
2429 
2430     // Further decode the version strings
2431     rc = decode_downstream_device_parameter_table_entry_versions(
2432         &versions, &entry_version.entry, entry_version.active_comp_ver_str,
2433         sizeof(entry_version.active_comp_ver_str),
2434         entry_version.pending_comp_ver_str,
2435         sizeof(entry_version.pending_comp_ver_str));
2436     struct pldm_downstream_device_parameters_entry entry = entry_version.entry;
2437     EXPECT_EQ(rc, 0);
2438 
2439     // Verify the decoded table entry
2440     EXPECT_EQ(entry.downstream_device_index, downstreamDeviceIndex);
2441     EXPECT_EQ(entry.active_comp_comparison_stamp, comparisonStamp);
2442     EXPECT_EQ(entry.active_comp_ver_str_type, PLDM_STR_TYPE_ASCII);
2443     EXPECT_EQ(entry.active_comp_ver_str_len, activeCompVerStrLen);
2444     EXPECT_EQ(0, memcmp(entry.active_comp_release_date, release_date,
2445                         sizeof(release_date)));
2446     EXPECT_EQ(entry.pending_comp_comparison_stamp, comparisonStamp);
2447     EXPECT_EQ(entry.pending_comp_ver_str_type, PLDM_STR_TYPE_ASCII);
2448     EXPECT_EQ(entry.pending_comp_ver_str_len, pendingCompVerStrLen);
2449     EXPECT_EQ(0, memcmp(entry.pending_comp_release_date, release_date,
2450                         sizeof(release_date)));
2451     EXPECT_EQ(entry.comp_activation_methods.value, compActivationMethods);
2452     EXPECT_EQ(entry.capabilities_during_update.value, capabilitiesDuringUpdate);
2453     EXPECT_EQ(entry.active_comp_ver_str_len + entry.pending_comp_ver_str_len,
2454               versions.length);
2455     EXPECT_EQ(0, memcmp(versions.ptr, activeCompVerStr, activeCompVerStrLen));
2456     EXPECT_EQ(0, memcmp(versions.ptr + entry.active_comp_ver_str_len,
2457                         pendingCompVerStr, pendingCompVerStrLen));
2458 
2459     // Verify version strings
2460     EXPECT_EQ(0, memcmp(entry_version.entry.active_comp_ver_str,
2461                         activeCompVerStr, activeCompVerStrLen));
2462     EXPECT_EQ('\0',
2463               entry_version.entry.active_comp_ver_str[activeCompVerStrLen]);
2464     EXPECT_EQ(0, memcmp(entry_version.entry.pending_comp_ver_str,
2465                         pendingCompVerStr, pendingCompVerStrLen));
2466     EXPECT_EQ('\0',
2467               entry_version.entry.pending_comp_ver_str[pendingCompVerStrLen]);
2468     EXPECT_EQ(0, memcmp(entry_version.active_comp_ver_str, activeCompVerStr,
2469                         activeCompVerStrLen));
2470     EXPECT_EQ('\0', entry_version.active_comp_ver_str[activeCompVerStrLen]);
2471     EXPECT_EQ(0, memcmp(entry_version.pending_comp_ver_str, pendingCompVerStr,
2472                         pendingCompVerStrLen));
2473     EXPECT_EQ('\0', entry_version.pending_comp_ver_str[pendingCompVerStrLen]);
2474 }
2475 #endif
2476 
2477 #ifdef LIBPLDM_API_TESTING
2478 TEST(GetDownstreamFirmwareParameters, goodPathDecodeDownstreamTableVersions)
2479 {
2480     // Arbitrary component version string length
2481     constexpr uint8_t activeCompVerStrLen = 8;
2482     constexpr uint8_t pendingCompVerStrLen = 8;
2483     // Arbitrary ActiveVersionStr and pendingVersionStr
2484     constexpr char versionsStr[] = {'1', '2', '3', '4', '5', '6', '7', '8',
2485                                     'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
2486     const struct variable_field versions = {
2487         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2488         .ptr = reinterpret_cast<const uint8_t*>(versionsStr),
2489         .length = sizeof(versionsStr)};
2490 
2491     struct pldm_downstream_device_parameter_entry_versions entryVersion = {};
2492     entryVersion.entry.active_comp_ver_str_len = activeCompVerStrLen;
2493     entryVersion.entry.pending_comp_ver_str_len = pendingCompVerStrLen;
2494 
2495     int rc = decode_downstream_device_parameter_table_entry_versions(
2496         &versions, &entryVersion.entry, entryVersion.active_comp_ver_str,
2497         sizeof(entryVersion.active_comp_ver_str),
2498         entryVersion.pending_comp_ver_str,
2499         sizeof(entryVersion.pending_comp_ver_str));
2500 
2501     EXPECT_EQ(rc, 0);
2502     EXPECT_EQ(0, memcmp(entryVersion.active_comp_ver_str, versions.ptr,
2503                         activeCompVerStrLen));
2504     EXPECT_EQ('\0', entryVersion.active_comp_ver_str[activeCompVerStrLen]);
2505     EXPECT_EQ(0,
2506               memcmp(entryVersion.pending_comp_ver_str,
2507                      versions.ptr + activeCompVerStrLen, pendingCompVerStrLen));
2508     EXPECT_EQ('\0', entryVersion.pending_comp_ver_str[activeCompVerStrLen]);
2509     EXPECT_EQ(0, memcmp(entryVersion.entry.active_comp_ver_str, versions.ptr,
2510                         activeCompVerStrLen));
2511     EXPECT_EQ('\0',
2512               entryVersion.entry.pending_comp_ver_str[activeCompVerStrLen]);
2513     EXPECT_EQ(0,
2514               memcmp(entryVersion.entry.pending_comp_ver_str,
2515                      versions.ptr + activeCompVerStrLen, pendingCompVerStrLen));
2516     EXPECT_EQ('\0',
2517               entryVersion.entry.pending_comp_ver_str[activeCompVerStrLen]);
2518 }
2519 #endif
2520 
2521 #ifdef LIBPLDM_API_TESTING
2522 TEST(GetDownstreamFirmwareParameters, decodeInvalidDownstreamTableVersions)
2523 {
2524     // Arbitrary ActiveVersionStr and pendingVersionStr
2525     constexpr char versionsStr[] = {'1', '2', '3', '4', '5', '6', '7', '8',
2526                                     'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
2527     const struct variable_field versions = {
2528         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2529         .ptr = reinterpret_cast<const uint8_t*>(versionsStr),
2530         .length = sizeof(versionsStr)};
2531 
2532     struct pldm_downstream_device_parameter_entry_versions entryVersion = {};
2533 
2534     int rc = decode_downstream_device_parameter_table_entry_versions(
2535         &versions, nullptr, entryVersion.active_comp_ver_str,
2536         sizeof(entryVersion.active_comp_ver_str),
2537         entryVersion.pending_comp_ver_str,
2538         sizeof(entryVersion.pending_comp_ver_str));
2539     EXPECT_EQ(rc, -EINVAL);
2540 }
2541 #endif
2542 
2543 #ifdef LIBPLDM_API_TESTING
2544 TEST(GetDownstreamFirmwareParameters, decodeOverflowDownstreamTableVersions)
2545 {
2546     // Arbitrary component version string length
2547     constexpr uint8_t activeCompVerStrLen = 8;
2548     constexpr uint8_t pendingCompVerStrLen = 8;
2549     // Arbitrary ActiveVersionStr and pendingVersionStr
2550     constexpr char versionsStr[] = {'1', '2', '3', '4', '5', '6', '7', '8',
2551                                     'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
2552     const struct variable_field versions = {
2553         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2554         .ptr = reinterpret_cast<const uint8_t*>(versionsStr),
2555         .length = sizeof(versionsStr) - 1 // Inject error length
2556     };
2557 
2558     struct pldm_downstream_device_parameter_entry_versions entryVersion = {};
2559     entryVersion.entry.active_comp_ver_str_len = activeCompVerStrLen;
2560     entryVersion.entry.pending_comp_ver_str_len = pendingCompVerStrLen;
2561 
2562     EXPECT_EQ(decode_downstream_device_parameter_table_entry_versions(
2563                   &versions, &entryVersion.entry,
2564                   entryVersion.active_comp_ver_str,
2565                   sizeof(entryVersion.active_comp_ver_str),
2566                   entryVersion.pending_comp_ver_str,
2567                   sizeof(entryVersion.pending_comp_ver_str)),
2568               -EOVERFLOW);
2569 }
2570 #endif
2571 
2572 TEST(RequestUpdate, goodPathEncodeRequest)
2573 {
2574     constexpr uint8_t instanceId = 1;
2575     constexpr uint32_t maxTransferSize = 512;
2576     constexpr uint16_t numOfComp = 3;
2577     constexpr uint8_t maxOutstandingTransferReq = 2;
2578     constexpr uint16_t pkgDataLen = 0x1234;
2579     constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2580     constexpr uint8_t compImgSetVerStrLen =
2581         static_cast<uint8_t>(compImgSetVerStr.size());
2582     variable_field compImgSetVerStrInfo{};
2583     compImgSetVerStrInfo.ptr =
2584         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2585         reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2586     compImgSetVerStrInfo.length = compImgSetVerStrLen;
2587 
2588     std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2589                             compImgSetVerStrLen>
2590         request{};
2591     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2592     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2593 
2594     auto rc = encode_request_update_req(
2595         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2596         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2597         &compImgSetVerStrInfo, requestMsg,
2598         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2599     EXPECT_EQ(rc, PLDM_SUCCESS);
2600 
2601     std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2602                             compImgSetVerStrLen>
2603         outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00,
2604                    0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e,
2605                    0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30};
2606     EXPECT_EQ(request, outRequest);
2607 }
2608 
2609 TEST(RequestUpdate, errorPathEncodeRequest)
2610 {
2611     constexpr uint8_t instanceId = 1;
2612     uint32_t maxTransferSize = 512;
2613     constexpr uint16_t numOfComp = 3;
2614     uint8_t maxOutstandingTransferReq = 2;
2615     constexpr uint16_t pkgDataLen = 0x1234;
2616     constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2617     uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2618     variable_field compImgSetVerStrInfo{};
2619     compImgSetVerStrInfo.ptr =
2620         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2621         reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2622     compImgSetVerStrInfo.length = compImgSetVerStrLen;
2623 
2624     std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2625                             compImgSetVerStr.size()>
2626         request{};
2627     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2628     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2629 
2630     auto rc = encode_request_update_req(
2631         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2632         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr,
2633         requestMsg,
2634         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2635     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2636 
2637     compImgSetVerStrInfo.ptr = nullptr;
2638     rc = encode_request_update_req(
2639         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2640         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2641         &compImgSetVerStrInfo, requestMsg,
2642         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2643     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2644     compImgSetVerStrInfo.ptr =
2645         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2646         reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2647 
2648     rc = encode_request_update_req(
2649         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2650         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2651         &compImgSetVerStrInfo, nullptr,
2652         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2653     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2654 
2655     rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp,
2656                                    maxOutstandingTransferReq, pkgDataLen,
2657                                    PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2658                                    &compImgSetVerStrInfo, requestMsg, 0);
2659     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2660 
2661     compImgSetVerStrLen = 0;
2662     rc = encode_request_update_req(
2663         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2664         pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr,
2665         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2666     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2667     compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2668 
2669     compImgSetVerStrInfo.length = 0xffff;
2670     rc = encode_request_update_req(
2671         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2672         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2673         &compImgSetVerStrInfo, nullptr,
2674         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2675     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2676     compImgSetVerStrInfo.length = compImgSetVerStrLen;
2677 
2678     maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1;
2679     rc = encode_request_update_req(
2680         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2681         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2682         &compImgSetVerStrInfo, nullptr,
2683         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2684     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2685     maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE;
2686 
2687     maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ - 1;
2688     rc = encode_request_update_req(
2689         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2690         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2691         &compImgSetVerStrInfo, nullptr,
2692         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2693     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2694     maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ;
2695 
2696     rc = encode_request_update_req(
2697         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2698         pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen,
2699         &compImgSetVerStrInfo, nullptr,
2700         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2701     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2702 }
2703 
2704 TEST(RequestUpdate, goodPathDecodeResponse)
2705 {
2706     constexpr uint16_t fdMetaDataLen = 1024;
2707     constexpr uint8_t fdWillSendPkgData = 1;
2708     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)>
2709         requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01};
2710 
2711     auto responseMsg1 =
2712         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2713         reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data());
2714     uint8_t outCompletionCode = 0;
2715     uint16_t outFdMetaDataLen = 0;
2716     uint8_t outFdWillSendPkgData = 0;
2717 
2718     auto rc = decode_request_update_resp(
2719         responseMsg1, requestUpdateResponse1.size() - hdrSize,
2720         &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2721     EXPECT_EQ(rc, PLDM_SUCCESS);
2722     EXPECT_EQ(outCompletionCode, PLDM_SUCCESS);
2723     EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen);
2724     EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData);
2725 
2726     outCompletionCode = 0;
2727     outFdMetaDataLen = 0;
2728     outFdWillSendPkgData = 0;
2729 
2730     constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)>
2731         requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
2732     auto responseMsg2 =
2733         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2734         reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data());
2735     rc = decode_request_update_resp(
2736         responseMsg2, requestUpdateResponse2.size() - hdrSize,
2737         &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2738     EXPECT_EQ(rc, PLDM_SUCCESS);
2739     EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
2740 }
2741 
2742 TEST(RequestUpdate, errorPathDecodeResponse)
2743 {
2744     constexpr std::array<uint8_t,
2745                          hdrSize + sizeof(pldm_request_update_resp) - 1>
2746         requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
2747 
2748     auto responseMsg =
2749         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2750         reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data());
2751     uint8_t outCompletionCode = 0;
2752     uint16_t outFdMetaDataLen = 0;
2753     uint8_t outFdWillSendPkgData = 0;
2754 
2755     auto rc = decode_request_update_resp(
2756         nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2757         &outFdMetaDataLen, &outFdWillSendPkgData);
2758     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2759 
2760     rc = decode_request_update_resp(
2761         responseMsg, requestUpdateResponse.size() - hdrSize, nullptr,
2762         &outFdMetaDataLen, &outFdWillSendPkgData);
2763     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2764 
2765     rc = decode_request_update_resp(
2766         responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2767         nullptr, &outFdWillSendPkgData);
2768     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2769 
2770     rc = decode_request_update_resp(
2771         responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2772         &outFdMetaDataLen, nullptr);
2773     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2774 
2775     rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode,
2776                                     &outFdMetaDataLen, &outFdWillSendPkgData);
2777     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2778 
2779     rc = decode_request_update_resp(
2780         responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2781         &outFdMetaDataLen, &outFdWillSendPkgData);
2782     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2783 }
2784 
2785 TEST(PassComponentTable, goodPathEncodeRequest)
2786 {
2787     constexpr uint8_t instanceId = 1;
2788     constexpr uint16_t compIdentifier = 400;
2789     constexpr uint8_t compClassificationIndex = 40;
2790     constexpr uint32_t compComparisonStamp = 0x12345678;
2791     constexpr std::string_view compVerStr = "0penBmcv1.1";
2792     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2793     variable_field compVerStrInfo{};
2794     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2795     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2796     compVerStrInfo.length = compVerStrLen;
2797 
2798     std::array<uint8_t,
2799                hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2800         request{};
2801     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2802     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2803 
2804     auto rc = encode_pass_component_table_req(
2805         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2806         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2807         compVerStrLen, &compVerStrInfo, requestMsg,
2808         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2809     EXPECT_EQ(rc, PLDM_SUCCESS);
2810 
2811     std::array<uint8_t,
2812                hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2813         outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28,
2814                    0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65,
2815                    0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31};
2816     EXPECT_EQ(request, outRequest);
2817 }
2818 
2819 TEST(PassComponentTable, errorPathEncodeRequest)
2820 {
2821     constexpr uint8_t instanceId = 1;
2822     constexpr uint16_t compIdentifier = 400;
2823     constexpr uint8_t compClassificationIndex = 40;
2824     constexpr uint32_t compComparisonStamp = 0x12345678;
2825     constexpr std::string_view compVerStr = "0penBmcv1.1";
2826     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2827     variable_field compVerStrInfo{};
2828     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2829     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2830     compVerStrInfo.length = compVerStrLen;
2831 
2832     std::array<uint8_t,
2833                hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2834         request{};
2835     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2836     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2837 
2838     auto rc = encode_pass_component_table_req(
2839         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2840         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2841         compVerStrLen, nullptr, requestMsg,
2842         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2843     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2844 
2845     compVerStrInfo.ptr = nullptr;
2846     rc = encode_pass_component_table_req(
2847         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2848         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2849         compVerStrLen, &compVerStrInfo, requestMsg,
2850         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2851     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2852     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2853     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2854 
2855     rc = encode_pass_component_table_req(
2856         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2857         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2858         compVerStrLen, &compVerStrInfo, nullptr,
2859         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2860     EXPECT_EQ(rc, PLDM_ERROR_INVALID_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, requestMsg,
2866         sizeof(pldm_pass_component_table_req));
2867     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
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, 0,
2872         &compVerStrInfo, requestMsg,
2873         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2874     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
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,
2879         compVerStrLen - 1, &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 + 1, PLDM_COMP_FIRMWARE, compIdentifier,
2885         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2886         compVerStrLen, &compVerStrInfo, requestMsg,
2887         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2888     EXPECT_EQ(rc, PLDM_INVALID_TRANSFER_OPERATION_FLAG);
2889 
2890     rc = encode_pass_component_table_req(
2891         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2892         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN,
2893         compVerStrLen, &compVerStrInfo, requestMsg,
2894         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2895     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2896 }
2897 
2898 TEST(PassComponentTable, goodPathDecodeResponse)
2899 {
2900     constexpr std::array<uint8_t,
2901                          hdrSize + sizeof(pldm_pass_component_table_resp)>
2902         passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
2903     auto responseMsg1 =
2904         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2905         reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
2906 
2907     uint8_t completionCode = 0;
2908     uint8_t compResp = 0;
2909     uint8_t compRespCode = 0;
2910 
2911     auto rc = decode_pass_component_table_resp(
2912         responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode,
2913         &compResp, &compRespCode);
2914 
2915     EXPECT_EQ(rc, PLDM_SUCCESS);
2916     EXPECT_EQ(completionCode, PLDM_SUCCESS);
2917     EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
2918     EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL);
2919 
2920     constexpr std::array<uint8_t,
2921                          hdrSize + sizeof(pldm_pass_component_table_resp)>
2922         passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0};
2923     auto responseMsg2 =
2924         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2925         reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
2926     rc = decode_pass_component_table_resp(
2927         responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
2928         &compResp, &compRespCode);
2929 
2930     EXPECT_EQ(rc, PLDM_SUCCESS);
2931     EXPECT_EQ(completionCode, PLDM_SUCCESS);
2932     EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
2933     EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN);
2934 
2935     constexpr std::array<uint8_t,
2936                          hdrSize + sizeof(pldm_pass_component_table_resp)>
2937         passCompTableResponse3{0x00, 0x00, 0x00, 0x80};
2938     auto responseMsg3 =
2939         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2940         reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
2941 
2942     rc = decode_pass_component_table_resp(
2943         responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
2944         &compResp, &compRespCode);
2945 
2946     EXPECT_EQ(rc, PLDM_SUCCESS);
2947     EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
2948 }
2949 
2950 TEST(PassComponentTable, errorPathDecodeResponse)
2951 {
2952     constexpr std::array<uint8_t,
2953                          hdrSize + sizeof(pldm_pass_component_table_resp) - 1>
2954         passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00};
2955     auto responseMsg1 =
2956         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2957         reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
2958 
2959     uint8_t completionCode = 0;
2960     uint8_t compResp = 0;
2961     uint8_t compRespCode = 0;
2962 
2963     auto rc = decode_pass_component_table_resp(
2964         nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode,
2965         &compResp, &compRespCode);
2966     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2967 
2968     rc = decode_pass_component_table_resp(
2969         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr,
2970         &compResp, &compRespCode);
2971     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2972 
2973     rc = decode_pass_component_table_resp(
2974         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
2975         &completionCode, nullptr, &compRespCode);
2976     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2977 
2978     rc = decode_pass_component_table_resp(
2979         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
2980         &completionCode, &compResp, nullptr);
2981     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2982 
2983     rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode,
2984                                           &compResp, &compRespCode);
2985     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2986 
2987     rc = decode_pass_component_table_resp(
2988         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
2989         &completionCode, &compResp, &compRespCode);
2990     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2991 
2992     constexpr std::array<uint8_t,
2993                          hdrSize + sizeof(pldm_pass_component_table_resp)>
2994         passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
2995     auto responseMsg2 =
2996         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2997         reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
2998     rc = decode_pass_component_table_resp(
2999         responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3000         &compResp, &compRespCode);
3001     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3002 
3003     constexpr std::array<uint8_t,
3004                          hdrSize + sizeof(pldm_pass_component_table_resp)>
3005         passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};
3006     auto responseMsg3 =
3007         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3008         reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3009     rc = decode_pass_component_table_resp(
3010         responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3011         &compResp, &compRespCode);
3012     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3013 
3014     constexpr std::array<uint8_t,
3015                          hdrSize + sizeof(pldm_pass_component_table_resp)>
3016         passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
3017     auto responseMsg4 =
3018         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3019         reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data());
3020     rc = decode_pass_component_table_resp(
3021         responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode,
3022         &compResp, &compRespCode);
3023     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3024 }
3025 
3026 TEST(UpdateComponent, goodPathEncodeRequest)
3027 {
3028     constexpr uint8_t instanceId = 2;
3029     constexpr uint16_t compIdentifier = 500;
3030     constexpr uint8_t compClassificationIndex = 50;
3031     constexpr uint32_t compComparisonStamp = 0x89abcdef;
3032     constexpr uint32_t compImageSize = 4096;
3033     constexpr bitfield32_t updateOptionFlags{1};
3034     constexpr std::string_view compVerStr = "OpenBmcv2.2";
3035     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3036     variable_field compVerStrInfo{};
3037     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3038     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3039     compVerStrInfo.length = compVerStrLen;
3040 
3041     std::array<uint8_t,
3042                hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3043         request{};
3044     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3045     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3046 
3047     auto rc = encode_update_component_req(
3048         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3049         compComparisonStamp, compImageSize, updateOptionFlags,
3050         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3051         sizeof(pldm_update_component_req) + compVerStrLen);
3052     EXPECT_EQ(rc, PLDM_SUCCESS);
3053 
3054     std::array<uint8_t,
3055                hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3056         outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
3057                    0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
3058                    0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
3059                    0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
3060     EXPECT_EQ(request, outRequest);
3061 }
3062 
3063 TEST(UpdateComponent, errorPathEncodeRequest)
3064 {
3065     constexpr uint8_t instanceId = 2;
3066     constexpr uint16_t compIdentifier = 500;
3067     constexpr uint8_t compClassificationIndex = 50;
3068     constexpr uint32_t compComparisonStamp = 0x89abcdef;
3069     constexpr uint32_t compImageSize = 4096;
3070     constexpr bitfield32_t updateOptionFlags{1};
3071     constexpr std::string_view compVerStr = "OpenBmcv2.2";
3072     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3073     variable_field compVerStrInfo{};
3074     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3075     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3076     compVerStrInfo.length = compVerStrLen;
3077 
3078     std::array<uint8_t,
3079                hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3080         request{};
3081     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3082     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3083 
3084     auto rc = encode_update_component_req(
3085         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3086         compComparisonStamp, compImageSize, updateOptionFlags,
3087         PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
3088         sizeof(pldm_update_component_req) + compVerStrLen);
3089     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3090 
3091     compVerStrInfo.ptr = nullptr;
3092     rc = encode_update_component_req(
3093         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3094         compComparisonStamp, compImageSize, updateOptionFlags,
3095         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3096         sizeof(pldm_update_component_req) + compVerStrLen);
3097     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3098     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3099     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3100 
3101     rc = encode_update_component_req(
3102         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3103         compComparisonStamp, compImageSize, updateOptionFlags,
3104         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
3105         sizeof(pldm_update_component_req) + compVerStrLen);
3106     EXPECT_EQ(rc, PLDM_ERROR_INVALID_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, requestMsg,
3112         sizeof(pldm_update_component_req));
3113     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3114 
3115     rc = encode_update_component_req(
3116         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3117         compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
3118         compVerStrLen, &compVerStrInfo, requestMsg,
3119         sizeof(pldm_update_component_req) + compVerStrLen);
3120     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3121 
3122     rc = encode_update_component_req(
3123         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3124         compComparisonStamp, compImageSize, updateOptionFlags,
3125         PLDM_STR_TYPE_ASCII, 0, &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, compVerStrLen - 1, &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_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
3140         sizeof(pldm_update_component_req) + compVerStrLen);
3141     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3142 }
3143 
3144 TEST(UpdateComponent, goodPathDecodeResponse)
3145 {
3146     constexpr std::bitset<32> forceUpdateComp{1};
3147     constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
3148     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3149         updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3150                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3151     auto responseMsg1 =
3152         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3153         reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3154 
3155     uint8_t completionCode = 0;
3156     uint8_t compCompatibilityResp = 0;
3157     uint8_t compCompatibilityRespCode = 0;
3158     bitfield32_t updateOptionFlagsEnabled{};
3159     uint16_t timeBeforeReqFWData = 0;
3160 
3161     auto rc = decode_update_component_resp(
3162         responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
3163         &compCompatibilityResp, &compCompatibilityRespCode,
3164         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3165 
3166     EXPECT_EQ(rc, PLDM_SUCCESS);
3167     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3168     EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
3169     EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
3170     EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
3171     EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
3172 
3173     constexpr std::bitset<32> noFlags{};
3174     constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
3175     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3176         updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3177                                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3178     auto responseMsg2 =
3179         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3180         reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3181     rc = decode_update_component_resp(
3182         responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3183         &compCompatibilityResp, &compCompatibilityRespCode,
3184         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3185 
3186     EXPECT_EQ(rc, PLDM_SUCCESS);
3187     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3188     EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
3189     EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
3190     EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
3191     EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
3192 
3193     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3194         updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
3195     auto responseMsg3 =
3196         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3197         reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3198 
3199     rc = decode_update_component_resp(
3200         responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3201         &compCompatibilityResp, &compCompatibilityRespCode,
3202         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3203 
3204     EXPECT_EQ(rc, PLDM_SUCCESS);
3205     EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3206 }
3207 
3208 TEST(UpdateComponent, errorPathDecodeResponse)
3209 {
3210     constexpr std::array<uint8_t,
3211                          hdrSize + sizeof(pldm_update_component_resp) - 1>
3212         updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3213                                  0x00, 0x00, 0x00, 0x00, 0x00};
3214     auto responseMsg1 =
3215         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3216         reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3217 
3218     uint8_t completionCode = 0;
3219     uint8_t compCompatibilityResp = 0;
3220     uint8_t compCompatibilityRespCode = 0;
3221     bitfield32_t updateOptionFlagsEnabled{};
3222     uint16_t timeBeforeReqFWData = 0;
3223 
3224     auto rc = decode_update_component_resp(
3225         nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
3226         &compCompatibilityResp, &compCompatibilityRespCode,
3227         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3228     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3229 
3230     rc = decode_update_component_resp(
3231         responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
3232         &compCompatibilityResp, &compCompatibilityRespCode,
3233         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3234     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3235 
3236     rc = decode_update_component_resp(
3237         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3238         nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3239         &timeBeforeReqFWData);
3240     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3241 
3242     rc = decode_update_component_resp(
3243         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3244         &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
3245         &timeBeforeReqFWData);
3246     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3247 
3248     rc = decode_update_component_resp(
3249         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3250         &compCompatibilityResp, &compCompatibilityRespCode, nullptr,
3251         &timeBeforeReqFWData);
3252     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3253 
3254     rc = decode_update_component_resp(
3255         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3256         &compCompatibilityResp, &compCompatibilityRespCode,
3257         &updateOptionFlagsEnabled, nullptr);
3258     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3259 
3260     rc = decode_update_component_resp(
3261         responseMsg1, 0, &completionCode, &compCompatibilityResp,
3262         &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3263         &timeBeforeReqFWData);
3264     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3265 
3266     rc = decode_update_component_resp(
3267         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3268         &compCompatibilityResp, &compCompatibilityRespCode,
3269         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3270     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3271 
3272     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3273         updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
3274                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3275     auto responseMsg2 =
3276         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3277         reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3278     rc = decode_update_component_resp(
3279         responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3280         &compCompatibilityResp, &compCompatibilityRespCode,
3281         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3282     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3283 
3284     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3285         updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
3286                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3287     auto responseMsg3 =
3288         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3289         reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3290     rc = decode_update_component_resp(
3291         responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3292         &compCompatibilityResp, &compCompatibilityRespCode,
3293         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3294     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3295 
3296     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3297         updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
3298                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3299     auto responseMsg4 =
3300         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3301         reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
3302     rc = decode_update_component_resp(
3303         responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
3304         &compCompatibilityResp, &compCompatibilityRespCode,
3305         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3306     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3307 }
3308 
3309 TEST(RequestFirmwareData, goodPathDecodeRequest)
3310 {
3311     constexpr uint32_t offset = 300;
3312     constexpr uint32_t length = 255;
3313     constexpr std::array<uint8_t,
3314                          hdrSize + sizeof(pldm_request_firmware_data_req)>
3315         reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3316                      0x00, 0xff, 0x00, 0x00, 0x00};
3317     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3318     auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3319 
3320     uint32_t outOffset = 0;
3321     uint32_t outLength = 0;
3322     auto rc = decode_request_firmware_data_req(
3323         requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3324         &outLength);
3325 
3326     EXPECT_EQ(rc, PLDM_SUCCESS);
3327     EXPECT_EQ(outOffset, offset);
3328     EXPECT_EQ(outLength, length);
3329 }
3330 
3331 TEST(RequestFirmwareData, errorPathDecodeRequest)
3332 {
3333     constexpr std::array<uint8_t,
3334                          hdrSize + sizeof(pldm_request_firmware_data_req)>
3335         reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3336                      0x00, 0x1f, 0x00, 0x00, 0x00};
3337     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3338     auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3339 
3340     uint32_t outOffset = 0;
3341     uint32_t outLength = 0;
3342     auto rc = decode_request_firmware_data_req(
3343         nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
3344         &outLength);
3345     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3346 
3347     rc = decode_request_firmware_data_req(
3348         requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
3349         &outLength);
3350     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3351 
3352     rc = decode_request_firmware_data_req(
3353         requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3354         nullptr);
3355     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3356 
3357     rc = decode_request_firmware_data_req(
3358         requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
3359         &outLength);
3360     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3361 
3362     rc = decode_request_firmware_data_req(
3363         requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3364         &outLength);
3365     EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
3366 }
3367 
3368 TEST(RequestFirmwareData, goodPathEncodeResponse)
3369 {
3370     constexpr uint8_t instanceId = 3;
3371     constexpr uint8_t completionCode = PLDM_SUCCESS;
3372     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
3373                                       PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3374         outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
3375                               0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3376                               0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3377                               0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3378                               0x1d, 0x1e, 0x1f, 0x20};
3379     std::array<uint8_t, hdrSize + sizeof(completionCode) +
3380                             PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3381         reqFwDataResponse1{0x00, 0x00, 0x00, 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     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3387     auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
3388     auto rc = encode_request_firmware_data_resp(
3389         instanceId, completionCode, responseMsg1,
3390         sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
3391     EXPECT_EQ(rc, PLDM_SUCCESS);
3392     EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
3393 
3394     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3395         outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
3396     std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
3397         0x00, 0x00, 0x00, 0x00};
3398     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3399     auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
3400     rc = encode_request_firmware_data_resp(
3401         instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
3402         sizeof(completionCode));
3403     EXPECT_EQ(rc, PLDM_SUCCESS);
3404     EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
3405 }
3406 
3407 TEST(RequestFirmwareData, errorPathEncodeResponse)
3408 {
3409     std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
3410     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3411     auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
3412     auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
3413     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3414 
3415     rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
3416     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3417 }
3418 
3419 TEST(TransferComplete, goodPathDecodeRequest)
3420 {
3421     constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
3422     constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3423         transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
3424     auto requestMsg1 =
3425         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3426         reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
3427     uint8_t outTransferResult = 0;
3428 
3429     auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
3430                                            &outTransferResult);
3431     EXPECT_EQ(rc, PLDM_SUCCESS);
3432     EXPECT_EQ(outTransferResult, transferResult);
3433 
3434     constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3435         transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
3436     auto requestMsg2 =
3437         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3438         reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
3439     rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
3440                                       &outTransferResult);
3441     EXPECT_EQ(rc, PLDM_SUCCESS);
3442     EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
3443 }
3444 
3445 TEST(TransferComplete, errorPathDecodeRequest)
3446 {
3447     constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
3448                                                                0x00};
3449     auto requestMsg =
3450         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3451         reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
3452     uint8_t outTransferResult = 0;
3453 
3454     auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
3455     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3456 
3457     rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
3458     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3459 
3460     rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
3461     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3462 }
3463 
3464 TEST(TransferComplete, goodPathEncodeResponse)
3465 {
3466     constexpr uint8_t instanceId = 4;
3467     constexpr uint8_t completionCode = PLDM_SUCCESS;
3468     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3469         outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
3470     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3471         transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3472     auto responseMsg1 =
3473         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3474         reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
3475     auto rc = encode_transfer_complete_resp(
3476         instanceId, completionCode, responseMsg1, sizeof(completionCode));
3477     EXPECT_EQ(rc, PLDM_SUCCESS);
3478     EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
3479 
3480     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3481         outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
3482     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3483         transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3484     auto responseMsg2 =
3485         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3486         reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
3487     rc = encode_transfer_complete_resp(instanceId,
3488                                        PLDM_FWUP_COMMAND_NOT_EXPECTED,
3489                                        responseMsg2, sizeof(completionCode));
3490     EXPECT_EQ(rc, PLDM_SUCCESS);
3491     EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
3492 }
3493 
3494 TEST(TransferComplete, errorPathEncodeResponse)
3495 {
3496     std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
3497     auto responseMsg =
3498         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3499         reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
3500     auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3501     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3502 
3503     rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3504     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3505 }
3506 
3507 TEST(VerifyComplete, goodPathDecodeRequest)
3508 {
3509     constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
3510     constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3511         verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
3512     auto requestMsg1 =
3513         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3514         reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
3515     uint8_t outVerifyResult = 0;
3516 
3517     auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
3518                                          &outVerifyResult);
3519     EXPECT_EQ(rc, PLDM_SUCCESS);
3520     EXPECT_EQ(outVerifyResult, verifyResult);
3521 
3522     constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3523         verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
3524     auto requestMsg2 =
3525         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3526         reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
3527     rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
3528                                     &outVerifyResult);
3529     EXPECT_EQ(rc, PLDM_SUCCESS);
3530     EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
3531 }
3532 
3533 TEST(VerifyComplete, errorPathDecodeRequest)
3534 {
3535     constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
3536     auto requestMsg =
3537         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3538         reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
3539     uint8_t outVerifyResult = 0;
3540 
3541     auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
3542     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3543 
3544     rc = decode_verify_complete_req(requestMsg, 0, nullptr);
3545     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3546 
3547     rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);
3548     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3549 }
3550 
3551 TEST(VerifyComplete, goodPathEncodeResponse)
3552 {
3553     constexpr uint8_t instanceId = 5;
3554     constexpr uint8_t completionCode = PLDM_SUCCESS;
3555     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3556         outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};
3557     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3558         verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3559     auto responseMsg1 =
3560         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3561         reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());
3562     auto rc = encode_verify_complete_resp(instanceId, completionCode,
3563                                           responseMsg1, sizeof(completionCode));
3564     EXPECT_EQ(rc, PLDM_SUCCESS);
3565     EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);
3566 
3567     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3568         outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88};
3569     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3570         verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3571     auto responseMsg2 =
3572         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3573         reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());
3574     rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3575                                      responseMsg2, sizeof(completionCode));
3576     EXPECT_EQ(rc, PLDM_SUCCESS);
3577     EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);
3578 }
3579 
3580 TEST(VerifyComplete, errorPathEncodeResponse)
3581 {
3582     std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00};
3583     auto responseMsg =
3584         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3585         reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());
3586     auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3587     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3588 
3589     rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3590     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3591 }
3592 
3593 TEST(ApplyComplete, goodPathDecodeRequest)
3594 {
3595     constexpr uint8_t applyResult1 =
3596         PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
3597     // DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
3598     constexpr std::bitset<16> compActivationModification1{0x30};
3599     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3600         applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
3601     auto requestMsg1 =
3602         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3603         reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3604     uint8_t outApplyResult = 0;
3605     bitfield16_t outCompActivationModification{};
3606     auto rc = decode_apply_complete_req(
3607         requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
3608         &outCompActivationModification);
3609     EXPECT_EQ(rc, PLDM_SUCCESS);
3610     EXPECT_EQ(outApplyResult, applyResult1);
3611     EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
3612 
3613     constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
3614     constexpr std::bitset<16> compActivationModification2{};
3615     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3616         applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3617     auto requestMsg2 =
3618         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3619         reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3620     rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3621                                    &outApplyResult,
3622                                    &outCompActivationModification);
3623     EXPECT_EQ(rc, PLDM_SUCCESS);
3624     EXPECT_EQ(outApplyResult, applyResult2);
3625     EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
3626 }
3627 
3628 TEST(ApplyComplete, errorPathDecodeRequest)
3629 {
3630     constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
3631     auto requestMsg1 =
3632         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3633         reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3634     uint8_t outApplyResult = 0;
3635     bitfield16_t outCompActivationModification{};
3636 
3637     auto rc = decode_apply_complete_req(
3638         nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
3639         &outCompActivationModification);
3640     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3641 
3642     rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3643                                    nullptr, &outCompActivationModification);
3644     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3645 
3646     rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3647                                    &outApplyResult, nullptr);
3648     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3649 
3650     rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
3651                                    &outCompActivationModification);
3652     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3653 
3654     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3655         applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
3656     auto requestMsg2 =
3657         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3658         reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3659     rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3660                                    &outApplyResult,
3661                                    &outCompActivationModification);
3662     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3663 }
3664 
3665 TEST(ApplyComplete, goodPathEncodeResponse)
3666 {
3667     constexpr uint8_t instanceId = 6;
3668     constexpr uint8_t completionCode = PLDM_SUCCESS;
3669     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3670         outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
3671     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3672         applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3673     auto responseMsg1 =
3674         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3675         reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
3676     auto rc = encode_apply_complete_resp(instanceId, completionCode,
3677                                          responseMsg1, sizeof(completionCode));
3678     EXPECT_EQ(rc, PLDM_SUCCESS);
3679     EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
3680 
3681     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3682         outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
3683     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3684         applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3685     auto responseMsg2 =
3686         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3687         reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
3688     rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3689                                     responseMsg2, sizeof(completionCode));
3690     EXPECT_EQ(rc, PLDM_SUCCESS);
3691     EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
3692 }
3693 
3694 TEST(ApplyComplete, errorPathEncodeResponse)
3695 {
3696     std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
3697     auto responseMsg =
3698         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3699         reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
3700     auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3701     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3702 
3703     rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3704     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3705 }
3706 
3707 TEST(ActivateFirmware, goodPathEncodeRequest)
3708 {
3709     constexpr uint8_t instanceId = 7;
3710 
3711     std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
3712     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3713     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3714 
3715     auto rc = encode_activate_firmware_req(
3716         instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
3717         sizeof(pldm_activate_firmware_req));
3718     EXPECT_EQ(rc, PLDM_SUCCESS);
3719 
3720     std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
3721         outRequest{0x87, 0x05, 0x1a, 0x01};
3722     EXPECT_EQ(request, outRequest);
3723 }
3724 
3725 TEST(ActivateFirmware, errorPathEncodeRequest)
3726 {
3727     std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
3728     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3729     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3730 
3731     auto rc = encode_activate_firmware_req(
3732         0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
3733         sizeof(pldm_activate_firmware_req));
3734     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3735 
3736     rc = encode_activate_firmware_req(
3737         0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
3738     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3739 
3740     rc = encode_activate_firmware_req(0, 2, requestMsg,
3741                                       sizeof(pldm_activate_firmware_req));
3742     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3743 }
3744 
3745 TEST(ActivateFirmware, goodPathDecodeResponse)
3746 {
3747     constexpr uint16_t estimatedTimeForActivation100s = 100;
3748     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3749         activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
3750     auto responseMsg1 =
3751         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3752         reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
3753 
3754     uint8_t completionCode = 0;
3755     uint16_t estimatedTimeForActivation = 0;
3756 
3757     auto rc = decode_activate_firmware_resp(
3758         responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
3759         &estimatedTimeForActivation);
3760 
3761     EXPECT_EQ(rc, PLDM_SUCCESS);
3762     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3763     EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
3764 
3765     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3766         activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
3767     auto responseMsg2 =
3768         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3769         reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data());
3770 
3771     rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
3772                                        &completionCode,
3773                                        &estimatedTimeForActivation);
3774 
3775     EXPECT_EQ(rc, PLDM_SUCCESS);
3776     EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
3777 }
3778 
3779 TEST(ActivateFirmware, errorPathDecodeResponse)
3780 {
3781     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3782         activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3783     auto responseMsg =
3784         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3785         reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
3786 
3787     uint8_t completionCode = 0;
3788     uint16_t estimatedTimeForActivation = 0;
3789 
3790     auto rc = decode_activate_firmware_resp(
3791         nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
3792         &estimatedTimeForActivation);
3793     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3794 
3795     rc = decode_activate_firmware_resp(responseMsg,
3796                                        sizeof(pldm_activate_firmware_resp),
3797                                        nullptr, &estimatedTimeForActivation);
3798     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3799 
3800     rc = decode_activate_firmware_resp(responseMsg,
3801                                        sizeof(pldm_activate_firmware_resp),
3802                                        &completionCode, nullptr);
3803     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3804 
3805     rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
3806                                        &estimatedTimeForActivation);
3807     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3808 
3809     rc = decode_activate_firmware_resp(
3810         responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
3811         &estimatedTimeForActivation);
3812     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3813 }
3814 
3815 TEST(GetStatus, goodPathEncodeRequest)
3816 {
3817     constexpr uint8_t instanceId = 8;
3818     std::array<uint8_t, hdrSize> request{};
3819     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3820     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3821 
3822     auto rc = encode_get_status_req(instanceId, requestMsg,
3823                                     PLDM_GET_STATUS_REQ_BYTES);
3824     EXPECT_EQ(rc, PLDM_SUCCESS);
3825 
3826     constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
3827     EXPECT_EQ(request, outRequest);
3828 }
3829 
3830 TEST(GetStatus, errorPathEncodeRequest)
3831 {
3832     std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
3833     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3834     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3835 
3836     auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
3837     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3838 
3839     rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);
3840     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3841 }
3842 
3843 TEST(GetStatus, goodPathDecodeResponse)
3844 {
3845     constexpr std::bitset<32> updateOptionFlagsEnabled1{0};
3846     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3847         getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
3848                            0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};
3849     auto responseMsg1 =
3850         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3851         reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
3852 
3853     uint8_t completionCode = 0;
3854     uint8_t currentState = 0;
3855     uint8_t previousState = 0;
3856     uint8_t auxState = 0;
3857     uint8_t auxStateStatus = 0;
3858     uint8_t progressPercent = 0;
3859     uint8_t reasonCode = 0;
3860     bitfield32_t updateOptionFlagsEnabled{0};
3861 
3862     auto rc = decode_get_status_resp(
3863         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3864         &currentState, &previousState, &auxState, &auxStateStatus,
3865         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3866 
3867     EXPECT_EQ(rc, PLDM_SUCCESS);
3868     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3869     EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);
3870     EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
3871     EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);
3872     EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);
3873     EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);
3874     EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
3875     EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);
3876 
3877     // Bit position 0 - Force update of component – FD will perform a force
3878     // update of the component.
3879     constexpr std::bitset<32> updateOptionFlagsEnabled2{1};
3880     constexpr uint8_t progressPercent2 = 50;
3881     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3882         getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,
3883                            0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};
3884     auto responseMsg2 =
3885         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3886         reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
3887 
3888     rc = decode_get_status_resp(
3889         responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
3890         &currentState, &previousState, &auxState, &auxStateStatus,
3891         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3892 
3893     EXPECT_EQ(rc, PLDM_SUCCESS);
3894     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3895     EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);
3896     EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
3897     EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);
3898     EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);
3899     EXPECT_EQ(progressPercent, progressPercent2);
3900     EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
3901     EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);
3902 
3903     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3904         getStatusResponse3{0x00, 0x00, 0x00, 0x04};
3905     auto responseMsg3 =
3906         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3907         reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
3908     rc = decode_get_status_resp(
3909         responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
3910         &currentState, &previousState, &auxState, &auxStateStatus,
3911         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3912     EXPECT_EQ(rc, PLDM_SUCCESS);
3913     EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);
3914 }
3915 
3916 TEST(GetStatus, errorPathDecodeResponse)
3917 {
3918     uint8_t completionCode = 0;
3919     uint8_t currentState = 0;
3920     uint8_t previousState = 0;
3921     uint8_t auxState = 0;
3922     uint8_t auxStateStatus = 0;
3923     uint8_t progressPercent = 0;
3924     uint8_t reasonCode = 0;
3925     bitfield32_t updateOptionFlagsEnabled{0};
3926 
3927     constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};
3928     auto responseMsg1 =
3929         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3930         reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
3931 
3932     auto rc = decode_get_status_resp(
3933         nullptr, getStatusResponse1.size() - hdrSize, &completionCode,
3934         &currentState, &previousState, &auxState, &auxStateStatus,
3935         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3936     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3937 
3938     rc = decode_get_status_resp(
3939         responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,
3940         &currentState, &previousState, &auxState, &auxStateStatus,
3941         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3942     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3943 
3944     rc = decode_get_status_resp(
3945         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3946         nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,
3947         &reasonCode, &updateOptionFlagsEnabled);
3948     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3949 
3950     rc = decode_get_status_resp(
3951         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3952         &currentState, nullptr, &auxState, &auxStateStatus, &progressPercent,
3953         &reasonCode, &updateOptionFlagsEnabled);
3954     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3955 
3956     rc = decode_get_status_resp(
3957         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3958         &currentState, &previousState, nullptr, &auxStateStatus,
3959         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3960     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3961 
3962     rc = decode_get_status_resp(
3963         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3964         &currentState, &previousState, &auxState, nullptr, &progressPercent,
3965         &reasonCode, &updateOptionFlagsEnabled);
3966     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3967 
3968     rc = decode_get_status_resp(
3969         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3970         &currentState, &previousState, &auxState, &auxStateStatus, nullptr,
3971         &reasonCode, &updateOptionFlagsEnabled);
3972     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3973 
3974     rc = decode_get_status_resp(
3975         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3976         &currentState, &previousState, &auxState, &auxStateStatus,
3977         &progressPercent, nullptr, &updateOptionFlagsEnabled);
3978     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3979 
3980     rc = decode_get_status_resp(
3981         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3982         &currentState, &previousState, &auxState, &auxStateStatus,
3983         &progressPercent, &reasonCode, nullptr);
3984     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3985 
3986     rc = decode_get_status_resp(
3987         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3988         &currentState, &previousState, &auxState, &auxStateStatus,
3989         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3990     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3991 
3992     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>
3993         getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3994                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3995     auto responseMsg2 =
3996         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3997         reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
3998     rc = decode_get_status_resp(
3999         responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4000         &currentState, &previousState, &auxState, &auxStateStatus,
4001         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4002     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4003 
4004     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4005         getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
4006                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4007     auto responseMsg3 =
4008         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4009         reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4010     rc = decode_get_status_resp(
4011         responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4012         &currentState, &previousState, &auxState, &auxStateStatus,
4013         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4014     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4015 
4016     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4017         getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
4018                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4019     auto responseMsg4 =
4020         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4021         reinterpret_cast<const pldm_msg*>(getStatusResponse4.data());
4022     rc = decode_get_status_resp(
4023         responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,
4024         &currentState, &previousState, &auxState, &auxStateStatus,
4025         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4026     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4027 
4028     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4029         getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
4030                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4031     auto responseMsg5 =
4032         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4033         reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());
4034     rc = decode_get_status_resp(
4035         responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,
4036         &currentState, &previousState, &auxState, &auxStateStatus,
4037         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4038     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4039 
4040     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4041         getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4042                            0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4043     auto responseMsg6 =
4044         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4045         reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());
4046     rc = decode_get_status_resp(
4047         responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,
4048         &currentState, &previousState, &auxState, &auxStateStatus,
4049         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4050     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4051 
4052     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4053         getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4054                            0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
4055     auto responseMsg7 =
4056         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4057         reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());
4058     rc = decode_get_status_resp(
4059         responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,
4060         &currentState, &previousState, &auxState, &auxStateStatus,
4061         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4062     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4063 
4064     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4065         getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4066                            0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00};
4067     auto responseMsg8 =
4068         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4069         reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());
4070     rc = decode_get_status_resp(
4071         responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,
4072         &currentState, &previousState, &auxState, &auxStateStatus,
4073         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4074     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4075 
4076     // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is
4077     // IDLE
4078     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4079         getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
4080                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4081     auto responseMsg9 =
4082         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4083         reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());
4084     rc = decode_get_status_resp(
4085         responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,
4086         &currentState, &previousState, &auxState, &auxStateStatus,
4087         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4088     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4089 }
4090 
4091 TEST(CancelUpdateComponent, goodPathEncodeRequest)
4092 {
4093     constexpr uint8_t instanceId = 9;
4094     std::array<uint8_t, hdrSize> request{};
4095     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4096     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4097 
4098     auto rc = encode_cancel_update_component_req(
4099         instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4100     EXPECT_EQ(rc, PLDM_SUCCESS);
4101 
4102     constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
4103     EXPECT_EQ(request, outRequest);
4104 }
4105 
4106 TEST(CancelUpdateComponent, errorPathEncodeRequest)
4107 {
4108     std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
4109     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4110     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4111 
4112     auto rc = encode_cancel_update_component_req(
4113         0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4114     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4115 
4116     rc = encode_cancel_update_component_req(
4117         0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);
4118     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4119 }
4120 
4121 TEST(CancelUpdateComponent, testGoodDecodeResponse)
4122 {
4123     uint8_t completionCode = 0;
4124     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4125         cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};
4126     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4127     auto responseMsg1 = reinterpret_cast<const pldm_msg*>(
4128         cancelUpdateComponentResponse1.data());
4129     auto rc = decode_cancel_update_component_resp(
4130         responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,
4131         &completionCode);
4132     EXPECT_EQ(rc, PLDM_SUCCESS);
4133     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4134 
4135     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4136         cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};
4137     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4138     auto responseMsg2 = reinterpret_cast<const pldm_msg*>(
4139         cancelUpdateComponentResponse2.data());
4140     rc = decode_cancel_update_component_resp(
4141         responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,
4142         &completionCode);
4143     EXPECT_EQ(rc, PLDM_SUCCESS);
4144     EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4145 }
4146 
4147 TEST(CancelUpdateComponent, testBadDecodeResponse)
4148 {
4149     uint8_t completionCode = 0;
4150     constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{
4151         0x00, 0x00, 0x00};
4152     auto responseMsg =
4153         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4154         reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data());
4155 
4156     auto rc = decode_cancel_update_component_resp(
4157         nullptr, cancelUpdateComponentResponse.size() - hdrSize,
4158         &completionCode);
4159     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4160 
4161     rc = decode_cancel_update_component_resp(
4162         responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);
4163     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4164 
4165     rc = decode_cancel_update_component_resp(
4166         responseMsg, cancelUpdateComponentResponse.size() - hdrSize,
4167         &completionCode);
4168     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4169 }
4170 
4171 TEST(CancelUpdate, goodPathEncodeRequest)
4172 {
4173     constexpr uint8_t instanceId = 10;
4174     std::array<uint8_t, hdrSize> request{};
4175     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4176     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4177 
4178     auto rc = encode_cancel_update_req(instanceId, requestMsg,
4179                                        PLDM_CANCEL_UPDATE_REQ_BYTES);
4180     EXPECT_EQ(rc, PLDM_SUCCESS);
4181 
4182     constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
4183     EXPECT_EQ(request, outRequest);
4184 }
4185 
4186 TEST(CancelUpdate, errorPathEncodeRequest)
4187 {
4188     std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
4189     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4190     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4191 
4192     auto rc =
4193         encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
4194     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4195 
4196     rc = encode_cancel_update_req(0, requestMsg,
4197                                   PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
4198     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4199 }
4200 
4201 TEST(CancelUpdate, goodPathDecodeResponse)
4202 {
4203     constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
4204     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4205         cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4206                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4207     auto responseMsg1 =
4208         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4209         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4210     uint8_t completionCode = 0;
4211     bool8_t nonFunctioningComponentIndication = 0;
4212     bitfield64_t nonFunctioningComponentBitmap{0};
4213     auto rc = decode_cancel_update_resp(
4214         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4215         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4216     EXPECT_EQ(rc, PLDM_SUCCESS);
4217     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4218     EXPECT_EQ(nonFunctioningComponentIndication,
4219               PLDM_FWUP_COMPONENTS_FUNCTIONING);
4220     EXPECT_EQ(nonFunctioningComponentBitmap.value,
4221               nonFunctioningComponentBitmap1);
4222 
4223     constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
4224     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4225         cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
4226                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4227     auto responseMsg2 =
4228         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4229         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4230     rc = decode_cancel_update_resp(
4231         responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4232         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4233     EXPECT_EQ(rc, PLDM_SUCCESS);
4234     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4235     EXPECT_EQ(nonFunctioningComponentIndication,
4236               PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING);
4237     EXPECT_EQ(nonFunctioningComponentBitmap.value,
4238               nonFunctioningComponentBitmap2);
4239 
4240     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4241         cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
4242     auto responseMsg3 =
4243         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4244         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4245     rc = decode_cancel_update_resp(
4246         responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4247         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4248     EXPECT_EQ(rc, PLDM_SUCCESS);
4249     EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4250 }
4251 
4252 TEST(CancelUpdate, errorPathDecodeResponse)
4253 {
4254     constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
4255                                                                  0x00};
4256     auto responseMsg1 =
4257         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4258         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4259     uint8_t completionCode = 0;
4260     bool8_t nonFunctioningComponentIndication = 0;
4261     bitfield64_t nonFunctioningComponentBitmap{0};
4262 
4263     auto rc = decode_cancel_update_resp(
4264         nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4265         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4266     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4267 
4268     rc = decode_cancel_update_resp(
4269         responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
4270         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4271     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4272 
4273     rc = decode_cancel_update_resp(
4274         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4275         nullptr, &nonFunctioningComponentBitmap);
4276     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4277 
4278     rc = decode_cancel_update_resp(
4279         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4280         &nonFunctioningComponentIndication, nullptr);
4281     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4282 
4283     rc = decode_cancel_update_resp(
4284         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4285         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4286     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4287 
4288     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4289         cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
4290     auto responseMsg2 =
4291         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4292         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4293     rc = decode_cancel_update_resp(
4294         responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4295         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4296     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4297 
4298     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4299         cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
4300                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4301     auto responseMsg3 =
4302         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4303         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4304     rc = decode_cancel_update_resp(
4305         responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4306         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4307     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4308 }
4309