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
TEST(DecodePackageHeaderInfo,goodPath)45 TEST(DecodePackageHeaderInfo, goodPath)
46 {
47 // Package header identifier for Version 1.0.x
48 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
49 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43,
50 0x98, 0x00, 0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02};
51 // Package header version for DSP0267 version 1.0.x
52 constexpr uint8_t pkgHeaderFormatRevision = 0x01;
53 // Random PackageHeaderSize
54 constexpr uint16_t pkgHeaderSize = 303;
55 // PackageReleaseDateTime - "25/12/2021 00:00:00"
56 std::array<uint8_t, PLDM_TIMESTAMP104_SIZE> package_release_date_time{
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00};
59 constexpr uint16_t componentBitmapBitLength = 8;
60 // PackageVersionString
61 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
62 constexpr size_t packagerHeaderSize =
63 sizeof(pldm_package_header_information) + packageVersionStr.size();
64
65 constexpr std::array<uint8_t, packagerHeaderSize> packagerHeaderInfo{
66 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
67 0x05, 0x9a, 0xca, 0x02, 0x01, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b,
69 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
70 pldm_package_header_information pkgHeader{};
71 variable_field packageVersion{};
72
73 auto rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
74 packagerHeaderInfo.size(),
75 &pkgHeader, &packageVersion);
76
77 EXPECT_EQ(rc, PLDM_SUCCESS);
78 EXPECT_EQ(true,
79 std::equal(pkgHeader.uuid, pkgHeader.uuid + PLDM_FWUP_UUID_LENGTH,
80 uuid.begin(), uuid.end()));
81 EXPECT_EQ(pkgHeader.package_header_format_version, pkgHeaderFormatRevision);
82 EXPECT_EQ(pkgHeader.package_header_size, pkgHeaderSize);
83 EXPECT_EQ(true, std::equal(pkgHeader.package_release_date_time,
84 pkgHeader.package_release_date_time +
85 PLDM_TIMESTAMP104_SIZE,
86 package_release_date_time.begin(),
87 package_release_date_time.end()));
88 EXPECT_EQ(pkgHeader.component_bitmap_bit_length, componentBitmapBitLength);
89 EXPECT_EQ(pkgHeader.package_version_string_type, PLDM_STR_TYPE_ASCII);
90 EXPECT_EQ(pkgHeader.package_version_string_length,
91 packageVersionStr.size());
92 std::string packageVersionString(
93 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
94 reinterpret_cast<const char*>(packageVersion.ptr),
95 packageVersion.length);
96 EXPECT_EQ(packageVersionString, packageVersionStr);
97 }
98
TEST(DecodePackageHeaderInfo,errorPaths)99 TEST(DecodePackageHeaderInfo, errorPaths)
100 {
101 int rc = 0;
102 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
103 constexpr size_t packagerHeaderSize =
104 sizeof(pldm_package_header_information) + packageVersionStr.size();
105
106 // Invalid Package Version String Type - 0x06
107 constexpr std::array<uint8_t, packagerHeaderSize>
108 invalidPackagerHeaderInfo1{
109 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
110 0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
112 0x07, 0x00, 0x08, 0x00, 0x06, 0x0b, 0x4f, 0x70, 0x65, 0x6e,
113 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
114
115 pldm_package_header_information packageHeader{};
116 variable_field packageVersion{};
117
118 rc = decode_pldm_package_header_info(nullptr,
119 invalidPackagerHeaderInfo1.size(),
120 &packageHeader, &packageVersion);
121 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
122
123 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
124 invalidPackagerHeaderInfo1.size(),
125 nullptr, &packageVersion);
126 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
127
128 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
129 invalidPackagerHeaderInfo1.size(),
130 &packageHeader, nullptr);
131 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
132
133 rc = decode_pldm_package_header_info(
134 invalidPackagerHeaderInfo1.data(),
135 sizeof(pldm_package_header_information) - 1, &packageHeader,
136 &packageVersion);
137 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
138
139 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
140 invalidPackagerHeaderInfo1.size(),
141 &packageHeader, &packageVersion);
142 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
143
144 // Invalid Package Version String Length - 0x00
145 constexpr std::array<uint8_t, packagerHeaderSize>
146 invalidPackagerHeaderInfo2{
147 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
148 0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
150 0x07, 0x00, 0x08, 0x00, 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e,
151 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
152 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo2.data(),
153 invalidPackagerHeaderInfo2.size(),
154 &packageHeader, &packageVersion);
155 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
156
157 // Package version string length less than in the header information
158 constexpr std::array<uint8_t, packagerHeaderSize - 1>
159 invalidPackagerHeaderInfo3{
160 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
161 0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
162 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
163 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e,
164 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e};
165 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo3.data(),
166 invalidPackagerHeaderInfo3.size(),
167 &packageHeader, &packageVersion);
168 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
169
170 // ComponentBitmapBitLength not a multiple of 8
171 constexpr std::array<uint8_t, packagerHeaderSize>
172 invalidPackagerHeaderInfo4{
173 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
174 0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
175 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
176 0x07, 0x00, 0x09, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e,
177 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
178 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo4.data(),
179 invalidPackagerHeaderInfo4.size(),
180 &packageHeader, &packageVersion);
181 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
182 }
183
TEST(DecodeFirmwareDeviceIdRecord,goodPath)184 TEST(DecodeFirmwareDeviceIdRecord, goodPath)
185 {
186 constexpr uint8_t descriptorCount = 1;
187 // Continue component updates after failure
188 constexpr std::bitset<32> deviceUpdateFlag{1};
189 constexpr uint16_t componentBitmapBitLength = 16;
190 // Applicable Components - 1,2,5,8,9
191 std::vector<std::bitset<8>> applicableComponentsBitfield{0x93, 0x01};
192 // ComponentImageSetVersionString
193 constexpr std::string_view imageSetVersionStr{"VersionString1"};
194 // Initial descriptor - UUID
195 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
196 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
197 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
198 constexpr uint16_t fwDevicePkgDataLen = 2;
199 // FirmwareDevicePackageData
200 constexpr std::array<uint8_t, fwDevicePkgDataLen> fwDevicePkgData{0xab,
201 0xcd};
202 // Size of the firmware device ID record
203 constexpr uint16_t recordLen =
204 sizeof(pldm_firmware_device_id_record) +
205 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
206 imageSetVersionStr.size() + sizeof(pldm_descriptor_tlv) - 1 +
207 uuid.size() + fwDevicePkgData.size();
208 // Firmware device ID record
209 constexpr std::array<uint8_t, recordLen> record{
210 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02,
211 0x00, 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
212 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10,
213 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0,
214 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xab, 0xcd};
215
216 pldm_firmware_device_id_record deviceIdRecHeader{};
217 variable_field applicableComponents{};
218 variable_field outCompImageSetVersionStr{};
219 variable_field recordDescriptors{};
220 variable_field outFwDevicePkgData{};
221
222 auto rc = decode_firmware_device_id_record(
223 record.data(), record.size(), componentBitmapBitLength,
224 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
225 &recordDescriptors, &outFwDevicePkgData);
226
227 EXPECT_EQ(rc, PLDM_SUCCESS);
228 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
229 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
230 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
231 deviceUpdateFlag);
232 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
233 PLDM_STR_TYPE_ASCII);
234 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
235 imageSetVersionStr.size());
236 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, fwDevicePkgDataLen);
237
238 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
239 EXPECT_EQ(true,
240 std::equal(applicableComponents.ptr,
241 applicableComponents.ptr + applicableComponents.length,
242 applicableComponentsBitfield.begin(),
243 applicableComponentsBitfield.end()));
244
245 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
246 std::string compImageSetVersionStr(
247 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
248 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
249 outCompImageSetVersionStr.length);
250 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
251
252 uint16_t descriptorType = 0;
253 uint16_t descriptorLen = 0;
254 variable_field descriptorData{};
255 // DescriptorCount is 1, so decode_descriptor_type_length_value called once
256 rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
257 recordDescriptors.length,
258 &descriptorType, &descriptorData);
259 EXPECT_EQ(rc, PLDM_SUCCESS);
260 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
261 sizeof(descriptorLen) +
262 descriptorData.length);
263 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
264 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
265 EXPECT_EQ(true, std::equal(descriptorData.ptr,
266 descriptorData.ptr + descriptorData.length,
267 uuid.begin(), uuid.end()));
268
269 EXPECT_EQ(outFwDevicePkgData.length, fwDevicePkgData.size());
270 EXPECT_EQ(true,
271 std::equal(outFwDevicePkgData.ptr,
272 outFwDevicePkgData.ptr + outFwDevicePkgData.length,
273 fwDevicePkgData.begin(), fwDevicePkgData.end()));
274 }
275
TEST(DecodeFirmwareDeviceIdRecord,goodPathNofwDevicePkgData)276 TEST(DecodeFirmwareDeviceIdRecord, goodPathNofwDevicePkgData)
277 {
278 constexpr uint8_t descriptorCount = 1;
279 // Continue component updates after failure
280 constexpr std::bitset<32> deviceUpdateFlag{1};
281 constexpr uint16_t componentBitmapBitLength = 8;
282 // Applicable Components - 1,2
283 std::vector<std::bitset<8>> applicableComponentsBitfield{0x03};
284 // ComponentImageSetVersionString
285 constexpr std::string_view imageSetVersionStr{"VersionString1"};
286 // Initial descriptor - UUID
287 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
288 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
289 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
290 constexpr uint16_t fwDevicePkgDataLen = 0;
291
292 // Size of the firmware device ID record
293 constexpr uint16_t recordLen =
294 sizeof(pldm_firmware_device_id_record) +
295 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
296 imageSetVersionStr.size() +
297 sizeof(pldm_descriptor_tlv().descriptor_type) +
298 sizeof(pldm_descriptor_tlv().descriptor_length) + uuid.size() +
299 fwDevicePkgDataLen;
300 // Firmware device ID record
301 constexpr std::array<uint8_t, recordLen> record{
302 0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x03,
303 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e,
304 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d,
305 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
306
307 pldm_firmware_device_id_record deviceIdRecHeader{};
308 variable_field applicableComponents{};
309 variable_field outCompImageSetVersionStr{};
310 variable_field recordDescriptors{};
311 variable_field outFwDevicePkgData{};
312
313 auto rc = decode_firmware_device_id_record(
314 record.data(), record.size(), componentBitmapBitLength,
315 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
316 &recordDescriptors, &outFwDevicePkgData);
317
318 EXPECT_EQ(rc, PLDM_SUCCESS);
319 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
320 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
321 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
322 deviceUpdateFlag);
323 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
324 PLDM_STR_TYPE_ASCII);
325 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
326 imageSetVersionStr.size());
327 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, 0);
328
329 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
330 EXPECT_EQ(true,
331 std::equal(applicableComponents.ptr,
332 applicableComponents.ptr + applicableComponents.length,
333 applicableComponentsBitfield.begin(),
334 applicableComponentsBitfield.end()));
335
336 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
337 std::string compImageSetVersionStr(
338 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
339 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
340 outCompImageSetVersionStr.length);
341 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
342
343 uint16_t descriptorType = 0;
344 uint16_t descriptorLen = 0;
345 variable_field descriptorData{};
346 // DescriptorCount is 1, so decode_descriptor_type_length_value called once
347 rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
348 recordDescriptors.length,
349 &descriptorType, &descriptorData);
350 EXPECT_EQ(rc, PLDM_SUCCESS);
351 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
352 sizeof(descriptorLen) +
353 descriptorData.length);
354 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
355 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
356 EXPECT_EQ(true, std::equal(descriptorData.ptr,
357 descriptorData.ptr + descriptorData.length,
358 uuid.begin(), uuid.end()));
359
360 EXPECT_EQ(outFwDevicePkgData.ptr, nullptr);
361 EXPECT_EQ(outFwDevicePkgData.length, 0);
362 }
363
TEST(DecodeFirmwareDeviceIdRecord,ErrorPaths)364 TEST(DecodeFirmwareDeviceIdRecord, ErrorPaths)
365 {
366 constexpr uint16_t componentBitmapBitLength = 8;
367 // Invalid ComponentImageSetVersionStringType
368 constexpr std::array<uint8_t, 11> invalidRecord1{
369 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
370
371 int rc = 0;
372 pldm_firmware_device_id_record deviceIdRecHeader{};
373 variable_field applicableComponents{};
374 variable_field outCompImageSetVersionStr{};
375 variable_field recordDescriptors{};
376 variable_field outFwDevicePkgData{};
377
378 rc = decode_firmware_device_id_record(
379 nullptr, invalidRecord1.size(), componentBitmapBitLength,
380 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
381 &recordDescriptors, &outFwDevicePkgData);
382 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
383
384 rc = decode_firmware_device_id_record(
385 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
386 nullptr, &applicableComponents, &outCompImageSetVersionStr,
387 &recordDescriptors, &outFwDevicePkgData);
388 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
389
390 rc = decode_firmware_device_id_record(
391 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
392 &deviceIdRecHeader, nullptr, &outCompImageSetVersionStr,
393 &recordDescriptors, &outFwDevicePkgData);
394 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
395
396 rc = decode_firmware_device_id_record(
397 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
398 &deviceIdRecHeader, &applicableComponents, nullptr, &recordDescriptors,
399 &outFwDevicePkgData);
400 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
401
402 rc = decode_firmware_device_id_record(
403 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
404 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
405 nullptr, &outFwDevicePkgData);
406 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
407
408 rc = decode_firmware_device_id_record(
409 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
410 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
411 &recordDescriptors, nullptr);
412 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
413
414 rc = decode_firmware_device_id_record(
415 invalidRecord1.data(), invalidRecord1.size() - 1,
416 componentBitmapBitLength, &deviceIdRecHeader, &applicableComponents,
417 &outCompImageSetVersionStr, &recordDescriptors, &outFwDevicePkgData);
418 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
419
420 rc = decode_firmware_device_id_record(
421 invalidRecord1.data(), invalidRecord1.size(),
422 componentBitmapBitLength + 1, &deviceIdRecHeader, &applicableComponents,
423 &outCompImageSetVersionStr, &recordDescriptors, &outFwDevicePkgData);
424 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
425
426 rc = decode_firmware_device_id_record(
427 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
428 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
429 &recordDescriptors, &outFwDevicePkgData);
430 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
431
432 // Invalid ComponentImageSetVersionStringLength
433 constexpr std::array<uint8_t, 11> invalidRecord2{
434 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
435 rc = decode_firmware_device_id_record(
436 invalidRecord2.data(), invalidRecord2.size(), componentBitmapBitLength,
437 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
438 &recordDescriptors, &outFwDevicePkgData);
439 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
440
441 // invalidRecord3 size is less than RecordLength
442 constexpr std::array<uint8_t, 11> invalidRecord3{
443 0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00};
444 rc = decode_firmware_device_id_record(
445 invalidRecord3.data(), invalidRecord3.size(), componentBitmapBitLength,
446 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
447 &recordDescriptors, &outFwDevicePkgData);
448 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
449
450 // RecordLength is less than the calculated RecordLength
451 constexpr std::array<uint8_t, 11> invalidRecord4{
452 0x15, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02, 0x00};
453 rc = decode_firmware_device_id_record(
454 invalidRecord4.data(), invalidRecord4.size(), componentBitmapBitLength,
455 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
456 &recordDescriptors, &outFwDevicePkgData);
457 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
458
459 // Large FirmwareDevicePackageDataLength could cause overflow in calculation
460 constexpr std::array<uint8_t, 49> invalidRecord5{
461 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e,
462 // FirmwareDevicePackageDataLength = 0xffff
463 0xff, 0xff,
464 //
465 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72,
466 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64,
467 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b,
468 0xab, 0xcd};
469 rc = decode_firmware_device_id_record(
470 invalidRecord5.data(), invalidRecord5.size(), componentBitmapBitLength,
471 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
472 &recordDescriptors, &outFwDevicePkgData);
473 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
474 }
475
TEST(DecodeDescriptors,goodPath3Descriptors)476 TEST(DecodeDescriptors, goodPath3Descriptors)
477 {
478 // In the descriptor data there are 3 descriptor entries
479 // 1) IANA enterprise ID
480 constexpr std::array<uint8_t, PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH> iana{
481 0x0a, 0x0b, 0x0c, 0xd};
482 // 2) UUID
483 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
484 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
485 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
486 // 3) Vendor Defined
487 constexpr std::string_view vendorTitle{"OpenBMC"};
488 constexpr size_t vendorDescriptorLen = 2;
489 constexpr std::array<uint8_t, vendorDescriptorLen> vendorDescriptorData{
490 0x01, 0x02};
491
492 constexpr size_t vendorDefinedDescriptorLen =
493 sizeof(pldm_vendor_defined_descriptor_title_data()
494 .vendor_defined_descriptor_title_str_type) +
495 sizeof(pldm_vendor_defined_descriptor_title_data()
496 .vendor_defined_descriptor_title_str_len) +
497 vendorTitle.size() + vendorDescriptorData.size();
498
499 constexpr size_t descriptorsLength =
500 3 * (sizeof(pldm_descriptor_tlv().descriptor_type) +
501 sizeof(pldm_descriptor_tlv().descriptor_length)) +
502 iana.size() + uuid.size() + vendorDefinedDescriptorLen;
503
504 constexpr std::array<uint8_t, descriptorsLength> descriptors{
505 0x01, 0x00, 0x04, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x02, 0x00, 0x10,
506 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
507 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xff, 0xff, 0x0b, 0x00, 0x01,
508 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x01, 0x02};
509
510 size_t descriptorCount = 1;
511 size_t descriptorsRemainingLength = descriptorsLength;
512 int rc = 0;
513
514 while (descriptorsRemainingLength && (descriptorCount <= 3))
515 {
516 uint16_t descriptorType = 0;
517 uint16_t descriptorLen = 0;
518 variable_field descriptorData{};
519
520 rc = decode_descriptor_type_length_value(
521 descriptors.data() + descriptorsLength - descriptorsRemainingLength,
522 descriptorsRemainingLength, &descriptorType, &descriptorData);
523 EXPECT_EQ(rc, PLDM_SUCCESS);
524
525 if (descriptorCount == 1)
526 {
527 EXPECT_EQ(descriptorType, PLDM_FWUP_IANA_ENTERPRISE_ID);
528 EXPECT_EQ(descriptorData.length,
529 PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH);
530 EXPECT_EQ(true,
531 std::equal(descriptorData.ptr,
532 descriptorData.ptr + descriptorData.length,
533 iana.begin(), iana.end()));
534 }
535 else if (descriptorCount == 2)
536 {
537 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
538 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
539 EXPECT_EQ(true,
540 std::equal(descriptorData.ptr,
541 descriptorData.ptr + descriptorData.length,
542 uuid.begin(), uuid.end()));
543 }
544 else if (descriptorCount == 3)
545 {
546 EXPECT_EQ(descriptorType, PLDM_FWUP_VENDOR_DEFINED);
547 EXPECT_EQ(descriptorData.length, vendorDefinedDescriptorLen);
548
549 uint8_t descriptorTitleStrType = 0;
550 variable_field descriptorTitleStr{};
551 variable_field vendorDefinedDescriptorData{};
552
553 rc = decode_vendor_defined_descriptor_value(
554 descriptorData.ptr, descriptorData.length,
555 &descriptorTitleStrType, &descriptorTitleStr,
556 &vendorDefinedDescriptorData);
557 EXPECT_EQ(rc, PLDM_SUCCESS);
558
559 EXPECT_EQ(descriptorTitleStrType, PLDM_STR_TYPE_ASCII);
560 EXPECT_EQ(descriptorTitleStr.length, vendorTitle.size());
561 std::string vendorTitleStr(
562 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
563 reinterpret_cast<const char*>(descriptorTitleStr.ptr),
564 descriptorTitleStr.length);
565 EXPECT_EQ(vendorTitleStr, vendorTitle);
566
567 EXPECT_EQ(vendorDefinedDescriptorData.length,
568 vendorDescriptorData.size());
569 EXPECT_EQ(true, std::equal(vendorDefinedDescriptorData.ptr,
570 vendorDefinedDescriptorData.ptr +
571 vendorDefinedDescriptorData.length,
572 vendorDescriptorData.begin(),
573 vendorDescriptorData.end()));
574 }
575
576 descriptorsRemainingLength -= sizeof(descriptorType) +
577 sizeof(descriptorLen) +
578 descriptorData.length;
579 descriptorCount++;
580 }
581 }
582
TEST(DecodeDescriptors,errorPathDecodeDescriptorTLV)583 TEST(DecodeDescriptors, errorPathDecodeDescriptorTLV)
584 {
585 int rc = 0;
586 // IANA Enterprise ID descriptor length incorrect
587 constexpr std::array<uint8_t, 7> invalidIANADescriptor1{
588 0x01, 0x00, 0x03, 0x00, 0x0a, 0x0b, 0x0c};
589 uint16_t descriptorType = 0;
590 variable_field descriptorData{};
591
592 rc = decode_descriptor_type_length_value(nullptr,
593 invalidIANADescriptor1.size(),
594 &descriptorType, &descriptorData);
595 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
596
597 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
598 invalidIANADescriptor1.size(),
599 nullptr, &descriptorData);
600 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
601
602 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
603 invalidIANADescriptor1.size(),
604 &descriptorType, nullptr);
605 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
606
607 rc = decode_descriptor_type_length_value(
608 invalidIANADescriptor1.data(), PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN - 1,
609 &descriptorType, &descriptorData);
610 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
611
612 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
613 invalidIANADescriptor1.size(),
614 &descriptorType, &descriptorData);
615 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
616
617 // IANA Enterprise ID descriptor data less than length
618 std::array<uint8_t, 7> invalidIANADescriptor2{0x01, 0x00, 0x04, 0x00,
619 0x0a, 0x0b, 0x0c};
620 rc = decode_descriptor_type_length_value(invalidIANADescriptor2.data(),
621 invalidIANADescriptor2.size(),
622 &descriptorType, &descriptorData);
623 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
624 }
625
TEST(DecodeDescriptors,errorPathVendorDefinedDescriptor)626 TEST(DecodeDescriptors, errorPathVendorDefinedDescriptor)
627 {
628 int rc = 0;
629 // VendorDefinedDescriptorTitleStringType is invalid
630 constexpr std::array<uint8_t, 9> invalidVendorDescriptor1{
631 0x06, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
632 uint8_t descriptorStringType = 0;
633 variable_field descriptorTitleStr{};
634 variable_field vendorDefinedDescriptorData{};
635
636 rc = decode_vendor_defined_descriptor_value(
637 nullptr, invalidVendorDescriptor1.size(), &descriptorStringType,
638 &descriptorTitleStr, &vendorDefinedDescriptorData);
639 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
640
641 rc = decode_vendor_defined_descriptor_value(
642 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
643 &descriptorStringType, &descriptorTitleStr,
644 &vendorDefinedDescriptorData);
645 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
646
647 rc = decode_vendor_defined_descriptor_value(
648 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
649 nullptr, &descriptorTitleStr, &vendorDefinedDescriptorData);
650 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
651
652 rc = decode_vendor_defined_descriptor_value(
653 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
654 &descriptorStringType, nullptr, &vendorDefinedDescriptorData);
655 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
656
657 rc = decode_vendor_defined_descriptor_value(
658 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
659 &descriptorStringType, &descriptorTitleStr, nullptr);
660 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
661
662 rc = decode_vendor_defined_descriptor_value(
663 invalidVendorDescriptor1.data(),
664 sizeof(pldm_vendor_defined_descriptor_title_data) - 1,
665 &descriptorStringType, &descriptorTitleStr,
666 &vendorDefinedDescriptorData);
667 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
668
669 rc = decode_vendor_defined_descriptor_value(
670 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
671 &descriptorStringType, &descriptorTitleStr,
672 &vendorDefinedDescriptorData);
673 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
674
675 // VendorDefinedDescriptorTitleStringLength is 0
676 std::array<uint8_t, 9> invalidVendorDescriptor2{
677 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
678 rc = decode_vendor_defined_descriptor_value(
679 invalidVendorDescriptor2.data(), invalidVendorDescriptor2.size(),
680 &descriptorStringType, &descriptorTitleStr,
681 &vendorDefinedDescriptorData);
682 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
683
684 // VendorDefinedDescriptorData not present in the data
685 std::array<uint8_t, 9> invalidVendorDescriptor3{
686 0x01, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
687 rc = decode_vendor_defined_descriptor_value(
688 invalidVendorDescriptor3.data(), invalidVendorDescriptor3.size(),
689 &descriptorStringType, &descriptorTitleStr,
690 &vendorDefinedDescriptorData);
691 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
692 }
693
TEST(DecodeComponentImageInfo,goodPath)694 TEST(DecodeComponentImageInfo, goodPath)
695 {
696 // Firmware
697 constexpr uint16_t compClassification = 16;
698 constexpr uint16_t compIdentifier = 300;
699 constexpr uint32_t compComparisonStamp = 0xffffffff;
700 // Force update
701 constexpr std::bitset<16> compOptions{1};
702 // System reboot[Bit position 3] & Medium-specific reset[Bit position 2]
703 constexpr std::bitset<16> reqCompActivationMethod{0x0c};
704 // Random ComponentLocationOffset
705 constexpr uint32_t compLocOffset = 357;
706 // Random ComponentSize
707 constexpr uint32_t compSize = 27;
708 // ComponentVersionString
709 constexpr std::string_view compVersionStr{"VersionString1"};
710 constexpr size_t compImageInfoSize =
711 sizeof(pldm_component_image_information) + compVersionStr.size();
712
713 constexpr std::array<uint8_t, compImageInfoSize> compImageInfo{
714 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
715 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
716 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
717 pldm_component_image_information outCompImageInfo{};
718 variable_field outCompVersionStr{};
719
720 auto rc =
721 decode_pldm_comp_image_info(compImageInfo.data(), compImageInfo.size(),
722 &outCompImageInfo, &outCompVersionStr);
723
724 EXPECT_EQ(rc, PLDM_SUCCESS);
725 EXPECT_EQ(outCompImageInfo.comp_classification, compClassification);
726 EXPECT_EQ(outCompImageInfo.comp_identifier, compIdentifier);
727 EXPECT_EQ(outCompImageInfo.comp_comparison_stamp, compComparisonStamp);
728 EXPECT_EQ(outCompImageInfo.comp_options.value, compOptions);
729 EXPECT_EQ(outCompImageInfo.requested_comp_activation_method.value,
730 reqCompActivationMethod);
731 EXPECT_EQ(outCompImageInfo.comp_location_offset, compLocOffset);
732 EXPECT_EQ(outCompImageInfo.comp_size, compSize);
733 EXPECT_EQ(outCompImageInfo.comp_version_string_type, PLDM_STR_TYPE_ASCII);
734 EXPECT_EQ(outCompImageInfo.comp_version_string_length,
735 compVersionStr.size());
736
737 EXPECT_EQ(outCompVersionStr.length,
738 outCompImageInfo.comp_version_string_length);
739 std::string componentVersionString(
740 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
741 reinterpret_cast<const char*>(outCompVersionStr.ptr),
742 outCompVersionStr.length);
743 EXPECT_EQ(componentVersionString, compVersionStr);
744 }
745
TEST(DecodeComponentImageInfo,errorPaths)746 TEST(DecodeComponentImageInfo, errorPaths)
747 {
748 int rc = 0;
749 // ComponentVersionString
750 constexpr std::string_view compVersionStr{"VersionString1"};
751 constexpr size_t compImageInfoSize =
752 sizeof(pldm_component_image_information) + compVersionStr.size();
753 // Invalid ComponentVersionStringType - 0x06
754 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo1{
755 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
756 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x56, 0x65,
757 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
758 pldm_component_image_information outCompImageInfo{};
759 variable_field outCompVersionStr{};
760
761 rc = decode_pldm_comp_image_info(nullptr, invalidCompImageInfo1.size(),
762 &outCompImageInfo, &outCompVersionStr);
763 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
764
765 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
766 invalidCompImageInfo1.size(), nullptr,
767 &outCompVersionStr);
768 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
769
770 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
771 invalidCompImageInfo1.size(),
772 &outCompImageInfo, nullptr);
773 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
774
775 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
776 sizeof(pldm_component_image_information) -
777 1,
778 &outCompImageInfo, &outCompVersionStr);
779 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
780
781 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
782 invalidCompImageInfo1.size(),
783 &outCompImageInfo, &outCompVersionStr);
784 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
785
786 // Invalid ComponentVersionStringLength - 0x00
787 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo2{
788 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
789 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x65,
790 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
791 rc = decode_pldm_comp_image_info(invalidCompImageInfo2.data(),
792 invalidCompImageInfo2.size(),
793 &outCompImageInfo, &outCompVersionStr);
794 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
795
796 // Use Component Comparison Stamp is not set, but ComponentComparisonStamp
797 // is not 0xffffffff
798 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo3{
799 0x10, 0x00, 0x2c, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00,
800 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
801 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
802
803 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
804 invalidCompImageInfo3.size() - 1,
805 &outCompImageInfo, &outCompVersionStr);
806 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
807
808 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
809 invalidCompImageInfo3.size(),
810 &outCompImageInfo, &outCompVersionStr);
811 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
812
813 // Invalid ComponentLocationOffset - 0
814 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo4{
815 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
816 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
817 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
818 rc = decode_pldm_comp_image_info(invalidCompImageInfo4.data(),
819 invalidCompImageInfo4.size(),
820 &outCompImageInfo, &outCompVersionStr);
821 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
822
823 // Invalid ComponentSize - 0
824 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo5{
825 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
826 0x65, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
827 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
828 rc = decode_pldm_comp_image_info(invalidCompImageInfo5.data(),
829 invalidCompImageInfo5.size(),
830 &outCompImageInfo, &outCompVersionStr);
831 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
832 }
833
TEST(QueryDeviceIdentifiers,goodPathEncodeRequest)834 TEST(QueryDeviceIdentifiers, goodPathEncodeRequest)
835 {
836 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
837 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
838 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
839
840 uint8_t instanceId = 0x01;
841
842 auto rc = encode_query_device_identifiers_req(
843 instanceId, PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES, requestPtr);
844 EXPECT_EQ(rc, PLDM_SUCCESS);
845 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
846 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
847 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
848 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DEVICE_IDENTIFIERS);
849 }
850
TEST(QueryDeviceIdentifiers,goodPathDecodeResponse)851 TEST(QueryDeviceIdentifiers, goodPathDecodeResponse)
852 {
853 // descriptorDataLen is not fixed here taking it as 6
854 constexpr uint8_t descriptorDataLen = 6;
855 std::array<uint8_t, hdrSize +
856 sizeof(struct pldm_query_device_identifiers_resp) +
857 descriptorDataLen>
858 responseMsg{};
859 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
860 auto inResp = reinterpret_cast<struct pldm_query_device_identifiers_resp*>(
861 responseMsg.data() + hdrSize);
862
863 inResp->completion_code = PLDM_SUCCESS;
864 inResp->device_identifiers_len = htole32(descriptorDataLen);
865 inResp->descriptor_count = 1;
866
867 // filling descriptor data
868 std::fill_n(responseMsg.data() + hdrSize +
869 sizeof(struct pldm_query_device_identifiers_resp),
870 descriptorDataLen, 0xff);
871
872 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
873 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
874 uint8_t completionCode = PLDM_SUCCESS;
875 uint32_t deviceIdentifiersLen = 0;
876 uint8_t descriptorCount = 0;
877 uint8_t* outDescriptorData = nullptr;
878
879 auto rc = decode_query_device_identifiers_resp(
880 response, responseMsg.size() - hdrSize, &completionCode,
881 &deviceIdentifiersLen, &descriptorCount, &outDescriptorData);
882
883 EXPECT_EQ(rc, PLDM_SUCCESS);
884 EXPECT_EQ(completionCode, PLDM_SUCCESS);
885 EXPECT_EQ(deviceIdentifiersLen, inResp->device_identifiers_len);
886 EXPECT_EQ(descriptorCount, inResp->descriptor_count);
887 EXPECT_EQ(true,
888 std::equal(outDescriptorData,
889 outDescriptorData + deviceIdentifiersLen,
890 responseMsg.begin() + hdrSize +
891 sizeof(struct pldm_query_device_identifiers_resp),
892 responseMsg.end()));
893 }
894
895 #ifdef LIBPLDM_API_TESTING
TEST(QueryDeviceIdentifiers,goodPathEncodeResponse)896 TEST(QueryDeviceIdentifiers, goodPathEncodeResponse)
897 {
898 int rc;
899 PLDM_MSG_DEFINE_P(enc, 1000);
900 size_t enc_payload_len = 1000;
901 pldm_descriptor check_desc[] = {
902 {
903 .descriptor_type = PLDM_FWUP_IANA_ENTERPRISE_ID,
904 .descriptor_length = 4,
905 .descriptor_data = "a123",
906 },
907 {
908 .descriptor_type = PLDM_FWUP_VENDOR_DEFINED,
909 .descriptor_length = 3,
910 .descriptor_data = "987",
911 },
912 };
913 rc = encode_query_device_identifiers_resp(FIXED_INSTANCE_ID, 2, check_desc,
914 enc, &enc_payload_len);
915 EXPECT_EQ(rc, 0);
916 EXPECT_THAT(std::span<uint8_t>(enc_buf + hdrSize, enc_payload_len),
917 ElementsAreArray<uint8_t>({
918 // completion code
919 0x00,
920 // device identifiers length = 15
921 0x0f,
922 0x00,
923 0x00,
924 0x00,
925 // descriptor count
926 0x02,
927 // desc 0
928 0x01,
929 0x00,
930 0x04,
931 0x00,
932 0x61,
933 0x31,
934 0x32,
935 0x33,
936 // desc 1
937 0xff,
938 0xff,
939 0x03,
940 0x00,
941 0x39,
942 0x38,
943 0x37,
944 }));
945
946 check_response(enc, PLDM_QUERY_DEVICE_IDENTIFIERS);
947 }
948 #endif
949
TEST(GetFirmwareParameters,goodPathEncodeRequest)950 TEST(GetFirmwareParameters, goodPathEncodeRequest)
951 {
952 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
953 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
954 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
955 uint8_t instanceId = 0x01;
956
957 auto rc = encode_get_firmware_parameters_req(
958 instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, requestPtr);
959 EXPECT_EQ(rc, PLDM_SUCCESS);
960 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
961 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
962 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
963 EXPECT_EQ(requestPtr->hdr.command, PLDM_GET_FIRMWARE_PARAMETERS);
964 }
965
TEST(GetFirmwareParameters,decodeResponse)966 TEST(GetFirmwareParameters, decodeResponse)
967 {
968 // CapabilitiesDuringUpdate of the firmware device
969 // Firmware device downgrade restrictions [Bit position 8] &
970 // Firmware Device Partial Updates [Bit position 3]
971 constexpr std::bitset<32> fdCapabilities{0x00000104};
972 constexpr uint16_t compCount = 1;
973 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
974 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
975
976 // constexpr uint16_t compClassification = 16;
977 // constexpr uint16_t compIdentifier = 300;
978 // constexpr uint8_t compClassificationIndex = 20;
979 // constexpr uint32_t activeCompComparisonStamp = 0xabcdefab;
980 // constexpr std::array<uint8_t, 8> activeComponentReleaseData = {
981 // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
982 // constexpr uint32_t pendingCompComparisonStamp = 0x12345678;
983 // constexpr std::array<uint8_t, 8> pendingComponentReleaseData = {
984 // 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
985 constexpr std::string_view activeCompVersion{"VersionString3"};
986 constexpr std::string_view pendingCompVersion{"VersionString4"};
987
988 constexpr size_t compParamTableSize =
989 sizeof(pldm_component_parameter_entry) + activeCompVersion.size() +
990 pendingCompVersion.size();
991
992 constexpr std::array<uint8_t, compParamTableSize> compParamTable{
993 0x10, 0x00, 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01,
994 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
995 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00, 0x02,
996 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74,
997 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
998 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
999
1000 constexpr size_t getFwParamsPayloadLen =
1001 sizeof(pldm_get_firmware_parameters_resp) +
1002 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size() +
1003 compParamTableSize;
1004
1005 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1006 getFwParamsResponse{
1007 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01,
1008 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
1009 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
1010 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x10, 0x00,
1011 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01, 0x02,
1012 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
1013 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00,
1014 0x02, 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1015 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73,
1016 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
1017
1018 auto responseMsg =
1019 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1020 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1021 pldm_get_firmware_parameters_resp outResp{};
1022 variable_field outActiveCompImageSetVersion{};
1023 variable_field outPendingCompImageSetVersion{};
1024 variable_field outCompParameterTable{};
1025
1026 auto rc = decode_get_firmware_parameters_resp(
1027 responseMsg, getFwParamsPayloadLen, &outResp,
1028 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1029 &outCompParameterTable);
1030
1031 EXPECT_EQ(rc, PLDM_SUCCESS);
1032 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1033 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1034 EXPECT_EQ(outResp.comp_count, compCount);
1035 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1036 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1037 activeCompImageSetVersion.size());
1038 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1039 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1040 pendingCompImageSetVersion.size());
1041 std::string activeCompImageSetVersionStr(
1042 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1043 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1044 outActiveCompImageSetVersion.length);
1045 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1046 std::string pendingCompImageSetVersionStr(
1047 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1048 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
1049 outPendingCompImageSetVersion.length);
1050 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1051 EXPECT_EQ(outCompParameterTable.length, compParamTableSize);
1052 EXPECT_EQ(true, std::equal(outCompParameterTable.ptr,
1053 outCompParameterTable.ptr +
1054 outCompParameterTable.length,
1055 compParamTable.begin(), compParamTable.end()));
1056 }
1057
TEST(GetFirmwareParameters,decodeResponseZeroCompCount)1058 TEST(GetFirmwareParameters, decodeResponseZeroCompCount)
1059 {
1060 // CapabilitiesDuringUpdate of the firmware device
1061 // FD Host Functionality during Firmware Update [Bit position 2] &
1062 // Component Update Failure Retry Capability [Bit position 1]
1063 constexpr std::bitset<32> fdCapabilities{0x06};
1064 constexpr uint16_t compCount = 0;
1065 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
1066 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
1067
1068 constexpr size_t getFwParamsPayloadLen =
1069 sizeof(pldm_get_firmware_parameters_resp) +
1070 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size();
1071
1072 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1073 getFwParamsResponse{
1074 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1075 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
1076 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
1077 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32};
1078
1079 auto responseMsg =
1080 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1081 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1082 pldm_get_firmware_parameters_resp outResp{};
1083 variable_field outActiveCompImageSetVersion{};
1084 variable_field outPendingCompImageSetVersion{};
1085 variable_field outCompParameterTable{};
1086
1087 auto rc = decode_get_firmware_parameters_resp(
1088 responseMsg, getFwParamsPayloadLen, &outResp,
1089 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1090 &outCompParameterTable);
1091
1092 EXPECT_EQ(rc, PLDM_SUCCESS);
1093 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1094 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1095 EXPECT_EQ(outResp.comp_count, compCount);
1096 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1097 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1098 activeCompImageSetVersion.size());
1099 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1100 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1101 pendingCompImageSetVersion.size());
1102 std::string activeCompImageSetVersionStr(
1103 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1104 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1105 outActiveCompImageSetVersion.length);
1106 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1107 std::string pendingCompImageSetVersionStr(
1108 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1109 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
1110 outPendingCompImageSetVersion.length);
1111 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1112 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1113 EXPECT_EQ(outCompParameterTable.length, 0);
1114 }
1115
TEST(GetFirmwareParameters,decodeResponseNoPendingCompImageVersionStrZeroCompCount)1116 TEST(GetFirmwareParameters,
1117 decodeResponseNoPendingCompImageVersionStrZeroCompCount)
1118 {
1119 // CapabilitiesDuringUpdate of the firmware device
1120 // FD Host Functionality during Firmware Update [Bit position 2] &
1121 // Component Update Failure Retry Capability [Bit position 1]
1122 constexpr std::bitset<32> fdCapabilities{0x06};
1123 constexpr uint16_t compCount = 0;
1124 constexpr std::string_view activeCompImageSetVersion{"VersionString"};
1125
1126 constexpr size_t getFwParamsPayloadLen =
1127 sizeof(pldm_get_firmware_parameters_resp) +
1128 activeCompImageSetVersion.size();
1129
1130 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1131 getFwParamsResponse{0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1132 0x00, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00,
1133 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1134 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67};
1135
1136 auto responseMsg =
1137 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1138 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1139 pldm_get_firmware_parameters_resp outResp{};
1140 variable_field outActiveCompImageSetVersion{};
1141 variable_field outPendingCompImageSetVersion{};
1142 variable_field outCompParameterTable{};
1143
1144 auto rc = decode_get_firmware_parameters_resp(
1145 responseMsg, getFwParamsPayloadLen, &outResp,
1146 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1147 &outCompParameterTable);
1148
1149 EXPECT_EQ(rc, PLDM_SUCCESS);
1150 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1151 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1152 EXPECT_EQ(outResp.comp_count, compCount);
1153 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1154 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1155 activeCompImageSetVersion.size());
1156 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type,
1157 PLDM_STR_TYPE_UNKNOWN);
1158 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len, 0);
1159 std::string activeCompImageSetVersionStr(
1160 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1161 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1162 outActiveCompImageSetVersion.length);
1163 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1164 EXPECT_EQ(outPendingCompImageSetVersion.ptr, nullptr);
1165 EXPECT_EQ(outPendingCompImageSetVersion.length, 0);
1166 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1167 EXPECT_EQ(outCompParameterTable.length, 0);
1168 }
1169
TEST(GetFirmwareParameters,decodeResponseErrorCompletionCode)1170 TEST(GetFirmwareParameters, decodeResponseErrorCompletionCode)
1171 {
1172 constexpr std::array<uint8_t, hdrSize + sizeof(uint8_t)>
1173 getFwParamsResponse{0x00, 0x00, 0x00, 0x01};
1174
1175 auto responseMsg =
1176 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1177 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1178 pldm_get_firmware_parameters_resp outResp{};
1179 variable_field outActiveCompImageSetVersion{};
1180 variable_field outPendingCompImageSetVersion{};
1181 variable_field outCompParameterTable{};
1182
1183 auto rc = decode_get_firmware_parameters_resp(
1184 responseMsg, getFwParamsResponse.size(), &outResp,
1185 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1186 &outCompParameterTable);
1187
1188 EXPECT_EQ(rc, PLDM_SUCCESS);
1189 EXPECT_EQ(outResp.completion_code, PLDM_ERROR);
1190 }
1191
TEST(GetFirmwareParameters,errorPathdecodeResponse)1192 TEST(GetFirmwareParameters, errorPathdecodeResponse)
1193 {
1194 int rc = 0;
1195 // Invalid ActiveComponentImageSetVersionStringType
1196 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse1{
1197 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1198 0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
1199
1200 auto responseMsg =
1201 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1202 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse1.data());
1203 pldm_get_firmware_parameters_resp outResp{};
1204 variable_field outActiveCompImageSetVersion{};
1205 variable_field outPendingCompImageSetVersion{};
1206 variable_field outCompParameterTable{};
1207
1208 rc = decode_get_firmware_parameters_resp(
1209 nullptr, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1210 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1211 &outCompParameterTable);
1212 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1213
1214 rc = decode_get_firmware_parameters_resp(
1215 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, nullptr,
1216 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1217 &outCompParameterTable);
1218 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1219
1220 rc = decode_get_firmware_parameters_resp(
1221 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1222 nullptr, &outPendingCompImageSetVersion, &outCompParameterTable);
1223 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1224
1225 rc = decode_get_firmware_parameters_resp(
1226 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1227 &outActiveCompImageSetVersion, nullptr, &outCompParameterTable);
1228 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1229
1230 rc = decode_get_firmware_parameters_resp(
1231 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1232 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, nullptr);
1233 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1234
1235 rc = decode_get_firmware_parameters_resp(
1236 responseMsg, 0, &outResp, &outActiveCompImageSetVersion,
1237 &outPendingCompImageSetVersion, &outCompParameterTable);
1238 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1239
1240 rc = decode_get_firmware_parameters_resp(
1241 responseMsg, invalidGetFwParamsResponse1.size() - 1 - hdrSize, &outResp,
1242 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1243 &outCompParameterTable);
1244 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1245
1246 rc = decode_get_firmware_parameters_resp(
1247 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1248 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1249 &outCompParameterTable);
1250 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1251
1252 // Invalid ActiveComponentImageSetVersionStringLength
1253 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse2{
1254 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1255 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
1256 responseMsg =
1257 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1258 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse2.data());
1259 rc = decode_get_firmware_parameters_resp(
1260 responseMsg, invalidGetFwParamsResponse2.size() - hdrSize, &outResp,
1261 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1262 &outCompParameterTable);
1263 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1264
1265 // Invalid PendingComponentImageSetVersionStringType &
1266 // PendingComponentImageSetVersionStringLength
1267 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse3{
1268 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1269 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x00};
1270 responseMsg =
1271 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1272 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse3.data());
1273 rc = decode_get_firmware_parameters_resp(
1274 responseMsg, invalidGetFwParamsResponse3.size() - hdrSize, &outResp,
1275 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1276 &outCompParameterTable);
1277 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1278
1279 // Invalid PendingComponentImageSetVersionStringType &
1280 // PendingComponentImageSetVersionStringLength
1281 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse4{
1282 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1283 0x00, 0x00, 0x00, 0x01, 0x0e, 0x06, 0x0e};
1284 responseMsg =
1285 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1286 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse4.data());
1287 rc = decode_get_firmware_parameters_resp(
1288 responseMsg, invalidGetFwParamsResponse4.size() - hdrSize, &outResp,
1289 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1290 &outCompParameterTable);
1291 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1292
1293 // Total payload length less than expected
1294 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse5{
1295 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1296 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x0e};
1297 responseMsg =
1298 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1299 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse5.data());
1300 rc = decode_get_firmware_parameters_resp(
1301 responseMsg, invalidGetFwParamsResponse5.size() - hdrSize, &outResp,
1302 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1303 &outCompParameterTable);
1304 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1305 }
1306
TEST(GetFirmwareParameters,goodPathDecodeComponentParameterEntry)1307 TEST(GetFirmwareParameters, goodPathDecodeComponentParameterEntry)
1308 {
1309 // Random value for component classification
1310 constexpr uint16_t compClassification = 0x0a0b;
1311 // Random value for component classification
1312 constexpr uint16_t compIdentifier = 0x0c0d;
1313 constexpr uint16_t compClassificationIndex = 0xf;
1314 // Random value for component classification
1315 constexpr uint32_t timestamp = 0x12345678;
1316 // Random value for component activation methods
1317 constexpr uint16_t compActivationMethods = 0xbbdd;
1318 // Random value for capabilities during update
1319 constexpr uint32_t capabilitiesDuringUpdate = 0xbadbeefe;
1320
1321 // ActiveCompImageSetVerStrLen is not fixed here taking it as 8
1322 constexpr uint8_t activeCompVerStrLen = 8;
1323 // PendingCompImageSetVerStrLen is not fixed here taking it as 8
1324 constexpr uint8_t pendingCompVerStrLen = 8;
1325 constexpr size_t entryLength =
1326 sizeof(struct pldm_component_parameter_entry) + activeCompVerStrLen +
1327 pendingCompVerStrLen;
1328 std::array<uint8_t, entryLength> entry{};
1329
1330 auto inEntry =
1331 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1332 reinterpret_cast<struct pldm_component_parameter_entry*>(entry.data());
1333
1334 inEntry->comp_classification = htole16(compClassification);
1335 inEntry->comp_identifier = htole16(compIdentifier);
1336 inEntry->comp_classification_index = compClassificationIndex;
1337 inEntry->active_comp_comparison_stamp = htole32(timestamp);
1338 inEntry->active_comp_ver_str_type = 1;
1339 inEntry->active_comp_ver_str_len = activeCompVerStrLen;
1340 std::fill_n(inEntry->active_comp_release_date,
1341 sizeof(inEntry->active_comp_release_date), 0xff);
1342 inEntry->pending_comp_comparison_stamp = htole32(timestamp);
1343 inEntry->pending_comp_ver_str_type = 1;
1344 inEntry->pending_comp_ver_str_len = pendingCompVerStrLen;
1345 std::fill_n(inEntry->pending_comp_release_date,
1346 sizeof(inEntry->pending_comp_release_date), 0xff);
1347 inEntry->comp_activation_methods.value = htole16(compActivationMethods);
1348 inEntry->capabilities_during_update.value =
1349 htole32(capabilitiesDuringUpdate);
1350 constexpr auto activeCompVerStrPos =
1351 sizeof(struct pldm_component_parameter_entry);
1352 std::fill_n(entry.data() + activeCompVerStrPos, activeCompVerStrLen, 0xaa);
1353 constexpr auto pendingCompVerStrPos =
1354 activeCompVerStrPos + activeCompVerStrLen;
1355 std::fill_n(entry.data() + pendingCompVerStrPos, pendingCompVerStrLen,
1356 0xbb);
1357
1358 struct pldm_component_parameter_entry outEntry;
1359 struct variable_field outActiveCompVerStr;
1360 struct variable_field outPendingCompVerStr;
1361
1362 auto rc = decode_get_firmware_parameters_resp_comp_entry(
1363 entry.data(), entryLength, &outEntry, &outActiveCompVerStr,
1364 &outPendingCompVerStr);
1365
1366 EXPECT_EQ(rc, PLDM_SUCCESS);
1367
1368 EXPECT_EQ(outEntry.comp_classification, compClassification);
1369 EXPECT_EQ(outEntry.comp_identifier, compIdentifier);
1370 EXPECT_EQ(inEntry->comp_classification_index,
1371 outEntry.comp_classification_index);
1372 EXPECT_EQ(outEntry.active_comp_comparison_stamp, timestamp);
1373 EXPECT_EQ(inEntry->active_comp_ver_str_type,
1374 outEntry.active_comp_ver_str_type);
1375 EXPECT_EQ(inEntry->active_comp_ver_str_len,
1376 outEntry.active_comp_ver_str_len);
1377 EXPECT_EQ(0, memcmp(inEntry->active_comp_release_date,
1378 outEntry.active_comp_release_date,
1379 sizeof(inEntry->active_comp_release_date)));
1380 EXPECT_EQ(outEntry.pending_comp_comparison_stamp, timestamp);
1381 EXPECT_EQ(inEntry->pending_comp_ver_str_type,
1382 outEntry.pending_comp_ver_str_type);
1383 EXPECT_EQ(inEntry->pending_comp_ver_str_len,
1384 outEntry.pending_comp_ver_str_len);
1385 EXPECT_EQ(0, memcmp(inEntry->pending_comp_release_date,
1386 outEntry.pending_comp_release_date,
1387 sizeof(inEntry->pending_comp_release_date)));
1388 EXPECT_EQ(outEntry.comp_activation_methods.value, compActivationMethods);
1389 EXPECT_EQ(outEntry.capabilities_during_update.value,
1390 capabilitiesDuringUpdate);
1391
1392 EXPECT_EQ(0, memcmp(outActiveCompVerStr.ptr,
1393 entry.data() + activeCompVerStrPos,
1394 outActiveCompVerStr.length));
1395 EXPECT_EQ(0, memcmp(outPendingCompVerStr.ptr,
1396 entry.data() + pendingCompVerStrPos,
1397 outPendingCompVerStr.length));
1398
1399 #ifdef LIBPLDM_API_TESTING
1400 /* Check the roundtrip matches */
1401 std::vector<uint8_t> enc_data(1000);
1402 size_t enc_payload_len = enc_data.size();
1403 struct pldm_component_parameter_entry_full entryFull = {
1404 .comp_classification = compClassification,
1405 .comp_identifier = compIdentifier,
1406 .comp_classification_index = compClassificationIndex,
1407 .active_ver =
1408 {
1409 .comparison_stamp = 0x12345678,
1410 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1411 .str_len = activeCompVerStrLen,
1412 .str_data = {}},
1413 .date = {},
1414 },
1415 .pending_ver =
1416 {
1417 .comparison_stamp = 0x12345678,
1418 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1419 .str_len = pendingCompVerStrLen,
1420 .str_data = {}},
1421 .date = {},
1422 },
1423 .comp_activation_methods = inEntry->comp_activation_methods,
1424 .capabilities_during_update = inEntry->capabilities_during_update,
1425 };
1426 // Fill strings
1427 std::fill_n(entryFull.active_ver.str.str_data, activeCompVerStrLen, 0xaa);
1428 std::fill_n(entryFull.pending_ver.str.str_data, pendingCompVerStrLen, 0xbb);
1429 std::fill_n(entryFull.active_ver.date, PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN,
1430 0xff);
1431 std::fill_n(entryFull.pending_ver.date,
1432 PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN, 0xff);
1433
1434 rc = encode_get_firmware_parameters_resp_comp_entry(
1435 &entryFull, enc_data.data(), &enc_payload_len);
1436 EXPECT_EQ(rc, PLDM_SUCCESS);
1437 EXPECT_EQ(enc_payload_len, entryLength);
1438 EXPECT_TRUE(std::equal(entry.begin(), entry.end(), enc_data.begin()));
1439 #endif
1440 }
1441
1442 #ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamDevices,goodPathEncodeRequest)1443 TEST(QueryDownstreamDevices, goodPathEncodeRequest)
1444 {
1445 constexpr uint8_t instanceId = 1;
1446 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
1447 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1448 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1449
1450 auto rc = encode_query_downstream_devices_req(instanceId, requestPtr);
1451
1452 EXPECT_EQ(rc, 0);
1453 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1454 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1455 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1456 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DOWNSTREAM_DEVICES);
1457 }
1458 #endif
1459
1460 #ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamDevices,encodeRequestInvalidData)1461 TEST(QueryDownstreamDevices, encodeRequestInvalidData)
1462 {
1463 constexpr uint8_t instanceId = 1;
1464
1465 auto rc = encode_query_downstream_devices_req(instanceId, nullptr);
1466
1467 EXPECT_EQ(rc, -EINVAL);
1468 }
1469 #endif
1470
1471 #ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamDevices,goodPathDecodeResponse)1472 TEST(QueryDownstreamDevices, goodPathDecodeResponse)
1473 {
1474 uint8_t completion_code_resp = PLDM_SUCCESS;
1475 uint8_t downstream_device_update_supported_resp =
1476 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1477 uint16_t number_of_downstream_devices_resp = 1;
1478 uint16_t max_number_of_downstream_devices_resp = 1;
1479 /** Capabilities of updating downstream devices
1480 * FDP supports downstream devices dynamically attached [Bit position 0] &
1481 * FDP supports downstream devices dynamically removed [Bit position 1]
1482 */
1483 bitfield32_t capabilities_resp = {.value = 0x0002};
1484 int rc;
1485
1486 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1487 responseMsg{};
1488
1489 struct pldm_msgbuf _buf;
1490 struct pldm_msgbuf* buf = &_buf;
1491 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1492 responseMsg.size() - hdrSize);
1493 EXPECT_EQ(rc, 0);
1494
1495 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1496 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1497 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1498 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1499 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
1500
1501 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1502 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1503 struct pldm_query_downstream_devices_resp resp_data;
1504
1505 rc = decode_query_downstream_devices_resp(
1506 response, responseMsg.size() - hdrSize, &resp_data);
1507
1508 EXPECT_EQ(rc, 0);
1509 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1510 EXPECT_EQ(resp_data.downstream_device_update_supported,
1511 downstream_device_update_supported_resp);
1512 EXPECT_EQ(resp_data.number_of_downstream_devices,
1513 number_of_downstream_devices_resp);
1514 EXPECT_EQ(resp_data.max_number_of_downstream_devices,
1515 max_number_of_downstream_devices_resp);
1516 EXPECT_EQ(resp_data.capabilities.value, capabilities_resp.value);
1517 }
1518 #endif
1519
1520 #ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamDevices,decodeRequestUndefinedValue)1521 TEST(QueryDownstreamDevices, decodeRequestUndefinedValue)
1522 {
1523 uint8_t completion_code_resp = PLDM_SUCCESS;
1524 uint8_t downstream_device_update_supported_resp = 0xe; /*Undefined value*/
1525 uint16_t number_of_downstream_devices_resp = 1;
1526 uint16_t max_number_of_downstream_devices_resp = 1;
1527 /** Capabilities of updating downstream devices
1528 * FDP supports downstream devices dynamically attached [Bit position 0] &
1529 * FDP supports downstream devices dynamically removed [Bit position 1]
1530 */
1531 bitfield32_t capabilities_resp = {.value = 0x0002};
1532 int rc;
1533
1534 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1535 responseMsg{};
1536
1537 struct pldm_msgbuf _buf;
1538 struct pldm_msgbuf* buf = &_buf;
1539 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1540 responseMsg.size() - hdrSize);
1541 EXPECT_EQ(rc, 0);
1542
1543 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1544 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1545 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1546 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1547 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
1548
1549 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1550 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1551 struct pldm_query_downstream_devices_resp resp_data;
1552
1553 rc = decode_query_downstream_devices_resp(
1554 response, responseMsg.size() - hdrSize, &resp_data);
1555
1556 ASSERT_EQ(rc, -EINVAL);
1557 }
1558 #endif
1559
1560 #ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamDevices,decodeRequestErrorBufSize)1561 TEST(QueryDownstreamDevices, decodeRequestErrorBufSize)
1562 {
1563 uint8_t completion_code_resp = PLDM_SUCCESS;
1564 uint8_t downstream_device_update_supported_resp =
1565 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1566 uint16_t number_of_downstream_devices_resp = 1;
1567 uint16_t max_number_of_downstream_devices_resp = 1;
1568 /** Capabilities of updating downstream devices
1569 * FDP supports downstream devices dynamically attached [Bit position 0] &
1570 * FDP supports downstream devices dynamically removed [Bit position 1]
1571 */
1572 bitfield32_t capabilities_resp = {.value = 0x0002};
1573 int rc;
1574
1575 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES -
1576 2 /* Inject error length*/>
1577 responseMsg{};
1578
1579 struct pldm_msgbuf _buf;
1580 struct pldm_msgbuf* buf = &_buf;
1581 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1582 responseMsg.size() - hdrSize);
1583 EXPECT_EQ(rc, 0);
1584
1585 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1586 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1587 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1588 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1589 // Inject error value
1590 pldm_msgbuf_insert_uint16(buf, (uint16_t)capabilities_resp.value);
1591
1592 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1593 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1594 struct pldm_query_downstream_devices_resp resp_data;
1595
1596 rc = decode_query_downstream_devices_resp(
1597 response, responseMsg.size() - hdrSize, &resp_data);
1598
1599 EXPECT_EQ(rc, -EBADMSG);
1600 }
1601 #endif
1602
1603 #ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamIdentifiers,goodPathEncodeRequest)1604 TEST(QueryDownstreamIdentifiers, goodPathEncodeRequest)
1605 {
1606 constexpr uint8_t instanceId = 1;
1607 constexpr size_t payloadLen = PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1608 PLDM_MSG_DEFINE_P(request, payloadLen);
1609 constexpr pldm_query_downstream_identifiers_req params_req{
1610 0xFFFFFFFF, PLDM_GET_FIRSTPART};
1611
1612 auto rc = encode_query_downstream_identifiers_req(instanceId, ¶ms_req,
1613 request, payloadLen);
1614 ASSERT_EQ(rc, 0);
1615 EXPECT_THAT(std::span<uint8_t>(request_buf, sizeof(request_buf)),
1616 ElementsAreArray<uint8_t>(
1617 {0x81, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x01}));
1618 }
1619 #endif
1620
1621 #ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamIdentifiers,encodeRequestInvalidErrorPaths)1622 TEST(QueryDownstreamIdentifiers, encodeRequestInvalidErrorPaths)
1623 {
1624 constexpr uint8_t instanceId = 1;
1625 constexpr pldm_query_downstream_identifiers_req params_req{
1626 0xFFFFFFFF, PLDM_GET_FIRSTPART};
1627 constexpr pldm_query_downstream_identifiers_req params_req_invalid{
1628 0xFFFFFFFF, PLDM_ACKNOWLEDGEMENT_ONLY};
1629 constexpr size_t payload_length =
1630 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1631 std::array<uint8_t, hdrSize + payload_length> requestMsg{};
1632 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1633 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1634
1635 auto rc = encode_query_downstream_identifiers_req(instanceId, ¶ms_req,
1636 nullptr, payload_length);
1637 EXPECT_EQ(rc, -EINVAL);
1638
1639 rc = encode_query_downstream_identifiers_req(
1640 instanceId, ¶ms_req, requestPtr, payload_length - 1);
1641 EXPECT_EQ(rc, -EOVERFLOW);
1642
1643 rc = encode_query_downstream_identifiers_req(
1644 instanceId, ¶ms_req_invalid, requestPtr, payload_length);
1645 EXPECT_EQ(rc, -EINVAL);
1646 }
1647 #endif
1648
1649 #ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamIdentifiers,decodeResponseNoDevices)1650 TEST(QueryDownstreamIdentifiers, decodeResponseNoDevices)
1651 {
1652 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1653 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1654 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1655 constexpr uint32_t downstream_devices_length_resp = 0;
1656 constexpr uint16_t number_of_downstream_devices_resp = 0;
1657
1658 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1659 struct pldm_query_downstream_identifiers_resp resp_data = {};
1660 struct pldm_downstream_device_iter devs;
1661 struct pldm_msgbuf _buf;
1662 struct pldm_msgbuf* buf = &_buf;
1663 int rc = 0;
1664
1665 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1666 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1667 ASSERT_EQ(rc, 0);
1668
1669 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1670 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1671 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1672 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1673 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1674
1675 ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1676
1677 rc = decode_query_downstream_identifiers_resp(
1678 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp_data,
1679 &devs);
1680
1681 ASSERT_EQ(rc, 0);
1682 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1683 EXPECT_EQ(resp_data.next_data_transfer_handle,
1684 next_data_transfer_handle_resp);
1685 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1686 EXPECT_EQ(resp_data.downstream_devices_length,
1687 downstream_devices_length_resp);
1688 EXPECT_EQ(resp_data.number_of_downstream_devices,
1689 number_of_downstream_devices_resp);
1690 }
1691 #endif
1692
1693 #ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamIdentifiers,decodeResponseNoDevicesBadCount)1694 TEST(QueryDownstreamIdentifiers, decodeResponseNoDevicesBadCount)
1695 {
1696 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1697 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1698 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1699 constexpr uint32_t downstream_devices_length_resp = 0;
1700 constexpr uint16_t number_of_downstream_devices_resp = 1;
1701
1702 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1703 struct pldm_query_downstream_identifiers_resp resp = {};
1704 struct pldm_downstream_device_iter devs;
1705 struct pldm_downstream_device dev;
1706 struct pldm_msgbuf _buf;
1707 struct pldm_msgbuf* buf = &_buf;
1708 int rc = 0;
1709
1710 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1711 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1712 ASSERT_EQ(rc, 0);
1713
1714 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1715 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1716 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1717 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1718 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1719
1720 ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1721
1722 rc = decode_query_downstream_identifiers_resp(
1723 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp, &devs);
1724 ASSERT_EQ(rc, 0);
1725
1726 foreach_pldm_downstream_device(devs, dev, rc)
1727 {
1728 FAIL();
1729 }
1730 ASSERT_NE(rc, 0);
1731 }
1732 #endif
1733
1734 #ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamIdentifiers,decodeResponseOneDeviceOneDescriptor)1735 TEST(QueryDownstreamIdentifiers, decodeResponseOneDeviceOneDescriptor)
1736 {
1737 constexpr uint32_t downstreamDevicesLen = 11;
1738 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1739 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1740 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1741 const uint32_t downstream_devices_length_resp =
1742 htole32(downstreamDevicesLen);
1743 constexpr uint16_t number_of_downstream_devices_resp = 1;
1744 constexpr size_t payloadLen =
1745 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstreamDevicesLen;
1746
1747 struct pldm_query_downstream_identifiers_resp resp_data = {};
1748 PLDM_MSG_DEFINE_P(response, payloadLen);
1749 struct pldm_downstream_device_iter devs;
1750 struct pldm_downstream_device dev;
1751 struct pldm_msgbuf _buf;
1752 struct pldm_msgbuf* buf = &_buf;
1753 int rc = 0;
1754
1755 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1756 ASSERT_EQ(rc, 0);
1757
1758 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1759 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1760 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1761 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1762 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1763
1764 /* Downstream device */
1765 pldm_msgbuf_insert_uint16(buf, 1);
1766 pldm_msgbuf_insert_uint8(buf, 1);
1767
1768 /* Device descriptor */
1769 pldm_msgbuf_insert_uint16(buf, 1);
1770 pldm_msgbuf_insert_uint16(buf, 4);
1771 pldm_msgbuf_insert_uint32(buf, 412);
1772
1773 ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1774
1775 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1776 &resp_data, &devs);
1777
1778 ASSERT_EQ(rc, 0);
1779 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1780 EXPECT_EQ(resp_data.next_data_transfer_handle,
1781 next_data_transfer_handle_resp);
1782 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1783 EXPECT_EQ(resp_data.downstream_devices_length,
1784 downstream_devices_length_resp);
1785 EXPECT_EQ(resp_data.number_of_downstream_devices,
1786 number_of_downstream_devices_resp);
1787
1788 foreach_pldm_downstream_device(devs, dev, rc)
1789 {
1790 struct pldm_descriptor desc;
1791
1792 EXPECT_EQ(dev.downstream_device_index, 1);
1793 EXPECT_EQ(dev.downstream_descriptor_count, 1);
1794
1795 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1796 {
1797 static const uint32_t dmtf = htole32(412);
1798 EXPECT_EQ(desc.descriptor_type, 1);
1799 EXPECT_EQ(desc.descriptor_length, 4);
1800 EXPECT_EQ(memcmp(desc.descriptor_data, &dmtf, sizeof(dmtf)), 0);
1801 }
1802 ASSERT_EQ(rc, 0);
1803 }
1804 ASSERT_EQ(rc, 0);
1805 }
1806 #endif
1807
1808 #ifdef LIBPLDM_API_TESTING
1809 constexpr const uint16_t descriptor_id_type_iana_pen = 0x1;
1810 constexpr const uint16_t descriptor_id_len_iana_pen = 0x4;
1811 const uint32_t iana_pen_openbmc = htole16(49871u);
1812 const uint32_t iana_pen_dmtf = htole16(412u);
1813 #endif
1814
1815 #ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamIdentifiers,decodeResponseTwoDevicesOneDescriptorEach)1816 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneDescriptorEach)
1817 {
1818 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1819 {0, 1},
1820 {1, 1},
1821 }};
1822
1823 constexpr const std::array<pldm_descriptor, 2> expected_descriptors = {{
1824 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1825 &iana_pen_dmtf},
1826 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1827 &iana_pen_openbmc},
1828 }};
1829
1830 constexpr uint32_t downstream_devices_len = 22;
1831 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1832 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1833 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1834 const uint32_t downstream_devices_length_resp =
1835 htole32(downstream_devices_len);
1836 constexpr uint16_t number_of_downstream_devices_resp = 2;
1837 constexpr size_t payloadLen =
1838 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
1839
1840 struct pldm_query_downstream_identifiers_resp resp_data{};
1841 PLDM_MSG_DEFINE_P(response, payloadLen);
1842 struct pldm_downstream_device_iter devs;
1843 struct pldm_downstream_device dev;
1844 struct pldm_msgbuf _buf;
1845 struct pldm_msgbuf* buf = &_buf;
1846 int rc = 0;
1847
1848 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1849 ASSERT_EQ(rc, 0);
1850
1851 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1852 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1853 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1854 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1855 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1856
1857 /* Downstream device */
1858 pldm_msgbuf_insert_uint16(buf, 0);
1859 pldm_msgbuf_insert_uint8(buf, 1);
1860
1861 /* Device descriptor */
1862 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1863 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1864 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1865
1866 /* Downstream device */
1867 pldm_msgbuf_insert_uint16(buf, 1);
1868 pldm_msgbuf_insert_uint8(buf, 1);
1869
1870 /* Device descriptor */
1871 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1872 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1873 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
1874
1875 ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1876
1877 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1878 &resp_data, &devs);
1879
1880 ASSERT_EQ(rc, 0);
1881 EXPECT_EQ(resp_data.number_of_downstream_devices,
1882 number_of_downstream_devices_resp);
1883
1884 size_t devIndex = 0;
1885 size_t descIndex = 0;
1886 foreach_pldm_downstream_device(devs, dev, rc)
1887 {
1888 struct pldm_descriptor desc;
1889
1890 ASSERT_LT(devIndex, expected_devices.size());
1891
1892 const struct pldm_downstream_device* expectedDev =
1893 &expected_devices[devIndex];
1894
1895 EXPECT_EQ(dev.downstream_device_index,
1896 expectedDev->downstream_device_index);
1897 EXPECT_EQ(dev.downstream_descriptor_count,
1898 expectedDev->downstream_descriptor_count);
1899
1900 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1901 {
1902 ASSERT_LT(descIndex, expected_descriptors.size());
1903
1904 const struct pldm_descriptor* expectedDesc =
1905 &expected_descriptors[descIndex];
1906
1907 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
1908 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
1909 EXPECT_EQ(memcmp(desc.descriptor_data,
1910 expectedDesc->descriptor_data,
1911 expectedDesc->descriptor_length),
1912 0);
1913
1914 descIndex++;
1915 }
1916 ASSERT_EQ(rc, 0);
1917 EXPECT_EQ(descIndex, 1 * devIndex + 1);
1918
1919 devIndex++;
1920 }
1921 ASSERT_EQ(rc, 0);
1922 EXPECT_EQ(devIndex, 2);
1923 }
1924 #endif
1925
1926 #ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamIdentifiers,decodeResponseTwoDevicesTwoOneDescriptors)1927 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesTwoOneDescriptors)
1928 {
1929 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1930 {0, 2},
1931 {1, 1},
1932 }};
1933
1934 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
1935 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1936 &iana_pen_dmtf},
1937 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1938 &iana_pen_openbmc},
1939 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1940 &iana_pen_dmtf},
1941 }};
1942
1943 constexpr uint32_t downstream_devices_len = 30;
1944 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1945 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1946 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1947 const uint32_t downstream_devices_length_resp =
1948 htole32(downstream_devices_len);
1949 constexpr uint16_t number_of_downstream_devices_resp = 2;
1950 constexpr size_t payloadLen =
1951 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
1952
1953 struct pldm_query_downstream_identifiers_resp resp_data{};
1954 PLDM_MSG_DEFINE_P(response, payloadLen);
1955 struct pldm_downstream_device_iter devs;
1956 struct pldm_downstream_device dev;
1957 struct pldm_msgbuf _buf;
1958 struct pldm_msgbuf* buf = &_buf;
1959 int rc = 0;
1960
1961 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1962 ASSERT_EQ(rc, 0);
1963
1964 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1965 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1966 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1967 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1968 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1969
1970 /* Downstream device */
1971 pldm_msgbuf_insert_uint16(buf, 0);
1972 pldm_msgbuf_insert_uint8(buf, 2);
1973
1974 /* Device descriptor */
1975 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1976 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1977 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1978
1979 /* Device descriptor */
1980 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1981 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1982 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
1983
1984 /* Downstream device */
1985 pldm_msgbuf_insert_uint16(buf, 1);
1986 pldm_msgbuf_insert_uint8(buf, 1);
1987
1988 /* Device descriptor */
1989 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1990 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1991 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1992
1993 ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1994
1995 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1996 &resp_data, &devs);
1997
1998 ASSERT_EQ(rc, 0);
1999 EXPECT_EQ(resp_data.number_of_downstream_devices,
2000 number_of_downstream_devices_resp);
2001
2002 size_t devIndex = 0;
2003 size_t descIndex = 0;
2004 foreach_pldm_downstream_device(devs, dev, rc)
2005 {
2006 struct pldm_descriptor desc;
2007
2008 ASSERT_LT(devIndex, expected_devices.size());
2009
2010 const struct pldm_downstream_device* expectedDev =
2011 &expected_devices[devIndex];
2012
2013 EXPECT_EQ(dev.downstream_device_index,
2014 expectedDev->downstream_device_index);
2015 EXPECT_EQ(dev.downstream_descriptor_count,
2016 expectedDev->downstream_descriptor_count);
2017
2018 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2019 {
2020 ASSERT_LT(descIndex, expected_descriptors.size());
2021
2022 const struct pldm_descriptor* expectedDesc =
2023 &expected_descriptors[descIndex];
2024
2025 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2026 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2027 EXPECT_EQ(memcmp(desc.descriptor_data,
2028 expectedDesc->descriptor_data,
2029 expectedDesc->descriptor_length),
2030 0);
2031
2032 descIndex++;
2033 }
2034 ASSERT_EQ(rc, 0);
2035
2036 devIndex++;
2037 }
2038 ASSERT_EQ(rc, 0);
2039 EXPECT_EQ(devIndex, 2);
2040 EXPECT_EQ(descIndex, 3);
2041 }
2042 #endif
2043
2044 #ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamIdentifiers,decodeResponseTwoDevicesOneTwoDescriptors)2045 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneTwoDescriptors)
2046 {
2047 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
2048 {0, 1},
2049 {1, 2},
2050 }};
2051
2052 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
2053 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2054 &iana_pen_dmtf},
2055 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2056 &iana_pen_openbmc},
2057 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2058 &iana_pen_dmtf},
2059 }};
2060
2061 constexpr uint32_t downstream_devices_len = 30;
2062 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2063 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2064 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2065 const uint32_t downstream_devices_length_resp =
2066 htole32(downstream_devices_len);
2067 constexpr uint16_t number_of_downstream_devices_resp = 2;
2068 constexpr size_t payloadLen =
2069 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2070
2071 struct pldm_query_downstream_identifiers_resp resp_data{};
2072 PLDM_MSG_DEFINE_P(response, payloadLen);
2073 struct pldm_downstream_device_iter devs;
2074 struct pldm_downstream_device dev;
2075 struct pldm_msgbuf _buf;
2076 struct pldm_msgbuf* buf = &_buf;
2077 int rc = 0;
2078
2079 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2080 ASSERT_EQ(rc, 0);
2081
2082 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2083 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2084 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2085 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2086 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2087
2088 /* Downstream device */
2089 pldm_msgbuf_insert_uint16(buf, 0);
2090 pldm_msgbuf_insert_uint8(buf, 1);
2091
2092 /* Device descriptor */
2093 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2094 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2095 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2096
2097 /* Downstream device */
2098 pldm_msgbuf_insert_uint16(buf, 1);
2099 pldm_msgbuf_insert_uint8(buf, 2);
2100
2101 /* Device descriptor */
2102 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2103 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2104 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2105
2106 /* Device descriptor */
2107 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2108 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2109 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2110
2111 ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
2112
2113 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2114 &resp_data, &devs);
2115
2116 ASSERT_EQ(rc, 0);
2117 EXPECT_EQ(resp_data.number_of_downstream_devices,
2118 number_of_downstream_devices_resp);
2119
2120 size_t devIndex = 0;
2121 size_t descIndex = 0;
2122 foreach_pldm_downstream_device(devs, dev, rc)
2123 {
2124 struct pldm_descriptor desc;
2125
2126 ASSERT_LT(devIndex, expected_devices.size());
2127
2128 const struct pldm_downstream_device* expectedDev =
2129 &expected_devices[devIndex];
2130
2131 EXPECT_EQ(dev.downstream_device_index,
2132 expectedDev->downstream_device_index);
2133 EXPECT_EQ(dev.downstream_descriptor_count,
2134 expectedDev->downstream_descriptor_count);
2135
2136 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2137 {
2138 ASSERT_LT(descIndex, expected_descriptors.size());
2139
2140 const struct pldm_descriptor* expectedDesc =
2141 &expected_descriptors[descIndex];
2142
2143 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2144 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2145 EXPECT_EQ(memcmp(desc.descriptor_data,
2146 expectedDesc->descriptor_data,
2147 expectedDesc->descriptor_length),
2148 0);
2149
2150 descIndex++;
2151 }
2152 ASSERT_EQ(rc, 0);
2153
2154 devIndex++;
2155 }
2156 ASSERT_EQ(rc, 0);
2157 EXPECT_EQ(devIndex, 2);
2158 EXPECT_EQ(descIndex, 3);
2159 }
2160 #endif
2161
2162 #ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamIdentifiers,decodeRequestErrorPaths)2163 TEST(QueryDownstreamIdentifiers, decodeRequestErrorPaths)
2164 {
2165 constexpr size_t payloadLen = sizeof(uint8_t);
2166
2167 struct pldm_query_downstream_identifiers_resp resp_data = {};
2168 struct pldm_downstream_device_iter devs;
2169 PLDM_MSG_DEFINE_P(response, payloadLen);
2170
2171 // Test nullptr
2172 auto rc = decode_query_downstream_identifiers_resp(nullptr, payloadLen,
2173 nullptr, &devs);
2174 EXPECT_EQ(rc, -EINVAL);
2175
2176 // Test not PLDM_SUCCESS completion code
2177 response->payload[0] = PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
2178 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2179 &resp_data, &devs);
2180 EXPECT_EQ(rc, 0);
2181 EXPECT_EQ(resp_data.completion_code, PLDM_ERROR_UNSUPPORTED_PLDM_CMD);
2182
2183 // Test payload length less than minimum length
2184 response->payload[0] = PLDM_SUCCESS;
2185 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2186 &resp_data, &devs);
2187
2188 EXPECT_EQ(rc, -EBADMSG);
2189 }
2190 #endif
2191
2192 #ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamIdentifiers,decodeRequestErrorDownstreamDevicesSize)2193 TEST(QueryDownstreamIdentifiers, decodeRequestErrorDownstreamDevicesSize)
2194 {
2195 // Len is not fixed here taking it as 9, contains 1 downstream device with
2196 // 1 descriptor
2197 constexpr uint32_t actualDownstreamDevicesLen = 9;
2198 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2199 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2200 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2201 constexpr uint16_t number_of_downstream_devices_resp = 1;
2202 constexpr size_t payloadLen =
2203 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN +
2204 actualDownstreamDevicesLen;
2205
2206 const uint32_t downstream_devices_length_resp =
2207 htole32(actualDownstreamDevicesLen + 1 /* inject error length*/);
2208
2209 struct pldm_query_downstream_identifiers_resp resp_data = {};
2210 struct pldm_downstream_device_iter devs;
2211 PLDM_MSG_DEFINE_P(response, payloadLen);
2212 struct pldm_msgbuf _buf;
2213 struct pldm_msgbuf* buf = &_buf;
2214 void* devicesStart = NULL;
2215 size_t devicesLen;
2216 int rc = 0;
2217
2218 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2219 EXPECT_EQ(rc, 0);
2220
2221 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2222 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2223 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2224 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2225 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2226 pldm_msgbuf_span_remaining(buf, &devicesStart, &devicesLen);
2227
2228 /** Filling descriptor data, the correctness of the downstream devices data
2229 * is not checked in this test case so filling with 0xff
2230 */
2231 std::fill_n(static_cast<uint8_t*>(devicesStart), actualDownstreamDevicesLen,
2232 0xff);
2233
2234 EXPECT_NE(decode_query_downstream_identifiers_resp(response, payloadLen,
2235 &resp_data, &devs),
2236 0);
2237 }
2238 #endif
2239
2240 #ifdef LIBPLDM_API_TESTING
TEST(QueryDownstreamIdentifiers,decodeRequestErrorBufSize)2241 TEST(QueryDownstreamIdentifiers, decodeRequestErrorBufSize)
2242 {
2243 constexpr uint32_t actualDownstreamDevicesLen = 0;
2244 constexpr uint16_t number_of_downstream_devices_resp = 1;
2245 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2246 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2247 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2248 constexpr size_t payloadLen =
2249 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN - 1;
2250
2251 const uint32_t downstream_devices_length_resp =
2252 htole32(actualDownstreamDevicesLen);
2253
2254 struct pldm_query_downstream_identifiers_resp resp_data = {};
2255 struct pldm_downstream_device_iter devs;
2256 PLDM_MSG_DEFINE_P(response, payloadLen);
2257 struct pldm_msgbuf _buf;
2258 struct pldm_msgbuf* buf = &_buf;
2259 int rc = 0;
2260
2261 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2262 ASSERT_EQ(rc, 0);
2263
2264 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2265 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2266 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2267 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2268 // Inject error buffer size
2269 pldm_msgbuf_insert_uint8(buf, (uint8_t)number_of_downstream_devices_resp);
2270
2271 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2272 &resp_data, &devs);
2273
2274 EXPECT_EQ(rc, -EBADMSG);
2275 }
2276 #endif
2277
2278 #ifdef LIBPLDM_API_TESTING
TEST(GetDownstreamFirmwareParameters,goodPathEncodeRequest)2279 TEST(GetDownstreamFirmwareParameters, goodPathEncodeRequest)
2280 {
2281 constexpr uint8_t instanceId = 1;
2282 constexpr pldm_get_downstream_firmware_parameters_req params_req{
2283 0x0, PLDM_GET_FIRSTPART};
2284 constexpr size_t payload_length =
2285 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
2286 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
2287 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2288 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2289
2290 auto rc = encode_get_downstream_firmware_parameters_req(
2291 instanceId, ¶ms_req, requestPtr, payload_length);
2292 EXPECT_EQ(rc, 0);
2293
2294 std::array<uint8_t,
2295 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES>
2296 expectedReq{0x81, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01};
2297 EXPECT_EQ(requestMsg, expectedReq);
2298 }
2299 #endif
2300
2301 #ifdef LIBPLDM_API_TESTING
TEST(GetDownstreamFirmwareParameters,encodeRequestInvalidTransferOperationFlag)2302 TEST(GetDownstreamFirmwareParameters, encodeRequestInvalidTransferOperationFlag)
2303 {
2304 constexpr uint8_t instanceId = 1;
2305 // Setup invalid transfer operation flag
2306 constexpr pldm_get_downstream_firmware_parameters_req params_req{
2307 0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
2308 constexpr size_t payload_length =
2309 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
2310 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
2311 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2312 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2313
2314 auto rc = encode_get_downstream_firmware_parameters_req(
2315 instanceId, ¶ms_req, requestPtr, payload_length);
2316 EXPECT_EQ(rc, -EBADMSG);
2317 }
2318 #endif
2319
2320 #ifdef LIBPLDM_API_TESTING
TEST(GetDownstreamFirmwareParameters,encodeRequestErrorBufSize)2321 TEST(GetDownstreamFirmwareParameters, encodeRequestErrorBufSize)
2322 {
2323 constexpr uint8_t instanceId = 1;
2324 // Setup invalid transfer operation flag
2325 constexpr pldm_get_downstream_firmware_parameters_req params_req{
2326 0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
2327 constexpr size_t payload_length =
2328 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES -
2329 1 /* inject erro length*/;
2330
2331 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
2332 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2333 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2334
2335 auto rc = encode_get_downstream_firmware_parameters_req(
2336 instanceId, ¶ms_req, requestPtr, payload_length);
2337 EXPECT_EQ(rc, -EOVERFLOW);
2338 }
2339 #endif
2340
2341 #ifdef LIBPLDM_API_TESTING
TEST(GetDownstreamFirmwareParameters,goodPathDecodeResponseOneEntry)2342 TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseOneEntry)
2343 {
2344 constexpr uint16_t downstreamDeviceCount = 1;
2345 constexpr uint8_t activeComponentVersionStringLength = 8;
2346 constexpr uint8_t pendingComponentVersionStringLength = 8;
2347 constexpr size_t downstreamDeviceParamTableLen =
2348 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2349 activeComponentVersionStringLength +
2350 pendingComponentVersionStringLength;
2351 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2352 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2353 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2354 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2355 constexpr size_t payload_len =
2356 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2357 downstreamDeviceParamTableLen;
2358
2359 PLDM_MSG_DEFINE_P(response, payload_len);
2360 struct pldm_msgbuf _buf;
2361 struct pldm_msgbuf* buf = &_buf;
2362 int rc = 0;
2363
2364 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
2365 EXPECT_EQ(rc, 0);
2366
2367 // Table 24
2368 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2369 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2370 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2371
2372 // Table 25
2373 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2374 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2375
2376 // Table 26
2377 pldm_msgbuf_insert_uint16(buf, 0);
2378
2379 // - Active metadata
2380 pldm_msgbuf_insert_uint32(buf, 0);
2381 pldm_msgbuf_insert_uint8(buf, 1);
2382 pldm_msgbuf_insert_uint8(buf, activeComponentVersionStringLength);
2383 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2384 ASSERT_EQ(rc, 0);
2385
2386 // - Pending metadata
2387 pldm_msgbuf_insert_uint32(buf, 0);
2388 pldm_msgbuf_insert_uint8(buf, 1);
2389 pldm_msgbuf_insert_uint8(buf, pendingComponentVersionStringLength);
2390 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2391 ASSERT_EQ(rc, 0);
2392
2393 // - Methods and capabilities
2394 pldm_msgbuf_insert_uint16(buf, 1);
2395 pldm_msgbuf_insert_uint32(buf, 0);
2396
2397 // - Version strings
2398 rc = pldm__msgbuf_insert_array_void(buf, activeComponentVersionStringLength,
2399 "abcdefgh", 8);
2400 ASSERT_EQ(rc, 0);
2401 rc = pldm__msgbuf_insert_array_void(
2402 buf, pendingComponentVersionStringLength, "zyxwvuts", 8);
2403 ASSERT_EQ(rc, 0);
2404
2405 rc = pldm_msgbuf_destroy_consumed(buf);
2406 ASSERT_EQ(rc, 0);
2407
2408 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2409 struct pldm_downstream_device_parameters_iter iter = {};
2410
2411 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2412 &resp_data, &iter);
2413
2414 ASSERT_EQ(rc, 0);
2415 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
2416 EXPECT_EQ(resp_data.next_data_transfer_handle,
2417 next_data_transfer_handle_resp);
2418 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2419 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
2420
2421 struct pldm_downstream_device_parameters_entry entry;
2422 size_t entries = 0;
2423 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2424 {
2425 EXPECT_EQ(entry.downstream_device_index, 0);
2426 EXPECT_EQ(entry.active_comp_comparison_stamp, 0);
2427 EXPECT_EQ(entry.active_comp_ver_str_type, 1);
2428 EXPECT_EQ(entry.active_comp_ver_str_len,
2429 activeComponentVersionStringLength);
2430 EXPECT_STREQ("20241206", entry.active_comp_release_date);
2431 EXPECT_EQ(entry.pending_comp_comparison_stamp, 0);
2432 EXPECT_EQ(entry.pending_comp_ver_str_type, 1);
2433 EXPECT_EQ(entry.pending_comp_ver_str_len,
2434 pendingComponentVersionStringLength);
2435 EXPECT_STREQ("20241206", entry.pending_comp_release_date);
2436 EXPECT_EQ(entry.comp_activation_methods.value, 1);
2437 EXPECT_EQ(entry.capabilities_during_update.value, 0);
2438 EXPECT_FALSE(memcmp("abcdefgh", entry.active_comp_ver_str,
2439 entry.active_comp_ver_str_len));
2440 EXPECT_FALSE(memcmp("zyxwvuts", entry.pending_comp_ver_str,
2441 entry.pending_comp_ver_str_len));
2442 entries++;
2443 }
2444 EXPECT_EQ(rc, 0);
2445 EXPECT_EQ(entries, 1);
2446 }
2447 #endif
2448
2449 #ifdef LIBPLDM_API_TESTING
TEST(GetDownstreamFirmwareParameters,goodPathDecodeResponseTwoEntries)2450 TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseTwoEntries)
2451 {
2452 /** Count is not fixed here taking it as 1, and the downstream device's
2453 * version strings length are set to 8
2454 */
2455 constexpr uint16_t downstreamDeviceCount = 2;
2456 constexpr uint8_t activeComponentVersionStringLength = 8;
2457 constexpr uint8_t pendingComponentVersionStringLength = 9;
2458 constexpr size_t downstreamDeviceParamTableLen =
2459 static_cast<size_t>(downstreamDeviceCount *
2460 (PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2461 activeComponentVersionStringLength +
2462 pendingComponentVersionStringLength));
2463 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2464 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2465 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2466 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2467 constexpr size_t payload_len =
2468 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2469 downstreamDeviceParamTableLen;
2470
2471 PLDM_MSG_DEFINE_P(response, payload_len);
2472 struct pldm_msgbuf _buf;
2473 struct pldm_msgbuf* buf = &_buf;
2474 int rc = 0;
2475
2476 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
2477 EXPECT_EQ(rc, 0);
2478
2479 // Table 24
2480 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2481 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2482 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2483
2484 // Table 25
2485 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2486 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2487
2488 constexpr const std::array<pldm_downstream_device_parameters_entry, 2>
2489 table = {{{
2490 0,
2491 0,
2492 1,
2493 8,
2494 "20241206",
2495 0,
2496 1,
2497 9,
2498 "20241209",
2499 {1},
2500 {0},
2501 "active_0",
2502 "pending_0",
2503 },
2504 {
2505 1,
2506 0,
2507 1,
2508 8,
2509 "20241209",
2510 0,
2511 1,
2512 9,
2513 "20241206",
2514 {1},
2515 {0},
2516 "active_1",
2517 "pending_1",
2518 }}};
2519 for (const auto& e : table)
2520 {
2521 // Table 26
2522 pldm_msgbuf_insert_uint16(buf, e.downstream_device_index);
2523
2524 // - Active metadata
2525 pldm_msgbuf_insert_uint32(buf, e.active_comp_comparison_stamp);
2526 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_type);
2527 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_len);
2528 rc = pldm__msgbuf_insert_array_void(buf, 8, &e.active_comp_release_date,
2529 sizeof(e.active_comp_release_date));
2530 ASSERT_EQ(rc, 0);
2531
2532 // - Pending metadata
2533 pldm_msgbuf_insert_uint32(buf, e.pending_comp_comparison_stamp);
2534 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_type);
2535 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_len);
2536 rc =
2537 pldm__msgbuf_insert_array_void(buf, 8, e.pending_comp_release_date,
2538 sizeof(e.pending_comp_release_date));
2539 ASSERT_EQ(rc, 0);
2540
2541 // - Methods and capabilities
2542 pldm_msgbuf_insert_uint16(buf, e.comp_activation_methods.value);
2543 pldm_msgbuf_insert_uint32(buf, e.capabilities_during_update.value);
2544
2545 // - Version strings
2546 rc = pldm__msgbuf_insert_array_void(buf, e.active_comp_ver_str_len,
2547 e.active_comp_ver_str,
2548 e.active_comp_ver_str_len);
2549 ASSERT_EQ(rc, 0);
2550 rc = pldm__msgbuf_insert_array_void(buf, e.pending_comp_ver_str_len,
2551 e.pending_comp_ver_str,
2552 e.pending_comp_ver_str_len);
2553 ASSERT_EQ(rc, 0);
2554 }
2555
2556 rc = pldm_msgbuf_destroy_consumed(buf);
2557 ASSERT_EQ(rc, 0);
2558
2559 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2560 struct pldm_downstream_device_parameters_iter iter = {};
2561
2562 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2563 &resp_data, &iter);
2564
2565 ASSERT_EQ(rc, 0);
2566 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
2567 EXPECT_EQ(resp_data.next_data_transfer_handle,
2568 next_data_transfer_handle_resp);
2569 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2570 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
2571
2572 struct pldm_downstream_device_parameters_entry entry;
2573 size_t entryIndex = 0;
2574 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2575 {
2576 ASSERT_LE(entryIndex, table.size());
2577
2578 EXPECT_EQ(table[entryIndex].downstream_device_index,
2579 entry.downstream_device_index);
2580 EXPECT_EQ(table[entryIndex].active_comp_comparison_stamp,
2581 entry.active_comp_comparison_stamp);
2582 EXPECT_EQ(table[entryIndex].active_comp_ver_str_type,
2583 entry.active_comp_ver_str_type);
2584 EXPECT_EQ(table[entryIndex].active_comp_ver_str_len,
2585 entry.active_comp_ver_str_len);
2586 EXPECT_STREQ(&table[entryIndex].active_comp_release_date[0],
2587 &entry.active_comp_release_date[0]);
2588 EXPECT_EQ(table[entryIndex].pending_comp_comparison_stamp,
2589 entry.pending_comp_comparison_stamp);
2590 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_type,
2591 entry.pending_comp_ver_str_type);
2592 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_len,
2593 entry.pending_comp_ver_str_len);
2594 EXPECT_STREQ(&table[entryIndex].pending_comp_release_date[0],
2595 &entry.pending_comp_release_date[0]);
2596 EXPECT_EQ(table[entryIndex].comp_activation_methods.value,
2597 entry.comp_activation_methods.value);
2598 EXPECT_EQ(table[entryIndex].capabilities_during_update.value,
2599 entry.capabilities_during_update.value);
2600 EXPECT_FALSE(memcmp(table[entryIndex].active_comp_ver_str,
2601 entry.active_comp_ver_str,
2602 table[entryIndex].active_comp_ver_str_len));
2603 EXPECT_FALSE(memcmp(table[entryIndex].pending_comp_ver_str,
2604 entry.pending_comp_ver_str,
2605 table[entryIndex].pending_comp_ver_str_len));
2606 entryIndex++;
2607 }
2608 EXPECT_EQ(rc, 0);
2609 EXPECT_EQ(entryIndex, table.size());
2610 }
2611 #endif
2612
2613 #ifdef LIBPLDM_API_TESTING
TEST(GetDownstreamFirmwareParameters,decodeResponseInvalidLength)2614 TEST(GetDownstreamFirmwareParameters, decodeResponseInvalidLength)
2615 {
2616 /** Count is not fixed here taking it as 1, and the downstream device's
2617 * version strings length are set to 8
2618 */
2619 constexpr uint16_t downstreamDeviceCount = 1;
2620 constexpr uint8_t activeComponentVersionStringLength = 8;
2621 constexpr uint8_t pendingComponentVersionStringLength = 8;
2622 constexpr size_t downstreamDeviceParamTableLen =
2623 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2624 activeComponentVersionStringLength +
2625 pendingComponentVersionStringLength;
2626 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2627 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2628 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2629 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2630
2631 std::array<uint8_t,
2632 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2633 downstreamDeviceParamTableLen - 1 /* inject error length*/>
2634 responseMsg{};
2635
2636 int rc = 0;
2637
2638 struct pldm_msgbuf _buf;
2639 struct pldm_msgbuf* buf = &_buf;
2640 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
2641 responseMsg.size() - hdrSize);
2642 EXPECT_EQ(rc, 0);
2643
2644 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2645 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2646 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2647 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2648 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2649
2650 /** Filling paramter table, the correctness of the downstream devices data
2651 * is not checked in this test case so filling with 0xff
2652 */
2653 std::fill_n(responseMsg.data() + hdrSize +
2654 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN,
2655 downstreamDeviceParamTableLen - 1 /* inject error length*/,
2656 0xff);
2657
2658 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2659 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
2660 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2661 struct pldm_downstream_device_parameters_iter iter;
2662
2663 rc = decode_get_downstream_firmware_parameters_resp(
2664 response, responseMsg.size() - hdrSize, &resp_data, &iter);
2665 EXPECT_EQ(rc, 0);
2666
2667 struct pldm_downstream_device_parameters_entry entry;
2668 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2669 {
2670 FAIL();
2671 }
2672 EXPECT_EQ(rc, -EOVERFLOW);
2673 }
2674 #endif
2675
TEST(RequestUpdate,goodPathEncodeRequest)2676 TEST(RequestUpdate, goodPathEncodeRequest)
2677 {
2678 constexpr uint8_t instanceId = 1;
2679 constexpr uint32_t maxTransferSize = 512;
2680 constexpr uint16_t numOfComp = 3;
2681 constexpr uint8_t maxOutstandingTransferReq = 2;
2682 constexpr uint16_t pkgDataLen = 0x1234;
2683 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2684 constexpr uint8_t compImgSetVerStrLen =
2685 static_cast<uint8_t>(compImgSetVerStr.size());
2686 variable_field compImgSetVerStrInfo{};
2687 compImgSetVerStrInfo.ptr =
2688 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2689 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2690 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2691
2692 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2693 compImgSetVerStrLen>
2694 request{};
2695 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2696 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2697
2698 auto rc = encode_request_update_req(
2699 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2700 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2701 &compImgSetVerStrInfo, requestMsg,
2702 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2703 EXPECT_EQ(rc, PLDM_SUCCESS);
2704
2705 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2706 compImgSetVerStrLen>
2707 outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00,
2708 0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e,
2709 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30};
2710 EXPECT_EQ(request, outRequest);
2711 }
2712
TEST(RequestUpdate,errorPathEncodeRequest)2713 TEST(RequestUpdate, errorPathEncodeRequest)
2714 {
2715 constexpr uint8_t instanceId = 1;
2716 uint32_t maxTransferSize = 512;
2717 constexpr uint16_t numOfComp = 3;
2718 uint8_t maxOutstandingTransferReq = 2;
2719 constexpr uint16_t pkgDataLen = 0x1234;
2720 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2721 uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2722 variable_field compImgSetVerStrInfo{};
2723 compImgSetVerStrInfo.ptr =
2724 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2725 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2726 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2727
2728 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2729 compImgSetVerStr.size()>
2730 request{};
2731 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2732 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2733
2734 auto rc = encode_request_update_req(
2735 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2736 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr,
2737 requestMsg,
2738 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2739 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2740
2741 compImgSetVerStrInfo.ptr = nullptr;
2742 rc = encode_request_update_req(
2743 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2744 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2745 &compImgSetVerStrInfo, requestMsg,
2746 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2747 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2748 compImgSetVerStrInfo.ptr =
2749 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2750 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2751
2752 rc = encode_request_update_req(
2753 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2754 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2755 &compImgSetVerStrInfo, nullptr,
2756 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2757 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2758
2759 rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp,
2760 maxOutstandingTransferReq, pkgDataLen,
2761 PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2762 &compImgSetVerStrInfo, requestMsg, 0);
2763 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2764
2765 compImgSetVerStrLen = 0;
2766 rc = encode_request_update_req(
2767 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2768 pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr,
2769 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2770 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2771 compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2772
2773 compImgSetVerStrInfo.length = 0xffff;
2774 rc = encode_request_update_req(
2775 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2776 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2777 &compImgSetVerStrInfo, nullptr,
2778 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2779 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2780 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2781
2782 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1;
2783 rc = encode_request_update_req(
2784 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2785 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2786 &compImgSetVerStrInfo, nullptr,
2787 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2788 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2789 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE;
2790
2791 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ - 1;
2792 rc = encode_request_update_req(
2793 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2794 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2795 &compImgSetVerStrInfo, nullptr,
2796 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2797 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2798 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ;
2799
2800 rc = encode_request_update_req(
2801 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2802 pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen,
2803 &compImgSetVerStrInfo, nullptr,
2804 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2805 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2806 }
2807
TEST(RequestUpdate,goodPathDecodeResponse)2808 TEST(RequestUpdate, goodPathDecodeResponse)
2809 {
2810 /* Test a success completion code */
2811 constexpr uint16_t fdMetaDataLen = 1024;
2812 constexpr uint8_t fdWillSendPkgData = 1;
2813 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)>
2814 requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01};
2815
2816 auto responseMsg1 =
2817 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2818 reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data());
2819 uint8_t outCompletionCode = 0;
2820 uint16_t outFdMetaDataLen = 0;
2821 uint8_t outFdWillSendPkgData = 0;
2822
2823 auto rc = decode_request_update_resp(
2824 responseMsg1, requestUpdateResponse1.size() - hdrSize,
2825 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2826 EXPECT_EQ(rc, PLDM_SUCCESS);
2827 EXPECT_EQ(outCompletionCode, PLDM_SUCCESS);
2828 EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen);
2829 EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData);
2830
2831 #ifdef LIBPLDM_API_TESTING
2832 /* Check the success roundtrip matches */
2833 PLDM_MSG_DEFINE_P(enc, 1000);
2834 size_t enc_payload_len = 1000;
2835 const struct pldm_request_update_resp resp_data = {
2836 .completion_code = PLDM_SUCCESS,
2837 .fd_meta_data_len = outFdMetaDataLen,
2838 .fd_will_send_pkg_data = outFdWillSendPkgData,
2839 };
2840 rc = encode_request_update_resp(FIXED_INSTANCE_ID, &resp_data, enc,
2841 &enc_payload_len);
2842 EXPECT_EQ(rc, PLDM_SUCCESS);
2843 EXPECT_EQ(enc_payload_len + hdrSize, requestUpdateResponse1.size());
2844 EXPECT_TRUE(std::equal(requestUpdateResponse1.begin() + hdrSize,
2845 requestUpdateResponse1.end(), enc_buf + hdrSize));
2846 check_response(enc, PLDM_REQUEST_UPDATE);
2847 #endif
2848
2849 /* Test a failure completion code */
2850 outCompletionCode = 0;
2851 outFdMetaDataLen = 0;
2852 outFdWillSendPkgData = 0;
2853
2854 constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)>
2855 requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
2856 auto responseMsg2 =
2857 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2858 reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data());
2859 rc = decode_request_update_resp(
2860 responseMsg2, requestUpdateResponse2.size() - hdrSize,
2861 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2862 EXPECT_EQ(rc, PLDM_SUCCESS);
2863 EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
2864 }
2865
TEST(RequestUpdate,errorPathDecodeResponse)2866 TEST(RequestUpdate, errorPathDecodeResponse)
2867 {
2868 constexpr std::array<uint8_t,
2869 hdrSize + sizeof(pldm_request_update_resp) - 1>
2870 requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
2871
2872 auto responseMsg =
2873 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2874 reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data());
2875 uint8_t outCompletionCode = 0;
2876 uint16_t outFdMetaDataLen = 0;
2877 uint8_t outFdWillSendPkgData = 0;
2878
2879 auto rc = decode_request_update_resp(
2880 nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2881 &outFdMetaDataLen, &outFdWillSendPkgData);
2882 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2883
2884 rc = decode_request_update_resp(
2885 responseMsg, requestUpdateResponse.size() - hdrSize, nullptr,
2886 &outFdMetaDataLen, &outFdWillSendPkgData);
2887 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2888
2889 rc = decode_request_update_resp(
2890 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2891 nullptr, &outFdWillSendPkgData);
2892 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2893
2894 rc = decode_request_update_resp(
2895 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2896 &outFdMetaDataLen, nullptr);
2897 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2898
2899 rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode,
2900 &outFdMetaDataLen, &outFdWillSendPkgData);
2901 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2902
2903 rc = decode_request_update_resp(
2904 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2905 &outFdMetaDataLen, &outFdWillSendPkgData);
2906 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2907 }
2908
TEST(PassComponentTable,goodPathEncodeRequest)2909 TEST(PassComponentTable, goodPathEncodeRequest)
2910 {
2911 constexpr uint8_t instanceId = 1;
2912 constexpr uint16_t compIdentifier = 400;
2913 constexpr uint8_t compClassificationIndex = 40;
2914 constexpr uint32_t compComparisonStamp = 0x12345678;
2915 constexpr std::string_view compVerStr = "0penBmcv1.1";
2916 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2917 variable_field compVerStrInfo{};
2918 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2919 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2920 compVerStrInfo.length = compVerStrLen;
2921
2922 std::array<uint8_t,
2923 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2924 request{};
2925 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2926 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2927
2928 auto rc = encode_pass_component_table_req(
2929 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2930 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2931 compVerStrLen, &compVerStrInfo, requestMsg,
2932 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2933 EXPECT_EQ(rc, PLDM_SUCCESS);
2934
2935 std::array<uint8_t,
2936 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2937 outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28,
2938 0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65,
2939 0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31};
2940 EXPECT_EQ(request, outRequest);
2941
2942 #ifdef LIBPLDM_API_TESTING
2943 /* Check the roundtrip */
2944 struct pldm_pass_component_table_req_full req;
2945 PLDM_MSG_DEFINE_P(dec, outRequest.size());
2946 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
2947 rc =
2948 decode_pass_component_table_req(dec, outRequest.size() - hdrSize, &req);
2949 ASSERT_EQ(rc, 0);
2950
2951 EXPECT_EQ(req.transfer_flag, PLDM_START_AND_END);
2952 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
2953 EXPECT_EQ(req.comp_identifier, compIdentifier);
2954 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
2955 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
2956 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
2957 EXPECT_EQ(req.version.str_len, compVerStrLen);
2958 EXPECT_TRUE(std::equal(req.version.str_data,
2959 req.version.str_data + req.version.str_len,
2960 compVerStr.data()));
2961 #endif
2962 }
2963
TEST(PassComponentTable,errorPathEncodeRequest)2964 TEST(PassComponentTable, errorPathEncodeRequest)
2965 {
2966 constexpr uint8_t instanceId = 1;
2967 constexpr uint16_t compIdentifier = 400;
2968 constexpr uint8_t compClassificationIndex = 40;
2969 constexpr uint32_t compComparisonStamp = 0x12345678;
2970 constexpr std::string_view compVerStr = "0penBmcv1.1";
2971 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2972 variable_field compVerStrInfo{};
2973 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2974 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2975 compVerStrInfo.length = compVerStrLen;
2976
2977 std::array<uint8_t,
2978 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2979 request{};
2980 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2981 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2982
2983 auto rc = encode_pass_component_table_req(
2984 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2985 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2986 compVerStrLen, nullptr, requestMsg,
2987 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2988 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2989
2990 compVerStrInfo.ptr = nullptr;
2991 rc = encode_pass_component_table_req(
2992 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2993 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2994 compVerStrLen, &compVerStrInfo, requestMsg,
2995 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2996 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2997 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2998 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2999
3000 rc = encode_pass_component_table_req(
3001 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3002 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3003 compVerStrLen, &compVerStrInfo, nullptr,
3004 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3005 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3006
3007 rc = encode_pass_component_table_req(
3008 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3009 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3010 compVerStrLen, &compVerStrInfo, requestMsg,
3011 sizeof(pldm_pass_component_table_req));
3012 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3013
3014 rc = encode_pass_component_table_req(
3015 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3016 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0,
3017 &compVerStrInfo, requestMsg,
3018 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3019 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3020
3021 rc = encode_pass_component_table_req(
3022 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3023 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3024 compVerStrLen - 1, &compVerStrInfo, requestMsg,
3025 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3026 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3027
3028 rc = encode_pass_component_table_req(
3029 instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier,
3030 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3031 compVerStrLen, &compVerStrInfo, requestMsg,
3032 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3033 EXPECT_EQ(rc, PLDM_INVALID_TRANSFER_OPERATION_FLAG);
3034
3035 rc = encode_pass_component_table_req(
3036 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3037 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN,
3038 compVerStrLen, &compVerStrInfo, requestMsg,
3039 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3040 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3041 }
3042
TEST(PassComponentTable,goodPathDecodeResponse)3043 TEST(PassComponentTable, goodPathDecodeResponse)
3044 {
3045 constexpr std::array<uint8_t,
3046 hdrSize + sizeof(pldm_pass_component_table_resp)>
3047 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
3048 auto responseMsg1 =
3049 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3050 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3051
3052 uint8_t completionCode = 0;
3053 uint8_t compResp = 0;
3054 uint8_t compRespCode = 0;
3055
3056 auto rc = decode_pass_component_table_resp(
3057 responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode,
3058 &compResp, &compRespCode);
3059
3060 EXPECT_EQ(rc, PLDM_SUCCESS);
3061 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3062 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3063 EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL);
3064
3065 constexpr std::array<uint8_t,
3066 hdrSize + sizeof(pldm_pass_component_table_resp)>
3067 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0};
3068 auto responseMsg2 =
3069 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3070 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3071 rc = decode_pass_component_table_resp(
3072 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3073 &compResp, &compRespCode);
3074
3075 EXPECT_EQ(rc, PLDM_SUCCESS);
3076 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3077 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3078 EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN);
3079
3080 constexpr std::array<uint8_t,
3081 hdrSize + sizeof(pldm_pass_component_table_resp)>
3082 passCompTableResponse3{0x00, 0x00, 0x00, 0x80};
3083 auto responseMsg3 =
3084 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3085 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3086
3087 rc = decode_pass_component_table_resp(
3088 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3089 &compResp, &compRespCode);
3090
3091 EXPECT_EQ(rc, PLDM_SUCCESS);
3092 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3093 }
3094
TEST(PassComponentTable,errorPathDecodeResponse)3095 TEST(PassComponentTable, errorPathDecodeResponse)
3096 {
3097 constexpr std::array<uint8_t,
3098 hdrSize + sizeof(pldm_pass_component_table_resp) - 1>
3099 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00};
3100 auto responseMsg1 =
3101 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3102 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3103
3104 uint8_t completionCode = 0;
3105 uint8_t compResp = 0;
3106 uint8_t compRespCode = 0;
3107
3108 auto rc = decode_pass_component_table_resp(
3109 nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode,
3110 &compResp, &compRespCode);
3111 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3112
3113 rc = decode_pass_component_table_resp(
3114 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr,
3115 &compResp, &compRespCode);
3116 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3117
3118 rc = decode_pass_component_table_resp(
3119 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3120 &completionCode, nullptr, &compRespCode);
3121 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3122
3123 rc = decode_pass_component_table_resp(
3124 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3125 &completionCode, &compResp, nullptr);
3126 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3127
3128 rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode,
3129 &compResp, &compRespCode);
3130 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3131
3132 rc = decode_pass_component_table_resp(
3133 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3134 &completionCode, &compResp, &compRespCode);
3135 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3136
3137 constexpr std::array<uint8_t,
3138 hdrSize + sizeof(pldm_pass_component_table_resp)>
3139 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
3140 auto responseMsg2 =
3141 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3142 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3143 rc = decode_pass_component_table_resp(
3144 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3145 &compResp, &compRespCode);
3146 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3147
3148 constexpr std::array<uint8_t,
3149 hdrSize + sizeof(pldm_pass_component_table_resp)>
3150 passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};
3151 auto responseMsg3 =
3152 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3153 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3154 rc = decode_pass_component_table_resp(
3155 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3156 &compResp, &compRespCode);
3157 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3158
3159 constexpr std::array<uint8_t,
3160 hdrSize + sizeof(pldm_pass_component_table_resp)>
3161 passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
3162 auto responseMsg4 =
3163 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3164 reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data());
3165 rc = decode_pass_component_table_resp(
3166 responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode,
3167 &compResp, &compRespCode);
3168 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3169 }
3170
TEST(UpdateComponent,goodPathEncodeRequest)3171 TEST(UpdateComponent, goodPathEncodeRequest)
3172 {
3173 constexpr uint8_t instanceId = 2;
3174 constexpr uint16_t compIdentifier = 500;
3175 constexpr uint8_t compClassificationIndex = 50;
3176 constexpr uint32_t compComparisonStamp = 0x89abcdef;
3177 constexpr uint32_t compImageSize = 4096;
3178 constexpr bitfield32_t updateOptionFlags{1};
3179 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3180 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3181 variable_field compVerStrInfo{};
3182 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3183 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3184 compVerStrInfo.length = compVerStrLen;
3185
3186 std::array<uint8_t,
3187 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3188 request{};
3189 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3190 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3191
3192 auto rc = encode_update_component_req(
3193 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3194 compComparisonStamp, compImageSize, updateOptionFlags,
3195 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3196 sizeof(pldm_update_component_req) + compVerStrLen);
3197 EXPECT_EQ(rc, PLDM_SUCCESS);
3198
3199 std::array<uint8_t,
3200 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3201 outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
3202 0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
3203 0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
3204 0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
3205 EXPECT_EQ(request, outRequest);
3206
3207 #ifdef LIBPLDM_API_TESTING
3208 /* Check the roundtrip */
3209 struct pldm_update_component_req_full req;
3210 PLDM_MSG_DEFINE_P(dec, outRequest.size());
3211 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3212 rc = decode_update_component_req(dec, outRequest.size() - hdrSize, &req);
3213 ASSERT_EQ(rc, 0);
3214
3215 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3216 EXPECT_EQ(req.comp_identifier, compIdentifier);
3217 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3218 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3219 EXPECT_EQ(req.comp_image_size, compImageSize);
3220 EXPECT_EQ(req.update_option_flags.value, updateOptionFlags.value);
3221 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3222 EXPECT_EQ(req.version.str_len, compVerStrLen);
3223 EXPECT_TRUE(std::equal(req.version.str_data,
3224 req.version.str_data + req.version.str_len,
3225 compVerStr.data()));
3226 #endif
3227 }
3228
TEST(UpdateComponent,errorPathEncodeRequest)3229 TEST(UpdateComponent, errorPathEncodeRequest)
3230 {
3231 constexpr uint8_t instanceId = 2;
3232 constexpr uint16_t compIdentifier = 500;
3233 constexpr uint8_t compClassificationIndex = 50;
3234 constexpr uint32_t compComparisonStamp = 0x89abcdef;
3235 constexpr uint32_t compImageSize = 4096;
3236 constexpr bitfield32_t updateOptionFlags{1};
3237 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3238 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3239 variable_field compVerStrInfo{};
3240 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3241 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3242 compVerStrInfo.length = compVerStrLen;
3243
3244 std::array<uint8_t,
3245 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3246 request{};
3247 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3248 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3249
3250 auto rc = encode_update_component_req(
3251 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3252 compComparisonStamp, compImageSize, updateOptionFlags,
3253 PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
3254 sizeof(pldm_update_component_req) + compVerStrLen);
3255 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3256
3257 compVerStrInfo.ptr = nullptr;
3258 rc = encode_update_component_req(
3259 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3260 compComparisonStamp, compImageSize, updateOptionFlags,
3261 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3262 sizeof(pldm_update_component_req) + compVerStrLen);
3263 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3264 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3265 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3266
3267 rc = encode_update_component_req(
3268 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3269 compComparisonStamp, compImageSize, updateOptionFlags,
3270 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
3271 sizeof(pldm_update_component_req) + compVerStrLen);
3272 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3273
3274 rc = encode_update_component_req(
3275 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3276 compComparisonStamp, compImageSize, updateOptionFlags,
3277 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3278 sizeof(pldm_update_component_req));
3279 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3280
3281 rc = encode_update_component_req(
3282 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3283 compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
3284 compVerStrLen, &compVerStrInfo, requestMsg,
3285 sizeof(pldm_update_component_req) + compVerStrLen);
3286 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3287
3288 rc = encode_update_component_req(
3289 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3290 compComparisonStamp, compImageSize, updateOptionFlags,
3291 PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg,
3292 sizeof(pldm_update_component_req) + compVerStrLen);
3293 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3294
3295 rc = encode_update_component_req(
3296 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3297 compComparisonStamp, compImageSize, updateOptionFlags,
3298 PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg,
3299 sizeof(pldm_update_component_req) + compVerStrLen);
3300 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3301
3302 rc = encode_update_component_req(
3303 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3304 compComparisonStamp, compImageSize, updateOptionFlags,
3305 PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
3306 sizeof(pldm_update_component_req) + compVerStrLen);
3307 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3308 }
3309
TEST(UpdateComponent,goodPathDecodeResponse)3310 TEST(UpdateComponent, goodPathDecodeResponse)
3311 {
3312 constexpr std::bitset<32> forceUpdateComp{1};
3313 constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
3314 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3315 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3316 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3317 auto responseMsg1 =
3318 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3319 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3320
3321 uint8_t completionCode = 0;
3322 uint8_t compCompatibilityResp = 0;
3323 uint8_t compCompatibilityRespCode = 0;
3324 bitfield32_t updateOptionFlagsEnabled{};
3325 uint16_t timeBeforeReqFWData = 0;
3326
3327 auto rc = decode_update_component_resp(
3328 responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
3329 &compCompatibilityResp, &compCompatibilityRespCode,
3330 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3331
3332 EXPECT_EQ(rc, PLDM_SUCCESS);
3333 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3334 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
3335 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
3336 EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
3337 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
3338
3339 constexpr std::bitset<32> noFlags{};
3340 constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
3341 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3342 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3344 auto responseMsg2 =
3345 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3346 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3347 rc = decode_update_component_resp(
3348 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3349 &compCompatibilityResp, &compCompatibilityRespCode,
3350 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3351
3352 EXPECT_EQ(rc, PLDM_SUCCESS);
3353 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3354 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
3355 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
3356 EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
3357 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
3358
3359 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3360 updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
3361 auto responseMsg3 =
3362 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3363 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3364
3365 rc = decode_update_component_resp(
3366 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3367 &compCompatibilityResp, &compCompatibilityRespCode,
3368 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3369
3370 EXPECT_EQ(rc, PLDM_SUCCESS);
3371 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3372 }
3373
TEST(UpdateComponent,errorPathDecodeResponse)3374 TEST(UpdateComponent, errorPathDecodeResponse)
3375 {
3376 constexpr std::array<uint8_t,
3377 hdrSize + sizeof(pldm_update_component_resp) - 1>
3378 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3379 0x00, 0x00, 0x00, 0x00, 0x00};
3380 auto responseMsg1 =
3381 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3382 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3383
3384 uint8_t completionCode = 0;
3385 uint8_t compCompatibilityResp = 0;
3386 uint8_t compCompatibilityRespCode = 0;
3387 bitfield32_t updateOptionFlagsEnabled{};
3388 uint16_t timeBeforeReqFWData = 0;
3389
3390 auto rc = decode_update_component_resp(
3391 nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
3392 &compCompatibilityResp, &compCompatibilityRespCode,
3393 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3394 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3395
3396 rc = decode_update_component_resp(
3397 responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
3398 &compCompatibilityResp, &compCompatibilityRespCode,
3399 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3400 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3401
3402 rc = decode_update_component_resp(
3403 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3404 nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3405 &timeBeforeReqFWData);
3406 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3407
3408 rc = decode_update_component_resp(
3409 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3410 &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
3411 &timeBeforeReqFWData);
3412 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3413
3414 rc = decode_update_component_resp(
3415 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3416 &compCompatibilityResp, &compCompatibilityRespCode, nullptr,
3417 &timeBeforeReqFWData);
3418 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3419
3420 rc = decode_update_component_resp(
3421 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3422 &compCompatibilityResp, &compCompatibilityRespCode,
3423 &updateOptionFlagsEnabled, nullptr);
3424 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3425
3426 rc = decode_update_component_resp(
3427 responseMsg1, 0, &completionCode, &compCompatibilityResp,
3428 &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3429 &timeBeforeReqFWData);
3430 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3431
3432 rc = decode_update_component_resp(
3433 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3434 &compCompatibilityResp, &compCompatibilityRespCode,
3435 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3436 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3437
3438 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3439 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
3440 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3441 auto responseMsg2 =
3442 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3443 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3444 rc = decode_update_component_resp(
3445 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3446 &compCompatibilityResp, &compCompatibilityRespCode,
3447 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3448 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3449
3450 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3451 updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
3452 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3453 auto responseMsg3 =
3454 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3455 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3456 rc = decode_update_component_resp(
3457 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3458 &compCompatibilityResp, &compCompatibilityRespCode,
3459 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3460 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3461
3462 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3463 updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
3464 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3465 auto responseMsg4 =
3466 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3467 reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
3468 rc = decode_update_component_resp(
3469 responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
3470 &compCompatibilityResp, &compCompatibilityRespCode,
3471 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3472 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3473 }
3474
TEST(RequestFirmwareData,goodPathDecodeRequest)3475 TEST(RequestFirmwareData, goodPathDecodeRequest)
3476 {
3477 constexpr uint32_t offset = 300;
3478 constexpr uint32_t length = 255;
3479 constexpr std::array<uint8_t,
3480 hdrSize + sizeof(pldm_request_firmware_data_req)>
3481 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3482 0x00, 0xff, 0x00, 0x00, 0x00};
3483 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3484 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3485
3486 uint32_t outOffset = 0;
3487 uint32_t outLength = 0;
3488 auto rc = decode_request_firmware_data_req(
3489 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3490 &outLength);
3491
3492 EXPECT_EQ(rc, PLDM_SUCCESS);
3493 EXPECT_EQ(outOffset, offset);
3494 EXPECT_EQ(outLength, length);
3495 }
3496
TEST(RequestFirmwareData,errorPathDecodeRequest)3497 TEST(RequestFirmwareData, errorPathDecodeRequest)
3498 {
3499 constexpr std::array<uint8_t,
3500 hdrSize + sizeof(pldm_request_firmware_data_req)>
3501 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3502 0x00, 0x1f, 0x00, 0x00, 0x00};
3503 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3504 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3505
3506 uint32_t outOffset = 0;
3507 uint32_t outLength = 0;
3508 auto rc = decode_request_firmware_data_req(
3509 nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
3510 &outLength);
3511 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3512
3513 rc = decode_request_firmware_data_req(
3514 requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
3515 &outLength);
3516 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3517
3518 rc = decode_request_firmware_data_req(
3519 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3520 nullptr);
3521 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3522
3523 rc = decode_request_firmware_data_req(
3524 requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
3525 &outLength);
3526 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3527
3528 rc = decode_request_firmware_data_req(
3529 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3530 &outLength);
3531 EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
3532 }
3533
TEST(RequestFirmwareData,goodPathEncodeResponse)3534 TEST(RequestFirmwareData, goodPathEncodeResponse)
3535 {
3536 constexpr uint8_t instanceId = 3;
3537 constexpr uint8_t completionCode = PLDM_SUCCESS;
3538 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
3539 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3540 outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
3541 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3542 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3543 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3544 0x1d, 0x1e, 0x1f, 0x20};
3545 std::array<uint8_t, hdrSize + sizeof(completionCode) +
3546 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3547 reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
3548 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3549 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3550 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3551 0x1d, 0x1e, 0x1f, 0x20};
3552 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3553 auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
3554 auto rc = encode_request_firmware_data_resp(
3555 instanceId, completionCode, responseMsg1,
3556 sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
3557 EXPECT_EQ(rc, PLDM_SUCCESS);
3558 EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
3559
3560 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3561 outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
3562 std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
3563 0x00, 0x00, 0x00, 0x00};
3564 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3565 auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
3566 rc = encode_request_firmware_data_resp(
3567 instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
3568 sizeof(completionCode));
3569 EXPECT_EQ(rc, PLDM_SUCCESS);
3570 EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
3571 }
3572
TEST(RequestFirmwareData,errorPathEncodeResponse)3573 TEST(RequestFirmwareData, errorPathEncodeResponse)
3574 {
3575 std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
3576 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3577 auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
3578 auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
3579 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3580
3581 rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
3582 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3583 }
3584
TEST(TransferComplete,goodPathDecodeRequest)3585 TEST(TransferComplete, goodPathDecodeRequest)
3586 {
3587 constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
3588 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3589 transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
3590 auto requestMsg1 =
3591 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3592 reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
3593 uint8_t outTransferResult = 0;
3594
3595 auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
3596 &outTransferResult);
3597 EXPECT_EQ(rc, PLDM_SUCCESS);
3598 EXPECT_EQ(outTransferResult, transferResult);
3599
3600 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3601 transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
3602 auto requestMsg2 =
3603 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3604 reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
3605 rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
3606 &outTransferResult);
3607 EXPECT_EQ(rc, PLDM_SUCCESS);
3608 EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
3609 }
3610
TEST(TransferComplete,errorPathDecodeRequest)3611 TEST(TransferComplete, errorPathDecodeRequest)
3612 {
3613 constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
3614 0x00};
3615 auto requestMsg =
3616 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3617 reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
3618 uint8_t outTransferResult = 0;
3619
3620 auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
3621 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3622
3623 rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
3624 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3625
3626 rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
3627 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3628 }
3629
TEST(TransferComplete,goodPathEncodeResponse)3630 TEST(TransferComplete, goodPathEncodeResponse)
3631 {
3632 constexpr uint8_t instanceId = 4;
3633 constexpr uint8_t completionCode = PLDM_SUCCESS;
3634 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3635 outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
3636 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3637 transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3638 auto responseMsg1 =
3639 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3640 reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
3641 auto rc = encode_transfer_complete_resp(
3642 instanceId, completionCode, responseMsg1, sizeof(completionCode));
3643 EXPECT_EQ(rc, PLDM_SUCCESS);
3644 EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
3645
3646 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3647 outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
3648 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3649 transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3650 auto responseMsg2 =
3651 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3652 reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
3653 rc = encode_transfer_complete_resp(instanceId,
3654 PLDM_FWUP_COMMAND_NOT_EXPECTED,
3655 responseMsg2, sizeof(completionCode));
3656 EXPECT_EQ(rc, PLDM_SUCCESS);
3657 EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
3658 }
3659
TEST(TransferComplete,errorPathEncodeResponse)3660 TEST(TransferComplete, errorPathEncodeResponse)
3661 {
3662 std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
3663 auto responseMsg =
3664 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3665 reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
3666 auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3667 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3668
3669 rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3670 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3671 }
3672
TEST(VerifyComplete,goodPathDecodeRequest)3673 TEST(VerifyComplete, goodPathDecodeRequest)
3674 {
3675 constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
3676 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3677 verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
3678 auto requestMsg1 =
3679 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3680 reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
3681 uint8_t outVerifyResult = 0;
3682
3683 auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
3684 &outVerifyResult);
3685 EXPECT_EQ(rc, PLDM_SUCCESS);
3686 EXPECT_EQ(outVerifyResult, verifyResult);
3687
3688 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3689 verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
3690 auto requestMsg2 =
3691 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3692 reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
3693 rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
3694 &outVerifyResult);
3695 EXPECT_EQ(rc, PLDM_SUCCESS);
3696 EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
3697 }
3698
TEST(VerifyComplete,errorPathDecodeRequest)3699 TEST(VerifyComplete, errorPathDecodeRequest)
3700 {
3701 constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
3702 auto requestMsg =
3703 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3704 reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
3705 uint8_t outVerifyResult = 0;
3706
3707 auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
3708 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3709
3710 rc = decode_verify_complete_req(requestMsg, 0, nullptr);
3711 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3712
3713 rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);
3714 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3715 }
3716
TEST(VerifyComplete,goodPathEncodeResponse)3717 TEST(VerifyComplete, goodPathEncodeResponse)
3718 {
3719 constexpr uint8_t instanceId = 5;
3720 constexpr uint8_t completionCode = PLDM_SUCCESS;
3721 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3722 outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};
3723 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3724 verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3725 auto responseMsg1 =
3726 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3727 reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());
3728 auto rc = encode_verify_complete_resp(instanceId, completionCode,
3729 responseMsg1, sizeof(completionCode));
3730 EXPECT_EQ(rc, PLDM_SUCCESS);
3731 EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);
3732
3733 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3734 outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88};
3735 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3736 verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3737 auto responseMsg2 =
3738 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3739 reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());
3740 rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3741 responseMsg2, sizeof(completionCode));
3742 EXPECT_EQ(rc, PLDM_SUCCESS);
3743 EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);
3744 }
3745
TEST(VerifyComplete,errorPathEncodeResponse)3746 TEST(VerifyComplete, errorPathEncodeResponse)
3747 {
3748 std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00};
3749 auto responseMsg =
3750 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3751 reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());
3752 auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3753 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3754
3755 rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3756 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3757 }
3758
TEST(ApplyComplete,goodPathDecodeRequest)3759 TEST(ApplyComplete, goodPathDecodeRequest)
3760 {
3761 constexpr uint8_t applyResult1 =
3762 PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
3763 // DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
3764 constexpr std::bitset<16> compActivationModification1{0x30};
3765 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3766 applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
3767 auto requestMsg1 =
3768 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3769 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3770 uint8_t outApplyResult = 0;
3771 bitfield16_t outCompActivationModification{};
3772 auto rc = decode_apply_complete_req(
3773 requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
3774 &outCompActivationModification);
3775 EXPECT_EQ(rc, PLDM_SUCCESS);
3776 EXPECT_EQ(outApplyResult, applyResult1);
3777 EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
3778
3779 constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
3780 constexpr std::bitset<16> compActivationModification2{};
3781 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3782 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3783 auto requestMsg2 =
3784 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3785 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3786 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3787 &outApplyResult,
3788 &outCompActivationModification);
3789 EXPECT_EQ(rc, PLDM_SUCCESS);
3790 EXPECT_EQ(outApplyResult, applyResult2);
3791 EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
3792 }
3793
TEST(ApplyComplete,errorPathDecodeRequest)3794 TEST(ApplyComplete, errorPathDecodeRequest)
3795 {
3796 constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
3797 auto requestMsg1 =
3798 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3799 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3800 uint8_t outApplyResult = 0;
3801 bitfield16_t outCompActivationModification{};
3802
3803 auto rc = decode_apply_complete_req(
3804 nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
3805 &outCompActivationModification);
3806 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3807
3808 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3809 nullptr, &outCompActivationModification);
3810 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3811
3812 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3813 &outApplyResult, nullptr);
3814 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3815
3816 rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
3817 &outCompActivationModification);
3818 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3819
3820 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3821 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
3822 auto requestMsg2 =
3823 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3824 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3825 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3826 &outApplyResult,
3827 &outCompActivationModification);
3828 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3829 }
3830
TEST(ApplyComplete,goodPathEncodeResponse)3831 TEST(ApplyComplete, goodPathEncodeResponse)
3832 {
3833 constexpr uint8_t instanceId = 6;
3834 constexpr uint8_t completionCode = PLDM_SUCCESS;
3835 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3836 outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
3837 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3838 applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3839 auto responseMsg1 =
3840 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3841 reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
3842 auto rc = encode_apply_complete_resp(instanceId, completionCode,
3843 responseMsg1, sizeof(completionCode));
3844 EXPECT_EQ(rc, PLDM_SUCCESS);
3845 EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
3846
3847 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3848 outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
3849 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3850 applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3851 auto responseMsg2 =
3852 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3853 reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
3854 rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3855 responseMsg2, sizeof(completionCode));
3856 EXPECT_EQ(rc, PLDM_SUCCESS);
3857 EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
3858 }
3859
TEST(ApplyComplete,errorPathEncodeResponse)3860 TEST(ApplyComplete, errorPathEncodeResponse)
3861 {
3862 std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
3863 auto responseMsg =
3864 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3865 reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
3866 auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3867 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3868
3869 rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3870 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3871 }
3872
TEST(ActivateFirmware,goodPathEncodeRequest)3873 TEST(ActivateFirmware, goodPathEncodeRequest)
3874 {
3875 constexpr uint8_t instanceId = 7;
3876
3877 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
3878 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3879 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3880
3881 auto rc = encode_activate_firmware_req(
3882 instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
3883 sizeof(pldm_activate_firmware_req));
3884 EXPECT_EQ(rc, PLDM_SUCCESS);
3885
3886 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
3887 outRequest{0x87, 0x05, 0x1a, 0x01};
3888 EXPECT_EQ(request, outRequest);
3889 }
3890
TEST(ActivateFirmware,errorPathEncodeRequest)3891 TEST(ActivateFirmware, errorPathEncodeRequest)
3892 {
3893 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
3894 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3895 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3896
3897 auto rc = encode_activate_firmware_req(
3898 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
3899 sizeof(pldm_activate_firmware_req));
3900 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3901
3902 rc = encode_activate_firmware_req(
3903 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
3904 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3905
3906 rc = encode_activate_firmware_req(0, 2, requestMsg,
3907 sizeof(pldm_activate_firmware_req));
3908 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3909 }
3910
TEST(ActivateFirmware,goodPathDecodeResponse)3911 TEST(ActivateFirmware, goodPathDecodeResponse)
3912 {
3913 constexpr uint16_t estimatedTimeForActivation100s = 100;
3914 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3915 activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
3916 auto responseMsg1 =
3917 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3918 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
3919
3920 uint8_t completionCode = 0;
3921 uint16_t estimatedTimeForActivation = 0;
3922
3923 auto rc = decode_activate_firmware_resp(
3924 responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
3925 &estimatedTimeForActivation);
3926
3927 EXPECT_EQ(rc, PLDM_SUCCESS);
3928 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3929 EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
3930
3931 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3932 activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
3933 auto responseMsg2 =
3934 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3935 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data());
3936
3937 rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
3938 &completionCode,
3939 &estimatedTimeForActivation);
3940
3941 EXPECT_EQ(rc, PLDM_SUCCESS);
3942 EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
3943 }
3944
TEST(ActivateFirmware,errorPathDecodeResponse)3945 TEST(ActivateFirmware, errorPathDecodeResponse)
3946 {
3947 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3948 activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3949 auto responseMsg =
3950 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3951 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
3952
3953 uint8_t completionCode = 0;
3954 uint16_t estimatedTimeForActivation = 0;
3955
3956 auto rc = decode_activate_firmware_resp(
3957 nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
3958 &estimatedTimeForActivation);
3959 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3960
3961 rc = decode_activate_firmware_resp(responseMsg,
3962 sizeof(pldm_activate_firmware_resp),
3963 nullptr, &estimatedTimeForActivation);
3964 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3965
3966 rc = decode_activate_firmware_resp(responseMsg,
3967 sizeof(pldm_activate_firmware_resp),
3968 &completionCode, nullptr);
3969 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3970
3971 rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
3972 &estimatedTimeForActivation);
3973 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3974
3975 rc = decode_activate_firmware_resp(
3976 responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
3977 &estimatedTimeForActivation);
3978 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3979 }
3980
TEST(GetStatus,goodPathEncodeRequest)3981 TEST(GetStatus, goodPathEncodeRequest)
3982 {
3983 constexpr uint8_t instanceId = 8;
3984 std::array<uint8_t, hdrSize> request{};
3985 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3986 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3987
3988 auto rc = encode_get_status_req(instanceId, requestMsg,
3989 PLDM_GET_STATUS_REQ_BYTES);
3990 EXPECT_EQ(rc, PLDM_SUCCESS);
3991
3992 constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
3993 EXPECT_EQ(request, outRequest);
3994 }
3995
TEST(GetStatus,errorPathEncodeRequest)3996 TEST(GetStatus, errorPathEncodeRequest)
3997 {
3998 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
3999 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4000 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4001
4002 auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
4003 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4004
4005 rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);
4006 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4007 }
4008
TEST(GetStatus,goodPathDecodeResponse)4009 TEST(GetStatus, goodPathDecodeResponse)
4010 {
4011 constexpr std::bitset<32> updateOptionFlagsEnabled1{0};
4012 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4013 getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
4014 0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};
4015 auto responseMsg1 =
4016 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4017 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4018
4019 uint8_t completionCode = 0;
4020 uint8_t currentState = 0;
4021 uint8_t previousState = 0;
4022 uint8_t auxState = 0;
4023 uint8_t auxStateStatus = 0;
4024 uint8_t progressPercent = 0;
4025 uint8_t reasonCode = 0;
4026 bitfield32_t updateOptionFlagsEnabled{0};
4027
4028 auto rc = decode_get_status_resp(
4029 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4030 ¤tState, &previousState, &auxState, &auxStateStatus,
4031 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4032
4033 EXPECT_EQ(rc, PLDM_SUCCESS);
4034 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4035 EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);
4036 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4037 EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);
4038 EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);
4039 EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);
4040 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4041 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);
4042
4043 // Bit position 0 - Force update of component – FD will perform a force
4044 // update of the component.
4045 constexpr std::bitset<32> updateOptionFlagsEnabled2{1};
4046 constexpr uint8_t progressPercent2 = 50;
4047 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4048 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,
4049 0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};
4050 auto responseMsg2 =
4051 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4052 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4053
4054 rc = decode_get_status_resp(
4055 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4056 ¤tState, &previousState, &auxState, &auxStateStatus,
4057 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4058
4059 EXPECT_EQ(rc, PLDM_SUCCESS);
4060 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4061 EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);
4062 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4063 EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);
4064 EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);
4065 EXPECT_EQ(progressPercent, progressPercent2);
4066 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4067 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);
4068
4069 #ifdef LIBPLDM_API_TESTING
4070 /* Check the roundtrip */
4071 PLDM_MSG_DEFINE_P(enc, 1000);
4072 size_t enc_payload_len = 1000;
4073 const struct pldm_get_status_resp status_enc = {
4074 .completion_code = PLDM_SUCCESS,
4075 .current_state = currentState,
4076 .previous_state = previousState,
4077 .aux_state = auxState,
4078 .aux_state_status = auxStateStatus,
4079 .progress_percent = progressPercent,
4080 .reason_code = reasonCode,
4081 .update_option_flags_enabled = updateOptionFlagsEnabled,
4082 };
4083 rc = encode_get_status_resp(FIXED_INSTANCE_ID, &status_enc, enc,
4084 &enc_payload_len);
4085 EXPECT_EQ(rc, PLDM_SUCCESS);
4086 EXPECT_EQ(enc_payload_len + hdrSize, getStatusResponse2.size());
4087 EXPECT_TRUE(std::equal(getStatusResponse2.begin() + hdrSize,
4088 getStatusResponse2.end(), enc_buf + hdrSize));
4089 check_response(enc, PLDM_GET_STATUS);
4090 #endif
4091
4092 /* Check a not-ready completion code */
4093 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4094 getStatusResponse3{0x00, 0x00, 0x00, 0x04};
4095 auto responseMsg3 =
4096 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4097 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4098 rc = decode_get_status_resp(
4099 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4100 ¤tState, &previousState, &auxState, &auxStateStatus,
4101 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4102 EXPECT_EQ(rc, PLDM_SUCCESS);
4103 EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);
4104 }
4105
TEST(GetStatus,errorPathDecodeResponse)4106 TEST(GetStatus, errorPathDecodeResponse)
4107 {
4108 uint8_t completionCode = 0;
4109 uint8_t currentState = 0;
4110 uint8_t previousState = 0;
4111 uint8_t auxState = 0;
4112 uint8_t auxStateStatus = 0;
4113 uint8_t progressPercent = 0;
4114 uint8_t reasonCode = 0;
4115 bitfield32_t updateOptionFlagsEnabled{0};
4116
4117 constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};
4118 auto responseMsg1 =
4119 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4120 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4121
4122 auto rc = decode_get_status_resp(
4123 nullptr, getStatusResponse1.size() - hdrSize, &completionCode,
4124 ¤tState, &previousState, &auxState, &auxStateStatus,
4125 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4126 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4127
4128 rc = decode_get_status_resp(
4129 responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,
4130 ¤tState, &previousState, &auxState, &auxStateStatus,
4131 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4132 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4133
4134 rc = decode_get_status_resp(
4135 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4136 nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,
4137 &reasonCode, &updateOptionFlagsEnabled);
4138 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4139
4140 rc = decode_get_status_resp(
4141 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4142 ¤tState, nullptr, &auxState, &auxStateStatus, &progressPercent,
4143 &reasonCode, &updateOptionFlagsEnabled);
4144 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4145
4146 rc = decode_get_status_resp(
4147 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4148 ¤tState, &previousState, nullptr, &auxStateStatus,
4149 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4150 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4151
4152 rc = decode_get_status_resp(
4153 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4154 ¤tState, &previousState, &auxState, nullptr, &progressPercent,
4155 &reasonCode, &updateOptionFlagsEnabled);
4156 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4157
4158 rc = decode_get_status_resp(
4159 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4160 ¤tState, &previousState, &auxState, &auxStateStatus, nullptr,
4161 &reasonCode, &updateOptionFlagsEnabled);
4162 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4163
4164 rc = decode_get_status_resp(
4165 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4166 ¤tState, &previousState, &auxState, &auxStateStatus,
4167 &progressPercent, nullptr, &updateOptionFlagsEnabled);
4168 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4169
4170 rc = decode_get_status_resp(
4171 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4172 ¤tState, &previousState, &auxState, &auxStateStatus,
4173 &progressPercent, &reasonCode, nullptr);
4174 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4175
4176 rc = decode_get_status_resp(
4177 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4178 ¤tState, &previousState, &auxState, &auxStateStatus,
4179 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4180 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4181
4182 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>
4183 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4185 auto responseMsg2 =
4186 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4187 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4188 rc = decode_get_status_resp(
4189 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4190 ¤tState, &previousState, &auxState, &auxStateStatus,
4191 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4192 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4193
4194 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4195 getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
4196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4197 auto responseMsg3 =
4198 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4199 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4200 rc = decode_get_status_resp(
4201 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4202 ¤tState, &previousState, &auxState, &auxStateStatus,
4203 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4204 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4205
4206 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4207 getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
4208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4209 auto responseMsg4 =
4210 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4211 reinterpret_cast<const pldm_msg*>(getStatusResponse4.data());
4212 rc = decode_get_status_resp(
4213 responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,
4214 ¤tState, &previousState, &auxState, &auxStateStatus,
4215 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4216 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4217
4218 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4219 getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
4220 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4221 auto responseMsg5 =
4222 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4223 reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());
4224 rc = decode_get_status_resp(
4225 responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,
4226 ¤tState, &previousState, &auxState, &auxStateStatus,
4227 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4228 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4229
4230 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4231 getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4232 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4233 auto responseMsg6 =
4234 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4235 reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());
4236 rc = decode_get_status_resp(
4237 responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,
4238 ¤tState, &previousState, &auxState, &auxStateStatus,
4239 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4240 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4241
4242 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4243 getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4244 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
4245 auto responseMsg7 =
4246 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4247 reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());
4248 rc = decode_get_status_resp(
4249 responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,
4250 ¤tState, &previousState, &auxState, &auxStateStatus,
4251 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4252 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4253
4254 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4255 getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4256 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00};
4257 auto responseMsg8 =
4258 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4259 reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());
4260 rc = decode_get_status_resp(
4261 responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,
4262 ¤tState, &previousState, &auxState, &auxStateStatus,
4263 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4264 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4265
4266 // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is
4267 // IDLE
4268 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4269 getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
4270 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4271 auto responseMsg9 =
4272 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4273 reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());
4274 rc = decode_get_status_resp(
4275 responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,
4276 ¤tState, &previousState, &auxState, &auxStateStatus,
4277 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4278 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4279 }
4280
TEST(CancelUpdateComponent,goodPathEncodeRequest)4281 TEST(CancelUpdateComponent, goodPathEncodeRequest)
4282 {
4283 constexpr uint8_t instanceId = 9;
4284 std::array<uint8_t, hdrSize> request{};
4285 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4286 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4287
4288 auto rc = encode_cancel_update_component_req(
4289 instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4290 EXPECT_EQ(rc, PLDM_SUCCESS);
4291
4292 constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
4293 EXPECT_EQ(request, outRequest);
4294 }
4295
TEST(CancelUpdateComponent,errorPathEncodeRequest)4296 TEST(CancelUpdateComponent, errorPathEncodeRequest)
4297 {
4298 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
4299 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4300 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4301
4302 auto rc = encode_cancel_update_component_req(
4303 0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4304 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4305
4306 rc = encode_cancel_update_component_req(
4307 0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);
4308 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4309 }
4310
TEST(CancelUpdateComponent,testGoodDecodeResponse)4311 TEST(CancelUpdateComponent, testGoodDecodeResponse)
4312 {
4313 uint8_t completionCode = 0;
4314 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4315 cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};
4316 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4317 auto responseMsg1 = reinterpret_cast<const pldm_msg*>(
4318 cancelUpdateComponentResponse1.data());
4319 auto rc = decode_cancel_update_component_resp(
4320 responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,
4321 &completionCode);
4322 EXPECT_EQ(rc, PLDM_SUCCESS);
4323 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4324
4325 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4326 cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};
4327 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4328 auto responseMsg2 = reinterpret_cast<const pldm_msg*>(
4329 cancelUpdateComponentResponse2.data());
4330 rc = decode_cancel_update_component_resp(
4331 responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,
4332 &completionCode);
4333 EXPECT_EQ(rc, PLDM_SUCCESS);
4334 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4335 }
4336
TEST(CancelUpdateComponent,testBadDecodeResponse)4337 TEST(CancelUpdateComponent, testBadDecodeResponse)
4338 {
4339 uint8_t completionCode = 0;
4340 constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{
4341 0x00, 0x00, 0x00};
4342 auto responseMsg =
4343 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4344 reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data());
4345
4346 auto rc = decode_cancel_update_component_resp(
4347 nullptr, cancelUpdateComponentResponse.size() - hdrSize,
4348 &completionCode);
4349 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4350
4351 rc = decode_cancel_update_component_resp(
4352 responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);
4353 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4354
4355 rc = decode_cancel_update_component_resp(
4356 responseMsg, cancelUpdateComponentResponse.size() - hdrSize,
4357 &completionCode);
4358 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4359 }
4360
TEST(CancelUpdate,goodPathEncodeRequest)4361 TEST(CancelUpdate, goodPathEncodeRequest)
4362 {
4363 constexpr uint8_t instanceId = 10;
4364 std::array<uint8_t, hdrSize> request{};
4365 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4366 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4367
4368 auto rc = encode_cancel_update_req(instanceId, requestMsg,
4369 PLDM_CANCEL_UPDATE_REQ_BYTES);
4370 EXPECT_EQ(rc, PLDM_SUCCESS);
4371
4372 constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
4373 EXPECT_EQ(request, outRequest);
4374 }
4375
TEST(CancelUpdate,errorPathEncodeRequest)4376 TEST(CancelUpdate, errorPathEncodeRequest)
4377 {
4378 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
4379 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4380 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4381
4382 auto rc =
4383 encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
4384 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4385
4386 rc = encode_cancel_update_req(0, requestMsg,
4387 PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
4388 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4389 }
4390
TEST(CancelUpdate,goodPathDecodeResponse)4391 TEST(CancelUpdate, goodPathDecodeResponse)
4392 {
4393 constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
4394 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4395 cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4397 auto responseMsg1 =
4398 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4399 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4400 uint8_t completionCode = 0;
4401 bool8_t nonFunctioningComponentIndication = 0;
4402 bitfield64_t nonFunctioningComponentBitmap{0};
4403 auto rc = decode_cancel_update_resp(
4404 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4405 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4406 EXPECT_EQ(rc, PLDM_SUCCESS);
4407 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4408 EXPECT_EQ(nonFunctioningComponentIndication,
4409 PLDM_FWUP_COMPONENTS_FUNCTIONING);
4410 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4411 nonFunctioningComponentBitmap1);
4412
4413 constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
4414 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4415 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
4416 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4417 auto responseMsg2 =
4418 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4419 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4420 rc = decode_cancel_update_resp(
4421 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4422 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4423 EXPECT_EQ(rc, PLDM_SUCCESS);
4424 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4425 EXPECT_EQ(nonFunctioningComponentIndication,
4426 PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING);
4427 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4428 nonFunctioningComponentBitmap2);
4429
4430 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4431 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
4432 auto responseMsg3 =
4433 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4434 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4435 rc = decode_cancel_update_resp(
4436 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4437 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4438 EXPECT_EQ(rc, PLDM_SUCCESS);
4439 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4440 }
4441
TEST(CancelUpdate,errorPathDecodeResponse)4442 TEST(CancelUpdate, errorPathDecodeResponse)
4443 {
4444 constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
4445 0x00};
4446 auto responseMsg1 =
4447 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4448 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4449 uint8_t completionCode = 0;
4450 bool8_t nonFunctioningComponentIndication = 0;
4451 bitfield64_t nonFunctioningComponentBitmap{0};
4452
4453 auto rc = decode_cancel_update_resp(
4454 nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4455 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4456 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4457
4458 rc = decode_cancel_update_resp(
4459 responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
4460 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4461 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4462
4463 rc = decode_cancel_update_resp(
4464 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4465 nullptr, &nonFunctioningComponentBitmap);
4466 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4467
4468 rc = decode_cancel_update_resp(
4469 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4470 &nonFunctioningComponentIndication, nullptr);
4471 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4472
4473 rc = decode_cancel_update_resp(
4474 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4475 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4476 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4477
4478 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4479 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
4480 auto responseMsg2 =
4481 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4482 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4483 rc = decode_cancel_update_resp(
4484 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4485 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4486 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4487
4488 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4489 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
4490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4491 auto responseMsg3 =
4492 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4493 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4494 rc = decode_cancel_update_resp(
4495 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4496 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4497 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4498 }
4499