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