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