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_DATA);
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 PLDM_MSGBUF_DEFINE_P(buf);
1485 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1486 responseMsg.size() - hdrSize);
1487 EXPECT_EQ(rc, 0);
1488
1489 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1490 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1491 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1492 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1493 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
1494 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
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 PLDM_MSGBUF_DEFINE_P(buf);
1531 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1532 responseMsg.size() - hdrSize);
1533 ASSERT_EQ(rc, 0);
1534 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1535 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1536 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1537 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1538 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
1539 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
1540
1541 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1542 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1543 struct pldm_query_downstream_devices_resp resp_data;
1544
1545 rc = decode_query_downstream_devices_resp(
1546 response, responseMsg.size() - hdrSize, &resp_data);
1547
1548 ASSERT_EQ(rc, -EINVAL);
1549 }
1550
TEST(QueryDownstreamDevices,decodeRequestErrorBufSize)1551 TEST(QueryDownstreamDevices, decodeRequestErrorBufSize)
1552 {
1553 uint8_t completion_code_resp = PLDM_SUCCESS;
1554 uint8_t downstream_device_update_supported_resp =
1555 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1556 uint16_t number_of_downstream_devices_resp = 1;
1557 uint16_t max_number_of_downstream_devices_resp = 1;
1558 /** Capabilities of updating downstream devices
1559 * FDP supports downstream devices dynamically attached [Bit position 0] &
1560 * FDP supports downstream devices dynamically removed [Bit position 1]
1561 */
1562 bitfield32_t capabilities_resp = {.value = 0x0002};
1563 int rc;
1564
1565 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES -
1566 2 /* Inject error length*/>
1567 responseMsg{};
1568
1569 PLDM_MSGBUF_DEFINE_P(buf);
1570 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1571 responseMsg.size() - hdrSize);
1572 ASSERT_EQ(rc, 0);
1573
1574 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1575 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1576 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1577 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1578 // Inject error value
1579 pldm_msgbuf_insert_uint16(buf, (uint16_t)capabilities_resp.value);
1580 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
1581
1582 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1583 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1584 struct pldm_query_downstream_devices_resp resp_data;
1585
1586 rc = decode_query_downstream_devices_resp(
1587 response, responseMsg.size() - hdrSize, &resp_data);
1588
1589 EXPECT_EQ(rc, -EBADMSG);
1590 }
1591
TEST(QueryDownstreamIdentifiers,goodPathEncodeRequest)1592 TEST(QueryDownstreamIdentifiers, goodPathEncodeRequest)
1593 {
1594 constexpr uint8_t instanceId = 1;
1595 constexpr size_t payloadLen = PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1596 PLDM_MSG_DEFINE_P(request, payloadLen);
1597 constexpr pldm_query_downstream_identifiers_req params_req{
1598 0xFFFFFFFF, PLDM_GET_FIRSTPART};
1599
1600 auto rc = encode_query_downstream_identifiers_req(instanceId, ¶ms_req,
1601 request, payloadLen);
1602 ASSERT_EQ(rc, 0);
1603 EXPECT_THAT(std::span<uint8_t>(request_buf, sizeof(request_buf)),
1604 ElementsAreArray<uint8_t>(
1605 {0x81, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x01}));
1606 }
1607
TEST(QueryDownstreamIdentifiers,encodeRequestInvalidErrorPaths)1608 TEST(QueryDownstreamIdentifiers, encodeRequestInvalidErrorPaths)
1609 {
1610 constexpr uint8_t instanceId = 1;
1611 constexpr pldm_query_downstream_identifiers_req params_req{
1612 0xFFFFFFFF, PLDM_GET_FIRSTPART};
1613 constexpr pldm_query_downstream_identifiers_req params_req_invalid{
1614 0xFFFFFFFF, PLDM_ACKNOWLEDGEMENT_ONLY};
1615 constexpr size_t payload_length =
1616 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1617 std::array<uint8_t, hdrSize + payload_length> requestMsg{};
1618 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
1619 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1620
1621 auto rc = encode_query_downstream_identifiers_req(instanceId, ¶ms_req,
1622 nullptr, payload_length);
1623 EXPECT_EQ(rc, -EINVAL);
1624
1625 rc = encode_query_downstream_identifiers_req(
1626 instanceId, ¶ms_req, requestPtr, payload_length - 1);
1627 EXPECT_EQ(rc, -EOVERFLOW);
1628
1629 rc = encode_query_downstream_identifiers_req(
1630 instanceId, ¶ms_req_invalid, requestPtr, payload_length);
1631 EXPECT_EQ(rc, -EINVAL);
1632 }
1633
TEST(QueryDownstreamIdentifiers,decodeResponseNoDevices)1634 TEST(QueryDownstreamIdentifiers, decodeResponseNoDevices)
1635 {
1636 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1637 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1638 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1639 constexpr uint32_t downstream_devices_length_resp = 0;
1640 constexpr uint16_t number_of_downstream_devices_resp = 0;
1641
1642 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1643 struct pldm_query_downstream_identifiers_resp resp_data = {};
1644 struct pldm_downstream_device_iter devs;
1645 PLDM_MSGBUF_DEFINE_P(buf);
1646 int rc = 0;
1647
1648 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1649 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1650 ASSERT_EQ(rc, 0);
1651
1652 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1653 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1654 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1655 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1656 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1657
1658 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
1659
1660 rc = decode_query_downstream_identifiers_resp(
1661 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp_data,
1662 &devs);
1663
1664 ASSERT_EQ(rc, 0);
1665 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1666 EXPECT_EQ(resp_data.next_data_transfer_handle,
1667 next_data_transfer_handle_resp);
1668 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1669 EXPECT_EQ(resp_data.downstream_devices_length,
1670 downstream_devices_length_resp);
1671 EXPECT_EQ(resp_data.number_of_downstream_devices,
1672 number_of_downstream_devices_resp);
1673 }
1674
TEST(QueryDownstreamIdentifiers,decodeResponseNoDevicesBadCount)1675 TEST(QueryDownstreamIdentifiers, decodeResponseNoDevicesBadCount)
1676 {
1677 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1678 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1679 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1680 constexpr uint32_t downstream_devices_length_resp = 0;
1681 constexpr uint16_t number_of_downstream_devices_resp = 1;
1682
1683 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1684 struct pldm_query_downstream_identifiers_resp resp = {};
1685 struct pldm_downstream_device_iter devs;
1686 struct pldm_downstream_device dev;
1687 PLDM_MSGBUF_DEFINE_P(buf);
1688 int rc = 0;
1689
1690 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1691 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1692 ASSERT_EQ(rc, 0);
1693
1694 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1695 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1696 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1697 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1698 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1699
1700 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
1701
1702 rc = decode_query_downstream_identifiers_resp(
1703 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp, &devs);
1704 ASSERT_EQ(rc, 0);
1705
1706 foreach_pldm_downstream_device(devs, dev, rc)
1707 {
1708 FAIL();
1709 }
1710 ASSERT_NE(rc, 0);
1711 }
1712
TEST(QueryDownstreamIdentifiers,decodeResponseOneDeviceOneDescriptor)1713 TEST(QueryDownstreamIdentifiers, decodeResponseOneDeviceOneDescriptor)
1714 {
1715 constexpr uint32_t downstreamDevicesLen = 11;
1716 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1717 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1718 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1719 const uint32_t downstream_devices_length_resp =
1720 htole32(downstreamDevicesLen);
1721 constexpr uint16_t number_of_downstream_devices_resp = 1;
1722 constexpr size_t payloadLen =
1723 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstreamDevicesLen;
1724
1725 struct pldm_query_downstream_identifiers_resp resp_data = {};
1726 PLDM_MSG_DEFINE_P(response, payloadLen);
1727 struct pldm_downstream_device_iter devs;
1728 struct pldm_downstream_device dev;
1729 PLDM_MSGBUF_DEFINE_P(buf);
1730 int rc = 0;
1731
1732 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1733 ASSERT_EQ(rc, 0);
1734
1735 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1736 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1737 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1738 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1739 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1740
1741 /* Downstream device */
1742 pldm_msgbuf_insert_uint16(buf, 1);
1743 pldm_msgbuf_insert_uint8(buf, 1);
1744
1745 /* Device descriptor */
1746 pldm_msgbuf_insert_uint16(buf, 1);
1747 pldm_msgbuf_insert_uint16(buf, 4);
1748 pldm_msgbuf_insert_uint32(buf, 412);
1749
1750 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
1751
1752 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1753 &resp_data, &devs);
1754
1755 ASSERT_EQ(rc, 0);
1756 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1757 EXPECT_EQ(resp_data.next_data_transfer_handle,
1758 next_data_transfer_handle_resp);
1759 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1760 EXPECT_EQ(resp_data.downstream_devices_length,
1761 downstream_devices_length_resp);
1762 EXPECT_EQ(resp_data.number_of_downstream_devices,
1763 number_of_downstream_devices_resp);
1764
1765 foreach_pldm_downstream_device(devs, dev, rc)
1766 {
1767 struct pldm_descriptor desc;
1768
1769 EXPECT_EQ(dev.downstream_device_index, 1);
1770 EXPECT_EQ(dev.downstream_descriptor_count, 1);
1771
1772 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1773 {
1774 static const uint32_t dmtf = htole32(412);
1775 EXPECT_EQ(desc.descriptor_type, 1);
1776 EXPECT_EQ(desc.descriptor_length, 4);
1777 EXPECT_EQ(memcmp(desc.descriptor_data, &dmtf, sizeof(dmtf)), 0);
1778 }
1779 ASSERT_EQ(rc, 0);
1780 }
1781 ASSERT_EQ(rc, 0);
1782 }
1783
1784 constexpr const uint16_t descriptor_id_type_iana_pen = 0x1;
1785 constexpr const uint16_t descriptor_id_len_iana_pen = 0x4;
1786 const uint32_t iana_pen_openbmc = htole16(49871u);
1787 const uint32_t iana_pen_dmtf = htole16(412u);
1788
TEST(QueryDownstreamIdentifiers,decodeResponseTwoDevicesOneDescriptorEach)1789 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneDescriptorEach)
1790 {
1791 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1792 {0, 1},
1793 {1, 1},
1794 }};
1795
1796 constexpr const std::array<pldm_descriptor, 2> expected_descriptors = {{
1797 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1798 &iana_pen_dmtf},
1799 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1800 &iana_pen_openbmc},
1801 }};
1802
1803 constexpr uint32_t downstream_devices_len = 22;
1804 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1805 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1806 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1807 const uint32_t downstream_devices_length_resp =
1808 htole32(downstream_devices_len);
1809 constexpr uint16_t number_of_downstream_devices_resp = 2;
1810 constexpr size_t payloadLen =
1811 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
1812
1813 struct pldm_query_downstream_identifiers_resp resp_data{};
1814 PLDM_MSG_DEFINE_P(response, payloadLen);
1815 struct pldm_downstream_device_iter devs;
1816 struct pldm_downstream_device dev;
1817 PLDM_MSGBUF_DEFINE_P(buf);
1818 int rc = 0;
1819
1820 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1821 ASSERT_EQ(rc, 0);
1822
1823 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1824 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1825 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1826 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1827 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1828
1829 /* Downstream device */
1830 pldm_msgbuf_insert_uint16(buf, 0);
1831 pldm_msgbuf_insert_uint8(buf, 1);
1832
1833 /* Device descriptor */
1834 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1835 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1836 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1837
1838 /* Downstream device */
1839 pldm_msgbuf_insert_uint16(buf, 1);
1840 pldm_msgbuf_insert_uint8(buf, 1);
1841
1842 /* Device descriptor */
1843 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1844 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1845 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
1846
1847 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
1848
1849 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1850 &resp_data, &devs);
1851
1852 ASSERT_EQ(rc, 0);
1853 EXPECT_EQ(resp_data.number_of_downstream_devices,
1854 number_of_downstream_devices_resp);
1855
1856 size_t devIndex = 0;
1857 size_t descIndex = 0;
1858 foreach_pldm_downstream_device(devs, dev, rc)
1859 {
1860 struct pldm_descriptor desc;
1861
1862 ASSERT_LT(devIndex, expected_devices.size());
1863
1864 const struct pldm_downstream_device* expectedDev =
1865 &expected_devices[devIndex];
1866
1867 EXPECT_EQ(dev.downstream_device_index,
1868 expectedDev->downstream_device_index);
1869 EXPECT_EQ(dev.downstream_descriptor_count,
1870 expectedDev->downstream_descriptor_count);
1871
1872 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1873 {
1874 ASSERT_LT(descIndex, expected_descriptors.size());
1875
1876 const struct pldm_descriptor* expectedDesc =
1877 &expected_descriptors[descIndex];
1878
1879 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
1880 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
1881 EXPECT_EQ(memcmp(desc.descriptor_data,
1882 expectedDesc->descriptor_data,
1883 expectedDesc->descriptor_length),
1884 0);
1885
1886 descIndex++;
1887 }
1888 ASSERT_EQ(rc, 0);
1889 EXPECT_EQ(descIndex, 1 * devIndex + 1);
1890
1891 devIndex++;
1892 }
1893 ASSERT_EQ(rc, 0);
1894 EXPECT_EQ(devIndex, 2);
1895 }
1896
TEST(QueryDownstreamIdentifiers,decodeResponseTwoDevicesTwoOneDescriptors)1897 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesTwoOneDescriptors)
1898 {
1899 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1900 {0, 2},
1901 {1, 1},
1902 }};
1903
1904 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
1905 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1906 &iana_pen_dmtf},
1907 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1908 &iana_pen_openbmc},
1909 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1910 &iana_pen_dmtf},
1911 }};
1912
1913 constexpr uint32_t downstream_devices_len = 30;
1914 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1915 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1916 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1917 const uint32_t downstream_devices_length_resp =
1918 htole32(downstream_devices_len);
1919 constexpr uint16_t number_of_downstream_devices_resp = 2;
1920 constexpr size_t payloadLen =
1921 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
1922
1923 struct pldm_query_downstream_identifiers_resp resp_data{};
1924 PLDM_MSG_DEFINE_P(response, payloadLen);
1925 struct pldm_downstream_device_iter devs;
1926 struct pldm_downstream_device dev;
1927 PLDM_MSGBUF_DEFINE_P(buf);
1928 int rc = 0;
1929
1930 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1931 ASSERT_EQ(rc, 0);
1932
1933 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1934 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1935 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1936 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1937 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1938
1939 /* Downstream device */
1940 pldm_msgbuf_insert_uint16(buf, 0);
1941 pldm_msgbuf_insert_uint8(buf, 2);
1942
1943 /* Device descriptor */
1944 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1945 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1946 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1947
1948 /* Device descriptor */
1949 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1950 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1951 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
1952
1953 /* Downstream device */
1954 pldm_msgbuf_insert_uint16(buf, 1);
1955 pldm_msgbuf_insert_uint8(buf, 1);
1956
1957 /* Device descriptor */
1958 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1959 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1960 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1961
1962 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
1963
1964 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1965 &resp_data, &devs);
1966
1967 ASSERT_EQ(rc, 0);
1968 EXPECT_EQ(resp_data.number_of_downstream_devices,
1969 number_of_downstream_devices_resp);
1970
1971 size_t devIndex = 0;
1972 size_t descIndex = 0;
1973 foreach_pldm_downstream_device(devs, dev, rc)
1974 {
1975 struct pldm_descriptor desc;
1976
1977 ASSERT_LT(devIndex, expected_devices.size());
1978
1979 const struct pldm_downstream_device* expectedDev =
1980 &expected_devices[devIndex];
1981
1982 EXPECT_EQ(dev.downstream_device_index,
1983 expectedDev->downstream_device_index);
1984 EXPECT_EQ(dev.downstream_descriptor_count,
1985 expectedDev->downstream_descriptor_count);
1986
1987 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1988 {
1989 ASSERT_LT(descIndex, expected_descriptors.size());
1990
1991 const struct pldm_descriptor* expectedDesc =
1992 &expected_descriptors[descIndex];
1993
1994 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
1995 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
1996 EXPECT_EQ(memcmp(desc.descriptor_data,
1997 expectedDesc->descriptor_data,
1998 expectedDesc->descriptor_length),
1999 0);
2000
2001 descIndex++;
2002 }
2003 ASSERT_EQ(rc, 0);
2004
2005 devIndex++;
2006 }
2007 ASSERT_EQ(rc, 0);
2008 EXPECT_EQ(devIndex, 2);
2009 EXPECT_EQ(descIndex, 3);
2010 }
2011
TEST(QueryDownstreamIdentifiers,decodeResponseTwoDevicesOneTwoDescriptors)2012 TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneTwoDescriptors)
2013 {
2014 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
2015 {0, 1},
2016 {1, 2},
2017 }};
2018
2019 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
2020 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2021 &iana_pen_dmtf},
2022 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2023 &iana_pen_openbmc},
2024 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2025 &iana_pen_dmtf},
2026 }};
2027
2028 constexpr uint32_t downstream_devices_len = 30;
2029 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2030 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2031 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2032 const uint32_t downstream_devices_length_resp =
2033 htole32(downstream_devices_len);
2034 constexpr uint16_t number_of_downstream_devices_resp = 2;
2035 constexpr size_t payloadLen =
2036 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2037
2038 struct pldm_query_downstream_identifiers_resp resp_data{};
2039 PLDM_MSG_DEFINE_P(response, payloadLen);
2040 struct pldm_downstream_device_iter devs;
2041 struct pldm_downstream_device dev;
2042 PLDM_MSGBUF_DEFINE_P(buf);
2043 int rc = 0;
2044
2045 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2046 ASSERT_EQ(rc, 0);
2047
2048 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2049 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2050 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2051 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2052 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2053
2054 /* Downstream device */
2055 pldm_msgbuf_insert_uint16(buf, 0);
2056 pldm_msgbuf_insert_uint8(buf, 1);
2057
2058 /* Device descriptor */
2059 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2060 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2061 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2062
2063 /* Downstream device */
2064 pldm_msgbuf_insert_uint16(buf, 1);
2065 pldm_msgbuf_insert_uint8(buf, 2);
2066
2067 /* Device descriptor */
2068 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2069 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2070 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2071
2072 /* Device descriptor */
2073 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2074 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2075 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2076
2077 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
2078
2079 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2080 &resp_data, &devs);
2081
2082 ASSERT_EQ(rc, 0);
2083 EXPECT_EQ(resp_data.number_of_downstream_devices,
2084 number_of_downstream_devices_resp);
2085
2086 size_t devIndex = 0;
2087 size_t descIndex = 0;
2088 foreach_pldm_downstream_device(devs, dev, rc)
2089 {
2090 struct pldm_descriptor desc;
2091
2092 ASSERT_LT(devIndex, expected_devices.size());
2093
2094 const struct pldm_downstream_device* expectedDev =
2095 &expected_devices[devIndex];
2096
2097 EXPECT_EQ(dev.downstream_device_index,
2098 expectedDev->downstream_device_index);
2099 EXPECT_EQ(dev.downstream_descriptor_count,
2100 expectedDev->downstream_descriptor_count);
2101
2102 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2103 {
2104 ASSERT_LT(descIndex, expected_descriptors.size());
2105
2106 const struct pldm_descriptor* expectedDesc =
2107 &expected_descriptors[descIndex];
2108
2109 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2110 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2111 EXPECT_EQ(memcmp(desc.descriptor_data,
2112 expectedDesc->descriptor_data,
2113 expectedDesc->descriptor_length),
2114 0);
2115
2116 descIndex++;
2117 }
2118 ASSERT_EQ(rc, 0);
2119
2120 devIndex++;
2121 }
2122 ASSERT_EQ(rc, 0);
2123 EXPECT_EQ(devIndex, 2);
2124 EXPECT_EQ(descIndex, 3);
2125 }
2126
TEST(QueryDownstreamIdentifiers,decodeRequestErrorPaths)2127 TEST(QueryDownstreamIdentifiers, decodeRequestErrorPaths)
2128 {
2129 constexpr size_t payloadLen = sizeof(uint8_t);
2130
2131 struct pldm_query_downstream_identifiers_resp resp_data = {};
2132 struct pldm_downstream_device_iter devs;
2133 PLDM_MSG_DEFINE_P(response, payloadLen);
2134
2135 // Test nullptr
2136 auto rc = decode_query_downstream_identifiers_resp(nullptr, payloadLen,
2137 nullptr, &devs);
2138 EXPECT_EQ(rc, -EINVAL);
2139
2140 // Test not PLDM_SUCCESS completion code
2141 response->payload[0] = PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
2142 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2143 &resp_data, &devs);
2144 EXPECT_EQ(rc, 0);
2145 EXPECT_EQ(resp_data.completion_code, PLDM_ERROR_UNSUPPORTED_PLDM_CMD);
2146
2147 // Test payload length less than minimum length
2148 response->payload[0] = PLDM_SUCCESS;
2149 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2150 &resp_data, &devs);
2151
2152 EXPECT_EQ(rc, -EBADMSG);
2153 }
2154
TEST(QueryDownstreamIdentifiers,decodeRequestErrorDownstreamDevicesSize)2155 TEST(QueryDownstreamIdentifiers, decodeRequestErrorDownstreamDevicesSize)
2156 {
2157 // Len is not fixed here taking it as 9, contains 1 downstream device with
2158 // 1 descriptor
2159 constexpr uint32_t actualDownstreamDevicesLen = 9;
2160 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2161 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2162 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2163 constexpr uint16_t number_of_downstream_devices_resp = 1;
2164 constexpr size_t payloadLen =
2165 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN +
2166 actualDownstreamDevicesLen;
2167
2168 const uint32_t downstream_devices_length_resp =
2169 htole32(actualDownstreamDevicesLen + 1 /* inject error length*/);
2170
2171 struct pldm_query_downstream_identifiers_resp resp_data = {};
2172 struct pldm_downstream_device_iter devs;
2173 PLDM_MSG_DEFINE_P(response, payloadLen);
2174 PLDM_MSGBUF_DEFINE_P(buf);
2175 void* devicesStart = NULL;
2176 size_t devicesLen;
2177 int rc = 0;
2178
2179 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2180 ASSERT_EQ(rc, 0);
2181
2182 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2183 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2184 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2185 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2186 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2187 pldm_msgbuf_span_remaining(buf, &devicesStart, &devicesLen);
2188
2189 ASSERT_EQ(0, pldm_msgbuf_complete(buf));
2190
2191 /** Filling descriptor data, the correctness of the downstream devices data
2192 * is not checked in this test case so filling with 0xff
2193 */
2194 std::fill_n(static_cast<uint8_t*>(devicesStart), actualDownstreamDevicesLen,
2195 0xff);
2196
2197 EXPECT_NE(decode_query_downstream_identifiers_resp(response, payloadLen,
2198 &resp_data, &devs),
2199 0);
2200 }
2201
TEST(QueryDownstreamIdentifiers,decodeRequestErrorBufSize)2202 TEST(QueryDownstreamIdentifiers, decodeRequestErrorBufSize)
2203 {
2204 constexpr uint32_t actualDownstreamDevicesLen = 0;
2205 constexpr uint16_t number_of_downstream_devices_resp = 1;
2206 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2207 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2208 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2209 constexpr size_t payloadLen =
2210 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN - 1;
2211
2212 const uint32_t downstream_devices_length_resp =
2213 htole32(actualDownstreamDevicesLen);
2214
2215 struct pldm_query_downstream_identifiers_resp resp_data = {};
2216 struct pldm_downstream_device_iter devs;
2217 PLDM_MSG_DEFINE_P(response, payloadLen);
2218 PLDM_MSGBUF_DEFINE_P(buf);
2219 int rc = 0;
2220
2221 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2222 ASSERT_EQ(rc, 0);
2223
2224 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2225 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2226 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2227 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2228 // Inject error buffer size
2229 pldm_msgbuf_insert_uint8(buf, (uint8_t)number_of_downstream_devices_resp);
2230 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
2231
2232 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2233 &resp_data, &devs);
2234
2235 EXPECT_EQ(rc, -EBADMSG);
2236 }
2237
TEST(GetDownstreamFirmwareParameters,goodPathEncodeRequest)2238 TEST(GetDownstreamFirmwareParameters, goodPathEncodeRequest)
2239 {
2240 constexpr uint8_t instanceId = 1;
2241 constexpr pldm_get_downstream_firmware_parameters_req params_req{
2242 0x0, PLDM_GET_FIRSTPART};
2243 constexpr size_t payload_length =
2244 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
2245 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
2246 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2247 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2248
2249 auto rc = encode_get_downstream_firmware_parameters_req(
2250 instanceId, ¶ms_req, requestPtr, payload_length);
2251 EXPECT_EQ(rc, 0);
2252
2253 std::array<uint8_t,
2254 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES>
2255 expectedReq{0x81, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01};
2256 EXPECT_EQ(requestMsg, expectedReq);
2257 }
2258
TEST(GetDownstreamFirmwareParameters,encodeRequestInvalidTransferOperationFlag)2259 TEST(GetDownstreamFirmwareParameters, encodeRequestInvalidTransferOperationFlag)
2260 {
2261 constexpr uint8_t instanceId = 1;
2262 // Setup invalid transfer operation flag
2263 constexpr pldm_get_downstream_firmware_parameters_req params_req{
2264 0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
2265 constexpr size_t payload_length =
2266 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
2267 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
2268 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2269 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2270
2271 auto rc = encode_get_downstream_firmware_parameters_req(
2272 instanceId, ¶ms_req, requestPtr, payload_length);
2273 EXPECT_EQ(rc, -EBADMSG);
2274 }
2275
TEST(GetDownstreamFirmwareParameters,encodeRequestErrorBufSize)2276 TEST(GetDownstreamFirmwareParameters, encodeRequestErrorBufSize)
2277 {
2278 constexpr uint8_t instanceId = 1;
2279 // Setup invalid transfer operation flag
2280 constexpr pldm_get_downstream_firmware_parameters_req params_req{
2281 0x0, PLDM_GET_FIRSTPART};
2282 constexpr size_t payload_length =
2283 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES -
2284 1 /* inject erro length*/;
2285
2286 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
2287 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2288 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2289
2290 auto rc = encode_get_downstream_firmware_parameters_req(
2291 instanceId, ¶ms_req, requestPtr, payload_length);
2292 EXPECT_EQ(rc, -EOVERFLOW);
2293 }
2294
TEST(GetDownstreamFirmwareParameters,goodPathDecodeResponseOneEntry)2295 TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseOneEntry)
2296 {
2297 constexpr uint16_t downstreamDeviceCount = 1;
2298 constexpr uint8_t activeComponentVersionStringLength = 8;
2299 constexpr uint8_t pendingComponentVersionStringLength = 8;
2300 constexpr size_t downstreamDeviceParamTableLen =
2301 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2302 activeComponentVersionStringLength +
2303 pendingComponentVersionStringLength;
2304 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2305 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2306 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2307 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2308 constexpr size_t payload_len =
2309 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2310 downstreamDeviceParamTableLen;
2311
2312 PLDM_MSG_DEFINE_P(response, payload_len);
2313 PLDM_MSGBUF_DEFINE_P(buf);
2314 int rc = 0;
2315
2316 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
2317 ASSERT_EQ(rc, 0);
2318
2319 // Table 24
2320 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2321 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2322 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2323
2324 // Table 25
2325 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2326 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2327
2328 // Table 26
2329 pldm_msgbuf_insert_uint16(buf, 0);
2330
2331 // - Active metadata
2332 pldm_msgbuf_insert_uint32(buf, 0);
2333 pldm_msgbuf_insert_uint8(buf, 1);
2334 pldm_msgbuf_insert_uint8(buf, activeComponentVersionStringLength);
2335 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2336 ASSERT_EQ(rc, 0);
2337
2338 // - Pending metadata
2339 pldm_msgbuf_insert_uint32(buf, 0);
2340 pldm_msgbuf_insert_uint8(buf, 1);
2341 pldm_msgbuf_insert_uint8(buf, pendingComponentVersionStringLength);
2342 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2343 ASSERT_EQ(rc, 0);
2344
2345 // - Methods and capabilities
2346 pldm_msgbuf_insert_uint16(buf, 1);
2347 pldm_msgbuf_insert_uint32(buf, 0);
2348
2349 // - Version strings
2350 rc = pldm__msgbuf_insert_array_void(buf, activeComponentVersionStringLength,
2351 "abcdefgh", 8);
2352 ASSERT_EQ(rc, 0);
2353 rc = pldm__msgbuf_insert_array_void(
2354 buf, pendingComponentVersionStringLength, "zyxwvuts", 8);
2355 ASSERT_EQ(rc, 0);
2356
2357 rc = pldm_msgbuf_complete_consumed(buf);
2358 ASSERT_EQ(rc, 0);
2359
2360 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2361 struct pldm_downstream_device_parameters_iter iter = {};
2362
2363 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2364 &resp_data, &iter);
2365
2366 ASSERT_EQ(rc, 0);
2367 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
2368 EXPECT_EQ(resp_data.next_data_transfer_handle,
2369 next_data_transfer_handle_resp);
2370 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2371 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
2372
2373 struct pldm_downstream_device_parameters_entry entry;
2374 size_t entries = 0;
2375 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2376 {
2377 EXPECT_EQ(entry.downstream_device_index, 0);
2378 EXPECT_EQ(entry.active_comp_comparison_stamp, 0);
2379 EXPECT_EQ(entry.active_comp_ver_str_type, 1);
2380 EXPECT_EQ(entry.active_comp_ver_str_len,
2381 activeComponentVersionStringLength);
2382 EXPECT_STREQ("20241206", entry.active_comp_release_date);
2383 EXPECT_EQ(entry.pending_comp_comparison_stamp, 0);
2384 EXPECT_EQ(entry.pending_comp_ver_str_type, 1);
2385 EXPECT_EQ(entry.pending_comp_ver_str_len,
2386 pendingComponentVersionStringLength);
2387 EXPECT_STREQ("20241206", entry.pending_comp_release_date);
2388 EXPECT_EQ(entry.comp_activation_methods.value, 1);
2389 EXPECT_EQ(entry.capabilities_during_update.value, 0);
2390 EXPECT_FALSE(memcmp("abcdefgh", entry.active_comp_ver_str,
2391 entry.active_comp_ver_str_len));
2392 EXPECT_FALSE(memcmp("zyxwvuts", entry.pending_comp_ver_str,
2393 entry.pending_comp_ver_str_len));
2394 entries++;
2395 }
2396 EXPECT_EQ(rc, 0);
2397 EXPECT_EQ(entries, 1);
2398 }
2399
TEST(GetDownstreamFirmwareParameters,goodPathDecodeResponseTwoEntries)2400 TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseTwoEntries)
2401 {
2402 /** Count is not fixed here taking it as 1, and the downstream device's
2403 * version strings length are set to 8
2404 */
2405 constexpr uint16_t downstreamDeviceCount = 2;
2406 constexpr uint8_t activeComponentVersionStringLength = 8;
2407 constexpr uint8_t pendingComponentVersionStringLength = 9;
2408 constexpr size_t downstreamDeviceParamTableLen =
2409 static_cast<size_t>(downstreamDeviceCount *
2410 (PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2411 activeComponentVersionStringLength +
2412 pendingComponentVersionStringLength));
2413 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2414 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2415 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2416 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2417 constexpr size_t payload_len =
2418 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2419 downstreamDeviceParamTableLen;
2420
2421 PLDM_MSG_DEFINE_P(response, payload_len);
2422 PLDM_MSGBUF_DEFINE_P(buf);
2423 int rc = 0;
2424
2425 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
2426 ASSERT_EQ(rc, 0);
2427
2428 // Table 24
2429 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2430 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2431 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2432
2433 // Table 25
2434 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2435 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2436
2437 constexpr const std::array<pldm_downstream_device_parameters_entry, 2>
2438 table = {{{
2439 0,
2440 0,
2441 1,
2442 8,
2443 "20241206",
2444 0,
2445 1,
2446 9,
2447 "20241209",
2448 {1},
2449 {0},
2450 "active_0",
2451 "pending_0",
2452 },
2453 {
2454 1,
2455 0,
2456 1,
2457 8,
2458 "20241209",
2459 0,
2460 1,
2461 9,
2462 "20241206",
2463 {1},
2464 {0},
2465 "active_1",
2466 "pending_1",
2467 }}};
2468 for (const auto& e : table)
2469 {
2470 // Table 26
2471 pldm_msgbuf_insert_uint16(buf, e.downstream_device_index);
2472
2473 // - Active metadata
2474 pldm_msgbuf_insert_uint32(buf, e.active_comp_comparison_stamp);
2475 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_type);
2476 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_len);
2477 rc = pldm__msgbuf_insert_array_void(buf, 8, &e.active_comp_release_date,
2478 sizeof(e.active_comp_release_date));
2479 ASSERT_EQ(rc, 0);
2480
2481 // - Pending metadata
2482 pldm_msgbuf_insert_uint32(buf, e.pending_comp_comparison_stamp);
2483 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_type);
2484 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_len);
2485 rc =
2486 pldm__msgbuf_insert_array_void(buf, 8, e.pending_comp_release_date,
2487 sizeof(e.pending_comp_release_date));
2488 ASSERT_EQ(rc, 0);
2489
2490 // - Methods and capabilities
2491 pldm_msgbuf_insert_uint16(buf, e.comp_activation_methods.value);
2492 pldm_msgbuf_insert_uint32(buf, e.capabilities_during_update.value);
2493
2494 // - Version strings
2495 rc = pldm__msgbuf_insert_array_void(buf, e.active_comp_ver_str_len,
2496 e.active_comp_ver_str,
2497 e.active_comp_ver_str_len);
2498 ASSERT_EQ(rc, 0);
2499 rc = pldm__msgbuf_insert_array_void(buf, e.pending_comp_ver_str_len,
2500 e.pending_comp_ver_str,
2501 e.pending_comp_ver_str_len);
2502 ASSERT_EQ(rc, 0);
2503 }
2504
2505 rc = pldm_msgbuf_complete_consumed(buf);
2506 ASSERT_EQ(rc, 0);
2507
2508 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2509 struct pldm_downstream_device_parameters_iter iter = {};
2510
2511 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2512 &resp_data, &iter);
2513
2514 ASSERT_EQ(rc, 0);
2515 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
2516 EXPECT_EQ(resp_data.next_data_transfer_handle,
2517 next_data_transfer_handle_resp);
2518 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2519 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
2520
2521 struct pldm_downstream_device_parameters_entry entry;
2522 size_t entryIndex = 0;
2523 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2524 {
2525 ASSERT_LE(entryIndex, table.size());
2526
2527 EXPECT_EQ(table[entryIndex].downstream_device_index,
2528 entry.downstream_device_index);
2529 EXPECT_EQ(table[entryIndex].active_comp_comparison_stamp,
2530 entry.active_comp_comparison_stamp);
2531 EXPECT_EQ(table[entryIndex].active_comp_ver_str_type,
2532 entry.active_comp_ver_str_type);
2533 EXPECT_EQ(table[entryIndex].active_comp_ver_str_len,
2534 entry.active_comp_ver_str_len);
2535 EXPECT_STREQ(&table[entryIndex].active_comp_release_date[0],
2536 &entry.active_comp_release_date[0]);
2537 EXPECT_EQ(table[entryIndex].pending_comp_comparison_stamp,
2538 entry.pending_comp_comparison_stamp);
2539 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_type,
2540 entry.pending_comp_ver_str_type);
2541 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_len,
2542 entry.pending_comp_ver_str_len);
2543 EXPECT_STREQ(&table[entryIndex].pending_comp_release_date[0],
2544 &entry.pending_comp_release_date[0]);
2545 EXPECT_EQ(table[entryIndex].comp_activation_methods.value,
2546 entry.comp_activation_methods.value);
2547 EXPECT_EQ(table[entryIndex].capabilities_during_update.value,
2548 entry.capabilities_during_update.value);
2549 EXPECT_FALSE(memcmp(table[entryIndex].active_comp_ver_str,
2550 entry.active_comp_ver_str,
2551 table[entryIndex].active_comp_ver_str_len));
2552 EXPECT_FALSE(memcmp(table[entryIndex].pending_comp_ver_str,
2553 entry.pending_comp_ver_str,
2554 table[entryIndex].pending_comp_ver_str_len));
2555 entryIndex++;
2556 }
2557 EXPECT_EQ(rc, 0);
2558 EXPECT_EQ(entryIndex, table.size());
2559 }
2560
TEST(GetDownstreamFirmwareParameters,decodeResponseInvalidLength)2561 TEST(GetDownstreamFirmwareParameters, decodeResponseInvalidLength)
2562 {
2563 /** Count is not fixed here taking it as 1, and the downstream device's
2564 * version strings length are set to 8
2565 */
2566 constexpr uint16_t downstreamDeviceCount = 1;
2567 constexpr uint8_t activeComponentVersionStringLength = 8;
2568 constexpr uint8_t pendingComponentVersionStringLength = 8;
2569 constexpr size_t downstreamDeviceParamTableLen =
2570 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2571 activeComponentVersionStringLength +
2572 pendingComponentVersionStringLength;
2573 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2574 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2575 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2576 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2577
2578 std::array<uint8_t,
2579 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2580 downstreamDeviceParamTableLen - 1 /* inject error length*/>
2581 responseMsg{};
2582
2583 int rc = 0;
2584
2585 PLDM_MSGBUF_DEFINE_P(buf);
2586 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
2587 responseMsg.size() - hdrSize);
2588 ASSERT_EQ(rc, 0);
2589
2590 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2591 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2592 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2593 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2594 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2595 ASSERT_EQ(pldm_msgbuf_complete(buf), 0);
2596
2597 /** Filling paramter table, the correctness of the downstream devices data
2598 * is not checked in this test case so filling with 0xff
2599 */
2600 std::fill_n(responseMsg.data() + hdrSize +
2601 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN,
2602 downstreamDeviceParamTableLen - 1 /* inject error length*/,
2603 0xff);
2604
2605 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2606 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
2607 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2608 struct pldm_downstream_device_parameters_iter iter;
2609
2610 rc = decode_get_downstream_firmware_parameters_resp(
2611 response, responseMsg.size() - hdrSize, &resp_data, &iter);
2612 EXPECT_EQ(rc, 0);
2613
2614 struct pldm_downstream_device_parameters_entry entry;
2615 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2616 {
2617 FAIL();
2618 }
2619 EXPECT_EQ(rc, -EOVERFLOW);
2620 }
2621
TEST(RequestUpdate,goodPathEncodeRequest)2622 TEST(RequestUpdate, goodPathEncodeRequest)
2623 {
2624 constexpr uint8_t instanceId = 1;
2625 constexpr uint32_t maxTransferSize = 512;
2626 constexpr uint16_t numOfComp = 3;
2627 constexpr uint8_t maxOutstandingTransferReq = 2;
2628 constexpr uint16_t pkgDataLen = 0x1234;
2629 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2630 constexpr uint8_t compImgSetVerStrLen =
2631 static_cast<uint8_t>(compImgSetVerStr.size());
2632 variable_field compImgSetVerStrInfo{};
2633 compImgSetVerStrInfo.ptr =
2634 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2635 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2636 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2637
2638 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2639 compImgSetVerStrLen>
2640 request{};
2641 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2642 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2643
2644 auto rc = encode_request_update_req(
2645 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2646 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2647 &compImgSetVerStrInfo, requestMsg,
2648 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2649 EXPECT_EQ(rc, PLDM_SUCCESS);
2650
2651 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2652 compImgSetVerStrLen>
2653 outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00,
2654 0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e,
2655 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30};
2656 EXPECT_EQ(request, outRequest);
2657 }
2658
TEST(RequestUpdate,errorPathEncodeRequest)2659 TEST(RequestUpdate, errorPathEncodeRequest)
2660 {
2661 constexpr uint8_t instanceId = 1;
2662 uint32_t maxTransferSize = 512;
2663 constexpr uint16_t numOfComp = 3;
2664 uint8_t maxOutstandingTransferReq = 2;
2665 constexpr uint16_t pkgDataLen = 0x1234;
2666 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2667 uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2668 variable_field compImgSetVerStrInfo{};
2669 compImgSetVerStrInfo.ptr =
2670 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2671 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2672 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2673
2674 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2675 compImgSetVerStr.size()>
2676 request{};
2677 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2678 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2679
2680 auto rc = encode_request_update_req(
2681 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2682 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr,
2683 requestMsg,
2684 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2685 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2686
2687 compImgSetVerStrInfo.ptr = nullptr;
2688 rc = encode_request_update_req(
2689 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2690 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2691 &compImgSetVerStrInfo, requestMsg,
2692 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2693 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2694 compImgSetVerStrInfo.ptr =
2695 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2696 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2697
2698 rc = encode_request_update_req(
2699 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2700 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2701 &compImgSetVerStrInfo, nullptr,
2702 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2703 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2704
2705 rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp,
2706 maxOutstandingTransferReq, pkgDataLen,
2707 PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2708 &compImgSetVerStrInfo, requestMsg, 0);
2709 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2710
2711 compImgSetVerStrLen = 0;
2712 rc = encode_request_update_req(
2713 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2714 pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr,
2715 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2716 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2717 compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2718
2719 compImgSetVerStrInfo.length = 0xffff;
2720 rc = encode_request_update_req(
2721 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2722 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2723 &compImgSetVerStrInfo, nullptr,
2724 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2725 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2726 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2727
2728 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1;
2729 rc = encode_request_update_req(
2730 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2731 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2732 &compImgSetVerStrInfo, nullptr,
2733 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2734 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2735 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE;
2736
2737 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ - 1;
2738 rc = encode_request_update_req(
2739 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2740 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2741 &compImgSetVerStrInfo, nullptr,
2742 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2743 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2744 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ;
2745
2746 rc = encode_request_update_req(
2747 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2748 pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen,
2749 &compImgSetVerStrInfo, nullptr,
2750 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2751 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2752 }
2753
TEST(RequestUpdate,goodPathDecodeResponse)2754 TEST(RequestUpdate, goodPathDecodeResponse)
2755 {
2756 /* Test a success completion code */
2757 constexpr uint16_t fdMetaDataLen = 1024;
2758 constexpr uint8_t fdWillSendPkgData = 1;
2759 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)>
2760 requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01};
2761
2762 auto responseMsg1 =
2763 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2764 reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data());
2765 uint8_t outCompletionCode = 0;
2766 uint16_t outFdMetaDataLen = 0;
2767 uint8_t outFdWillSendPkgData = 0;
2768
2769 auto rc = decode_request_update_resp(
2770 responseMsg1, requestUpdateResponse1.size() - hdrSize,
2771 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2772 EXPECT_EQ(rc, PLDM_SUCCESS);
2773 EXPECT_EQ(outCompletionCode, PLDM_SUCCESS);
2774 EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen);
2775 EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData);
2776
2777 #ifdef LIBPLDM_API_TESTING
2778 /* Check the success roundtrip matches */
2779 PLDM_MSG_DEFINE_P(enc, 1000);
2780 size_t enc_payload_len = 1000;
2781 const struct pldm_request_update_resp resp_data = {
2782 .completion_code = PLDM_SUCCESS,
2783 .fd_meta_data_len = outFdMetaDataLen,
2784 .fd_will_send_pkg_data = outFdWillSendPkgData,
2785 };
2786 rc = encode_request_update_resp(FIXED_INSTANCE_ID, &resp_data, enc,
2787 &enc_payload_len);
2788 EXPECT_EQ(rc, PLDM_SUCCESS);
2789 EXPECT_EQ(enc_payload_len + hdrSize, requestUpdateResponse1.size());
2790 EXPECT_TRUE(std::equal(requestUpdateResponse1.begin() + hdrSize,
2791 requestUpdateResponse1.end(), enc_buf + hdrSize));
2792 check_response(enc, PLDM_REQUEST_UPDATE);
2793 #endif
2794
2795 /* Test a failure completion code */
2796 outCompletionCode = 0;
2797 outFdMetaDataLen = 0;
2798 outFdWillSendPkgData = 0;
2799
2800 constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)>
2801 requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
2802 auto responseMsg2 =
2803 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2804 reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data());
2805 rc = decode_request_update_resp(
2806 responseMsg2, requestUpdateResponse2.size() - hdrSize,
2807 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2808 EXPECT_EQ(rc, PLDM_SUCCESS);
2809 EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
2810 }
2811
TEST(RequestUpdate,errorPathDecodeResponse)2812 TEST(RequestUpdate, errorPathDecodeResponse)
2813 {
2814 constexpr std::array<uint8_t,
2815 hdrSize + sizeof(pldm_request_update_resp) - 1>
2816 requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
2817
2818 auto responseMsg =
2819 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2820 reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data());
2821 uint8_t outCompletionCode = 0;
2822 uint16_t outFdMetaDataLen = 0;
2823 uint8_t outFdWillSendPkgData = 0;
2824
2825 auto rc = decode_request_update_resp(
2826 nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2827 &outFdMetaDataLen, &outFdWillSendPkgData);
2828 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2829
2830 rc = decode_request_update_resp(
2831 responseMsg, requestUpdateResponse.size() - hdrSize, nullptr,
2832 &outFdMetaDataLen, &outFdWillSendPkgData);
2833 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2834
2835 rc = decode_request_update_resp(
2836 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2837 nullptr, &outFdWillSendPkgData);
2838 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2839
2840 rc = decode_request_update_resp(
2841 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2842 &outFdMetaDataLen, nullptr);
2843 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2844
2845 rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode,
2846 &outFdMetaDataLen, &outFdWillSendPkgData);
2847 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2848
2849 rc = decode_request_update_resp(
2850 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2851 &outFdMetaDataLen, &outFdWillSendPkgData);
2852 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2853 }
2854
TEST(PassComponentTable,goodPathEncodeRequest)2855 TEST(PassComponentTable, goodPathEncodeRequest)
2856 {
2857 constexpr uint8_t instanceId = 1;
2858 constexpr uint16_t compIdentifier = 400;
2859 constexpr uint8_t compClassificationIndex = 40;
2860 constexpr uint32_t compComparisonStamp = 0x12345678;
2861 constexpr std::string_view compVerStr = "0penBmcv1.1";
2862 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2863 variable_field compVerStrInfo{};
2864 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2865 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2866 compVerStrInfo.length = compVerStrLen;
2867
2868 std::array<uint8_t,
2869 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2870 request{};
2871 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2872 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2873
2874 auto rc = encode_pass_component_table_req(
2875 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2876 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2877 compVerStrLen, &compVerStrInfo, requestMsg,
2878 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2879 EXPECT_EQ(rc, PLDM_SUCCESS);
2880
2881 std::array<uint8_t,
2882 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2883 outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28,
2884 0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65,
2885 0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31};
2886 EXPECT_EQ(request, outRequest);
2887
2888 #ifdef LIBPLDM_API_TESTING
2889 /* Check the roundtrip */
2890 struct pldm_pass_component_table_req_full req;
2891 PLDM_MSG_DEFINE_P(dec, outRequest.size());
2892 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
2893 rc =
2894 decode_pass_component_table_req(dec, outRequest.size() - hdrSize, &req);
2895 ASSERT_EQ(rc, 0);
2896
2897 EXPECT_EQ(req.transfer_flag, PLDM_START_AND_END);
2898 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
2899 EXPECT_EQ(req.comp_identifier, compIdentifier);
2900 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
2901 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
2902 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
2903 EXPECT_EQ(req.version.str_len, compVerStrLen);
2904 EXPECT_TRUE(std::equal(req.version.str_data,
2905 req.version.str_data + req.version.str_len,
2906 compVerStr.data()));
2907 #endif
2908 }
2909
TEST(PassComponentTable,errorPathEncodeRequest)2910 TEST(PassComponentTable, errorPathEncodeRequest)
2911 {
2912 constexpr uint8_t instanceId = 1;
2913 constexpr uint16_t compIdentifier = 400;
2914 constexpr uint8_t compClassificationIndex = 40;
2915 constexpr uint32_t compComparisonStamp = 0x12345678;
2916 constexpr std::string_view compVerStr = "0penBmcv1.1";
2917 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2918 variable_field compVerStrInfo{};
2919 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2920 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2921 compVerStrInfo.length = compVerStrLen;
2922
2923 std::array<uint8_t,
2924 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2925 request{};
2926 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2927 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2928
2929 auto rc = encode_pass_component_table_req(
2930 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2931 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2932 compVerStrLen, nullptr, requestMsg,
2933 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2934 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2935
2936 compVerStrInfo.ptr = nullptr;
2937 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, &compVerStrInfo, requestMsg,
2941 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2942 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2943 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2944 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2945
2946 rc = encode_pass_component_table_req(
2947 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2948 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2949 compVerStrLen, &compVerStrInfo, nullptr,
2950 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2951 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2952
2953 rc = encode_pass_component_table_req(
2954 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2955 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2956 compVerStrLen, &compVerStrInfo, requestMsg,
2957 sizeof(pldm_pass_component_table_req));
2958 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2959
2960 rc = encode_pass_component_table_req(
2961 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2962 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0,
2963 &compVerStrInfo, requestMsg,
2964 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2965 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2966
2967 rc = encode_pass_component_table_req(
2968 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2969 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2970 compVerStrLen - 1, &compVerStrInfo, requestMsg,
2971 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2972 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2973
2974 rc = encode_pass_component_table_req(
2975 instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier,
2976 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2977 compVerStrLen, &compVerStrInfo, requestMsg,
2978 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2979 EXPECT_EQ(rc, PLDM_INVALID_TRANSFER_OPERATION_FLAG);
2980
2981 rc = encode_pass_component_table_req(
2982 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2983 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN,
2984 compVerStrLen, &compVerStrInfo, requestMsg,
2985 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2986 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2987 }
2988
TEST(PassComponentTable,goodPathDecodeResponse)2989 TEST(PassComponentTable, goodPathDecodeResponse)
2990 {
2991 constexpr std::array<uint8_t,
2992 hdrSize + sizeof(pldm_pass_component_table_resp)>
2993 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
2994 auto responseMsg1 =
2995 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
2996 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
2997
2998 uint8_t completionCode = 0;
2999 uint8_t compResp = 0;
3000 uint8_t compRespCode = 0;
3001
3002 auto rc = decode_pass_component_table_resp(
3003 responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode,
3004 &compResp, &compRespCode);
3005
3006 EXPECT_EQ(rc, PLDM_SUCCESS);
3007 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3008 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3009 EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL);
3010
3011 constexpr std::array<uint8_t,
3012 hdrSize + sizeof(pldm_pass_component_table_resp)>
3013 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0};
3014 auto responseMsg2 =
3015 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3016 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3017 rc = decode_pass_component_table_resp(
3018 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3019 &compResp, &compRespCode);
3020
3021 EXPECT_EQ(rc, PLDM_SUCCESS);
3022 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3023 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3024 EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN);
3025
3026 constexpr std::array<uint8_t,
3027 hdrSize + sizeof(pldm_pass_component_table_resp)>
3028 passCompTableResponse3{0x00, 0x00, 0x00, 0x80};
3029 auto responseMsg3 =
3030 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3031 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3032
3033 rc = decode_pass_component_table_resp(
3034 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3035 &compResp, &compRespCode);
3036
3037 EXPECT_EQ(rc, PLDM_SUCCESS);
3038 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3039 }
3040
TEST(PassComponentTable,errorPathDecodeResponse)3041 TEST(PassComponentTable, errorPathDecodeResponse)
3042 {
3043 constexpr std::array<uint8_t,
3044 hdrSize + sizeof(pldm_pass_component_table_resp) - 1>
3045 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00};
3046 auto responseMsg1 =
3047 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3048 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3049
3050 uint8_t completionCode = 0;
3051 uint8_t compResp = 0;
3052 uint8_t compRespCode = 0;
3053
3054 auto rc = decode_pass_component_table_resp(
3055 nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode,
3056 &compResp, &compRespCode);
3057 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3058
3059 rc = decode_pass_component_table_resp(
3060 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr,
3061 &compResp, &compRespCode);
3062 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3063
3064 rc = decode_pass_component_table_resp(
3065 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3066 &completionCode, nullptr, &compRespCode);
3067 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3068
3069 rc = decode_pass_component_table_resp(
3070 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3071 &completionCode, &compResp, nullptr);
3072 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3073
3074 rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode,
3075 &compResp, &compRespCode);
3076 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3077
3078 rc = decode_pass_component_table_resp(
3079 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3080 &completionCode, &compResp, &compRespCode);
3081 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3082
3083 constexpr std::array<uint8_t,
3084 hdrSize + sizeof(pldm_pass_component_table_resp)>
3085 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
3086 auto responseMsg2 =
3087 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3088 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3089 rc = decode_pass_component_table_resp(
3090 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3091 &compResp, &compRespCode);
3092 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3093
3094 constexpr std::array<uint8_t,
3095 hdrSize + sizeof(pldm_pass_component_table_resp)>
3096 passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};
3097 auto responseMsg3 =
3098 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3099 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3100 rc = decode_pass_component_table_resp(
3101 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3102 &compResp, &compRespCode);
3103 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3104
3105 constexpr std::array<uint8_t,
3106 hdrSize + sizeof(pldm_pass_component_table_resp)>
3107 passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
3108 auto responseMsg4 =
3109 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3110 reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data());
3111 rc = decode_pass_component_table_resp(
3112 responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode,
3113 &compResp, &compRespCode);
3114 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3115 }
3116
TEST(UpdateComponent,goodPathEncodeRequest)3117 TEST(UpdateComponent, goodPathEncodeRequest)
3118 {
3119 constexpr uint8_t instanceId = 2;
3120 constexpr uint16_t compIdentifier = 500;
3121 constexpr uint8_t compClassificationIndex = 50;
3122 constexpr uint32_t compComparisonStamp = 0x89abcdef;
3123 constexpr uint32_t compImageSize = 4096;
3124 constexpr bitfield32_t updateOptionFlags{1};
3125 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3126 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3127 variable_field compVerStrInfo{};
3128 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3129 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3130 compVerStrInfo.length = compVerStrLen;
3131
3132 std::array<uint8_t,
3133 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3134 request{};
3135 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3136 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3137
3138 auto rc = encode_update_component_req(
3139 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3140 compComparisonStamp, compImageSize, updateOptionFlags,
3141 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3142 sizeof(pldm_update_component_req) + compVerStrLen);
3143 EXPECT_EQ(rc, PLDM_SUCCESS);
3144
3145 std::array<uint8_t,
3146 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3147 outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
3148 0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
3149 0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
3150 0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
3151 EXPECT_EQ(request, outRequest);
3152
3153 #ifdef LIBPLDM_API_TESTING
3154 /* Check the roundtrip */
3155 struct pldm_update_component_req_full req;
3156 PLDM_MSG_DEFINE_P(dec, outRequest.size());
3157 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3158 rc = decode_update_component_req(dec, outRequest.size() - hdrSize, &req);
3159 ASSERT_EQ(rc, 0);
3160
3161 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3162 EXPECT_EQ(req.comp_identifier, compIdentifier);
3163 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3164 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3165 EXPECT_EQ(req.comp_image_size, compImageSize);
3166 EXPECT_EQ(req.update_option_flags.value, updateOptionFlags.value);
3167 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3168 EXPECT_EQ(req.version.str_len, compVerStrLen);
3169 EXPECT_TRUE(std::equal(req.version.str_data,
3170 req.version.str_data + req.version.str_len,
3171 compVerStr.data()));
3172 #endif
3173 }
3174
TEST(UpdateComponent,errorPathEncodeRequest)3175 TEST(UpdateComponent, errorPathEncodeRequest)
3176 {
3177 constexpr uint8_t instanceId = 2;
3178 constexpr uint16_t compIdentifier = 500;
3179 constexpr uint8_t compClassificationIndex = 50;
3180 constexpr uint32_t compComparisonStamp = 0x89abcdef;
3181 constexpr uint32_t compImageSize = 4096;
3182 constexpr bitfield32_t updateOptionFlags{1};
3183 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3184 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3185 variable_field compVerStrInfo{};
3186 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3187 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3188 compVerStrInfo.length = compVerStrLen;
3189
3190 std::array<uint8_t,
3191 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3192 request{};
3193 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3194 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3195
3196 auto rc = encode_update_component_req(
3197 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3198 compComparisonStamp, compImageSize, updateOptionFlags,
3199 PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
3200 sizeof(pldm_update_component_req) + compVerStrLen);
3201 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3202
3203 compVerStrInfo.ptr = nullptr;
3204 rc = encode_update_component_req(
3205 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3206 compComparisonStamp, compImageSize, updateOptionFlags,
3207 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3208 sizeof(pldm_update_component_req) + compVerStrLen);
3209 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3210 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3211 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3212
3213 rc = encode_update_component_req(
3214 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3215 compComparisonStamp, compImageSize, updateOptionFlags,
3216 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
3217 sizeof(pldm_update_component_req) + compVerStrLen);
3218 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3219
3220 rc = encode_update_component_req(
3221 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3222 compComparisonStamp, compImageSize, updateOptionFlags,
3223 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3224 sizeof(pldm_update_component_req));
3225 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3226
3227 rc = encode_update_component_req(
3228 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3229 compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
3230 compVerStrLen, &compVerStrInfo, requestMsg,
3231 sizeof(pldm_update_component_req) + compVerStrLen);
3232 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3233
3234 rc = encode_update_component_req(
3235 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3236 compComparisonStamp, compImageSize, updateOptionFlags,
3237 PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg,
3238 sizeof(pldm_update_component_req) + compVerStrLen);
3239 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3240
3241 rc = encode_update_component_req(
3242 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3243 compComparisonStamp, compImageSize, updateOptionFlags,
3244 PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg,
3245 sizeof(pldm_update_component_req) + compVerStrLen);
3246 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3247
3248 rc = encode_update_component_req(
3249 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3250 compComparisonStamp, compImageSize, updateOptionFlags,
3251 PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
3252 sizeof(pldm_update_component_req) + compVerStrLen);
3253 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3254 }
3255
TEST(UpdateComponent,goodPathDecodeResponse)3256 TEST(UpdateComponent, goodPathDecodeResponse)
3257 {
3258 constexpr std::bitset<32> forceUpdateComp{1};
3259 constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
3260 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3261 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3262 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3263 auto responseMsg1 =
3264 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3265 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3266
3267 uint8_t completionCode = 0;
3268 uint8_t compCompatibilityResp = 0;
3269 uint8_t compCompatibilityRespCode = 0;
3270 bitfield32_t updateOptionFlagsEnabled{};
3271 uint16_t timeBeforeReqFWData = 0;
3272
3273 auto rc = decode_update_component_resp(
3274 responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
3275 &compCompatibilityResp, &compCompatibilityRespCode,
3276 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3277
3278 EXPECT_EQ(rc, PLDM_SUCCESS);
3279 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3280 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
3281 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
3282 EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
3283 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
3284
3285 constexpr std::bitset<32> noFlags{};
3286 constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
3287 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3288 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3290 auto responseMsg2 =
3291 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3292 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3293 rc = decode_update_component_resp(
3294 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3295 &compCompatibilityResp, &compCompatibilityRespCode,
3296 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3297
3298 EXPECT_EQ(rc, PLDM_SUCCESS);
3299 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3300 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
3301 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
3302 EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
3303 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
3304
3305 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3306 updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
3307 auto responseMsg3 =
3308 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3309 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3310
3311 rc = decode_update_component_resp(
3312 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3313 &compCompatibilityResp, &compCompatibilityRespCode,
3314 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3315
3316 EXPECT_EQ(rc, PLDM_SUCCESS);
3317 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3318 }
3319
TEST(UpdateComponent,errorPathDecodeResponse)3320 TEST(UpdateComponent, errorPathDecodeResponse)
3321 {
3322 constexpr std::array<uint8_t,
3323 hdrSize + sizeof(pldm_update_component_resp) - 1>
3324 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3325 0x00, 0x00, 0x00, 0x00, 0x00};
3326 auto responseMsg1 =
3327 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3328 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3329
3330 uint8_t completionCode = 0;
3331 uint8_t compCompatibilityResp = 0;
3332 uint8_t compCompatibilityRespCode = 0;
3333 bitfield32_t updateOptionFlagsEnabled{};
3334 uint16_t timeBeforeReqFWData = 0;
3335
3336 auto rc = decode_update_component_resp(
3337 nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
3338 &compCompatibilityResp, &compCompatibilityRespCode,
3339 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3340 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3341
3342 rc = decode_update_component_resp(
3343 responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
3344 &compCompatibilityResp, &compCompatibilityRespCode,
3345 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3346 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3347
3348 rc = decode_update_component_resp(
3349 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3350 nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3351 &timeBeforeReqFWData);
3352 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3353
3354 rc = decode_update_component_resp(
3355 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3356 &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
3357 &timeBeforeReqFWData);
3358 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3359
3360 rc = decode_update_component_resp(
3361 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3362 &compCompatibilityResp, &compCompatibilityRespCode, nullptr,
3363 &timeBeforeReqFWData);
3364 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3365
3366 rc = decode_update_component_resp(
3367 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3368 &compCompatibilityResp, &compCompatibilityRespCode,
3369 &updateOptionFlagsEnabled, nullptr);
3370 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3371
3372 rc = decode_update_component_resp(
3373 responseMsg1, 0, &completionCode, &compCompatibilityResp,
3374 &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3375 &timeBeforeReqFWData);
3376 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3377
3378 rc = decode_update_component_resp(
3379 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3380 &compCompatibilityResp, &compCompatibilityRespCode,
3381 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3382 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3383
3384 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3385 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
3386 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3387 auto responseMsg2 =
3388 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3389 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3390 rc = decode_update_component_resp(
3391 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3392 &compCompatibilityResp, &compCompatibilityRespCode,
3393 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3394 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3395
3396 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3397 updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
3398 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3399 auto responseMsg3 =
3400 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3401 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3402 rc = decode_update_component_resp(
3403 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3404 &compCompatibilityResp, &compCompatibilityRespCode,
3405 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3406 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3407
3408 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3409 updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
3410 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3411 auto responseMsg4 =
3412 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3413 reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
3414 rc = decode_update_component_resp(
3415 responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
3416 &compCompatibilityResp, &compCompatibilityRespCode,
3417 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3418 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3419 }
3420
TEST(RequestFirmwareData,goodPathDecodeRequest)3421 TEST(RequestFirmwareData, goodPathDecodeRequest)
3422 {
3423 constexpr uint32_t offset = 300;
3424 constexpr uint32_t length = 255;
3425 constexpr std::array<uint8_t,
3426 hdrSize + sizeof(pldm_request_firmware_data_req)>
3427 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3428 0x00, 0xff, 0x00, 0x00, 0x00};
3429 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3430 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3431
3432 uint32_t outOffset = 0;
3433 uint32_t outLength = 0;
3434 auto rc = decode_request_firmware_data_req(
3435 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3436 &outLength);
3437
3438 EXPECT_EQ(rc, PLDM_SUCCESS);
3439 EXPECT_EQ(outOffset, offset);
3440 EXPECT_EQ(outLength, length);
3441 }
3442
TEST(RequestFirmwareData,errorPathDecodeRequest)3443 TEST(RequestFirmwareData, errorPathDecodeRequest)
3444 {
3445 constexpr std::array<uint8_t,
3446 hdrSize + sizeof(pldm_request_firmware_data_req)>
3447 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3448 0x00, 0x1f, 0x00, 0x00, 0x00};
3449 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3450 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3451
3452 uint32_t outOffset = 0;
3453 uint32_t outLength = 0;
3454 auto rc = decode_request_firmware_data_req(
3455 nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
3456 &outLength);
3457 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3458
3459 rc = decode_request_firmware_data_req(
3460 requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
3461 &outLength);
3462 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3463
3464 rc = decode_request_firmware_data_req(
3465 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3466 nullptr);
3467 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3468
3469 rc = decode_request_firmware_data_req(
3470 requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
3471 &outLength);
3472 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3473
3474 rc = decode_request_firmware_data_req(
3475 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3476 &outLength);
3477 EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
3478 }
3479
TEST(RequestFirmwareData,goodPathEncodeResponse)3480 TEST(RequestFirmwareData, goodPathEncodeResponse)
3481 {
3482 constexpr uint8_t instanceId = 3;
3483 constexpr uint8_t completionCode = PLDM_SUCCESS;
3484 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
3485 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3486 outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
3487 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3488 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3489 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3490 0x1d, 0x1e, 0x1f, 0x20};
3491 std::array<uint8_t, hdrSize + sizeof(completionCode) +
3492 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3493 reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
3494 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3495 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3496 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3497 0x1d, 0x1e, 0x1f, 0x20};
3498 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3499 auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
3500 auto rc = encode_request_firmware_data_resp(
3501 instanceId, completionCode, responseMsg1,
3502 sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
3503 EXPECT_EQ(rc, PLDM_SUCCESS);
3504 EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
3505
3506 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3507 outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
3508 std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
3509 0x00, 0x00, 0x00, 0x00};
3510 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3511 auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
3512 rc = encode_request_firmware_data_resp(
3513 instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
3514 sizeof(completionCode));
3515 EXPECT_EQ(rc, PLDM_SUCCESS);
3516 EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
3517 }
3518
TEST(RequestFirmwareData,errorPathEncodeResponse)3519 TEST(RequestFirmwareData, errorPathEncodeResponse)
3520 {
3521 std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
3522 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3523 auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
3524 auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
3525 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3526
3527 rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
3528 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3529 }
3530
TEST(TransferComplete,goodPathDecodeRequest)3531 TEST(TransferComplete, goodPathDecodeRequest)
3532 {
3533 constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
3534 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3535 transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
3536 auto requestMsg1 =
3537 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3538 reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
3539 uint8_t outTransferResult = 0;
3540
3541 auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
3542 &outTransferResult);
3543 EXPECT_EQ(rc, PLDM_SUCCESS);
3544 EXPECT_EQ(outTransferResult, transferResult);
3545
3546 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3547 transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
3548 auto requestMsg2 =
3549 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3550 reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
3551 rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
3552 &outTransferResult);
3553 EXPECT_EQ(rc, PLDM_SUCCESS);
3554 EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
3555 }
3556
TEST(TransferComplete,errorPathDecodeRequest)3557 TEST(TransferComplete, errorPathDecodeRequest)
3558 {
3559 constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
3560 0x00};
3561 auto requestMsg =
3562 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3563 reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
3564 uint8_t outTransferResult = 0;
3565
3566 auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
3567 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3568
3569 rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
3570 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3571
3572 rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
3573 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3574 }
3575
TEST(TransferComplete,goodPathEncodeResponse)3576 TEST(TransferComplete, goodPathEncodeResponse)
3577 {
3578 constexpr uint8_t instanceId = 4;
3579 constexpr uint8_t completionCode = PLDM_SUCCESS;
3580 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3581 outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
3582 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3583 transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3584 auto responseMsg1 =
3585 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3586 reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
3587 auto rc = encode_transfer_complete_resp(
3588 instanceId, completionCode, responseMsg1, sizeof(completionCode));
3589 EXPECT_EQ(rc, PLDM_SUCCESS);
3590 EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
3591
3592 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3593 outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
3594 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3595 transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3596 auto responseMsg2 =
3597 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3598 reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
3599 rc = encode_transfer_complete_resp(instanceId,
3600 PLDM_FWUP_COMMAND_NOT_EXPECTED,
3601 responseMsg2, sizeof(completionCode));
3602 EXPECT_EQ(rc, PLDM_SUCCESS);
3603 EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
3604 }
3605
TEST(TransferComplete,errorPathEncodeResponse)3606 TEST(TransferComplete, errorPathEncodeResponse)
3607 {
3608 std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
3609 auto responseMsg =
3610 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3611 reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
3612 auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3613 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3614
3615 rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3616 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3617 }
3618
TEST(VerifyComplete,goodPathDecodeRequest)3619 TEST(VerifyComplete, goodPathDecodeRequest)
3620 {
3621 constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
3622 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3623 verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
3624 auto requestMsg1 =
3625 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3626 reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
3627 uint8_t outVerifyResult = 0;
3628
3629 auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
3630 &outVerifyResult);
3631 EXPECT_EQ(rc, PLDM_SUCCESS);
3632 EXPECT_EQ(outVerifyResult, verifyResult);
3633
3634 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3635 verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
3636 auto requestMsg2 =
3637 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3638 reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
3639 rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
3640 &outVerifyResult);
3641 EXPECT_EQ(rc, PLDM_SUCCESS);
3642 EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
3643 }
3644
TEST(VerifyComplete,errorPathDecodeRequest)3645 TEST(VerifyComplete, errorPathDecodeRequest)
3646 {
3647 constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
3648 auto requestMsg =
3649 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3650 reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
3651 uint8_t outVerifyResult = 0;
3652
3653 auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
3654 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3655
3656 rc = decode_verify_complete_req(requestMsg, 0, nullptr);
3657 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3658
3659 rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);
3660 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3661 }
3662
TEST(VerifyComplete,goodPathEncodeResponse)3663 TEST(VerifyComplete, goodPathEncodeResponse)
3664 {
3665 constexpr uint8_t instanceId = 5;
3666 constexpr uint8_t completionCode = PLDM_SUCCESS;
3667 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3668 outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};
3669 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3670 verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3671 auto responseMsg1 =
3672 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3673 reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());
3674 auto rc = encode_verify_complete_resp(instanceId, completionCode,
3675 responseMsg1, sizeof(completionCode));
3676 EXPECT_EQ(rc, PLDM_SUCCESS);
3677 EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);
3678
3679 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3680 outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88};
3681 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3682 verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3683 auto responseMsg2 =
3684 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3685 reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());
3686 rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3687 responseMsg2, sizeof(completionCode));
3688 EXPECT_EQ(rc, PLDM_SUCCESS);
3689 EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);
3690 }
3691
TEST(VerifyComplete,errorPathEncodeResponse)3692 TEST(VerifyComplete, errorPathEncodeResponse)
3693 {
3694 std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00};
3695 auto responseMsg =
3696 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3697 reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());
3698 auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3699 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3700
3701 rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3702 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3703 }
3704
TEST(ApplyComplete,goodPathDecodeRequest)3705 TEST(ApplyComplete, goodPathDecodeRequest)
3706 {
3707 constexpr uint8_t applyResult1 =
3708 PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
3709 // DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
3710 constexpr std::bitset<16> compActivationModification1{0x30};
3711 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3712 applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
3713 auto requestMsg1 =
3714 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3715 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3716 uint8_t outApplyResult = 0;
3717 bitfield16_t outCompActivationModification{};
3718 auto rc = decode_apply_complete_req(
3719 requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
3720 &outCompActivationModification);
3721 EXPECT_EQ(rc, PLDM_SUCCESS);
3722 EXPECT_EQ(outApplyResult, applyResult1);
3723 EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
3724
3725 constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
3726 constexpr std::bitset<16> compActivationModification2{};
3727 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3728 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3729 auto requestMsg2 =
3730 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3731 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3732 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3733 &outApplyResult,
3734 &outCompActivationModification);
3735 EXPECT_EQ(rc, PLDM_SUCCESS);
3736 EXPECT_EQ(outApplyResult, applyResult2);
3737 EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
3738 }
3739
TEST(ApplyComplete,errorPathDecodeRequest)3740 TEST(ApplyComplete, errorPathDecodeRequest)
3741 {
3742 constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
3743 auto requestMsg1 =
3744 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3745 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3746 uint8_t outApplyResult = 0;
3747 bitfield16_t outCompActivationModification{};
3748
3749 auto rc = decode_apply_complete_req(
3750 nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
3751 &outCompActivationModification);
3752 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3753
3754 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3755 nullptr, &outCompActivationModification);
3756 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3757
3758 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3759 &outApplyResult, nullptr);
3760 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3761
3762 rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
3763 &outCompActivationModification);
3764 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3765
3766 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3767 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
3768 auto requestMsg2 =
3769 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3770 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3771 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3772 &outApplyResult,
3773 &outCompActivationModification);
3774 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3775 }
3776
TEST(ApplyComplete,goodPathEncodeResponse)3777 TEST(ApplyComplete, goodPathEncodeResponse)
3778 {
3779 constexpr uint8_t instanceId = 6;
3780 constexpr uint8_t completionCode = PLDM_SUCCESS;
3781 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3782 outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
3783 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3784 applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3785 auto responseMsg1 =
3786 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3787 reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
3788 auto rc = encode_apply_complete_resp(instanceId, completionCode,
3789 responseMsg1, sizeof(completionCode));
3790 EXPECT_EQ(rc, PLDM_SUCCESS);
3791 EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
3792
3793 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3794 outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
3795 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3796 applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3797 auto responseMsg2 =
3798 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3799 reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
3800 rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3801 responseMsg2, sizeof(completionCode));
3802 EXPECT_EQ(rc, PLDM_SUCCESS);
3803 EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
3804 }
3805
TEST(ApplyComplete,errorPathEncodeResponse)3806 TEST(ApplyComplete, errorPathEncodeResponse)
3807 {
3808 std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
3809 auto responseMsg =
3810 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3811 reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
3812 auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3813 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3814
3815 rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3816 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3817 }
3818
TEST(ActivateFirmware,goodPathEncodeRequest)3819 TEST(ActivateFirmware, goodPathEncodeRequest)
3820 {
3821 constexpr uint8_t instanceId = 7;
3822
3823 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
3824 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3825 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3826
3827 auto rc = encode_activate_firmware_req(
3828 instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
3829 sizeof(pldm_activate_firmware_req));
3830 EXPECT_EQ(rc, PLDM_SUCCESS);
3831
3832 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
3833 outRequest{0x87, 0x05, 0x1a, 0x01};
3834 EXPECT_EQ(request, outRequest);
3835 }
3836
TEST(ActivateFirmware,errorPathEncodeRequest)3837 TEST(ActivateFirmware, errorPathEncodeRequest)
3838 {
3839 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
3840 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3841 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3842
3843 auto rc = encode_activate_firmware_req(
3844 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
3845 sizeof(pldm_activate_firmware_req));
3846 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3847
3848 rc = encode_activate_firmware_req(
3849 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
3850 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3851
3852 rc = encode_activate_firmware_req(0, 2, requestMsg,
3853 sizeof(pldm_activate_firmware_req));
3854 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3855 }
3856
TEST(ActivateFirmware,goodPathDecodeResponse)3857 TEST(ActivateFirmware, goodPathDecodeResponse)
3858 {
3859 constexpr uint16_t estimatedTimeForActivation100s = 100;
3860 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3861 activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
3862 auto responseMsg1 =
3863 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3864 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
3865
3866 uint8_t completionCode = 0;
3867 uint16_t estimatedTimeForActivation = 0;
3868
3869 auto rc = decode_activate_firmware_resp(
3870 responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
3871 &estimatedTimeForActivation);
3872
3873 EXPECT_EQ(rc, PLDM_SUCCESS);
3874 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3875 EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
3876
3877 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3878 activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
3879 auto responseMsg2 =
3880 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3881 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data());
3882
3883 rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
3884 &completionCode,
3885 &estimatedTimeForActivation);
3886
3887 EXPECT_EQ(rc, PLDM_SUCCESS);
3888 EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
3889 }
3890
TEST(ActivateFirmware,errorPathDecodeResponse)3891 TEST(ActivateFirmware, errorPathDecodeResponse)
3892 {
3893 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3894 activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3895 auto responseMsg =
3896 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3897 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
3898
3899 uint8_t completionCode = 0;
3900 uint16_t estimatedTimeForActivation = 0;
3901
3902 auto rc = decode_activate_firmware_resp(
3903 nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
3904 &estimatedTimeForActivation);
3905 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3906
3907 rc = decode_activate_firmware_resp(responseMsg,
3908 sizeof(pldm_activate_firmware_resp),
3909 nullptr, &estimatedTimeForActivation);
3910 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3911
3912 rc = decode_activate_firmware_resp(responseMsg,
3913 sizeof(pldm_activate_firmware_resp),
3914 &completionCode, nullptr);
3915 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3916
3917 rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
3918 &estimatedTimeForActivation);
3919 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3920
3921 rc = decode_activate_firmware_resp(
3922 responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
3923 &estimatedTimeForActivation);
3924 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3925 }
3926
TEST(GetStatus,goodPathEncodeRequest)3927 TEST(GetStatus, goodPathEncodeRequest)
3928 {
3929 constexpr uint8_t instanceId = 8;
3930 std::array<uint8_t, hdrSize> request{};
3931 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3932 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3933
3934 auto rc = encode_get_status_req(instanceId, requestMsg,
3935 PLDM_GET_STATUS_REQ_BYTES);
3936 EXPECT_EQ(rc, PLDM_SUCCESS);
3937
3938 constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
3939 EXPECT_EQ(request, outRequest);
3940 }
3941
TEST(GetStatus,errorPathEncodeRequest)3942 TEST(GetStatus, errorPathEncodeRequest)
3943 {
3944 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
3945 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3946 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3947
3948 auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
3949 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3950
3951 rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);
3952 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3953 }
3954
TEST(GetStatus,goodPathDecodeResponse)3955 TEST(GetStatus, goodPathDecodeResponse)
3956 {
3957 constexpr std::bitset<32> updateOptionFlagsEnabled1{0};
3958 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3959 getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
3960 0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};
3961 auto responseMsg1 =
3962 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3963 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
3964
3965 uint8_t completionCode = 0;
3966 uint8_t currentState = 0;
3967 uint8_t previousState = 0;
3968 uint8_t auxState = 0;
3969 uint8_t auxStateStatus = 0;
3970 uint8_t progressPercent = 0;
3971 uint8_t reasonCode = 0;
3972 bitfield32_t updateOptionFlagsEnabled{0};
3973
3974 auto rc = decode_get_status_resp(
3975 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3976 ¤tState, &previousState, &auxState, &auxStateStatus,
3977 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3978
3979 EXPECT_EQ(rc, PLDM_SUCCESS);
3980 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3981 EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);
3982 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
3983 EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);
3984 EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);
3985 EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);
3986 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
3987 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);
3988
3989 // Bit position 0 - Force update of component – FD will perform a force
3990 // update of the component.
3991 constexpr std::bitset<32> updateOptionFlagsEnabled2{1};
3992 constexpr uint8_t progressPercent2 = 50;
3993 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3994 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,
3995 0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};
3996 auto responseMsg2 =
3997 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
3998 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
3999
4000 rc = decode_get_status_resp(
4001 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4002 ¤tState, &previousState, &auxState, &auxStateStatus,
4003 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4004
4005 EXPECT_EQ(rc, PLDM_SUCCESS);
4006 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4007 EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);
4008 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4009 EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);
4010 EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);
4011 EXPECT_EQ(progressPercent, progressPercent2);
4012 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4013 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);
4014
4015 #ifdef LIBPLDM_API_TESTING
4016 /* Check the roundtrip */
4017 PLDM_MSG_DEFINE_P(enc, 1000);
4018 size_t enc_payload_len = 1000;
4019 const struct pldm_get_status_resp status_enc = {
4020 .completion_code = PLDM_SUCCESS,
4021 .current_state = currentState,
4022 .previous_state = previousState,
4023 .aux_state = auxState,
4024 .aux_state_status = auxStateStatus,
4025 .progress_percent = progressPercent,
4026 .reason_code = reasonCode,
4027 .update_option_flags_enabled = updateOptionFlagsEnabled,
4028 };
4029 rc = encode_get_status_resp(FIXED_INSTANCE_ID, &status_enc, enc,
4030 &enc_payload_len);
4031 EXPECT_EQ(rc, PLDM_SUCCESS);
4032 EXPECT_EQ(enc_payload_len + hdrSize, getStatusResponse2.size());
4033 EXPECT_TRUE(std::equal(getStatusResponse2.begin() + hdrSize,
4034 getStatusResponse2.end(), enc_buf + hdrSize));
4035 check_response(enc, PLDM_GET_STATUS);
4036 #endif
4037
4038 /* Check a not-ready completion code */
4039 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4040 getStatusResponse3{0x00, 0x00, 0x00, 0x04};
4041 auto responseMsg3 =
4042 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4043 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4044 rc = decode_get_status_resp(
4045 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4046 ¤tState, &previousState, &auxState, &auxStateStatus,
4047 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4048 EXPECT_EQ(rc, PLDM_SUCCESS);
4049 EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);
4050 }
4051
TEST(GetStatus,errorPathDecodeResponse)4052 TEST(GetStatus, errorPathDecodeResponse)
4053 {
4054 uint8_t completionCode = 0;
4055 uint8_t currentState = 0;
4056 uint8_t previousState = 0;
4057 uint8_t auxState = 0;
4058 uint8_t auxStateStatus = 0;
4059 uint8_t progressPercent = 0;
4060 uint8_t reasonCode = 0;
4061 bitfield32_t updateOptionFlagsEnabled{0};
4062
4063 constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};
4064 auto responseMsg1 =
4065 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4066 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4067
4068 auto rc = decode_get_status_resp(
4069 nullptr, getStatusResponse1.size() - hdrSize, &completionCode,
4070 ¤tState, &previousState, &auxState, &auxStateStatus,
4071 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4072 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4073
4074 rc = decode_get_status_resp(
4075 responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,
4076 ¤tState, &previousState, &auxState, &auxStateStatus,
4077 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4078 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4079
4080 rc = decode_get_status_resp(
4081 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4082 nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,
4083 &reasonCode, &updateOptionFlagsEnabled);
4084 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4085
4086 rc = decode_get_status_resp(
4087 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4088 ¤tState, nullptr, &auxState, &auxStateStatus, &progressPercent,
4089 &reasonCode, &updateOptionFlagsEnabled);
4090 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4091
4092 rc = decode_get_status_resp(
4093 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4094 ¤tState, &previousState, nullptr, &auxStateStatus,
4095 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4096 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4097
4098 rc = decode_get_status_resp(
4099 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4100 ¤tState, &previousState, &auxState, nullptr, &progressPercent,
4101 &reasonCode, &updateOptionFlagsEnabled);
4102 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4103
4104 rc = decode_get_status_resp(
4105 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4106 ¤tState, &previousState, &auxState, &auxStateStatus, nullptr,
4107 &reasonCode, &updateOptionFlagsEnabled);
4108 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4109
4110 rc = decode_get_status_resp(
4111 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4112 ¤tState, &previousState, &auxState, &auxStateStatus,
4113 &progressPercent, nullptr, &updateOptionFlagsEnabled);
4114 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4115
4116 rc = decode_get_status_resp(
4117 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4118 ¤tState, &previousState, &auxState, &auxStateStatus,
4119 &progressPercent, &reasonCode, nullptr);
4120 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4121
4122 rc = decode_get_status_resp(
4123 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4124 ¤tState, &previousState, &auxState, &auxStateStatus,
4125 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4126 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4127
4128 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>
4129 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4131 auto responseMsg2 =
4132 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4133 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4134 rc = decode_get_status_resp(
4135 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4136 ¤tState, &previousState, &auxState, &auxStateStatus,
4137 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4138 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4139
4140 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4141 getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
4142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4143 auto responseMsg3 =
4144 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4145 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4146 rc = decode_get_status_resp(
4147 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4148 ¤tState, &previousState, &auxState, &auxStateStatus,
4149 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4150 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4151
4152 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4153 getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
4154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4155 auto responseMsg4 =
4156 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4157 reinterpret_cast<const pldm_msg*>(getStatusResponse4.data());
4158 rc = decode_get_status_resp(
4159 responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,
4160 ¤tState, &previousState, &auxState, &auxStateStatus,
4161 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4162 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4163
4164 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4165 getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
4166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4167 auto responseMsg5 =
4168 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4169 reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());
4170 rc = decode_get_status_resp(
4171 responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,
4172 ¤tState, &previousState, &auxState, &auxStateStatus,
4173 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4174 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4175
4176 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4177 getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4178 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4179 auto responseMsg6 =
4180 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4181 reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());
4182 rc = decode_get_status_resp(
4183 responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,
4184 ¤tState, &previousState, &auxState, &auxStateStatus,
4185 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4186 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4187
4188 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4189 getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4190 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
4191 auto responseMsg7 =
4192 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4193 reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());
4194 rc = decode_get_status_resp(
4195 responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,
4196 ¤tState, &previousState, &auxState, &auxStateStatus,
4197 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4198 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4199
4200 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4201 getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4202 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00};
4203 auto responseMsg8 =
4204 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4205 reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());
4206 rc = decode_get_status_resp(
4207 responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,
4208 ¤tState, &previousState, &auxState, &auxStateStatus,
4209 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4210 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4211
4212 // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is
4213 // IDLE
4214 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4215 getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
4216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4217 auto responseMsg9 =
4218 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4219 reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());
4220 rc = decode_get_status_resp(
4221 responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,
4222 ¤tState, &previousState, &auxState, &auxStateStatus,
4223 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4224 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4225 }
4226
TEST(CancelUpdateComponent,goodPathEncodeRequest)4227 TEST(CancelUpdateComponent, goodPathEncodeRequest)
4228 {
4229 constexpr uint8_t instanceId = 9;
4230 std::array<uint8_t, hdrSize> request{};
4231 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4232 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4233
4234 auto rc = encode_cancel_update_component_req(
4235 instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4236 EXPECT_EQ(rc, PLDM_SUCCESS);
4237
4238 constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
4239 EXPECT_EQ(request, outRequest);
4240 }
4241
TEST(CancelUpdateComponent,errorPathEncodeRequest)4242 TEST(CancelUpdateComponent, errorPathEncodeRequest)
4243 {
4244 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
4245 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4246 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4247
4248 auto rc = encode_cancel_update_component_req(
4249 0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4250 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4251
4252 rc = encode_cancel_update_component_req(
4253 0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);
4254 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4255 }
4256
TEST(CancelUpdateComponent,testGoodDecodeResponse)4257 TEST(CancelUpdateComponent, testGoodDecodeResponse)
4258 {
4259 uint8_t completionCode = 0;
4260 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4261 cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};
4262 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4263 auto responseMsg1 = reinterpret_cast<const pldm_msg*>(
4264 cancelUpdateComponentResponse1.data());
4265 auto rc = decode_cancel_update_component_resp(
4266 responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,
4267 &completionCode);
4268 EXPECT_EQ(rc, PLDM_SUCCESS);
4269 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4270
4271 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4272 cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};
4273 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4274 auto responseMsg2 = reinterpret_cast<const pldm_msg*>(
4275 cancelUpdateComponentResponse2.data());
4276 rc = decode_cancel_update_component_resp(
4277 responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,
4278 &completionCode);
4279 EXPECT_EQ(rc, PLDM_SUCCESS);
4280 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4281 }
4282
TEST(CancelUpdateComponent,testBadDecodeResponse)4283 TEST(CancelUpdateComponent, testBadDecodeResponse)
4284 {
4285 uint8_t completionCode = 0;
4286 constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{
4287 0x00, 0x00, 0x00};
4288 auto responseMsg =
4289 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4290 reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data());
4291
4292 auto rc = decode_cancel_update_component_resp(
4293 nullptr, cancelUpdateComponentResponse.size() - hdrSize,
4294 &completionCode);
4295 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4296
4297 rc = decode_cancel_update_component_resp(
4298 responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);
4299 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4300
4301 rc = decode_cancel_update_component_resp(
4302 responseMsg, cancelUpdateComponentResponse.size() - hdrSize,
4303 &completionCode);
4304 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4305 }
4306
TEST(CancelUpdate,goodPathEncodeRequest)4307 TEST(CancelUpdate, goodPathEncodeRequest)
4308 {
4309 constexpr uint8_t instanceId = 10;
4310 std::array<uint8_t, hdrSize> request{};
4311 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4312 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4313
4314 auto rc = encode_cancel_update_req(instanceId, requestMsg,
4315 PLDM_CANCEL_UPDATE_REQ_BYTES);
4316 EXPECT_EQ(rc, PLDM_SUCCESS);
4317
4318 constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
4319 EXPECT_EQ(request, outRequest);
4320 }
4321
TEST(CancelUpdate,errorPathEncodeRequest)4322 TEST(CancelUpdate, errorPathEncodeRequest)
4323 {
4324 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
4325 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4326 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4327
4328 auto rc =
4329 encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
4330 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4331
4332 rc = encode_cancel_update_req(0, requestMsg,
4333 PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
4334 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4335 }
4336
TEST(CancelUpdate,goodPathDecodeResponse)4337 TEST(CancelUpdate, goodPathDecodeResponse)
4338 {
4339 constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
4340 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4341 cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4343 auto responseMsg1 =
4344 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4345 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4346 uint8_t completionCode = 0;
4347 bool8_t nonFunctioningComponentIndication = 0;
4348 bitfield64_t nonFunctioningComponentBitmap{0};
4349 auto rc = decode_cancel_update_resp(
4350 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4351 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4352 EXPECT_EQ(rc, PLDM_SUCCESS);
4353 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4354 EXPECT_EQ(nonFunctioningComponentIndication,
4355 PLDM_FWUP_COMPONENTS_FUNCTIONING);
4356 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4357 nonFunctioningComponentBitmap1);
4358
4359 constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
4360 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4361 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
4362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4363 auto responseMsg2 =
4364 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4365 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4366 rc = decode_cancel_update_resp(
4367 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4368 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4369 EXPECT_EQ(rc, PLDM_SUCCESS);
4370 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4371 EXPECT_EQ(nonFunctioningComponentIndication,
4372 PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING);
4373 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4374 nonFunctioningComponentBitmap2);
4375
4376 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4377 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
4378 auto responseMsg3 =
4379 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4380 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4381 rc = decode_cancel_update_resp(
4382 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4383 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4384 EXPECT_EQ(rc, PLDM_SUCCESS);
4385 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4386 }
4387
TEST(CancelUpdate,errorPathDecodeResponse)4388 TEST(CancelUpdate, errorPathDecodeResponse)
4389 {
4390 constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
4391 0x00};
4392 auto responseMsg1 =
4393 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4394 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4395 uint8_t completionCode = 0;
4396 bool8_t nonFunctioningComponentIndication = 0;
4397 bitfield64_t nonFunctioningComponentBitmap{0};
4398
4399 auto rc = decode_cancel_update_resp(
4400 nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4401 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4402 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4403
4404 rc = decode_cancel_update_resp(
4405 responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
4406 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4407 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4408
4409 rc = decode_cancel_update_resp(
4410 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4411 nullptr, &nonFunctioningComponentBitmap);
4412 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4413
4414 rc = decode_cancel_update_resp(
4415 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4416 &nonFunctioningComponentIndication, nullptr);
4417 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4418
4419 rc = decode_cancel_update_resp(
4420 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4421 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4422 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4423
4424 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4425 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
4426 auto responseMsg2 =
4427 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4428 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4429 rc = decode_cancel_update_resp(
4430 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4431 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4432 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4433
4434 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4435 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
4436 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4437 auto responseMsg3 =
4438 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
4439 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4440 rc = decode_cancel_update_resp(
4441 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4442 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4443 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4444 }
4445