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