xref: /openbmc/libpldm/tests/dsp/firmware_update.cpp (revision d2f8a7e3b37634ec0e42230a8ad14411f34e9149)
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_params_req params_req{
2156         0x0, PLDM_GET_FIRSTPART};
2157     constexpr size_t payload_length =
2158         PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_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_params_req(
2164         instanceId, &params_req, requestPtr, payload_length);
2165     EXPECT_EQ(rc, 0);
2166 
2167     std::array<uint8_t, hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_REQ_BYTES>
2168         expectedReq{0x81, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01};
2169     EXPECT_EQ(requestMsg, expectedReq);
2170 }
2171 #endif
2172 
2173 #ifdef LIBPLDM_API_TESTING
2174 TEST(GetDownstreamFirmwareParameters, encodeRequestInvalidTransferOperationFlag)
2175 {
2176     constexpr uint8_t instanceId = 1;
2177     // Setup invalid transfer operation flag
2178     constexpr pldm_get_downstream_firmware_params_req params_req{
2179         0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
2180     constexpr size_t payload_length =
2181         PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_REQ_BYTES;
2182     std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
2183     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2184     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2185 
2186     auto rc = encode_get_downstream_firmware_params_req(
2187         instanceId, &params_req, requestPtr, payload_length);
2188     EXPECT_EQ(rc, -EBADMSG);
2189 }
2190 #endif
2191 
2192 #ifdef LIBPLDM_API_TESTING
2193 TEST(GetDownstreamFirmwareParameters, encodeRequestErrorBufSize)
2194 {
2195     constexpr uint8_t instanceId = 1;
2196     // Setup invalid transfer operation flag
2197     constexpr pldm_get_downstream_firmware_params_req params_req{
2198         0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
2199     constexpr size_t payload_length =
2200         PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_REQ_BYTES -
2201         1 /* inject erro length*/;
2202 
2203     std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
2204     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2205     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2206 
2207     auto rc = encode_get_downstream_firmware_params_req(
2208         instanceId, &params_req, requestPtr, payload_length);
2209     EXPECT_EQ(rc, -EOVERFLOW);
2210 }
2211 #endif
2212 
2213 #ifdef LIBPLDM_API_TESTING
2214 TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponse)
2215 {
2216     /** Count is not fixed here taking it as 1, and the downstream device's
2217      *  version strings length are set to 8
2218      */
2219     constexpr uint16_t downstreamDeviceCount = 1;
2220     constexpr uint8_t activeComponentVersionStringLength = 8;
2221     constexpr uint8_t pendingComponentVersionStringLength = 8;
2222     constexpr size_t downstreamDeviceParamTableLen =
2223         sizeof(pldm_component_parameter_entry) +
2224         activeComponentVersionStringLength +
2225         pendingComponentVersionStringLength;
2226     constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2227     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2228     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2229     constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2230 
2231     std::array<uint8_t, hdrSize +
2232                             PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_RESP_MIN_LEN +
2233                             downstreamDeviceParamTableLen>
2234         responseMsg{};
2235 
2236     int rc = 0;
2237 
2238     struct pldm_msgbuf _buf;
2239     struct pldm_msgbuf* buf = &_buf;
2240     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
2241                                 responseMsg.size() - hdrSize);
2242     EXPECT_EQ(rc, 0);
2243 
2244     pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2245     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2246     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2247     pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2248     pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2249 
2250     /** Filling paramter table, the correctness of the downstream devices data
2251      *  is not checked in this test case so filling with 0xff
2252      */
2253     std::fill_n(responseMsg.data() + hdrSize +
2254                     PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_RESP_MIN_LEN,
2255                 downstreamDeviceParamTableLen, 0xff);
2256     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2257     auto table = reinterpret_cast<pldm_component_parameter_entry*>(
2258         responseMsg.data() + hdrSize +
2259         PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_RESP_MIN_LEN);
2260     table->active_comp_ver_str_len = activeComponentVersionStringLength;
2261     table->pending_comp_ver_str_len = pendingComponentVersionStringLength;
2262 
2263     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2264     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
2265     struct pldm_get_downstream_firmware_params_resp resp_data = {};
2266     struct variable_field downstreamDeviceParamTable = {};
2267 
2268     rc = decode_get_downstream_firmware_params_resp(
2269         response, responseMsg.size() - hdrSize, &resp_data,
2270         &downstreamDeviceParamTable);
2271 
2272     EXPECT_EQ(rc, 0);
2273     EXPECT_EQ(resp_data.completion_code, complition_code_resp);
2274     EXPECT_EQ(resp_data.next_data_transfer_handle,
2275               next_data_transfer_handle_resp);
2276     EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2277     EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
2278     EXPECT_EQ(downstreamDeviceParamTable.length, downstreamDeviceParamTableLen);
2279     EXPECT_EQ(true,
2280               std::equal(downstreamDeviceParamTable.ptr,
2281                          downstreamDeviceParamTable.ptr +
2282                              downstreamDeviceParamTable.length,
2283                          responseMsg.begin() + hdrSize +
2284                              PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_RESP_MIN_LEN,
2285                          responseMsg.end()));
2286 }
2287 #endif
2288 
2289 #ifdef LIBPLDM_API_TESTING
2290 TEST(GetDownstreamFirmwareParameters, decodeResponseInvalidLength)
2291 {
2292     /** Count is not fixed here taking it as 1, and the downstream device's
2293      *  version strings length are set to 8
2294      */
2295     constexpr uint16_t downstreamDeviceCount = 1;
2296     constexpr uint8_t activeComponentVersionStringLength = 8;
2297     constexpr uint8_t pendingComponentVersionStringLength = 8;
2298     constexpr size_t downstreamDeviceParamTableLen =
2299         PLDM_DOWNSTREAM_DEVICE_PARAMETER_ENTRY_MIN_LEN +
2300         activeComponentVersionStringLength +
2301         pendingComponentVersionStringLength;
2302     constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2303     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2304     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2305     constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2306 
2307     std::array<uint8_t,
2308                hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_RESP_MIN_LEN +
2309                    downstreamDeviceParamTableLen - 1 /* inject error length*/>
2310         responseMsg{};
2311 
2312     int rc = 0;
2313 
2314     struct pldm_msgbuf _buf;
2315     struct pldm_msgbuf* buf = &_buf;
2316     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
2317                                 responseMsg.size() - hdrSize);
2318     EXPECT_EQ(rc, 0);
2319 
2320     pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2321     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2322     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2323     pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2324     pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2325 
2326     /** Filling paramter table, the correctness of the downstream devices data
2327      *  is not checked in this test case so filling with 0xff
2328      */
2329     std::fill_n(responseMsg.data() + hdrSize +
2330                     PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMS_RESP_MIN_LEN,
2331                 downstreamDeviceParamTableLen - 1 /* inject error length*/,
2332                 0xff);
2333 
2334     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2335     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
2336     struct pldm_get_downstream_firmware_params_resp resp_data = {};
2337     struct variable_field downstreamDeviceParamTable = {};
2338 
2339     rc = decode_get_downstream_firmware_params_resp(
2340         response, responseMsg.size() - hdrSize, &resp_data,
2341         &downstreamDeviceParamTable);
2342     EXPECT_EQ(rc, 0);
2343 
2344     pldm_downstream_device_parameter_entry entry{};
2345     variable_field versions{};
2346 
2347     EXPECT_NE(decode_downstream_device_parameter_table_entry(
2348                   &downstreamDeviceParamTable, &entry, &versions),
2349               0);
2350 }
2351 #endif
2352 
2353 #ifdef LIBPLDM_API_TESTING
2354 TEST(GetDownstreamFirmwareParameters, goodPathDecodeDownstreamDeviceParamTable)
2355 {
2356     // Arbitrary downstream device index
2357     constexpr uint16_t downstreamDeviceIndex = 1;
2358     // Arbitrary value for component classification
2359     constexpr uint32_t comparisonStamp = 0x12345678;
2360     // Arbitrary value for component activation methods
2361     constexpr uint16_t compActivationMethods = 0xbbdd;
2362     // Arbitrary value for capabilities during update
2363     constexpr uint32_t capabilitiesDuringUpdate = 0xbadbeefe;
2364     // ActiveCompImageSetVerStrLen is not fixed here taking it as 8
2365     constexpr uint8_t activeCompVerStrLen = 8;
2366     // PendingCompImageSetVerStrLen is not fixed here taking it as 8
2367     constexpr uint8_t pendingCompVerStrLen = 8;
2368     // Arbitrary value for release date
2369     constexpr char release_date[8] = {'2', '0', '2', '4', '0', '6', '2', '1'};
2370     // Arbitrary version strings
2371     constexpr char activeCompVerStr[activeCompVerStrLen] = {'1', '2', '3', '4',
2372                                                             '5', '6', '7', '8'};
2373     constexpr char pendingCompVerStr[pendingCompVerStrLen] = {
2374         'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
2375 
2376     std::array<uint8_t, PLDM_DOWNSTREAM_DEVICE_PARAMETER_ENTRY_MIN_LEN +
2377                             activeCompVerStrLen + pendingCompVerStrLen>
2378         responseMsg{};
2379 
2380     int rc = 0;
2381 
2382     struct pldm_msgbuf _buf;
2383     struct pldm_msgbuf* buf = &_buf;
2384     rc = pldm_msgbuf_init_errno(buf,
2385                                 PLDM_DOWNSTREAM_DEVICE_PARAMETER_ENTRY_MIN_LEN,
2386                                 responseMsg.data(), responseMsg.size());
2387     EXPECT_EQ(rc, 0);
2388 
2389     pldm_msgbuf_insert_uint16(buf, downstreamDeviceIndex);
2390     pldm_msgbuf_insert_uint32(buf, comparisonStamp);
2391     pldm_msgbuf_insert_uint8(buf, (uint8_t)PLDM_STR_TYPE_ASCII);
2392     pldm_msgbuf_insert_uint8(buf, activeCompVerStrLen);
2393     rc = pldm_msgbuf_insert_array_char(buf, sizeof(release_date), release_date,
2394                                        sizeof(release_date));
2395     ASSERT_EQ(rc, 0);
2396     pldm_msgbuf_insert_uint32(buf, comparisonStamp);
2397     pldm_msgbuf_insert_uint8(buf, (uint8_t)PLDM_STR_TYPE_ASCII);
2398     pldm_msgbuf_insert_uint8(buf, pendingCompVerStrLen);
2399     rc = pldm_msgbuf_insert_array_char(buf, sizeof(release_date), release_date,
2400                                        sizeof(release_date));
2401     ASSERT_EQ(rc, 0);
2402     pldm_msgbuf_insert_uint16(buf, compActivationMethods);
2403     pldm_msgbuf_insert_uint32(buf, capabilitiesDuringUpdate);
2404     rc = pldm_msgbuf_insert_array_char(
2405         buf, activeCompVerStrLen, activeCompVerStr, sizeof(activeCompVerStr));
2406     ASSERT_EQ(rc, 0);
2407     rc = pldm_msgbuf_insert_array_char(buf, pendingCompVerStrLen,
2408                                        pendingCompVerStr,
2409                                        sizeof(pendingCompVerStr));
2410     ASSERT_EQ(rc, 0);
2411 
2412     variable_field rawData = {.ptr = responseMsg.data(),
2413                               .length = responseMsg.size()};
2414     struct pldm_downstream_device_parameter_entry_versions entry_version = {};
2415     struct variable_field versions = {};
2416     const uint8_t* original_ptr = rawData.ptr;
2417 
2418     rc = decode_downstream_device_parameter_table_entry(
2419         &rawData, &entry_version.entry, &versions);
2420 
2421     EXPECT_EQ(rc, 0);
2422     EXPECT_EQ(rawData.ptr, original_ptr +
2423                                PLDM_DOWNSTREAM_DEVICE_PARAMETER_ENTRY_MIN_LEN +
2424                                entry_version.entry.active_comp_ver_str_len +
2425                                entry_version.entry.pending_comp_ver_str_len);
2426     EXPECT_EQ(rawData.length, 0);
2427 
2428     // Further decode the version strings
2429     rc = decode_downstream_device_parameter_table_entry_versions(
2430         &versions, &entry_version.entry, entry_version.active_comp_ver_str,
2431         sizeof(entry_version.active_comp_ver_str),
2432         entry_version.pending_comp_ver_str,
2433         sizeof(entry_version.pending_comp_ver_str));
2434     struct pldm_downstream_device_parameter_entry entry = entry_version.entry;
2435     EXPECT_EQ(rc, 0);
2436 
2437     // Verify the decoded table entry
2438     EXPECT_EQ(entry.downstream_device_index, downstreamDeviceIndex);
2439     EXPECT_EQ(entry.active_comp_comparison_stamp, comparisonStamp);
2440     EXPECT_EQ(entry.active_comp_ver_str_type, PLDM_STR_TYPE_ASCII);
2441     EXPECT_EQ(entry.active_comp_ver_str_len, activeCompVerStrLen);
2442     EXPECT_EQ(0, memcmp(entry.active_comp_release_date, release_date,
2443                         sizeof(release_date)));
2444     EXPECT_EQ(entry.pending_comp_comparison_stamp, comparisonStamp);
2445     EXPECT_EQ(entry.pending_comp_ver_str_type, PLDM_STR_TYPE_ASCII);
2446     EXPECT_EQ(entry.pending_comp_ver_str_len, pendingCompVerStrLen);
2447     EXPECT_EQ(0, memcmp(entry.pending_comp_release_date, release_date,
2448                         sizeof(release_date)));
2449     EXPECT_EQ(entry.comp_activation_methods.value, compActivationMethods);
2450     EXPECT_EQ(entry.capabilities_during_update.value, capabilitiesDuringUpdate);
2451     EXPECT_EQ(entry.active_comp_ver_str_len + entry.pending_comp_ver_str_len,
2452               versions.length);
2453     EXPECT_EQ(0, memcmp(versions.ptr, activeCompVerStr, activeCompVerStrLen));
2454     EXPECT_EQ(0, memcmp(versions.ptr + entry.active_comp_ver_str_len,
2455                         pendingCompVerStr, pendingCompVerStrLen));
2456 
2457     // Verify version strings
2458     EXPECT_EQ(0, memcmp(entry_version.entry.active_comp_ver_str,
2459                         activeCompVerStr, activeCompVerStrLen));
2460     EXPECT_EQ('\0',
2461               entry_version.entry.active_comp_ver_str[activeCompVerStrLen]);
2462     EXPECT_EQ(0, memcmp(entry_version.entry.pending_comp_ver_str,
2463                         pendingCompVerStr, pendingCompVerStrLen));
2464     EXPECT_EQ('\0',
2465               entry_version.entry.pending_comp_ver_str[pendingCompVerStrLen]);
2466     EXPECT_EQ(0, memcmp(entry_version.active_comp_ver_str, activeCompVerStr,
2467                         activeCompVerStrLen));
2468     EXPECT_EQ('\0', entry_version.active_comp_ver_str[activeCompVerStrLen]);
2469     EXPECT_EQ(0, memcmp(entry_version.pending_comp_ver_str, pendingCompVerStr,
2470                         pendingCompVerStrLen));
2471     EXPECT_EQ('\0', entry_version.pending_comp_ver_str[pendingCompVerStrLen]);
2472 }
2473 #endif
2474 
2475 #ifdef LIBPLDM_API_TESTING
2476 TEST(GetDownstreamFirmwareParameters, goodPathDecodeDownstreamTableVersions)
2477 {
2478     // Arbitrary component version string length
2479     constexpr uint8_t activeCompVerStrLen = 8;
2480     constexpr uint8_t pendingCompVerStrLen = 8;
2481     // Arbitrary ActiveVersionStr and pendingVersionStr
2482     constexpr char versionsStr[] = {'1', '2', '3', '4', '5', '6', '7', '8',
2483                                     'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
2484     const struct variable_field versions = {
2485         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2486         .ptr = reinterpret_cast<const uint8_t*>(versionsStr),
2487         .length = sizeof(versionsStr)};
2488 
2489     struct pldm_downstream_device_parameter_entry_versions entryVersion = {};
2490     entryVersion.entry.active_comp_ver_str_len = activeCompVerStrLen;
2491     entryVersion.entry.pending_comp_ver_str_len = pendingCompVerStrLen;
2492 
2493     int rc = decode_downstream_device_parameter_table_entry_versions(
2494         &versions, &entryVersion.entry, entryVersion.active_comp_ver_str,
2495         sizeof(entryVersion.active_comp_ver_str),
2496         entryVersion.pending_comp_ver_str,
2497         sizeof(entryVersion.pending_comp_ver_str));
2498 
2499     EXPECT_EQ(rc, 0);
2500     EXPECT_EQ(0, memcmp(entryVersion.active_comp_ver_str, versions.ptr,
2501                         activeCompVerStrLen));
2502     EXPECT_EQ('\0', entryVersion.active_comp_ver_str[activeCompVerStrLen]);
2503     EXPECT_EQ(0,
2504               memcmp(entryVersion.pending_comp_ver_str,
2505                      versions.ptr + activeCompVerStrLen, pendingCompVerStrLen));
2506     EXPECT_EQ('\0', entryVersion.pending_comp_ver_str[activeCompVerStrLen]);
2507     EXPECT_EQ(0, memcmp(entryVersion.entry.active_comp_ver_str, versions.ptr,
2508                         activeCompVerStrLen));
2509     EXPECT_EQ('\0',
2510               entryVersion.entry.pending_comp_ver_str[activeCompVerStrLen]);
2511     EXPECT_EQ(0,
2512               memcmp(entryVersion.entry.pending_comp_ver_str,
2513                      versions.ptr + activeCompVerStrLen, pendingCompVerStrLen));
2514     EXPECT_EQ('\0',
2515               entryVersion.entry.pending_comp_ver_str[activeCompVerStrLen]);
2516 }
2517 #endif
2518 
2519 #ifdef LIBPLDM_API_TESTING
2520 TEST(GetDownstreamFirmwareParameters, decodeInvalidDownstreamTableVersions)
2521 {
2522     // Arbitrary ActiveVersionStr and pendingVersionStr
2523     constexpr char versionsStr[] = {'1', '2', '3', '4', '5', '6', '7', '8',
2524                                     'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
2525     const struct variable_field versions = {
2526         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2527         .ptr = reinterpret_cast<const uint8_t*>(versionsStr),
2528         .length = sizeof(versionsStr)};
2529 
2530     struct pldm_downstream_device_parameter_entry_versions entryVersion = {};
2531 
2532     int rc = decode_downstream_device_parameter_table_entry_versions(
2533         &versions, nullptr, entryVersion.active_comp_ver_str,
2534         sizeof(entryVersion.active_comp_ver_str),
2535         entryVersion.pending_comp_ver_str,
2536         sizeof(entryVersion.pending_comp_ver_str));
2537     EXPECT_EQ(rc, -EINVAL);
2538 }
2539 #endif
2540 
2541 #ifdef LIBPLDM_API_TESTING
2542 TEST(GetDownstreamFirmwareParameters, decodeOverflowDownstreamTableVersions)
2543 {
2544     // Arbitrary component version string length
2545     constexpr uint8_t activeCompVerStrLen = 8;
2546     constexpr uint8_t pendingCompVerStrLen = 8;
2547     // Arbitrary ActiveVersionStr and pendingVersionStr
2548     constexpr char versionsStr[] = {'1', '2', '3', '4', '5', '6', '7', '8',
2549                                     'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
2550     const struct variable_field versions = {
2551         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2552         .ptr = reinterpret_cast<const uint8_t*>(versionsStr),
2553         .length = sizeof(versionsStr) - 1 // Inject error length
2554     };
2555 
2556     struct pldm_downstream_device_parameter_entry_versions entryVersion = {};
2557     entryVersion.entry.active_comp_ver_str_len = activeCompVerStrLen;
2558     entryVersion.entry.pending_comp_ver_str_len = pendingCompVerStrLen;
2559 
2560     EXPECT_EQ(decode_downstream_device_parameter_table_entry_versions(
2561                   &versions, &entryVersion.entry,
2562                   entryVersion.active_comp_ver_str,
2563                   sizeof(entryVersion.active_comp_ver_str),
2564                   entryVersion.pending_comp_ver_str,
2565                   sizeof(entryVersion.pending_comp_ver_str)),
2566               -EOVERFLOW);
2567 }
2568 #endif
2569 
2570 TEST(RequestUpdate, goodPathEncodeRequest)
2571 {
2572     constexpr uint8_t instanceId = 1;
2573     constexpr uint32_t maxTransferSize = 512;
2574     constexpr uint16_t numOfComp = 3;
2575     constexpr uint8_t maxOutstandingTransferReq = 2;
2576     constexpr uint16_t pkgDataLen = 0x1234;
2577     constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2578     constexpr uint8_t compImgSetVerStrLen =
2579         static_cast<uint8_t>(compImgSetVerStr.size());
2580     variable_field compImgSetVerStrInfo{};
2581     compImgSetVerStrInfo.ptr =
2582         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2583         reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2584     compImgSetVerStrInfo.length = compImgSetVerStrLen;
2585 
2586     std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2587                             compImgSetVerStrLen>
2588         request{};
2589     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2590     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2591 
2592     auto rc = encode_request_update_req(
2593         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2594         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2595         &compImgSetVerStrInfo, requestMsg,
2596         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2597     EXPECT_EQ(rc, PLDM_SUCCESS);
2598 
2599     std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2600                             compImgSetVerStrLen>
2601         outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00,
2602                    0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e,
2603                    0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30};
2604     EXPECT_EQ(request, outRequest);
2605 }
2606 
2607 TEST(RequestUpdate, errorPathEncodeRequest)
2608 {
2609     constexpr uint8_t instanceId = 1;
2610     uint32_t maxTransferSize = 512;
2611     constexpr uint16_t numOfComp = 3;
2612     uint8_t maxOutstandingTransferReq = 2;
2613     constexpr uint16_t pkgDataLen = 0x1234;
2614     constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2615     uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2616     variable_field compImgSetVerStrInfo{};
2617     compImgSetVerStrInfo.ptr =
2618         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2619         reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2620     compImgSetVerStrInfo.length = compImgSetVerStrLen;
2621 
2622     std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2623                             compImgSetVerStr.size()>
2624         request{};
2625     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2626     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2627 
2628     auto rc = encode_request_update_req(
2629         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2630         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr,
2631         requestMsg,
2632         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2633     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2634 
2635     compImgSetVerStrInfo.ptr = nullptr;
2636     rc = encode_request_update_req(
2637         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2638         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2639         &compImgSetVerStrInfo, requestMsg,
2640         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2641     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2642     compImgSetVerStrInfo.ptr =
2643         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2644         reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2645 
2646     rc = encode_request_update_req(
2647         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2648         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2649         &compImgSetVerStrInfo, nullptr,
2650         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2651     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2652 
2653     rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp,
2654                                    maxOutstandingTransferReq, pkgDataLen,
2655                                    PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2656                                    &compImgSetVerStrInfo, requestMsg, 0);
2657     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2658 
2659     compImgSetVerStrLen = 0;
2660     rc = encode_request_update_req(
2661         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2662         pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr,
2663         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2664     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2665     compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2666 
2667     compImgSetVerStrInfo.length = 0xffff;
2668     rc = encode_request_update_req(
2669         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2670         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2671         &compImgSetVerStrInfo, nullptr,
2672         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2673     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2674     compImgSetVerStrInfo.length = compImgSetVerStrLen;
2675 
2676     maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1;
2677     rc = encode_request_update_req(
2678         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2679         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2680         &compImgSetVerStrInfo, nullptr,
2681         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2682     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2683     maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE;
2684 
2685     maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ - 1;
2686     rc = encode_request_update_req(
2687         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2688         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2689         &compImgSetVerStrInfo, nullptr,
2690         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2691     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2692     maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ;
2693 
2694     rc = encode_request_update_req(
2695         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2696         pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen,
2697         &compImgSetVerStrInfo, nullptr,
2698         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2699     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2700 }
2701 
2702 TEST(RequestUpdate, goodPathDecodeResponse)
2703 {
2704     constexpr uint16_t fdMetaDataLen = 1024;
2705     constexpr uint8_t fdWillSendPkgData = 1;
2706     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)>
2707         requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01};
2708 
2709     auto responseMsg1 =
2710         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2711         reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data());
2712     uint8_t outCompletionCode = 0;
2713     uint16_t outFdMetaDataLen = 0;
2714     uint8_t outFdWillSendPkgData = 0;
2715 
2716     auto rc = decode_request_update_resp(
2717         responseMsg1, requestUpdateResponse1.size() - hdrSize,
2718         &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2719     EXPECT_EQ(rc, PLDM_SUCCESS);
2720     EXPECT_EQ(outCompletionCode, PLDM_SUCCESS);
2721     EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen);
2722     EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData);
2723 
2724     outCompletionCode = 0;
2725     outFdMetaDataLen = 0;
2726     outFdWillSendPkgData = 0;
2727 
2728     constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)>
2729         requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
2730     auto responseMsg2 =
2731         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2732         reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data());
2733     rc = decode_request_update_resp(
2734         responseMsg2, requestUpdateResponse2.size() - hdrSize,
2735         &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2736     EXPECT_EQ(rc, PLDM_SUCCESS);
2737     EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
2738 }
2739 
2740 TEST(RequestUpdate, errorPathDecodeResponse)
2741 {
2742     constexpr std::array<uint8_t,
2743                          hdrSize + sizeof(pldm_request_update_resp) - 1>
2744         requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
2745 
2746     auto responseMsg =
2747         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2748         reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data());
2749     uint8_t outCompletionCode = 0;
2750     uint16_t outFdMetaDataLen = 0;
2751     uint8_t outFdWillSendPkgData = 0;
2752 
2753     auto rc = decode_request_update_resp(
2754         nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2755         &outFdMetaDataLen, &outFdWillSendPkgData);
2756     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2757 
2758     rc = decode_request_update_resp(
2759         responseMsg, requestUpdateResponse.size() - hdrSize, nullptr,
2760         &outFdMetaDataLen, &outFdWillSendPkgData);
2761     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2762 
2763     rc = decode_request_update_resp(
2764         responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2765         nullptr, &outFdWillSendPkgData);
2766     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2767 
2768     rc = decode_request_update_resp(
2769         responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2770         &outFdMetaDataLen, nullptr);
2771     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2772 
2773     rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode,
2774                                     &outFdMetaDataLen, &outFdWillSendPkgData);
2775     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2776 
2777     rc = decode_request_update_resp(
2778         responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2779         &outFdMetaDataLen, &outFdWillSendPkgData);
2780     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2781 }
2782 
2783 TEST(PassComponentTable, goodPathEncodeRequest)
2784 {
2785     constexpr uint8_t instanceId = 1;
2786     constexpr uint16_t compIdentifier = 400;
2787     constexpr uint8_t compClassificationIndex = 40;
2788     constexpr uint32_t compComparisonStamp = 0x12345678;
2789     constexpr std::string_view compVerStr = "0penBmcv1.1";
2790     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2791     variable_field compVerStrInfo{};
2792     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2793     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2794     compVerStrInfo.length = compVerStrLen;
2795 
2796     std::array<uint8_t,
2797                hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2798         request{};
2799     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2800     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2801 
2802     auto rc = encode_pass_component_table_req(
2803         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2804         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2805         compVerStrLen, &compVerStrInfo, requestMsg,
2806         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2807     EXPECT_EQ(rc, PLDM_SUCCESS);
2808 
2809     std::array<uint8_t,
2810                hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2811         outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28,
2812                    0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65,
2813                    0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31};
2814     EXPECT_EQ(request, outRequest);
2815 }
2816 
2817 TEST(PassComponentTable, errorPathEncodeRequest)
2818 {
2819     constexpr uint8_t instanceId = 1;
2820     constexpr uint16_t compIdentifier = 400;
2821     constexpr uint8_t compClassificationIndex = 40;
2822     constexpr uint32_t compComparisonStamp = 0x12345678;
2823     constexpr std::string_view compVerStr = "0penBmcv1.1";
2824     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2825     variable_field compVerStrInfo{};
2826     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2827     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2828     compVerStrInfo.length = compVerStrLen;
2829 
2830     std::array<uint8_t,
2831                hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2832         request{};
2833     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2834     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2835 
2836     auto rc = encode_pass_component_table_req(
2837         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2838         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2839         compVerStrLen, nullptr, requestMsg,
2840         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2841     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2842 
2843     compVerStrInfo.ptr = nullptr;
2844     rc = encode_pass_component_table_req(
2845         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2846         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2847         compVerStrLen, &compVerStrInfo, requestMsg,
2848         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2849     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2850     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2851     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2852 
2853     rc = encode_pass_component_table_req(
2854         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2855         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2856         compVerStrLen, &compVerStrInfo, nullptr,
2857         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2858     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2859 
2860     rc = encode_pass_component_table_req(
2861         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2862         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2863         compVerStrLen, &compVerStrInfo, requestMsg,
2864         sizeof(pldm_pass_component_table_req));
2865     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2866 
2867     rc = encode_pass_component_table_req(
2868         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2869         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0,
2870         &compVerStrInfo, requestMsg,
2871         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2872     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2873 
2874     rc = encode_pass_component_table_req(
2875         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2876         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2877         compVerStrLen - 1, &compVerStrInfo, requestMsg,
2878         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2879     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2880 
2881     rc = encode_pass_component_table_req(
2882         instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier,
2883         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2884         compVerStrLen, &compVerStrInfo, requestMsg,
2885         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2886     EXPECT_EQ(rc, PLDM_INVALID_TRANSFER_OPERATION_FLAG);
2887 
2888     rc = encode_pass_component_table_req(
2889         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2890         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN,
2891         compVerStrLen, &compVerStrInfo, requestMsg,
2892         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2893     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2894 }
2895 
2896 TEST(PassComponentTable, goodPathDecodeResponse)
2897 {
2898     constexpr std::array<uint8_t,
2899                          hdrSize + sizeof(pldm_pass_component_table_resp)>
2900         passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
2901     auto responseMsg1 =
2902         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2903         reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
2904 
2905     uint8_t completionCode = 0;
2906     uint8_t compResp = 0;
2907     uint8_t compRespCode = 0;
2908 
2909     auto rc = decode_pass_component_table_resp(
2910         responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode,
2911         &compResp, &compRespCode);
2912 
2913     EXPECT_EQ(rc, PLDM_SUCCESS);
2914     EXPECT_EQ(completionCode, PLDM_SUCCESS);
2915     EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
2916     EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL);
2917 
2918     constexpr std::array<uint8_t,
2919                          hdrSize + sizeof(pldm_pass_component_table_resp)>
2920         passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0};
2921     auto responseMsg2 =
2922         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2923         reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
2924     rc = decode_pass_component_table_resp(
2925         responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
2926         &compResp, &compRespCode);
2927 
2928     EXPECT_EQ(rc, PLDM_SUCCESS);
2929     EXPECT_EQ(completionCode, PLDM_SUCCESS);
2930     EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
2931     EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN);
2932 
2933     constexpr std::array<uint8_t,
2934                          hdrSize + sizeof(pldm_pass_component_table_resp)>
2935         passCompTableResponse3{0x00, 0x00, 0x00, 0x80};
2936     auto responseMsg3 =
2937         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2938         reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
2939 
2940     rc = decode_pass_component_table_resp(
2941         responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
2942         &compResp, &compRespCode);
2943 
2944     EXPECT_EQ(rc, PLDM_SUCCESS);
2945     EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
2946 }
2947 
2948 TEST(PassComponentTable, errorPathDecodeResponse)
2949 {
2950     constexpr std::array<uint8_t,
2951                          hdrSize + sizeof(pldm_pass_component_table_resp) - 1>
2952         passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00};
2953     auto responseMsg1 =
2954         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2955         reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
2956 
2957     uint8_t completionCode = 0;
2958     uint8_t compResp = 0;
2959     uint8_t compRespCode = 0;
2960 
2961     auto rc = decode_pass_component_table_resp(
2962         nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode,
2963         &compResp, &compRespCode);
2964     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2965 
2966     rc = decode_pass_component_table_resp(
2967         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr,
2968         &compResp, &compRespCode);
2969     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2970 
2971     rc = decode_pass_component_table_resp(
2972         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
2973         &completionCode, nullptr, &compRespCode);
2974     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2975 
2976     rc = decode_pass_component_table_resp(
2977         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
2978         &completionCode, &compResp, nullptr);
2979     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2980 
2981     rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode,
2982                                           &compResp, &compRespCode);
2983     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2984 
2985     rc = decode_pass_component_table_resp(
2986         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
2987         &completionCode, &compResp, &compRespCode);
2988     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2989 
2990     constexpr std::array<uint8_t,
2991                          hdrSize + sizeof(pldm_pass_component_table_resp)>
2992         passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
2993     auto responseMsg2 =
2994         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2995         reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
2996     rc = decode_pass_component_table_resp(
2997         responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
2998         &compResp, &compRespCode);
2999     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3000 
3001     constexpr std::array<uint8_t,
3002                          hdrSize + sizeof(pldm_pass_component_table_resp)>
3003         passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};
3004     auto responseMsg3 =
3005         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3006         reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3007     rc = decode_pass_component_table_resp(
3008         responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3009         &compResp, &compRespCode);
3010     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3011 
3012     constexpr std::array<uint8_t,
3013                          hdrSize + sizeof(pldm_pass_component_table_resp)>
3014         passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
3015     auto responseMsg4 =
3016         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3017         reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data());
3018     rc = decode_pass_component_table_resp(
3019         responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode,
3020         &compResp, &compRespCode);
3021     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3022 }
3023 
3024 TEST(UpdateComponent, goodPathEncodeRequest)
3025 {
3026     constexpr uint8_t instanceId = 2;
3027     constexpr uint16_t compIdentifier = 500;
3028     constexpr uint8_t compClassificationIndex = 50;
3029     constexpr uint32_t compComparisonStamp = 0x89abcdef;
3030     constexpr uint32_t compImageSize = 4096;
3031     constexpr bitfield32_t updateOptionFlags{1};
3032     constexpr std::string_view compVerStr = "OpenBmcv2.2";
3033     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3034     variable_field compVerStrInfo{};
3035     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3036     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3037     compVerStrInfo.length = compVerStrLen;
3038 
3039     std::array<uint8_t,
3040                hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3041         request{};
3042     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3043     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3044 
3045     auto rc = encode_update_component_req(
3046         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3047         compComparisonStamp, compImageSize, updateOptionFlags,
3048         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3049         sizeof(pldm_update_component_req) + compVerStrLen);
3050     EXPECT_EQ(rc, PLDM_SUCCESS);
3051 
3052     std::array<uint8_t,
3053                hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3054         outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
3055                    0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
3056                    0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
3057                    0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
3058     EXPECT_EQ(request, outRequest);
3059 }
3060 
3061 TEST(UpdateComponent, errorPathEncodeRequest)
3062 {
3063     constexpr uint8_t instanceId = 2;
3064     constexpr uint16_t compIdentifier = 500;
3065     constexpr uint8_t compClassificationIndex = 50;
3066     constexpr uint32_t compComparisonStamp = 0x89abcdef;
3067     constexpr uint32_t compImageSize = 4096;
3068     constexpr bitfield32_t updateOptionFlags{1};
3069     constexpr std::string_view compVerStr = "OpenBmcv2.2";
3070     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3071     variable_field compVerStrInfo{};
3072     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3073     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3074     compVerStrInfo.length = compVerStrLen;
3075 
3076     std::array<uint8_t,
3077                hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3078         request{};
3079     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3080     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3081 
3082     auto rc = encode_update_component_req(
3083         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3084         compComparisonStamp, compImageSize, updateOptionFlags,
3085         PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
3086         sizeof(pldm_update_component_req) + compVerStrLen);
3087     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3088 
3089     compVerStrInfo.ptr = nullptr;
3090     rc = encode_update_component_req(
3091         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3092         compComparisonStamp, compImageSize, updateOptionFlags,
3093         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3094         sizeof(pldm_update_component_req) + compVerStrLen);
3095     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3096     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3097     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3098 
3099     rc = encode_update_component_req(
3100         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3101         compComparisonStamp, compImageSize, updateOptionFlags,
3102         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
3103         sizeof(pldm_update_component_req) + compVerStrLen);
3104     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3105 
3106     rc = encode_update_component_req(
3107         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3108         compComparisonStamp, compImageSize, updateOptionFlags,
3109         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3110         sizeof(pldm_update_component_req));
3111     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3112 
3113     rc = encode_update_component_req(
3114         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3115         compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
3116         compVerStrLen, &compVerStrInfo, requestMsg,
3117         sizeof(pldm_update_component_req) + compVerStrLen);
3118     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3119 
3120     rc = encode_update_component_req(
3121         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3122         compComparisonStamp, compImageSize, updateOptionFlags,
3123         PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg,
3124         sizeof(pldm_update_component_req) + compVerStrLen);
3125     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3126 
3127     rc = encode_update_component_req(
3128         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3129         compComparisonStamp, compImageSize, updateOptionFlags,
3130         PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg,
3131         sizeof(pldm_update_component_req) + compVerStrLen);
3132     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3133 
3134     rc = encode_update_component_req(
3135         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3136         compComparisonStamp, compImageSize, updateOptionFlags,
3137         PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
3138         sizeof(pldm_update_component_req) + compVerStrLen);
3139     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3140 }
3141 
3142 TEST(UpdateComponent, goodPathDecodeResponse)
3143 {
3144     constexpr std::bitset<32> forceUpdateComp{1};
3145     constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
3146     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3147         updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3148                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3149     auto responseMsg1 =
3150         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3151         reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3152 
3153     uint8_t completionCode = 0;
3154     uint8_t compCompatibilityResp = 0;
3155     uint8_t compCompatibilityRespCode = 0;
3156     bitfield32_t updateOptionFlagsEnabled{};
3157     uint16_t timeBeforeReqFWData = 0;
3158 
3159     auto rc = decode_update_component_resp(
3160         responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
3161         &compCompatibilityResp, &compCompatibilityRespCode,
3162         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3163 
3164     EXPECT_EQ(rc, PLDM_SUCCESS);
3165     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3166     EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
3167     EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
3168     EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
3169     EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
3170 
3171     constexpr std::bitset<32> noFlags{};
3172     constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
3173     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3174         updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3175                                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3176     auto responseMsg2 =
3177         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3178         reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3179     rc = decode_update_component_resp(
3180         responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3181         &compCompatibilityResp, &compCompatibilityRespCode,
3182         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3183 
3184     EXPECT_EQ(rc, PLDM_SUCCESS);
3185     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3186     EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
3187     EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
3188     EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
3189     EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
3190 
3191     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3192         updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
3193     auto responseMsg3 =
3194         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3195         reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3196 
3197     rc = decode_update_component_resp(
3198         responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3199         &compCompatibilityResp, &compCompatibilityRespCode,
3200         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3201 
3202     EXPECT_EQ(rc, PLDM_SUCCESS);
3203     EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3204 }
3205 
3206 TEST(UpdateComponent, errorPathDecodeResponse)
3207 {
3208     constexpr std::array<uint8_t,
3209                          hdrSize + sizeof(pldm_update_component_resp) - 1>
3210         updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3211                                  0x00, 0x00, 0x00, 0x00, 0x00};
3212     auto responseMsg1 =
3213         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3214         reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3215 
3216     uint8_t completionCode = 0;
3217     uint8_t compCompatibilityResp = 0;
3218     uint8_t compCompatibilityRespCode = 0;
3219     bitfield32_t updateOptionFlagsEnabled{};
3220     uint16_t timeBeforeReqFWData = 0;
3221 
3222     auto rc = decode_update_component_resp(
3223         nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
3224         &compCompatibilityResp, &compCompatibilityRespCode,
3225         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3226     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3227 
3228     rc = decode_update_component_resp(
3229         responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
3230         &compCompatibilityResp, &compCompatibilityRespCode,
3231         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3232     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3233 
3234     rc = decode_update_component_resp(
3235         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3236         nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3237         &timeBeforeReqFWData);
3238     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3239 
3240     rc = decode_update_component_resp(
3241         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3242         &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
3243         &timeBeforeReqFWData);
3244     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3245 
3246     rc = decode_update_component_resp(
3247         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3248         &compCompatibilityResp, &compCompatibilityRespCode, nullptr,
3249         &timeBeforeReqFWData);
3250     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3251 
3252     rc = decode_update_component_resp(
3253         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3254         &compCompatibilityResp, &compCompatibilityRespCode,
3255         &updateOptionFlagsEnabled, nullptr);
3256     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3257 
3258     rc = decode_update_component_resp(
3259         responseMsg1, 0, &completionCode, &compCompatibilityResp,
3260         &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3261         &timeBeforeReqFWData);
3262     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3263 
3264     rc = decode_update_component_resp(
3265         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3266         &compCompatibilityResp, &compCompatibilityRespCode,
3267         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3268     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3269 
3270     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3271         updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
3272                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3273     auto responseMsg2 =
3274         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3275         reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3276     rc = decode_update_component_resp(
3277         responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3278         &compCompatibilityResp, &compCompatibilityRespCode,
3279         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3280     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3281 
3282     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3283         updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
3284                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3285     auto responseMsg3 =
3286         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3287         reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3288     rc = decode_update_component_resp(
3289         responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3290         &compCompatibilityResp, &compCompatibilityRespCode,
3291         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3292     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3293 
3294     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3295         updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
3296                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3297     auto responseMsg4 =
3298         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3299         reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
3300     rc = decode_update_component_resp(
3301         responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
3302         &compCompatibilityResp, &compCompatibilityRespCode,
3303         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3304     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3305 }
3306 
3307 TEST(RequestFirmwareData, goodPathDecodeRequest)
3308 {
3309     constexpr uint32_t offset = 300;
3310     constexpr uint32_t length = 255;
3311     constexpr std::array<uint8_t,
3312                          hdrSize + sizeof(pldm_request_firmware_data_req)>
3313         reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3314                      0x00, 0xff, 0x00, 0x00, 0x00};
3315     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3316     auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3317 
3318     uint32_t outOffset = 0;
3319     uint32_t outLength = 0;
3320     auto rc = decode_request_firmware_data_req(
3321         requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3322         &outLength);
3323 
3324     EXPECT_EQ(rc, PLDM_SUCCESS);
3325     EXPECT_EQ(outOffset, offset);
3326     EXPECT_EQ(outLength, length);
3327 }
3328 
3329 TEST(RequestFirmwareData, errorPathDecodeRequest)
3330 {
3331     constexpr std::array<uint8_t,
3332                          hdrSize + sizeof(pldm_request_firmware_data_req)>
3333         reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3334                      0x00, 0x1f, 0x00, 0x00, 0x00};
3335     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3336     auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3337 
3338     uint32_t outOffset = 0;
3339     uint32_t outLength = 0;
3340     auto rc = decode_request_firmware_data_req(
3341         nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
3342         &outLength);
3343     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3344 
3345     rc = decode_request_firmware_data_req(
3346         requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
3347         &outLength);
3348     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3349 
3350     rc = decode_request_firmware_data_req(
3351         requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3352         nullptr);
3353     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3354 
3355     rc = decode_request_firmware_data_req(
3356         requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
3357         &outLength);
3358     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3359 
3360     rc = decode_request_firmware_data_req(
3361         requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3362         &outLength);
3363     EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
3364 }
3365 
3366 TEST(RequestFirmwareData, goodPathEncodeResponse)
3367 {
3368     constexpr uint8_t instanceId = 3;
3369     constexpr uint8_t completionCode = PLDM_SUCCESS;
3370     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
3371                                       PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3372         outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
3373                               0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3374                               0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3375                               0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3376                               0x1d, 0x1e, 0x1f, 0x20};
3377     std::array<uint8_t, hdrSize + sizeof(completionCode) +
3378                             PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3379         reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
3380                            0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3381                            0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3382                            0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3383                            0x1d, 0x1e, 0x1f, 0x20};
3384     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3385     auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
3386     auto rc = encode_request_firmware_data_resp(
3387         instanceId, completionCode, responseMsg1,
3388         sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
3389     EXPECT_EQ(rc, PLDM_SUCCESS);
3390     EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
3391 
3392     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3393         outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
3394     std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
3395         0x00, 0x00, 0x00, 0x00};
3396     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3397     auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
3398     rc = encode_request_firmware_data_resp(
3399         instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
3400         sizeof(completionCode));
3401     EXPECT_EQ(rc, PLDM_SUCCESS);
3402     EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
3403 }
3404 
3405 TEST(RequestFirmwareData, errorPathEncodeResponse)
3406 {
3407     std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
3408     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3409     auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
3410     auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
3411     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3412 
3413     rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
3414     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3415 }
3416 
3417 TEST(TransferComplete, goodPathDecodeRequest)
3418 {
3419     constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
3420     constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3421         transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
3422     auto requestMsg1 =
3423         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3424         reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
3425     uint8_t outTransferResult = 0;
3426 
3427     auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
3428                                            &outTransferResult);
3429     EXPECT_EQ(rc, PLDM_SUCCESS);
3430     EXPECT_EQ(outTransferResult, transferResult);
3431 
3432     constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3433         transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
3434     auto requestMsg2 =
3435         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3436         reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
3437     rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
3438                                       &outTransferResult);
3439     EXPECT_EQ(rc, PLDM_SUCCESS);
3440     EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
3441 }
3442 
3443 TEST(TransferComplete, errorPathDecodeRequest)
3444 {
3445     constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
3446                                                                0x00};
3447     auto requestMsg =
3448         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3449         reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
3450     uint8_t outTransferResult = 0;
3451 
3452     auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
3453     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3454 
3455     rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
3456     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3457 
3458     rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
3459     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3460 }
3461 
3462 TEST(TransferComplete, goodPathEncodeResponse)
3463 {
3464     constexpr uint8_t instanceId = 4;
3465     constexpr uint8_t completionCode = PLDM_SUCCESS;
3466     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3467         outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
3468     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3469         transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3470     auto responseMsg1 =
3471         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3472         reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
3473     auto rc = encode_transfer_complete_resp(
3474         instanceId, completionCode, responseMsg1, sizeof(completionCode));
3475     EXPECT_EQ(rc, PLDM_SUCCESS);
3476     EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
3477 
3478     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3479         outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
3480     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3481         transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3482     auto responseMsg2 =
3483         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3484         reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
3485     rc = encode_transfer_complete_resp(instanceId,
3486                                        PLDM_FWUP_COMMAND_NOT_EXPECTED,
3487                                        responseMsg2, sizeof(completionCode));
3488     EXPECT_EQ(rc, PLDM_SUCCESS);
3489     EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
3490 }
3491 
3492 TEST(TransferComplete, errorPathEncodeResponse)
3493 {
3494     std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
3495     auto responseMsg =
3496         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3497         reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
3498     auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3499     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3500 
3501     rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3502     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3503 }
3504 
3505 TEST(VerifyComplete, goodPathDecodeRequest)
3506 {
3507     constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
3508     constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3509         verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
3510     auto requestMsg1 =
3511         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3512         reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
3513     uint8_t outVerifyResult = 0;
3514 
3515     auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
3516                                          &outVerifyResult);
3517     EXPECT_EQ(rc, PLDM_SUCCESS);
3518     EXPECT_EQ(outVerifyResult, verifyResult);
3519 
3520     constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3521         verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
3522     auto requestMsg2 =
3523         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3524         reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
3525     rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
3526                                     &outVerifyResult);
3527     EXPECT_EQ(rc, PLDM_SUCCESS);
3528     EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
3529 }
3530 
3531 TEST(VerifyComplete, errorPathDecodeRequest)
3532 {
3533     constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
3534     auto requestMsg =
3535         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3536         reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
3537     uint8_t outVerifyResult = 0;
3538 
3539     auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
3540     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3541 
3542     rc = decode_verify_complete_req(requestMsg, 0, nullptr);
3543     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3544 
3545     rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);
3546     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3547 }
3548 
3549 TEST(VerifyComplete, goodPathEncodeResponse)
3550 {
3551     constexpr uint8_t instanceId = 5;
3552     constexpr uint8_t completionCode = PLDM_SUCCESS;
3553     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3554         outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};
3555     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3556         verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3557     auto responseMsg1 =
3558         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3559         reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());
3560     auto rc = encode_verify_complete_resp(instanceId, completionCode,
3561                                           responseMsg1, sizeof(completionCode));
3562     EXPECT_EQ(rc, PLDM_SUCCESS);
3563     EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);
3564 
3565     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3566         outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88};
3567     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3568         verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3569     auto responseMsg2 =
3570         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3571         reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());
3572     rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3573                                      responseMsg2, sizeof(completionCode));
3574     EXPECT_EQ(rc, PLDM_SUCCESS);
3575     EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);
3576 }
3577 
3578 TEST(VerifyComplete, errorPathEncodeResponse)
3579 {
3580     std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00};
3581     auto responseMsg =
3582         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3583         reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());
3584     auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3585     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3586 
3587     rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3588     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3589 }
3590 
3591 TEST(ApplyComplete, goodPathDecodeRequest)
3592 {
3593     constexpr uint8_t applyResult1 =
3594         PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
3595     // DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
3596     constexpr std::bitset<16> compActivationModification1{0x30};
3597     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3598         applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
3599     auto requestMsg1 =
3600         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3601         reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3602     uint8_t outApplyResult = 0;
3603     bitfield16_t outCompActivationModification{};
3604     auto rc = decode_apply_complete_req(
3605         requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
3606         &outCompActivationModification);
3607     EXPECT_EQ(rc, PLDM_SUCCESS);
3608     EXPECT_EQ(outApplyResult, applyResult1);
3609     EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
3610 
3611     constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
3612     constexpr std::bitset<16> compActivationModification2{};
3613     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3614         applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3615     auto requestMsg2 =
3616         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3617         reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3618     rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3619                                    &outApplyResult,
3620                                    &outCompActivationModification);
3621     EXPECT_EQ(rc, PLDM_SUCCESS);
3622     EXPECT_EQ(outApplyResult, applyResult2);
3623     EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
3624 }
3625 
3626 TEST(ApplyComplete, errorPathDecodeRequest)
3627 {
3628     constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
3629     auto requestMsg1 =
3630         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3631         reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3632     uint8_t outApplyResult = 0;
3633     bitfield16_t outCompActivationModification{};
3634 
3635     auto rc = decode_apply_complete_req(
3636         nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
3637         &outCompActivationModification);
3638     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3639 
3640     rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3641                                    nullptr, &outCompActivationModification);
3642     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3643 
3644     rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3645                                    &outApplyResult, nullptr);
3646     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3647 
3648     rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
3649                                    &outCompActivationModification);
3650     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3651 
3652     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3653         applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
3654     auto requestMsg2 =
3655         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3656         reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3657     rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3658                                    &outApplyResult,
3659                                    &outCompActivationModification);
3660     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3661 }
3662 
3663 TEST(ApplyComplete, goodPathEncodeResponse)
3664 {
3665     constexpr uint8_t instanceId = 6;
3666     constexpr uint8_t completionCode = PLDM_SUCCESS;
3667     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3668         outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
3669     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3670         applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3671     auto responseMsg1 =
3672         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3673         reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
3674     auto rc = encode_apply_complete_resp(instanceId, completionCode,
3675                                          responseMsg1, sizeof(completionCode));
3676     EXPECT_EQ(rc, PLDM_SUCCESS);
3677     EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
3678 
3679     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3680         outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
3681     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3682         applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3683     auto responseMsg2 =
3684         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3685         reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
3686     rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3687                                     responseMsg2, sizeof(completionCode));
3688     EXPECT_EQ(rc, PLDM_SUCCESS);
3689     EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
3690 }
3691 
3692 TEST(ApplyComplete, errorPathEncodeResponse)
3693 {
3694     std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
3695     auto responseMsg =
3696         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3697         reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
3698     auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3699     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3700 
3701     rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3702     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3703 }
3704 
3705 TEST(ActivateFirmware, goodPathEncodeRequest)
3706 {
3707     constexpr uint8_t instanceId = 7;
3708 
3709     std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
3710     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3711     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3712 
3713     auto rc = encode_activate_firmware_req(
3714         instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
3715         sizeof(pldm_activate_firmware_req));
3716     EXPECT_EQ(rc, PLDM_SUCCESS);
3717 
3718     std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
3719         outRequest{0x87, 0x05, 0x1a, 0x01};
3720     EXPECT_EQ(request, outRequest);
3721 }
3722 
3723 TEST(ActivateFirmware, errorPathEncodeRequest)
3724 {
3725     std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
3726     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3727     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3728 
3729     auto rc = encode_activate_firmware_req(
3730         0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
3731         sizeof(pldm_activate_firmware_req));
3732     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3733 
3734     rc = encode_activate_firmware_req(
3735         0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
3736     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3737 
3738     rc = encode_activate_firmware_req(0, 2, requestMsg,
3739                                       sizeof(pldm_activate_firmware_req));
3740     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3741 }
3742 
3743 TEST(ActivateFirmware, goodPathDecodeResponse)
3744 {
3745     constexpr uint16_t estimatedTimeForActivation100s = 100;
3746     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3747         activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
3748     auto responseMsg1 =
3749         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3750         reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
3751 
3752     uint8_t completionCode = 0;
3753     uint16_t estimatedTimeForActivation = 0;
3754 
3755     auto rc = decode_activate_firmware_resp(
3756         responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
3757         &estimatedTimeForActivation);
3758 
3759     EXPECT_EQ(rc, PLDM_SUCCESS);
3760     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3761     EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
3762 
3763     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3764         activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
3765     auto responseMsg2 =
3766         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3767         reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data());
3768 
3769     rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
3770                                        &completionCode,
3771                                        &estimatedTimeForActivation);
3772 
3773     EXPECT_EQ(rc, PLDM_SUCCESS);
3774     EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
3775 }
3776 
3777 TEST(ActivateFirmware, errorPathDecodeResponse)
3778 {
3779     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3780         activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3781     auto responseMsg =
3782         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3783         reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
3784 
3785     uint8_t completionCode = 0;
3786     uint16_t estimatedTimeForActivation = 0;
3787 
3788     auto rc = decode_activate_firmware_resp(
3789         nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
3790         &estimatedTimeForActivation);
3791     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3792 
3793     rc = decode_activate_firmware_resp(responseMsg,
3794                                        sizeof(pldm_activate_firmware_resp),
3795                                        nullptr, &estimatedTimeForActivation);
3796     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3797 
3798     rc = decode_activate_firmware_resp(responseMsg,
3799                                        sizeof(pldm_activate_firmware_resp),
3800                                        &completionCode, nullptr);
3801     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3802 
3803     rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
3804                                        &estimatedTimeForActivation);
3805     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3806 
3807     rc = decode_activate_firmware_resp(
3808         responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
3809         &estimatedTimeForActivation);
3810     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3811 }
3812 
3813 TEST(GetStatus, goodPathEncodeRequest)
3814 {
3815     constexpr uint8_t instanceId = 8;
3816     std::array<uint8_t, hdrSize> request{};
3817     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3818     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3819 
3820     auto rc = encode_get_status_req(instanceId, requestMsg,
3821                                     PLDM_GET_STATUS_REQ_BYTES);
3822     EXPECT_EQ(rc, PLDM_SUCCESS);
3823 
3824     constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
3825     EXPECT_EQ(request, outRequest);
3826 }
3827 
3828 TEST(GetStatus, errorPathEncodeRequest)
3829 {
3830     std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
3831     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3832     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3833 
3834     auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
3835     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3836 
3837     rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);
3838     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3839 }
3840 
3841 TEST(GetStatus, goodPathDecodeResponse)
3842 {
3843     constexpr std::bitset<32> updateOptionFlagsEnabled1{0};
3844     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3845         getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
3846                            0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};
3847     auto responseMsg1 =
3848         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3849         reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
3850 
3851     uint8_t completionCode = 0;
3852     uint8_t currentState = 0;
3853     uint8_t previousState = 0;
3854     uint8_t auxState = 0;
3855     uint8_t auxStateStatus = 0;
3856     uint8_t progressPercent = 0;
3857     uint8_t reasonCode = 0;
3858     bitfield32_t updateOptionFlagsEnabled{0};
3859 
3860     auto rc = decode_get_status_resp(
3861         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3862         &currentState, &previousState, &auxState, &auxStateStatus,
3863         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3864 
3865     EXPECT_EQ(rc, PLDM_SUCCESS);
3866     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3867     EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);
3868     EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
3869     EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);
3870     EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);
3871     EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);
3872     EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
3873     EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);
3874 
3875     // Bit position 0 - Force update of component – FD will perform a force
3876     // update of the component.
3877     constexpr std::bitset<32> updateOptionFlagsEnabled2{1};
3878     constexpr uint8_t progressPercent2 = 50;
3879     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3880         getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,
3881                            0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};
3882     auto responseMsg2 =
3883         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3884         reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
3885 
3886     rc = decode_get_status_resp(
3887         responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
3888         &currentState, &previousState, &auxState, &auxStateStatus,
3889         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3890 
3891     EXPECT_EQ(rc, PLDM_SUCCESS);
3892     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3893     EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);
3894     EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
3895     EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);
3896     EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);
3897     EXPECT_EQ(progressPercent, progressPercent2);
3898     EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
3899     EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);
3900 
3901     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3902         getStatusResponse3{0x00, 0x00, 0x00, 0x04};
3903     auto responseMsg3 =
3904         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3905         reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
3906     rc = decode_get_status_resp(
3907         responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
3908         &currentState, &previousState, &auxState, &auxStateStatus,
3909         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3910     EXPECT_EQ(rc, PLDM_SUCCESS);
3911     EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);
3912 }
3913 
3914 TEST(GetStatus, errorPathDecodeResponse)
3915 {
3916     uint8_t completionCode = 0;
3917     uint8_t currentState = 0;
3918     uint8_t previousState = 0;
3919     uint8_t auxState = 0;
3920     uint8_t auxStateStatus = 0;
3921     uint8_t progressPercent = 0;
3922     uint8_t reasonCode = 0;
3923     bitfield32_t updateOptionFlagsEnabled{0};
3924 
3925     constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};
3926     auto responseMsg1 =
3927         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3928         reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
3929 
3930     auto rc = decode_get_status_resp(
3931         nullptr, getStatusResponse1.size() - hdrSize, &completionCode,
3932         &currentState, &previousState, &auxState, &auxStateStatus,
3933         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3934     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3935 
3936     rc = decode_get_status_resp(
3937         responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,
3938         &currentState, &previousState, &auxState, &auxStateStatus,
3939         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3940     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3941 
3942     rc = decode_get_status_resp(
3943         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3944         nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,
3945         &reasonCode, &updateOptionFlagsEnabled);
3946     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3947 
3948     rc = decode_get_status_resp(
3949         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3950         &currentState, nullptr, &auxState, &auxStateStatus, &progressPercent,
3951         &reasonCode, &updateOptionFlagsEnabled);
3952     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3953 
3954     rc = decode_get_status_resp(
3955         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3956         &currentState, &previousState, nullptr, &auxStateStatus,
3957         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3958     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3959 
3960     rc = decode_get_status_resp(
3961         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3962         &currentState, &previousState, &auxState, nullptr, &progressPercent,
3963         &reasonCode, &updateOptionFlagsEnabled);
3964     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3965 
3966     rc = decode_get_status_resp(
3967         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3968         &currentState, &previousState, &auxState, &auxStateStatus, nullptr,
3969         &reasonCode, &updateOptionFlagsEnabled);
3970     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3971 
3972     rc = decode_get_status_resp(
3973         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3974         &currentState, &previousState, &auxState, &auxStateStatus,
3975         &progressPercent, nullptr, &updateOptionFlagsEnabled);
3976     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3977 
3978     rc = decode_get_status_resp(
3979         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3980         &currentState, &previousState, &auxState, &auxStateStatus,
3981         &progressPercent, &reasonCode, nullptr);
3982     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3983 
3984     rc = decode_get_status_resp(
3985         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3986         &currentState, &previousState, &auxState, &auxStateStatus,
3987         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3988     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3989 
3990     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>
3991         getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3992                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3993     auto responseMsg2 =
3994         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3995         reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
3996     rc = decode_get_status_resp(
3997         responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
3998         &currentState, &previousState, &auxState, &auxStateStatus,
3999         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4000     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4001 
4002     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4003         getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
4004                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4005     auto responseMsg3 =
4006         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4007         reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4008     rc = decode_get_status_resp(
4009         responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4010         &currentState, &previousState, &auxState, &auxStateStatus,
4011         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4012     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4013 
4014     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4015         getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
4016                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4017     auto responseMsg4 =
4018         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4019         reinterpret_cast<const pldm_msg*>(getStatusResponse4.data());
4020     rc = decode_get_status_resp(
4021         responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,
4022         &currentState, &previousState, &auxState, &auxStateStatus,
4023         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4024     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4025 
4026     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4027         getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
4028                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4029     auto responseMsg5 =
4030         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4031         reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());
4032     rc = decode_get_status_resp(
4033         responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,
4034         &currentState, &previousState, &auxState, &auxStateStatus,
4035         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4036     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4037 
4038     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4039         getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4040                            0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4041     auto responseMsg6 =
4042         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4043         reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());
4044     rc = decode_get_status_resp(
4045         responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,
4046         &currentState, &previousState, &auxState, &auxStateStatus,
4047         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4048     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4049 
4050     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4051         getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4052                            0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
4053     auto responseMsg7 =
4054         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4055         reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());
4056     rc = decode_get_status_resp(
4057         responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,
4058         &currentState, &previousState, &auxState, &auxStateStatus,
4059         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4060     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4061 
4062     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4063         getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4064                            0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00};
4065     auto responseMsg8 =
4066         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4067         reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());
4068     rc = decode_get_status_resp(
4069         responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,
4070         &currentState, &previousState, &auxState, &auxStateStatus,
4071         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4072     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4073 
4074     // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is
4075     // IDLE
4076     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4077         getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
4078                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4079     auto responseMsg9 =
4080         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4081         reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());
4082     rc = decode_get_status_resp(
4083         responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,
4084         &currentState, &previousState, &auxState, &auxStateStatus,
4085         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4086     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4087 }
4088 
4089 TEST(CancelUpdateComponent, goodPathEncodeRequest)
4090 {
4091     constexpr uint8_t instanceId = 9;
4092     std::array<uint8_t, hdrSize> request{};
4093     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4094     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4095 
4096     auto rc = encode_cancel_update_component_req(
4097         instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4098     EXPECT_EQ(rc, PLDM_SUCCESS);
4099 
4100     constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
4101     EXPECT_EQ(request, outRequest);
4102 }
4103 
4104 TEST(CancelUpdateComponent, errorPathEncodeRequest)
4105 {
4106     std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
4107     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4108     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4109 
4110     auto rc = encode_cancel_update_component_req(
4111         0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4112     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4113 
4114     rc = encode_cancel_update_component_req(
4115         0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);
4116     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4117 }
4118 
4119 TEST(CancelUpdateComponent, testGoodDecodeResponse)
4120 {
4121     uint8_t completionCode = 0;
4122     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4123         cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};
4124     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4125     auto responseMsg1 = reinterpret_cast<const pldm_msg*>(
4126         cancelUpdateComponentResponse1.data());
4127     auto rc = decode_cancel_update_component_resp(
4128         responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,
4129         &completionCode);
4130     EXPECT_EQ(rc, PLDM_SUCCESS);
4131     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4132 
4133     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4134         cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};
4135     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4136     auto responseMsg2 = reinterpret_cast<const pldm_msg*>(
4137         cancelUpdateComponentResponse2.data());
4138     rc = decode_cancel_update_component_resp(
4139         responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,
4140         &completionCode);
4141     EXPECT_EQ(rc, PLDM_SUCCESS);
4142     EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4143 }
4144 
4145 TEST(CancelUpdateComponent, testBadDecodeResponse)
4146 {
4147     uint8_t completionCode = 0;
4148     constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{
4149         0x00, 0x00, 0x00};
4150     auto responseMsg =
4151         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4152         reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data());
4153 
4154     auto rc = decode_cancel_update_component_resp(
4155         nullptr, cancelUpdateComponentResponse.size() - hdrSize,
4156         &completionCode);
4157     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4158 
4159     rc = decode_cancel_update_component_resp(
4160         responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);
4161     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4162 
4163     rc = decode_cancel_update_component_resp(
4164         responseMsg, cancelUpdateComponentResponse.size() - hdrSize,
4165         &completionCode);
4166     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4167 }
4168 
4169 TEST(CancelUpdate, goodPathEncodeRequest)
4170 {
4171     constexpr uint8_t instanceId = 10;
4172     std::array<uint8_t, hdrSize> request{};
4173     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4174     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4175 
4176     auto rc = encode_cancel_update_req(instanceId, requestMsg,
4177                                        PLDM_CANCEL_UPDATE_REQ_BYTES);
4178     EXPECT_EQ(rc, PLDM_SUCCESS);
4179 
4180     constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
4181     EXPECT_EQ(request, outRequest);
4182 }
4183 
4184 TEST(CancelUpdate, errorPathEncodeRequest)
4185 {
4186     std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
4187     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4188     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4189 
4190     auto rc =
4191         encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
4192     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4193 
4194     rc = encode_cancel_update_req(0, requestMsg,
4195                                   PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
4196     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4197 }
4198 
4199 TEST(CancelUpdate, goodPathDecodeResponse)
4200 {
4201     constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
4202     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4203         cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4204                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4205     auto responseMsg1 =
4206         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4207         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4208     uint8_t completionCode = 0;
4209     bool8_t nonFunctioningComponentIndication = 0;
4210     bitfield64_t nonFunctioningComponentBitmap{0};
4211     auto rc = decode_cancel_update_resp(
4212         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4213         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4214     EXPECT_EQ(rc, PLDM_SUCCESS);
4215     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4216     EXPECT_EQ(nonFunctioningComponentIndication,
4217               PLDM_FWUP_COMPONENTS_FUNCTIONING);
4218     EXPECT_EQ(nonFunctioningComponentBitmap.value,
4219               nonFunctioningComponentBitmap1);
4220 
4221     constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
4222     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4223         cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
4224                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4225     auto responseMsg2 =
4226         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4227         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4228     rc = decode_cancel_update_resp(
4229         responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4230         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4231     EXPECT_EQ(rc, PLDM_SUCCESS);
4232     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4233     EXPECT_EQ(nonFunctioningComponentIndication,
4234               PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING);
4235     EXPECT_EQ(nonFunctioningComponentBitmap.value,
4236               nonFunctioningComponentBitmap2);
4237 
4238     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4239         cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
4240     auto responseMsg3 =
4241         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4242         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4243     rc = decode_cancel_update_resp(
4244         responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4245         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4246     EXPECT_EQ(rc, PLDM_SUCCESS);
4247     EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4248 }
4249 
4250 TEST(CancelUpdate, errorPathDecodeResponse)
4251 {
4252     constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
4253                                                                  0x00};
4254     auto responseMsg1 =
4255         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4256         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4257     uint8_t completionCode = 0;
4258     bool8_t nonFunctioningComponentIndication = 0;
4259     bitfield64_t nonFunctioningComponentBitmap{0};
4260 
4261     auto rc = decode_cancel_update_resp(
4262         nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4263         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4264     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4265 
4266     rc = decode_cancel_update_resp(
4267         responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
4268         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4269     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4270 
4271     rc = decode_cancel_update_resp(
4272         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4273         nullptr, &nonFunctioningComponentBitmap);
4274     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4275 
4276     rc = decode_cancel_update_resp(
4277         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4278         &nonFunctioningComponentIndication, nullptr);
4279     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4280 
4281     rc = decode_cancel_update_resp(
4282         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4283         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4284     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4285 
4286     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4287         cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
4288     auto responseMsg2 =
4289         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4290         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4291     rc = decode_cancel_update_resp(
4292         responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4293         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4294     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4295 
4296     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4297         cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
4298                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4299     auto responseMsg3 =
4300         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4301         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4302     rc = decode_cancel_update_resp(
4303         responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4304         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4305     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4306 }
4307