blob: ea93e21706c8d994e0526b3a77188e653d6da32f [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>
Andrew Jeffery5a5129b2024-12-04 16:12:40 +103010#include <cstddef>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +053011#include <cstdint>
Andrew Jeffery9c766792022-08-10 23:12:49 +093012#include <cstring>
Matt Johnstond5d1f662024-11-27 13:30:20 +080013#include <span>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +053014#include <string>
15#include <string_view>
16#include <vector>
Andrew Jeffery9c766792022-08-10 23:12:49 +093017
Chris Wang4c1f2c72024-03-21 17:09:44 +080018#include "msgbuf.h"
19
Andrew Jefferydec237b2024-11-08 14:33:45 +103020#include <gmock/gmock.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +093021#include <gtest/gtest.h>
22
Andrew Jefferydec237b2024-11-08 14:33:45 +103023using testing::ElementsAreArray;
24
Andrew Jeffery9c766792022-08-10 23:12:49 +093025constexpr auto hdrSize = sizeof(pldm_msg_hdr);
26
Matt Johnstoncf9a2df2024-11-07 15:29:29 +080027#ifdef LIBPLDM_API_TESTING
28
29static const uint8_t FIXED_INSTANCE_ID = 31;
30
31/* data is a pointer to pldm message response header */
32static void check_response(const void* data, uint8_t command)
33{
34 auto enc = static_cast<const pldm_msg*>(data);
35 EXPECT_EQ(enc->hdr.request, PLDM_RESPONSE);
36 EXPECT_EQ(enc->hdr.type, PLDM_FWUP);
37 EXPECT_EQ(enc->hdr.command, command);
38 EXPECT_EQ(enc->hdr.reserved, 0);
39 EXPECT_EQ(enc->hdr.datagram, 0);
40 EXPECT_EQ(enc->hdr.header_ver, 0);
41 EXPECT_EQ(enc->hdr.instance_id, FIXED_INSTANCE_ID);
42}
43#endif
44
Andrew Jefferye038b962025-03-06 16:04:59 +103045static constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH>
46 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0{0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d,
47 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
48 0x05, 0x9a, 0xca, 0x02};
49
50static constexpr uint8_t PLDM_FWUP_PACKAGE_HEADER_FORMAT_REVISION_V1_0 = 0x01;
51
Andrew Jeffery9c766792022-08-10 23:12:49 +093052TEST(DecodePackageHeaderInfo, goodPath)
53{
Andrew Jeffery9c766792022-08-10 23:12:49 +093054 // Random PackageHeaderSize
55 constexpr uint16_t pkgHeaderSize = 303;
56 // PackageReleaseDateTime - "25/12/2021 00:00:00"
57 std::array<uint8_t, PLDM_TIMESTAMP104_SIZE> package_release_date_time{
58 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00};
60 constexpr uint16_t componentBitmapBitLength = 8;
61 // PackageVersionString
62 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
Andrew Jefferya3eba612025-03-06 17:11:20 +103063 constexpr size_t packageHeaderSize =
Andrew Jeffery9c766792022-08-10 23:12:49 +093064 sizeof(pldm_package_header_information) + packageVersionStr.size();
65
Andrew Jefferya3eba612025-03-06 17:11:20 +103066 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -060067 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
Andrew Jeffery9c766792022-08-10 23:12:49 +093068 0x05, 0x9a, 0xca, 0x02, 0x01, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b,
70 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
71 pldm_package_header_information pkgHeader{};
72 variable_field packageVersion{};
73
74 auto rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
75 packagerHeaderInfo.size(),
76 &pkgHeader, &packageVersion);
77
78 EXPECT_EQ(rc, PLDM_SUCCESS);
79 EXPECT_EQ(true,
80 std::equal(pkgHeader.uuid, pkgHeader.uuid + PLDM_FWUP_UUID_LENGTH,
Andrew Jefferye038b962025-03-06 16:04:59 +103081 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.begin(),
82 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.end()));
83 EXPECT_EQ(pkgHeader.package_header_format_version,
84 PLDM_FWUP_PACKAGE_HEADER_FORMAT_REVISION_V1_0);
Andrew Jeffery9c766792022-08-10 23:12:49 +093085 EXPECT_EQ(pkgHeader.package_header_size, pkgHeaderSize);
86 EXPECT_EQ(true, std::equal(pkgHeader.package_release_date_time,
87 pkgHeader.package_release_date_time +
88 PLDM_TIMESTAMP104_SIZE,
89 package_release_date_time.begin(),
90 package_release_date_time.end()));
91 EXPECT_EQ(pkgHeader.component_bitmap_bit_length, componentBitmapBitLength);
92 EXPECT_EQ(pkgHeader.package_version_string_type, PLDM_STR_TYPE_ASCII);
93 EXPECT_EQ(pkgHeader.package_version_string_length,
94 packageVersionStr.size());
95 std::string packageVersionString(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +093096 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +093097 reinterpret_cast<const char*>(packageVersion.ptr),
98 packageVersion.length);
99 EXPECT_EQ(packageVersionString, packageVersionStr);
100}
101
102TEST(DecodePackageHeaderInfo, errorPaths)
103{
104 int rc = 0;
105 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
Andrew Jefferya3eba612025-03-06 17:11:20 +1030106 constexpr size_t packageHeaderSize =
Andrew Jeffery9c766792022-08-10 23:12:49 +0930107 sizeof(pldm_package_header_information) + packageVersionStr.size();
108
109 // Invalid Package Version String Type - 0x06
Andrew Jefferya3eba612025-03-06 17:11:20 +1030110 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo1{
111 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
112 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
113 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x06, 0x0b,
114 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
Andrew Jeffery9c766792022-08-10 23:12:49 +0930115
116 pldm_package_header_information packageHeader{};
117 variable_field packageVersion{};
118
119 rc = decode_pldm_package_header_info(nullptr,
120 invalidPackagerHeaderInfo1.size(),
121 &packageHeader, &packageVersion);
122 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
123
124 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
125 invalidPackagerHeaderInfo1.size(),
126 nullptr, &packageVersion);
127 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
128
129 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
130 invalidPackagerHeaderInfo1.size(),
131 &packageHeader, nullptr);
132 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
133
134 rc = decode_pldm_package_header_info(
135 invalidPackagerHeaderInfo1.data(),
136 sizeof(pldm_package_header_information) - 1, &packageHeader,
137 &packageVersion);
138 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
139
140 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
141 invalidPackagerHeaderInfo1.size(),
142 &packageHeader, &packageVersion);
143 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
144
145 // Invalid Package Version String Length - 0x00
Andrew Jefferya3eba612025-03-06 17:11:20 +1030146 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo2{
147 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
148 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x00,
150 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
Andrew Jeffery9c766792022-08-10 23:12:49 +0930151 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo2.data(),
152 invalidPackagerHeaderInfo2.size(),
153 &packageHeader, &packageVersion);
154 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
155
156 // Package version string length less than in the header information
Andrew Jefferya3eba612025-03-06 17:11:20 +1030157 constexpr std::array<uint8_t, packageHeaderSize - 1>
Andrew Jeffery9c766792022-08-10 23:12:49 +0930158 invalidPackagerHeaderInfo3{
159 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600160 0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
162 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e,
163 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e};
164 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo3.data(),
165 invalidPackagerHeaderInfo3.size(),
166 &packageHeader, &packageVersion);
167 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
168
169 // ComponentBitmapBitLength not a multiple of 8
Andrew Jefferya3eba612025-03-06 17:11:20 +1030170 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo4{
171 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
172 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
173 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x09, 0x00, 0x01, 0x0b,
174 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
Andrew Jeffery9c766792022-08-10 23:12:49 +0930175 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo4.data(),
176 invalidPackagerHeaderInfo4.size(),
177 &packageHeader, &packageVersion);
178 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
179}
180
181TEST(DecodeFirmwareDeviceIdRecord, goodPath)
182{
183 constexpr uint8_t descriptorCount = 1;
184 // Continue component updates after failure
185 constexpr std::bitset<32> deviceUpdateFlag{1};
186 constexpr uint16_t componentBitmapBitLength = 16;
187 // Applicable Components - 1,2,5,8,9
188 std::vector<std::bitset<8>> applicableComponentsBitfield{0x93, 0x01};
189 // ComponentImageSetVersionString
190 constexpr std::string_view imageSetVersionStr{"VersionString1"};
191 // Initial descriptor - UUID
192 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
193 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
194 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
195 constexpr uint16_t fwDevicePkgDataLen = 2;
196 // FirmwareDevicePackageData
197 constexpr std::array<uint8_t, fwDevicePkgDataLen> fwDevicePkgData{0xab,
198 0xcd};
199 // Size of the firmware device ID record
200 constexpr uint16_t recordLen =
201 sizeof(pldm_firmware_device_id_record) +
202 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
203 imageSetVersionStr.size() + sizeof(pldm_descriptor_tlv) - 1 +
204 uuid.size() + fwDevicePkgData.size();
205 // Firmware device ID record
206 constexpr std::array<uint8_t, recordLen> record{
207 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02,
208 0x00, 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
209 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10,
210 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0,
211 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xab, 0xcd};
212
213 pldm_firmware_device_id_record deviceIdRecHeader{};
214 variable_field applicableComponents{};
215 variable_field outCompImageSetVersionStr{};
216 variable_field recordDescriptors{};
217 variable_field outFwDevicePkgData{};
218
219 auto rc = decode_firmware_device_id_record(
220 record.data(), record.size(), componentBitmapBitLength,
221 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
222 &recordDescriptors, &outFwDevicePkgData);
223
224 EXPECT_EQ(rc, PLDM_SUCCESS);
225 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
226 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
227 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
228 deviceUpdateFlag);
229 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
230 PLDM_STR_TYPE_ASCII);
231 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
232 imageSetVersionStr.size());
233 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, fwDevicePkgDataLen);
234
235 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
236 EXPECT_EQ(true,
237 std::equal(applicableComponents.ptr,
238 applicableComponents.ptr + applicableComponents.length,
239 applicableComponentsBitfield.begin(),
240 applicableComponentsBitfield.end()));
241
242 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
243 std::string compImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930244 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930245 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
246 outCompImageSetVersionStr.length);
247 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
248
249 uint16_t descriptorType = 0;
250 uint16_t descriptorLen = 0;
251 variable_field descriptorData{};
252 // DescriptorCount is 1, so decode_descriptor_type_length_value called once
253 rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
254 recordDescriptors.length,
255 &descriptorType, &descriptorData);
256 EXPECT_EQ(rc, PLDM_SUCCESS);
257 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
258 sizeof(descriptorLen) +
259 descriptorData.length);
260 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
261 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
262 EXPECT_EQ(true, std::equal(descriptorData.ptr,
263 descriptorData.ptr + descriptorData.length,
264 uuid.begin(), uuid.end()));
265
266 EXPECT_EQ(outFwDevicePkgData.length, fwDevicePkgData.size());
267 EXPECT_EQ(true,
268 std::equal(outFwDevicePkgData.ptr,
269 outFwDevicePkgData.ptr + outFwDevicePkgData.length,
270 fwDevicePkgData.begin(), fwDevicePkgData.end()));
271}
272
273TEST(DecodeFirmwareDeviceIdRecord, goodPathNofwDevicePkgData)
274{
275 constexpr uint8_t descriptorCount = 1;
276 // Continue component updates after failure
277 constexpr std::bitset<32> deviceUpdateFlag{1};
278 constexpr uint16_t componentBitmapBitLength = 8;
279 // Applicable Components - 1,2
280 std::vector<std::bitset<8>> applicableComponentsBitfield{0x03};
281 // ComponentImageSetVersionString
282 constexpr std::string_view imageSetVersionStr{"VersionString1"};
283 // Initial descriptor - UUID
284 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
285 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
286 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
287 constexpr uint16_t fwDevicePkgDataLen = 0;
288
289 // Size of the firmware device ID record
290 constexpr uint16_t recordLen =
291 sizeof(pldm_firmware_device_id_record) +
292 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
293 imageSetVersionStr.size() +
294 sizeof(pldm_descriptor_tlv().descriptor_type) +
295 sizeof(pldm_descriptor_tlv().descriptor_length) + uuid.size() +
296 fwDevicePkgDataLen;
297 // Firmware device ID record
298 constexpr std::array<uint8_t, recordLen> record{
299 0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x03,
300 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e,
301 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d,
302 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
303
304 pldm_firmware_device_id_record deviceIdRecHeader{};
305 variable_field applicableComponents{};
306 variable_field outCompImageSetVersionStr{};
307 variable_field recordDescriptors{};
308 variable_field outFwDevicePkgData{};
309
310 auto rc = decode_firmware_device_id_record(
311 record.data(), record.size(), componentBitmapBitLength,
312 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
313 &recordDescriptors, &outFwDevicePkgData);
314
315 EXPECT_EQ(rc, PLDM_SUCCESS);
316 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
317 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
318 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
319 deviceUpdateFlag);
320 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
321 PLDM_STR_TYPE_ASCII);
322 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
323 imageSetVersionStr.size());
324 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, 0);
325
326 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
327 EXPECT_EQ(true,
328 std::equal(applicableComponents.ptr,
329 applicableComponents.ptr + applicableComponents.length,
330 applicableComponentsBitfield.begin(),
331 applicableComponentsBitfield.end()));
332
333 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
334 std::string compImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930335 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930336 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
337 outCompImageSetVersionStr.length);
338 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
339
340 uint16_t descriptorType = 0;
341 uint16_t descriptorLen = 0;
342 variable_field descriptorData{};
343 // DescriptorCount is 1, so decode_descriptor_type_length_value called once
344 rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
345 recordDescriptors.length,
346 &descriptorType, &descriptorData);
347 EXPECT_EQ(rc, PLDM_SUCCESS);
348 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
349 sizeof(descriptorLen) +
350 descriptorData.length);
351 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
352 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
353 EXPECT_EQ(true, std::equal(descriptorData.ptr,
354 descriptorData.ptr + descriptorData.length,
355 uuid.begin(), uuid.end()));
356
357 EXPECT_EQ(outFwDevicePkgData.ptr, nullptr);
358 EXPECT_EQ(outFwDevicePkgData.length, 0);
359}
360
361TEST(DecodeFirmwareDeviceIdRecord, ErrorPaths)
362{
363 constexpr uint16_t componentBitmapBitLength = 8;
364 // Invalid ComponentImageSetVersionStringType
365 constexpr std::array<uint8_t, 11> invalidRecord1{
366 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
367
368 int rc = 0;
369 pldm_firmware_device_id_record deviceIdRecHeader{};
370 variable_field applicableComponents{};
371 variable_field outCompImageSetVersionStr{};
372 variable_field recordDescriptors{};
373 variable_field outFwDevicePkgData{};
374
375 rc = decode_firmware_device_id_record(
376 nullptr, invalidRecord1.size(), componentBitmapBitLength,
377 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
378 &recordDescriptors, &outFwDevicePkgData);
379 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
380
381 rc = decode_firmware_device_id_record(
382 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
383 nullptr, &applicableComponents, &outCompImageSetVersionStr,
384 &recordDescriptors, &outFwDevicePkgData);
385 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
386
387 rc = decode_firmware_device_id_record(
388 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
389 &deviceIdRecHeader, nullptr, &outCompImageSetVersionStr,
390 &recordDescriptors, &outFwDevicePkgData);
391 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
392
393 rc = decode_firmware_device_id_record(
394 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
395 &deviceIdRecHeader, &applicableComponents, nullptr, &recordDescriptors,
396 &outFwDevicePkgData);
397 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
398
399 rc = decode_firmware_device_id_record(
400 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
401 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
402 nullptr, &outFwDevicePkgData);
403 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
404
405 rc = decode_firmware_device_id_record(
406 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
407 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
408 &recordDescriptors, nullptr);
409 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
410
411 rc = decode_firmware_device_id_record(
412 invalidRecord1.data(), invalidRecord1.size() - 1,
413 componentBitmapBitLength, &deviceIdRecHeader, &applicableComponents,
414 &outCompImageSetVersionStr, &recordDescriptors, &outFwDevicePkgData);
415 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
416
417 rc = decode_firmware_device_id_record(
418 invalidRecord1.data(), invalidRecord1.size(),
419 componentBitmapBitLength + 1, &deviceIdRecHeader, &applicableComponents,
420 &outCompImageSetVersionStr, &recordDescriptors, &outFwDevicePkgData);
421 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
422
423 rc = decode_firmware_device_id_record(
424 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
425 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
426 &recordDescriptors, &outFwDevicePkgData);
427 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
428
429 // Invalid ComponentImageSetVersionStringLength
430 constexpr std::array<uint8_t, 11> invalidRecord2{
431 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
432 rc = decode_firmware_device_id_record(
433 invalidRecord2.data(), invalidRecord2.size(), componentBitmapBitLength,
434 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
435 &recordDescriptors, &outFwDevicePkgData);
436 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
437
438 // invalidRecord3 size is less than RecordLength
439 constexpr std::array<uint8_t, 11> invalidRecord3{
440 0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00};
441 rc = decode_firmware_device_id_record(
442 invalidRecord3.data(), invalidRecord3.size(), componentBitmapBitLength,
443 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
444 &recordDescriptors, &outFwDevicePkgData);
445 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
446
447 // RecordLength is less than the calculated RecordLength
448 constexpr std::array<uint8_t, 11> invalidRecord4{
449 0x15, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02, 0x00};
450 rc = decode_firmware_device_id_record(
451 invalidRecord4.data(), invalidRecord4.size(), componentBitmapBitLength,
452 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
453 &recordDescriptors, &outFwDevicePkgData);
454 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Matt Johnstonc4d1c8b2024-12-18 11:16:55 +0800455
456 // Large FirmwareDevicePackageDataLength could cause overflow in calculation
457 constexpr std::array<uint8_t, 49> invalidRecord5{
458 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e,
459 // FirmwareDevicePackageDataLength = 0xffff
460 0xff, 0xff,
461 //
462 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72,
463 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64,
464 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b,
465 0xab, 0xcd};
466 rc = decode_firmware_device_id_record(
467 invalidRecord5.data(), invalidRecord5.size(), componentBitmapBitLength,
468 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
469 &recordDescriptors, &outFwDevicePkgData);
470 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930471}
472
473TEST(DecodeDescriptors, goodPath3Descriptors)
474{
475 // In the descriptor data there are 3 descriptor entries
476 // 1) IANA enterprise ID
477 constexpr std::array<uint8_t, PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH> iana{
478 0x0a, 0x0b, 0x0c, 0xd};
479 // 2) UUID
480 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
481 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
482 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
483 // 3) Vendor Defined
484 constexpr std::string_view vendorTitle{"OpenBMC"};
485 constexpr size_t vendorDescriptorLen = 2;
486 constexpr std::array<uint8_t, vendorDescriptorLen> vendorDescriptorData{
487 0x01, 0x02};
488
489 constexpr size_t vendorDefinedDescriptorLen =
490 sizeof(pldm_vendor_defined_descriptor_title_data()
491 .vendor_defined_descriptor_title_str_type) +
492 sizeof(pldm_vendor_defined_descriptor_title_data()
493 .vendor_defined_descriptor_title_str_len) +
494 vendorTitle.size() + vendorDescriptorData.size();
495
496 constexpr size_t descriptorsLength =
497 3 * (sizeof(pldm_descriptor_tlv().descriptor_type) +
498 sizeof(pldm_descriptor_tlv().descriptor_length)) +
499 iana.size() + uuid.size() + vendorDefinedDescriptorLen;
500
501 constexpr std::array<uint8_t, descriptorsLength> descriptors{
502 0x01, 0x00, 0x04, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x02, 0x00, 0x10,
503 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600504 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xff, 0xff, 0x0b, 0x00, 0x01,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930505 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x01, 0x02};
506
507 size_t descriptorCount = 1;
508 size_t descriptorsRemainingLength = descriptorsLength;
509 int rc = 0;
510
511 while (descriptorsRemainingLength && (descriptorCount <= 3))
512 {
513 uint16_t descriptorType = 0;
514 uint16_t descriptorLen = 0;
515 variable_field descriptorData{};
516
517 rc = decode_descriptor_type_length_value(
518 descriptors.data() + descriptorsLength - descriptorsRemainingLength,
519 descriptorsRemainingLength, &descriptorType, &descriptorData);
520 EXPECT_EQ(rc, PLDM_SUCCESS);
521
522 if (descriptorCount == 1)
523 {
524 EXPECT_EQ(descriptorType, PLDM_FWUP_IANA_ENTERPRISE_ID);
525 EXPECT_EQ(descriptorData.length,
526 PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH);
527 EXPECT_EQ(true,
528 std::equal(descriptorData.ptr,
529 descriptorData.ptr + descriptorData.length,
530 iana.begin(), iana.end()));
531 }
532 else if (descriptorCount == 2)
533 {
534 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
535 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
536 EXPECT_EQ(true,
537 std::equal(descriptorData.ptr,
538 descriptorData.ptr + descriptorData.length,
539 uuid.begin(), uuid.end()));
540 }
541 else if (descriptorCount == 3)
542 {
543 EXPECT_EQ(descriptorType, PLDM_FWUP_VENDOR_DEFINED);
544 EXPECT_EQ(descriptorData.length, vendorDefinedDescriptorLen);
545
546 uint8_t descriptorTitleStrType = 0;
547 variable_field descriptorTitleStr{};
548 variable_field vendorDefinedDescriptorData{};
549
550 rc = decode_vendor_defined_descriptor_value(
551 descriptorData.ptr, descriptorData.length,
552 &descriptorTitleStrType, &descriptorTitleStr,
553 &vendorDefinedDescriptorData);
554 EXPECT_EQ(rc, PLDM_SUCCESS);
555
556 EXPECT_EQ(descriptorTitleStrType, PLDM_STR_TYPE_ASCII);
557 EXPECT_EQ(descriptorTitleStr.length, vendorTitle.size());
558 std::string vendorTitleStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930559 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930560 reinterpret_cast<const char*>(descriptorTitleStr.ptr),
561 descriptorTitleStr.length);
562 EXPECT_EQ(vendorTitleStr, vendorTitle);
563
564 EXPECT_EQ(vendorDefinedDescriptorData.length,
565 vendorDescriptorData.size());
566 EXPECT_EQ(true, std::equal(vendorDefinedDescriptorData.ptr,
567 vendorDefinedDescriptorData.ptr +
568 vendorDefinedDescriptorData.length,
569 vendorDescriptorData.begin(),
570 vendorDescriptorData.end()));
571 }
572
573 descriptorsRemainingLength -= sizeof(descriptorType) +
574 sizeof(descriptorLen) +
575 descriptorData.length;
576 descriptorCount++;
577 }
578}
579
580TEST(DecodeDescriptors, errorPathDecodeDescriptorTLV)
581{
582 int rc = 0;
583 // IANA Enterprise ID descriptor length incorrect
584 constexpr std::array<uint8_t, 7> invalidIANADescriptor1{
585 0x01, 0x00, 0x03, 0x00, 0x0a, 0x0b, 0x0c};
586 uint16_t descriptorType = 0;
587 variable_field descriptorData{};
588
589 rc = decode_descriptor_type_length_value(nullptr,
590 invalidIANADescriptor1.size(),
591 &descriptorType, &descriptorData);
592 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
593
594 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
595 invalidIANADescriptor1.size(),
596 nullptr, &descriptorData);
597 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
598
599 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
600 invalidIANADescriptor1.size(),
601 &descriptorType, nullptr);
602 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
603
604 rc = decode_descriptor_type_length_value(
605 invalidIANADescriptor1.data(), PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN - 1,
606 &descriptorType, &descriptorData);
607 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
608
609 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
610 invalidIANADescriptor1.size(),
611 &descriptorType, &descriptorData);
Andrew Jeffery779e9db2025-02-21 12:14:28 +1030612 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930613
614 // IANA Enterprise ID descriptor data less than length
615 std::array<uint8_t, 7> invalidIANADescriptor2{0x01, 0x00, 0x04, 0x00,
616 0x0a, 0x0b, 0x0c};
617 rc = decode_descriptor_type_length_value(invalidIANADescriptor2.data(),
618 invalidIANADescriptor2.size(),
619 &descriptorType, &descriptorData);
620 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
621}
622
623TEST(DecodeDescriptors, errorPathVendorDefinedDescriptor)
624{
625 int rc = 0;
626 // VendorDefinedDescriptorTitleStringType is invalid
627 constexpr std::array<uint8_t, 9> invalidVendorDescriptor1{
628 0x06, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
629 uint8_t descriptorStringType = 0;
630 variable_field descriptorTitleStr{};
631 variable_field vendorDefinedDescriptorData{};
632
633 rc = decode_vendor_defined_descriptor_value(
634 nullptr, invalidVendorDescriptor1.size(), &descriptorStringType,
635 &descriptorTitleStr, &vendorDefinedDescriptorData);
636 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
637
638 rc = decode_vendor_defined_descriptor_value(
639 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
640 &descriptorStringType, &descriptorTitleStr,
641 &vendorDefinedDescriptorData);
642 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
643
644 rc = decode_vendor_defined_descriptor_value(
645 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
646 nullptr, &descriptorTitleStr, &vendorDefinedDescriptorData);
647 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
648
649 rc = decode_vendor_defined_descriptor_value(
650 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
651 &descriptorStringType, nullptr, &vendorDefinedDescriptorData);
652 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
653
654 rc = decode_vendor_defined_descriptor_value(
655 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
656 &descriptorStringType, &descriptorTitleStr, nullptr);
657 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
658
659 rc = decode_vendor_defined_descriptor_value(
660 invalidVendorDescriptor1.data(),
661 sizeof(pldm_vendor_defined_descriptor_title_data) - 1,
662 &descriptorStringType, &descriptorTitleStr,
663 &vendorDefinedDescriptorData);
664 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
665
666 rc = decode_vendor_defined_descriptor_value(
667 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
668 &descriptorStringType, &descriptorTitleStr,
669 &vendorDefinedDescriptorData);
670 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
671
672 // VendorDefinedDescriptorTitleStringLength is 0
673 std::array<uint8_t, 9> invalidVendorDescriptor2{
674 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
675 rc = decode_vendor_defined_descriptor_value(
676 invalidVendorDescriptor2.data(), invalidVendorDescriptor2.size(),
677 &descriptorStringType, &descriptorTitleStr,
678 &vendorDefinedDescriptorData);
679 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
680
681 // VendorDefinedDescriptorData not present in the data
682 std::array<uint8_t, 9> invalidVendorDescriptor3{
683 0x01, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
684 rc = decode_vendor_defined_descriptor_value(
685 invalidVendorDescriptor3.data(), invalidVendorDescriptor3.size(),
686 &descriptorStringType, &descriptorTitleStr,
687 &vendorDefinedDescriptorData);
688 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
689}
690
691TEST(DecodeComponentImageInfo, goodPath)
692{
693 // Firmware
694 constexpr uint16_t compClassification = 16;
695 constexpr uint16_t compIdentifier = 300;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600696 constexpr uint32_t compComparisonStamp = 0xffffffff;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930697 // Force update
698 constexpr std::bitset<16> compOptions{1};
699 // System reboot[Bit position 3] & Medium-specific reset[Bit position 2]
700 constexpr std::bitset<16> reqCompActivationMethod{0x0c};
701 // Random ComponentLocationOffset
702 constexpr uint32_t compLocOffset = 357;
703 // Random ComponentSize
704 constexpr uint32_t compSize = 27;
705 // ComponentVersionString
706 constexpr std::string_view compVersionStr{"VersionString1"};
707 constexpr size_t compImageInfoSize =
708 sizeof(pldm_component_image_information) + compVersionStr.size();
709
710 constexpr std::array<uint8_t, compImageInfoSize> compImageInfo{
711 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
712 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
713 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
714 pldm_component_image_information outCompImageInfo{};
715 variable_field outCompVersionStr{};
716
717 auto rc =
718 decode_pldm_comp_image_info(compImageInfo.data(), compImageInfo.size(),
719 &outCompImageInfo, &outCompVersionStr);
720
721 EXPECT_EQ(rc, PLDM_SUCCESS);
722 EXPECT_EQ(outCompImageInfo.comp_classification, compClassification);
723 EXPECT_EQ(outCompImageInfo.comp_identifier, compIdentifier);
724 EXPECT_EQ(outCompImageInfo.comp_comparison_stamp, compComparisonStamp);
725 EXPECT_EQ(outCompImageInfo.comp_options.value, compOptions);
726 EXPECT_EQ(outCompImageInfo.requested_comp_activation_method.value,
727 reqCompActivationMethod);
728 EXPECT_EQ(outCompImageInfo.comp_location_offset, compLocOffset);
729 EXPECT_EQ(outCompImageInfo.comp_size, compSize);
730 EXPECT_EQ(outCompImageInfo.comp_version_string_type, PLDM_STR_TYPE_ASCII);
731 EXPECT_EQ(outCompImageInfo.comp_version_string_length,
732 compVersionStr.size());
733
734 EXPECT_EQ(outCompVersionStr.length,
735 outCompImageInfo.comp_version_string_length);
736 std::string componentVersionString(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930737 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930738 reinterpret_cast<const char*>(outCompVersionStr.ptr),
739 outCompVersionStr.length);
740 EXPECT_EQ(componentVersionString, compVersionStr);
741}
742
743TEST(DecodeComponentImageInfo, errorPaths)
744{
745 int rc = 0;
746 // ComponentVersionString
747 constexpr std::string_view compVersionStr{"VersionString1"};
748 constexpr size_t compImageInfoSize =
749 sizeof(pldm_component_image_information) + compVersionStr.size();
750 // Invalid ComponentVersionStringType - 0x06
751 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo1{
752 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
753 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x56, 0x65,
754 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
755 pldm_component_image_information outCompImageInfo{};
756 variable_field outCompVersionStr{};
757
758 rc = decode_pldm_comp_image_info(nullptr, invalidCompImageInfo1.size(),
759 &outCompImageInfo, &outCompVersionStr);
760 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
761
762 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
763 invalidCompImageInfo1.size(), nullptr,
764 &outCompVersionStr);
765 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
766
767 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
768 invalidCompImageInfo1.size(),
769 &outCompImageInfo, nullptr);
770 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
771
772 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
773 sizeof(pldm_component_image_information) -
774 1,
775 &outCompImageInfo, &outCompVersionStr);
776 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
777
778 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
779 invalidCompImageInfo1.size(),
780 &outCompImageInfo, &outCompVersionStr);
781 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
782
783 // Invalid ComponentVersionStringLength - 0x00
784 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo2{
785 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
786 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x65,
787 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
788 rc = decode_pldm_comp_image_info(invalidCompImageInfo2.data(),
789 invalidCompImageInfo2.size(),
790 &outCompImageInfo, &outCompVersionStr);
791 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
792
793 // Use Component Comparison Stamp is not set, but ComponentComparisonStamp
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600794 // is not 0xffffffff
Andrew Jeffery9c766792022-08-10 23:12:49 +0930795 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo3{
796 0x10, 0x00, 0x2c, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00,
797 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
798 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
799
800 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
801 invalidCompImageInfo3.size() - 1,
802 &outCompImageInfo, &outCompVersionStr);
803 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
804
805 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
806 invalidCompImageInfo3.size(),
807 &outCompImageInfo, &outCompVersionStr);
808 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
809
810 // Invalid ComponentLocationOffset - 0
811 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo4{
812 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
813 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
814 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
815 rc = decode_pldm_comp_image_info(invalidCompImageInfo4.data(),
816 invalidCompImageInfo4.size(),
817 &outCompImageInfo, &outCompVersionStr);
818 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
819
820 // Invalid ComponentSize - 0
821 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo5{
822 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
823 0x65, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
824 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
825 rc = decode_pldm_comp_image_info(invalidCompImageInfo5.data(),
826 invalidCompImageInfo5.size(),
827 &outCompImageInfo, &outCompVersionStr);
828 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
829}
830
831TEST(QueryDeviceIdentifiers, goodPathEncodeRequest)
832{
833 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930834 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930835 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
836
837 uint8_t instanceId = 0x01;
838
839 auto rc = encode_query_device_identifiers_req(
840 instanceId, PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES, requestPtr);
841 EXPECT_EQ(rc, PLDM_SUCCESS);
842 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
843 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
844 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
845 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DEVICE_IDENTIFIERS);
846}
847
848TEST(QueryDeviceIdentifiers, goodPathDecodeResponse)
849{
850 // descriptorDataLen is not fixed here taking it as 6
851 constexpr uint8_t descriptorDataLen = 6;
852 std::array<uint8_t, hdrSize +
853 sizeof(struct pldm_query_device_identifiers_resp) +
854 descriptorDataLen>
855 responseMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930856 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930857 auto inResp = reinterpret_cast<struct pldm_query_device_identifiers_resp*>(
858 responseMsg.data() + hdrSize);
859
860 inResp->completion_code = PLDM_SUCCESS;
861 inResp->device_identifiers_len = htole32(descriptorDataLen);
862 inResp->descriptor_count = 1;
863
864 // filling descriptor data
865 std::fill_n(responseMsg.data() + hdrSize +
866 sizeof(struct pldm_query_device_identifiers_resp),
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600867 descriptorDataLen, 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930868
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930869 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930870 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
871 uint8_t completionCode = PLDM_SUCCESS;
872 uint32_t deviceIdentifiersLen = 0;
873 uint8_t descriptorCount = 0;
874 uint8_t* outDescriptorData = nullptr;
875
876 auto rc = decode_query_device_identifiers_resp(
877 response, responseMsg.size() - hdrSize, &completionCode,
878 &deviceIdentifiersLen, &descriptorCount, &outDescriptorData);
879
880 EXPECT_EQ(rc, PLDM_SUCCESS);
881 EXPECT_EQ(completionCode, PLDM_SUCCESS);
882 EXPECT_EQ(deviceIdentifiersLen, inResp->device_identifiers_len);
883 EXPECT_EQ(descriptorCount, inResp->descriptor_count);
884 EXPECT_EQ(true,
885 std::equal(outDescriptorData,
886 outDescriptorData + deviceIdentifiersLen,
887 responseMsg.begin() + hdrSize +
888 sizeof(struct pldm_query_device_identifiers_resp),
889 responseMsg.end()));
890}
891
Matt Johnstoncf9a2df2024-11-07 15:29:29 +0800892#ifdef LIBPLDM_API_TESTING
893TEST(QueryDeviceIdentifiers, goodPathEncodeResponse)
894{
895 int rc;
896 PLDM_MSG_DEFINE_P(enc, 1000);
897 size_t enc_payload_len = 1000;
898 pldm_descriptor check_desc[] = {
899 {
900 .descriptor_type = PLDM_FWUP_IANA_ENTERPRISE_ID,
901 .descriptor_length = 4,
902 .descriptor_data = "a123",
903 },
904 {
905 .descriptor_type = PLDM_FWUP_VENDOR_DEFINED,
906 .descriptor_length = 3,
907 .descriptor_data = "987",
908 },
909 };
910 rc = encode_query_device_identifiers_resp(FIXED_INSTANCE_ID, 2, check_desc,
911 enc, &enc_payload_len);
912 EXPECT_EQ(rc, 0);
913 EXPECT_THAT(std::span<uint8_t>(enc_buf + hdrSize, enc_payload_len),
914 ElementsAreArray<uint8_t>({
915 // completion code
916 0x00,
917 // device identifiers length = 15
918 0x0f,
919 0x00,
920 0x00,
921 0x00,
922 // descriptor count
923 0x02,
924 // desc 0
925 0x01,
926 0x00,
927 0x04,
928 0x00,
929 0x61,
930 0x31,
931 0x32,
932 0x33,
933 // desc 1
934 0xff,
935 0xff,
936 0x03,
937 0x00,
938 0x39,
939 0x38,
940 0x37,
941 }));
942
943 check_response(enc, PLDM_QUERY_DEVICE_IDENTIFIERS);
944}
945#endif
946
Andrew Jeffery9c766792022-08-10 23:12:49 +0930947TEST(GetFirmwareParameters, goodPathEncodeRequest)
948{
949 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930950 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930951 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
952 uint8_t instanceId = 0x01;
953
954 auto rc = encode_get_firmware_parameters_req(
955 instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, requestPtr);
956 EXPECT_EQ(rc, PLDM_SUCCESS);
957 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
958 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
959 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
960 EXPECT_EQ(requestPtr->hdr.command, PLDM_GET_FIRMWARE_PARAMETERS);
961}
962
963TEST(GetFirmwareParameters, decodeResponse)
964{
965 // CapabilitiesDuringUpdate of the firmware device
966 // Firmware device downgrade restrictions [Bit position 8] &
967 // Firmware Device Partial Updates [Bit position 3]
968 constexpr std::bitset<32> fdCapabilities{0x00000104};
969 constexpr uint16_t compCount = 1;
970 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
971 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
972
973 // constexpr uint16_t compClassification = 16;
974 // constexpr uint16_t compIdentifier = 300;
975 // constexpr uint8_t compClassificationIndex = 20;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600976 // constexpr uint32_t activeCompComparisonStamp = 0xabcdefab;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930977 // constexpr std::array<uint8_t, 8> activeComponentReleaseData = {
978 // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
979 // constexpr uint32_t pendingCompComparisonStamp = 0x12345678;
980 // constexpr std::array<uint8_t, 8> pendingComponentReleaseData = {
981 // 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
982 constexpr std::string_view activeCompVersion{"VersionString3"};
983 constexpr std::string_view pendingCompVersion{"VersionString4"};
Andrew Jeffery9c766792022-08-10 23:12:49 +0930984
985 constexpr size_t compParamTableSize =
986 sizeof(pldm_component_parameter_entry) + activeCompVersion.size() +
987 pendingCompVersion.size();
988
989 constexpr std::array<uint8_t, compParamTableSize> compParamTable{
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600990 0x10, 0x00, 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930991 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
992 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00, 0x02,
993 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74,
994 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
995 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
996
997 constexpr size_t getFwParamsPayloadLen =
998 sizeof(pldm_get_firmware_parameters_resp) +
999 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size() +
1000 compParamTableSize;
1001
1002 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1003 getFwParamsResponse{
1004 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01,
1005 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
1006 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
1007 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x10, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001008 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01, 0x02,
Andrew Jeffery9c766792022-08-10 23:12:49 +09301009 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
1010 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00,
1011 0x02, 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1012 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73,
1013 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
1014
1015 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301016 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301017 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1018 pldm_get_firmware_parameters_resp outResp{};
1019 variable_field outActiveCompImageSetVersion{};
1020 variable_field outPendingCompImageSetVersion{};
1021 variable_field outCompParameterTable{};
1022
1023 auto rc = decode_get_firmware_parameters_resp(
1024 responseMsg, getFwParamsPayloadLen, &outResp,
1025 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1026 &outCompParameterTable);
1027
1028 EXPECT_EQ(rc, PLDM_SUCCESS);
1029 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1030 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1031 EXPECT_EQ(outResp.comp_count, compCount);
1032 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1033 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1034 activeCompImageSetVersion.size());
1035 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1036 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1037 pendingCompImageSetVersion.size());
1038 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301039 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301040 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1041 outActiveCompImageSetVersion.length);
1042 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1043 std::string pendingCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301044 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301045 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
1046 outPendingCompImageSetVersion.length);
1047 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1048 EXPECT_EQ(outCompParameterTable.length, compParamTableSize);
1049 EXPECT_EQ(true, std::equal(outCompParameterTable.ptr,
1050 outCompParameterTable.ptr +
1051 outCompParameterTable.length,
1052 compParamTable.begin(), compParamTable.end()));
1053}
1054
1055TEST(GetFirmwareParameters, decodeResponseZeroCompCount)
1056{
1057 // CapabilitiesDuringUpdate of the firmware device
1058 // FD Host Functionality during Firmware Update [Bit position 2] &
1059 // Component Update Failure Retry Capability [Bit position 1]
1060 constexpr std::bitset<32> fdCapabilities{0x06};
1061 constexpr uint16_t compCount = 0;
1062 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
1063 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
1064
1065 constexpr size_t getFwParamsPayloadLen =
1066 sizeof(pldm_get_firmware_parameters_resp) +
1067 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size();
1068
1069 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1070 getFwParamsResponse{
1071 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1072 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
1073 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
1074 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32};
1075
1076 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301077 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301078 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1079 pldm_get_firmware_parameters_resp outResp{};
1080 variable_field outActiveCompImageSetVersion{};
1081 variable_field outPendingCompImageSetVersion{};
1082 variable_field outCompParameterTable{};
1083
1084 auto rc = decode_get_firmware_parameters_resp(
1085 responseMsg, getFwParamsPayloadLen, &outResp,
1086 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1087 &outCompParameterTable);
1088
1089 EXPECT_EQ(rc, PLDM_SUCCESS);
1090 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1091 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1092 EXPECT_EQ(outResp.comp_count, compCount);
1093 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1094 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1095 activeCompImageSetVersion.size());
1096 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1097 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1098 pendingCompImageSetVersion.size());
1099 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301100 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301101 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1102 outActiveCompImageSetVersion.length);
1103 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1104 std::string pendingCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301105 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301106 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
1107 outPendingCompImageSetVersion.length);
1108 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1109 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1110 EXPECT_EQ(outCompParameterTable.length, 0);
1111}
1112
1113TEST(GetFirmwareParameters,
1114 decodeResponseNoPendingCompImageVersionStrZeroCompCount)
1115{
1116 // CapabilitiesDuringUpdate of the firmware device
1117 // FD Host Functionality during Firmware Update [Bit position 2] &
1118 // Component Update Failure Retry Capability [Bit position 1]
1119 constexpr std::bitset<32> fdCapabilities{0x06};
1120 constexpr uint16_t compCount = 0;
1121 constexpr std::string_view activeCompImageSetVersion{"VersionString"};
1122
1123 constexpr size_t getFwParamsPayloadLen =
1124 sizeof(pldm_get_firmware_parameters_resp) +
1125 activeCompImageSetVersion.size();
1126
1127 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1128 getFwParamsResponse{0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1129 0x00, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00,
1130 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1131 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67};
1132
1133 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301134 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301135 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1136 pldm_get_firmware_parameters_resp outResp{};
1137 variable_field outActiveCompImageSetVersion{};
1138 variable_field outPendingCompImageSetVersion{};
1139 variable_field outCompParameterTable{};
1140
1141 auto rc = decode_get_firmware_parameters_resp(
1142 responseMsg, getFwParamsPayloadLen, &outResp,
1143 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1144 &outCompParameterTable);
1145
1146 EXPECT_EQ(rc, PLDM_SUCCESS);
1147 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1148 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1149 EXPECT_EQ(outResp.comp_count, compCount);
1150 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1151 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1152 activeCompImageSetVersion.size());
1153 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type,
1154 PLDM_STR_TYPE_UNKNOWN);
1155 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len, 0);
1156 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301157 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301158 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1159 outActiveCompImageSetVersion.length);
1160 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1161 EXPECT_EQ(outPendingCompImageSetVersion.ptr, nullptr);
1162 EXPECT_EQ(outPendingCompImageSetVersion.length, 0);
1163 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1164 EXPECT_EQ(outCompParameterTable.length, 0);
1165}
1166
1167TEST(GetFirmwareParameters, decodeResponseErrorCompletionCode)
1168{
1169 constexpr std::array<uint8_t, hdrSize + sizeof(uint8_t)>
1170 getFwParamsResponse{0x00, 0x00, 0x00, 0x01};
1171
1172 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301173 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301174 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1175 pldm_get_firmware_parameters_resp outResp{};
1176 variable_field outActiveCompImageSetVersion{};
1177 variable_field outPendingCompImageSetVersion{};
1178 variable_field outCompParameterTable{};
1179
1180 auto rc = decode_get_firmware_parameters_resp(
1181 responseMsg, getFwParamsResponse.size(), &outResp,
1182 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1183 &outCompParameterTable);
1184
1185 EXPECT_EQ(rc, PLDM_SUCCESS);
1186 EXPECT_EQ(outResp.completion_code, PLDM_ERROR);
1187}
1188
1189TEST(GetFirmwareParameters, errorPathdecodeResponse)
1190{
1191 int rc = 0;
1192 // Invalid ActiveComponentImageSetVersionStringType
1193 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse1{
1194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1195 0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
1196
1197 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301198 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301199 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse1.data());
1200 pldm_get_firmware_parameters_resp outResp{};
1201 variable_field outActiveCompImageSetVersion{};
1202 variable_field outPendingCompImageSetVersion{};
1203 variable_field outCompParameterTable{};
1204
1205 rc = decode_get_firmware_parameters_resp(
1206 nullptr, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1207 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1208 &outCompParameterTable);
1209 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1210
1211 rc = decode_get_firmware_parameters_resp(
1212 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, nullptr,
1213 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1214 &outCompParameterTable);
1215 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1216
1217 rc = decode_get_firmware_parameters_resp(
1218 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1219 nullptr, &outPendingCompImageSetVersion, &outCompParameterTable);
1220 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1221
1222 rc = decode_get_firmware_parameters_resp(
1223 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1224 &outActiveCompImageSetVersion, nullptr, &outCompParameterTable);
1225 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1226
1227 rc = decode_get_firmware_parameters_resp(
1228 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1229 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, nullptr);
1230 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1231
1232 rc = decode_get_firmware_parameters_resp(
1233 responseMsg, 0, &outResp, &outActiveCompImageSetVersion,
1234 &outPendingCompImageSetVersion, &outCompParameterTable);
1235 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1236
1237 rc = decode_get_firmware_parameters_resp(
1238 responseMsg, invalidGetFwParamsResponse1.size() - 1 - hdrSize, &outResp,
1239 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1240 &outCompParameterTable);
1241 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1242
1243 rc = decode_get_firmware_parameters_resp(
1244 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1245 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1246 &outCompParameterTable);
1247 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1248
1249 // Invalid ActiveComponentImageSetVersionStringLength
1250 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse2{
1251 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1252 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
1253 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301254 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301255 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse2.data());
1256 rc = decode_get_firmware_parameters_resp(
1257 responseMsg, invalidGetFwParamsResponse2.size() - hdrSize, &outResp,
1258 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1259 &outCompParameterTable);
1260 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1261
1262 // Invalid PendingComponentImageSetVersionStringType &
1263 // PendingComponentImageSetVersionStringLength
1264 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse3{
1265 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1266 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x00};
1267 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301268 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301269 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse3.data());
1270 rc = decode_get_firmware_parameters_resp(
1271 responseMsg, invalidGetFwParamsResponse3.size() - hdrSize, &outResp,
1272 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1273 &outCompParameterTable);
1274 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1275
1276 // Invalid PendingComponentImageSetVersionStringType &
1277 // PendingComponentImageSetVersionStringLength
1278 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse4{
1279 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1280 0x00, 0x00, 0x00, 0x01, 0x0e, 0x06, 0x0e};
1281 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301282 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301283 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse4.data());
1284 rc = decode_get_firmware_parameters_resp(
1285 responseMsg, invalidGetFwParamsResponse4.size() - hdrSize, &outResp,
1286 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1287 &outCompParameterTable);
1288 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1289
1290 // Total payload length less than expected
1291 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse5{
1292 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1293 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x0e};
1294 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301295 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301296 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse5.data());
1297 rc = decode_get_firmware_parameters_resp(
1298 responseMsg, invalidGetFwParamsResponse5.size() - hdrSize, &outResp,
1299 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1300 &outCompParameterTable);
1301 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1302}
1303
1304TEST(GetFirmwareParameters, goodPathDecodeComponentParameterEntry)
1305{
1306 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001307 constexpr uint16_t compClassification = 0x0a0b;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301308 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001309 constexpr uint16_t compIdentifier = 0x0c0d;
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001310 constexpr uint16_t compClassificationIndex = 0xf;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301311 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001312 constexpr uint32_t timestamp = 0x12345678;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301313 // Random value for component activation methods
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001314 constexpr uint16_t compActivationMethods = 0xbbdd;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301315 // Random value for capabilities during update
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001316 constexpr uint32_t capabilitiesDuringUpdate = 0xbadbeefe;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301317
1318 // ActiveCompImageSetVerStrLen is not fixed here taking it as 8
1319 constexpr uint8_t activeCompVerStrLen = 8;
1320 // PendingCompImageSetVerStrLen is not fixed here taking it as 8
1321 constexpr uint8_t pendingCompVerStrLen = 8;
1322 constexpr size_t entryLength =
1323 sizeof(struct pldm_component_parameter_entry) + activeCompVerStrLen +
1324 pendingCompVerStrLen;
1325 std::array<uint8_t, entryLength> entry{};
1326
1327 auto inEntry =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301328 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301329 reinterpret_cast<struct pldm_component_parameter_entry*>(entry.data());
1330
1331 inEntry->comp_classification = htole16(compClassification);
1332 inEntry->comp_identifier = htole16(compIdentifier);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001333 inEntry->comp_classification_index = compClassificationIndex;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301334 inEntry->active_comp_comparison_stamp = htole32(timestamp);
1335 inEntry->active_comp_ver_str_type = 1;
1336 inEntry->active_comp_ver_str_len = activeCompVerStrLen;
1337 std::fill_n(inEntry->active_comp_release_date,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001338 sizeof(inEntry->active_comp_release_date), 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301339 inEntry->pending_comp_comparison_stamp = htole32(timestamp);
1340 inEntry->pending_comp_ver_str_type = 1;
1341 inEntry->pending_comp_ver_str_len = pendingCompVerStrLen;
1342 std::fill_n(inEntry->pending_comp_release_date,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001343 sizeof(inEntry->pending_comp_release_date), 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301344 inEntry->comp_activation_methods.value = htole16(compActivationMethods);
1345 inEntry->capabilities_during_update.value =
1346 htole32(capabilitiesDuringUpdate);
1347 constexpr auto activeCompVerStrPos =
1348 sizeof(struct pldm_component_parameter_entry);
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001349 std::fill_n(entry.data() + activeCompVerStrPos, activeCompVerStrLen, 0xaa);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301350 constexpr auto pendingCompVerStrPos =
1351 activeCompVerStrPos + activeCompVerStrLen;
1352 std::fill_n(entry.data() + pendingCompVerStrPos, pendingCompVerStrLen,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001353 0xbb);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301354
1355 struct pldm_component_parameter_entry outEntry;
1356 struct variable_field outActiveCompVerStr;
1357 struct variable_field outPendingCompVerStr;
1358
1359 auto rc = decode_get_firmware_parameters_resp_comp_entry(
1360 entry.data(), entryLength, &outEntry, &outActiveCompVerStr,
1361 &outPendingCompVerStr);
1362
1363 EXPECT_EQ(rc, PLDM_SUCCESS);
1364
1365 EXPECT_EQ(outEntry.comp_classification, compClassification);
1366 EXPECT_EQ(outEntry.comp_identifier, compIdentifier);
1367 EXPECT_EQ(inEntry->comp_classification_index,
1368 outEntry.comp_classification_index);
1369 EXPECT_EQ(outEntry.active_comp_comparison_stamp, timestamp);
1370 EXPECT_EQ(inEntry->active_comp_ver_str_type,
1371 outEntry.active_comp_ver_str_type);
1372 EXPECT_EQ(inEntry->active_comp_ver_str_len,
1373 outEntry.active_comp_ver_str_len);
1374 EXPECT_EQ(0, memcmp(inEntry->active_comp_release_date,
1375 outEntry.active_comp_release_date,
1376 sizeof(inEntry->active_comp_release_date)));
1377 EXPECT_EQ(outEntry.pending_comp_comparison_stamp, timestamp);
1378 EXPECT_EQ(inEntry->pending_comp_ver_str_type,
1379 outEntry.pending_comp_ver_str_type);
1380 EXPECT_EQ(inEntry->pending_comp_ver_str_len,
1381 outEntry.pending_comp_ver_str_len);
1382 EXPECT_EQ(0, memcmp(inEntry->pending_comp_release_date,
1383 outEntry.pending_comp_release_date,
1384 sizeof(inEntry->pending_comp_release_date)));
1385 EXPECT_EQ(outEntry.comp_activation_methods.value, compActivationMethods);
1386 EXPECT_EQ(outEntry.capabilities_during_update.value,
1387 capabilitiesDuringUpdate);
1388
1389 EXPECT_EQ(0, memcmp(outActiveCompVerStr.ptr,
1390 entry.data() + activeCompVerStrPos,
1391 outActiveCompVerStr.length));
1392 EXPECT_EQ(0, memcmp(outPendingCompVerStr.ptr,
1393 entry.data() + pendingCompVerStrPos,
1394 outPendingCompVerStr.length));
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001395
1396#ifdef LIBPLDM_API_TESTING
1397 /* Check the roundtrip matches */
1398 std::vector<uint8_t> enc_data(1000);
1399 size_t enc_payload_len = enc_data.size();
1400 struct pldm_component_parameter_entry_full entryFull = {
1401 .comp_classification = compClassification,
1402 .comp_identifier = compIdentifier,
1403 .comp_classification_index = compClassificationIndex,
1404 .active_ver =
1405 {
1406 .comparison_stamp = 0x12345678,
1407 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1408 .str_len = activeCompVerStrLen,
1409 .str_data = {}},
1410 .date = {},
1411 },
1412 .pending_ver =
1413 {
1414 .comparison_stamp = 0x12345678,
1415 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1416 .str_len = pendingCompVerStrLen,
1417 .str_data = {}},
1418 .date = {},
1419 },
1420 .comp_activation_methods = inEntry->comp_activation_methods,
1421 .capabilities_during_update = inEntry->capabilities_during_update,
1422 };
1423 // Fill strings
1424 std::fill_n(entryFull.active_ver.str.str_data, activeCompVerStrLen, 0xaa);
1425 std::fill_n(entryFull.pending_ver.str.str_data, pendingCompVerStrLen, 0xbb);
1426 std::fill_n(entryFull.active_ver.date, PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN,
1427 0xff);
1428 std::fill_n(entryFull.pending_ver.date,
1429 PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN, 0xff);
1430
1431 rc = encode_get_firmware_parameters_resp_comp_entry(
1432 &entryFull, enc_data.data(), &enc_payload_len);
1433 EXPECT_EQ(rc, PLDM_SUCCESS);
1434 EXPECT_EQ(enc_payload_len, entryLength);
1435 EXPECT_TRUE(std::equal(entry.begin(), entry.end(), enc_data.begin()));
1436#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09301437}
1438
Chris Wang4c1f2c72024-03-21 17:09:44 +08001439TEST(QueryDownstreamDevices, goodPathEncodeRequest)
1440{
1441 constexpr uint8_t instanceId = 1;
1442 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301443 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001444 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1445
1446 auto rc = encode_query_downstream_devices_req(instanceId, requestPtr);
1447
Unive Tien71e935c2024-11-25 17:21:43 +08001448 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001449 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1450 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1451 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1452 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DOWNSTREAM_DEVICES);
1453}
1454
1455TEST(QueryDownstreamDevices, encodeRequestInvalidData)
1456{
1457 constexpr uint8_t instanceId = 1;
1458
1459 auto rc = encode_query_downstream_devices_req(instanceId, nullptr);
1460
Unive Tien71e935c2024-11-25 17:21:43 +08001461 EXPECT_EQ(rc, -EINVAL);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001462}
1463
1464TEST(QueryDownstreamDevices, goodPathDecodeResponse)
1465{
1466 uint8_t completion_code_resp = PLDM_SUCCESS;
1467 uint8_t downstream_device_update_supported_resp =
1468 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1469 uint16_t number_of_downstream_devices_resp = 1;
1470 uint16_t max_number_of_downstream_devices_resp = 1;
1471 /** Capabilities of updating downstream devices
1472 * FDP supports downstream devices dynamically attached [Bit position 0] &
1473 * FDP supports downstream devices dynamically removed [Bit position 1]
1474 */
1475 bitfield32_t capabilities_resp = {.value = 0x0002};
1476 int rc;
1477
1478 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1479 responseMsg{};
1480
Andrew Jefferya1896962025-03-03 21:41:25 +10301481 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301482 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1483 responseMsg.size() - hdrSize);
1484 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001485
1486 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1487 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1488 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1489 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1490 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301491 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001492
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301493 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001494 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1495 struct pldm_query_downstream_devices_resp resp_data;
1496
1497 rc = decode_query_downstream_devices_resp(
1498 response, responseMsg.size() - hdrSize, &resp_data);
1499
Unive Tien71e935c2024-11-25 17:21:43 +08001500 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001501 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1502 EXPECT_EQ(resp_data.downstream_device_update_supported,
1503 downstream_device_update_supported_resp);
1504 EXPECT_EQ(resp_data.number_of_downstream_devices,
1505 number_of_downstream_devices_resp);
1506 EXPECT_EQ(resp_data.max_number_of_downstream_devices,
1507 max_number_of_downstream_devices_resp);
1508 EXPECT_EQ(resp_data.capabilities.value, capabilities_resp.value);
1509}
1510
1511TEST(QueryDownstreamDevices, decodeRequestUndefinedValue)
1512{
1513 uint8_t completion_code_resp = PLDM_SUCCESS;
1514 uint8_t downstream_device_update_supported_resp = 0xe; /*Undefined value*/
1515 uint16_t number_of_downstream_devices_resp = 1;
1516 uint16_t max_number_of_downstream_devices_resp = 1;
1517 /** Capabilities of updating downstream devices
1518 * FDP supports downstream devices dynamically attached [Bit position 0] &
1519 * FDP supports downstream devices dynamically removed [Bit position 1]
1520 */
1521 bitfield32_t capabilities_resp = {.value = 0x0002};
1522 int rc;
1523
1524 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1525 responseMsg{};
1526
Andrew Jefferya1896962025-03-03 21:41:25 +10301527 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301528 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1529 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10301530 ASSERT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001531 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1532 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1533 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1534 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1535 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301536 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001537
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301538 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001539 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1540 struct pldm_query_downstream_devices_resp resp_data;
1541
1542 rc = decode_query_downstream_devices_resp(
1543 response, responseMsg.size() - hdrSize, &resp_data);
1544
Unive Tien71e935c2024-11-25 17:21:43 +08001545 ASSERT_EQ(rc, -EINVAL);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001546}
1547
1548TEST(QueryDownstreamDevices, decodeRequestErrorBufSize)
1549{
1550 uint8_t completion_code_resp = PLDM_SUCCESS;
1551 uint8_t downstream_device_update_supported_resp =
1552 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1553 uint16_t number_of_downstream_devices_resp = 1;
1554 uint16_t max_number_of_downstream_devices_resp = 1;
1555 /** Capabilities of updating downstream devices
1556 * FDP supports downstream devices dynamically attached [Bit position 0] &
1557 * FDP supports downstream devices dynamically removed [Bit position 1]
1558 */
1559 bitfield32_t capabilities_resp = {.value = 0x0002};
1560 int rc;
1561
1562 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES -
1563 2 /* Inject error length*/>
1564 responseMsg{};
1565
Andrew Jefferya1896962025-03-03 21:41:25 +10301566 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301567 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1568 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10301569 ASSERT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001570
1571 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1572 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1573 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1574 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1575 // Inject error value
1576 pldm_msgbuf_insert_uint16(buf, (uint16_t)capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301577 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001578
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301579 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001580 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1581 struct pldm_query_downstream_devices_resp resp_data;
1582
1583 rc = decode_query_downstream_devices_resp(
1584 response, responseMsg.size() - hdrSize, &resp_data);
1585
Unive Tien71e935c2024-11-25 17:21:43 +08001586 EXPECT_EQ(rc, -EBADMSG);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001587}
1588
Chris Wang458475a2024-03-26 17:59:19 +08001589TEST(QueryDownstreamIdentifiers, goodPathEncodeRequest)
1590{
1591 constexpr uint8_t instanceId = 1;
Andrew Jefferydec237b2024-11-08 14:33:45 +10301592 constexpr size_t payloadLen = PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1593 PLDM_MSG_DEFINE_P(request, payloadLen);
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001594 constexpr pldm_query_downstream_identifiers_req params_req{
1595 0xFFFFFFFF, PLDM_GET_FIRSTPART};
Chris Wang458475a2024-03-26 17:59:19 +08001596
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001597 auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1598 request, payloadLen);
Unive Tien71e935c2024-11-25 17:21:43 +08001599 ASSERT_EQ(rc, 0);
Andrew Jefferydec237b2024-11-08 14:33:45 +10301600 EXPECT_THAT(std::span<uint8_t>(request_buf, sizeof(request_buf)),
1601 ElementsAreArray<uint8_t>(
1602 {0x81, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x01}));
Chris Wang458475a2024-03-26 17:59:19 +08001603}
1604
1605TEST(QueryDownstreamIdentifiers, encodeRequestInvalidErrorPaths)
1606{
1607 constexpr uint8_t instanceId = 1;
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001608 constexpr pldm_query_downstream_identifiers_req params_req{
1609 0xFFFFFFFF, PLDM_GET_FIRSTPART};
1610 constexpr pldm_query_downstream_identifiers_req params_req_invalid{
1611 0xFFFFFFFF, PLDM_ACKNOWLEDGEMENT_ONLY};
Chris Wang458475a2024-03-26 17:59:19 +08001612 constexpr size_t payload_length =
1613 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1614 std::array<uint8_t, hdrSize + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301615 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang458475a2024-03-26 17:59:19 +08001616 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1617
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001618 auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1619 nullptr, payload_length);
Unive Tien71e935c2024-11-25 17:21:43 +08001620 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08001621
1622 rc = encode_query_downstream_identifiers_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001623 instanceId, &params_req, requestPtr, payload_length - 1);
Unive Tien71e935c2024-11-25 17:21:43 +08001624 EXPECT_EQ(rc, -EOVERFLOW);
Chris Wang458475a2024-03-26 17:59:19 +08001625
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001626 rc = encode_query_downstream_identifiers_req(
1627 instanceId, &params_req_invalid, requestPtr, payload_length);
Unive Tien71e935c2024-11-25 17:21:43 +08001628 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08001629}
1630
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301631TEST(QueryDownstreamIdentifiers, decodeResponseNoDevices)
Chris Wang458475a2024-03-26 17:59:19 +08001632{
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301633 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1634 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1635 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1636 constexpr uint32_t downstream_devices_length_resp = 0;
1637 constexpr uint16_t number_of_downstream_devices_resp = 0;
1638
1639 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1640 struct pldm_query_downstream_identifiers_resp resp_data = {};
1641 struct pldm_downstream_device_iter devs;
Andrew Jefferya1896962025-03-03 21:41:25 +10301642 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301643 int rc = 0;
1644
1645 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1646 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1647 ASSERT_EQ(rc, 0);
1648
1649 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1650 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1651 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1652 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1653 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1654
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301655 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301656
1657 rc = decode_query_downstream_identifiers_resp(
1658 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp_data,
1659 &devs);
1660
Unive Tien71e935c2024-11-25 17:21:43 +08001661 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301662 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1663 EXPECT_EQ(resp_data.next_data_transfer_handle,
1664 next_data_transfer_handle_resp);
1665 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1666 EXPECT_EQ(resp_data.downstream_devices_length,
1667 downstream_devices_length_resp);
1668 EXPECT_EQ(resp_data.number_of_downstream_devices,
1669 number_of_downstream_devices_resp);
1670}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301671
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301672TEST(QueryDownstreamIdentifiers, decodeResponseNoDevicesBadCount)
1673{
1674 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1675 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1676 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1677 constexpr uint32_t downstream_devices_length_resp = 0;
1678 constexpr uint16_t number_of_downstream_devices_resp = 1;
1679
1680 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1681 struct pldm_query_downstream_identifiers_resp resp = {};
1682 struct pldm_downstream_device_iter devs;
1683 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301684 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301685 int rc = 0;
1686
1687 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1688 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1689 ASSERT_EQ(rc, 0);
1690
1691 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1692 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1693 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1694 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1695 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1696
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301697 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301698
1699 rc = decode_query_downstream_identifiers_resp(
1700 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08001701 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301702
1703 foreach_pldm_downstream_device(devs, dev, rc)
1704 {
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10301705 FAIL();
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301706 }
1707 ASSERT_NE(rc, 0);
1708}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301709
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301710TEST(QueryDownstreamIdentifiers, decodeResponseOneDeviceOneDescriptor)
1711{
1712 constexpr uint32_t downstreamDevicesLen = 11;
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301713 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
Chris Wang458475a2024-03-26 17:59:19 +08001714 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1715 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1716 const uint32_t downstream_devices_length_resp =
1717 htole32(downstreamDevicesLen);
1718 constexpr uint16_t number_of_downstream_devices_resp = 1;
Andrew Jefferydec237b2024-11-08 14:33:45 +10301719 constexpr size_t payloadLen =
1720 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstreamDevicesLen;
Chris Wang458475a2024-03-26 17:59:19 +08001721
Andrew Jefferydec237b2024-11-08 14:33:45 +10301722 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jefferydec237b2024-11-08 14:33:45 +10301723 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301724 struct pldm_downstream_device_iter devs;
1725 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301726 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10301727 int rc = 0;
1728
1729 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1730 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08001731
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301732 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
Chris Wang458475a2024-03-26 17:59:19 +08001733 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1734 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1735 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1736 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1737
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301738 /* Downstream device */
1739 pldm_msgbuf_insert_uint16(buf, 1);
1740 pldm_msgbuf_insert_uint8(buf, 1);
Chris Wang458475a2024-03-26 17:59:19 +08001741
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301742 /* Device descriptor */
1743 pldm_msgbuf_insert_uint16(buf, 1);
1744 pldm_msgbuf_insert_uint16(buf, 4);
1745 pldm_msgbuf_insert_uint32(buf, 412);
Chris Wang458475a2024-03-26 17:59:19 +08001746
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301747 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301748
1749 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1750 &resp_data, &devs);
1751
Unive Tien71e935c2024-11-25 17:21:43 +08001752 ASSERT_EQ(rc, 0);
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301753 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
Chris Wang458475a2024-03-26 17:59:19 +08001754 EXPECT_EQ(resp_data.next_data_transfer_handle,
1755 next_data_transfer_handle_resp);
1756 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1757 EXPECT_EQ(resp_data.downstream_devices_length,
1758 downstream_devices_length_resp);
1759 EXPECT_EQ(resp_data.number_of_downstream_devices,
1760 number_of_downstream_devices_resp);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301761
1762 foreach_pldm_downstream_device(devs, dev, rc)
1763 {
1764 struct pldm_descriptor desc;
1765
1766 EXPECT_EQ(dev.downstream_device_index, 1);
1767 EXPECT_EQ(dev.downstream_descriptor_count, 1);
1768
1769 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1770 {
1771 static const uint32_t dmtf = htole32(412);
1772 EXPECT_EQ(desc.descriptor_type, 1);
1773 EXPECT_EQ(desc.descriptor_length, 4);
1774 EXPECT_EQ(memcmp(desc.descriptor_data, &dmtf, sizeof(dmtf)), 0);
1775 }
1776 ASSERT_EQ(rc, 0);
1777 }
1778 ASSERT_EQ(rc, 0);
1779}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301780
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301781constexpr const uint16_t descriptor_id_type_iana_pen = 0x1;
1782constexpr const uint16_t descriptor_id_len_iana_pen = 0x4;
1783const uint32_t iana_pen_openbmc = htole16(49871u);
1784const uint32_t iana_pen_dmtf = htole16(412u);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301785
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301786TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneDescriptorEach)
1787{
1788 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1789 {0, 1},
1790 {1, 1},
1791 }};
1792
1793 constexpr const std::array<pldm_descriptor, 2> expected_descriptors = {{
1794 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1795 &iana_pen_dmtf},
1796 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1797 &iana_pen_openbmc},
1798 }};
1799
1800 constexpr uint32_t downstream_devices_len = 22;
1801 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1802 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1803 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1804 const uint32_t downstream_devices_length_resp =
1805 htole32(downstream_devices_len);
1806 constexpr uint16_t number_of_downstream_devices_resp = 2;
1807 constexpr size_t payloadLen =
1808 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
1809
Patrick Williamsf37edd72024-12-18 11:22:58 -05001810 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301811 PLDM_MSG_DEFINE_P(response, payloadLen);
1812 struct pldm_downstream_device_iter devs;
1813 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301814 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301815 int rc = 0;
1816
1817 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1818 ASSERT_EQ(rc, 0);
1819
1820 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1821 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1822 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1823 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1824 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1825
1826 /* Downstream device */
1827 pldm_msgbuf_insert_uint16(buf, 0);
1828 pldm_msgbuf_insert_uint8(buf, 1);
1829
1830 /* Device descriptor */
1831 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1832 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1833 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1834
1835 /* Downstream device */
1836 pldm_msgbuf_insert_uint16(buf, 1);
1837 pldm_msgbuf_insert_uint8(buf, 1);
1838
1839 /* Device descriptor */
1840 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1841 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1842 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
1843
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301844 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301845
1846 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1847 &resp_data, &devs);
1848
Unive Tien71e935c2024-11-25 17:21:43 +08001849 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301850 EXPECT_EQ(resp_data.number_of_downstream_devices,
1851 number_of_downstream_devices_resp);
1852
1853 size_t devIndex = 0;
1854 size_t descIndex = 0;
1855 foreach_pldm_downstream_device(devs, dev, rc)
1856 {
1857 struct pldm_descriptor desc;
1858
1859 ASSERT_LT(devIndex, expected_devices.size());
1860
1861 const struct pldm_downstream_device* expectedDev =
1862 &expected_devices[devIndex];
1863
1864 EXPECT_EQ(dev.downstream_device_index,
1865 expectedDev->downstream_device_index);
1866 EXPECT_EQ(dev.downstream_descriptor_count,
1867 expectedDev->downstream_descriptor_count);
1868
1869 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1870 {
1871 ASSERT_LT(descIndex, expected_descriptors.size());
1872
1873 const struct pldm_descriptor* expectedDesc =
1874 &expected_descriptors[descIndex];
1875
1876 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
1877 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
1878 EXPECT_EQ(memcmp(desc.descriptor_data,
1879 expectedDesc->descriptor_data,
1880 expectedDesc->descriptor_length),
1881 0);
1882
1883 descIndex++;
1884 }
1885 ASSERT_EQ(rc, 0);
1886 EXPECT_EQ(descIndex, 1 * devIndex + 1);
1887
1888 devIndex++;
1889 }
1890 ASSERT_EQ(rc, 0);
1891 EXPECT_EQ(devIndex, 2);
1892}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301893
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301894TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesTwoOneDescriptors)
1895{
1896 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1897 {0, 2},
1898 {1, 1},
1899 }};
1900
1901 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
1902 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1903 &iana_pen_dmtf},
1904 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1905 &iana_pen_openbmc},
1906 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1907 &iana_pen_dmtf},
1908 }};
1909
1910 constexpr uint32_t downstream_devices_len = 30;
1911 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1912 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1913 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1914 const uint32_t downstream_devices_length_resp =
1915 htole32(downstream_devices_len);
1916 constexpr uint16_t number_of_downstream_devices_resp = 2;
1917 constexpr size_t payloadLen =
1918 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
1919
Patrick Williamsf37edd72024-12-18 11:22:58 -05001920 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301921 PLDM_MSG_DEFINE_P(response, payloadLen);
1922 struct pldm_downstream_device_iter devs;
1923 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301924 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301925 int rc = 0;
1926
1927 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1928 ASSERT_EQ(rc, 0);
1929
1930 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1931 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1932 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1933 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1934 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1935
1936 /* Downstream device */
1937 pldm_msgbuf_insert_uint16(buf, 0);
1938 pldm_msgbuf_insert_uint8(buf, 2);
1939
1940 /* Device descriptor */
1941 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1942 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1943 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1944
1945 /* Device descriptor */
1946 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1947 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1948 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
1949
1950 /* Downstream device */
1951 pldm_msgbuf_insert_uint16(buf, 1);
1952 pldm_msgbuf_insert_uint8(buf, 1);
1953
1954 /* Device descriptor */
1955 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1956 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1957 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1958
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301959 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301960
1961 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1962 &resp_data, &devs);
1963
Unive Tien71e935c2024-11-25 17:21:43 +08001964 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301965 EXPECT_EQ(resp_data.number_of_downstream_devices,
1966 number_of_downstream_devices_resp);
1967
1968 size_t devIndex = 0;
1969 size_t descIndex = 0;
1970 foreach_pldm_downstream_device(devs, dev, rc)
1971 {
1972 struct pldm_descriptor desc;
1973
1974 ASSERT_LT(devIndex, expected_devices.size());
1975
1976 const struct pldm_downstream_device* expectedDev =
1977 &expected_devices[devIndex];
1978
1979 EXPECT_EQ(dev.downstream_device_index,
1980 expectedDev->downstream_device_index);
1981 EXPECT_EQ(dev.downstream_descriptor_count,
1982 expectedDev->downstream_descriptor_count);
1983
1984 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1985 {
1986 ASSERT_LT(descIndex, expected_descriptors.size());
1987
1988 const struct pldm_descriptor* expectedDesc =
1989 &expected_descriptors[descIndex];
1990
1991 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
1992 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
1993 EXPECT_EQ(memcmp(desc.descriptor_data,
1994 expectedDesc->descriptor_data,
1995 expectedDesc->descriptor_length),
1996 0);
1997
1998 descIndex++;
1999 }
2000 ASSERT_EQ(rc, 0);
2001
2002 devIndex++;
2003 }
2004 ASSERT_EQ(rc, 0);
2005 EXPECT_EQ(devIndex, 2);
2006 EXPECT_EQ(descIndex, 3);
2007}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302008
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302009TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneTwoDescriptors)
2010{
2011 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
2012 {0, 1},
2013 {1, 2},
2014 }};
2015
2016 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
2017 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2018 &iana_pen_dmtf},
2019 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2020 &iana_pen_openbmc},
2021 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2022 &iana_pen_dmtf},
2023 }};
2024
2025 constexpr uint32_t downstream_devices_len = 30;
2026 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2027 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2028 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2029 const uint32_t downstream_devices_length_resp =
2030 htole32(downstream_devices_len);
2031 constexpr uint16_t number_of_downstream_devices_resp = 2;
2032 constexpr size_t payloadLen =
2033 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2034
Patrick Williamsf37edd72024-12-18 11:22:58 -05002035 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302036 PLDM_MSG_DEFINE_P(response, payloadLen);
2037 struct pldm_downstream_device_iter devs;
2038 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10302039 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302040 int rc = 0;
2041
2042 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2043 ASSERT_EQ(rc, 0);
2044
2045 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2046 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2047 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2048 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2049 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2050
2051 /* Downstream device */
2052 pldm_msgbuf_insert_uint16(buf, 0);
2053 pldm_msgbuf_insert_uint8(buf, 1);
2054
2055 /* Device descriptor */
2056 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2057 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2058 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2059
2060 /* Downstream device */
2061 pldm_msgbuf_insert_uint16(buf, 1);
2062 pldm_msgbuf_insert_uint8(buf, 2);
2063
2064 /* Device descriptor */
2065 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2066 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2067 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2068
2069 /* Device descriptor */
2070 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2071 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2072 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2073
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302074 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302075
2076 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2077 &resp_data, &devs);
2078
Unive Tien71e935c2024-11-25 17:21:43 +08002079 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302080 EXPECT_EQ(resp_data.number_of_downstream_devices,
2081 number_of_downstream_devices_resp);
2082
2083 size_t devIndex = 0;
2084 size_t descIndex = 0;
2085 foreach_pldm_downstream_device(devs, dev, rc)
2086 {
2087 struct pldm_descriptor desc;
2088
2089 ASSERT_LT(devIndex, expected_devices.size());
2090
2091 const struct pldm_downstream_device* expectedDev =
2092 &expected_devices[devIndex];
2093
2094 EXPECT_EQ(dev.downstream_device_index,
2095 expectedDev->downstream_device_index);
2096 EXPECT_EQ(dev.downstream_descriptor_count,
2097 expectedDev->downstream_descriptor_count);
2098
2099 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2100 {
2101 ASSERT_LT(descIndex, expected_descriptors.size());
2102
2103 const struct pldm_descriptor* expectedDesc =
2104 &expected_descriptors[descIndex];
2105
2106 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2107 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2108 EXPECT_EQ(memcmp(desc.descriptor_data,
2109 expectedDesc->descriptor_data,
2110 expectedDesc->descriptor_length),
2111 0);
2112
2113 descIndex++;
2114 }
2115 ASSERT_EQ(rc, 0);
2116
2117 devIndex++;
2118 }
2119 ASSERT_EQ(rc, 0);
2120 EXPECT_EQ(devIndex, 2);
2121 EXPECT_EQ(descIndex, 3);
Chris Wang458475a2024-03-26 17:59:19 +08002122}
2123
2124TEST(QueryDownstreamIdentifiers, decodeRequestErrorPaths)
2125{
Andrew Jefferydec237b2024-11-08 14:33:45 +10302126 constexpr size_t payloadLen = sizeof(uint8_t);
2127
Chris Wang458475a2024-03-26 17:59:19 +08002128 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302129 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302130 PLDM_MSG_DEFINE_P(response, payloadLen);
Chris Wang458475a2024-03-26 17:59:19 +08002131
2132 // Test nullptr
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302133 auto rc = decode_query_downstream_identifiers_resp(nullptr, payloadLen,
2134 nullptr, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08002135 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08002136
2137 // Test not PLDM_SUCCESS completion code
2138 response->payload[0] = PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302139 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2140 &resp_data, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08002141 EXPECT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002142 EXPECT_EQ(resp_data.completion_code, PLDM_ERROR_UNSUPPORTED_PLDM_CMD);
2143
2144 // Test payload length less than minimum length
2145 response->payload[0] = PLDM_SUCCESS;
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302146 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2147 &resp_data, &devs);
Chris Wang458475a2024-03-26 17:59:19 +08002148
Unive Tien71e935c2024-11-25 17:21:43 +08002149 EXPECT_EQ(rc, -EBADMSG);
Chris Wang458475a2024-03-26 17:59:19 +08002150}
2151
2152TEST(QueryDownstreamIdentifiers, decodeRequestErrorDownstreamDevicesSize)
2153{
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +05302154 // Len is not fixed here taking it as 9, contains 1 downstream device with
Chris Wang458475a2024-03-26 17:59:19 +08002155 // 1 descriptor
2156 constexpr uint32_t actualDownstreamDevicesLen = 9;
2157 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2158 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2159 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302160 constexpr uint16_t number_of_downstream_devices_resp = 1;
2161 constexpr size_t payloadLen =
2162 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN +
2163 actualDownstreamDevicesLen;
2164
Chris Wang458475a2024-03-26 17:59:19 +08002165 const uint32_t downstream_devices_length_resp =
2166 htole32(actualDownstreamDevicesLen + 1 /* inject error length*/);
Chris Wang458475a2024-03-26 17:59:19 +08002167
Andrew Jefferydec237b2024-11-08 14:33:45 +10302168 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302169 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302170 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302171 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302172 void* devicesStart = NULL;
2173 size_t devicesLen;
2174 int rc = 0;
2175
2176 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302177 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002178
2179 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2180 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2181 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2182 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2183 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302184 pldm_msgbuf_span_remaining(buf, &devicesStart, &devicesLen);
Chris Wang458475a2024-03-26 17:59:19 +08002185
Andrew Jefferya1896962025-03-03 21:41:25 +10302186 ASSERT_EQ(0, pldm_msgbuf_complete(buf));
2187
Chris Wang458475a2024-03-26 17:59:19 +08002188 /** Filling descriptor data, the correctness of the downstream devices data
2189 * is not checked in this test case so filling with 0xff
2190 */
Andrew Jefferydec237b2024-11-08 14:33:45 +10302191 std::fill_n(static_cast<uint8_t*>(devicesStart), actualDownstreamDevicesLen,
2192 0xff);
Chris Wang458475a2024-03-26 17:59:19 +08002193
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302194 EXPECT_NE(decode_query_downstream_identifiers_resp(response, payloadLen,
2195 &resp_data, &devs),
Unive Tien71e935c2024-11-25 17:21:43 +08002196 0);
Chris Wang458475a2024-03-26 17:59:19 +08002197}
2198
2199TEST(QueryDownstreamIdentifiers, decodeRequestErrorBufSize)
2200{
2201 constexpr uint32_t actualDownstreamDevicesLen = 0;
2202 constexpr uint16_t number_of_downstream_devices_resp = 1;
2203 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2204 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2205 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302206 constexpr size_t payloadLen =
2207 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN - 1;
2208
Chris Wang458475a2024-03-26 17:59:19 +08002209 const uint32_t downstream_devices_length_resp =
2210 htole32(actualDownstreamDevicesLen);
2211
Andrew Jefferydec237b2024-11-08 14:33:45 +10302212 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302213 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302214 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302215 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302216 int rc = 0;
2217
2218 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2219 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002220
2221 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2222 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2223 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2224 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2225 // Inject error buffer size
2226 pldm_msgbuf_insert_uint8(buf, (uint8_t)number_of_downstream_devices_resp);
Andrew Jefferya1896962025-03-03 21:41:25 +10302227 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang458475a2024-03-26 17:59:19 +08002228
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302229 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2230 &resp_data, &devs);
Chris Wang458475a2024-03-26 17:59:19 +08002231
Unive Tien71e935c2024-11-25 17:21:43 +08002232 EXPECT_EQ(rc, -EBADMSG);
Chris Wang458475a2024-03-26 17:59:19 +08002233}
2234
Chris Wangb6ef35b2024-07-03 09:35:42 +08002235TEST(GetDownstreamFirmwareParameters, goodPathEncodeRequest)
2236{
2237 constexpr uint8_t instanceId = 1;
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302238 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002239 0x0, PLDM_GET_FIRSTPART};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002240 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302241 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002242 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302243 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002244 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2245
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302246 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002247 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002248 EXPECT_EQ(rc, 0);
2249
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302250 std::array<uint8_t,
2251 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES>
Chris Wangb6ef35b2024-07-03 09:35:42 +08002252 expectedReq{0x81, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01};
2253 EXPECT_EQ(requestMsg, expectedReq);
2254}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002255
Chris Wangb6ef35b2024-07-03 09:35:42 +08002256TEST(GetDownstreamFirmwareParameters, encodeRequestInvalidTransferOperationFlag)
2257{
2258 constexpr uint8_t instanceId = 1;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002259 // Setup invalid transfer operation flag
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302260 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002261 0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002262 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302263 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002264 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302265 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002266 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2267
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302268 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002269 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002270 EXPECT_EQ(rc, -EBADMSG);
2271}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002272
Chris Wangb6ef35b2024-07-03 09:35:42 +08002273TEST(GetDownstreamFirmwareParameters, encodeRequestErrorBufSize)
2274{
2275 constexpr uint8_t instanceId = 1;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002276 // Setup invalid transfer operation flag
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302277 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Andrew Jeffery53b08672025-03-04 12:26:18 +10302278 0x0, PLDM_GET_FIRSTPART};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002279 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302280 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES -
Chris Wangb6ef35b2024-07-03 09:35:42 +08002281 1 /* inject erro length*/;
2282
2283 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302284 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002285 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2286
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302287 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002288 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002289 EXPECT_EQ(rc, -EOVERFLOW);
2290}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002291
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302292TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseOneEntry)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002293{
Chris Wangb6ef35b2024-07-03 09:35:42 +08002294 constexpr uint16_t downstreamDeviceCount = 1;
2295 constexpr uint8_t activeComponentVersionStringLength = 8;
2296 constexpr uint8_t pendingComponentVersionStringLength = 8;
2297 constexpr size_t downstreamDeviceParamTableLen =
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302298 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002299 activeComponentVersionStringLength +
2300 pendingComponentVersionStringLength;
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302301 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002302 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2303 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2304 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302305 constexpr size_t payload_len =
2306 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2307 downstreamDeviceParamTableLen;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002308
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302309 PLDM_MSG_DEFINE_P(response, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302310 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302311 int rc = 0;
2312
2313 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302314 ASSERT_EQ(rc, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002315
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302316 // Table 24
2317 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002318 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2319 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302320
2321 // Table 25
Chris Wangb6ef35b2024-07-03 09:35:42 +08002322 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2323 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2324
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302325 // Table 26
2326 pldm_msgbuf_insert_uint16(buf, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002327
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302328 // - Active metadata
2329 pldm_msgbuf_insert_uint32(buf, 0);
2330 pldm_msgbuf_insert_uint8(buf, 1);
2331 pldm_msgbuf_insert_uint8(buf, activeComponentVersionStringLength);
2332 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2333 ASSERT_EQ(rc, 0);
2334
2335 // - Pending metadata
2336 pldm_msgbuf_insert_uint32(buf, 0);
2337 pldm_msgbuf_insert_uint8(buf, 1);
2338 pldm_msgbuf_insert_uint8(buf, pendingComponentVersionStringLength);
2339 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2340 ASSERT_EQ(rc, 0);
2341
2342 // - Methods and capabilities
2343 pldm_msgbuf_insert_uint16(buf, 1);
2344 pldm_msgbuf_insert_uint32(buf, 0);
2345
2346 // - Version strings
2347 rc = pldm__msgbuf_insert_array_void(buf, activeComponentVersionStringLength,
2348 "abcdefgh", 8);
2349 ASSERT_EQ(rc, 0);
2350 rc = pldm__msgbuf_insert_array_void(
2351 buf, pendingComponentVersionStringLength, "zyxwvuts", 8);
2352 ASSERT_EQ(rc, 0);
2353
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302354 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302355 ASSERT_EQ(rc, 0);
2356
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302357 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302358 struct pldm_downstream_device_parameters_iter iter = {};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002359
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302360 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2361 &resp_data, &iter);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002362
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302363 ASSERT_EQ(rc, 0);
2364 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002365 EXPECT_EQ(resp_data.next_data_transfer_handle,
2366 next_data_transfer_handle_resp);
2367 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2368 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302369
2370 struct pldm_downstream_device_parameters_entry entry;
2371 size_t entries = 0;
2372 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2373 {
2374 EXPECT_EQ(entry.downstream_device_index, 0);
2375 EXPECT_EQ(entry.active_comp_comparison_stamp, 0);
2376 EXPECT_EQ(entry.active_comp_ver_str_type, 1);
2377 EXPECT_EQ(entry.active_comp_ver_str_len,
2378 activeComponentVersionStringLength);
2379 EXPECT_STREQ("20241206", entry.active_comp_release_date);
2380 EXPECT_EQ(entry.pending_comp_comparison_stamp, 0);
2381 EXPECT_EQ(entry.pending_comp_ver_str_type, 1);
2382 EXPECT_EQ(entry.pending_comp_ver_str_len,
2383 pendingComponentVersionStringLength);
2384 EXPECT_STREQ("20241206", entry.pending_comp_release_date);
2385 EXPECT_EQ(entry.comp_activation_methods.value, 1);
2386 EXPECT_EQ(entry.capabilities_during_update.value, 0);
2387 EXPECT_FALSE(memcmp("abcdefgh", entry.active_comp_ver_str,
2388 entry.active_comp_ver_str_len));
2389 EXPECT_FALSE(memcmp("zyxwvuts", entry.pending_comp_ver_str,
2390 entry.pending_comp_ver_str_len));
2391 entries++;
2392 }
2393 EXPECT_EQ(rc, 0);
2394 EXPECT_EQ(entries, 1);
2395}
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302396
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302397TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseTwoEntries)
2398{
2399 /** Count is not fixed here taking it as 1, and the downstream device's
2400 * version strings length are set to 8
2401 */
2402 constexpr uint16_t downstreamDeviceCount = 2;
2403 constexpr uint8_t activeComponentVersionStringLength = 8;
2404 constexpr uint8_t pendingComponentVersionStringLength = 9;
2405 constexpr size_t downstreamDeviceParamTableLen =
2406 static_cast<size_t>(downstreamDeviceCount *
2407 (PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2408 activeComponentVersionStringLength +
2409 pendingComponentVersionStringLength));
2410 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2411 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2412 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2413 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2414 constexpr size_t payload_len =
2415 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2416 downstreamDeviceParamTableLen;
2417
2418 PLDM_MSG_DEFINE_P(response, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302419 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302420 int rc = 0;
2421
2422 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302423 ASSERT_EQ(rc, 0);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302424
2425 // Table 24
2426 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2427 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2428 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2429
2430 // Table 25
2431 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2432 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2433
2434 constexpr const std::array<pldm_downstream_device_parameters_entry, 2>
2435 table = {{{
2436 0,
2437 0,
2438 1,
2439 8,
2440 "20241206",
2441 0,
2442 1,
2443 9,
2444 "20241209",
2445 {1},
2446 {0},
2447 "active_0",
2448 "pending_0",
2449 },
2450 {
2451 1,
2452 0,
2453 1,
2454 8,
2455 "20241209",
2456 0,
2457 1,
2458 9,
2459 "20241206",
2460 {1},
2461 {0},
2462 "active_1",
2463 "pending_1",
2464 }}};
2465 for (const auto& e : table)
2466 {
2467 // Table 26
2468 pldm_msgbuf_insert_uint16(buf, e.downstream_device_index);
2469
2470 // - Active metadata
2471 pldm_msgbuf_insert_uint32(buf, e.active_comp_comparison_stamp);
2472 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_type);
2473 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_len);
2474 rc = pldm__msgbuf_insert_array_void(buf, 8, &e.active_comp_release_date,
2475 sizeof(e.active_comp_release_date));
2476 ASSERT_EQ(rc, 0);
2477
2478 // - Pending metadata
2479 pldm_msgbuf_insert_uint32(buf, e.pending_comp_comparison_stamp);
2480 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_type);
2481 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_len);
2482 rc =
2483 pldm__msgbuf_insert_array_void(buf, 8, e.pending_comp_release_date,
2484 sizeof(e.pending_comp_release_date));
2485 ASSERT_EQ(rc, 0);
2486
2487 // - Methods and capabilities
2488 pldm_msgbuf_insert_uint16(buf, e.comp_activation_methods.value);
2489 pldm_msgbuf_insert_uint32(buf, e.capabilities_during_update.value);
2490
2491 // - Version strings
2492 rc = pldm__msgbuf_insert_array_void(buf, e.active_comp_ver_str_len,
2493 e.active_comp_ver_str,
2494 e.active_comp_ver_str_len);
2495 ASSERT_EQ(rc, 0);
2496 rc = pldm__msgbuf_insert_array_void(buf, e.pending_comp_ver_str_len,
2497 e.pending_comp_ver_str,
2498 e.pending_comp_ver_str_len);
2499 ASSERT_EQ(rc, 0);
2500 }
2501
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302502 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302503 ASSERT_EQ(rc, 0);
2504
2505 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2506 struct pldm_downstream_device_parameters_iter iter = {};
2507
2508 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2509 &resp_data, &iter);
2510
2511 ASSERT_EQ(rc, 0);
2512 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
2513 EXPECT_EQ(resp_data.next_data_transfer_handle,
2514 next_data_transfer_handle_resp);
2515 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2516 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
2517
2518 struct pldm_downstream_device_parameters_entry entry;
2519 size_t entryIndex = 0;
2520 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2521 {
2522 ASSERT_LE(entryIndex, table.size());
2523
2524 EXPECT_EQ(table[entryIndex].downstream_device_index,
2525 entry.downstream_device_index);
2526 EXPECT_EQ(table[entryIndex].active_comp_comparison_stamp,
2527 entry.active_comp_comparison_stamp);
2528 EXPECT_EQ(table[entryIndex].active_comp_ver_str_type,
2529 entry.active_comp_ver_str_type);
2530 EXPECT_EQ(table[entryIndex].active_comp_ver_str_len,
2531 entry.active_comp_ver_str_len);
2532 EXPECT_STREQ(&table[entryIndex].active_comp_release_date[0],
2533 &entry.active_comp_release_date[0]);
2534 EXPECT_EQ(table[entryIndex].pending_comp_comparison_stamp,
2535 entry.pending_comp_comparison_stamp);
2536 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_type,
2537 entry.pending_comp_ver_str_type);
2538 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_len,
2539 entry.pending_comp_ver_str_len);
2540 EXPECT_STREQ(&table[entryIndex].pending_comp_release_date[0],
2541 &entry.pending_comp_release_date[0]);
2542 EXPECT_EQ(table[entryIndex].comp_activation_methods.value,
2543 entry.comp_activation_methods.value);
2544 EXPECT_EQ(table[entryIndex].capabilities_during_update.value,
2545 entry.capabilities_during_update.value);
2546 EXPECT_FALSE(memcmp(table[entryIndex].active_comp_ver_str,
2547 entry.active_comp_ver_str,
2548 table[entryIndex].active_comp_ver_str_len));
2549 EXPECT_FALSE(memcmp(table[entryIndex].pending_comp_ver_str,
2550 entry.pending_comp_ver_str,
2551 table[entryIndex].pending_comp_ver_str_len));
2552 entryIndex++;
2553 }
2554 EXPECT_EQ(rc, 0);
2555 EXPECT_EQ(entryIndex, table.size());
Chris Wangb6ef35b2024-07-03 09:35:42 +08002556}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002557
Chris Wangb6ef35b2024-07-03 09:35:42 +08002558TEST(GetDownstreamFirmwareParameters, decodeResponseInvalidLength)
2559{
2560 /** Count is not fixed here taking it as 1, and the downstream device's
2561 * version strings length are set to 8
2562 */
2563 constexpr uint16_t downstreamDeviceCount = 1;
2564 constexpr uint8_t activeComponentVersionStringLength = 8;
2565 constexpr uint8_t pendingComponentVersionStringLength = 8;
2566 constexpr size_t downstreamDeviceParamTableLen =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302567 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002568 activeComponentVersionStringLength +
2569 pendingComponentVersionStringLength;
2570 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2571 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2572 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2573 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2574
2575 std::array<uint8_t,
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302576 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002577 downstreamDeviceParamTableLen - 1 /* inject error length*/>
2578 responseMsg{};
2579
2580 int rc = 0;
2581
Andrew Jefferya1896962025-03-03 21:41:25 +10302582 PLDM_MSGBUF_DEFINE_P(buf);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002583 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
2584 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10302585 ASSERT_EQ(rc, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002586
2587 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2588 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2589 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2590 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2591 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
Andrew Jefferya1896962025-03-03 21:41:25 +10302592 ASSERT_EQ(pldm_msgbuf_complete(buf), 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002593
2594 /** Filling paramter table, the correctness of the downstream devices data
2595 * is not checked in this test case so filling with 0xff
2596 */
2597 std::fill_n(responseMsg.data() + hdrSize +
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302598 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN,
Chris Wangb6ef35b2024-07-03 09:35:42 +08002599 downstreamDeviceParamTableLen - 1 /* inject error length*/,
2600 0xff);
2601
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302602 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002603 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302604 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302605 struct pldm_downstream_device_parameters_iter iter;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002606
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302607 rc = decode_get_downstream_firmware_parameters_resp(
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302608 response, responseMsg.size() - hdrSize, &resp_data, &iter);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002609 EXPECT_EQ(rc, 0);
2610
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302611 struct pldm_downstream_device_parameters_entry entry;
2612 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2613 {
2614 FAIL();
2615 }
2616 EXPECT_EQ(rc, -EOVERFLOW);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002617}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002618
Andrew Jeffery9c766792022-08-10 23:12:49 +09302619TEST(RequestUpdate, goodPathEncodeRequest)
2620{
2621 constexpr uint8_t instanceId = 1;
2622 constexpr uint32_t maxTransferSize = 512;
2623 constexpr uint16_t numOfComp = 3;
2624 constexpr uint8_t maxOutstandingTransferReq = 2;
2625 constexpr uint16_t pkgDataLen = 0x1234;
2626 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2627 constexpr uint8_t compImgSetVerStrLen =
2628 static_cast<uint8_t>(compImgSetVerStr.size());
2629 variable_field compImgSetVerStrInfo{};
2630 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302631 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302632 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2633 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2634
2635 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2636 compImgSetVerStrLen>
2637 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302638 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302639 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2640
2641 auto rc = encode_request_update_req(
2642 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2643 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2644 &compImgSetVerStrInfo, requestMsg,
2645 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2646 EXPECT_EQ(rc, PLDM_SUCCESS);
2647
2648 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2649 compImgSetVerStrLen>
2650 outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00,
2651 0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e,
2652 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30};
2653 EXPECT_EQ(request, outRequest);
2654}
2655
2656TEST(RequestUpdate, errorPathEncodeRequest)
2657{
2658 constexpr uint8_t instanceId = 1;
2659 uint32_t maxTransferSize = 512;
2660 constexpr uint16_t numOfComp = 3;
2661 uint8_t maxOutstandingTransferReq = 2;
2662 constexpr uint16_t pkgDataLen = 0x1234;
2663 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2664 uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2665 variable_field compImgSetVerStrInfo{};
2666 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302667 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302668 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2669 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2670
2671 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2672 compImgSetVerStr.size()>
2673 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302674 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302675 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2676
2677 auto rc = encode_request_update_req(
2678 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2679 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr,
2680 requestMsg,
2681 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2682 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2683
2684 compImgSetVerStrInfo.ptr = nullptr;
2685 rc = encode_request_update_req(
2686 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2687 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2688 &compImgSetVerStrInfo, requestMsg,
2689 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2690 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2691 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302692 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302693 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2694
2695 rc = encode_request_update_req(
2696 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2697 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2698 &compImgSetVerStrInfo, nullptr,
2699 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2700 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2701
2702 rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp,
2703 maxOutstandingTransferReq, pkgDataLen,
2704 PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2705 &compImgSetVerStrInfo, requestMsg, 0);
2706 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2707
2708 compImgSetVerStrLen = 0;
2709 rc = encode_request_update_req(
2710 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2711 pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr,
2712 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2713 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2714 compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2715
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06002716 compImgSetVerStrInfo.length = 0xffff;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302717 rc = encode_request_update_req(
2718 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2719 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2720 &compImgSetVerStrInfo, nullptr,
2721 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2722 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2723 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2724
2725 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1;
2726 rc = encode_request_update_req(
2727 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2728 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2729 &compImgSetVerStrInfo, nullptr,
2730 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2731 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2732 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE;
2733
2734 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ - 1;
2735 rc = encode_request_update_req(
2736 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2737 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2738 &compImgSetVerStrInfo, nullptr,
2739 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2740 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2741 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ;
2742
2743 rc = encode_request_update_req(
2744 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2745 pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen,
2746 &compImgSetVerStrInfo, nullptr,
2747 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2748 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2749}
2750
2751TEST(RequestUpdate, goodPathDecodeResponse)
2752{
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002753 /* Test a success completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09302754 constexpr uint16_t fdMetaDataLen = 1024;
2755 constexpr uint8_t fdWillSendPkgData = 1;
2756 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)>
2757 requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01};
2758
2759 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302760 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302761 reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data());
2762 uint8_t outCompletionCode = 0;
2763 uint16_t outFdMetaDataLen = 0;
2764 uint8_t outFdWillSendPkgData = 0;
2765
2766 auto rc = decode_request_update_resp(
2767 responseMsg1, requestUpdateResponse1.size() - hdrSize,
2768 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2769 EXPECT_EQ(rc, PLDM_SUCCESS);
2770 EXPECT_EQ(outCompletionCode, PLDM_SUCCESS);
2771 EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen);
2772 EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData);
2773
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002774#ifdef LIBPLDM_API_TESTING
2775 /* Check the success roundtrip matches */
2776 PLDM_MSG_DEFINE_P(enc, 1000);
2777 size_t enc_payload_len = 1000;
2778 const struct pldm_request_update_resp resp_data = {
2779 .completion_code = PLDM_SUCCESS,
2780 .fd_meta_data_len = outFdMetaDataLen,
2781 .fd_will_send_pkg_data = outFdWillSendPkgData,
2782 };
2783 rc = encode_request_update_resp(FIXED_INSTANCE_ID, &resp_data, enc,
2784 &enc_payload_len);
2785 EXPECT_EQ(rc, PLDM_SUCCESS);
2786 EXPECT_EQ(enc_payload_len + hdrSize, requestUpdateResponse1.size());
2787 EXPECT_TRUE(std::equal(requestUpdateResponse1.begin() + hdrSize,
2788 requestUpdateResponse1.end(), enc_buf + hdrSize));
2789 check_response(enc, PLDM_REQUEST_UPDATE);
2790#endif
2791
2792 /* Test a failure completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09302793 outCompletionCode = 0;
2794 outFdMetaDataLen = 0;
2795 outFdWillSendPkgData = 0;
2796
2797 constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)>
2798 requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
2799 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302800 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302801 reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data());
2802 rc = decode_request_update_resp(
2803 responseMsg2, requestUpdateResponse2.size() - hdrSize,
2804 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2805 EXPECT_EQ(rc, PLDM_SUCCESS);
2806 EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
2807}
2808
2809TEST(RequestUpdate, errorPathDecodeResponse)
2810{
2811 constexpr std::array<uint8_t,
2812 hdrSize + sizeof(pldm_request_update_resp) - 1>
2813 requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
2814
2815 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302816 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302817 reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data());
2818 uint8_t outCompletionCode = 0;
2819 uint16_t outFdMetaDataLen = 0;
2820 uint8_t outFdWillSendPkgData = 0;
2821
2822 auto rc = decode_request_update_resp(
2823 nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2824 &outFdMetaDataLen, &outFdWillSendPkgData);
2825 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2826
2827 rc = decode_request_update_resp(
2828 responseMsg, requestUpdateResponse.size() - hdrSize, nullptr,
2829 &outFdMetaDataLen, &outFdWillSendPkgData);
2830 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2831
2832 rc = decode_request_update_resp(
2833 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2834 nullptr, &outFdWillSendPkgData);
2835 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2836
2837 rc = decode_request_update_resp(
2838 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2839 &outFdMetaDataLen, nullptr);
2840 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2841
2842 rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode,
2843 &outFdMetaDataLen, &outFdWillSendPkgData);
2844 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2845
2846 rc = decode_request_update_resp(
2847 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2848 &outFdMetaDataLen, &outFdWillSendPkgData);
2849 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2850}
2851
2852TEST(PassComponentTable, goodPathEncodeRequest)
2853{
2854 constexpr uint8_t instanceId = 1;
2855 constexpr uint16_t compIdentifier = 400;
2856 constexpr uint8_t compClassificationIndex = 40;
2857 constexpr uint32_t compComparisonStamp = 0x12345678;
2858 constexpr std::string_view compVerStr = "0penBmcv1.1";
2859 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2860 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302861 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302862 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2863 compVerStrInfo.length = compVerStrLen;
2864
2865 std::array<uint8_t,
2866 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2867 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302868 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302869 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2870
2871 auto rc = encode_pass_component_table_req(
2872 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2873 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2874 compVerStrLen, &compVerStrInfo, requestMsg,
2875 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2876 EXPECT_EQ(rc, PLDM_SUCCESS);
2877
2878 std::array<uint8_t,
2879 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06002880 outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28,
2881 0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65,
2882 0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31};
Andrew Jeffery9c766792022-08-10 23:12:49 +09302883 EXPECT_EQ(request, outRequest);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002884
2885#ifdef LIBPLDM_API_TESTING
2886 /* Check the roundtrip */
2887 struct pldm_pass_component_table_req_full req;
2888 PLDM_MSG_DEFINE_P(dec, outRequest.size());
2889 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
2890 rc =
2891 decode_pass_component_table_req(dec, outRequest.size() - hdrSize, &req);
2892 ASSERT_EQ(rc, 0);
2893
2894 EXPECT_EQ(req.transfer_flag, PLDM_START_AND_END);
2895 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
2896 EXPECT_EQ(req.comp_identifier, compIdentifier);
2897 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
2898 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
2899 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
2900 EXPECT_EQ(req.version.str_len, compVerStrLen);
2901 EXPECT_TRUE(std::equal(req.version.str_data,
2902 req.version.str_data + req.version.str_len,
2903 compVerStr.data()));
2904#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09302905}
2906
2907TEST(PassComponentTable, errorPathEncodeRequest)
2908{
2909 constexpr uint8_t instanceId = 1;
2910 constexpr uint16_t compIdentifier = 400;
2911 constexpr uint8_t compClassificationIndex = 40;
2912 constexpr uint32_t compComparisonStamp = 0x12345678;
2913 constexpr std::string_view compVerStr = "0penBmcv1.1";
2914 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2915 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302916 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302917 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2918 compVerStrInfo.length = compVerStrLen;
2919
2920 std::array<uint8_t,
2921 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2922 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302923 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302924 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2925
2926 auto rc = encode_pass_component_table_req(
2927 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2928 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2929 compVerStrLen, nullptr, requestMsg,
2930 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2931 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2932
2933 compVerStrInfo.ptr = nullptr;
2934 rc = encode_pass_component_table_req(
2935 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2936 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2937 compVerStrLen, &compVerStrInfo, requestMsg,
2938 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2939 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302940 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302941 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2942
2943 rc = encode_pass_component_table_req(
2944 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2945 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2946 compVerStrLen, &compVerStrInfo, nullptr,
2947 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2948 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2949
2950 rc = encode_pass_component_table_req(
2951 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2952 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2953 compVerStrLen, &compVerStrInfo, requestMsg,
2954 sizeof(pldm_pass_component_table_req));
2955 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2956
2957 rc = encode_pass_component_table_req(
2958 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2959 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0,
2960 &compVerStrInfo, requestMsg,
2961 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2962 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2963
2964 rc = encode_pass_component_table_req(
2965 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2966 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2967 compVerStrLen - 1, &compVerStrInfo, requestMsg,
2968 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2969 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2970
2971 rc = encode_pass_component_table_req(
2972 instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier,
2973 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2974 compVerStrLen, &compVerStrInfo, requestMsg,
2975 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2976 EXPECT_EQ(rc, PLDM_INVALID_TRANSFER_OPERATION_FLAG);
2977
2978 rc = encode_pass_component_table_req(
2979 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2980 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN,
2981 compVerStrLen, &compVerStrInfo, requestMsg,
2982 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2983 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2984}
2985
2986TEST(PassComponentTable, goodPathDecodeResponse)
2987{
2988 constexpr std::array<uint8_t,
2989 hdrSize + sizeof(pldm_pass_component_table_resp)>
2990 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
2991 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302992 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302993 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
2994
2995 uint8_t completionCode = 0;
2996 uint8_t compResp = 0;
2997 uint8_t compRespCode = 0;
2998
2999 auto rc = decode_pass_component_table_resp(
3000 responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode,
3001 &compResp, &compRespCode);
3002
3003 EXPECT_EQ(rc, PLDM_SUCCESS);
3004 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3005 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3006 EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL);
3007
3008 constexpr std::array<uint8_t,
3009 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003010 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303011 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303012 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303013 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3014 rc = decode_pass_component_table_resp(
3015 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3016 &compResp, &compRespCode);
3017
3018 EXPECT_EQ(rc, PLDM_SUCCESS);
3019 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3020 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3021 EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN);
3022
3023 constexpr std::array<uint8_t,
3024 hdrSize + sizeof(pldm_pass_component_table_resp)>
3025 passCompTableResponse3{0x00, 0x00, 0x00, 0x80};
3026 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303027 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303028 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3029
3030 rc = decode_pass_component_table_resp(
3031 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3032 &compResp, &compRespCode);
3033
3034 EXPECT_EQ(rc, PLDM_SUCCESS);
3035 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3036}
3037
3038TEST(PassComponentTable, errorPathDecodeResponse)
3039{
3040 constexpr std::array<uint8_t,
3041 hdrSize + sizeof(pldm_pass_component_table_resp) - 1>
3042 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00};
3043 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303044 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303045 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3046
3047 uint8_t completionCode = 0;
3048 uint8_t compResp = 0;
3049 uint8_t compRespCode = 0;
3050
3051 auto rc = decode_pass_component_table_resp(
3052 nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode,
3053 &compResp, &compRespCode);
3054 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3055
3056 rc = decode_pass_component_table_resp(
3057 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr,
3058 &compResp, &compRespCode);
3059 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3060
3061 rc = decode_pass_component_table_resp(
3062 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3063 &completionCode, nullptr, &compRespCode);
3064 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3065
3066 rc = decode_pass_component_table_resp(
3067 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3068 &completionCode, &compResp, nullptr);
3069 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3070
3071 rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode,
3072 &compResp, &compRespCode);
3073 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3074
3075 rc = decode_pass_component_table_resp(
3076 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3077 &completionCode, &compResp, &compRespCode);
3078 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3079
3080 constexpr std::array<uint8_t,
3081 hdrSize + sizeof(pldm_pass_component_table_resp)>
3082 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
3083 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303084 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303085 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3086 rc = decode_pass_component_table_resp(
3087 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3088 &compResp, &compRespCode);
3089 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3090
3091 constexpr std::array<uint8_t,
3092 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003093 passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303094 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303095 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303096 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3097 rc = decode_pass_component_table_resp(
3098 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3099 &compResp, &compRespCode);
3100 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3101
3102 constexpr std::array<uint8_t,
3103 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003104 passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303105 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303106 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303107 reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data());
3108 rc = decode_pass_component_table_resp(
3109 responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode,
3110 &compResp, &compRespCode);
3111 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3112}
3113
3114TEST(UpdateComponent, goodPathEncodeRequest)
3115{
3116 constexpr uint8_t instanceId = 2;
3117 constexpr uint16_t compIdentifier = 500;
3118 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003119 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303120 constexpr uint32_t compImageSize = 4096;
3121 constexpr bitfield32_t updateOptionFlags{1};
3122 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3123 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3124 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303125 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303126 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3127 compVerStrInfo.length = compVerStrLen;
3128
3129 std::array<uint8_t,
3130 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3131 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303132 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303133 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3134
3135 auto rc = encode_update_component_req(
3136 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3137 compComparisonStamp, compImageSize, updateOptionFlags,
3138 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3139 sizeof(pldm_update_component_req) + compVerStrLen);
3140 EXPECT_EQ(rc, PLDM_SUCCESS);
3141
3142 std::array<uint8_t,
3143 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003144 outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
3145 0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
3146 0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
3147 0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303148 EXPECT_EQ(request, outRequest);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08003149
3150#ifdef LIBPLDM_API_TESTING
3151 /* Check the roundtrip */
3152 struct pldm_update_component_req_full req;
3153 PLDM_MSG_DEFINE_P(dec, outRequest.size());
3154 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3155 rc = decode_update_component_req(dec, outRequest.size() - hdrSize, &req);
3156 ASSERT_EQ(rc, 0);
3157
3158 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3159 EXPECT_EQ(req.comp_identifier, compIdentifier);
3160 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3161 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3162 EXPECT_EQ(req.comp_image_size, compImageSize);
3163 EXPECT_EQ(req.update_option_flags.value, updateOptionFlags.value);
3164 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3165 EXPECT_EQ(req.version.str_len, compVerStrLen);
3166 EXPECT_TRUE(std::equal(req.version.str_data,
3167 req.version.str_data + req.version.str_len,
3168 compVerStr.data()));
3169#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09303170}
3171
3172TEST(UpdateComponent, errorPathEncodeRequest)
3173{
3174 constexpr uint8_t instanceId = 2;
3175 constexpr uint16_t compIdentifier = 500;
3176 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003177 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303178 constexpr uint32_t compImageSize = 4096;
3179 constexpr bitfield32_t updateOptionFlags{1};
3180 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3181 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3182 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303183 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303184 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3185 compVerStrInfo.length = compVerStrLen;
3186
3187 std::array<uint8_t,
3188 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3189 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303190 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303191 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3192
3193 auto rc = encode_update_component_req(
3194 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3195 compComparisonStamp, compImageSize, updateOptionFlags,
3196 PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
3197 sizeof(pldm_update_component_req) + compVerStrLen);
3198 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3199
3200 compVerStrInfo.ptr = nullptr;
3201 rc = encode_update_component_req(
3202 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3203 compComparisonStamp, compImageSize, updateOptionFlags,
3204 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3205 sizeof(pldm_update_component_req) + compVerStrLen);
3206 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303207 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303208 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3209
3210 rc = encode_update_component_req(
3211 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3212 compComparisonStamp, compImageSize, updateOptionFlags,
3213 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
3214 sizeof(pldm_update_component_req) + compVerStrLen);
3215 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3216
3217 rc = encode_update_component_req(
3218 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3219 compComparisonStamp, compImageSize, updateOptionFlags,
3220 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3221 sizeof(pldm_update_component_req));
3222 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3223
3224 rc = encode_update_component_req(
3225 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3226 compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
3227 compVerStrLen, &compVerStrInfo, requestMsg,
3228 sizeof(pldm_update_component_req) + compVerStrLen);
3229 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3230
3231 rc = encode_update_component_req(
3232 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3233 compComparisonStamp, compImageSize, updateOptionFlags,
3234 PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg,
3235 sizeof(pldm_update_component_req) + compVerStrLen);
3236 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3237
3238 rc = encode_update_component_req(
3239 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3240 compComparisonStamp, compImageSize, updateOptionFlags,
3241 PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg,
3242 sizeof(pldm_update_component_req) + compVerStrLen);
3243 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3244
3245 rc = encode_update_component_req(
3246 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3247 compComparisonStamp, compImageSize, updateOptionFlags,
3248 PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
3249 sizeof(pldm_update_component_req) + compVerStrLen);
3250 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3251}
3252
3253TEST(UpdateComponent, goodPathDecodeResponse)
3254{
3255 constexpr std::bitset<32> forceUpdateComp{1};
3256 constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
3257 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3258 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3259 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3260 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303261 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303262 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3263
3264 uint8_t completionCode = 0;
3265 uint8_t compCompatibilityResp = 0;
3266 uint8_t compCompatibilityRespCode = 0;
3267 bitfield32_t updateOptionFlagsEnabled{};
3268 uint16_t timeBeforeReqFWData = 0;
3269
3270 auto rc = decode_update_component_resp(
3271 responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
3272 &compCompatibilityResp, &compCompatibilityRespCode,
3273 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3274
3275 EXPECT_EQ(rc, PLDM_SUCCESS);
3276 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3277 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
3278 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
3279 EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
3280 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
3281
3282 constexpr std::bitset<32> noFlags{};
3283 constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
3284 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3285 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3287 auto responseMsg2 =
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*>(updateComponentResponse2.data());
3290 rc = decode_update_component_resp(
3291 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3292 &compCompatibilityResp, &compCompatibilityRespCode,
3293 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3294
3295 EXPECT_EQ(rc, PLDM_SUCCESS);
3296 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3297 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
3298 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
3299 EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
3300 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
3301
3302 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3303 updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
3304 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303305 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303306 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3307
3308 rc = decode_update_component_resp(
3309 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3310 &compCompatibilityResp, &compCompatibilityRespCode,
3311 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3312
3313 EXPECT_EQ(rc, PLDM_SUCCESS);
3314 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3315}
3316
3317TEST(UpdateComponent, errorPathDecodeResponse)
3318{
3319 constexpr std::array<uint8_t,
3320 hdrSize + sizeof(pldm_update_component_resp) - 1>
3321 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3322 0x00, 0x00, 0x00, 0x00, 0x00};
3323 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303324 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303325 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3326
3327 uint8_t completionCode = 0;
3328 uint8_t compCompatibilityResp = 0;
3329 uint8_t compCompatibilityRespCode = 0;
3330 bitfield32_t updateOptionFlagsEnabled{};
3331 uint16_t timeBeforeReqFWData = 0;
3332
3333 auto rc = decode_update_component_resp(
3334 nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
3335 &compCompatibilityResp, &compCompatibilityRespCode,
3336 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3337 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3338
3339 rc = decode_update_component_resp(
3340 responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
3341 &compCompatibilityResp, &compCompatibilityRespCode,
3342 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3343 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3344
3345 rc = decode_update_component_resp(
3346 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3347 nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3348 &timeBeforeReqFWData);
3349 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3350
3351 rc = decode_update_component_resp(
3352 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3353 &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
3354 &timeBeforeReqFWData);
3355 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3356
3357 rc = decode_update_component_resp(
3358 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3359 &compCompatibilityResp, &compCompatibilityRespCode, nullptr,
3360 &timeBeforeReqFWData);
3361 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3362
3363 rc = decode_update_component_resp(
3364 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3365 &compCompatibilityResp, &compCompatibilityRespCode,
3366 &updateOptionFlagsEnabled, nullptr);
3367 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3368
3369 rc = decode_update_component_resp(
3370 responseMsg1, 0, &completionCode, &compCompatibilityResp,
3371 &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3372 &timeBeforeReqFWData);
3373 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3374
3375 rc = decode_update_component_resp(
3376 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3377 &compCompatibilityResp, &compCompatibilityRespCode,
3378 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3379 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3380
3381 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3382 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
3383 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3384 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303385 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303386 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3387 rc = decode_update_component_resp(
3388 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3389 &compCompatibilityResp, &compCompatibilityRespCode,
3390 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3391 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3392
3393 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003394 updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303395 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3396 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303397 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303398 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3399 rc = decode_update_component_resp(
3400 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3401 &compCompatibilityResp, &compCompatibilityRespCode,
3402 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3403 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3404
3405 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003406 updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303407 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3408 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303409 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303410 reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
3411 rc = decode_update_component_resp(
3412 responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
3413 &compCompatibilityResp, &compCompatibilityRespCode,
3414 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3415 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3416}
3417
3418TEST(RequestFirmwareData, goodPathDecodeRequest)
3419{
3420 constexpr uint32_t offset = 300;
3421 constexpr uint32_t length = 255;
3422 constexpr std::array<uint8_t,
3423 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003424 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3425 0x00, 0xff, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303426 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303427 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3428
3429 uint32_t outOffset = 0;
3430 uint32_t outLength = 0;
3431 auto rc = decode_request_firmware_data_req(
3432 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3433 &outLength);
3434
3435 EXPECT_EQ(rc, PLDM_SUCCESS);
3436 EXPECT_EQ(outOffset, offset);
3437 EXPECT_EQ(outLength, length);
3438}
3439
3440TEST(RequestFirmwareData, errorPathDecodeRequest)
3441{
3442 constexpr std::array<uint8_t,
3443 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003444 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3445 0x00, 0x1f, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303446 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303447 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3448
3449 uint32_t outOffset = 0;
3450 uint32_t outLength = 0;
3451 auto rc = decode_request_firmware_data_req(
3452 nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
3453 &outLength);
3454 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3455
3456 rc = decode_request_firmware_data_req(
3457 requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
3458 &outLength);
3459 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3460
3461 rc = decode_request_firmware_data_req(
3462 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3463 nullptr);
3464 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3465
3466 rc = decode_request_firmware_data_req(
3467 requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
3468 &outLength);
3469 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3470
3471 rc = decode_request_firmware_data_req(
3472 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3473 &outLength);
3474 EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
3475}
3476
3477TEST(RequestFirmwareData, goodPathEncodeResponse)
3478{
3479 constexpr uint8_t instanceId = 3;
3480 constexpr uint8_t completionCode = PLDM_SUCCESS;
3481 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
3482 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3483 outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003484 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3485 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3486 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3487 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303488 std::array<uint8_t, hdrSize + sizeof(completionCode) +
3489 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3490 reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003491 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3492 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3493 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3494 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303495 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303496 auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
3497 auto rc = encode_request_firmware_data_resp(
3498 instanceId, completionCode, responseMsg1,
3499 sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
3500 EXPECT_EQ(rc, PLDM_SUCCESS);
3501 EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
3502
3503 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3504 outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
3505 std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
3506 0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303507 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303508 auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
3509 rc = encode_request_firmware_data_resp(
3510 instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
3511 sizeof(completionCode));
3512 EXPECT_EQ(rc, PLDM_SUCCESS);
3513 EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
3514}
3515
3516TEST(RequestFirmwareData, errorPathEncodeResponse)
3517{
3518 std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303519 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303520 auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
3521 auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
3522 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3523
3524 rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
3525 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3526}
3527
3528TEST(TransferComplete, goodPathDecodeRequest)
3529{
3530 constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
3531 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3532 transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
3533 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303534 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303535 reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
3536 uint8_t outTransferResult = 0;
3537
3538 auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
3539 &outTransferResult);
3540 EXPECT_EQ(rc, PLDM_SUCCESS);
3541 EXPECT_EQ(outTransferResult, transferResult);
3542
3543 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3544 transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
3545 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303546 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303547 reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
3548 rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
3549 &outTransferResult);
3550 EXPECT_EQ(rc, PLDM_SUCCESS);
3551 EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
3552}
3553
3554TEST(TransferComplete, errorPathDecodeRequest)
3555{
3556 constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
3557 0x00};
3558 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303559 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303560 reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
3561 uint8_t outTransferResult = 0;
3562
3563 auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
3564 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3565
3566 rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
3567 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3568
3569 rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
3570 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3571}
3572
3573TEST(TransferComplete, goodPathEncodeResponse)
3574{
3575 constexpr uint8_t instanceId = 4;
3576 constexpr uint8_t completionCode = PLDM_SUCCESS;
3577 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3578 outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
3579 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3580 transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3581 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303582 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303583 reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
3584 auto rc = encode_transfer_complete_resp(
3585 instanceId, completionCode, responseMsg1, sizeof(completionCode));
3586 EXPECT_EQ(rc, PLDM_SUCCESS);
3587 EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
3588
3589 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3590 outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
3591 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3592 transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3593 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303594 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303595 reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
3596 rc = encode_transfer_complete_resp(instanceId,
3597 PLDM_FWUP_COMMAND_NOT_EXPECTED,
3598 responseMsg2, sizeof(completionCode));
3599 EXPECT_EQ(rc, PLDM_SUCCESS);
3600 EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
3601}
3602
3603TEST(TransferComplete, errorPathEncodeResponse)
3604{
3605 std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
3606 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303607 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303608 reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
3609 auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3610 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3611
3612 rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3613 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3614}
3615
3616TEST(VerifyComplete, goodPathDecodeRequest)
3617{
3618 constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
3619 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3620 verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
3621 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303622 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303623 reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
3624 uint8_t outVerifyResult = 0;
3625
3626 auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
3627 &outVerifyResult);
3628 EXPECT_EQ(rc, PLDM_SUCCESS);
3629 EXPECT_EQ(outVerifyResult, verifyResult);
3630
3631 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3632 verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
3633 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303634 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303635 reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
3636 rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
3637 &outVerifyResult);
3638 EXPECT_EQ(rc, PLDM_SUCCESS);
3639 EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
3640}
3641
3642TEST(VerifyComplete, errorPathDecodeRequest)
3643{
3644 constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
3645 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303646 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303647 reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
3648 uint8_t outVerifyResult = 0;
3649
3650 auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
3651 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3652
3653 rc = decode_verify_complete_req(requestMsg, 0, nullptr);
3654 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3655
3656 rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);
3657 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3658}
3659
3660TEST(VerifyComplete, goodPathEncodeResponse)
3661{
3662 constexpr uint8_t instanceId = 5;
3663 constexpr uint8_t completionCode = PLDM_SUCCESS;
3664 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3665 outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};
3666 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3667 verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3668 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303669 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303670 reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());
3671 auto rc = encode_verify_complete_resp(instanceId, completionCode,
3672 responseMsg1, sizeof(completionCode));
3673 EXPECT_EQ(rc, PLDM_SUCCESS);
3674 EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);
3675
3676 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3677 outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88};
3678 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3679 verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3680 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303681 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303682 reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());
3683 rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3684 responseMsg2, sizeof(completionCode));
3685 EXPECT_EQ(rc, PLDM_SUCCESS);
3686 EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);
3687}
3688
3689TEST(VerifyComplete, errorPathEncodeResponse)
3690{
3691 std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00};
3692 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303693 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303694 reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());
3695 auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3696 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3697
3698 rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3699 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3700}
3701
3702TEST(ApplyComplete, goodPathDecodeRequest)
3703{
3704 constexpr uint8_t applyResult1 =
3705 PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
3706 // DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
3707 constexpr std::bitset<16> compActivationModification1{0x30};
3708 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3709 applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
3710 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303711 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303712 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3713 uint8_t outApplyResult = 0;
3714 bitfield16_t outCompActivationModification{};
3715 auto rc = decode_apply_complete_req(
3716 requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
3717 &outCompActivationModification);
3718 EXPECT_EQ(rc, PLDM_SUCCESS);
3719 EXPECT_EQ(outApplyResult, applyResult1);
3720 EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
3721
3722 constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
3723 constexpr std::bitset<16> compActivationModification2{};
3724 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3725 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3726 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303727 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303728 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3729 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3730 &outApplyResult,
3731 &outCompActivationModification);
3732 EXPECT_EQ(rc, PLDM_SUCCESS);
3733 EXPECT_EQ(outApplyResult, applyResult2);
3734 EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
3735}
3736
3737TEST(ApplyComplete, errorPathDecodeRequest)
3738{
3739 constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
3740 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303741 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303742 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3743 uint8_t outApplyResult = 0;
3744 bitfield16_t outCompActivationModification{};
3745
3746 auto rc = decode_apply_complete_req(
3747 nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
3748 &outCompActivationModification);
3749 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3750
3751 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3752 nullptr, &outCompActivationModification);
3753 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3754
3755 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3756 &outApplyResult, nullptr);
3757 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3758
3759 rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
3760 &outCompActivationModification);
3761 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3762
3763 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3764 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
3765 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303766 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303767 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3768 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3769 &outApplyResult,
3770 &outCompActivationModification);
3771 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3772}
3773
3774TEST(ApplyComplete, goodPathEncodeResponse)
3775{
3776 constexpr uint8_t instanceId = 6;
3777 constexpr uint8_t completionCode = PLDM_SUCCESS;
3778 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3779 outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
3780 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3781 applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3782 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303783 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303784 reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
3785 auto rc = encode_apply_complete_resp(instanceId, completionCode,
3786 responseMsg1, sizeof(completionCode));
3787 EXPECT_EQ(rc, PLDM_SUCCESS);
3788 EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
3789
3790 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3791 outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
3792 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3793 applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3794 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303795 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303796 reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
3797 rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3798 responseMsg2, sizeof(completionCode));
3799 EXPECT_EQ(rc, PLDM_SUCCESS);
3800 EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
3801}
3802
3803TEST(ApplyComplete, errorPathEncodeResponse)
3804{
3805 std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
3806 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303807 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303808 reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
3809 auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3810 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3811
3812 rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3813 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3814}
3815
3816TEST(ActivateFirmware, goodPathEncodeRequest)
3817{
3818 constexpr uint8_t instanceId = 7;
3819
3820 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303821 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303822 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3823
3824 auto rc = encode_activate_firmware_req(
3825 instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
3826 sizeof(pldm_activate_firmware_req));
3827 EXPECT_EQ(rc, PLDM_SUCCESS);
3828
3829 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003830 outRequest{0x87, 0x05, 0x1a, 0x01};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303831 EXPECT_EQ(request, outRequest);
3832}
3833
3834TEST(ActivateFirmware, errorPathEncodeRequest)
3835{
3836 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303837 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303838 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3839
3840 auto rc = encode_activate_firmware_req(
3841 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
3842 sizeof(pldm_activate_firmware_req));
3843 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3844
3845 rc = encode_activate_firmware_req(
3846 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
3847 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3848
3849 rc = encode_activate_firmware_req(0, 2, requestMsg,
3850 sizeof(pldm_activate_firmware_req));
3851 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3852}
3853
3854TEST(ActivateFirmware, goodPathDecodeResponse)
3855{
3856 constexpr uint16_t estimatedTimeForActivation100s = 100;
3857 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3858 activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
3859 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303860 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303861 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
3862
3863 uint8_t completionCode = 0;
3864 uint16_t estimatedTimeForActivation = 0;
3865
3866 auto rc = decode_activate_firmware_resp(
3867 responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
3868 &estimatedTimeForActivation);
3869
3870 EXPECT_EQ(rc, PLDM_SUCCESS);
3871 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3872 EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
3873
3874 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3875 activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
3876 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303877 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303878 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data());
3879
3880 rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
3881 &completionCode,
3882 &estimatedTimeForActivation);
3883
3884 EXPECT_EQ(rc, PLDM_SUCCESS);
3885 EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
3886}
3887
3888TEST(ActivateFirmware, errorPathDecodeResponse)
3889{
3890 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3891 activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3892 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303893 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303894 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
3895
3896 uint8_t completionCode = 0;
3897 uint16_t estimatedTimeForActivation = 0;
3898
3899 auto rc = decode_activate_firmware_resp(
3900 nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
3901 &estimatedTimeForActivation);
3902 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3903
3904 rc = decode_activate_firmware_resp(responseMsg,
3905 sizeof(pldm_activate_firmware_resp),
3906 nullptr, &estimatedTimeForActivation);
3907 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3908
3909 rc = decode_activate_firmware_resp(responseMsg,
3910 sizeof(pldm_activate_firmware_resp),
3911 &completionCode, nullptr);
3912 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3913
3914 rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
3915 &estimatedTimeForActivation);
3916 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3917
3918 rc = decode_activate_firmware_resp(
3919 responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
3920 &estimatedTimeForActivation);
3921 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3922}
3923
3924TEST(GetStatus, goodPathEncodeRequest)
3925{
3926 constexpr uint8_t instanceId = 8;
3927 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303928 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303929 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3930
3931 auto rc = encode_get_status_req(instanceId, requestMsg,
3932 PLDM_GET_STATUS_REQ_BYTES);
3933 EXPECT_EQ(rc, PLDM_SUCCESS);
3934
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003935 constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303936 EXPECT_EQ(request, outRequest);
3937}
3938
3939TEST(GetStatus, errorPathEncodeRequest)
3940{
3941 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303942 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303943 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3944
3945 auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
3946 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3947
3948 rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);
3949 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3950}
3951
3952TEST(GetStatus, goodPathDecodeResponse)
3953{
3954 constexpr std::bitset<32> updateOptionFlagsEnabled1{0};
3955 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3956 getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
3957 0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};
3958 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303959 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303960 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
3961
3962 uint8_t completionCode = 0;
3963 uint8_t currentState = 0;
3964 uint8_t previousState = 0;
3965 uint8_t auxState = 0;
3966 uint8_t auxStateStatus = 0;
3967 uint8_t progressPercent = 0;
3968 uint8_t reasonCode = 0;
3969 bitfield32_t updateOptionFlagsEnabled{0};
3970
3971 auto rc = decode_get_status_resp(
3972 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3973 &currentState, &previousState, &auxState, &auxStateStatus,
3974 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3975
3976 EXPECT_EQ(rc, PLDM_SUCCESS);
3977 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3978 EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);
3979 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
3980 EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);
3981 EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);
3982 EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);
3983 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
3984 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);
3985
3986 // Bit position 0 - Force update of component – FD will perform a force
3987 // update of the component.
3988 constexpr std::bitset<32> updateOptionFlagsEnabled2{1};
3989 constexpr uint8_t progressPercent2 = 50;
3990 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3991 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,
3992 0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};
3993 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303994 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303995 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
3996
3997 rc = decode_get_status_resp(
3998 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
3999 &currentState, &previousState, &auxState, &auxStateStatus,
4000 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4001
4002 EXPECT_EQ(rc, PLDM_SUCCESS);
4003 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4004 EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);
4005 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4006 EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);
4007 EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);
4008 EXPECT_EQ(progressPercent, progressPercent2);
4009 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4010 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);
4011
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08004012#ifdef LIBPLDM_API_TESTING
4013 /* Check the roundtrip */
4014 PLDM_MSG_DEFINE_P(enc, 1000);
4015 size_t enc_payload_len = 1000;
4016 const struct pldm_get_status_resp status_enc = {
4017 .completion_code = PLDM_SUCCESS,
4018 .current_state = currentState,
4019 .previous_state = previousState,
4020 .aux_state = auxState,
4021 .aux_state_status = auxStateStatus,
4022 .progress_percent = progressPercent,
4023 .reason_code = reasonCode,
4024 .update_option_flags_enabled = updateOptionFlagsEnabled,
4025 };
4026 rc = encode_get_status_resp(FIXED_INSTANCE_ID, &status_enc, enc,
4027 &enc_payload_len);
4028 EXPECT_EQ(rc, PLDM_SUCCESS);
4029 EXPECT_EQ(enc_payload_len + hdrSize, getStatusResponse2.size());
4030 EXPECT_TRUE(std::equal(getStatusResponse2.begin() + hdrSize,
4031 getStatusResponse2.end(), enc_buf + hdrSize));
4032 check_response(enc, PLDM_GET_STATUS);
4033#endif
4034
4035 /* Check a not-ready completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09304036 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4037 getStatusResponse3{0x00, 0x00, 0x00, 0x04};
4038 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304039 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304040 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4041 rc = decode_get_status_resp(
4042 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4043 &currentState, &previousState, &auxState, &auxStateStatus,
4044 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4045 EXPECT_EQ(rc, PLDM_SUCCESS);
4046 EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);
4047}
4048
4049TEST(GetStatus, errorPathDecodeResponse)
4050{
4051 uint8_t completionCode = 0;
4052 uint8_t currentState = 0;
4053 uint8_t previousState = 0;
4054 uint8_t auxState = 0;
4055 uint8_t auxStateStatus = 0;
4056 uint8_t progressPercent = 0;
4057 uint8_t reasonCode = 0;
4058 bitfield32_t updateOptionFlagsEnabled{0};
4059
4060 constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};
4061 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304062 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304063 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4064
4065 auto rc = decode_get_status_resp(
4066 nullptr, getStatusResponse1.size() - hdrSize, &completionCode,
4067 &currentState, &previousState, &auxState, &auxStateStatus,
4068 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4069 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4070
4071 rc = decode_get_status_resp(
4072 responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,
4073 &currentState, &previousState, &auxState, &auxStateStatus,
4074 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4075 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4076
4077 rc = decode_get_status_resp(
4078 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4079 nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,
4080 &reasonCode, &updateOptionFlagsEnabled);
4081 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4082
4083 rc = decode_get_status_resp(
4084 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4085 &currentState, nullptr, &auxState, &auxStateStatus, &progressPercent,
4086 &reasonCode, &updateOptionFlagsEnabled);
4087 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4088
4089 rc = decode_get_status_resp(
4090 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4091 &currentState, &previousState, nullptr, &auxStateStatus,
4092 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4093 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4094
4095 rc = decode_get_status_resp(
4096 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4097 &currentState, &previousState, &auxState, nullptr, &progressPercent,
4098 &reasonCode, &updateOptionFlagsEnabled);
4099 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4100
4101 rc = decode_get_status_resp(
4102 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4103 &currentState, &previousState, &auxState, &auxStateStatus, nullptr,
4104 &reasonCode, &updateOptionFlagsEnabled);
4105 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4106
4107 rc = decode_get_status_resp(
4108 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4109 &currentState, &previousState, &auxState, &auxStateStatus,
4110 &progressPercent, nullptr, &updateOptionFlagsEnabled);
4111 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4112
4113 rc = decode_get_status_resp(
4114 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4115 &currentState, &previousState, &auxState, &auxStateStatus,
4116 &progressPercent, &reasonCode, nullptr);
4117 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4118
4119 rc = decode_get_status_resp(
4120 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4121 &currentState, &previousState, &auxState, &auxStateStatus,
4122 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4123 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4124
4125 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>
4126 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4128 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304129 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304130 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4131 rc = decode_get_status_resp(
4132 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4133 &currentState, &previousState, &auxState, &auxStateStatus,
4134 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4135 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4136
4137 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4138 getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
4139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4140 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304141 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304142 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4143 rc = decode_get_status_resp(
4144 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4145 &currentState, &previousState, &auxState, &auxStateStatus,
4146 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4147 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4148
4149 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4150 getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
4151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4152 auto responseMsg4 =
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*>(getStatusResponse4.data());
4155 rc = decode_get_status_resp(
4156 responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,
4157 &currentState, &previousState, &auxState, &auxStateStatus,
4158 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4159 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4160
4161 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4162 getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
4163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4164 auto responseMsg5 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304165 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304166 reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());
4167 rc = decode_get_status_resp(
4168 responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,
4169 &currentState, &previousState, &auxState, &auxStateStatus,
4170 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4171 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4172
4173 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4174 getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004175 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304176 auto responseMsg6 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304177 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304178 reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());
4179 rc = decode_get_status_resp(
4180 responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,
4181 &currentState, &previousState, &auxState, &auxStateStatus,
4182 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4183 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4184
4185 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4186 getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4187 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
4188 auto responseMsg7 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304189 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304190 reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());
4191 rc = decode_get_status_resp(
4192 responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,
4193 &currentState, &previousState, &auxState, &auxStateStatus,
4194 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4195 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4196
4197 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4198 getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004199 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304200 auto responseMsg8 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304201 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304202 reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());
4203 rc = decode_get_status_resp(
4204 responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,
4205 &currentState, &previousState, &auxState, &auxStateStatus,
4206 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4207 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4208
4209 // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is
4210 // IDLE
4211 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4212 getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
4213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4214 auto responseMsg9 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304215 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304216 reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());
4217 rc = decode_get_status_resp(
4218 responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,
4219 &currentState, &previousState, &auxState, &auxStateStatus,
4220 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4221 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4222}
4223
4224TEST(CancelUpdateComponent, goodPathEncodeRequest)
4225{
4226 constexpr uint8_t instanceId = 9;
4227 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304228 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304229 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4230
4231 auto rc = encode_cancel_update_component_req(
4232 instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4233 EXPECT_EQ(rc, PLDM_SUCCESS);
4234
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004235 constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304236 EXPECT_EQ(request, outRequest);
4237}
4238
4239TEST(CancelUpdateComponent, errorPathEncodeRequest)
4240{
4241 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304242 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304243 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4244
4245 auto rc = encode_cancel_update_component_req(
4246 0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4247 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4248
4249 rc = encode_cancel_update_component_req(
4250 0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);
4251 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4252}
4253
4254TEST(CancelUpdateComponent, testGoodDecodeResponse)
4255{
4256 uint8_t completionCode = 0;
4257 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4258 cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304259 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304260 auto responseMsg1 = reinterpret_cast<const pldm_msg*>(
4261 cancelUpdateComponentResponse1.data());
4262 auto rc = decode_cancel_update_component_resp(
4263 responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,
4264 &completionCode);
4265 EXPECT_EQ(rc, PLDM_SUCCESS);
4266 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4267
4268 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4269 cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304270 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304271 auto responseMsg2 = reinterpret_cast<const pldm_msg*>(
4272 cancelUpdateComponentResponse2.data());
4273 rc = decode_cancel_update_component_resp(
4274 responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,
4275 &completionCode);
4276 EXPECT_EQ(rc, PLDM_SUCCESS);
4277 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4278}
4279
4280TEST(CancelUpdateComponent, testBadDecodeResponse)
4281{
4282 uint8_t completionCode = 0;
4283 constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{
4284 0x00, 0x00, 0x00};
4285 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304286 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304287 reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data());
4288
4289 auto rc = decode_cancel_update_component_resp(
4290 nullptr, cancelUpdateComponentResponse.size() - hdrSize,
4291 &completionCode);
4292 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4293
4294 rc = decode_cancel_update_component_resp(
4295 responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);
4296 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4297
4298 rc = decode_cancel_update_component_resp(
4299 responseMsg, cancelUpdateComponentResponse.size() - hdrSize,
4300 &completionCode);
4301 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4302}
4303
4304TEST(CancelUpdate, goodPathEncodeRequest)
4305{
4306 constexpr uint8_t instanceId = 10;
4307 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304308 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304309 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4310
4311 auto rc = encode_cancel_update_req(instanceId, requestMsg,
4312 PLDM_CANCEL_UPDATE_REQ_BYTES);
4313 EXPECT_EQ(rc, PLDM_SUCCESS);
4314
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004315 constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304316 EXPECT_EQ(request, outRequest);
4317}
4318
4319TEST(CancelUpdate, errorPathEncodeRequest)
4320{
4321 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304322 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304323 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4324
4325 auto rc =
4326 encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
4327 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4328
4329 rc = encode_cancel_update_req(0, requestMsg,
4330 PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
4331 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4332}
4333
4334TEST(CancelUpdate, goodPathDecodeResponse)
4335{
4336 constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
4337 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4338 cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4340 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304341 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304342 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4343 uint8_t completionCode = 0;
4344 bool8_t nonFunctioningComponentIndication = 0;
4345 bitfield64_t nonFunctioningComponentBitmap{0};
4346 auto rc = decode_cancel_update_resp(
4347 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4348 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4349 EXPECT_EQ(rc, PLDM_SUCCESS);
4350 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4351 EXPECT_EQ(nonFunctioningComponentIndication,
4352 PLDM_FWUP_COMPONENTS_FUNCTIONING);
4353 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4354 nonFunctioningComponentBitmap1);
4355
4356 constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
4357 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4358 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
4359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4360 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304361 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304362 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4363 rc = decode_cancel_update_resp(
4364 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4365 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4366 EXPECT_EQ(rc, PLDM_SUCCESS);
4367 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4368 EXPECT_EQ(nonFunctioningComponentIndication,
4369 PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING);
4370 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4371 nonFunctioningComponentBitmap2);
4372
4373 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4374 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
4375 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304376 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304377 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4378 rc = decode_cancel_update_resp(
4379 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4380 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4381 EXPECT_EQ(rc, PLDM_SUCCESS);
4382 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4383}
4384
4385TEST(CancelUpdate, errorPathDecodeResponse)
4386{
4387 constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
4388 0x00};
4389 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304390 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304391 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4392 uint8_t completionCode = 0;
4393 bool8_t nonFunctioningComponentIndication = 0;
4394 bitfield64_t nonFunctioningComponentBitmap{0};
4395
4396 auto rc = decode_cancel_update_resp(
4397 nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4398 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4399 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4400
4401 rc = decode_cancel_update_resp(
4402 responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
4403 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4404 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4405
4406 rc = decode_cancel_update_resp(
4407 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4408 nullptr, &nonFunctioningComponentBitmap);
4409 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4410
4411 rc = decode_cancel_update_resp(
4412 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4413 &nonFunctioningComponentIndication, nullptr);
4414 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4415
4416 rc = decode_cancel_update_resp(
4417 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4418 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4419 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4420
4421 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4422 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
4423 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304424 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304425 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4426 rc = decode_cancel_update_resp(
4427 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4428 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4429 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4430
4431 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4432 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
4433 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4434 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304435 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304436 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4437 rc = decode_cancel_update_resp(
4438 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4439 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4440 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4441}