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