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