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