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