xref: /openbmc/libpldm/tests/dsp/firmware_update.cpp (revision e5c3f1483ab0c9ea0013ad3d0211ad958a8034d5)
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 
TEST(QueryDownstreamDevices,goodPathEncodeRequest)1442 TEST(QueryDownstreamDevices, goodPathEncodeRequest)
1443 {
1444     constexpr uint8_t instanceId = 1;
1445     std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
1446     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1447     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1448 
1449     auto rc = encode_query_downstream_devices_req(instanceId, requestPtr);
1450 
1451     EXPECT_EQ(rc, 0);
1452     EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1453     EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1454     EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1455     EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DOWNSTREAM_DEVICES);
1456 }
1457 
TEST(QueryDownstreamDevices,encodeRequestInvalidData)1458 TEST(QueryDownstreamDevices, encodeRequestInvalidData)
1459 {
1460     constexpr uint8_t instanceId = 1;
1461 
1462     auto rc = encode_query_downstream_devices_req(instanceId, nullptr);
1463 
1464     EXPECT_EQ(rc, -EINVAL);
1465 }
1466 
TEST(QueryDownstreamDevices,goodPathDecodeResponse)1467 TEST(QueryDownstreamDevices, goodPathDecodeResponse)
1468 {
1469     uint8_t completion_code_resp = PLDM_SUCCESS;
1470     uint8_t downstream_device_update_supported_resp =
1471         PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1472     uint16_t number_of_downstream_devices_resp = 1;
1473     uint16_t max_number_of_downstream_devices_resp = 1;
1474     /** Capabilities of updating downstream devices
1475      * FDP supports downstream devices dynamically attached [Bit position 0] &
1476      * FDP supports downstream devices dynamically removed [Bit position 1]
1477      */
1478     bitfield32_t capabilities_resp = {.value = 0x0002};
1479     int rc;
1480 
1481     std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1482         responseMsg{};
1483 
1484     struct pldm_msgbuf _buf;
1485     struct pldm_msgbuf* buf = &_buf;
1486     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1487                                 responseMsg.size() - hdrSize);
1488     EXPECT_EQ(rc, 0);
1489 
1490     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1491     pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1492     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1493     pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1494     pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
1495 
1496     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1497     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1498     struct pldm_query_downstream_devices_resp resp_data;
1499 
1500     rc = decode_query_downstream_devices_resp(
1501         response, responseMsg.size() - hdrSize, &resp_data);
1502 
1503     EXPECT_EQ(rc, 0);
1504     EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1505     EXPECT_EQ(resp_data.downstream_device_update_supported,
1506               downstream_device_update_supported_resp);
1507     EXPECT_EQ(resp_data.number_of_downstream_devices,
1508               number_of_downstream_devices_resp);
1509     EXPECT_EQ(resp_data.max_number_of_downstream_devices,
1510               max_number_of_downstream_devices_resp);
1511     EXPECT_EQ(resp_data.capabilities.value, capabilities_resp.value);
1512 }
1513 
TEST(QueryDownstreamDevices,decodeRequestUndefinedValue)1514 TEST(QueryDownstreamDevices, decodeRequestUndefinedValue)
1515 {
1516     uint8_t completion_code_resp = PLDM_SUCCESS;
1517     uint8_t downstream_device_update_supported_resp = 0xe; /*Undefined value*/
1518     uint16_t number_of_downstream_devices_resp = 1;
1519     uint16_t max_number_of_downstream_devices_resp = 1;
1520     /** Capabilities of updating downstream devices
1521      * FDP supports downstream devices dynamically attached [Bit position 0] &
1522      * FDP supports downstream devices dynamically removed [Bit position 1]
1523      */
1524     bitfield32_t capabilities_resp = {.value = 0x0002};
1525     int rc;
1526 
1527     std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1528         responseMsg{};
1529 
1530     struct pldm_msgbuf _buf;
1531     struct pldm_msgbuf* buf = &_buf;
1532     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1533                                 responseMsg.size() - hdrSize);
1534     EXPECT_EQ(rc, 0);
1535 
1536     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1537     pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1538     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1539     pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1540     pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
1541 
1542     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1543     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1544     struct pldm_query_downstream_devices_resp resp_data;
1545 
1546     rc = decode_query_downstream_devices_resp(
1547         response, responseMsg.size() - hdrSize, &resp_data);
1548 
1549     ASSERT_EQ(rc, -EINVAL);
1550 }
1551 
TEST(QueryDownstreamDevices,decodeRequestErrorBufSize)1552 TEST(QueryDownstreamDevices, decodeRequestErrorBufSize)
1553 {
1554     uint8_t completion_code_resp = PLDM_SUCCESS;
1555     uint8_t downstream_device_update_supported_resp =
1556         PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1557     uint16_t number_of_downstream_devices_resp = 1;
1558     uint16_t max_number_of_downstream_devices_resp = 1;
1559     /** Capabilities of updating downstream devices
1560      * FDP supports downstream devices dynamically attached [Bit position 0] &
1561      * FDP supports downstream devices dynamically removed [Bit position 1]
1562      */
1563     bitfield32_t capabilities_resp = {.value = 0x0002};
1564     int rc;
1565 
1566     std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES -
1567                             2 /* Inject error length*/>
1568         responseMsg{};
1569 
1570     struct pldm_msgbuf _buf;
1571     struct pldm_msgbuf* buf = &_buf;
1572     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1573                                 responseMsg.size() - hdrSize);
1574     EXPECT_EQ(rc, 0);
1575 
1576     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1577     pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1578     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1579     pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1580     // Inject error value
1581     pldm_msgbuf_insert_uint16(buf, (uint16_t)capabilities_resp.value);
1582 
1583     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1584     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1585     struct pldm_query_downstream_devices_resp resp_data;
1586 
1587     rc = decode_query_downstream_devices_resp(
1588         response, responseMsg.size() - hdrSize, &resp_data);
1589 
1590     EXPECT_EQ(rc, -EBADMSG);
1591 }
1592 
TEST(QueryDownstreamIdentifiers,goodPathEncodeRequest)1593 TEST(QueryDownstreamIdentifiers, goodPathEncodeRequest)
1594 {
1595     constexpr uint8_t instanceId = 1;
1596     constexpr size_t payloadLen = PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1597     PLDM_MSG_DEFINE_P(request, payloadLen);
1598     constexpr pldm_query_downstream_identifiers_req params_req{
1599         0xFFFFFFFF, PLDM_GET_FIRSTPART};
1600 
1601     auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1602                                                       request, payloadLen);
1603     ASSERT_EQ(rc, 0);
1604     EXPECT_THAT(std::span<uint8_t>(request_buf, sizeof(request_buf)),
1605                 ElementsAreArray<uint8_t>(
1606                     {0x81, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x01}));
1607 }
1608 
TEST(QueryDownstreamIdentifiers,encodeRequestInvalidErrorPaths)1609 TEST(QueryDownstreamIdentifiers, encodeRequestInvalidErrorPaths)
1610 {
1611     constexpr uint8_t instanceId = 1;
1612     constexpr pldm_query_downstream_identifiers_req params_req{
1613         0xFFFFFFFF, PLDM_GET_FIRSTPART};
1614     constexpr pldm_query_downstream_identifiers_req params_req_invalid{
1615         0xFFFFFFFF, PLDM_ACKNOWLEDGEMENT_ONLY};
1616     constexpr size_t payload_length =
1617         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1618     std::array<uint8_t, hdrSize + payload_length> requestMsg{};
1619     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1620     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1621 
1622     auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1623                                                       nullptr, payload_length);
1624     EXPECT_EQ(rc, -EINVAL);
1625 
1626     rc = encode_query_downstream_identifiers_req(
1627         instanceId, &params_req, requestPtr, payload_length - 1);
1628     EXPECT_EQ(rc, -EOVERFLOW);
1629 
1630     rc = encode_query_downstream_identifiers_req(
1631         instanceId, &params_req_invalid, requestPtr, payload_length);
1632     EXPECT_EQ(rc, -EINVAL);
1633 }
1634 
TEST(QueryDownstreamIdentifiers,decodeResponseNoDevices)1635 TEST(QueryDownstreamIdentifiers, decodeResponseNoDevices)
1636 {
1637     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1638     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1639     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1640     constexpr uint32_t downstream_devices_length_resp = 0;
1641     constexpr uint16_t number_of_downstream_devices_resp = 0;
1642 
1643     PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1644     struct pldm_query_downstream_identifiers_resp resp_data = {};
1645     struct pldm_downstream_device_iter devs;
1646     struct pldm_msgbuf _buf;
1647     struct pldm_msgbuf* buf = &_buf;
1648     int rc = 0;
1649 
1650     rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1651                                 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1652     ASSERT_EQ(rc, 0);
1653 
1654     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1655     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1656     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1657     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1658     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1659 
1660     ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1661 
1662     rc = decode_query_downstream_identifiers_resp(
1663         response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp_data,
1664         &devs);
1665 
1666     ASSERT_EQ(rc, 0);
1667     EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1668     EXPECT_EQ(resp_data.next_data_transfer_handle,
1669               next_data_transfer_handle_resp);
1670     EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1671     EXPECT_EQ(resp_data.downstream_devices_length,
1672               downstream_devices_length_resp);
1673     EXPECT_EQ(resp_data.number_of_downstream_devices,
1674               number_of_downstream_devices_resp);
1675 }
1676 
TEST(QueryDownstreamIdentifiers,decodeResponseNoDevicesBadCount)1677 TEST(QueryDownstreamIdentifiers, decodeResponseNoDevicesBadCount)
1678 {
1679     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1680     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1681     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1682     constexpr uint32_t downstream_devices_length_resp = 0;
1683     constexpr uint16_t number_of_downstream_devices_resp = 1;
1684 
1685     PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1686     struct pldm_query_downstream_identifiers_resp resp = {};
1687     struct pldm_downstream_device_iter devs;
1688     struct pldm_downstream_device dev;
1689     struct pldm_msgbuf _buf;
1690     struct pldm_msgbuf* buf = &_buf;
1691     int rc = 0;
1692 
1693     rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1694                                 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1695     ASSERT_EQ(rc, 0);
1696 
1697     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1698     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1699     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1700     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1701     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1702 
1703     ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1704 
1705     rc = decode_query_downstream_identifiers_resp(
1706         response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp, &devs);
1707     ASSERT_EQ(rc, 0);
1708 
1709     foreach_pldm_downstream_device(devs, dev, rc)
1710     {
1711         FAIL();
1712     }
1713     ASSERT_NE(rc, 0);
1714 }
1715 
TEST(QueryDownstreamIdentifiers,decodeResponseOneDeviceOneDescriptor)1716 TEST(QueryDownstreamIdentifiers, decodeResponseOneDeviceOneDescriptor)
1717 {
1718     constexpr uint32_t downstreamDevicesLen = 11;
1719     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1720     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1721     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1722     const uint32_t downstream_devices_length_resp =
1723         htole32(downstreamDevicesLen);
1724     constexpr uint16_t number_of_downstream_devices_resp = 1;
1725     constexpr size_t payloadLen =
1726         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstreamDevicesLen;
1727 
1728     struct pldm_query_downstream_identifiers_resp resp_data = {};
1729     PLDM_MSG_DEFINE_P(response, payloadLen);
1730     struct pldm_downstream_device_iter devs;
1731     struct pldm_downstream_device dev;
1732     struct pldm_msgbuf _buf;
1733     struct pldm_msgbuf* buf = &_buf;
1734     int rc = 0;
1735 
1736     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1737     ASSERT_EQ(rc, 0);
1738 
1739     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1740     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1741     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1742     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1743     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1744 
1745     /* Downstream device */
1746     pldm_msgbuf_insert_uint16(buf, 1);
1747     pldm_msgbuf_insert_uint8(buf, 1);
1748 
1749     /* Device descriptor */
1750     pldm_msgbuf_insert_uint16(buf, 1);
1751     pldm_msgbuf_insert_uint16(buf, 4);
1752     pldm_msgbuf_insert_uint32(buf, 412);
1753 
1754     ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1755 
1756     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1757                                                   &resp_data, &devs);
1758 
1759     ASSERT_EQ(rc, 0);
1760     EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1761     EXPECT_EQ(resp_data.next_data_transfer_handle,
1762               next_data_transfer_handle_resp);
1763     EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1764     EXPECT_EQ(resp_data.downstream_devices_length,
1765               downstream_devices_length_resp);
1766     EXPECT_EQ(resp_data.number_of_downstream_devices,
1767               number_of_downstream_devices_resp);
1768 
1769     foreach_pldm_downstream_device(devs, dev, rc)
1770     {
1771         struct pldm_descriptor desc;
1772 
1773         EXPECT_EQ(dev.downstream_device_index, 1);
1774         EXPECT_EQ(dev.downstream_descriptor_count, 1);
1775 
1776         foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1777         {
1778             static const uint32_t dmtf = htole32(412);
1779             EXPECT_EQ(desc.descriptor_type, 1);
1780             EXPECT_EQ(desc.descriptor_length, 4);
1781             EXPECT_EQ(memcmp(desc.descriptor_data, &dmtf, sizeof(dmtf)), 0);
1782         }
1783         ASSERT_EQ(rc, 0);
1784     }
1785     ASSERT_EQ(rc, 0);
1786 }
1787 
1788 constexpr const uint16_t descriptor_id_type_iana_pen = 0x1;
1789 constexpr const uint16_t descriptor_id_len_iana_pen = 0x4;
1790 const uint32_t iana_pen_openbmc = htole16(49871u);
1791 const uint32_t iana_pen_dmtf = htole16(412u);
1792 
TEST(QueryDownstreamIdentifiers,decodeResponseTwoDevicesOneDescriptorEach)1793 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneDescriptorEach)
1794 {
1795     constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1796         {0, 1},
1797         {1, 1},
1798     }};
1799 
1800     constexpr const std::array<pldm_descriptor, 2> expected_descriptors = {{
1801         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1802          &iana_pen_dmtf},
1803         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1804          &iana_pen_openbmc},
1805     }};
1806 
1807     constexpr uint32_t downstream_devices_len = 22;
1808     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1809     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1810     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1811     const uint32_t downstream_devices_length_resp =
1812         htole32(downstream_devices_len);
1813     constexpr uint16_t number_of_downstream_devices_resp = 2;
1814     constexpr size_t payloadLen =
1815         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
1816 
1817     struct pldm_query_downstream_identifiers_resp resp_data{};
1818     PLDM_MSG_DEFINE_P(response, payloadLen);
1819     struct pldm_downstream_device_iter devs;
1820     struct pldm_downstream_device dev;
1821     struct pldm_msgbuf _buf;
1822     struct pldm_msgbuf* buf = &_buf;
1823     int rc = 0;
1824 
1825     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1826     ASSERT_EQ(rc, 0);
1827 
1828     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1829     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1830     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1831     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1832     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1833 
1834     /* Downstream device */
1835     pldm_msgbuf_insert_uint16(buf, 0);
1836     pldm_msgbuf_insert_uint8(buf, 1);
1837 
1838     /* Device descriptor */
1839     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1840     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1841     pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1842 
1843     /* Downstream device */
1844     pldm_msgbuf_insert_uint16(buf, 1);
1845     pldm_msgbuf_insert_uint8(buf, 1);
1846 
1847     /* Device descriptor */
1848     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1849     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1850     pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
1851 
1852     ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1853 
1854     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1855                                                   &resp_data, &devs);
1856 
1857     ASSERT_EQ(rc, 0);
1858     EXPECT_EQ(resp_data.number_of_downstream_devices,
1859               number_of_downstream_devices_resp);
1860 
1861     size_t devIndex = 0;
1862     size_t descIndex = 0;
1863     foreach_pldm_downstream_device(devs, dev, rc)
1864     {
1865         struct pldm_descriptor desc;
1866 
1867         ASSERT_LT(devIndex, expected_devices.size());
1868 
1869         const struct pldm_downstream_device* expectedDev =
1870             &expected_devices[devIndex];
1871 
1872         EXPECT_EQ(dev.downstream_device_index,
1873                   expectedDev->downstream_device_index);
1874         EXPECT_EQ(dev.downstream_descriptor_count,
1875                   expectedDev->downstream_descriptor_count);
1876 
1877         foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1878         {
1879             ASSERT_LT(descIndex, expected_descriptors.size());
1880 
1881             const struct pldm_descriptor* expectedDesc =
1882                 &expected_descriptors[descIndex];
1883 
1884             EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
1885             ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
1886             EXPECT_EQ(memcmp(desc.descriptor_data,
1887                              expectedDesc->descriptor_data,
1888                              expectedDesc->descriptor_length),
1889                       0);
1890 
1891             descIndex++;
1892         }
1893         ASSERT_EQ(rc, 0);
1894         EXPECT_EQ(descIndex, 1 * devIndex + 1);
1895 
1896         devIndex++;
1897     }
1898     ASSERT_EQ(rc, 0);
1899     EXPECT_EQ(devIndex, 2);
1900 }
1901 
TEST(QueryDownstreamIdentifiers,decodeResponseTwoDevicesTwoOneDescriptors)1902 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesTwoOneDescriptors)
1903 {
1904     constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1905         {0, 2},
1906         {1, 1},
1907     }};
1908 
1909     constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
1910         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1911          &iana_pen_dmtf},
1912         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1913          &iana_pen_openbmc},
1914         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1915          &iana_pen_dmtf},
1916     }};
1917 
1918     constexpr uint32_t downstream_devices_len = 30;
1919     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1920     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1921     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1922     const uint32_t downstream_devices_length_resp =
1923         htole32(downstream_devices_len);
1924     constexpr uint16_t number_of_downstream_devices_resp = 2;
1925     constexpr size_t payloadLen =
1926         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
1927 
1928     struct pldm_query_downstream_identifiers_resp resp_data{};
1929     PLDM_MSG_DEFINE_P(response, payloadLen);
1930     struct pldm_downstream_device_iter devs;
1931     struct pldm_downstream_device dev;
1932     struct pldm_msgbuf _buf;
1933     struct pldm_msgbuf* buf = &_buf;
1934     int rc = 0;
1935 
1936     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1937     ASSERT_EQ(rc, 0);
1938 
1939     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1940     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1941     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1942     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1943     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1944 
1945     /* Downstream device */
1946     pldm_msgbuf_insert_uint16(buf, 0);
1947     pldm_msgbuf_insert_uint8(buf, 2);
1948 
1949     /* Device descriptor */
1950     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1951     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1952     pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1953 
1954     /* Device descriptor */
1955     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1956     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1957     pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
1958 
1959     /* Downstream device */
1960     pldm_msgbuf_insert_uint16(buf, 1);
1961     pldm_msgbuf_insert_uint8(buf, 1);
1962 
1963     /* Device descriptor */
1964     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1965     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1966     pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1967 
1968     ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1969 
1970     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1971                                                   &resp_data, &devs);
1972 
1973     ASSERT_EQ(rc, 0);
1974     EXPECT_EQ(resp_data.number_of_downstream_devices,
1975               number_of_downstream_devices_resp);
1976 
1977     size_t devIndex = 0;
1978     size_t descIndex = 0;
1979     foreach_pldm_downstream_device(devs, dev, rc)
1980     {
1981         struct pldm_descriptor desc;
1982 
1983         ASSERT_LT(devIndex, expected_devices.size());
1984 
1985         const struct pldm_downstream_device* expectedDev =
1986             &expected_devices[devIndex];
1987 
1988         EXPECT_EQ(dev.downstream_device_index,
1989                   expectedDev->downstream_device_index);
1990         EXPECT_EQ(dev.downstream_descriptor_count,
1991                   expectedDev->downstream_descriptor_count);
1992 
1993         foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1994         {
1995             ASSERT_LT(descIndex, expected_descriptors.size());
1996 
1997             const struct pldm_descriptor* expectedDesc =
1998                 &expected_descriptors[descIndex];
1999 
2000             EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2001             ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2002             EXPECT_EQ(memcmp(desc.descriptor_data,
2003                              expectedDesc->descriptor_data,
2004                              expectedDesc->descriptor_length),
2005                       0);
2006 
2007             descIndex++;
2008         }
2009         ASSERT_EQ(rc, 0);
2010 
2011         devIndex++;
2012     }
2013     ASSERT_EQ(rc, 0);
2014     EXPECT_EQ(devIndex, 2);
2015     EXPECT_EQ(descIndex, 3);
2016 }
2017 
TEST(QueryDownstreamIdentifiers,decodeResponseTwoDevicesOneTwoDescriptors)2018 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneTwoDescriptors)
2019 {
2020     constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
2021         {0, 1},
2022         {1, 2},
2023     }};
2024 
2025     constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
2026         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2027          &iana_pen_dmtf},
2028         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2029          &iana_pen_openbmc},
2030         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2031          &iana_pen_dmtf},
2032     }};
2033 
2034     constexpr uint32_t downstream_devices_len = 30;
2035     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2036     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2037     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2038     const uint32_t downstream_devices_length_resp =
2039         htole32(downstream_devices_len);
2040     constexpr uint16_t number_of_downstream_devices_resp = 2;
2041     constexpr size_t payloadLen =
2042         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2043 
2044     struct pldm_query_downstream_identifiers_resp resp_data{};
2045     PLDM_MSG_DEFINE_P(response, payloadLen);
2046     struct pldm_downstream_device_iter devs;
2047     struct pldm_downstream_device dev;
2048     struct pldm_msgbuf _buf;
2049     struct pldm_msgbuf* buf = &_buf;
2050     int rc = 0;
2051 
2052     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2053     ASSERT_EQ(rc, 0);
2054 
2055     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2056     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2057     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2058     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2059     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2060 
2061     /* Downstream device */
2062     pldm_msgbuf_insert_uint16(buf, 0);
2063     pldm_msgbuf_insert_uint8(buf, 1);
2064 
2065     /* Device descriptor */
2066     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2067     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2068     pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2069 
2070     /* Downstream device */
2071     pldm_msgbuf_insert_uint16(buf, 1);
2072     pldm_msgbuf_insert_uint8(buf, 2);
2073 
2074     /* Device descriptor */
2075     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2076     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2077     pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2078 
2079     /* Device descriptor */
2080     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2081     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2082     pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2083 
2084     ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
2085 
2086     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2087                                                   &resp_data, &devs);
2088 
2089     ASSERT_EQ(rc, 0);
2090     EXPECT_EQ(resp_data.number_of_downstream_devices,
2091               number_of_downstream_devices_resp);
2092 
2093     size_t devIndex = 0;
2094     size_t descIndex = 0;
2095     foreach_pldm_downstream_device(devs, dev, rc)
2096     {
2097         struct pldm_descriptor desc;
2098 
2099         ASSERT_LT(devIndex, expected_devices.size());
2100 
2101         const struct pldm_downstream_device* expectedDev =
2102             &expected_devices[devIndex];
2103 
2104         EXPECT_EQ(dev.downstream_device_index,
2105                   expectedDev->downstream_device_index);
2106         EXPECT_EQ(dev.downstream_descriptor_count,
2107                   expectedDev->downstream_descriptor_count);
2108 
2109         foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2110         {
2111             ASSERT_LT(descIndex, expected_descriptors.size());
2112 
2113             const struct pldm_descriptor* expectedDesc =
2114                 &expected_descriptors[descIndex];
2115 
2116             EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2117             ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2118             EXPECT_EQ(memcmp(desc.descriptor_data,
2119                              expectedDesc->descriptor_data,
2120                              expectedDesc->descriptor_length),
2121                       0);
2122 
2123             descIndex++;
2124         }
2125         ASSERT_EQ(rc, 0);
2126 
2127         devIndex++;
2128     }
2129     ASSERT_EQ(rc, 0);
2130     EXPECT_EQ(devIndex, 2);
2131     EXPECT_EQ(descIndex, 3);
2132 }
2133 
TEST(QueryDownstreamIdentifiers,decodeRequestErrorPaths)2134 TEST(QueryDownstreamIdentifiers, decodeRequestErrorPaths)
2135 {
2136     constexpr size_t payloadLen = sizeof(uint8_t);
2137 
2138     struct pldm_query_downstream_identifiers_resp resp_data = {};
2139     struct pldm_downstream_device_iter devs;
2140     PLDM_MSG_DEFINE_P(response, payloadLen);
2141 
2142     // Test nullptr
2143     auto rc = decode_query_downstream_identifiers_resp(nullptr, payloadLen,
2144                                                        nullptr, &devs);
2145     EXPECT_EQ(rc, -EINVAL);
2146 
2147     // Test not PLDM_SUCCESS completion code
2148     response->payload[0] = PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
2149     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2150                                                   &resp_data, &devs);
2151     EXPECT_EQ(rc, 0);
2152     EXPECT_EQ(resp_data.completion_code, PLDM_ERROR_UNSUPPORTED_PLDM_CMD);
2153 
2154     // Test payload length less than minimum length
2155     response->payload[0] = PLDM_SUCCESS;
2156     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2157                                                   &resp_data, &devs);
2158 
2159     EXPECT_EQ(rc, -EBADMSG);
2160 }
2161 
TEST(QueryDownstreamIdentifiers,decodeRequestErrorDownstreamDevicesSize)2162 TEST(QueryDownstreamIdentifiers, decodeRequestErrorDownstreamDevicesSize)
2163 {
2164     // Len is not fixed here taking it as 9, contains 1 downstream device with
2165     // 1 descriptor
2166     constexpr uint32_t actualDownstreamDevicesLen = 9;
2167     constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2168     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2169     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2170     constexpr uint16_t number_of_downstream_devices_resp = 1;
2171     constexpr size_t payloadLen =
2172         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN +
2173         actualDownstreamDevicesLen;
2174 
2175     const uint32_t downstream_devices_length_resp =
2176         htole32(actualDownstreamDevicesLen + 1 /* inject error length*/);
2177 
2178     struct pldm_query_downstream_identifiers_resp resp_data = {};
2179     struct pldm_downstream_device_iter devs;
2180     PLDM_MSG_DEFINE_P(response, payloadLen);
2181     struct pldm_msgbuf _buf;
2182     struct pldm_msgbuf* buf = &_buf;
2183     void* devicesStart = NULL;
2184     size_t devicesLen;
2185     int rc = 0;
2186 
2187     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2188     EXPECT_EQ(rc, 0);
2189 
2190     pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2191     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2192     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2193     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2194     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2195     pldm_msgbuf_span_remaining(buf, &devicesStart, &devicesLen);
2196 
2197     /** Filling descriptor data, the correctness of the downstream devices data
2198      *  is not checked in this test case so filling with 0xff
2199      */
2200     std::fill_n(static_cast<uint8_t*>(devicesStart), actualDownstreamDevicesLen,
2201                 0xff);
2202 
2203     EXPECT_NE(decode_query_downstream_identifiers_resp(response, payloadLen,
2204                                                        &resp_data, &devs),
2205               0);
2206 }
2207 
TEST(QueryDownstreamIdentifiers,decodeRequestErrorBufSize)2208 TEST(QueryDownstreamIdentifiers, decodeRequestErrorBufSize)
2209 {
2210     constexpr uint32_t actualDownstreamDevicesLen = 0;
2211     constexpr uint16_t number_of_downstream_devices_resp = 1;
2212     constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2213     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2214     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2215     constexpr size_t payloadLen =
2216         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN - 1;
2217 
2218     const uint32_t downstream_devices_length_resp =
2219         htole32(actualDownstreamDevicesLen);
2220 
2221     struct pldm_query_downstream_identifiers_resp resp_data = {};
2222     struct pldm_downstream_device_iter devs;
2223     PLDM_MSG_DEFINE_P(response, payloadLen);
2224     struct pldm_msgbuf _buf;
2225     struct pldm_msgbuf* buf = &_buf;
2226     int rc = 0;
2227 
2228     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2229     ASSERT_EQ(rc, 0);
2230 
2231     pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2232     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2233     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2234     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2235     // Inject error buffer size
2236     pldm_msgbuf_insert_uint8(buf, (uint8_t)number_of_downstream_devices_resp);
2237 
2238     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2239                                                   &resp_data, &devs);
2240 
2241     EXPECT_EQ(rc, -EBADMSG);
2242 }
2243 
TEST(GetDownstreamFirmwareParameters,goodPathEncodeRequest)2244 TEST(GetDownstreamFirmwareParameters, goodPathEncodeRequest)
2245 {
2246     constexpr uint8_t instanceId = 1;
2247     constexpr pldm_get_downstream_firmware_parameters_req params_req{
2248         0x0, PLDM_GET_FIRSTPART};
2249     constexpr size_t payload_length =
2250         PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
2251     std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
2252     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2253     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2254 
2255     auto rc = encode_get_downstream_firmware_parameters_req(
2256         instanceId, &params_req, requestPtr, payload_length);
2257     EXPECT_EQ(rc, 0);
2258 
2259     std::array<uint8_t,
2260                hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES>
2261         expectedReq{0x81, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01};
2262     EXPECT_EQ(requestMsg, expectedReq);
2263 }
2264 
TEST(GetDownstreamFirmwareParameters,encodeRequestInvalidTransferOperationFlag)2265 TEST(GetDownstreamFirmwareParameters, encodeRequestInvalidTransferOperationFlag)
2266 {
2267     constexpr uint8_t instanceId = 1;
2268     // Setup invalid transfer operation flag
2269     constexpr pldm_get_downstream_firmware_parameters_req params_req{
2270         0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
2271     constexpr size_t payload_length =
2272         PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
2273     std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
2274     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2275     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2276 
2277     auto rc = encode_get_downstream_firmware_parameters_req(
2278         instanceId, &params_req, requestPtr, payload_length);
2279     EXPECT_EQ(rc, -EBADMSG);
2280 }
2281 
TEST(GetDownstreamFirmwareParameters,encodeRequestErrorBufSize)2282 TEST(GetDownstreamFirmwareParameters, encodeRequestErrorBufSize)
2283 {
2284     constexpr uint8_t instanceId = 1;
2285     // Setup invalid transfer operation flag
2286     constexpr pldm_get_downstream_firmware_parameters_req params_req{
2287         0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
2288     constexpr size_t payload_length =
2289         PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES -
2290         1 /* inject erro length*/;
2291 
2292     std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
2293     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2294     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2295 
2296     auto rc = encode_get_downstream_firmware_parameters_req(
2297         instanceId, &params_req, requestPtr, payload_length);
2298     EXPECT_EQ(rc, -EOVERFLOW);
2299 }
2300 
TEST(GetDownstreamFirmwareParameters,goodPathDecodeResponseOneEntry)2301 TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseOneEntry)
2302 {
2303     constexpr uint16_t downstreamDeviceCount = 1;
2304     constexpr uint8_t activeComponentVersionStringLength = 8;
2305     constexpr uint8_t pendingComponentVersionStringLength = 8;
2306     constexpr size_t downstreamDeviceParamTableLen =
2307         PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2308         activeComponentVersionStringLength +
2309         pendingComponentVersionStringLength;
2310     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2311     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2312     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2313     constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2314     constexpr size_t payload_len =
2315         PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2316         downstreamDeviceParamTableLen;
2317 
2318     PLDM_MSG_DEFINE_P(response, payload_len);
2319     struct pldm_msgbuf _buf;
2320     struct pldm_msgbuf* buf = &_buf;
2321     int rc = 0;
2322 
2323     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
2324     EXPECT_EQ(rc, 0);
2325 
2326     // Table 24
2327     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2328     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2329     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2330 
2331     // Table 25
2332     pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2333     pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2334 
2335     // Table 26
2336     pldm_msgbuf_insert_uint16(buf, 0);
2337 
2338     // - Active metadata
2339     pldm_msgbuf_insert_uint32(buf, 0);
2340     pldm_msgbuf_insert_uint8(buf, 1);
2341     pldm_msgbuf_insert_uint8(buf, activeComponentVersionStringLength);
2342     rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2343     ASSERT_EQ(rc, 0);
2344 
2345     // - Pending metadata
2346     pldm_msgbuf_insert_uint32(buf, 0);
2347     pldm_msgbuf_insert_uint8(buf, 1);
2348     pldm_msgbuf_insert_uint8(buf, pendingComponentVersionStringLength);
2349     rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2350     ASSERT_EQ(rc, 0);
2351 
2352     // - Methods and capabilities
2353     pldm_msgbuf_insert_uint16(buf, 1);
2354     pldm_msgbuf_insert_uint32(buf, 0);
2355 
2356     // - Version strings
2357     rc = pldm__msgbuf_insert_array_void(buf, activeComponentVersionStringLength,
2358                                         "abcdefgh", 8);
2359     ASSERT_EQ(rc, 0);
2360     rc = pldm__msgbuf_insert_array_void(
2361         buf, pendingComponentVersionStringLength, "zyxwvuts", 8);
2362     ASSERT_EQ(rc, 0);
2363 
2364     rc = pldm_msgbuf_destroy_consumed(buf);
2365     ASSERT_EQ(rc, 0);
2366 
2367     struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2368     struct pldm_downstream_device_parameters_iter iter = {};
2369 
2370     rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2371                                                         &resp_data, &iter);
2372 
2373     ASSERT_EQ(rc, 0);
2374     EXPECT_EQ(resp_data.completion_code, completion_code_resp);
2375     EXPECT_EQ(resp_data.next_data_transfer_handle,
2376               next_data_transfer_handle_resp);
2377     EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2378     EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
2379 
2380     struct pldm_downstream_device_parameters_entry entry;
2381     size_t entries = 0;
2382     foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2383     {
2384         EXPECT_EQ(entry.downstream_device_index, 0);
2385         EXPECT_EQ(entry.active_comp_comparison_stamp, 0);
2386         EXPECT_EQ(entry.active_comp_ver_str_type, 1);
2387         EXPECT_EQ(entry.active_comp_ver_str_len,
2388                   activeComponentVersionStringLength);
2389         EXPECT_STREQ("20241206", entry.active_comp_release_date);
2390         EXPECT_EQ(entry.pending_comp_comparison_stamp, 0);
2391         EXPECT_EQ(entry.pending_comp_ver_str_type, 1);
2392         EXPECT_EQ(entry.pending_comp_ver_str_len,
2393                   pendingComponentVersionStringLength);
2394         EXPECT_STREQ("20241206", entry.pending_comp_release_date);
2395         EXPECT_EQ(entry.comp_activation_methods.value, 1);
2396         EXPECT_EQ(entry.capabilities_during_update.value, 0);
2397         EXPECT_FALSE(memcmp("abcdefgh", entry.active_comp_ver_str,
2398                             entry.active_comp_ver_str_len));
2399         EXPECT_FALSE(memcmp("zyxwvuts", entry.pending_comp_ver_str,
2400                             entry.pending_comp_ver_str_len));
2401         entries++;
2402     }
2403     EXPECT_EQ(rc, 0);
2404     EXPECT_EQ(entries, 1);
2405 }
2406 
TEST(GetDownstreamFirmwareParameters,goodPathDecodeResponseTwoEntries)2407 TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseTwoEntries)
2408 {
2409     /** Count is not fixed here taking it as 1, and the downstream device's
2410      *  version strings length are set to 8
2411      */
2412     constexpr uint16_t downstreamDeviceCount = 2;
2413     constexpr uint8_t activeComponentVersionStringLength = 8;
2414     constexpr uint8_t pendingComponentVersionStringLength = 9;
2415     constexpr size_t downstreamDeviceParamTableLen =
2416         static_cast<size_t>(downstreamDeviceCount *
2417                             (PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2418                              activeComponentVersionStringLength +
2419                              pendingComponentVersionStringLength));
2420     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2421     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2422     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2423     constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2424     constexpr size_t payload_len =
2425         PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2426         downstreamDeviceParamTableLen;
2427 
2428     PLDM_MSG_DEFINE_P(response, payload_len);
2429     struct pldm_msgbuf _buf;
2430     struct pldm_msgbuf* buf = &_buf;
2431     int rc = 0;
2432 
2433     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
2434     EXPECT_EQ(rc, 0);
2435 
2436     // Table 24
2437     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2438     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2439     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2440 
2441     // Table 25
2442     pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2443     pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2444 
2445     constexpr const std::array<pldm_downstream_device_parameters_entry, 2>
2446         table = {{{
2447                       0,
2448                       0,
2449                       1,
2450                       8,
2451                       "20241206",
2452                       0,
2453                       1,
2454                       9,
2455                       "20241209",
2456                       {1},
2457                       {0},
2458                       "active_0",
2459                       "pending_0",
2460                   },
2461                   {
2462                       1,
2463                       0,
2464                       1,
2465                       8,
2466                       "20241209",
2467                       0,
2468                       1,
2469                       9,
2470                       "20241206",
2471                       {1},
2472                       {0},
2473                       "active_1",
2474                       "pending_1",
2475                   }}};
2476     for (const auto& e : table)
2477     {
2478         // Table 26
2479         pldm_msgbuf_insert_uint16(buf, e.downstream_device_index);
2480 
2481         // - Active metadata
2482         pldm_msgbuf_insert_uint32(buf, e.active_comp_comparison_stamp);
2483         pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_type);
2484         pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_len);
2485         rc = pldm__msgbuf_insert_array_void(buf, 8, &e.active_comp_release_date,
2486                                             sizeof(e.active_comp_release_date));
2487         ASSERT_EQ(rc, 0);
2488 
2489         // - Pending metadata
2490         pldm_msgbuf_insert_uint32(buf, e.pending_comp_comparison_stamp);
2491         pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_type);
2492         pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_len);
2493         rc =
2494             pldm__msgbuf_insert_array_void(buf, 8, e.pending_comp_release_date,
2495                                            sizeof(e.pending_comp_release_date));
2496         ASSERT_EQ(rc, 0);
2497 
2498         // - Methods and capabilities
2499         pldm_msgbuf_insert_uint16(buf, e.comp_activation_methods.value);
2500         pldm_msgbuf_insert_uint32(buf, e.capabilities_during_update.value);
2501 
2502         // - Version strings
2503         rc = pldm__msgbuf_insert_array_void(buf, e.active_comp_ver_str_len,
2504                                             e.active_comp_ver_str,
2505                                             e.active_comp_ver_str_len);
2506         ASSERT_EQ(rc, 0);
2507         rc = pldm__msgbuf_insert_array_void(buf, e.pending_comp_ver_str_len,
2508                                             e.pending_comp_ver_str,
2509                                             e.pending_comp_ver_str_len);
2510         ASSERT_EQ(rc, 0);
2511     }
2512 
2513     rc = pldm_msgbuf_destroy_consumed(buf);
2514     ASSERT_EQ(rc, 0);
2515 
2516     struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2517     struct pldm_downstream_device_parameters_iter iter = {};
2518 
2519     rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2520                                                         &resp_data, &iter);
2521 
2522     ASSERT_EQ(rc, 0);
2523     EXPECT_EQ(resp_data.completion_code, completion_code_resp);
2524     EXPECT_EQ(resp_data.next_data_transfer_handle,
2525               next_data_transfer_handle_resp);
2526     EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2527     EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
2528 
2529     struct pldm_downstream_device_parameters_entry entry;
2530     size_t entryIndex = 0;
2531     foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2532     {
2533         ASSERT_LE(entryIndex, table.size());
2534 
2535         EXPECT_EQ(table[entryIndex].downstream_device_index,
2536                   entry.downstream_device_index);
2537         EXPECT_EQ(table[entryIndex].active_comp_comparison_stamp,
2538                   entry.active_comp_comparison_stamp);
2539         EXPECT_EQ(table[entryIndex].active_comp_ver_str_type,
2540                   entry.active_comp_ver_str_type);
2541         EXPECT_EQ(table[entryIndex].active_comp_ver_str_len,
2542                   entry.active_comp_ver_str_len);
2543         EXPECT_STREQ(&table[entryIndex].active_comp_release_date[0],
2544                      &entry.active_comp_release_date[0]);
2545         EXPECT_EQ(table[entryIndex].pending_comp_comparison_stamp,
2546                   entry.pending_comp_comparison_stamp);
2547         EXPECT_EQ(table[entryIndex].pending_comp_ver_str_type,
2548                   entry.pending_comp_ver_str_type);
2549         EXPECT_EQ(table[entryIndex].pending_comp_ver_str_len,
2550                   entry.pending_comp_ver_str_len);
2551         EXPECT_STREQ(&table[entryIndex].pending_comp_release_date[0],
2552                      &entry.pending_comp_release_date[0]);
2553         EXPECT_EQ(table[entryIndex].comp_activation_methods.value,
2554                   entry.comp_activation_methods.value);
2555         EXPECT_EQ(table[entryIndex].capabilities_during_update.value,
2556                   entry.capabilities_during_update.value);
2557         EXPECT_FALSE(memcmp(table[entryIndex].active_comp_ver_str,
2558                             entry.active_comp_ver_str,
2559                             table[entryIndex].active_comp_ver_str_len));
2560         EXPECT_FALSE(memcmp(table[entryIndex].pending_comp_ver_str,
2561                             entry.pending_comp_ver_str,
2562                             table[entryIndex].pending_comp_ver_str_len));
2563         entryIndex++;
2564     }
2565     EXPECT_EQ(rc, 0);
2566     EXPECT_EQ(entryIndex, table.size());
2567 }
2568 
TEST(GetDownstreamFirmwareParameters,decodeResponseInvalidLength)2569 TEST(GetDownstreamFirmwareParameters, decodeResponseInvalidLength)
2570 {
2571     /** Count is not fixed here taking it as 1, and the downstream device's
2572      *  version strings length are set to 8
2573      */
2574     constexpr uint16_t downstreamDeviceCount = 1;
2575     constexpr uint8_t activeComponentVersionStringLength = 8;
2576     constexpr uint8_t pendingComponentVersionStringLength = 8;
2577     constexpr size_t downstreamDeviceParamTableLen =
2578         PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2579         activeComponentVersionStringLength +
2580         pendingComponentVersionStringLength;
2581     constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2582     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2583     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2584     constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2585 
2586     std::array<uint8_t,
2587                hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2588                    downstreamDeviceParamTableLen - 1 /* inject error length*/>
2589         responseMsg{};
2590 
2591     int rc = 0;
2592 
2593     struct pldm_msgbuf _buf;
2594     struct pldm_msgbuf* buf = &_buf;
2595     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
2596                                 responseMsg.size() - hdrSize);
2597     EXPECT_EQ(rc, 0);
2598 
2599     pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2600     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2601     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2602     pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2603     pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2604 
2605     /** Filling paramter table, the correctness of the downstream devices data
2606      *  is not checked in this test case so filling with 0xff
2607      */
2608     std::fill_n(responseMsg.data() + hdrSize +
2609                     PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN,
2610                 downstreamDeviceParamTableLen - 1 /* inject error length*/,
2611                 0xff);
2612 
2613     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2614     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
2615     struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2616     struct pldm_downstream_device_parameters_iter iter;
2617 
2618     rc = decode_get_downstream_firmware_parameters_resp(
2619         response, responseMsg.size() - hdrSize, &resp_data, &iter);
2620     EXPECT_EQ(rc, 0);
2621 
2622     struct pldm_downstream_device_parameters_entry entry;
2623     foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2624     {
2625         FAIL();
2626     }
2627     EXPECT_EQ(rc, -EOVERFLOW);
2628 }
2629 
TEST(RequestUpdate,goodPathEncodeRequest)2630 TEST(RequestUpdate, goodPathEncodeRequest)
2631 {
2632     constexpr uint8_t instanceId = 1;
2633     constexpr uint32_t maxTransferSize = 512;
2634     constexpr uint16_t numOfComp = 3;
2635     constexpr uint8_t maxOutstandingTransferReq = 2;
2636     constexpr uint16_t pkgDataLen = 0x1234;
2637     constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2638     constexpr uint8_t compImgSetVerStrLen =
2639         static_cast<uint8_t>(compImgSetVerStr.size());
2640     variable_field compImgSetVerStrInfo{};
2641     compImgSetVerStrInfo.ptr =
2642         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2643         reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2644     compImgSetVerStrInfo.length = compImgSetVerStrLen;
2645 
2646     std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2647                             compImgSetVerStrLen>
2648         request{};
2649     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2650     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2651 
2652     auto rc = encode_request_update_req(
2653         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2654         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2655         &compImgSetVerStrInfo, requestMsg,
2656         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2657     EXPECT_EQ(rc, PLDM_SUCCESS);
2658 
2659     std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2660                             compImgSetVerStrLen>
2661         outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00,
2662                    0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e,
2663                    0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30};
2664     EXPECT_EQ(request, outRequest);
2665 }
2666 
TEST(RequestUpdate,errorPathEncodeRequest)2667 TEST(RequestUpdate, errorPathEncodeRequest)
2668 {
2669     constexpr uint8_t instanceId = 1;
2670     uint32_t maxTransferSize = 512;
2671     constexpr uint16_t numOfComp = 3;
2672     uint8_t maxOutstandingTransferReq = 2;
2673     constexpr uint16_t pkgDataLen = 0x1234;
2674     constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2675     uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2676     variable_field compImgSetVerStrInfo{};
2677     compImgSetVerStrInfo.ptr =
2678         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2679         reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2680     compImgSetVerStrInfo.length = compImgSetVerStrLen;
2681 
2682     std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2683                             compImgSetVerStr.size()>
2684         request{};
2685     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2686     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2687 
2688     auto rc = encode_request_update_req(
2689         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2690         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr,
2691         requestMsg,
2692         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2693     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2694 
2695     compImgSetVerStrInfo.ptr = nullptr;
2696     rc = encode_request_update_req(
2697         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2698         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2699         &compImgSetVerStrInfo, requestMsg,
2700         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2701     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2702     compImgSetVerStrInfo.ptr =
2703         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2704         reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2705 
2706     rc = encode_request_update_req(
2707         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2708         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2709         &compImgSetVerStrInfo, nullptr,
2710         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2711     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2712 
2713     rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp,
2714                                    maxOutstandingTransferReq, pkgDataLen,
2715                                    PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2716                                    &compImgSetVerStrInfo, requestMsg, 0);
2717     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2718 
2719     compImgSetVerStrLen = 0;
2720     rc = encode_request_update_req(
2721         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2722         pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr,
2723         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2724     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2725     compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2726 
2727     compImgSetVerStrInfo.length = 0xffff;
2728     rc = encode_request_update_req(
2729         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2730         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2731         &compImgSetVerStrInfo, nullptr,
2732         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2733     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2734     compImgSetVerStrInfo.length = compImgSetVerStrLen;
2735 
2736     maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1;
2737     rc = encode_request_update_req(
2738         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2739         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2740         &compImgSetVerStrInfo, nullptr,
2741         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2742     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2743     maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE;
2744 
2745     maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ - 1;
2746     rc = encode_request_update_req(
2747         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2748         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2749         &compImgSetVerStrInfo, nullptr,
2750         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2751     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2752     maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ;
2753 
2754     rc = encode_request_update_req(
2755         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2756         pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen,
2757         &compImgSetVerStrInfo, nullptr,
2758         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2759     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2760 }
2761 
TEST(RequestUpdate,goodPathDecodeResponse)2762 TEST(RequestUpdate, goodPathDecodeResponse)
2763 {
2764     /* Test a success completion code */
2765     constexpr uint16_t fdMetaDataLen = 1024;
2766     constexpr uint8_t fdWillSendPkgData = 1;
2767     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)>
2768         requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01};
2769 
2770     auto responseMsg1 =
2771         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2772         reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data());
2773     uint8_t outCompletionCode = 0;
2774     uint16_t outFdMetaDataLen = 0;
2775     uint8_t outFdWillSendPkgData = 0;
2776 
2777     auto rc = decode_request_update_resp(
2778         responseMsg1, requestUpdateResponse1.size() - hdrSize,
2779         &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2780     EXPECT_EQ(rc, PLDM_SUCCESS);
2781     EXPECT_EQ(outCompletionCode, PLDM_SUCCESS);
2782     EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen);
2783     EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData);
2784 
2785 #ifdef LIBPLDM_API_TESTING
2786     /* Check the success roundtrip matches */
2787     PLDM_MSG_DEFINE_P(enc, 1000);
2788     size_t enc_payload_len = 1000;
2789     const struct pldm_request_update_resp resp_data = {
2790         .completion_code = PLDM_SUCCESS,
2791         .fd_meta_data_len = outFdMetaDataLen,
2792         .fd_will_send_pkg_data = outFdWillSendPkgData,
2793     };
2794     rc = encode_request_update_resp(FIXED_INSTANCE_ID, &resp_data, enc,
2795                                     &enc_payload_len);
2796     EXPECT_EQ(rc, PLDM_SUCCESS);
2797     EXPECT_EQ(enc_payload_len + hdrSize, requestUpdateResponse1.size());
2798     EXPECT_TRUE(std::equal(requestUpdateResponse1.begin() + hdrSize,
2799                            requestUpdateResponse1.end(), enc_buf + hdrSize));
2800     check_response(enc, PLDM_REQUEST_UPDATE);
2801 #endif
2802 
2803     /* Test a failure completion code */
2804     outCompletionCode = 0;
2805     outFdMetaDataLen = 0;
2806     outFdWillSendPkgData = 0;
2807 
2808     constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)>
2809         requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
2810     auto responseMsg2 =
2811         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2812         reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data());
2813     rc = decode_request_update_resp(
2814         responseMsg2, requestUpdateResponse2.size() - hdrSize,
2815         &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2816     EXPECT_EQ(rc, PLDM_SUCCESS);
2817     EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
2818 }
2819 
TEST(RequestUpdate,errorPathDecodeResponse)2820 TEST(RequestUpdate, errorPathDecodeResponse)
2821 {
2822     constexpr std::array<uint8_t,
2823                          hdrSize + sizeof(pldm_request_update_resp) - 1>
2824         requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
2825 
2826     auto responseMsg =
2827         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2828         reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data());
2829     uint8_t outCompletionCode = 0;
2830     uint16_t outFdMetaDataLen = 0;
2831     uint8_t outFdWillSendPkgData = 0;
2832 
2833     auto rc = decode_request_update_resp(
2834         nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2835         &outFdMetaDataLen, &outFdWillSendPkgData);
2836     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2837 
2838     rc = decode_request_update_resp(
2839         responseMsg, requestUpdateResponse.size() - hdrSize, nullptr,
2840         &outFdMetaDataLen, &outFdWillSendPkgData);
2841     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2842 
2843     rc = decode_request_update_resp(
2844         responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2845         nullptr, &outFdWillSendPkgData);
2846     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2847 
2848     rc = decode_request_update_resp(
2849         responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2850         &outFdMetaDataLen, nullptr);
2851     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2852 
2853     rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode,
2854                                     &outFdMetaDataLen, &outFdWillSendPkgData);
2855     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2856 
2857     rc = decode_request_update_resp(
2858         responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2859         &outFdMetaDataLen, &outFdWillSendPkgData);
2860     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2861 }
2862 
TEST(PassComponentTable,goodPathEncodeRequest)2863 TEST(PassComponentTable, goodPathEncodeRequest)
2864 {
2865     constexpr uint8_t instanceId = 1;
2866     constexpr uint16_t compIdentifier = 400;
2867     constexpr uint8_t compClassificationIndex = 40;
2868     constexpr uint32_t compComparisonStamp = 0x12345678;
2869     constexpr std::string_view compVerStr = "0penBmcv1.1";
2870     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2871     variable_field compVerStrInfo{};
2872     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2873     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2874     compVerStrInfo.length = compVerStrLen;
2875 
2876     std::array<uint8_t,
2877                hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2878         request{};
2879     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2880     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2881 
2882     auto rc = encode_pass_component_table_req(
2883         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2884         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2885         compVerStrLen, &compVerStrInfo, requestMsg,
2886         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2887     EXPECT_EQ(rc, PLDM_SUCCESS);
2888 
2889     std::array<uint8_t,
2890                hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2891         outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28,
2892                    0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65,
2893                    0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31};
2894     EXPECT_EQ(request, outRequest);
2895 
2896 #ifdef LIBPLDM_API_TESTING
2897     /* Check the roundtrip */
2898     struct pldm_pass_component_table_req_full req;
2899     PLDM_MSG_DEFINE_P(dec, outRequest.size());
2900     std::copy(outRequest.begin(), outRequest.end(), dec_buf);
2901     rc =
2902         decode_pass_component_table_req(dec, outRequest.size() - hdrSize, &req);
2903     ASSERT_EQ(rc, 0);
2904 
2905     EXPECT_EQ(req.transfer_flag, PLDM_START_AND_END);
2906     EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
2907     EXPECT_EQ(req.comp_identifier, compIdentifier);
2908     EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
2909     EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
2910     EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
2911     EXPECT_EQ(req.version.str_len, compVerStrLen);
2912     EXPECT_TRUE(std::equal(req.version.str_data,
2913                            req.version.str_data + req.version.str_len,
2914                            compVerStr.data()));
2915 #endif
2916 }
2917 
TEST(PassComponentTable,errorPathEncodeRequest)2918 TEST(PassComponentTable, errorPathEncodeRequest)
2919 {
2920     constexpr uint8_t instanceId = 1;
2921     constexpr uint16_t compIdentifier = 400;
2922     constexpr uint8_t compClassificationIndex = 40;
2923     constexpr uint32_t compComparisonStamp = 0x12345678;
2924     constexpr std::string_view compVerStr = "0penBmcv1.1";
2925     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2926     variable_field compVerStrInfo{};
2927     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2928     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2929     compVerStrInfo.length = compVerStrLen;
2930 
2931     std::array<uint8_t,
2932                hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2933         request{};
2934     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2935     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2936 
2937     auto rc = encode_pass_component_table_req(
2938         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2939         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2940         compVerStrLen, nullptr, requestMsg,
2941         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2942     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2943 
2944     compVerStrInfo.ptr = nullptr;
2945     rc = encode_pass_component_table_req(
2946         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2947         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2948         compVerStrLen, &compVerStrInfo, requestMsg,
2949         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2950     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2951     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2952     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2953 
2954     rc = encode_pass_component_table_req(
2955         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2956         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2957         compVerStrLen, &compVerStrInfo, nullptr,
2958         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2959     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2960 
2961     rc = encode_pass_component_table_req(
2962         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2963         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2964         compVerStrLen, &compVerStrInfo, requestMsg,
2965         sizeof(pldm_pass_component_table_req));
2966     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2967 
2968     rc = encode_pass_component_table_req(
2969         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2970         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0,
2971         &compVerStrInfo, requestMsg,
2972         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2973     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2974 
2975     rc = encode_pass_component_table_req(
2976         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2977         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2978         compVerStrLen - 1, &compVerStrInfo, requestMsg,
2979         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2980     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2981 
2982     rc = encode_pass_component_table_req(
2983         instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier,
2984         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2985         compVerStrLen, &compVerStrInfo, requestMsg,
2986         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2987     EXPECT_EQ(rc, PLDM_INVALID_TRANSFER_OPERATION_FLAG);
2988 
2989     rc = encode_pass_component_table_req(
2990         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2991         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN,
2992         compVerStrLen, &compVerStrInfo, requestMsg,
2993         sizeof(pldm_pass_component_table_req) + compVerStrLen);
2994     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2995 }
2996 
TEST(PassComponentTable,goodPathDecodeResponse)2997 TEST(PassComponentTable, goodPathDecodeResponse)
2998 {
2999     constexpr std::array<uint8_t,
3000                          hdrSize + sizeof(pldm_pass_component_table_resp)>
3001         passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
3002     auto responseMsg1 =
3003         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3004         reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3005 
3006     uint8_t completionCode = 0;
3007     uint8_t compResp = 0;
3008     uint8_t compRespCode = 0;
3009 
3010     auto rc = decode_pass_component_table_resp(
3011         responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode,
3012         &compResp, &compRespCode);
3013 
3014     EXPECT_EQ(rc, PLDM_SUCCESS);
3015     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3016     EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3017     EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL);
3018 
3019     constexpr std::array<uint8_t,
3020                          hdrSize + sizeof(pldm_pass_component_table_resp)>
3021         passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0};
3022     auto responseMsg2 =
3023         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3024         reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3025     rc = decode_pass_component_table_resp(
3026         responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3027         &compResp, &compRespCode);
3028 
3029     EXPECT_EQ(rc, PLDM_SUCCESS);
3030     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3031     EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3032     EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN);
3033 
3034     constexpr std::array<uint8_t,
3035                          hdrSize + sizeof(pldm_pass_component_table_resp)>
3036         passCompTableResponse3{0x00, 0x00, 0x00, 0x80};
3037     auto responseMsg3 =
3038         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3039         reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3040 
3041     rc = decode_pass_component_table_resp(
3042         responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3043         &compResp, &compRespCode);
3044 
3045     EXPECT_EQ(rc, PLDM_SUCCESS);
3046     EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3047 }
3048 
TEST(PassComponentTable,errorPathDecodeResponse)3049 TEST(PassComponentTable, errorPathDecodeResponse)
3050 {
3051     constexpr std::array<uint8_t,
3052                          hdrSize + sizeof(pldm_pass_component_table_resp) - 1>
3053         passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00};
3054     auto responseMsg1 =
3055         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3056         reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3057 
3058     uint8_t completionCode = 0;
3059     uint8_t compResp = 0;
3060     uint8_t compRespCode = 0;
3061 
3062     auto rc = decode_pass_component_table_resp(
3063         nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode,
3064         &compResp, &compRespCode);
3065     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3066 
3067     rc = decode_pass_component_table_resp(
3068         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr,
3069         &compResp, &compRespCode);
3070     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3071 
3072     rc = decode_pass_component_table_resp(
3073         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3074         &completionCode, nullptr, &compRespCode);
3075     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3076 
3077     rc = decode_pass_component_table_resp(
3078         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3079         &completionCode, &compResp, nullptr);
3080     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3081 
3082     rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode,
3083                                           &compResp, &compRespCode);
3084     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3085 
3086     rc = decode_pass_component_table_resp(
3087         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3088         &completionCode, &compResp, &compRespCode);
3089     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3090 
3091     constexpr std::array<uint8_t,
3092                          hdrSize + sizeof(pldm_pass_component_table_resp)>
3093         passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
3094     auto responseMsg2 =
3095         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3096         reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3097     rc = decode_pass_component_table_resp(
3098         responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3099         &compResp, &compRespCode);
3100     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3101 
3102     constexpr std::array<uint8_t,
3103                          hdrSize + sizeof(pldm_pass_component_table_resp)>
3104         passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};
3105     auto responseMsg3 =
3106         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3107         reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3108     rc = decode_pass_component_table_resp(
3109         responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3110         &compResp, &compRespCode);
3111     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3112 
3113     constexpr std::array<uint8_t,
3114                          hdrSize + sizeof(pldm_pass_component_table_resp)>
3115         passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
3116     auto responseMsg4 =
3117         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3118         reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data());
3119     rc = decode_pass_component_table_resp(
3120         responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode,
3121         &compResp, &compRespCode);
3122     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3123 }
3124 
TEST(UpdateComponent,goodPathEncodeRequest)3125 TEST(UpdateComponent, goodPathEncodeRequest)
3126 {
3127     constexpr uint8_t instanceId = 2;
3128     constexpr uint16_t compIdentifier = 500;
3129     constexpr uint8_t compClassificationIndex = 50;
3130     constexpr uint32_t compComparisonStamp = 0x89abcdef;
3131     constexpr uint32_t compImageSize = 4096;
3132     constexpr bitfield32_t updateOptionFlags{1};
3133     constexpr std::string_view compVerStr = "OpenBmcv2.2";
3134     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3135     variable_field compVerStrInfo{};
3136     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3137     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3138     compVerStrInfo.length = compVerStrLen;
3139 
3140     std::array<uint8_t,
3141                hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3142         request{};
3143     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3144     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3145 
3146     auto rc = encode_update_component_req(
3147         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3148         compComparisonStamp, compImageSize, updateOptionFlags,
3149         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3150         sizeof(pldm_update_component_req) + compVerStrLen);
3151     EXPECT_EQ(rc, PLDM_SUCCESS);
3152 
3153     std::array<uint8_t,
3154                hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3155         outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
3156                    0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
3157                    0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
3158                    0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
3159     EXPECT_EQ(request, outRequest);
3160 
3161 #ifdef LIBPLDM_API_TESTING
3162     /* Check the roundtrip */
3163     struct pldm_update_component_req_full req;
3164     PLDM_MSG_DEFINE_P(dec, outRequest.size());
3165     std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3166     rc = decode_update_component_req(dec, outRequest.size() - hdrSize, &req);
3167     ASSERT_EQ(rc, 0);
3168 
3169     EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3170     EXPECT_EQ(req.comp_identifier, compIdentifier);
3171     EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3172     EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3173     EXPECT_EQ(req.comp_image_size, compImageSize);
3174     EXPECT_EQ(req.update_option_flags.value, updateOptionFlags.value);
3175     EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3176     EXPECT_EQ(req.version.str_len, compVerStrLen);
3177     EXPECT_TRUE(std::equal(req.version.str_data,
3178                            req.version.str_data + req.version.str_len,
3179                            compVerStr.data()));
3180 #endif
3181 }
3182 
TEST(UpdateComponent,errorPathEncodeRequest)3183 TEST(UpdateComponent, errorPathEncodeRequest)
3184 {
3185     constexpr uint8_t instanceId = 2;
3186     constexpr uint16_t compIdentifier = 500;
3187     constexpr uint8_t compClassificationIndex = 50;
3188     constexpr uint32_t compComparisonStamp = 0x89abcdef;
3189     constexpr uint32_t compImageSize = 4096;
3190     constexpr bitfield32_t updateOptionFlags{1};
3191     constexpr std::string_view compVerStr = "OpenBmcv2.2";
3192     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3193     variable_field compVerStrInfo{};
3194     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3195     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3196     compVerStrInfo.length = compVerStrLen;
3197 
3198     std::array<uint8_t,
3199                hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3200         request{};
3201     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3202     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3203 
3204     auto rc = encode_update_component_req(
3205         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3206         compComparisonStamp, compImageSize, updateOptionFlags,
3207         PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
3208         sizeof(pldm_update_component_req) + compVerStrLen);
3209     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3210 
3211     compVerStrInfo.ptr = nullptr;
3212     rc = encode_update_component_req(
3213         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3214         compComparisonStamp, compImageSize, updateOptionFlags,
3215         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3216         sizeof(pldm_update_component_req) + compVerStrLen);
3217     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3218     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3219     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3220 
3221     rc = encode_update_component_req(
3222         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3223         compComparisonStamp, compImageSize, updateOptionFlags,
3224         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
3225         sizeof(pldm_update_component_req) + compVerStrLen);
3226     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3227 
3228     rc = encode_update_component_req(
3229         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3230         compComparisonStamp, compImageSize, updateOptionFlags,
3231         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3232         sizeof(pldm_update_component_req));
3233     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3234 
3235     rc = encode_update_component_req(
3236         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3237         compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
3238         compVerStrLen, &compVerStrInfo, requestMsg,
3239         sizeof(pldm_update_component_req) + compVerStrLen);
3240     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3241 
3242     rc = encode_update_component_req(
3243         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3244         compComparisonStamp, compImageSize, updateOptionFlags,
3245         PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg,
3246         sizeof(pldm_update_component_req) + compVerStrLen);
3247     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3248 
3249     rc = encode_update_component_req(
3250         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3251         compComparisonStamp, compImageSize, updateOptionFlags,
3252         PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg,
3253         sizeof(pldm_update_component_req) + compVerStrLen);
3254     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3255 
3256     rc = encode_update_component_req(
3257         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3258         compComparisonStamp, compImageSize, updateOptionFlags,
3259         PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
3260         sizeof(pldm_update_component_req) + compVerStrLen);
3261     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3262 }
3263 
TEST(UpdateComponent,goodPathDecodeResponse)3264 TEST(UpdateComponent, goodPathDecodeResponse)
3265 {
3266     constexpr std::bitset<32> forceUpdateComp{1};
3267     constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
3268     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3269         updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3270                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3271     auto responseMsg1 =
3272         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3273         reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3274 
3275     uint8_t completionCode = 0;
3276     uint8_t compCompatibilityResp = 0;
3277     uint8_t compCompatibilityRespCode = 0;
3278     bitfield32_t updateOptionFlagsEnabled{};
3279     uint16_t timeBeforeReqFWData = 0;
3280 
3281     auto rc = decode_update_component_resp(
3282         responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
3283         &compCompatibilityResp, &compCompatibilityRespCode,
3284         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3285 
3286     EXPECT_EQ(rc, PLDM_SUCCESS);
3287     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3288     EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
3289     EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
3290     EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
3291     EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
3292 
3293     constexpr std::bitset<32> noFlags{};
3294     constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
3295     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3296         updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3297                                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3298     auto responseMsg2 =
3299         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3300         reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3301     rc = decode_update_component_resp(
3302         responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3303         &compCompatibilityResp, &compCompatibilityRespCode,
3304         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3305 
3306     EXPECT_EQ(rc, PLDM_SUCCESS);
3307     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3308     EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
3309     EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
3310     EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
3311     EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
3312 
3313     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3314         updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
3315     auto responseMsg3 =
3316         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3317         reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3318 
3319     rc = decode_update_component_resp(
3320         responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3321         &compCompatibilityResp, &compCompatibilityRespCode,
3322         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3323 
3324     EXPECT_EQ(rc, PLDM_SUCCESS);
3325     EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3326 }
3327 
TEST(UpdateComponent,errorPathDecodeResponse)3328 TEST(UpdateComponent, errorPathDecodeResponse)
3329 {
3330     constexpr std::array<uint8_t,
3331                          hdrSize + sizeof(pldm_update_component_resp) - 1>
3332         updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3333                                  0x00, 0x00, 0x00, 0x00, 0x00};
3334     auto responseMsg1 =
3335         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3336         reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3337 
3338     uint8_t completionCode = 0;
3339     uint8_t compCompatibilityResp = 0;
3340     uint8_t compCompatibilityRespCode = 0;
3341     bitfield32_t updateOptionFlagsEnabled{};
3342     uint16_t timeBeforeReqFWData = 0;
3343 
3344     auto rc = decode_update_component_resp(
3345         nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
3346         &compCompatibilityResp, &compCompatibilityRespCode,
3347         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3348     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3349 
3350     rc = decode_update_component_resp(
3351         responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
3352         &compCompatibilityResp, &compCompatibilityRespCode,
3353         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3354     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3355 
3356     rc = decode_update_component_resp(
3357         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3358         nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3359         &timeBeforeReqFWData);
3360     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3361 
3362     rc = decode_update_component_resp(
3363         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3364         &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
3365         &timeBeforeReqFWData);
3366     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3367 
3368     rc = decode_update_component_resp(
3369         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3370         &compCompatibilityResp, &compCompatibilityRespCode, nullptr,
3371         &timeBeforeReqFWData);
3372     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3373 
3374     rc = decode_update_component_resp(
3375         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3376         &compCompatibilityResp, &compCompatibilityRespCode,
3377         &updateOptionFlagsEnabled, nullptr);
3378     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3379 
3380     rc = decode_update_component_resp(
3381         responseMsg1, 0, &completionCode, &compCompatibilityResp,
3382         &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3383         &timeBeforeReqFWData);
3384     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3385 
3386     rc = decode_update_component_resp(
3387         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3388         &compCompatibilityResp, &compCompatibilityRespCode,
3389         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3390     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3391 
3392     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3393         updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
3394                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3395     auto responseMsg2 =
3396         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3397         reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3398     rc = decode_update_component_resp(
3399         responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3400         &compCompatibilityResp, &compCompatibilityRespCode,
3401         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3402     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3403 
3404     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3405         updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
3406                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3407     auto responseMsg3 =
3408         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3409         reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3410     rc = decode_update_component_resp(
3411         responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3412         &compCompatibilityResp, &compCompatibilityRespCode,
3413         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3414     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3415 
3416     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3417         updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
3418                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3419     auto responseMsg4 =
3420         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3421         reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
3422     rc = decode_update_component_resp(
3423         responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
3424         &compCompatibilityResp, &compCompatibilityRespCode,
3425         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3426     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3427 }
3428 
TEST(RequestFirmwareData,goodPathDecodeRequest)3429 TEST(RequestFirmwareData, goodPathDecodeRequest)
3430 {
3431     constexpr uint32_t offset = 300;
3432     constexpr uint32_t length = 255;
3433     constexpr std::array<uint8_t,
3434                          hdrSize + sizeof(pldm_request_firmware_data_req)>
3435         reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3436                      0x00, 0xff, 0x00, 0x00, 0x00};
3437     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3438     auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3439 
3440     uint32_t outOffset = 0;
3441     uint32_t outLength = 0;
3442     auto rc = decode_request_firmware_data_req(
3443         requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3444         &outLength);
3445 
3446     EXPECT_EQ(rc, PLDM_SUCCESS);
3447     EXPECT_EQ(outOffset, offset);
3448     EXPECT_EQ(outLength, length);
3449 }
3450 
TEST(RequestFirmwareData,errorPathDecodeRequest)3451 TEST(RequestFirmwareData, errorPathDecodeRequest)
3452 {
3453     constexpr std::array<uint8_t,
3454                          hdrSize + sizeof(pldm_request_firmware_data_req)>
3455         reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3456                      0x00, 0x1f, 0x00, 0x00, 0x00};
3457     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3458     auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3459 
3460     uint32_t outOffset = 0;
3461     uint32_t outLength = 0;
3462     auto rc = decode_request_firmware_data_req(
3463         nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
3464         &outLength);
3465     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3466 
3467     rc = decode_request_firmware_data_req(
3468         requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
3469         &outLength);
3470     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3471 
3472     rc = decode_request_firmware_data_req(
3473         requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3474         nullptr);
3475     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3476 
3477     rc = decode_request_firmware_data_req(
3478         requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
3479         &outLength);
3480     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3481 
3482     rc = decode_request_firmware_data_req(
3483         requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3484         &outLength);
3485     EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
3486 }
3487 
TEST(RequestFirmwareData,goodPathEncodeResponse)3488 TEST(RequestFirmwareData, goodPathEncodeResponse)
3489 {
3490     constexpr uint8_t instanceId = 3;
3491     constexpr uint8_t completionCode = PLDM_SUCCESS;
3492     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
3493                                       PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3494         outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
3495                               0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3496                               0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3497                               0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3498                               0x1d, 0x1e, 0x1f, 0x20};
3499     std::array<uint8_t, hdrSize + sizeof(completionCode) +
3500                             PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3501         reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
3502                            0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3503                            0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3504                            0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3505                            0x1d, 0x1e, 0x1f, 0x20};
3506     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3507     auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
3508     auto rc = encode_request_firmware_data_resp(
3509         instanceId, completionCode, responseMsg1,
3510         sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
3511     EXPECT_EQ(rc, PLDM_SUCCESS);
3512     EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
3513 
3514     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3515         outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
3516     std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
3517         0x00, 0x00, 0x00, 0x00};
3518     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3519     auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
3520     rc = encode_request_firmware_data_resp(
3521         instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
3522         sizeof(completionCode));
3523     EXPECT_EQ(rc, PLDM_SUCCESS);
3524     EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
3525 }
3526 
TEST(RequestFirmwareData,errorPathEncodeResponse)3527 TEST(RequestFirmwareData, errorPathEncodeResponse)
3528 {
3529     std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
3530     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3531     auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
3532     auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
3533     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3534 
3535     rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
3536     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3537 }
3538 
TEST(TransferComplete,goodPathDecodeRequest)3539 TEST(TransferComplete, goodPathDecodeRequest)
3540 {
3541     constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
3542     constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3543         transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
3544     auto requestMsg1 =
3545         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3546         reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
3547     uint8_t outTransferResult = 0;
3548 
3549     auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
3550                                            &outTransferResult);
3551     EXPECT_EQ(rc, PLDM_SUCCESS);
3552     EXPECT_EQ(outTransferResult, transferResult);
3553 
3554     constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3555         transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
3556     auto requestMsg2 =
3557         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3558         reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
3559     rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
3560                                       &outTransferResult);
3561     EXPECT_EQ(rc, PLDM_SUCCESS);
3562     EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
3563 }
3564 
TEST(TransferComplete,errorPathDecodeRequest)3565 TEST(TransferComplete, errorPathDecodeRequest)
3566 {
3567     constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
3568                                                                0x00};
3569     auto requestMsg =
3570         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3571         reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
3572     uint8_t outTransferResult = 0;
3573 
3574     auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
3575     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3576 
3577     rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
3578     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3579 
3580     rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
3581     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3582 }
3583 
TEST(TransferComplete,goodPathEncodeResponse)3584 TEST(TransferComplete, goodPathEncodeResponse)
3585 {
3586     constexpr uint8_t instanceId = 4;
3587     constexpr uint8_t completionCode = PLDM_SUCCESS;
3588     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3589         outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
3590     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3591         transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3592     auto responseMsg1 =
3593         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3594         reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
3595     auto rc = encode_transfer_complete_resp(
3596         instanceId, completionCode, responseMsg1, sizeof(completionCode));
3597     EXPECT_EQ(rc, PLDM_SUCCESS);
3598     EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
3599 
3600     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3601         outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
3602     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3603         transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3604     auto responseMsg2 =
3605         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3606         reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
3607     rc = encode_transfer_complete_resp(instanceId,
3608                                        PLDM_FWUP_COMMAND_NOT_EXPECTED,
3609                                        responseMsg2, sizeof(completionCode));
3610     EXPECT_EQ(rc, PLDM_SUCCESS);
3611     EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
3612 }
3613 
TEST(TransferComplete,errorPathEncodeResponse)3614 TEST(TransferComplete, errorPathEncodeResponse)
3615 {
3616     std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
3617     auto responseMsg =
3618         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3619         reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
3620     auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3621     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3622 
3623     rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3624     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3625 }
3626 
TEST(VerifyComplete,goodPathDecodeRequest)3627 TEST(VerifyComplete, goodPathDecodeRequest)
3628 {
3629     constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
3630     constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3631         verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
3632     auto requestMsg1 =
3633         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3634         reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
3635     uint8_t outVerifyResult = 0;
3636 
3637     auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
3638                                          &outVerifyResult);
3639     EXPECT_EQ(rc, PLDM_SUCCESS);
3640     EXPECT_EQ(outVerifyResult, verifyResult);
3641 
3642     constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3643         verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
3644     auto requestMsg2 =
3645         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3646         reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
3647     rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
3648                                     &outVerifyResult);
3649     EXPECT_EQ(rc, PLDM_SUCCESS);
3650     EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
3651 }
3652 
TEST(VerifyComplete,errorPathDecodeRequest)3653 TEST(VerifyComplete, errorPathDecodeRequest)
3654 {
3655     constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
3656     auto requestMsg =
3657         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3658         reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
3659     uint8_t outVerifyResult = 0;
3660 
3661     auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
3662     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3663 
3664     rc = decode_verify_complete_req(requestMsg, 0, nullptr);
3665     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3666 
3667     rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);
3668     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3669 }
3670 
TEST(VerifyComplete,goodPathEncodeResponse)3671 TEST(VerifyComplete, goodPathEncodeResponse)
3672 {
3673     constexpr uint8_t instanceId = 5;
3674     constexpr uint8_t completionCode = PLDM_SUCCESS;
3675     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3676         outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};
3677     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3678         verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3679     auto responseMsg1 =
3680         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3681         reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());
3682     auto rc = encode_verify_complete_resp(instanceId, completionCode,
3683                                           responseMsg1, sizeof(completionCode));
3684     EXPECT_EQ(rc, PLDM_SUCCESS);
3685     EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);
3686 
3687     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3688         outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88};
3689     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3690         verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3691     auto responseMsg2 =
3692         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3693         reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());
3694     rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3695                                      responseMsg2, sizeof(completionCode));
3696     EXPECT_EQ(rc, PLDM_SUCCESS);
3697     EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);
3698 }
3699 
TEST(VerifyComplete,errorPathEncodeResponse)3700 TEST(VerifyComplete, errorPathEncodeResponse)
3701 {
3702     std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00};
3703     auto responseMsg =
3704         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3705         reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());
3706     auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3707     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3708 
3709     rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3710     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3711 }
3712 
TEST(ApplyComplete,goodPathDecodeRequest)3713 TEST(ApplyComplete, goodPathDecodeRequest)
3714 {
3715     constexpr uint8_t applyResult1 =
3716         PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
3717     // DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
3718     constexpr std::bitset<16> compActivationModification1{0x30};
3719     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3720         applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
3721     auto requestMsg1 =
3722         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3723         reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3724     uint8_t outApplyResult = 0;
3725     bitfield16_t outCompActivationModification{};
3726     auto rc = decode_apply_complete_req(
3727         requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
3728         &outCompActivationModification);
3729     EXPECT_EQ(rc, PLDM_SUCCESS);
3730     EXPECT_EQ(outApplyResult, applyResult1);
3731     EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
3732 
3733     constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
3734     constexpr std::bitset<16> compActivationModification2{};
3735     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3736         applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3737     auto requestMsg2 =
3738         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3739         reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3740     rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3741                                    &outApplyResult,
3742                                    &outCompActivationModification);
3743     EXPECT_EQ(rc, PLDM_SUCCESS);
3744     EXPECT_EQ(outApplyResult, applyResult2);
3745     EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
3746 }
3747 
TEST(ApplyComplete,errorPathDecodeRequest)3748 TEST(ApplyComplete, errorPathDecodeRequest)
3749 {
3750     constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
3751     auto requestMsg1 =
3752         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3753         reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3754     uint8_t outApplyResult = 0;
3755     bitfield16_t outCompActivationModification{};
3756 
3757     auto rc = decode_apply_complete_req(
3758         nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
3759         &outCompActivationModification);
3760     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3761 
3762     rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3763                                    nullptr, &outCompActivationModification);
3764     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3765 
3766     rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3767                                    &outApplyResult, nullptr);
3768     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3769 
3770     rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
3771                                    &outCompActivationModification);
3772     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3773 
3774     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3775         applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
3776     auto requestMsg2 =
3777         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3778         reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3779     rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3780                                    &outApplyResult,
3781                                    &outCompActivationModification);
3782     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3783 }
3784 
TEST(ApplyComplete,goodPathEncodeResponse)3785 TEST(ApplyComplete, goodPathEncodeResponse)
3786 {
3787     constexpr uint8_t instanceId = 6;
3788     constexpr uint8_t completionCode = PLDM_SUCCESS;
3789     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3790         outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
3791     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3792         applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3793     auto responseMsg1 =
3794         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3795         reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
3796     auto rc = encode_apply_complete_resp(instanceId, completionCode,
3797                                          responseMsg1, sizeof(completionCode));
3798     EXPECT_EQ(rc, PLDM_SUCCESS);
3799     EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
3800 
3801     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3802         outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
3803     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3804         applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3805     auto responseMsg2 =
3806         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3807         reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
3808     rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3809                                     responseMsg2, sizeof(completionCode));
3810     EXPECT_EQ(rc, PLDM_SUCCESS);
3811     EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
3812 }
3813 
TEST(ApplyComplete,errorPathEncodeResponse)3814 TEST(ApplyComplete, errorPathEncodeResponse)
3815 {
3816     std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
3817     auto responseMsg =
3818         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3819         reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
3820     auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3821     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3822 
3823     rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3824     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3825 }
3826 
TEST(ActivateFirmware,goodPathEncodeRequest)3827 TEST(ActivateFirmware, goodPathEncodeRequest)
3828 {
3829     constexpr uint8_t instanceId = 7;
3830 
3831     std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
3832     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3833     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3834 
3835     auto rc = encode_activate_firmware_req(
3836         instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
3837         sizeof(pldm_activate_firmware_req));
3838     EXPECT_EQ(rc, PLDM_SUCCESS);
3839 
3840     std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
3841         outRequest{0x87, 0x05, 0x1a, 0x01};
3842     EXPECT_EQ(request, outRequest);
3843 }
3844 
TEST(ActivateFirmware,errorPathEncodeRequest)3845 TEST(ActivateFirmware, errorPathEncodeRequest)
3846 {
3847     std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
3848     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3849     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3850 
3851     auto rc = encode_activate_firmware_req(
3852         0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
3853         sizeof(pldm_activate_firmware_req));
3854     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3855 
3856     rc = encode_activate_firmware_req(
3857         0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
3858     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3859 
3860     rc = encode_activate_firmware_req(0, 2, requestMsg,
3861                                       sizeof(pldm_activate_firmware_req));
3862     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3863 }
3864 
TEST(ActivateFirmware,goodPathDecodeResponse)3865 TEST(ActivateFirmware, goodPathDecodeResponse)
3866 {
3867     constexpr uint16_t estimatedTimeForActivation100s = 100;
3868     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3869         activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
3870     auto responseMsg1 =
3871         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3872         reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
3873 
3874     uint8_t completionCode = 0;
3875     uint16_t estimatedTimeForActivation = 0;
3876 
3877     auto rc = decode_activate_firmware_resp(
3878         responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
3879         &estimatedTimeForActivation);
3880 
3881     EXPECT_EQ(rc, PLDM_SUCCESS);
3882     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3883     EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
3884 
3885     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3886         activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
3887     auto responseMsg2 =
3888         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3889         reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data());
3890 
3891     rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
3892                                        &completionCode,
3893                                        &estimatedTimeForActivation);
3894 
3895     EXPECT_EQ(rc, PLDM_SUCCESS);
3896     EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
3897 }
3898 
TEST(ActivateFirmware,errorPathDecodeResponse)3899 TEST(ActivateFirmware, errorPathDecodeResponse)
3900 {
3901     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3902         activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3903     auto responseMsg =
3904         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3905         reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
3906 
3907     uint8_t completionCode = 0;
3908     uint16_t estimatedTimeForActivation = 0;
3909 
3910     auto rc = decode_activate_firmware_resp(
3911         nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
3912         &estimatedTimeForActivation);
3913     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3914 
3915     rc = decode_activate_firmware_resp(responseMsg,
3916                                        sizeof(pldm_activate_firmware_resp),
3917                                        nullptr, &estimatedTimeForActivation);
3918     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3919 
3920     rc = decode_activate_firmware_resp(responseMsg,
3921                                        sizeof(pldm_activate_firmware_resp),
3922                                        &completionCode, nullptr);
3923     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3924 
3925     rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
3926                                        &estimatedTimeForActivation);
3927     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3928 
3929     rc = decode_activate_firmware_resp(
3930         responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
3931         &estimatedTimeForActivation);
3932     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3933 }
3934 
TEST(GetStatus,goodPathEncodeRequest)3935 TEST(GetStatus, goodPathEncodeRequest)
3936 {
3937     constexpr uint8_t instanceId = 8;
3938     std::array<uint8_t, hdrSize> request{};
3939     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3940     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3941 
3942     auto rc = encode_get_status_req(instanceId, requestMsg,
3943                                     PLDM_GET_STATUS_REQ_BYTES);
3944     EXPECT_EQ(rc, PLDM_SUCCESS);
3945 
3946     constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
3947     EXPECT_EQ(request, outRequest);
3948 }
3949 
TEST(GetStatus,errorPathEncodeRequest)3950 TEST(GetStatus, errorPathEncodeRequest)
3951 {
3952     std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
3953     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3954     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3955 
3956     auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
3957     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3958 
3959     rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);
3960     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3961 }
3962 
TEST(GetStatus,goodPathDecodeResponse)3963 TEST(GetStatus, goodPathDecodeResponse)
3964 {
3965     constexpr std::bitset<32> updateOptionFlagsEnabled1{0};
3966     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3967         getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
3968                            0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};
3969     auto responseMsg1 =
3970         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3971         reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
3972 
3973     uint8_t completionCode = 0;
3974     uint8_t currentState = 0;
3975     uint8_t previousState = 0;
3976     uint8_t auxState = 0;
3977     uint8_t auxStateStatus = 0;
3978     uint8_t progressPercent = 0;
3979     uint8_t reasonCode = 0;
3980     bitfield32_t updateOptionFlagsEnabled{0};
3981 
3982     auto rc = decode_get_status_resp(
3983         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3984         &currentState, &previousState, &auxState, &auxStateStatus,
3985         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3986 
3987     EXPECT_EQ(rc, PLDM_SUCCESS);
3988     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3989     EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);
3990     EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
3991     EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);
3992     EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);
3993     EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);
3994     EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
3995     EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);
3996 
3997     // Bit position 0 - Force update of component – FD will perform a force
3998     // update of the component.
3999     constexpr std::bitset<32> updateOptionFlagsEnabled2{1};
4000     constexpr uint8_t progressPercent2 = 50;
4001     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4002         getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,
4003                            0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};
4004     auto responseMsg2 =
4005         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4006         reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4007 
4008     rc = decode_get_status_resp(
4009         responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4010         &currentState, &previousState, &auxState, &auxStateStatus,
4011         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4012 
4013     EXPECT_EQ(rc, PLDM_SUCCESS);
4014     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4015     EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);
4016     EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4017     EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);
4018     EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);
4019     EXPECT_EQ(progressPercent, progressPercent2);
4020     EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4021     EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);
4022 
4023 #ifdef LIBPLDM_API_TESTING
4024     /* Check the roundtrip */
4025     PLDM_MSG_DEFINE_P(enc, 1000);
4026     size_t enc_payload_len = 1000;
4027     const struct pldm_get_status_resp status_enc = {
4028         .completion_code = PLDM_SUCCESS,
4029         .current_state = currentState,
4030         .previous_state = previousState,
4031         .aux_state = auxState,
4032         .aux_state_status = auxStateStatus,
4033         .progress_percent = progressPercent,
4034         .reason_code = reasonCode,
4035         .update_option_flags_enabled = updateOptionFlagsEnabled,
4036     };
4037     rc = encode_get_status_resp(FIXED_INSTANCE_ID, &status_enc, enc,
4038                                 &enc_payload_len);
4039     EXPECT_EQ(rc, PLDM_SUCCESS);
4040     EXPECT_EQ(enc_payload_len + hdrSize, getStatusResponse2.size());
4041     EXPECT_TRUE(std::equal(getStatusResponse2.begin() + hdrSize,
4042                            getStatusResponse2.end(), enc_buf + hdrSize));
4043     check_response(enc, PLDM_GET_STATUS);
4044 #endif
4045 
4046     /* Check a not-ready completion code */
4047     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4048         getStatusResponse3{0x00, 0x00, 0x00, 0x04};
4049     auto responseMsg3 =
4050         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4051         reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4052     rc = decode_get_status_resp(
4053         responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4054         &currentState, &previousState, &auxState, &auxStateStatus,
4055         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4056     EXPECT_EQ(rc, PLDM_SUCCESS);
4057     EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);
4058 }
4059 
TEST(GetStatus,errorPathDecodeResponse)4060 TEST(GetStatus, errorPathDecodeResponse)
4061 {
4062     uint8_t completionCode = 0;
4063     uint8_t currentState = 0;
4064     uint8_t previousState = 0;
4065     uint8_t auxState = 0;
4066     uint8_t auxStateStatus = 0;
4067     uint8_t progressPercent = 0;
4068     uint8_t reasonCode = 0;
4069     bitfield32_t updateOptionFlagsEnabled{0};
4070 
4071     constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};
4072     auto responseMsg1 =
4073         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4074         reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4075 
4076     auto rc = decode_get_status_resp(
4077         nullptr, getStatusResponse1.size() - hdrSize, &completionCode,
4078         &currentState, &previousState, &auxState, &auxStateStatus,
4079         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4080     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4081 
4082     rc = decode_get_status_resp(
4083         responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,
4084         &currentState, &previousState, &auxState, &auxStateStatus,
4085         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4086     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4087 
4088     rc = decode_get_status_resp(
4089         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4090         nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,
4091         &reasonCode, &updateOptionFlagsEnabled);
4092     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4093 
4094     rc = decode_get_status_resp(
4095         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4096         &currentState, nullptr, &auxState, &auxStateStatus, &progressPercent,
4097         &reasonCode, &updateOptionFlagsEnabled);
4098     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4099 
4100     rc = decode_get_status_resp(
4101         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4102         &currentState, &previousState, nullptr, &auxStateStatus,
4103         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4104     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4105 
4106     rc = decode_get_status_resp(
4107         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4108         &currentState, &previousState, &auxState, nullptr, &progressPercent,
4109         &reasonCode, &updateOptionFlagsEnabled);
4110     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4111 
4112     rc = decode_get_status_resp(
4113         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4114         &currentState, &previousState, &auxState, &auxStateStatus, nullptr,
4115         &reasonCode, &updateOptionFlagsEnabled);
4116     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4117 
4118     rc = decode_get_status_resp(
4119         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4120         &currentState, &previousState, &auxState, &auxStateStatus,
4121         &progressPercent, nullptr, &updateOptionFlagsEnabled);
4122     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4123 
4124     rc = decode_get_status_resp(
4125         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4126         &currentState, &previousState, &auxState, &auxStateStatus,
4127         &progressPercent, &reasonCode, nullptr);
4128     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4129 
4130     rc = decode_get_status_resp(
4131         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4132         &currentState, &previousState, &auxState, &auxStateStatus,
4133         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4134     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4135 
4136     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>
4137         getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4138                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4139     auto responseMsg2 =
4140         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4141         reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4142     rc = decode_get_status_resp(
4143         responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4144         &currentState, &previousState, &auxState, &auxStateStatus,
4145         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4146     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4147 
4148     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4149         getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
4150                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4151     auto responseMsg3 =
4152         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4153         reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4154     rc = decode_get_status_resp(
4155         responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4156         &currentState, &previousState, &auxState, &auxStateStatus,
4157         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4158     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4159 
4160     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4161         getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
4162                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4163     auto responseMsg4 =
4164         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4165         reinterpret_cast<const pldm_msg*>(getStatusResponse4.data());
4166     rc = decode_get_status_resp(
4167         responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,
4168         &currentState, &previousState, &auxState, &auxStateStatus,
4169         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4170     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4171 
4172     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4173         getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
4174                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4175     auto responseMsg5 =
4176         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4177         reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());
4178     rc = decode_get_status_resp(
4179         responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,
4180         &currentState, &previousState, &auxState, &auxStateStatus,
4181         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4182     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4183 
4184     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4185         getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4186                            0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4187     auto responseMsg6 =
4188         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4189         reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());
4190     rc = decode_get_status_resp(
4191         responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,
4192         &currentState, &previousState, &auxState, &auxStateStatus,
4193         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4194     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4195 
4196     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4197         getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4198                            0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
4199     auto responseMsg7 =
4200         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4201         reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());
4202     rc = decode_get_status_resp(
4203         responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,
4204         &currentState, &previousState, &auxState, &auxStateStatus,
4205         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4206     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4207 
4208     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4209         getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4210                            0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00};
4211     auto responseMsg8 =
4212         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4213         reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());
4214     rc = decode_get_status_resp(
4215         responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,
4216         &currentState, &previousState, &auxState, &auxStateStatus,
4217         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4218     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4219 
4220     // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is
4221     // IDLE
4222     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4223         getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
4224                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4225     auto responseMsg9 =
4226         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4227         reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());
4228     rc = decode_get_status_resp(
4229         responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,
4230         &currentState, &previousState, &auxState, &auxStateStatus,
4231         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4232     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4233 }
4234 
TEST(CancelUpdateComponent,goodPathEncodeRequest)4235 TEST(CancelUpdateComponent, goodPathEncodeRequest)
4236 {
4237     constexpr uint8_t instanceId = 9;
4238     std::array<uint8_t, hdrSize> request{};
4239     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4240     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4241 
4242     auto rc = encode_cancel_update_component_req(
4243         instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4244     EXPECT_EQ(rc, PLDM_SUCCESS);
4245 
4246     constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
4247     EXPECT_EQ(request, outRequest);
4248 }
4249 
TEST(CancelUpdateComponent,errorPathEncodeRequest)4250 TEST(CancelUpdateComponent, errorPathEncodeRequest)
4251 {
4252     std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
4253     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4254     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4255 
4256     auto rc = encode_cancel_update_component_req(
4257         0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4258     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4259 
4260     rc = encode_cancel_update_component_req(
4261         0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);
4262     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4263 }
4264 
TEST(CancelUpdateComponent,testGoodDecodeResponse)4265 TEST(CancelUpdateComponent, testGoodDecodeResponse)
4266 {
4267     uint8_t completionCode = 0;
4268     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4269         cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};
4270     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4271     auto responseMsg1 = reinterpret_cast<const pldm_msg*>(
4272         cancelUpdateComponentResponse1.data());
4273     auto rc = decode_cancel_update_component_resp(
4274         responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,
4275         &completionCode);
4276     EXPECT_EQ(rc, PLDM_SUCCESS);
4277     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4278 
4279     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4280         cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};
4281     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4282     auto responseMsg2 = reinterpret_cast<const pldm_msg*>(
4283         cancelUpdateComponentResponse2.data());
4284     rc = decode_cancel_update_component_resp(
4285         responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,
4286         &completionCode);
4287     EXPECT_EQ(rc, PLDM_SUCCESS);
4288     EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4289 }
4290 
TEST(CancelUpdateComponent,testBadDecodeResponse)4291 TEST(CancelUpdateComponent, testBadDecodeResponse)
4292 {
4293     uint8_t completionCode = 0;
4294     constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{
4295         0x00, 0x00, 0x00};
4296     auto responseMsg =
4297         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4298         reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data());
4299 
4300     auto rc = decode_cancel_update_component_resp(
4301         nullptr, cancelUpdateComponentResponse.size() - hdrSize,
4302         &completionCode);
4303     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4304 
4305     rc = decode_cancel_update_component_resp(
4306         responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);
4307     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4308 
4309     rc = decode_cancel_update_component_resp(
4310         responseMsg, cancelUpdateComponentResponse.size() - hdrSize,
4311         &completionCode);
4312     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4313 }
4314 
TEST(CancelUpdate,goodPathEncodeRequest)4315 TEST(CancelUpdate, goodPathEncodeRequest)
4316 {
4317     constexpr uint8_t instanceId = 10;
4318     std::array<uint8_t, hdrSize> request{};
4319     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4320     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4321 
4322     auto rc = encode_cancel_update_req(instanceId, requestMsg,
4323                                        PLDM_CANCEL_UPDATE_REQ_BYTES);
4324     EXPECT_EQ(rc, PLDM_SUCCESS);
4325 
4326     constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
4327     EXPECT_EQ(request, outRequest);
4328 }
4329 
TEST(CancelUpdate,errorPathEncodeRequest)4330 TEST(CancelUpdate, errorPathEncodeRequest)
4331 {
4332     std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
4333     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4334     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4335 
4336     auto rc =
4337         encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
4338     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4339 
4340     rc = encode_cancel_update_req(0, requestMsg,
4341                                   PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
4342     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4343 }
4344 
TEST(CancelUpdate,goodPathDecodeResponse)4345 TEST(CancelUpdate, goodPathDecodeResponse)
4346 {
4347     constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
4348     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4349         cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4350                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4351     auto responseMsg1 =
4352         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4353         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4354     uint8_t completionCode = 0;
4355     bool8_t nonFunctioningComponentIndication = 0;
4356     bitfield64_t nonFunctioningComponentBitmap{0};
4357     auto rc = decode_cancel_update_resp(
4358         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4359         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4360     EXPECT_EQ(rc, PLDM_SUCCESS);
4361     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4362     EXPECT_EQ(nonFunctioningComponentIndication,
4363               PLDM_FWUP_COMPONENTS_FUNCTIONING);
4364     EXPECT_EQ(nonFunctioningComponentBitmap.value,
4365               nonFunctioningComponentBitmap1);
4366 
4367     constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
4368     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4369         cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
4370                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4371     auto responseMsg2 =
4372         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4373         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4374     rc = decode_cancel_update_resp(
4375         responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4376         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4377     EXPECT_EQ(rc, PLDM_SUCCESS);
4378     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4379     EXPECT_EQ(nonFunctioningComponentIndication,
4380               PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING);
4381     EXPECT_EQ(nonFunctioningComponentBitmap.value,
4382               nonFunctioningComponentBitmap2);
4383 
4384     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4385         cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
4386     auto responseMsg3 =
4387         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4388         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4389     rc = decode_cancel_update_resp(
4390         responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4391         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4392     EXPECT_EQ(rc, PLDM_SUCCESS);
4393     EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4394 }
4395 
TEST(CancelUpdate,errorPathDecodeResponse)4396 TEST(CancelUpdate, errorPathDecodeResponse)
4397 {
4398     constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
4399                                                                  0x00};
4400     auto responseMsg1 =
4401         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4402         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4403     uint8_t completionCode = 0;
4404     bool8_t nonFunctioningComponentIndication = 0;
4405     bitfield64_t nonFunctioningComponentBitmap{0};
4406 
4407     auto rc = decode_cancel_update_resp(
4408         nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4409         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4410     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4411 
4412     rc = decode_cancel_update_resp(
4413         responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
4414         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4415     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4416 
4417     rc = decode_cancel_update_resp(
4418         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4419         nullptr, &nonFunctioningComponentBitmap);
4420     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4421 
4422     rc = decode_cancel_update_resp(
4423         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4424         &nonFunctioningComponentIndication, nullptr);
4425     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4426 
4427     rc = decode_cancel_update_resp(
4428         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4429         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4430     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4431 
4432     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4433         cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
4434     auto responseMsg2 =
4435         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4436         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4437     rc = decode_cancel_update_resp(
4438         responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4439         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4440     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4441 
4442     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4443         cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
4444                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4445     auto responseMsg3 =
4446         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4447         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4448     rc = decode_cancel_update_resp(
4449         responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4450         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4451     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4452 }
4453