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