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