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