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