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