blob: ffb25ff3833583d759a2bd13d1aacd9865eefa47 [file] [log] [blame]
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05301#include <endian.h>
Andrew Jefferyb0c1d202023-11-07 22:08:44 +10302#include <libpldm/base.h>
3#include <libpldm/firmware_update.h>
4#include <libpldm/pldm_types.h>
5#include <libpldm/utils.h>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05306
7#include <algorithm>
8#include <array>
Andrew Jeffery9c766792022-08-10 23:12:49 +09309#include <bitset>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +053010#include <cstdint>
Andrew Jeffery9c766792022-08-10 23:12:49 +093011#include <cstring>
Matt Johnstond5d1f662024-11-27 13:30:20 +080012#include <span>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +053013#include <string>
14#include <string_view>
15#include <vector>
Andrew Jeffery9c766792022-08-10 23:12:49 +093016
Chris Wang4c1f2c72024-03-21 17:09:44 +080017#include "msgbuf.h"
18
Andrew Jefferydec237b2024-11-08 14:33:45 +103019#include <gmock/gmock.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +093020#include <gtest/gtest.h>
21
Andrew Jefferydec237b2024-11-08 14:33:45 +103022using testing::ElementsAreArray;
23
Andrew Jeffery9c766792022-08-10 23:12:49 +093024constexpr auto hdrSize = sizeof(pldm_msg_hdr);
25
26TEST(DecodePackageHeaderInfo, goodPath)
27{
28 // Package header identifier for Version 1.0.x
29 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
30 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -060031 0x98, 0x00, 0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02};
Andrew Jeffery9c766792022-08-10 23:12:49 +093032 // Package header version for DSP0267 version 1.0.x
33 constexpr uint8_t pkgHeaderFormatRevision = 0x01;
34 // Random PackageHeaderSize
35 constexpr uint16_t pkgHeaderSize = 303;
36 // PackageReleaseDateTime - "25/12/2021 00:00:00"
37 std::array<uint8_t, PLDM_TIMESTAMP104_SIZE> package_release_date_time{
38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00};
40 constexpr uint16_t componentBitmapBitLength = 8;
41 // PackageVersionString
42 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
43 constexpr size_t packagerHeaderSize =
44 sizeof(pldm_package_header_information) + packageVersionStr.size();
45
46 constexpr std::array<uint8_t, packagerHeaderSize> packagerHeaderInfo{
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -060047 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
Andrew Jeffery9c766792022-08-10 23:12:49 +093048 0x05, 0x9a, 0xca, 0x02, 0x01, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b,
50 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
51 pldm_package_header_information pkgHeader{};
52 variable_field packageVersion{};
53
54 auto rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
55 packagerHeaderInfo.size(),
56 &pkgHeader, &packageVersion);
57
58 EXPECT_EQ(rc, PLDM_SUCCESS);
59 EXPECT_EQ(true,
60 std::equal(pkgHeader.uuid, pkgHeader.uuid + PLDM_FWUP_UUID_LENGTH,
61 uuid.begin(), uuid.end()));
62 EXPECT_EQ(pkgHeader.package_header_format_version, pkgHeaderFormatRevision);
63 EXPECT_EQ(pkgHeader.package_header_size, pkgHeaderSize);
64 EXPECT_EQ(true, std::equal(pkgHeader.package_release_date_time,
65 pkgHeader.package_release_date_time +
66 PLDM_TIMESTAMP104_SIZE,
67 package_release_date_time.begin(),
68 package_release_date_time.end()));
69 EXPECT_EQ(pkgHeader.component_bitmap_bit_length, componentBitmapBitLength);
70 EXPECT_EQ(pkgHeader.package_version_string_type, PLDM_STR_TYPE_ASCII);
71 EXPECT_EQ(pkgHeader.package_version_string_length,
72 packageVersionStr.size());
73 std::string packageVersionString(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +093074 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +093075 reinterpret_cast<const char*>(packageVersion.ptr),
76 packageVersion.length);
77 EXPECT_EQ(packageVersionString, packageVersionStr);
78}
79
80TEST(DecodePackageHeaderInfo, errorPaths)
81{
82 int rc = 0;
83 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
84 constexpr size_t packagerHeaderSize =
85 sizeof(pldm_package_header_information) + packageVersionStr.size();
86
87 // Invalid Package Version String Type - 0x06
88 constexpr std::array<uint8_t, packagerHeaderSize>
89 invalidPackagerHeaderInfo1{
90 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -060091 0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
Andrew Jeffery9c766792022-08-10 23:12:49 +093092 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
93 0x07, 0x00, 0x08, 0x00, 0x06, 0x0b, 0x4f, 0x70, 0x65, 0x6e,
94 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
95
96 pldm_package_header_information packageHeader{};
97 variable_field packageVersion{};
98
99 rc = decode_pldm_package_header_info(nullptr,
100 invalidPackagerHeaderInfo1.size(),
101 &packageHeader, &packageVersion);
102 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
103
104 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
105 invalidPackagerHeaderInfo1.size(),
106 nullptr, &packageVersion);
107 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
108
109 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
110 invalidPackagerHeaderInfo1.size(),
111 &packageHeader, nullptr);
112 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
113
114 rc = decode_pldm_package_header_info(
115 invalidPackagerHeaderInfo1.data(),
116 sizeof(pldm_package_header_information) - 1, &packageHeader,
117 &packageVersion);
118 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
119
120 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
121 invalidPackagerHeaderInfo1.size(),
122 &packageHeader, &packageVersion);
123 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
124
125 // Invalid Package Version String Length - 0x00
126 constexpr std::array<uint8_t, packagerHeaderSize>
127 invalidPackagerHeaderInfo2{
128 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600129 0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
131 0x07, 0x00, 0x08, 0x00, 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e,
132 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
133 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo2.data(),
134 invalidPackagerHeaderInfo2.size(),
135 &packageHeader, &packageVersion);
136 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
137
138 // Package version string length less than in the header information
139 constexpr std::array<uint8_t, packagerHeaderSize - 1>
140 invalidPackagerHeaderInfo3{
141 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600142 0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
144 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e,
145 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e};
146 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo3.data(),
147 invalidPackagerHeaderInfo3.size(),
148 &packageHeader, &packageVersion);
149 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
150
151 // ComponentBitmapBitLength not a multiple of 8
152 constexpr std::array<uint8_t, packagerHeaderSize>
153 invalidPackagerHeaderInfo4{
154 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600155 0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
157 0x07, 0x00, 0x09, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e,
158 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
159 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo4.data(),
160 invalidPackagerHeaderInfo4.size(),
161 &packageHeader, &packageVersion);
162 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
163}
164
165TEST(DecodeFirmwareDeviceIdRecord, goodPath)
166{
167 constexpr uint8_t descriptorCount = 1;
168 // Continue component updates after failure
169 constexpr std::bitset<32> deviceUpdateFlag{1};
170 constexpr uint16_t componentBitmapBitLength = 16;
171 // Applicable Components - 1,2,5,8,9
172 std::vector<std::bitset<8>> applicableComponentsBitfield{0x93, 0x01};
173 // ComponentImageSetVersionString
174 constexpr std::string_view imageSetVersionStr{"VersionString1"};
175 // Initial descriptor - UUID
176 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
177 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
178 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
179 constexpr uint16_t fwDevicePkgDataLen = 2;
180 // FirmwareDevicePackageData
181 constexpr std::array<uint8_t, fwDevicePkgDataLen> fwDevicePkgData{0xab,
182 0xcd};
183 // Size of the firmware device ID record
184 constexpr uint16_t recordLen =
185 sizeof(pldm_firmware_device_id_record) +
186 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
187 imageSetVersionStr.size() + sizeof(pldm_descriptor_tlv) - 1 +
188 uuid.size() + fwDevicePkgData.size();
189 // Firmware device ID record
190 constexpr std::array<uint8_t, recordLen> record{
191 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02,
192 0x00, 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
193 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10,
194 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0,
195 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xab, 0xcd};
196
197 pldm_firmware_device_id_record deviceIdRecHeader{};
198 variable_field applicableComponents{};
199 variable_field outCompImageSetVersionStr{};
200 variable_field recordDescriptors{};
201 variable_field outFwDevicePkgData{};
202
203 auto rc = decode_firmware_device_id_record(
204 record.data(), record.size(), componentBitmapBitLength,
205 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
206 &recordDescriptors, &outFwDevicePkgData);
207
208 EXPECT_EQ(rc, PLDM_SUCCESS);
209 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
210 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
211 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
212 deviceUpdateFlag);
213 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
214 PLDM_STR_TYPE_ASCII);
215 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
216 imageSetVersionStr.size());
217 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, fwDevicePkgDataLen);
218
219 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
220 EXPECT_EQ(true,
221 std::equal(applicableComponents.ptr,
222 applicableComponents.ptr + applicableComponents.length,
223 applicableComponentsBitfield.begin(),
224 applicableComponentsBitfield.end()));
225
226 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
227 std::string compImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930228 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930229 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
230 outCompImageSetVersionStr.length);
231 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
232
233 uint16_t descriptorType = 0;
234 uint16_t descriptorLen = 0;
235 variable_field descriptorData{};
236 // DescriptorCount is 1, so decode_descriptor_type_length_value called once
237 rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
238 recordDescriptors.length,
239 &descriptorType, &descriptorData);
240 EXPECT_EQ(rc, PLDM_SUCCESS);
241 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
242 sizeof(descriptorLen) +
243 descriptorData.length);
244 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
245 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
246 EXPECT_EQ(true, std::equal(descriptorData.ptr,
247 descriptorData.ptr + descriptorData.length,
248 uuid.begin(), uuid.end()));
249
250 EXPECT_EQ(outFwDevicePkgData.length, fwDevicePkgData.size());
251 EXPECT_EQ(true,
252 std::equal(outFwDevicePkgData.ptr,
253 outFwDevicePkgData.ptr + outFwDevicePkgData.length,
254 fwDevicePkgData.begin(), fwDevicePkgData.end()));
255}
256
257TEST(DecodeFirmwareDeviceIdRecord, goodPathNofwDevicePkgData)
258{
259 constexpr uint8_t descriptorCount = 1;
260 // Continue component updates after failure
261 constexpr std::bitset<32> deviceUpdateFlag{1};
262 constexpr uint16_t componentBitmapBitLength = 8;
263 // Applicable Components - 1,2
264 std::vector<std::bitset<8>> applicableComponentsBitfield{0x03};
265 // ComponentImageSetVersionString
266 constexpr std::string_view imageSetVersionStr{"VersionString1"};
267 // Initial descriptor - UUID
268 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
269 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
270 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
271 constexpr uint16_t fwDevicePkgDataLen = 0;
272
273 // Size of the firmware device ID record
274 constexpr uint16_t recordLen =
275 sizeof(pldm_firmware_device_id_record) +
276 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
277 imageSetVersionStr.size() +
278 sizeof(pldm_descriptor_tlv().descriptor_type) +
279 sizeof(pldm_descriptor_tlv().descriptor_length) + uuid.size() +
280 fwDevicePkgDataLen;
281 // Firmware device ID record
282 constexpr std::array<uint8_t, recordLen> record{
283 0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x03,
284 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e,
285 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d,
286 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
287
288 pldm_firmware_device_id_record deviceIdRecHeader{};
289 variable_field applicableComponents{};
290 variable_field outCompImageSetVersionStr{};
291 variable_field recordDescriptors{};
292 variable_field outFwDevicePkgData{};
293
294 auto rc = decode_firmware_device_id_record(
295 record.data(), record.size(), componentBitmapBitLength,
296 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
297 &recordDescriptors, &outFwDevicePkgData);
298
299 EXPECT_EQ(rc, PLDM_SUCCESS);
300 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
301 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
302 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
303 deviceUpdateFlag);
304 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
305 PLDM_STR_TYPE_ASCII);
306 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
307 imageSetVersionStr.size());
308 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, 0);
309
310 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
311 EXPECT_EQ(true,
312 std::equal(applicableComponents.ptr,
313 applicableComponents.ptr + applicableComponents.length,
314 applicableComponentsBitfield.begin(),
315 applicableComponentsBitfield.end()));
316
317 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
318 std::string compImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930319 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930320 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
321 outCompImageSetVersionStr.length);
322 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
323
324 uint16_t descriptorType = 0;
325 uint16_t descriptorLen = 0;
326 variable_field descriptorData{};
327 // DescriptorCount is 1, so decode_descriptor_type_length_value called once
328 rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
329 recordDescriptors.length,
330 &descriptorType, &descriptorData);
331 EXPECT_EQ(rc, PLDM_SUCCESS);
332 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
333 sizeof(descriptorLen) +
334 descriptorData.length);
335 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
336 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
337 EXPECT_EQ(true, std::equal(descriptorData.ptr,
338 descriptorData.ptr + descriptorData.length,
339 uuid.begin(), uuid.end()));
340
341 EXPECT_EQ(outFwDevicePkgData.ptr, nullptr);
342 EXPECT_EQ(outFwDevicePkgData.length, 0);
343}
344
345TEST(DecodeFirmwareDeviceIdRecord, ErrorPaths)
346{
347 constexpr uint16_t componentBitmapBitLength = 8;
348 // Invalid ComponentImageSetVersionStringType
349 constexpr std::array<uint8_t, 11> invalidRecord1{
350 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
351
352 int rc = 0;
353 pldm_firmware_device_id_record deviceIdRecHeader{};
354 variable_field applicableComponents{};
355 variable_field outCompImageSetVersionStr{};
356 variable_field recordDescriptors{};
357 variable_field outFwDevicePkgData{};
358
359 rc = decode_firmware_device_id_record(
360 nullptr, invalidRecord1.size(), componentBitmapBitLength,
361 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
362 &recordDescriptors, &outFwDevicePkgData);
363 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
364
365 rc = decode_firmware_device_id_record(
366 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
367 nullptr, &applicableComponents, &outCompImageSetVersionStr,
368 &recordDescriptors, &outFwDevicePkgData);
369 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
370
371 rc = decode_firmware_device_id_record(
372 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
373 &deviceIdRecHeader, nullptr, &outCompImageSetVersionStr,
374 &recordDescriptors, &outFwDevicePkgData);
375 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
376
377 rc = decode_firmware_device_id_record(
378 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
379 &deviceIdRecHeader, &applicableComponents, nullptr, &recordDescriptors,
380 &outFwDevicePkgData);
381 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
382
383 rc = decode_firmware_device_id_record(
384 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
385 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
386 nullptr, &outFwDevicePkgData);
387 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
388
389 rc = decode_firmware_device_id_record(
390 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
391 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
392 &recordDescriptors, nullptr);
393 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
394
395 rc = decode_firmware_device_id_record(
396 invalidRecord1.data(), invalidRecord1.size() - 1,
397 componentBitmapBitLength, &deviceIdRecHeader, &applicableComponents,
398 &outCompImageSetVersionStr, &recordDescriptors, &outFwDevicePkgData);
399 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
400
401 rc = decode_firmware_device_id_record(
402 invalidRecord1.data(), invalidRecord1.size(),
403 componentBitmapBitLength + 1, &deviceIdRecHeader, &applicableComponents,
404 &outCompImageSetVersionStr, &recordDescriptors, &outFwDevicePkgData);
405 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
406
407 rc = decode_firmware_device_id_record(
408 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
409 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
410 &recordDescriptors, &outFwDevicePkgData);
411 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
412
413 // Invalid ComponentImageSetVersionStringLength
414 constexpr std::array<uint8_t, 11> invalidRecord2{
415 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
416 rc = decode_firmware_device_id_record(
417 invalidRecord2.data(), invalidRecord2.size(), componentBitmapBitLength,
418 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
419 &recordDescriptors, &outFwDevicePkgData);
420 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
421
422 // invalidRecord3 size is less than RecordLength
423 constexpr std::array<uint8_t, 11> invalidRecord3{
424 0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00};
425 rc = decode_firmware_device_id_record(
426 invalidRecord3.data(), invalidRecord3.size(), componentBitmapBitLength,
427 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
428 &recordDescriptors, &outFwDevicePkgData);
429 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
430
431 // RecordLength is less than the calculated RecordLength
432 constexpr std::array<uint8_t, 11> invalidRecord4{
433 0x15, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02, 0x00};
434 rc = decode_firmware_device_id_record(
435 invalidRecord4.data(), invalidRecord4.size(), componentBitmapBitLength,
436 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
437 &recordDescriptors, &outFwDevicePkgData);
438 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
439}
440
441TEST(DecodeDescriptors, goodPath3Descriptors)
442{
443 // In the descriptor data there are 3 descriptor entries
444 // 1) IANA enterprise ID
445 constexpr std::array<uint8_t, PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH> iana{
446 0x0a, 0x0b, 0x0c, 0xd};
447 // 2) UUID
448 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
449 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
450 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
451 // 3) Vendor Defined
452 constexpr std::string_view vendorTitle{"OpenBMC"};
453 constexpr size_t vendorDescriptorLen = 2;
454 constexpr std::array<uint8_t, vendorDescriptorLen> vendorDescriptorData{
455 0x01, 0x02};
456
457 constexpr size_t vendorDefinedDescriptorLen =
458 sizeof(pldm_vendor_defined_descriptor_title_data()
459 .vendor_defined_descriptor_title_str_type) +
460 sizeof(pldm_vendor_defined_descriptor_title_data()
461 .vendor_defined_descriptor_title_str_len) +
462 vendorTitle.size() + vendorDescriptorData.size();
463
464 constexpr size_t descriptorsLength =
465 3 * (sizeof(pldm_descriptor_tlv().descriptor_type) +
466 sizeof(pldm_descriptor_tlv().descriptor_length)) +
467 iana.size() + uuid.size() + vendorDefinedDescriptorLen;
468
469 constexpr std::array<uint8_t, descriptorsLength> descriptors{
470 0x01, 0x00, 0x04, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x02, 0x00, 0x10,
471 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600472 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xff, 0xff, 0x0b, 0x00, 0x01,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930473 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x01, 0x02};
474
475 size_t descriptorCount = 1;
476 size_t descriptorsRemainingLength = descriptorsLength;
477 int rc = 0;
478
479 while (descriptorsRemainingLength && (descriptorCount <= 3))
480 {
481 uint16_t descriptorType = 0;
482 uint16_t descriptorLen = 0;
483 variable_field descriptorData{};
484
485 rc = decode_descriptor_type_length_value(
486 descriptors.data() + descriptorsLength - descriptorsRemainingLength,
487 descriptorsRemainingLength, &descriptorType, &descriptorData);
488 EXPECT_EQ(rc, PLDM_SUCCESS);
489
490 if (descriptorCount == 1)
491 {
492 EXPECT_EQ(descriptorType, PLDM_FWUP_IANA_ENTERPRISE_ID);
493 EXPECT_EQ(descriptorData.length,
494 PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH);
495 EXPECT_EQ(true,
496 std::equal(descriptorData.ptr,
497 descriptorData.ptr + descriptorData.length,
498 iana.begin(), iana.end()));
499 }
500 else if (descriptorCount == 2)
501 {
502 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
503 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
504 EXPECT_EQ(true,
505 std::equal(descriptorData.ptr,
506 descriptorData.ptr + descriptorData.length,
507 uuid.begin(), uuid.end()));
508 }
509 else if (descriptorCount == 3)
510 {
511 EXPECT_EQ(descriptorType, PLDM_FWUP_VENDOR_DEFINED);
512 EXPECT_EQ(descriptorData.length, vendorDefinedDescriptorLen);
513
514 uint8_t descriptorTitleStrType = 0;
515 variable_field descriptorTitleStr{};
516 variable_field vendorDefinedDescriptorData{};
517
518 rc = decode_vendor_defined_descriptor_value(
519 descriptorData.ptr, descriptorData.length,
520 &descriptorTitleStrType, &descriptorTitleStr,
521 &vendorDefinedDescriptorData);
522 EXPECT_EQ(rc, PLDM_SUCCESS);
523
524 EXPECT_EQ(descriptorTitleStrType, PLDM_STR_TYPE_ASCII);
525 EXPECT_EQ(descriptorTitleStr.length, vendorTitle.size());
526 std::string vendorTitleStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930527 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930528 reinterpret_cast<const char*>(descriptorTitleStr.ptr),
529 descriptorTitleStr.length);
530 EXPECT_EQ(vendorTitleStr, vendorTitle);
531
532 EXPECT_EQ(vendorDefinedDescriptorData.length,
533 vendorDescriptorData.size());
534 EXPECT_EQ(true, std::equal(vendorDefinedDescriptorData.ptr,
535 vendorDefinedDescriptorData.ptr +
536 vendorDefinedDescriptorData.length,
537 vendorDescriptorData.begin(),
538 vendorDescriptorData.end()));
539 }
540
541 descriptorsRemainingLength -= sizeof(descriptorType) +
542 sizeof(descriptorLen) +
543 descriptorData.length;
544 descriptorCount++;
545 }
546}
547
548TEST(DecodeDescriptors, errorPathDecodeDescriptorTLV)
549{
550 int rc = 0;
551 // IANA Enterprise ID descriptor length incorrect
552 constexpr std::array<uint8_t, 7> invalidIANADescriptor1{
553 0x01, 0x00, 0x03, 0x00, 0x0a, 0x0b, 0x0c};
554 uint16_t descriptorType = 0;
555 variable_field descriptorData{};
556
557 rc = decode_descriptor_type_length_value(nullptr,
558 invalidIANADescriptor1.size(),
559 &descriptorType, &descriptorData);
560 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
561
562 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
563 invalidIANADescriptor1.size(),
564 nullptr, &descriptorData);
565 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
566
567 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
568 invalidIANADescriptor1.size(),
569 &descriptorType, nullptr);
570 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
571
572 rc = decode_descriptor_type_length_value(
573 invalidIANADescriptor1.data(), PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN - 1,
574 &descriptorType, &descriptorData);
575 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
576
577 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
578 invalidIANADescriptor1.size(),
579 &descriptorType, &descriptorData);
580 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
581
582 // IANA Enterprise ID descriptor data less than length
583 std::array<uint8_t, 7> invalidIANADescriptor2{0x01, 0x00, 0x04, 0x00,
584 0x0a, 0x0b, 0x0c};
585 rc = decode_descriptor_type_length_value(invalidIANADescriptor2.data(),
586 invalidIANADescriptor2.size(),
587 &descriptorType, &descriptorData);
588 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
589}
590
591TEST(DecodeDescriptors, errorPathVendorDefinedDescriptor)
592{
593 int rc = 0;
594 // VendorDefinedDescriptorTitleStringType is invalid
595 constexpr std::array<uint8_t, 9> invalidVendorDescriptor1{
596 0x06, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
597 uint8_t descriptorStringType = 0;
598 variable_field descriptorTitleStr{};
599 variable_field vendorDefinedDescriptorData{};
600
601 rc = decode_vendor_defined_descriptor_value(
602 nullptr, invalidVendorDescriptor1.size(), &descriptorStringType,
603 &descriptorTitleStr, &vendorDefinedDescriptorData);
604 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
605
606 rc = decode_vendor_defined_descriptor_value(
607 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
608 &descriptorStringType, &descriptorTitleStr,
609 &vendorDefinedDescriptorData);
610 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
611
612 rc = decode_vendor_defined_descriptor_value(
613 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
614 nullptr, &descriptorTitleStr, &vendorDefinedDescriptorData);
615 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
616
617 rc = decode_vendor_defined_descriptor_value(
618 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
619 &descriptorStringType, nullptr, &vendorDefinedDescriptorData);
620 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
621
622 rc = decode_vendor_defined_descriptor_value(
623 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
624 &descriptorStringType, &descriptorTitleStr, nullptr);
625 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
626
627 rc = decode_vendor_defined_descriptor_value(
628 invalidVendorDescriptor1.data(),
629 sizeof(pldm_vendor_defined_descriptor_title_data) - 1,
630 &descriptorStringType, &descriptorTitleStr,
631 &vendorDefinedDescriptorData);
632 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
633
634 rc = decode_vendor_defined_descriptor_value(
635 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
636 &descriptorStringType, &descriptorTitleStr,
637 &vendorDefinedDescriptorData);
638 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
639
640 // VendorDefinedDescriptorTitleStringLength is 0
641 std::array<uint8_t, 9> invalidVendorDescriptor2{
642 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
643 rc = decode_vendor_defined_descriptor_value(
644 invalidVendorDescriptor2.data(), invalidVendorDescriptor2.size(),
645 &descriptorStringType, &descriptorTitleStr,
646 &vendorDefinedDescriptorData);
647 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
648
649 // VendorDefinedDescriptorData not present in the data
650 std::array<uint8_t, 9> invalidVendorDescriptor3{
651 0x01, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
652 rc = decode_vendor_defined_descriptor_value(
653 invalidVendorDescriptor3.data(), invalidVendorDescriptor3.size(),
654 &descriptorStringType, &descriptorTitleStr,
655 &vendorDefinedDescriptorData);
656 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
657}
658
659TEST(DecodeComponentImageInfo, goodPath)
660{
661 // Firmware
662 constexpr uint16_t compClassification = 16;
663 constexpr uint16_t compIdentifier = 300;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600664 constexpr uint32_t compComparisonStamp = 0xffffffff;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930665 // Force update
666 constexpr std::bitset<16> compOptions{1};
667 // System reboot[Bit position 3] & Medium-specific reset[Bit position 2]
668 constexpr std::bitset<16> reqCompActivationMethod{0x0c};
669 // Random ComponentLocationOffset
670 constexpr uint32_t compLocOffset = 357;
671 // Random ComponentSize
672 constexpr uint32_t compSize = 27;
673 // ComponentVersionString
674 constexpr std::string_view compVersionStr{"VersionString1"};
675 constexpr size_t compImageInfoSize =
676 sizeof(pldm_component_image_information) + compVersionStr.size();
677
678 constexpr std::array<uint8_t, compImageInfoSize> compImageInfo{
679 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
680 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
681 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
682 pldm_component_image_information outCompImageInfo{};
683 variable_field outCompVersionStr{};
684
685 auto rc =
686 decode_pldm_comp_image_info(compImageInfo.data(), compImageInfo.size(),
687 &outCompImageInfo, &outCompVersionStr);
688
689 EXPECT_EQ(rc, PLDM_SUCCESS);
690 EXPECT_EQ(outCompImageInfo.comp_classification, compClassification);
691 EXPECT_EQ(outCompImageInfo.comp_identifier, compIdentifier);
692 EXPECT_EQ(outCompImageInfo.comp_comparison_stamp, compComparisonStamp);
693 EXPECT_EQ(outCompImageInfo.comp_options.value, compOptions);
694 EXPECT_EQ(outCompImageInfo.requested_comp_activation_method.value,
695 reqCompActivationMethod);
696 EXPECT_EQ(outCompImageInfo.comp_location_offset, compLocOffset);
697 EXPECT_EQ(outCompImageInfo.comp_size, compSize);
698 EXPECT_EQ(outCompImageInfo.comp_version_string_type, PLDM_STR_TYPE_ASCII);
699 EXPECT_EQ(outCompImageInfo.comp_version_string_length,
700 compVersionStr.size());
701
702 EXPECT_EQ(outCompVersionStr.length,
703 outCompImageInfo.comp_version_string_length);
704 std::string componentVersionString(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930705 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930706 reinterpret_cast<const char*>(outCompVersionStr.ptr),
707 outCompVersionStr.length);
708 EXPECT_EQ(componentVersionString, compVersionStr);
709}
710
711TEST(DecodeComponentImageInfo, errorPaths)
712{
713 int rc = 0;
714 // ComponentVersionString
715 constexpr std::string_view compVersionStr{"VersionString1"};
716 constexpr size_t compImageInfoSize =
717 sizeof(pldm_component_image_information) + compVersionStr.size();
718 // Invalid ComponentVersionStringType - 0x06
719 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo1{
720 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
721 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x56, 0x65,
722 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
723 pldm_component_image_information outCompImageInfo{};
724 variable_field outCompVersionStr{};
725
726 rc = decode_pldm_comp_image_info(nullptr, invalidCompImageInfo1.size(),
727 &outCompImageInfo, &outCompVersionStr);
728 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
729
730 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
731 invalidCompImageInfo1.size(), nullptr,
732 &outCompVersionStr);
733 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
734
735 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
736 invalidCompImageInfo1.size(),
737 &outCompImageInfo, nullptr);
738 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
739
740 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
741 sizeof(pldm_component_image_information) -
742 1,
743 &outCompImageInfo, &outCompVersionStr);
744 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
745
746 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
747 invalidCompImageInfo1.size(),
748 &outCompImageInfo, &outCompVersionStr);
749 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
750
751 // Invalid ComponentVersionStringLength - 0x00
752 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo2{
753 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
754 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x65,
755 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
756 rc = decode_pldm_comp_image_info(invalidCompImageInfo2.data(),
757 invalidCompImageInfo2.size(),
758 &outCompImageInfo, &outCompVersionStr);
759 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
760
761 // Use Component Comparison Stamp is not set, but ComponentComparisonStamp
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600762 // is not 0xffffffff
Andrew Jeffery9c766792022-08-10 23:12:49 +0930763 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo3{
764 0x10, 0x00, 0x2c, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00,
765 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
766 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
767
768 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
769 invalidCompImageInfo3.size() - 1,
770 &outCompImageInfo, &outCompVersionStr);
771 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
772
773 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
774 invalidCompImageInfo3.size(),
775 &outCompImageInfo, &outCompVersionStr);
776 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
777
778 // Invalid ComponentLocationOffset - 0
779 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo4{
780 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
781 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
782 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
783 rc = decode_pldm_comp_image_info(invalidCompImageInfo4.data(),
784 invalidCompImageInfo4.size(),
785 &outCompImageInfo, &outCompVersionStr);
786 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
787
788 // Invalid ComponentSize - 0
789 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo5{
790 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
791 0x65, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
792 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
793 rc = decode_pldm_comp_image_info(invalidCompImageInfo5.data(),
794 invalidCompImageInfo5.size(),
795 &outCompImageInfo, &outCompVersionStr);
796 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
797}
798
799TEST(QueryDeviceIdentifiers, goodPathEncodeRequest)
800{
801 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930802 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930803 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
804
805 uint8_t instanceId = 0x01;
806
807 auto rc = encode_query_device_identifiers_req(
808 instanceId, PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES, requestPtr);
809 EXPECT_EQ(rc, PLDM_SUCCESS);
810 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
811 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
812 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
813 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DEVICE_IDENTIFIERS);
814}
815
816TEST(QueryDeviceIdentifiers, goodPathDecodeResponse)
817{
818 // descriptorDataLen is not fixed here taking it as 6
819 constexpr uint8_t descriptorDataLen = 6;
820 std::array<uint8_t, hdrSize +
821 sizeof(struct pldm_query_device_identifiers_resp) +
822 descriptorDataLen>
823 responseMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930824 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930825 auto inResp = reinterpret_cast<struct pldm_query_device_identifiers_resp*>(
826 responseMsg.data() + hdrSize);
827
828 inResp->completion_code = PLDM_SUCCESS;
829 inResp->device_identifiers_len = htole32(descriptorDataLen);
830 inResp->descriptor_count = 1;
831
832 // filling descriptor data
833 std::fill_n(responseMsg.data() + hdrSize +
834 sizeof(struct pldm_query_device_identifiers_resp),
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600835 descriptorDataLen, 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930836
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930837 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930838 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
839 uint8_t completionCode = PLDM_SUCCESS;
840 uint32_t deviceIdentifiersLen = 0;
841 uint8_t descriptorCount = 0;
842 uint8_t* outDescriptorData = nullptr;
843
844 auto rc = decode_query_device_identifiers_resp(
845 response, responseMsg.size() - hdrSize, &completionCode,
846 &deviceIdentifiersLen, &descriptorCount, &outDescriptorData);
847
848 EXPECT_EQ(rc, PLDM_SUCCESS);
849 EXPECT_EQ(completionCode, PLDM_SUCCESS);
850 EXPECT_EQ(deviceIdentifiersLen, inResp->device_identifiers_len);
851 EXPECT_EQ(descriptorCount, inResp->descriptor_count);
852 EXPECT_EQ(true,
853 std::equal(outDescriptorData,
854 outDescriptorData + deviceIdentifiersLen,
855 responseMsg.begin() + hdrSize +
856 sizeof(struct pldm_query_device_identifiers_resp),
857 responseMsg.end()));
858}
859
860TEST(GetFirmwareParameters, goodPathEncodeRequest)
861{
862 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930863 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930864 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
865 uint8_t instanceId = 0x01;
866
867 auto rc = encode_get_firmware_parameters_req(
868 instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, requestPtr);
869 EXPECT_EQ(rc, PLDM_SUCCESS);
870 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
871 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
872 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
873 EXPECT_EQ(requestPtr->hdr.command, PLDM_GET_FIRMWARE_PARAMETERS);
874}
875
876TEST(GetFirmwareParameters, decodeResponse)
877{
878 // CapabilitiesDuringUpdate of the firmware device
879 // Firmware device downgrade restrictions [Bit position 8] &
880 // Firmware Device Partial Updates [Bit position 3]
881 constexpr std::bitset<32> fdCapabilities{0x00000104};
882 constexpr uint16_t compCount = 1;
883 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
884 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
885
886 // constexpr uint16_t compClassification = 16;
887 // constexpr uint16_t compIdentifier = 300;
888 // constexpr uint8_t compClassificationIndex = 20;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600889 // constexpr uint32_t activeCompComparisonStamp = 0xabcdefab;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930890 // constexpr std::array<uint8_t, 8> activeComponentReleaseData = {
891 // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
892 // constexpr uint32_t pendingCompComparisonStamp = 0x12345678;
893 // constexpr std::array<uint8_t, 8> pendingComponentReleaseData = {
894 // 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
895 constexpr std::string_view activeCompVersion{"VersionString3"};
896 constexpr std::string_view pendingCompVersion{"VersionString4"};
Andrew Jeffery9c766792022-08-10 23:12:49 +0930897
898 constexpr size_t compParamTableSize =
899 sizeof(pldm_component_parameter_entry) + activeCompVersion.size() +
900 pendingCompVersion.size();
901
902 constexpr std::array<uint8_t, compParamTableSize> compParamTable{
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600903 0x10, 0x00, 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930904 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
905 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00, 0x02,
906 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74,
907 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
908 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
909
910 constexpr size_t getFwParamsPayloadLen =
911 sizeof(pldm_get_firmware_parameters_resp) +
912 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size() +
913 compParamTableSize;
914
915 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
916 getFwParamsResponse{
917 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01,
918 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
919 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
920 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x10, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600921 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01, 0x02,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930922 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
923 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00,
924 0x02, 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
925 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73,
926 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
927
928 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930929 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930930 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
931 pldm_get_firmware_parameters_resp outResp{};
932 variable_field outActiveCompImageSetVersion{};
933 variable_field outPendingCompImageSetVersion{};
934 variable_field outCompParameterTable{};
935
936 auto rc = decode_get_firmware_parameters_resp(
937 responseMsg, getFwParamsPayloadLen, &outResp,
938 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
939 &outCompParameterTable);
940
941 EXPECT_EQ(rc, PLDM_SUCCESS);
942 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
943 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
944 EXPECT_EQ(outResp.comp_count, compCount);
945 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
946 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
947 activeCompImageSetVersion.size());
948 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
949 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
950 pendingCompImageSetVersion.size());
951 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930952 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930953 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
954 outActiveCompImageSetVersion.length);
955 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
956 std::string pendingCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930957 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930958 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
959 outPendingCompImageSetVersion.length);
960 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
961 EXPECT_EQ(outCompParameterTable.length, compParamTableSize);
962 EXPECT_EQ(true, std::equal(outCompParameterTable.ptr,
963 outCompParameterTable.ptr +
964 outCompParameterTable.length,
965 compParamTable.begin(), compParamTable.end()));
966}
967
968TEST(GetFirmwareParameters, decodeResponseZeroCompCount)
969{
970 // CapabilitiesDuringUpdate of the firmware device
971 // FD Host Functionality during Firmware Update [Bit position 2] &
972 // Component Update Failure Retry Capability [Bit position 1]
973 constexpr std::bitset<32> fdCapabilities{0x06};
974 constexpr uint16_t compCount = 0;
975 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
976 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
977
978 constexpr size_t getFwParamsPayloadLen =
979 sizeof(pldm_get_firmware_parameters_resp) +
980 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size();
981
982 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
983 getFwParamsResponse{
984 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
985 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
986 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
987 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32};
988
989 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930990 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930991 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
992 pldm_get_firmware_parameters_resp outResp{};
993 variable_field outActiveCompImageSetVersion{};
994 variable_field outPendingCompImageSetVersion{};
995 variable_field outCompParameterTable{};
996
997 auto rc = decode_get_firmware_parameters_resp(
998 responseMsg, getFwParamsPayloadLen, &outResp,
999 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1000 &outCompParameterTable);
1001
1002 EXPECT_EQ(rc, PLDM_SUCCESS);
1003 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1004 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1005 EXPECT_EQ(outResp.comp_count, compCount);
1006 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1007 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1008 activeCompImageSetVersion.size());
1009 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1010 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1011 pendingCompImageSetVersion.size());
1012 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301013 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301014 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1015 outActiveCompImageSetVersion.length);
1016 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1017 std::string pendingCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301018 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301019 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
1020 outPendingCompImageSetVersion.length);
1021 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1022 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1023 EXPECT_EQ(outCompParameterTable.length, 0);
1024}
1025
1026TEST(GetFirmwareParameters,
1027 decodeResponseNoPendingCompImageVersionStrZeroCompCount)
1028{
1029 // CapabilitiesDuringUpdate of the firmware device
1030 // FD Host Functionality during Firmware Update [Bit position 2] &
1031 // Component Update Failure Retry Capability [Bit position 1]
1032 constexpr std::bitset<32> fdCapabilities{0x06};
1033 constexpr uint16_t compCount = 0;
1034 constexpr std::string_view activeCompImageSetVersion{"VersionString"};
1035
1036 constexpr size_t getFwParamsPayloadLen =
1037 sizeof(pldm_get_firmware_parameters_resp) +
1038 activeCompImageSetVersion.size();
1039
1040 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1041 getFwParamsResponse{0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1042 0x00, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00,
1043 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1044 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67};
1045
1046 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301047 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301048 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1049 pldm_get_firmware_parameters_resp outResp{};
1050 variable_field outActiveCompImageSetVersion{};
1051 variable_field outPendingCompImageSetVersion{};
1052 variable_field outCompParameterTable{};
1053
1054 auto rc = decode_get_firmware_parameters_resp(
1055 responseMsg, getFwParamsPayloadLen, &outResp,
1056 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1057 &outCompParameterTable);
1058
1059 EXPECT_EQ(rc, PLDM_SUCCESS);
1060 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1061 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1062 EXPECT_EQ(outResp.comp_count, compCount);
1063 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1064 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1065 activeCompImageSetVersion.size());
1066 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type,
1067 PLDM_STR_TYPE_UNKNOWN);
1068 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len, 0);
1069 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301070 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301071 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1072 outActiveCompImageSetVersion.length);
1073 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1074 EXPECT_EQ(outPendingCompImageSetVersion.ptr, nullptr);
1075 EXPECT_EQ(outPendingCompImageSetVersion.length, 0);
1076 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1077 EXPECT_EQ(outCompParameterTable.length, 0);
1078}
1079
1080TEST(GetFirmwareParameters, decodeResponseErrorCompletionCode)
1081{
1082 constexpr std::array<uint8_t, hdrSize + sizeof(uint8_t)>
1083 getFwParamsResponse{0x00, 0x00, 0x00, 0x01};
1084
1085 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301086 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301087 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1088 pldm_get_firmware_parameters_resp outResp{};
1089 variable_field outActiveCompImageSetVersion{};
1090 variable_field outPendingCompImageSetVersion{};
1091 variable_field outCompParameterTable{};
1092
1093 auto rc = decode_get_firmware_parameters_resp(
1094 responseMsg, getFwParamsResponse.size(), &outResp,
1095 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1096 &outCompParameterTable);
1097
1098 EXPECT_EQ(rc, PLDM_SUCCESS);
1099 EXPECT_EQ(outResp.completion_code, PLDM_ERROR);
1100}
1101
1102TEST(GetFirmwareParameters, errorPathdecodeResponse)
1103{
1104 int rc = 0;
1105 // Invalid ActiveComponentImageSetVersionStringType
1106 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse1{
1107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1108 0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
1109
1110 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301111 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301112 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse1.data());
1113 pldm_get_firmware_parameters_resp outResp{};
1114 variable_field outActiveCompImageSetVersion{};
1115 variable_field outPendingCompImageSetVersion{};
1116 variable_field outCompParameterTable{};
1117
1118 rc = decode_get_firmware_parameters_resp(
1119 nullptr, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1120 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1121 &outCompParameterTable);
1122 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1123
1124 rc = decode_get_firmware_parameters_resp(
1125 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, nullptr,
1126 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1127 &outCompParameterTable);
1128 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1129
1130 rc = decode_get_firmware_parameters_resp(
1131 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1132 nullptr, &outPendingCompImageSetVersion, &outCompParameterTable);
1133 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1134
1135 rc = decode_get_firmware_parameters_resp(
1136 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1137 &outActiveCompImageSetVersion, nullptr, &outCompParameterTable);
1138 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1139
1140 rc = decode_get_firmware_parameters_resp(
1141 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1142 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, nullptr);
1143 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1144
1145 rc = decode_get_firmware_parameters_resp(
1146 responseMsg, 0, &outResp, &outActiveCompImageSetVersion,
1147 &outPendingCompImageSetVersion, &outCompParameterTable);
1148 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1149
1150 rc = decode_get_firmware_parameters_resp(
1151 responseMsg, invalidGetFwParamsResponse1.size() - 1 - hdrSize, &outResp,
1152 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1153 &outCompParameterTable);
1154 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1155
1156 rc = decode_get_firmware_parameters_resp(
1157 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1158 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1159 &outCompParameterTable);
1160 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1161
1162 // Invalid ActiveComponentImageSetVersionStringLength
1163 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse2{
1164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1165 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
1166 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301167 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301168 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse2.data());
1169 rc = decode_get_firmware_parameters_resp(
1170 responseMsg, invalidGetFwParamsResponse2.size() - hdrSize, &outResp,
1171 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1172 &outCompParameterTable);
1173 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1174
1175 // Invalid PendingComponentImageSetVersionStringType &
1176 // PendingComponentImageSetVersionStringLength
1177 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse3{
1178 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1179 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x00};
1180 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301181 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301182 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse3.data());
1183 rc = decode_get_firmware_parameters_resp(
1184 responseMsg, invalidGetFwParamsResponse3.size() - hdrSize, &outResp,
1185 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1186 &outCompParameterTable);
1187 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1188
1189 // Invalid PendingComponentImageSetVersionStringType &
1190 // PendingComponentImageSetVersionStringLength
1191 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse4{
1192 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1193 0x00, 0x00, 0x00, 0x01, 0x0e, 0x06, 0x0e};
1194 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301195 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301196 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse4.data());
1197 rc = decode_get_firmware_parameters_resp(
1198 responseMsg, invalidGetFwParamsResponse4.size() - hdrSize, &outResp,
1199 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1200 &outCompParameterTable);
1201 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1202
1203 // Total payload length less than expected
1204 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse5{
1205 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1206 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x0e};
1207 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301208 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301209 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse5.data());
1210 rc = decode_get_firmware_parameters_resp(
1211 responseMsg, invalidGetFwParamsResponse5.size() - hdrSize, &outResp,
1212 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1213 &outCompParameterTable);
1214 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1215}
1216
1217TEST(GetFirmwareParameters, goodPathDecodeComponentParameterEntry)
1218{
1219 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001220 constexpr uint16_t compClassification = 0x0a0b;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301221 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001222 constexpr uint16_t compIdentifier = 0x0c0d;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301223 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001224 constexpr uint32_t timestamp = 0x12345678;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301225 // Random value for component activation methods
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001226 constexpr uint16_t compActivationMethods = 0xbbdd;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301227 // Random value for capabilities during update
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001228 constexpr uint32_t capabilitiesDuringUpdate = 0xbadbeefe;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301229
1230 // ActiveCompImageSetVerStrLen is not fixed here taking it as 8
1231 constexpr uint8_t activeCompVerStrLen = 8;
1232 // PendingCompImageSetVerStrLen is not fixed here taking it as 8
1233 constexpr uint8_t pendingCompVerStrLen = 8;
1234 constexpr size_t entryLength =
1235 sizeof(struct pldm_component_parameter_entry) + activeCompVerStrLen +
1236 pendingCompVerStrLen;
1237 std::array<uint8_t, entryLength> entry{};
1238
1239 auto inEntry =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301240 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301241 reinterpret_cast<struct pldm_component_parameter_entry*>(entry.data());
1242
1243 inEntry->comp_classification = htole16(compClassification);
1244 inEntry->comp_identifier = htole16(compIdentifier);
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001245 inEntry->comp_classification_index = 0x0f;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301246 inEntry->active_comp_comparison_stamp = htole32(timestamp);
1247 inEntry->active_comp_ver_str_type = 1;
1248 inEntry->active_comp_ver_str_len = activeCompVerStrLen;
1249 std::fill_n(inEntry->active_comp_release_date,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001250 sizeof(inEntry->active_comp_release_date), 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301251 inEntry->pending_comp_comparison_stamp = htole32(timestamp);
1252 inEntry->pending_comp_ver_str_type = 1;
1253 inEntry->pending_comp_ver_str_len = pendingCompVerStrLen;
1254 std::fill_n(inEntry->pending_comp_release_date,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001255 sizeof(inEntry->pending_comp_release_date), 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301256 inEntry->comp_activation_methods.value = htole16(compActivationMethods);
1257 inEntry->capabilities_during_update.value =
1258 htole32(capabilitiesDuringUpdate);
1259 constexpr auto activeCompVerStrPos =
1260 sizeof(struct pldm_component_parameter_entry);
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001261 std::fill_n(entry.data() + activeCompVerStrPos, activeCompVerStrLen, 0xaa);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301262 constexpr auto pendingCompVerStrPos =
1263 activeCompVerStrPos + activeCompVerStrLen;
1264 std::fill_n(entry.data() + pendingCompVerStrPos, pendingCompVerStrLen,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001265 0xbb);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301266
1267 struct pldm_component_parameter_entry outEntry;
1268 struct variable_field outActiveCompVerStr;
1269 struct variable_field outPendingCompVerStr;
1270
1271 auto rc = decode_get_firmware_parameters_resp_comp_entry(
1272 entry.data(), entryLength, &outEntry, &outActiveCompVerStr,
1273 &outPendingCompVerStr);
1274
1275 EXPECT_EQ(rc, PLDM_SUCCESS);
1276
1277 EXPECT_EQ(outEntry.comp_classification, compClassification);
1278 EXPECT_EQ(outEntry.comp_identifier, compIdentifier);
1279 EXPECT_EQ(inEntry->comp_classification_index,
1280 outEntry.comp_classification_index);
1281 EXPECT_EQ(outEntry.active_comp_comparison_stamp, timestamp);
1282 EXPECT_EQ(inEntry->active_comp_ver_str_type,
1283 outEntry.active_comp_ver_str_type);
1284 EXPECT_EQ(inEntry->active_comp_ver_str_len,
1285 outEntry.active_comp_ver_str_len);
1286 EXPECT_EQ(0, memcmp(inEntry->active_comp_release_date,
1287 outEntry.active_comp_release_date,
1288 sizeof(inEntry->active_comp_release_date)));
1289 EXPECT_EQ(outEntry.pending_comp_comparison_stamp, timestamp);
1290 EXPECT_EQ(inEntry->pending_comp_ver_str_type,
1291 outEntry.pending_comp_ver_str_type);
1292 EXPECT_EQ(inEntry->pending_comp_ver_str_len,
1293 outEntry.pending_comp_ver_str_len);
1294 EXPECT_EQ(0, memcmp(inEntry->pending_comp_release_date,
1295 outEntry.pending_comp_release_date,
1296 sizeof(inEntry->pending_comp_release_date)));
1297 EXPECT_EQ(outEntry.comp_activation_methods.value, compActivationMethods);
1298 EXPECT_EQ(outEntry.capabilities_during_update.value,
1299 capabilitiesDuringUpdate);
1300
1301 EXPECT_EQ(0, memcmp(outActiveCompVerStr.ptr,
1302 entry.data() + activeCompVerStrPos,
1303 outActiveCompVerStr.length));
1304 EXPECT_EQ(0, memcmp(outPendingCompVerStr.ptr,
1305 entry.data() + pendingCompVerStrPos,
1306 outPendingCompVerStr.length));
1307}
1308
Andrew Jeffery688be622024-05-23 11:22:51 +09301309#ifdef LIBPLDM_API_TESTING
Chris Wang4c1f2c72024-03-21 17:09:44 +08001310TEST(QueryDownstreamDevices, goodPathEncodeRequest)
1311{
1312 constexpr uint8_t instanceId = 1;
1313 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301314 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001315 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1316
1317 auto rc = encode_query_downstream_devices_req(instanceId, requestPtr);
1318
Unive Tien71e935c2024-11-25 17:21:43 +08001319 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001320 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1321 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1322 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1323 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DOWNSTREAM_DEVICES);
1324}
Andrew Jeffery688be622024-05-23 11:22:51 +09301325#endif
Chris Wang4c1f2c72024-03-21 17:09:44 +08001326
Andrew Jeffery688be622024-05-23 11:22:51 +09301327#ifdef LIBPLDM_API_TESTING
Chris Wang4c1f2c72024-03-21 17:09:44 +08001328TEST(QueryDownstreamDevices, encodeRequestInvalidData)
1329{
1330 constexpr uint8_t instanceId = 1;
1331
1332 auto rc = encode_query_downstream_devices_req(instanceId, nullptr);
1333
Unive Tien71e935c2024-11-25 17:21:43 +08001334 EXPECT_EQ(rc, -EINVAL);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001335}
Andrew Jeffery688be622024-05-23 11:22:51 +09301336#endif
Chris Wang4c1f2c72024-03-21 17:09:44 +08001337
Andrew Jeffery688be622024-05-23 11:22:51 +09301338#ifdef LIBPLDM_API_TESTING
Chris Wang4c1f2c72024-03-21 17:09:44 +08001339TEST(QueryDownstreamDevices, goodPathDecodeResponse)
1340{
1341 uint8_t completion_code_resp = PLDM_SUCCESS;
1342 uint8_t downstream_device_update_supported_resp =
1343 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1344 uint16_t number_of_downstream_devices_resp = 1;
1345 uint16_t max_number_of_downstream_devices_resp = 1;
1346 /** Capabilities of updating downstream devices
1347 * FDP supports downstream devices dynamically attached [Bit position 0] &
1348 * FDP supports downstream devices dynamically removed [Bit position 1]
1349 */
1350 bitfield32_t capabilities_resp = {.value = 0x0002};
1351 int rc;
1352
1353 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1354 responseMsg{};
1355
1356 struct pldm_msgbuf _buf;
1357 struct pldm_msgbuf* buf = &_buf;
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301358 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1359 responseMsg.size() - hdrSize);
1360 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001361
1362 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1363 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1364 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1365 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1366 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
1367
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301368 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001369 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1370 struct pldm_query_downstream_devices_resp resp_data;
1371
1372 rc = decode_query_downstream_devices_resp(
1373 response, responseMsg.size() - hdrSize, &resp_data);
1374
Unive Tien71e935c2024-11-25 17:21:43 +08001375 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001376 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1377 EXPECT_EQ(resp_data.downstream_device_update_supported,
1378 downstream_device_update_supported_resp);
1379 EXPECT_EQ(resp_data.number_of_downstream_devices,
1380 number_of_downstream_devices_resp);
1381 EXPECT_EQ(resp_data.max_number_of_downstream_devices,
1382 max_number_of_downstream_devices_resp);
1383 EXPECT_EQ(resp_data.capabilities.value, capabilities_resp.value);
1384}
Andrew Jeffery688be622024-05-23 11:22:51 +09301385#endif
Chris Wang4c1f2c72024-03-21 17:09:44 +08001386
Andrew Jeffery688be622024-05-23 11:22:51 +09301387#ifdef LIBPLDM_API_TESTING
Chris Wang4c1f2c72024-03-21 17:09:44 +08001388TEST(QueryDownstreamDevices, decodeRequestUndefinedValue)
1389{
1390 uint8_t completion_code_resp = PLDM_SUCCESS;
1391 uint8_t downstream_device_update_supported_resp = 0xe; /*Undefined value*/
1392 uint16_t number_of_downstream_devices_resp = 1;
1393 uint16_t max_number_of_downstream_devices_resp = 1;
1394 /** Capabilities of updating downstream devices
1395 * FDP supports downstream devices dynamically attached [Bit position 0] &
1396 * FDP supports downstream devices dynamically removed [Bit position 1]
1397 */
1398 bitfield32_t capabilities_resp = {.value = 0x0002};
1399 int rc;
1400
1401 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1402 responseMsg{};
1403
1404 struct pldm_msgbuf _buf;
1405 struct pldm_msgbuf* buf = &_buf;
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301406 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1407 responseMsg.size() - hdrSize);
1408 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001409
1410 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1411 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1412 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1413 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1414 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
1415
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301416 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001417 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1418 struct pldm_query_downstream_devices_resp resp_data;
1419
1420 rc = decode_query_downstream_devices_resp(
1421 response, responseMsg.size() - hdrSize, &resp_data);
1422
Unive Tien71e935c2024-11-25 17:21:43 +08001423 ASSERT_EQ(rc, -EINVAL);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001424}
Andrew Jeffery688be622024-05-23 11:22:51 +09301425#endif
Chris Wang4c1f2c72024-03-21 17:09:44 +08001426
Andrew Jeffery688be622024-05-23 11:22:51 +09301427#ifdef LIBPLDM_API_TESTING
Chris Wang4c1f2c72024-03-21 17:09:44 +08001428TEST(QueryDownstreamDevices, decodeRequestErrorBufSize)
1429{
1430 uint8_t completion_code_resp = PLDM_SUCCESS;
1431 uint8_t downstream_device_update_supported_resp =
1432 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1433 uint16_t number_of_downstream_devices_resp = 1;
1434 uint16_t max_number_of_downstream_devices_resp = 1;
1435 /** Capabilities of updating downstream devices
1436 * FDP supports downstream devices dynamically attached [Bit position 0] &
1437 * FDP supports downstream devices dynamically removed [Bit position 1]
1438 */
1439 bitfield32_t capabilities_resp = {.value = 0x0002};
1440 int rc;
1441
1442 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES -
1443 2 /* Inject error length*/>
1444 responseMsg{};
1445
1446 struct pldm_msgbuf _buf;
1447 struct pldm_msgbuf* buf = &_buf;
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301448 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1449 responseMsg.size() - hdrSize);
1450 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001451
1452 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1453 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1454 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1455 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1456 // Inject error value
1457 pldm_msgbuf_insert_uint16(buf, (uint16_t)capabilities_resp.value);
1458
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301459 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001460 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1461 struct pldm_query_downstream_devices_resp resp_data;
1462
1463 rc = decode_query_downstream_devices_resp(
1464 response, responseMsg.size() - hdrSize, &resp_data);
1465
Unive Tien71e935c2024-11-25 17:21:43 +08001466 EXPECT_EQ(rc, -EBADMSG);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001467}
Andrew Jeffery688be622024-05-23 11:22:51 +09301468#endif
Chris Wang4c1f2c72024-03-21 17:09:44 +08001469
Andrew Jeffery688be622024-05-23 11:22:51 +09301470#ifdef LIBPLDM_API_TESTING
Chris Wang458475a2024-03-26 17:59:19 +08001471TEST(QueryDownstreamIdentifiers, goodPathEncodeRequest)
1472{
1473 constexpr uint8_t instanceId = 1;
Andrew Jefferydec237b2024-11-08 14:33:45 +10301474 constexpr size_t payloadLen = PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1475 PLDM_MSG_DEFINE_P(request, payloadLen);
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001476 constexpr pldm_query_downstream_identifiers_req params_req{
1477 0xFFFFFFFF, PLDM_GET_FIRSTPART};
Chris Wang458475a2024-03-26 17:59:19 +08001478
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001479 auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1480 request, payloadLen);
Unive Tien71e935c2024-11-25 17:21:43 +08001481 ASSERT_EQ(rc, 0);
Andrew Jefferydec237b2024-11-08 14:33:45 +10301482 EXPECT_THAT(std::span<uint8_t>(request_buf, sizeof(request_buf)),
1483 ElementsAreArray<uint8_t>(
1484 {0x81, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x01}));
Chris Wang458475a2024-03-26 17:59:19 +08001485}
Andrew Jeffery688be622024-05-23 11:22:51 +09301486#endif
Chris Wang458475a2024-03-26 17:59:19 +08001487
Andrew Jeffery688be622024-05-23 11:22:51 +09301488#ifdef LIBPLDM_API_TESTING
Chris Wang458475a2024-03-26 17:59:19 +08001489TEST(QueryDownstreamIdentifiers, encodeRequestInvalidErrorPaths)
1490{
1491 constexpr uint8_t instanceId = 1;
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001492 constexpr pldm_query_downstream_identifiers_req params_req{
1493 0xFFFFFFFF, PLDM_GET_FIRSTPART};
1494 constexpr pldm_query_downstream_identifiers_req params_req_invalid{
1495 0xFFFFFFFF, PLDM_ACKNOWLEDGEMENT_ONLY};
Chris Wang458475a2024-03-26 17:59:19 +08001496 constexpr size_t payload_length =
1497 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1498 std::array<uint8_t, hdrSize + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301499 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang458475a2024-03-26 17:59:19 +08001500 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1501
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001502 auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1503 nullptr, payload_length);
Unive Tien71e935c2024-11-25 17:21:43 +08001504 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08001505
1506 rc = encode_query_downstream_identifiers_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001507 instanceId, &params_req, requestPtr, payload_length - 1);
Unive Tien71e935c2024-11-25 17:21:43 +08001508 EXPECT_EQ(rc, -EOVERFLOW);
Chris Wang458475a2024-03-26 17:59:19 +08001509
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001510 rc = encode_query_downstream_identifiers_req(
1511 instanceId, &params_req_invalid, requestPtr, payload_length);
Unive Tien71e935c2024-11-25 17:21:43 +08001512 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08001513}
Andrew Jeffery688be622024-05-23 11:22:51 +09301514#endif
Chris Wang458475a2024-03-26 17:59:19 +08001515
Andrew Jeffery688be622024-05-23 11:22:51 +09301516#ifdef LIBPLDM_API_TESTING
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301517TEST(QueryDownstreamIdentifiers, decodeResponseNoDevices)
Chris Wang458475a2024-03-26 17:59:19 +08001518{
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301519 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1520 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1521 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1522 constexpr uint32_t downstream_devices_length_resp = 0;
1523 constexpr uint16_t number_of_downstream_devices_resp = 0;
1524
1525 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1526 struct pldm_query_downstream_identifiers_resp resp_data = {};
1527 struct pldm_downstream_device_iter devs;
1528 struct pldm_msgbuf _buf;
1529 struct pldm_msgbuf* buf = &_buf;
1530 int rc = 0;
1531
1532 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1533 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1534 ASSERT_EQ(rc, 0);
1535
1536 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1537 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1538 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1539 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1540 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1541
1542 ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1543
1544 rc = decode_query_downstream_identifiers_resp(
1545 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp_data,
1546 &devs);
1547
Unive Tien71e935c2024-11-25 17:21:43 +08001548 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301549 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1550 EXPECT_EQ(resp_data.next_data_transfer_handle,
1551 next_data_transfer_handle_resp);
1552 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1553 EXPECT_EQ(resp_data.downstream_devices_length,
1554 downstream_devices_length_resp);
1555 EXPECT_EQ(resp_data.number_of_downstream_devices,
1556 number_of_downstream_devices_resp);
1557}
1558#endif
1559
1560#ifdef LIBPLDM_API_TESTING
1561TEST(QueryDownstreamIdentifiers, decodeResponseNoDevicesBadCount)
1562{
1563 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1564 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1565 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1566 constexpr uint32_t downstream_devices_length_resp = 0;
1567 constexpr uint16_t number_of_downstream_devices_resp = 1;
1568
1569 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1570 struct pldm_query_downstream_identifiers_resp resp = {};
1571 struct pldm_downstream_device_iter devs;
1572 struct pldm_downstream_device dev;
1573 struct pldm_msgbuf _buf;
1574 struct pldm_msgbuf* buf = &_buf;
1575 int rc = 0;
1576
1577 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1578 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1579 ASSERT_EQ(rc, 0);
1580
1581 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1582 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1583 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1584 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1585 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1586
1587 ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1588
1589 rc = decode_query_downstream_identifiers_resp(
1590 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08001591 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301592
1593 foreach_pldm_downstream_device(devs, dev, rc)
1594 {
1595 ASSERT_TRUE(false);
1596 }
1597 ASSERT_NE(rc, 0);
1598}
1599#endif
1600
1601#ifdef LIBPLDM_API_TESTING
1602TEST(QueryDownstreamIdentifiers, decodeResponseOneDeviceOneDescriptor)
1603{
1604 constexpr uint32_t downstreamDevicesLen = 11;
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301605 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
Chris Wang458475a2024-03-26 17:59:19 +08001606 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1607 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1608 const uint32_t downstream_devices_length_resp =
1609 htole32(downstreamDevicesLen);
1610 constexpr uint16_t number_of_downstream_devices_resp = 1;
Andrew Jefferydec237b2024-11-08 14:33:45 +10301611 constexpr size_t payloadLen =
1612 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstreamDevicesLen;
Chris Wang458475a2024-03-26 17:59:19 +08001613
Andrew Jefferydec237b2024-11-08 14:33:45 +10301614 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jefferydec237b2024-11-08 14:33:45 +10301615 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301616 struct pldm_downstream_device_iter devs;
1617 struct pldm_downstream_device dev;
Chris Wang458475a2024-03-26 17:59:19 +08001618 struct pldm_msgbuf _buf;
1619 struct pldm_msgbuf* buf = &_buf;
Andrew Jefferydec237b2024-11-08 14:33:45 +10301620 int rc = 0;
1621
1622 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1623 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08001624
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301625 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
Chris Wang458475a2024-03-26 17:59:19 +08001626 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1627 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1628 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1629 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1630
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301631 /* Downstream device */
1632 pldm_msgbuf_insert_uint16(buf, 1);
1633 pldm_msgbuf_insert_uint8(buf, 1);
Chris Wang458475a2024-03-26 17:59:19 +08001634
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301635 /* Device descriptor */
1636 pldm_msgbuf_insert_uint16(buf, 1);
1637 pldm_msgbuf_insert_uint16(buf, 4);
1638 pldm_msgbuf_insert_uint32(buf, 412);
Chris Wang458475a2024-03-26 17:59:19 +08001639
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301640 ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1641
1642 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1643 &resp_data, &devs);
1644
Unive Tien71e935c2024-11-25 17:21:43 +08001645 ASSERT_EQ(rc, 0);
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301646 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
Chris Wang458475a2024-03-26 17:59:19 +08001647 EXPECT_EQ(resp_data.next_data_transfer_handle,
1648 next_data_transfer_handle_resp);
1649 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1650 EXPECT_EQ(resp_data.downstream_devices_length,
1651 downstream_devices_length_resp);
1652 EXPECT_EQ(resp_data.number_of_downstream_devices,
1653 number_of_downstream_devices_resp);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301654
1655 foreach_pldm_downstream_device(devs, dev, rc)
1656 {
1657 struct pldm_descriptor desc;
1658
1659 EXPECT_EQ(dev.downstream_device_index, 1);
1660 EXPECT_EQ(dev.downstream_descriptor_count, 1);
1661
1662 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1663 {
1664 static const uint32_t dmtf = htole32(412);
1665 EXPECT_EQ(desc.descriptor_type, 1);
1666 EXPECT_EQ(desc.descriptor_length, 4);
1667 EXPECT_EQ(memcmp(desc.descriptor_data, &dmtf, sizeof(dmtf)), 0);
1668 }
1669 ASSERT_EQ(rc, 0);
1670 }
1671 ASSERT_EQ(rc, 0);
1672}
1673#endif
1674
1675#ifdef LIBPLDM_API_TESTING
1676constexpr const uint16_t descriptor_id_type_iana_pen = 0x1;
1677constexpr const uint16_t descriptor_id_len_iana_pen = 0x4;
1678const uint32_t iana_pen_openbmc = htole16(49871u);
1679const uint32_t iana_pen_dmtf = htole16(412u);
1680#endif
1681
1682#ifdef LIBPLDM_API_TESTING
1683TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneDescriptorEach)
1684{
1685 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1686 {0, 1},
1687 {1, 1},
1688 }};
1689
1690 constexpr const std::array<pldm_descriptor, 2> expected_descriptors = {{
1691 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1692 &iana_pen_dmtf},
1693 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1694 &iana_pen_openbmc},
1695 }};
1696
1697 constexpr uint32_t downstream_devices_len = 22;
1698 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1699 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1700 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1701 const uint32_t downstream_devices_length_resp =
1702 htole32(downstream_devices_len);
1703 constexpr uint16_t number_of_downstream_devices_resp = 2;
1704 constexpr size_t payloadLen =
1705 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
1706
1707 struct pldm_query_downstream_identifiers_resp resp_data
1708 {
1709 };
1710 PLDM_MSG_DEFINE_P(response, payloadLen);
1711 struct pldm_downstream_device_iter devs;
1712 struct pldm_downstream_device dev;
1713 struct pldm_msgbuf _buf;
1714 struct pldm_msgbuf* buf = &_buf;
1715 int rc = 0;
1716
1717 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1718 ASSERT_EQ(rc, 0);
1719
1720 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1721 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1722 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1723 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1724 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1725
1726 /* Downstream device */
1727 pldm_msgbuf_insert_uint16(buf, 0);
1728 pldm_msgbuf_insert_uint8(buf, 1);
1729
1730 /* Device descriptor */
1731 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1732 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1733 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1734
1735 /* Downstream device */
1736 pldm_msgbuf_insert_uint16(buf, 1);
1737 pldm_msgbuf_insert_uint8(buf, 1);
1738
1739 /* Device descriptor */
1740 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1741 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1742 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
1743
1744 ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1745
1746 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1747 &resp_data, &devs);
1748
Unive Tien71e935c2024-11-25 17:21:43 +08001749 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301750 EXPECT_EQ(resp_data.number_of_downstream_devices,
1751 number_of_downstream_devices_resp);
1752
1753 size_t devIndex = 0;
1754 size_t descIndex = 0;
1755 foreach_pldm_downstream_device(devs, dev, rc)
1756 {
1757 struct pldm_descriptor desc;
1758
1759 ASSERT_LT(devIndex, expected_devices.size());
1760
1761 const struct pldm_downstream_device* expectedDev =
1762 &expected_devices[devIndex];
1763
1764 EXPECT_EQ(dev.downstream_device_index,
1765 expectedDev->downstream_device_index);
1766 EXPECT_EQ(dev.downstream_descriptor_count,
1767 expectedDev->downstream_descriptor_count);
1768
1769 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1770 {
1771 ASSERT_LT(descIndex, expected_descriptors.size());
1772
1773 const struct pldm_descriptor* expectedDesc =
1774 &expected_descriptors[descIndex];
1775
1776 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
1777 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
1778 EXPECT_EQ(memcmp(desc.descriptor_data,
1779 expectedDesc->descriptor_data,
1780 expectedDesc->descriptor_length),
1781 0);
1782
1783 descIndex++;
1784 }
1785 ASSERT_EQ(rc, 0);
1786 EXPECT_EQ(descIndex, 1 * devIndex + 1);
1787
1788 devIndex++;
1789 }
1790 ASSERT_EQ(rc, 0);
1791 EXPECT_EQ(devIndex, 2);
1792}
1793#endif
1794
1795#ifdef LIBPLDM_API_TESTING
1796TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesTwoOneDescriptors)
1797{
1798 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1799 {0, 2},
1800 {1, 1},
1801 }};
1802
1803 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
1804 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1805 &iana_pen_dmtf},
1806 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1807 &iana_pen_openbmc},
1808 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1809 &iana_pen_dmtf},
1810 }};
1811
1812 constexpr uint32_t downstream_devices_len = 30;
1813 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1814 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1815 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1816 const uint32_t downstream_devices_length_resp =
1817 htole32(downstream_devices_len);
1818 constexpr uint16_t number_of_downstream_devices_resp = 2;
1819 constexpr size_t payloadLen =
1820 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
1821
1822 struct pldm_query_downstream_identifiers_resp resp_data
1823 {
1824 };
1825 PLDM_MSG_DEFINE_P(response, payloadLen);
1826 struct pldm_downstream_device_iter devs;
1827 struct pldm_downstream_device dev;
1828 struct pldm_msgbuf _buf;
1829 struct pldm_msgbuf* buf = &_buf;
1830 int rc = 0;
1831
1832 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1833 ASSERT_EQ(rc, 0);
1834
1835 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1836 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1837 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1838 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1839 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1840
1841 /* Downstream device */
1842 pldm_msgbuf_insert_uint16(buf, 0);
1843 pldm_msgbuf_insert_uint8(buf, 2);
1844
1845 /* Device descriptor */
1846 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1847 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1848 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1849
1850 /* Device descriptor */
1851 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1852 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1853 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
1854
1855 /* Downstream device */
1856 pldm_msgbuf_insert_uint16(buf, 1);
1857 pldm_msgbuf_insert_uint8(buf, 1);
1858
1859 /* Device descriptor */
1860 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1861 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1862 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1863
1864 ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1865
1866 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1867 &resp_data, &devs);
1868
Unive Tien71e935c2024-11-25 17:21:43 +08001869 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301870 EXPECT_EQ(resp_data.number_of_downstream_devices,
1871 number_of_downstream_devices_resp);
1872
1873 size_t devIndex = 0;
1874 size_t descIndex = 0;
1875 foreach_pldm_downstream_device(devs, dev, rc)
1876 {
1877 struct pldm_descriptor desc;
1878
1879 ASSERT_LT(devIndex, expected_devices.size());
1880
1881 const struct pldm_downstream_device* expectedDev =
1882 &expected_devices[devIndex];
1883
1884 EXPECT_EQ(dev.downstream_device_index,
1885 expectedDev->downstream_device_index);
1886 EXPECT_EQ(dev.downstream_descriptor_count,
1887 expectedDev->downstream_descriptor_count);
1888
1889 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1890 {
1891 ASSERT_LT(descIndex, expected_descriptors.size());
1892
1893 const struct pldm_descriptor* expectedDesc =
1894 &expected_descriptors[descIndex];
1895
1896 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
1897 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
1898 EXPECT_EQ(memcmp(desc.descriptor_data,
1899 expectedDesc->descriptor_data,
1900 expectedDesc->descriptor_length),
1901 0);
1902
1903 descIndex++;
1904 }
1905 ASSERT_EQ(rc, 0);
1906
1907 devIndex++;
1908 }
1909 ASSERT_EQ(rc, 0);
1910 EXPECT_EQ(devIndex, 2);
1911 EXPECT_EQ(descIndex, 3);
1912}
1913#endif
1914
1915#ifdef LIBPLDM_API_TESTING
1916TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneTwoDescriptors)
1917{
1918 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1919 {0, 1},
1920 {1, 2},
1921 }};
1922
1923 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
1924 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1925 &iana_pen_dmtf},
1926 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1927 &iana_pen_openbmc},
1928 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1929 &iana_pen_dmtf},
1930 }};
1931
1932 constexpr uint32_t downstream_devices_len = 30;
1933 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1934 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1935 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1936 const uint32_t downstream_devices_length_resp =
1937 htole32(downstream_devices_len);
1938 constexpr uint16_t number_of_downstream_devices_resp = 2;
1939 constexpr size_t payloadLen =
1940 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
1941
1942 struct pldm_query_downstream_identifiers_resp resp_data
1943 {
1944 };
1945 PLDM_MSG_DEFINE_P(response, payloadLen);
1946 struct pldm_downstream_device_iter devs;
1947 struct pldm_downstream_device dev;
1948 struct pldm_msgbuf _buf;
1949 struct pldm_msgbuf* buf = &_buf;
1950 int rc = 0;
1951
1952 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1953 ASSERT_EQ(rc, 0);
1954
1955 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1956 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1957 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1958 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1959 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1960
1961 /* Downstream device */
1962 pldm_msgbuf_insert_uint16(buf, 0);
1963 pldm_msgbuf_insert_uint8(buf, 1);
1964
1965 /* Device descriptor */
1966 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1967 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1968 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1969
1970 /* Downstream device */
1971 pldm_msgbuf_insert_uint16(buf, 1);
1972 pldm_msgbuf_insert_uint8(buf, 2);
1973
1974 /* Device descriptor */
1975 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1976 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1977 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
1978
1979 /* Device descriptor */
1980 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1981 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1982 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1983
1984 ASSERT_EQ(pldm_msgbuf_destroy_consumed(buf), 0);
1985
1986 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1987 &resp_data, &devs);
1988
Unive Tien71e935c2024-11-25 17:21:43 +08001989 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301990 EXPECT_EQ(resp_data.number_of_downstream_devices,
1991 number_of_downstream_devices_resp);
1992
1993 size_t devIndex = 0;
1994 size_t descIndex = 0;
1995 foreach_pldm_downstream_device(devs, dev, rc)
1996 {
1997 struct pldm_descriptor desc;
1998
1999 ASSERT_LT(devIndex, expected_devices.size());
2000
2001 const struct pldm_downstream_device* expectedDev =
2002 &expected_devices[devIndex];
2003
2004 EXPECT_EQ(dev.downstream_device_index,
2005 expectedDev->downstream_device_index);
2006 EXPECT_EQ(dev.downstream_descriptor_count,
2007 expectedDev->downstream_descriptor_count);
2008
2009 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2010 {
2011 ASSERT_LT(descIndex, expected_descriptors.size());
2012
2013 const struct pldm_descriptor* expectedDesc =
2014 &expected_descriptors[descIndex];
2015
2016 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2017 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2018 EXPECT_EQ(memcmp(desc.descriptor_data,
2019 expectedDesc->descriptor_data,
2020 expectedDesc->descriptor_length),
2021 0);
2022
2023 descIndex++;
2024 }
2025 ASSERT_EQ(rc, 0);
2026
2027 devIndex++;
2028 }
2029 ASSERT_EQ(rc, 0);
2030 EXPECT_EQ(devIndex, 2);
2031 EXPECT_EQ(descIndex, 3);
Chris Wang458475a2024-03-26 17:59:19 +08002032}
Andrew Jeffery688be622024-05-23 11:22:51 +09302033#endif
Chris Wang458475a2024-03-26 17:59:19 +08002034
Andrew Jeffery688be622024-05-23 11:22:51 +09302035#ifdef LIBPLDM_API_TESTING
Chris Wang458475a2024-03-26 17:59:19 +08002036TEST(QueryDownstreamIdentifiers, decodeRequestErrorPaths)
2037{
Andrew Jefferydec237b2024-11-08 14:33:45 +10302038 constexpr size_t payloadLen = sizeof(uint8_t);
2039
Chris Wang458475a2024-03-26 17:59:19 +08002040 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302041 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302042 PLDM_MSG_DEFINE_P(response, payloadLen);
Chris Wang458475a2024-03-26 17:59:19 +08002043
2044 // Test nullptr
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302045 auto rc = decode_query_downstream_identifiers_resp(nullptr, payloadLen,
2046 nullptr, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08002047 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08002048
2049 // Test not PLDM_SUCCESS completion code
2050 response->payload[0] = PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302051 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2052 &resp_data, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08002053 EXPECT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002054 EXPECT_EQ(resp_data.completion_code, PLDM_ERROR_UNSUPPORTED_PLDM_CMD);
2055
2056 // Test payload length less than minimum length
2057 response->payload[0] = PLDM_SUCCESS;
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302058 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2059 &resp_data, &devs);
Chris Wang458475a2024-03-26 17:59:19 +08002060
Unive Tien71e935c2024-11-25 17:21:43 +08002061 EXPECT_EQ(rc, -EBADMSG);
Chris Wang458475a2024-03-26 17:59:19 +08002062}
Andrew Jeffery688be622024-05-23 11:22:51 +09302063#endif
Chris Wang458475a2024-03-26 17:59:19 +08002064
Andrew Jeffery688be622024-05-23 11:22:51 +09302065#ifdef LIBPLDM_API_TESTING
Chris Wang458475a2024-03-26 17:59:19 +08002066TEST(QueryDownstreamIdentifiers, decodeRequestErrorDownstreamDevicesSize)
2067{
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +05302068 // Len is not fixed here taking it as 9, contains 1 downstream device with
Chris Wang458475a2024-03-26 17:59:19 +08002069 // 1 descriptor
2070 constexpr uint32_t actualDownstreamDevicesLen = 9;
2071 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2072 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2073 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302074 constexpr uint16_t number_of_downstream_devices_resp = 1;
2075 constexpr size_t payloadLen =
2076 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN +
2077 actualDownstreamDevicesLen;
2078
Chris Wang458475a2024-03-26 17:59:19 +08002079 const uint32_t downstream_devices_length_resp =
2080 htole32(actualDownstreamDevicesLen + 1 /* inject error length*/);
Chris Wang458475a2024-03-26 17:59:19 +08002081
Andrew Jefferydec237b2024-11-08 14:33:45 +10302082 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302083 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302084 PLDM_MSG_DEFINE_P(response, payloadLen);
Chris Wang458475a2024-03-26 17:59:19 +08002085 struct pldm_msgbuf _buf;
2086 struct pldm_msgbuf* buf = &_buf;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302087 void* devicesStart = NULL;
2088 size_t devicesLen;
2089 int rc = 0;
2090
2091 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09302092 EXPECT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002093
2094 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2095 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2096 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2097 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2098 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302099 pldm_msgbuf_span_remaining(buf, &devicesStart, &devicesLen);
Chris Wang458475a2024-03-26 17:59:19 +08002100
2101 /** Filling descriptor data, the correctness of the downstream devices data
2102 * is not checked in this test case so filling with 0xff
2103 */
Andrew Jefferydec237b2024-11-08 14:33:45 +10302104 std::fill_n(static_cast<uint8_t*>(devicesStart), actualDownstreamDevicesLen,
2105 0xff);
Chris Wang458475a2024-03-26 17:59:19 +08002106
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302107 EXPECT_NE(decode_query_downstream_identifiers_resp(response, payloadLen,
2108 &resp_data, &devs),
Unive Tien71e935c2024-11-25 17:21:43 +08002109 0);
Chris Wang458475a2024-03-26 17:59:19 +08002110}
Andrew Jeffery688be622024-05-23 11:22:51 +09302111#endif
Chris Wang458475a2024-03-26 17:59:19 +08002112
Andrew Jeffery688be622024-05-23 11:22:51 +09302113#ifdef LIBPLDM_API_TESTING
Chris Wang458475a2024-03-26 17:59:19 +08002114TEST(QueryDownstreamIdentifiers, decodeRequestErrorBufSize)
2115{
2116 constexpr uint32_t actualDownstreamDevicesLen = 0;
2117 constexpr uint16_t number_of_downstream_devices_resp = 1;
2118 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2119 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2120 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302121 constexpr size_t payloadLen =
2122 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN - 1;
2123
Chris Wang458475a2024-03-26 17:59:19 +08002124 const uint32_t downstream_devices_length_resp =
2125 htole32(actualDownstreamDevicesLen);
2126
Andrew Jefferydec237b2024-11-08 14:33:45 +10302127 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302128 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302129 PLDM_MSG_DEFINE_P(response, payloadLen);
Chris Wang458475a2024-03-26 17:59:19 +08002130 struct pldm_msgbuf _buf;
2131 struct pldm_msgbuf* buf = &_buf;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302132 int rc = 0;
2133
2134 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2135 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002136
2137 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2138 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2139 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2140 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2141 // Inject error buffer size
2142 pldm_msgbuf_insert_uint8(buf, (uint8_t)number_of_downstream_devices_resp);
2143
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302144 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2145 &resp_data, &devs);
Chris Wang458475a2024-03-26 17:59:19 +08002146
Unive Tien71e935c2024-11-25 17:21:43 +08002147 EXPECT_EQ(rc, -EBADMSG);
Chris Wang458475a2024-03-26 17:59:19 +08002148}
Andrew Jeffery688be622024-05-23 11:22:51 +09302149#endif
Chris Wang458475a2024-03-26 17:59:19 +08002150
Chris Wangb6ef35b2024-07-03 09:35:42 +08002151#ifdef LIBPLDM_API_TESTING
2152TEST(GetDownstreamFirmwareParameters, goodPathEncodeRequest)
2153{
2154 constexpr uint8_t instanceId = 1;
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302155 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002156 0x0, PLDM_GET_FIRSTPART};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002157 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302158 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002159 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302160 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002161 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2162
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302163 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002164 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002165 EXPECT_EQ(rc, 0);
2166
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302167 std::array<uint8_t,
2168 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES>
Chris Wangb6ef35b2024-07-03 09:35:42 +08002169 expectedReq{0x81, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01};
2170 EXPECT_EQ(requestMsg, expectedReq);
2171}
2172#endif
2173
2174#ifdef LIBPLDM_API_TESTING
2175TEST(GetDownstreamFirmwareParameters, encodeRequestInvalidTransferOperationFlag)
2176{
2177 constexpr uint8_t instanceId = 1;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002178 // Setup invalid transfer operation flag
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302179 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002180 0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002181 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302182 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002183 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302184 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002185 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2186
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302187 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002188 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002189 EXPECT_EQ(rc, -EBADMSG);
2190}
2191#endif
2192
2193#ifdef LIBPLDM_API_TESTING
2194TEST(GetDownstreamFirmwareParameters, encodeRequestErrorBufSize)
2195{
2196 constexpr uint8_t instanceId = 1;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002197 // Setup invalid transfer operation flag
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302198 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002199 0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002200 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302201 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES -
Chris Wangb6ef35b2024-07-03 09:35:42 +08002202 1 /* inject erro length*/;
2203
2204 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302205 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002206 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2207
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302208 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002209 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002210 EXPECT_EQ(rc, -EOVERFLOW);
2211}
2212#endif
2213
2214#ifdef LIBPLDM_API_TESTING
2215TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponse)
2216{
2217 /** Count is not fixed here taking it as 1, and the downstream device's
2218 * version strings length are set to 8
2219 */
2220 constexpr uint16_t downstreamDeviceCount = 1;
2221 constexpr uint8_t activeComponentVersionStringLength = 8;
2222 constexpr uint8_t pendingComponentVersionStringLength = 8;
2223 constexpr size_t downstreamDeviceParamTableLen =
2224 sizeof(pldm_component_parameter_entry) +
2225 activeComponentVersionStringLength +
2226 pendingComponentVersionStringLength;
2227 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2228 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2229 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2230 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2231
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302232 std::array<uint8_t,
2233 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2234 downstreamDeviceParamTableLen>
Chris Wangb6ef35b2024-07-03 09:35:42 +08002235 responseMsg{};
2236
2237 int rc = 0;
2238
2239 struct pldm_msgbuf _buf;
2240 struct pldm_msgbuf* buf = &_buf;
2241 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
2242 responseMsg.size() - hdrSize);
2243 EXPECT_EQ(rc, 0);
2244
2245 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2246 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2247 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2248 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2249 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2250
2251 /** Filling paramter table, the correctness of the downstream devices data
2252 * is not checked in this test case so filling with 0xff
2253 */
2254 std::fill_n(responseMsg.data() + hdrSize +
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302255 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN,
Chris Wangb6ef35b2024-07-03 09:35:42 +08002256 downstreamDeviceParamTableLen, 0xff);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302257 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002258 auto table = reinterpret_cast<pldm_component_parameter_entry*>(
2259 responseMsg.data() + hdrSize +
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302260 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002261 table->active_comp_ver_str_len = activeComponentVersionStringLength;
2262 table->pending_comp_ver_str_len = pendingComponentVersionStringLength;
2263
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302264 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002265 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302266 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002267 struct variable_field downstreamDeviceParamTable = {};
2268
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302269 rc = decode_get_downstream_firmware_parameters_resp(
Chris Wangb6ef35b2024-07-03 09:35:42 +08002270 response, responseMsg.size() - hdrSize, &resp_data,
2271 &downstreamDeviceParamTable);
2272
2273 EXPECT_EQ(rc, 0);
2274 EXPECT_EQ(resp_data.completion_code, complition_code_resp);
2275 EXPECT_EQ(resp_data.next_data_transfer_handle,
2276 next_data_transfer_handle_resp);
2277 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2278 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
2279 EXPECT_EQ(downstreamDeviceParamTable.length, downstreamDeviceParamTableLen);
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302280 EXPECT_EQ(
2281 true,
2282 std::equal(downstreamDeviceParamTable.ptr,
2283 downstreamDeviceParamTable.ptr +
2284 downstreamDeviceParamTable.length,
2285 responseMsg.begin() + hdrSize +
2286 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN,
2287 responseMsg.end()));
Chris Wangb6ef35b2024-07-03 09:35:42 +08002288}
2289#endif
2290
2291#ifdef LIBPLDM_API_TESTING
2292TEST(GetDownstreamFirmwareParameters, decodeResponseInvalidLength)
2293{
2294 /** Count is not fixed here taking it as 1, and the downstream device's
2295 * version strings length are set to 8
2296 */
2297 constexpr uint16_t downstreamDeviceCount = 1;
2298 constexpr uint8_t activeComponentVersionStringLength = 8;
2299 constexpr uint8_t pendingComponentVersionStringLength = 8;
2300 constexpr size_t downstreamDeviceParamTableLen =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302301 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002302 activeComponentVersionStringLength +
2303 pendingComponentVersionStringLength;
2304 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2305 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2306 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2307 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2308
2309 std::array<uint8_t,
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302310 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002311 downstreamDeviceParamTableLen - 1 /* inject error length*/>
2312 responseMsg{};
2313
2314 int rc = 0;
2315
2316 struct pldm_msgbuf _buf;
2317 struct pldm_msgbuf* buf = &_buf;
2318 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
2319 responseMsg.size() - hdrSize);
2320 EXPECT_EQ(rc, 0);
2321
2322 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2323 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2324 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2325 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2326 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2327
2328 /** Filling paramter table, the correctness of the downstream devices data
2329 * is not checked in this test case so filling with 0xff
2330 */
2331 std::fill_n(responseMsg.data() + hdrSize +
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302332 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN,
Chris Wangb6ef35b2024-07-03 09:35:42 +08002333 downstreamDeviceParamTableLen - 1 /* inject error length*/,
2334 0xff);
2335
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302336 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002337 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302338 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002339 struct variable_field downstreamDeviceParamTable = {};
2340
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302341 rc = decode_get_downstream_firmware_parameters_resp(
Chris Wangb6ef35b2024-07-03 09:35:42 +08002342 response, responseMsg.size() - hdrSize, &resp_data,
2343 &downstreamDeviceParamTable);
2344 EXPECT_EQ(rc, 0);
2345
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302346 pldm_downstream_device_parameters_entry entry{};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002347 variable_field versions{};
2348
Chris Wangb6ef35b2024-07-03 09:35:42 +08002349 EXPECT_NE(decode_downstream_device_parameter_table_entry(
2350 &downstreamDeviceParamTable, &entry, &versions),
2351 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002352}
2353#endif
2354
2355#ifdef LIBPLDM_API_TESTING
2356TEST(GetDownstreamFirmwareParameters, goodPathDecodeDownstreamDeviceParamTable)
2357{
2358 // Arbitrary downstream device index
2359 constexpr uint16_t downstreamDeviceIndex = 1;
2360 // Arbitrary value for component classification
2361 constexpr uint32_t comparisonStamp = 0x12345678;
2362 // Arbitrary value for component activation methods
2363 constexpr uint16_t compActivationMethods = 0xbbdd;
2364 // Arbitrary value for capabilities during update
2365 constexpr uint32_t capabilitiesDuringUpdate = 0xbadbeefe;
2366 // ActiveCompImageSetVerStrLen is not fixed here taking it as 8
2367 constexpr uint8_t activeCompVerStrLen = 8;
2368 // PendingCompImageSetVerStrLen is not fixed here taking it as 8
2369 constexpr uint8_t pendingCompVerStrLen = 8;
2370 // Arbitrary value for release date
2371 constexpr char release_date[8] = {'2', '0', '2', '4', '0', '6', '2', '1'};
2372 // Arbitrary version strings
2373 constexpr char activeCompVerStr[activeCompVerStrLen] = {'1', '2', '3', '4',
2374 '5', '6', '7', '8'};
2375 constexpr char pendingCompVerStr[pendingCompVerStrLen] = {
2376 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
2377
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302378 std::array<uint8_t, PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002379 activeCompVerStrLen + pendingCompVerStrLen>
2380 responseMsg{};
2381
2382 int rc = 0;
2383
2384 struct pldm_msgbuf _buf;
2385 struct pldm_msgbuf* buf = &_buf;
2386 rc = pldm_msgbuf_init_errno(buf,
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302387 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN,
Chris Wangb6ef35b2024-07-03 09:35:42 +08002388 responseMsg.data(), responseMsg.size());
2389 EXPECT_EQ(rc, 0);
2390
2391 pldm_msgbuf_insert_uint16(buf, downstreamDeviceIndex);
2392 pldm_msgbuf_insert_uint32(buf, comparisonStamp);
2393 pldm_msgbuf_insert_uint8(buf, (uint8_t)PLDM_STR_TYPE_ASCII);
2394 pldm_msgbuf_insert_uint8(buf, activeCompVerStrLen);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00002395 rc = pldm_msgbuf_insert_array_char(buf, sizeof(release_date), release_date,
2396 sizeof(release_date));
2397 ASSERT_EQ(rc, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002398 pldm_msgbuf_insert_uint32(buf, comparisonStamp);
2399 pldm_msgbuf_insert_uint8(buf, (uint8_t)PLDM_STR_TYPE_ASCII);
2400 pldm_msgbuf_insert_uint8(buf, pendingCompVerStrLen);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00002401 rc = pldm_msgbuf_insert_array_char(buf, sizeof(release_date), release_date,
2402 sizeof(release_date));
2403 ASSERT_EQ(rc, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002404 pldm_msgbuf_insert_uint16(buf, compActivationMethods);
2405 pldm_msgbuf_insert_uint32(buf, capabilitiesDuringUpdate);
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +00002406 rc = pldm_msgbuf_insert_array_char(
2407 buf, activeCompVerStrLen, activeCompVerStr, sizeof(activeCompVerStr));
2408 ASSERT_EQ(rc, 0);
2409 rc = pldm_msgbuf_insert_array_char(buf, pendingCompVerStrLen,
2410 pendingCompVerStr,
2411 sizeof(pendingCompVerStr));
2412 ASSERT_EQ(rc, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002413
2414 variable_field rawData = {.ptr = responseMsg.data(),
2415 .length = responseMsg.size()};
2416 struct pldm_downstream_device_parameter_entry_versions entry_version = {};
2417 struct variable_field versions = {};
2418 const uint8_t* original_ptr = rawData.ptr;
2419
2420 rc = decode_downstream_device_parameter_table_entry(
2421 &rawData, &entry_version.entry, &versions);
2422
2423 EXPECT_EQ(rc, 0);
2424 EXPECT_EQ(rawData.ptr, original_ptr +
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302425 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002426 entry_version.entry.active_comp_ver_str_len +
2427 entry_version.entry.pending_comp_ver_str_len);
2428 EXPECT_EQ(rawData.length, 0);
2429
2430 // Further decode the version strings
2431 rc = decode_downstream_device_parameter_table_entry_versions(
2432 &versions, &entry_version.entry, entry_version.active_comp_ver_str,
Andrew Jefferya9892492024-10-03 14:07:17 +09302433 sizeof(entry_version.active_comp_ver_str),
2434 entry_version.pending_comp_ver_str,
2435 sizeof(entry_version.pending_comp_ver_str));
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302436 struct pldm_downstream_device_parameters_entry entry = entry_version.entry;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002437 EXPECT_EQ(rc, 0);
2438
2439 // Verify the decoded table entry
2440 EXPECT_EQ(entry.downstream_device_index, downstreamDeviceIndex);
2441 EXPECT_EQ(entry.active_comp_comparison_stamp, comparisonStamp);
2442 EXPECT_EQ(entry.active_comp_ver_str_type, PLDM_STR_TYPE_ASCII);
2443 EXPECT_EQ(entry.active_comp_ver_str_len, activeCompVerStrLen);
2444 EXPECT_EQ(0, memcmp(entry.active_comp_release_date, release_date,
2445 sizeof(release_date)));
2446 EXPECT_EQ(entry.pending_comp_comparison_stamp, comparisonStamp);
2447 EXPECT_EQ(entry.pending_comp_ver_str_type, PLDM_STR_TYPE_ASCII);
2448 EXPECT_EQ(entry.pending_comp_ver_str_len, pendingCompVerStrLen);
2449 EXPECT_EQ(0, memcmp(entry.pending_comp_release_date, release_date,
2450 sizeof(release_date)));
2451 EXPECT_EQ(entry.comp_activation_methods.value, compActivationMethods);
2452 EXPECT_EQ(entry.capabilities_during_update.value, capabilitiesDuringUpdate);
2453 EXPECT_EQ(entry.active_comp_ver_str_len + entry.pending_comp_ver_str_len,
2454 versions.length);
2455 EXPECT_EQ(0, memcmp(versions.ptr, activeCompVerStr, activeCompVerStrLen));
2456 EXPECT_EQ(0, memcmp(versions.ptr + entry.active_comp_ver_str_len,
2457 pendingCompVerStr, pendingCompVerStrLen));
2458
2459 // Verify version strings
2460 EXPECT_EQ(0, memcmp(entry_version.entry.active_comp_ver_str,
2461 activeCompVerStr, activeCompVerStrLen));
2462 EXPECT_EQ('\0',
2463 entry_version.entry.active_comp_ver_str[activeCompVerStrLen]);
2464 EXPECT_EQ(0, memcmp(entry_version.entry.pending_comp_ver_str,
2465 pendingCompVerStr, pendingCompVerStrLen));
2466 EXPECT_EQ('\0',
2467 entry_version.entry.pending_comp_ver_str[pendingCompVerStrLen]);
2468 EXPECT_EQ(0, memcmp(entry_version.active_comp_ver_str, activeCompVerStr,
2469 activeCompVerStrLen));
2470 EXPECT_EQ('\0', entry_version.active_comp_ver_str[activeCompVerStrLen]);
2471 EXPECT_EQ(0, memcmp(entry_version.pending_comp_ver_str, pendingCompVerStr,
2472 pendingCompVerStrLen));
2473 EXPECT_EQ('\0', entry_version.pending_comp_ver_str[pendingCompVerStrLen]);
2474}
2475#endif
2476
2477#ifdef LIBPLDM_API_TESTING
2478TEST(GetDownstreamFirmwareParameters, goodPathDecodeDownstreamTableVersions)
2479{
2480 // Arbitrary component version string length
2481 constexpr uint8_t activeCompVerStrLen = 8;
2482 constexpr uint8_t pendingCompVerStrLen = 8;
2483 // Arbitrary ActiveVersionStr and pendingVersionStr
2484 constexpr char versionsStr[] = {'1', '2', '3', '4', '5', '6', '7', '8',
2485 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
2486 const struct variable_field versions = {
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302487 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002488 .ptr = reinterpret_cast<const uint8_t*>(versionsStr),
2489 .length = sizeof(versionsStr)};
2490
2491 struct pldm_downstream_device_parameter_entry_versions entryVersion = {};
2492 entryVersion.entry.active_comp_ver_str_len = activeCompVerStrLen;
2493 entryVersion.entry.pending_comp_ver_str_len = pendingCompVerStrLen;
2494
2495 int rc = decode_downstream_device_parameter_table_entry_versions(
2496 &versions, &entryVersion.entry, entryVersion.active_comp_ver_str,
Andrew Jefferya9892492024-10-03 14:07:17 +09302497 sizeof(entryVersion.active_comp_ver_str),
2498 entryVersion.pending_comp_ver_str,
2499 sizeof(entryVersion.pending_comp_ver_str));
Chris Wangb6ef35b2024-07-03 09:35:42 +08002500
2501 EXPECT_EQ(rc, 0);
2502 EXPECT_EQ(0, memcmp(entryVersion.active_comp_ver_str, versions.ptr,
2503 activeCompVerStrLen));
2504 EXPECT_EQ('\0', entryVersion.active_comp_ver_str[activeCompVerStrLen]);
2505 EXPECT_EQ(0,
2506 memcmp(entryVersion.pending_comp_ver_str,
2507 versions.ptr + activeCompVerStrLen, pendingCompVerStrLen));
2508 EXPECT_EQ('\0', entryVersion.pending_comp_ver_str[activeCompVerStrLen]);
2509 EXPECT_EQ(0, memcmp(entryVersion.entry.active_comp_ver_str, versions.ptr,
2510 activeCompVerStrLen));
2511 EXPECT_EQ('\0',
2512 entryVersion.entry.pending_comp_ver_str[activeCompVerStrLen]);
2513 EXPECT_EQ(0,
2514 memcmp(entryVersion.entry.pending_comp_ver_str,
2515 versions.ptr + activeCompVerStrLen, pendingCompVerStrLen));
2516 EXPECT_EQ('\0',
2517 entryVersion.entry.pending_comp_ver_str[activeCompVerStrLen]);
2518}
2519#endif
2520
2521#ifdef LIBPLDM_API_TESTING
2522TEST(GetDownstreamFirmwareParameters, decodeInvalidDownstreamTableVersions)
2523{
2524 // Arbitrary ActiveVersionStr and pendingVersionStr
2525 constexpr char versionsStr[] = {'1', '2', '3', '4', '5', '6', '7', '8',
2526 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
2527 const struct variable_field versions = {
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302528 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002529 .ptr = reinterpret_cast<const uint8_t*>(versionsStr),
2530 .length = sizeof(versionsStr)};
2531
2532 struct pldm_downstream_device_parameter_entry_versions entryVersion = {};
2533
2534 int rc = decode_downstream_device_parameter_table_entry_versions(
2535 &versions, nullptr, entryVersion.active_comp_ver_str,
Andrew Jefferya9892492024-10-03 14:07:17 +09302536 sizeof(entryVersion.active_comp_ver_str),
2537 entryVersion.pending_comp_ver_str,
2538 sizeof(entryVersion.pending_comp_ver_str));
Chris Wangb6ef35b2024-07-03 09:35:42 +08002539 EXPECT_EQ(rc, -EINVAL);
2540}
2541#endif
2542
2543#ifdef LIBPLDM_API_TESTING
2544TEST(GetDownstreamFirmwareParameters, decodeOverflowDownstreamTableVersions)
2545{
2546 // Arbitrary component version string length
2547 constexpr uint8_t activeCompVerStrLen = 8;
2548 constexpr uint8_t pendingCompVerStrLen = 8;
2549 // Arbitrary ActiveVersionStr and pendingVersionStr
2550 constexpr char versionsStr[] = {'1', '2', '3', '4', '5', '6', '7', '8',
2551 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
2552 const struct variable_field versions = {
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302553 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002554 .ptr = reinterpret_cast<const uint8_t*>(versionsStr),
2555 .length = sizeof(versionsStr) - 1 // Inject error length
2556 };
2557
2558 struct pldm_downstream_device_parameter_entry_versions entryVersion = {};
2559 entryVersion.entry.active_comp_ver_str_len = activeCompVerStrLen;
2560 entryVersion.entry.pending_comp_ver_str_len = pendingCompVerStrLen;
2561
2562 EXPECT_EQ(decode_downstream_device_parameter_table_entry_versions(
2563 &versions, &entryVersion.entry,
2564 entryVersion.active_comp_ver_str,
Andrew Jefferya9892492024-10-03 14:07:17 +09302565 sizeof(entryVersion.active_comp_ver_str),
2566 entryVersion.pending_comp_ver_str,
2567 sizeof(entryVersion.pending_comp_ver_str)),
Chris Wangb6ef35b2024-07-03 09:35:42 +08002568 -EOVERFLOW);
2569}
2570#endif
2571
Andrew Jeffery9c766792022-08-10 23:12:49 +09302572TEST(RequestUpdate, goodPathEncodeRequest)
2573{
2574 constexpr uint8_t instanceId = 1;
2575 constexpr uint32_t maxTransferSize = 512;
2576 constexpr uint16_t numOfComp = 3;
2577 constexpr uint8_t maxOutstandingTransferReq = 2;
2578 constexpr uint16_t pkgDataLen = 0x1234;
2579 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2580 constexpr uint8_t compImgSetVerStrLen =
2581 static_cast<uint8_t>(compImgSetVerStr.size());
2582 variable_field compImgSetVerStrInfo{};
2583 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302584 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302585 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2586 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2587
2588 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2589 compImgSetVerStrLen>
2590 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302591 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302592 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2593
2594 auto rc = encode_request_update_req(
2595 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2596 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2597 &compImgSetVerStrInfo, requestMsg,
2598 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2599 EXPECT_EQ(rc, PLDM_SUCCESS);
2600
2601 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2602 compImgSetVerStrLen>
2603 outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00,
2604 0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e,
2605 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30};
2606 EXPECT_EQ(request, outRequest);
2607}
2608
2609TEST(RequestUpdate, errorPathEncodeRequest)
2610{
2611 constexpr uint8_t instanceId = 1;
2612 uint32_t maxTransferSize = 512;
2613 constexpr uint16_t numOfComp = 3;
2614 uint8_t maxOutstandingTransferReq = 2;
2615 constexpr uint16_t pkgDataLen = 0x1234;
2616 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2617 uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2618 variable_field compImgSetVerStrInfo{};
2619 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302620 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302621 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2622 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2623
2624 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2625 compImgSetVerStr.size()>
2626 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302627 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302628 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2629
2630 auto rc = encode_request_update_req(
2631 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2632 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr,
2633 requestMsg,
2634 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2635 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2636
2637 compImgSetVerStrInfo.ptr = nullptr;
2638 rc = encode_request_update_req(
2639 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2640 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2641 &compImgSetVerStrInfo, requestMsg,
2642 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2643 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2644 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302645 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302646 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2647
2648 rc = encode_request_update_req(
2649 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2650 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2651 &compImgSetVerStrInfo, nullptr,
2652 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2653 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2654
2655 rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp,
2656 maxOutstandingTransferReq, pkgDataLen,
2657 PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2658 &compImgSetVerStrInfo, requestMsg, 0);
2659 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2660
2661 compImgSetVerStrLen = 0;
2662 rc = encode_request_update_req(
2663 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2664 pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr,
2665 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2666 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2667 compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2668
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06002669 compImgSetVerStrInfo.length = 0xffff;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302670 rc = encode_request_update_req(
2671 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2672 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2673 &compImgSetVerStrInfo, nullptr,
2674 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2675 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2676 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2677
2678 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1;
2679 rc = encode_request_update_req(
2680 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2681 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2682 &compImgSetVerStrInfo, nullptr,
2683 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2684 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2685 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE;
2686
2687 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ - 1;
2688 rc = encode_request_update_req(
2689 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2690 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2691 &compImgSetVerStrInfo, nullptr,
2692 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2693 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2694 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ;
2695
2696 rc = encode_request_update_req(
2697 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2698 pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen,
2699 &compImgSetVerStrInfo, nullptr,
2700 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2701 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2702}
2703
2704TEST(RequestUpdate, goodPathDecodeResponse)
2705{
2706 constexpr uint16_t fdMetaDataLen = 1024;
2707 constexpr uint8_t fdWillSendPkgData = 1;
2708 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)>
2709 requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01};
2710
2711 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302712 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302713 reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data());
2714 uint8_t outCompletionCode = 0;
2715 uint16_t outFdMetaDataLen = 0;
2716 uint8_t outFdWillSendPkgData = 0;
2717
2718 auto rc = decode_request_update_resp(
2719 responseMsg1, requestUpdateResponse1.size() - hdrSize,
2720 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2721 EXPECT_EQ(rc, PLDM_SUCCESS);
2722 EXPECT_EQ(outCompletionCode, PLDM_SUCCESS);
2723 EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen);
2724 EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData);
2725
2726 outCompletionCode = 0;
2727 outFdMetaDataLen = 0;
2728 outFdWillSendPkgData = 0;
2729
2730 constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)>
2731 requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
2732 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302733 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302734 reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data());
2735 rc = decode_request_update_resp(
2736 responseMsg2, requestUpdateResponse2.size() - hdrSize,
2737 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2738 EXPECT_EQ(rc, PLDM_SUCCESS);
2739 EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
2740}
2741
2742TEST(RequestUpdate, errorPathDecodeResponse)
2743{
2744 constexpr std::array<uint8_t,
2745 hdrSize + sizeof(pldm_request_update_resp) - 1>
2746 requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
2747
2748 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302749 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302750 reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data());
2751 uint8_t outCompletionCode = 0;
2752 uint16_t outFdMetaDataLen = 0;
2753 uint8_t outFdWillSendPkgData = 0;
2754
2755 auto rc = decode_request_update_resp(
2756 nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2757 &outFdMetaDataLen, &outFdWillSendPkgData);
2758 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2759
2760 rc = decode_request_update_resp(
2761 responseMsg, requestUpdateResponse.size() - hdrSize, nullptr,
2762 &outFdMetaDataLen, &outFdWillSendPkgData);
2763 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2764
2765 rc = decode_request_update_resp(
2766 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2767 nullptr, &outFdWillSendPkgData);
2768 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2769
2770 rc = decode_request_update_resp(
2771 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2772 &outFdMetaDataLen, nullptr);
2773 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2774
2775 rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode,
2776 &outFdMetaDataLen, &outFdWillSendPkgData);
2777 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2778
2779 rc = decode_request_update_resp(
2780 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2781 &outFdMetaDataLen, &outFdWillSendPkgData);
2782 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2783}
2784
2785TEST(PassComponentTable, goodPathEncodeRequest)
2786{
2787 constexpr uint8_t instanceId = 1;
2788 constexpr uint16_t compIdentifier = 400;
2789 constexpr uint8_t compClassificationIndex = 40;
2790 constexpr uint32_t compComparisonStamp = 0x12345678;
2791 constexpr std::string_view compVerStr = "0penBmcv1.1";
2792 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2793 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302794 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302795 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2796 compVerStrInfo.length = compVerStrLen;
2797
2798 std::array<uint8_t,
2799 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2800 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302801 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302802 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2803
2804 auto rc = encode_pass_component_table_req(
2805 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2806 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2807 compVerStrLen, &compVerStrInfo, requestMsg,
2808 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2809 EXPECT_EQ(rc, PLDM_SUCCESS);
2810
2811 std::array<uint8_t,
2812 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06002813 outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28,
2814 0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65,
2815 0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31};
Andrew Jeffery9c766792022-08-10 23:12:49 +09302816 EXPECT_EQ(request, outRequest);
2817}
2818
2819TEST(PassComponentTable, errorPathEncodeRequest)
2820{
2821 constexpr uint8_t instanceId = 1;
2822 constexpr uint16_t compIdentifier = 400;
2823 constexpr uint8_t compClassificationIndex = 40;
2824 constexpr uint32_t compComparisonStamp = 0x12345678;
2825 constexpr std::string_view compVerStr = "0penBmcv1.1";
2826 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2827 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302828 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302829 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2830 compVerStrInfo.length = compVerStrLen;
2831
2832 std::array<uint8_t,
2833 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2834 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302835 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302836 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2837
2838 auto rc = encode_pass_component_table_req(
2839 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2840 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2841 compVerStrLen, nullptr, requestMsg,
2842 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2843 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2844
2845 compVerStrInfo.ptr = nullptr;
2846 rc = encode_pass_component_table_req(
2847 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2848 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2849 compVerStrLen, &compVerStrInfo, requestMsg,
2850 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2851 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302852 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302853 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2854
2855 rc = encode_pass_component_table_req(
2856 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2857 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2858 compVerStrLen, &compVerStrInfo, nullptr,
2859 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2860 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2861
2862 rc = encode_pass_component_table_req(
2863 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2864 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2865 compVerStrLen, &compVerStrInfo, requestMsg,
2866 sizeof(pldm_pass_component_table_req));
2867 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2868
2869 rc = encode_pass_component_table_req(
2870 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2871 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0,
2872 &compVerStrInfo, requestMsg,
2873 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2874 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2875
2876 rc = encode_pass_component_table_req(
2877 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2878 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2879 compVerStrLen - 1, &compVerStrInfo, requestMsg,
2880 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2881 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2882
2883 rc = encode_pass_component_table_req(
2884 instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier,
2885 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2886 compVerStrLen, &compVerStrInfo, requestMsg,
2887 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2888 EXPECT_EQ(rc, PLDM_INVALID_TRANSFER_OPERATION_FLAG);
2889
2890 rc = encode_pass_component_table_req(
2891 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2892 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN,
2893 compVerStrLen, &compVerStrInfo, requestMsg,
2894 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2895 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2896}
2897
2898TEST(PassComponentTable, goodPathDecodeResponse)
2899{
2900 constexpr std::array<uint8_t,
2901 hdrSize + sizeof(pldm_pass_component_table_resp)>
2902 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
2903 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302904 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302905 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
2906
2907 uint8_t completionCode = 0;
2908 uint8_t compResp = 0;
2909 uint8_t compRespCode = 0;
2910
2911 auto rc = decode_pass_component_table_resp(
2912 responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode,
2913 &compResp, &compRespCode);
2914
2915 EXPECT_EQ(rc, PLDM_SUCCESS);
2916 EXPECT_EQ(completionCode, PLDM_SUCCESS);
2917 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
2918 EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL);
2919
2920 constexpr std::array<uint8_t,
2921 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06002922 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09302923 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302924 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302925 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
2926 rc = decode_pass_component_table_resp(
2927 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
2928 &compResp, &compRespCode);
2929
2930 EXPECT_EQ(rc, PLDM_SUCCESS);
2931 EXPECT_EQ(completionCode, PLDM_SUCCESS);
2932 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
2933 EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN);
2934
2935 constexpr std::array<uint8_t,
2936 hdrSize + sizeof(pldm_pass_component_table_resp)>
2937 passCompTableResponse3{0x00, 0x00, 0x00, 0x80};
2938 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302939 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302940 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
2941
2942 rc = decode_pass_component_table_resp(
2943 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
2944 &compResp, &compRespCode);
2945
2946 EXPECT_EQ(rc, PLDM_SUCCESS);
2947 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
2948}
2949
2950TEST(PassComponentTable, errorPathDecodeResponse)
2951{
2952 constexpr std::array<uint8_t,
2953 hdrSize + sizeof(pldm_pass_component_table_resp) - 1>
2954 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00};
2955 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302956 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302957 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
2958
2959 uint8_t completionCode = 0;
2960 uint8_t compResp = 0;
2961 uint8_t compRespCode = 0;
2962
2963 auto rc = decode_pass_component_table_resp(
2964 nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode,
2965 &compResp, &compRespCode);
2966 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2967
2968 rc = decode_pass_component_table_resp(
2969 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr,
2970 &compResp, &compRespCode);
2971 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2972
2973 rc = decode_pass_component_table_resp(
2974 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
2975 &completionCode, nullptr, &compRespCode);
2976 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2977
2978 rc = decode_pass_component_table_resp(
2979 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
2980 &completionCode, &compResp, nullptr);
2981 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2982
2983 rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode,
2984 &compResp, &compRespCode);
2985 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2986
2987 rc = decode_pass_component_table_resp(
2988 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
2989 &completionCode, &compResp, &compRespCode);
2990 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2991
2992 constexpr std::array<uint8_t,
2993 hdrSize + sizeof(pldm_pass_component_table_resp)>
2994 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
2995 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302996 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302997 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
2998 rc = decode_pass_component_table_resp(
2999 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3000 &compResp, &compRespCode);
3001 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3002
3003 constexpr std::array<uint8_t,
3004 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003005 passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303006 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303007 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303008 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3009 rc = decode_pass_component_table_resp(
3010 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3011 &compResp, &compRespCode);
3012 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3013
3014 constexpr std::array<uint8_t,
3015 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003016 passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303017 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303018 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303019 reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data());
3020 rc = decode_pass_component_table_resp(
3021 responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode,
3022 &compResp, &compRespCode);
3023 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3024}
3025
3026TEST(UpdateComponent, goodPathEncodeRequest)
3027{
3028 constexpr uint8_t instanceId = 2;
3029 constexpr uint16_t compIdentifier = 500;
3030 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003031 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303032 constexpr uint32_t compImageSize = 4096;
3033 constexpr bitfield32_t updateOptionFlags{1};
3034 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3035 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3036 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303037 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303038 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3039 compVerStrInfo.length = compVerStrLen;
3040
3041 std::array<uint8_t,
3042 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3043 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303044 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303045 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3046
3047 auto rc = encode_update_component_req(
3048 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3049 compComparisonStamp, compImageSize, updateOptionFlags,
3050 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3051 sizeof(pldm_update_component_req) + compVerStrLen);
3052 EXPECT_EQ(rc, PLDM_SUCCESS);
3053
3054 std::array<uint8_t,
3055 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003056 outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
3057 0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
3058 0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
3059 0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303060 EXPECT_EQ(request, outRequest);
3061}
3062
3063TEST(UpdateComponent, errorPathEncodeRequest)
3064{
3065 constexpr uint8_t instanceId = 2;
3066 constexpr uint16_t compIdentifier = 500;
3067 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003068 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303069 constexpr uint32_t compImageSize = 4096;
3070 constexpr bitfield32_t updateOptionFlags{1};
3071 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3072 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3073 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303074 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303075 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3076 compVerStrInfo.length = compVerStrLen;
3077
3078 std::array<uint8_t,
3079 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3080 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303081 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303082 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3083
3084 auto rc = encode_update_component_req(
3085 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3086 compComparisonStamp, compImageSize, updateOptionFlags,
3087 PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
3088 sizeof(pldm_update_component_req) + compVerStrLen);
3089 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3090
3091 compVerStrInfo.ptr = nullptr;
3092 rc = encode_update_component_req(
3093 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3094 compComparisonStamp, compImageSize, updateOptionFlags,
3095 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3096 sizeof(pldm_update_component_req) + compVerStrLen);
3097 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303098 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303099 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3100
3101 rc = encode_update_component_req(
3102 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3103 compComparisonStamp, compImageSize, updateOptionFlags,
3104 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
3105 sizeof(pldm_update_component_req) + compVerStrLen);
3106 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3107
3108 rc = encode_update_component_req(
3109 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3110 compComparisonStamp, compImageSize, updateOptionFlags,
3111 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3112 sizeof(pldm_update_component_req));
3113 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3114
3115 rc = encode_update_component_req(
3116 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3117 compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
3118 compVerStrLen, &compVerStrInfo, requestMsg,
3119 sizeof(pldm_update_component_req) + compVerStrLen);
3120 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3121
3122 rc = encode_update_component_req(
3123 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3124 compComparisonStamp, compImageSize, updateOptionFlags,
3125 PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg,
3126 sizeof(pldm_update_component_req) + compVerStrLen);
3127 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3128
3129 rc = encode_update_component_req(
3130 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3131 compComparisonStamp, compImageSize, updateOptionFlags,
3132 PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg,
3133 sizeof(pldm_update_component_req) + compVerStrLen);
3134 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3135
3136 rc = encode_update_component_req(
3137 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3138 compComparisonStamp, compImageSize, updateOptionFlags,
3139 PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
3140 sizeof(pldm_update_component_req) + compVerStrLen);
3141 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3142}
3143
3144TEST(UpdateComponent, goodPathDecodeResponse)
3145{
3146 constexpr std::bitset<32> forceUpdateComp{1};
3147 constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
3148 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3149 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3150 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3151 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303152 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303153 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3154
3155 uint8_t completionCode = 0;
3156 uint8_t compCompatibilityResp = 0;
3157 uint8_t compCompatibilityRespCode = 0;
3158 bitfield32_t updateOptionFlagsEnabled{};
3159 uint16_t timeBeforeReqFWData = 0;
3160
3161 auto rc = decode_update_component_resp(
3162 responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
3163 &compCompatibilityResp, &compCompatibilityRespCode,
3164 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3165
3166 EXPECT_EQ(rc, PLDM_SUCCESS);
3167 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3168 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
3169 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
3170 EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
3171 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
3172
3173 constexpr std::bitset<32> noFlags{};
3174 constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
3175 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3176 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3178 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303179 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303180 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3181 rc = decode_update_component_resp(
3182 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3183 &compCompatibilityResp, &compCompatibilityRespCode,
3184 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3185
3186 EXPECT_EQ(rc, PLDM_SUCCESS);
3187 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3188 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
3189 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
3190 EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
3191 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
3192
3193 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3194 updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
3195 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303196 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303197 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3198
3199 rc = decode_update_component_resp(
3200 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3201 &compCompatibilityResp, &compCompatibilityRespCode,
3202 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3203
3204 EXPECT_EQ(rc, PLDM_SUCCESS);
3205 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3206}
3207
3208TEST(UpdateComponent, errorPathDecodeResponse)
3209{
3210 constexpr std::array<uint8_t,
3211 hdrSize + sizeof(pldm_update_component_resp) - 1>
3212 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3213 0x00, 0x00, 0x00, 0x00, 0x00};
3214 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303215 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303216 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3217
3218 uint8_t completionCode = 0;
3219 uint8_t compCompatibilityResp = 0;
3220 uint8_t compCompatibilityRespCode = 0;
3221 bitfield32_t updateOptionFlagsEnabled{};
3222 uint16_t timeBeforeReqFWData = 0;
3223
3224 auto rc = decode_update_component_resp(
3225 nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
3226 &compCompatibilityResp, &compCompatibilityRespCode,
3227 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3228 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3229
3230 rc = decode_update_component_resp(
3231 responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
3232 &compCompatibilityResp, &compCompatibilityRespCode,
3233 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3234 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3235
3236 rc = decode_update_component_resp(
3237 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3238 nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3239 &timeBeforeReqFWData);
3240 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3241
3242 rc = decode_update_component_resp(
3243 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3244 &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
3245 &timeBeforeReqFWData);
3246 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3247
3248 rc = decode_update_component_resp(
3249 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3250 &compCompatibilityResp, &compCompatibilityRespCode, nullptr,
3251 &timeBeforeReqFWData);
3252 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3253
3254 rc = decode_update_component_resp(
3255 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3256 &compCompatibilityResp, &compCompatibilityRespCode,
3257 &updateOptionFlagsEnabled, nullptr);
3258 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3259
3260 rc = decode_update_component_resp(
3261 responseMsg1, 0, &completionCode, &compCompatibilityResp,
3262 &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3263 &timeBeforeReqFWData);
3264 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3265
3266 rc = decode_update_component_resp(
3267 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3268 &compCompatibilityResp, &compCompatibilityRespCode,
3269 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3270 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3271
3272 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3273 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
3274 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3275 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303276 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303277 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3278 rc = decode_update_component_resp(
3279 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3280 &compCompatibilityResp, &compCompatibilityRespCode,
3281 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3282 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3283
3284 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003285 updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303286 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3287 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303288 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303289 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3290 rc = decode_update_component_resp(
3291 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3292 &compCompatibilityResp, &compCompatibilityRespCode,
3293 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3294 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3295
3296 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003297 updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303298 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3299 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303300 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303301 reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
3302 rc = decode_update_component_resp(
3303 responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
3304 &compCompatibilityResp, &compCompatibilityRespCode,
3305 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3306 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3307}
3308
3309TEST(RequestFirmwareData, goodPathDecodeRequest)
3310{
3311 constexpr uint32_t offset = 300;
3312 constexpr uint32_t length = 255;
3313 constexpr std::array<uint8_t,
3314 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003315 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3316 0x00, 0xff, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303317 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303318 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3319
3320 uint32_t outOffset = 0;
3321 uint32_t outLength = 0;
3322 auto rc = decode_request_firmware_data_req(
3323 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3324 &outLength);
3325
3326 EXPECT_EQ(rc, PLDM_SUCCESS);
3327 EXPECT_EQ(outOffset, offset);
3328 EXPECT_EQ(outLength, length);
3329}
3330
3331TEST(RequestFirmwareData, errorPathDecodeRequest)
3332{
3333 constexpr std::array<uint8_t,
3334 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003335 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3336 0x00, 0x1f, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303337 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303338 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3339
3340 uint32_t outOffset = 0;
3341 uint32_t outLength = 0;
3342 auto rc = decode_request_firmware_data_req(
3343 nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
3344 &outLength);
3345 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3346
3347 rc = decode_request_firmware_data_req(
3348 requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
3349 &outLength);
3350 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3351
3352 rc = decode_request_firmware_data_req(
3353 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3354 nullptr);
3355 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3356
3357 rc = decode_request_firmware_data_req(
3358 requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
3359 &outLength);
3360 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3361
3362 rc = decode_request_firmware_data_req(
3363 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3364 &outLength);
3365 EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
3366}
3367
3368TEST(RequestFirmwareData, goodPathEncodeResponse)
3369{
3370 constexpr uint8_t instanceId = 3;
3371 constexpr uint8_t completionCode = PLDM_SUCCESS;
3372 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
3373 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3374 outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003375 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3376 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3377 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3378 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303379 std::array<uint8_t, hdrSize + sizeof(completionCode) +
3380 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3381 reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003382 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3383 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3384 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3385 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303386 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303387 auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
3388 auto rc = encode_request_firmware_data_resp(
3389 instanceId, completionCode, responseMsg1,
3390 sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
3391 EXPECT_EQ(rc, PLDM_SUCCESS);
3392 EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
3393
3394 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3395 outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
3396 std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
3397 0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303398 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303399 auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
3400 rc = encode_request_firmware_data_resp(
3401 instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
3402 sizeof(completionCode));
3403 EXPECT_EQ(rc, PLDM_SUCCESS);
3404 EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
3405}
3406
3407TEST(RequestFirmwareData, errorPathEncodeResponse)
3408{
3409 std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303410 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303411 auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
3412 auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
3413 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3414
3415 rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
3416 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3417}
3418
3419TEST(TransferComplete, goodPathDecodeRequest)
3420{
3421 constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
3422 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3423 transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
3424 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303425 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303426 reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
3427 uint8_t outTransferResult = 0;
3428
3429 auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
3430 &outTransferResult);
3431 EXPECT_EQ(rc, PLDM_SUCCESS);
3432 EXPECT_EQ(outTransferResult, transferResult);
3433
3434 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3435 transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
3436 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303437 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303438 reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
3439 rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
3440 &outTransferResult);
3441 EXPECT_EQ(rc, PLDM_SUCCESS);
3442 EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
3443}
3444
3445TEST(TransferComplete, errorPathDecodeRequest)
3446{
3447 constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
3448 0x00};
3449 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303450 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303451 reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
3452 uint8_t outTransferResult = 0;
3453
3454 auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
3455 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3456
3457 rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
3458 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3459
3460 rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
3461 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3462}
3463
3464TEST(TransferComplete, goodPathEncodeResponse)
3465{
3466 constexpr uint8_t instanceId = 4;
3467 constexpr uint8_t completionCode = PLDM_SUCCESS;
3468 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3469 outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
3470 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3471 transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3472 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303473 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303474 reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
3475 auto rc = encode_transfer_complete_resp(
3476 instanceId, completionCode, responseMsg1, sizeof(completionCode));
3477 EXPECT_EQ(rc, PLDM_SUCCESS);
3478 EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
3479
3480 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3481 outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
3482 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3483 transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3484 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303485 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303486 reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
3487 rc = encode_transfer_complete_resp(instanceId,
3488 PLDM_FWUP_COMMAND_NOT_EXPECTED,
3489 responseMsg2, sizeof(completionCode));
3490 EXPECT_EQ(rc, PLDM_SUCCESS);
3491 EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
3492}
3493
3494TEST(TransferComplete, errorPathEncodeResponse)
3495{
3496 std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
3497 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303498 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303499 reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
3500 auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3501 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3502
3503 rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3504 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3505}
3506
3507TEST(VerifyComplete, goodPathDecodeRequest)
3508{
3509 constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
3510 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3511 verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
3512 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303513 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303514 reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
3515 uint8_t outVerifyResult = 0;
3516
3517 auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
3518 &outVerifyResult);
3519 EXPECT_EQ(rc, PLDM_SUCCESS);
3520 EXPECT_EQ(outVerifyResult, verifyResult);
3521
3522 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3523 verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
3524 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303525 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303526 reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
3527 rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
3528 &outVerifyResult);
3529 EXPECT_EQ(rc, PLDM_SUCCESS);
3530 EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
3531}
3532
3533TEST(VerifyComplete, errorPathDecodeRequest)
3534{
3535 constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
3536 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303537 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303538 reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
3539 uint8_t outVerifyResult = 0;
3540
3541 auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
3542 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3543
3544 rc = decode_verify_complete_req(requestMsg, 0, nullptr);
3545 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3546
3547 rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);
3548 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3549}
3550
3551TEST(VerifyComplete, goodPathEncodeResponse)
3552{
3553 constexpr uint8_t instanceId = 5;
3554 constexpr uint8_t completionCode = PLDM_SUCCESS;
3555 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3556 outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};
3557 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3558 verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3559 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303560 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303561 reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());
3562 auto rc = encode_verify_complete_resp(instanceId, completionCode,
3563 responseMsg1, sizeof(completionCode));
3564 EXPECT_EQ(rc, PLDM_SUCCESS);
3565 EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);
3566
3567 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3568 outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88};
3569 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3570 verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3571 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303572 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303573 reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());
3574 rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3575 responseMsg2, sizeof(completionCode));
3576 EXPECT_EQ(rc, PLDM_SUCCESS);
3577 EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);
3578}
3579
3580TEST(VerifyComplete, errorPathEncodeResponse)
3581{
3582 std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00};
3583 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303584 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303585 reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());
3586 auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3587 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3588
3589 rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3590 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3591}
3592
3593TEST(ApplyComplete, goodPathDecodeRequest)
3594{
3595 constexpr uint8_t applyResult1 =
3596 PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
3597 // DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
3598 constexpr std::bitset<16> compActivationModification1{0x30};
3599 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3600 applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
3601 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303602 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303603 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3604 uint8_t outApplyResult = 0;
3605 bitfield16_t outCompActivationModification{};
3606 auto rc = decode_apply_complete_req(
3607 requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
3608 &outCompActivationModification);
3609 EXPECT_EQ(rc, PLDM_SUCCESS);
3610 EXPECT_EQ(outApplyResult, applyResult1);
3611 EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
3612
3613 constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
3614 constexpr std::bitset<16> compActivationModification2{};
3615 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3616 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3617 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303618 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303619 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3620 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3621 &outApplyResult,
3622 &outCompActivationModification);
3623 EXPECT_EQ(rc, PLDM_SUCCESS);
3624 EXPECT_EQ(outApplyResult, applyResult2);
3625 EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
3626}
3627
3628TEST(ApplyComplete, errorPathDecodeRequest)
3629{
3630 constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
3631 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303632 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303633 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3634 uint8_t outApplyResult = 0;
3635 bitfield16_t outCompActivationModification{};
3636
3637 auto rc = decode_apply_complete_req(
3638 nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
3639 &outCompActivationModification);
3640 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3641
3642 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3643 nullptr, &outCompActivationModification);
3644 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3645
3646 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3647 &outApplyResult, nullptr);
3648 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3649
3650 rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
3651 &outCompActivationModification);
3652 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3653
3654 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3655 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
3656 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303657 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303658 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3659 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3660 &outApplyResult,
3661 &outCompActivationModification);
3662 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3663}
3664
3665TEST(ApplyComplete, goodPathEncodeResponse)
3666{
3667 constexpr uint8_t instanceId = 6;
3668 constexpr uint8_t completionCode = PLDM_SUCCESS;
3669 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3670 outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
3671 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3672 applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3673 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303674 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303675 reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
3676 auto rc = encode_apply_complete_resp(instanceId, completionCode,
3677 responseMsg1, sizeof(completionCode));
3678 EXPECT_EQ(rc, PLDM_SUCCESS);
3679 EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
3680
3681 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3682 outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
3683 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3684 applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3685 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303686 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303687 reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
3688 rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3689 responseMsg2, sizeof(completionCode));
3690 EXPECT_EQ(rc, PLDM_SUCCESS);
3691 EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
3692}
3693
3694TEST(ApplyComplete, errorPathEncodeResponse)
3695{
3696 std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
3697 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303698 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303699 reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
3700 auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3701 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3702
3703 rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3704 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3705}
3706
3707TEST(ActivateFirmware, goodPathEncodeRequest)
3708{
3709 constexpr uint8_t instanceId = 7;
3710
3711 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303712 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303713 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3714
3715 auto rc = encode_activate_firmware_req(
3716 instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
3717 sizeof(pldm_activate_firmware_req));
3718 EXPECT_EQ(rc, PLDM_SUCCESS);
3719
3720 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003721 outRequest{0x87, 0x05, 0x1a, 0x01};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303722 EXPECT_EQ(request, outRequest);
3723}
3724
3725TEST(ActivateFirmware, errorPathEncodeRequest)
3726{
3727 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303728 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303729 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3730
3731 auto rc = encode_activate_firmware_req(
3732 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
3733 sizeof(pldm_activate_firmware_req));
3734 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3735
3736 rc = encode_activate_firmware_req(
3737 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
3738 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3739
3740 rc = encode_activate_firmware_req(0, 2, requestMsg,
3741 sizeof(pldm_activate_firmware_req));
3742 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3743}
3744
3745TEST(ActivateFirmware, goodPathDecodeResponse)
3746{
3747 constexpr uint16_t estimatedTimeForActivation100s = 100;
3748 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3749 activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
3750 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303751 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303752 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
3753
3754 uint8_t completionCode = 0;
3755 uint16_t estimatedTimeForActivation = 0;
3756
3757 auto rc = decode_activate_firmware_resp(
3758 responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
3759 &estimatedTimeForActivation);
3760
3761 EXPECT_EQ(rc, PLDM_SUCCESS);
3762 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3763 EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
3764
3765 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3766 activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
3767 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303768 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303769 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data());
3770
3771 rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
3772 &completionCode,
3773 &estimatedTimeForActivation);
3774
3775 EXPECT_EQ(rc, PLDM_SUCCESS);
3776 EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
3777}
3778
3779TEST(ActivateFirmware, errorPathDecodeResponse)
3780{
3781 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3782 activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3783 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303784 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303785 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
3786
3787 uint8_t completionCode = 0;
3788 uint16_t estimatedTimeForActivation = 0;
3789
3790 auto rc = decode_activate_firmware_resp(
3791 nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
3792 &estimatedTimeForActivation);
3793 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3794
3795 rc = decode_activate_firmware_resp(responseMsg,
3796 sizeof(pldm_activate_firmware_resp),
3797 nullptr, &estimatedTimeForActivation);
3798 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3799
3800 rc = decode_activate_firmware_resp(responseMsg,
3801 sizeof(pldm_activate_firmware_resp),
3802 &completionCode, nullptr);
3803 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3804
3805 rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
3806 &estimatedTimeForActivation);
3807 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3808
3809 rc = decode_activate_firmware_resp(
3810 responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
3811 &estimatedTimeForActivation);
3812 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3813}
3814
3815TEST(GetStatus, goodPathEncodeRequest)
3816{
3817 constexpr uint8_t instanceId = 8;
3818 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303819 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303820 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3821
3822 auto rc = encode_get_status_req(instanceId, requestMsg,
3823 PLDM_GET_STATUS_REQ_BYTES);
3824 EXPECT_EQ(rc, PLDM_SUCCESS);
3825
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003826 constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303827 EXPECT_EQ(request, outRequest);
3828}
3829
3830TEST(GetStatus, errorPathEncodeRequest)
3831{
3832 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303833 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303834 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3835
3836 auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
3837 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3838
3839 rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);
3840 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3841}
3842
3843TEST(GetStatus, goodPathDecodeResponse)
3844{
3845 constexpr std::bitset<32> updateOptionFlagsEnabled1{0};
3846 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3847 getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
3848 0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};
3849 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303850 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303851 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
3852
3853 uint8_t completionCode = 0;
3854 uint8_t currentState = 0;
3855 uint8_t previousState = 0;
3856 uint8_t auxState = 0;
3857 uint8_t auxStateStatus = 0;
3858 uint8_t progressPercent = 0;
3859 uint8_t reasonCode = 0;
3860 bitfield32_t updateOptionFlagsEnabled{0};
3861
3862 auto rc = decode_get_status_resp(
3863 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3864 &currentState, &previousState, &auxState, &auxStateStatus,
3865 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3866
3867 EXPECT_EQ(rc, PLDM_SUCCESS);
3868 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3869 EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);
3870 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
3871 EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);
3872 EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);
3873 EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);
3874 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
3875 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);
3876
3877 // Bit position 0 - Force update of component – FD will perform a force
3878 // update of the component.
3879 constexpr std::bitset<32> updateOptionFlagsEnabled2{1};
3880 constexpr uint8_t progressPercent2 = 50;
3881 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3882 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,
3883 0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};
3884 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303885 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303886 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
3887
3888 rc = decode_get_status_resp(
3889 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
3890 &currentState, &previousState, &auxState, &auxStateStatus,
3891 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3892
3893 EXPECT_EQ(rc, PLDM_SUCCESS);
3894 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3895 EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);
3896 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
3897 EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);
3898 EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);
3899 EXPECT_EQ(progressPercent, progressPercent2);
3900 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
3901 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);
3902
3903 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3904 getStatusResponse3{0x00, 0x00, 0x00, 0x04};
3905 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303906 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303907 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
3908 rc = decode_get_status_resp(
3909 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
3910 &currentState, &previousState, &auxState, &auxStateStatus,
3911 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3912 EXPECT_EQ(rc, PLDM_SUCCESS);
3913 EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);
3914}
3915
3916TEST(GetStatus, errorPathDecodeResponse)
3917{
3918 uint8_t completionCode = 0;
3919 uint8_t currentState = 0;
3920 uint8_t previousState = 0;
3921 uint8_t auxState = 0;
3922 uint8_t auxStateStatus = 0;
3923 uint8_t progressPercent = 0;
3924 uint8_t reasonCode = 0;
3925 bitfield32_t updateOptionFlagsEnabled{0};
3926
3927 constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};
3928 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303929 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303930 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
3931
3932 auto rc = decode_get_status_resp(
3933 nullptr, getStatusResponse1.size() - hdrSize, &completionCode,
3934 &currentState, &previousState, &auxState, &auxStateStatus,
3935 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3936 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3937
3938 rc = decode_get_status_resp(
3939 responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,
3940 &currentState, &previousState, &auxState, &auxStateStatus,
3941 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3942 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3943
3944 rc = decode_get_status_resp(
3945 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3946 nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,
3947 &reasonCode, &updateOptionFlagsEnabled);
3948 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3949
3950 rc = decode_get_status_resp(
3951 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3952 &currentState, nullptr, &auxState, &auxStateStatus, &progressPercent,
3953 &reasonCode, &updateOptionFlagsEnabled);
3954 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3955
3956 rc = decode_get_status_resp(
3957 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3958 &currentState, &previousState, nullptr, &auxStateStatus,
3959 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3960 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3961
3962 rc = decode_get_status_resp(
3963 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3964 &currentState, &previousState, &auxState, nullptr, &progressPercent,
3965 &reasonCode, &updateOptionFlagsEnabled);
3966 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3967
3968 rc = decode_get_status_resp(
3969 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3970 &currentState, &previousState, &auxState, &auxStateStatus, nullptr,
3971 &reasonCode, &updateOptionFlagsEnabled);
3972 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3973
3974 rc = decode_get_status_resp(
3975 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3976 &currentState, &previousState, &auxState, &auxStateStatus,
3977 &progressPercent, nullptr, &updateOptionFlagsEnabled);
3978 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3979
3980 rc = decode_get_status_resp(
3981 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3982 &currentState, &previousState, &auxState, &auxStateStatus,
3983 &progressPercent, &reasonCode, nullptr);
3984 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3985
3986 rc = decode_get_status_resp(
3987 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3988 &currentState, &previousState, &auxState, &auxStateStatus,
3989 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3990 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3991
3992 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>
3993 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3994 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3995 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303996 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303997 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
3998 rc = decode_get_status_resp(
3999 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4000 &currentState, &previousState, &auxState, &auxStateStatus,
4001 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4002 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4003
4004 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4005 getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
4006 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4007 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304008 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304009 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4010 rc = decode_get_status_resp(
4011 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4012 &currentState, &previousState, &auxState, &auxStateStatus,
4013 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4014 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4015
4016 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4017 getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
4018 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4019 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304020 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304021 reinterpret_cast<const pldm_msg*>(getStatusResponse4.data());
4022 rc = decode_get_status_resp(
4023 responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,
4024 &currentState, &previousState, &auxState, &auxStateStatus,
4025 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4026 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4027
4028 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4029 getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
4030 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4031 auto responseMsg5 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304032 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304033 reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());
4034 rc = decode_get_status_resp(
4035 responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,
4036 &currentState, &previousState, &auxState, &auxStateStatus,
4037 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4038 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4039
4040 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4041 getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004042 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304043 auto responseMsg6 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304044 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304045 reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());
4046 rc = decode_get_status_resp(
4047 responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,
4048 &currentState, &previousState, &auxState, &auxStateStatus,
4049 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4050 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4051
4052 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4053 getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4054 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
4055 auto responseMsg7 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304056 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304057 reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());
4058 rc = decode_get_status_resp(
4059 responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,
4060 &currentState, &previousState, &auxState, &auxStateStatus,
4061 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4062 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4063
4064 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4065 getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004066 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304067 auto responseMsg8 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304068 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304069 reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());
4070 rc = decode_get_status_resp(
4071 responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,
4072 &currentState, &previousState, &auxState, &auxStateStatus,
4073 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4074 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4075
4076 // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is
4077 // IDLE
4078 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4079 getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
4080 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4081 auto responseMsg9 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304082 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304083 reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());
4084 rc = decode_get_status_resp(
4085 responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,
4086 &currentState, &previousState, &auxState, &auxStateStatus,
4087 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4088 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4089}
4090
4091TEST(CancelUpdateComponent, goodPathEncodeRequest)
4092{
4093 constexpr uint8_t instanceId = 9;
4094 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304095 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304096 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4097
4098 auto rc = encode_cancel_update_component_req(
4099 instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4100 EXPECT_EQ(rc, PLDM_SUCCESS);
4101
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004102 constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304103 EXPECT_EQ(request, outRequest);
4104}
4105
4106TEST(CancelUpdateComponent, errorPathEncodeRequest)
4107{
4108 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304109 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304110 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4111
4112 auto rc = encode_cancel_update_component_req(
4113 0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4114 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4115
4116 rc = encode_cancel_update_component_req(
4117 0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);
4118 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4119}
4120
4121TEST(CancelUpdateComponent, testGoodDecodeResponse)
4122{
4123 uint8_t completionCode = 0;
4124 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4125 cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304126 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304127 auto responseMsg1 = reinterpret_cast<const pldm_msg*>(
4128 cancelUpdateComponentResponse1.data());
4129 auto rc = decode_cancel_update_component_resp(
4130 responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,
4131 &completionCode);
4132 EXPECT_EQ(rc, PLDM_SUCCESS);
4133 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4134
4135 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4136 cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304137 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304138 auto responseMsg2 = reinterpret_cast<const pldm_msg*>(
4139 cancelUpdateComponentResponse2.data());
4140 rc = decode_cancel_update_component_resp(
4141 responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,
4142 &completionCode);
4143 EXPECT_EQ(rc, PLDM_SUCCESS);
4144 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4145}
4146
4147TEST(CancelUpdateComponent, testBadDecodeResponse)
4148{
4149 uint8_t completionCode = 0;
4150 constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{
4151 0x00, 0x00, 0x00};
4152 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304153 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304154 reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data());
4155
4156 auto rc = decode_cancel_update_component_resp(
4157 nullptr, cancelUpdateComponentResponse.size() - hdrSize,
4158 &completionCode);
4159 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4160
4161 rc = decode_cancel_update_component_resp(
4162 responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);
4163 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4164
4165 rc = decode_cancel_update_component_resp(
4166 responseMsg, cancelUpdateComponentResponse.size() - hdrSize,
4167 &completionCode);
4168 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4169}
4170
4171TEST(CancelUpdate, goodPathEncodeRequest)
4172{
4173 constexpr uint8_t instanceId = 10;
4174 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304175 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304176 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4177
4178 auto rc = encode_cancel_update_req(instanceId, requestMsg,
4179 PLDM_CANCEL_UPDATE_REQ_BYTES);
4180 EXPECT_EQ(rc, PLDM_SUCCESS);
4181
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004182 constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304183 EXPECT_EQ(request, outRequest);
4184}
4185
4186TEST(CancelUpdate, errorPathEncodeRequest)
4187{
4188 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304189 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304190 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4191
4192 auto rc =
4193 encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
4194 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4195
4196 rc = encode_cancel_update_req(0, requestMsg,
4197 PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
4198 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4199}
4200
4201TEST(CancelUpdate, goodPathDecodeResponse)
4202{
4203 constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
4204 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4205 cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4206 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4207 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304208 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304209 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4210 uint8_t completionCode = 0;
4211 bool8_t nonFunctioningComponentIndication = 0;
4212 bitfield64_t nonFunctioningComponentBitmap{0};
4213 auto rc = decode_cancel_update_resp(
4214 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4215 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4216 EXPECT_EQ(rc, PLDM_SUCCESS);
4217 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4218 EXPECT_EQ(nonFunctioningComponentIndication,
4219 PLDM_FWUP_COMPONENTS_FUNCTIONING);
4220 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4221 nonFunctioningComponentBitmap1);
4222
4223 constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
4224 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4225 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
4226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4227 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304228 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304229 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4230 rc = decode_cancel_update_resp(
4231 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4232 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4233 EXPECT_EQ(rc, PLDM_SUCCESS);
4234 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4235 EXPECT_EQ(nonFunctioningComponentIndication,
4236 PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING);
4237 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4238 nonFunctioningComponentBitmap2);
4239
4240 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4241 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
4242 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304243 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304244 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4245 rc = decode_cancel_update_resp(
4246 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4247 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4248 EXPECT_EQ(rc, PLDM_SUCCESS);
4249 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4250}
4251
4252TEST(CancelUpdate, errorPathDecodeResponse)
4253{
4254 constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
4255 0x00};
4256 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304257 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304258 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4259 uint8_t completionCode = 0;
4260 bool8_t nonFunctioningComponentIndication = 0;
4261 bitfield64_t nonFunctioningComponentBitmap{0};
4262
4263 auto rc = decode_cancel_update_resp(
4264 nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4265 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4266 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4267
4268 rc = decode_cancel_update_resp(
4269 responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
4270 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4271 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4272
4273 rc = decode_cancel_update_resp(
4274 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4275 nullptr, &nonFunctioningComponentBitmap);
4276 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4277
4278 rc = decode_cancel_update_resp(
4279 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4280 &nonFunctioningComponentIndication, nullptr);
4281 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4282
4283 rc = decode_cancel_update_resp(
4284 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4285 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4286 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4287
4288 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4289 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
4290 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304291 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304292 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4293 rc = decode_cancel_update_resp(
4294 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4295 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4296 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4297
4298 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4299 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
4300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4301 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304302 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304303 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4304 rc = decode_cancel_update_resp(
4305 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4306 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4307 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4308}