blob: 411e3a6546ad72ad1b5aa6d738b7d3c56aaea3fc [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 Jeffery9c766792022-08-10 23:12:49 +093045TEST(DecodePackageHeaderInfo, goodPath)
46{
47 // Package header identifier for Version 1.0.x
48 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
49 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -060050 0x98, 0x00, 0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02};
Andrew Jeffery9c766792022-08-10 23:12:49 +093051 // Package header version for DSP0267 version 1.0.x
52 constexpr uint8_t pkgHeaderFormatRevision = 0x01;
53 // Random PackageHeaderSize
54 constexpr uint16_t pkgHeaderSize = 303;
55 // PackageReleaseDateTime - "25/12/2021 00:00:00"
56 std::array<uint8_t, PLDM_TIMESTAMP104_SIZE> package_release_date_time{
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00};
59 constexpr uint16_t componentBitmapBitLength = 8;
60 // PackageVersionString
61 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
Andrew Jefferya3eba612025-03-06 17:11:20 +103062 constexpr size_t packageHeaderSize =
Andrew Jeffery9c766792022-08-10 23:12:49 +093063 sizeof(pldm_package_header_information) + packageVersionStr.size();
64
Andrew Jefferya3eba612025-03-06 17:11:20 +103065 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -060066 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
Andrew Jeffery9c766792022-08-10 23:12:49 +093067 0x05, 0x9a, 0xca, 0x02, 0x01, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b,
69 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
70 pldm_package_header_information pkgHeader{};
71 variable_field packageVersion{};
72
73 auto rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
74 packagerHeaderInfo.size(),
75 &pkgHeader, &packageVersion);
76
77 EXPECT_EQ(rc, PLDM_SUCCESS);
78 EXPECT_EQ(true,
79 std::equal(pkgHeader.uuid, pkgHeader.uuid + PLDM_FWUP_UUID_LENGTH,
80 uuid.begin(), uuid.end()));
81 EXPECT_EQ(pkgHeader.package_header_format_version, pkgHeaderFormatRevision);
82 EXPECT_EQ(pkgHeader.package_header_size, pkgHeaderSize);
83 EXPECT_EQ(true, std::equal(pkgHeader.package_release_date_time,
84 pkgHeader.package_release_date_time +
85 PLDM_TIMESTAMP104_SIZE,
86 package_release_date_time.begin(),
87 package_release_date_time.end()));
88 EXPECT_EQ(pkgHeader.component_bitmap_bit_length, componentBitmapBitLength);
89 EXPECT_EQ(pkgHeader.package_version_string_type, PLDM_STR_TYPE_ASCII);
90 EXPECT_EQ(pkgHeader.package_version_string_length,
91 packageVersionStr.size());
92 std::string packageVersionString(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +093093 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +093094 reinterpret_cast<const char*>(packageVersion.ptr),
95 packageVersion.length);
96 EXPECT_EQ(packageVersionString, packageVersionStr);
97}
98
99TEST(DecodePackageHeaderInfo, errorPaths)
100{
101 int rc = 0;
102 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
Andrew Jefferya3eba612025-03-06 17:11:20 +1030103 constexpr size_t packageHeaderSize =
Andrew Jeffery9c766792022-08-10 23:12:49 +0930104 sizeof(pldm_package_header_information) + packageVersionStr.size();
105
106 // Invalid Package Version String Type - 0x06
Andrew Jefferya3eba612025-03-06 17:11:20 +1030107 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo1{
108 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
109 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
110 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x06, 0x0b,
111 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
Andrew Jeffery9c766792022-08-10 23:12:49 +0930112
113 pldm_package_header_information packageHeader{};
114 variable_field packageVersion{};
115
116 rc = decode_pldm_package_header_info(nullptr,
117 invalidPackagerHeaderInfo1.size(),
118 &packageHeader, &packageVersion);
119 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
120
121 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
122 invalidPackagerHeaderInfo1.size(),
123 nullptr, &packageVersion);
124 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
125
126 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
127 invalidPackagerHeaderInfo1.size(),
128 &packageHeader, nullptr);
129 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
130
131 rc = decode_pldm_package_header_info(
132 invalidPackagerHeaderInfo1.data(),
133 sizeof(pldm_package_header_information) - 1, &packageHeader,
134 &packageVersion);
135 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
136
137 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
138 invalidPackagerHeaderInfo1.size(),
139 &packageHeader, &packageVersion);
140 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
141
142 // Invalid Package Version String Length - 0x00
Andrew Jefferya3eba612025-03-06 17:11:20 +1030143 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo2{
144 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
145 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x00,
147 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
Andrew Jeffery9c766792022-08-10 23:12:49 +0930148 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo2.data(),
149 invalidPackagerHeaderInfo2.size(),
150 &packageHeader, &packageVersion);
151 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
152
153 // Package version string length less than in the header information
Andrew Jefferya3eba612025-03-06 17:11:20 +1030154 constexpr std::array<uint8_t, packageHeaderSize - 1>
Andrew Jeffery9c766792022-08-10 23:12:49 +0930155 invalidPackagerHeaderInfo3{
156 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600157 0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
159 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e,
160 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e};
161 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo3.data(),
162 invalidPackagerHeaderInfo3.size(),
163 &packageHeader, &packageVersion);
164 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
165
166 // ComponentBitmapBitLength not a multiple of 8
Andrew Jefferya3eba612025-03-06 17:11:20 +1030167 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo4{
168 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
169 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x09, 0x00, 0x01, 0x0b,
171 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
Andrew Jeffery9c766792022-08-10 23:12:49 +0930172 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo4.data(),
173 invalidPackagerHeaderInfo4.size(),
174 &packageHeader, &packageVersion);
175 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
176}
177
178TEST(DecodeFirmwareDeviceIdRecord, goodPath)
179{
180 constexpr uint8_t descriptorCount = 1;
181 // Continue component updates after failure
182 constexpr std::bitset<32> deviceUpdateFlag{1};
183 constexpr uint16_t componentBitmapBitLength = 16;
184 // Applicable Components - 1,2,5,8,9
185 std::vector<std::bitset<8>> applicableComponentsBitfield{0x93, 0x01};
186 // ComponentImageSetVersionString
187 constexpr std::string_view imageSetVersionStr{"VersionString1"};
188 // Initial descriptor - UUID
189 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
190 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
191 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
192 constexpr uint16_t fwDevicePkgDataLen = 2;
193 // FirmwareDevicePackageData
194 constexpr std::array<uint8_t, fwDevicePkgDataLen> fwDevicePkgData{0xab,
195 0xcd};
196 // Size of the firmware device ID record
197 constexpr uint16_t recordLen =
198 sizeof(pldm_firmware_device_id_record) +
199 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
200 imageSetVersionStr.size() + sizeof(pldm_descriptor_tlv) - 1 +
201 uuid.size() + fwDevicePkgData.size();
202 // Firmware device ID record
203 constexpr std::array<uint8_t, recordLen> record{
204 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02,
205 0x00, 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
206 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10,
207 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0,
208 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xab, 0xcd};
209
210 pldm_firmware_device_id_record deviceIdRecHeader{};
211 variable_field applicableComponents{};
212 variable_field outCompImageSetVersionStr{};
213 variable_field recordDescriptors{};
214 variable_field outFwDevicePkgData{};
215
216 auto rc = decode_firmware_device_id_record(
217 record.data(), record.size(), componentBitmapBitLength,
218 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
219 &recordDescriptors, &outFwDevicePkgData);
220
221 EXPECT_EQ(rc, PLDM_SUCCESS);
222 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
223 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
224 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
225 deviceUpdateFlag);
226 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
227 PLDM_STR_TYPE_ASCII);
228 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
229 imageSetVersionStr.size());
230 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, fwDevicePkgDataLen);
231
232 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
233 EXPECT_EQ(true,
234 std::equal(applicableComponents.ptr,
235 applicableComponents.ptr + applicableComponents.length,
236 applicableComponentsBitfield.begin(),
237 applicableComponentsBitfield.end()));
238
239 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
240 std::string compImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930241 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930242 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
243 outCompImageSetVersionStr.length);
244 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
245
246 uint16_t descriptorType = 0;
247 uint16_t descriptorLen = 0;
248 variable_field descriptorData{};
249 // DescriptorCount is 1, so decode_descriptor_type_length_value called once
250 rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
251 recordDescriptors.length,
252 &descriptorType, &descriptorData);
253 EXPECT_EQ(rc, PLDM_SUCCESS);
254 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
255 sizeof(descriptorLen) +
256 descriptorData.length);
257 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
258 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
259 EXPECT_EQ(true, std::equal(descriptorData.ptr,
260 descriptorData.ptr + descriptorData.length,
261 uuid.begin(), uuid.end()));
262
263 EXPECT_EQ(outFwDevicePkgData.length, fwDevicePkgData.size());
264 EXPECT_EQ(true,
265 std::equal(outFwDevicePkgData.ptr,
266 outFwDevicePkgData.ptr + outFwDevicePkgData.length,
267 fwDevicePkgData.begin(), fwDevicePkgData.end()));
268}
269
270TEST(DecodeFirmwareDeviceIdRecord, goodPathNofwDevicePkgData)
271{
272 constexpr uint8_t descriptorCount = 1;
273 // Continue component updates after failure
274 constexpr std::bitset<32> deviceUpdateFlag{1};
275 constexpr uint16_t componentBitmapBitLength = 8;
276 // Applicable Components - 1,2
277 std::vector<std::bitset<8>> applicableComponentsBitfield{0x03};
278 // ComponentImageSetVersionString
279 constexpr std::string_view imageSetVersionStr{"VersionString1"};
280 // Initial descriptor - UUID
281 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
282 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
283 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
284 constexpr uint16_t fwDevicePkgDataLen = 0;
285
286 // Size of the firmware device ID record
287 constexpr uint16_t recordLen =
288 sizeof(pldm_firmware_device_id_record) +
289 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
290 imageSetVersionStr.size() +
291 sizeof(pldm_descriptor_tlv().descriptor_type) +
292 sizeof(pldm_descriptor_tlv().descriptor_length) + uuid.size() +
293 fwDevicePkgDataLen;
294 // Firmware device ID record
295 constexpr std::array<uint8_t, recordLen> record{
296 0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x03,
297 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e,
298 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d,
299 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
300
301 pldm_firmware_device_id_record deviceIdRecHeader{};
302 variable_field applicableComponents{};
303 variable_field outCompImageSetVersionStr{};
304 variable_field recordDescriptors{};
305 variable_field outFwDevicePkgData{};
306
307 auto rc = decode_firmware_device_id_record(
308 record.data(), record.size(), componentBitmapBitLength,
309 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
310 &recordDescriptors, &outFwDevicePkgData);
311
312 EXPECT_EQ(rc, PLDM_SUCCESS);
313 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
314 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
315 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
316 deviceUpdateFlag);
317 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
318 PLDM_STR_TYPE_ASCII);
319 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
320 imageSetVersionStr.size());
321 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, 0);
322
323 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
324 EXPECT_EQ(true,
325 std::equal(applicableComponents.ptr,
326 applicableComponents.ptr + applicableComponents.length,
327 applicableComponentsBitfield.begin(),
328 applicableComponentsBitfield.end()));
329
330 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
331 std::string compImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930332 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930333 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
334 outCompImageSetVersionStr.length);
335 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
336
337 uint16_t descriptorType = 0;
338 uint16_t descriptorLen = 0;
339 variable_field descriptorData{};
340 // DescriptorCount is 1, so decode_descriptor_type_length_value called once
341 rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
342 recordDescriptors.length,
343 &descriptorType, &descriptorData);
344 EXPECT_EQ(rc, PLDM_SUCCESS);
345 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
346 sizeof(descriptorLen) +
347 descriptorData.length);
348 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
349 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
350 EXPECT_EQ(true, std::equal(descriptorData.ptr,
351 descriptorData.ptr + descriptorData.length,
352 uuid.begin(), uuid.end()));
353
354 EXPECT_EQ(outFwDevicePkgData.ptr, nullptr);
355 EXPECT_EQ(outFwDevicePkgData.length, 0);
356}
357
358TEST(DecodeFirmwareDeviceIdRecord, ErrorPaths)
359{
360 constexpr uint16_t componentBitmapBitLength = 8;
361 // Invalid ComponentImageSetVersionStringType
362 constexpr std::array<uint8_t, 11> invalidRecord1{
363 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
364
365 int rc = 0;
366 pldm_firmware_device_id_record deviceIdRecHeader{};
367 variable_field applicableComponents{};
368 variable_field outCompImageSetVersionStr{};
369 variable_field recordDescriptors{};
370 variable_field outFwDevicePkgData{};
371
372 rc = decode_firmware_device_id_record(
373 nullptr, invalidRecord1.size(), componentBitmapBitLength,
374 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
375 &recordDescriptors, &outFwDevicePkgData);
376 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
377
378 rc = decode_firmware_device_id_record(
379 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
380 nullptr, &applicableComponents, &outCompImageSetVersionStr,
381 &recordDescriptors, &outFwDevicePkgData);
382 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
383
384 rc = decode_firmware_device_id_record(
385 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
386 &deviceIdRecHeader, nullptr, &outCompImageSetVersionStr,
387 &recordDescriptors, &outFwDevicePkgData);
388 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
389
390 rc = decode_firmware_device_id_record(
391 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
392 &deviceIdRecHeader, &applicableComponents, nullptr, &recordDescriptors,
393 &outFwDevicePkgData);
394 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
395
396 rc = decode_firmware_device_id_record(
397 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
398 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
399 nullptr, &outFwDevicePkgData);
400 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
401
402 rc = decode_firmware_device_id_record(
403 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
404 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
405 &recordDescriptors, nullptr);
406 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
407
408 rc = decode_firmware_device_id_record(
409 invalidRecord1.data(), invalidRecord1.size() - 1,
410 componentBitmapBitLength, &deviceIdRecHeader, &applicableComponents,
411 &outCompImageSetVersionStr, &recordDescriptors, &outFwDevicePkgData);
412 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
413
414 rc = decode_firmware_device_id_record(
415 invalidRecord1.data(), invalidRecord1.size(),
416 componentBitmapBitLength + 1, &deviceIdRecHeader, &applicableComponents,
417 &outCompImageSetVersionStr, &recordDescriptors, &outFwDevicePkgData);
418 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
419
420 rc = decode_firmware_device_id_record(
421 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
422 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
423 &recordDescriptors, &outFwDevicePkgData);
424 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
425
426 // Invalid ComponentImageSetVersionStringLength
427 constexpr std::array<uint8_t, 11> invalidRecord2{
428 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
429 rc = decode_firmware_device_id_record(
430 invalidRecord2.data(), invalidRecord2.size(), componentBitmapBitLength,
431 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
432 &recordDescriptors, &outFwDevicePkgData);
433 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
434
435 // invalidRecord3 size is less than RecordLength
436 constexpr std::array<uint8_t, 11> invalidRecord3{
437 0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00};
438 rc = decode_firmware_device_id_record(
439 invalidRecord3.data(), invalidRecord3.size(), componentBitmapBitLength,
440 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
441 &recordDescriptors, &outFwDevicePkgData);
442 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
443
444 // RecordLength is less than the calculated RecordLength
445 constexpr std::array<uint8_t, 11> invalidRecord4{
446 0x15, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02, 0x00};
447 rc = decode_firmware_device_id_record(
448 invalidRecord4.data(), invalidRecord4.size(), componentBitmapBitLength,
449 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
450 &recordDescriptors, &outFwDevicePkgData);
451 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Matt Johnstonc4d1c8b2024-12-18 11:16:55 +0800452
453 // Large FirmwareDevicePackageDataLength could cause overflow in calculation
454 constexpr std::array<uint8_t, 49> invalidRecord5{
455 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e,
456 // FirmwareDevicePackageDataLength = 0xffff
457 0xff, 0xff,
458 //
459 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72,
460 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64,
461 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b,
462 0xab, 0xcd};
463 rc = decode_firmware_device_id_record(
464 invalidRecord5.data(), invalidRecord5.size(), componentBitmapBitLength,
465 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
466 &recordDescriptors, &outFwDevicePkgData);
467 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930468}
469
470TEST(DecodeDescriptors, goodPath3Descriptors)
471{
472 // In the descriptor data there are 3 descriptor entries
473 // 1) IANA enterprise ID
474 constexpr std::array<uint8_t, PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH> iana{
475 0x0a, 0x0b, 0x0c, 0xd};
476 // 2) UUID
477 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
478 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
479 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
480 // 3) Vendor Defined
481 constexpr std::string_view vendorTitle{"OpenBMC"};
482 constexpr size_t vendorDescriptorLen = 2;
483 constexpr std::array<uint8_t, vendorDescriptorLen> vendorDescriptorData{
484 0x01, 0x02};
485
486 constexpr size_t vendorDefinedDescriptorLen =
487 sizeof(pldm_vendor_defined_descriptor_title_data()
488 .vendor_defined_descriptor_title_str_type) +
489 sizeof(pldm_vendor_defined_descriptor_title_data()
490 .vendor_defined_descriptor_title_str_len) +
491 vendorTitle.size() + vendorDescriptorData.size();
492
493 constexpr size_t descriptorsLength =
494 3 * (sizeof(pldm_descriptor_tlv().descriptor_type) +
495 sizeof(pldm_descriptor_tlv().descriptor_length)) +
496 iana.size() + uuid.size() + vendorDefinedDescriptorLen;
497
498 constexpr std::array<uint8_t, descriptorsLength> descriptors{
499 0x01, 0x00, 0x04, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x02, 0x00, 0x10,
500 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600501 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xff, 0xff, 0x0b, 0x00, 0x01,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930502 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x01, 0x02};
503
504 size_t descriptorCount = 1;
505 size_t descriptorsRemainingLength = descriptorsLength;
506 int rc = 0;
507
508 while (descriptorsRemainingLength && (descriptorCount <= 3))
509 {
510 uint16_t descriptorType = 0;
511 uint16_t descriptorLen = 0;
512 variable_field descriptorData{};
513
514 rc = decode_descriptor_type_length_value(
515 descriptors.data() + descriptorsLength - descriptorsRemainingLength,
516 descriptorsRemainingLength, &descriptorType, &descriptorData);
517 EXPECT_EQ(rc, PLDM_SUCCESS);
518
519 if (descriptorCount == 1)
520 {
521 EXPECT_EQ(descriptorType, PLDM_FWUP_IANA_ENTERPRISE_ID);
522 EXPECT_EQ(descriptorData.length,
523 PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH);
524 EXPECT_EQ(true,
525 std::equal(descriptorData.ptr,
526 descriptorData.ptr + descriptorData.length,
527 iana.begin(), iana.end()));
528 }
529 else if (descriptorCount == 2)
530 {
531 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
532 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
533 EXPECT_EQ(true,
534 std::equal(descriptorData.ptr,
535 descriptorData.ptr + descriptorData.length,
536 uuid.begin(), uuid.end()));
537 }
538 else if (descriptorCount == 3)
539 {
540 EXPECT_EQ(descriptorType, PLDM_FWUP_VENDOR_DEFINED);
541 EXPECT_EQ(descriptorData.length, vendorDefinedDescriptorLen);
542
543 uint8_t descriptorTitleStrType = 0;
544 variable_field descriptorTitleStr{};
545 variable_field vendorDefinedDescriptorData{};
546
547 rc = decode_vendor_defined_descriptor_value(
548 descriptorData.ptr, descriptorData.length,
549 &descriptorTitleStrType, &descriptorTitleStr,
550 &vendorDefinedDescriptorData);
551 EXPECT_EQ(rc, PLDM_SUCCESS);
552
553 EXPECT_EQ(descriptorTitleStrType, PLDM_STR_TYPE_ASCII);
554 EXPECT_EQ(descriptorTitleStr.length, vendorTitle.size());
555 std::string vendorTitleStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930556 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930557 reinterpret_cast<const char*>(descriptorTitleStr.ptr),
558 descriptorTitleStr.length);
559 EXPECT_EQ(vendorTitleStr, vendorTitle);
560
561 EXPECT_EQ(vendorDefinedDescriptorData.length,
562 vendorDescriptorData.size());
563 EXPECT_EQ(true, std::equal(vendorDefinedDescriptorData.ptr,
564 vendorDefinedDescriptorData.ptr +
565 vendorDefinedDescriptorData.length,
566 vendorDescriptorData.begin(),
567 vendorDescriptorData.end()));
568 }
569
570 descriptorsRemainingLength -= sizeof(descriptorType) +
571 sizeof(descriptorLen) +
572 descriptorData.length;
573 descriptorCount++;
574 }
575}
576
577TEST(DecodeDescriptors, errorPathDecodeDescriptorTLV)
578{
579 int rc = 0;
580 // IANA Enterprise ID descriptor length incorrect
581 constexpr std::array<uint8_t, 7> invalidIANADescriptor1{
582 0x01, 0x00, 0x03, 0x00, 0x0a, 0x0b, 0x0c};
583 uint16_t descriptorType = 0;
584 variable_field descriptorData{};
585
586 rc = decode_descriptor_type_length_value(nullptr,
587 invalidIANADescriptor1.size(),
588 &descriptorType, &descriptorData);
589 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
590
591 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
592 invalidIANADescriptor1.size(),
593 nullptr, &descriptorData);
594 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
595
596 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
597 invalidIANADescriptor1.size(),
598 &descriptorType, nullptr);
599 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
600
601 rc = decode_descriptor_type_length_value(
602 invalidIANADescriptor1.data(), PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN - 1,
603 &descriptorType, &descriptorData);
604 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
605
606 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
607 invalidIANADescriptor1.size(),
608 &descriptorType, &descriptorData);
Andrew Jeffery779e9db2025-02-21 12:14:28 +1030609 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930610
611 // IANA Enterprise ID descriptor data less than length
612 std::array<uint8_t, 7> invalidIANADescriptor2{0x01, 0x00, 0x04, 0x00,
613 0x0a, 0x0b, 0x0c};
614 rc = decode_descriptor_type_length_value(invalidIANADescriptor2.data(),
615 invalidIANADescriptor2.size(),
616 &descriptorType, &descriptorData);
617 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
618}
619
620TEST(DecodeDescriptors, errorPathVendorDefinedDescriptor)
621{
622 int rc = 0;
623 // VendorDefinedDescriptorTitleStringType is invalid
624 constexpr std::array<uint8_t, 9> invalidVendorDescriptor1{
625 0x06, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
626 uint8_t descriptorStringType = 0;
627 variable_field descriptorTitleStr{};
628 variable_field vendorDefinedDescriptorData{};
629
630 rc = decode_vendor_defined_descriptor_value(
631 nullptr, invalidVendorDescriptor1.size(), &descriptorStringType,
632 &descriptorTitleStr, &vendorDefinedDescriptorData);
633 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
634
635 rc = decode_vendor_defined_descriptor_value(
636 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
637 &descriptorStringType, &descriptorTitleStr,
638 &vendorDefinedDescriptorData);
639 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
640
641 rc = decode_vendor_defined_descriptor_value(
642 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
643 nullptr, &descriptorTitleStr, &vendorDefinedDescriptorData);
644 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
645
646 rc = decode_vendor_defined_descriptor_value(
647 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
648 &descriptorStringType, nullptr, &vendorDefinedDescriptorData);
649 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
650
651 rc = decode_vendor_defined_descriptor_value(
652 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
653 &descriptorStringType, &descriptorTitleStr, nullptr);
654 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
655
656 rc = decode_vendor_defined_descriptor_value(
657 invalidVendorDescriptor1.data(),
658 sizeof(pldm_vendor_defined_descriptor_title_data) - 1,
659 &descriptorStringType, &descriptorTitleStr,
660 &vendorDefinedDescriptorData);
661 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
662
663 rc = decode_vendor_defined_descriptor_value(
664 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
665 &descriptorStringType, &descriptorTitleStr,
666 &vendorDefinedDescriptorData);
667 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
668
669 // VendorDefinedDescriptorTitleStringLength is 0
670 std::array<uint8_t, 9> invalidVendorDescriptor2{
671 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
672 rc = decode_vendor_defined_descriptor_value(
673 invalidVendorDescriptor2.data(), invalidVendorDescriptor2.size(),
674 &descriptorStringType, &descriptorTitleStr,
675 &vendorDefinedDescriptorData);
676 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
677
678 // VendorDefinedDescriptorData not present in the data
679 std::array<uint8_t, 9> invalidVendorDescriptor3{
680 0x01, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
681 rc = decode_vendor_defined_descriptor_value(
682 invalidVendorDescriptor3.data(), invalidVendorDescriptor3.size(),
683 &descriptorStringType, &descriptorTitleStr,
684 &vendorDefinedDescriptorData);
685 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
686}
687
688TEST(DecodeComponentImageInfo, goodPath)
689{
690 // Firmware
691 constexpr uint16_t compClassification = 16;
692 constexpr uint16_t compIdentifier = 300;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600693 constexpr uint32_t compComparisonStamp = 0xffffffff;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930694 // Force update
695 constexpr std::bitset<16> compOptions{1};
696 // System reboot[Bit position 3] & Medium-specific reset[Bit position 2]
697 constexpr std::bitset<16> reqCompActivationMethod{0x0c};
698 // Random ComponentLocationOffset
699 constexpr uint32_t compLocOffset = 357;
700 // Random ComponentSize
701 constexpr uint32_t compSize = 27;
702 // ComponentVersionString
703 constexpr std::string_view compVersionStr{"VersionString1"};
704 constexpr size_t compImageInfoSize =
705 sizeof(pldm_component_image_information) + compVersionStr.size();
706
707 constexpr std::array<uint8_t, compImageInfoSize> compImageInfo{
708 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
709 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
710 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
711 pldm_component_image_information outCompImageInfo{};
712 variable_field outCompVersionStr{};
713
714 auto rc =
715 decode_pldm_comp_image_info(compImageInfo.data(), compImageInfo.size(),
716 &outCompImageInfo, &outCompVersionStr);
717
718 EXPECT_EQ(rc, PLDM_SUCCESS);
719 EXPECT_EQ(outCompImageInfo.comp_classification, compClassification);
720 EXPECT_EQ(outCompImageInfo.comp_identifier, compIdentifier);
721 EXPECT_EQ(outCompImageInfo.comp_comparison_stamp, compComparisonStamp);
722 EXPECT_EQ(outCompImageInfo.comp_options.value, compOptions);
723 EXPECT_EQ(outCompImageInfo.requested_comp_activation_method.value,
724 reqCompActivationMethod);
725 EXPECT_EQ(outCompImageInfo.comp_location_offset, compLocOffset);
726 EXPECT_EQ(outCompImageInfo.comp_size, compSize);
727 EXPECT_EQ(outCompImageInfo.comp_version_string_type, PLDM_STR_TYPE_ASCII);
728 EXPECT_EQ(outCompImageInfo.comp_version_string_length,
729 compVersionStr.size());
730
731 EXPECT_EQ(outCompVersionStr.length,
732 outCompImageInfo.comp_version_string_length);
733 std::string componentVersionString(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930734 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930735 reinterpret_cast<const char*>(outCompVersionStr.ptr),
736 outCompVersionStr.length);
737 EXPECT_EQ(componentVersionString, compVersionStr);
738}
739
740TEST(DecodeComponentImageInfo, errorPaths)
741{
742 int rc = 0;
743 // ComponentVersionString
744 constexpr std::string_view compVersionStr{"VersionString1"};
745 constexpr size_t compImageInfoSize =
746 sizeof(pldm_component_image_information) + compVersionStr.size();
747 // Invalid ComponentVersionStringType - 0x06
748 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo1{
749 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
750 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x56, 0x65,
751 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
752 pldm_component_image_information outCompImageInfo{};
753 variable_field outCompVersionStr{};
754
755 rc = decode_pldm_comp_image_info(nullptr, invalidCompImageInfo1.size(),
756 &outCompImageInfo, &outCompVersionStr);
757 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
758
759 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
760 invalidCompImageInfo1.size(), nullptr,
761 &outCompVersionStr);
762 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
763
764 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
765 invalidCompImageInfo1.size(),
766 &outCompImageInfo, nullptr);
767 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
768
769 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
770 sizeof(pldm_component_image_information) -
771 1,
772 &outCompImageInfo, &outCompVersionStr);
773 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
774
775 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
776 invalidCompImageInfo1.size(),
777 &outCompImageInfo, &outCompVersionStr);
778 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
779
780 // Invalid ComponentVersionStringLength - 0x00
781 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo2{
782 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
783 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x65,
784 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
785 rc = decode_pldm_comp_image_info(invalidCompImageInfo2.data(),
786 invalidCompImageInfo2.size(),
787 &outCompImageInfo, &outCompVersionStr);
788 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
789
790 // Use Component Comparison Stamp is not set, but ComponentComparisonStamp
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600791 // is not 0xffffffff
Andrew Jeffery9c766792022-08-10 23:12:49 +0930792 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo3{
793 0x10, 0x00, 0x2c, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00,
794 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
795 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
796
797 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
798 invalidCompImageInfo3.size() - 1,
799 &outCompImageInfo, &outCompVersionStr);
800 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
801
802 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
803 invalidCompImageInfo3.size(),
804 &outCompImageInfo, &outCompVersionStr);
805 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
806
807 // Invalid ComponentLocationOffset - 0
808 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo4{
809 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
810 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
811 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
812 rc = decode_pldm_comp_image_info(invalidCompImageInfo4.data(),
813 invalidCompImageInfo4.size(),
814 &outCompImageInfo, &outCompVersionStr);
815 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
816
817 // Invalid ComponentSize - 0
818 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo5{
819 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
820 0x65, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
821 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
822 rc = decode_pldm_comp_image_info(invalidCompImageInfo5.data(),
823 invalidCompImageInfo5.size(),
824 &outCompImageInfo, &outCompVersionStr);
825 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
826}
827
828TEST(QueryDeviceIdentifiers, goodPathEncodeRequest)
829{
830 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930831 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930832 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
833
834 uint8_t instanceId = 0x01;
835
836 auto rc = encode_query_device_identifiers_req(
837 instanceId, PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES, requestPtr);
838 EXPECT_EQ(rc, PLDM_SUCCESS);
839 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
840 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
841 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
842 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DEVICE_IDENTIFIERS);
843}
844
845TEST(QueryDeviceIdentifiers, goodPathDecodeResponse)
846{
847 // descriptorDataLen is not fixed here taking it as 6
848 constexpr uint8_t descriptorDataLen = 6;
849 std::array<uint8_t, hdrSize +
850 sizeof(struct pldm_query_device_identifiers_resp) +
851 descriptorDataLen>
852 responseMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930853 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930854 auto inResp = reinterpret_cast<struct pldm_query_device_identifiers_resp*>(
855 responseMsg.data() + hdrSize);
856
857 inResp->completion_code = PLDM_SUCCESS;
858 inResp->device_identifiers_len = htole32(descriptorDataLen);
859 inResp->descriptor_count = 1;
860
861 // filling descriptor data
862 std::fill_n(responseMsg.data() + hdrSize +
863 sizeof(struct pldm_query_device_identifiers_resp),
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600864 descriptorDataLen, 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930865
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930866 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930867 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
868 uint8_t completionCode = PLDM_SUCCESS;
869 uint32_t deviceIdentifiersLen = 0;
870 uint8_t descriptorCount = 0;
871 uint8_t* outDescriptorData = nullptr;
872
873 auto rc = decode_query_device_identifiers_resp(
874 response, responseMsg.size() - hdrSize, &completionCode,
875 &deviceIdentifiersLen, &descriptorCount, &outDescriptorData);
876
877 EXPECT_EQ(rc, PLDM_SUCCESS);
878 EXPECT_EQ(completionCode, PLDM_SUCCESS);
879 EXPECT_EQ(deviceIdentifiersLen, inResp->device_identifiers_len);
880 EXPECT_EQ(descriptorCount, inResp->descriptor_count);
881 EXPECT_EQ(true,
882 std::equal(outDescriptorData,
883 outDescriptorData + deviceIdentifiersLen,
884 responseMsg.begin() + hdrSize +
885 sizeof(struct pldm_query_device_identifiers_resp),
886 responseMsg.end()));
887}
888
Matt Johnstoncf9a2df2024-11-07 15:29:29 +0800889#ifdef LIBPLDM_API_TESTING
890TEST(QueryDeviceIdentifiers, goodPathEncodeResponse)
891{
892 int rc;
893 PLDM_MSG_DEFINE_P(enc, 1000);
894 size_t enc_payload_len = 1000;
895 pldm_descriptor check_desc[] = {
896 {
897 .descriptor_type = PLDM_FWUP_IANA_ENTERPRISE_ID,
898 .descriptor_length = 4,
899 .descriptor_data = "a123",
900 },
901 {
902 .descriptor_type = PLDM_FWUP_VENDOR_DEFINED,
903 .descriptor_length = 3,
904 .descriptor_data = "987",
905 },
906 };
907 rc = encode_query_device_identifiers_resp(FIXED_INSTANCE_ID, 2, check_desc,
908 enc, &enc_payload_len);
909 EXPECT_EQ(rc, 0);
910 EXPECT_THAT(std::span<uint8_t>(enc_buf + hdrSize, enc_payload_len),
911 ElementsAreArray<uint8_t>({
912 // completion code
913 0x00,
914 // device identifiers length = 15
915 0x0f,
916 0x00,
917 0x00,
918 0x00,
919 // descriptor count
920 0x02,
921 // desc 0
922 0x01,
923 0x00,
924 0x04,
925 0x00,
926 0x61,
927 0x31,
928 0x32,
929 0x33,
930 // desc 1
931 0xff,
932 0xff,
933 0x03,
934 0x00,
935 0x39,
936 0x38,
937 0x37,
938 }));
939
940 check_response(enc, PLDM_QUERY_DEVICE_IDENTIFIERS);
941}
942#endif
943
Andrew Jeffery9c766792022-08-10 23:12:49 +0930944TEST(GetFirmwareParameters, goodPathEncodeRequest)
945{
946 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930947 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930948 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
949 uint8_t instanceId = 0x01;
950
951 auto rc = encode_get_firmware_parameters_req(
952 instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, requestPtr);
953 EXPECT_EQ(rc, PLDM_SUCCESS);
954 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
955 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
956 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
957 EXPECT_EQ(requestPtr->hdr.command, PLDM_GET_FIRMWARE_PARAMETERS);
958}
959
960TEST(GetFirmwareParameters, decodeResponse)
961{
962 // CapabilitiesDuringUpdate of the firmware device
963 // Firmware device downgrade restrictions [Bit position 8] &
964 // Firmware Device Partial Updates [Bit position 3]
965 constexpr std::bitset<32> fdCapabilities{0x00000104};
966 constexpr uint16_t compCount = 1;
967 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
968 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
969
970 // constexpr uint16_t compClassification = 16;
971 // constexpr uint16_t compIdentifier = 300;
972 // constexpr uint8_t compClassificationIndex = 20;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600973 // constexpr uint32_t activeCompComparisonStamp = 0xabcdefab;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930974 // constexpr std::array<uint8_t, 8> activeComponentReleaseData = {
975 // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
976 // constexpr uint32_t pendingCompComparisonStamp = 0x12345678;
977 // constexpr std::array<uint8_t, 8> pendingComponentReleaseData = {
978 // 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
979 constexpr std::string_view activeCompVersion{"VersionString3"};
980 constexpr std::string_view pendingCompVersion{"VersionString4"};
Andrew Jeffery9c766792022-08-10 23:12:49 +0930981
982 constexpr size_t compParamTableSize =
983 sizeof(pldm_component_parameter_entry) + activeCompVersion.size() +
984 pendingCompVersion.size();
985
986 constexpr std::array<uint8_t, compParamTableSize> compParamTable{
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600987 0x10, 0x00, 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930988 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
989 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00, 0x02,
990 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74,
991 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
992 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
993
994 constexpr size_t getFwParamsPayloadLen =
995 sizeof(pldm_get_firmware_parameters_resp) +
996 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size() +
997 compParamTableSize;
998
999 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1000 getFwParamsResponse{
1001 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01,
1002 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
1003 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
1004 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x10, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001005 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01, 0x02,
Andrew Jeffery9c766792022-08-10 23:12:49 +09301006 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
1007 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00,
1008 0x02, 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1009 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73,
1010 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
1011
1012 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301013 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301014 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1015 pldm_get_firmware_parameters_resp outResp{};
1016 variable_field outActiveCompImageSetVersion{};
1017 variable_field outPendingCompImageSetVersion{};
1018 variable_field outCompParameterTable{};
1019
1020 auto rc = decode_get_firmware_parameters_resp(
1021 responseMsg, getFwParamsPayloadLen, &outResp,
1022 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1023 &outCompParameterTable);
1024
1025 EXPECT_EQ(rc, PLDM_SUCCESS);
1026 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1027 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1028 EXPECT_EQ(outResp.comp_count, compCount);
1029 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1030 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1031 activeCompImageSetVersion.size());
1032 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1033 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1034 pendingCompImageSetVersion.size());
1035 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301036 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301037 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1038 outActiveCompImageSetVersion.length);
1039 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1040 std::string pendingCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301041 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301042 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
1043 outPendingCompImageSetVersion.length);
1044 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1045 EXPECT_EQ(outCompParameterTable.length, compParamTableSize);
1046 EXPECT_EQ(true, std::equal(outCompParameterTable.ptr,
1047 outCompParameterTable.ptr +
1048 outCompParameterTable.length,
1049 compParamTable.begin(), compParamTable.end()));
1050}
1051
1052TEST(GetFirmwareParameters, decodeResponseZeroCompCount)
1053{
1054 // CapabilitiesDuringUpdate of the firmware device
1055 // FD Host Functionality during Firmware Update [Bit position 2] &
1056 // Component Update Failure Retry Capability [Bit position 1]
1057 constexpr std::bitset<32> fdCapabilities{0x06};
1058 constexpr uint16_t compCount = 0;
1059 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
1060 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
1061
1062 constexpr size_t getFwParamsPayloadLen =
1063 sizeof(pldm_get_firmware_parameters_resp) +
1064 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size();
1065
1066 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1067 getFwParamsResponse{
1068 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1069 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
1070 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
1071 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32};
1072
1073 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301074 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301075 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1076 pldm_get_firmware_parameters_resp outResp{};
1077 variable_field outActiveCompImageSetVersion{};
1078 variable_field outPendingCompImageSetVersion{};
1079 variable_field outCompParameterTable{};
1080
1081 auto rc = decode_get_firmware_parameters_resp(
1082 responseMsg, getFwParamsPayloadLen, &outResp,
1083 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1084 &outCompParameterTable);
1085
1086 EXPECT_EQ(rc, PLDM_SUCCESS);
1087 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1088 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1089 EXPECT_EQ(outResp.comp_count, compCount);
1090 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1091 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1092 activeCompImageSetVersion.size());
1093 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1094 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1095 pendingCompImageSetVersion.size());
1096 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301097 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301098 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1099 outActiveCompImageSetVersion.length);
1100 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1101 std::string pendingCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301102 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301103 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
1104 outPendingCompImageSetVersion.length);
1105 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1106 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1107 EXPECT_EQ(outCompParameterTable.length, 0);
1108}
1109
1110TEST(GetFirmwareParameters,
1111 decodeResponseNoPendingCompImageVersionStrZeroCompCount)
1112{
1113 // CapabilitiesDuringUpdate of the firmware device
1114 // FD Host Functionality during Firmware Update [Bit position 2] &
1115 // Component Update Failure Retry Capability [Bit position 1]
1116 constexpr std::bitset<32> fdCapabilities{0x06};
1117 constexpr uint16_t compCount = 0;
1118 constexpr std::string_view activeCompImageSetVersion{"VersionString"};
1119
1120 constexpr size_t getFwParamsPayloadLen =
1121 sizeof(pldm_get_firmware_parameters_resp) +
1122 activeCompImageSetVersion.size();
1123
1124 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1125 getFwParamsResponse{0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1126 0x00, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00,
1127 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1128 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67};
1129
1130 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301131 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301132 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1133 pldm_get_firmware_parameters_resp outResp{};
1134 variable_field outActiveCompImageSetVersion{};
1135 variable_field outPendingCompImageSetVersion{};
1136 variable_field outCompParameterTable{};
1137
1138 auto rc = decode_get_firmware_parameters_resp(
1139 responseMsg, getFwParamsPayloadLen, &outResp,
1140 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1141 &outCompParameterTable);
1142
1143 EXPECT_EQ(rc, PLDM_SUCCESS);
1144 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1145 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1146 EXPECT_EQ(outResp.comp_count, compCount);
1147 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1148 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1149 activeCompImageSetVersion.size());
1150 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type,
1151 PLDM_STR_TYPE_UNKNOWN);
1152 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len, 0);
1153 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301154 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301155 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1156 outActiveCompImageSetVersion.length);
1157 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1158 EXPECT_EQ(outPendingCompImageSetVersion.ptr, nullptr);
1159 EXPECT_EQ(outPendingCompImageSetVersion.length, 0);
1160 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1161 EXPECT_EQ(outCompParameterTable.length, 0);
1162}
1163
1164TEST(GetFirmwareParameters, decodeResponseErrorCompletionCode)
1165{
1166 constexpr std::array<uint8_t, hdrSize + sizeof(uint8_t)>
1167 getFwParamsResponse{0x00, 0x00, 0x00, 0x01};
1168
1169 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301170 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301171 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1172 pldm_get_firmware_parameters_resp outResp{};
1173 variable_field outActiveCompImageSetVersion{};
1174 variable_field outPendingCompImageSetVersion{};
1175 variable_field outCompParameterTable{};
1176
1177 auto rc = decode_get_firmware_parameters_resp(
1178 responseMsg, getFwParamsResponse.size(), &outResp,
1179 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1180 &outCompParameterTable);
1181
1182 EXPECT_EQ(rc, PLDM_SUCCESS);
1183 EXPECT_EQ(outResp.completion_code, PLDM_ERROR);
1184}
1185
1186TEST(GetFirmwareParameters, errorPathdecodeResponse)
1187{
1188 int rc = 0;
1189 // Invalid ActiveComponentImageSetVersionStringType
1190 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse1{
1191 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1192 0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
1193
1194 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301195 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301196 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse1.data());
1197 pldm_get_firmware_parameters_resp outResp{};
1198 variable_field outActiveCompImageSetVersion{};
1199 variable_field outPendingCompImageSetVersion{};
1200 variable_field outCompParameterTable{};
1201
1202 rc = decode_get_firmware_parameters_resp(
1203 nullptr, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1204 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1205 &outCompParameterTable);
1206 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1207
1208 rc = decode_get_firmware_parameters_resp(
1209 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, nullptr,
1210 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1211 &outCompParameterTable);
1212 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1213
1214 rc = decode_get_firmware_parameters_resp(
1215 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1216 nullptr, &outPendingCompImageSetVersion, &outCompParameterTable);
1217 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1218
1219 rc = decode_get_firmware_parameters_resp(
1220 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1221 &outActiveCompImageSetVersion, nullptr, &outCompParameterTable);
1222 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1223
1224 rc = decode_get_firmware_parameters_resp(
1225 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1226 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, nullptr);
1227 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1228
1229 rc = decode_get_firmware_parameters_resp(
1230 responseMsg, 0, &outResp, &outActiveCompImageSetVersion,
1231 &outPendingCompImageSetVersion, &outCompParameterTable);
1232 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1233
1234 rc = decode_get_firmware_parameters_resp(
1235 responseMsg, invalidGetFwParamsResponse1.size() - 1 - hdrSize, &outResp,
1236 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1237 &outCompParameterTable);
1238 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1239
1240 rc = decode_get_firmware_parameters_resp(
1241 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1242 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1243 &outCompParameterTable);
1244 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1245
1246 // Invalid ActiveComponentImageSetVersionStringLength
1247 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse2{
1248 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1249 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
1250 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301251 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301252 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse2.data());
1253 rc = decode_get_firmware_parameters_resp(
1254 responseMsg, invalidGetFwParamsResponse2.size() - hdrSize, &outResp,
1255 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1256 &outCompParameterTable);
1257 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1258
1259 // Invalid PendingComponentImageSetVersionStringType &
1260 // PendingComponentImageSetVersionStringLength
1261 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse3{
1262 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1263 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x00};
1264 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301265 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301266 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse3.data());
1267 rc = decode_get_firmware_parameters_resp(
1268 responseMsg, invalidGetFwParamsResponse3.size() - hdrSize, &outResp,
1269 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1270 &outCompParameterTable);
1271 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1272
1273 // Invalid PendingComponentImageSetVersionStringType &
1274 // PendingComponentImageSetVersionStringLength
1275 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse4{
1276 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1277 0x00, 0x00, 0x00, 0x01, 0x0e, 0x06, 0x0e};
1278 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301279 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301280 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse4.data());
1281 rc = decode_get_firmware_parameters_resp(
1282 responseMsg, invalidGetFwParamsResponse4.size() - hdrSize, &outResp,
1283 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1284 &outCompParameterTable);
1285 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1286
1287 // Total payload length less than expected
1288 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse5{
1289 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1290 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x0e};
1291 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301292 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301293 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse5.data());
1294 rc = decode_get_firmware_parameters_resp(
1295 responseMsg, invalidGetFwParamsResponse5.size() - hdrSize, &outResp,
1296 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1297 &outCompParameterTable);
1298 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1299}
1300
1301TEST(GetFirmwareParameters, goodPathDecodeComponentParameterEntry)
1302{
1303 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001304 constexpr uint16_t compClassification = 0x0a0b;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301305 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001306 constexpr uint16_t compIdentifier = 0x0c0d;
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001307 constexpr uint16_t compClassificationIndex = 0xf;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301308 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001309 constexpr uint32_t timestamp = 0x12345678;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301310 // Random value for component activation methods
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001311 constexpr uint16_t compActivationMethods = 0xbbdd;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301312 // Random value for capabilities during update
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001313 constexpr uint32_t capabilitiesDuringUpdate = 0xbadbeefe;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301314
1315 // ActiveCompImageSetVerStrLen is not fixed here taking it as 8
1316 constexpr uint8_t activeCompVerStrLen = 8;
1317 // PendingCompImageSetVerStrLen is not fixed here taking it as 8
1318 constexpr uint8_t pendingCompVerStrLen = 8;
1319 constexpr size_t entryLength =
1320 sizeof(struct pldm_component_parameter_entry) + activeCompVerStrLen +
1321 pendingCompVerStrLen;
1322 std::array<uint8_t, entryLength> entry{};
1323
1324 auto inEntry =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301325 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301326 reinterpret_cast<struct pldm_component_parameter_entry*>(entry.data());
1327
1328 inEntry->comp_classification = htole16(compClassification);
1329 inEntry->comp_identifier = htole16(compIdentifier);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001330 inEntry->comp_classification_index = compClassificationIndex;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301331 inEntry->active_comp_comparison_stamp = htole32(timestamp);
1332 inEntry->active_comp_ver_str_type = 1;
1333 inEntry->active_comp_ver_str_len = activeCompVerStrLen;
1334 std::fill_n(inEntry->active_comp_release_date,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001335 sizeof(inEntry->active_comp_release_date), 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301336 inEntry->pending_comp_comparison_stamp = htole32(timestamp);
1337 inEntry->pending_comp_ver_str_type = 1;
1338 inEntry->pending_comp_ver_str_len = pendingCompVerStrLen;
1339 std::fill_n(inEntry->pending_comp_release_date,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001340 sizeof(inEntry->pending_comp_release_date), 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301341 inEntry->comp_activation_methods.value = htole16(compActivationMethods);
1342 inEntry->capabilities_during_update.value =
1343 htole32(capabilitiesDuringUpdate);
1344 constexpr auto activeCompVerStrPos =
1345 sizeof(struct pldm_component_parameter_entry);
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001346 std::fill_n(entry.data() + activeCompVerStrPos, activeCompVerStrLen, 0xaa);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301347 constexpr auto pendingCompVerStrPos =
1348 activeCompVerStrPos + activeCompVerStrLen;
1349 std::fill_n(entry.data() + pendingCompVerStrPos, pendingCompVerStrLen,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001350 0xbb);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301351
1352 struct pldm_component_parameter_entry outEntry;
1353 struct variable_field outActiveCompVerStr;
1354 struct variable_field outPendingCompVerStr;
1355
1356 auto rc = decode_get_firmware_parameters_resp_comp_entry(
1357 entry.data(), entryLength, &outEntry, &outActiveCompVerStr,
1358 &outPendingCompVerStr);
1359
1360 EXPECT_EQ(rc, PLDM_SUCCESS);
1361
1362 EXPECT_EQ(outEntry.comp_classification, compClassification);
1363 EXPECT_EQ(outEntry.comp_identifier, compIdentifier);
1364 EXPECT_EQ(inEntry->comp_classification_index,
1365 outEntry.comp_classification_index);
1366 EXPECT_EQ(outEntry.active_comp_comparison_stamp, timestamp);
1367 EXPECT_EQ(inEntry->active_comp_ver_str_type,
1368 outEntry.active_comp_ver_str_type);
1369 EXPECT_EQ(inEntry->active_comp_ver_str_len,
1370 outEntry.active_comp_ver_str_len);
1371 EXPECT_EQ(0, memcmp(inEntry->active_comp_release_date,
1372 outEntry.active_comp_release_date,
1373 sizeof(inEntry->active_comp_release_date)));
1374 EXPECT_EQ(outEntry.pending_comp_comparison_stamp, timestamp);
1375 EXPECT_EQ(inEntry->pending_comp_ver_str_type,
1376 outEntry.pending_comp_ver_str_type);
1377 EXPECT_EQ(inEntry->pending_comp_ver_str_len,
1378 outEntry.pending_comp_ver_str_len);
1379 EXPECT_EQ(0, memcmp(inEntry->pending_comp_release_date,
1380 outEntry.pending_comp_release_date,
1381 sizeof(inEntry->pending_comp_release_date)));
1382 EXPECT_EQ(outEntry.comp_activation_methods.value, compActivationMethods);
1383 EXPECT_EQ(outEntry.capabilities_during_update.value,
1384 capabilitiesDuringUpdate);
1385
1386 EXPECT_EQ(0, memcmp(outActiveCompVerStr.ptr,
1387 entry.data() + activeCompVerStrPos,
1388 outActiveCompVerStr.length));
1389 EXPECT_EQ(0, memcmp(outPendingCompVerStr.ptr,
1390 entry.data() + pendingCompVerStrPos,
1391 outPendingCompVerStr.length));
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001392
1393#ifdef LIBPLDM_API_TESTING
1394 /* Check the roundtrip matches */
1395 std::vector<uint8_t> enc_data(1000);
1396 size_t enc_payload_len = enc_data.size();
1397 struct pldm_component_parameter_entry_full entryFull = {
1398 .comp_classification = compClassification,
1399 .comp_identifier = compIdentifier,
1400 .comp_classification_index = compClassificationIndex,
1401 .active_ver =
1402 {
1403 .comparison_stamp = 0x12345678,
1404 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1405 .str_len = activeCompVerStrLen,
1406 .str_data = {}},
1407 .date = {},
1408 },
1409 .pending_ver =
1410 {
1411 .comparison_stamp = 0x12345678,
1412 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1413 .str_len = pendingCompVerStrLen,
1414 .str_data = {}},
1415 .date = {},
1416 },
1417 .comp_activation_methods = inEntry->comp_activation_methods,
1418 .capabilities_during_update = inEntry->capabilities_during_update,
1419 };
1420 // Fill strings
1421 std::fill_n(entryFull.active_ver.str.str_data, activeCompVerStrLen, 0xaa);
1422 std::fill_n(entryFull.pending_ver.str.str_data, pendingCompVerStrLen, 0xbb);
1423 std::fill_n(entryFull.active_ver.date, PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN,
1424 0xff);
1425 std::fill_n(entryFull.pending_ver.date,
1426 PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN, 0xff);
1427
1428 rc = encode_get_firmware_parameters_resp_comp_entry(
1429 &entryFull, enc_data.data(), &enc_payload_len);
1430 EXPECT_EQ(rc, PLDM_SUCCESS);
1431 EXPECT_EQ(enc_payload_len, entryLength);
1432 EXPECT_TRUE(std::equal(entry.begin(), entry.end(), enc_data.begin()));
1433#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09301434}
1435
Chris Wang4c1f2c72024-03-21 17:09:44 +08001436TEST(QueryDownstreamDevices, goodPathEncodeRequest)
1437{
1438 constexpr uint8_t instanceId = 1;
1439 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301440 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001441 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1442
1443 auto rc = encode_query_downstream_devices_req(instanceId, requestPtr);
1444
Unive Tien71e935c2024-11-25 17:21:43 +08001445 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001446 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1447 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1448 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1449 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DOWNSTREAM_DEVICES);
1450}
1451
1452TEST(QueryDownstreamDevices, encodeRequestInvalidData)
1453{
1454 constexpr uint8_t instanceId = 1;
1455
1456 auto rc = encode_query_downstream_devices_req(instanceId, nullptr);
1457
Unive Tien71e935c2024-11-25 17:21:43 +08001458 EXPECT_EQ(rc, -EINVAL);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001459}
1460
1461TEST(QueryDownstreamDevices, goodPathDecodeResponse)
1462{
1463 uint8_t completion_code_resp = PLDM_SUCCESS;
1464 uint8_t downstream_device_update_supported_resp =
1465 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1466 uint16_t number_of_downstream_devices_resp = 1;
1467 uint16_t max_number_of_downstream_devices_resp = 1;
1468 /** Capabilities of updating downstream devices
1469 * FDP supports downstream devices dynamically attached [Bit position 0] &
1470 * FDP supports downstream devices dynamically removed [Bit position 1]
1471 */
1472 bitfield32_t capabilities_resp = {.value = 0x0002};
1473 int rc;
1474
1475 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1476 responseMsg{};
1477
Andrew Jefferya1896962025-03-03 21:41:25 +10301478 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301479 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1480 responseMsg.size() - hdrSize);
1481 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001482
1483 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1484 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1485 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1486 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1487 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301488 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001489
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301490 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001491 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1492 struct pldm_query_downstream_devices_resp resp_data;
1493
1494 rc = decode_query_downstream_devices_resp(
1495 response, responseMsg.size() - hdrSize, &resp_data);
1496
Unive Tien71e935c2024-11-25 17:21:43 +08001497 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001498 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1499 EXPECT_EQ(resp_data.downstream_device_update_supported,
1500 downstream_device_update_supported_resp);
1501 EXPECT_EQ(resp_data.number_of_downstream_devices,
1502 number_of_downstream_devices_resp);
1503 EXPECT_EQ(resp_data.max_number_of_downstream_devices,
1504 max_number_of_downstream_devices_resp);
1505 EXPECT_EQ(resp_data.capabilities.value, capabilities_resp.value);
1506}
1507
1508TEST(QueryDownstreamDevices, decodeRequestUndefinedValue)
1509{
1510 uint8_t completion_code_resp = PLDM_SUCCESS;
1511 uint8_t downstream_device_update_supported_resp = 0xe; /*Undefined value*/
1512 uint16_t number_of_downstream_devices_resp = 1;
1513 uint16_t max_number_of_downstream_devices_resp = 1;
1514 /** Capabilities of updating downstream devices
1515 * FDP supports downstream devices dynamically attached [Bit position 0] &
1516 * FDP supports downstream devices dynamically removed [Bit position 1]
1517 */
1518 bitfield32_t capabilities_resp = {.value = 0x0002};
1519 int rc;
1520
1521 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1522 responseMsg{};
1523
Andrew Jefferya1896962025-03-03 21:41:25 +10301524 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301525 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1526 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10301527 ASSERT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001528 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1529 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1530 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1531 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1532 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301533 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001534
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301535 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001536 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1537 struct pldm_query_downstream_devices_resp resp_data;
1538
1539 rc = decode_query_downstream_devices_resp(
1540 response, responseMsg.size() - hdrSize, &resp_data);
1541
Unive Tien71e935c2024-11-25 17:21:43 +08001542 ASSERT_EQ(rc, -EINVAL);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001543}
1544
1545TEST(QueryDownstreamDevices, decodeRequestErrorBufSize)
1546{
1547 uint8_t completion_code_resp = PLDM_SUCCESS;
1548 uint8_t downstream_device_update_supported_resp =
1549 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1550 uint16_t number_of_downstream_devices_resp = 1;
1551 uint16_t max_number_of_downstream_devices_resp = 1;
1552 /** Capabilities of updating downstream devices
1553 * FDP supports downstream devices dynamically attached [Bit position 0] &
1554 * FDP supports downstream devices dynamically removed [Bit position 1]
1555 */
1556 bitfield32_t capabilities_resp = {.value = 0x0002};
1557 int rc;
1558
1559 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES -
1560 2 /* Inject error length*/>
1561 responseMsg{};
1562
Andrew Jefferya1896962025-03-03 21:41:25 +10301563 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301564 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1565 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10301566 ASSERT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001567
1568 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1569 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1570 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1571 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1572 // Inject error value
1573 pldm_msgbuf_insert_uint16(buf, (uint16_t)capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301574 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001575
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301576 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001577 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1578 struct pldm_query_downstream_devices_resp resp_data;
1579
1580 rc = decode_query_downstream_devices_resp(
1581 response, responseMsg.size() - hdrSize, &resp_data);
1582
Unive Tien71e935c2024-11-25 17:21:43 +08001583 EXPECT_EQ(rc, -EBADMSG);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001584}
1585
Chris Wang458475a2024-03-26 17:59:19 +08001586TEST(QueryDownstreamIdentifiers, goodPathEncodeRequest)
1587{
1588 constexpr uint8_t instanceId = 1;
Andrew Jefferydec237b2024-11-08 14:33:45 +10301589 constexpr size_t payloadLen = PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1590 PLDM_MSG_DEFINE_P(request, payloadLen);
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001591 constexpr pldm_query_downstream_identifiers_req params_req{
1592 0xFFFFFFFF, PLDM_GET_FIRSTPART};
Chris Wang458475a2024-03-26 17:59:19 +08001593
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001594 auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1595 request, payloadLen);
Unive Tien71e935c2024-11-25 17:21:43 +08001596 ASSERT_EQ(rc, 0);
Andrew Jefferydec237b2024-11-08 14:33:45 +10301597 EXPECT_THAT(std::span<uint8_t>(request_buf, sizeof(request_buf)),
1598 ElementsAreArray<uint8_t>(
1599 {0x81, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x01}));
Chris Wang458475a2024-03-26 17:59:19 +08001600}
1601
1602TEST(QueryDownstreamIdentifiers, encodeRequestInvalidErrorPaths)
1603{
1604 constexpr uint8_t instanceId = 1;
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001605 constexpr pldm_query_downstream_identifiers_req params_req{
1606 0xFFFFFFFF, PLDM_GET_FIRSTPART};
1607 constexpr pldm_query_downstream_identifiers_req params_req_invalid{
1608 0xFFFFFFFF, PLDM_ACKNOWLEDGEMENT_ONLY};
Chris Wang458475a2024-03-26 17:59:19 +08001609 constexpr size_t payload_length =
1610 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1611 std::array<uint8_t, hdrSize + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301612 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang458475a2024-03-26 17:59:19 +08001613 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1614
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001615 auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1616 nullptr, payload_length);
Unive Tien71e935c2024-11-25 17:21:43 +08001617 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08001618
1619 rc = encode_query_downstream_identifiers_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001620 instanceId, &params_req, requestPtr, payload_length - 1);
Unive Tien71e935c2024-11-25 17:21:43 +08001621 EXPECT_EQ(rc, -EOVERFLOW);
Chris Wang458475a2024-03-26 17:59:19 +08001622
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001623 rc = encode_query_downstream_identifiers_req(
1624 instanceId, &params_req_invalid, requestPtr, payload_length);
Unive Tien71e935c2024-11-25 17:21:43 +08001625 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08001626}
1627
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301628TEST(QueryDownstreamIdentifiers, decodeResponseNoDevices)
Chris Wang458475a2024-03-26 17:59:19 +08001629{
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301630 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1631 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1632 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1633 constexpr uint32_t downstream_devices_length_resp = 0;
1634 constexpr uint16_t number_of_downstream_devices_resp = 0;
1635
1636 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1637 struct pldm_query_downstream_identifiers_resp resp_data = {};
1638 struct pldm_downstream_device_iter devs;
Andrew Jefferya1896962025-03-03 21:41:25 +10301639 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301640 int rc = 0;
1641
1642 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1643 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1644 ASSERT_EQ(rc, 0);
1645
1646 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1647 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1648 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1649 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1650 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1651
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301652 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301653
1654 rc = decode_query_downstream_identifiers_resp(
1655 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp_data,
1656 &devs);
1657
Unive Tien71e935c2024-11-25 17:21:43 +08001658 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301659 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1660 EXPECT_EQ(resp_data.next_data_transfer_handle,
1661 next_data_transfer_handle_resp);
1662 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1663 EXPECT_EQ(resp_data.downstream_devices_length,
1664 downstream_devices_length_resp);
1665 EXPECT_EQ(resp_data.number_of_downstream_devices,
1666 number_of_downstream_devices_resp);
1667}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301668
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301669TEST(QueryDownstreamIdentifiers, decodeResponseNoDevicesBadCount)
1670{
1671 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1672 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1673 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1674 constexpr uint32_t downstream_devices_length_resp = 0;
1675 constexpr uint16_t number_of_downstream_devices_resp = 1;
1676
1677 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1678 struct pldm_query_downstream_identifiers_resp resp = {};
1679 struct pldm_downstream_device_iter devs;
1680 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301681 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301682 int rc = 0;
1683
1684 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1685 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1686 ASSERT_EQ(rc, 0);
1687
1688 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1689 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1690 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1691 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1692 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1693
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301694 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301695
1696 rc = decode_query_downstream_identifiers_resp(
1697 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08001698 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301699
1700 foreach_pldm_downstream_device(devs, dev, rc)
1701 {
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10301702 FAIL();
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301703 }
1704 ASSERT_NE(rc, 0);
1705}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301706
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301707TEST(QueryDownstreamIdentifiers, decodeResponseOneDeviceOneDescriptor)
1708{
1709 constexpr uint32_t downstreamDevicesLen = 11;
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301710 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
Chris Wang458475a2024-03-26 17:59:19 +08001711 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1712 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1713 const uint32_t downstream_devices_length_resp =
1714 htole32(downstreamDevicesLen);
1715 constexpr uint16_t number_of_downstream_devices_resp = 1;
Andrew Jefferydec237b2024-11-08 14:33:45 +10301716 constexpr size_t payloadLen =
1717 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstreamDevicesLen;
Chris Wang458475a2024-03-26 17:59:19 +08001718
Andrew Jefferydec237b2024-11-08 14:33:45 +10301719 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jefferydec237b2024-11-08 14:33:45 +10301720 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301721 struct pldm_downstream_device_iter devs;
1722 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301723 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10301724 int rc = 0;
1725
1726 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1727 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08001728
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301729 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
Chris Wang458475a2024-03-26 17:59:19 +08001730 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1731 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1732 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1733 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1734
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301735 /* Downstream device */
1736 pldm_msgbuf_insert_uint16(buf, 1);
1737 pldm_msgbuf_insert_uint8(buf, 1);
Chris Wang458475a2024-03-26 17:59:19 +08001738
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301739 /* Device descriptor */
1740 pldm_msgbuf_insert_uint16(buf, 1);
1741 pldm_msgbuf_insert_uint16(buf, 4);
1742 pldm_msgbuf_insert_uint32(buf, 412);
Chris Wang458475a2024-03-26 17:59:19 +08001743
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301744 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301745
1746 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1747 &resp_data, &devs);
1748
Unive Tien71e935c2024-11-25 17:21:43 +08001749 ASSERT_EQ(rc, 0);
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301750 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
Chris Wang458475a2024-03-26 17:59:19 +08001751 EXPECT_EQ(resp_data.next_data_transfer_handle,
1752 next_data_transfer_handle_resp);
1753 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1754 EXPECT_EQ(resp_data.downstream_devices_length,
1755 downstream_devices_length_resp);
1756 EXPECT_EQ(resp_data.number_of_downstream_devices,
1757 number_of_downstream_devices_resp);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301758
1759 foreach_pldm_downstream_device(devs, dev, rc)
1760 {
1761 struct pldm_descriptor desc;
1762
1763 EXPECT_EQ(dev.downstream_device_index, 1);
1764 EXPECT_EQ(dev.downstream_descriptor_count, 1);
1765
1766 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1767 {
1768 static const uint32_t dmtf = htole32(412);
1769 EXPECT_EQ(desc.descriptor_type, 1);
1770 EXPECT_EQ(desc.descriptor_length, 4);
1771 EXPECT_EQ(memcmp(desc.descriptor_data, &dmtf, sizeof(dmtf)), 0);
1772 }
1773 ASSERT_EQ(rc, 0);
1774 }
1775 ASSERT_EQ(rc, 0);
1776}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301777
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301778constexpr const uint16_t descriptor_id_type_iana_pen = 0x1;
1779constexpr const uint16_t descriptor_id_len_iana_pen = 0x4;
1780const uint32_t iana_pen_openbmc = htole16(49871u);
1781const uint32_t iana_pen_dmtf = htole16(412u);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301782
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301783TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneDescriptorEach)
1784{
1785 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1786 {0, 1},
1787 {1, 1},
1788 }};
1789
1790 constexpr const std::array<pldm_descriptor, 2> expected_descriptors = {{
1791 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1792 &iana_pen_dmtf},
1793 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1794 &iana_pen_openbmc},
1795 }};
1796
1797 constexpr uint32_t downstream_devices_len = 22;
1798 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1799 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1800 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1801 const uint32_t downstream_devices_length_resp =
1802 htole32(downstream_devices_len);
1803 constexpr uint16_t number_of_downstream_devices_resp = 2;
1804 constexpr size_t payloadLen =
1805 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
1806
Patrick Williamsf37edd72024-12-18 11:22:58 -05001807 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301808 PLDM_MSG_DEFINE_P(response, payloadLen);
1809 struct pldm_downstream_device_iter devs;
1810 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301811 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301812 int rc = 0;
1813
1814 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1815 ASSERT_EQ(rc, 0);
1816
1817 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1818 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1819 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1820 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1821 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1822
1823 /* Downstream device */
1824 pldm_msgbuf_insert_uint16(buf, 0);
1825 pldm_msgbuf_insert_uint8(buf, 1);
1826
1827 /* Device descriptor */
1828 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1829 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1830 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1831
1832 /* Downstream device */
1833 pldm_msgbuf_insert_uint16(buf, 1);
1834 pldm_msgbuf_insert_uint8(buf, 1);
1835
1836 /* Device descriptor */
1837 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1838 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1839 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
1840
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301841 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301842
1843 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1844 &resp_data, &devs);
1845
Unive Tien71e935c2024-11-25 17:21:43 +08001846 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301847 EXPECT_EQ(resp_data.number_of_downstream_devices,
1848 number_of_downstream_devices_resp);
1849
1850 size_t devIndex = 0;
1851 size_t descIndex = 0;
1852 foreach_pldm_downstream_device(devs, dev, rc)
1853 {
1854 struct pldm_descriptor desc;
1855
1856 ASSERT_LT(devIndex, expected_devices.size());
1857
1858 const struct pldm_downstream_device* expectedDev =
1859 &expected_devices[devIndex];
1860
1861 EXPECT_EQ(dev.downstream_device_index,
1862 expectedDev->downstream_device_index);
1863 EXPECT_EQ(dev.downstream_descriptor_count,
1864 expectedDev->downstream_descriptor_count);
1865
1866 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1867 {
1868 ASSERT_LT(descIndex, expected_descriptors.size());
1869
1870 const struct pldm_descriptor* expectedDesc =
1871 &expected_descriptors[descIndex];
1872
1873 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
1874 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
1875 EXPECT_EQ(memcmp(desc.descriptor_data,
1876 expectedDesc->descriptor_data,
1877 expectedDesc->descriptor_length),
1878 0);
1879
1880 descIndex++;
1881 }
1882 ASSERT_EQ(rc, 0);
1883 EXPECT_EQ(descIndex, 1 * devIndex + 1);
1884
1885 devIndex++;
1886 }
1887 ASSERT_EQ(rc, 0);
1888 EXPECT_EQ(devIndex, 2);
1889}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301890
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301891TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesTwoOneDescriptors)
1892{
1893 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1894 {0, 2},
1895 {1, 1},
1896 }};
1897
1898 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
1899 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1900 &iana_pen_dmtf},
1901 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1902 &iana_pen_openbmc},
1903 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1904 &iana_pen_dmtf},
1905 }};
1906
1907 constexpr uint32_t downstream_devices_len = 30;
1908 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1909 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1910 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1911 const uint32_t downstream_devices_length_resp =
1912 htole32(downstream_devices_len);
1913 constexpr uint16_t number_of_downstream_devices_resp = 2;
1914 constexpr size_t payloadLen =
1915 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
1916
Patrick Williamsf37edd72024-12-18 11:22:58 -05001917 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301918 PLDM_MSG_DEFINE_P(response, payloadLen);
1919 struct pldm_downstream_device_iter devs;
1920 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301921 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301922 int rc = 0;
1923
1924 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1925 ASSERT_EQ(rc, 0);
1926
1927 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1928 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1929 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1930 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1931 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1932
1933 /* Downstream device */
1934 pldm_msgbuf_insert_uint16(buf, 0);
1935 pldm_msgbuf_insert_uint8(buf, 2);
1936
1937 /* Device descriptor */
1938 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1939 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1940 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1941
1942 /* Device descriptor */
1943 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1944 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1945 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
1946
1947 /* Downstream device */
1948 pldm_msgbuf_insert_uint16(buf, 1);
1949 pldm_msgbuf_insert_uint8(buf, 1);
1950
1951 /* Device descriptor */
1952 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1953 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1954 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1955
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301956 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301957
1958 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1959 &resp_data, &devs);
1960
Unive Tien71e935c2024-11-25 17:21:43 +08001961 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301962 EXPECT_EQ(resp_data.number_of_downstream_devices,
1963 number_of_downstream_devices_resp);
1964
1965 size_t devIndex = 0;
1966 size_t descIndex = 0;
1967 foreach_pldm_downstream_device(devs, dev, rc)
1968 {
1969 struct pldm_descriptor desc;
1970
1971 ASSERT_LT(devIndex, expected_devices.size());
1972
1973 const struct pldm_downstream_device* expectedDev =
1974 &expected_devices[devIndex];
1975
1976 EXPECT_EQ(dev.downstream_device_index,
1977 expectedDev->downstream_device_index);
1978 EXPECT_EQ(dev.downstream_descriptor_count,
1979 expectedDev->downstream_descriptor_count);
1980
1981 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1982 {
1983 ASSERT_LT(descIndex, expected_descriptors.size());
1984
1985 const struct pldm_descriptor* expectedDesc =
1986 &expected_descriptors[descIndex];
1987
1988 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
1989 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
1990 EXPECT_EQ(memcmp(desc.descriptor_data,
1991 expectedDesc->descriptor_data,
1992 expectedDesc->descriptor_length),
1993 0);
1994
1995 descIndex++;
1996 }
1997 ASSERT_EQ(rc, 0);
1998
1999 devIndex++;
2000 }
2001 ASSERT_EQ(rc, 0);
2002 EXPECT_EQ(devIndex, 2);
2003 EXPECT_EQ(descIndex, 3);
2004}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302005
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302006TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneTwoDescriptors)
2007{
2008 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
2009 {0, 1},
2010 {1, 2},
2011 }};
2012
2013 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
2014 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2015 &iana_pen_dmtf},
2016 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2017 &iana_pen_openbmc},
2018 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2019 &iana_pen_dmtf},
2020 }};
2021
2022 constexpr uint32_t downstream_devices_len = 30;
2023 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2024 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2025 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2026 const uint32_t downstream_devices_length_resp =
2027 htole32(downstream_devices_len);
2028 constexpr uint16_t number_of_downstream_devices_resp = 2;
2029 constexpr size_t payloadLen =
2030 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2031
Patrick Williamsf37edd72024-12-18 11:22:58 -05002032 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302033 PLDM_MSG_DEFINE_P(response, payloadLen);
2034 struct pldm_downstream_device_iter devs;
2035 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10302036 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302037 int rc = 0;
2038
2039 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2040 ASSERT_EQ(rc, 0);
2041
2042 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2043 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2044 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2045 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2046 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2047
2048 /* Downstream device */
2049 pldm_msgbuf_insert_uint16(buf, 0);
2050 pldm_msgbuf_insert_uint8(buf, 1);
2051
2052 /* Device descriptor */
2053 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2054 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2055 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2056
2057 /* Downstream device */
2058 pldm_msgbuf_insert_uint16(buf, 1);
2059 pldm_msgbuf_insert_uint8(buf, 2);
2060
2061 /* Device descriptor */
2062 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2063 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2064 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2065
2066 /* Device descriptor */
2067 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2068 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2069 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2070
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302071 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302072
2073 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2074 &resp_data, &devs);
2075
Unive Tien71e935c2024-11-25 17:21:43 +08002076 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302077 EXPECT_EQ(resp_data.number_of_downstream_devices,
2078 number_of_downstream_devices_resp);
2079
2080 size_t devIndex = 0;
2081 size_t descIndex = 0;
2082 foreach_pldm_downstream_device(devs, dev, rc)
2083 {
2084 struct pldm_descriptor desc;
2085
2086 ASSERT_LT(devIndex, expected_devices.size());
2087
2088 const struct pldm_downstream_device* expectedDev =
2089 &expected_devices[devIndex];
2090
2091 EXPECT_EQ(dev.downstream_device_index,
2092 expectedDev->downstream_device_index);
2093 EXPECT_EQ(dev.downstream_descriptor_count,
2094 expectedDev->downstream_descriptor_count);
2095
2096 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2097 {
2098 ASSERT_LT(descIndex, expected_descriptors.size());
2099
2100 const struct pldm_descriptor* expectedDesc =
2101 &expected_descriptors[descIndex];
2102
2103 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2104 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2105 EXPECT_EQ(memcmp(desc.descriptor_data,
2106 expectedDesc->descriptor_data,
2107 expectedDesc->descriptor_length),
2108 0);
2109
2110 descIndex++;
2111 }
2112 ASSERT_EQ(rc, 0);
2113
2114 devIndex++;
2115 }
2116 ASSERT_EQ(rc, 0);
2117 EXPECT_EQ(devIndex, 2);
2118 EXPECT_EQ(descIndex, 3);
Chris Wang458475a2024-03-26 17:59:19 +08002119}
2120
2121TEST(QueryDownstreamIdentifiers, decodeRequestErrorPaths)
2122{
Andrew Jefferydec237b2024-11-08 14:33:45 +10302123 constexpr size_t payloadLen = sizeof(uint8_t);
2124
Chris Wang458475a2024-03-26 17:59:19 +08002125 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302126 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302127 PLDM_MSG_DEFINE_P(response, payloadLen);
Chris Wang458475a2024-03-26 17:59:19 +08002128
2129 // Test nullptr
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302130 auto rc = decode_query_downstream_identifiers_resp(nullptr, payloadLen,
2131 nullptr, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08002132 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08002133
2134 // Test not PLDM_SUCCESS completion code
2135 response->payload[0] = PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302136 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2137 &resp_data, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08002138 EXPECT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002139 EXPECT_EQ(resp_data.completion_code, PLDM_ERROR_UNSUPPORTED_PLDM_CMD);
2140
2141 // Test payload length less than minimum length
2142 response->payload[0] = PLDM_SUCCESS;
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302143 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2144 &resp_data, &devs);
Chris Wang458475a2024-03-26 17:59:19 +08002145
Unive Tien71e935c2024-11-25 17:21:43 +08002146 EXPECT_EQ(rc, -EBADMSG);
Chris Wang458475a2024-03-26 17:59:19 +08002147}
2148
2149TEST(QueryDownstreamIdentifiers, decodeRequestErrorDownstreamDevicesSize)
2150{
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +05302151 // Len is not fixed here taking it as 9, contains 1 downstream device with
Chris Wang458475a2024-03-26 17:59:19 +08002152 // 1 descriptor
2153 constexpr uint32_t actualDownstreamDevicesLen = 9;
2154 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2155 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2156 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302157 constexpr uint16_t number_of_downstream_devices_resp = 1;
2158 constexpr size_t payloadLen =
2159 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN +
2160 actualDownstreamDevicesLen;
2161
Chris Wang458475a2024-03-26 17:59:19 +08002162 const uint32_t downstream_devices_length_resp =
2163 htole32(actualDownstreamDevicesLen + 1 /* inject error length*/);
Chris Wang458475a2024-03-26 17:59:19 +08002164
Andrew Jefferydec237b2024-11-08 14:33:45 +10302165 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302166 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302167 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302168 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302169 void* devicesStart = NULL;
2170 size_t devicesLen;
2171 int rc = 0;
2172
2173 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302174 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002175
2176 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2177 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2178 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2179 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2180 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302181 pldm_msgbuf_span_remaining(buf, &devicesStart, &devicesLen);
Chris Wang458475a2024-03-26 17:59:19 +08002182
Andrew Jefferya1896962025-03-03 21:41:25 +10302183 ASSERT_EQ(0, pldm_msgbuf_complete(buf));
2184
Chris Wang458475a2024-03-26 17:59:19 +08002185 /** Filling descriptor data, the correctness of the downstream devices data
2186 * is not checked in this test case so filling with 0xff
2187 */
Andrew Jefferydec237b2024-11-08 14:33:45 +10302188 std::fill_n(static_cast<uint8_t*>(devicesStart), actualDownstreamDevicesLen,
2189 0xff);
Chris Wang458475a2024-03-26 17:59:19 +08002190
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302191 EXPECT_NE(decode_query_downstream_identifiers_resp(response, payloadLen,
2192 &resp_data, &devs),
Unive Tien71e935c2024-11-25 17:21:43 +08002193 0);
Chris Wang458475a2024-03-26 17:59:19 +08002194}
2195
2196TEST(QueryDownstreamIdentifiers, decodeRequestErrorBufSize)
2197{
2198 constexpr uint32_t actualDownstreamDevicesLen = 0;
2199 constexpr uint16_t number_of_downstream_devices_resp = 1;
2200 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2201 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2202 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302203 constexpr size_t payloadLen =
2204 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN - 1;
2205
Chris Wang458475a2024-03-26 17:59:19 +08002206 const uint32_t downstream_devices_length_resp =
2207 htole32(actualDownstreamDevicesLen);
2208
Andrew Jefferydec237b2024-11-08 14:33:45 +10302209 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302210 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302211 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302212 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302213 int rc = 0;
2214
2215 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2216 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002217
2218 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2219 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2220 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2221 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2222 // Inject error buffer size
2223 pldm_msgbuf_insert_uint8(buf, (uint8_t)number_of_downstream_devices_resp);
Andrew Jefferya1896962025-03-03 21:41:25 +10302224 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang458475a2024-03-26 17:59:19 +08002225
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302226 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2227 &resp_data, &devs);
Chris Wang458475a2024-03-26 17:59:19 +08002228
Unive Tien71e935c2024-11-25 17:21:43 +08002229 EXPECT_EQ(rc, -EBADMSG);
Chris Wang458475a2024-03-26 17:59:19 +08002230}
2231
Chris Wangb6ef35b2024-07-03 09:35:42 +08002232TEST(GetDownstreamFirmwareParameters, goodPathEncodeRequest)
2233{
2234 constexpr uint8_t instanceId = 1;
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302235 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002236 0x0, PLDM_GET_FIRSTPART};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002237 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302238 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002239 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302240 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002241 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2242
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302243 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002244 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002245 EXPECT_EQ(rc, 0);
2246
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302247 std::array<uint8_t,
2248 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES>
Chris Wangb6ef35b2024-07-03 09:35:42 +08002249 expectedReq{0x81, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01};
2250 EXPECT_EQ(requestMsg, expectedReq);
2251}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002252
Chris Wangb6ef35b2024-07-03 09:35:42 +08002253TEST(GetDownstreamFirmwareParameters, encodeRequestInvalidTransferOperationFlag)
2254{
2255 constexpr uint8_t instanceId = 1;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002256 // Setup invalid transfer operation flag
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302257 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002258 0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002259 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302260 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002261 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302262 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002263 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2264
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302265 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002266 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002267 EXPECT_EQ(rc, -EBADMSG);
2268}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002269
Chris Wangb6ef35b2024-07-03 09:35:42 +08002270TEST(GetDownstreamFirmwareParameters, encodeRequestErrorBufSize)
2271{
2272 constexpr uint8_t instanceId = 1;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002273 // Setup invalid transfer operation flag
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302274 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Andrew Jeffery53b08672025-03-04 12:26:18 +10302275 0x0, PLDM_GET_FIRSTPART};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002276 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302277 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES -
Chris Wangb6ef35b2024-07-03 09:35:42 +08002278 1 /* inject erro length*/;
2279
2280 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302281 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002282 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2283
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302284 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002285 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002286 EXPECT_EQ(rc, -EOVERFLOW);
2287}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002288
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302289TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseOneEntry)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002290{
Chris Wangb6ef35b2024-07-03 09:35:42 +08002291 constexpr uint16_t downstreamDeviceCount = 1;
2292 constexpr uint8_t activeComponentVersionStringLength = 8;
2293 constexpr uint8_t pendingComponentVersionStringLength = 8;
2294 constexpr size_t downstreamDeviceParamTableLen =
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302295 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002296 activeComponentVersionStringLength +
2297 pendingComponentVersionStringLength;
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302298 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002299 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2300 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2301 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302302 constexpr size_t payload_len =
2303 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2304 downstreamDeviceParamTableLen;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002305
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302306 PLDM_MSG_DEFINE_P(response, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302307 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302308 int rc = 0;
2309
2310 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302311 ASSERT_EQ(rc, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002312
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302313 // Table 24
2314 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002315 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2316 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302317
2318 // Table 25
Chris Wangb6ef35b2024-07-03 09:35:42 +08002319 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2320 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2321
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302322 // Table 26
2323 pldm_msgbuf_insert_uint16(buf, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002324
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302325 // - Active metadata
2326 pldm_msgbuf_insert_uint32(buf, 0);
2327 pldm_msgbuf_insert_uint8(buf, 1);
2328 pldm_msgbuf_insert_uint8(buf, activeComponentVersionStringLength);
2329 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2330 ASSERT_EQ(rc, 0);
2331
2332 // - Pending metadata
2333 pldm_msgbuf_insert_uint32(buf, 0);
2334 pldm_msgbuf_insert_uint8(buf, 1);
2335 pldm_msgbuf_insert_uint8(buf, pendingComponentVersionStringLength);
2336 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2337 ASSERT_EQ(rc, 0);
2338
2339 // - Methods and capabilities
2340 pldm_msgbuf_insert_uint16(buf, 1);
2341 pldm_msgbuf_insert_uint32(buf, 0);
2342
2343 // - Version strings
2344 rc = pldm__msgbuf_insert_array_void(buf, activeComponentVersionStringLength,
2345 "abcdefgh", 8);
2346 ASSERT_EQ(rc, 0);
2347 rc = pldm__msgbuf_insert_array_void(
2348 buf, pendingComponentVersionStringLength, "zyxwvuts", 8);
2349 ASSERT_EQ(rc, 0);
2350
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302351 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302352 ASSERT_EQ(rc, 0);
2353
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302354 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302355 struct pldm_downstream_device_parameters_iter iter = {};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002356
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302357 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2358 &resp_data, &iter);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002359
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302360 ASSERT_EQ(rc, 0);
2361 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002362 EXPECT_EQ(resp_data.next_data_transfer_handle,
2363 next_data_transfer_handle_resp);
2364 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2365 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302366
2367 struct pldm_downstream_device_parameters_entry entry;
2368 size_t entries = 0;
2369 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2370 {
2371 EXPECT_EQ(entry.downstream_device_index, 0);
2372 EXPECT_EQ(entry.active_comp_comparison_stamp, 0);
2373 EXPECT_EQ(entry.active_comp_ver_str_type, 1);
2374 EXPECT_EQ(entry.active_comp_ver_str_len,
2375 activeComponentVersionStringLength);
2376 EXPECT_STREQ("20241206", entry.active_comp_release_date);
2377 EXPECT_EQ(entry.pending_comp_comparison_stamp, 0);
2378 EXPECT_EQ(entry.pending_comp_ver_str_type, 1);
2379 EXPECT_EQ(entry.pending_comp_ver_str_len,
2380 pendingComponentVersionStringLength);
2381 EXPECT_STREQ("20241206", entry.pending_comp_release_date);
2382 EXPECT_EQ(entry.comp_activation_methods.value, 1);
2383 EXPECT_EQ(entry.capabilities_during_update.value, 0);
2384 EXPECT_FALSE(memcmp("abcdefgh", entry.active_comp_ver_str,
2385 entry.active_comp_ver_str_len));
2386 EXPECT_FALSE(memcmp("zyxwvuts", entry.pending_comp_ver_str,
2387 entry.pending_comp_ver_str_len));
2388 entries++;
2389 }
2390 EXPECT_EQ(rc, 0);
2391 EXPECT_EQ(entries, 1);
2392}
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302393
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302394TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseTwoEntries)
2395{
2396 /** Count is not fixed here taking it as 1, and the downstream device's
2397 * version strings length are set to 8
2398 */
2399 constexpr uint16_t downstreamDeviceCount = 2;
2400 constexpr uint8_t activeComponentVersionStringLength = 8;
2401 constexpr uint8_t pendingComponentVersionStringLength = 9;
2402 constexpr size_t downstreamDeviceParamTableLen =
2403 static_cast<size_t>(downstreamDeviceCount *
2404 (PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2405 activeComponentVersionStringLength +
2406 pendingComponentVersionStringLength));
2407 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2408 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2409 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2410 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2411 constexpr size_t payload_len =
2412 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2413 downstreamDeviceParamTableLen;
2414
2415 PLDM_MSG_DEFINE_P(response, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302416 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302417 int rc = 0;
2418
2419 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302420 ASSERT_EQ(rc, 0);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302421
2422 // Table 24
2423 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2424 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2425 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2426
2427 // Table 25
2428 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2429 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2430
2431 constexpr const std::array<pldm_downstream_device_parameters_entry, 2>
2432 table = {{{
2433 0,
2434 0,
2435 1,
2436 8,
2437 "20241206",
2438 0,
2439 1,
2440 9,
2441 "20241209",
2442 {1},
2443 {0},
2444 "active_0",
2445 "pending_0",
2446 },
2447 {
2448 1,
2449 0,
2450 1,
2451 8,
2452 "20241209",
2453 0,
2454 1,
2455 9,
2456 "20241206",
2457 {1},
2458 {0},
2459 "active_1",
2460 "pending_1",
2461 }}};
2462 for (const auto& e : table)
2463 {
2464 // Table 26
2465 pldm_msgbuf_insert_uint16(buf, e.downstream_device_index);
2466
2467 // - Active metadata
2468 pldm_msgbuf_insert_uint32(buf, e.active_comp_comparison_stamp);
2469 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_type);
2470 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_len);
2471 rc = pldm__msgbuf_insert_array_void(buf, 8, &e.active_comp_release_date,
2472 sizeof(e.active_comp_release_date));
2473 ASSERT_EQ(rc, 0);
2474
2475 // - Pending metadata
2476 pldm_msgbuf_insert_uint32(buf, e.pending_comp_comparison_stamp);
2477 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_type);
2478 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_len);
2479 rc =
2480 pldm__msgbuf_insert_array_void(buf, 8, e.pending_comp_release_date,
2481 sizeof(e.pending_comp_release_date));
2482 ASSERT_EQ(rc, 0);
2483
2484 // - Methods and capabilities
2485 pldm_msgbuf_insert_uint16(buf, e.comp_activation_methods.value);
2486 pldm_msgbuf_insert_uint32(buf, e.capabilities_during_update.value);
2487
2488 // - Version strings
2489 rc = pldm__msgbuf_insert_array_void(buf, e.active_comp_ver_str_len,
2490 e.active_comp_ver_str,
2491 e.active_comp_ver_str_len);
2492 ASSERT_EQ(rc, 0);
2493 rc = pldm__msgbuf_insert_array_void(buf, e.pending_comp_ver_str_len,
2494 e.pending_comp_ver_str,
2495 e.pending_comp_ver_str_len);
2496 ASSERT_EQ(rc, 0);
2497 }
2498
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302499 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302500 ASSERT_EQ(rc, 0);
2501
2502 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2503 struct pldm_downstream_device_parameters_iter iter = {};
2504
2505 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2506 &resp_data, &iter);
2507
2508 ASSERT_EQ(rc, 0);
2509 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
2510 EXPECT_EQ(resp_data.next_data_transfer_handle,
2511 next_data_transfer_handle_resp);
2512 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2513 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
2514
2515 struct pldm_downstream_device_parameters_entry entry;
2516 size_t entryIndex = 0;
2517 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2518 {
2519 ASSERT_LE(entryIndex, table.size());
2520
2521 EXPECT_EQ(table[entryIndex].downstream_device_index,
2522 entry.downstream_device_index);
2523 EXPECT_EQ(table[entryIndex].active_comp_comparison_stamp,
2524 entry.active_comp_comparison_stamp);
2525 EXPECT_EQ(table[entryIndex].active_comp_ver_str_type,
2526 entry.active_comp_ver_str_type);
2527 EXPECT_EQ(table[entryIndex].active_comp_ver_str_len,
2528 entry.active_comp_ver_str_len);
2529 EXPECT_STREQ(&table[entryIndex].active_comp_release_date[0],
2530 &entry.active_comp_release_date[0]);
2531 EXPECT_EQ(table[entryIndex].pending_comp_comparison_stamp,
2532 entry.pending_comp_comparison_stamp);
2533 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_type,
2534 entry.pending_comp_ver_str_type);
2535 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_len,
2536 entry.pending_comp_ver_str_len);
2537 EXPECT_STREQ(&table[entryIndex].pending_comp_release_date[0],
2538 &entry.pending_comp_release_date[0]);
2539 EXPECT_EQ(table[entryIndex].comp_activation_methods.value,
2540 entry.comp_activation_methods.value);
2541 EXPECT_EQ(table[entryIndex].capabilities_during_update.value,
2542 entry.capabilities_during_update.value);
2543 EXPECT_FALSE(memcmp(table[entryIndex].active_comp_ver_str,
2544 entry.active_comp_ver_str,
2545 table[entryIndex].active_comp_ver_str_len));
2546 EXPECT_FALSE(memcmp(table[entryIndex].pending_comp_ver_str,
2547 entry.pending_comp_ver_str,
2548 table[entryIndex].pending_comp_ver_str_len));
2549 entryIndex++;
2550 }
2551 EXPECT_EQ(rc, 0);
2552 EXPECT_EQ(entryIndex, table.size());
Chris Wangb6ef35b2024-07-03 09:35:42 +08002553}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002554
Chris Wangb6ef35b2024-07-03 09:35:42 +08002555TEST(GetDownstreamFirmwareParameters, decodeResponseInvalidLength)
2556{
2557 /** Count is not fixed here taking it as 1, and the downstream device's
2558 * version strings length are set to 8
2559 */
2560 constexpr uint16_t downstreamDeviceCount = 1;
2561 constexpr uint8_t activeComponentVersionStringLength = 8;
2562 constexpr uint8_t pendingComponentVersionStringLength = 8;
2563 constexpr size_t downstreamDeviceParamTableLen =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302564 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002565 activeComponentVersionStringLength +
2566 pendingComponentVersionStringLength;
2567 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2568 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2569 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2570 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2571
2572 std::array<uint8_t,
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302573 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002574 downstreamDeviceParamTableLen - 1 /* inject error length*/>
2575 responseMsg{};
2576
2577 int rc = 0;
2578
Andrew Jefferya1896962025-03-03 21:41:25 +10302579 PLDM_MSGBUF_DEFINE_P(buf);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002580 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
2581 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10302582 ASSERT_EQ(rc, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002583
2584 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2585 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2586 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2587 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2588 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
Andrew Jefferya1896962025-03-03 21:41:25 +10302589 ASSERT_EQ(pldm_msgbuf_complete(buf), 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002590
2591 /** Filling paramter table, the correctness of the downstream devices data
2592 * is not checked in this test case so filling with 0xff
2593 */
2594 std::fill_n(responseMsg.data() + hdrSize +
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302595 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN,
Chris Wangb6ef35b2024-07-03 09:35:42 +08002596 downstreamDeviceParamTableLen - 1 /* inject error length*/,
2597 0xff);
2598
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302599 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002600 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302601 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302602 struct pldm_downstream_device_parameters_iter iter;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002603
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302604 rc = decode_get_downstream_firmware_parameters_resp(
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302605 response, responseMsg.size() - hdrSize, &resp_data, &iter);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002606 EXPECT_EQ(rc, 0);
2607
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302608 struct pldm_downstream_device_parameters_entry entry;
2609 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2610 {
2611 FAIL();
2612 }
2613 EXPECT_EQ(rc, -EOVERFLOW);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002614}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002615
Andrew Jeffery9c766792022-08-10 23:12:49 +09302616TEST(RequestUpdate, goodPathEncodeRequest)
2617{
2618 constexpr uint8_t instanceId = 1;
2619 constexpr uint32_t maxTransferSize = 512;
2620 constexpr uint16_t numOfComp = 3;
2621 constexpr uint8_t maxOutstandingTransferReq = 2;
2622 constexpr uint16_t pkgDataLen = 0x1234;
2623 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2624 constexpr uint8_t compImgSetVerStrLen =
2625 static_cast<uint8_t>(compImgSetVerStr.size());
2626 variable_field compImgSetVerStrInfo{};
2627 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302628 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302629 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2630 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2631
2632 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2633 compImgSetVerStrLen>
2634 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302635 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302636 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2637
2638 auto rc = encode_request_update_req(
2639 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2640 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2641 &compImgSetVerStrInfo, requestMsg,
2642 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2643 EXPECT_EQ(rc, PLDM_SUCCESS);
2644
2645 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2646 compImgSetVerStrLen>
2647 outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00,
2648 0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e,
2649 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30};
2650 EXPECT_EQ(request, outRequest);
2651}
2652
2653TEST(RequestUpdate, errorPathEncodeRequest)
2654{
2655 constexpr uint8_t instanceId = 1;
2656 uint32_t maxTransferSize = 512;
2657 constexpr uint16_t numOfComp = 3;
2658 uint8_t maxOutstandingTransferReq = 2;
2659 constexpr uint16_t pkgDataLen = 0x1234;
2660 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2661 uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2662 variable_field compImgSetVerStrInfo{};
2663 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302664 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302665 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2666 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2667
2668 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2669 compImgSetVerStr.size()>
2670 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302671 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302672 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2673
2674 auto rc = encode_request_update_req(
2675 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2676 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr,
2677 requestMsg,
2678 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2679 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2680
2681 compImgSetVerStrInfo.ptr = nullptr;
2682 rc = encode_request_update_req(
2683 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2684 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2685 &compImgSetVerStrInfo, requestMsg,
2686 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2687 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2688 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302689 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302690 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2691
2692 rc = encode_request_update_req(
2693 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2694 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2695 &compImgSetVerStrInfo, nullptr,
2696 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2697 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2698
2699 rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp,
2700 maxOutstandingTransferReq, pkgDataLen,
2701 PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2702 &compImgSetVerStrInfo, requestMsg, 0);
2703 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2704
2705 compImgSetVerStrLen = 0;
2706 rc = encode_request_update_req(
2707 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2708 pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr,
2709 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2710 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2711 compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2712
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06002713 compImgSetVerStrInfo.length = 0xffff;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302714 rc = encode_request_update_req(
2715 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2716 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2717 &compImgSetVerStrInfo, nullptr,
2718 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2719 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2720 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2721
2722 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1;
2723 rc = encode_request_update_req(
2724 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2725 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2726 &compImgSetVerStrInfo, nullptr,
2727 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2728 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2729 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE;
2730
2731 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ - 1;
2732 rc = encode_request_update_req(
2733 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2734 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2735 &compImgSetVerStrInfo, nullptr,
2736 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2737 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2738 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ;
2739
2740 rc = encode_request_update_req(
2741 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2742 pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen,
2743 &compImgSetVerStrInfo, nullptr,
2744 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2745 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2746}
2747
2748TEST(RequestUpdate, goodPathDecodeResponse)
2749{
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002750 /* Test a success completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09302751 constexpr uint16_t fdMetaDataLen = 1024;
2752 constexpr uint8_t fdWillSendPkgData = 1;
2753 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)>
2754 requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01};
2755
2756 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302757 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302758 reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data());
2759 uint8_t outCompletionCode = 0;
2760 uint16_t outFdMetaDataLen = 0;
2761 uint8_t outFdWillSendPkgData = 0;
2762
2763 auto rc = decode_request_update_resp(
2764 responseMsg1, requestUpdateResponse1.size() - hdrSize,
2765 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2766 EXPECT_EQ(rc, PLDM_SUCCESS);
2767 EXPECT_EQ(outCompletionCode, PLDM_SUCCESS);
2768 EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen);
2769 EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData);
2770
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002771#ifdef LIBPLDM_API_TESTING
2772 /* Check the success roundtrip matches */
2773 PLDM_MSG_DEFINE_P(enc, 1000);
2774 size_t enc_payload_len = 1000;
2775 const struct pldm_request_update_resp resp_data = {
2776 .completion_code = PLDM_SUCCESS,
2777 .fd_meta_data_len = outFdMetaDataLen,
2778 .fd_will_send_pkg_data = outFdWillSendPkgData,
2779 };
2780 rc = encode_request_update_resp(FIXED_INSTANCE_ID, &resp_data, enc,
2781 &enc_payload_len);
2782 EXPECT_EQ(rc, PLDM_SUCCESS);
2783 EXPECT_EQ(enc_payload_len + hdrSize, requestUpdateResponse1.size());
2784 EXPECT_TRUE(std::equal(requestUpdateResponse1.begin() + hdrSize,
2785 requestUpdateResponse1.end(), enc_buf + hdrSize));
2786 check_response(enc, PLDM_REQUEST_UPDATE);
2787#endif
2788
2789 /* Test a failure completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09302790 outCompletionCode = 0;
2791 outFdMetaDataLen = 0;
2792 outFdWillSendPkgData = 0;
2793
2794 constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)>
2795 requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
2796 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302797 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302798 reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data());
2799 rc = decode_request_update_resp(
2800 responseMsg2, requestUpdateResponse2.size() - hdrSize,
2801 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2802 EXPECT_EQ(rc, PLDM_SUCCESS);
2803 EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
2804}
2805
2806TEST(RequestUpdate, errorPathDecodeResponse)
2807{
2808 constexpr std::array<uint8_t,
2809 hdrSize + sizeof(pldm_request_update_resp) - 1>
2810 requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
2811
2812 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302813 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302814 reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data());
2815 uint8_t outCompletionCode = 0;
2816 uint16_t outFdMetaDataLen = 0;
2817 uint8_t outFdWillSendPkgData = 0;
2818
2819 auto rc = decode_request_update_resp(
2820 nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2821 &outFdMetaDataLen, &outFdWillSendPkgData);
2822 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2823
2824 rc = decode_request_update_resp(
2825 responseMsg, requestUpdateResponse.size() - hdrSize, nullptr,
2826 &outFdMetaDataLen, &outFdWillSendPkgData);
2827 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2828
2829 rc = decode_request_update_resp(
2830 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2831 nullptr, &outFdWillSendPkgData);
2832 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2833
2834 rc = decode_request_update_resp(
2835 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2836 &outFdMetaDataLen, nullptr);
2837 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2838
2839 rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode,
2840 &outFdMetaDataLen, &outFdWillSendPkgData);
2841 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2842
2843 rc = decode_request_update_resp(
2844 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2845 &outFdMetaDataLen, &outFdWillSendPkgData);
2846 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2847}
2848
2849TEST(PassComponentTable, goodPathEncodeRequest)
2850{
2851 constexpr uint8_t instanceId = 1;
2852 constexpr uint16_t compIdentifier = 400;
2853 constexpr uint8_t compClassificationIndex = 40;
2854 constexpr uint32_t compComparisonStamp = 0x12345678;
2855 constexpr std::string_view compVerStr = "0penBmcv1.1";
2856 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2857 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302858 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302859 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2860 compVerStrInfo.length = compVerStrLen;
2861
2862 std::array<uint8_t,
2863 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2864 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302865 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302866 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2867
2868 auto rc = encode_pass_component_table_req(
2869 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2870 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2871 compVerStrLen, &compVerStrInfo, requestMsg,
2872 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2873 EXPECT_EQ(rc, PLDM_SUCCESS);
2874
2875 std::array<uint8_t,
2876 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06002877 outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28,
2878 0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65,
2879 0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31};
Andrew Jeffery9c766792022-08-10 23:12:49 +09302880 EXPECT_EQ(request, outRequest);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002881
2882#ifdef LIBPLDM_API_TESTING
2883 /* Check the roundtrip */
2884 struct pldm_pass_component_table_req_full req;
2885 PLDM_MSG_DEFINE_P(dec, outRequest.size());
2886 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
2887 rc =
2888 decode_pass_component_table_req(dec, outRequest.size() - hdrSize, &req);
2889 ASSERT_EQ(rc, 0);
2890
2891 EXPECT_EQ(req.transfer_flag, PLDM_START_AND_END);
2892 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
2893 EXPECT_EQ(req.comp_identifier, compIdentifier);
2894 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
2895 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
2896 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
2897 EXPECT_EQ(req.version.str_len, compVerStrLen);
2898 EXPECT_TRUE(std::equal(req.version.str_data,
2899 req.version.str_data + req.version.str_len,
2900 compVerStr.data()));
2901#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09302902}
2903
2904TEST(PassComponentTable, errorPathEncodeRequest)
2905{
2906 constexpr uint8_t instanceId = 1;
2907 constexpr uint16_t compIdentifier = 400;
2908 constexpr uint8_t compClassificationIndex = 40;
2909 constexpr uint32_t compComparisonStamp = 0x12345678;
2910 constexpr std::string_view compVerStr = "0penBmcv1.1";
2911 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2912 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302913 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302914 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2915 compVerStrInfo.length = compVerStrLen;
2916
2917 std::array<uint8_t,
2918 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2919 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302920 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302921 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2922
2923 auto rc = encode_pass_component_table_req(
2924 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2925 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2926 compVerStrLen, nullptr, requestMsg,
2927 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2928 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2929
2930 compVerStrInfo.ptr = nullptr;
2931 rc = encode_pass_component_table_req(
2932 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2933 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2934 compVerStrLen, &compVerStrInfo, requestMsg,
2935 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2936 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302937 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302938 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2939
2940 rc = encode_pass_component_table_req(
2941 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2942 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2943 compVerStrLen, &compVerStrInfo, nullptr,
2944 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2945 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2946
2947 rc = encode_pass_component_table_req(
2948 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2949 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2950 compVerStrLen, &compVerStrInfo, requestMsg,
2951 sizeof(pldm_pass_component_table_req));
2952 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2953
2954 rc = encode_pass_component_table_req(
2955 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2956 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0,
2957 &compVerStrInfo, requestMsg,
2958 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2959 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2960
2961 rc = encode_pass_component_table_req(
2962 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2963 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2964 compVerStrLen - 1, &compVerStrInfo, requestMsg,
2965 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2966 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2967
2968 rc = encode_pass_component_table_req(
2969 instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier,
2970 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2971 compVerStrLen, &compVerStrInfo, requestMsg,
2972 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2973 EXPECT_EQ(rc, PLDM_INVALID_TRANSFER_OPERATION_FLAG);
2974
2975 rc = encode_pass_component_table_req(
2976 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2977 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN,
2978 compVerStrLen, &compVerStrInfo, requestMsg,
2979 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2980 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2981}
2982
2983TEST(PassComponentTable, goodPathDecodeResponse)
2984{
2985 constexpr std::array<uint8_t,
2986 hdrSize + sizeof(pldm_pass_component_table_resp)>
2987 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
2988 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302989 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302990 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
2991
2992 uint8_t completionCode = 0;
2993 uint8_t compResp = 0;
2994 uint8_t compRespCode = 0;
2995
2996 auto rc = decode_pass_component_table_resp(
2997 responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode,
2998 &compResp, &compRespCode);
2999
3000 EXPECT_EQ(rc, PLDM_SUCCESS);
3001 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3002 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3003 EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL);
3004
3005 constexpr std::array<uint8_t,
3006 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003007 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303008 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303009 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303010 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3011 rc = decode_pass_component_table_resp(
3012 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3013 &compResp, &compRespCode);
3014
3015 EXPECT_EQ(rc, PLDM_SUCCESS);
3016 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3017 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3018 EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN);
3019
3020 constexpr std::array<uint8_t,
3021 hdrSize + sizeof(pldm_pass_component_table_resp)>
3022 passCompTableResponse3{0x00, 0x00, 0x00, 0x80};
3023 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303024 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303025 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3026
3027 rc = decode_pass_component_table_resp(
3028 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3029 &compResp, &compRespCode);
3030
3031 EXPECT_EQ(rc, PLDM_SUCCESS);
3032 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3033}
3034
3035TEST(PassComponentTable, errorPathDecodeResponse)
3036{
3037 constexpr std::array<uint8_t,
3038 hdrSize + sizeof(pldm_pass_component_table_resp) - 1>
3039 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00};
3040 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303041 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303042 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3043
3044 uint8_t completionCode = 0;
3045 uint8_t compResp = 0;
3046 uint8_t compRespCode = 0;
3047
3048 auto rc = decode_pass_component_table_resp(
3049 nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode,
3050 &compResp, &compRespCode);
3051 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3052
3053 rc = decode_pass_component_table_resp(
3054 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr,
3055 &compResp, &compRespCode);
3056 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3057
3058 rc = decode_pass_component_table_resp(
3059 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3060 &completionCode, nullptr, &compRespCode);
3061 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3062
3063 rc = decode_pass_component_table_resp(
3064 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3065 &completionCode, &compResp, nullptr);
3066 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3067
3068 rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode,
3069 &compResp, &compRespCode);
3070 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3071
3072 rc = decode_pass_component_table_resp(
3073 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3074 &completionCode, &compResp, &compRespCode);
3075 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3076
3077 constexpr std::array<uint8_t,
3078 hdrSize + sizeof(pldm_pass_component_table_resp)>
3079 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
3080 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303081 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303082 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3083 rc = decode_pass_component_table_resp(
3084 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3085 &compResp, &compRespCode);
3086 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3087
3088 constexpr std::array<uint8_t,
3089 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003090 passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303091 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303092 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303093 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3094 rc = decode_pass_component_table_resp(
3095 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3096 &compResp, &compRespCode);
3097 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3098
3099 constexpr std::array<uint8_t,
3100 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003101 passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303102 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303103 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303104 reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data());
3105 rc = decode_pass_component_table_resp(
3106 responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode,
3107 &compResp, &compRespCode);
3108 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3109}
3110
3111TEST(UpdateComponent, goodPathEncodeRequest)
3112{
3113 constexpr uint8_t instanceId = 2;
3114 constexpr uint16_t compIdentifier = 500;
3115 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003116 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303117 constexpr uint32_t compImageSize = 4096;
3118 constexpr bitfield32_t updateOptionFlags{1};
3119 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3120 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3121 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303122 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303123 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3124 compVerStrInfo.length = compVerStrLen;
3125
3126 std::array<uint8_t,
3127 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3128 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303129 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303130 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3131
3132 auto rc = encode_update_component_req(
3133 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3134 compComparisonStamp, compImageSize, updateOptionFlags,
3135 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3136 sizeof(pldm_update_component_req) + compVerStrLen);
3137 EXPECT_EQ(rc, PLDM_SUCCESS);
3138
3139 std::array<uint8_t,
3140 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003141 outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
3142 0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
3143 0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
3144 0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303145 EXPECT_EQ(request, outRequest);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08003146
3147#ifdef LIBPLDM_API_TESTING
3148 /* Check the roundtrip */
3149 struct pldm_update_component_req_full req;
3150 PLDM_MSG_DEFINE_P(dec, outRequest.size());
3151 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3152 rc = decode_update_component_req(dec, outRequest.size() - hdrSize, &req);
3153 ASSERT_EQ(rc, 0);
3154
3155 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3156 EXPECT_EQ(req.comp_identifier, compIdentifier);
3157 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3158 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3159 EXPECT_EQ(req.comp_image_size, compImageSize);
3160 EXPECT_EQ(req.update_option_flags.value, updateOptionFlags.value);
3161 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3162 EXPECT_EQ(req.version.str_len, compVerStrLen);
3163 EXPECT_TRUE(std::equal(req.version.str_data,
3164 req.version.str_data + req.version.str_len,
3165 compVerStr.data()));
3166#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09303167}
3168
3169TEST(UpdateComponent, errorPathEncodeRequest)
3170{
3171 constexpr uint8_t instanceId = 2;
3172 constexpr uint16_t compIdentifier = 500;
3173 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003174 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303175 constexpr uint32_t compImageSize = 4096;
3176 constexpr bitfield32_t updateOptionFlags{1};
3177 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3178 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3179 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303180 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303181 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3182 compVerStrInfo.length = compVerStrLen;
3183
3184 std::array<uint8_t,
3185 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3186 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303187 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303188 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3189
3190 auto rc = encode_update_component_req(
3191 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3192 compComparisonStamp, compImageSize, updateOptionFlags,
3193 PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
3194 sizeof(pldm_update_component_req) + compVerStrLen);
3195 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3196
3197 compVerStrInfo.ptr = nullptr;
3198 rc = encode_update_component_req(
3199 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3200 compComparisonStamp, compImageSize, updateOptionFlags,
3201 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3202 sizeof(pldm_update_component_req) + compVerStrLen);
3203 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303204 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303205 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3206
3207 rc = encode_update_component_req(
3208 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3209 compComparisonStamp, compImageSize, updateOptionFlags,
3210 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
3211 sizeof(pldm_update_component_req) + compVerStrLen);
3212 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3213
3214 rc = encode_update_component_req(
3215 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3216 compComparisonStamp, compImageSize, updateOptionFlags,
3217 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3218 sizeof(pldm_update_component_req));
3219 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3220
3221 rc = encode_update_component_req(
3222 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3223 compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
3224 compVerStrLen, &compVerStrInfo, requestMsg,
3225 sizeof(pldm_update_component_req) + compVerStrLen);
3226 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3227
3228 rc = encode_update_component_req(
3229 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3230 compComparisonStamp, compImageSize, updateOptionFlags,
3231 PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg,
3232 sizeof(pldm_update_component_req) + compVerStrLen);
3233 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3234
3235 rc = encode_update_component_req(
3236 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3237 compComparisonStamp, compImageSize, updateOptionFlags,
3238 PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg,
3239 sizeof(pldm_update_component_req) + compVerStrLen);
3240 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3241
3242 rc = encode_update_component_req(
3243 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3244 compComparisonStamp, compImageSize, updateOptionFlags,
3245 PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
3246 sizeof(pldm_update_component_req) + compVerStrLen);
3247 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3248}
3249
3250TEST(UpdateComponent, goodPathDecodeResponse)
3251{
3252 constexpr std::bitset<32> forceUpdateComp{1};
3253 constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
3254 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3255 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3256 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3257 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303258 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303259 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3260
3261 uint8_t completionCode = 0;
3262 uint8_t compCompatibilityResp = 0;
3263 uint8_t compCompatibilityRespCode = 0;
3264 bitfield32_t updateOptionFlagsEnabled{};
3265 uint16_t timeBeforeReqFWData = 0;
3266
3267 auto rc = decode_update_component_resp(
3268 responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
3269 &compCompatibilityResp, &compCompatibilityRespCode,
3270 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3271
3272 EXPECT_EQ(rc, PLDM_SUCCESS);
3273 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3274 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
3275 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
3276 EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
3277 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
3278
3279 constexpr std::bitset<32> noFlags{};
3280 constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
3281 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3282 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3283 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3284 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303285 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303286 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3287 rc = decode_update_component_resp(
3288 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3289 &compCompatibilityResp, &compCompatibilityRespCode,
3290 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3291
3292 EXPECT_EQ(rc, PLDM_SUCCESS);
3293 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3294 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
3295 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
3296 EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
3297 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
3298
3299 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3300 updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
3301 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303302 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303303 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3304
3305 rc = decode_update_component_resp(
3306 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3307 &compCompatibilityResp, &compCompatibilityRespCode,
3308 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3309
3310 EXPECT_EQ(rc, PLDM_SUCCESS);
3311 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3312}
3313
3314TEST(UpdateComponent, errorPathDecodeResponse)
3315{
3316 constexpr std::array<uint8_t,
3317 hdrSize + sizeof(pldm_update_component_resp) - 1>
3318 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3319 0x00, 0x00, 0x00, 0x00, 0x00};
3320 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303321 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303322 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3323
3324 uint8_t completionCode = 0;
3325 uint8_t compCompatibilityResp = 0;
3326 uint8_t compCompatibilityRespCode = 0;
3327 bitfield32_t updateOptionFlagsEnabled{};
3328 uint16_t timeBeforeReqFWData = 0;
3329
3330 auto rc = decode_update_component_resp(
3331 nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
3332 &compCompatibilityResp, &compCompatibilityRespCode,
3333 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3334 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3335
3336 rc = decode_update_component_resp(
3337 responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
3338 &compCompatibilityResp, &compCompatibilityRespCode,
3339 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3340 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3341
3342 rc = decode_update_component_resp(
3343 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3344 nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3345 &timeBeforeReqFWData);
3346 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3347
3348 rc = decode_update_component_resp(
3349 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3350 &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
3351 &timeBeforeReqFWData);
3352 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3353
3354 rc = decode_update_component_resp(
3355 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3356 &compCompatibilityResp, &compCompatibilityRespCode, nullptr,
3357 &timeBeforeReqFWData);
3358 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3359
3360 rc = decode_update_component_resp(
3361 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3362 &compCompatibilityResp, &compCompatibilityRespCode,
3363 &updateOptionFlagsEnabled, nullptr);
3364 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3365
3366 rc = decode_update_component_resp(
3367 responseMsg1, 0, &completionCode, &compCompatibilityResp,
3368 &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3369 &timeBeforeReqFWData);
3370 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3371
3372 rc = decode_update_component_resp(
3373 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3374 &compCompatibilityResp, &compCompatibilityRespCode,
3375 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3376 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3377
3378 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3379 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
3380 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3381 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303382 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303383 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3384 rc = decode_update_component_resp(
3385 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3386 &compCompatibilityResp, &compCompatibilityRespCode,
3387 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3388 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3389
3390 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003391 updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303392 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3393 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303394 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303395 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3396 rc = decode_update_component_resp(
3397 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3398 &compCompatibilityResp, &compCompatibilityRespCode,
3399 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3400 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3401
3402 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003403 updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303404 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3405 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303406 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303407 reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
3408 rc = decode_update_component_resp(
3409 responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
3410 &compCompatibilityResp, &compCompatibilityRespCode,
3411 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3412 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3413}
3414
3415TEST(RequestFirmwareData, goodPathDecodeRequest)
3416{
3417 constexpr uint32_t offset = 300;
3418 constexpr uint32_t length = 255;
3419 constexpr std::array<uint8_t,
3420 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003421 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3422 0x00, 0xff, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303423 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303424 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3425
3426 uint32_t outOffset = 0;
3427 uint32_t outLength = 0;
3428 auto rc = decode_request_firmware_data_req(
3429 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3430 &outLength);
3431
3432 EXPECT_EQ(rc, PLDM_SUCCESS);
3433 EXPECT_EQ(outOffset, offset);
3434 EXPECT_EQ(outLength, length);
3435}
3436
3437TEST(RequestFirmwareData, errorPathDecodeRequest)
3438{
3439 constexpr std::array<uint8_t,
3440 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003441 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3442 0x00, 0x1f, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303443 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303444 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3445
3446 uint32_t outOffset = 0;
3447 uint32_t outLength = 0;
3448 auto rc = decode_request_firmware_data_req(
3449 nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
3450 &outLength);
3451 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3452
3453 rc = decode_request_firmware_data_req(
3454 requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
3455 &outLength);
3456 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3457
3458 rc = decode_request_firmware_data_req(
3459 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3460 nullptr);
3461 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3462
3463 rc = decode_request_firmware_data_req(
3464 requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
3465 &outLength);
3466 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3467
3468 rc = decode_request_firmware_data_req(
3469 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3470 &outLength);
3471 EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
3472}
3473
3474TEST(RequestFirmwareData, goodPathEncodeResponse)
3475{
3476 constexpr uint8_t instanceId = 3;
3477 constexpr uint8_t completionCode = PLDM_SUCCESS;
3478 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
3479 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3480 outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003481 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3482 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3483 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3484 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303485 std::array<uint8_t, hdrSize + sizeof(completionCode) +
3486 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3487 reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003488 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3489 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3490 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3491 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303492 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303493 auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
3494 auto rc = encode_request_firmware_data_resp(
3495 instanceId, completionCode, responseMsg1,
3496 sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
3497 EXPECT_EQ(rc, PLDM_SUCCESS);
3498 EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
3499
3500 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3501 outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
3502 std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
3503 0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303504 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303505 auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
3506 rc = encode_request_firmware_data_resp(
3507 instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
3508 sizeof(completionCode));
3509 EXPECT_EQ(rc, PLDM_SUCCESS);
3510 EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
3511}
3512
3513TEST(RequestFirmwareData, errorPathEncodeResponse)
3514{
3515 std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303516 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303517 auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
3518 auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
3519 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3520
3521 rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
3522 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3523}
3524
3525TEST(TransferComplete, goodPathDecodeRequest)
3526{
3527 constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
3528 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3529 transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
3530 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303531 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303532 reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
3533 uint8_t outTransferResult = 0;
3534
3535 auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
3536 &outTransferResult);
3537 EXPECT_EQ(rc, PLDM_SUCCESS);
3538 EXPECT_EQ(outTransferResult, transferResult);
3539
3540 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3541 transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
3542 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303543 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303544 reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
3545 rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
3546 &outTransferResult);
3547 EXPECT_EQ(rc, PLDM_SUCCESS);
3548 EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
3549}
3550
3551TEST(TransferComplete, errorPathDecodeRequest)
3552{
3553 constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
3554 0x00};
3555 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303556 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303557 reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
3558 uint8_t outTransferResult = 0;
3559
3560 auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
3561 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3562
3563 rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
3564 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3565
3566 rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
3567 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3568}
3569
3570TEST(TransferComplete, goodPathEncodeResponse)
3571{
3572 constexpr uint8_t instanceId = 4;
3573 constexpr uint8_t completionCode = PLDM_SUCCESS;
3574 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3575 outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
3576 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3577 transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3578 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303579 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303580 reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
3581 auto rc = encode_transfer_complete_resp(
3582 instanceId, completionCode, responseMsg1, sizeof(completionCode));
3583 EXPECT_EQ(rc, PLDM_SUCCESS);
3584 EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
3585
3586 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3587 outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
3588 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3589 transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3590 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303591 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303592 reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
3593 rc = encode_transfer_complete_resp(instanceId,
3594 PLDM_FWUP_COMMAND_NOT_EXPECTED,
3595 responseMsg2, sizeof(completionCode));
3596 EXPECT_EQ(rc, PLDM_SUCCESS);
3597 EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
3598}
3599
3600TEST(TransferComplete, errorPathEncodeResponse)
3601{
3602 std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
3603 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303604 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303605 reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
3606 auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3607 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3608
3609 rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3610 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3611}
3612
3613TEST(VerifyComplete, goodPathDecodeRequest)
3614{
3615 constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
3616 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3617 verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
3618 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303619 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303620 reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
3621 uint8_t outVerifyResult = 0;
3622
3623 auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
3624 &outVerifyResult);
3625 EXPECT_EQ(rc, PLDM_SUCCESS);
3626 EXPECT_EQ(outVerifyResult, verifyResult);
3627
3628 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3629 verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
3630 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303631 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303632 reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
3633 rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
3634 &outVerifyResult);
3635 EXPECT_EQ(rc, PLDM_SUCCESS);
3636 EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
3637}
3638
3639TEST(VerifyComplete, errorPathDecodeRequest)
3640{
3641 constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
3642 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303643 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303644 reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
3645 uint8_t outVerifyResult = 0;
3646
3647 auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
3648 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3649
3650 rc = decode_verify_complete_req(requestMsg, 0, nullptr);
3651 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3652
3653 rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);
3654 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3655}
3656
3657TEST(VerifyComplete, goodPathEncodeResponse)
3658{
3659 constexpr uint8_t instanceId = 5;
3660 constexpr uint8_t completionCode = PLDM_SUCCESS;
3661 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3662 outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};
3663 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3664 verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3665 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303666 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303667 reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());
3668 auto rc = encode_verify_complete_resp(instanceId, completionCode,
3669 responseMsg1, sizeof(completionCode));
3670 EXPECT_EQ(rc, PLDM_SUCCESS);
3671 EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);
3672
3673 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3674 outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88};
3675 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3676 verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3677 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303678 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303679 reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());
3680 rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3681 responseMsg2, sizeof(completionCode));
3682 EXPECT_EQ(rc, PLDM_SUCCESS);
3683 EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);
3684}
3685
3686TEST(VerifyComplete, errorPathEncodeResponse)
3687{
3688 std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00};
3689 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303690 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303691 reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());
3692 auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3693 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3694
3695 rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3696 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3697}
3698
3699TEST(ApplyComplete, goodPathDecodeRequest)
3700{
3701 constexpr uint8_t applyResult1 =
3702 PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
3703 // DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
3704 constexpr std::bitset<16> compActivationModification1{0x30};
3705 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3706 applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
3707 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303708 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303709 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3710 uint8_t outApplyResult = 0;
3711 bitfield16_t outCompActivationModification{};
3712 auto rc = decode_apply_complete_req(
3713 requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
3714 &outCompActivationModification);
3715 EXPECT_EQ(rc, PLDM_SUCCESS);
3716 EXPECT_EQ(outApplyResult, applyResult1);
3717 EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
3718
3719 constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
3720 constexpr std::bitset<16> compActivationModification2{};
3721 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3722 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3723 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303724 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303725 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3726 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3727 &outApplyResult,
3728 &outCompActivationModification);
3729 EXPECT_EQ(rc, PLDM_SUCCESS);
3730 EXPECT_EQ(outApplyResult, applyResult2);
3731 EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
3732}
3733
3734TEST(ApplyComplete, errorPathDecodeRequest)
3735{
3736 constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
3737 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303738 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303739 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3740 uint8_t outApplyResult = 0;
3741 bitfield16_t outCompActivationModification{};
3742
3743 auto rc = decode_apply_complete_req(
3744 nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
3745 &outCompActivationModification);
3746 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3747
3748 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3749 nullptr, &outCompActivationModification);
3750 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3751
3752 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3753 &outApplyResult, nullptr);
3754 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3755
3756 rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
3757 &outCompActivationModification);
3758 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3759
3760 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3761 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
3762 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303763 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303764 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3765 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3766 &outApplyResult,
3767 &outCompActivationModification);
3768 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3769}
3770
3771TEST(ApplyComplete, goodPathEncodeResponse)
3772{
3773 constexpr uint8_t instanceId = 6;
3774 constexpr uint8_t completionCode = PLDM_SUCCESS;
3775 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3776 outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
3777 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3778 applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3779 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303780 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303781 reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
3782 auto rc = encode_apply_complete_resp(instanceId, completionCode,
3783 responseMsg1, sizeof(completionCode));
3784 EXPECT_EQ(rc, PLDM_SUCCESS);
3785 EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
3786
3787 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3788 outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
3789 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3790 applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3791 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303792 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303793 reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
3794 rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3795 responseMsg2, sizeof(completionCode));
3796 EXPECT_EQ(rc, PLDM_SUCCESS);
3797 EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
3798}
3799
3800TEST(ApplyComplete, errorPathEncodeResponse)
3801{
3802 std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
3803 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303804 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303805 reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
3806 auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3807 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3808
3809 rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3810 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3811}
3812
3813TEST(ActivateFirmware, goodPathEncodeRequest)
3814{
3815 constexpr uint8_t instanceId = 7;
3816
3817 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303818 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303819 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3820
3821 auto rc = encode_activate_firmware_req(
3822 instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
3823 sizeof(pldm_activate_firmware_req));
3824 EXPECT_EQ(rc, PLDM_SUCCESS);
3825
3826 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003827 outRequest{0x87, 0x05, 0x1a, 0x01};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303828 EXPECT_EQ(request, outRequest);
3829}
3830
3831TEST(ActivateFirmware, errorPathEncodeRequest)
3832{
3833 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303834 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303835 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3836
3837 auto rc = encode_activate_firmware_req(
3838 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
3839 sizeof(pldm_activate_firmware_req));
3840 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3841
3842 rc = encode_activate_firmware_req(
3843 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
3844 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3845
3846 rc = encode_activate_firmware_req(0, 2, requestMsg,
3847 sizeof(pldm_activate_firmware_req));
3848 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3849}
3850
3851TEST(ActivateFirmware, goodPathDecodeResponse)
3852{
3853 constexpr uint16_t estimatedTimeForActivation100s = 100;
3854 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3855 activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
3856 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303857 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303858 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
3859
3860 uint8_t completionCode = 0;
3861 uint16_t estimatedTimeForActivation = 0;
3862
3863 auto rc = decode_activate_firmware_resp(
3864 responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
3865 &estimatedTimeForActivation);
3866
3867 EXPECT_EQ(rc, PLDM_SUCCESS);
3868 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3869 EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
3870
3871 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3872 activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
3873 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303874 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303875 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data());
3876
3877 rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
3878 &completionCode,
3879 &estimatedTimeForActivation);
3880
3881 EXPECT_EQ(rc, PLDM_SUCCESS);
3882 EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
3883}
3884
3885TEST(ActivateFirmware, errorPathDecodeResponse)
3886{
3887 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3888 activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3889 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303890 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303891 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
3892
3893 uint8_t completionCode = 0;
3894 uint16_t estimatedTimeForActivation = 0;
3895
3896 auto rc = decode_activate_firmware_resp(
3897 nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
3898 &estimatedTimeForActivation);
3899 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3900
3901 rc = decode_activate_firmware_resp(responseMsg,
3902 sizeof(pldm_activate_firmware_resp),
3903 nullptr, &estimatedTimeForActivation);
3904 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3905
3906 rc = decode_activate_firmware_resp(responseMsg,
3907 sizeof(pldm_activate_firmware_resp),
3908 &completionCode, nullptr);
3909 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3910
3911 rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
3912 &estimatedTimeForActivation);
3913 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3914
3915 rc = decode_activate_firmware_resp(
3916 responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
3917 &estimatedTimeForActivation);
3918 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3919}
3920
3921TEST(GetStatus, goodPathEncodeRequest)
3922{
3923 constexpr uint8_t instanceId = 8;
3924 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303925 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303926 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3927
3928 auto rc = encode_get_status_req(instanceId, requestMsg,
3929 PLDM_GET_STATUS_REQ_BYTES);
3930 EXPECT_EQ(rc, PLDM_SUCCESS);
3931
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003932 constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303933 EXPECT_EQ(request, outRequest);
3934}
3935
3936TEST(GetStatus, errorPathEncodeRequest)
3937{
3938 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303939 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303940 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3941
3942 auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
3943 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3944
3945 rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);
3946 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3947}
3948
3949TEST(GetStatus, goodPathDecodeResponse)
3950{
3951 constexpr std::bitset<32> updateOptionFlagsEnabled1{0};
3952 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3953 getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
3954 0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};
3955 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303956 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303957 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
3958
3959 uint8_t completionCode = 0;
3960 uint8_t currentState = 0;
3961 uint8_t previousState = 0;
3962 uint8_t auxState = 0;
3963 uint8_t auxStateStatus = 0;
3964 uint8_t progressPercent = 0;
3965 uint8_t reasonCode = 0;
3966 bitfield32_t updateOptionFlagsEnabled{0};
3967
3968 auto rc = decode_get_status_resp(
3969 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
3970 &currentState, &previousState, &auxState, &auxStateStatus,
3971 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3972
3973 EXPECT_EQ(rc, PLDM_SUCCESS);
3974 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3975 EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);
3976 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
3977 EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);
3978 EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);
3979 EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);
3980 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
3981 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);
3982
3983 // Bit position 0 - Force update of component – FD will perform a force
3984 // update of the component.
3985 constexpr std::bitset<32> updateOptionFlagsEnabled2{1};
3986 constexpr uint8_t progressPercent2 = 50;
3987 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
3988 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,
3989 0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};
3990 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303991 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303992 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
3993
3994 rc = decode_get_status_resp(
3995 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
3996 &currentState, &previousState, &auxState, &auxStateStatus,
3997 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
3998
3999 EXPECT_EQ(rc, PLDM_SUCCESS);
4000 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4001 EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);
4002 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4003 EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);
4004 EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);
4005 EXPECT_EQ(progressPercent, progressPercent2);
4006 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4007 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);
4008
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08004009#ifdef LIBPLDM_API_TESTING
4010 /* Check the roundtrip */
4011 PLDM_MSG_DEFINE_P(enc, 1000);
4012 size_t enc_payload_len = 1000;
4013 const struct pldm_get_status_resp status_enc = {
4014 .completion_code = PLDM_SUCCESS,
4015 .current_state = currentState,
4016 .previous_state = previousState,
4017 .aux_state = auxState,
4018 .aux_state_status = auxStateStatus,
4019 .progress_percent = progressPercent,
4020 .reason_code = reasonCode,
4021 .update_option_flags_enabled = updateOptionFlagsEnabled,
4022 };
4023 rc = encode_get_status_resp(FIXED_INSTANCE_ID, &status_enc, enc,
4024 &enc_payload_len);
4025 EXPECT_EQ(rc, PLDM_SUCCESS);
4026 EXPECT_EQ(enc_payload_len + hdrSize, getStatusResponse2.size());
4027 EXPECT_TRUE(std::equal(getStatusResponse2.begin() + hdrSize,
4028 getStatusResponse2.end(), enc_buf + hdrSize));
4029 check_response(enc, PLDM_GET_STATUS);
4030#endif
4031
4032 /* Check a not-ready completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09304033 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4034 getStatusResponse3{0x00, 0x00, 0x00, 0x04};
4035 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304036 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304037 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4038 rc = decode_get_status_resp(
4039 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4040 &currentState, &previousState, &auxState, &auxStateStatus,
4041 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4042 EXPECT_EQ(rc, PLDM_SUCCESS);
4043 EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);
4044}
4045
4046TEST(GetStatus, errorPathDecodeResponse)
4047{
4048 uint8_t completionCode = 0;
4049 uint8_t currentState = 0;
4050 uint8_t previousState = 0;
4051 uint8_t auxState = 0;
4052 uint8_t auxStateStatus = 0;
4053 uint8_t progressPercent = 0;
4054 uint8_t reasonCode = 0;
4055 bitfield32_t updateOptionFlagsEnabled{0};
4056
4057 constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};
4058 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304059 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304060 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4061
4062 auto rc = decode_get_status_resp(
4063 nullptr, getStatusResponse1.size() - hdrSize, &completionCode,
4064 &currentState, &previousState, &auxState, &auxStateStatus,
4065 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4066 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4067
4068 rc = decode_get_status_resp(
4069 responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,
4070 &currentState, &previousState, &auxState, &auxStateStatus,
4071 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4072 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4073
4074 rc = decode_get_status_resp(
4075 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4076 nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,
4077 &reasonCode, &updateOptionFlagsEnabled);
4078 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4079
4080 rc = decode_get_status_resp(
4081 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4082 &currentState, nullptr, &auxState, &auxStateStatus, &progressPercent,
4083 &reasonCode, &updateOptionFlagsEnabled);
4084 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4085
4086 rc = decode_get_status_resp(
4087 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4088 &currentState, &previousState, nullptr, &auxStateStatus,
4089 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4090 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4091
4092 rc = decode_get_status_resp(
4093 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4094 &currentState, &previousState, &auxState, nullptr, &progressPercent,
4095 &reasonCode, &updateOptionFlagsEnabled);
4096 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4097
4098 rc = decode_get_status_resp(
4099 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4100 &currentState, &previousState, &auxState, &auxStateStatus, nullptr,
4101 &reasonCode, &updateOptionFlagsEnabled);
4102 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4103
4104 rc = decode_get_status_resp(
4105 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4106 &currentState, &previousState, &auxState, &auxStateStatus,
4107 &progressPercent, nullptr, &updateOptionFlagsEnabled);
4108 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4109
4110 rc = decode_get_status_resp(
4111 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4112 &currentState, &previousState, &auxState, &auxStateStatus,
4113 &progressPercent, &reasonCode, nullptr);
4114 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4115
4116 rc = decode_get_status_resp(
4117 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4118 &currentState, &previousState, &auxState, &auxStateStatus,
4119 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4120 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4121
4122 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>
4123 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4125 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304126 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304127 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4128 rc = decode_get_status_resp(
4129 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4130 &currentState, &previousState, &auxState, &auxStateStatus,
4131 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4132 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4133
4134 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4135 getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
4136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4137 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304138 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304139 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4140 rc = decode_get_status_resp(
4141 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4142 &currentState, &previousState, &auxState, &auxStateStatus,
4143 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4144 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4145
4146 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4147 getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
4148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4149 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304150 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304151 reinterpret_cast<const pldm_msg*>(getStatusResponse4.data());
4152 rc = decode_get_status_resp(
4153 responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,
4154 &currentState, &previousState, &auxState, &auxStateStatus,
4155 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4156 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4157
4158 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4159 getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
4160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4161 auto responseMsg5 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304162 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304163 reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());
4164 rc = decode_get_status_resp(
4165 responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,
4166 &currentState, &previousState, &auxState, &auxStateStatus,
4167 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4168 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4169
4170 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4171 getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004172 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304173 auto responseMsg6 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304174 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304175 reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());
4176 rc = decode_get_status_resp(
4177 responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,
4178 &currentState, &previousState, &auxState, &auxStateStatus,
4179 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4180 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4181
4182 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4183 getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4184 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
4185 auto responseMsg7 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304186 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304187 reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());
4188 rc = decode_get_status_resp(
4189 responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,
4190 &currentState, &previousState, &auxState, &auxStateStatus,
4191 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4192 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4193
4194 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4195 getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004196 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304197 auto responseMsg8 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304198 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304199 reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());
4200 rc = decode_get_status_resp(
4201 responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,
4202 &currentState, &previousState, &auxState, &auxStateStatus,
4203 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4204 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4205
4206 // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is
4207 // IDLE
4208 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4209 getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
4210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4211 auto responseMsg9 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304212 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304213 reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());
4214 rc = decode_get_status_resp(
4215 responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,
4216 &currentState, &previousState, &auxState, &auxStateStatus,
4217 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4218 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4219}
4220
4221TEST(CancelUpdateComponent, goodPathEncodeRequest)
4222{
4223 constexpr uint8_t instanceId = 9;
4224 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304225 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304226 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4227
4228 auto rc = encode_cancel_update_component_req(
4229 instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4230 EXPECT_EQ(rc, PLDM_SUCCESS);
4231
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004232 constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304233 EXPECT_EQ(request, outRequest);
4234}
4235
4236TEST(CancelUpdateComponent, errorPathEncodeRequest)
4237{
4238 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304239 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304240 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4241
4242 auto rc = encode_cancel_update_component_req(
4243 0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4244 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4245
4246 rc = encode_cancel_update_component_req(
4247 0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);
4248 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4249}
4250
4251TEST(CancelUpdateComponent, testGoodDecodeResponse)
4252{
4253 uint8_t completionCode = 0;
4254 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4255 cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304256 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304257 auto responseMsg1 = reinterpret_cast<const pldm_msg*>(
4258 cancelUpdateComponentResponse1.data());
4259 auto rc = decode_cancel_update_component_resp(
4260 responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,
4261 &completionCode);
4262 EXPECT_EQ(rc, PLDM_SUCCESS);
4263 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4264
4265 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4266 cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304267 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304268 auto responseMsg2 = reinterpret_cast<const pldm_msg*>(
4269 cancelUpdateComponentResponse2.data());
4270 rc = decode_cancel_update_component_resp(
4271 responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,
4272 &completionCode);
4273 EXPECT_EQ(rc, PLDM_SUCCESS);
4274 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4275}
4276
4277TEST(CancelUpdateComponent, testBadDecodeResponse)
4278{
4279 uint8_t completionCode = 0;
4280 constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{
4281 0x00, 0x00, 0x00};
4282 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304283 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304284 reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data());
4285
4286 auto rc = decode_cancel_update_component_resp(
4287 nullptr, cancelUpdateComponentResponse.size() - hdrSize,
4288 &completionCode);
4289 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4290
4291 rc = decode_cancel_update_component_resp(
4292 responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);
4293 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4294
4295 rc = decode_cancel_update_component_resp(
4296 responseMsg, cancelUpdateComponentResponse.size() - hdrSize,
4297 &completionCode);
4298 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4299}
4300
4301TEST(CancelUpdate, goodPathEncodeRequest)
4302{
4303 constexpr uint8_t instanceId = 10;
4304 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304305 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304306 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4307
4308 auto rc = encode_cancel_update_req(instanceId, requestMsg,
4309 PLDM_CANCEL_UPDATE_REQ_BYTES);
4310 EXPECT_EQ(rc, PLDM_SUCCESS);
4311
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004312 constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304313 EXPECT_EQ(request, outRequest);
4314}
4315
4316TEST(CancelUpdate, errorPathEncodeRequest)
4317{
4318 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304319 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304320 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4321
4322 auto rc =
4323 encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
4324 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4325
4326 rc = encode_cancel_update_req(0, requestMsg,
4327 PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
4328 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4329}
4330
4331TEST(CancelUpdate, goodPathDecodeResponse)
4332{
4333 constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
4334 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4335 cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4337 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304338 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304339 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4340 uint8_t completionCode = 0;
4341 bool8_t nonFunctioningComponentIndication = 0;
4342 bitfield64_t nonFunctioningComponentBitmap{0};
4343 auto rc = decode_cancel_update_resp(
4344 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4345 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4346 EXPECT_EQ(rc, PLDM_SUCCESS);
4347 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4348 EXPECT_EQ(nonFunctioningComponentIndication,
4349 PLDM_FWUP_COMPONENTS_FUNCTIONING);
4350 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4351 nonFunctioningComponentBitmap1);
4352
4353 constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
4354 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4355 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
4356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4357 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304358 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304359 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4360 rc = decode_cancel_update_resp(
4361 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4362 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4363 EXPECT_EQ(rc, PLDM_SUCCESS);
4364 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4365 EXPECT_EQ(nonFunctioningComponentIndication,
4366 PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING);
4367 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4368 nonFunctioningComponentBitmap2);
4369
4370 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4371 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
4372 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304373 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304374 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4375 rc = decode_cancel_update_resp(
4376 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4377 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4378 EXPECT_EQ(rc, PLDM_SUCCESS);
4379 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4380}
4381
4382TEST(CancelUpdate, errorPathDecodeResponse)
4383{
4384 constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
4385 0x00};
4386 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304387 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304388 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4389 uint8_t completionCode = 0;
4390 bool8_t nonFunctioningComponentIndication = 0;
4391 bitfield64_t nonFunctioningComponentBitmap{0};
4392
4393 auto rc = decode_cancel_update_resp(
4394 nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4395 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4396 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4397
4398 rc = decode_cancel_update_resp(
4399 responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
4400 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4401 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4402
4403 rc = decode_cancel_update_resp(
4404 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4405 nullptr, &nonFunctioningComponentBitmap);
4406 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4407
4408 rc = decode_cancel_update_resp(
4409 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4410 &nonFunctioningComponentIndication, nullptr);
4411 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4412
4413 rc = decode_cancel_update_resp(
4414 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4415 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4416 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4417
4418 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4419 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
4420 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304421 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304422 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4423 rc = decode_cancel_update_resp(
4424 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4425 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4426 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4427
4428 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4429 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
4430 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4431 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304432 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304433 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4434 rc = decode_cancel_update_resp(
4435 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4436 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4437 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4438}