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