xref: /openbmc/libpldm/tests/dsp/firmware_update.cpp (revision c6837f00be70b3aac2c654d5e399f57a652452ae)
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 
TEST(UpdateComponent,goodPathEncodeRequest)3496 TEST(UpdateComponent, goodPathEncodeRequest)
3497 {
3498     constexpr uint8_t instanceId = 2;
3499     constexpr uint16_t compIdentifier = 500;
3500     constexpr uint8_t compClassificationIndex = 50;
3501     constexpr uint32_t compComparisonStamp = 0x89abcdef;
3502     constexpr uint32_t compImageSize = 4096;
3503     constexpr bitfield32_t updateOptionFlags{1};
3504     constexpr std::string_view compVerStr = "OpenBmcv2.2";
3505     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3506     variable_field compVerStrInfo{};
3507     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3508     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3509     compVerStrInfo.length = compVerStrLen;
3510 
3511     std::array<uint8_t,
3512                hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3513         request{};
3514     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3515     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3516 
3517     auto rc = encode_update_component_req(
3518         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3519         compComparisonStamp, compImageSize, updateOptionFlags,
3520         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3521         sizeof(pldm_update_component_req) + compVerStrLen);
3522     EXPECT_EQ(rc, PLDM_SUCCESS);
3523 
3524     std::array<uint8_t,
3525                hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3526         outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
3527                    0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
3528                    0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
3529                    0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
3530     EXPECT_EQ(request, outRequest);
3531 
3532 #ifdef LIBPLDM_API_TESTING
3533     /* Check the roundtrip */
3534     struct pldm_update_component_req_full req;
3535     PLDM_MSG_DEFINE_P(dec, outRequest.size());
3536     std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3537     rc = decode_update_component_req(dec, outRequest.size() - hdrSize, &req);
3538     ASSERT_EQ(rc, 0);
3539 
3540     EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3541     EXPECT_EQ(req.comp_identifier, compIdentifier);
3542     EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3543     EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3544     EXPECT_EQ(req.comp_image_size, compImageSize);
3545     EXPECT_EQ(req.update_option_flags.value, updateOptionFlags.value);
3546     EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3547     EXPECT_EQ(req.version.str_len, compVerStrLen);
3548     EXPECT_TRUE(std::equal(req.version.str_data,
3549                            req.version.str_data + req.version.str_len,
3550                            compVerStr.data()));
3551 #endif
3552 }
3553 
TEST(UpdateComponent,errorPathEncodeRequest)3554 TEST(UpdateComponent, errorPathEncodeRequest)
3555 {
3556     constexpr uint8_t instanceId = 2;
3557     constexpr uint16_t compIdentifier = 500;
3558     constexpr uint8_t compClassificationIndex = 50;
3559     constexpr uint32_t compComparisonStamp = 0x89abcdef;
3560     constexpr uint32_t compImageSize = 4096;
3561     constexpr bitfield32_t updateOptionFlags{1};
3562     constexpr std::string_view compVerStr = "OpenBmcv2.2";
3563     constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3564     variable_field compVerStrInfo{};
3565     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3566     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3567     compVerStrInfo.length = compVerStrLen;
3568 
3569     std::array<uint8_t,
3570                hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3571         request{};
3572     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3573     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3574 
3575     auto rc = encode_update_component_req(
3576         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3577         compComparisonStamp, compImageSize, updateOptionFlags,
3578         PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
3579         sizeof(pldm_update_component_req) + compVerStrLen);
3580     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3581 
3582     compVerStrInfo.ptr = nullptr;
3583     rc = encode_update_component_req(
3584         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3585         compComparisonStamp, compImageSize, updateOptionFlags,
3586         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3587         sizeof(pldm_update_component_req) + compVerStrLen);
3588     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3589     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3590     compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3591 
3592     rc = encode_update_component_req(
3593         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3594         compComparisonStamp, compImageSize, updateOptionFlags,
3595         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
3596         sizeof(pldm_update_component_req) + compVerStrLen);
3597     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3598 
3599     rc = encode_update_component_req(
3600         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3601         compComparisonStamp, compImageSize, updateOptionFlags,
3602         PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3603         sizeof(pldm_update_component_req));
3604     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3605 
3606     rc = encode_update_component_req(
3607         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3608         compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
3609         compVerStrLen, &compVerStrInfo, requestMsg,
3610         sizeof(pldm_update_component_req) + compVerStrLen);
3611     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3612 
3613     rc = encode_update_component_req(
3614         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3615         compComparisonStamp, compImageSize, updateOptionFlags,
3616         PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg,
3617         sizeof(pldm_update_component_req) + compVerStrLen);
3618     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3619 
3620     rc = encode_update_component_req(
3621         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3622         compComparisonStamp, compImageSize, updateOptionFlags,
3623         PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg,
3624         sizeof(pldm_update_component_req) + compVerStrLen);
3625     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3626 
3627     rc = encode_update_component_req(
3628         instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3629         compComparisonStamp, compImageSize, updateOptionFlags,
3630         PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
3631         sizeof(pldm_update_component_req) + compVerStrLen);
3632     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3633 }
3634 
TEST(UpdateComponent,goodPathDecodeResponse)3635 TEST(UpdateComponent, goodPathDecodeResponse)
3636 {
3637     constexpr std::bitset<32> forceUpdateComp{1};
3638     constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
3639     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3640         updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3641                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3642     auto responseMsg1 =
3643         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3644         reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3645 
3646     uint8_t completionCode = 0;
3647     uint8_t compCompatibilityResp = 0;
3648     uint8_t compCompatibilityRespCode = 0;
3649     bitfield32_t updateOptionFlagsEnabled{};
3650     uint16_t timeBeforeReqFWData = 0;
3651 
3652     auto rc = decode_update_component_resp(
3653         responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
3654         &compCompatibilityResp, &compCompatibilityRespCode,
3655         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3656 
3657     EXPECT_EQ(rc, PLDM_SUCCESS);
3658     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3659     EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
3660     EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
3661     EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
3662     EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
3663 
3664     constexpr std::bitset<32> noFlags{};
3665     constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
3666     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3667         updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3668                                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3669     auto responseMsg2 =
3670         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3671         reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3672     rc = decode_update_component_resp(
3673         responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3674         &compCompatibilityResp, &compCompatibilityRespCode,
3675         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3676 
3677     EXPECT_EQ(rc, PLDM_SUCCESS);
3678     EXPECT_EQ(completionCode, PLDM_SUCCESS);
3679     EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
3680     EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
3681     EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
3682     EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
3683 
3684     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3685         updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
3686     auto responseMsg3 =
3687         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3688         reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3689 
3690     rc = decode_update_component_resp(
3691         responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3692         &compCompatibilityResp, &compCompatibilityRespCode,
3693         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3694 
3695     EXPECT_EQ(rc, PLDM_SUCCESS);
3696     EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3697 }
3698 
TEST(UpdateComponent,errorPathDecodeResponse)3699 TEST(UpdateComponent, errorPathDecodeResponse)
3700 {
3701     constexpr std::array<uint8_t,
3702                          hdrSize + sizeof(pldm_update_component_resp) - 1>
3703         updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3704                                  0x00, 0x00, 0x00, 0x00, 0x00};
3705     auto responseMsg1 =
3706         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3707         reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3708 
3709     uint8_t completionCode = 0;
3710     uint8_t compCompatibilityResp = 0;
3711     uint8_t compCompatibilityRespCode = 0;
3712     bitfield32_t updateOptionFlagsEnabled{};
3713     uint16_t timeBeforeReqFWData = 0;
3714 
3715     auto rc = decode_update_component_resp(
3716         nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
3717         &compCompatibilityResp, &compCompatibilityRespCode,
3718         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3719     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3720 
3721     rc = decode_update_component_resp(
3722         responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
3723         &compCompatibilityResp, &compCompatibilityRespCode,
3724         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3725     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3726 
3727     rc = decode_update_component_resp(
3728         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3729         nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3730         &timeBeforeReqFWData);
3731     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3732 
3733     rc = decode_update_component_resp(
3734         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3735         &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
3736         &timeBeforeReqFWData);
3737     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3738 
3739     rc = decode_update_component_resp(
3740         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3741         &compCompatibilityResp, &compCompatibilityRespCode, nullptr,
3742         &timeBeforeReqFWData);
3743     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3744 
3745     rc = decode_update_component_resp(
3746         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3747         &compCompatibilityResp, &compCompatibilityRespCode,
3748         &updateOptionFlagsEnabled, nullptr);
3749     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3750 
3751     rc = decode_update_component_resp(
3752         responseMsg1, 0, &completionCode, &compCompatibilityResp,
3753         &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3754         &timeBeforeReqFWData);
3755     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3756 
3757     rc = decode_update_component_resp(
3758         responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3759         &compCompatibilityResp, &compCompatibilityRespCode,
3760         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3761     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3762 
3763     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3764         updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
3765                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3766     auto responseMsg2 =
3767         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3768         reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3769     rc = decode_update_component_resp(
3770         responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3771         &compCompatibilityResp, &compCompatibilityRespCode,
3772         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3773     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3774 
3775     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3776         updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
3777                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3778     auto responseMsg3 =
3779         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3780         reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3781     rc = decode_update_component_resp(
3782         responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3783         &compCompatibilityResp, &compCompatibilityRespCode,
3784         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3785     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3786 
3787     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3788         updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
3789                                  0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3790     auto responseMsg4 =
3791         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3792         reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
3793     rc = decode_update_component_resp(
3794         responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
3795         &compCompatibilityResp, &compCompatibilityRespCode,
3796         &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3797     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3798 }
3799 
TEST(RequestFirmwareData,goodPathDecodeRequest)3800 TEST(RequestFirmwareData, goodPathDecodeRequest)
3801 {
3802     constexpr uint32_t offset = 300;
3803     constexpr uint32_t length = 255;
3804     constexpr std::array<uint8_t,
3805                          hdrSize + sizeof(pldm_request_firmware_data_req)>
3806         reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3807                      0x00, 0xff, 0x00, 0x00, 0x00};
3808     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3809     auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3810 
3811     uint32_t outOffset = 0;
3812     uint32_t outLength = 0;
3813     auto rc = decode_request_firmware_data_req(
3814         requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3815         &outLength);
3816 
3817     EXPECT_EQ(rc, PLDM_SUCCESS);
3818     EXPECT_EQ(outOffset, offset);
3819     EXPECT_EQ(outLength, length);
3820 }
3821 
TEST(RequestFirmwareData,errorPathDecodeRequest)3822 TEST(RequestFirmwareData, errorPathDecodeRequest)
3823 {
3824     constexpr std::array<uint8_t,
3825                          hdrSize + sizeof(pldm_request_firmware_data_req)>
3826         reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3827                      0x00, 0x1f, 0x00, 0x00, 0x00};
3828     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3829     auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3830 
3831     uint32_t outOffset = 0;
3832     uint32_t outLength = 0;
3833     auto rc = decode_request_firmware_data_req(
3834         nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
3835         &outLength);
3836     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3837 
3838     rc = decode_request_firmware_data_req(
3839         requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
3840         &outLength);
3841     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3842 
3843     rc = decode_request_firmware_data_req(
3844         requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3845         nullptr);
3846     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3847 
3848     rc = decode_request_firmware_data_req(
3849         requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
3850         &outLength);
3851     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3852 
3853     rc = decode_request_firmware_data_req(
3854         requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3855         &outLength);
3856     EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
3857 }
3858 
TEST(RequestFirmwareData,goodPathEncodeResponse)3859 TEST(RequestFirmwareData, goodPathEncodeResponse)
3860 {
3861     constexpr uint8_t instanceId = 3;
3862     constexpr uint8_t completionCode = PLDM_SUCCESS;
3863     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
3864                                       PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3865         outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
3866                               0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3867                               0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3868                               0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3869                               0x1d, 0x1e, 0x1f, 0x20};
3870     std::array<uint8_t, hdrSize + sizeof(completionCode) +
3871                             PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3872         reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
3873                            0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3874                            0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3875                            0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3876                            0x1d, 0x1e, 0x1f, 0x20};
3877     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3878     auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
3879     auto rc = encode_request_firmware_data_resp(
3880         instanceId, completionCode, responseMsg1,
3881         sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
3882     EXPECT_EQ(rc, PLDM_SUCCESS);
3883     EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
3884 
3885     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3886         outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
3887     std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
3888         0x00, 0x00, 0x00, 0x00};
3889     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3890     auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
3891     rc = encode_request_firmware_data_resp(
3892         instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
3893         sizeof(completionCode));
3894     EXPECT_EQ(rc, PLDM_SUCCESS);
3895     EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
3896 }
3897 
TEST(RequestFirmwareData,errorPathEncodeResponse)3898 TEST(RequestFirmwareData, errorPathEncodeResponse)
3899 {
3900     std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
3901     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3902     auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
3903     auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
3904     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3905 
3906     rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
3907     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3908 }
3909 
TEST(TransferComplete,goodPathDecodeRequest)3910 TEST(TransferComplete, goodPathDecodeRequest)
3911 {
3912     constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
3913     constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3914         transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
3915     auto requestMsg1 =
3916         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3917         reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
3918     uint8_t outTransferResult = 0;
3919 
3920     auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
3921                                            &outTransferResult);
3922     EXPECT_EQ(rc, PLDM_SUCCESS);
3923     EXPECT_EQ(outTransferResult, transferResult);
3924 
3925     constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3926         transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
3927     auto requestMsg2 =
3928         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3929         reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
3930     rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
3931                                       &outTransferResult);
3932     EXPECT_EQ(rc, PLDM_SUCCESS);
3933     EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
3934 }
3935 
TEST(TransferComplete,errorPathDecodeRequest)3936 TEST(TransferComplete, errorPathDecodeRequest)
3937 {
3938     constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
3939                                                                0x00};
3940     auto requestMsg =
3941         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3942         reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
3943     uint8_t outTransferResult = 0;
3944 
3945     auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
3946     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3947 
3948     rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
3949     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3950 
3951     rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
3952     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3953 }
3954 
TEST(TransferComplete,goodPathEncodeResponse)3955 TEST(TransferComplete, goodPathEncodeResponse)
3956 {
3957     constexpr uint8_t instanceId = 4;
3958     constexpr uint8_t completionCode = PLDM_SUCCESS;
3959     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3960         outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
3961     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3962         transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3963     auto responseMsg1 =
3964         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3965         reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
3966     auto rc = encode_transfer_complete_resp(
3967         instanceId, completionCode, responseMsg1, sizeof(completionCode));
3968     EXPECT_EQ(rc, PLDM_SUCCESS);
3969     EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
3970 
3971     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3972         outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
3973     std::array<uint8_t, hdrSize + sizeof(completionCode)>
3974         transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3975     auto responseMsg2 =
3976         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3977         reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
3978     rc = encode_transfer_complete_resp(instanceId,
3979                                        PLDM_FWUP_COMMAND_NOT_EXPECTED,
3980                                        responseMsg2, sizeof(completionCode));
3981     EXPECT_EQ(rc, PLDM_SUCCESS);
3982     EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
3983 }
3984 
TEST(TransferComplete,errorPathEncodeResponse)3985 TEST(TransferComplete, errorPathEncodeResponse)
3986 {
3987     std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
3988     auto responseMsg =
3989         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3990         reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
3991     auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3992     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3993 
3994     rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3995     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3996 }
3997 
TEST(VerifyComplete,goodPathDecodeRequest)3998 TEST(VerifyComplete, goodPathDecodeRequest)
3999 {
4000     constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
4001     constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
4002         verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
4003     auto requestMsg1 =
4004         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4005         reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
4006     uint8_t outVerifyResult = 0;
4007 
4008     auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
4009                                          &outVerifyResult);
4010     EXPECT_EQ(rc, PLDM_SUCCESS);
4011     EXPECT_EQ(outVerifyResult, verifyResult);
4012 
4013     constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
4014         verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
4015     auto requestMsg2 =
4016         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4017         reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
4018     rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
4019                                     &outVerifyResult);
4020     EXPECT_EQ(rc, PLDM_SUCCESS);
4021     EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
4022 }
4023 
TEST(VerifyComplete,errorPathDecodeRequest)4024 TEST(VerifyComplete, errorPathDecodeRequest)
4025 {
4026     constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
4027     auto requestMsg =
4028         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4029         reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
4030     uint8_t outVerifyResult = 0;
4031 
4032     auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
4033     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4034 
4035     rc = decode_verify_complete_req(requestMsg, 0, nullptr);
4036     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4037 
4038     rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);
4039     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4040 }
4041 
TEST(VerifyComplete,goodPathEncodeResponse)4042 TEST(VerifyComplete, goodPathEncodeResponse)
4043 {
4044     constexpr uint8_t instanceId = 5;
4045     constexpr uint8_t completionCode = PLDM_SUCCESS;
4046     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4047         outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};
4048     std::array<uint8_t, hdrSize + sizeof(completionCode)>
4049         verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
4050     auto responseMsg1 =
4051         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4052         reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());
4053     auto rc = encode_verify_complete_resp(instanceId, completionCode,
4054                                           responseMsg1, sizeof(completionCode));
4055     EXPECT_EQ(rc, PLDM_SUCCESS);
4056     EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);
4057 
4058     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4059         outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88};
4060     std::array<uint8_t, hdrSize + sizeof(completionCode)>
4061         verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
4062     auto responseMsg2 =
4063         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4064         reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());
4065     rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
4066                                      responseMsg2, sizeof(completionCode));
4067     EXPECT_EQ(rc, PLDM_SUCCESS);
4068     EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);
4069 }
4070 
TEST(VerifyComplete,errorPathEncodeResponse)4071 TEST(VerifyComplete, errorPathEncodeResponse)
4072 {
4073     std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00};
4074     auto responseMsg =
4075         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4076         reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());
4077     auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
4078     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4079 
4080     rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
4081     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4082 }
4083 
TEST(ApplyComplete,goodPathDecodeRequest)4084 TEST(ApplyComplete, goodPathDecodeRequest)
4085 {
4086     constexpr uint8_t applyResult1 =
4087         PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
4088     // DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
4089     constexpr std::bitset<16> compActivationModification1{0x30};
4090     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4091         applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
4092     auto requestMsg1 =
4093         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4094         reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
4095     uint8_t outApplyResult = 0;
4096     bitfield16_t outCompActivationModification{};
4097     auto rc = decode_apply_complete_req(
4098         requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
4099         &outCompActivationModification);
4100     EXPECT_EQ(rc, PLDM_SUCCESS);
4101     EXPECT_EQ(outApplyResult, applyResult1);
4102     EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
4103 
4104     constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
4105     constexpr std::bitset<16> compActivationModification2{};
4106     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4107         applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4108     auto requestMsg2 =
4109         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4110         reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
4111     rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
4112                                    &outApplyResult,
4113                                    &outCompActivationModification);
4114     EXPECT_EQ(rc, PLDM_SUCCESS);
4115     EXPECT_EQ(outApplyResult, applyResult2);
4116     EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
4117 }
4118 
TEST(ApplyComplete,errorPathDecodeRequest)4119 TEST(ApplyComplete, errorPathDecodeRequest)
4120 {
4121     constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
4122     auto requestMsg1 =
4123         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4124         reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
4125     uint8_t outApplyResult = 0;
4126     bitfield16_t outCompActivationModification{};
4127 
4128     auto rc = decode_apply_complete_req(
4129         nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
4130         &outCompActivationModification);
4131     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4132 
4133     rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
4134                                    nullptr, &outCompActivationModification);
4135     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4136 
4137     rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
4138                                    &outApplyResult, nullptr);
4139     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4140 
4141     rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
4142                                    &outCompActivationModification);
4143     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4144 
4145     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4146         applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
4147     auto requestMsg2 =
4148         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4149         reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
4150     rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
4151                                    &outApplyResult,
4152                                    &outCompActivationModification);
4153     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4154 }
4155 
TEST(ApplyComplete,goodPathEncodeResponse)4156 TEST(ApplyComplete, goodPathEncodeResponse)
4157 {
4158     constexpr uint8_t instanceId = 6;
4159     constexpr uint8_t completionCode = PLDM_SUCCESS;
4160     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4161         outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
4162     std::array<uint8_t, hdrSize + sizeof(completionCode)>
4163         applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
4164     auto responseMsg1 =
4165         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4166         reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
4167     auto rc = encode_apply_complete_resp(instanceId, completionCode,
4168                                          responseMsg1, sizeof(completionCode));
4169     EXPECT_EQ(rc, PLDM_SUCCESS);
4170     EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
4171 
4172     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4173         outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
4174     std::array<uint8_t, hdrSize + sizeof(completionCode)>
4175         applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
4176     auto responseMsg2 =
4177         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4178         reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
4179     rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
4180                                     responseMsg2, sizeof(completionCode));
4181     EXPECT_EQ(rc, PLDM_SUCCESS);
4182     EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
4183 }
4184 
TEST(ApplyComplete,errorPathEncodeResponse)4185 TEST(ApplyComplete, errorPathEncodeResponse)
4186 {
4187     std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
4188     auto responseMsg =
4189         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4190         reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
4191     auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
4192     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4193 
4194     rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
4195     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4196 }
4197 
TEST(ActivateFirmware,goodPathEncodeRequest)4198 TEST(ActivateFirmware, goodPathEncodeRequest)
4199 {
4200     constexpr uint8_t instanceId = 7;
4201 
4202     std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
4203     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4204     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4205 
4206     auto rc = encode_activate_firmware_req(
4207         instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
4208         sizeof(pldm_activate_firmware_req));
4209     EXPECT_EQ(rc, PLDM_SUCCESS);
4210 
4211     std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
4212         outRequest{0x87, 0x05, 0x1a, 0x01};
4213     EXPECT_EQ(request, outRequest);
4214 }
4215 
TEST(ActivateFirmware,errorPathEncodeRequest)4216 TEST(ActivateFirmware, errorPathEncodeRequest)
4217 {
4218     std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
4219     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4220     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4221 
4222     auto rc = encode_activate_firmware_req(
4223         0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
4224         sizeof(pldm_activate_firmware_req));
4225     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4226 
4227     rc = encode_activate_firmware_req(
4228         0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
4229     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4230 
4231     rc = encode_activate_firmware_req(0, 2, requestMsg,
4232                                       sizeof(pldm_activate_firmware_req));
4233     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4234 }
4235 
TEST(ActivateFirmware,goodPathDecodeResponse)4236 TEST(ActivateFirmware, goodPathDecodeResponse)
4237 {
4238     constexpr uint16_t estimatedTimeForActivation100s = 100;
4239     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
4240         activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
4241     auto responseMsg1 =
4242         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4243         reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
4244 
4245     uint8_t completionCode = 0;
4246     uint16_t estimatedTimeForActivation = 0;
4247 
4248     auto rc = decode_activate_firmware_resp(
4249         responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
4250         &estimatedTimeForActivation);
4251 
4252     EXPECT_EQ(rc, PLDM_SUCCESS);
4253     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4254     EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
4255 
4256     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4257         activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
4258     auto responseMsg2 =
4259         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4260         reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data());
4261 
4262     rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
4263                                        &completionCode,
4264                                        &estimatedTimeForActivation);
4265 
4266     EXPECT_EQ(rc, PLDM_SUCCESS);
4267     EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
4268 }
4269 
TEST(ActivateFirmware,errorPathDecodeResponse)4270 TEST(ActivateFirmware, errorPathDecodeResponse)
4271 {
4272     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
4273         activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4274     auto responseMsg =
4275         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4276         reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
4277 
4278     uint8_t completionCode = 0;
4279     uint16_t estimatedTimeForActivation = 0;
4280 
4281     auto rc = decode_activate_firmware_resp(
4282         nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
4283         &estimatedTimeForActivation);
4284     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4285 
4286     rc = decode_activate_firmware_resp(responseMsg,
4287                                        sizeof(pldm_activate_firmware_resp),
4288                                        nullptr, &estimatedTimeForActivation);
4289     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4290 
4291     rc = decode_activate_firmware_resp(responseMsg,
4292                                        sizeof(pldm_activate_firmware_resp),
4293                                        &completionCode, nullptr);
4294     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4295 
4296     rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
4297                                        &estimatedTimeForActivation);
4298     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4299 
4300     rc = decode_activate_firmware_resp(
4301         responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
4302         &estimatedTimeForActivation);
4303     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4304 }
4305 
TEST(GetStatus,goodPathEncodeRequest)4306 TEST(GetStatus, goodPathEncodeRequest)
4307 {
4308     constexpr uint8_t instanceId = 8;
4309     std::array<uint8_t, hdrSize> request{};
4310     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4311     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4312 
4313     auto rc = encode_get_status_req(instanceId, requestMsg,
4314                                     PLDM_GET_STATUS_REQ_BYTES);
4315     EXPECT_EQ(rc, PLDM_SUCCESS);
4316 
4317     constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
4318     EXPECT_EQ(request, outRequest);
4319 }
4320 
TEST(GetStatus,errorPathEncodeRequest)4321 TEST(GetStatus, errorPathEncodeRequest)
4322 {
4323     std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
4324     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4325     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4326 
4327     auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
4328     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4329 
4330     rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);
4331     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4332 }
4333 
TEST(GetStatus,goodPathDecodeResponse)4334 TEST(GetStatus, goodPathDecodeResponse)
4335 {
4336     constexpr std::bitset<32> updateOptionFlagsEnabled1{0};
4337     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4338         getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
4339                            0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};
4340     auto responseMsg1 =
4341         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4342         reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4343 
4344     uint8_t completionCode = 0;
4345     uint8_t currentState = 0;
4346     uint8_t previousState = 0;
4347     uint8_t auxState = 0;
4348     uint8_t auxStateStatus = 0;
4349     uint8_t progressPercent = 0;
4350     uint8_t reasonCode = 0;
4351     bitfield32_t updateOptionFlagsEnabled{0};
4352 
4353     auto rc = decode_get_status_resp(
4354         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4355         &currentState, &previousState, &auxState, &auxStateStatus,
4356         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4357 
4358     EXPECT_EQ(rc, PLDM_SUCCESS);
4359     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4360     EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);
4361     EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4362     EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);
4363     EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);
4364     EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);
4365     EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4366     EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);
4367 
4368     // Bit position 0 - Force update of component – FD will perform a force
4369     // update of the component.
4370     constexpr std::bitset<32> updateOptionFlagsEnabled2{1};
4371     constexpr uint8_t progressPercent2 = 50;
4372     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4373         getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,
4374                            0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};
4375     auto responseMsg2 =
4376         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4377         reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4378 
4379     rc = decode_get_status_resp(
4380         responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4381         &currentState, &previousState, &auxState, &auxStateStatus,
4382         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4383 
4384     EXPECT_EQ(rc, PLDM_SUCCESS);
4385     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4386     EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);
4387     EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4388     EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);
4389     EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);
4390     EXPECT_EQ(progressPercent, progressPercent2);
4391     EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4392     EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);
4393 
4394 #ifdef LIBPLDM_API_TESTING
4395     /* Check the roundtrip */
4396     PLDM_MSG_DEFINE_P(enc, 1000);
4397     size_t enc_payload_len = 1000;
4398     const struct pldm_get_status_resp status_enc = {
4399         .completion_code = PLDM_SUCCESS,
4400         .current_state = currentState,
4401         .previous_state = previousState,
4402         .aux_state = auxState,
4403         .aux_state_status = auxStateStatus,
4404         .progress_percent = progressPercent,
4405         .reason_code = reasonCode,
4406         .update_option_flags_enabled = updateOptionFlagsEnabled,
4407     };
4408     rc = encode_get_status_resp(FIXED_INSTANCE_ID, &status_enc, enc,
4409                                 &enc_payload_len);
4410     EXPECT_EQ(rc, PLDM_SUCCESS);
4411     EXPECT_EQ(enc_payload_len + hdrSize, getStatusResponse2.size());
4412     EXPECT_TRUE(std::equal(getStatusResponse2.begin() + hdrSize,
4413                            getStatusResponse2.end(), enc_buf + hdrSize));
4414     check_response(enc, PLDM_GET_STATUS);
4415 #endif
4416 
4417     /* Check a not-ready completion code */
4418     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4419         getStatusResponse3{0x00, 0x00, 0x00, 0x04};
4420     auto responseMsg3 =
4421         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4422         reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4423     rc = decode_get_status_resp(
4424         responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4425         &currentState, &previousState, &auxState, &auxStateStatus,
4426         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4427     EXPECT_EQ(rc, PLDM_SUCCESS);
4428     EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);
4429 }
4430 
TEST(GetStatus,errorPathDecodeResponse)4431 TEST(GetStatus, errorPathDecodeResponse)
4432 {
4433     uint8_t completionCode = 0;
4434     uint8_t currentState = 0;
4435     uint8_t previousState = 0;
4436     uint8_t auxState = 0;
4437     uint8_t auxStateStatus = 0;
4438     uint8_t progressPercent = 0;
4439     uint8_t reasonCode = 0;
4440     bitfield32_t updateOptionFlagsEnabled{0};
4441 
4442     constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};
4443     auto responseMsg1 =
4444         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4445         reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4446 
4447     auto rc = decode_get_status_resp(
4448         nullptr, getStatusResponse1.size() - hdrSize, &completionCode,
4449         &currentState, &previousState, &auxState, &auxStateStatus,
4450         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4451     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4452 
4453     rc = decode_get_status_resp(
4454         responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,
4455         &currentState, &previousState, &auxState, &auxStateStatus,
4456         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4457     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4458 
4459     rc = decode_get_status_resp(
4460         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4461         nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,
4462         &reasonCode, &updateOptionFlagsEnabled);
4463     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4464 
4465     rc = decode_get_status_resp(
4466         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4467         &currentState, nullptr, &auxState, &auxStateStatus, &progressPercent,
4468         &reasonCode, &updateOptionFlagsEnabled);
4469     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4470 
4471     rc = decode_get_status_resp(
4472         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4473         &currentState, &previousState, nullptr, &auxStateStatus,
4474         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4475     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4476 
4477     rc = decode_get_status_resp(
4478         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4479         &currentState, &previousState, &auxState, nullptr, &progressPercent,
4480         &reasonCode, &updateOptionFlagsEnabled);
4481     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4482 
4483     rc = decode_get_status_resp(
4484         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4485         &currentState, &previousState, &auxState, &auxStateStatus, nullptr,
4486         &reasonCode, &updateOptionFlagsEnabled);
4487     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4488 
4489     rc = decode_get_status_resp(
4490         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4491         &currentState, &previousState, &auxState, &auxStateStatus,
4492         &progressPercent, nullptr, &updateOptionFlagsEnabled);
4493     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4494 
4495     rc = decode_get_status_resp(
4496         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4497         &currentState, &previousState, &auxState, &auxStateStatus,
4498         &progressPercent, &reasonCode, nullptr);
4499     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4500 
4501     rc = decode_get_status_resp(
4502         responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4503         &currentState, &previousState, &auxState, &auxStateStatus,
4504         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4505     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4506 
4507     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>
4508         getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4509                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4510     auto responseMsg2 =
4511         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4512         reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4513     rc = decode_get_status_resp(
4514         responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4515         &currentState, &previousState, &auxState, &auxStateStatus,
4516         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4517     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4518 
4519     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4520         getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
4521                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4522     auto responseMsg3 =
4523         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4524         reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4525     rc = decode_get_status_resp(
4526         responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4527         &currentState, &previousState, &auxState, &auxStateStatus,
4528         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4529     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4530 
4531     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4532         getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
4533                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4534     auto responseMsg4 =
4535         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4536         reinterpret_cast<const pldm_msg*>(getStatusResponse4.data());
4537     rc = decode_get_status_resp(
4538         responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,
4539         &currentState, &previousState, &auxState, &auxStateStatus,
4540         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4541     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4542 
4543     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4544         getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
4545                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4546     auto responseMsg5 =
4547         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4548         reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());
4549     rc = decode_get_status_resp(
4550         responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,
4551         &currentState, &previousState, &auxState, &auxStateStatus,
4552         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4553     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4554 
4555     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4556         getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4557                            0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4558     auto responseMsg6 =
4559         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4560         reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());
4561     rc = decode_get_status_resp(
4562         responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,
4563         &currentState, &previousState, &auxState, &auxStateStatus,
4564         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4565     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4566 
4567     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4568         getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4569                            0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
4570     auto responseMsg7 =
4571         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4572         reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());
4573     rc = decode_get_status_resp(
4574         responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,
4575         &currentState, &previousState, &auxState, &auxStateStatus,
4576         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4577     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4578 
4579     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4580         getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4581                            0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00};
4582     auto responseMsg8 =
4583         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4584         reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());
4585     rc = decode_get_status_resp(
4586         responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,
4587         &currentState, &previousState, &auxState, &auxStateStatus,
4588         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4589     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4590 
4591     // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is
4592     // IDLE
4593     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4594         getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
4595                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4596     auto responseMsg9 =
4597         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4598         reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());
4599     rc = decode_get_status_resp(
4600         responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,
4601         &currentState, &previousState, &auxState, &auxStateStatus,
4602         &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4603     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4604 }
4605 
TEST(CancelUpdateComponent,goodPathEncodeRequest)4606 TEST(CancelUpdateComponent, goodPathEncodeRequest)
4607 {
4608     constexpr uint8_t instanceId = 9;
4609     std::array<uint8_t, hdrSize> request{};
4610     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4611     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4612 
4613     auto rc = encode_cancel_update_component_req(
4614         instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4615     EXPECT_EQ(rc, PLDM_SUCCESS);
4616 
4617     constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
4618     EXPECT_EQ(request, outRequest);
4619 }
4620 
TEST(CancelUpdateComponent,errorPathEncodeRequest)4621 TEST(CancelUpdateComponent, errorPathEncodeRequest)
4622 {
4623     std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
4624     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4625     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4626 
4627     auto rc = encode_cancel_update_component_req(
4628         0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4629     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4630 
4631     rc = encode_cancel_update_component_req(
4632         0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);
4633     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4634 }
4635 
TEST(CancelUpdateComponent,testGoodDecodeResponse)4636 TEST(CancelUpdateComponent, testGoodDecodeResponse)
4637 {
4638     uint8_t completionCode = 0;
4639     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4640         cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};
4641     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4642     auto responseMsg1 = reinterpret_cast<const pldm_msg*>(
4643         cancelUpdateComponentResponse1.data());
4644     auto rc = decode_cancel_update_component_resp(
4645         responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,
4646         &completionCode);
4647     EXPECT_EQ(rc, PLDM_SUCCESS);
4648     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4649 
4650     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4651         cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};
4652     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4653     auto responseMsg2 = reinterpret_cast<const pldm_msg*>(
4654         cancelUpdateComponentResponse2.data());
4655     rc = decode_cancel_update_component_resp(
4656         responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,
4657         &completionCode);
4658     EXPECT_EQ(rc, PLDM_SUCCESS);
4659     EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4660 }
4661 
TEST(CancelUpdateComponent,testBadDecodeResponse)4662 TEST(CancelUpdateComponent, testBadDecodeResponse)
4663 {
4664     uint8_t completionCode = 0;
4665     constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{
4666         0x00, 0x00, 0x00};
4667     auto responseMsg =
4668         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4669         reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data());
4670 
4671     auto rc = decode_cancel_update_component_resp(
4672         nullptr, cancelUpdateComponentResponse.size() - hdrSize,
4673         &completionCode);
4674     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4675 
4676     rc = decode_cancel_update_component_resp(
4677         responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);
4678     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4679 
4680     rc = decode_cancel_update_component_resp(
4681         responseMsg, cancelUpdateComponentResponse.size() - hdrSize,
4682         &completionCode);
4683     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4684 }
4685 
TEST(CancelUpdate,goodPathEncodeRequest)4686 TEST(CancelUpdate, goodPathEncodeRequest)
4687 {
4688     constexpr uint8_t instanceId = 10;
4689     std::array<uint8_t, hdrSize> request{};
4690     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4691     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4692 
4693     auto rc = encode_cancel_update_req(instanceId, requestMsg,
4694                                        PLDM_CANCEL_UPDATE_REQ_BYTES);
4695     EXPECT_EQ(rc, PLDM_SUCCESS);
4696 
4697     constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
4698     EXPECT_EQ(request, outRequest);
4699 }
4700 
TEST(CancelUpdate,errorPathEncodeRequest)4701 TEST(CancelUpdate, errorPathEncodeRequest)
4702 {
4703     std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
4704     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4705     auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4706 
4707     auto rc =
4708         encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
4709     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4710 
4711     rc = encode_cancel_update_req(0, requestMsg,
4712                                   PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
4713     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4714 }
4715 
TEST(CancelUpdate,goodPathDecodeResponse)4716 TEST(CancelUpdate, goodPathDecodeResponse)
4717 {
4718     constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
4719     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4720         cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4721                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4722     auto responseMsg1 =
4723         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4724         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4725     uint8_t completionCode = 0;
4726     bool8_t nonFunctioningComponentIndication = 0;
4727     bitfield64_t nonFunctioningComponentBitmap{0};
4728     auto rc = decode_cancel_update_resp(
4729         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4730         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4731     EXPECT_EQ(rc, PLDM_SUCCESS);
4732     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4733     EXPECT_EQ(nonFunctioningComponentIndication,
4734               PLDM_FWUP_COMPONENTS_FUNCTIONING);
4735     EXPECT_EQ(nonFunctioningComponentBitmap.value,
4736               nonFunctioningComponentBitmap1);
4737 
4738     constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
4739     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4740         cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
4741                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4742     auto responseMsg2 =
4743         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4744         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4745     rc = decode_cancel_update_resp(
4746         responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4747         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4748     EXPECT_EQ(rc, PLDM_SUCCESS);
4749     EXPECT_EQ(completionCode, PLDM_SUCCESS);
4750     EXPECT_EQ(nonFunctioningComponentIndication,
4751               PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING);
4752     EXPECT_EQ(nonFunctioningComponentBitmap.value,
4753               nonFunctioningComponentBitmap2);
4754 
4755     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4756         cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
4757     auto responseMsg3 =
4758         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4759         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4760     rc = decode_cancel_update_resp(
4761         responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4762         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4763     EXPECT_EQ(rc, PLDM_SUCCESS);
4764     EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4765 }
4766 
TEST(CancelUpdate,errorPathDecodeResponse)4767 TEST(CancelUpdate, errorPathDecodeResponse)
4768 {
4769     constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
4770                                                                  0x00};
4771     auto responseMsg1 =
4772         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4773         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4774     uint8_t completionCode = 0;
4775     bool8_t nonFunctioningComponentIndication = 0;
4776     bitfield64_t nonFunctioningComponentBitmap{0};
4777 
4778     auto rc = decode_cancel_update_resp(
4779         nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4780         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4781     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4782 
4783     rc = decode_cancel_update_resp(
4784         responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
4785         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4786     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4787 
4788     rc = decode_cancel_update_resp(
4789         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4790         nullptr, &nonFunctioningComponentBitmap);
4791     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4792 
4793     rc = decode_cancel_update_resp(
4794         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4795         &nonFunctioningComponentIndication, nullptr);
4796     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4797 
4798     rc = decode_cancel_update_resp(
4799         responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4800         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4801     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4802 
4803     constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4804         cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
4805     auto responseMsg2 =
4806         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4807         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4808     rc = decode_cancel_update_resp(
4809         responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4810         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4811     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4812 
4813     constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4814         cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
4815                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4816     auto responseMsg3 =
4817         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4818         reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4819     rc = decode_cancel_update_resp(
4820         responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4821         &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4822     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4823 }
4824 
TEST(DecodePldmFirmwareUpdatePackage,badArguments)4825 TEST(DecodePldmFirmwareUpdatePackage, badArguments)
4826 {
4827     DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
4828     pldm_package_header_information_pad hdr;
4829     struct pldm_package pkg{};
4830     uint8_t data = 0;
4831     int rc;
4832 
4833     rc = decode_pldm_firmware_update_package(nullptr, 0, &pin, &hdr, &pkg, 0);
4834     EXPECT_EQ(rc, -EINVAL);
4835 
4836     rc = decode_pldm_firmware_update_package(&data, sizeof(data), nullptr, &hdr,
4837                                              &pkg, 0);
4838     EXPECT_EQ(rc, -EINVAL);
4839 
4840     rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, nullptr,
4841                                              &pkg, 0);
4842     EXPECT_EQ(rc, -EINVAL);
4843 
4844     rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, &hdr,
4845                                              nullptr, 0);
4846     EXPECT_EQ(rc, -EINVAL);
4847 
4848     rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, &hdr,
4849                                              &pkg, UINT32_MAX);
4850     EXPECT_EQ(rc, -EINVAL);
4851 }
4852 
TEST(DecodePldmFirmwareUpdatePackage,unsupportedPinVersion)4853 TEST(DecodePldmFirmwareUpdatePackage, unsupportedPinVersion)
4854 {
4855     const struct pldm_package_format_pin pin = {
4856         .meta =
4857             {
4858                 .magic = 0,
4859                 .version = UINT8_MAX,
4860             },
4861         .format =
4862             {
4863                 .identifier = {0},
4864                 .revision = 0,
4865             },
4866     };
4867 
4868     pldm_package_header_information_pad hdr;
4869     struct pldm_package pkg{};
4870     uint8_t data = 0;
4871     int rc;
4872 
4873     rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, &hdr,
4874                                              &pkg, 0);
4875     EXPECT_EQ(rc, -ENOTSUP);
4876 }
4877 
TEST(DecodePldmFirmwareUpdatePackage,badPinRevision)4878 TEST(DecodePldmFirmwareUpdatePackage, badPinRevision)
4879 {
4880     const struct pldm_package_format_pin lowPin = {
4881         .meta =
4882             {
4883                 .magic = 0,
4884                 .version = 0,
4885             },
4886         .format =
4887             {
4888                 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4889                 .revision = 0,
4890             },
4891     };
4892 
4893     const struct pldm_package_format_pin highPin = {
4894         .meta =
4895             {
4896                 .magic = 0,
4897                 .version = 0,
4898             },
4899         .format =
4900             {
4901                 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4902                 .revision = 3,
4903             },
4904     };
4905 
4906     pldm_package_header_information_pad hdr;
4907     struct pldm_package pkg{};
4908     uint8_t data = 0;
4909     int rc;
4910 
4911     rc = decode_pldm_firmware_update_package(&data, sizeof(data), &lowPin, &hdr,
4912                                              &pkg, 0);
4913     EXPECT_EQ(rc, -EINVAL);
4914 
4915     rc = decode_pldm_firmware_update_package(&data, sizeof(data), &highPin,
4916                                              &hdr, &pkg, 0);
4917     EXPECT_EQ(rc, -ENOTSUP);
4918 }
4919 
TEST(DecodePldmFirmwareUpdatePackage,badPinMagic)4920 TEST(DecodePldmFirmwareUpdatePackage, badPinMagic)
4921 {
4922     const struct pldm_package_format_pin lowPin = {
4923         .meta =
4924             {
4925                 .magic = 0,
4926                 .version = 0,
4927             },
4928         .format =
4929             {
4930                 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4931                 .revision = 2,
4932             },
4933     };
4934 
4935     const struct pldm_package_format_pin highPin = {
4936         .meta =
4937             {
4938                 .magic = UINT32_MAX,
4939                 .version = 0,
4940             },
4941         .format =
4942             {
4943                 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4944                 .revision = 2,
4945             },
4946     };
4947 
4948     pldm_package_header_information_pad hdr;
4949     struct pldm_package pkg{};
4950     uint8_t data = 0;
4951     int rc;
4952 
4953     rc = decode_pldm_firmware_update_package(&data, sizeof(data), &lowPin, &hdr,
4954                                              &pkg, 0);
4955     EXPECT_EQ(rc, -EINVAL);
4956 
4957     rc = decode_pldm_firmware_update_package(&data, sizeof(data), &highPin,
4958                                              &hdr, &pkg, 0);
4959     EXPECT_EQ(rc, -EINVAL);
4960 }
4961 
TEST(DecodePldmFirmwareUpdatePackage,unsupportedPinIdentifier)4962 TEST(DecodePldmFirmwareUpdatePackage, unsupportedPinIdentifier)
4963 {
4964     const struct pldm_package_format_pin pin = {
4965         .meta =
4966             {
4967                 .magic =
4968                     LIBPLDM_SIZEAT(struct pldm_package, iter) +
4969                     LIBPLDM_SIZEAT(struct pldm__package_header_information,
4970                                    package_version_string) +
4971                     LIBPLDM_SIZEAT(
4972                         struct pldm_package_firmware_device_id_record,
4973                         firmware_device_package_data) +
4974                     LIBPLDM_SIZEAT(struct pldm_descriptor, descriptor_data) +
4975                     LIBPLDM_SIZEAT(
4976                         struct pldm_package_downstream_device_id_record,
4977                         package_data) +
4978                     LIBPLDM_SIZEAT(
4979                         struct pldm_package_component_image_information,
4980                         component_version_string),
4981                 .version = 0,
4982             },
4983         .format =
4984             {
4985                 .identifier = {0},
4986                 .revision = PLDM_PACKAGE_HEADER_FORMAT_REVISION_FR02H,
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,oldConsumer)5000 TEST(DecodePldmFirmwareUpdatePackage, oldConsumer)
5001 {
5002     /* Package format revision 2 header */
5003     const std::array<uint8_t, 150> package{
5004         0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
5005         0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5a, 0x02, 0x94, 0x00, 0x00,
5006         0xe9, 0x07, 0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00,
5007         0x76, 0x02, 0x08, 0x00, 0x01, 0x04, 't',  'e',  's',  't',
5008     };
5009 
5010     /* Package format revision 1 consumer */
5011     DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR01H(pin);
5012 
5013     pldm_package_header_information_pad hdr;
5014     struct pldm_package pkg{};
5015     int rc;
5016 
5017     rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5018                                              &pin, &hdr, &pkg, 0);
5019     EXPECT_EQ(rc, -ENOTSUP);
5020 }
5021 
TEST(DecodePldmFirmwareUpdatePackage,v1h1fd1fdd1cii)5022 TEST(DecodePldmFirmwareUpdatePackage, v1h1fd1fdd1cii)
5023 {
5024     const std::array<uint8_t, 102> package{
5025         0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
5026         0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x65, 0x00, 0x00, 0xe9, 0x07,
5027         0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08,
5028         0x00, 0x01, 0x04, 't',  'e',  's',  't',
5029 
5030         0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00,
5031         0x00, 0x01, 'v',  '0',  '.',  '1',  0x01, 0x00, 0x04, 0x00, 0x9c,
5032         0x01, 0x00, 0x00,
5033 
5034         0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
5035         0x00, 0x01, 0x00, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5036         0x01, 0x04, 'v',  '0',  '.',  '2',  0x00, 0x00, 0x00, 0x00,
5037 
5038         0xb5, 0x3f, 0xf6, 0x6a,
5039 
5040         0x5a,
5041     };
5042 
5043     struct pldm_package_component_image_information info;
5044     struct pldm_package_firmware_device_id_record fdrec;
5045     DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR01H(pin);
5046     pldm_package_header_information_pad hdr;
5047     struct pldm_package pkg{};
5048     int nr_fdrec_desc = 0;
5049     int nr_fdrec = 0;
5050     int nr_infos = 0;
5051     int rc;
5052 
5053     rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5054                                              &pin, &hdr, &pkg, 0);
5055     ASSERT_EQ(rc, 0);
5056 
5057     EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.data(),
5058                      hdr.package_header_identifier,
5059                      PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.size()),
5060               0);
5061     EXPECT_EQ(hdr.package_header_format_revision, 1);
5062 
5063     static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5064                                                    0x16, 0x03, 0x00, 0x00, 0x00,
5065                                                    0x00, 0x76, 0x02};
5066     ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5067     EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5068                      timestamp.size()),
5069               0);
5070 
5071     EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5072     EXPECT_EQ(hdr.package_version_string_type, 1);
5073     ASSERT_EQ(hdr.package_version_string.length, 4ul);
5074     EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5075                      hdr.package_version_string.length),
5076               0);
5077     EXPECT_NE(pkg.areas.ptr, nullptr);
5078     EXPECT_NE(pkg.areas.length, 0ul);
5079     EXPECT_NE(pkg.package.ptr, nullptr);
5080     EXPECT_NE(pkg.package.length, 0ul);
5081 
5082     foreach_pldm_package_firmware_device_id_record(pkg, fdrec, rc)
5083     {
5084         struct pldm_descriptor desc;
5085 
5086         EXPECT_EQ(fdrec.descriptor_count, 1u);
5087         EXPECT_EQ(fdrec.device_update_option_flags.value, 0u);
5088         EXPECT_EQ(fdrec.component_image_set_version_string_type, 1u);
5089         ASSERT_EQ(fdrec.component_image_set_version_string.length, 4ul);
5090         EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5091                          fdrec.component_image_set_version_string.length),
5092                   0);
5093         ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1ul);
5094         EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1u);
5095         EXPECT_NE(fdrec.record_descriptors.length, 0ul);
5096         EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5097         ASSERT_EQ(fdrec.firmware_device_package_data.length, 0ul);
5098 
5099         foreach_pldm_package_firmware_device_id_record_descriptor(pkg, fdrec,
5100                                                                   desc, rc)
5101         {
5102             static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5103 
5104             EXPECT_EQ(desc.descriptor_type, 1ul);
5105             ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5106             EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5107                              sizeof(iana_pen_dmtf)),
5108                       0);
5109 
5110             nr_fdrec_desc++;
5111         }
5112         ASSERT_EQ(rc, 0);
5113 
5114         nr_fdrec++;
5115     }
5116     ASSERT_EQ(rc, 0);
5117 
5118     EXPECT_EQ(nr_fdrec, 1);
5119     EXPECT_EQ(nr_fdrec_desc, 1);
5120 
5121     static const pldm_package_component_image_information expected_info{
5122         0x000a,       0x0000, 0xffffffff,   {0},         {1},
5123         {nullptr, 1}, 0x01,   {nullptr, 0}, {nullptr, 0}};
5124 
5125     foreach_pldm_package_component_image_information(pkg, info, rc)
5126     {
5127         EXPECT_EQ(info.component_classification,
5128                   expected_info.component_classification);
5129         EXPECT_EQ(info.component_identifier,
5130                   expected_info.component_identifier);
5131         EXPECT_EQ(info.component_comparison_stamp,
5132                   expected_info.component_comparison_stamp);
5133         EXPECT_EQ(info.component_options.value,
5134                   expected_info.component_options.value);
5135         EXPECT_EQ(info.requested_component_activation_method.value,
5136                   expected_info.requested_component_activation_method.value);
5137         EXPECT_NE(nullptr, info.component_image.ptr);
5138         EXPECT_EQ(info.component_image.length,
5139                   expected_info.component_image.length);
5140         EXPECT_EQ(info.component_version_string_type,
5141                   expected_info.component_version_string_type);
5142         ASSERT_EQ(info.component_version_string.length, 4ul);
5143         EXPECT_EQ(memcmp("v0.2", info.component_version_string.ptr,
5144                          info.component_version_string.length),
5145                   0);
5146 
5147         nr_infos++;
5148     }
5149     ASSERT_EQ(rc, 0);
5150 
5151     EXPECT_EQ(nr_infos, 1);
5152 }
5153 
TEST(DecodePldmFirmwareUpdatePackage,invalidDownstreamDeviceIteration)5154 TEST(DecodePldmFirmwareUpdatePackage, invalidDownstreamDeviceIteration)
5155 {
5156     const std::array<uint8_t, 102> package{
5157         0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
5158         0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x65, 0x00, 0x00, 0xe9, 0x07,
5159         0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08,
5160         0x00, 0x01, 0x04, 't',  'e',  's',  't',
5161 
5162         0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00,
5163         0x00, 0x01, 'v',  '0',  '.',  '1',  0x01, 0x00, 0x04, 0x00, 0x9c,
5164         0x01, 0x00, 0x00,
5165 
5166         0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
5167         0x00, 0x01, 0x00, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5168         0x01, 0x04, 'v',  '0',  '.',  '2',  0x00, 0x00, 0x00, 0x00,
5169 
5170         0xb5, 0x3f, 0xf6, 0x6a,
5171 
5172         0x5a,
5173     };
5174 
5175     struct pldm_package_downstream_device_id_record ddrec;
5176     struct pldm_package_firmware_device_id_record fdrec;
5177     DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR01H(pin);
5178     pldm_package_header_information_pad hdr;
5179     struct pldm_package pkg{};
5180     int nr_fdrec_desc = 0;
5181     int nr_fdrec = 0;
5182     int rc;
5183 
5184     rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5185                                              &pin, &hdr, &pkg, 0);
5186     ASSERT_EQ(rc, 0);
5187 
5188     EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.data(),
5189                      hdr.package_header_identifier,
5190                      PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.size()),
5191               0);
5192     EXPECT_EQ(hdr.package_header_format_revision, 1);
5193 
5194     static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5195                                                    0x16, 0x03, 0x00, 0x00, 0x00,
5196                                                    0x00, 0x76, 0x02};
5197     ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5198     EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5199                      timestamp.size()),
5200               0);
5201 
5202     EXPECT_EQ(hdr.component_bitmap_bit_length, 8u);
5203     EXPECT_EQ(hdr.package_version_string_type, 1u);
5204     ASSERT_EQ(hdr.package_version_string.length, 4ul);
5205     EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5206                      hdr.package_version_string.length),
5207               0);
5208     EXPECT_NE(pkg.areas.ptr, nullptr);
5209     EXPECT_NE(pkg.areas.length, 0ul);
5210     EXPECT_NE(pkg.package.ptr, nullptr);
5211     EXPECT_NE(pkg.package.length, 0ul);
5212 
5213     foreach_pldm_package_firmware_device_id_record(pkg, fdrec, rc)
5214     {
5215         struct pldm_descriptor desc;
5216 
5217         EXPECT_EQ(fdrec.descriptor_count, 1u);
5218         EXPECT_EQ(fdrec.device_update_option_flags.value, 0u);
5219         EXPECT_EQ(fdrec.component_image_set_version_string_type, 1u);
5220         ASSERT_EQ(fdrec.component_image_set_version_string.length, 4ul);
5221         EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5222                          fdrec.component_image_set_version_string.length),
5223                   0);
5224         ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1ul);
5225         EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1u);
5226         EXPECT_NE(fdrec.record_descriptors.length, 0ul);
5227         EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5228         ASSERT_EQ(fdrec.firmware_device_package_data.length, 0ul);
5229 
5230         foreach_pldm_package_firmware_device_id_record_descriptor(pkg, fdrec,
5231                                                                   desc, rc)
5232         {
5233             static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5234 
5235             EXPECT_EQ(desc.descriptor_type, 1u);
5236             ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5237             EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5238                              sizeof(iana_pen_dmtf)),
5239                       0);
5240 
5241             nr_fdrec_desc++;
5242         }
5243         ASSERT_EQ(rc, 0);
5244 
5245         nr_fdrec++;
5246     }
5247     ASSERT_EQ(rc, 0);
5248 
5249     EXPECT_EQ(nr_fdrec, 1);
5250     EXPECT_EQ(nr_fdrec_desc, 1);
5251 
5252     foreach_pldm_package_downstream_device_id_record(pkg, ddrec, rc)
5253         EXPECT_NE(rc, 0);
5254 }
5255 
TEST(DecodePldmFirmwareUpdatePackage,p2v1h1fd1fdd1cii)5256 TEST(DecodePldmFirmwareUpdatePackage, p2v1h1fd1fdd1cii)
5257 {
5258     const std::array<uint8_t, 102> package{
5259         0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
5260         0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x65, 0x00, 0x00, 0xe9, 0x07,
5261         0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08,
5262         0x00, 0x01, 0x04, 't',  'e',  's',  't',
5263 
5264         0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00,
5265         0x00, 0x01, 'v',  '0',  '.',  '1',  0x01, 0x00, 0x04, 0x00, 0x9c,
5266         0x01, 0x00, 0x00,
5267 
5268         0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
5269         0x00, 0x01, 0x00, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5270         0x01, 0x04, 'v',  '0',  '.',  '2',  0x00, 0x00, 0x00, 0x00,
5271 
5272         0xb5, 0x3f, 0xf6, 0x6a,
5273 
5274         0x5a,
5275     };
5276 
5277     struct pldm_package_downstream_device_id_record ddrec;
5278     struct pldm_package_component_image_information info;
5279     struct pldm_package_firmware_device_id_record fdrec;
5280     DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
5281     pldm_package_header_information_pad hdr;
5282     struct pldm_package pkg{};
5283     int nr_fdrec_desc = 0;
5284     int nr_ddrec_desc = 0;
5285     int nr_fdrec = 0;
5286     int nr_ddrec = 0;
5287     int nr_infos = 0;
5288     int rc;
5289 
5290     rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5291                                              &pin, &hdr, &pkg, 0);
5292     ASSERT_EQ(rc, 0);
5293 
5294     EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.data(),
5295                      hdr.package_header_identifier,
5296                      PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.size()),
5297               0);
5298     EXPECT_EQ(hdr.package_header_format_revision, 1);
5299 
5300     static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5301                                                    0x16, 0x03, 0x00, 0x00, 0x00,
5302                                                    0x00, 0x76, 0x02};
5303     ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5304     EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5305                      timestamp.size()),
5306               0);
5307 
5308     EXPECT_EQ(hdr.component_bitmap_bit_length, 8u);
5309     EXPECT_EQ(hdr.package_version_string_type, 1u);
5310     ASSERT_EQ(hdr.package_version_string.length, 4ul);
5311     EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5312                      hdr.package_version_string.length),
5313               0);
5314     EXPECT_NE(pkg.areas.ptr, nullptr);
5315     EXPECT_NE(pkg.areas.length, 0ul);
5316     EXPECT_NE(pkg.package.ptr, nullptr);
5317     EXPECT_NE(pkg.package.length, 0ul);
5318 
5319     foreach_pldm_package_firmware_device_id_record(pkg, fdrec, rc)
5320     {
5321         struct pldm_descriptor desc;
5322 
5323         EXPECT_EQ(fdrec.descriptor_count, 1u);
5324         EXPECT_EQ(fdrec.device_update_option_flags.value, 0u);
5325         EXPECT_EQ(fdrec.component_image_set_version_string_type, 1u);
5326         ASSERT_EQ(fdrec.component_image_set_version_string.length, 4ul);
5327         EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5328                          fdrec.component_image_set_version_string.length),
5329                   0);
5330         ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1ul);
5331         EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1u);
5332         EXPECT_NE(fdrec.record_descriptors.length, 0ul);
5333         EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5334         ASSERT_EQ(fdrec.firmware_device_package_data.length, 0ul);
5335 
5336         foreach_pldm_package_firmware_device_id_record_descriptor(pkg, fdrec,
5337                                                                   desc, rc)
5338         {
5339             static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5340 
5341             EXPECT_EQ(desc.descriptor_type, 1u);
5342             ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5343             EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5344                              sizeof(iana_pen_dmtf)),
5345                       0);
5346 
5347             nr_fdrec_desc++;
5348         }
5349         ASSERT_EQ(rc, 0);
5350 
5351         nr_fdrec++;
5352     }
5353     ASSERT_EQ(rc, 0);
5354 
5355     EXPECT_EQ(nr_fdrec, 1);
5356     EXPECT_EQ(nr_fdrec_desc, 1);
5357 
5358     foreach_pldm_package_downstream_device_id_record(pkg, ddrec, rc)
5359     {
5360         struct pldm_descriptor desc;
5361 
5362         foreach_pldm_package_downstream_device_id_record_descriptor(pkg, ddrec,
5363                                                                     desc, rc)
5364         {
5365             nr_ddrec_desc++;
5366         }
5367         ASSERT_EQ(rc, 0);
5368 
5369         nr_ddrec++;
5370     }
5371     ASSERT_EQ(rc, 0);
5372 
5373     EXPECT_EQ(nr_ddrec, 0);
5374     EXPECT_EQ(nr_ddrec_desc, 0);
5375 
5376     static const pldm_package_component_image_information expected_info{
5377         0x000a,       0x0000, 0xffffffff,   {0},         {1},
5378         {nullptr, 1}, 0x01,   {nullptr, 0}, {nullptr, 0}};
5379 
5380     foreach_pldm_package_component_image_information(pkg, info, rc)
5381     {
5382         EXPECT_EQ(info.component_classification,
5383                   expected_info.component_classification);
5384         EXPECT_EQ(info.component_identifier,
5385                   expected_info.component_identifier);
5386         EXPECT_EQ(info.component_comparison_stamp,
5387                   expected_info.component_comparison_stamp);
5388         EXPECT_EQ(info.component_options.value,
5389                   expected_info.component_options.value);
5390         EXPECT_EQ(info.requested_component_activation_method.value,
5391                   expected_info.requested_component_activation_method.value);
5392         EXPECT_NE(nullptr, info.component_image.ptr);
5393         EXPECT_EQ(info.component_image.length,
5394                   expected_info.component_image.length);
5395         EXPECT_EQ(info.component_version_string_type,
5396                   expected_info.component_version_string_type);
5397         ASSERT_EQ(info.component_version_string.length, 4ul);
5398         EXPECT_EQ(memcmp("v0.2", info.component_version_string.ptr,
5399                          info.component_version_string.length),
5400                   0);
5401 
5402         nr_infos++;
5403     }
5404     ASSERT_EQ(rc, 0);
5405 
5406     EXPECT_EQ(nr_infos, 1);
5407 }
5408 
TEST(DecodePldmFirmwareUpdatePackage,v2h1fd1fdd1dd1ddd2cii)5409 TEST(DecodePldmFirmwareUpdatePackage, v2h1fd1fdd1dd1ddd2cii)
5410 {
5411     const std::array<uint8_t, 150> package{
5412         0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
5413         0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5a, 0x02, 0x94, 0x00, 0x00,
5414         0xe9, 0x07, 0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00,
5415         0x76, 0x02, 0x08, 0x00, 0x01, 0x04, 't',  'e',  's',  't',
5416 
5417         0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
5418         0x00, 0x00, 0x01, 'v',  '0',  '.',  '1',  0x01, 0x00, 0x04,
5419         0x00, 0x9c, 0x01, 0x00, 0x00,
5420 
5421         0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
5422         0x00, 0x00, 0x02, 'v',  '1',  '.',  '0',  0x01, 0x00, 0x04,
5423         0x00, 0x9c, 0x01, 0x00, 0x00,
5424 
5425         0x02, 0x00,
5426 
5427         0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
5428         0x01, 0x00, 0x94, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5429         0x01, 0x04, 'v',  '0',  '.',  '2',
5430 
5431         0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
5432         0x01, 0x00, 0x95, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5433         0x01, 0x04, 'v',  '2',  '.',  '0',
5434 
5435         0xd3, 0x5c, 0x1c, 0x8a,
5436 
5437         0x5a,
5438 
5439         0xa5,
5440     };
5441     struct pldm_package_downstream_device_id_record ddrec;
5442     struct pldm_package_component_image_information info;
5443     struct pldm_package_firmware_device_id_record fdrec;
5444     DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
5445     pldm_package_header_information_pad hdr;
5446     struct pldm_package pkg{};
5447     int nr_fdrec_desc = 0;
5448     int nr_ddrec_desc = 0;
5449     int nr_fdrec = 0;
5450     int nr_ddrec = 0;
5451     int nr_infos = 0;
5452     int rc;
5453 
5454     rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5455                                              &pin, &hdr, &pkg, 0);
5456     ASSERT_EQ(rc, 0);
5457 
5458     EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_1.data(),
5459                      hdr.package_header_identifier,
5460                      PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_1.size()),
5461               0);
5462     EXPECT_EQ(hdr.package_header_format_revision, 2);
5463 
5464     static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5465                                                    0x16, 0x03, 0x00, 0x00, 0x00,
5466                                                    0x00, 0x76, 0x02};
5467     ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5468     EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5469                      timestamp.size()),
5470               0);
5471 
5472     EXPECT_EQ(hdr.component_bitmap_bit_length, 8u);
5473     EXPECT_EQ(hdr.package_version_string_type, 1u);
5474     ASSERT_EQ(hdr.package_version_string.length, 4ul);
5475     EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5476                      hdr.package_version_string.length),
5477               0);
5478     EXPECT_NE(pkg.areas.ptr, nullptr);
5479     EXPECT_NE(pkg.areas.length, 0ul);
5480     EXPECT_NE(pkg.package.ptr, nullptr);
5481     EXPECT_NE(pkg.package.length, 0ul);
5482 
5483     foreach_pldm_package_firmware_device_id_record(pkg, fdrec, rc)
5484     {
5485         struct pldm_descriptor desc;
5486 
5487         EXPECT_EQ(fdrec.descriptor_count, 1u);
5488         EXPECT_EQ(fdrec.device_update_option_flags.value, 0u);
5489         EXPECT_EQ(fdrec.component_image_set_version_string_type, 1u);
5490         ASSERT_EQ(fdrec.component_image_set_version_string.length, 4ul);
5491         EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5492                          fdrec.component_image_set_version_string.length),
5493                   0);
5494         ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1ul);
5495         EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1u);
5496         EXPECT_NE(fdrec.record_descriptors.length, 0ul);
5497         EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5498         ASSERT_EQ(fdrec.firmware_device_package_data.length, 0ul);
5499 
5500         foreach_pldm_package_firmware_device_id_record_descriptor(pkg, fdrec,
5501                                                                   desc, rc)
5502         {
5503             static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5504 
5505             EXPECT_EQ(desc.descriptor_type, 1u);
5506             ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5507             EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5508                              sizeof(iana_pen_dmtf)),
5509                       0);
5510 
5511             nr_fdrec_desc++;
5512         }
5513         ASSERT_EQ(rc, 0);
5514 
5515         nr_fdrec++;
5516     }
5517     ASSERT_EQ(rc, 0);
5518 
5519     EXPECT_EQ(nr_fdrec, 1);
5520     EXPECT_EQ(nr_fdrec_desc, 1);
5521 
5522     foreach_pldm_package_downstream_device_id_record(pkg, ddrec, rc)
5523     {
5524         struct pldm_descriptor desc;
5525 
5526         EXPECT_EQ(ddrec.descriptor_count, 1u);
5527         EXPECT_EQ(ddrec.update_option_flags.value, 0u);
5528         EXPECT_EQ(ddrec.self_contained_activation_min_version_string_type, 1u);
5529         ASSERT_EQ(ddrec.self_contained_activation_min_version_string.length,
5530                   4ul);
5531         EXPECT_EQ(
5532             memcmp("v1.0",
5533                    ddrec.self_contained_activation_min_version_string.ptr,
5534                    ddrec.self_contained_activation_min_version_string.length),
5535             0);
5536         EXPECT_EQ(ddrec.self_contained_activation_min_version_comparison_stamp,
5537                   0u);
5538         ASSERT_EQ(ddrec.applicable_components.bitmap.length, 1ul);
5539         EXPECT_EQ(*ddrec.applicable_components.bitmap.ptr, 2u);
5540         EXPECT_NE(ddrec.record_descriptors.length, 0ul);
5541         EXPECT_NE(ddrec.record_descriptors.ptr, nullptr);
5542         EXPECT_EQ(ddrec.package_data.length, 0ul);
5543 
5544         foreach_pldm_package_downstream_device_id_record_descriptor(pkg, ddrec,
5545                                                                     desc, rc)
5546         {
5547             static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5548 
5549             EXPECT_EQ(desc.descriptor_type, 1u);
5550             ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5551             EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5552                              sizeof(iana_pen_dmtf)),
5553                       0);
5554 
5555             nr_ddrec_desc++;
5556         }
5557         ASSERT_EQ(rc, 0);
5558 
5559         nr_ddrec++;
5560     }
5561     ASSERT_EQ(rc, 0);
5562 
5563     EXPECT_EQ(nr_ddrec, 1);
5564     EXPECT_EQ(nr_ddrec_desc, 1);
5565 
5566     static const std::array<const char*, 2> component_versions = {
5567         "v0.2",
5568         "v2.0",
5569     };
5570     static const std::array<pldm_package_component_image_information, 2>
5571         expected_infos{{{0x000a,
5572                          0x0000,
5573                          0xffffffff,
5574                          {0},
5575                          {1},
5576                          {nullptr, 1},
5577                          0x01,
5578                          {nullptr, 0},
5579                          {nullptr, 0}},
5580                         {0x000a,
5581                          0x0000,
5582                          0xffffffff,
5583                          {0},
5584                          {1},
5585                          {nullptr, 1},
5586                          0x01,
5587                          {nullptr, 0},
5588                          {nullptr, 0}}}};
5589     static const std::array<uint8_t, 2> expected_images{0x5a, 0xa5};
5590 
5591     foreach_pldm_package_component_image_information(pkg, info, rc)
5592     {
5593         const struct pldm_package_component_image_information* expected;
5594         const char* version;
5595         uint8_t image;
5596 
5597         expected = &expected_infos.at(nr_infos);
5598         version = component_versions.at(nr_infos);
5599         image = expected_images.at(nr_infos);
5600 
5601         EXPECT_EQ(info.component_classification,
5602                   expected->component_classification);
5603         EXPECT_EQ(info.component_identifier, expected->component_identifier);
5604         EXPECT_EQ(info.component_comparison_stamp,
5605                   expected->component_comparison_stamp);
5606         EXPECT_EQ(info.component_options.value,
5607                   expected->component_options.value);
5608         EXPECT_EQ(info.requested_component_activation_method.value,
5609                   expected->requested_component_activation_method.value);
5610         EXPECT_NE(info.component_image.ptr, expected->component_image.ptr);
5611         EXPECT_EQ(info.component_image.length,
5612                   expected->component_image.length);
5613         EXPECT_EQ(*info.component_image.ptr, image);
5614         EXPECT_EQ(info.component_version_string_type,
5615                   expected->component_version_string_type);
5616         ASSERT_EQ(info.component_version_string.length, 4ul);
5617         EXPECT_EQ(memcmp(version, info.component_version_string.ptr,
5618                          info.component_version_string.length),
5619                   0);
5620 
5621         nr_infos++;
5622     }
5623     ASSERT_EQ(rc, 0);
5624 
5625     EXPECT_EQ(nr_infos, 2);
5626 }
5627 
TEST(DecodePldmFirmwareUpdatePackage,v3h1fd1fdd1dd1ddd2cii)5628 TEST(DecodePldmFirmwareUpdatePackage, v3h1fd1fdd1dd1ddd2cii)
5629 {
5630     const std::array<uint8_t, 166> package{
5631         0x31, 0x19, 0xce, 0x2f, 0xe8, 0x0a, 0x4a, 0x99, 0xaf, 0x6d, 0x46, 0xf8,
5632         0xb1, 0x21, 0xf6, 0xbf, 0x03, 0xA4, 0x00, 0x00, 0xe9, 0x07, 0x03, 0x0b,
5633         0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08, 0x00, 0x01, 0x04,
5634         't',  'e',  's',  't',
5635 
5636         0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
5637         0x01, 'v',  '0',  '.',  '1',  0x01, 0x00, 0x04, 0x00, 0x9c, 0x01, 0x00,
5638         0x00,
5639 
5640         0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
5641         0x02, 'v',  '1',  '.',  '0',  0x01, 0x00, 0x04, 0x00, 0x9c, 0x01, 0x00,
5642         0x00,
5643 
5644         0x02, 0x00,
5645 
5646         0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
5647         0xA4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v',  '0',
5648         '.',  '2',  0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
5649 
5650         0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
5651         0xA5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v',  '2',
5652         '.',  '0',  0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
5653 
5654         0xed, 0x9d, 0x97, 0x7a,
5655 
5656         0x5a,
5657 
5658         0xa5,
5659 
5660     };
5661 
5662     struct pldm_package_downstream_device_id_record ddrec;
5663     struct pldm_package_component_image_information info;
5664     struct pldm_package_firmware_device_id_record fdrec;
5665     DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR03H(pin);
5666     pldm_package_header_information_pad hdr;
5667     struct pldm_package pkg{};
5668     int nr_fdrec_desc = 0;
5669     int nr_ddrec_desc = 0;
5670     int nr_fdrec = 0;
5671     int nr_ddrec = 0;
5672     int nr_infos = 0;
5673     int rc;
5674 
5675     rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5676                                              &pin, &hdr, &pkg, 0);
5677     ASSERT_EQ(rc, 0);
5678 
5679     EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_2.data(),
5680                      hdr.package_header_identifier,
5681                      PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_2.size()),
5682               0);
5683     EXPECT_EQ(hdr.package_header_format_revision, 3);
5684 
5685     static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5686                                                    0x16, 0x03, 0x00, 0x00, 0x00,
5687                                                    0x00, 0x76, 0x02};
5688     ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5689     EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5690                      timestamp.size()),
5691               0);
5692 
5693     EXPECT_EQ(hdr.component_bitmap_bit_length, 8u);
5694     EXPECT_EQ(hdr.package_version_string_type, 1u);
5695     ASSERT_EQ(hdr.package_version_string.length, 4ul);
5696     EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5697                      hdr.package_version_string.length),
5698               0);
5699     EXPECT_NE(pkg.areas.ptr, nullptr);
5700     EXPECT_NE(pkg.areas.length, 0ul);
5701     EXPECT_NE(pkg.package.ptr, nullptr);
5702     EXPECT_NE(pkg.package.length, 0ul);
5703 
5704     foreach_pldm_package_firmware_device_id_record(pkg, fdrec, rc)
5705     {
5706         struct pldm_descriptor desc;
5707 
5708         EXPECT_EQ(fdrec.descriptor_count, 1u);
5709         EXPECT_EQ(fdrec.device_update_option_flags.value, 0u);
5710         EXPECT_EQ(fdrec.component_image_set_version_string_type, 1u);
5711         ASSERT_EQ(fdrec.component_image_set_version_string.length, 4ul);
5712         EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5713                          fdrec.component_image_set_version_string.length),
5714                   0);
5715         ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1ul);
5716         EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1u);
5717         EXPECT_NE(fdrec.record_descriptors.length, 0ul);
5718         EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5719         ASSERT_EQ(fdrec.firmware_device_package_data.length, 0ul);
5720 
5721         foreach_pldm_package_firmware_device_id_record_descriptor(pkg, fdrec,
5722                                                                   desc, rc)
5723         {
5724             static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5725 
5726             EXPECT_EQ(desc.descriptor_type, 1u);
5727             ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5728             EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5729                              sizeof(iana_pen_dmtf)),
5730                       0);
5731 
5732             nr_fdrec_desc++;
5733         }
5734         ASSERT_EQ(rc, 0);
5735 
5736         nr_fdrec++;
5737     }
5738     ASSERT_EQ(rc, 0);
5739 
5740     EXPECT_EQ(nr_fdrec, 1);
5741     EXPECT_EQ(nr_fdrec_desc, 1);
5742 
5743     foreach_pldm_package_downstream_device_id_record(pkg, ddrec, rc)
5744     {
5745         struct pldm_descriptor desc;
5746 
5747         EXPECT_EQ(ddrec.descriptor_count, 1u);
5748         EXPECT_EQ(ddrec.update_option_flags.value, 0u);
5749         EXPECT_EQ(ddrec.self_contained_activation_min_version_string_type, 1u);
5750         ASSERT_EQ(ddrec.self_contained_activation_min_version_string.length,
5751                   4ul);
5752         EXPECT_EQ(
5753             memcmp("v1.0",
5754                    ddrec.self_contained_activation_min_version_string.ptr,
5755                    ddrec.self_contained_activation_min_version_string.length),
5756             0);
5757         EXPECT_EQ(ddrec.self_contained_activation_min_version_comparison_stamp,
5758                   0u);
5759         ASSERT_EQ(ddrec.applicable_components.bitmap.length, 1ul);
5760         EXPECT_EQ(*ddrec.applicable_components.bitmap.ptr, 2u);
5761         EXPECT_NE(ddrec.record_descriptors.length, 0ul);
5762         EXPECT_NE(ddrec.record_descriptors.ptr, nullptr);
5763         EXPECT_EQ(ddrec.package_data.length, 0ul);
5764 
5765         foreach_pldm_package_downstream_device_id_record_descriptor(pkg, ddrec,
5766                                                                     desc, rc)
5767         {
5768             static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5769 
5770             EXPECT_EQ(desc.descriptor_type, 1u);
5771             ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5772             EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5773                              sizeof(iana_pen_dmtf)),
5774                       0);
5775 
5776             nr_ddrec_desc++;
5777         }
5778         ASSERT_EQ(rc, 0);
5779 
5780         nr_ddrec++;
5781     }
5782     ASSERT_EQ(rc, 0);
5783 
5784     EXPECT_EQ(nr_ddrec, 1);
5785     EXPECT_EQ(nr_ddrec_desc, 1);
5786 
5787     static const std::array<const char*, 2> component_versions = {
5788         "v0.2",
5789         "v2.0",
5790     };
5791 
5792     static std::array<uint8_t, 4> expected_opaque_data = {0x12, 0x34, 0x56,
5793                                                           0x78};
5794 
5795     static const std::array<pldm_package_component_image_information, 2>
5796         expected_infos{
5797             {{0x000a,
5798               0x0000,
5799               0xffffffff,
5800               {0},
5801               {1},
5802               {nullptr, 1},
5803               0x01,
5804               {nullptr, 0},
5805               {expected_opaque_data.data(), expected_opaque_data.size()}},
5806              {0x000a,
5807               0x0000,
5808               0xffffffff,
5809               {0},
5810               {1},
5811               {nullptr, 1},
5812               0x01,
5813               {nullptr, 0},
5814               {expected_opaque_data.data(), expected_opaque_data.size()}}}};
5815     static const std::array<uint8_t, 2> expected_images{0x5a, 0xa5};
5816 
5817     foreach_pldm_package_component_image_information(pkg, info, rc)
5818     {
5819         const struct pldm_package_component_image_information* expected;
5820         const char* version;
5821         uint8_t image;
5822 
5823         expected = &expected_infos.at(nr_infos);
5824         version = component_versions.at(nr_infos);
5825         image = expected_images.at(nr_infos);
5826 
5827         EXPECT_EQ(info.component_classification,
5828                   expected->component_classification);
5829         EXPECT_EQ(info.component_identifier, expected->component_identifier);
5830         EXPECT_EQ(info.component_comparison_stamp,
5831                   expected->component_comparison_stamp);
5832         EXPECT_EQ(info.component_options.value,
5833                   expected->component_options.value);
5834         EXPECT_EQ(info.requested_component_activation_method.value,
5835                   expected->requested_component_activation_method.value);
5836         EXPECT_NE(info.component_image.ptr, expected->component_image.ptr);
5837         EXPECT_EQ(info.component_image.length,
5838                   expected->component_image.length);
5839         EXPECT_EQ(*info.component_image.ptr, image);
5840         EXPECT_EQ(info.component_version_string_type,
5841                   expected->component_version_string_type);
5842         ASSERT_EQ(info.component_version_string.length, 4ul);
5843         EXPECT_EQ(memcmp(version, info.component_version_string.ptr,
5844                          info.component_version_string.length),
5845                   0);
5846         EXPECT_EQ(info.component_opaque_data.length,
5847                   expected->component_opaque_data.length);
5848         EXPECT_EQ(memcmp(info.component_opaque_data.ptr,
5849                          expected->component_opaque_data.ptr,
5850                          expected->component_opaque_data.length),
5851                   0);
5852         nr_infos++;
5853     }
5854     ASSERT_EQ(rc, 0);
5855 
5856     EXPECT_EQ(nr_infos, 2);
5857 }
5858 
TEST(DecodePldmFirmwareUpdatePackage,v4h1fd1fdd1dd1ddd2cii)5859 TEST(DecodePldmFirmwareUpdatePackage, v4h1fd1fdd1dd1ddd2cii)
5860 {
5861     const std::array<uint8_t, 182> package{
5862         0x7B, 0x29, 0x1C, 0x99, 0x6D, 0xB6, 0x42, 0x08, 0x80, 0x1B, 0x02, 0x02,
5863         0x6E, 0x46, 0x3C, 0x78, 0x04, 0xB4, 0x00, 0x00, 0xe9, 0x07, 0x03, 0x0b,
5864         0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08, 0x00, 0x01, 0x04,
5865         't',  'e',  's',  't',
5866 
5867         0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
5868         0x02, 0x00, 0x00, 0x00, 0x01, 'v',  '0',  '.',  '1',  0x01, 0x00, 0x04,
5869         0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
5870 
5871         0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
5872         0x02, 0x00, 0x00, 0x00, 0x02, 'v',  '1',  '.',  '0',  0x01, 0x00, 0x04,
5873         0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
5874 
5875         0x02, 0x00,
5876 
5877         0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
5878         0xB4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v',  '0',
5879         '.',  '2',  0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
5880 
5881         0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
5882         0xB5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v',  '2',
5883         '.',  '0',  0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
5884 
5885         0xf7, 0xf7, 0xfd, 0x79,
5886 
5887         0x46, 0xf0, 0x31, 0xa7,
5888 
5889         0x5a,
5890 
5891         0xa5,
5892 
5893     };
5894 
5895     struct pldm_package_downstream_device_id_record ddrec;
5896     struct pldm_package_component_image_information info;
5897     struct pldm_package_firmware_device_id_record fdrec;
5898     DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR04H(pin);
5899     pldm_package_header_information_pad hdr;
5900     struct pldm_package pkg{};
5901     int nr_fdrec_desc = 0;
5902     int nr_ddrec_desc = 0;
5903     int nr_fdrec = 0;
5904     int nr_ddrec = 0;
5905     int nr_infos = 0;
5906     int rc;
5907 
5908     rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5909                                              &pin, &hdr, &pkg, 0);
5910     ASSERT_EQ(rc, 0);
5911 
5912     EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_3.data(),
5913                      hdr.package_header_identifier,
5914                      PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_3.size()),
5915               0);
5916     EXPECT_EQ(hdr.package_header_format_revision, 4);
5917 
5918     static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5919                                                    0x16, 0x03, 0x00, 0x00, 0x00,
5920                                                    0x00, 0x76, 0x02};
5921     ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5922     EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5923                      timestamp.size()),
5924               0);
5925 
5926     EXPECT_EQ(hdr.component_bitmap_bit_length, 8u);
5927     EXPECT_EQ(hdr.package_version_string_type, 1u);
5928     ASSERT_EQ(hdr.package_version_string.length, 4ul);
5929     EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5930                      hdr.package_version_string.length),
5931               0);
5932     EXPECT_NE(pkg.areas.ptr, nullptr);
5933     EXPECT_NE(pkg.areas.length, 0ul);
5934     EXPECT_NE(pkg.package.ptr, nullptr);
5935     EXPECT_NE(pkg.package.length, 0ul);
5936 
5937     foreach_pldm_package_firmware_device_id_record(pkg, fdrec, rc)
5938     {
5939         struct pldm_descriptor desc;
5940 
5941         static const uint8_t expected_reference_manifest_data[] = {0x87, 0x65};
5942 
5943         EXPECT_EQ(fdrec.descriptor_count, 1u);
5944         EXPECT_EQ(fdrec.device_update_option_flags.value, 0u);
5945         EXPECT_EQ(fdrec.component_image_set_version_string_type, 1u);
5946         ASSERT_EQ(fdrec.component_image_set_version_string.length, 4ul);
5947         EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5948                          fdrec.component_image_set_version_string.length),
5949                   0);
5950         ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1ul);
5951         EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1u);
5952         EXPECT_NE(fdrec.record_descriptors.length, 0ul);
5953         EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5954         ASSERT_EQ(fdrec.firmware_device_package_data.length, 0ul);
5955         EXPECT_EQ(fdrec.reference_manifest_data.length,
5956                   sizeof(expected_reference_manifest_data));
5957         EXPECT_EQ(memcmp(fdrec.reference_manifest_data.ptr,
5958                          expected_reference_manifest_data,
5959                          sizeof(expected_reference_manifest_data)),
5960                   0);
5961         foreach_pldm_package_firmware_device_id_record_descriptor(pkg, fdrec,
5962                                                                   desc, rc)
5963         {
5964             static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5965 
5966             EXPECT_EQ(desc.descriptor_type, 1u);
5967             ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5968             EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5969                              sizeof(iana_pen_dmtf)),
5970                       0);
5971 
5972             nr_fdrec_desc++;
5973         }
5974         ASSERT_EQ(rc, 0);
5975 
5976         nr_fdrec++;
5977     }
5978     ASSERT_EQ(rc, 0);
5979 
5980     EXPECT_EQ(nr_fdrec, 1);
5981     EXPECT_EQ(nr_fdrec_desc, 1);
5982 
5983     foreach_pldm_package_downstream_device_id_record(pkg, ddrec, rc)
5984     {
5985         struct pldm_descriptor desc;
5986 
5987         static const uint8_t expected_reference_manifest_data[] = {0x87, 0x65};
5988 
5989         EXPECT_EQ(ddrec.descriptor_count, 1u);
5990         EXPECT_EQ(ddrec.update_option_flags.value, 0u);
5991         EXPECT_EQ(ddrec.self_contained_activation_min_version_string_type, 1u);
5992         ASSERT_EQ(ddrec.self_contained_activation_min_version_string.length,
5993                   4ul);
5994         EXPECT_EQ(
5995             memcmp("v1.0",
5996                    ddrec.self_contained_activation_min_version_string.ptr,
5997                    ddrec.self_contained_activation_min_version_string.length),
5998             0);
5999         EXPECT_EQ(ddrec.self_contained_activation_min_version_comparison_stamp,
6000                   0u);
6001         ASSERT_EQ(ddrec.applicable_components.bitmap.length, 1ul);
6002         EXPECT_EQ(*ddrec.applicable_components.bitmap.ptr, 2u);
6003         EXPECT_NE(ddrec.record_descriptors.length, 0ul);
6004         EXPECT_NE(ddrec.record_descriptors.ptr, nullptr);
6005         EXPECT_EQ(ddrec.package_data.length, 0ul);
6006         EXPECT_EQ(fdrec.reference_manifest_data.length,
6007                   sizeof(expected_reference_manifest_data));
6008         EXPECT_EQ(memcmp(fdrec.reference_manifest_data.ptr,
6009                          expected_reference_manifest_data,
6010                          sizeof(expected_reference_manifest_data)),
6011                   0);
6012 
6013         foreach_pldm_package_downstream_device_id_record_descriptor(pkg, ddrec,
6014                                                                     desc, rc)
6015         {
6016             static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
6017 
6018             EXPECT_EQ(desc.descriptor_type, 1u);
6019             ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
6020             EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
6021                              sizeof(iana_pen_dmtf)),
6022                       0);
6023 
6024             nr_ddrec_desc++;
6025         }
6026         ASSERT_EQ(rc, 0);
6027 
6028         nr_ddrec++;
6029     }
6030     ASSERT_EQ(rc, 0);
6031 
6032     EXPECT_EQ(nr_ddrec, 1);
6033     EXPECT_EQ(nr_ddrec_desc, 1);
6034 
6035     static const std::array<const char*, 2> component_versions = {
6036         "v0.2",
6037         "v2.0",
6038     };
6039 
6040     static std::array<uint8_t, 4> expected_opaque_data = {0x12, 0x34, 0x56,
6041                                                           0x78};
6042 
6043     static const std::array<pldm_package_component_image_information, 2>
6044         expected_infos{
6045             {{0x000a,
6046               0x0000,
6047               0xffffffff,
6048               {0},
6049               {1},
6050               {nullptr, 1},
6051               0x01,
6052               {nullptr, 0},
6053               {expected_opaque_data.data(), expected_opaque_data.size()}},
6054              {0x000a,
6055               0x0000,
6056               0xffffffff,
6057               {0},
6058               {1},
6059               {nullptr, 1},
6060               0x01,
6061               {nullptr, 0},
6062               {expected_opaque_data.data(), expected_opaque_data.size()}}}};
6063     static const std::array<uint8_t, 2> expected_images{0x5a, 0xa5};
6064 
6065     foreach_pldm_package_component_image_information(pkg, info, rc)
6066     {
6067         const struct pldm_package_component_image_information* expected;
6068         const char* version;
6069         uint8_t image;
6070 
6071         expected = &expected_infos.at(nr_infos);
6072         version = component_versions.at(nr_infos);
6073         image = expected_images.at(nr_infos);
6074 
6075         EXPECT_EQ(info.component_classification,
6076                   expected->component_classification);
6077         EXPECT_EQ(info.component_identifier, expected->component_identifier);
6078         EXPECT_EQ(info.component_comparison_stamp,
6079                   expected->component_comparison_stamp);
6080         EXPECT_EQ(info.component_options.value,
6081                   expected->component_options.value);
6082         EXPECT_EQ(info.requested_component_activation_method.value,
6083                   expected->requested_component_activation_method.value);
6084         EXPECT_NE(info.component_image.ptr, expected->component_image.ptr);
6085         EXPECT_EQ(info.component_image.length,
6086                   expected->component_image.length);
6087         EXPECT_EQ(*info.component_image.ptr, image);
6088         EXPECT_EQ(info.component_version_string_type,
6089                   expected->component_version_string_type);
6090         ASSERT_EQ(info.component_version_string.length, 4ul);
6091         EXPECT_EQ(memcmp(version, info.component_version_string.ptr,
6092                          info.component_version_string.length),
6093                   0);
6094         EXPECT_EQ(info.component_opaque_data.length,
6095                   expected->component_opaque_data.length);
6096         EXPECT_EQ(memcmp(info.component_opaque_data.ptr,
6097                          expected->component_opaque_data.ptr,
6098                          expected->component_opaque_data.length),
6099                   0);
6100 
6101         nr_infos++;
6102     }
6103     ASSERT_EQ(rc, 0);
6104 
6105     EXPECT_EQ(nr_infos, 2);
6106 }
6107 
TEST(DecodePldmFirmwareUpdatePackage,downstreamDeviceBeforeFirmwareDevice)6108 TEST(DecodePldmFirmwareUpdatePackage, downstreamDeviceBeforeFirmwareDevice)
6109 {
6110     const std::array<uint8_t, 182> package{
6111         0x7B, 0x29, 0x1C, 0x99, 0x6D, 0xB6, 0x42, 0x08, 0x80, 0x1B, 0x02, 0x02,
6112         0x6E, 0x46, 0x3C, 0x78, 0x04, 0xB4, 0x00, 0x00, 0xe9, 0x07, 0x03, 0x0b,
6113         0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08, 0x00, 0x01, 0x04,
6114         't',  'e',  's',  't',
6115 
6116         0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
6117         0x02, 0x00, 0x00, 0x00, 0x01, 'v',  '0',  '.',  '1',  0x01, 0x00, 0x04,
6118         0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
6119 
6120         0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
6121         0x02, 0x00, 0x00, 0x00, 0x02, 'v',  '1',  '.',  '0',  0x01, 0x00, 0x04,
6122         0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
6123 
6124         0x02, 0x00,
6125 
6126         0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
6127         0xB4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v',  '0',
6128         '.',  '2',  0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
6129 
6130         0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
6131         0xB5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v',  '2',
6132         '.',  '0',  0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
6133 
6134         0xf7, 0xf7, 0xfd, 0x79,
6135 
6136         0x46, 0xf0, 0x31, 0xa7,
6137 
6138         0x5a,
6139 
6140         0xa5,
6141 
6142     };
6143 
6144     struct pldm_package_downstream_device_id_record ddrec;
6145     DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR04H(pin);
6146     pldm_package_header_information_pad hdr;
6147     struct pldm_package pkg{};
6148     int rc;
6149 
6150     rc = decode_pldm_firmware_update_package(package.data(), package.size(),
6151                                              &pin, &hdr, &pkg, 0);
6152     ASSERT_EQ(rc, 0);
6153 
6154     foreach_pldm_package_downstream_device_id_record(pkg, ddrec, rc)
6155     {
6156     }
6157     EXPECT_NE(rc, 0);
6158 }
6159 
TEST(DecodePldmFirmwareUpdatePackage,componentImageInfosBeforeFirmwareDevice)6160 TEST(DecodePldmFirmwareUpdatePackage, componentImageInfosBeforeFirmwareDevice)
6161 {
6162     const std::array<uint8_t, 182> package{
6163         0x7B, 0x29, 0x1C, 0x99, 0x6D, 0xB6, 0x42, 0x08, 0x80, 0x1B, 0x02, 0x02,
6164         0x6E, 0x46, 0x3C, 0x78, 0x04, 0xB4, 0x00, 0x00, 0xe9, 0x07, 0x03, 0x0b,
6165         0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08, 0x00, 0x01, 0x04,
6166         't',  'e',  's',  't',
6167 
6168         0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
6169         0x02, 0x00, 0x00, 0x00, 0x01, 'v',  '0',  '.',  '1',  0x01, 0x00, 0x04,
6170         0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
6171 
6172         0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
6173         0x02, 0x00, 0x00, 0x00, 0x02, 'v',  '1',  '.',  '0',  0x01, 0x00, 0x04,
6174         0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
6175 
6176         0x02, 0x00,
6177 
6178         0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
6179         0xB4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v',  '0',
6180         '.',  '2',  0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
6181 
6182         0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
6183         0xB5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v',  '2',
6184         '.',  '0',  0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
6185 
6186         0xf7, 0xf7, 0xfd, 0x79,
6187 
6188         0x46, 0xf0, 0x31, 0xa7,
6189 
6190         0x5a,
6191 
6192         0xa5,
6193 
6194     };
6195 
6196     struct pldm_package_component_image_information info;
6197     DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR04H(pin);
6198     pldm_package_header_information_pad hdr;
6199     struct pldm_package pkg{};
6200     int rc;
6201 
6202     rc = decode_pldm_firmware_update_package(package.data(), package.size(),
6203                                              &pin, &hdr, &pkg, 0);
6204     ASSERT_EQ(rc, 0);
6205 
6206     foreach_pldm_package_component_image_information(pkg, info, rc)
6207     {
6208     }
6209     EXPECT_NE(rc, 0);
6210 }
6211 
TEST(DecodePldmFirmwareUpdatePackage,p4v2ComponentImageInfosBeforeDownstreamDevice)6212 TEST(DecodePldmFirmwareUpdatePackage,
6213      p4v2ComponentImageInfosBeforeDownstreamDevice)
6214 {
6215     const std::array<uint8_t, 182> package{
6216         0x7B, 0x29, 0x1C, 0x99, 0x6D, 0xB6, 0x42, 0x08, 0x80, 0x1B, 0x02, 0x02,
6217         0x6E, 0x46, 0x3C, 0x78, 0x04, 0xB4, 0x00, 0x00, 0xe9, 0x07, 0x03, 0x0b,
6218         0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08, 0x00, 0x01, 0x04,
6219         't',  'e',  's',  't',
6220 
6221         0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
6222         0x02, 0x00, 0x00, 0x00, 0x01, 'v',  '0',  '.',  '1',  0x01, 0x00, 0x04,
6223         0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
6224 
6225         0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
6226         0x02, 0x00, 0x00, 0x00, 0x02, 'v',  '1',  '.',  '0',  0x01, 0x00, 0x04,
6227         0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
6228 
6229         0x02, 0x00,
6230 
6231         0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
6232         0xB4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v',  '0',
6233         '.',  '2',  0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
6234 
6235         0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
6236         0xB5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v',  '2',
6237         '.',  '0',  0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
6238 
6239         0xf7, 0xf7, 0xfd, 0x79,
6240 
6241         0x46, 0xf0, 0x31, 0xa7,
6242 
6243         0x5a,
6244 
6245         0xa5,
6246 
6247     };
6248 
6249     struct pldm_package_component_image_information info;
6250     struct pldm_package_firmware_device_id_record fdrec;
6251     DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR04H(pin);
6252     pldm_package_header_information_pad hdr;
6253     struct pldm_package pkg{};
6254     int rc;
6255 
6256     rc = decode_pldm_firmware_update_package(package.data(), package.size(),
6257                                              &pin, &hdr, &pkg, 0);
6258     ASSERT_EQ(rc, 0);
6259 
6260     foreach_pldm_package_firmware_device_id_record(pkg, fdrec, rc)
6261     {
6262         struct pldm_descriptor desc;
6263 
6264         foreach_pldm_package_firmware_device_id_record_descriptor(pkg, fdrec,
6265                                                                   desc, rc)
6266         {
6267         }
6268         ASSERT_EQ(rc, 0);
6269     }
6270     ASSERT_EQ(rc, 0);
6271 
6272     foreach_pldm_package_component_image_information(pkg, info, rc)
6273     {
6274     }
6275     EXPECT_NE(rc, 0);
6276 }
6277