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, ¶ms_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, ¶ms_req,
1827 nullptr, payload_length);
1828 EXPECT_EQ(rc, -EINVAL);
1829
1830 rc = encode_query_downstream_identifiers_req(
1831 instanceId, ¶ms_req, requestPtr, payload_length - 1);
1832 EXPECT_EQ(rc, -EOVERFLOW);
1833
1834 rc = encode_query_downstream_identifiers_req(
1835 instanceId, ¶ms_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, ¶ms_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, ¶ms_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, ¶ms_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 ¤tState, &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 ¤tState, &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 ¤tState, &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 ¤tState, &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 ¤tState, &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 ¤tState, 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 ¤tState, &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 ¤tState, &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 ¤tState, &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 ¤tState, &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 ¤tState, &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 ¤tState, &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 ¤tState, &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 ¤tState, &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 ¤tState, &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 ¤tState, &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 ¤tState, &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 ¤tState, &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 ¤tState, &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 ¤tState, &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