xref: /openbmc/libpldm/tests/dsp/firmware_update.cpp (revision 0178274543250f489db18420782379ff4e62c6a5)
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 
45 static constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH>
46     PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0{0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d,
47                                              0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
48                                              0x05, 0x9a, 0xca, 0x02};
49 
50 static constexpr uint8_t PLDM_FWUP_PACKAGE_HEADER_FORMAT_REVISION_V1_0 = 0x01;
51 
52 static constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH>
53     PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_1{
54         0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
55         0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5a,
56     };
57 
58 static constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH>
59     PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_2{0x31, 0x19, 0xce, 0x2f, 0xe8, 0x0a,
60                                              0x4a, 0x99, 0xaf, 0x6d, 0x46, 0xf8,
61                                              0xb1, 0x21, 0xf6, 0xbf};
62 
63 static constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH>
64     PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_3{0x7b, 0x29, 0x1c, 0x99, 0x6d, 0xb6,
65                                              0x42, 0x08, 0x80, 0x1B, 0x02, 0x02,
66                                              0x6E, 0x46, 0x3C, 0x78};
67 
68 static constexpr size_t PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 = 43;
69 
70 static constexpr std::array<uint8_t, PLDM_TIMESTAMP104_SIZE>
71     testPackageReleaseDateTime{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72                                0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00};
73 
TEST(DecodePackageHeaderInfo,goodPath)74 TEST(DecodePackageHeaderInfo, goodPath)
75 {
76     constexpr uint16_t componentBitmapBitLength = 8;
77     constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
78     constexpr size_t packageHeaderSize =
79         PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
80 
81     constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
82         0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
83         0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
84         0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
85         0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
86         0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x61, 0xe3, 0x64, 0x6e};
87     pldm_package_header_information pkgHeader{};
88     variable_field packageVersion{};
89 
90     auto rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
91                                               packagerHeaderInfo.size(),
92                                               &pkgHeader, &packageVersion);
93 
94     ASSERT_EQ(rc, PLDM_SUCCESS);
95     EXPECT_EQ(true,
96               std::equal(pkgHeader.uuid, pkgHeader.uuid + PLDM_FWUP_UUID_LENGTH,
97                          PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.begin(),
98                          PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.end()));
99     EXPECT_EQ(pkgHeader.package_header_format_version,
100               PLDM_FWUP_PACKAGE_HEADER_FORMAT_REVISION_V1_0);
101     EXPECT_EQ(pkgHeader.package_header_size, packageHeaderSize);
102     EXPECT_EQ(true, std::equal(pkgHeader.package_release_date_time,
103                                pkgHeader.package_release_date_time +
104                                    PLDM_TIMESTAMP104_SIZE,
105                                testPackageReleaseDateTime.begin(),
106                                testPackageReleaseDateTime.end()));
107     EXPECT_EQ(pkgHeader.component_bitmap_bit_length, componentBitmapBitLength);
108     EXPECT_EQ(pkgHeader.package_version_string_type, PLDM_STR_TYPE_ASCII);
109     EXPECT_EQ(pkgHeader.package_version_string_length,
110               packageVersionStr.size());
111     std::string packageVersionString(
112         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
113         reinterpret_cast<const char*>(packageVersion.ptr),
114         packageVersion.length);
115     EXPECT_EQ(packageVersionString, packageVersionStr);
116 }
117 
TEST(DecodePackageHeaderInfo,invalidArguments)118 TEST(DecodePackageHeaderInfo, invalidArguments)
119 {
120     constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
121     constexpr size_t packageHeaderSize =
122         PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
123 
124     constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
125         0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
126         0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
127         0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
128         0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
129         0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
130 
131     pldm_package_header_information packageHeader{};
132     variable_field packageVersion{};
133     int rc = 0;
134 
135     rc = decode_pldm_package_header_info(nullptr, packagerHeaderInfo.size(),
136                                          &packageHeader, &packageVersion);
137     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
138 
139     rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
140                                          packagerHeaderInfo.size(), nullptr,
141                                          &packageVersion);
142     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
143 
144     rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
145                                          packagerHeaderInfo.size(),
146                                          &packageHeader, nullptr);
147     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
148 }
149 
TEST(DecodePackageHeaderInfo,invalidPackageLengths)150 TEST(DecodePackageHeaderInfo, invalidPackageLengths)
151 {
152     constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
153     constexpr size_t packageHeaderSize =
154         PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
155 
156     constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
157         0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
158         0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
159         0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
160         0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
161         0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
162 
163     pldm_package_header_information packageHeader{};
164     variable_field packageVersion{};
165     int rc = 0;
166 
167     rc = decode_pldm_package_header_info(packagerHeaderInfo.data(), 0,
168                                          &packageHeader, &packageVersion);
169     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
170 
171     rc = decode_pldm_package_header_info(packagerHeaderInfo.data(), 35,
172                                          &packageHeader, &packageVersion);
173     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
174 
175     rc = decode_pldm_package_header_info(packagerHeaderInfo.data(), 36,
176                                          &packageHeader, &packageVersion);
177     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
178 
179     rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
180                                          packagerHeaderInfo.size() - 1,
181                                          &packageHeader, &packageVersion);
182     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
183 }
184 
TEST(DecodePackageHeaderInfo,unspecifiedPackageHeaderIdentifier)185 TEST(DecodePackageHeaderInfo, unspecifiedPackageHeaderIdentifier)
186 {
187     constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
188     constexpr size_t packageHeaderSize =
189         PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
190 
191     constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
192         0xff, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
193         0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
194         0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
195         0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
196         0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
197 
198     pldm_package_header_information packageHeader{};
199     variable_field packageVersion{};
200     int rc = 0;
201 
202     rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
203                                          packagerHeaderInfo.size(),
204                                          &packageHeader, &packageVersion);
205     EXPECT_EQ(rc, PLDM_ERROR);
206 }
207 
TEST(DecodePackageHeaderInfo,incongruentPackageHeaderFormatRevision)208 TEST(DecodePackageHeaderInfo, incongruentPackageHeaderFormatRevision)
209 {
210     constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
211     constexpr size_t packageHeaderSize =
212         PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + 1 + packageVersionStr.size();
213 
214     constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
215         0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
216         0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x37, 0x00, 0x00, 0x00, 0x00,
217         0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
218         0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
219         0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
220 
221     pldm_package_header_information packageHeader{};
222     variable_field packageVersion{};
223     int rc = 0;
224 
225     rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
226                                          packagerHeaderInfo.size(),
227                                          &packageHeader, &packageVersion);
228     EXPECT_EQ(rc, PLDM_ERROR);
229 }
230 
TEST(DecodePackageHeaderInfo,invalidPackageVersionStringType)231 TEST(DecodePackageHeaderInfo, invalidPackageVersionStringType)
232 {
233     constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
234     constexpr size_t packageHeaderSize =
235         PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
236 
237     constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
238         0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
239         0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
240         0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
241         0x00, 0x06, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
242         0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
243 
244     pldm_package_header_information packageHeader{};
245     variable_field packageVersion{};
246     int rc = 0;
247 
248     rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
249                                          invalidPackagerHeaderInfo.size(),
250                                          &packageHeader, &packageVersion);
251     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
252 }
253 
TEST(DecodePackageHeaderInfo,invalidPackageVersionStringLength)254 TEST(DecodePackageHeaderInfo, invalidPackageVersionStringLength)
255 {
256     constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
257     constexpr size_t packageHeaderSize =
258         PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
259 
260     constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
261         0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
262         0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
263         0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
264         0x00, 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
265         0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
266 
267     pldm_package_header_information packageHeader{};
268     variable_field packageVersion{};
269     int rc = 0;
270 
271     rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
272                                          invalidPackagerHeaderInfo.size(),
273                                          &packageHeader, &packageVersion);
274     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
275 }
276 
TEST(DecodePackageHeaderInfo,corruptPackageVersionStringLength)277 TEST(DecodePackageHeaderInfo, corruptPackageVersionStringLength)
278 {
279     constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
280     constexpr size_t packageHeaderSize =
281         PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
282 
283     constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
284         0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
285         0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
286         0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
287         0x00, 0x01, 0x10, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
288         0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
289 
290     pldm_package_header_information packageHeader{};
291     variable_field packageVersion{};
292     int rc = 0;
293 
294     rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
295                                          invalidPackagerHeaderInfo.size(),
296                                          &packageHeader, &packageVersion);
297     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
298 }
299 
TEST(DecodePackageHeaderInfo,invalidComponentBitmapBitLength)300 TEST(DecodePackageHeaderInfo, invalidComponentBitmapBitLength)
301 {
302     constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
303     constexpr size_t packageHeaderSize =
304         PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
305 
306     constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
307         0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
308         0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
309         0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x07,
310         0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
311         0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
312 
313     pldm_package_header_information packageHeader{};
314     variable_field packageVersion{};
315     int rc = 0;
316 
317     rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
318                                          invalidPackagerHeaderInfo.size(),
319                                          &packageHeader, &packageVersion);
320     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
321 }
322 
TEST(DecodePackageHeaderInfo,badChecksum)323 TEST(DecodePackageHeaderInfo, badChecksum)
324 {
325     constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
326     constexpr size_t packageHeaderSize =
327         PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
328 
329     constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
330         0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
331         0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
332         0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x10,
333         0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
334         0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
335 
336     pldm_package_header_information packageHeader{};
337     variable_field packageVersion{};
338     int rc = 0;
339 
340     rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
341                                          invalidPackagerHeaderInfo.size(),
342                                          &packageHeader, &packageVersion);
343     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
344 }
345 
TEST(DecodeFirmwareDeviceIdRecord,goodPath)346 TEST(DecodeFirmwareDeviceIdRecord, goodPath)
347 {
348     constexpr uint8_t descriptorCount = 1;
349     // Continue component updates after failure
350     constexpr std::bitset<32> deviceUpdateFlag{1};
351     constexpr uint16_t componentBitmapBitLength = 16;
352     // Applicable Components - 1,2,5,8,9
353     std::vector<std::bitset<8>> applicableComponentsBitfield{0x93, 0x01};
354     // ComponentImageSetVersionString
355     constexpr std::string_view imageSetVersionStr{"VersionString1"};
356     // Initial descriptor - UUID
357     constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
358         0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
359         0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
360     constexpr uint16_t fwDevicePkgDataLen = 2;
361     // FirmwareDevicePackageData
362     constexpr std::array<uint8_t, fwDevicePkgDataLen> fwDevicePkgData{0xab,
363                                                                       0xcd};
364     // Size of the firmware device ID record
365     constexpr uint16_t recordLen =
366         sizeof(pldm_firmware_device_id_record) +
367         (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
368         imageSetVersionStr.size() + sizeof(pldm_descriptor_tlv) - 1 +
369         uuid.size() + fwDevicePkgData.size();
370     // Firmware device ID record
371     constexpr std::array<uint8_t, recordLen> record{
372         0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02,
373         0x00, 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
374         0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10,
375         0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0,
376         0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xab, 0xcd};
377 
378     pldm_firmware_device_id_record deviceIdRecHeader{};
379     variable_field applicableComponents{};
380     variable_field outCompImageSetVersionStr{};
381     variable_field recordDescriptors{};
382     variable_field outFwDevicePkgData{};
383 
384     auto rc = decode_firmware_device_id_record(
385         record.data(), record.size(), componentBitmapBitLength,
386         &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
387         &recordDescriptors, &outFwDevicePkgData);
388 
389     ASSERT_EQ(rc, PLDM_SUCCESS);
390     EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
391     EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
392     EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
393               deviceUpdateFlag);
394     EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
395               PLDM_STR_TYPE_ASCII);
396     EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
397               imageSetVersionStr.size());
398     EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, fwDevicePkgDataLen);
399 
400     EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
401     EXPECT_EQ(true,
402               std::equal(applicableComponents.ptr,
403                          applicableComponents.ptr + applicableComponents.length,
404                          applicableComponentsBitfield.begin(),
405                          applicableComponentsBitfield.end()));
406 
407     EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
408     std::string compImageSetVersionStr(
409         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
410         reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
411         outCompImageSetVersionStr.length);
412     EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
413 
414     uint16_t descriptorType = 0;
415     uint16_t descriptorLen = 0;
416     variable_field descriptorData{};
417     // DescriptorCount is 1, so decode_descriptor_type_length_value called once
418     rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
419                                              recordDescriptors.length,
420                                              &descriptorType, &descriptorData);
421     EXPECT_EQ(rc, PLDM_SUCCESS);
422     EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
423                                             sizeof(descriptorLen) +
424                                             descriptorData.length);
425     EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
426     EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
427     EXPECT_EQ(true, std::equal(descriptorData.ptr,
428                                descriptorData.ptr + descriptorData.length,
429                                uuid.begin(), uuid.end()));
430 
431     EXPECT_EQ(outFwDevicePkgData.length, fwDevicePkgData.size());
432     EXPECT_EQ(true,
433               std::equal(outFwDevicePkgData.ptr,
434                          outFwDevicePkgData.ptr + outFwDevicePkgData.length,
435                          fwDevicePkgData.begin(), fwDevicePkgData.end()));
436 }
437 
TEST(DecodeFirmwareDeviceIdRecord,goodPathNofwDevicePkgData)438 TEST(DecodeFirmwareDeviceIdRecord, goodPathNofwDevicePkgData)
439 {
440     constexpr uint8_t descriptorCount = 1;
441     // Continue component updates after failure
442     constexpr std::bitset<32> deviceUpdateFlag{1};
443     constexpr uint16_t componentBitmapBitLength = 8;
444     // Applicable Components - 1,2
445     std::vector<std::bitset<8>> applicableComponentsBitfield{0x03};
446     // ComponentImageSetVersionString
447     constexpr std::string_view imageSetVersionStr{"VersionString1"};
448     // Initial descriptor - UUID
449     constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
450         0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
451         0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
452     constexpr uint16_t fwDevicePkgDataLen = 0;
453 
454     // Size of the firmware device ID record
455     constexpr uint16_t recordLen =
456         sizeof(pldm_firmware_device_id_record) +
457         (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
458         imageSetVersionStr.size() +
459         sizeof(pldm_descriptor_tlv().descriptor_type) +
460         sizeof(pldm_descriptor_tlv().descriptor_length) + uuid.size() +
461         fwDevicePkgDataLen;
462     // Firmware device ID record
463     constexpr std::array<uint8_t, recordLen> record{
464         0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x03,
465         0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e,
466         0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d,
467         0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
468 
469     pldm_firmware_device_id_record deviceIdRecHeader{};
470     variable_field applicableComponents{};
471     variable_field outCompImageSetVersionStr{};
472     variable_field recordDescriptors{};
473     variable_field outFwDevicePkgData{};
474 
475     auto rc = decode_firmware_device_id_record(
476         record.data(), record.size(), componentBitmapBitLength,
477         &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
478         &recordDescriptors, &outFwDevicePkgData);
479 
480     EXPECT_EQ(rc, PLDM_SUCCESS);
481     EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
482     EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
483     EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
484               deviceUpdateFlag);
485     EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
486               PLDM_STR_TYPE_ASCII);
487     EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
488               imageSetVersionStr.size());
489     EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, 0);
490 
491     EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
492     EXPECT_EQ(true,
493               std::equal(applicableComponents.ptr,
494                          applicableComponents.ptr + applicableComponents.length,
495                          applicableComponentsBitfield.begin(),
496                          applicableComponentsBitfield.end()));
497 
498     EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
499     std::string compImageSetVersionStr(
500         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
501         reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
502         outCompImageSetVersionStr.length);
503     EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
504 
505     uint16_t descriptorType = 0;
506     uint16_t descriptorLen = 0;
507     variable_field descriptorData{};
508     // DescriptorCount is 1, so decode_descriptor_type_length_value called once
509     rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
510                                              recordDescriptors.length,
511                                              &descriptorType, &descriptorData);
512     EXPECT_EQ(rc, PLDM_SUCCESS);
513     EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
514                                             sizeof(descriptorLen) +
515                                             descriptorData.length);
516     EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
517     EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
518     EXPECT_EQ(true, std::equal(descriptorData.ptr,
519                                descriptorData.ptr + descriptorData.length,
520                                uuid.begin(), uuid.end()));
521 
522     EXPECT_EQ(outFwDevicePkgData.ptr, nullptr);
523     EXPECT_EQ(outFwDevicePkgData.length, 0);
524 }
525 
TEST(DecodeFirmwareDeviceIdRecord,ErrorPaths)526 TEST(DecodeFirmwareDeviceIdRecord, ErrorPaths)
527 {
528     // Invalid ComponentImageSetVersionStringType
529     constexpr std::array<uint8_t, 11> rec{0x0b, 0x00, 0x01, 0x01, 0x00, 0x00,
530                                           0x00, 0x06, 0x0e, 0x00, 0x00};
531     constexpr uint16_t componentBitmapBitLength = 8;
532 
533     pldm_firmware_device_id_record deviceIdRecHeader{};
534     variable_field outCompImageSetVersionStr{};
535     variable_field applicableComponents{};
536     variable_field outFwDevicePkgData{};
537     variable_field recordDescriptors{};
538     int rc = 0;
539 
540     rc = decode_firmware_device_id_record(
541         nullptr, rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
542         &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
543         &outFwDevicePkgData);
544     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
545 
546     rc = decode_firmware_device_id_record(
547         rec.data(), rec.size(), componentBitmapBitLength, nullptr,
548         &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
549         &outFwDevicePkgData);
550     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
551 
552     rc = decode_firmware_device_id_record(
553         rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
554         nullptr, &outCompImageSetVersionStr, &recordDescriptors,
555         &outFwDevicePkgData);
556     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
557 
558     rc = decode_firmware_device_id_record(
559         rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
560         &applicableComponents, nullptr, &recordDescriptors,
561         &outFwDevicePkgData);
562     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
563 
564     rc = decode_firmware_device_id_record(
565         rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
566         &applicableComponents, &outCompImageSetVersionStr, nullptr,
567         &outFwDevicePkgData);
568     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
569 
570     rc = decode_firmware_device_id_record(
571         rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
572         &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
573         nullptr);
574     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
575 
576     rc = decode_firmware_device_id_record(
577         rec.data(), rec.size() - 1, componentBitmapBitLength,
578         &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
579         &recordDescriptors, &outFwDevicePkgData);
580     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
581 
582     rc = decode_firmware_device_id_record(
583         rec.data(), rec.size(), componentBitmapBitLength + 1,
584         &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
585         &recordDescriptors, &outFwDevicePkgData);
586     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
587 
588     rc = decode_firmware_device_id_record(
589         rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
590         &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
591         &outFwDevicePkgData);
592     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
593 }
594 
TEST(DecodeFirmwareDeviceIdRecord,invalidComponentImageSetVersionStringLength)595 TEST(DecodeFirmwareDeviceIdRecord, invalidComponentImageSetVersionStringLength)
596 {
597     constexpr std::array<uint8_t, 11> rec{0x0b, 0x00, 0x01, 0x01, 0x00, 0x00,
598                                           0x00, 0x01, 0x00, 0x00, 0x00};
599     constexpr uint16_t componentBitmapBitLength = 8;
600 
601     int rc = 0;
602     pldm_firmware_device_id_record deviceIdRecHeader{};
603     variable_field applicableComponents{};
604     variable_field outCompImageSetVersionStr{};
605     variable_field recordDescriptors{};
606     variable_field outFwDevicePkgData{};
607 
608     rc = decode_firmware_device_id_record(
609         rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
610         &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
611         &outFwDevicePkgData);
612     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
613 }
614 
TEST(DecodeFirmwareDeviceIdRecord,shortBuffer)615 TEST(DecodeFirmwareDeviceIdRecord, shortBuffer)
616 {
617     constexpr std::array<uint8_t, 11> rec{0x2e, 0x00, 0x01, 0x01, 0x00, 0x00,
618                                           0x00, 0x01, 0x0e, 0x00, 0x00};
619     constexpr uint16_t componentBitmapBitLength = 8;
620 
621     pldm_firmware_device_id_record deviceIdRecHeader{};
622     variable_field outCompImageSetVersionStr{};
623     variable_field applicableComponents{};
624     variable_field outFwDevicePkgData{};
625     variable_field recordDescriptors{};
626     int rc = 0;
627 
628     rc = decode_firmware_device_id_record(
629         rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
630         &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
631         &outFwDevicePkgData);
632     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
633 }
634 
TEST(DecodeFirmwareDeviceIdRecord,recordLengthMismatch)635 TEST(DecodeFirmwareDeviceIdRecord, recordLengthMismatch)
636 {
637     constexpr std::array<uint8_t, 11> rec{0x15, 0x00, 0x01, 0x01, 0x00, 0x00,
638                                           0x00, 0x01, 0x0e, 0x02, 0x00};
639     constexpr uint16_t componentBitmapBitLength = 8;
640 
641     pldm_firmware_device_id_record deviceIdRecHeader{};
642     variable_field outCompImageSetVersionStr{};
643     variable_field applicableComponents{};
644     variable_field outFwDevicePkgData{};
645     variable_field recordDescriptors{};
646     int rc = 0;
647 
648     rc = decode_firmware_device_id_record(
649         rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
650         &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
651         &outFwDevicePkgData);
652     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
653 }
654 
TEST(DecodeFirmwareDeviceIdRecord,invalidFirmwareDevicePackageDataLength)655 TEST(DecodeFirmwareDeviceIdRecord, invalidFirmwareDevicePackageDataLength)
656 {
657     constexpr std::array<uint8_t, 49> rec{
658         0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e,
659         // FirmwareDevicePackageDataLength = 0xffff
660         0xff, 0xff,
661         //
662         0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72,
663         0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64,
664         0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b,
665         0xab, 0xcd};
666     constexpr uint16_t componentBitmapBitLength = 8;
667 
668     pldm_firmware_device_id_record deviceIdRecHeader{};
669     variable_field outCompImageSetVersionStr{};
670     variable_field applicableComponents{};
671     variable_field outFwDevicePkgData{};
672     variable_field recordDescriptors{};
673     int rc = 0;
674 
675     rc = decode_firmware_device_id_record(
676         rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
677         &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
678         &outFwDevicePkgData);
679     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
680 }
681 
TEST(DecodeDescriptors,goodPath3Descriptors)682 TEST(DecodeDescriptors, goodPath3Descriptors)
683 {
684     // In the descriptor data there are 3 descriptor entries
685     // 1) IANA enterprise ID
686     constexpr std::array<uint8_t, PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH> iana{
687         0x0a, 0x0b, 0x0c, 0xd};
688     // 2) UUID
689     constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
690         0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
691         0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
692     // 3) Vendor Defined
693     constexpr std::string_view vendorTitle{"OpenBMC"};
694     constexpr size_t vendorDescriptorLen = 2;
695     constexpr std::array<uint8_t, vendorDescriptorLen> vendorDescriptorData{
696         0x01, 0x02};
697 
698     constexpr size_t vendorDefinedDescriptorLen =
699         sizeof(pldm_vendor_defined_descriptor_title_data()
700                    .vendor_defined_descriptor_title_str_type) +
701         sizeof(pldm_vendor_defined_descriptor_title_data()
702                    .vendor_defined_descriptor_title_str_len) +
703         vendorTitle.size() + vendorDescriptorData.size();
704 
705     constexpr size_t descriptorsLength =
706         3 * (sizeof(pldm_descriptor_tlv().descriptor_type) +
707              sizeof(pldm_descriptor_tlv().descriptor_length)) +
708         iana.size() + uuid.size() + vendorDefinedDescriptorLen;
709 
710     constexpr std::array<uint8_t, descriptorsLength> descriptors{
711         0x01, 0x00, 0x04, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x02, 0x00, 0x10,
712         0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
713         0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xff, 0xff, 0x0b, 0x00, 0x01,
714         0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x01, 0x02};
715 
716     size_t descriptorCount = 1;
717     size_t descriptorsRemainingLength = descriptorsLength;
718     int rc = 0;
719 
720     while (descriptorsRemainingLength && (descriptorCount <= 3))
721     {
722         uint16_t descriptorType = 0;
723         uint16_t descriptorLen = 0;
724         variable_field descriptorData{};
725 
726         rc = decode_descriptor_type_length_value(
727             descriptors.data() + descriptorsLength - descriptorsRemainingLength,
728             descriptorsRemainingLength, &descriptorType, &descriptorData);
729         EXPECT_EQ(rc, PLDM_SUCCESS);
730 
731         if (descriptorCount == 1)
732         {
733             EXPECT_EQ(descriptorType, PLDM_FWUP_IANA_ENTERPRISE_ID);
734             EXPECT_EQ(descriptorData.length,
735                       PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH);
736             EXPECT_EQ(true,
737                       std::equal(descriptorData.ptr,
738                                  descriptorData.ptr + descriptorData.length,
739                                  iana.begin(), iana.end()));
740         }
741         else if (descriptorCount == 2)
742         {
743             EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
744             EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
745             EXPECT_EQ(true,
746                       std::equal(descriptorData.ptr,
747                                  descriptorData.ptr + descriptorData.length,
748                                  uuid.begin(), uuid.end()));
749         }
750         else if (descriptorCount == 3)
751         {
752             EXPECT_EQ(descriptorType, PLDM_FWUP_VENDOR_DEFINED);
753             EXPECT_EQ(descriptorData.length, vendorDefinedDescriptorLen);
754 
755             uint8_t descriptorTitleStrType = 0;
756             variable_field descriptorTitleStr{};
757             variable_field vendorDefinedDescriptorData{};
758 
759             rc = decode_vendor_defined_descriptor_value(
760                 descriptorData.ptr, descriptorData.length,
761                 &descriptorTitleStrType, &descriptorTitleStr,
762                 &vendorDefinedDescriptorData);
763             EXPECT_EQ(rc, PLDM_SUCCESS);
764 
765             EXPECT_EQ(descriptorTitleStrType, PLDM_STR_TYPE_ASCII);
766             EXPECT_EQ(descriptorTitleStr.length, vendorTitle.size());
767             std::string vendorTitleStr(
768                 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
769                 reinterpret_cast<const char*>(descriptorTitleStr.ptr),
770                 descriptorTitleStr.length);
771             EXPECT_EQ(vendorTitleStr, vendorTitle);
772 
773             EXPECT_EQ(vendorDefinedDescriptorData.length,
774                       vendorDescriptorData.size());
775             EXPECT_EQ(true, std::equal(vendorDefinedDescriptorData.ptr,
776                                        vendorDefinedDescriptorData.ptr +
777                                            vendorDefinedDescriptorData.length,
778                                        vendorDescriptorData.begin(),
779                                        vendorDescriptorData.end()));
780         }
781 
782         descriptorsRemainingLength -= sizeof(descriptorType) +
783                                       sizeof(descriptorLen) +
784                                       descriptorData.length;
785         descriptorCount++;
786     }
787 }
788 
TEST(DecodeDescriptors,errorPathDecodeDescriptorTLV)789 TEST(DecodeDescriptors, errorPathDecodeDescriptorTLV)
790 {
791     int rc = 0;
792     // IANA Enterprise ID descriptor length incorrect
793     constexpr std::array<uint8_t, 7> invalidIANADescriptor1{
794         0x01, 0x00, 0x03, 0x00, 0x0a, 0x0b, 0x0c};
795     uint16_t descriptorType = 0;
796     variable_field descriptorData{};
797 
798     rc = decode_descriptor_type_length_value(nullptr,
799                                              invalidIANADescriptor1.size(),
800                                              &descriptorType, &descriptorData);
801     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
802 
803     rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
804                                              invalidIANADescriptor1.size(),
805                                              nullptr, &descriptorData);
806     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
807 
808     rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
809                                              invalidIANADescriptor1.size(),
810                                              &descriptorType, nullptr);
811     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
812 
813     rc = decode_descriptor_type_length_value(
814         invalidIANADescriptor1.data(), PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN - 1,
815         &descriptorType, &descriptorData);
816     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
817 
818     rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
819                                              invalidIANADescriptor1.size(),
820                                              &descriptorType, &descriptorData);
821     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
822 
823     // IANA Enterprise ID descriptor data less than length
824     std::array<uint8_t, 7> invalidIANADescriptor2{0x01, 0x00, 0x04, 0x00,
825                                                   0x0a, 0x0b, 0x0c};
826     rc = decode_descriptor_type_length_value(invalidIANADescriptor2.data(),
827                                              invalidIANADescriptor2.size(),
828                                              &descriptorType, &descriptorData);
829     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
830 }
831 
TEST(DecodeDescriptors,errorPathVendorDefinedDescriptor)832 TEST(DecodeDescriptors, errorPathVendorDefinedDescriptor)
833 {
834     int rc = 0;
835     // VendorDefinedDescriptorTitleStringType is invalid
836     constexpr std::array<uint8_t, 9> invalidVendorDescriptor1{
837         0x06, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
838     uint8_t descriptorStringType = 0;
839     variable_field descriptorTitleStr{};
840     variable_field vendorDefinedDescriptorData{};
841 
842     rc = decode_vendor_defined_descriptor_value(
843         nullptr, invalidVendorDescriptor1.size(), &descriptorStringType,
844         &descriptorTitleStr, &vendorDefinedDescriptorData);
845     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
846 
847     rc = decode_vendor_defined_descriptor_value(
848         invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
849         &descriptorStringType, &descriptorTitleStr,
850         &vendorDefinedDescriptorData);
851     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
852 
853     rc = decode_vendor_defined_descriptor_value(
854         invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
855         nullptr, &descriptorTitleStr, &vendorDefinedDescriptorData);
856     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
857 
858     rc = decode_vendor_defined_descriptor_value(
859         invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
860         &descriptorStringType, nullptr, &vendorDefinedDescriptorData);
861     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
862 
863     rc = decode_vendor_defined_descriptor_value(
864         invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
865         &descriptorStringType, &descriptorTitleStr, nullptr);
866     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
867 
868     rc = decode_vendor_defined_descriptor_value(
869         invalidVendorDescriptor1.data(),
870         sizeof(pldm_vendor_defined_descriptor_title_data) - 1,
871         &descriptorStringType, &descriptorTitleStr,
872         &vendorDefinedDescriptorData);
873     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
874 
875     rc = decode_vendor_defined_descriptor_value(
876         invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
877         &descriptorStringType, &descriptorTitleStr,
878         &vendorDefinedDescriptorData);
879     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
880 
881     // VendorDefinedDescriptorTitleStringLength is 0
882     std::array<uint8_t, 9> invalidVendorDescriptor2{
883         0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
884     rc = decode_vendor_defined_descriptor_value(
885         invalidVendorDescriptor2.data(), invalidVendorDescriptor2.size(),
886         &descriptorStringType, &descriptorTitleStr,
887         &vendorDefinedDescriptorData);
888     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
889 
890     // VendorDefinedDescriptorData not present in the data
891     std::array<uint8_t, 9> invalidVendorDescriptor3{
892         0x01, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
893     rc = decode_vendor_defined_descriptor_value(
894         invalidVendorDescriptor3.data(), invalidVendorDescriptor3.size(),
895         &descriptorStringType, &descriptorTitleStr,
896         &vendorDefinedDescriptorData);
897     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
898 }
899 
TEST(DecodeComponentImageInfo,goodPath)900 TEST(DecodeComponentImageInfo, goodPath)
901 {
902     // Firmware
903     constexpr uint16_t compClassification = 16;
904     constexpr uint16_t compIdentifier = 300;
905     constexpr uint32_t compComparisonStamp = 0xffffffff;
906     // Force update
907     constexpr std::bitset<16> compOptions{1};
908     // System reboot[Bit position 3] & Medium-specific reset[Bit position 2]
909     constexpr std::bitset<16> reqCompActivationMethod{0x0c};
910     // Random ComponentLocationOffset
911     constexpr uint32_t compLocOffset = 357;
912     // Random ComponentSize
913     constexpr uint32_t compSize = 27;
914     // ComponentVersionString
915     constexpr std::string_view compVersionStr{"VersionString1"};
916     constexpr size_t compImageInfoSize =
917         sizeof(pldm_component_image_information) + compVersionStr.size();
918 
919     constexpr std::array<uint8_t, compImageInfoSize> compImageInfo{
920         0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
921         0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
922         0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
923     pldm_component_image_information outCompImageInfo{};
924     variable_field outCompVersionStr{};
925 
926     auto rc =
927         decode_pldm_comp_image_info(compImageInfo.data(), compImageInfo.size(),
928                                     &outCompImageInfo, &outCompVersionStr);
929 
930     EXPECT_EQ(rc, PLDM_SUCCESS);
931     EXPECT_EQ(outCompImageInfo.comp_classification, compClassification);
932     EXPECT_EQ(outCompImageInfo.comp_identifier, compIdentifier);
933     EXPECT_EQ(outCompImageInfo.comp_comparison_stamp, compComparisonStamp);
934     EXPECT_EQ(outCompImageInfo.comp_options.value, compOptions);
935     EXPECT_EQ(outCompImageInfo.requested_comp_activation_method.value,
936               reqCompActivationMethod);
937     EXPECT_EQ(outCompImageInfo.comp_location_offset, compLocOffset);
938     EXPECT_EQ(outCompImageInfo.comp_size, compSize);
939     EXPECT_EQ(outCompImageInfo.comp_version_string_type, PLDM_STR_TYPE_ASCII);
940     EXPECT_EQ(outCompImageInfo.comp_version_string_length,
941               compVersionStr.size());
942 
943     EXPECT_EQ(outCompVersionStr.length,
944               outCompImageInfo.comp_version_string_length);
945     std::string componentVersionString(
946         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
947         reinterpret_cast<const char*>(outCompVersionStr.ptr),
948         outCompVersionStr.length);
949     EXPECT_EQ(componentVersionString, compVersionStr);
950 }
951 
TEST(DecodeComponentImageInfo,errorPaths)952 TEST(DecodeComponentImageInfo, errorPaths)
953 {
954     int rc = 0;
955     // ComponentVersionString
956     constexpr std::string_view compVersionStr{"VersionString1"};
957     constexpr size_t compImageInfoSize =
958         sizeof(pldm_component_image_information) + compVersionStr.size();
959     // Invalid ComponentVersionStringType - 0x06
960     constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo1{
961         0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
962         0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x56, 0x65,
963         0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
964     pldm_component_image_information outCompImageInfo{};
965     variable_field outCompVersionStr{};
966 
967     rc = decode_pldm_comp_image_info(nullptr, invalidCompImageInfo1.size(),
968                                      &outCompImageInfo, &outCompVersionStr);
969     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
970 
971     rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
972                                      invalidCompImageInfo1.size(), nullptr,
973                                      &outCompVersionStr);
974     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
975 
976     rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
977                                      invalidCompImageInfo1.size(),
978                                      &outCompImageInfo, nullptr);
979     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
980 
981     rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
982                                      sizeof(pldm_component_image_information) -
983                                          1,
984                                      &outCompImageInfo, &outCompVersionStr);
985     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
986 
987     rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
988                                      invalidCompImageInfo1.size(),
989                                      &outCompImageInfo, &outCompVersionStr);
990     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
991 
992     // Invalid ComponentVersionStringLength - 0x00
993     constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo2{
994         0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
995         0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x65,
996         0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
997     rc = decode_pldm_comp_image_info(invalidCompImageInfo2.data(),
998                                      invalidCompImageInfo2.size(),
999                                      &outCompImageInfo, &outCompVersionStr);
1000     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1001 
1002     // Use Component Comparison Stamp is not set, but ComponentComparisonStamp
1003     // is not 0xffffffff
1004     constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo3{
1005         0x10, 0x00, 0x2c, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00,
1006         0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
1007         0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
1008 
1009     rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
1010                                      invalidCompImageInfo3.size() - 1,
1011                                      &outCompImageInfo, &outCompVersionStr);
1012     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1013 
1014     rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
1015                                      invalidCompImageInfo3.size(),
1016                                      &outCompImageInfo, &outCompVersionStr);
1017     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1018 
1019     // Invalid ComponentLocationOffset - 0
1020     constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo4{
1021         0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
1022         0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
1023         0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
1024     rc = decode_pldm_comp_image_info(invalidCompImageInfo4.data(),
1025                                      invalidCompImageInfo4.size(),
1026                                      &outCompImageInfo, &outCompVersionStr);
1027     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1028 
1029     // Invalid ComponentSize - 0
1030     constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo5{
1031         0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
1032         0x65, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
1033         0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
1034     rc = decode_pldm_comp_image_info(invalidCompImageInfo5.data(),
1035                                      invalidCompImageInfo5.size(),
1036                                      &outCompImageInfo, &outCompVersionStr);
1037     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1038 }
1039 
TEST(QueryDeviceIdentifiers,goodPathEncodeRequest)1040 TEST(QueryDeviceIdentifiers, goodPathEncodeRequest)
1041 {
1042     std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
1043     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1044     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1045 
1046     uint8_t instanceId = 0x01;
1047 
1048     auto rc = encode_query_device_identifiers_req(
1049         instanceId, PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES, requestPtr);
1050     EXPECT_EQ(rc, PLDM_SUCCESS);
1051     EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1052     EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1053     EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1054     EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DEVICE_IDENTIFIERS);
1055 }
1056 
TEST(QueryDeviceIdentifiers,goodPathDecodeResponse)1057 TEST(QueryDeviceIdentifiers, goodPathDecodeResponse)
1058 {
1059     // descriptorDataLen is not fixed here taking it as 6
1060     constexpr uint8_t descriptorDataLen = 6;
1061     std::array<uint8_t, hdrSize +
1062                             sizeof(struct pldm_query_device_identifiers_resp) +
1063                             descriptorDataLen>
1064         responseMsg{};
1065     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1066     auto inResp = reinterpret_cast<struct pldm_query_device_identifiers_resp*>(
1067         responseMsg.data() + hdrSize);
1068 
1069     inResp->completion_code = PLDM_SUCCESS;
1070     inResp->device_identifiers_len = htole32(descriptorDataLen);
1071     inResp->descriptor_count = 1;
1072 
1073     // filling descriptor data
1074     std::fill_n(responseMsg.data() + hdrSize +
1075                     sizeof(struct pldm_query_device_identifiers_resp),
1076                 descriptorDataLen, 0xff);
1077 
1078     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1079     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1080     uint8_t completionCode = PLDM_SUCCESS;
1081     uint32_t deviceIdentifiersLen = 0;
1082     uint8_t descriptorCount = 0;
1083     uint8_t* outDescriptorData = nullptr;
1084 
1085     auto rc = decode_query_device_identifiers_resp(
1086         response, responseMsg.size() - hdrSize, &completionCode,
1087         &deviceIdentifiersLen, &descriptorCount, &outDescriptorData);
1088 
1089     EXPECT_EQ(rc, PLDM_SUCCESS);
1090     EXPECT_EQ(completionCode, PLDM_SUCCESS);
1091     EXPECT_EQ(deviceIdentifiersLen, inResp->device_identifiers_len);
1092     EXPECT_EQ(descriptorCount, inResp->descriptor_count);
1093     EXPECT_EQ(true,
1094               std::equal(outDescriptorData,
1095                          outDescriptorData + deviceIdentifiersLen,
1096                          responseMsg.begin() + hdrSize +
1097                              sizeof(struct pldm_query_device_identifiers_resp),
1098                          responseMsg.end()));
1099 }
1100 
1101 #ifdef LIBPLDM_API_TESTING
TEST(QueryDeviceIdentifiers,goodPathEncodeResponse)1102 TEST(QueryDeviceIdentifiers, goodPathEncodeResponse)
1103 {
1104     int rc;
1105     PLDM_MSG_DEFINE_P(enc, 1000);
1106     size_t enc_payload_len = 1000;
1107     pldm_descriptor check_desc[] = {
1108         {
1109             .descriptor_type = PLDM_FWUP_IANA_ENTERPRISE_ID,
1110             .descriptor_length = 4,
1111             .descriptor_data = "a123",
1112         },
1113         {
1114             .descriptor_type = PLDM_FWUP_VENDOR_DEFINED,
1115             .descriptor_length = 3,
1116             .descriptor_data = "987",
1117         },
1118     };
1119     rc = encode_query_device_identifiers_resp(FIXED_INSTANCE_ID, 2, check_desc,
1120                                               enc, &enc_payload_len);
1121     EXPECT_EQ(rc, 0);
1122     EXPECT_THAT(std::span<uint8_t>(enc_buf + hdrSize, enc_payload_len),
1123                 ElementsAreArray<uint8_t>({
1124                     // completion code
1125                     0x00,
1126                     // device identifiers length = 15
1127                     0x0f,
1128                     0x00,
1129                     0x00,
1130                     0x00,
1131                     // descriptor count
1132                     0x02,
1133                     // desc 0
1134                     0x01,
1135                     0x00,
1136                     0x04,
1137                     0x00,
1138                     0x61,
1139                     0x31,
1140                     0x32,
1141                     0x33,
1142                     // desc 1
1143                     0xff,
1144                     0xff,
1145                     0x03,
1146                     0x00,
1147                     0x39,
1148                     0x38,
1149                     0x37,
1150                 }));
1151 
1152     check_response(enc, PLDM_QUERY_DEVICE_IDENTIFIERS);
1153 }
1154 #endif
1155 
TEST(GetFirmwareParameters,goodPathEncodeRequest)1156 TEST(GetFirmwareParameters, goodPathEncodeRequest)
1157 {
1158     std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
1159     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1160     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1161     uint8_t instanceId = 0x01;
1162 
1163     auto rc = encode_get_firmware_parameters_req(
1164         instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, requestPtr);
1165     EXPECT_EQ(rc, PLDM_SUCCESS);
1166     EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1167     EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1168     EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1169     EXPECT_EQ(requestPtr->hdr.command, PLDM_GET_FIRMWARE_PARAMETERS);
1170 }
1171 
TEST(GetFirmwareParameters,decodeResponse)1172 TEST(GetFirmwareParameters, decodeResponse)
1173 {
1174     // CapabilitiesDuringUpdate of the firmware device
1175     // Firmware device downgrade restrictions [Bit position 8] &
1176     // Firmware Device Partial Updates [Bit position 3]
1177     constexpr std::bitset<32> fdCapabilities{0x00000104};
1178     constexpr uint16_t compCount = 1;
1179     constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
1180     constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
1181 
1182     // constexpr uint16_t compClassification = 16;
1183     // constexpr uint16_t compIdentifier = 300;
1184     // constexpr uint8_t compClassificationIndex = 20;
1185     // constexpr uint32_t activeCompComparisonStamp = 0xabcdefab;
1186     // constexpr std::array<uint8_t, 8> activeComponentReleaseData = {
1187     //     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
1188     // constexpr uint32_t pendingCompComparisonStamp = 0x12345678;
1189     // constexpr std::array<uint8_t, 8> pendingComponentReleaseData = {
1190     //     0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
1191     constexpr std::string_view activeCompVersion{"VersionString3"};
1192     constexpr std::string_view pendingCompVersion{"VersionString4"};
1193 
1194     constexpr size_t compParamTableSize =
1195         sizeof(pldm_component_parameter_entry) + activeCompVersion.size() +
1196         pendingCompVersion.size();
1197 
1198     constexpr std::array<uint8_t, compParamTableSize> compParamTable{
1199         0x10, 0x00, 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01,
1200         0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
1201         0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00, 0x02,
1202         0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74,
1203         0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1204         0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
1205 
1206     constexpr size_t getFwParamsPayloadLen =
1207         sizeof(pldm_get_firmware_parameters_resp) +
1208         activeCompImageSetVersion.size() + pendingCompImageSetVersion.size() +
1209         compParamTableSize;
1210 
1211     constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1212         getFwParamsResponse{
1213             0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01,
1214             0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
1215             0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
1216             0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x10, 0x00,
1217             0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01, 0x02,
1218             0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
1219             0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00,
1220             0x02, 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1221             0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73,
1222             0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
1223 
1224     auto responseMsg =
1225         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1226         reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1227     pldm_get_firmware_parameters_resp outResp{};
1228     variable_field outActiveCompImageSetVersion{};
1229     variable_field outPendingCompImageSetVersion{};
1230     variable_field outCompParameterTable{};
1231 
1232     auto rc = decode_get_firmware_parameters_resp(
1233         responseMsg, getFwParamsPayloadLen, &outResp,
1234         &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1235         &outCompParameterTable);
1236 
1237     EXPECT_EQ(rc, PLDM_SUCCESS);
1238     EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1239     EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1240     EXPECT_EQ(outResp.comp_count, compCount);
1241     EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1242     EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1243               activeCompImageSetVersion.size());
1244     EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1245     EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1246               pendingCompImageSetVersion.size());
1247     std::string activeCompImageSetVersionStr(
1248         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1249         reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1250         outActiveCompImageSetVersion.length);
1251     EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1252     std::string pendingCompImageSetVersionStr(
1253         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1254         reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
1255         outPendingCompImageSetVersion.length);
1256     EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1257     EXPECT_EQ(outCompParameterTable.length, compParamTableSize);
1258     EXPECT_EQ(true, std::equal(outCompParameterTable.ptr,
1259                                outCompParameterTable.ptr +
1260                                    outCompParameterTable.length,
1261                                compParamTable.begin(), compParamTable.end()));
1262 }
1263 
TEST(GetFirmwareParameters,decodeResponseZeroCompCount)1264 TEST(GetFirmwareParameters, decodeResponseZeroCompCount)
1265 {
1266     // CapabilitiesDuringUpdate of the firmware device
1267     // FD Host Functionality during Firmware Update [Bit position 2] &
1268     // Component Update Failure Retry Capability [Bit position 1]
1269     constexpr std::bitset<32> fdCapabilities{0x06};
1270     constexpr uint16_t compCount = 0;
1271     constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
1272     constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
1273 
1274     constexpr size_t getFwParamsPayloadLen =
1275         sizeof(pldm_get_firmware_parameters_resp) +
1276         activeCompImageSetVersion.size() + pendingCompImageSetVersion.size();
1277 
1278     constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1279         getFwParamsResponse{
1280             0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1281             0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
1282             0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
1283             0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32};
1284 
1285     auto responseMsg =
1286         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1287         reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1288     pldm_get_firmware_parameters_resp outResp{};
1289     variable_field outActiveCompImageSetVersion{};
1290     variable_field outPendingCompImageSetVersion{};
1291     variable_field outCompParameterTable{};
1292 
1293     auto rc = decode_get_firmware_parameters_resp(
1294         responseMsg, getFwParamsPayloadLen, &outResp,
1295         &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1296         &outCompParameterTable);
1297 
1298     EXPECT_EQ(rc, PLDM_SUCCESS);
1299     EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1300     EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1301     EXPECT_EQ(outResp.comp_count, compCount);
1302     EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1303     EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1304               activeCompImageSetVersion.size());
1305     EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1306     EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1307               pendingCompImageSetVersion.size());
1308     std::string activeCompImageSetVersionStr(
1309         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1310         reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1311         outActiveCompImageSetVersion.length);
1312     EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1313     std::string pendingCompImageSetVersionStr(
1314         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1315         reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
1316         outPendingCompImageSetVersion.length);
1317     EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1318     EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1319     EXPECT_EQ(outCompParameterTable.length, 0);
1320 }
1321 
TEST(GetFirmwareParameters,decodeResponseNoPendingCompImageVersionStrZeroCompCount)1322 TEST(GetFirmwareParameters,
1323      decodeResponseNoPendingCompImageVersionStrZeroCompCount)
1324 {
1325     // CapabilitiesDuringUpdate of the firmware device
1326     // FD Host Functionality during Firmware Update [Bit position 2] &
1327     // Component Update Failure Retry Capability [Bit position 1]
1328     constexpr std::bitset<32> fdCapabilities{0x06};
1329     constexpr uint16_t compCount = 0;
1330     constexpr std::string_view activeCompImageSetVersion{"VersionString"};
1331 
1332     constexpr size_t getFwParamsPayloadLen =
1333         sizeof(pldm_get_firmware_parameters_resp) +
1334         activeCompImageSetVersion.size();
1335 
1336     constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1337         getFwParamsResponse{0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1338                             0x00, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00,
1339                             0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1340                             0x53, 0x74, 0x72, 0x69, 0x6e, 0x67};
1341 
1342     auto responseMsg =
1343         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1344         reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1345     pldm_get_firmware_parameters_resp outResp{};
1346     variable_field outActiveCompImageSetVersion{};
1347     variable_field outPendingCompImageSetVersion{};
1348     variable_field outCompParameterTable{};
1349 
1350     auto rc = decode_get_firmware_parameters_resp(
1351         responseMsg, getFwParamsPayloadLen, &outResp,
1352         &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1353         &outCompParameterTable);
1354 
1355     EXPECT_EQ(rc, PLDM_SUCCESS);
1356     EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1357     EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1358     EXPECT_EQ(outResp.comp_count, compCount);
1359     EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1360     EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1361               activeCompImageSetVersion.size());
1362     EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type,
1363               PLDM_STR_TYPE_UNKNOWN);
1364     EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len, 0);
1365     std::string activeCompImageSetVersionStr(
1366         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1367         reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1368         outActiveCompImageSetVersion.length);
1369     EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1370     EXPECT_EQ(outPendingCompImageSetVersion.ptr, nullptr);
1371     EXPECT_EQ(outPendingCompImageSetVersion.length, 0);
1372     EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1373     EXPECT_EQ(outCompParameterTable.length, 0);
1374 }
1375 
TEST(GetFirmwareParameters,decodeResponseErrorCompletionCode)1376 TEST(GetFirmwareParameters, decodeResponseErrorCompletionCode)
1377 {
1378     constexpr std::array<uint8_t, hdrSize + sizeof(uint8_t)>
1379         getFwParamsResponse{0x00, 0x00, 0x00, 0x01};
1380 
1381     auto responseMsg =
1382         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1383         reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1384     pldm_get_firmware_parameters_resp outResp{};
1385     variable_field outActiveCompImageSetVersion{};
1386     variable_field outPendingCompImageSetVersion{};
1387     variable_field outCompParameterTable{};
1388 
1389     auto rc = decode_get_firmware_parameters_resp(
1390         responseMsg, getFwParamsResponse.size(), &outResp,
1391         &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1392         &outCompParameterTable);
1393 
1394     EXPECT_EQ(rc, PLDM_SUCCESS);
1395     EXPECT_EQ(outResp.completion_code, PLDM_ERROR);
1396 }
1397 
TEST(GetFirmwareParameters,errorPathdecodeResponse)1398 TEST(GetFirmwareParameters, errorPathdecodeResponse)
1399 {
1400     int rc = 0;
1401     // Invalid ActiveComponentImageSetVersionStringType
1402     constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse1{
1403         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1404         0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
1405 
1406     auto responseMsg =
1407         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1408         reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse1.data());
1409     pldm_get_firmware_parameters_resp outResp{};
1410     variable_field outActiveCompImageSetVersion{};
1411     variable_field outPendingCompImageSetVersion{};
1412     variable_field outCompParameterTable{};
1413 
1414     rc = decode_get_firmware_parameters_resp(
1415         nullptr, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1416         &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1417         &outCompParameterTable);
1418     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1419 
1420     rc = decode_get_firmware_parameters_resp(
1421         responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, nullptr,
1422         &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1423         &outCompParameterTable);
1424     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1425 
1426     rc = decode_get_firmware_parameters_resp(
1427         responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1428         nullptr, &outPendingCompImageSetVersion, &outCompParameterTable);
1429     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1430 
1431     rc = decode_get_firmware_parameters_resp(
1432         responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1433         &outActiveCompImageSetVersion, nullptr, &outCompParameterTable);
1434     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1435 
1436     rc = decode_get_firmware_parameters_resp(
1437         responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1438         &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, nullptr);
1439     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1440 
1441     rc = decode_get_firmware_parameters_resp(
1442         responseMsg, 0, &outResp, &outActiveCompImageSetVersion,
1443         &outPendingCompImageSetVersion, &outCompParameterTable);
1444     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1445 
1446     rc = decode_get_firmware_parameters_resp(
1447         responseMsg, invalidGetFwParamsResponse1.size() - 1 - hdrSize, &outResp,
1448         &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1449         &outCompParameterTable);
1450     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1451 
1452     rc = decode_get_firmware_parameters_resp(
1453         responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1454         &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1455         &outCompParameterTable);
1456     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1457 
1458     // Invalid ActiveComponentImageSetVersionStringLength
1459     constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse2{
1460         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1461         0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
1462     responseMsg =
1463         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1464         reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse2.data());
1465     rc = decode_get_firmware_parameters_resp(
1466         responseMsg, invalidGetFwParamsResponse2.size() - hdrSize, &outResp,
1467         &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1468         &outCompParameterTable);
1469     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1470 
1471     // Invalid PendingComponentImageSetVersionStringType &
1472     // PendingComponentImageSetVersionStringLength
1473     constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse3{
1474         0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1475         0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x00};
1476     responseMsg =
1477         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1478         reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse3.data());
1479     rc = decode_get_firmware_parameters_resp(
1480         responseMsg, invalidGetFwParamsResponse3.size() - hdrSize, &outResp,
1481         &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1482         &outCompParameterTable);
1483     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1484 
1485     // Invalid PendingComponentImageSetVersionStringType &
1486     // PendingComponentImageSetVersionStringLength
1487     constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse4{
1488         0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1489         0x00, 0x00, 0x00, 0x01, 0x0e, 0x06, 0x0e};
1490     responseMsg =
1491         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1492         reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse4.data());
1493     rc = decode_get_firmware_parameters_resp(
1494         responseMsg, invalidGetFwParamsResponse4.size() - hdrSize, &outResp,
1495         &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1496         &outCompParameterTable);
1497     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1498 
1499     // Total payload length less than expected
1500     constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse5{
1501         0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1502         0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x0e};
1503     responseMsg =
1504         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1505         reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse5.data());
1506     rc = decode_get_firmware_parameters_resp(
1507         responseMsg, invalidGetFwParamsResponse5.size() - hdrSize, &outResp,
1508         &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1509         &outCompParameterTable);
1510     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1511 }
1512 
TEST(GetFirmwareParameters,goodPathDecodeComponentParameterEntry)1513 TEST(GetFirmwareParameters, goodPathDecodeComponentParameterEntry)
1514 {
1515     // Random value for component classification
1516     constexpr uint16_t compClassification = 0x0a0b;
1517     // Random value for component classification
1518     constexpr uint16_t compIdentifier = 0x0c0d;
1519     constexpr uint16_t compClassificationIndex = 0xf;
1520     // Random value for component classification
1521     constexpr uint32_t timestamp = 0x12345678;
1522     // Random value for component activation methods
1523     constexpr uint16_t compActivationMethods = 0xbbdd;
1524     // Random value for capabilities during update
1525     constexpr uint32_t capabilitiesDuringUpdate = 0xbadbeefe;
1526 
1527     // ActiveCompImageSetVerStrLen is not fixed here taking it as 8
1528     constexpr uint8_t activeCompVerStrLen = 8;
1529     // PendingCompImageSetVerStrLen is not fixed here taking it as 8
1530     constexpr uint8_t pendingCompVerStrLen = 8;
1531     constexpr size_t entryLength =
1532         sizeof(struct pldm_component_parameter_entry) + activeCompVerStrLen +
1533         pendingCompVerStrLen;
1534     std::array<uint8_t, entryLength> entry{};
1535 
1536     auto inEntry =
1537         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1538         reinterpret_cast<struct pldm_component_parameter_entry*>(entry.data());
1539 
1540     inEntry->comp_classification = htole16(compClassification);
1541     inEntry->comp_identifier = htole16(compIdentifier);
1542     inEntry->comp_classification_index = compClassificationIndex;
1543     inEntry->active_comp_comparison_stamp = htole32(timestamp);
1544     inEntry->active_comp_ver_str_type = 1;
1545     inEntry->active_comp_ver_str_len = activeCompVerStrLen;
1546     std::fill_n(inEntry->active_comp_release_date,
1547                 sizeof(inEntry->active_comp_release_date), 0xff);
1548     inEntry->pending_comp_comparison_stamp = htole32(timestamp);
1549     inEntry->pending_comp_ver_str_type = 1;
1550     inEntry->pending_comp_ver_str_len = pendingCompVerStrLen;
1551     std::fill_n(inEntry->pending_comp_release_date,
1552                 sizeof(inEntry->pending_comp_release_date), 0xff);
1553     inEntry->comp_activation_methods.value = htole16(compActivationMethods);
1554     inEntry->capabilities_during_update.value =
1555         htole32(capabilitiesDuringUpdate);
1556     constexpr auto activeCompVerStrPos =
1557         sizeof(struct pldm_component_parameter_entry);
1558     std::fill_n(entry.data() + activeCompVerStrPos, activeCompVerStrLen, 0xaa);
1559     constexpr auto pendingCompVerStrPos =
1560         activeCompVerStrPos + activeCompVerStrLen;
1561     std::fill_n(entry.data() + pendingCompVerStrPos, pendingCompVerStrLen,
1562                 0xbb);
1563 
1564     struct pldm_component_parameter_entry outEntry;
1565     struct variable_field outActiveCompVerStr;
1566     struct variable_field outPendingCompVerStr;
1567 
1568     auto rc = decode_get_firmware_parameters_resp_comp_entry(
1569         entry.data(), entryLength, &outEntry, &outActiveCompVerStr,
1570         &outPendingCompVerStr);
1571 
1572     EXPECT_EQ(rc, PLDM_SUCCESS);
1573 
1574     EXPECT_EQ(outEntry.comp_classification, compClassification);
1575     EXPECT_EQ(outEntry.comp_identifier, compIdentifier);
1576     EXPECT_EQ(inEntry->comp_classification_index,
1577               outEntry.comp_classification_index);
1578     EXPECT_EQ(outEntry.active_comp_comparison_stamp, timestamp);
1579     EXPECT_EQ(inEntry->active_comp_ver_str_type,
1580               outEntry.active_comp_ver_str_type);
1581     EXPECT_EQ(inEntry->active_comp_ver_str_len,
1582               outEntry.active_comp_ver_str_len);
1583     EXPECT_EQ(0, memcmp(inEntry->active_comp_release_date,
1584                         outEntry.active_comp_release_date,
1585                         sizeof(inEntry->active_comp_release_date)));
1586     EXPECT_EQ(outEntry.pending_comp_comparison_stamp, timestamp);
1587     EXPECT_EQ(inEntry->pending_comp_ver_str_type,
1588               outEntry.pending_comp_ver_str_type);
1589     EXPECT_EQ(inEntry->pending_comp_ver_str_len,
1590               outEntry.pending_comp_ver_str_len);
1591     EXPECT_EQ(0, memcmp(inEntry->pending_comp_release_date,
1592                         outEntry.pending_comp_release_date,
1593                         sizeof(inEntry->pending_comp_release_date)));
1594     EXPECT_EQ(outEntry.comp_activation_methods.value, compActivationMethods);
1595     EXPECT_EQ(outEntry.capabilities_during_update.value,
1596               capabilitiesDuringUpdate);
1597 
1598     EXPECT_EQ(0, memcmp(outActiveCompVerStr.ptr,
1599                         entry.data() + activeCompVerStrPos,
1600                         outActiveCompVerStr.length));
1601     EXPECT_EQ(0, memcmp(outPendingCompVerStr.ptr,
1602                         entry.data() + pendingCompVerStrPos,
1603                         outPendingCompVerStr.length));
1604 
1605 #ifdef LIBPLDM_API_TESTING
1606     /* Check the roundtrip matches */
1607     std::vector<uint8_t> enc_data(1000);
1608     size_t enc_payload_len = enc_data.size();
1609     struct pldm_component_parameter_entry_full entryFull = {
1610         .comp_classification = compClassification,
1611         .comp_identifier = compIdentifier,
1612         .comp_classification_index = compClassificationIndex,
1613         .active_ver =
1614             {
1615                 .comparison_stamp = 0x12345678,
1616                 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1617                         .str_len = activeCompVerStrLen,
1618                         .str_data = {}},
1619                 .date = {},
1620             },
1621         .pending_ver =
1622             {
1623                 .comparison_stamp = 0x12345678,
1624                 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1625                         .str_len = pendingCompVerStrLen,
1626                         .str_data = {}},
1627                 .date = {},
1628             },
1629         .comp_activation_methods = inEntry->comp_activation_methods,
1630         .capabilities_during_update = inEntry->capabilities_during_update,
1631     };
1632     // Fill strings
1633     std::fill_n(entryFull.active_ver.str.str_data, activeCompVerStrLen, 0xaa);
1634     std::fill_n(entryFull.pending_ver.str.str_data, pendingCompVerStrLen, 0xbb);
1635     std::fill_n(entryFull.active_ver.date, PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN,
1636                 0xff);
1637     std::fill_n(entryFull.pending_ver.date,
1638                 PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN, 0xff);
1639 
1640     rc = encode_get_firmware_parameters_resp_comp_entry(
1641         &entryFull, enc_data.data(), &enc_payload_len);
1642     EXPECT_EQ(rc, PLDM_SUCCESS);
1643     EXPECT_EQ(enc_payload_len, entryLength);
1644     EXPECT_TRUE(std::equal(entry.begin(), entry.end(), enc_data.begin()));
1645 #endif
1646 }
1647 
TEST(QueryDownstreamDevices,goodPathEncodeRequest)1648 TEST(QueryDownstreamDevices, goodPathEncodeRequest)
1649 {
1650     constexpr uint8_t instanceId = 1;
1651     std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
1652     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1653     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1654 
1655     auto rc = encode_query_downstream_devices_req(instanceId, requestPtr);
1656 
1657     EXPECT_EQ(rc, 0);
1658     EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1659     EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1660     EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1661     EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DOWNSTREAM_DEVICES);
1662 }
1663 
TEST(QueryDownstreamDevices,encodeRequestInvalidData)1664 TEST(QueryDownstreamDevices, encodeRequestInvalidData)
1665 {
1666     constexpr uint8_t instanceId = 1;
1667 
1668     auto rc = encode_query_downstream_devices_req(instanceId, nullptr);
1669 
1670     EXPECT_EQ(rc, -EINVAL);
1671 }
1672 
TEST(QueryDownstreamDevices,goodPathDecodeResponse)1673 TEST(QueryDownstreamDevices, goodPathDecodeResponse)
1674 {
1675     uint8_t completion_code_resp = PLDM_SUCCESS;
1676     uint8_t downstream_device_update_supported_resp =
1677         PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1678     uint16_t number_of_downstream_devices_resp = 1;
1679     uint16_t max_number_of_downstream_devices_resp = 1;
1680     /** Capabilities of updating downstream devices
1681      * FDP supports downstream devices dynamically attached [Bit position 0] &
1682      * FDP supports downstream devices dynamically removed [Bit position 1]
1683      */
1684     bitfield32_t capabilities_resp = {.value = 0x0002};
1685     int rc;
1686 
1687     std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1688         responseMsg{};
1689 
1690     PLDM_MSGBUF_DEFINE_P(buf);
1691     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1692                                 responseMsg.size() - hdrSize);
1693     EXPECT_EQ(rc, 0);
1694 
1695     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1696     pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1697     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1698     pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1699     pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
1700     ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
1701 
1702     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1703     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1704     struct pldm_query_downstream_devices_resp resp_data;
1705 
1706     rc = decode_query_downstream_devices_resp(
1707         response, responseMsg.size() - hdrSize, &resp_data);
1708 
1709     EXPECT_EQ(rc, 0);
1710     EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1711     EXPECT_EQ(resp_data.downstream_device_update_supported,
1712               downstream_device_update_supported_resp);
1713     EXPECT_EQ(resp_data.number_of_downstream_devices,
1714               number_of_downstream_devices_resp);
1715     EXPECT_EQ(resp_data.max_number_of_downstream_devices,
1716               max_number_of_downstream_devices_resp);
1717     EXPECT_EQ(resp_data.capabilities.value, capabilities_resp.value);
1718 }
1719 
TEST(QueryDownstreamDevices,decodeRequestUndefinedValue)1720 TEST(QueryDownstreamDevices, decodeRequestUndefinedValue)
1721 {
1722     uint8_t completion_code_resp = PLDM_SUCCESS;
1723     uint8_t downstream_device_update_supported_resp = 0xe; /*Undefined value*/
1724     uint16_t number_of_downstream_devices_resp = 1;
1725     uint16_t max_number_of_downstream_devices_resp = 1;
1726     /** Capabilities of updating downstream devices
1727      * FDP supports downstream devices dynamically attached [Bit position 0] &
1728      * FDP supports downstream devices dynamically removed [Bit position 1]
1729      */
1730     bitfield32_t capabilities_resp = {.value = 0x0002};
1731     int rc;
1732 
1733     std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1734         responseMsg{};
1735 
1736     PLDM_MSGBUF_DEFINE_P(buf);
1737     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1738                                 responseMsg.size() - hdrSize);
1739     ASSERT_EQ(rc, 0);
1740     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1741     pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1742     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1743     pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1744     pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
1745     ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
1746 
1747     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1748     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1749     struct pldm_query_downstream_devices_resp resp_data;
1750 
1751     rc = decode_query_downstream_devices_resp(
1752         response, responseMsg.size() - hdrSize, &resp_data);
1753 
1754     ASSERT_EQ(rc, -EINVAL);
1755 }
1756 
TEST(QueryDownstreamDevices,decodeRequestErrorBufSize)1757 TEST(QueryDownstreamDevices, decodeRequestErrorBufSize)
1758 {
1759     uint8_t completion_code_resp = PLDM_SUCCESS;
1760     uint8_t downstream_device_update_supported_resp =
1761         PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1762     uint16_t number_of_downstream_devices_resp = 1;
1763     uint16_t max_number_of_downstream_devices_resp = 1;
1764     /** Capabilities of updating downstream devices
1765      * FDP supports downstream devices dynamically attached [Bit position 0] &
1766      * FDP supports downstream devices dynamically removed [Bit position 1]
1767      */
1768     bitfield32_t capabilities_resp = {.value = 0x0002};
1769     int rc;
1770 
1771     std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES -
1772                             2 /* Inject error length*/>
1773         responseMsg{};
1774 
1775     PLDM_MSGBUF_DEFINE_P(buf);
1776     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1777                                 responseMsg.size() - hdrSize);
1778     ASSERT_EQ(rc, 0);
1779 
1780     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1781     pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1782     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1783     pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1784     // Inject error value
1785     pldm_msgbuf_insert_uint16(buf, (uint16_t)capabilities_resp.value);
1786     ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
1787 
1788     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1789     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1790     struct pldm_query_downstream_devices_resp resp_data;
1791 
1792     rc = decode_query_downstream_devices_resp(
1793         response, responseMsg.size() - hdrSize, &resp_data);
1794 
1795     EXPECT_EQ(rc, -EBADMSG);
1796 }
1797 
TEST(QueryDownstreamIdentifiers,goodPathEncodeRequest)1798 TEST(QueryDownstreamIdentifiers, goodPathEncodeRequest)
1799 {
1800     constexpr uint8_t instanceId = 1;
1801     constexpr size_t payloadLen = PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1802     PLDM_MSG_DEFINE_P(request, payloadLen);
1803     constexpr pldm_query_downstream_identifiers_req params_req{
1804         0xFFFFFFFF, PLDM_GET_FIRSTPART};
1805 
1806     auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1807                                                       request, payloadLen);
1808     ASSERT_EQ(rc, 0);
1809     EXPECT_THAT(std::span<uint8_t>(request_buf, sizeof(request_buf)),
1810                 ElementsAreArray<uint8_t>(
1811                     {0x81, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x01}));
1812 }
1813 
TEST(QueryDownstreamIdentifiers,encodeRequestInvalidErrorPaths)1814 TEST(QueryDownstreamIdentifiers, encodeRequestInvalidErrorPaths)
1815 {
1816     constexpr uint8_t instanceId = 1;
1817     constexpr pldm_query_downstream_identifiers_req params_req{
1818         0xFFFFFFFF, PLDM_GET_FIRSTPART};
1819     constexpr pldm_query_downstream_identifiers_req params_req_invalid{
1820         0xFFFFFFFF, PLDM_ACKNOWLEDGEMENT_ONLY};
1821     constexpr size_t payload_length =
1822         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1823     std::array<uint8_t, hdrSize + payload_length> requestMsg{};
1824     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1825     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1826 
1827     auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1828                                                       nullptr, payload_length);
1829     EXPECT_EQ(rc, -EINVAL);
1830 
1831     rc = encode_query_downstream_identifiers_req(
1832         instanceId, &params_req, requestPtr, payload_length - 1);
1833     EXPECT_EQ(rc, -EOVERFLOW);
1834 
1835     rc = encode_query_downstream_identifiers_req(
1836         instanceId, &params_req_invalid, requestPtr, payload_length);
1837     EXPECT_EQ(rc, -EINVAL);
1838 }
1839 
TEST(QueryDownstreamIdentifiers,decodeResponseNoDevices)1840 TEST(QueryDownstreamIdentifiers, decodeResponseNoDevices)
1841 {
1842     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1843     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1844     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1845     constexpr uint32_t downstream_devices_length_resp = 0;
1846     constexpr uint16_t number_of_downstream_devices_resp = 0;
1847 
1848     PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1849     struct pldm_query_downstream_identifiers_resp resp_data = {};
1850     struct pldm_downstream_device_iter devs;
1851     PLDM_MSGBUF_DEFINE_P(buf);
1852     int rc = 0;
1853 
1854     rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1855                                 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1856     ASSERT_EQ(rc, 0);
1857 
1858     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1859     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1860     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1861     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1862     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1863 
1864     ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
1865 
1866     rc = decode_query_downstream_identifiers_resp(
1867         response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp_data,
1868         &devs);
1869 
1870     ASSERT_EQ(rc, 0);
1871     EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1872     EXPECT_EQ(resp_data.next_data_transfer_handle,
1873               next_data_transfer_handle_resp);
1874     EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1875     EXPECT_EQ(resp_data.downstream_devices_length,
1876               downstream_devices_length_resp);
1877     EXPECT_EQ(resp_data.number_of_downstream_devices,
1878               number_of_downstream_devices_resp);
1879 }
1880 
TEST(QueryDownstreamIdentifiers,decodeResponseNoDevicesBadCount)1881 TEST(QueryDownstreamIdentifiers, decodeResponseNoDevicesBadCount)
1882 {
1883     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1884     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1885     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1886     constexpr uint32_t downstream_devices_length_resp = 0;
1887     constexpr uint16_t number_of_downstream_devices_resp = 1;
1888 
1889     PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1890     struct pldm_query_downstream_identifiers_resp resp = {};
1891     struct pldm_downstream_device_iter devs;
1892     struct pldm_downstream_device dev;
1893     PLDM_MSGBUF_DEFINE_P(buf);
1894     int rc = 0;
1895 
1896     rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1897                                 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1898     ASSERT_EQ(rc, 0);
1899 
1900     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1901     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1902     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1903     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1904     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1905 
1906     ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
1907 
1908     rc = decode_query_downstream_identifiers_resp(
1909         response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp, &devs);
1910     ASSERT_EQ(rc, 0);
1911 
1912     foreach_pldm_downstream_device(devs, dev, rc)
1913     {
1914         FAIL();
1915     }
1916     ASSERT_NE(rc, 0);
1917 }
1918 
TEST(QueryDownstreamIdentifiers,decodeResponseOneDeviceOneDescriptor)1919 TEST(QueryDownstreamIdentifiers, decodeResponseOneDeviceOneDescriptor)
1920 {
1921     constexpr uint32_t downstreamDevicesLen = 11;
1922     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1923     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1924     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1925     const uint32_t downstream_devices_length_resp =
1926         htole32(downstreamDevicesLen);
1927     constexpr uint16_t number_of_downstream_devices_resp = 1;
1928     constexpr size_t payloadLen =
1929         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstreamDevicesLen;
1930 
1931     struct pldm_query_downstream_identifiers_resp resp_data = {};
1932     PLDM_MSG_DEFINE_P(response, payloadLen);
1933     struct pldm_downstream_device_iter devs;
1934     struct pldm_downstream_device dev;
1935     PLDM_MSGBUF_DEFINE_P(buf);
1936     int rc = 0;
1937 
1938     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1939     ASSERT_EQ(rc, 0);
1940 
1941     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1942     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1943     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1944     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1945     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1946 
1947     /* Downstream device */
1948     pldm_msgbuf_insert_uint16(buf, 1);
1949     pldm_msgbuf_insert_uint8(buf, 1);
1950 
1951     /* Device descriptor */
1952     pldm_msgbuf_insert_uint16(buf, 1);
1953     pldm_msgbuf_insert_uint16(buf, 4);
1954     pldm_msgbuf_insert_uint32(buf, 412);
1955 
1956     ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
1957 
1958     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1959                                                   &resp_data, &devs);
1960 
1961     ASSERT_EQ(rc, 0);
1962     EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1963     EXPECT_EQ(resp_data.next_data_transfer_handle,
1964               next_data_transfer_handle_resp);
1965     EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1966     EXPECT_EQ(resp_data.downstream_devices_length,
1967               downstream_devices_length_resp);
1968     EXPECT_EQ(resp_data.number_of_downstream_devices,
1969               number_of_downstream_devices_resp);
1970 
1971     foreach_pldm_downstream_device(devs, dev, rc)
1972     {
1973         struct pldm_descriptor desc;
1974 
1975         EXPECT_EQ(dev.downstream_device_index, 1);
1976         EXPECT_EQ(dev.downstream_descriptor_count, 1);
1977 
1978         foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1979         {
1980             static const uint32_t dmtf = htole32(412);
1981             EXPECT_EQ(desc.descriptor_type, 1);
1982             EXPECT_EQ(desc.descriptor_length, 4);
1983             EXPECT_EQ(memcmp(desc.descriptor_data, &dmtf, sizeof(dmtf)), 0);
1984         }
1985         ASSERT_EQ(rc, 0);
1986     }
1987     ASSERT_EQ(rc, 0);
1988 }
1989 
1990 constexpr const uint16_t descriptor_id_type_iana_pen = 0x1;
1991 constexpr const uint16_t descriptor_id_len_iana_pen = 0x4;
1992 const uint32_t iana_pen_openbmc = htole16(49871u);
1993 const uint32_t iana_pen_dmtf = htole16(412u);
1994 
TEST(QueryDownstreamIdentifiers,decodeResponseTwoDevicesOneDescriptorEach)1995 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneDescriptorEach)
1996 {
1997     constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1998         {0, 1},
1999         {1, 1},
2000     }};
2001 
2002     constexpr const std::array<pldm_descriptor, 2> expected_descriptors = {{
2003         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2004          &iana_pen_dmtf},
2005         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2006          &iana_pen_openbmc},
2007     }};
2008 
2009     constexpr uint32_t downstream_devices_len = 22;
2010     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2011     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2012     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2013     const uint32_t downstream_devices_length_resp =
2014         htole32(downstream_devices_len);
2015     constexpr uint16_t number_of_downstream_devices_resp = 2;
2016     constexpr size_t payloadLen =
2017         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2018 
2019     struct pldm_query_downstream_identifiers_resp resp_data{};
2020     PLDM_MSG_DEFINE_P(response, payloadLen);
2021     struct pldm_downstream_device_iter devs;
2022     struct pldm_downstream_device dev;
2023     PLDM_MSGBUF_DEFINE_P(buf);
2024     int rc = 0;
2025 
2026     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2027     ASSERT_EQ(rc, 0);
2028 
2029     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2030     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2031     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2032     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2033     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2034 
2035     /* Downstream device */
2036     pldm_msgbuf_insert_uint16(buf, 0);
2037     pldm_msgbuf_insert_uint8(buf, 1);
2038 
2039     /* Device descriptor */
2040     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2041     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2042     pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2043 
2044     /* Downstream device */
2045     pldm_msgbuf_insert_uint16(buf, 1);
2046     pldm_msgbuf_insert_uint8(buf, 1);
2047 
2048     /* Device descriptor */
2049     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2050     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2051     pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2052 
2053     ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
2054 
2055     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2056                                                   &resp_data, &devs);
2057 
2058     ASSERT_EQ(rc, 0);
2059     EXPECT_EQ(resp_data.number_of_downstream_devices,
2060               number_of_downstream_devices_resp);
2061 
2062     size_t devIndex = 0;
2063     size_t descIndex = 0;
2064     foreach_pldm_downstream_device(devs, dev, rc)
2065     {
2066         struct pldm_descriptor desc;
2067 
2068         ASSERT_LT(devIndex, expected_devices.size());
2069 
2070         const struct pldm_downstream_device* expectedDev =
2071             &expected_devices[devIndex];
2072 
2073         EXPECT_EQ(dev.downstream_device_index,
2074                   expectedDev->downstream_device_index);
2075         EXPECT_EQ(dev.downstream_descriptor_count,
2076                   expectedDev->downstream_descriptor_count);
2077 
2078         foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2079         {
2080             ASSERT_LT(descIndex, expected_descriptors.size());
2081 
2082             const struct pldm_descriptor* expectedDesc =
2083                 &expected_descriptors[descIndex];
2084 
2085             EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2086             ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2087             EXPECT_EQ(memcmp(desc.descriptor_data,
2088                              expectedDesc->descriptor_data,
2089                              expectedDesc->descriptor_length),
2090                       0);
2091 
2092             descIndex++;
2093         }
2094         ASSERT_EQ(rc, 0);
2095         EXPECT_EQ(descIndex, 1 * devIndex + 1);
2096 
2097         devIndex++;
2098     }
2099     ASSERT_EQ(rc, 0);
2100     EXPECT_EQ(devIndex, 2);
2101 }
2102 
TEST(QueryDownstreamIdentifiers,decodeResponseTwoDevicesTwoOneDescriptors)2103 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesTwoOneDescriptors)
2104 {
2105     constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
2106         {0, 2},
2107         {1, 1},
2108     }};
2109 
2110     constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
2111         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2112          &iana_pen_dmtf},
2113         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2114          &iana_pen_openbmc},
2115         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2116          &iana_pen_dmtf},
2117     }};
2118 
2119     constexpr uint32_t downstream_devices_len = 30;
2120     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2121     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2122     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2123     const uint32_t downstream_devices_length_resp =
2124         htole32(downstream_devices_len);
2125     constexpr uint16_t number_of_downstream_devices_resp = 2;
2126     constexpr size_t payloadLen =
2127         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2128 
2129     struct pldm_query_downstream_identifiers_resp resp_data{};
2130     PLDM_MSG_DEFINE_P(response, payloadLen);
2131     struct pldm_downstream_device_iter devs;
2132     struct pldm_downstream_device dev;
2133     PLDM_MSGBUF_DEFINE_P(buf);
2134     int rc = 0;
2135 
2136     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2137     ASSERT_EQ(rc, 0);
2138 
2139     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2140     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2141     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2142     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2143     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2144 
2145     /* Downstream device */
2146     pldm_msgbuf_insert_uint16(buf, 0);
2147     pldm_msgbuf_insert_uint8(buf, 2);
2148 
2149     /* Device descriptor */
2150     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2151     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2152     pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2153 
2154     /* Device descriptor */
2155     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2156     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2157     pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2158 
2159     /* Downstream device */
2160     pldm_msgbuf_insert_uint16(buf, 1);
2161     pldm_msgbuf_insert_uint8(buf, 1);
2162 
2163     /* Device descriptor */
2164     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2165     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2166     pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2167 
2168     ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
2169 
2170     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2171                                                   &resp_data, &devs);
2172 
2173     ASSERT_EQ(rc, 0);
2174     EXPECT_EQ(resp_data.number_of_downstream_devices,
2175               number_of_downstream_devices_resp);
2176 
2177     size_t devIndex = 0;
2178     size_t descIndex = 0;
2179     foreach_pldm_downstream_device(devs, dev, rc)
2180     {
2181         struct pldm_descriptor desc;
2182 
2183         ASSERT_LT(devIndex, expected_devices.size());
2184 
2185         const struct pldm_downstream_device* expectedDev =
2186             &expected_devices[devIndex];
2187 
2188         EXPECT_EQ(dev.downstream_device_index,
2189                   expectedDev->downstream_device_index);
2190         EXPECT_EQ(dev.downstream_descriptor_count,
2191                   expectedDev->downstream_descriptor_count);
2192 
2193         foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2194         {
2195             ASSERT_LT(descIndex, expected_descriptors.size());
2196 
2197             const struct pldm_descriptor* expectedDesc =
2198                 &expected_descriptors[descIndex];
2199 
2200             EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2201             ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2202             EXPECT_EQ(memcmp(desc.descriptor_data,
2203                              expectedDesc->descriptor_data,
2204                              expectedDesc->descriptor_length),
2205                       0);
2206 
2207             descIndex++;
2208         }
2209         ASSERT_EQ(rc, 0);
2210 
2211         devIndex++;
2212     }
2213     ASSERT_EQ(rc, 0);
2214     EXPECT_EQ(devIndex, 2);
2215     EXPECT_EQ(descIndex, 3);
2216 }
2217 
TEST(QueryDownstreamIdentifiers,decodeResponseTwoDevicesOneTwoDescriptors)2218 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneTwoDescriptors)
2219 {
2220     constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
2221         {0, 1},
2222         {1, 2},
2223     }};
2224 
2225     constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
2226         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2227          &iana_pen_dmtf},
2228         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2229          &iana_pen_openbmc},
2230         {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2231          &iana_pen_dmtf},
2232     }};
2233 
2234     constexpr uint32_t downstream_devices_len = 30;
2235     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2236     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2237     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2238     const uint32_t downstream_devices_length_resp =
2239         htole32(downstream_devices_len);
2240     constexpr uint16_t number_of_downstream_devices_resp = 2;
2241     constexpr size_t payloadLen =
2242         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2243 
2244     struct pldm_query_downstream_identifiers_resp resp_data{};
2245     PLDM_MSG_DEFINE_P(response, payloadLen);
2246     struct pldm_downstream_device_iter devs;
2247     struct pldm_downstream_device dev;
2248     PLDM_MSGBUF_DEFINE_P(buf);
2249     int rc = 0;
2250 
2251     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2252     ASSERT_EQ(rc, 0);
2253 
2254     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2255     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2256     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2257     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2258     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2259 
2260     /* Downstream device */
2261     pldm_msgbuf_insert_uint16(buf, 0);
2262     pldm_msgbuf_insert_uint8(buf, 1);
2263 
2264     /* Device descriptor */
2265     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2266     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2267     pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2268 
2269     /* Downstream device */
2270     pldm_msgbuf_insert_uint16(buf, 1);
2271     pldm_msgbuf_insert_uint8(buf, 2);
2272 
2273     /* Device descriptor */
2274     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2275     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2276     pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2277 
2278     /* Device descriptor */
2279     pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2280     pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2281     pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2282 
2283     ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
2284 
2285     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2286                                                   &resp_data, &devs);
2287 
2288     ASSERT_EQ(rc, 0);
2289     EXPECT_EQ(resp_data.number_of_downstream_devices,
2290               number_of_downstream_devices_resp);
2291 
2292     size_t devIndex = 0;
2293     size_t descIndex = 0;
2294     foreach_pldm_downstream_device(devs, dev, rc)
2295     {
2296         struct pldm_descriptor desc;
2297 
2298         ASSERT_LT(devIndex, expected_devices.size());
2299 
2300         const struct pldm_downstream_device* expectedDev =
2301             &expected_devices[devIndex];
2302 
2303         EXPECT_EQ(dev.downstream_device_index,
2304                   expectedDev->downstream_device_index);
2305         EXPECT_EQ(dev.downstream_descriptor_count,
2306                   expectedDev->downstream_descriptor_count);
2307 
2308         foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2309         {
2310             ASSERT_LT(descIndex, expected_descriptors.size());
2311 
2312             const struct pldm_descriptor* expectedDesc =
2313                 &expected_descriptors[descIndex];
2314 
2315             EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2316             ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2317             EXPECT_EQ(memcmp(desc.descriptor_data,
2318                              expectedDesc->descriptor_data,
2319                              expectedDesc->descriptor_length),
2320                       0);
2321 
2322             descIndex++;
2323         }
2324         ASSERT_EQ(rc, 0);
2325 
2326         devIndex++;
2327     }
2328     ASSERT_EQ(rc, 0);
2329     EXPECT_EQ(devIndex, 2);
2330     EXPECT_EQ(descIndex, 3);
2331 }
2332 
TEST(QueryDownstreamIdentifiers,decodeRequestErrorPaths)2333 TEST(QueryDownstreamIdentifiers, decodeRequestErrorPaths)
2334 {
2335     constexpr size_t payloadLen = sizeof(uint8_t);
2336 
2337     struct pldm_query_downstream_identifiers_resp resp_data = {};
2338     struct pldm_downstream_device_iter devs;
2339     PLDM_MSG_DEFINE_P(response, payloadLen);
2340 
2341     // Test nullptr
2342     auto rc = decode_query_downstream_identifiers_resp(nullptr, payloadLen,
2343                                                        nullptr, &devs);
2344     EXPECT_EQ(rc, -EINVAL);
2345 
2346     // Test not PLDM_SUCCESS completion code
2347     response->payload[0] = PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
2348     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2349                                                   &resp_data, &devs);
2350     EXPECT_EQ(rc, 0);
2351     EXPECT_EQ(resp_data.completion_code, PLDM_ERROR_UNSUPPORTED_PLDM_CMD);
2352 
2353     // Test payload length less than minimum length
2354     response->payload[0] = PLDM_SUCCESS;
2355     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2356                                                   &resp_data, &devs);
2357 
2358     EXPECT_EQ(rc, -EBADMSG);
2359 }
2360 
TEST(QueryDownstreamIdentifiers,decodeRequestErrorDownstreamDevicesSize)2361 TEST(QueryDownstreamIdentifiers, decodeRequestErrorDownstreamDevicesSize)
2362 {
2363     // Len is not fixed here taking it as 9, contains 1 downstream device with
2364     // 1 descriptor
2365     constexpr uint32_t actualDownstreamDevicesLen = 9;
2366     constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2367     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2368     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2369     constexpr uint16_t number_of_downstream_devices_resp = 1;
2370     constexpr size_t payloadLen =
2371         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN +
2372         actualDownstreamDevicesLen;
2373 
2374     const uint32_t downstream_devices_length_resp =
2375         htole32(actualDownstreamDevicesLen + 1 /* inject error length*/);
2376 
2377     struct pldm_query_downstream_identifiers_resp resp_data = {};
2378     struct pldm_downstream_device_iter devs;
2379     PLDM_MSG_DEFINE_P(response, payloadLen);
2380     PLDM_MSGBUF_DEFINE_P(buf);
2381     void* devicesStart = NULL;
2382     size_t devicesLen;
2383     int rc = 0;
2384 
2385     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2386     ASSERT_EQ(rc, 0);
2387 
2388     pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2389     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2390     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2391     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2392     pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2393     pldm_msgbuf_span_remaining(buf, &devicesStart, &devicesLen);
2394 
2395     ASSERT_EQ(0, pldm_msgbuf_complete(buf));
2396 
2397     /** Filling descriptor data, the correctness of the downstream devices data
2398      *  is not checked in this test case so filling with 0xff
2399      */
2400     std::fill_n(static_cast<uint8_t*>(devicesStart), actualDownstreamDevicesLen,
2401                 0xff);
2402 
2403     EXPECT_NE(decode_query_downstream_identifiers_resp(response, payloadLen,
2404                                                        &resp_data, &devs),
2405               0);
2406 }
2407 
TEST(QueryDownstreamIdentifiers,decodeRequestErrorBufSize)2408 TEST(QueryDownstreamIdentifiers, decodeRequestErrorBufSize)
2409 {
2410     constexpr uint32_t actualDownstreamDevicesLen = 0;
2411     constexpr uint16_t number_of_downstream_devices_resp = 1;
2412     constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2413     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2414     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2415     constexpr size_t payloadLen =
2416         PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN - 1;
2417 
2418     const uint32_t downstream_devices_length_resp =
2419         htole32(actualDownstreamDevicesLen);
2420 
2421     struct pldm_query_downstream_identifiers_resp resp_data = {};
2422     struct pldm_downstream_device_iter devs;
2423     PLDM_MSG_DEFINE_P(response, payloadLen);
2424     PLDM_MSGBUF_DEFINE_P(buf);
2425     int rc = 0;
2426 
2427     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2428     ASSERT_EQ(rc, 0);
2429 
2430     pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2431     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2432     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2433     pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2434     // Inject error buffer size
2435     pldm_msgbuf_insert_uint8(buf, (uint8_t)number_of_downstream_devices_resp);
2436     ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
2437 
2438     rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2439                                                   &resp_data, &devs);
2440 
2441     EXPECT_EQ(rc, -EBADMSG);
2442 }
2443 
TEST(GetDownstreamFirmwareParameters,goodPathEncodeRequest)2444 TEST(GetDownstreamFirmwareParameters, goodPathEncodeRequest)
2445 {
2446     constexpr uint8_t instanceId = 1;
2447     constexpr pldm_get_downstream_firmware_parameters_req params_req{
2448         0x0, PLDM_GET_FIRSTPART};
2449     constexpr size_t payload_length =
2450         PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
2451     std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
2452     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2453     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2454 
2455     auto rc = encode_get_downstream_firmware_parameters_req(
2456         instanceId, &params_req, requestPtr, payload_length);
2457     EXPECT_EQ(rc, 0);
2458 
2459     std::array<uint8_t,
2460                hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES>
2461         expectedReq{0x81, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01};
2462     EXPECT_EQ(requestMsg, expectedReq);
2463 }
2464 
TEST(GetDownstreamFirmwareParameters,encodeRequestInvalidTransferOperationFlag)2465 TEST(GetDownstreamFirmwareParameters, encodeRequestInvalidTransferOperationFlag)
2466 {
2467     constexpr uint8_t instanceId = 1;
2468     // Setup invalid transfer operation flag
2469     constexpr pldm_get_downstream_firmware_parameters_req params_req{
2470         0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
2471     constexpr size_t payload_length =
2472         PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
2473     std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
2474     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2475     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2476 
2477     auto rc = encode_get_downstream_firmware_parameters_req(
2478         instanceId, &params_req, requestPtr, payload_length);
2479     EXPECT_EQ(rc, -EBADMSG);
2480 }
2481 
TEST(GetDownstreamFirmwareParameters,encodeRequestErrorBufSize)2482 TEST(GetDownstreamFirmwareParameters, encodeRequestErrorBufSize)
2483 {
2484     constexpr uint8_t instanceId = 1;
2485     // Setup invalid transfer operation flag
2486     constexpr pldm_get_downstream_firmware_parameters_req params_req{
2487         0x0, PLDM_GET_FIRSTPART};
2488     constexpr size_t payload_length =
2489         PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES -
2490         1 /* inject erro length*/;
2491 
2492     std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
2493     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2494     auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2495 
2496     auto rc = encode_get_downstream_firmware_parameters_req(
2497         instanceId, &params_req, requestPtr, payload_length);
2498     EXPECT_EQ(rc, -EOVERFLOW);
2499 }
2500 
TEST(GetDownstreamFirmwareParameters,goodPathDecodeResponseOneEntry)2501 TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseOneEntry)
2502 {
2503     constexpr uint16_t downstreamDeviceCount = 1;
2504     constexpr uint8_t activeComponentVersionStringLength = 8;
2505     constexpr uint8_t pendingComponentVersionStringLength = 8;
2506     constexpr size_t downstreamDeviceParamTableLen =
2507         PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2508         activeComponentVersionStringLength +
2509         pendingComponentVersionStringLength;
2510     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2511     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2512     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2513     constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2514     constexpr size_t payload_len =
2515         PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2516         downstreamDeviceParamTableLen;
2517 
2518     PLDM_MSG_DEFINE_P(response, payload_len);
2519     PLDM_MSGBUF_DEFINE_P(buf);
2520     int rc = 0;
2521 
2522     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
2523     ASSERT_EQ(rc, 0);
2524 
2525     // Table 24
2526     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2527     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2528     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2529 
2530     // Table 25
2531     pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2532     pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2533 
2534     // Table 26
2535     pldm_msgbuf_insert_uint16(buf, 0);
2536 
2537     // - Active metadata
2538     pldm_msgbuf_insert_uint32(buf, 0);
2539     pldm_msgbuf_insert_uint8(buf, 1);
2540     pldm_msgbuf_insert_uint8(buf, activeComponentVersionStringLength);
2541     rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2542     ASSERT_EQ(rc, 0);
2543 
2544     // - Pending metadata
2545     pldm_msgbuf_insert_uint32(buf, 0);
2546     pldm_msgbuf_insert_uint8(buf, 1);
2547     pldm_msgbuf_insert_uint8(buf, pendingComponentVersionStringLength);
2548     rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2549     ASSERT_EQ(rc, 0);
2550 
2551     // - Methods and capabilities
2552     pldm_msgbuf_insert_uint16(buf, 1);
2553     pldm_msgbuf_insert_uint32(buf, 0);
2554 
2555     // - Version strings
2556     rc = pldm__msgbuf_insert_array_void(buf, activeComponentVersionStringLength,
2557                                         "abcdefgh", 8);
2558     ASSERT_EQ(rc, 0);
2559     rc = pldm__msgbuf_insert_array_void(
2560         buf, pendingComponentVersionStringLength, "zyxwvuts", 8);
2561     ASSERT_EQ(rc, 0);
2562 
2563     rc = pldm_msgbuf_complete_consumed(buf);
2564     ASSERT_EQ(rc, 0);
2565 
2566     struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2567     struct pldm_downstream_device_parameters_iter iter = {};
2568 
2569     rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2570                                                         &resp_data, &iter);
2571 
2572     ASSERT_EQ(rc, 0);
2573     EXPECT_EQ(resp_data.completion_code, completion_code_resp);
2574     EXPECT_EQ(resp_data.next_data_transfer_handle,
2575               next_data_transfer_handle_resp);
2576     EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2577     EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
2578 
2579     struct pldm_downstream_device_parameters_entry entry;
2580     size_t entries = 0;
2581     foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2582     {
2583         EXPECT_EQ(entry.downstream_device_index, 0);
2584         EXPECT_EQ(entry.active_comp_comparison_stamp, 0);
2585         EXPECT_EQ(entry.active_comp_ver_str_type, 1);
2586         EXPECT_EQ(entry.active_comp_ver_str_len,
2587                   activeComponentVersionStringLength);
2588         EXPECT_STREQ("20241206", entry.active_comp_release_date);
2589         EXPECT_EQ(entry.pending_comp_comparison_stamp, 0);
2590         EXPECT_EQ(entry.pending_comp_ver_str_type, 1);
2591         EXPECT_EQ(entry.pending_comp_ver_str_len,
2592                   pendingComponentVersionStringLength);
2593         EXPECT_STREQ("20241206", entry.pending_comp_release_date);
2594         EXPECT_EQ(entry.comp_activation_methods.value, 1);
2595         EXPECT_EQ(entry.capabilities_during_update.value, 0);
2596         EXPECT_FALSE(memcmp("abcdefgh", entry.active_comp_ver_str,
2597                             entry.active_comp_ver_str_len));
2598         EXPECT_FALSE(memcmp("zyxwvuts", entry.pending_comp_ver_str,
2599                             entry.pending_comp_ver_str_len));
2600         entries++;
2601     }
2602     EXPECT_EQ(rc, 0);
2603     EXPECT_EQ(entries, 1);
2604 }
2605 
TEST(GetDownstreamFirmwareParameters,goodPathDecodeResponseTwoEntries)2606 TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseTwoEntries)
2607 {
2608     /** Count is not fixed here taking it as 1, and the downstream device's
2609      *  version strings length are set to 8
2610      */
2611     constexpr uint16_t downstreamDeviceCount = 2;
2612     constexpr uint8_t activeComponentVersionStringLength = 8;
2613     constexpr uint8_t pendingComponentVersionStringLength = 9;
2614     constexpr size_t downstreamDeviceParamTableLen =
2615         static_cast<size_t>(downstreamDeviceCount *
2616                             (PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2617                              activeComponentVersionStringLength +
2618                              pendingComponentVersionStringLength));
2619     constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2620     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2621     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2622     constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2623     constexpr size_t payload_len =
2624         PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2625         downstreamDeviceParamTableLen;
2626 
2627     PLDM_MSG_DEFINE_P(response, payload_len);
2628     PLDM_MSGBUF_DEFINE_P(buf);
2629     int rc = 0;
2630 
2631     rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
2632     ASSERT_EQ(rc, 0);
2633 
2634     // Table 24
2635     pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2636     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2637     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2638 
2639     // Table 25
2640     pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2641     pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2642 
2643     constexpr const std::array<pldm_downstream_device_parameters_entry, 2>
2644         table = {{{
2645                       0,
2646                       0,
2647                       1,
2648                       8,
2649                       "20241206",
2650                       0,
2651                       1,
2652                       9,
2653                       "20241209",
2654                       {1},
2655                       {0},
2656                       "active_0",
2657                       "pending_0",
2658                   },
2659                   {
2660                       1,
2661                       0,
2662                       1,
2663                       8,
2664                       "20241209",
2665                       0,
2666                       1,
2667                       9,
2668                       "20241206",
2669                       {1},
2670                       {0},
2671                       "active_1",
2672                       "pending_1",
2673                   }}};
2674     for (const auto& e : table)
2675     {
2676         // Table 26
2677         pldm_msgbuf_insert_uint16(buf, e.downstream_device_index);
2678 
2679         // - Active metadata
2680         pldm_msgbuf_insert_uint32(buf, e.active_comp_comparison_stamp);
2681         pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_type);
2682         pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_len);
2683         rc = pldm__msgbuf_insert_array_void(buf, 8, &e.active_comp_release_date,
2684                                             sizeof(e.active_comp_release_date));
2685         ASSERT_EQ(rc, 0);
2686 
2687         // - Pending metadata
2688         pldm_msgbuf_insert_uint32(buf, e.pending_comp_comparison_stamp);
2689         pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_type);
2690         pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_len);
2691         rc =
2692             pldm__msgbuf_insert_array_void(buf, 8, e.pending_comp_release_date,
2693                                            sizeof(e.pending_comp_release_date));
2694         ASSERT_EQ(rc, 0);
2695 
2696         // - Methods and capabilities
2697         pldm_msgbuf_insert_uint16(buf, e.comp_activation_methods.value);
2698         pldm_msgbuf_insert_uint32(buf, e.capabilities_during_update.value);
2699 
2700         // - Version strings
2701         rc = pldm__msgbuf_insert_array_void(buf, e.active_comp_ver_str_len,
2702                                             e.active_comp_ver_str,
2703                                             e.active_comp_ver_str_len);
2704         ASSERT_EQ(rc, 0);
2705         rc = pldm__msgbuf_insert_array_void(buf, e.pending_comp_ver_str_len,
2706                                             e.pending_comp_ver_str,
2707                                             e.pending_comp_ver_str_len);
2708         ASSERT_EQ(rc, 0);
2709     }
2710 
2711     rc = pldm_msgbuf_complete_consumed(buf);
2712     ASSERT_EQ(rc, 0);
2713 
2714     struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2715     struct pldm_downstream_device_parameters_iter iter = {};
2716 
2717     rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2718                                                         &resp_data, &iter);
2719 
2720     ASSERT_EQ(rc, 0);
2721     EXPECT_EQ(resp_data.completion_code, completion_code_resp);
2722     EXPECT_EQ(resp_data.next_data_transfer_handle,
2723               next_data_transfer_handle_resp);
2724     EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2725     EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
2726 
2727     struct pldm_downstream_device_parameters_entry entry;
2728     size_t entryIndex = 0;
2729     foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2730     {
2731         ASSERT_LE(entryIndex, table.size());
2732 
2733         EXPECT_EQ(table[entryIndex].downstream_device_index,
2734                   entry.downstream_device_index);
2735         EXPECT_EQ(table[entryIndex].active_comp_comparison_stamp,
2736                   entry.active_comp_comparison_stamp);
2737         EXPECT_EQ(table[entryIndex].active_comp_ver_str_type,
2738                   entry.active_comp_ver_str_type);
2739         EXPECT_EQ(table[entryIndex].active_comp_ver_str_len,
2740                   entry.active_comp_ver_str_len);
2741         EXPECT_STREQ(&table[entryIndex].active_comp_release_date[0],
2742                      &entry.active_comp_release_date[0]);
2743         EXPECT_EQ(table[entryIndex].pending_comp_comparison_stamp,
2744                   entry.pending_comp_comparison_stamp);
2745         EXPECT_EQ(table[entryIndex].pending_comp_ver_str_type,
2746                   entry.pending_comp_ver_str_type);
2747         EXPECT_EQ(table[entryIndex].pending_comp_ver_str_len,
2748                   entry.pending_comp_ver_str_len);
2749         EXPECT_STREQ(&table[entryIndex].pending_comp_release_date[0],
2750                      &entry.pending_comp_release_date[0]);
2751         EXPECT_EQ(table[entryIndex].comp_activation_methods.value,
2752                   entry.comp_activation_methods.value);
2753         EXPECT_EQ(table[entryIndex].capabilities_during_update.value,
2754                   entry.capabilities_during_update.value);
2755         EXPECT_FALSE(memcmp(table[entryIndex].active_comp_ver_str,
2756                             entry.active_comp_ver_str,
2757                             table[entryIndex].active_comp_ver_str_len));
2758         EXPECT_FALSE(memcmp(table[entryIndex].pending_comp_ver_str,
2759                             entry.pending_comp_ver_str,
2760                             table[entryIndex].pending_comp_ver_str_len));
2761         entryIndex++;
2762     }
2763     EXPECT_EQ(rc, 0);
2764     EXPECT_EQ(entryIndex, table.size());
2765 }
2766 
TEST(GetDownstreamFirmwareParameters,decodeResponseInvalidLength)2767 TEST(GetDownstreamFirmwareParameters, decodeResponseInvalidLength)
2768 {
2769     /** Count is not fixed here taking it as 1, and the downstream device's
2770      *  version strings length are set to 8
2771      */
2772     constexpr uint16_t downstreamDeviceCount = 1;
2773     constexpr uint8_t activeComponentVersionStringLength = 8;
2774     constexpr uint8_t pendingComponentVersionStringLength = 8;
2775     constexpr size_t downstreamDeviceParamTableLen =
2776         PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2777         activeComponentVersionStringLength +
2778         pendingComponentVersionStringLength;
2779     constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2780     constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2781     constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2782     constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2783 
2784     std::array<uint8_t,
2785                hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2786                    downstreamDeviceParamTableLen - 1 /* inject error length*/>
2787         responseMsg{};
2788 
2789     int rc = 0;
2790 
2791     PLDM_MSGBUF_DEFINE_P(buf);
2792     rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
2793                                 responseMsg.size() - hdrSize);
2794     ASSERT_EQ(rc, 0);
2795 
2796     pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2797     pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2798     pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2799     pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2800     pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2801     ASSERT_EQ(pldm_msgbuf_complete(buf), 0);
2802 
2803     /** Filling paramter table, the correctness of the downstream devices data
2804      *  is not checked in this test case so filling with 0xff
2805      */
2806     std::fill_n(responseMsg.data() + hdrSize +
2807                     PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN,
2808                 downstreamDeviceParamTableLen - 1 /* inject error length*/,
2809                 0xff);
2810 
2811     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2812     auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
2813     struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2814     struct pldm_downstream_device_parameters_iter iter;
2815 
2816     rc = decode_get_downstream_firmware_parameters_resp(
2817         response, responseMsg.size() - hdrSize, &resp_data, &iter);
2818     EXPECT_EQ(rc, 0);
2819 
2820     struct pldm_downstream_device_parameters_entry entry;
2821     foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2822     {
2823         FAIL();
2824     }
2825     EXPECT_EQ(rc, -EOVERFLOW);
2826 }
2827 
TEST(RequestUpdate,goodPathEncodeRequest)2828 TEST(RequestUpdate, goodPathEncodeRequest)
2829 {
2830     constexpr uint8_t instanceId = 1;
2831     constexpr uint32_t maxTransferSize = 512;
2832     constexpr uint16_t numOfComp = 3;
2833     constexpr uint8_t maxOutstandingTransferReq = 2;
2834     constexpr uint16_t pkgDataLen = 0x1234;
2835     constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2836     constexpr uint8_t compImgSetVerStrLen =
2837         static_cast<uint8_t>(compImgSetVerStr.size());
2838     variable_field compImgSetVerStrInfo{};
2839     compImgSetVerStrInfo.ptr =
2840         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2841         reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2842     compImgSetVerStrInfo.length = compImgSetVerStrLen;
2843 
2844     std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2845                             compImgSetVerStrLen>
2846         request{};
2847     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2848     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2849 
2850     auto rc = encode_request_update_req(
2851         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2852         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2853         &compImgSetVerStrInfo, requestMsg,
2854         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2855     EXPECT_EQ(rc, PLDM_SUCCESS);
2856 
2857     std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2858                             compImgSetVerStrLen>
2859         outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00,
2860                    0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e,
2861                    0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30};
2862     EXPECT_EQ(request, outRequest);
2863 }
2864 
TEST(RequestUpdate,errorPathEncodeRequest)2865 TEST(RequestUpdate, errorPathEncodeRequest)
2866 {
2867     constexpr uint8_t instanceId = 1;
2868     uint32_t maxTransferSize = 512;
2869     constexpr uint16_t numOfComp = 3;
2870     uint8_t maxOutstandingTransferReq = 2;
2871     constexpr uint16_t pkgDataLen = 0x1234;
2872     constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2873     uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2874     variable_field compImgSetVerStrInfo{};
2875     compImgSetVerStrInfo.ptr =
2876         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2877         reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2878     compImgSetVerStrInfo.length = compImgSetVerStrLen;
2879 
2880     std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2881                             compImgSetVerStr.size()>
2882         request{};
2883     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2884     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2885 
2886     auto rc = encode_request_update_req(
2887         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2888         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr,
2889         requestMsg,
2890         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2891     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2892 
2893     compImgSetVerStrInfo.ptr = nullptr;
2894     rc = encode_request_update_req(
2895         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2896         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2897         &compImgSetVerStrInfo, requestMsg,
2898         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2899     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2900     compImgSetVerStrInfo.ptr =
2901         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2902         reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2903 
2904     rc = encode_request_update_req(
2905         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2906         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2907         &compImgSetVerStrInfo, nullptr,
2908         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2909     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2910 
2911     rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp,
2912                                    maxOutstandingTransferReq, pkgDataLen,
2913                                    PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2914                                    &compImgSetVerStrInfo, requestMsg, 0);
2915     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2916 
2917     compImgSetVerStrLen = 0;
2918     rc = encode_request_update_req(
2919         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2920         pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr,
2921         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2922     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2923     compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2924 
2925     compImgSetVerStrInfo.length = 0xffff;
2926     rc = encode_request_update_req(
2927         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2928         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2929         &compImgSetVerStrInfo, nullptr,
2930         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2931     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2932     compImgSetVerStrInfo.length = compImgSetVerStrLen;
2933 
2934     maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1;
2935     rc = encode_request_update_req(
2936         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2937         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2938         &compImgSetVerStrInfo, nullptr,
2939         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2940     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2941     maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE;
2942 
2943     maxOutstandingTransferReq = 0;
2944     rc = encode_request_update_req(
2945         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2946         pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2947         &compImgSetVerStrInfo, nullptr,
2948         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2949     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2950     maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ;
2951 
2952     rc = encode_request_update_req(
2953         instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2954         pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen,
2955         &compImgSetVerStrInfo, nullptr,
2956         sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2957     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2958 }
2959 
TEST(RequestUpdate,goodPathDecodeResponse)2960 TEST(RequestUpdate, goodPathDecodeResponse)
2961 {
2962     /* Test a success completion code */
2963     constexpr uint16_t fdMetaDataLen = 1024;
2964     constexpr uint8_t fdWillSendPkgData = 1;
2965     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)>
2966         requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01};
2967 
2968     auto responseMsg1 =
2969         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2970         reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data());
2971     uint8_t outCompletionCode = 0;
2972     uint16_t outFdMetaDataLen = 0;
2973     uint8_t outFdWillSendPkgData = 0;
2974 
2975     auto rc = decode_request_update_resp(
2976         responseMsg1, requestUpdateResponse1.size() - hdrSize,
2977         &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2978     EXPECT_EQ(rc, PLDM_SUCCESS);
2979     EXPECT_EQ(outCompletionCode, PLDM_SUCCESS);
2980     EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen);
2981     EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData);
2982 
2983 #ifdef LIBPLDM_API_TESTING
2984     /* Check the success roundtrip matches */
2985     PLDM_MSG_DEFINE_P(enc, 1000);
2986     size_t enc_payload_len = 1000;
2987     const struct pldm_request_update_resp resp_data = {
2988         .completion_code = PLDM_SUCCESS,
2989         .fd_meta_data_len = outFdMetaDataLen,
2990         .fd_will_send_pkg_data = outFdWillSendPkgData,
2991     };
2992     rc = encode_request_update_resp(FIXED_INSTANCE_ID, &resp_data, enc,
2993                                     &enc_payload_len);
2994     EXPECT_EQ(rc, PLDM_SUCCESS);
2995     EXPECT_EQ(enc_payload_len + hdrSize, requestUpdateResponse1.size());
2996     EXPECT_TRUE(std::equal(requestUpdateResponse1.begin() + hdrSize,
2997                            requestUpdateResponse1.end(), enc_buf + hdrSize));
2998     check_response(enc, PLDM_REQUEST_UPDATE);
2999 #endif
3000 
3001     /* Test a failure completion code */
3002     outCompletionCode = 0;
3003     outFdMetaDataLen = 0;
3004     outFdWillSendPkgData = 0;
3005 
3006     constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)>
3007         requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
3008     auto responseMsg2 =
3009         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3010         reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data());
3011     rc = decode_request_update_resp(
3012         responseMsg2, requestUpdateResponse2.size() - hdrSize,
3013         &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
3014     EXPECT_EQ(rc, PLDM_SUCCESS);
3015     EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
3016 }
3017 
TEST(RequestUpdate,errorPathDecodeResponse)3018 TEST(RequestUpdate, errorPathDecodeResponse)
3019 {
3020     constexpr std::array<uint8_t,
3021                          hdrSize + sizeof(pldm_request_update_resp) - 1>
3022         requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
3023 
3024     auto responseMsg =
3025         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3026         reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data());
3027     uint8_t outCompletionCode = 0;
3028     uint16_t outFdMetaDataLen = 0;
3029     uint8_t outFdWillSendPkgData = 0;
3030 
3031     auto rc = decode_request_update_resp(
3032         nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3033         &outFdMetaDataLen, &outFdWillSendPkgData);
3034     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3035 
3036     rc = decode_request_update_resp(
3037         responseMsg, requestUpdateResponse.size() - hdrSize, nullptr,
3038         &outFdMetaDataLen, &outFdWillSendPkgData);
3039     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3040 
3041     rc = decode_request_update_resp(
3042         responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3043         nullptr, &outFdWillSendPkgData);
3044     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3045 
3046     rc = decode_request_update_resp(
3047         responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3048         &outFdMetaDataLen, nullptr);
3049     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3050 
3051     rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode,
3052                                     &outFdMetaDataLen, &outFdWillSendPkgData);
3053     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3054 
3055     rc = decode_request_update_resp(
3056         responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3057         &outFdMetaDataLen, &outFdWillSendPkgData);
3058     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3059 }
3060 
3061 #ifdef LIBPLDM_API_TESTING
TEST(RequestDownstreamDeviceUpdate,goodPathEncodeRequest)3062 TEST(RequestDownstreamDeviceUpdate, goodPathEncodeRequest)
3063 {
3064     constexpr uint8_t instanceId = 1;
3065 
3066     std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES>
3067         request{};
3068 
3069     auto requestMsg = new (request.data()) pldm_msg;
3070 
3071     constexpr struct pldm_request_downstream_device_update_req req_data = {
3072         .maximum_downstream_device_transfer_size = 512,
3073         .maximum_outstanding_transfer_requests = 2,
3074         .downstream_device_package_data_length = 0x1234,
3075     };
3076     size_t enc_payload_len = PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES;
3077 
3078     auto rc = encode_request_downstream_device_update_req(
3079         instanceId, &req_data, requestMsg, &enc_payload_len);
3080 
3081     EXPECT_EQ(rc, 0);
3082 
3083     std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES>
3084         outRequest{0x81, 0x05, 0x20, 0x00, 0x02, 0x00, 0x00, 0x02, 0x34, 0x12};
3085     EXPECT_EQ(request, outRequest);
3086 }
3087 #endif // LIBPLDM_API_TESTING
3088 
3089 #ifdef LIBPLDM_API_TESTING
TEST(RequestDownstreamDeviceUpdate,errorPathEncodeRequest)3090 TEST(RequestDownstreamDeviceUpdate, errorPathEncodeRequest)
3091 {
3092     constexpr uint8_t instanceId = 1;
3093     size_t enc_payload_len = PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES;
3094 
3095     std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES>
3096         request{};
3097 
3098     struct pldm_request_downstream_device_update_req req_data = {
3099         .maximum_downstream_device_transfer_size = 512,
3100         .maximum_outstanding_transfer_requests = 2,
3101         .downstream_device_package_data_length = 0x1234,
3102     };
3103 
3104     auto requestMsg = new (request.data()) pldm_msg;
3105 
3106     auto rc = encode_request_downstream_device_update_req(
3107         instanceId, nullptr, requestMsg, &enc_payload_len);
3108     EXPECT_EQ(rc, -EINVAL);
3109     rc = encode_request_downstream_device_update_req(
3110         instanceId, &req_data, requestMsg, &enc_payload_len);
3111     EXPECT_EQ(rc, 0);
3112 
3113     rc = encode_request_downstream_device_update_req(instanceId, &req_data,
3114                                                      nullptr, &enc_payload_len);
3115     EXPECT_EQ(rc, -EINVAL);
3116     rc = encode_request_downstream_device_update_req(
3117         instanceId, &req_data, requestMsg, &enc_payload_len);
3118     EXPECT_EQ(rc, 0);
3119 
3120     rc = encode_request_downstream_device_update_req(instanceId, &req_data,
3121                                                      requestMsg, nullptr);
3122     EXPECT_EQ(rc, -EINVAL);
3123     rc = encode_request_downstream_device_update_req(
3124         instanceId, &req_data, requestMsg, &enc_payload_len);
3125     EXPECT_EQ(rc, 0);
3126 
3127     enc_payload_len =
3128         static_cast<size_t>(PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES) - 1;
3129     rc = encode_request_downstream_device_update_req(
3130         instanceId, &req_data, requestMsg, &enc_payload_len);
3131     EXPECT_EQ(rc, -EOVERFLOW);
3132     enc_payload_len =
3133         static_cast<size_t>(PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES);
3134     rc = encode_request_downstream_device_update_req(
3135         instanceId, &req_data, requestMsg, &enc_payload_len);
3136     EXPECT_EQ(rc, 0);
3137 
3138     req_data.maximum_downstream_device_transfer_size = 31;
3139     rc = encode_request_downstream_device_update_req(
3140         instanceId, &req_data, requestMsg, &enc_payload_len);
3141     EXPECT_EQ(rc, -EINVAL);
3142     req_data.maximum_downstream_device_transfer_size =
3143         PLDM_FWUP_BASELINE_TRANSFER_SIZE;
3144 
3145     req_data.maximum_outstanding_transfer_requests = 0;
3146     rc = encode_request_downstream_device_update_req(
3147         instanceId, &req_data, requestMsg, &enc_payload_len);
3148     EXPECT_EQ(rc, -EINVAL);
3149     req_data.maximum_outstanding_transfer_requests = 2;
3150     rc = encode_request_downstream_device_update_req(
3151         instanceId, &req_data, requestMsg, &enc_payload_len);
3152     EXPECT_EQ(rc, 0);
3153 }
3154 #endif // LIBPLDM_API_TESTING
3155 
3156 #ifdef LIBPLDM_API_TESTING
TEST(RequestDownstreamDeviceUpdate,goodPathDecodeResponse)3157 TEST(RequestDownstreamDeviceUpdate, goodPathDecodeResponse)
3158 {
3159     /* Test a success completion code */
3160     constexpr uint16_t ddMetaDataLen = 1024;
3161     constexpr uint8_t ddWillSendPkgData = 1;
3162     constexpr uint16_t getPkgDataMaxTransferSize = 512;
3163     std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES>
3164         requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00,
3165                                0x04, 0x01, 0x00, 0x02};
3166 
3167     auto responseMsg1 = new (requestUpdateResponse1.data()) pldm_msg;
3168 
3169     struct pldm_request_downstream_device_update_resp resp_data1 = {
3170         .completion_code = 0,
3171         .downstream_device_meta_data_length = 0,
3172         .downstream_device_will_send_get_package_data = 0,
3173         .get_package_data_maximum_transfer_size = 0};
3174 
3175     auto rc = decode_request_downstream_device_update_resp(
3176         responseMsg1, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES,
3177         &resp_data1);
3178     EXPECT_EQ(rc, 0);
3179     EXPECT_EQ(resp_data1.completion_code, PLDM_SUCCESS);
3180     EXPECT_EQ(resp_data1.downstream_device_meta_data_length, ddMetaDataLen);
3181     EXPECT_EQ(resp_data1.downstream_device_will_send_get_package_data,
3182               ddWillSendPkgData);
3183     EXPECT_EQ(resp_data1.get_package_data_maximum_transfer_size,
3184               getPkgDataMaxTransferSize);
3185 
3186     /* Test a failure completion code */
3187     std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES>
3188         requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
3189 
3190     auto responseMsg2 = new (requestUpdateResponse2.data()) pldm_msg;
3191 
3192     struct pldm_request_downstream_device_update_resp resp_data2 = {
3193         .completion_code = 0,
3194         .downstream_device_meta_data_length = 0,
3195         .downstream_device_will_send_get_package_data = 0,
3196         .get_package_data_maximum_transfer_size = 0};
3197 
3198     rc = decode_request_downstream_device_update_resp(
3199         responseMsg2, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES,
3200         &resp_data2);
3201     EXPECT_EQ(rc, 0);
3202     EXPECT_EQ(resp_data2.completion_code, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
3203 }
3204 #endif // LIBPLDM_API_TESTING
3205 
3206 #ifdef LIBPLDM_API_TESTING
TEST(RequestDownstreamDeviceUpdate,errorPathDecodeResponse)3207 TEST(RequestDownstreamDeviceUpdate, errorPathDecodeResponse)
3208 {
3209     std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES>
3210         requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00,
3211                               0x04, 0x01, 0x00, 0x02};
3212 
3213     auto responseMsg = new (requestUpdateResponse.data()) pldm_msg;
3214 
3215     struct pldm_request_downstream_device_update_resp resp_data = {
3216         .completion_code = 0,
3217         .downstream_device_meta_data_length = 0,
3218         .downstream_device_will_send_get_package_data = 0,
3219         .get_package_data_maximum_transfer_size = 0};
3220 
3221     auto rc = decode_request_downstream_device_update_resp(
3222         nullptr, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES, &resp_data);
3223     EXPECT_EQ(rc, -EINVAL);
3224 
3225     rc = decode_request_downstream_device_update_resp(
3226         responseMsg, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES, nullptr);
3227     EXPECT_EQ(rc, -EINVAL);
3228 
3229     rc = decode_request_downstream_device_update_resp(responseMsg, 0,
3230                                                       &resp_data);
3231     EXPECT_EQ(rc, -EOVERFLOW);
3232 }
3233 #endif // LIBPLDM_API_TESTING
3234 
TEST(PassComponentTable,goodPathEncodeRequest)3235 TEST(PassComponentTable, goodPathEncodeRequest)
3236 {
3237     constexpr uint8_t instanceId = 1;
3238     constexpr uint16_t compIdentifier = 400;
3239     constexpr uint8_t compClassificationIndex = 40;
3240     constexpr uint32_t compComparisonStamp = 0x12345678;
3241     constexpr std::string_view compVerStr = "0penBmcv1.1";
3242     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3243     variable_field compVerStrInfo{};
3244     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3245     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3246     compVerStrInfo.length = compVerStrLen;
3247 
3248     std::array<uint8_t,
3249                hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
3250         request{};
3251     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3252     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3253 
3254     auto rc = encode_pass_component_table_req(
3255         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3256         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3257         compVerStrLen, &compVerStrInfo, requestMsg,
3258         sizeof(pldm_pass_component_table_req) + compVerStrLen);
3259     EXPECT_EQ(rc, PLDM_SUCCESS);
3260 
3261     std::array<uint8_t,
3262                hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
3263         outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28,
3264                    0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65,
3265                    0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31};
3266     EXPECT_EQ(request, outRequest);
3267 
3268 #ifdef LIBPLDM_API_TESTING
3269     /* Check the roundtrip */
3270     struct pldm_pass_component_table_req_full req;
3271     PLDM_MSG_DEFINE_P(dec, outRequest.size());
3272     std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3273     rc =
3274         decode_pass_component_table_req(dec, outRequest.size() - hdrSize, &req);
3275     ASSERT_EQ(rc, 0);
3276 
3277     EXPECT_EQ(req.transfer_flag, PLDM_START_AND_END);
3278     EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3279     EXPECT_EQ(req.comp_identifier, compIdentifier);
3280     EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3281     EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3282     EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3283     EXPECT_EQ(req.version.str_len, compVerStrLen);
3284     EXPECT_TRUE(std::equal(req.version.str_data,
3285                            req.version.str_data + req.version.str_len,
3286                            compVerStr.data()));
3287 #endif
3288 }
3289 
TEST(PassComponentTable,errorPathEncodeRequest)3290 TEST(PassComponentTable, errorPathEncodeRequest)
3291 {
3292     constexpr uint8_t instanceId = 1;
3293     constexpr uint16_t compIdentifier = 400;
3294     constexpr uint8_t compClassificationIndex = 40;
3295     constexpr uint32_t compComparisonStamp = 0x12345678;
3296     constexpr std::string_view compVerStr = "0penBmcv1.1";
3297     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3298     variable_field compVerStrInfo{};
3299     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3300     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3301     compVerStrInfo.length = compVerStrLen;
3302 
3303     std::array<uint8_t,
3304                hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
3305         request{};
3306     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3307     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3308 
3309     auto rc = encode_pass_component_table_req(
3310         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3311         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3312         compVerStrLen, nullptr, requestMsg,
3313         sizeof(pldm_pass_component_table_req) + compVerStrLen);
3314     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3315 
3316     compVerStrInfo.ptr = nullptr;
3317     rc = encode_pass_component_table_req(
3318         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3319         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3320         compVerStrLen, &compVerStrInfo, requestMsg,
3321         sizeof(pldm_pass_component_table_req) + compVerStrLen);
3322     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3323     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3324     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3325 
3326     rc = encode_pass_component_table_req(
3327         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3328         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3329         compVerStrLen, &compVerStrInfo, nullptr,
3330         sizeof(pldm_pass_component_table_req) + compVerStrLen);
3331     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3332 
3333     rc = encode_pass_component_table_req(
3334         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3335         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3336         compVerStrLen, &compVerStrInfo, requestMsg,
3337         sizeof(pldm_pass_component_table_req));
3338     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3339 
3340     rc = encode_pass_component_table_req(
3341         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3342         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0,
3343         &compVerStrInfo, requestMsg,
3344         sizeof(pldm_pass_component_table_req) + compVerStrLen);
3345     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3346 
3347     rc = encode_pass_component_table_req(
3348         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3349         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3350         compVerStrLen - 1, &compVerStrInfo, requestMsg,
3351         sizeof(pldm_pass_component_table_req) + compVerStrLen);
3352     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3353 
3354     rc = encode_pass_component_table_req(
3355         instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier,
3356         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3357         compVerStrLen, &compVerStrInfo, requestMsg,
3358         sizeof(pldm_pass_component_table_req) + compVerStrLen);
3359     EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_OPERATION_FLAG);
3360 
3361     rc = encode_pass_component_table_req(
3362         instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3363         compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN,
3364         compVerStrLen, &compVerStrInfo, requestMsg,
3365         sizeof(pldm_pass_component_table_req) + compVerStrLen);
3366     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3367 }
3368 
TEST(PassComponentTable,goodPathDecodeResponse)3369 TEST(PassComponentTable, goodPathDecodeResponse)
3370 {
3371     constexpr std::array<uint8_t,
3372                          hdrSize + sizeof(pldm_pass_component_table_resp)>
3373         passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
3374     auto responseMsg1 =
3375         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3376         reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3377 
3378     uint8_t completionCode = 0;
3379     uint8_t compResp = 0;
3380     uint8_t compRespCode = 0;
3381 
3382     auto rc = decode_pass_component_table_resp(
3383         responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode,
3384         &compResp, &compRespCode);
3385 
3386     EXPECT_EQ(rc, PLDM_SUCCESS);
3387     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3388     EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3389     EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL);
3390 
3391     constexpr std::array<uint8_t,
3392                          hdrSize + sizeof(pldm_pass_component_table_resp)>
3393         passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0};
3394     auto responseMsg2 =
3395         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3396         reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3397     rc = decode_pass_component_table_resp(
3398         responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3399         &compResp, &compRespCode);
3400 
3401     EXPECT_EQ(rc, PLDM_SUCCESS);
3402     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3403     EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3404     EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN);
3405 
3406     constexpr std::array<uint8_t,
3407                          hdrSize + sizeof(pldm_pass_component_table_resp)>
3408         passCompTableResponse3{0x00, 0x00, 0x00, 0x80};
3409     auto responseMsg3 =
3410         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3411         reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3412 
3413     rc = decode_pass_component_table_resp(
3414         responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3415         &compResp, &compRespCode);
3416 
3417     EXPECT_EQ(rc, PLDM_SUCCESS);
3418     EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3419 }
3420 
TEST(PassComponentTable,errorPathDecodeResponse)3421 TEST(PassComponentTable, errorPathDecodeResponse)
3422 {
3423     constexpr std::array<uint8_t,
3424                          hdrSize + sizeof(pldm_pass_component_table_resp) - 1>
3425         passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00};
3426     auto responseMsg1 =
3427         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3428         reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3429 
3430     uint8_t completionCode = 0;
3431     uint8_t compResp = 0;
3432     uint8_t compRespCode = 0;
3433 
3434     auto rc = decode_pass_component_table_resp(
3435         nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode,
3436         &compResp, &compRespCode);
3437     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3438 
3439     rc = decode_pass_component_table_resp(
3440         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr,
3441         &compResp, &compRespCode);
3442     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3443 
3444     rc = decode_pass_component_table_resp(
3445         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3446         &completionCode, nullptr, &compRespCode);
3447     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3448 
3449     rc = decode_pass_component_table_resp(
3450         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3451         &completionCode, &compResp, nullptr);
3452     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3453 
3454     rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode,
3455                                           &compResp, &compRespCode);
3456     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3457 
3458     rc = decode_pass_component_table_resp(
3459         responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3460         &completionCode, &compResp, &compRespCode);
3461     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3462 
3463     constexpr std::array<uint8_t,
3464                          hdrSize + sizeof(pldm_pass_component_table_resp)>
3465         passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
3466     auto responseMsg2 =
3467         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3468         reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3469     rc = decode_pass_component_table_resp(
3470         responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3471         &compResp, &compRespCode);
3472     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3473 
3474     constexpr std::array<uint8_t,
3475                          hdrSize + sizeof(pldm_pass_component_table_resp)>
3476         passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};
3477     auto responseMsg3 =
3478         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3479         reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3480     rc = decode_pass_component_table_resp(
3481         responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3482         &compResp, &compRespCode);
3483     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3484 
3485     constexpr std::array<uint8_t,
3486                          hdrSize + sizeof(pldm_pass_component_table_resp)>
3487         passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
3488     auto responseMsg4 =
3489         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3490         reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data());
3491     rc = decode_pass_component_table_resp(
3492         responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode,
3493         &compResp, &compRespCode);
3494     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3495 }
3496 
TEST(UpdateComponent,goodPathEncodeRequest)3497 TEST(UpdateComponent, goodPathEncodeRequest)
3498 {
3499     constexpr uint8_t instanceId = 2;
3500     constexpr uint16_t compIdentifier = 500;
3501     constexpr uint8_t compClassificationIndex = 50;
3502     constexpr uint32_t compComparisonStamp = 0x89abcdef;
3503     constexpr uint32_t compImageSize = 4096;
3504     constexpr bitfield32_t updateOptionFlags{1};
3505     constexpr std::string_view compVerStr = "OpenBmcv2.2";
3506     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3507     variable_field compVerStrInfo{};
3508     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3509     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3510     compVerStrInfo.length = compVerStrLen;
3511 
3512     std::array<uint8_t,
3513                hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3514         request{};
3515     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3516     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3517 
3518     auto rc = encode_update_component_req(
3519         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3520         compComparisonStamp, compImageSize, updateOptionFlags,
3521         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3522         sizeof(pldm_update_component_req) + compVerStrLen);
3523     EXPECT_EQ(rc, PLDM_SUCCESS);
3524 
3525     std::array<uint8_t,
3526                hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3527         outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
3528                    0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
3529                    0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
3530                    0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
3531     EXPECT_EQ(request, outRequest);
3532 
3533 #ifdef LIBPLDM_API_TESTING
3534     /* Check the roundtrip */
3535     struct pldm_update_component_req_full req;
3536     PLDM_MSG_DEFINE_P(dec, outRequest.size());
3537     std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3538     rc = decode_update_component_req(dec, outRequest.size() - hdrSize, &req);
3539     ASSERT_EQ(rc, 0);
3540 
3541     EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3542     EXPECT_EQ(req.comp_identifier, compIdentifier);
3543     EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3544     EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3545     EXPECT_EQ(req.comp_image_size, compImageSize);
3546     EXPECT_EQ(req.update_option_flags.value, updateOptionFlags.value);
3547     EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3548     EXPECT_EQ(req.version.str_len, compVerStrLen);
3549     EXPECT_TRUE(std::equal(req.version.str_data,
3550                            req.version.str_data + req.version.str_len,
3551                            compVerStr.data()));
3552 #endif
3553 }
3554 
TEST(UpdateComponent,errorPathEncodeRequest)3555 TEST(UpdateComponent, errorPathEncodeRequest)
3556 {
3557     constexpr uint8_t instanceId = 2;
3558     constexpr uint16_t compIdentifier = 500;
3559     constexpr uint8_t compClassificationIndex = 50;
3560     constexpr uint32_t compComparisonStamp = 0x89abcdef;
3561     constexpr uint32_t compImageSize = 4096;
3562     constexpr bitfield32_t updateOptionFlags{1};
3563     constexpr std::string_view compVerStr = "OpenBmcv2.2";
3564     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3565     variable_field compVerStrInfo{};
3566     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3567     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3568     compVerStrInfo.length = compVerStrLen;
3569 
3570     std::array<uint8_t,
3571                hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3572         request{};
3573     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3574     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3575 
3576     auto rc = encode_update_component_req(
3577         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3578         compComparisonStamp, compImageSize, updateOptionFlags,
3579         PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
3580         sizeof(pldm_update_component_req) + compVerStrLen);
3581     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3582 
3583     compVerStrInfo.ptr = nullptr;
3584     rc = encode_update_component_req(
3585         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3586         compComparisonStamp, compImageSize, updateOptionFlags,
3587         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3588         sizeof(pldm_update_component_req) + compVerStrLen);
3589     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3590     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3591     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3592 
3593     rc = encode_update_component_req(
3594         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3595         compComparisonStamp, compImageSize, updateOptionFlags,
3596         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
3597         sizeof(pldm_update_component_req) + compVerStrLen);
3598     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3599 
3600     rc = encode_update_component_req(
3601         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3602         compComparisonStamp, compImageSize, updateOptionFlags,
3603         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3604         sizeof(pldm_update_component_req));
3605     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3606 
3607     rc = encode_update_component_req(
3608         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3609         compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
3610         compVerStrLen, &compVerStrInfo, requestMsg,
3611         sizeof(pldm_update_component_req) + compVerStrLen);
3612     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3613 
3614     rc = encode_update_component_req(
3615         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3616         compComparisonStamp, compImageSize, updateOptionFlags,
3617         PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg,
3618         sizeof(pldm_update_component_req) + compVerStrLen);
3619     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3620 
3621     rc = encode_update_component_req(
3622         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3623         compComparisonStamp, compImageSize, updateOptionFlags,
3624         PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg,
3625         sizeof(pldm_update_component_req) + compVerStrLen);
3626     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3627 
3628     rc = encode_update_component_req(
3629         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3630         compComparisonStamp, compImageSize, updateOptionFlags,
3631         PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
3632         sizeof(pldm_update_component_req) + compVerStrLen);
3633     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3634 }
3635 
TEST(UpdateComponent,goodPathDecodeResponse)3636 TEST(UpdateComponent, goodPathDecodeResponse)
3637 {
3638     constexpr std::bitset<32> forceUpdateComp{1};
3639     constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
3640     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3641         updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3642                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3643     auto responseMsg1 =
3644         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3645         reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3646 
3647     uint8_t completionCode = 0;
3648     uint8_t compCompatibilityResp = 0;
3649     uint8_t compCompatibilityRespCode = 0;
3650     bitfield32_t updateOptionFlagsEnabled{};
3651     uint16_t timeBeforeReqFWData = 0;
3652 
3653     auto rc = decode_update_component_resp(
3654         responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
3655         &compCompatibilityResp, &compCompatibilityRespCode,
3656         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3657 
3658     EXPECT_EQ(rc, PLDM_SUCCESS);
3659     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3660     EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
3661     EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
3662     EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
3663     EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
3664 
3665     constexpr std::bitset<32> noFlags{};
3666     constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
3667     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3668         updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3669                                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3670     auto responseMsg2 =
3671         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3672         reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3673     rc = decode_update_component_resp(
3674         responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3675         &compCompatibilityResp, &compCompatibilityRespCode,
3676         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3677 
3678     EXPECT_EQ(rc, PLDM_SUCCESS);
3679     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3680     EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
3681     EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
3682     EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
3683     EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
3684 
3685     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3686         updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
3687     auto responseMsg3 =
3688         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3689         reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3690 
3691     rc = decode_update_component_resp(
3692         responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3693         &compCompatibilityResp, &compCompatibilityRespCode,
3694         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3695 
3696     EXPECT_EQ(rc, PLDM_SUCCESS);
3697     EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3698 }
3699 
TEST(UpdateComponent,errorPathDecodeResponse)3700 TEST(UpdateComponent, errorPathDecodeResponse)
3701 {
3702     constexpr std::array<uint8_t,
3703                          hdrSize + sizeof(pldm_update_component_resp) - 1>
3704         updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3705                                  0x00, 0x00, 0x00, 0x00, 0x00};
3706     auto responseMsg1 =
3707         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3708         reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3709 
3710     uint8_t completionCode = 0;
3711     uint8_t compCompatibilityResp = 0;
3712     uint8_t compCompatibilityRespCode = 0;
3713     bitfield32_t updateOptionFlagsEnabled{};
3714     uint16_t timeBeforeReqFWData = 0;
3715 
3716     auto rc = decode_update_component_resp(
3717         nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
3718         &compCompatibilityResp, &compCompatibilityRespCode,
3719         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3720     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3721 
3722     rc = decode_update_component_resp(
3723         responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
3724         &compCompatibilityResp, &compCompatibilityRespCode,
3725         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3726     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3727 
3728     rc = decode_update_component_resp(
3729         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3730         nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3731         &timeBeforeReqFWData);
3732     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3733 
3734     rc = decode_update_component_resp(
3735         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3736         &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
3737         &timeBeforeReqFWData);
3738     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3739 
3740     rc = decode_update_component_resp(
3741         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3742         &compCompatibilityResp, &compCompatibilityRespCode, nullptr,
3743         &timeBeforeReqFWData);
3744     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3745 
3746     rc = decode_update_component_resp(
3747         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3748         &compCompatibilityResp, &compCompatibilityRespCode,
3749         &updateOptionFlagsEnabled, nullptr);
3750     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3751 
3752     rc = decode_update_component_resp(
3753         responseMsg1, 0, &completionCode, &compCompatibilityResp,
3754         &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3755         &timeBeforeReqFWData);
3756     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3757 
3758     rc = decode_update_component_resp(
3759         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3760         &compCompatibilityResp, &compCompatibilityRespCode,
3761         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3762     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3763 
3764     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3765         updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
3766                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3767     auto responseMsg2 =
3768         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3769         reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3770     rc = decode_update_component_resp(
3771         responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3772         &compCompatibilityResp, &compCompatibilityRespCode,
3773         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3774     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3775 
3776     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3777         updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
3778                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3779     auto responseMsg3 =
3780         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3781         reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3782     rc = decode_update_component_resp(
3783         responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3784         &compCompatibilityResp, &compCompatibilityRespCode,
3785         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3786     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3787 
3788     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3789         updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
3790                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3791     auto responseMsg4 =
3792         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3793         reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
3794     rc = decode_update_component_resp(
3795         responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
3796         &compCompatibilityResp, &compCompatibilityRespCode,
3797         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3798     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3799 }
3800 
TEST(RequestFirmwareData,goodPathDecodeRequest)3801 TEST(RequestFirmwareData, goodPathDecodeRequest)
3802 {
3803     constexpr uint32_t offset = 300;
3804     constexpr uint32_t length = 255;
3805     constexpr std::array<uint8_t,
3806                          hdrSize + sizeof(pldm_request_firmware_data_req)>
3807         reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3808                      0x00, 0xff, 0x00, 0x00, 0x00};
3809     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3810     auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3811 
3812     uint32_t outOffset = 0;
3813     uint32_t outLength = 0;
3814     auto rc = decode_request_firmware_data_req(
3815         requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3816         &outLength);
3817 
3818     EXPECT_EQ(rc, PLDM_SUCCESS);
3819     EXPECT_EQ(outOffset, offset);
3820     EXPECT_EQ(outLength, length);
3821 }
3822 
TEST(RequestFirmwareData,errorPathDecodeRequest)3823 TEST(RequestFirmwareData, errorPathDecodeRequest)
3824 {
3825     constexpr std::array<uint8_t,
3826                          hdrSize + sizeof(pldm_request_firmware_data_req)>
3827         reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3828                      0x00, 0x1f, 0x00, 0x00, 0x00};
3829     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3830     auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3831 
3832     uint32_t outOffset = 0;
3833     uint32_t outLength = 0;
3834     auto rc = decode_request_firmware_data_req(
3835         nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
3836         &outLength);
3837     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3838 
3839     rc = decode_request_firmware_data_req(
3840         requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
3841         &outLength);
3842     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3843 
3844     rc = decode_request_firmware_data_req(
3845         requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3846         nullptr);
3847     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3848 
3849     rc = decode_request_firmware_data_req(
3850         requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
3851         &outLength);
3852     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3853 
3854     rc = decode_request_firmware_data_req(
3855         requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3856         &outLength);
3857     EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
3858 }
3859 
TEST(RequestFirmwareData,goodPathEncodeResponse)3860 TEST(RequestFirmwareData, goodPathEncodeResponse)
3861 {
3862     constexpr uint8_t instanceId = 3;
3863     constexpr uint8_t completionCode = PLDM_SUCCESS;
3864     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
3865                                       PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3866         outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
3867                               0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3868                               0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3869                               0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3870                               0x1d, 0x1e, 0x1f, 0x20};
3871     std::array<uint8_t, hdrSize + sizeof(completionCode) +
3872                             PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3873         reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
3874                            0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3875                            0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3876                            0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3877                            0x1d, 0x1e, 0x1f, 0x20};
3878     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3879     auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
3880     auto rc = encode_request_firmware_data_resp(
3881         instanceId, completionCode, responseMsg1,
3882         sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
3883     EXPECT_EQ(rc, PLDM_SUCCESS);
3884     EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
3885 
3886     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3887         outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
3888     std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
3889         0x00, 0x00, 0x00, 0x00};
3890     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3891     auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
3892     rc = encode_request_firmware_data_resp(
3893         instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
3894         sizeof(completionCode));
3895     EXPECT_EQ(rc, PLDM_SUCCESS);
3896     EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
3897 }
3898 
TEST(RequestFirmwareData,errorPathEncodeResponse)3899 TEST(RequestFirmwareData, errorPathEncodeResponse)
3900 {
3901     std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
3902     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3903     auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
3904     auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
3905     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3906 
3907     rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
3908     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3909 }
3910 
TEST(TransferComplete,goodPathDecodeRequest)3911 TEST(TransferComplete, goodPathDecodeRequest)
3912 {
3913     constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
3914     constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3915         transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
3916     auto requestMsg1 =
3917         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3918         reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
3919     uint8_t outTransferResult = 0;
3920 
3921     auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
3922                                            &outTransferResult);
3923     EXPECT_EQ(rc, PLDM_SUCCESS);
3924     EXPECT_EQ(outTransferResult, transferResult);
3925 
3926     constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3927         transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
3928     auto requestMsg2 =
3929         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3930         reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
3931     rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
3932                                       &outTransferResult);
3933     EXPECT_EQ(rc, PLDM_SUCCESS);
3934     EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
3935 }
3936 
TEST(TransferComplete,errorPathDecodeRequest)3937 TEST(TransferComplete, errorPathDecodeRequest)
3938 {
3939     constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
3940                                                                0x00};
3941     auto requestMsg =
3942         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3943         reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
3944     uint8_t outTransferResult = 0;
3945 
3946     auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
3947     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3948 
3949     rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
3950     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3951 
3952     rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
3953     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3954 }
3955 
TEST(TransferComplete,goodPathEncodeResponse)3956 TEST(TransferComplete, goodPathEncodeResponse)
3957 {
3958     constexpr uint8_t instanceId = 4;
3959     constexpr uint8_t completionCode = PLDM_SUCCESS;
3960     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3961         outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
3962     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3963         transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3964     auto responseMsg1 =
3965         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3966         reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
3967     auto rc = encode_transfer_complete_resp(
3968         instanceId, completionCode, responseMsg1, sizeof(completionCode));
3969     EXPECT_EQ(rc, PLDM_SUCCESS);
3970     EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
3971 
3972     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3973         outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
3974     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3975         transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3976     auto responseMsg2 =
3977         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3978         reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
3979     rc = encode_transfer_complete_resp(instanceId,
3980                                        PLDM_FWUP_COMMAND_NOT_EXPECTED,
3981                                        responseMsg2, sizeof(completionCode));
3982     EXPECT_EQ(rc, PLDM_SUCCESS);
3983     EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
3984 }
3985 
TEST(TransferComplete,errorPathEncodeResponse)3986 TEST(TransferComplete, errorPathEncodeResponse)
3987 {
3988     std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
3989     auto responseMsg =
3990         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3991         reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
3992     auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3993     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3994 
3995     rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3996     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3997 }
3998 
TEST(VerifyComplete,goodPathDecodeRequest)3999 TEST(VerifyComplete, goodPathDecodeRequest)
4000 {
4001     constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
4002     constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
4003         verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
4004     auto requestMsg1 =
4005         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4006         reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
4007     uint8_t outVerifyResult = 0;
4008 
4009     auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
4010                                          &outVerifyResult);
4011     EXPECT_EQ(rc, PLDM_SUCCESS);
4012     EXPECT_EQ(outVerifyResult, verifyResult);
4013 
4014     constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
4015         verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
4016     auto requestMsg2 =
4017         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4018         reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
4019     rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
4020                                     &outVerifyResult);
4021     EXPECT_EQ(rc, PLDM_SUCCESS);
4022     EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
4023 }
4024 
TEST(VerifyComplete,errorPathDecodeRequest)4025 TEST(VerifyComplete, errorPathDecodeRequest)
4026 {
4027     constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
4028     auto requestMsg =
4029         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4030         reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
4031     uint8_t outVerifyResult = 0;
4032 
4033     auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
4034     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4035 
4036     rc = decode_verify_complete_req(requestMsg, 0, nullptr);
4037     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4038 
4039     rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);
4040     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4041 }
4042 
TEST(VerifyComplete,goodPathEncodeResponse)4043 TEST(VerifyComplete, goodPathEncodeResponse)
4044 {
4045     constexpr uint8_t instanceId = 5;
4046     constexpr uint8_t completionCode = PLDM_SUCCESS;
4047     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4048         outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};
4049     std::array<uint8_t, hdrSize + sizeof(completionCode)>
4050         verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
4051     auto responseMsg1 =
4052         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4053         reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());
4054     auto rc = encode_verify_complete_resp(instanceId, completionCode,
4055                                           responseMsg1, sizeof(completionCode));
4056     EXPECT_EQ(rc, PLDM_SUCCESS);
4057     EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);
4058 
4059     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4060         outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88};
4061     std::array<uint8_t, hdrSize + sizeof(completionCode)>
4062         verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
4063     auto responseMsg2 =
4064         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4065         reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());
4066     rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
4067                                      responseMsg2, sizeof(completionCode));
4068     EXPECT_EQ(rc, PLDM_SUCCESS);
4069     EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);
4070 }
4071 
TEST(VerifyComplete,errorPathEncodeResponse)4072 TEST(VerifyComplete, errorPathEncodeResponse)
4073 {
4074     std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00};
4075     auto responseMsg =
4076         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4077         reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());
4078     auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
4079     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4080 
4081     rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
4082     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4083 }
4084 
TEST(ApplyComplete,goodPathDecodeRequest)4085 TEST(ApplyComplete, goodPathDecodeRequest)
4086 {
4087     constexpr uint8_t applyResult1 =
4088         PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
4089     // DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
4090     constexpr std::bitset<16> compActivationModification1{0x30};
4091     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4092         applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
4093     auto requestMsg1 =
4094         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4095         reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
4096     uint8_t outApplyResult = 0;
4097     bitfield16_t outCompActivationModification{};
4098     auto rc = decode_apply_complete_req(
4099         requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
4100         &outCompActivationModification);
4101     EXPECT_EQ(rc, PLDM_SUCCESS);
4102     EXPECT_EQ(outApplyResult, applyResult1);
4103     EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
4104 
4105     constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
4106     constexpr std::bitset<16> compActivationModification2{};
4107     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4108         applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4109     auto requestMsg2 =
4110         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4111         reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
4112     rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
4113                                    &outApplyResult,
4114                                    &outCompActivationModification);
4115     EXPECT_EQ(rc, PLDM_SUCCESS);
4116     EXPECT_EQ(outApplyResult, applyResult2);
4117     EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
4118 }
4119 
TEST(ApplyComplete,errorPathDecodeRequest)4120 TEST(ApplyComplete, errorPathDecodeRequest)
4121 {
4122     constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
4123     auto requestMsg1 =
4124         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4125         reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
4126     uint8_t outApplyResult = 0;
4127     bitfield16_t outCompActivationModification{};
4128 
4129     auto rc = decode_apply_complete_req(
4130         nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
4131         &outCompActivationModification);
4132     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4133 
4134     rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
4135                                    nullptr, &outCompActivationModification);
4136     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4137 
4138     rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
4139                                    &outApplyResult, nullptr);
4140     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4141 
4142     rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
4143                                    &outCompActivationModification);
4144     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4145 
4146     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4147         applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
4148     auto requestMsg2 =
4149         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4150         reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
4151     rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
4152                                    &outApplyResult,
4153                                    &outCompActivationModification);
4154     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4155 }
4156 
TEST(ApplyComplete,goodPathEncodeResponse)4157 TEST(ApplyComplete, goodPathEncodeResponse)
4158 {
4159     constexpr uint8_t instanceId = 6;
4160     constexpr uint8_t completionCode = PLDM_SUCCESS;
4161     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4162         outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
4163     std::array<uint8_t, hdrSize + sizeof(completionCode)>
4164         applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
4165     auto responseMsg1 =
4166         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4167         reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
4168     auto rc = encode_apply_complete_resp(instanceId, completionCode,
4169                                          responseMsg1, sizeof(completionCode));
4170     EXPECT_EQ(rc, PLDM_SUCCESS);
4171     EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
4172 
4173     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4174         outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
4175     std::array<uint8_t, hdrSize + sizeof(completionCode)>
4176         applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
4177     auto responseMsg2 =
4178         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4179         reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
4180     rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
4181                                     responseMsg2, sizeof(completionCode));
4182     EXPECT_EQ(rc, PLDM_SUCCESS);
4183     EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
4184 }
4185 
TEST(ApplyComplete,errorPathEncodeResponse)4186 TEST(ApplyComplete, errorPathEncodeResponse)
4187 {
4188     std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
4189     auto responseMsg =
4190         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4191         reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
4192     auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
4193     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4194 
4195     rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
4196     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4197 }
4198 
TEST(ActivateFirmware,goodPathEncodeRequest)4199 TEST(ActivateFirmware, goodPathEncodeRequest)
4200 {
4201     constexpr uint8_t instanceId = 7;
4202 
4203     std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
4204     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4205     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4206 
4207     auto rc = encode_activate_firmware_req(
4208         instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
4209         sizeof(pldm_activate_firmware_req));
4210     EXPECT_EQ(rc, PLDM_SUCCESS);
4211 
4212     std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
4213         outRequest{0x87, 0x05, 0x1a, 0x01};
4214     EXPECT_EQ(request, outRequest);
4215 }
4216 
TEST(ActivateFirmware,errorPathEncodeRequest)4217 TEST(ActivateFirmware, errorPathEncodeRequest)
4218 {
4219     std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
4220     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4221     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4222 
4223     auto rc = encode_activate_firmware_req(
4224         0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
4225         sizeof(pldm_activate_firmware_req));
4226     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4227 
4228     rc = encode_activate_firmware_req(
4229         0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
4230     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4231 
4232     rc = encode_activate_firmware_req(0, 2, requestMsg,
4233                                       sizeof(pldm_activate_firmware_req));
4234     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4235 }
4236 
TEST(ActivateFirmware,goodPathDecodeResponse)4237 TEST(ActivateFirmware, goodPathDecodeResponse)
4238 {
4239     constexpr uint16_t estimatedTimeForActivation100s = 100;
4240     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
4241         activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
4242     auto responseMsg1 =
4243         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4244         reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
4245 
4246     uint8_t completionCode = 0;
4247     uint16_t estimatedTimeForActivation = 0;
4248 
4249     auto rc = decode_activate_firmware_resp(
4250         responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
4251         &estimatedTimeForActivation);
4252 
4253     EXPECT_EQ(rc, PLDM_SUCCESS);
4254     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4255     EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
4256 
4257     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4258         activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
4259     auto responseMsg2 =
4260         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4261         reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data());
4262 
4263     rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
4264                                        &completionCode,
4265                                        &estimatedTimeForActivation);
4266 
4267     EXPECT_EQ(rc, PLDM_SUCCESS);
4268     EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
4269 }
4270 
TEST(ActivateFirmware,errorPathDecodeResponse)4271 TEST(ActivateFirmware, errorPathDecodeResponse)
4272 {
4273     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
4274         activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4275     auto responseMsg =
4276         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4277         reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
4278 
4279     uint8_t completionCode = 0;
4280     uint16_t estimatedTimeForActivation = 0;
4281 
4282     auto rc = decode_activate_firmware_resp(
4283         nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
4284         &estimatedTimeForActivation);
4285     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4286 
4287     rc = decode_activate_firmware_resp(responseMsg,
4288                                        sizeof(pldm_activate_firmware_resp),
4289                                        nullptr, &estimatedTimeForActivation);
4290     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4291 
4292     rc = decode_activate_firmware_resp(responseMsg,
4293                                        sizeof(pldm_activate_firmware_resp),
4294                                        &completionCode, nullptr);
4295     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4296 
4297     rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
4298                                        &estimatedTimeForActivation);
4299     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4300 
4301     rc = decode_activate_firmware_resp(
4302         responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
4303         &estimatedTimeForActivation);
4304     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4305 }
4306 
TEST(GetStatus,goodPathEncodeRequest)4307 TEST(GetStatus, goodPathEncodeRequest)
4308 {
4309     constexpr uint8_t instanceId = 8;
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_get_status_req(instanceId, requestMsg,
4315                                     PLDM_GET_STATUS_REQ_BYTES);
4316     EXPECT_EQ(rc, PLDM_SUCCESS);
4317 
4318     constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
4319     EXPECT_EQ(request, outRequest);
4320 }
4321 
TEST(GetStatus,errorPathEncodeRequest)4322 TEST(GetStatus, 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 = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
4329     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4330 
4331     rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);
4332     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4333 }
4334 
TEST(GetStatus,goodPathDecodeResponse)4335 TEST(GetStatus, goodPathDecodeResponse)
4336 {
4337     constexpr std::bitset<32> updateOptionFlagsEnabled1{0};
4338     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4339         getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
4340                            0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};
4341     auto responseMsg1 =
4342         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4343         reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4344 
4345     uint8_t completionCode = 0;
4346     uint8_t currentState = 0;
4347     uint8_t previousState = 0;
4348     uint8_t auxState = 0;
4349     uint8_t auxStateStatus = 0;
4350     uint8_t progressPercent = 0;
4351     uint8_t reasonCode = 0;
4352     bitfield32_t updateOptionFlagsEnabled{0};
4353 
4354     auto rc = decode_get_status_resp(
4355         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4356         &currentState, &previousState, &auxState, &auxStateStatus,
4357         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4358 
4359     EXPECT_EQ(rc, PLDM_SUCCESS);
4360     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4361     EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);
4362     EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4363     EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);
4364     EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);
4365     EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);
4366     EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4367     EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);
4368 
4369     // Bit position 0 - Force update of component – FD will perform a force
4370     // update of the component.
4371     constexpr std::bitset<32> updateOptionFlagsEnabled2{1};
4372     constexpr uint8_t progressPercent2 = 50;
4373     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4374         getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,
4375                            0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};
4376     auto responseMsg2 =
4377         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4378         reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4379 
4380     rc = decode_get_status_resp(
4381         responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4382         &currentState, &previousState, &auxState, &auxStateStatus,
4383         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4384 
4385     EXPECT_EQ(rc, PLDM_SUCCESS);
4386     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4387     EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);
4388     EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4389     EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);
4390     EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);
4391     EXPECT_EQ(progressPercent, progressPercent2);
4392     EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4393     EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);
4394 
4395 #ifdef LIBPLDM_API_TESTING
4396     /* Check the roundtrip */
4397     PLDM_MSG_DEFINE_P(enc, 1000);
4398     size_t enc_payload_len = 1000;
4399     const struct pldm_get_status_resp status_enc = {
4400         .completion_code = PLDM_SUCCESS,
4401         .current_state = currentState,
4402         .previous_state = previousState,
4403         .aux_state = auxState,
4404         .aux_state_status = auxStateStatus,
4405         .progress_percent = progressPercent,
4406         .reason_code = reasonCode,
4407         .update_option_flags_enabled = updateOptionFlagsEnabled,
4408     };
4409     rc = encode_get_status_resp(FIXED_INSTANCE_ID, &status_enc, enc,
4410                                 &enc_payload_len);
4411     EXPECT_EQ(rc, PLDM_SUCCESS);
4412     EXPECT_EQ(enc_payload_len + hdrSize, getStatusResponse2.size());
4413     EXPECT_TRUE(std::equal(getStatusResponse2.begin() + hdrSize,
4414                            getStatusResponse2.end(), enc_buf + hdrSize));
4415     check_response(enc, PLDM_GET_STATUS);
4416 #endif
4417 
4418     /* Check a not-ready completion code */
4419     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4420         getStatusResponse3{0x00, 0x00, 0x00, 0x04};
4421     auto responseMsg3 =
4422         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4423         reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4424     rc = decode_get_status_resp(
4425         responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4426         &currentState, &previousState, &auxState, &auxStateStatus,
4427         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4428     EXPECT_EQ(rc, PLDM_SUCCESS);
4429     EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);
4430 }
4431 
TEST(GetStatus,errorPathDecodeResponse)4432 TEST(GetStatus, errorPathDecodeResponse)
4433 {
4434     uint8_t completionCode = 0;
4435     uint8_t currentState = 0;
4436     uint8_t previousState = 0;
4437     uint8_t auxState = 0;
4438     uint8_t auxStateStatus = 0;
4439     uint8_t progressPercent = 0;
4440     uint8_t reasonCode = 0;
4441     bitfield32_t updateOptionFlagsEnabled{0};
4442 
4443     constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};
4444     auto responseMsg1 =
4445         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4446         reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4447 
4448     auto rc = decode_get_status_resp(
4449         nullptr, getStatusResponse1.size() - hdrSize, &completionCode,
4450         &currentState, &previousState, &auxState, &auxStateStatus,
4451         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4452     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4453 
4454     rc = decode_get_status_resp(
4455         responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,
4456         &currentState, &previousState, &auxState, &auxStateStatus,
4457         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4458     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4459 
4460     rc = decode_get_status_resp(
4461         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4462         nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,
4463         &reasonCode, &updateOptionFlagsEnabled);
4464     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4465 
4466     rc = decode_get_status_resp(
4467         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4468         &currentState, nullptr, &auxState, &auxStateStatus, &progressPercent,
4469         &reasonCode, &updateOptionFlagsEnabled);
4470     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4471 
4472     rc = decode_get_status_resp(
4473         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4474         &currentState, &previousState, nullptr, &auxStateStatus,
4475         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4476     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4477 
4478     rc = decode_get_status_resp(
4479         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4480         &currentState, &previousState, &auxState, nullptr, &progressPercent,
4481         &reasonCode, &updateOptionFlagsEnabled);
4482     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4483 
4484     rc = decode_get_status_resp(
4485         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4486         &currentState, &previousState, &auxState, &auxStateStatus, nullptr,
4487         &reasonCode, &updateOptionFlagsEnabled);
4488     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4489 
4490     rc = decode_get_status_resp(
4491         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4492         &currentState, &previousState, &auxState, &auxStateStatus,
4493         &progressPercent, nullptr, &updateOptionFlagsEnabled);
4494     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4495 
4496     rc = decode_get_status_resp(
4497         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4498         &currentState, &previousState, &auxState, &auxStateStatus,
4499         &progressPercent, &reasonCode, nullptr);
4500     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4501 
4502     rc = decode_get_status_resp(
4503         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4504         &currentState, &previousState, &auxState, &auxStateStatus,
4505         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4506     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4507 
4508     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>
4509         getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4510                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4511     auto responseMsg2 =
4512         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4513         reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4514     rc = decode_get_status_resp(
4515         responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4516         &currentState, &previousState, &auxState, &auxStateStatus,
4517         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4518     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4519 
4520     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4521         getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
4522                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4523     auto responseMsg3 =
4524         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4525         reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4526     rc = decode_get_status_resp(
4527         responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4528         &currentState, &previousState, &auxState, &auxStateStatus,
4529         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4530     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4531 
4532     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4533         getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
4534                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4535     auto responseMsg4 =
4536         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4537         reinterpret_cast<const pldm_msg*>(getStatusResponse4.data());
4538     rc = decode_get_status_resp(
4539         responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,
4540         &currentState, &previousState, &auxState, &auxStateStatus,
4541         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4542     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4543 
4544     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4545         getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
4546                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4547     auto responseMsg5 =
4548         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4549         reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());
4550     rc = decode_get_status_resp(
4551         responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,
4552         &currentState, &previousState, &auxState, &auxStateStatus,
4553         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4554     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4555 
4556     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4557         getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4558                            0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4559     auto responseMsg6 =
4560         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4561         reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());
4562     rc = decode_get_status_resp(
4563         responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,
4564         &currentState, &previousState, &auxState, &auxStateStatus,
4565         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4566     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4567 
4568     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4569         getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4570                            0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
4571     auto responseMsg7 =
4572         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4573         reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());
4574     rc = decode_get_status_resp(
4575         responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,
4576         &currentState, &previousState, &auxState, &auxStateStatus,
4577         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4578     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4579 
4580     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4581         getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4582                            0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00};
4583     auto responseMsg8 =
4584         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4585         reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());
4586     rc = decode_get_status_resp(
4587         responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,
4588         &currentState, &previousState, &auxState, &auxStateStatus,
4589         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4590     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4591 
4592     // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is
4593     // IDLE
4594     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4595         getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
4596                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4597     auto responseMsg9 =
4598         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4599         reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());
4600     rc = decode_get_status_resp(
4601         responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,
4602         &currentState, &previousState, &auxState, &auxStateStatus,
4603         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4604     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4605 }
4606 
TEST(CancelUpdateComponent,goodPathEncodeRequest)4607 TEST(CancelUpdateComponent, goodPathEncodeRequest)
4608 {
4609     constexpr uint8_t instanceId = 9;
4610     std::array<uint8_t, hdrSize> request{};
4611     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4612     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4613 
4614     auto rc = encode_cancel_update_component_req(
4615         instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4616     EXPECT_EQ(rc, PLDM_SUCCESS);
4617 
4618     constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
4619     EXPECT_EQ(request, outRequest);
4620 }
4621 
TEST(CancelUpdateComponent,errorPathEncodeRequest)4622 TEST(CancelUpdateComponent, errorPathEncodeRequest)
4623 {
4624     std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
4625     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4626     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4627 
4628     auto rc = encode_cancel_update_component_req(
4629         0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4630     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4631 
4632     rc = encode_cancel_update_component_req(
4633         0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);
4634     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4635 }
4636 
TEST(CancelUpdateComponent,testGoodDecodeResponse)4637 TEST(CancelUpdateComponent, testGoodDecodeResponse)
4638 {
4639     uint8_t completionCode = 0;
4640     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4641         cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};
4642     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4643     auto responseMsg1 = reinterpret_cast<const pldm_msg*>(
4644         cancelUpdateComponentResponse1.data());
4645     auto rc = decode_cancel_update_component_resp(
4646         responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,
4647         &completionCode);
4648     EXPECT_EQ(rc, PLDM_SUCCESS);
4649     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4650 
4651     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4652         cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};
4653     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4654     auto responseMsg2 = reinterpret_cast<const pldm_msg*>(
4655         cancelUpdateComponentResponse2.data());
4656     rc = decode_cancel_update_component_resp(
4657         responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,
4658         &completionCode);
4659     EXPECT_EQ(rc, PLDM_SUCCESS);
4660     EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4661 }
4662 
TEST(CancelUpdateComponent,testBadDecodeResponse)4663 TEST(CancelUpdateComponent, testBadDecodeResponse)
4664 {
4665     uint8_t completionCode = 0;
4666     constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{
4667         0x00, 0x00, 0x00};
4668     auto responseMsg =
4669         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4670         reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data());
4671 
4672     auto rc = decode_cancel_update_component_resp(
4673         nullptr, cancelUpdateComponentResponse.size() - hdrSize,
4674         &completionCode);
4675     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4676 
4677     rc = decode_cancel_update_component_resp(
4678         responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);
4679     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4680 
4681     rc = decode_cancel_update_component_resp(
4682         responseMsg, cancelUpdateComponentResponse.size() - hdrSize,
4683         &completionCode);
4684     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4685 }
4686 
TEST(CancelUpdate,goodPathEncodeRequest)4687 TEST(CancelUpdate, goodPathEncodeRequest)
4688 {
4689     constexpr uint8_t instanceId = 10;
4690     std::array<uint8_t, hdrSize> request{};
4691     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4692     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4693 
4694     auto rc = encode_cancel_update_req(instanceId, requestMsg,
4695                                        PLDM_CANCEL_UPDATE_REQ_BYTES);
4696     EXPECT_EQ(rc, PLDM_SUCCESS);
4697 
4698     constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
4699     EXPECT_EQ(request, outRequest);
4700 }
4701 
TEST(CancelUpdate,errorPathEncodeRequest)4702 TEST(CancelUpdate, errorPathEncodeRequest)
4703 {
4704     std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
4705     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4706     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4707 
4708     auto rc =
4709         encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
4710     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4711 
4712     rc = encode_cancel_update_req(0, requestMsg,
4713                                   PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
4714     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4715 }
4716 
TEST(CancelUpdate,goodPathDecodeResponse)4717 TEST(CancelUpdate, goodPathDecodeResponse)
4718 {
4719     constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
4720     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4721         cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4722                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4723     auto responseMsg1 =
4724         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4725         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4726     uint8_t completionCode = 0;
4727     bool8_t nonFunctioningComponentIndication = 0;
4728     bitfield64_t nonFunctioningComponentBitmap{0};
4729     auto rc = decode_cancel_update_resp(
4730         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4731         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4732     EXPECT_EQ(rc, PLDM_SUCCESS);
4733     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4734     EXPECT_EQ(nonFunctioningComponentIndication,
4735               PLDM_FWUP_COMPONENTS_FUNCTIONING);
4736     EXPECT_EQ(nonFunctioningComponentBitmap.value,
4737               nonFunctioningComponentBitmap1);
4738 
4739     constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
4740     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4741         cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
4742                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4743     auto responseMsg2 =
4744         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4745         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4746     rc = decode_cancel_update_resp(
4747         responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4748         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4749     EXPECT_EQ(rc, PLDM_SUCCESS);
4750     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4751     EXPECT_EQ(nonFunctioningComponentIndication,
4752               PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING);
4753     EXPECT_EQ(nonFunctioningComponentBitmap.value,
4754               nonFunctioningComponentBitmap2);
4755 
4756     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4757         cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
4758     auto responseMsg3 =
4759         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4760         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4761     rc = decode_cancel_update_resp(
4762         responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4763         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4764     EXPECT_EQ(rc, PLDM_SUCCESS);
4765     EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4766 }
4767 
TEST(CancelUpdate,errorPathDecodeResponse)4768 TEST(CancelUpdate, errorPathDecodeResponse)
4769 {
4770     constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
4771                                                                  0x00};
4772     auto responseMsg1 =
4773         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4774         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4775     uint8_t completionCode = 0;
4776     bool8_t nonFunctioningComponentIndication = 0;
4777     bitfield64_t nonFunctioningComponentBitmap{0};
4778 
4779     auto rc = decode_cancel_update_resp(
4780         nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4781         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4782     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4783 
4784     rc = decode_cancel_update_resp(
4785         responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
4786         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4787     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4788 
4789     rc = decode_cancel_update_resp(
4790         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4791         nullptr, &nonFunctioningComponentBitmap);
4792     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4793 
4794     rc = decode_cancel_update_resp(
4795         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4796         &nonFunctioningComponentIndication, nullptr);
4797     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4798 
4799     rc = decode_cancel_update_resp(
4800         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4801         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4802     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4803 
4804     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4805         cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
4806     auto responseMsg2 =
4807         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4808         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4809     rc = decode_cancel_update_resp(
4810         responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4811         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4812     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4813 
4814     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4815         cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
4816                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4817     auto responseMsg3 =
4818         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4819         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4820     rc = decode_cancel_update_resp(
4821         responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4822         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4823     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4824 }
4825 
4826 #ifdef LIBPLDM_API_TESTING
TEST(DecodePldmFirmwareUpdatePackage,badArguments)4827 TEST(DecodePldmFirmwareUpdatePackage, badArguments)
4828 {
4829     DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
4830     pldm_package_header_information_pad hdr;
4831     struct pldm_package_iter iter;
4832     uint8_t data;
4833     int rc;
4834 
4835     rc = decode_pldm_firmware_update_package(nullptr, 0, &pin, &hdr, &iter);
4836     EXPECT_EQ(rc, -EINVAL);
4837 
4838     rc = decode_pldm_firmware_update_package(&data, sizeof(data), nullptr, &hdr,
4839                                              &iter);
4840     EXPECT_EQ(rc, -EINVAL);
4841 
4842     rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, nullptr,
4843                                              &iter);
4844     EXPECT_EQ(rc, -EINVAL);
4845 
4846     rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, &hdr,
4847                                              nullptr);
4848     EXPECT_EQ(rc, -EINVAL);
4849 }
4850 #endif
4851 
4852 #ifdef LIBPLDM_API_TESTING
TEST(DecodePldmFirmwareUpdatePackage,unsupportedPinVersion)4853 TEST(DecodePldmFirmwareUpdatePackage, unsupportedPinVersion)
4854 {
4855     const struct pldm_package_format_pin pin = {
4856         .meta =
4857             {
4858                 .magic = 0,
4859                 .version = UINT8_MAX,
4860             },
4861         .format =
4862             {
4863                 .identifier = {0},
4864                 .revision = 0,
4865             },
4866     };
4867 
4868     pldm_package_header_information_pad hdr;
4869     struct pldm_package_iter iter;
4870     uint8_t data = 0;
4871     int rc;
4872 
4873     rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, &hdr,
4874                                              &iter);
4875     EXPECT_EQ(rc, -ENOTSUP);
4876 }
4877 #endif
4878 
4879 #ifdef LIBPLDM_API_TESTING
TEST(DecodePldmFirmwareUpdatePackage,badPinRevision)4880 TEST(DecodePldmFirmwareUpdatePackage, badPinRevision)
4881 {
4882     const struct pldm_package_format_pin lowPin = {
4883         .meta =
4884             {
4885                 .magic = 0,
4886                 .version = 0,
4887             },
4888         .format =
4889             {
4890                 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4891                 .revision = 0,
4892             },
4893     };
4894 
4895     const struct pldm_package_format_pin highPin = {
4896         .meta =
4897             {
4898                 .magic = 0,
4899                 .version = 0,
4900             },
4901         .format =
4902             {
4903                 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4904                 .revision = 3,
4905             },
4906     };
4907 
4908     pldm_package_header_information_pad hdr;
4909     struct pldm_package_iter iter;
4910     uint8_t data = 0;
4911     int rc;
4912 
4913     rc = decode_pldm_firmware_update_package(&data, sizeof(data), &lowPin, &hdr,
4914                                              &iter);
4915     EXPECT_EQ(rc, -EINVAL);
4916 
4917     rc = decode_pldm_firmware_update_package(&data, sizeof(data), &highPin,
4918                                              &hdr, &iter);
4919     EXPECT_EQ(rc, -ENOTSUP);
4920 }
4921 #endif
4922 
4923 #ifdef LIBPLDM_API_TESTING
TEST(DecodePldmFirmwareUpdatePackage,badPinMagic)4924 TEST(DecodePldmFirmwareUpdatePackage, badPinMagic)
4925 {
4926     const struct pldm_package_format_pin lowPin = {
4927         .meta =
4928             {
4929                 .magic = 0,
4930                 .version = 0,
4931             },
4932         .format =
4933             {
4934                 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4935                 .revision = 2,
4936             },
4937     };
4938 
4939     const struct pldm_package_format_pin highPin = {
4940         .meta =
4941             {
4942                 .magic = UINT32_MAX,
4943                 .version = 0,
4944             },
4945         .format =
4946             {
4947                 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4948                 .revision = 2,
4949             },
4950     };
4951 
4952     pldm_package_header_information_pad hdr;
4953     struct pldm_package_iter iter;
4954     uint8_t data = 0;
4955     int rc;
4956 
4957     rc = decode_pldm_firmware_update_package(&data, sizeof(data), &lowPin, &hdr,
4958                                              &iter);
4959     EXPECT_EQ(rc, -EINVAL);
4960 
4961     rc = decode_pldm_firmware_update_package(&data, sizeof(data), &highPin,
4962                                              &hdr, &iter);
4963     EXPECT_EQ(rc, -EINVAL);
4964 }
4965 #endif
4966 
4967 #ifdef LIBPLDM_API_TESTING
TEST(DecodePldmFirmwareUpdatePackage,unsupportedPinIdentifier)4968 TEST(DecodePldmFirmwareUpdatePackage, unsupportedPinIdentifier)
4969 {
4970     const struct pldm_package_format_pin pin = {
4971         .meta =
4972             {
4973                 .magic =
4974                     LIBPLDM_SIZEAT(struct pldm__package_header_information,
4975                                    package) +
4976                     LIBPLDM_SIZEAT(
4977                         struct pldm_package_firmware_device_id_record,
4978                         firmware_device_package_data) +
4979                     LIBPLDM_SIZEAT(struct pldm_descriptor, descriptor_data) +
4980                     LIBPLDM_SIZEAT(
4981                         struct pldm_package_downstream_device_id_record,
4982                         package_data) +
4983                     LIBPLDM_SIZEAT(
4984                         struct pldm_package_component_image_information,
4985                         component_version_string) +
4986                     LIBPLDM_SIZEAT(struct pldm_package_iter, infos),
4987                 .version = 0,
4988             },
4989         .format =
4990             {
4991                 .identifier = {0},
4992                 .revision = PLDM_PACKAGE_HEADER_FORMAT_REVISION_FR02H,
4993             },
4994     };
4995 
4996     pldm_package_header_information_pad hdr;
4997     struct pldm_package_iter iter;
4998     uint8_t data = 0;
4999     int rc;
5000 
5001     rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, &hdr,
5002                                              &iter);
5003     EXPECT_EQ(rc, -ENOTSUP);
5004 }
5005 #endif
5006 
5007 #ifdef LIBPLDM_API_TESTING
TEST(DecodePldmFirmwareUpdatePackage,oldConsumer)5008 TEST(DecodePldmFirmwareUpdatePackage, oldConsumer)
5009 {
5010     /* Package format revision 2 header */
5011     const std::array<uint8_t, 150> package{
5012         0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
5013         0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5a, 0x02, 0x94, 0x00, 0x00,
5014         0xe9, 0x07, 0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00,
5015         0x76, 0x02, 0x08, 0x00, 0x01, 0x04, 't',  'e',  's',  't',
5016     };
5017 
5018     /* Package format revision 1 consumer */
5019     DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR01H(pin);
5020 
5021     pldm_package_header_information_pad hdr;
5022     struct pldm_package_iter iter;
5023     int rc;
5024 
5025     rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5026                                              &pin, &hdr, &iter);
5027     EXPECT_EQ(rc, -ENOTSUP);
5028 }
5029 #endif
5030 
5031 #ifdef LIBPLDM_API_TESTING
TEST(DecodePldmFirmwareUpdatePackage,v1h1fd1fdd1cii)5032 TEST(DecodePldmFirmwareUpdatePackage, v1h1fd1fdd1cii)
5033 {
5034     const std::array<uint8_t, 102> package{
5035         0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
5036         0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x65, 0x00, 0x00, 0xe9, 0x07,
5037         0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08,
5038         0x00, 0x01, 0x04, 't',  'e',  's',  't',
5039 
5040         0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00,
5041         0x00, 0x01, 'v',  '0',  '.',  '1',  0x01, 0x00, 0x04, 0x00, 0x9c,
5042         0x01, 0x00, 0x00,
5043 
5044         0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
5045         0x00, 0x01, 0x00, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5046         0x01, 0x04, 'v',  '0',  '.',  '2',  0x00, 0x00, 0x00, 0x00,
5047 
5048         0xb5, 0x3f, 0xf6, 0x6a,
5049 
5050         0x5a,
5051     };
5052 
5053     struct pldm_package_downstream_device_id_record ddrec;
5054     struct pldm_package_component_image_information info;
5055     struct pldm_package_firmware_device_id_record fdrec;
5056     DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
5057     pldm_package_header_information_pad hdr;
5058     struct pldm_package_iter iter;
5059     int nr_fdrec_desc = 0;
5060     int nr_ddrec_desc = 0;
5061     int nr_fdrec = 0;
5062     int nr_ddrec = 0;
5063     int nr_infos = 0;
5064     int rc;
5065 
5066     rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5067                                              &pin, &hdr, &iter);
5068     ASSERT_EQ(rc, 0);
5069 
5070     EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.data(),
5071                      hdr.package_header_identifier,
5072                      PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.size()),
5073               0);
5074     EXPECT_EQ(hdr.package_header_format_revision, 1);
5075 
5076     static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5077                                                    0x16, 0x03, 0x00, 0x00, 0x00,
5078                                                    0x00, 0x76, 0x02};
5079     ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5080     EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5081                      timestamp.size()),
5082               0);
5083 
5084     EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5085     EXPECT_EQ(hdr.package_version_string_type, 1);
5086     ASSERT_EQ(hdr.package_version_string.length, 4);
5087     EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5088                      hdr.package_version_string.length),
5089               0);
5090     EXPECT_NE(hdr.areas.ptr, nullptr);
5091     EXPECT_NE(hdr.areas.length, 0);
5092     EXPECT_NE(hdr.package.ptr, nullptr);
5093     EXPECT_NE(hdr.package.length, 0);
5094 
5095     foreach_pldm_package_firmware_device_id_record(iter, fdrec, rc)
5096     {
5097         struct pldm_descriptor desc;
5098 
5099         EXPECT_EQ(fdrec.descriptor_count, 1);
5100         EXPECT_EQ(fdrec.device_update_option_flags.value, 0);
5101         EXPECT_EQ(fdrec.component_image_set_version_string_type, 1);
5102         ASSERT_EQ(fdrec.component_image_set_version_string.length, 4);
5103         EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5104                          fdrec.component_image_set_version_string.length),
5105                   0);
5106         ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1);
5107         EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1);
5108         EXPECT_NE(fdrec.record_descriptors.length, 0);
5109         EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5110         ASSERT_EQ(fdrec.firmware_device_package_data.length, 0);
5111 
5112         foreach_pldm_package_firmware_device_id_record_descriptor(iter, fdrec,
5113                                                                   desc, rc)
5114         {
5115             static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5116 
5117             EXPECT_EQ(desc.descriptor_type, 1);
5118             ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5119             EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5120                              sizeof(iana_pen_dmtf)),
5121                       0);
5122 
5123             nr_fdrec_desc++;
5124         }
5125         ASSERT_EQ(rc, 0);
5126 
5127         nr_fdrec++;
5128     }
5129     ASSERT_EQ(rc, 0);
5130 
5131     EXPECT_EQ(nr_fdrec, 1);
5132     EXPECT_EQ(nr_fdrec_desc, 1);
5133 
5134     foreach_pldm_package_downstream_device_id_record(iter, ddrec, rc)
5135     {
5136         struct pldm_descriptor desc;
5137 
5138         EXPECT_EQ(ddrec.descriptor_count, 1);
5139         EXPECT_EQ(ddrec.update_option_flags.value, 0);
5140         EXPECT_EQ(ddrec.self_contained_activation_min_version_string_type, 1);
5141         ASSERT_EQ(ddrec.self_contained_activation_min_version_string.length, 4);
5142         EXPECT_EQ(
5143             memcmp("v1.0",
5144                    ddrec.self_contained_activation_min_version_string.ptr,
5145                    ddrec.self_contained_activation_min_version_string.length),
5146             0);
5147         EXPECT_EQ(ddrec.self_contained_activation_min_version_comparison_stamp,
5148                   0);
5149         ASSERT_EQ(ddrec.applicable_components.bitmap.length, 1);
5150         EXPECT_EQ(*ddrec.applicable_components.bitmap.ptr, 2);
5151         EXPECT_NE(ddrec.record_descriptors.length, 0);
5152         EXPECT_NE(ddrec.record_descriptors.ptr, nullptr);
5153         EXPECT_EQ(ddrec.package_data.length, 0);
5154 
5155         foreach_pldm_package_downstream_device_id_record_descriptor(iter, ddrec,
5156                                                                     desc, rc)
5157         {
5158             static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5159 
5160             EXPECT_EQ(desc.descriptor_type, 1);
5161             ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5162             EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5163                              sizeof(iana_pen_dmtf)),
5164                       0);
5165 
5166             nr_ddrec_desc++;
5167         }
5168         ASSERT_EQ(rc, 0);
5169 
5170         nr_ddrec++;
5171     }
5172     ASSERT_EQ(rc, 0);
5173 
5174     EXPECT_EQ(nr_ddrec, 0);
5175     EXPECT_EQ(nr_ddrec_desc, 0);
5176 
5177     static const pldm_package_component_image_information expected_info{
5178         0x000a,       0x0000, 0xffffffff,   {0},         {1},
5179         {nullptr, 1}, 0x01,   {nullptr, 0}, {nullptr, 0}};
5180 
5181     foreach_pldm_package_component_image_information(iter, info, rc)
5182     {
5183         EXPECT_EQ(info.component_classification,
5184                   expected_info.component_classification);
5185         EXPECT_EQ(info.component_identifier,
5186                   expected_info.component_identifier);
5187         EXPECT_EQ(info.component_comparison_stamp,
5188                   expected_info.component_comparison_stamp);
5189         EXPECT_EQ(info.component_options.value,
5190                   expected_info.component_options.value);
5191         EXPECT_EQ(info.requested_component_activation_method.value,
5192                   expected_info.requested_component_activation_method.value);
5193         EXPECT_NE(nullptr, info.component_image.ptr);
5194         EXPECT_EQ(info.component_image.length,
5195                   expected_info.component_image.length);
5196         EXPECT_EQ(info.component_version_string_type,
5197                   expected_info.component_version_string_type);
5198         ASSERT_EQ(info.component_version_string.length, 4);
5199         EXPECT_EQ(memcmp("v0.2", info.component_version_string.ptr,
5200                          info.component_version_string.length),
5201                   0);
5202 
5203         nr_infos++;
5204     }
5205     ASSERT_EQ(rc, 0);
5206 
5207     EXPECT_EQ(nr_infos, 1);
5208 }
5209 #endif
5210 
5211 #ifdef LIBPLDM_API_TESTING
TEST(DecodePldmFirmwareUpdatePackage,v2h1fd1fdd1dd1ddd2cii)5212 TEST(DecodePldmFirmwareUpdatePackage, v2h1fd1fdd1dd1ddd2cii)
5213 {
5214     const std::array<uint8_t, 150> package{
5215         0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
5216         0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5a, 0x02, 0x94, 0x00, 0x00,
5217         0xe9, 0x07, 0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00,
5218         0x76, 0x02, 0x08, 0x00, 0x01, 0x04, 't',  'e',  's',  't',
5219 
5220         0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
5221         0x00, 0x00, 0x01, 'v',  '0',  '.',  '1',  0x01, 0x00, 0x04,
5222         0x00, 0x9c, 0x01, 0x00, 0x00,
5223 
5224         0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
5225         0x00, 0x00, 0x02, 'v',  '1',  '.',  '0',  0x01, 0x00, 0x04,
5226         0x00, 0x9c, 0x01, 0x00, 0x00,
5227 
5228         0x02, 0x00,
5229 
5230         0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
5231         0x01, 0x00, 0x94, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5232         0x01, 0x04, 'v',  '0',  '.',  '2',
5233 
5234         0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
5235         0x01, 0x00, 0x95, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5236         0x01, 0x04, 'v',  '2',  '.',  '0',
5237 
5238         0xd3, 0x5c, 0x1c, 0x8a,
5239 
5240         0x5a,
5241 
5242         0xa5,
5243     };
5244     struct pldm_package_downstream_device_id_record ddrec;
5245     struct pldm_package_component_image_information info;
5246     struct pldm_package_firmware_device_id_record fdrec;
5247     DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
5248     pldm_package_header_information_pad hdr;
5249     struct pldm_package_iter iter;
5250     int nr_fdrec_desc = 0;
5251     int nr_ddrec_desc = 0;
5252     int nr_fdrec = 0;
5253     int nr_ddrec = 0;
5254     int nr_infos = 0;
5255     int rc;
5256 
5257     rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5258                                              &pin, &hdr, &iter);
5259     ASSERT_EQ(rc, 0);
5260 
5261     EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_1.data(),
5262                      hdr.package_header_identifier,
5263                      PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_1.size()),
5264               0);
5265     EXPECT_EQ(hdr.package_header_format_revision, 2);
5266 
5267     static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5268                                                    0x16, 0x03, 0x00, 0x00, 0x00,
5269                                                    0x00, 0x76, 0x02};
5270     ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5271     EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5272                      timestamp.size()),
5273               0);
5274 
5275     EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5276     EXPECT_EQ(hdr.package_version_string_type, 1);
5277     ASSERT_EQ(hdr.package_version_string.length, 4);
5278     EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5279                      hdr.package_version_string.length),
5280               0);
5281     EXPECT_NE(hdr.areas.ptr, nullptr);
5282     EXPECT_NE(hdr.areas.length, 0);
5283     EXPECT_NE(hdr.package.ptr, nullptr);
5284     EXPECT_NE(hdr.package.length, 0);
5285 
5286     foreach_pldm_package_firmware_device_id_record(iter, fdrec, rc)
5287     {
5288         struct pldm_descriptor desc;
5289 
5290         EXPECT_EQ(fdrec.descriptor_count, 1);
5291         EXPECT_EQ(fdrec.device_update_option_flags.value, 0);
5292         EXPECT_EQ(fdrec.component_image_set_version_string_type, 1);
5293         ASSERT_EQ(fdrec.component_image_set_version_string.length, 4);
5294         EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5295                          fdrec.component_image_set_version_string.length),
5296                   0);
5297         ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1);
5298         EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1);
5299         EXPECT_NE(fdrec.record_descriptors.length, 0);
5300         EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5301         ASSERT_EQ(fdrec.firmware_device_package_data.length, 0);
5302 
5303         foreach_pldm_package_firmware_device_id_record_descriptor(iter, fdrec,
5304                                                                   desc, rc)
5305         {
5306             static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5307 
5308             EXPECT_EQ(desc.descriptor_type, 1);
5309             ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5310             EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5311                              sizeof(iana_pen_dmtf)),
5312                       0);
5313 
5314             nr_fdrec_desc++;
5315         }
5316         ASSERT_EQ(rc, 0);
5317 
5318         nr_fdrec++;
5319     }
5320     ASSERT_EQ(rc, 0);
5321 
5322     EXPECT_EQ(nr_fdrec, 1);
5323     EXPECT_EQ(nr_fdrec_desc, 1);
5324 
5325     foreach_pldm_package_downstream_device_id_record(iter, ddrec, rc)
5326     {
5327         struct pldm_descriptor desc;
5328 
5329         EXPECT_EQ(ddrec.descriptor_count, 1);
5330         EXPECT_EQ(ddrec.update_option_flags.value, 0);
5331         EXPECT_EQ(ddrec.self_contained_activation_min_version_string_type, 1);
5332         ASSERT_EQ(ddrec.self_contained_activation_min_version_string.length, 4);
5333         EXPECT_EQ(
5334             memcmp("v1.0",
5335                    ddrec.self_contained_activation_min_version_string.ptr,
5336                    ddrec.self_contained_activation_min_version_string.length),
5337             0);
5338         EXPECT_EQ(ddrec.self_contained_activation_min_version_comparison_stamp,
5339                   0);
5340         ASSERT_EQ(ddrec.applicable_components.bitmap.length, 1);
5341         EXPECT_EQ(*ddrec.applicable_components.bitmap.ptr, 2);
5342         EXPECT_NE(ddrec.record_descriptors.length, 0);
5343         EXPECT_NE(ddrec.record_descriptors.ptr, nullptr);
5344         EXPECT_EQ(ddrec.package_data.length, 0);
5345 
5346         foreach_pldm_package_downstream_device_id_record_descriptor(iter, ddrec,
5347                                                                     desc, rc)
5348         {
5349             static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5350 
5351             EXPECT_EQ(desc.descriptor_type, 1);
5352             ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5353             EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5354                              sizeof(iana_pen_dmtf)),
5355                       0);
5356 
5357             nr_ddrec_desc++;
5358         }
5359         ASSERT_EQ(rc, 0);
5360 
5361         nr_ddrec++;
5362     }
5363     ASSERT_EQ(rc, 0);
5364 
5365     EXPECT_EQ(nr_ddrec, 1);
5366     EXPECT_EQ(nr_ddrec_desc, 1);
5367 
5368     static const std::array<const char*, 2> component_versions = {
5369         "v0.2",
5370         "v2.0",
5371     };
5372     static const std::array<pldm_package_component_image_information, 2>
5373         expected_infos{{{0x000a,
5374                          0x0000,
5375                          0xffffffff,
5376                          {0},
5377                          {1},
5378                          {nullptr, 1},
5379                          0x01,
5380                          {nullptr, 0},
5381                          {nullptr, 0}},
5382                         {0x000a,
5383                          0x0000,
5384                          0xffffffff,
5385                          {0},
5386                          {1},
5387                          {nullptr, 1},
5388                          0x01,
5389                          {nullptr, 0},
5390                          {nullptr, 0}}}};
5391     static const std::array<uint8_t, 2> expected_images{0x5a, 0xa5};
5392 
5393     foreach_pldm_package_component_image_information(iter, info, rc)
5394     {
5395         const struct pldm_package_component_image_information* expected;
5396         const char* version;
5397         uint8_t image;
5398 
5399         expected = &expected_infos.at(nr_infos);
5400         version = component_versions.at(nr_infos);
5401         image = expected_images.at(nr_infos);
5402 
5403         EXPECT_EQ(info.component_classification,
5404                   expected->component_classification);
5405         EXPECT_EQ(info.component_identifier, expected->component_identifier);
5406         EXPECT_EQ(info.component_comparison_stamp,
5407                   expected->component_comparison_stamp);
5408         EXPECT_EQ(info.component_options.value,
5409                   expected->component_options.value);
5410         EXPECT_EQ(info.requested_component_activation_method.value,
5411                   expected->requested_component_activation_method.value);
5412         EXPECT_NE(info.component_image.ptr, expected->component_image.ptr);
5413         EXPECT_EQ(info.component_image.length,
5414                   expected->component_image.length);
5415         EXPECT_EQ(*info.component_image.ptr, image);
5416         EXPECT_EQ(info.component_version_string_type,
5417                   expected->component_version_string_type);
5418         ASSERT_EQ(info.component_version_string.length, 4);
5419         EXPECT_EQ(memcmp(version, info.component_version_string.ptr,
5420                          info.component_version_string.length),
5421                   0);
5422 
5423         nr_infos++;
5424     }
5425     ASSERT_EQ(rc, 0);
5426 
5427     EXPECT_EQ(nr_infos, 2);
5428 }
5429 #endif
5430 
5431 #ifdef LIBPLDM_API_TESTING
TEST(DecodePldmFirmwareUpdatePackage,v3h1fd1fdd1dd1ddd2cii)5432 TEST(DecodePldmFirmwareUpdatePackage, v3h1fd1fdd1dd1ddd2cii)
5433 {
5434     const std::array<uint8_t, 166> package{
5435         0x31, 0x19, 0xce, 0x2f, 0xe8, 0x0a, 0x4a, 0x99, 0xaf, 0x6d, 0x46, 0xf8,
5436         0xb1, 0x21, 0xf6, 0xbf, 0x03, 0xA4, 0x00, 0x00, 0xe9, 0x07, 0x03, 0x0b,
5437         0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08, 0x00, 0x01, 0x04,
5438         't',  'e',  's',  't',
5439 
5440         0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
5441         0x01, 'v',  '0',  '.',  '1',  0x01, 0x00, 0x04, 0x00, 0x9c, 0x01, 0x00,
5442         0x00,
5443 
5444         0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
5445         0x02, 'v',  '1',  '.',  '0',  0x01, 0x00, 0x04, 0x00, 0x9c, 0x01, 0x00,
5446         0x00,
5447 
5448         0x02, 0x00,
5449 
5450         0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
5451         0xA4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v',  '0',
5452         '.',  '2',  0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
5453 
5454         0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
5455         0xA5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v',  '2',
5456         '.',  '0',  0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
5457 
5458         0xed, 0x9d, 0x97, 0x7a,
5459 
5460         0x5a,
5461 
5462         0xa5,
5463 
5464     };
5465 
5466     struct pldm_package_downstream_device_id_record ddrec;
5467     struct pldm_package_component_image_information info;
5468     struct pldm_package_firmware_device_id_record fdrec;
5469     DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR03H(pin);
5470     pldm_package_header_information_pad hdr;
5471     struct pldm_package_iter iter;
5472     int nr_fdrec_desc = 0;
5473     int nr_ddrec_desc = 0;
5474     int nr_fdrec = 0;
5475     int nr_ddrec = 0;
5476     int nr_infos = 0;
5477     int rc;
5478 
5479     rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5480                                              &pin, &hdr, &iter);
5481     ASSERT_EQ(rc, 0);
5482 
5483     EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_2.data(),
5484                      hdr.package_header_identifier,
5485                      PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_2.size()),
5486               0);
5487     EXPECT_EQ(hdr.package_header_format_revision, 3);
5488 
5489     static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5490                                                    0x16, 0x03, 0x00, 0x00, 0x00,
5491                                                    0x00, 0x76, 0x02};
5492     ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5493     EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5494                      timestamp.size()),
5495               0);
5496 
5497     EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5498     EXPECT_EQ(hdr.package_version_string_type, 1);
5499     ASSERT_EQ(hdr.package_version_string.length, 4);
5500     EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5501                      hdr.package_version_string.length),
5502               0);
5503     EXPECT_NE(hdr.areas.ptr, nullptr);
5504     EXPECT_NE(hdr.areas.length, 0);
5505     EXPECT_NE(hdr.package.ptr, nullptr);
5506     EXPECT_NE(hdr.package.length, 0);
5507 
5508     foreach_pldm_package_firmware_device_id_record(iter, fdrec, rc)
5509     {
5510         struct pldm_descriptor desc;
5511 
5512         EXPECT_EQ(fdrec.descriptor_count, 1);
5513         EXPECT_EQ(fdrec.device_update_option_flags.value, 0);
5514         EXPECT_EQ(fdrec.component_image_set_version_string_type, 1);
5515         ASSERT_EQ(fdrec.component_image_set_version_string.length, 4);
5516         EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5517                          fdrec.component_image_set_version_string.length),
5518                   0);
5519         ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1);
5520         EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1);
5521         EXPECT_NE(fdrec.record_descriptors.length, 0);
5522         EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5523         ASSERT_EQ(fdrec.firmware_device_package_data.length, 0);
5524 
5525         foreach_pldm_package_firmware_device_id_record_descriptor(iter, fdrec,
5526                                                                   desc, rc)
5527         {
5528             static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5529 
5530             EXPECT_EQ(desc.descriptor_type, 1);
5531             ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5532             EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5533                              sizeof(iana_pen_dmtf)),
5534                       0);
5535 
5536             nr_fdrec_desc++;
5537         }
5538         ASSERT_EQ(rc, 0);
5539 
5540         nr_fdrec++;
5541     }
5542     ASSERT_EQ(rc, 0);
5543 
5544     EXPECT_EQ(nr_fdrec, 1);
5545     EXPECT_EQ(nr_fdrec_desc, 1);
5546 
5547     foreach_pldm_package_downstream_device_id_record(iter, ddrec, rc)
5548     {
5549         struct pldm_descriptor desc;
5550 
5551         EXPECT_EQ(ddrec.descriptor_count, 1);
5552         EXPECT_EQ(ddrec.update_option_flags.value, 0);
5553         EXPECT_EQ(ddrec.self_contained_activation_min_version_string_type, 1);
5554         ASSERT_EQ(ddrec.self_contained_activation_min_version_string.length, 4);
5555         EXPECT_EQ(
5556             memcmp("v1.0",
5557                    ddrec.self_contained_activation_min_version_string.ptr,
5558                    ddrec.self_contained_activation_min_version_string.length),
5559             0);
5560         EXPECT_EQ(ddrec.self_contained_activation_min_version_comparison_stamp,
5561                   0);
5562         ASSERT_EQ(ddrec.applicable_components.bitmap.length, 1);
5563         EXPECT_EQ(*ddrec.applicable_components.bitmap.ptr, 2);
5564         EXPECT_NE(ddrec.record_descriptors.length, 0);
5565         EXPECT_NE(ddrec.record_descriptors.ptr, nullptr);
5566         EXPECT_EQ(ddrec.package_data.length, 0);
5567 
5568         foreach_pldm_package_downstream_device_id_record_descriptor(iter, ddrec,
5569                                                                     desc, rc)
5570         {
5571             static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5572 
5573             EXPECT_EQ(desc.descriptor_type, 1);
5574             ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5575             EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5576                              sizeof(iana_pen_dmtf)),
5577                       0);
5578 
5579             nr_ddrec_desc++;
5580         }
5581         ASSERT_EQ(rc, 0);
5582 
5583         nr_ddrec++;
5584     }
5585     ASSERT_EQ(rc, 0);
5586 
5587     EXPECT_EQ(nr_ddrec, 1);
5588     EXPECT_EQ(nr_ddrec_desc, 1);
5589 
5590     static const std::array<const char*, 2> component_versions = {
5591         "v0.2",
5592         "v2.0",
5593     };
5594 
5595     static std::array<uint8_t, 4> expected_opaque_data = {0x12, 0x34, 0x56,
5596                                                           0x78};
5597 
5598     static const std::array<pldm_package_component_image_information, 2>
5599         expected_infos{
5600             {{0x000a,
5601               0x0000,
5602               0xffffffff,
5603               {0},
5604               {1},
5605               {nullptr, 1},
5606               0x01,
5607               {nullptr, 0},
5608               {expected_opaque_data.data(), expected_opaque_data.size()}},
5609              {0x000a,
5610               0x0000,
5611               0xffffffff,
5612               {0},
5613               {1},
5614               {nullptr, 1},
5615               0x01,
5616               {nullptr, 0},
5617               {expected_opaque_data.data(), expected_opaque_data.size()}}}};
5618     static const std::array<uint8_t, 2> expected_images{0x5a, 0xa5};
5619 
5620     foreach_pldm_package_component_image_information(iter, info, rc)
5621     {
5622         const struct pldm_package_component_image_information* expected;
5623         const char* version;
5624         uint8_t image;
5625 
5626         expected = &expected_infos.at(nr_infos);
5627         version = component_versions.at(nr_infos);
5628         image = expected_images.at(nr_infos);
5629 
5630         EXPECT_EQ(info.component_classification,
5631                   expected->component_classification);
5632         EXPECT_EQ(info.component_identifier, expected->component_identifier);
5633         EXPECT_EQ(info.component_comparison_stamp,
5634                   expected->component_comparison_stamp);
5635         EXPECT_EQ(info.component_options.value,
5636                   expected->component_options.value);
5637         EXPECT_EQ(info.requested_component_activation_method.value,
5638                   expected->requested_component_activation_method.value);
5639         EXPECT_NE(info.component_image.ptr, expected->component_image.ptr);
5640         EXPECT_EQ(info.component_image.length,
5641                   expected->component_image.length);
5642         EXPECT_EQ(*info.component_image.ptr, image);
5643         EXPECT_EQ(info.component_version_string_type,
5644                   expected->component_version_string_type);
5645         ASSERT_EQ(info.component_version_string.length, 4);
5646         EXPECT_EQ(memcmp(version, info.component_version_string.ptr,
5647                          info.component_version_string.length),
5648                   0);
5649         EXPECT_EQ(info.component_opaque_data.length,
5650                   expected->component_opaque_data.length);
5651         EXPECT_EQ(memcmp(info.component_opaque_data.ptr,
5652                          expected->component_opaque_data.ptr,
5653                          expected->component_opaque_data.length),
5654                   0);
5655         nr_infos++;
5656     }
5657     ASSERT_EQ(rc, 0);
5658 
5659     EXPECT_EQ(nr_infos, 2);
5660 }
5661 #endif
5662 
5663 #ifdef LIBPLDM_API_TESTING
TEST(DecodePldmFirmwareUpdatePackage,v4h1fd1fdd1dd1ddd2cii)5664 TEST(DecodePldmFirmwareUpdatePackage, v4h1fd1fdd1dd1ddd2cii)
5665 {
5666     const std::array<uint8_t, 182> package{
5667         0x7B, 0x29, 0x1C, 0x99, 0x6D, 0xB6, 0x42, 0x08, 0x80, 0x1B, 0x02, 0x02,
5668         0x6E, 0x46, 0x3C, 0x78, 0x04, 0xB4, 0x00, 0x00, 0xe9, 0x07, 0x03, 0x0b,
5669         0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08, 0x00, 0x01, 0x04,
5670         't',  'e',  's',  't',
5671 
5672         0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
5673         0x02, 0x00, 0x00, 0x00, 0x01, 'v',  '0',  '.',  '1',  0x01, 0x00, 0x04,
5674         0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
5675 
5676         0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
5677         0x02, 0x00, 0x00, 0x00, 0x02, 'v',  '1',  '.',  '0',  0x01, 0x00, 0x04,
5678         0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
5679 
5680         0x02, 0x00,
5681 
5682         0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
5683         0xB4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v',  '0',
5684         '.',  '2',  0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
5685 
5686         0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
5687         0xB5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v',  '2',
5688         '.',  '0',  0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
5689 
5690         0xf7, 0xf7, 0xfd, 0x79,
5691 
5692         0x46, 0xf0, 0x31, 0xa7,
5693 
5694         0x5a,
5695 
5696         0xa5,
5697 
5698     };
5699 
5700     struct pldm_package_downstream_device_id_record ddrec;
5701     struct pldm_package_component_image_information info;
5702     struct pldm_package_firmware_device_id_record fdrec;
5703     DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR04H(pin);
5704     pldm_package_header_information_pad hdr;
5705     struct pldm_package_iter iter;
5706     int nr_fdrec_desc = 0;
5707     int nr_ddrec_desc = 0;
5708     int nr_fdrec = 0;
5709     int nr_ddrec = 0;
5710     int nr_infos = 0;
5711     int rc;
5712 
5713     rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5714                                              &pin, &hdr, &iter);
5715     ASSERT_EQ(rc, 0);
5716 
5717     EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_3.data(),
5718                      hdr.package_header_identifier,
5719                      PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_3.size()),
5720               0);
5721     EXPECT_EQ(hdr.package_header_format_revision, 4);
5722 
5723     static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5724                                                    0x16, 0x03, 0x00, 0x00, 0x00,
5725                                                    0x00, 0x76, 0x02};
5726     ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5727     EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5728                      timestamp.size()),
5729               0);
5730 
5731     EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5732     EXPECT_EQ(hdr.package_version_string_type, 1);
5733     ASSERT_EQ(hdr.package_version_string.length, 4);
5734     EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5735                      hdr.package_version_string.length),
5736               0);
5737     EXPECT_NE(hdr.areas.ptr, nullptr);
5738     EXPECT_NE(hdr.areas.length, 0);
5739     EXPECT_NE(hdr.package.ptr, nullptr);
5740     EXPECT_NE(hdr.package.length, 0);
5741 
5742     foreach_pldm_package_firmware_device_id_record(iter, fdrec, rc)
5743     {
5744         struct pldm_descriptor desc;
5745 
5746         static const uint8_t expected_reference_manifest_data[] = {0x87, 0x65};
5747 
5748         EXPECT_EQ(fdrec.descriptor_count, 1);
5749         EXPECT_EQ(fdrec.device_update_option_flags.value, 0);
5750         EXPECT_EQ(fdrec.component_image_set_version_string_type, 1);
5751         ASSERT_EQ(fdrec.component_image_set_version_string.length, 4);
5752         EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5753                          fdrec.component_image_set_version_string.length),
5754                   0);
5755         ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1);
5756         EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1);
5757         EXPECT_NE(fdrec.record_descriptors.length, 0);
5758         EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5759         ASSERT_EQ(fdrec.firmware_device_package_data.length, 0);
5760         EXPECT_EQ(fdrec.reference_manifest_data.length,
5761                   sizeof(expected_reference_manifest_data));
5762         EXPECT_EQ(memcmp(fdrec.reference_manifest_data.ptr,
5763                          expected_reference_manifest_data,
5764                          sizeof(expected_reference_manifest_data)),
5765                   0);
5766         foreach_pldm_package_firmware_device_id_record_descriptor(iter, fdrec,
5767                                                                   desc, rc)
5768         {
5769             static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5770 
5771             EXPECT_EQ(desc.descriptor_type, 1);
5772             ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5773             EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5774                              sizeof(iana_pen_dmtf)),
5775                       0);
5776 
5777             nr_fdrec_desc++;
5778         }
5779         ASSERT_EQ(rc, 0);
5780 
5781         nr_fdrec++;
5782     }
5783     ASSERT_EQ(rc, 0);
5784 
5785     EXPECT_EQ(nr_fdrec, 1);
5786     EXPECT_EQ(nr_fdrec_desc, 1);
5787 
5788     foreach_pldm_package_downstream_device_id_record(iter, ddrec, rc)
5789     {
5790         struct pldm_descriptor desc;
5791 
5792         static const uint8_t expected_reference_manifest_data[] = {0x87, 0x65};
5793 
5794         EXPECT_EQ(ddrec.descriptor_count, 1);
5795         EXPECT_EQ(ddrec.update_option_flags.value, 0);
5796         EXPECT_EQ(ddrec.self_contained_activation_min_version_string_type, 1);
5797         ASSERT_EQ(ddrec.self_contained_activation_min_version_string.length, 4);
5798         EXPECT_EQ(
5799             memcmp("v1.0",
5800                    ddrec.self_contained_activation_min_version_string.ptr,
5801                    ddrec.self_contained_activation_min_version_string.length),
5802             0);
5803         EXPECT_EQ(ddrec.self_contained_activation_min_version_comparison_stamp,
5804                   0);
5805         ASSERT_EQ(ddrec.applicable_components.bitmap.length, 1);
5806         EXPECT_EQ(*ddrec.applicable_components.bitmap.ptr, 2);
5807         EXPECT_NE(ddrec.record_descriptors.length, 0);
5808         EXPECT_NE(ddrec.record_descriptors.ptr, nullptr);
5809         EXPECT_EQ(ddrec.package_data.length, 0);
5810         EXPECT_EQ(fdrec.reference_manifest_data.length,
5811                   sizeof(expected_reference_manifest_data));
5812         EXPECT_EQ(memcmp(fdrec.reference_manifest_data.ptr,
5813                          expected_reference_manifest_data,
5814                          sizeof(expected_reference_manifest_data)),
5815                   0);
5816 
5817         foreach_pldm_package_downstream_device_id_record_descriptor(iter, ddrec,
5818                                                                     desc, rc)
5819         {
5820             static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5821 
5822             EXPECT_EQ(desc.descriptor_type, 1);
5823             ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5824             EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5825                              sizeof(iana_pen_dmtf)),
5826                       0);
5827 
5828             nr_ddrec_desc++;
5829         }
5830         ASSERT_EQ(rc, 0);
5831 
5832         nr_ddrec++;
5833     }
5834     ASSERT_EQ(rc, 0);
5835 
5836     EXPECT_EQ(nr_ddrec, 1);
5837     EXPECT_EQ(nr_ddrec_desc, 1);
5838 
5839     static const std::array<const char*, 2> component_versions = {
5840         "v0.2",
5841         "v2.0",
5842     };
5843 
5844     static std::array<uint8_t, 4> expected_opaque_data = {0x12, 0x34, 0x56,
5845                                                           0x78};
5846 
5847     static const std::array<pldm_package_component_image_information, 2>
5848         expected_infos{
5849             {{0x000a,
5850               0x0000,
5851               0xffffffff,
5852               {0},
5853               {1},
5854               {nullptr, 1},
5855               0x01,
5856               {nullptr, 0},
5857               {expected_opaque_data.data(), expected_opaque_data.size()}},
5858              {0x000a,
5859               0x0000,
5860               0xffffffff,
5861               {0},
5862               {1},
5863               {nullptr, 1},
5864               0x01,
5865               {nullptr, 0},
5866               {expected_opaque_data.data(), expected_opaque_data.size()}}}};
5867     static const std::array<uint8_t, 2> expected_images{0x5a, 0xa5};
5868 
5869     foreach_pldm_package_component_image_information(iter, info, rc)
5870     {
5871         const struct pldm_package_component_image_information* expected;
5872         const char* version;
5873         uint8_t image;
5874 
5875         expected = &expected_infos.at(nr_infos);
5876         version = component_versions.at(nr_infos);
5877         image = expected_images.at(nr_infos);
5878 
5879         EXPECT_EQ(info.component_classification,
5880                   expected->component_classification);
5881         EXPECT_EQ(info.component_identifier, expected->component_identifier);
5882         EXPECT_EQ(info.component_comparison_stamp,
5883                   expected->component_comparison_stamp);
5884         EXPECT_EQ(info.component_options.value,
5885                   expected->component_options.value);
5886         EXPECT_EQ(info.requested_component_activation_method.value,
5887                   expected->requested_component_activation_method.value);
5888         EXPECT_NE(info.component_image.ptr, expected->component_image.ptr);
5889         EXPECT_EQ(info.component_image.length,
5890                   expected->component_image.length);
5891         EXPECT_EQ(*info.component_image.ptr, image);
5892         EXPECT_EQ(info.component_version_string_type,
5893                   expected->component_version_string_type);
5894         ASSERT_EQ(info.component_version_string.length, 4);
5895         EXPECT_EQ(memcmp(version, info.component_version_string.ptr,
5896                          info.component_version_string.length),
5897                   0);
5898         EXPECT_EQ(info.component_opaque_data.length,
5899                   expected->component_opaque_data.length);
5900         EXPECT_EQ(memcmp(info.component_opaque_data.ptr,
5901                          expected->component_opaque_data.ptr,
5902                          expected->component_opaque_data.length),
5903                   0);
5904 
5905         nr_infos++;
5906     }
5907     ASSERT_EQ(rc, 0);
5908 
5909     EXPECT_EQ(nr_infos, 2);
5910 }
5911 #endif